From c55dfabdd5d926ade12a23157240fffd74ed557e Mon Sep 17 00:00:00 2001 From: Glenford Williams Date: Tue, 11 Jan 2022 06:26:04 -0500 Subject: [PATCH] Spreadsheet: Use FileSystemAccessClient for the reading of files --- .../Applications/Spreadsheet/CMakeLists.txt | 2 +- .../Applications/Spreadsheet/HelpWindow.cpp | 2 +- .../Applications/Spreadsheet/ImportDialog.cpp | 4 +- .../Applications/Spreadsheet/ImportDialog.h | 2 +- .../Spreadsheet/SpreadsheetWidget.cpp | 19 +++++++--- .../Spreadsheet/SpreadsheetWidget.h | 4 +- .../Applications/Spreadsheet/Workbook.cpp | 37 +++++++++++++------ Userland/Applications/Spreadsheet/Workbook.h | 5 ++- Userland/Applications/Spreadsheet/main.cpp | 17 +++++++-- 9 files changed, 63 insertions(+), 29 deletions(-) diff --git a/Userland/Applications/Spreadsheet/CMakeLists.txt b/Userland/Applications/Spreadsheet/CMakeLists.txt index a98e03325ec..481eae1f544 100644 --- a/Userland/Applications/Spreadsheet/CMakeLists.txt +++ b/Userland/Applications/Spreadsheet/CMakeLists.txt @@ -41,7 +41,7 @@ set(GENERATED_SOURCES ) serenity_app(Spreadsheet ICON app-spreadsheet) -target_link_libraries(Spreadsheet LibGUI LibJS LibWeb) +target_link_libraries(Spreadsheet LibFileSystemAccessClient LibGUI LibJS LibWeb) link_with_unicode_data(Spreadsheet) serenity_test(Writers/Test/TestXSVWriter.cpp Spreadsheet) diff --git a/Userland/Applications/Spreadsheet/HelpWindow.cpp b/Userland/Applications/Spreadsheet/HelpWindow.cpp index 0263bc1d773..8db4322eb3c 100644 --- a/Userland/Applications/Spreadsheet/HelpWindow.cpp +++ b/Userland/Applications/Spreadsheet/HelpWindow.cpp @@ -110,7 +110,7 @@ HelpWindow::HelpWindow(GUI::Window* parent) window->set_title(String::formatted("Spreadsheet Help - Example {} for {}", name, entry)); window->on_close = [window = window.ptr()] { window->remove_from_parent(); }; - auto& widget = window->set_main_widget(NonnullRefPtrVector {}, false); + auto& widget = window->set_main_widget(window, NonnullRefPtrVector {}, false); auto sheet = Sheet::from_json(value.as_object(), widget.workbook()); if (!sheet) { GUI::MessageBox::show_error(this, String::formatted("Corrupted example '{}' in '{}'", name, url.path())); diff --git a/Userland/Applications/Spreadsheet/ImportDialog.cpp b/Userland/Applications/Spreadsheet/ImportDialog.cpp index 4540b738b10..aa6558c9f70 100644 --- a/Userland/Applications/Spreadsheet/ImportDialog.cpp +++ b/Userland/Applications/Spreadsheet/ImportDialog.cpp @@ -175,9 +175,9 @@ void CSVImportDialogPage::update_preview() m_data_preview_table_view->update(); } -Result, String> ImportDialog::make_and_run_for(GUI::Window* parent, StringView mime, Core::File& file, Workbook& workbook) +Result, String> ImportDialog::make_and_run_for(GUI::Window& parent, StringView mime, Core::File& file, Workbook& workbook) { - auto wizard = GUI::WizardDialog::construct(parent); + auto wizard = GUI::WizardDialog::construct(&parent); wizard->set_title("File Import Wizard"); wizard->set_icon(GUI::Icon::default_icon("app-spreadsheet").bitmap_for_size(16)); diff --git a/Userland/Applications/Spreadsheet/ImportDialog.h b/Userland/Applications/Spreadsheet/ImportDialog.h index c0e3a45e210..f510af09d1e 100644 --- a/Userland/Applications/Spreadsheet/ImportDialog.h +++ b/Userland/Applications/Spreadsheet/ImportDialog.h @@ -56,7 +56,7 @@ private: }; struct ImportDialog { - static Result, String> make_and_run_for(GUI::Window* parent, StringView mime, Core::File& file, Workbook&); + static Result, String> make_and_run_for(GUI::Window& parent, StringView mime, Core::File& file, Workbook&); }; } diff --git a/Userland/Applications/Spreadsheet/SpreadsheetWidget.cpp b/Userland/Applications/Spreadsheet/SpreadsheetWidget.cpp index 50814fbac0d..6a7dcd53165 100644 --- a/Userland/Applications/Spreadsheet/SpreadsheetWidget.cpp +++ b/Userland/Applications/Spreadsheet/SpreadsheetWidget.cpp @@ -7,6 +7,7 @@ #include "SpreadsheetWidget.h" #include "CellSyntaxHighlighter.h" #include "HelpWindow.h" +#include "LibFileSystemAccessClient/Client.h" #include #include #include @@ -25,8 +26,8 @@ namespace Spreadsheet { -SpreadsheetWidget::SpreadsheetWidget(NonnullRefPtrVector&& sheets, bool should_add_sheet_if_empty) - : m_workbook(make(move(sheets), window())) +SpreadsheetWidget::SpreadsheetWidget(GUI::Window& parent_window, NonnullRefPtrVector&& sheets, bool should_add_sheet_if_empty) + : m_workbook(make(move(sheets), parent_window)) { set_fill_with_background_color(true); set_layout().set_margins(2); @@ -123,7 +124,15 @@ SpreadsheetWidget::SpreadsheetWidget(NonnullRefPtrVector&& sheets, bool s if (!load_path.has_value()) return; - load(load_path.value()); + auto response = FileSystemAccessClient::Client::the().request_file_read_only_approved(window()->window_id(), *load_path); + + if (response.error != 0) { + if (response.error != -1) + GUI::MessageBox::show_error(window(), String::formatted("Opening \"{}\" failed: {}", *response.chosen_file, strerror(response.error))); + return; + } + + load_file(*response.fd, *load_path); }); m_save_action = GUI::CommonActions::make_save_action([&](auto&) { @@ -391,9 +400,9 @@ void SpreadsheetWidget::save(StringView filename) GUI::MessageBox::show_error(window(), result.error()); } -void SpreadsheetWidget::load(StringView filename) +void SpreadsheetWidget::load_file(int fd, StringView filename) { - auto result = m_workbook->load(filename); + auto result = m_workbook->open_file(fd, filename); if (result.is_error()) { GUI::MessageBox::show_error(window(), result.error()); return; diff --git a/Userland/Applications/Spreadsheet/SpreadsheetWidget.h b/Userland/Applications/Spreadsheet/SpreadsheetWidget.h index 3ec08531bba..f9bbae7dae5 100644 --- a/Userland/Applications/Spreadsheet/SpreadsheetWidget.h +++ b/Userland/Applications/Spreadsheet/SpreadsheetWidget.h @@ -20,7 +20,7 @@ public: ~SpreadsheetWidget(); void save(StringView filename); - void load(StringView filename); + void load_file(int fd, StringView filename); bool request_close(); void add_sheet(); void add_sheet(NonnullRefPtr&&); @@ -45,7 +45,7 @@ public: private: virtual void resize_event(GUI::ResizeEvent&) override; - explicit SpreadsheetWidget(NonnullRefPtrVector&& sheets = {}, bool should_add_sheet_if_empty = true); + explicit SpreadsheetWidget(GUI::Window& window, NonnullRefPtrVector&& sheets = {}, bool should_add_sheet_if_empty = true); void setup_tabs(NonnullRefPtrVector new_sheets); diff --git a/Userland/Applications/Spreadsheet/Workbook.cpp b/Userland/Applications/Spreadsheet/Workbook.cpp index 41a133e74ac..d67e64ae5a5 100644 --- a/Userland/Applications/Spreadsheet/Workbook.cpp +++ b/Userland/Applications/Spreadsheet/Workbook.cpp @@ -8,16 +8,20 @@ #include "ExportDialog.h" #include "ImportDialog.h" #include "JSIntegration.h" +#include "LibGUI/MessageBox.h" #include "Readers/CSV.h" #include +#include #include #include +#include #include +#include #include namespace Spreadsheet { -Workbook::Workbook(NonnullRefPtrVector&& sheets, GUI::Window* parent_window) +Workbook::Workbook(NonnullRefPtrVector&& sheets, GUI::Window& parent_window) : m_sheets(move(sheets)) , m_vm(JS::VM::create()) , m_interpreter(JS::Interpreter::create(m_vm)) @@ -47,23 +51,18 @@ bool Workbook::set_filename(const String& filename) return true; } -Result Workbook::load(StringView filename) +Result Workbook::open_file(int fd, StringView filename) { - auto file_or_error = Core::File::open(filename, Core::OpenMode::ReadOnly); - if (file_or_error.is_error()) { - StringBuilder sb; - sb.append("Failed to open "); - sb.append(filename); - sb.append(" for reading. Error: "); - sb.appendff("{}", file_or_error.error()); + auto file = Core::File::construct(); - return sb.to_string(); + if (!file->open(fd, Core::OpenMode::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes) && file->error() != ENOENT) { + return String::formatted("Opening \"{}\" failed: {}", file, strerror(errno)); } auto mime = Core::guess_mime_type_based_on_filename(filename); // Make an import dialog, we might need to import it. - auto result = ImportDialog::make_and_run_for(m_parent_window, mime, file_or_error.value(), *this); + auto result = ImportDialog::make_and_run_for(m_parent_window, mime, file, *this); if (result.is_error()) return result.error(); @@ -74,6 +73,22 @@ Result Workbook::load(StringView filename) return true; } +Result Workbook::load(StringView filename) +{ + auto response = FileSystemAccessClient::Client::the().request_file_read_only_approved(m_parent_window.window_id(), filename); + if (response.error != 0) { + StringBuilder sb; + sb.append("Failed to open "); + sb.append(filename); + sb.append(" for reading. Error: "); + sb.appendff("{}", response.error); + + return sb.to_string(); + } + + return open_file(*response.fd, filename); +} + Result Workbook::save(StringView filename) { auto mime = Core::guess_mime_type_based_on_filename(filename); diff --git a/Userland/Applications/Spreadsheet/Workbook.h b/Userland/Applications/Spreadsheet/Workbook.h index 7fa79461365..c0c49d3f44a 100644 --- a/Userland/Applications/Spreadsheet/Workbook.h +++ b/Userland/Applications/Spreadsheet/Workbook.h @@ -15,10 +15,11 @@ namespace Spreadsheet { class Workbook { public: - Workbook(NonnullRefPtrVector&& sheets, GUI::Window* parent_window); + Workbook(NonnullRefPtrVector&& sheets, GUI::Window& parent_window); Result save(StringView filename); Result load(StringView filename); + Result open_file(int fd, StringView filename); const String& current_filename() const { return m_current_filename; } bool set_filename(const String& filename); @@ -48,7 +49,7 @@ private: JS::VM::InterpreterExecutionScope m_interpreter_scope; WorkbookObject* m_workbook_object { nullptr }; JS::ExecutionContext m_main_execution_context; - GUI::Window* m_parent_window { nullptr }; + GUI::Window& m_parent_window; String m_current_filename; bool m_dirty { false }; diff --git a/Userland/Applications/Spreadsheet/main.cpp b/Userland/Applications/Spreadsheet/main.cpp index 0ed5a66f220..29b4084f87c 100644 --- a/Userland/Applications/Spreadsheet/main.cpp +++ b/Userland/Applications/Spreadsheet/main.cpp @@ -5,6 +5,7 @@ */ #include "HelpWindow.h" +#include "LibFileSystemAccessClient/Client.h" #include "Spreadsheet.h" #include "SpreadsheetWidget.h" #include @@ -80,10 +81,7 @@ int main(int argc, char* argv[]) window->resize(640, 480); window->set_icon(app_icon.bitmap_for_size(16)); - auto& spreadsheet_widget = window->set_main_widget(NonnullRefPtrVector {}, filename == nullptr); - - if (filename) - spreadsheet_widget.load(filename); + auto& spreadsheet_widget = window->set_main_widget(*window, NonnullRefPtrVector {}, filename == nullptr); spreadsheet_widget.initialize_menubar(*window); @@ -95,5 +93,16 @@ int main(int argc, char* argv[]) window->show(); + if (filename) { + auto response = FileSystemAccessClient::Client::the().request_file_read_only_approved(window->window_id(), filename); + + if (response.error != 0) { + if (response.error != -1) + GUI::MessageBox::show_error(window, String::formatted("Opening \"{}\" failed: {}", *response.chosen_file, strerror(response.error))); + return 1; + } + spreadsheet_widget.load_file(*response.fd, filename); + } + return app->exec(); }