From 292e459901c8f04ec8e051e44b5f26e42f8d97df Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sun, 20 Mar 2022 13:05:26 +0330 Subject: [PATCH] Spreadsheet: Allow the user to format Identity cells via JS expressions Also add some hints as to what the format field expects as it would be very confusing otherwise. --- .../Applications/Spreadsheet/CellType/Date.cpp | 7 +++++++ .../Applications/Spreadsheet/CellType/Date.h | 1 + .../Spreadsheet/CellType/Identity.cpp | 18 ++++++++++++++++-- .../Spreadsheet/CellType/Identity.h | 1 + .../Spreadsheet/CellType/Numeric.cpp | 8 ++++++++ .../Spreadsheet/CellType/Numeric.h | 1 + .../Spreadsheet/CellType/String.cpp | 7 +++++++ .../Applications/Spreadsheet/CellType/String.h | 1 + .../Applications/Spreadsheet/CellType/Type.h | 8 ++++++++ .../Spreadsheet/CellTypeDialog.cpp | 3 +++ 10 files changed, 53 insertions(+), 2 deletions(-) diff --git a/Userland/Applications/Spreadsheet/CellType/Date.cpp b/Userland/Applications/Spreadsheet/CellType/Date.cpp index 2db71c875f..3bc12c55af 100644 --- a/Userland/Applications/Spreadsheet/CellType/Date.cpp +++ b/Userland/Applications/Spreadsheet/CellType/Date.cpp @@ -37,4 +37,11 @@ JS::ThrowCompletionOr DateCell::js_value(Cell& cell, const CellTypeMe return JS::Value(value / 1000); // Turn it to seconds } +String DateCell::metadata_hint(MetadataName metadata) const +{ + if (metadata == MetadataName::Format) + return "Date format string as supported by `strftime'"; + return {}; +} + } diff --git a/Userland/Applications/Spreadsheet/CellType/Date.h b/Userland/Applications/Spreadsheet/CellType/Date.h index ddf90fc63e..b8df17a8ff 100644 --- a/Userland/Applications/Spreadsheet/CellType/Date.h +++ b/Userland/Applications/Spreadsheet/CellType/Date.h @@ -18,6 +18,7 @@ public: virtual ~DateCell() override = default; virtual JS::ThrowCompletionOr display(Cell&, const CellTypeMetadata&) const override; virtual JS::ThrowCompletionOr js_value(Cell&, const CellTypeMetadata&) const override; + String metadata_hint(MetadataName) const override; }; } diff --git a/Userland/Applications/Spreadsheet/CellType/Identity.cpp b/Userland/Applications/Spreadsheet/CellType/Identity.cpp index 2a35ed3a46..b73f026210 100644 --- a/Userland/Applications/Spreadsheet/CellType/Identity.cpp +++ b/Userland/Applications/Spreadsheet/CellType/Identity.cpp @@ -15,9 +15,13 @@ IdentityCell::IdentityCell() { } -JS::ThrowCompletionOr IdentityCell::display(Cell& cell, const CellTypeMetadata&) const +JS::ThrowCompletionOr IdentityCell::display(Cell& cell, const CellTypeMetadata& metadata) const { - return cell.js_data().to_string(cell.sheet().global_object()); + auto data = cell.js_data(); + if (!metadata.format.is_empty()) + data = TRY(cell.sheet().evaluate(metadata.format, &cell)); + + return data.to_string(cell.sheet().global_object()); } JS::ThrowCompletionOr IdentityCell::js_value(Cell& cell, const CellTypeMetadata&) const @@ -25,4 +29,14 @@ JS::ThrowCompletionOr IdentityCell::js_value(Cell& cell, const CellTy return cell.js_data(); } +String IdentityCell::metadata_hint(MetadataName metadata) const +{ + if (metadata == MetadataName::Length) + return "Ignored"; + if (metadata == MetadataName::Format) + return "JavaScript expression, `value' refers to the cell's value"; + + return {}; +} + } diff --git a/Userland/Applications/Spreadsheet/CellType/Identity.h b/Userland/Applications/Spreadsheet/CellType/Identity.h index 917e7140c5..8e8cc7c701 100644 --- a/Userland/Applications/Spreadsheet/CellType/Identity.h +++ b/Userland/Applications/Spreadsheet/CellType/Identity.h @@ -17,6 +17,7 @@ public: virtual ~IdentityCell() override = default; virtual JS::ThrowCompletionOr display(Cell&, const CellTypeMetadata&) const override; virtual JS::ThrowCompletionOr js_value(Cell&, const CellTypeMetadata&) const override; + String metadata_hint(MetadataName) const override; }; } diff --git a/Userland/Applications/Spreadsheet/CellType/Numeric.cpp b/Userland/Applications/Spreadsheet/CellType/Numeric.cpp index 0b41cb2453..72c59d6529 100644 --- a/Userland/Applications/Spreadsheet/CellType/Numeric.cpp +++ b/Userland/Applications/Spreadsheet/CellType/Numeric.cpp @@ -41,4 +41,12 @@ JS::ThrowCompletionOr NumericCell::js_value(Cell& cell, const CellTyp }); } +String NumericCell::metadata_hint(MetadataName metadata) const +{ + if (metadata == MetadataName::Format) + return "Format string as accepted by `printf', all numeric formats refer to the same value (the cell's value)"; + + return {}; +} + } diff --git a/Userland/Applications/Spreadsheet/CellType/Numeric.h b/Userland/Applications/Spreadsheet/CellType/Numeric.h index daad9df765..d0f3b8491b 100644 --- a/Userland/Applications/Spreadsheet/CellType/Numeric.h +++ b/Userland/Applications/Spreadsheet/CellType/Numeric.h @@ -28,6 +28,7 @@ public: virtual ~NumericCell() override = default; virtual JS::ThrowCompletionOr display(Cell&, const CellTypeMetadata&) const override; virtual JS::ThrowCompletionOr js_value(Cell&, const CellTypeMetadata&) const override; + String metadata_hint(MetadataName) const override; }; } diff --git a/Userland/Applications/Spreadsheet/CellType/String.cpp b/Userland/Applications/Spreadsheet/CellType/String.cpp index 1b768c863f..310bda6e83 100644 --- a/Userland/Applications/Spreadsheet/CellType/String.cpp +++ b/Userland/Applications/Spreadsheet/CellType/String.cpp @@ -30,4 +30,11 @@ JS::ThrowCompletionOr StringCell::js_value(Cell& cell, const CellType return JS::js_string(cell.sheet().interpreter().heap(), string); } +String StringCell::metadata_hint(MetadataName metadata) const +{ + if (metadata == MetadataName::Format) + return "Ignored"; + return {}; +} + } diff --git a/Userland/Applications/Spreadsheet/CellType/String.h b/Userland/Applications/Spreadsheet/CellType/String.h index c6e71d217e..aecf1a23a6 100644 --- a/Userland/Applications/Spreadsheet/CellType/String.h +++ b/Userland/Applications/Spreadsheet/CellType/String.h @@ -17,6 +17,7 @@ public: virtual ~StringCell() override = default; virtual JS::ThrowCompletionOr display(Cell&, const CellTypeMetadata&) const override; virtual JS::ThrowCompletionOr js_value(Cell&, const CellTypeMetadata&) const override; + String metadata_hint(MetadataName) const override; }; } diff --git a/Userland/Applications/Spreadsheet/CellType/Type.h b/Userland/Applications/Spreadsheet/CellType/Type.h index 7f5e1086ff..10d27027d8 100644 --- a/Userland/Applications/Spreadsheet/CellType/Type.h +++ b/Userland/Applications/Spreadsheet/CellType/Type.h @@ -23,6 +23,13 @@ struct CellTypeMetadata { Format static_format; }; +enum class MetadataName { + Length, + Format, + Alignment, + StaticFormat, +}; + class CellType { public: static const CellType* get_by_name(StringView); @@ -30,6 +37,7 @@ public: virtual JS::ThrowCompletionOr display(Cell&, const CellTypeMetadata&) const = 0; virtual JS::ThrowCompletionOr js_value(Cell&, const CellTypeMetadata&) const = 0; + virtual String metadata_hint(MetadataName) const { return {}; } virtual ~CellType() = default; const String& name() const { return m_name; } diff --git a/Userland/Applications/Spreadsheet/CellTypeDialog.cpp b/Userland/Applications/Spreadsheet/CellTypeDialog.cpp index 8e9cdd0c3d..97112f16a4 100644 --- a/Userland/Applications/Spreadsheet/CellTypeDialog.cpp +++ b/Userland/Applications/Spreadsheet/CellTypeDialog.cpp @@ -153,6 +153,8 @@ void CellTypeDialog::setup_tabs(GUI::TabWidget& tabs, const Vector& po } m_type = CellType::get_by_name(g_types.at(index.row())); + if (auto* editor = right_side.find_descendant_of_type_named("format_editor")) + editor->set_tooltip(m_type->metadata_hint(MetadataName::Format)); }; { @@ -179,6 +181,7 @@ void CellTypeDialog::setup_tabs(GUI::TabWidget& tabs, const Vector& po auto& checkbox = right_side.add("Override display format"); auto& editor = right_side.add(); checkbox.set_checked(!m_format.is_empty()); + editor.set_name("format_editor"); editor.set_should_hide_unnecessary_scrollbars(true); editor.set_enabled(!m_format.is_empty()); editor.set_text(m_format);