diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-11-21 03:38:10 +0330 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-12-12 14:49:49 +0330 |
commit | 91444de2cf312eea160eacf0cb6ffff7b64c024b (patch) | |
tree | 0b9509a48d70bef64e22f07961adefbde3ac7829 /Userland/Applications/Spreadsheet | |
parent | 892e585e9aa5725193f006d1782312a23387d1b1 (diff) | |
download | serenity-91444de2cf312eea160eacf0cb6ffff7b64c024b.zip |
Spreadsheet: Reimplement ranges as lazy objects instead of arrays
Doing so makes it possible to talk about theoretically infinite ranges
like "all of column A".
Diffstat (limited to 'Userland/Applications/Spreadsheet')
4 files changed, 33 insertions, 4 deletions
diff --git a/Userland/Applications/Spreadsheet/JSIntegration.cpp b/Userland/Applications/Spreadsheet/JSIntegration.cpp index 681fa4d9d9..85d4f35346 100644 --- a/Userland/Applications/Spreadsheet/JSIntegration.cpp +++ b/Userland/Applications/Spreadsheet/JSIntegration.cpp @@ -157,6 +157,7 @@ void SheetGlobalObject::initialize_global_object() define_native_function("current_cell_position", current_cell_position, 0, attr); define_native_function("column_arithmetic", column_arithmetic, 2, attr); define_native_function("column_index", column_index, 1, attr); + define_native_function("get_column_bound", get_column_bound, 1, attr); } void SheetGlobalObject::visit_edges(Visitor& visitor) @@ -329,6 +330,31 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic) return JS::js_string(vm, new_column.release_value()); } +JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound) +{ + if (vm.argument_count() != 1) + return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to get_column_bound()"); + + auto column_name = vm.argument(0); + if (!column_name.is_string()) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String"); + + auto& column_name_str = column_name.as_string().string(); + auto* this_object = TRY(vm.this_value(global_object).to_object(global_object)); + + if (!is<SheetGlobalObject>(this_object)) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); + + auto sheet_object = static_cast<SheetGlobalObject*>(this_object); + auto& sheet = sheet_object->m_sheet; + auto maybe_column_index = sheet.column_index(column_name_str); + if (!maybe_column_index.has_value()) + return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' is not a valid column", column_name_str)); + + auto bounds = sheet.written_data_bounds(*maybe_column_index); + return JS::Value(bounds.row); +} + WorkbookObject::WorkbookObject(Workbook& workbook) : JS::Object(*JS::Object::create(workbook.global_object(), workbook.global_object().object_prototype())) , m_workbook(workbook) diff --git a/Userland/Applications/Spreadsheet/JSIntegration.h b/Userland/Applications/Spreadsheet/JSIntegration.h index c82070eee9..24ed2e8bd7 100644 --- a/Userland/Applications/Spreadsheet/JSIntegration.h +++ b/Userland/Applications/Spreadsheet/JSIntegration.h @@ -38,6 +38,7 @@ public: JS_DECLARE_NATIVE_FUNCTION(current_cell_position); JS_DECLARE_NATIVE_FUNCTION(column_index); JS_DECLARE_NATIVE_FUNCTION(column_arithmetic); + JS_DECLARE_NATIVE_FUNCTION(get_column_bound); private: virtual void visit_edges(Visitor&) override; diff --git a/Userland/Applications/Spreadsheet/Spreadsheet.cpp b/Userland/Applications/Spreadsheet/Spreadsheet.cpp index 188a4d8e59..beaa6fc38e 100644 --- a/Userland/Applications/Spreadsheet/Spreadsheet.cpp +++ b/Userland/Applications/Spreadsheet/Spreadsheet.cpp @@ -468,12 +468,14 @@ RefPtr<Sheet> Sheet::from_json(const JsonObject& object, Workbook& workbook) return sheet; } -Position Sheet::written_data_bounds() const +Position Sheet::written_data_bounds(Optional<size_t> column_index) const { Position bound; - for (auto& entry : m_cells) { + for (auto const& entry : m_cells) { if (entry.value->data().is_empty()) continue; + if (column_index.has_value() && entry.key.column != *column_index) + continue; if (entry.key.row >= bound.row) bound.row = entry.key.row; if (entry.key.column >= bound.column) diff --git a/Userland/Applications/Spreadsheet/Spreadsheet.h b/Userland/Applications/Spreadsheet/Spreadsheet.h index e3f0f24e95..69248dff8b 100644 --- a/Userland/Applications/Spreadsheet/Spreadsheet.h +++ b/Userland/Applications/Spreadsheet/Spreadsheet.h @@ -127,8 +127,8 @@ public: void copy_cells(Vector<Position> from, Vector<Position> to, Optional<Position> resolve_relative_to = {}, CopyOperation copy_operation = CopyOperation::Copy); - /// Gives the bottom-right corner of the smallest bounding box containing all the written data. - Position written_data_bounds() const; + /// Gives the bottom-right corner of the smallest bounding box containing all the written data, optionally limited to the given column. + Position written_data_bounds(Optional<size_t> column_index = {}) const; bool columns_are_standard() const; |