diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-08-26 06:00:23 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-27 10:27:20 +0200 |
commit | e1f5f709eeecdd9aea0714b924f6bbb2096abdbf (patch) | |
tree | a49f2962141658c84fc322840a52c7ba6c464318 | |
parent | 6ea7e67b62222c0a2f48f12e4cef6719f7e02333 (diff) | |
download | serenity-e1f5f709eeecdd9aea0714b924f6bbb2096abdbf.zip |
Spreadsheet: Move sheet management to a Workbook class
-rw-r--r-- | Applications/Spreadsheet/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Applications/Spreadsheet/SpreadsheetWidget.cpp | 127 | ||||
-rw-r--r-- | Applications/Spreadsheet/SpreadsheetWidget.h | 8 | ||||
-rw-r--r-- | Applications/Spreadsheet/Workbook.cpp | 136 | ||||
-rw-r--r-- | Applications/Spreadsheet/Workbook.h | 66 |
5 files changed, 228 insertions, 110 deletions
diff --git a/Applications/Spreadsheet/CMakeLists.txt b/Applications/Spreadsheet/CMakeLists.txt index 61db474cf4..614fbc4ae0 100644 --- a/Applications/Spreadsheet/CMakeLists.txt +++ b/Applications/Spreadsheet/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCES SpreadsheetModel.cpp SpreadsheetView.cpp SpreadsheetWidget.cpp + Workbook.cpp main.cpp ) diff --git a/Applications/Spreadsheet/SpreadsheetWidget.cpp b/Applications/Spreadsheet/SpreadsheetWidget.cpp index 88fd89e7fd..b56c93857a 100644 --- a/Applications/Spreadsheet/SpreadsheetWidget.cpp +++ b/Applications/Spreadsheet/SpreadsheetWidget.cpp @@ -27,10 +27,6 @@ #include "SpreadsheetWidget.h" #include "CellSyntaxHighlighter.h" #include "HelpWindow.h" -#include <AK/JsonArray.h> -#include <AK/JsonObject.h> -#include <AK/JsonObjectSerializer.h> -#include <AK/JsonParser.h> #include <LibCore/File.h> #include <LibGUI/BoxLayout.h> #include <LibGUI/Button.h> @@ -44,7 +40,7 @@ namespace Spreadsheet { SpreadsheetWidget::SpreadsheetWidget(NonnullRefPtrVector<Sheet>&& sheets, bool should_add_sheet_if_empty) - : m_sheets(move(sheets)) + : m_workbook(make<Workbook>(move(sheets))) { set_fill_with_background_color(true); set_layout<GUI::VerticalBoxLayout>().set_margins({ 2, 2, 2, 2 }); @@ -82,8 +78,8 @@ SpreadsheetWidget::SpreadsheetWidget(NonnullRefPtrVector<Sheet>&& sheets, bool s m_cell_value_editor = cell_value_editor; m_current_cell_label = current_cell_label; - if (m_sheets.is_empty() && should_add_sheet_if_empty) - m_sheets.append(Sheet::construct("Sheet 1")); + if (!m_workbook->has_sheets() && should_add_sheet_if_empty) + m_workbook->add_sheet("Sheet 1"); setup_tabs(); } @@ -91,7 +87,7 @@ SpreadsheetWidget::SpreadsheetWidget(NonnullRefPtrVector<Sheet>&& sheets, bool s void SpreadsheetWidget::setup_tabs() { RefPtr<GUI::Widget> first_tab_widget; - for (auto& sheet : m_sheets) { + for (auto& sheet : m_workbook->sheets()) { auto& tab = m_tab_widget->add_tab<SpreadsheetView>(sheet.name(), sheet); if (!first_tab_widget) first_tab_widget = &tab; @@ -134,121 +130,40 @@ void SpreadsheetWidget::setup_tabs() }; } -SpreadsheetWidget::~SpreadsheetWidget() -{ -} - -void SpreadsheetWidget::set_filename(const String& filename) +void SpreadsheetWidget::save(const StringView& filename) { - if (m_current_filename == filename) - return; - - m_current_filename = filename; - StringBuilder builder; - builder.append("Spreadsheet - "); - builder.append(m_current_filename); - - window()->set_title(builder.string_view()); - window()->update(); + auto result = m_workbook->save(filename); + if (result.is_error()) + GUI::MessageBox::show_error(window(), result.error()); } void SpreadsheetWidget::load(const StringView& filename) { - auto file_or_error = Core::File::open(filename, Core::IODevice::OpenMode::ReadOnly); - if (file_or_error.is_error()) { - StringBuilder sb; - sb.append("Failed to open "); - sb.append(filename); - sb.append(" for reading. Error: "); - sb.append(file_or_error.error()); - - GUI::MessageBox::show(window(), sb.to_string(), "Error", GUI::MessageBox::Type::Error); + auto result = m_workbook->load(filename); + if (result.is_error()) { + GUI::MessageBox::show_error(window(), result.error()); return; } - - auto json_value_option = JsonParser(file_or_error.value()->read_all()).parse(); - if (!json_value_option.has_value()) { - StringBuilder sb; - sb.append("Failed to parse "); - sb.append(filename); - - GUI::MessageBox::show(window(), sb.to_string(), "Error", GUI::MessageBox::Type::Error); - return; - } - - auto& json_value = json_value_option.value(); - if (!json_value.is_array()) { - StringBuilder sb; - sb.append("Did not find a spreadsheet in "); - sb.append(filename); - - GUI::MessageBox::show(window(), sb.to_string(), "Error", GUI::MessageBox::Type::Error); - return; - } - - NonnullRefPtrVector<Sheet> sheets; - - auto& json_array = json_value.as_array(); - json_array.for_each([&](auto& sheet_json) { - if (!sheet_json.is_object()) - return IterationDecision::Continue; - - auto sheet = Sheet::from_json(sheet_json.as_object()); - if (!sheet) - return IterationDecision::Continue; - - sheets.append(sheet.release_nonnull()); - - return IterationDecision::Continue; - }); - - m_sheets.clear(); - m_sheets = move(sheets); - while (auto* widget = m_tab_widget->active_widget()) { m_tab_widget->remove_tab(*widget); } setup_tabs(); - - set_filename(filename); } -void SpreadsheetWidget::save(const StringView& filename) +void SpreadsheetWidget::set_filename(const String& filename) { - JsonArray array; - m_tab_widget->for_each_child_of_type<SpreadsheetView>([&](auto& view) { - array.append(view.sheet().to_json()); - return IterationDecision::Continue; - }); - - auto file_content = array.to_string(); - - auto file = Core::File::construct(filename); - file->open(Core::IODevice::WriteOnly); - if (!file->is_open()) { - StringBuilder sb; - sb.append("Failed to open "); - sb.append(filename); - sb.append(" for write. Error: "); - sb.append(file->error_string()); - - GUI::MessageBox::show(window(), sb.to_string(), "Error", GUI::MessageBox::Type::Error); - return; - } + if (m_workbook->set_filename(filename)) { + StringBuilder builder; + builder.append("Spreadsheet - "); + builder.append(current_filename()); - bool result = file->write(file_content); - if (!result) { - int error_number = errno; - StringBuilder sb; - sb.append("Unable to save file. Error: "); - sb.append(strerror(error_number)); - - GUI::MessageBox::show(window(), sb.to_string(), "Error", GUI::MessageBox::Type::Error); - return; + window()->set_title(builder.string_view()); + window()->update(); } - - set_filename(filename); } +SpreadsheetWidget::~SpreadsheetWidget() +{ +} } diff --git a/Applications/Spreadsheet/SpreadsheetWidget.h b/Applications/Spreadsheet/SpreadsheetWidget.h index 6ade762440..c32483f455 100644 --- a/Applications/Spreadsheet/SpreadsheetWidget.h +++ b/Applications/Spreadsheet/SpreadsheetWidget.h @@ -27,6 +27,7 @@ #pragma once #include "SpreadsheetView.h" +#include "Workbook.h" #include <AK/NonnullRefPtrVector.h> #include <LibGUI/Widget.h> @@ -41,7 +42,7 @@ public: void save(const StringView& filename); void load(const StringView& filename); - const String& current_filename() const { return m_current_filename; } + const String& current_filename() const { return m_workbook->current_filename(); } void set_filename(const String& filename); private: @@ -49,13 +50,12 @@ private: void setup_tabs(); - NonnullRefPtrVector<Sheet> m_sheets; SpreadsheetView* m_selected_view { nullptr }; - RefPtr<GUI::TabWidget> m_tab_widget; RefPtr<GUI::Label> m_current_cell_label; RefPtr<GUI::TextEditor> m_cell_value_editor; + RefPtr<GUI::TabWidget> m_tab_widget; - String m_current_filename; + OwnPtr<Workbook> m_workbook; }; } diff --git a/Applications/Spreadsheet/Workbook.cpp b/Applications/Spreadsheet/Workbook.cpp new file mode 100644 index 0000000000..8f20eb9897 --- /dev/null +++ b/Applications/Spreadsheet/Workbook.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Workbook.h" +#include <AK/JsonArray.h> +#include <AK/JsonObject.h> +#include <AK/JsonObjectSerializer.h> +#include <AK/JsonParser.h> +#include <LibCore/File.h> +#include <string.h> + +namespace Spreadsheet { + +bool Workbook::set_filename(const String& filename) +{ + if (m_current_filename == filename) + return false; + + m_current_filename = filename; + return true; +} + +Result<bool, String> Workbook::load(const StringView& filename) +{ + auto file_or_error = Core::File::open(filename, Core::IODevice::OpenMode::ReadOnly); + if (file_or_error.is_error()) { + StringBuilder sb; + sb.append("Failed to open "); + sb.append(filename); + sb.append(" for reading. Error: "); + sb.append(file_or_error.error()); + + return sb.to_string(); + } + + auto json_value_option = JsonParser(file_or_error.value()->read_all()).parse(); + if (!json_value_option.has_value()) { + StringBuilder sb; + sb.append("Failed to parse "); + sb.append(filename); + + return sb.to_string(); + } + + auto& json_value = json_value_option.value(); + if (!json_value.is_array()) { + StringBuilder sb; + sb.append("Did not find a spreadsheet in "); + sb.append(filename); + + return sb.to_string(); + } + + NonnullRefPtrVector<Sheet> sheets; + + auto& json_array = json_value.as_array(); + json_array.for_each([&](auto& sheet_json) { + if (!sheet_json.is_object()) + return IterationDecision::Continue; + + auto sheet = Sheet::from_json(sheet_json.as_object()); + if (!sheet) + return IterationDecision::Continue; + + sheets.append(sheet.release_nonnull()); + + return IterationDecision::Continue; + }); + + m_sheets.clear(); + m_sheets = move(sheets); + + set_filename(filename); + + return true; +} + +Result<bool, String> Workbook::save(const StringView& filename) +{ + JsonArray array; + + for (auto& sheet : m_sheets) + array.append(sheet.to_json()); + + auto file_content = array.to_string(); + + auto file = Core::File::construct(filename); + file->open(Core::IODevice::WriteOnly); + if (!file->is_open()) { + StringBuilder sb; + sb.append("Failed to open "); + sb.append(filename); + sb.append(" for write. Error: "); + sb.append(file->error_string()); + + return sb.to_string(); + } + + bool result = file->write(file_content); + if (!result) { + int error_number = errno; + StringBuilder sb; + sb.append("Unable to save file. Error: "); + sb.append(strerror(error_number)); + + return sb.to_string(); + } + + set_filename(filename); + return true; +} + +} diff --git a/Applications/Spreadsheet/Workbook.h b/Applications/Spreadsheet/Workbook.h new file mode 100644 index 0000000000..e3ec253ad3 --- /dev/null +++ b/Applications/Spreadsheet/Workbook.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "Spreadsheet.h" +#include <AK/NonnullOwnPtrVector.h> +#include <AK/Result.h> + +namespace Spreadsheet { + +class Workbook { +public: + Workbook(NonnullRefPtrVector<Sheet>&& sheets) + : m_sheets(move(sheets)) + { + } + + Result<bool, String> save(const StringView& filename); + Result<bool, String> load(const StringView& filename); + + const String& current_filename() const { return m_current_filename; } + bool set_filename(const String& filename); + + bool has_sheets() const { return !m_sheets.is_empty(); } + + const NonnullRefPtrVector<Sheet>& sheets() const { return m_sheets; } + NonnullRefPtrVector<Sheet> sheets() { return m_sheets; } + + Sheet& add_sheet(const StringView& name) + { + auto sheet = Sheet::construct(name); + m_sheets.append(sheet); + return *sheet; + } + +private: + NonnullRefPtrVector<Sheet> m_sheets; + + String m_current_filename; +}; + +} |