1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:57:45 +00:00

Spreadsheet: Show the error (if any) in csv import dialog's preview

...and don't try to read from a CSV that has errors.
Fixes #5942.
This commit is contained in:
AnotherTest 2021-03-25 10:25:24 +04:30 committed by Andreas Kling
parent bbf6847d50
commit 102065a8a9
6 changed files with 43 additions and 14 deletions

View file

@ -97,12 +97,7 @@ CSVExportDialogPage::CSVExportDialogPage(const Sheet& sheet)
m_data_preview_text_editor->set_should_hide_unnecessary_scrollbars(true); m_data_preview_text_editor->set_should_hide_unnecessary_scrollbars(true);
Vector<String> quote_escape_items { m_quote_escape_combo_box->set_model(GUI::ItemListModel<String>::create(m_quote_escape_items));
// Note: Keep in sync with Writer::WriterTraits::QuoteEscape.
"Repeat",
"Backslash",
};
m_quote_escape_combo_box->set_model(GUI::ItemListModel<String>::create(quote_escape_items));
// By default, use commas, double quotes with repeat, disable headers, and quote only the fields that require quoting. // By default, use commas, double quotes with repeat, disable headers, and quote only the fields that require quoting.
m_delimiter_comma_radio->set_checked(true); m_delimiter_comma_radio->set_checked(true);

View file

@ -69,6 +69,12 @@ private:
RefPtr<GUI::CheckBox> m_export_header_check_box; RefPtr<GUI::CheckBox> m_export_header_check_box;
RefPtr<GUI::CheckBox> m_quote_all_fields_check_box; RefPtr<GUI::CheckBox> m_quote_all_fields_check_box;
RefPtr<GUI::TextEditor> m_data_preview_text_editor; RefPtr<GUI::TextEditor> m_data_preview_text_editor;
Vector<String> m_quote_escape_items {
// Note: Keep in sync with Writer::WriterTraits::QuoteEscape.
"Repeat",
"Backslash",
};
String m_temp_output_file_path; String m_temp_output_file_path;
}; };

View file

@ -38,6 +38,7 @@
#include <LibGUI/ComboBox.h> #include <LibGUI/ComboBox.h>
#include <LibGUI/ItemListModel.h> #include <LibGUI/ItemListModel.h>
#include <LibGUI/RadioButton.h> #include <LibGUI/RadioButton.h>
#include <LibGUI/StackWidget.h>
#include <LibGUI/TableView.h> #include <LibGUI/TableView.h>
#include <LibGUI/TextBox.h> #include <LibGUI/TextBox.h>
#include <LibGUI/Wizards/AbstractWizardPage.h> #include <LibGUI/Wizards/AbstractWizardPage.h>
@ -71,13 +72,10 @@ CSVImportDialogPage::CSVImportDialogPage(StringView csv)
m_trim_leading_field_spaces_check_box = m_page->body_widget().find_descendant_of_type_named<GUI::CheckBox>("trim_leading_field_spaces_check_box"); m_trim_leading_field_spaces_check_box = m_page->body_widget().find_descendant_of_type_named<GUI::CheckBox>("trim_leading_field_spaces_check_box");
m_trim_trailing_field_spaces_check_box = m_page->body_widget().find_descendant_of_type_named<GUI::CheckBox>("trim_trailing_field_spaces_check_box"); m_trim_trailing_field_spaces_check_box = m_page->body_widget().find_descendant_of_type_named<GUI::CheckBox>("trim_trailing_field_spaces_check_box");
m_data_preview_table_view = m_page->body_widget().find_descendant_of_type_named<GUI::TableView>("data_preview_table_view"); m_data_preview_table_view = m_page->body_widget().find_descendant_of_type_named<GUI::TableView>("data_preview_table_view");
m_data_preview_error_label = m_page->body_widget().find_descendant_of_type_named<GUI::Label>("data_preview_error_label");
m_data_preview_widget = m_page->body_widget().find_descendant_of_type_named<GUI::StackWidget>("data_preview_widget");
Vector<String> quote_escape_items { m_quote_escape_combo_box->set_model(GUI::ItemListModel<String>::create(m_quote_escape_items));
// Note: Keep in sync with Reader::ParserTraits::QuoteEscape.
"Repeat",
"Backslash",
};
m_quote_escape_combo_box->set_model(GUI::ItemListModel<String>::create(quote_escape_items));
// By default, use commas, double quotes with repeat, and disable headers. // By default, use commas, double quotes with repeat, and disable headers.
m_delimiter_comma_radio->set_checked(true); m_delimiter_comma_radio->set_checked(true);
@ -178,14 +176,24 @@ void CSVImportDialogPage::update_preview()
m_previously_made_reader = make_reader(); m_previously_made_reader = make_reader();
if (!m_previously_made_reader.has_value()) { if (!m_previously_made_reader.has_value()) {
m_data_preview_table_view->set_model(nullptr); m_data_preview_table_view->set_model(nullptr);
m_data_preview_error_label->set_text("Could not read the given file");
m_data_preview_widget->set_active_widget(m_data_preview_error_label);
return; return;
} }
auto& reader = *m_previously_made_reader; auto& reader = *m_previously_made_reader;
if (reader.has_error()) {
m_data_preview_table_view->set_model(nullptr);
m_data_preview_error_label->set_text(String::formatted("XSV parse error:\n{}", reader.error_string()));
m_data_preview_widget->set_active_widget(m_data_preview_error_label);
return;
}
auto headers = reader.headers(); auto headers = reader.headers();
m_data_preview_table_view->set_model( m_data_preview_table_view->set_model(
GUI::ItemListModel<Reader::XSV::Row, Reader::XSV, Vector<String>>::create(reader, headers, min(8ul, reader.size()))); GUI::ItemListModel<Reader::XSV::Row, Reader::XSV, Vector<String>>::create(reader, headers, min(8ul, reader.size())));
m_data_preview_widget->set_active_widget(m_data_preview_table_view);
m_data_preview_table_view->update(); m_data_preview_table_view->update();
} }
@ -207,6 +215,9 @@ Result<NonnullRefPtrVector<Sheet>, String> ImportDialog::make_and_run_for(String
NonnullRefPtrVector<Sheet> sheets; NonnullRefPtrVector<Sheet> sheets;
if (reader.has_value()) { if (reader.has_value()) {
if (reader.value().has_error())
return String::formatted("CSV Import failed: {}", reader.value().error_string());
auto sheet = Sheet::from_xsv(reader.value(), workbook); auto sheet = Sheet::from_xsv(reader.value(), workbook);
if (sheet) if (sheet)
sheets.append(sheet.release_nonnull()); sheets.append(sheet.release_nonnull());

View file

@ -66,6 +66,13 @@ private:
RefPtr<GUI::CheckBox> m_trim_leading_field_spaces_check_box; RefPtr<GUI::CheckBox> m_trim_leading_field_spaces_check_box;
RefPtr<GUI::CheckBox> m_trim_trailing_field_spaces_check_box; RefPtr<GUI::CheckBox> m_trim_trailing_field_spaces_check_box;
RefPtr<GUI::TableView> m_data_preview_table_view; RefPtr<GUI::TableView> m_data_preview_table_view;
RefPtr<GUI::Label> m_data_preview_error_label;
RefPtr<GUI::StackWidget> m_data_preview_widget;
Vector<String> m_quote_escape_items {
// Note: Keep in sync with Reader::ParserTraits::QuoteEscape.
"Repeat",
"Backslash",
};
}; };
struct ImportDialog { struct ImportDialog {

View file

@ -105,6 +105,8 @@ Vector<XSV::Field> XSV::read_row(bool header_row)
if (!header_row && (m_behaviours & ParserBehaviour::ReadHeaders) != ParserBehaviour::None && row.size() != m_names.size()) if (!header_row && (m_behaviours & ParserBehaviour::ReadHeaders) != ParserBehaviour::None && row.size() != m_names.size())
set_error(ReadError::NonConformingColumnCount); set_error(ReadError::NonConformingColumnCount);
else if (!header_row && !has_explicit_headers() && !m_rows.is_empty() && m_rows.first().size() != row.size())
set_error(ReadError::NonConformingColumnCount);
return row; return row;
} }

View file

@ -168,8 +168,16 @@
margins: [10, 20, 10, 10] margins: [10, 20, 10, 10]
} }
@GUI::TableView { @GUI::StackWidget {
name: "data_preview_table_view" name: "data_preview_widget"
@GUI::TableView {
name: "data_preview_table_view"
}
@GUI::Label {
name: "data_preview_error_label"
word_wrap: true
}
} }
} }
} }