Rebased ref, commits from common ancestor:
commit 00eaa360c99df1b539e7f1d70ff385468cf758e7
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Tue Mar 15 15:18:16 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Tue Mar 15 15:18:16 2022 +0900
sc: support deleting a Sparkline with 'Clear Content' function
Change-Id: Ida61b402170238fb0505c777e49954c15d376cf0
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 5472419e2297..91bb18b4813b 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -619,6 +619,8 @@ public:
// Spaklines
sc::SparklineCell* GetSparklineCell(SCROW nRow);
void CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const&
pSparkline);
+ void DeleteSparklineCells(sc::ColumnBlockPosition& rBlockPos, SCROW nRow1,
SCROW nRow2);
+ bool DeleteSparkline(SCROW nRow);
// cell notes
ScPostIt* GetCellNote( SCROW nRow );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 1b86695ba94b..c101612ab2dc 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1246,6 +1246,7 @@ public:
SC_DLLPUBLIC sc::Sparkline* GetSparkline(ScAddress const & rPosition);
SC_DLLPUBLIC sc::Sparkline* CreateSparkline(ScAddress const & rPosition,
std::shared_ptr<sc::SparklineGroup> & pSparklineGroup);
SC_DLLPUBLIC sc::SparklineList* GetSparklineList(SCTAB nTab);
+ SC_DLLPUBLIC bool DeleteSparkline(ScAddress const& rPosition);
/** Notes **/
SC_DLLPUBLIC ScPostIt* GetNote(const ScAddress& rPos);
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 283231ddf5f1..5f1b5179cdd9 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -157,19 +157,20 @@ enum class InsertDeleteFlags : sal_uInt16
OBJECTS = 0x0080, /// Drawing objects.
EDITATTR = 0x0100, /// Rich-text attributes.
OUTLINE = 0x0800, /// Sheet / outlining (grouping) information
+ SPARKLINES = 0x4000, /// Sparklines in a cell.
NOCAPTIONS = 0x0200, /// Internal use only (undo etc.): do not
copy/delete caption objects of cell notes.
ADDNOTES = 0x0400, /// Internal use only (copy from clip): do
not delete existing cell contents when pasting notes.
SPECIAL_BOOLEAN = 0x1000,
FORGETCAPTIONS = 0x2000, /// Internal use only (d&d undo): do not
delete caption objects of cell notes.
ATTRIB = HARDATTR | STYLES,
- CONTENTS = VALUE | DATETIME | STRING | NOTE | FORMULA | OUTLINE,
- ALL = CONTENTS | ATTRIB | OBJECTS,
+ CONTENTS = VALUE | DATETIME | STRING | NOTE | FORMULA | OUTLINE |
SPARKLINES,
+ ALL = CONTENTS | ATTRIB | OBJECTS | SPARKLINES,
/// Copy flags for auto/series fill functions: do not touch notes and
drawing objects.
AUTOFILL = ALL & ~(NOTE | OBJECTS)
};
namespace o3tl
{
- template<> struct typed_flags<InsertDeleteFlags> :
is_typed_flags<InsertDeleteFlags, 0x3fff> {};
+ template<> struct typed_flags<InsertDeleteFlags> :
is_typed_flags<InsertDeleteFlags, 0x7fff> {};
}
// This doesn't work at the moment, perhaps when we have constexpr we can
modify InsertDeleteFlags to make it work.
//static_assert((InsertDeleteFlags::ATTRIB & InsertDeleteFlags::CONTENTS) ==
InsertDeleteFlags::NONE, "these must match");
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index ee669c0a6e6b..72f65d2b72ff 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -142,6 +142,7 @@ typedef mdds::mtv::soa::multi_type_vector<CellFunc,
CellStoreTrait> CellStoreTyp
struct ColumnBlockPosition
{
CellNoteStoreType::iterator miCellNotePos;
+ SparklineStoreType::iterator miSparklinePos;
BroadcasterStoreType::iterator miBroadcasterPos;
CellTextAttrStoreType::iterator miCellTextAttrPos;
CellStoreType::iterator miCellPos;
@@ -152,6 +153,7 @@ struct ColumnBlockPosition
struct ColumnBlockConstPosition
{
CellNoteStoreType::const_iterator miCellNotePos;
+ SparklineStoreType::const_iterator miSparklinePos;
CellTextAttrStoreType::const_iterator miCellTextAttrPos;
CellStoreType::const_iterator miCellPos;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 39cc4736d12d..2393f8ace994 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -477,6 +477,7 @@ public:
sc::Sparkline* GetSparkline(SCCOL nCol, SCROW nRow);
sc::Sparkline* CreateSparkline(SCCOL nCol, SCROW nRow,
std::shared_ptr<sc::SparklineGroup> & pSparklineGroup);
+ bool DeleteSparkline(SCCOL nCol, SCROW nRow);
sc::SparklineList& GetSparklineList();
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index cccd2af0fb34..c7e2dd5d8006 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1979,6 +1979,8 @@ void ScColumn::PrepareBroadcastersForDestruction()
}
}
+// Sparklines
+
sc::SparklineCell* ScColumn::GetSparklineCell(SCROW nRow)
{
return maSparklines.get<sc::SparklineCell*>(nRow);
@@ -1989,6 +1991,22 @@ void ScColumn::CreateSparklineCell(SCROW nRow,
std::shared_ptr<sc::Sparkline> co
maSparklines.set(nRow, new sc::SparklineCell(pSparkline));
}
+void ScColumn::DeleteSparklineCells(sc::ColumnBlockPosition& rBlockPos, SCROW
nRow1, SCROW nRow2)
+{
+ rBlockPos.miSparklinePos =
maSparklines.set_empty(rBlockPos.miSparklinePos, nRow1, nRow2);
+}
+
+bool ScColumn::DeleteSparkline(SCROW nRow)
+{
+ if (!GetDoc().ValidRow(nRow))
+ return false;
+
+ maSparklines.set_empty(nRow, nRow);
+ return true;
+}
+
+// Notes
+
ScPostIt* ScColumn::GetCellNote(SCROW nRow)
{
return maCellNotes.get<ScPostIt*>(nRow);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 793797cb1c79..dc6a68420a6f 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1022,6 +1022,11 @@ void ScColumn::DeleteArea(
DeleteCellNotes(aBlockPos, nStartRow, nEndRow,
bForgetCaptionOwnership);
}
+ if (nDelFlag & InsertDeleteFlags::SPARKLINES)
+ {
+ DeleteSparklineCells(aBlockPos, nStartRow, nEndRow);
+ }
+
if ( nDelFlag & InsertDeleteFlags::EDITATTR )
{
OSL_ENSURE( nContFlag == InsertDeleteFlags::NONE, "DeleteArea: Wrong
Flags" );
@@ -1050,6 +1055,7 @@ void ScColumn::InitBlockPosition(
sc::ColumnBlockPosition& rBlockPos )
rBlockPos.miCellNotePos = maCellNotes.begin();
rBlockPos.miCellTextAttrPos = maCellTextAttrs.begin();
rBlockPos.miCellPos = maCells.begin();
+ rBlockPos.miSparklinePos = maSparklines.begin();
}
void ScColumn::InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos )
const
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index e0b1037c8d3e..03f468520a03 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6529,9 +6529,21 @@ sc::Sparkline* ScDocument::CreateSparkline(ScAddress
const & rPosition, std::sha
return nullptr;
}
+bool ScDocument::DeleteSparkline(ScAddress const & rPosition)
+{
+ SCTAB nTab = rPosition.Tab();
+
+ if (TableExists(nTab))
+ {
+ return maTabs[nTab]->DeleteSparkline(rPosition.Col(), rPosition.Row());
+ }
+
+ return false;
+}
+
sc::SparklineList* ScDocument::GetSparklineList(SCTAB nTab)
{
- if (ValidTab(nTab) && nTab < SCTAB(maTabs.size()))
+ if (TableExists(nTab))
{
return &maTabs[nTab]->GetSparklineList();
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index aa218ee44cec..88f9a4e8ee97 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1839,6 +1839,16 @@ sc::Sparkline* ScTable::CreateSparkline(SCCOL nCol,
SCROW nRow, std::shared_ptr<
return pSparkline.get();
}
+bool ScTable::DeleteSparkline(SCCOL nCol, SCROW nRow)
+{
+ if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())
+ return false;
+
+ aCol[nCol].DeleteSparkline(nRow);
+
+ return true;
+}
+
sc::SparklineList& ScTable::GetSparklineList()
{
return maSparklineList;
commit f8d1bedd8bfc47d9bfc26bf55ceb45d23ece3a0e
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Sat Mar 12 23:30:40 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Mon Mar 14 13:52:32 2022 +0900
sc: SparklineDialog add type, colors and properties
Change-Id: Ie8243985d61cc719fd0444b0e1aaf18f43489d5c
diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx
index f87475559547..ec3a8c8a971f 100644
--- a/sc/inc/SparklineGroup.hxx
+++ b/sc/inc/SparklineGroup.hxx
@@ -76,13 +76,13 @@ public:
SparklineGroup()
: m_aColorSeries(COL_BLUE)
- , m_aColorNegative(COL_TRANSPARENT)
- , m_aColorAxis(COL_TRANSPARENT)
- , m_aColorMarkers(COL_TRANSPARENT)
- , m_aColorFirst(COL_TRANSPARENT)
- , m_aColorLast(COL_TRANSPARENT)
- , m_aColorHigh(COL_TRANSPARENT)
- , m_aColorLow(COL_TRANSPARENT)
+ , m_aColorNegative(COL_RED)
+ , m_aColorAxis(COL_RED)
+ , m_aColorMarkers(COL_RED)
+ , m_aColorFirst(COL_RED)
+ , m_aColorLast(COL_RED)
+ , m_aColorHigh(COL_RED)
+ , m_aColorLow(COL_RED)
, m_eMinAxisType(AxisType::Individual)
, m_eMaxAxisType(AxisType::Individual)
, m_fLineWeight(0.75)
diff --git a/sc/source/ui/dialogs/SparklineDialog.cxx
b/sc/source/ui/dialogs/SparklineDialog.cxx
index 5a167fe8b7c1..fac1d8274be5 100644
--- a/sc/source/ui/dialogs/SparklineDialog.cxx
+++ b/sc/source/ui/dialogs/SparklineDialog.cxx
@@ -12,6 +12,8 @@
#include <Sparkline.hxx>
#include <reffact.hxx>
+#include <svx/colorbox.hxx>
+
namespace sc
{
SparklineDialog::SparklineDialog(SfxBindings* pBindings, SfxChildWindow*
pChildWindow,
@@ -30,6 +32,30 @@ SparklineDialog::SparklineDialog(SfxBindings* pBindings,
SfxChildWindow* pChildW
, mxOutputRangeLabel(m_xBuilder->weld_label("output-range-label"))
, mxOutputRangeEdit(new
formula::RefEdit(m_xBuilder->weld_entry("output-range-edit")))
, mxOutputRangeButton(new
formula::RefButton(m_xBuilder->weld_button("output-range-button")))
+ , mxColorSeries(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-series"),
+ [pWindow] { return pWindow; }))
+ , mxColorNegative(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-negative"),
+ [pWindow] { return pWindow; }))
+ , mxColorMarker(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-marker"),
+ [pWindow] { return pWindow; }))
+ , mxColorHigh(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-high"),
+ [pWindow] { return pWindow; }))
+ , mxColorLow(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-low"),
+ [pWindow] { return pWindow; }))
+ , mxColorFirst(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-first"),
+ [pWindow] { return pWindow; }))
+ , mxColorLast(new
ColorListBox(m_xBuilder->weld_menu_button("color-button-last"),
+ [pWindow] { return pWindow; }))
+ , mxCheckButtonNegative(m_xBuilder->weld_check_button("check-negative"))
+ , mxCheckButtonMarker(m_xBuilder->weld_check_button("check-marker"))
+ , mxCheckButtonHigh(m_xBuilder->weld_check_button("check-high"))
+ , mxCheckButtonLow(m_xBuilder->weld_check_button("check-low"))
+ , mxCheckButtonFirst(m_xBuilder->weld_check_button("check-first"))
+ , mxCheckButtonLast(m_xBuilder->weld_check_button("check-last"))
+ , mxRadioLine(m_xBuilder->weld_radio_button("line-radiobutton"))
+ , mxRadioColumn(m_xBuilder->weld_radio_button("column-radiobutton"))
+ , mxRadioStacked(m_xBuilder->weld_radio_button("stacked-radiobutton"))
+ , mpLocalSparklineGroup(new sc::SparklineGroup())
{
mxInputRangeEdit->SetReferences(this, mxInputRangeText.get());
mxInputRangeButton->SetReferences(this, mxInputRangeEdit.get());
@@ -59,13 +85,60 @@ SparklineDialog::SparklineDialog(SfxBindings* pBindings,
SfxChildWindow* pChildW
mxInputRangeEdit->SetModifyHdl(aModifyLink);
mxOutputRangeEdit->SetModifyHdl(aModifyLink);
- mxOutputRangeEdit->GrabFocus();
+ Link<weld::Toggleable&, void> aRadioButtonLink
+ = LINK(this, SparklineDialog, SelectSparklineType);
+ mxRadioLine->connect_toggled(aRadioButtonLink);
+ mxRadioColumn->connect_toggled(aRadioButtonLink);
+ mxRadioStacked->connect_toggled(aRadioButtonLink);
+
+ Link<weld::Toggleable&, void> aLink = LINK(this, SparklineDialog,
ToggleHandler);
+ mxCheckButtonNegative->connect_toggled(aLink);
+ mxCheckButtonMarker->connect_toggled(aLink);
+ mxCheckButtonHigh->connect_toggled(aLink);
+ mxCheckButtonLow->connect_toggled(aLink);
+ mxCheckButtonFirst->connect_toggled(aLink);
+ mxCheckButtonLast->connect_toggled(aLink);
+
+ setupValues(mpLocalSparklineGroup);
GetRangeFromSelection();
+
+ mxOutputRangeEdit->GrabFocus();
}
SparklineDialog::~SparklineDialog() {}
+void SparklineDialog::setupValues(std::shared_ptr<sc::SparklineGroup> const&
pSparklineGroup)
+{
+ switch (pSparklineGroup->m_eType)
+ {
+ case sc::SparklineType::Line:
+ mxRadioLine->set_active(true);
+ break;
+ case sc::SparklineType::Column:
+ mxRadioColumn->set_active(true);
+ break;
+ case sc::SparklineType::Stacked:
+ mxRadioStacked->set_active(true);
+ break;
+ }
+
+ mxColorSeries->SelectEntry(pSparklineGroup->m_aColorSeries);
+ mxColorNegative->SelectEntry(pSparklineGroup->m_aColorNegative);
+ mxColorMarker->SelectEntry(pSparklineGroup->m_aColorMarkers);
+ mxColorHigh->SelectEntry(pSparklineGroup->m_aColorHigh);
+ mxColorLow->SelectEntry(pSparklineGroup->m_aColorLow);
+ mxColorFirst->SelectEntry(pSparklineGroup->m_aColorFirst);
+ mxColorLast->SelectEntry(pSparklineGroup->m_aColorLast);
+
+ mxCheckButtonNegative->set_active(pSparklineGroup->m_bNegative);
+ mxCheckButtonMarker->set_active(pSparklineGroup->m_bMarkers);
+ mxCheckButtonHigh->set_active(pSparklineGroup->m_bHigh);
+ mxCheckButtonLow->set_active(pSparklineGroup->m_bLow);
+ mxCheckButtonFirst->set_active(pSparklineGroup->m_bFirst);
+ mxCheckButtonLast->set_active(pSparklineGroup->m_bLast);
+}
+
void SparklineDialog::Close() {
DoClose(sc::SparklineDialogWrapper::GetChildWindowId()); }
void SparklineDialog::SetActive()
@@ -211,6 +284,32 @@ IMPL_LINK(SparklineDialog, ButtonClicked, weld::Button&,
rButton, void)
}
}
+IMPL_LINK(SparklineDialog, ToggleHandler, weld::Toggleable&, rToggle, void)
+{
+ if (mxCheckButtonNegative.get() == &rToggle)
+ mpLocalSparklineGroup->m_bNegative =
mxCheckButtonNegative->get_active();
+ if (mxCheckButtonMarker.get() == &rToggle)
+ mpLocalSparklineGroup->m_bMarkers = mxCheckButtonMarker->get_active();
+ if (mxCheckButtonHigh.get() == &rToggle)
+ mpLocalSparklineGroup->m_bHigh = mxCheckButtonHigh->get_active();
+ if (mxCheckButtonLow.get() == &rToggle)
+ mpLocalSparklineGroup->m_bLow = mxCheckButtonLow->get_active();
+ if (mxCheckButtonFirst.get() == &rToggle)
+ mpLocalSparklineGroup->m_bFirst = mxCheckButtonFirst->get_active();
+ if (mxCheckButtonLast.get() == &rToggle)
+ mpLocalSparklineGroup->m_bLast = mxCheckButtonLast->get_active();
+}
+
+IMPL_LINK_NOARG(SparklineDialog, SelectSparklineType, weld::Toggleable&, void)
+{
+ if (mxRadioLine->get_active())
+ mpLocalSparklineGroup->m_eType = sc::SparklineType::Line;
+ else if (mxRadioColumn->get_active())
+ mpLocalSparklineGroup->m_eType = sc::SparklineType::Column;
+ else if (mxRadioStacked->get_active())
+ mpLocalSparklineGroup->m_eType = sc::SparklineType::Stacked;
+}
+
namespace
{
enum class RangeOrientation
@@ -257,7 +356,13 @@ bool SparklineDialog::checkValidInputOutput()
void SparklineDialog::perform()
{
- auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+ mpLocalSparklineGroup->m_aColorSeries =
mxColorSeries->GetSelectEntryColor();
+ mpLocalSparklineGroup->m_aColorNegative =
mxColorNegative->GetSelectEntryColor();
+ mpLocalSparklineGroup->m_aColorMarkers =
mxColorMarker->GetSelectEntryColor();
+ mpLocalSparklineGroup->m_aColorHigh = mxColorHigh->GetSelectEntryColor();
+ mpLocalSparklineGroup->m_aColorLow = mxColorLow->GetSelectEntryColor();
+ mpLocalSparklineGroup->m_aColorFirst = mxColorFirst->GetSelectEntryColor();
+ mpLocalSparklineGroup->m_aColorLast = mxColorLast->GetSelectEntryColor();
if (maOutputRange.aStart.Col() == maOutputRange.aEnd.Col())
{
@@ -283,7 +388,7 @@ void SparklineDialog::perform()
aInputRangeSlice.aStart.SetCol(maInputRange.aStart.Col() +
nIndex);
aInputRangeSlice.aEnd.SetCol(maInputRange.aStart.Col() +
nIndex);
}
- auto* pCreated = mrDocument.CreateSparkline(aAddress,
pSparklineGroup);
+ auto* pCreated = mrDocument.CreateSparkline(aAddress,
mpLocalSparklineGroup);
pCreated->setInputRange(aInputRangeSlice);
nIndex++;
}
@@ -313,7 +418,7 @@ void SparklineDialog::perform()
aInputRangeSlice.aStart.SetCol(maInputRange.aStart.Col() +
nIndex);
aInputRangeSlice.aEnd.SetCol(maInputRange.aStart.Col() +
nIndex);
}
- auto* pCreated = mrDocument.CreateSparkline(aAddress,
pSparklineGroup);
+ auto* pCreated = mrDocument.CreateSparkline(aAddress,
mpLocalSparklineGroup);
pCreated->setInputRange(aInputRangeSlice);
nIndex++;
}
diff --git a/sc/source/ui/inc/SparklineDialog.hxx
b/sc/source/ui/inc/SparklineDialog.hxx
index a4a03f33491d..1fe2616a4c59 100644
--- a/sc/source/ui/inc/SparklineDialog.hxx
+++ b/sc/source/ui/inc/SparklineDialog.hxx
@@ -13,6 +13,8 @@
#include "anyrefdg.hxx"
#include <viewdata.hxx>
+class ColorListBox;
+
namespace sc
{
class SparklineDialog : public ScAnyRefDlgController
@@ -38,6 +40,25 @@ private:
std::unique_ptr<formula::RefEdit> mxOutputRangeEdit;
std::unique_ptr<formula::RefButton> mxOutputRangeButton;
+ std::unique_ptr<ColorListBox> mxColorSeries;
+ std::unique_ptr<ColorListBox> mxColorNegative;
+ std::unique_ptr<ColorListBox> mxColorMarker;
+ std::unique_ptr<ColorListBox> mxColorHigh;
+ std::unique_ptr<ColorListBox> mxColorLow;
+ std::unique_ptr<ColorListBox> mxColorFirst;
+ std::unique_ptr<ColorListBox> mxColorLast;
+
+ std::unique_ptr<weld::CheckButton> mxCheckButtonNegative;
+ std::unique_ptr<weld::CheckButton> mxCheckButtonMarker;
+ std::unique_ptr<weld::CheckButton> mxCheckButtonHigh;
+ std::unique_ptr<weld::CheckButton> mxCheckButtonLow;
+ std::unique_ptr<weld::CheckButton> mxCheckButtonFirst;
+ std::unique_ptr<weld::CheckButton> mxCheckButtonLast;
+
+ std::unique_ptr<weld::RadioButton> mxRadioLine;
+ std::unique_ptr<weld::RadioButton> mxRadioColumn;
+ std::unique_ptr<weld::RadioButton> mxRadioStacked;
+
void GetRangeFromSelection();
DECL_LINK(ButtonClicked, weld::Button&, void);
@@ -46,7 +67,12 @@ private:
DECL_LINK(LoseEditFocusHandler, formula::RefEdit&, void);
DECL_LINK(LoseButtonFocusHandler, formula::RefButton&, void);
DECL_LINK(RefInputModifyHandler, formula::RefEdit&, void);
+ DECL_LINK(ToggleHandler, weld::Toggleable&, void);
+ DECL_LINK(SelectSparklineType, weld::Toggleable&, void);
+
+ std::shared_ptr<sc::SparklineGroup> mpLocalSparklineGroup;
+ void setupValues(std::shared_ptr<sc::SparklineGroup> const&
pSparklineGroup);
void perform();
bool checkValidInputOutput();
diff --git a/sc/uiconfig/scalc/ui/sparklinedialog.ui
b/sc/uiconfig/scalc/ui/sparklinedialog.ui
index 9070ce2cd86e..8c2119ca2c63 100644
--- a/sc/uiconfig/scalc/ui/sparklinedialog.ui
+++ b/sc/uiconfig/scalc/ui/sparklinedialog.ui
@@ -70,7 +70,7 @@
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
- <property name="position">0</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -84,10 +84,10 @@
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="margin-start">6</property>
+ <property name="margin-start">12</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
- <property name="margin-bottom">7</property>
+ <property name="margin-bottom">6</property>
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<child>
@@ -201,10 +201,501 @@
</object>
</child>
<child type="label">
- <object class="GtkLabel" id="label1">
+ <object class="GtkLabel" id="label-data">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes"
context="SparklineDialog|label-data">Data</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame-properties">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=6 n-rows=5 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <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">
+ <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>
+ <child>
+ <placeholder/>
+ </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/>
+ </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/>
+ </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/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="label-high"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">2</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">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/>
+ </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/>
+ </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/>
+ </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/>
+ </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/>
+ </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/>
+ </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/>
+ </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/>
+ </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>
+ </packing>
+ </child>
+ <child>
+ <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="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <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>
+ <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">0</property>
+ </packing>
+ </child>
+ <child>
+ <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">1</property>
+ </packing>
+ </child>
+ <child>
+ <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">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="width">5</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label-properties">
<property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label" translatable="yes"
context="randomnumbergenerator|label1">Data</property>
+ <property name="label" translatable="yes"
context="SparklineDialog|label-properties">Properties</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
commit f799202447a4206da495a693a0521f7ae2053332
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Fri Mar 11 20:49:09 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Mon Mar 14 13:52:31 2022 +0900
sc: SparklineDialog and "Insert Sparkline" to context menu
This adds a SparklineDialog, which is used to add/edit the
Sparkline input/output ranges. The command for the context menu
"Insert Sparkline" calls the SparklineDialog for inserting a new
sparkline into cells. Currently the SparklineDialog include the
properties for the SparklineGroup, which will be added in a later
commit.
Change-Id: I9036d788fdf2a035f1ce10fc7413327a92144137
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
index c7bfe5e55577..0d539ab76b68 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
@@ -1074,6 +1074,14 @@
<value>1</value>
</prop>
</node>
+ <node oor:name=".uno:InsertSparkline" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="en-US">Insert Sparkline...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
<node oor:name=".uno:EditHeaderAndFooter" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">~Headers and Footers...</value>
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 62ab22a797c4..f145d3a7fbf2 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -418,6 +418,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/dbgui/sfiltdlg \
sc/source/ui/dbgui/validate \
sc/source/ui/dialogs/searchresults \
+ sc/source/ui/dialogs/SparklineDialog \
sc/source/ui/docshell/arealink \
sc/source/ui/docshell/autostyl \
sc/source/ui/docshell/datastream \
diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index bc320cc44fd7..302f08ff3fb3 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -244,6 +244,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
sc/uiconfig/scalc/ui/sortkey \
sc/uiconfig/scalc/ui/sortoptionspage \
sc/uiconfig/scalc/ui/sortwarning \
+ sc/uiconfig/scalc/ui/sparklinedialog \
sc/uiconfig/scalc/ui/splitcolumnentry \
sc/uiconfig/scalc/ui/subtotaldialog \
sc/uiconfig/scalc/ui/subtotaloptionspage \
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index f391e618357b..b9dc48169235 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -238,6 +238,8 @@ class SvxZoomSliderItem;
#define SID_COLUMN_OPERATIONS (SC_MESSAGE_START + 86)
#define SID_ROW_OPERATIONS (SC_MESSAGE_START + 87)
#define SID_FOURIER_ANALYSIS_DIALOG (SC_MESSAGE_START + 88)
+#define SID_SPARKLINE_DIALOG (SC_MESSAGE_START + 89)
+
// functions
@@ -306,7 +308,8 @@ class SvxZoomSliderItem;
#define FID_INS_ROWS_BEFORE (INSERT_MENU_START + 22)
#define FID_INS_COLUMNS_BEFORE (INSERT_MENU_START + 23)
#define FID_DEFINE_CURRENT_NAME (INSERT_MENU_START + 24)
-#define INSERT_MENU_END (INSERT_MENU_START + 25)
+#define SID_INSERT_SPARKLINE (INSERT_MENU_START + 25)
+#define INSERT_MENU_END (INSERT_MENU_START + 26)
#define FORMAT_MENU_START (INSERT_MENU_END)
#define FID_CELL_FORMAT (FORMAT_MENU_START)
diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index c9eed43d665b..8feaf0c590e0 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -235,6 +235,7 @@ interface CellSelection
SID_SELECT_VISIBLE_ROWS [ ExecMethod = ExecuteEdit;]
SID_SELECT_VISIBLE_COLUMNS [ ExecMethod = ExecuteEdit;]
SID_CURRENT_FORMULA_RANGE [ ExecMethod = ExecuteEdit;]
+ SID_INSERT_SPARKLINE [ ExecMethod = ExecuteEdit;
StateMethod = GetBlockState; ]
SID_THESAURUS [ ExecMethod = ExecuteEdit; StateMethod = GetCellState; ]
SID_SPELL_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index 8457654946fd..4a8d8747cc14 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -2287,6 +2287,23 @@ SfxVoidItem SolverDialog SID_OPENDLG_OPTSOLVER
GroupId = SfxGroupId::Options;
]
+SfxVoidItem InsertSparkline SID_INSERT_SPARKLINE
+()
+[
+ AutoUpdate = FALSE,
+ FastCall = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ ToolBoxConfig = TRUE,
+ GroupId = SfxGroupId::Insert;
+]
+
SfxVoidItem SearchResultsDialog SID_SEARCH_RESULTS_DIALOG
(SfxBoolItem Visible SID_SEARCH_RESULTS_DIALOG)
[
diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx
index b7f58002f71b..a0bdf08b16c0 100644
--- a/sc/source/ui/app/scdll.cxx
+++ b/sc/source/ui/app/scdll.cxx
@@ -206,6 +206,7 @@ void ScDLL::Init()
ScZTestDialogWrapper ::RegisterChildWindow(false, pMod);
ScChiSquareTestDialogWrapper ::RegisterChildWindow(false, pMod);
ScFourierAnalysisDialogWrapper ::RegisterChildWindow(false, pMod);
+ sc::SparklineDialogWrapper ::RegisterChildWindow(false, pMod);
// Redlining Window
ScAcceptChgDlgWrapper ::RegisterChildWindow(false, pMod);
diff --git a/sc/source/ui/dialogs/SparklineDialog.cxx
b/sc/source/ui/dialogs/SparklineDialog.cxx
new file mode 100644
index 000000000000..5a167fe8b7c1
--- /dev/null
+++ b/sc/source/ui/dialogs/SparklineDialog.cxx
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SparklineDialog.hxx>
+#include <SparklineGroup.hxx>
+#include <Sparkline.hxx>
+#include <reffact.hxx>
+
+namespace sc
+{
+SparklineDialog::SparklineDialog(SfxBindings* pBindings, SfxChildWindow*
pChildWindow,
+ weld::Window* pWindow, ScViewData& rViewData)
+ : ScAnyRefDlgController(pBindings, pChildWindow, pWindow,
+ u"modules/scalc/ui/sparklinedialog.ui",
"SparklineDialog")
+ , mrViewData(rViewData)
+ , mrDocument(rViewData.GetDocument())
+ , mpActiveEdit(nullptr)
+ , mbDialogLostFocus(false)
+ , mxButtonOk(m_xBuilder->weld_button("ok"))
+ , mxButtonCancel(m_xBuilder->weld_button("cancel"))
+ , mxInputRangeText(m_xBuilder->weld_label("cell-range-label"))
+ , mxInputRangeEdit(new
formula::RefEdit(m_xBuilder->weld_entry("cell-range-edit")))
+ , mxInputRangeButton(new
formula::RefButton(m_xBuilder->weld_button("cell-range-button")))
+ , mxOutputRangeLabel(m_xBuilder->weld_label("output-range-label"))
+ , mxOutputRangeEdit(new
formula::RefEdit(m_xBuilder->weld_entry("output-range-edit")))
+ , mxOutputRangeButton(new
formula::RefButton(m_xBuilder->weld_button("output-range-button")))
+{
+ mxInputRangeEdit->SetReferences(this, mxInputRangeText.get());
+ mxInputRangeButton->SetReferences(this, mxInputRangeEdit.get());
+
+ mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get());
+ mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get());
+
+ mxButtonCancel->connect_clicked(LINK(this, SparklineDialog,
ButtonClicked));
+ mxButtonOk->connect_clicked(LINK(this, SparklineDialog, ButtonClicked));
+ mxButtonOk->set_sensitive(false);
+
+ Link<formula::RefEdit&, void> aEditLink = LINK(this, SparklineDialog,
EditFocusHandler);
+ mxInputRangeEdit->SetGetFocusHdl(aEditLink);
+ mxOutputRangeEdit->SetGetFocusHdl(aEditLink);
+ aEditLink = LINK(this, SparklineDialog, LoseEditFocusHandler);
+ mxInputRangeEdit->SetLoseFocusHdl(aEditLink);
+ mxOutputRangeEdit->SetLoseFocusHdl(aEditLink);
+
+ Link<formula::RefButton&, void> aButtonLink = LINK(this, SparklineDialog,
ButtonFocusHandler);
+ mxInputRangeButton->SetGetFocusHdl(aButtonLink);
+ mxOutputRangeButton->SetGetFocusHdl(aButtonLink);
+ aButtonLink = LINK(this, SparklineDialog, LoseButtonFocusHandler);
+ mxInputRangeButton->SetLoseFocusHdl(aButtonLink);
+ mxOutputRangeButton->SetLoseFocusHdl(aButtonLink);
+
+ Link<formula::RefEdit&, void> aModifyLink = LINK(this, SparklineDialog,
RefInputModifyHandler);
+ mxInputRangeEdit->SetModifyHdl(aModifyLink);
+ mxOutputRangeEdit->SetModifyHdl(aModifyLink);
+
+ mxOutputRangeEdit->GrabFocus();
+
+ GetRangeFromSelection();
+}
+
+SparklineDialog::~SparklineDialog() {}
+
+void SparklineDialog::Close() {
DoClose(sc::SparklineDialogWrapper::GetChildWindowId()); }
+
+void SparklineDialog::SetActive()
+{
+ if (mbDialogLostFocus)
+ {
+ mbDialogLostFocus = false;
+ if (mpActiveEdit)
+ mpActiveEdit->GrabFocus();
+ }
+ else
+ {
+ m_xDialog->grab_focus();
+ }
+ RefInputDone();
+}
+
+void SparklineDialog::GetRangeFromSelection()
+{
+ mrViewData.GetSimpleArea(maInputRange);
+ OUString aString = maInputRange.Format(mrDocument, ScRefFlags::VALID |
ScRefFlags::TAB_3D,
+ mrDocument.GetAddressConvention());
+ mxInputRangeEdit->SetRefString(aString);
+}
+
+void SparklineDialog::SetReference(const ScRange& rReferenceRange, ScDocument&
rDocument)
+{
+ if (mpActiveEdit)
+ {
+ if (rReferenceRange.aStart != rReferenceRange.aEnd)
+ RefInputStart(mpActiveEdit);
+
+ OUString aString;
+ const ScRefFlags eFlags = ScRefFlags::VALID | ScRefFlags::TAB_3D;
+ auto eAddressConvention = rDocument.GetAddressConvention();
+
+ if (mpActiveEdit == mxInputRangeEdit.get())
+ {
+ maInputRange = rReferenceRange;
+ aString = maInputRange.Format(rDocument, eFlags,
eAddressConvention);
+ mxInputRangeEdit->SetRefString(aString);
+ }
+ else if (mpActiveEdit == mxOutputRangeEdit.get())
+ {
+ maOutputRange = rReferenceRange;
+ aString = maOutputRange.Format(rDocument, eFlags,
eAddressConvention);
+ mxOutputRangeEdit->SetRefString(aString);
+ }
+ }
+
+ mxButtonOk->set_sensitive(checkValidInputOutput());
+}
+
+IMPL_LINK(SparklineDialog, EditFocusHandler, formula::RefEdit&, rEdit, void)
+{
+ auto* pEdit = &rEdit;
+
+ if (mxInputRangeEdit.get() == pEdit)
+ mpActiveEdit = mxInputRangeEdit.get();
+ else if (mxOutputRangeEdit.get() == pEdit)
+ mpActiveEdit = mxOutputRangeEdit.get();
+ else
+ mpActiveEdit = nullptr;
+
+ if (mpActiveEdit)
+ mpActiveEdit->SelectAll();
+}
+
+IMPL_LINK(SparklineDialog, ButtonFocusHandler, formula::RefButton&, rButton,
void)
+{
+ auto* pButton = &rButton;
+
+ if (mxInputRangeButton.get() == pButton)
+ mpActiveEdit = mxInputRangeEdit.get();
+ else if (mxOutputRangeButton.get() == pButton)
+ mpActiveEdit = mxOutputRangeEdit.get();
+ else
+ mpActiveEdit = nullptr;
+
+ if (mpActiveEdit)
+ mpActiveEdit->SelectAll();
+}
+
+IMPL_LINK_NOARG(SparklineDialog, LoseEditFocusHandler, formula::RefEdit&, void)
+{
+ mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
+}
+
+IMPL_LINK_NOARG(SparklineDialog, LoseButtonFocusHandler, formula::RefButton&,
void)
+{
+ mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
+}
+
+IMPL_LINK_NOARG(SparklineDialog, RefInputModifyHandler, formula::RefEdit&,
void)
+{
+ if (mpActiveEdit)
+ {
+ if (mpActiveEdit == mxInputRangeEdit.get())
+ {
+ ScRangeList aRangeList;
+ bool bValid = ParseWithNames(aRangeList,
mxInputRangeEdit->GetText(), mrDocument);
+ const ScRange* pRange = (bValid && aRangeList.size() == 1) ?
&aRangeList[0] : nullptr;
+ if (pRange)
+ {
+ maInputRange = *pRange;
+ mxInputRangeEdit->StartUpdateData();
+ }
+ else
+ {
+ maInputRange = ScRange(ScAddress::INITIALIZE_INVALID);
+ }
+ }
+ else if (mpActiveEdit == mxOutputRangeEdit.get())
+ {
+ ScRangeList aRangeList;
+ bool bValid = ParseWithNames(aRangeList,
mxOutputRangeEdit->GetText(), mrDocument);
+ const ScRange* pRange = (bValid && aRangeList.size() == 1) ?
&aRangeList[0] : nullptr;
+ if (pRange)
+ {
+ maOutputRange = *pRange;
+ mxOutputRangeEdit->StartUpdateData();
+ }
+ else
+ {
+ maOutputRange = ScRange(ScAddress::INITIALIZE_INVALID);
+ }
+ }
+ }
+
+ mxButtonOk->set_sensitive(checkValidInputOutput());
+}
+
+IMPL_LINK(SparklineDialog, ButtonClicked, weld::Button&, rButton, void)
+{
+ if (mxButtonOk.get() == &rButton)
+ {
+ perform();
+ response(RET_OK);
+ }
+ else
+ {
+ response(RET_CANCEL);
+ }
+}
+
+namespace
+{
+enum class RangeOrientation
+{
+ Unknown,
+ Row,
+ Col
+};
+
+RangeOrientation calculateOrientation(sal_Int32 nOutputSize, ScRange const&
rInputRange)
+{
+ sal_Int32 nRowSize = rInputRange.aEnd.Row() - rInputRange.aStart.Row();
+ sal_Int32 nColSize = rInputRange.aEnd.Col() - rInputRange.aStart.Col();
+
+ auto eInputOrientation = RangeOrientation::Unknown;
+ if (nOutputSize == nRowSize)
+ eInputOrientation = RangeOrientation::Row;
+ else if (nOutputSize == nColSize)
+ eInputOrientation = RangeOrientation::Col;
+ return eInputOrientation;
+}
+
+} // end anonymous namespace
+
+bool SparklineDialog::checkValidInputOutput()
+{
+ if (!maInputRange.IsValid() || !maOutputRange.IsValid())
+ return false;
+
+ RangeOrientation eInputOrientation = RangeOrientation::Unknown;
+ if (maOutputRange.aStart.Col() == maOutputRange.aEnd.Col())
+ {
+ sal_Int32 nOutputRowSize = maOutputRange.aEnd.Row() -
maOutputRange.aStart.Row();
+ eInputOrientation = calculateOrientation(nOutputRowSize, maInputRange);
+ }
+ else if (maOutputRange.aStart.Row() == maOutputRange.aEnd.Row())
+ {
+ sal_Int32 nOutputColSize = maOutputRange.aEnd.Col() -
maOutputRange.aStart.Col();
+ eInputOrientation = calculateOrientation(nOutputColSize, maInputRange);
+ }
+
+ return eInputOrientation != RangeOrientation::Unknown;
+}
+
+void SparklineDialog::perform()
+{
+ auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+
+ if (maOutputRange.aStart.Col() == maOutputRange.aEnd.Col())
+ {
+ sal_Int32 nOutputRowSize = maOutputRange.aEnd.Row() -
maOutputRange.aStart.Row();
+
+ auto eInputOrientation = calculateOrientation(nOutputRowSize,
maInputRange);
+
+ if (eInputOrientation == RangeOrientation::Unknown)
+ return;
+
+ sal_Int32 nIndex = 0;
+ for (ScAddress aAddress = maOutputRange.aStart; aAddress.Row() <=
maOutputRange.aEnd.Row();
+ aAddress.IncRow())
+ {
+ ScRange aInputRangeSlice = maInputRange;
+ if (eInputOrientation == RangeOrientation::Row)
+ {
+ aInputRangeSlice.aStart.SetRow(maInputRange.aStart.Row() +
nIndex);
+ aInputRangeSlice.aEnd.SetRow(maInputRange.aStart.Row() +
nIndex);
+ }
+ else
+ {
+ aInputRangeSlice.aStart.SetCol(maInputRange.aStart.Col() +
nIndex);
+ aInputRangeSlice.aEnd.SetCol(maInputRange.aStart.Col() +
nIndex);
+ }
+ auto* pCreated = mrDocument.CreateSparkline(aAddress,
pSparklineGroup);
+ pCreated->setInputRange(aInputRangeSlice);
+ nIndex++;
+ }
+ }
+ else if (maOutputRange.aStart.Row() == maOutputRange.aEnd.Row())
+ {
+ sal_Int32 nOutputColSize = maOutputRange.aEnd.Col() -
maOutputRange.aStart.Col();
+
+ auto eInputOrientation = calculateOrientation(nOutputColSize,
maInputRange);
+
+ if (eInputOrientation == RangeOrientation::Unknown)
+ return;
+
+ sal_Int32 nIndex = 0;
+
+ for (ScAddress aAddress = maOutputRange.aStart; aAddress.Col() <=
maOutputRange.aEnd.Col();
+ aAddress.IncCol())
+ {
+ ScRange aInputRangeSlice = maInputRange;
+ if (eInputOrientation == RangeOrientation::Row)
+ {
+ aInputRangeSlice.aStart.SetRow(maInputRange.aStart.Row() +
nIndex);
+ aInputRangeSlice.aEnd.SetRow(maInputRange.aStart.Row() +
nIndex);
+ }
+ else
+ {
+ aInputRangeSlice.aStart.SetCol(maInputRange.aStart.Col() +
nIndex);
+ aInputRangeSlice.aEnd.SetCol(maInputRange.aStart.Col() +
nIndex);
+ }
+ auto* pCreated = mrDocument.CreateSparkline(aAddress,
pSparklineGroup);
+ pCreated->setInputRange(aInputRangeSlice);
+ nIndex++;
+ }
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/SparklineDialog.hxx
b/sc/source/ui/inc/SparklineDialog.hxx
new file mode 100644
index 000000000000..a4a03f33491d
--- /dev/null
+++ b/sc/source/ui/inc/SparklineDialog.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <address.hxx>
+#include "anyrefdg.hxx"
+#include <viewdata.hxx>
+
+namespace sc
+{
+class SparklineDialog : public ScAnyRefDlgController
+{
+private:
+ ScViewData& mrViewData;
+ ScDocument& mrDocument;
+
+ ScRange maInputRange;
+ ScRange maOutputRange;
+
+ formula::RefEdit* mpActiveEdit;
+ bool mbDialogLostFocus;
+
+ std::unique_ptr<weld::Button> mxButtonOk;
+ std::unique_ptr<weld::Button> mxButtonCancel;
+
+ std::unique_ptr<weld::Label> mxInputRangeText;
+ std::unique_ptr<formula::RefEdit> mxInputRangeEdit;
+ std::unique_ptr<formula::RefButton> mxInputRangeButton;
+
+ std::unique_ptr<weld::Label> mxOutputRangeLabel;
+ std::unique_ptr<formula::RefEdit> mxOutputRangeEdit;
+ std::unique_ptr<formula::RefButton> mxOutputRangeButton;
+
+ void GetRangeFromSelection();
+
+ DECL_LINK(ButtonClicked, weld::Button&, void);
+ DECL_LINK(EditFocusHandler, formula::RefEdit&, void);
+ DECL_LINK(ButtonFocusHandler, formula::RefButton&, void);
+ DECL_LINK(LoseEditFocusHandler, formula::RefEdit&, void);
+ DECL_LINK(LoseButtonFocusHandler, formula::RefButton&, void);
+ DECL_LINK(RefInputModifyHandler, formula::RefEdit&, void);
+
+ void perform();
+ bool checkValidInputOutput();
+
+public:
+ SparklineDialog(SfxBindings* pBindings, SfxChildWindow* pChildWindow,
weld::Window* pWindow,
+ ScViewData& rViewData);
+ virtual ~SparklineDialog() override;
+
+ virtual void SetReference(const ScRange& rRef, ScDocument& rDocument)
override;
+ virtual void SetActive() override;
+ virtual void Close() override;
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/reffact.hxx b/sc/source/ui/inc/reffact.hxx
index c1b73606eb7f..4bf1254b4556 100644
--- a/sc/source/ui/inc/reffact.hxx
+++ b/sc/source/ui/inc/reffact.hxx
@@ -147,6 +147,18 @@ private:
ScFourierAnalysisDialogWrapper() = delete;
};
+namespace sc
+{
+
+class SparklineDialogWrapper :
+ public ChildControllerWrapper<SID_SPARKLINE_DIALOG>
+{
+private:
+ SparklineDialogWrapper() = delete;
+};
+
+}
+
class ScAcceptChgDlgWrapper : public SfxChildWindow
{
public:
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 1a5f697a0a99..13d4430a956a 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -179,6 +179,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
case SID_ANALYSIS_OF_VARIANCE_DIALOG:
case SID_CORRELATION_DIALOG:
case SID_COVARIANCE_DIALOG:
+ case SID_INSERT_SPARKLINE:
{
bDisable = !bSimpleArea;
}
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 7314ee15413c..44c640eb8aed 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1051,6 +1051,15 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
}
break;
+ case SID_INSERT_SPARKLINE:
+ {
+ sal_uInt16 nId = sc::SparklineDialogWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWindow = pViewFrame->GetChildWindow(nId);
+ pScMod->SetRefDialog(nId, pWindow == nullptr);
+ }
+ break;
+
// disposal (Outlines)
// SID_AUTO_OUTLINE, SID_OUTLINE_DELETEALL in Execute (in docsh.idl)
diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx
index d8e48596f3f6..7337b5cc2f0d 100644
--- a/sc/source/ui/view/tabvwsh.cxx
+++ b/sc/source/ui/view/tabvwsh.cxx
@@ -97,6 +97,7 @@ void ScTabViewShell::InitInterface_Impl()
GetStaticInterface()->RegisterChildWindow(ScChiSquareTestDialogWrapper::GetChildWindowId());
GetStaticInterface()->RegisterChildWindow(ScFourierAnalysisDialogWrapper::GetChildWindowId());
GetStaticInterface()->RegisterChildWindow(ScCondFormatDlgWrapper::GetChildWindowId());
+
GetStaticInterface()->RegisterChildWindow(sc::SparklineDialogWrapper::GetChildWindowId());
}
SFX_IMPL_NAMED_VIEWFACTORY( ScTabViewShell, "Default" )
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index e43cb2ff31bc..667992e57da9 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -69,6 +69,7 @@
#include <FourierAnalysisDialog.hxx>
#include <PivotLayoutDialog.hxx>
+#include <SparklineDialog.hxx>
#include <comphelper/lok.hxx>
#include <o3tl/make_shared.hxx>
@@ -236,6 +237,11 @@ std::shared_ptr<SfxModelessDialogController>
ScTabViewShell::CreateRefDialogCont
case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
xResult = std::make_shared<ScRandomNumberGeneratorDialog>(pB, pCW,
pParent, GetViewData());
break;
+ case SID_SPARKLINE_DIALOG:
+ {
+ xResult = std::make_shared<sc::SparklineDialog>(pB, pCW, pParent,
GetViewData());
+ break;
+ }
case SID_DEFINE_DBNAME:
{
// when called for an existing range, then mark
diff --git a/sc/uiconfig/scalc/popupmenu/cell.xml
b/sc/uiconfig/scalc/popupmenu/cell.xml
index fd086d0af975..135cfb2e742e 100644
--- a/sc/uiconfig/scalc/popupmenu/cell.xml
+++ b/sc/uiconfig/scalc/popupmenu/cell.xml
@@ -63,6 +63,8 @@
<menu:menuitem menu:id=".uno:ShowNote"/>
<menu:menuitem menu:id=".uno:HideNote"/>
<menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:InsertSparkline"/>
+ <menu:menuseparator/>
<menu:menuitem menu:id=".uno:CurrentConditionalFormatDialog"/>
<menu:menuitem menu:id=".uno:CurrentConditionalFormatManagerDialog"/>
<menu:menuitem menu:id=".uno:FormatCellDialog"/>
diff --git a/sc/uiconfig/scalc/ui/sparklinedialog.ui
b/sc/uiconfig/scalc/ui/sparklinedialog.ui
new file mode 100644
index 000000000000..9070ce2cd86e
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/sparklinedialog.ui
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="sc">
+ <requires lib="gtk+" version="3.20"/>
+ <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="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes"
context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes"
context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes"
context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame-data">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=3 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">7</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkButton" id="cell-range-button">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="cell-range-label"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="cell-range-edit">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="width-chars">30</property>
+ <property name="truncate-multiline">True</property>
+ <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>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="output-range-button">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <accessibility>
+ <relation type="labelled-by"
target="output-range-label"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="output-range-edit">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="width-chars">30</property>
+ <property name="truncate-multiline">True</property>
+ <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>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <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="use-underline">True</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="cell-range-button"/>
+ <relation type="label-for" target="cell-range-edit"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <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="use-underline">True</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="output-range-button"/>
+ <relation type="label-for" target="output-range-edit"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes"
context="randomnumbergenerator|label1">Data</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <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>
+</interface>
commit 77411e89cfa7667db3ead3bf81b3c01957254805
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Mar 10 14:08:35 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Mon Mar 14 13:52:31 2022 +0900
sc: simple unit test for adding a new Sparkline to a new document
Change-Id: Ifb42167300dadd0e6c48bf178b7e8902985db3d1
diff --git a/sc/CppunitTest_sc_sparkline_test.mk
b/sc/CppunitTest_sc_sparkline_test.mk
index 30513b273791..499eaaf4ea38 100644
--- a/sc/CppunitTest_sc_sparkline_test.mk
+++ b/sc/CppunitTest_sc_sparkline_test.mk
@@ -15,6 +15,7 @@ $(eval $(call
gb_CppunitTest_use_common_precompiled_header,sc_sparkline_test))
$(eval $(call gb_CppunitTest_add_exception_objects,sc_sparkline_test, \
sc/qa/unit/SparklineImportExportTest \
+ sc/qa/unit/SparklineTest \
))
$(eval $(call gb_CppunitTest_use_libraries,sc_sparkline_test, \
diff --git a/sc/qa/unit/SparklineTest.cxx b/sc/qa/unit/SparklineTest.cxx
new file mode 100644
index 000000000000..d4a8d2d119a8
--- /dev/null
+++ b/sc/qa/unit/SparklineTest.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "helper/qahelper.hxx"
+#include <docsh.hxx>
+#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
+
+using namespace css;
+
+class SparklineTest : public ScBootstrapFixture
+{
+private:
+ uno::Reference<uno::XInterface> m_xCalcComponent;
+
+public:
+ SparklineTest()
+ : ScBootstrapFixture("sc/qa/unit/data")
+ {
+ }
+
+ virtual void setUp() override
+ {
+ test::BootstrapFixture::setUp();
+
+ // This is a bit of a fudge, we do this to ensure that
ScGlobals::ensure,
+ // which is a private symbol to us, gets called
+ m_xCalcComponent = getMultiServiceFactory()->createInstance(
+ "com.sun.star.comp.Calc.SpreadsheetDocument");
+ CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
+ }
+
+ virtual void tearDown() override
+ {
+ uno::Reference<lang::XComponent>(m_xCalcComponent,
uno::UNO_QUERY_THROW)->dispose();
+ test::BootstrapFixture::tearDown();
+ }
+
+ void testAddSparkline();
+
+ CPPUNIT_TEST_SUITE(SparklineTest);
+ CPPUNIT_TEST(testAddSparkline);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void SparklineTest::testAddSparkline()
+{
+ ScDocShellRef xDocSh = loadEmptyDocument();
+ CPPUNIT_ASSERT(xDocSh);
+
+ ScDocument& rDocument = xDocSh->GetDocument();
+ auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+
+ sc::Sparkline* pSparkline = rDocument.CreateSparkline(ScAddress(0, 0, 0),
pSparklineGroup);
+ CPPUNIT_ASSERT(pSparkline);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SparklineTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 8aef68130b58055a5ad5b0d158f5a077654027a1
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Mar 10 14:05:41 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Mon Mar 14 13:52:20 2022 +0900
sc: use forward decl. instead of include for SparklineGroup
Shouldn't trigger large rebuilding when SparklineGroup.hxx is
changed.
Change-Id: I9c5d265e94dd92d9f23e86e3fc75ca0644991339
diff --git a/sc/inc/Sparkline.hxx b/sc/inc/Sparkline.hxx
index ad4688f33a5e..7b7785f3169a 100644
--- a/sc/inc/Sparkline.hxx
+++ b/sc/inc/Sparkline.hxx
@@ -11,12 +11,13 @@
#pragma once
#include "scdllapi.h"
-#include "SparklineGroup.hxx"
#include "rangelst.hxx"
#include <memory>
namespace sc
{
+class SparklineGroup;
+
class SC_DLLPUBLIC Sparkline
{
SCCOL m_nColumn;
diff --git a/sc/qa/unit/SparklineImportExportTest.cxx
b/sc/qa/unit/SparklineImportExportTest.cxx
index 2b8de3e34c29..650a45b89c6f 100644
--- a/sc/qa/unit/SparklineImportExportTest.cxx
+++ b/sc/qa/unit/SparklineImportExportTest.cxx
@@ -12,6 +12,7 @@
#include <com/sun/star/lang/XComponent.hpp>
#include <docsh.hxx>
#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
using namespace css;
@@ -52,7 +53,6 @@ public:
namespace
{
-
void checkSparklines(ScDocument& rDocument)
{
// Sparkline at Sheet1:A2
diff --git a/sc/source/filter/excel/export/SparklineExt.cxx
b/sc/source/filter/excel/export/SparklineExt.cxx
index f1e97b2c62ed..883389572ef7 100644
--- a/sc/source/filter/excel/export/SparklineExt.cxx
+++ b/sc/source/filter/excel/export/SparklineExt.cxx
@@ -12,6 +12,7 @@
#include <oox/export/utils.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
+#include <SparklineGroup.hxx>
using namespace oox;
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index a6f9e91ec8fa..17903c3a23fd 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -64,6 +64,7 @@
#include <colorscale.hxx>
#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
#include <math.h>
#include <memory>