comphelper/source/xml/xmltools.cxx | 13 include/tools/Guid.hxx | 157 ++ sc/inc/SparklineGroup.hxx | 7 sc/inc/column.hxx | 3 sc/inc/document.hxx | 7 sc/qa/unit/SparklineImportExportTest.cxx | 4 sc/qa/unit/SparklineTest.cxx | 11 sc/source/core/data/column2.cxx | 37 sc/source/core/data/column4.cxx | 7 sc/source/core/data/document.cxx | 18 sc/source/core/data/table1.cxx | 61 sc/source/core/data/table2.cxx | 4 sc/source/filter/excel/export/SparklineExt.cxx | 2 sc/source/filter/oox/SparklineFragment.cxx | 5 sc/source/filter/xcl97/XclExpChangeTrack.cxx | 20 sc/source/filter/xml/SparklineGroupsExport.cxx | 7 sc/source/filter/xml/SparklineGroupsImportContext.cxx | 4 sc/source/ui/dialogs/SparklineDialog.cxx | 172 ++ sc/source/ui/inc/SparklineDialog.hxx | 18 sc/source/ui/sparklines/SparklineGroup.cxx | 7 sc/source/ui/view/printfun.cxx | 2 sc/uiconfig/scalc/ui/sparklinedialog.ui | 1114 +++++++++++------- tools/CppunitTest_tools_test.mk | 1 tools/qa/cppunit/test_guid.cxx | 123 + 24 files changed, 1384 insertions(+), 420 deletions(-)
New commits: commit bd044cb9165f048f42f3dff6d3352fb7e61bbc62 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Mar 29 09:31:08 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Tue Mar 29 09:31:08 2022 +0900 sc: edit all sparkline attributes in SparklineDialog Change-Id: I6ca9e3436e0dd807b30585576ae2067076c3b7ce diff --git a/sc/source/ui/dialogs/SparklineDialog.cxx b/sc/source/ui/dialogs/SparklineDialog.cxx index ba01a64912c6..60e3d87da486 100644 --- a/sc/source/ui/dialogs/SparklineDialog.cxx +++ b/sc/source/ui/dialogs/SparklineDialog.cxx @@ -16,6 +16,7 @@ #include <docfunc.hxx> #include <svx/colorbox.hxx> +#include <vcl/formatter.hxx> namespace sc { @@ -56,9 +57,20 @@ SparklineDialog::SparklineDialog(SfxBindings* pBindings, SfxChildWindow* pChildW , mxCheckButtonLow(m_xBuilder->weld_check_button("check-low")) , mxCheckButtonFirst(m_xBuilder->weld_check_button("check-first")) , mxCheckButtonLast(m_xBuilder->weld_check_button("check-last")) + , mxSpinLineWidth(m_xBuilder->weld_spin_button("spin-line-width")) , mxRadioLine(m_xBuilder->weld_radio_button("line-radiobutton")) , mxRadioColumn(m_xBuilder->weld_radio_button("column-radiobutton")) , mxRadioStacked(m_xBuilder->weld_radio_button("stacked-radiobutton")) + , mxCheckDisplayXAxis(m_xBuilder->weld_check_button("check-display-x-axis")) + , mxCheckDisplayHidden(m_xBuilder->weld_check_button("check-display-hidden")) + , mxCheckRightToLeft(m_xBuilder->weld_check_button("check-right-to-left")) + , mxRadioDisplayEmptyGap(m_xBuilder->weld_radio_button("display-empty-radiobutton-gap")) + , mxRadioDisplayEmptyZero(m_xBuilder->weld_radio_button("display-empty-radiobutton-zero")) + , mxRadioDisplayEmptySpan(m_xBuilder->weld_radio_button("display-empty-radiobutton-span")) + , mxComboMinAxisType(m_xBuilder->weld_combo_box("combo-min-axis-type")) + , mxComboMaxAxisType(m_xBuilder->weld_combo_box("combo-max-axis-type")) + , mxSpinCustomMin(m_xBuilder->weld_formatted_spin_button("spin-custom-min")) + , mxSpinCustomMax(m_xBuilder->weld_formatted_spin_button("spin-custom-max")) , mbEditMode(false) { mxInputRangeEdit->SetReferences(this, mxInputRangeLabel.get()); @@ -94,6 +106,9 @@ SparklineDialog::SparklineDialog(SfxBindings* pBindings, SfxChildWindow* pChildW mxRadioLine->connect_toggled(aRadioButtonLink); mxRadioColumn->connect_toggled(aRadioButtonLink); mxRadioStacked->connect_toggled(aRadioButtonLink); + mxRadioDisplayEmptyGap->connect_toggled(aRadioButtonLink); + mxRadioDisplayEmptyZero->connect_toggled(aRadioButtonLink); + mxRadioDisplayEmptySpan->connect_toggled(aRadioButtonLink); Link<weld::Toggleable&, void> aLink = LINK(this, SparklineDialog, ToggleHandler); mxCheckButtonNegative->connect_toggled(aLink); @@ -102,6 +117,26 @@ SparklineDialog::SparklineDialog(SfxBindings* pBindings, SfxChildWindow* pChildW mxCheckButtonLow->connect_toggled(aLink); mxCheckButtonFirst->connect_toggled(aLink); mxCheckButtonLast->connect_toggled(aLink); + mxCheckDisplayXAxis->connect_toggled(aLink); + mxCheckDisplayHidden->connect_toggled(aLink); + mxCheckRightToLeft->connect_toggled(aLink); + + mxSpinLineWidth->connect_value_changed(LINK(this, SparklineDialog, SpinLineWidthChanged)); + + mxComboMinAxisType->connect_changed(LINK(this, SparklineDialog, ComboValueChanged)); + mxComboMaxAxisType->connect_changed(LINK(this, SparklineDialog, ComboValueChanged)); + + mxSpinCustomMin->connect_value_changed(LINK(this, SparklineDialog, SpinCustomChanged)); + Formatter& rSpinCustomMinFormatter = mxSpinCustomMin->GetFormatter(); + rSpinCustomMinFormatter.ClearMinValue(); + rSpinCustomMinFormatter.ClearMaxValue(); + rSpinCustomMinFormatter.UseInputStringForFormatting(); + + mxSpinCustomMax->connect_value_changed(LINK(this, SparklineDialog, SpinCustomChanged)); + Formatter& rSpinCustomMaxFormatter = mxSpinCustomMax->GetFormatter(); + rSpinCustomMaxFormatter.ClearMinValue(); + rSpinCustomMaxFormatter.ClearMaxValue(); + rSpinCustomMaxFormatter.UseInputStringForFormatting(); setupValues(); @@ -160,6 +195,19 @@ void SparklineDialog::setupValues() break; } + switch (rAttribute.getDisplayEmptyCellsAs()) + { + case sc::DisplayEmptyCellsAs::Gap: + mxRadioDisplayEmptyGap->set_active(true); + break; + case sc::DisplayEmptyCellsAs::Zero: + mxRadioDisplayEmptyZero->set_active(true); + break; + case sc::DisplayEmptyCellsAs::Span: + mxRadioDisplayEmptySpan->set_active(true); + break; + } + mxColorSeries->SelectEntry(rAttribute.getColorSeries()); mxColorNegative->SelectEntry(rAttribute.getColorNegative()); mxColorMarker->SelectEntry(rAttribute.getColorMarkers()); @@ -174,6 +222,48 @@ void SparklineDialog::setupValues() mxCheckButtonLow->set_active(rAttribute.isLow()); mxCheckButtonFirst->set_active(rAttribute.isFirst()); mxCheckButtonLast->set_active(rAttribute.isLast()); + + mxSpinLineWidth->set_value(sal_Int64(rAttribute.getLineWeight() * 100.0)); + + mxCheckDisplayXAxis->set_active(rAttribute.shouldDisplayXAxis()); + mxCheckDisplayHidden->set_active(rAttribute.shouldDisplayHidden()); + mxCheckRightToLeft->set_active(rAttribute.isRightToLeft()); + + switch (rAttribute.getMinAxisType()) + { + case sc::AxisType::Individual: + mxComboMinAxisType->set_active(0); + mxSpinCustomMin->GetFormatter().SetValue(0.0); + break; + case sc::AxisType::Group: + mxComboMinAxisType->set_active(1); + mxSpinCustomMin->GetFormatter().SetValue(0.0); + break; + case sc::AxisType::Custom: + mxComboMinAxisType->set_active(2); + if (rAttribute.getManualMin()) + mxSpinCustomMin->GetFormatter().SetValue(*rAttribute.getManualMin()); + break; + } + ComboValueChanged(*mxComboMinAxisType); + + switch (rAttribute.getMaxAxisType()) + { + case sc::AxisType::Individual: + mxComboMaxAxisType->set_active(0); + mxSpinCustomMax->GetFormatter().SetValue(0.0); + break; + case sc::AxisType::Group: + mxComboMaxAxisType->set_active(1); + mxSpinCustomMax->GetFormatter().SetValue(0.0); + break; + case sc::AxisType::Custom: + mxComboMaxAxisType->set_active(2); + if (rAttribute.getManualMin()) + mxSpinCustomMax->GetFormatter().SetValue(*rAttribute.getManualMax()); + break; + } + ComboValueChanged(*mxComboMaxAxisType); } void SparklineDialog::Close() { DoClose(sc::SparklineDialogWrapper::GetChildWindowId()); } @@ -329,6 +419,12 @@ IMPL_LINK(SparklineDialog, ToggleHandler, weld::Toggleable&, rToggle, void) rAttribute.setFirst(mxCheckButtonFirst->get_active()); if (mxCheckButtonLast.get() == &rToggle) rAttribute.setLast(mxCheckButtonLast->get_active()); + if (mxCheckDisplayXAxis.get() == &rToggle) + rAttribute.setDisplayXAxis(mxCheckDisplayXAxis->get_active()); + if (mxCheckDisplayHidden.get() == &rToggle) + rAttribute.setDisplayHidden(mxCheckDisplayHidden->get_active()); + if (mxCheckRightToLeft.get() == &rToggle) + rAttribute.setRightToLeft(mxCheckRightToLeft->get_active()); } IMPL_LINK_NOARG(SparklineDialog, SelectSparklineType, weld::Toggleable&, void) @@ -341,6 +437,82 @@ IMPL_LINK_NOARG(SparklineDialog, SelectSparklineType, weld::Toggleable&, void) rAttribute.setType(sc::SparklineType::Column); else if (mxRadioStacked->get_active()) rAttribute.setType(sc::SparklineType::Stacked); + + if (mxRadioDisplayEmptyGap->get_active()) + rAttribute.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Gap); + else if (mxRadioDisplayEmptyZero->get_active()) + rAttribute.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Zero); + else if (mxRadioDisplayEmptySpan->get_active()) + rAttribute.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Span); +} + +IMPL_LINK_NOARG(SparklineDialog, SpinLineWidthChanged, weld::SpinButton&, void) +{ + auto& rAttribute = mpLocalSparklineGroup->getAttributes(); + + double value = mxSpinLineWidth->get_value() / 100.0; + rAttribute.setLineWeight(value); +} + +IMPL_LINK(SparklineDialog, SpinCustomChanged, weld::FormattedSpinButton&, rFormatted, void) +{ + auto& rAttribute = mpLocalSparklineGroup->getAttributes(); + + if (mxSpinCustomMin.get() == &rFormatted) + { + rAttribute.setManualMin(rFormatted.GetFormatter().GetValue()); + } + else if (mxSpinCustomMax.get() == &rFormatted) + { + rAttribute.setManualMax(rFormatted.GetFormatter().GetValue()); + } +} + +IMPL_LINK(SparklineDialog, ComboValueChanged, weld::ComboBox&, rComboBox, void) +{ + auto& rAttribute = mpLocalSparklineGroup->getAttributes(); + int nActive = rComboBox.get_active(); + + if (mxComboMinAxisType.get() == &rComboBox) + { + switch (nActive) + { + case 0: + rAttribute.setMinAxisType(sc::AxisType::Individual); + mxSpinCustomMin->set_sensitive(false); + break; + case 1: + rAttribute.setMinAxisType(sc::AxisType::Group); + mxSpinCustomMin->set_sensitive(false); + break; + case 2: + rAttribute.setMinAxisType(sc::AxisType::Custom); + mxSpinCustomMin->set_sensitive(true); + break; + default: + break; + } + } + else if (mxComboMaxAxisType.get() == &rComboBox) + { + switch (nActive) + { + case 0: + rAttribute.setMaxAxisType(sc::AxisType::Individual); + mxSpinCustomMax->set_sensitive(false); + break; + case 1: + rAttribute.setMaxAxisType(sc::AxisType::Group); + mxSpinCustomMax->set_sensitive(false); + break; + case 2: + rAttribute.setMaxAxisType(sc::AxisType::Custom); + mxSpinCustomMax->set_sensitive(true); + break; + default: + break; + } + } } bool SparklineDialog::checkValidInputOutput() diff --git a/sc/source/ui/inc/SparklineDialog.hxx b/sc/source/ui/inc/SparklineDialog.hxx index 25957d714033..776480b05fce 100644 --- a/sc/source/ui/inc/SparklineDialog.hxx +++ b/sc/source/ui/inc/SparklineDialog.hxx @@ -57,10 +57,25 @@ private: std::unique_ptr<weld::CheckButton> mxCheckButtonFirst; std::unique_ptr<weld::CheckButton> mxCheckButtonLast; + std::unique_ptr<weld::SpinButton> mxSpinLineWidth; std::unique_ptr<weld::RadioButton> mxRadioLine; std::unique_ptr<weld::RadioButton> mxRadioColumn; std::unique_ptr<weld::RadioButton> mxRadioStacked; + std::unique_ptr<weld::CheckButton> mxCheckDisplayXAxis; + std::unique_ptr<weld::CheckButton> mxCheckDisplayHidden; + std::unique_ptr<weld::CheckButton> mxCheckRightToLeft; + + std::unique_ptr<weld::RadioButton> mxRadioDisplayEmptyGap; + std::unique_ptr<weld::RadioButton> mxRadioDisplayEmptyZero; + std::unique_ptr<weld::RadioButton> mxRadioDisplayEmptySpan; + + std::unique_ptr<weld::ComboBox> mxComboMinAxisType; + std::unique_ptr<weld::ComboBox> mxComboMaxAxisType; + + std::unique_ptr<weld::FormattedSpinButton> mxSpinCustomMin; + std::unique_ptr<weld::FormattedSpinButton> mxSpinCustomMax; + DECL_LINK(ButtonClicked, weld::Button&, void); DECL_LINK(EditFocusHandler, formula::RefEdit&, void); DECL_LINK(ButtonFocusHandler, formula::RefButton&, void); @@ -69,6 +84,9 @@ private: DECL_LINK(RefInputModifyHandler, formula::RefEdit&, void); DECL_LINK(ToggleHandler, weld::Toggleable&, void); DECL_LINK(SelectSparklineType, weld::Toggleable&, void); + DECL_LINK(ComboValueChanged, weld::ComboBox&, void); + DECL_LINK(SpinLineWidthChanged, weld::SpinButton&, void); + DECL_LINK(SpinCustomChanged, weld::FormattedSpinButton&, void); std::shared_ptr<sc::SparklineGroup> mpLocalSparklineGroup; diff --git a/sc/uiconfig/scalc/ui/sparklinedialog.ui b/sc/uiconfig/scalc/ui/sparklinedialog.ui index 8c2119ca2c63..8b3ee15a0ad5 100644 --- a/sc/uiconfig/scalc/ui/sparklinedialog.ui +++ b/sc/uiconfig/scalc/ui/sparklinedialog.ui @@ -2,13 +2,25 @@ <!-- Generated with glade 3.38.2 --> <interface domain="sc"> <requires lib="gtk+" version="3.20"/> + <object class="GtkAdjustment" id="adjustment-custom-max"> + <property name="step-increment">1</property> + <property name="page-increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment-custom-min"> + <property name="step-increment">1</property> + <property name="page-increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment-line-width"> + <property name="lower">0.5</property> + <property name="upper">8</property> + <property name="value">1</property> + <property name="step-increment">0.25</property> + <property name="page-increment">1</property> + </object> <object class="GtkDialog" id="SparklineDialog"> <property name="can-focus">False</property> <property name="border-width">6</property> - <property name="title" translatable="yes" context="randomnumbergenerator|RandomNumberGeneratorDialog">Sparkline Dialog</property> - <property name="resizable">False</property> - <property name="default-width">0</property> - <property name="default-height">0</property> + <property name="title" translatable="yes" context="SparklineDialog">Sparkline Dialog</property> <property name="type-hint">dialog</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> @@ -116,11 +128,6 @@ <accessibility> <relation type="labelled-by" target="cell-range-label"/> </accessibility> - <child internal-child="accessible"> - <object class="AtkObject" id="cell-range-edit-atkobject"> - <property name="AtkObject::accessible-description" translatable="yes" context="randomnumbergenerator|extended_tip|cell-range-edit">Define the range of cells to fill with random numbers. If you have previously selected a range, it will be displayed here.</property> - </object> - </child> </object> <packing> <property name="left-attach">1</property> @@ -153,11 +160,6 @@ <accessibility> <relation type="labelled-by" target="output-range-label"/> </accessibility> - <child internal-child="accessible"> - <object class="AtkObject" id="output-range-edit-atkobject"> - <property name="AtkObject::accessible-description" translatable="yes" context="randomnumbergenerator|extended_tip|cell-range-edit">Define the range of cells to fill with random numbers. If you have previously selected a range, it will be displayed here.</property> - </object> - </child> </object> <packing> <property name="left-attach">1</property> @@ -168,7 +170,7 @@ <object class="GtkLabel" id="cell-range-label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes" context="randomnumbergenerator|cell-range-label">Input range:</property> + <property name="label" translatable="yes" context="SparklineDialog|cell-range-label">Input range:</property> <property name="use-underline">True</property> <property name="xalign">0</property> <accessibility> @@ -185,7 +187,7 @@ <object class="GtkLabel" id="output-range-label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes" context="randomnumbergenerator|cell-range-label">Output range:</property> + <property name="label" translatable="yes" context="SparklineDialog|cell-range-label">Output range:</property> <property name="use-underline">True</property> <property name="xalign">0</property> <accessibility> @@ -224,7 +226,7 @@ <property name="label-xalign">0</property> <property name="shadow-type">none</property> <child> - <!-- n-columns=6 n-rows=5 --> + <!-- n-columns=1 n-rows=6 --> <object class="GtkGrid"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -235,377 +237,538 @@ <property name="row-spacing">6</property> <property name="column-spacing">6</property> <child> - <object class="GtkLabel" id="label-series"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-series">Series:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="color-button-series"/> - </accessibility> - </object> - <packing> - <property name="left-attach">0</property> - <property name="top-attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-negative"> + <object class="GtkBox"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-negative">Negative Points:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="color-button-negative"/> - <relation type="label-for" target="check-negative"/> - </accessibility> - </object> - <packing> - <property name="left-attach">0</property> - <property name="top-attach">2</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="color-button-series"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> + <property name="hexpand">True</property> + <property name="spacing">6</property> <child> - <placeholder/> + <object class="GtkLabel" id="label-type"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-type">Type:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="line-radiobutton"/> + <relation type="label-for" target="column-radiobutton"/> + <relation type="label-for" target="stacked-radiobutton"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-series"/> - </accessibility> - </object> - <packing> - <property name="left-attach">2</property> - <property name="top-attach">1</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="color-button-negative"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkRadioButton" id="line-radiobutton"> + <property name="label" translatable="yes" context="SparklineDialog|line-radiobutton">Line</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="hexpand">True</property> + <property name="active">True</property> + <property name="draw-indicator">True</property> + <accessibility> + <relation type="labelled-by" target="label-type"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-negative"/> - </accessibility> - </object> - <packing> - <property name="left-attach">2</property> - <property name="top-attach">2</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="check-negative"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="image-position">right</property> - <property name="always-show-image">True</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkRadioButton" id="column-radiobutton"> + <property name="label" translatable="yes" context="SparklineDialog|column-radiobutton">Column</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="hexpand">True</property> + <property name="draw-indicator">True</property> + <property name="group">line-radiobutton</property> + <accessibility> + <relation type="labelled-by" target="label-type"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-negative"/> - </accessibility> - </object> - <packing> - <property name="left-attach">1</property> - <property name="top-attach">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-low"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-low">Low Points:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="color-button-low"/> - <relation type="label-for" target="check-low"/> - </accessibility> - </object> - <packing> - <property name="left-attach">0</property> - <property name="top-attach">4</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="color-button-high"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkRadioButton" id="stacked-radiobutton"> + <property name="label" translatable="yes" context="SparklineDialog|stacked-radiobutton">Stacked</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="hexpand">True</property> + <property name="draw-indicator">True</property> + <property name="group">line-radiobutton</property> + <accessibility> + <relation type="labelled-by" target="label-type"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-high"/> - </accessibility> </object> <packing> - <property name="left-attach">2</property> - <property name="top-attach">3</property> + <property name="left-attach">0</property> + <property name="top-attach">0</property> </packing> </child> <child> - <object class="GtkMenuButton" id="color-button-low"> + <!-- n-columns=6 n-rows=4 --> + <object class="GtkGrid"> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="row-spacing">6</property> + <property name="column-spacing">6</property> <child> - <placeholder/> + <object class="GtkLabel" id="label-series"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-series">Series:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="color-button-series"/> + </accessibility> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + <property name="width">2</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-low"/> - </accessibility> - </object> - <packing> - <property name="left-attach">2</property> - <property name="top-attach">4</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="check-low"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="image-position">right</property> - <property name="always-show-image">True</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkMenuButton" id="color-button-series"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="hexpand">False</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-series"/> + </accessibility> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">0</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-low"/> - </accessibility> - </object> - <packing> - <property name="left-attach">1</property> - <property name="top-attach">4</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-high"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-high">High Points:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="color-button-high"/> - <relation type="label-for" target="check-high"/> - </accessibility> - </object> - <packing> - <property name="left-attach">0</property> - <property name="top-attach">3</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="check-high"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="image-position">right</property> - <property name="always-show-image">True</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkLabel" id="label-negative"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-negative">Negative Points:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="check-negative"/> + <relation type="label-for" target="color-button-negative"/> + </accessibility> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-high"/> - </accessibility> - </object> - <packing> - <property name="left-attach">1</property> - <property name="top-attach">3</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-marker"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-marker">Marker:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="check-marker"/> - <relation type="label-for" target="color-button-marker"/> - </accessibility> - </object> - <packing> - <property name="left-attach">3</property> - <property name="top-attach">2</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="check-marker"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="image-position">right</property> - <property name="always-show-image">True</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkLabel" id="label-high"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-high">High Points:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="check-high"/> + <relation type="label-for" target="color-button-high"/> + </accessibility> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">2</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-marker"/> - </accessibility> - </object> - <packing> - <property name="left-attach">4</property> - <property name="top-attach">2</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="color-button-marker"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkCheckButton" id="check-negative"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-negative"/> + </accessibility> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">1</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-marker"/> - </accessibility> - </object> - <packing> - <property name="left-attach">5</property> - <property name="top-attach">2</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="color-button-first"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkCheckButton" id="check-high"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-high"/> + </accessibility> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">2</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-first"/> - </accessibility> - </object> - <packing> - <property name="left-attach">5</property> - <property name="top-attach">3</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="color-button-last"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkMenuButton" id="color-button-negative"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="hexpand">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-negative"/> + </accessibility> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">1</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-last"/> - </accessibility> - </object> - <packing> - <property name="left-attach">5</property> - <property name="top-attach">4</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="check-first"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="image-position">right</property> - <property name="always-show-image">True</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkMenuButton" id="color-button-high"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-high"/> + </accessibility> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">2</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-first"/> - </accessibility> - </object> - <packing> - <property name="left-attach">4</property> - <property name="top-attach">3</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="check-last"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="image-position">right</property> - <property name="always-show-image">True</property> - <property name="draw-indicator">True</property> <child> - <placeholder/> + <object class="GtkLabel" id="label-low"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-low">Low Points:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="check-low"/> + <relation type="label-for" target="color-button-low"/> + </accessibility> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check-low"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-low"/> + </accessibility> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="color-button-low"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-low"/> + </accessibility> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-last"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-last">Last Points:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="check-last"/> + <relation type="label-for" target="color-button-last"/> + </accessibility> + </object> + <packing> + <property name="left-attach">3</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-first"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-first">First Points:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="check-first"/> + <relation type="label-for" target="color-button-first"/> + </accessibility> + </object> + <packing> + <property name="left-attach">3</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-marker"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-marker">Marker:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="check-marker"/> + <relation type="label-for" target="color-button-marker"/> + </accessibility> + </object> + <packing> + <property name="left-attach">3</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check-marker"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-marker"/> + </accessibility> + </object> + <packing> + <property name="left-attach">4</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check-first"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-first"/> + </accessibility> + </object> + <packing> + <property name="left-attach">4</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check-last"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-last"/> + </accessibility> + </object> + <packing> + <property name="left-attach">4</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="color-button-marker"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="hexpand">True</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-marker"/> + </accessibility> + </object> + <packing> + <property name="left-attach">5</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="color-button-first"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-first"/> + </accessibility> + </object> + <packing> + <property name="left-attach">5</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="color-button-last"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + <child> + <placeholder/> + </child> + <accessibility> + <relation type="labelled-by" target="label-last"/> + </accessibility> + </object> + <packing> + <property name="left-attach">5</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkFixed"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + <packing> + <property name="left-attach">3</property> + <property name="top-attach">0</property> + <property name="width">3</property> + </packing> </child> - <accessibility> - <relation type="labelled-by" target="label-last"/> - </accessibility> - </object> - <packing> - <property name="left-attach">4</property> - <property name="top-attach">4</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-first"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-first">First Points:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="color-button-first"/> - <relation type="label-for" target="check-first"/> - </accessibility> - </object> - <packing> - <property name="left-attach">3</property> - <property name="top-attach">3</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-last"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-last">Last Points:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="color-button-last"/> - <relation type="label-for" target="check-last"/> - </accessibility> </object> <packing> - <property name="left-attach">3</property> - <property name="top-attach">4</property> + <property name="left-attach">0</property> + <property name="top-attach">1</property> </packing> </child> <child> - <object class="GtkLabel" id="label-type"> + <object class="GtkBox"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes" context="SparklineDialog|label-type">Type:</property> - <property name="xalign">0</property> - <accessibility> - <relation type="label-for" target="line-radiobutton"/> - <relation type="label-for" target="column-radiobutton"/> - <relation type="label-for" target="stacked-radiobutton"/> - </accessibility> + <property name="hexpand">True</property> + <property name="spacing">6</property> + <child> + <object class="GtkCheckButton" id="check-display-x-axis"> + <property name="label" translatable="yes" context="SparklineDialog|check-display-x-axis">Display X Axis</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check-display-hidden"> + <property name="label" translatable="yes" context="SparklineDialog|check-display-hidden">Display Hidden</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check-right-to-left"> + <property name="label" translatable="yes" context="SparklineDialog|check-right-to-left">Right To Left</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="image-position">right</property> + <property name="always-show-image">True</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> </object> <packing> <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="top-attach">3</property> </packing> </child> <child> @@ -614,8 +777,26 @@ <property name="can-focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkRadioButton" id="line-radiobutton"> - <property name="label" translatable="yes" context="SparklineDialog|line-radiobutton">Line</property> + <object class="GtkLabel" id="label-display-empty-cells-as"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-type">Display Empty Cells As:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="display-empty-radiobutton-gap"/> + <relation type="label-for" target="display-empty-radiobutton-zero"/> + <relation type="label-for" target="display-empty-radiobutton-span"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="display-empty-radiobutton-gap"> + <property name="label" translatable="yes" context="SparklineDialog|line-radiobutton">Gap</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">False</property> @@ -623,71 +804,246 @@ <property name="active">True</property> <property name="draw-indicator">True</property> <accessibility> - <relation type="labelled-by" target="label-type"/> + <relation type="labelled-by" target="label-display-empty-cells-as"/> </accessibility> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkRadioButton" id="column-radiobutton"> - <property name="label" translatable="yes" context="SparklineDialog|column-radiobutton">Column</property> + <object class="GtkRadioButton" id="display-empty-radiobutton-zero"> + <property name="label" translatable="yes" context="SparklineDialog|line-radiobutton">Zero</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">False</property> <property name="hexpand">True</property> + <property name="active">True</property> <property name="draw-indicator">True</property> - <property name="group">line-radiobutton</property> + <property name="group">display-empty-radiobutton-gap</property> <accessibility> - <relation type="labelled-by" target="label-type"/> + <relation type="labelled-by" target="label-display-empty-cells-as"/> </accessibility> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> <child> - <object class="GtkRadioButton" id="stacked-radiobutton"> - <property name="label" translatable="yes" context="SparklineDialog|stacked-radiobutton">Stacked</property> + <object class="GtkRadioButton" id="display-empty-radiobutton-span"> + <property name="label" translatable="yes" context="SparklineDialog|line-radiobutton">Span</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">False</property> <property name="hexpand">True</property> + <property name="active">True</property> <property name="draw-indicator">True</property> - <property name="group">line-radiobutton</property> + <property name="group">display-empty-radiobutton-gap</property> <accessibility> - <relation type="labelled-by" target="label-type"/> + <relation type="labelled-by" target="label-display-empty-cells-as"/> </accessibility> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">2</property> + <property name="position">3</property> </packing> </child> </object> <packing> - <property name="left-attach">1</property> - <property name="top-attach">0</property> - <property name="width">5</property> + <property name="left-attach">0</property> + <property name="top-attach">4</property> </packing> </child> <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> + <object class="GtkExpander"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="expanded">True</property> + <property name="label-fill">True</property> + <property name="resize-toplevel">True</property> + <child> + <!-- n-columns=3 n-rows=2 --> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="row-spacing">6</property> + <property name="column-spacing">6</property> + <child> + <object class="GtkLabel" id="label-minimum"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="xpad">12</property> + <property name="label" translatable="yes" context="SparklineDialog|label-series">Minimum Value:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="combo-min-axis-type"/> + <relation type="label-for" target="spin-custom-min"/> + </accessibility> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-maximum"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="xpad">12</property> + <property name="label" translatable="yes" context="SparklineDialog|label-series">Maximum Value:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="combo-max-axis-type"/> + <relation type="label-for" target="spin-custom-max"/> + </accessibility> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkComboBoxText" id="combo-min-axis-type"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="active">0</property> + <items> + <item id="0" translatable="yes" context="SparklineDialog|combo-min-axis-type_0">Individual</item> + <item id="1" translatable="yes" context="SparklineDialog|combo-min-axis-type_1">Group</item> + <item id="2" translatable="yes" context="SparklineDialog|combo-min-axis-type_2">Custom</item> + </items> + <accessibility> + <relation type="labelled-by" target="label-minimum"/> + </accessibility> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkComboBoxText" id="combo-max-axis-type"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="active">0</property> + <items> + <item id="0" translatable="yes" context="SparklineDialog|combo-max-axis-type_0">Individual</item> + <item id="1" translatable="yes" context="SparklineDialog|combo-max-axis-type_1">Group</item> + <item id="2" translatable="yes" context="SparklineDialog|combo-max-axis-type_2">Custom</item> + </items> + <accessibility> + <relation type="labelled-by" target="label-maximum"/> + </accessibility> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spin-custom-min"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="activates-default">True</property> + <property name="width-chars">10</property> + <property name="truncate-multiline">True</property> + <property name="adjustment">adjustment-custom-min</property> + <accessibility> + <relation type="labelled-by" target="label-minimum"/> + </accessibility> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spin-custom-max"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="activates-default">True</property> + <property name="width-chars">10</property> + <property name="truncate-multiline">True</property> + <property name="adjustment">adjustment-custom-max</property> + <accessibility> + <relation type="labelled-by" target="label-maximum"/> + </accessibility> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">1</property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-vertical-axis">Vertical Axis</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">5</property> + </packing> </child> <child> - <placeholder/> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkLabel" id="label-line-width"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="SparklineDialog|label-line-width">Line Width:</property> + <property name="xalign">0</property> + <accessibility> + <relation type="label-for" target="spin-line-width"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spin-line-width"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="input-purpose">number</property> + <property name="adjustment">adjustment-line-width</property> + <property name="climb-rate">0.25</property> + <property name="digits">2</property> + <property name="snap-to-ticks">True</property> + <property name="numeric">True</property> + <property name="value">1</property> + <accessibility> + <relation type="labelled-by" target="label-line-width"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">2</property> + </packing> </child> </object> </child> @@ -715,10 +1071,20 @@ <action-widget response="-6">cancel</action-widget> <action-widget response="-11">help</action-widget> </action-widgets> - <child internal-child="accessible"> - <object class="AtkObject" id="SparklineDialog-atkobject"> - <property name="AtkObject::accessible-description" translatable="yes" context="randomnumbergenerator|extended_tip|RandomNumberGeneratorDialog">Populate a cell range with automatically generated pseudo random numbers with the selected distribution function and its parameters.</property> - </object> - </child> + </object> + <object class="GtkSizeGroup"> + <widgets> + <widget name="cell-range-label"/> + <widget name="output-range-label"/> + <widget name="label-type"/> + <widget name="label-series"/> + <widget name="label-negative"/> + <widget name="label-high"/> + <widget name="label-low"/> + <widget name="label-display-empty-cells-as"/> + <widget name="label-minimum"/> + <widget name="label-maximum"/> + <widget name="label-line-width"/> + </widgets> </object> </interface> commit 96db9e1ad90b43535b886c7a509a35209b895338 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Mon Mar 28 22:51:08 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Mon Mar 28 22:51:08 2022 +0900 sc: use GUID for the SparklineGroup ID and use that This adds tools::Guid as the SparklineGroup ID. At import the Guid is parsed by tools::Guid and later it is used to identify the SparklineGroup. This is useful when copying sparklines so we can preserve to which group it belongs, when that is desired. Change-Id: I4f2b560d5ea74552e8add57bb05469be57cf4a69 diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx index ce90cd9917a0..d6cb8cf4402d 100644 --- a/sc/inc/SparklineGroup.hxx +++ b/sc/inc/SparklineGroup.hxx @@ -14,6 +14,7 @@ #include <tools/color.hxx> #include <optional> #include <SparklineAttributes.hxx> +#include <tools/Guid.hxx> namespace sc { @@ -21,15 +22,15 @@ class SC_DLLPUBLIC SparklineGroup { private: SparklineAttributes m_aAttributes; - OUString m_sUID; + tools::Guid m_aGUID; public: SparklineAttributes& getAttributes() { return m_aAttributes; } SparklineAttributes const& getAttributes() const { return m_aAttributes; } - OUString getID() { return m_sUID; } + tools::Guid& getID() { return m_aGUID; } - void setID(OUString const& rID) { m_sUID = rID; } + void setID(tools::Guid const& rGuid) { m_aGUID = rGuid; } SparklineGroup(); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index f45c5f41be14..758227e2b1a7 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -69,12 +69,12 @@ enum class EEHorizontalTextDirection; namespace editeng { class SvxBorderLine; } namespace formula { struct VectorRefArray; } namespace svl { - class SharedString; class SharedStringPool; - } +namespace tools { class Guid; } + namespace sc { struct FormulaGroupContext; @@ -208,6 +208,7 @@ typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes; struct ScSheetLimits; struct ScDataAreaExtras; + namespace sc { typedef std::map<OUString, BitmapEx> IconSetBitmapMap; @@ -1249,6 +1250,8 @@ public: SC_DLLPUBLIC sc::SparklineList* GetSparklineList(SCTAB nTab); SC_DLLPUBLIC bool DeleteSparkline(ScAddress const& rPosition); SC_DLLPUBLIC bool HasOneSparklineGroup(ScRange const& rRange); + SC_DLLPUBLIC std::shared_ptr<sc::SparklineGroup> SearchSparklineGroup(tools::Guid const& rGuid); + /** Notes **/ SC_DLLPUBLIC ScPostIt* GetNote(const ScAddress& rPos); SC_DLLPUBLIC ScPostIt* GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab); diff --git a/sc/qa/unit/SparklineImportExportTest.cxx b/sc/qa/unit/SparklineImportExportTest.cxx index 591916e9a932..2176383185d7 100644 --- a/sc/qa/unit/SparklineImportExportTest.cxx +++ b/sc/qa/unit/SparklineImportExportTest.cxx @@ -69,8 +69,8 @@ void checkSparklines(ScDocument& rDocument) { auto pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 0)); // A2 CPPUNIT_ASSERT(pSparkline); - CPPUNIT_ASSERT_EQUAL(OUString("{1C5C5DE0-3C09-4CB3-A3EC-9E763301EC82}"), - pSparkline->getSparklineGroup()->getID()); + CPPUNIT_ASSERT_EQUAL(OString("{1C5C5DE0-3C09-4CB3-A3EC-9E763301EC82}"), + pSparkline->getSparklineGroup()->getID().getString()); auto& rAttributes = pSparkline->getSparklineGroup()->getAttributes(); CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, rAttributes.getType()); diff --git a/sc/qa/unit/SparklineTest.cxx b/sc/qa/unit/SparklineTest.cxx index 185328d58776..64f05a703590 100644 --- a/sc/qa/unit/SparklineTest.cxx +++ b/sc/qa/unit/SparklineTest.cxx @@ -153,6 +153,7 @@ void SparklineTest::testCopyPasteSparkline() ScRange aSourceRange(0, 6, 0, 0, 6, 0); auto pSparkline = rDocument.GetSparkline(aSourceRange.aStart); + auto const& pOriginalGroup = pSparkline->getSparklineGroup(); CPPUNIT_ASSERT(pSparkline); CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparkline->getColumn()); @@ -177,6 +178,11 @@ void SparklineTest::testCopyPasteSparkline() CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparklineCopy->getColumn()); CPPUNIT_ASSERT_EQUAL(SCROW(7), pSparklineCopy->getRow()); + + auto const& pCopyGroup = pSparklineCopy->getSparklineGroup(); + + CPPUNIT_ASSERT(pOriginalGroup->getID() == pCopyGroup->getID()); + CPPUNIT_ASSERT(pOriginalGroup.get() == pCopyGroup.get()); } // Copy / Paste with a ClipDoc @@ -198,6 +204,11 @@ void SparklineTest::testCopyPasteSparkline() CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparklineCopy->getColumn()); CPPUNIT_ASSERT_EQUAL(SCROW(8), pSparklineCopy->getRow()); + + auto const& pCopyGroup = pSparklineCopy->getSparklineGroup(); + + CPPUNIT_ASSERT(pOriginalGroup->getID() == pCopyGroup->getID()); + CPPUNIT_ASSERT(pOriginalGroup.get() == pCopyGroup.get()); } xDocSh->DoClose(); diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 5be5461e66d0..5eb27580dc57 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -2054,9 +2054,11 @@ public: auto const& pSparkline = pCell->getSparkline(); auto const& pGroup = pCell->getSparklineGroup(); - auto pNewSparklineGroup = std::make_shared<sc::SparklineGroup>(*pGroup); // Copy the group - auto pNewSparkline = std::make_shared<sc::Sparkline>(mnDestCol, nDestRow, pNewSparklineGroup); + auto pDestinationGroup = mrDestCol.GetDoc().SearchSparklineGroup(pGroup->getID()); + if (!pDestinationGroup) + pDestinationGroup = std::make_shared<sc::SparklineGroup>(*pGroup); // Copy the group + auto pNewSparkline = std::make_shared<sc::Sparkline>(mnDestCol, nDestRow, pDestinationGroup); pNewSparkline->setInputRange(pSparkline->getInputRange()); miDestPosition = mrDestSparkline.set(miDestPosition, nDestRow, new sc::SparklineCell(pNewSparkline)); diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index 334652d86987..d87cbb59c8af 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -373,8 +373,11 @@ void ScColumn::duplicateSparkline(sc::CopyFromClipContext& rContext, sc::ColumnB ScAddress aCurrentPosition = aDestPosition; for (size_t i = 0; i < nDestSize; ++i) { - auto pNewSparklineGroup = std::make_shared<sc::SparklineGroup>(*pSparklineGroup); - auto pNewSparkline = std::make_shared<sc::Sparkline>(aCurrentPosition.Col(), aCurrentPosition.Row(), pNewSparklineGroup); + auto pDuplicatedGroup = GetDoc().SearchSparklineGroup(pSparklineGroup->getID()); + if (!pDuplicatedGroup) + pDuplicatedGroup = std::make_shared<sc::SparklineGroup>(*pSparklineGroup); + + auto pNewSparkline = std::make_shared<sc::Sparkline>(aCurrentPosition.Col(), aCurrentPosition.Row(), pDuplicatedGroup); pNewSparkline->setInputRange(pSparkline->getInputRange()); aSparklines[i] = new sc::SparklineCell(pNewSparkline); aCurrentPosition.IncRow(); diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 01bf9bcffa5b..351e795ac5da 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -86,6 +86,7 @@ #include <tokenstringcontext.hxx> #include <compressedarray.hxx> #include <recursionhelper.hxx> +#include <SparklineGroup.hxx> #include <formula/vectortoken.hxx> @@ -6583,6 +6584,23 @@ bool ScDocument::HasOneSparklineGroup(ScRange const& rRange) return true; } +std::shared_ptr<sc::SparklineGroup> ScDocument::SearchSparklineGroup(tools::Guid const& rGuid) +{ + for (auto const& rTable : maTabs) + { + std::vector<std::shared_ptr<sc::SparklineGroup>> aSparklineGroupMap; + + for (auto const& pSparkline : rTable->GetSparklineList().getSparklines()) + { + auto const& pGroup = pSparkline->getSparklineGroup(); + if (pGroup->getID() == rGuid) + return pGroup; + } + } + + return std::shared_ptr<sc::SparklineGroup>(); +} + // Notes ScPostIt* ScDocument::GetNote(const ScAddress& rPos) diff --git a/sc/source/filter/excel/export/SparklineExt.cxx b/sc/source/filter/excel/export/SparklineExt.cxx index c36d78d0750b..47e469a31ef0 100644 --- a/sc/source/filter/excel/export/SparklineExt.cxx +++ b/sc/source/filter/excel/export/SparklineExt.cxx @@ -189,7 +189,7 @@ void SparklineExt::addSparklineGroup(XclExpXmlStream& rStream, sc::SparklineGrou auto pAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); // Write ID - OString sUID = OUStringToOString(rSparklineGroup.getID(), RTL_TEXTENCODING_UTF8); + OString sUID = rSparklineGroup.getID().getString(); pAttrList->addNS(XML_xr2, XML_uid, sUID); // Write attributes diff --git a/sc/source/filter/oox/SparklineFragment.cxx b/sc/source/filter/oox/SparklineFragment.cxx index f9475ebf014b..8f6d305c0145 100644 --- a/sc/source/filter/oox/SparklineFragment.cxx +++ b/sc/source/filter/oox/SparklineFragment.cxx @@ -173,8 +173,9 @@ ContextHandlerRef SparklineGroupsContext::onCreateContext(sal_Int32 nElement, auto& rLastGroup = m_aSparklineGroups.emplace_back(); auto& rSparklineAttributes = rLastGroup.getSparklineGroup()->getAttributes(); addAttributesToSparklineAttributes(rSparklineAttributes, rAttribs); - OUString sUID = rAttribs.getString(XR2_TOKEN(uid), OUString()); - rLastGroup.getSparklineGroup()->setID(sUID); + OUString sGUID = rAttribs.getString(XR2_TOKEN(uid), OUString()); + tools::Guid aGuid(OUStringToOString(sGUID, RTL_TEXTENCODING_ASCII_US)); + rLastGroup.getSparklineGroup()->setID(aGuid); return this; } case XLS14_TOKEN(colorSeries): diff --git a/sc/source/filter/xml/SparklineGroupsExport.cxx b/sc/source/filter/xml/SparklineGroupsExport.cxx index 6be8a616a423..4de56fcfaf58 100644 --- a/sc/source/filter/xml/SparklineGroupsExport.cxx +++ b/sc/source/filter/xml/SparklineGroupsExport.cxx @@ -187,11 +187,8 @@ void SparklineGroupsExport::addSparklineGroup(SparklineGroup* pSparklineGroup) { auto const& rAttributes = pSparklineGroup->getAttributes(); - OUString sID = pSparklineGroup->getID(); - if (!sID.isEmpty()) - { - m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_ID, sID); - } + OUString sID = pSparklineGroup->getID().getOUString(); + m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_ID, sID); addSparklineGroupAttributes(rAttributes); diff --git a/sc/source/filter/xml/SparklineGroupsImportContext.cxx b/sc/source/filter/xml/SparklineGroupsImportContext.cxx index 33d831d08608..dae486582b6a 100644 --- a/sc/source/filter/xml/SparklineGroupsImportContext.cxx +++ b/sc/source/filter/xml/SparklineGroupsImportContext.cxx @@ -70,7 +70,9 @@ void SparklineGroupsImportContext::fillSparklineGroupID( { case XML_ELEMENT(CALC_EXT, XML_ID): { - m_pCurrentSparklineGroup->setID(rIter.toString()); + OString aString = OUStringToOString(rIter.toString(), RTL_TEXTENCODING_ASCII_US); + tools::Guid aGuid(aString); + m_pCurrentSparklineGroup->setID(aGuid); break; } } diff --git a/sc/source/ui/sparklines/SparklineGroup.cxx b/sc/source/ui/sparklines/SparklineGroup.cxx index 55f52ff4665f..9ef2c7044ab0 100644 --- a/sc/source/ui/sparklines/SparklineGroup.cxx +++ b/sc/source/ui/sparklines/SparklineGroup.cxx @@ -12,11 +12,14 @@ namespace sc { -SparklineGroup::SparklineGroup() {} +SparklineGroup::SparklineGroup() + : m_aGUID(tools::Guid::Generate) +{ +} SparklineGroup::SparklineGroup(SparklineGroup const& pOtherSparkline) : m_aAttributes(pOtherSparkline.m_aAttributes) - , m_sUID(pOtherSparkline.m_sUID) + , m_aGUID(pOtherSparkline.m_aGUID) { } commit 9061ded66e953f37381a69b10d5b92251df7ef64 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Mon Mar 28 14:31:21 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Mon Mar 28 14:31:21 2022 +0900 sc: make printing of Sparklines work Sparkline cells don't contain any data, so they would be ignored if we don't include them in the function that determine if there is any data in a cell or not. This is the main reason why the cells weren't drawn when printing as they had no data so they were ignored. Change-Id: I7849f1a00c9421616b8af90bdac368fd63ae1087 diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 61c51761c0a0..0e31374c38cd 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -630,6 +630,9 @@ public: void CopyCellSparklinesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, SCROW nRowOffsetDest = 0) const; void DuplicateSparklines(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol, sc::ColumnBlockPosition& rDestBlockPos, SCROW nRowOffsetDest = 0) const; + bool HasSparklines() const; + SCROW GetSparklinesMaxRow() const; + SCROW GetSparklinesMinRow() const; // cell notes ScPostIt* GetCellNote( SCROW nRow ); diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 24702e11d5a3..5be5461e66d0 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -2082,6 +2082,37 @@ void ScColumn::DuplicateSparklines(SCROW nStartRow, size_t nDataSize, ScColumn& rDestBlockPos.miSparklinePos = rDestCol.maSparklines.begin(); } +bool ScColumn::HasSparklines() const +{ + if (maSparklines.block_size() == 1 && maSparklines.begin()->type == sc::element_type_empty) + return false; // all elements are empty + return true; // otherwise some must be sparklines +} + +SCROW ScColumn::GetSparklinesMaxRow() const +{ + SCROW maxRow = 0; + for (const auto& rSparkline : maSparklines) + { + if (rSparkline.type == sc::element_type_sparkline) + maxRow = rSparkline.position + rSparkline.size - 1; + } + return maxRow; +} + +SCROW ScColumn::GetSparklinesMinRow() const +{ + SCROW minRow = 0; + sc::SparklineStoreType::const_iterator it = std::find_if(maSparklines.begin(), maSparklines.end(), + [](const auto& rSparkline) + { + return rSparkline.type == sc::element_type_sparkline; + }); + if (it != maSparklines.end()) + minRow = it->position; + return minRow; +} + // Notes ScPostIt* ScColumn::GetCellNote(SCROW nRow) diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index ba7c18ad3722..84b06f30a3ff 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -539,6 +539,20 @@ bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const nMaxX = i; } } + if (aCol[i].HasSparklines()) + { + SCROW maxSparklineRow = aCol[i].GetSparklinesMaxRow(); + if (maxSparklineRow >= nMaxY) + { + bFound = true; + nMaxY = maxSparklineRow; + } + if (i > nMaxX) + { + bFound = true; + nMaxX = i; + } + } } rEndCol = nMaxX; @@ -608,6 +622,20 @@ bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, bool bC nMaxX = i; } } + if (aCol[i].HasSparklines()) + { + SCROW maxSparklineRow = aCol[i].GetSparklinesMaxRow(); + if (maxSparklineRow >= nMaxY) + { + bFound = true; + nMaxY = maxSparklineRow; + } + if (i > nMaxX) + { + bFound = true; + nMaxX = i; + } + } } } @@ -695,8 +723,16 @@ bool ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow, if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow )) //TODO: bNotes ?????? { bFound = true; - if (i>nMaxX) + if (i > nMaxX) + nMaxX = i; + } + else if (aCol[i].HasSparklines()) + { + if (i > nMaxX) + { + bFound = true; nMaxX = i; + } } } ... etc. - the rest is truncated