summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Applications/Spreadsheet/CMakeLists.txt1
-rw-r--r--Applications/Spreadsheet/Cell.cpp120
-rw-r--r--Applications/Spreadsheet/Cell.h84
-rw-r--r--Applications/Spreadsheet/Forward.h38
-rw-r--r--Applications/Spreadsheet/JSIntegration.h4
-rw-r--r--Applications/Spreadsheet/Spreadsheet.cpp64
-rw-r--r--Applications/Spreadsheet/Spreadsheet.h82
-rw-r--r--Applications/Spreadsheet/Workbook.h3
8 files changed, 250 insertions, 146 deletions
diff --git a/Applications/Spreadsheet/CMakeLists.txt b/Applications/Spreadsheet/CMakeLists.txt
index 9eac41dc0f..5ec5efee9a 100644
--- a/Applications/Spreadsheet/CMakeLists.txt
+++ b/Applications/Spreadsheet/CMakeLists.txt
@@ -1,4 +1,5 @@
set(SOURCES
+ Cell.cpp
CellSyntaxHighlighter.cpp
HelpWindow.cpp
JSIntegration.cpp
diff --git a/Applications/Spreadsheet/Cell.cpp b/Applications/Spreadsheet/Cell.cpp
new file mode 100644
index 0000000000..d44d02debf
--- /dev/null
+++ b/Applications/Spreadsheet/Cell.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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 "Cell.h"
+#include "Spreadsheet.h"
+#include <AK/StringBuilder.h>
+
+namespace Spreadsheet {
+
+void Cell::set_data(String new_data)
+{
+ if (data == new_data)
+ return;
+
+ if (new_data.starts_with("=")) {
+ new_data = new_data.substring(1, new_data.length() - 1);
+ kind = Formula;
+ } else {
+ kind = LiteralString;
+ }
+
+ data = move(new_data);
+ dirty = true;
+ evaluated_externally = false;
+}
+
+void Cell::set_data(JS::Value new_data)
+{
+ dirty = true;
+ evaluated_externally = true;
+
+ StringBuilder builder;
+
+ builder.append(new_data.to_string_without_side_effects());
+ data = builder.build();
+
+ evaluated_data = move(new_data);
+}
+
+void Cell::update_data()
+{
+ TemporaryChange cell_change { sheet->current_evaluated_cell(), this };
+ if (!dirty)
+ return;
+
+ dirty = false;
+ if (kind == Formula) {
+ if (!evaluated_externally)
+ evaluated_data = sheet->evaluate(data, this);
+ }
+
+ for (auto& ref : referencing_cells) {
+ if (ref) {
+ ref->dirty = true;
+ ref->update();
+ }
+ }
+}
+
+void Cell::update()
+{
+ sheet->update(*this);
+}
+
+JS::Value Cell::js_data()
+{
+ if (dirty)
+ update();
+
+ if (kind == Formula)
+ return evaluated_data;
+
+ return JS::js_string(sheet->interpreter(), data);
+}
+
+String Cell::source() const
+{
+ StringBuilder builder;
+ if (kind == Formula)
+ builder.append('=');
+ builder.append(data);
+ return builder.to_string();
+}
+
+// FIXME: Find a better way to figure out dependencies
+void Cell::reference_from(Cell* other)
+{
+ if (!other || other == this)
+ return;
+
+ if (!referencing_cells.find([other](auto& ptr) { return ptr.ptr() == other; }).is_end())
+ return;
+
+ referencing_cells.append(other->make_weak_ptr());
+}
+
+}
diff --git a/Applications/Spreadsheet/Cell.h b/Applications/Spreadsheet/Cell.h
new file mode 100644
index 0000000000..6fed58f4b9
--- /dev/null
+++ b/Applications/Spreadsheet/Cell.h
@@ -0,0 +1,84 @@
+/*
+ * 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 "Forward.h"
+#include "JSIntegration.h"
+#include <AK/String.h>
+#include <AK/Types.h>
+#include <AK/WeakPtr.h>
+
+namespace Spreadsheet {
+
+struct Cell : public Weakable<Cell> {
+ Cell(String data, WeakPtr<Sheet> sheet)
+ : dirty(false)
+ , data(move(data))
+ , kind(LiteralString)
+ , sheet(sheet)
+ {
+ }
+
+ Cell(String source, JS::Value&& cell_value, WeakPtr<Sheet> sheet)
+ : dirty(false)
+ , data(move(source))
+ , evaluated_data(move(cell_value))
+ , kind(Formula)
+ , sheet(sheet)
+ {
+ }
+
+ void reference_from(Cell*);
+
+ void set_data(String new_data);
+ void set_data(JS::Value new_data);
+
+ String source() const;
+
+ JS::Value js_data();
+
+ void update(Badge<Sheet>) { update_data(); }
+ void update();
+
+ enum Kind {
+ LiteralString,
+ Formula,
+ };
+
+ bool dirty { false };
+ bool evaluated_externally { false };
+ String data;
+ JS::Value evaluated_data;
+ Kind kind { LiteralString };
+ WeakPtr<Sheet> sheet;
+ Vector<WeakPtr<Cell>> referencing_cells;
+
+private:
+ void update_data();
+};
+
+}
diff --git a/Applications/Spreadsheet/Forward.h b/Applications/Spreadsheet/Forward.h
new file mode 100644
index 0000000000..5bd5480025
--- /dev/null
+++ b/Applications/Spreadsheet/Forward.h
@@ -0,0 +1,38 @@
+/*
+ * 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
+
+namespace Spreadsheet {
+
+struct Cell;
+class Sheet;
+struct Position;
+class Workbook;
+class WorkbookObject;
+class SheetGlobalObject;
+
+}
diff --git a/Applications/Spreadsheet/JSIntegration.h b/Applications/Spreadsheet/JSIntegration.h
index bd3bd1e77f..ace3e3c823 100644
--- a/Applications/Spreadsheet/JSIntegration.h
+++ b/Applications/Spreadsheet/JSIntegration.h
@@ -26,14 +26,12 @@
#pragma once
+#include "Forward.h"
#include <LibJS/Forward.h>
#include <LibJS/Runtime/GlobalObject.h>
namespace Spreadsheet {
-class Sheet;
-class Workbook;
-
class SheetGlobalObject : public JS::GlobalObject {
JS_OBJECT(SheetGlobalObject, JS::GlobalObject);
diff --git a/Applications/Spreadsheet/Spreadsheet.cpp b/Applications/Spreadsheet/Spreadsheet.cpp
index de8410d06d..fb250d177e 100644
--- a/Applications/Spreadsheet/Spreadsheet.cpp
+++ b/Applications/Spreadsheet/Spreadsheet.cpp
@@ -77,16 +77,15 @@ Sheet::Sheet(Workbook& workbook)
}
}
}
-
}
-JS::Interpreter& Sheet::interpreter() const
+Sheet::~Sheet()
{
- return m_workbook.interpreter();
}
-Sheet::~Sheet()
+JS::Interpreter& Sheet::interpreter() const
{
+ return m_workbook.interpreter();
}
size_t Sheet::add_row()
@@ -171,42 +170,6 @@ JS::Value Sheet::evaluate(const StringView& source, Cell* on_behalf_of)
return value;
}
-void Cell::update_data()
-{
- TemporaryChange cell_change { sheet->current_evaluated_cell(), this };
- if (!dirty)
- return;
-
- dirty = false;
- if (kind == Formula) {
- if (!evaluated_externally)
- evaluated_data = sheet->evaluate(data, this);
- }
-
- for (auto& ref : referencing_cells) {
- if (ref) {
- ref->dirty = true;
- ref->update();
- }
- }
-}
-
-void Cell::update()
-{
- sheet->update(*this);
-}
-
-JS::Value Cell::js_data()
-{
- if (dirty)
- update();
-
- if (kind == Formula)
- return evaluated_data;
-
- return JS::js_string(sheet->interpreter(), data);
-}
-
Cell* Sheet::at(const StringView& name)
{
auto pos = parse_cell_name(name);
@@ -238,27 +201,6 @@ Optional<Position> Sheet::parse_cell_name(const StringView& name)
return Position { col, row.to_uint().value() };
}
-String Cell::source() const
-{
- StringBuilder builder;
- if (kind == Formula)
- builder.append('=');
- builder.append(data);
- return builder.to_string();
-}
-
-// FIXME: Find a better way to figure out dependencies
-void Cell::reference_from(Cell* other)
-{
- if (!other || other == this)
- return;
-
- if (!referencing_cells.find([other](auto& ptr) { return ptr.ptr() == other; }).is_end())
- return;
-
- referencing_cells.append(other->make_weak_ptr());
-}
-
RefPtr<Sheet> Sheet::from_json(const JsonObject& object, Workbook& workbook)
{
auto sheet = adopt(*new Sheet(workbook));
diff --git a/Applications/Spreadsheet/Spreadsheet.h b/Applications/Spreadsheet/Spreadsheet.h
index c711624ce4..3207398ec8 100644
--- a/Applications/Spreadsheet/Spreadsheet.h
+++ b/Applications/Spreadsheet/Spreadsheet.h
@@ -26,6 +26,8 @@
#pragma once
+#include "Cell.h"
+#include "Forward.h"
#include <AK/HashMap.h>
#include <AK/HashTable.h>
#include <AK/String.h>
@@ -39,9 +41,6 @@
namespace Spreadsheet {
-class Workbook;
-class SheetGlobalObject;
-
struct Position {
String column;
size_t row { 0 };
@@ -57,83 +56,6 @@ struct Position {
}
};
-class Sheet;
-
-struct Cell : public Weakable<Cell> {
- Cell(String data, WeakPtr<Sheet> sheet)
- : dirty(false)
- , data(move(data))
- , kind(LiteralString)
- , sheet(sheet)
- {
- }
-
- Cell(String source, JS::Value&& cell_value, WeakPtr<Sheet> sheet)
- : dirty(false)
- , data(move(source))
- , evaluated_data(move(cell_value))
- , kind(Formula)
- , sheet(sheet)
- {
- }
-
- bool dirty { false };
- bool evaluated_externally { false };
- String data;
- JS::Value evaluated_data;
-
- enum Kind {
- LiteralString,
- Formula,
- } kind { LiteralString };
-
- WeakPtr<Sheet> sheet;
- Vector<WeakPtr<Cell>> referencing_cells;
-
- void reference_from(Cell*);
-
- void set_data(String new_data)
- {
- if (data == new_data)
- return;
-
- if (new_data.starts_with("=")) {
- new_data = new_data.substring(1, new_data.length() - 1);
- kind = Formula;
- } else {
- kind = LiteralString;
- }
-
- data = move(new_data);
- dirty = true;
- evaluated_externally = false;
- }
-
- void set_data(JS::Value new_data)
- {
- dirty = true;
- evaluated_externally = true;
-
- StringBuilder builder;
-
- builder.append("=");
- builder.append(new_data.to_string_without_side_effects());
- data = builder.build();
-
- evaluated_data = move(new_data);
- }
-
- String source() const;
-
- JS::Value js_data();
-
- void update(Badge<Sheet>) { update_data(); }
- void update();
-
-private:
- void update_data();
-};
-
class Sheet : public Core::Object {
C_OBJECT(Sheet);
diff --git a/Applications/Spreadsheet/Workbook.h b/Applications/Spreadsheet/Workbook.h
index 54295fbe67..7c31db1f31 100644
--- a/Applications/Spreadsheet/Workbook.h
+++ b/Applications/Spreadsheet/Workbook.h
@@ -26,14 +26,13 @@
#pragma once
+#include "Forward.h"
#include "Spreadsheet.h"
#include <AK/NonnullOwnPtrVector.h>
#include <AK/Result.h>
namespace Spreadsheet {
-class WorkbookObject;
-
class Workbook {
public:
Workbook(NonnullRefPtrVector<Sheet>&& sheets);