diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-09-25 22:31:39 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-09-25 23:55:33 +0200 |
commit | 395df7b27d70e6c9000456f5c4f662bd27aa8860 (patch) | |
tree | 59130dd9ab50a970aa214168f0001ff162906b88 | |
parent | 6902a09e479acc5c4ab102fe1b16f4977e922e87 (diff) | |
download | serenity-395df7b27d70e6c9000456f5c4f662bd27aa8860.zip |
Spreadsheet: Add conditional formatting
Currently only supports setting the foregound and the background colours.
This patch also unifies `foreground_color' and `background_color' used
throughout to a `Format' struct, in hopes of getting more formatting
options one day :P
-rw-r--r-- | Applications/Spreadsheet/CMakeLists.txt | 5 | ||||
-rw-r--r-- | Applications/Spreadsheet/Cell.cpp | 37 | ||||
-rw-r--r-- | Applications/Spreadsheet/Cell.h | 12 | ||||
-rw-r--r-- | Applications/Spreadsheet/CellType/Type.h | 4 | ||||
-rw-r--r-- | Applications/Spreadsheet/CellTypeDialog.cpp | 125 | ||||
-rw-r--r-- | Applications/Spreadsheet/CellTypeDialog.h | 6 | ||||
-rw-r--r-- | Applications/Spreadsheet/CondFormatting.json | 47 | ||||
-rw-r--r-- | Applications/Spreadsheet/CondView.json | 93 | ||||
-rw-r--r-- | Applications/Spreadsheet/ConditionalFormatting.h | 73 | ||||
-rw-r--r-- | Applications/Spreadsheet/Forward.h | 9 | ||||
-rw-r--r-- | Applications/Spreadsheet/JSIntegration.cpp | 6 | ||||
-rw-r--r-- | Applications/Spreadsheet/SpreadsheetModel.cpp | 11 | ||||
-rw-r--r-- | Applications/Spreadsheet/SpreadsheetView.cpp | 1 |
13 files changed, 401 insertions, 28 deletions
diff --git a/Applications/Spreadsheet/CMakeLists.txt b/Applications/Spreadsheet/CMakeLists.txt index 5f3ff546e2..7b43bab53c 100644 --- a/Applications/Spreadsheet/CMakeLists.txt +++ b/Applications/Spreadsheet/CMakeLists.txt @@ -1,3 +1,6 @@ +compile_json_gui(CondFormatting.json CondFormattingUI.h cond_fmt_ui_json) +compile_json_gui(CondView.json CondFormattingViewUI.h cond_fmt_view_ui_json) + set(SOURCES Cell.cpp CellSyntaxHighlighter.cpp @@ -7,6 +10,8 @@ set(SOURCES CellType/String.cpp CellType/Type.cpp CellTypeDialog.cpp + CondFormattingUI.h + CondFormattingViewUI.h HelpWindow.cpp JSIntegration.cpp Spreadsheet.cpp diff --git a/Applications/Spreadsheet/Cell.cpp b/Applications/Spreadsheet/Cell.cpp index 3c01eaaace..c82f072fe9 100644 --- a/Applications/Spreadsheet/Cell.cpp +++ b/Applications/Spreadsheet/Cell.cpp @@ -109,16 +109,37 @@ void Cell::update_data() if (!dirty) return; - dirty = false; - if (kind == Formula) { - if (!evaluated_externally) - evaluated_data = sheet->evaluate(data, this); + if (dirty) { + 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(); + } + } } - for (auto& ref : referencing_cells) { - if (ref) { - ref->dirty = true; - ref->update(); + m_evaluated_formats.background_color.clear(); + m_evaluated_formats.foreground_color.clear(); + StringBuilder builder; + for (auto& fmt : m_conditional_formats) { + if (!fmt.condition.is_empty()) { + builder.clear(); + builder.append("return ("); + builder.append(fmt.condition); + builder.append(')'); + auto value = sheet->evaluate(builder.string_view(), this); + if (value.to_boolean()) { + if (fmt.background_color.has_value()) + m_evaluated_formats.background_color = fmt.background_color; + if (fmt.foreground_color.has_value()) + m_evaluated_formats.foreground_color = fmt.foreground_color; + } } } } diff --git a/Applications/Spreadsheet/Cell.h b/Applications/Spreadsheet/Cell.h index 532cb5c6af..3942d83c94 100644 --- a/Applications/Spreadsheet/Cell.h +++ b/Applications/Spreadsheet/Cell.h @@ -27,6 +27,7 @@ #pragma once #include "CellType/Type.h" +#include "ConditionalFormatting.h" #include "Forward.h" #include "JSIntegration.h" #include <AK/String.h> @@ -62,6 +63,14 @@ struct Cell : public Weakable<Cell> { void set_type(const CellType*); void set_type_metadata(CellTypeMetadata&&); + const Format& evaluated_formats() const { return m_evaluated_formats; } + const Vector<ConditionalFormat>& conditional_formats() const { return m_conditional_formats; } + void set_conditional_formats(Vector<ConditionalFormat>&& fmts) + { + dirty = true; + m_conditional_formats = move(fmts); + } + String typed_display() const; JS::Value typed_js_data() const; @@ -91,6 +100,9 @@ struct Cell : public Weakable<Cell> { const CellType* m_type { nullptr }; CellTypeMetadata m_type_metadata; + Vector<ConditionalFormat> m_conditional_formats; + Format m_evaluated_formats; + private: void update_data(); }; diff --git a/Applications/Spreadsheet/CellType/Type.h b/Applications/Spreadsheet/CellType/Type.h index 2797c3e221..022e1c9e13 100644 --- a/Applications/Spreadsheet/CellType/Type.h +++ b/Applications/Spreadsheet/CellType/Type.h @@ -27,6 +27,7 @@ #pragma once #include "../Forward.h" +#include "../ConditionalFormatting.h" #include <AK/Forward.h> #include <AK/String.h> #include <LibGfx/Color.h> @@ -39,8 +40,7 @@ struct CellTypeMetadata { int length { -1 }; String format; Gfx::TextAlignment alignment { Gfx::TextAlignment::CenterRight }; - Optional<Gfx::Color> static_foreground_color; - Optional<Gfx::Color> static_background_color; + Format static_format; }; class CellType { diff --git a/Applications/Spreadsheet/CellTypeDialog.cpp b/Applications/Spreadsheet/CellTypeDialog.cpp index 4023c856f3..0466f8427e 100644 --- a/Applications/Spreadsheet/CellTypeDialog.cpp +++ b/Applications/Spreadsheet/CellTypeDialog.cpp @@ -28,12 +28,15 @@ #include "Cell.h" #include "Spreadsheet.h" #include <AK/StringBuilder.h> +#include <Applications/Spreadsheet/CondFormattingUI.h> +#include <Applications/Spreadsheet/CondFormattingViewUI.h> #include <LibGUI/BoxLayout.h> #include <LibGUI/Button.h> #include <LibGUI/CheckBox.h> #include <LibGUI/ColorInput.h> #include <LibGUI/ComboBox.h> #include <LibGUI/ItemListModel.h> +#include <LibGUI/JSSyntaxHighlighter.h> #include <LibGUI/Label.h> #include <LibGUI/ListView.h> #include <LibGUI/SpinBox.h> @@ -41,6 +44,8 @@ #include <LibGUI/TextEditor.h> #include <LibGUI/Widget.h> +REGISTER_WIDGET(Spreadsheet, ConditionsView); + namespace Spreadsheet { CellTypeDialog::CellTypeDialog(const Vector<Position>& positions, Sheet& sheet, GUI::Window* parent) @@ -56,7 +61,7 @@ CellTypeDialog::CellTypeDialog(const Vector<Position>& positions, Sheet& sheet, builder.appendf("Format %zu Cells", positions.size()); set_title(builder.string_view()); - resize(270, 360); + resize(285, 360); auto& main_widget = set_main_widget<GUI::Widget>(); main_widget.set_layout<GUI::VerticalBoxLayout>().set_margins({ 4, 4, 4, 4 }); @@ -138,8 +143,8 @@ void CellTypeDialog::setup_tabs(GUI::TabWidget& tabs, const Vector<Position>& po m_type = &cell.type(); m_vertical_alignment = vertical_alignment_from(cell.type_metadata().alignment); m_horizontal_alignment = horizontal_alignment_from(cell.type_metadata().alignment); - m_static_background_color = cell.type_metadata().static_background_color; - m_static_foreground_color = cell.type_metadata().static_foreground_color; + m_static_format = cell.type_metadata().static_format; + m_conditional_formats = cell.conditional_formats(); } auto& type_tab = tabs.add_tab<GUI::Widget>("Type"); @@ -317,10 +322,10 @@ void CellTypeDialog::setup_tabs(GUI::TabWidget& tabs, const Vector<Position>& po auto& foreground_selector = foreground_container.add<GUI::ColorInput>(); foreground_selector.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); foreground_selector.set_preferred_size(0, 22); - if (m_static_foreground_color.has_value()) - foreground_selector.set_color(m_static_foreground_color.value()); + if (m_static_format.foreground_color.has_value()) + foreground_selector.set_color(m_static_format.foreground_color.value()); foreground_selector.on_change = [&]() { - m_static_foreground_color = foreground_selector.color(); + m_static_format.foreground_color = foreground_selector.color(); }; } @@ -340,14 +345,32 @@ void CellTypeDialog::setup_tabs(GUI::TabWidget& tabs, const Vector<Position>& po auto& background_selector = background_container.add<GUI::ColorInput>(); background_selector.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); background_selector.set_preferred_size(0, 22); - if (m_static_background_color.has_value()) - background_selector.set_color(m_static_background_color.value()); + if (m_static_format.background_color.has_value()) + background_selector.set_color(m_static_format.background_color.value()); background_selector.on_change = [&]() { - m_static_background_color = background_selector.color(); + m_static_format.background_color = background_selector.color(); }; } } } + + auto& conditional_fmt_tab = tabs.add_tab<GUI::Widget>("Conditional Format"); + conditional_fmt_tab.load_from_json(cond_fmt_ui_json); + { + auto& view = static_cast<Spreadsheet::ConditionsView&>(*conditional_fmt_tab.find_descendant_by_name("conditions_view")); + view.set_formats(&m_conditional_formats); + + auto& add_button = static_cast<GUI::Button&>(*conditional_fmt_tab.find_descendant_by_name("add_button")); + add_button.on_click = [&](auto) { + view.add_format(); + }; + + // FIXME: Disable this when empty. + auto& remove_button = static_cast<GUI::Button&>(*conditional_fmt_tab.find_descendant_by_name("remove_button")); + remove_button.on_click = [&](auto) { + view.remove_top(); + }; + } } CellTypeMetadata CellTypeDialog::metadata() const @@ -355,8 +378,7 @@ CellTypeMetadata CellTypeDialog::metadata() const CellTypeMetadata metadata; metadata.format = m_format; metadata.length = m_length; - metadata.static_foreground_color = m_static_foreground_color; - metadata.static_background_color = m_static_background_color; + metadata.static_format = m_static_format; switch (m_vertical_alignment) { case VerticalAlignment::Top: @@ -403,4 +425,85 @@ CellTypeMetadata CellTypeDialog::metadata() const return metadata; } +ConditionView::ConditionView(ConditionalFormat& fmt) + : m_format(fmt) +{ + load_from_json(cond_fmt_view_ui_json); + + auto& fg_input = *static_cast<GUI::ColorInput*>(find_descendant_by_name("foreground_input")); + auto& bg_input = *static_cast<GUI::ColorInput*>(find_descendant_by_name("background_input")); + auto& formula_editor = *static_cast<GUI::TextEditor*>(find_descendant_by_name("formula_editor")); + + if (m_format.foreground_color.has_value()) + fg_input.set_color(m_format.foreground_color.value()); + + if (m_format.background_color.has_value()) + bg_input.set_color(m_format.background_color.value()); + + formula_editor.set_text(m_format.condition); + + // FIXME: Allow unsetting these. + fg_input.on_change = [&] { + m_format.foreground_color = fg_input.color(); + }; + + bg_input.on_change = [&] { + m_format.background_color = bg_input.color(); + }; + + formula_editor.set_syntax_highlighter(make<GUI::JSSyntaxHighlighter>()); + formula_editor.set_should_hide_unnecessary_scrollbars(true); + formula_editor.set_font(&Gfx::Font::default_fixed_width_font()); + formula_editor.on_change = [&] { + m_format.condition = formula_editor.text(); + }; +} + +ConditionView::~ConditionView() +{ +} + +ConditionsView::ConditionsView() +{ + set_layout<GUI::VerticalBoxLayout>().set_spacing(2); +} + +void ConditionsView::set_formats(Vector<ConditionalFormat>* formats) +{ + ASSERT(!m_formats); + + m_formats = formats; + + for (auto& entry : *m_formats) + m_widgets.append(add<ConditionView>(entry)); +} + +void ConditionsView::add_format() +{ + ASSERT(m_formats); + + m_formats->empend(); + auto& last = m_formats->last(); + + m_widgets.append(add<ConditionView>(last)); + + update(); +} + +void ConditionsView::remove_top() +{ + ASSERT(m_formats); + + if (m_formats->is_empty()) + return; + + m_formats->take_last(); + m_widgets.take_last()->remove_from_parent(); + update(); +} + +ConditionsView::~ConditionsView() +{ +} + } diff --git a/Applications/Spreadsheet/CellTypeDialog.h b/Applications/Spreadsheet/CellTypeDialog.h index 73ee09b608..ede19ebd51 100644 --- a/Applications/Spreadsheet/CellTypeDialog.h +++ b/Applications/Spreadsheet/CellTypeDialog.h @@ -27,6 +27,7 @@ #pragma once #include "CellType/Type.h" +#include "ConditionalFormatting.h" #include "Forward.h" #include <LibGUI/Dialog.h> @@ -38,6 +39,7 @@ class CellTypeDialog : public GUI::Dialog { public: CellTypeMetadata metadata() const; const CellType* type() const { return m_type; } + Vector<ConditionalFormat> conditional_formats() { return m_conditional_formats; } enum class HorizontalAlignment : int { Left = 0, @@ -60,8 +62,8 @@ private: String m_format; HorizontalAlignment m_horizontal_alignment { HorizontalAlignment::Right }; VerticalAlignment m_vertical_alignment { VerticalAlignment::Center }; - Optional<Color> m_static_foreground_color; - Optional<Color> m_static_background_color; + Format m_static_format; + Vector<ConditionalFormat> m_conditional_formats; }; } diff --git a/Applications/Spreadsheet/CondFormatting.json b/Applications/Spreadsheet/CondFormatting.json new file mode 100644 index 0000000000..c5b10d6b0f --- /dev/null +++ b/Applications/Spreadsheet/CondFormatting.json @@ -0,0 +1,47 @@ +{ + "name": "main", + "fill_with_background_color": true, + + "layout": { + "class": "GUI::VerticalBoxLayout", + "spacing": 4 + }, + + "children": [ + { + "class": "Spreadsheet::ConditionsView", + "name": "conditions_view" + }, + { + "class": "GUI::Widget", + "vertical_size_policy": "Fixed", + "horizontal_size_policy": "Fill", + "preferred_width": 0, + "preferred_height": 20, + "layout": { + "class": "GUI::HorizontalBoxLayout", + "spacing": 10 + }, + "children": [ + { + "class": "GUI::Button", + "name": "add_button", + "text": "Add", + "horizontal_size_policy": "Fixed", + "vertical_size_policy": "Fixed", + "preferred_width": 100, + "preferred_height": 20 + }, + { + "class": "GUI::Button", + "name": "remove_button", + "text": "Remove", + "horizontal_size_policy": "Fixed", + "vertical_size_policy": "Fixed", + "preferred_width": 100, + "preferred_height": 20 + } + ] + } + ] +} diff --git a/Applications/Spreadsheet/CondView.json b/Applications/Spreadsheet/CondView.json new file mode 100644 index 0000000000..f4cdac362b --- /dev/null +++ b/Applications/Spreadsheet/CondView.json @@ -0,0 +1,93 @@ +{ + "class": "GUI::Widget", + "layout": { + "class": "GUI::VerticalBoxLayout", + "spacing": 2 + }, + "children": [ + { + "class": "GUI::Widget", + "layout": { + "class": "GUI::HorizontalBoxLayout", + "spacing": 10 + }, + "vertical_size_policy": "Fixed", + "preferred_height": 25, + "children": [ + { + "class": "GUI::Label", + "name": "if_label", + "horizontal_size_policy": "Fixed", + "vertical_size_policy": "Fixed", + "text": "if...", + "preferred_width": 40, + "preferred_height": 25 + }, + { + "class": "GUI::TextEditor", + "name": "formula_editor", + "horizontal_size_policy": "Fill", + "vertical_size_policy": "Fixed", + "tooltip": "Use 'value' to refer to the current cell's value", + "preferred_height": 25 + } + ] + }, + { + "class": "GUI::Widget", + "layout": { + "class": "GUI::HorizontalBoxLayout", + "spacing": 10 + }, + "vertical_size_policy": "Fixed", + "preferred_height": 25, + "children": [ + { + "class": "GUI::Label", + "name": "fg_color_label", + "horizontal_size_policy": "Fixed", + "vertical_size_policy": "Fixed", + "text": "Foreground...", + "preferred_width": 150, + "preferred_height": 25 + }, + { + "class": "GUI::ColorInput", + "name": "foreground_input", + "horizontal_size_policy": "Fill", + "vertical_size_policy": "Fixed", + "preferred_height": 25, + "preferred_width": 25 + } + ] + }, + { + "class": "GUI::Widget", + "layout": { + "class": "GUI::HorizontalBoxLayout", + "spacing": 10 + }, + "vertical_size_policy": "Fixed", + "preferred_height": 25, + "children": [ + { + "class": "GUI::Label", + "name": "bg_color_label", + "horizontal_size_policy": "Fixed", + "vertical_size_policy": "Fixed", + "text": "Background...", + "preferred_width": 150, + "preferred_height": 25 + }, + { + "class": "GUI::ColorInput", + "name": "background_input", + "horizontal_size_policy": "Fill", + "vertical_size_policy": "Fixed", + "preferred_height": 25, + "preferred_width": 25 + } + ] + } + ] +} diff --git a/Applications/Spreadsheet/ConditionalFormatting.h b/Applications/Spreadsheet/ConditionalFormatting.h new file mode 100644 index 0000000000..8e32bc8046 --- /dev/null +++ b/Applications/Spreadsheet/ConditionalFormatting.h @@ -0,0 +1,73 @@ +/* + * 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 <AK/String.h> +#include <LibGUI/ScrollableWidget.h> +#include <LibGfx/Color.h> + +namespace Spreadsheet { + +struct Format { + Optional<Color> foreground_color; + Optional<Color> background_color; +}; + +struct ConditionalFormat : public Format { + String condition; +}; + +class ConditionView : public GUI::Widget { + C_OBJECT(ConditionView) +public: + virtual ~ConditionView() override; + +private: + ConditionView(ConditionalFormat&); + + ConditionalFormat& m_format; +}; + +class ConditionsView : public GUI::Widget { + C_OBJECT(ConditionsView) +public: + virtual ~ConditionsView() override; + + void set_formats(Vector<ConditionalFormat>*); + + void add_format(); + void remove_top(); + +private: + ConditionsView(); + + Vector<ConditionalFormat>* m_formats { nullptr }; + NonnullRefPtrVector<GUI::Widget> m_widgets; +}; + +} diff --git a/Applications/Spreadsheet/Forward.h b/Applications/Spreadsheet/Forward.h index 5bd5480025..183c684972 100644 --- a/Applications/Spreadsheet/Forward.h +++ b/Applications/Spreadsheet/Forward.h @@ -28,11 +28,14 @@ namespace Spreadsheet { -struct Cell; +class ConditionView; class Sheet; -struct Position; +class SheetGlobalObject; class Workbook; class WorkbookObject; -class SheetGlobalObject; +struct Cell; +struct ConditionalFormat; +struct Format; +struct Position; } diff --git a/Applications/Spreadsheet/JSIntegration.cpp b/Applications/Spreadsheet/JSIntegration.cpp index 2431b5e409..54f48a5ab5 100644 --- a/Applications/Spreadsheet/JSIntegration.cpp +++ b/Applications/Spreadsheet/JSIntegration.cpp @@ -46,6 +46,12 @@ SheetGlobalObject::~SheetGlobalObject() JS::Value SheetGlobalObject::get(const JS::PropertyName& name, JS::Value receiver) const { if (name.is_string()) { + if (name.as_string() == "value") { + if (auto cell = m_sheet.current_evaluated_cell()) + return cell->js_data(); + + return JS::js_undefined(); + } if (auto pos = Sheet::parse_cell_name(name.as_string()); pos.has_value()) { auto& cell = m_sheet.ensure(pos.value()); cell.reference_from(m_sheet.current_evaluated_cell()); diff --git a/Applications/Spreadsheet/SpreadsheetModel.cpp b/Applications/Spreadsheet/SpreadsheetModel.cpp index 50976aa1fd..34925c0780 100644 --- a/Applications/Spreadsheet/SpreadsheetModel.cpp +++ b/Applications/Spreadsheet/SpreadsheetModel.cpp @@ -25,6 +25,7 @@ */ #include "SpreadsheetModel.h" +#include "ConditionalFormatting.h" #include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/Object.h> @@ -85,7 +86,10 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) return Color(Color::Red); } - if (auto color = cell->type_metadata().static_foreground_color; color.has_value()) + if (cell->evaluated_formats().foreground_color.has_value()) + return cell->evaluated_formats().foreground_color.value(); + + if (auto color = cell->type_metadata().static_format.foreground_color; color.has_value()) return color.value(); return {}; @@ -96,7 +100,10 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) if (!cell) return {}; - if (auto color = cell->type_metadata().static_background_color; color.has_value()) + if (cell->evaluated_formats().background_color.has_value()) + return cell->evaluated_formats().background_color.value(); + + if (auto color = cell->type_metadata().static_format.background_color; color.has_value()) return color.value(); return {}; diff --git a/Applications/Spreadsheet/SpreadsheetView.cpp b/Applications/Spreadsheet/SpreadsheetView.cpp index e2067dff0f..d4925ec5c6 100644 --- a/Applications/Spreadsheet/SpreadsheetView.cpp +++ b/Applications/Spreadsheet/SpreadsheetView.cpp @@ -140,6 +140,7 @@ SpreadsheetView::SpreadsheetView(Sheet& sheet) auto& cell = m_sheet->ensure(position); cell.set_type(dialog->type()); cell.set_type_metadata(dialog->metadata()); + cell.set_conditional_formats(dialog->conditional_formats()); } m_table_view->update(); |