summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/dialogs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sc/source/ui/dialogs
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/ui/dialogs')
-rw-r--r--sc/source/ui/dialogs/SparklineDataRangeDialog.cxx202
-rw-r--r--sc/source/ui/dialogs/SparklineDialog.cxx552
-rw-r--r--sc/source/ui/dialogs/searchresults.cxx287
3 files changed, 1041 insertions, 0 deletions
diff --git a/sc/source/ui/dialogs/SparklineDataRangeDialog.cxx b/sc/source/ui/dialogs/SparklineDataRangeDialog.cxx
new file mode 100644
index 0000000000..0e91051db4
--- /dev/null
+++ b/sc/source/ui/dialogs/SparklineDataRangeDialog.cxx
@@ -0,0 +1,202 @@
+/* -*- 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 <SparklineDataRangeDialog.hxx>
+#include <Sparkline.hxx>
+#include <reffact.hxx>
+#include <docfunc.hxx>
+
+namespace sc
+{
+SparklineDataRangeDialog::SparklineDataRangeDialog(SfxBindings* pBindings,
+ SfxChildWindow* pChildWindow,
+ weld::Window* pWindow, ScViewData& rViewData)
+ : ScAnyRefDlgController(pBindings, pChildWindow, pWindow,
+ u"modules/scalc/ui/sparklinedatarangedialog.ui"_ustr,
+ "SparklineDataRangeDialog")
+ , mrViewData(rViewData)
+ , mrDocument(rViewData.GetDocument())
+ , mpActiveEdit(nullptr)
+ , mbDialogLostFocus(false)
+ , mxButtonOk(m_xBuilder->weld_button("ok"))
+ , mxButtonCancel(m_xBuilder->weld_button("cancel"))
+ , mxDataRangeLabel(m_xBuilder->weld_label("cell-range-label"))
+ , mxDataRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("cell-range-edit")))
+ , mxDataRangeButton(new formula::RefButton(m_xBuilder->weld_button("cell-range-button")))
+
+{
+ mxDataRangeEdit->SetReferences(this, mxDataRangeLabel.get());
+ mxDataRangeButton->SetReferences(this, mxDataRangeEdit.get());
+
+ mxButtonCancel->connect_clicked(LINK(this, SparklineDataRangeDialog, ButtonClicked));
+ mxButtonOk->connect_clicked(LINK(this, SparklineDataRangeDialog, ButtonClicked));
+
+ mxButtonOk->set_sensitive(false);
+
+ Link<formula::RefEdit&, void> aEditLink
+ = LINK(this, SparklineDataRangeDialog, EditFocusHandler);
+ mxDataRangeEdit->SetGetFocusHdl(aEditLink);
+ aEditLink = LINK(this, SparklineDataRangeDialog, LoseEditFocusHandler);
+ mxDataRangeEdit->SetLoseFocusHdl(aEditLink);
+
+ Link<formula::RefButton&, void> aButtonLink
+ = LINK(this, SparklineDataRangeDialog, ButtonFocusHandler);
+ mxDataRangeButton->SetGetFocusHdl(aButtonLink);
+ aButtonLink = LINK(this, SparklineDataRangeDialog, LoseButtonFocusHandler);
+ mxDataRangeButton->SetLoseFocusHdl(aButtonLink);
+
+ Link<formula::RefEdit&, void> aModifyLink
+ = LINK(this, SparklineDataRangeDialog, RefInputModifyHandler);
+ mxDataRangeEdit->SetModifyHdl(aModifyLink);
+
+ setupValues();
+
+ mxDataRangeEdit->GrabFocus();
+}
+
+SparklineDataRangeDialog::~SparklineDataRangeDialog() = default;
+
+void SparklineDataRangeDialog::setupValues()
+{
+ ScAddress aCurrentAddress = mrViewData.GetCurPos();
+ mpSparkline = mrDocument.GetSparkline(aCurrentAddress);
+
+ if (mpSparkline)
+ {
+ ScRangeList aRangeList(mpSparkline->getInputRange());
+ if (!aRangeList.empty())
+ {
+ maDataRange = aRangeList[0];
+ OUString aString
+ = maDataRange.Format(mrDocument, ScRefFlags::VALID | ScRefFlags::TAB_3D,
+ mrDocument.GetAddressConvention());
+ mxDataRangeEdit->SetRefString(aString);
+ mxButtonOk->set_sensitive(true);
+ }
+ }
+}
+
+void SparklineDataRangeDialog::Close()
+{
+ DoClose(sc::SparklineDataRangeDialogWrapper::GetChildWindowId());
+}
+
+void SparklineDataRangeDialog::SetActive()
+{
+ if (mbDialogLostFocus)
+ {
+ mbDialogLostFocus = false;
+ if (mpActiveEdit)
+ mpActiveEdit->GrabFocus();
+ }
+ else
+ {
+ m_xDialog->grab_focus();
+ }
+ RefInputDone();
+}
+
+void SparklineDataRangeDialog::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 == mxDataRangeEdit.get())
+ {
+ maDataRange = rReferenceRange;
+ aString = maDataRange.Format(rDocument, eFlags, eAddressConvention);
+ mxDataRangeEdit->SetRefString(aString);
+ }
+ }
+}
+
+IMPL_LINK(SparklineDataRangeDialog, EditFocusHandler, formula::RefEdit&, rEdit, void)
+{
+ if (mxDataRangeEdit.get() == &rEdit)
+ mpActiveEdit = mxDataRangeEdit.get();
+ else
+ mpActiveEdit = nullptr;
+
+ if (mpActiveEdit)
+ mpActiveEdit->SelectAll();
+}
+
+IMPL_LINK(SparklineDataRangeDialog, ButtonFocusHandler, formula::RefButton&, rButton, void)
+{
+ if (mxDataRangeButton.get() == &rButton)
+ mpActiveEdit = mxDataRangeEdit.get();
+ else
+ mpActiveEdit = nullptr;
+
+ if (mpActiveEdit)
+ mpActiveEdit->SelectAll();
+}
+
+IMPL_LINK_NOARG(SparklineDataRangeDialog, LoseEditFocusHandler, formula::RefEdit&, void)
+{
+ mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
+}
+
+IMPL_LINK_NOARG(SparklineDataRangeDialog, LoseButtonFocusHandler, formula::RefButton&, void)
+{
+ mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
+}
+
+IMPL_LINK_NOARG(SparklineDataRangeDialog, RefInputModifyHandler, formula::RefEdit&, void)
+{
+ if (mpActiveEdit)
+ {
+ if (mpActiveEdit == mxDataRangeEdit.get())
+ {
+ ScRangeList aRangeList;
+ bool bValid = ParseWithNames(aRangeList, mxDataRangeEdit->GetText(), mrDocument);
+ const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
+ if (pRange)
+ {
+ maDataRange = *pRange;
+ mxDataRangeEdit->StartUpdateData();
+ }
+ else
+ {
+ maDataRange = ScRange(ScAddress::INITIALIZE_INVALID);
+ }
+ }
+ }
+}
+
+IMPL_LINK(SparklineDataRangeDialog, ButtonClicked, weld::Button&, rButton, void)
+{
+ if (mxButtonOk.get() == &rButton)
+ {
+ perform();
+ response(RET_OK);
+ }
+ else
+ {
+ response(RET_CANCEL);
+ }
+}
+
+void SparklineDataRangeDialog::perform()
+{
+ ScRangeList aList{ maDataRange };
+
+ auto& rDocFunc = mrViewData.GetDocShell()->GetDocFunc();
+ rDocFunc.ChangeSparkline(mpSparkline, mrViewData.GetTabNo(), aList);
+}
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dialogs/SparklineDialog.cxx b/sc/source/ui/dialogs/SparklineDialog.cxx
new file mode 100644
index 0000000000..ff56e629e6
--- /dev/null
+++ b/sc/source/ui/dialogs/SparklineDialog.cxx
@@ -0,0 +1,552 @@
+/* -*- 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 <SparklineData.hxx>
+#include <SparklineGroup.hxx>
+#include <Sparkline.hxx>
+#include <reffact.hxx>
+
+#include <docfunc.hxx>
+
+#include <svx/colorbox.hxx>
+#include <vcl/formatter.hxx>
+
+namespace sc
+{
+SparklineDialog::SparklineDialog(SfxBindings* pBindings, SfxChildWindow* pChildWindow,
+ weld::Window* pWindow, ScViewData& rViewData)
+ : ScAnyRefDlgController(pBindings, pChildWindow, pWindow,
+ u"modules/scalc/ui/sparklinedialog.ui"_ustr, "SparklineDialog")
+ , mrViewData(rViewData)
+ , mrDocument(rViewData.GetDocument())
+ , mpActiveEdit(nullptr)
+ , mbDialogLostFocus(false)
+ , mxButtonOk(m_xBuilder->weld_button("ok"))
+ , mxButtonCancel(m_xBuilder->weld_button("cancel"))
+ , mxFrameData(m_xBuilder->weld_frame("frmData"))
+ , mxInputRangeLabel(m_xBuilder->weld_label("lbInputRange"))
+ , mxInputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("edInputRange")))
+ , mxInputRangeButton(new formula::RefButton(m_xBuilder->weld_button("btnInputRange")))
+ , mxOutputRangeLabel(m_xBuilder->weld_label("lbOutputRange"))
+ , mxOutputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("edOutputRange")))
+ , mxOutputRangeButton(new formula::RefButton(m_xBuilder->weld_button("btnOutputRange")))
+ , mxColorSeries(new ColorListBox(m_xBuilder->weld_menu_button("colSeries"),
+ [pWindow] { return pWindow; }))
+ , mxColorNegative(new ColorListBox(m_xBuilder->weld_menu_button("colNegative"),
+ [pWindow] { return pWindow; }))
+ , mxColorMarker(new ColorListBox(m_xBuilder->weld_menu_button("colMarker"),
+ [pWindow] { return pWindow; }))
+ , mxColorHigh(
+ new ColorListBox(m_xBuilder->weld_menu_button("colHigh"), [pWindow] { return pWindow; }))
+ , mxColorLow(
+ new ColorListBox(m_xBuilder->weld_menu_button("colLow"), [pWindow] { return pWindow; }))
+ , mxColorFirst(
+ new ColorListBox(m_xBuilder->weld_menu_button("colFirst"), [pWindow] { return pWindow; }))
+ , mxColorLast(
+ new ColorListBox(m_xBuilder->weld_menu_button("colLast"), [pWindow] { return pWindow; }))
+ , mxCheckButtonNegative(m_xBuilder->weld_check_button("cbNegative"))
+ , mxCheckButtonMarker(m_xBuilder->weld_check_button("cbMarker"))
+ , mxCheckButtonHigh(m_xBuilder->weld_check_button("cbHigh"))
+ , mxCheckButtonLow(m_xBuilder->weld_check_button("cbLow"))
+ , mxCheckButtonFirst(m_xBuilder->weld_check_button("cbFirst"))
+ , mxCheckButtonLast(m_xBuilder->weld_check_button("cbLast"))
+ , mxSpinLineWidth(m_xBuilder->weld_spin_button("seLineWidth"))
+ , mxType(m_xBuilder->weld_combo_box("cbType"))
+ , mxCheckDisplayXAxis(m_xBuilder->weld_check_button("cbDisplayXAxis"))
+ , mxCheckDisplayHidden(m_xBuilder->weld_check_button("cbHidden"))
+ , mxCheckRightToLeft(m_xBuilder->weld_check_button("cbRTL"))
+ , mxDisplayEmptyGap(m_xBuilder->weld_combo_box("cbEmptyCells"))
+ , mxComboMinAxisType(m_xBuilder->weld_combo_box("cbMinAxisType"))
+ , mxComboMaxAxisType(m_xBuilder->weld_combo_box("cbMaxAxisType"))
+ , mxSpinCustomMin(m_xBuilder->weld_formatted_spin_button("seMinAxis"))
+ , mxSpinCustomMax(m_xBuilder->weld_formatted_spin_button("seMaxAxis"))
+ , mbEditMode(false)
+{
+ mxInputRangeEdit->SetReferences(this, mxInputRangeLabel.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);
+
+ mxType->connect_changed(LINK(this, SparklineDialog, SelectSparklineType));
+ mxDisplayEmptyGap->connect_changed(LINK(this, SparklineDialog, SelectSparklineType));
+
+ 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);
+ 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();
+
+ mxOutputRangeEdit->GrabFocus();
+ mxButtonOk->set_sensitive(checkValidInputOutput());
+}
+
+SparklineDialog::~SparklineDialog() = default;
+
+void SparklineDialog::setInputSelection()
+{
+ mrViewData.GetSimpleArea(maInputRange);
+ OUString aString = maInputRange.Format(mrDocument, ScRefFlags::VALID | ScRefFlags::TAB_3D,
+ mrDocument.GetAddressConvention());
+ mxInputRangeEdit->SetRefString(aString);
+}
+
+void SparklineDialog::setupValues()
+{
+ ScRange aSelectionRange;
+ mrViewData.GetSimpleArea(aSelectionRange);
+
+ if (mrDocument.HasOneSparklineGroup(aSelectionRange))
+ {
+ if (auto pSparkline = mrDocument.GetSparkline(aSelectionRange.aStart))
+ {
+ mpSparklineGroup = pSparkline->getSparklineGroup();
+ maAttributes = mpSparklineGroup->getAttributes();
+ mxFrameData->set_visible(false);
+ mbEditMode = true;
+ }
+ }
+ else
+ {
+ maInputRange = aSelectionRange;
+ }
+
+ setInputSelection();
+
+ switch (maAttributes.getType())
+ {
+ case sc::SparklineType::Line:
+ mxType->set_active(0);
+ break;
+ case sc::SparklineType::Column:
+ mxType->set_active(1);
+ break;
+ case sc::SparklineType::Stacked:
+ mxType->set_active(2);
+ break;
+ }
+
+ switch (maAttributes.getDisplayEmptyCellsAs())
+ {
+ case sc::DisplayEmptyCellsAs::Gap:
+ mxDisplayEmptyGap->set_active(0);
+ break;
+ case sc::DisplayEmptyCellsAs::Zero:
+ mxDisplayEmptyGap->set_active(1);
+ break;
+ case sc::DisplayEmptyCellsAs::Span:
+ mxDisplayEmptyGap->set_active(2);
+ break;
+ }
+
+ mxColorSeries->SelectEntry(maAttributes.getColorSeries().getFinalColor());
+ mxColorNegative->SelectEntry(maAttributes.getColorNegative().getFinalColor());
+ mxColorMarker->SelectEntry(maAttributes.getColorMarkers().getFinalColor());
+ mxColorHigh->SelectEntry(maAttributes.getColorHigh().getFinalColor());
+ mxColorLow->SelectEntry(maAttributes.getColorLow().getFinalColor());
+ mxColorFirst->SelectEntry(maAttributes.getColorFirst().getFinalColor());
+ mxColorLast->SelectEntry(maAttributes.getColorLast().getFinalColor());
+
+ mxCheckButtonNegative->set_active(maAttributes.isNegative());
+ mxCheckButtonMarker->set_active(maAttributes.isMarkers());
+ mxCheckButtonHigh->set_active(maAttributes.isHigh());
+ mxCheckButtonLow->set_active(maAttributes.isLow());
+ mxCheckButtonFirst->set_active(maAttributes.isFirst());
+ mxCheckButtonLast->set_active(maAttributes.isLast());
+
+ mxSpinLineWidth->set_value(sal_Int64(maAttributes.getLineWeight() * 100.0));
+
+ mxCheckDisplayXAxis->set_active(maAttributes.shouldDisplayXAxis());
+ mxCheckDisplayHidden->set_active(maAttributes.shouldDisplayHidden());
+ mxCheckRightToLeft->set_active(maAttributes.isRightToLeft());
+
+ switch (maAttributes.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 (maAttributes.getManualMin())
+ mxSpinCustomMin->GetFormatter().SetValue(*maAttributes.getManualMin());
+ break;
+ }
+ ComboValueChanged(*mxComboMinAxisType);
+
+ switch (maAttributes.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 (maAttributes.getManualMax())
+ mxSpinCustomMax->GetFormatter().SetValue(*maAttributes.getManualMax());
+ break;
+ }
+ ComboValueChanged(*mxComboMaxAxisType);
+}
+
+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::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);
+ }
+}
+
+IMPL_LINK(SparklineDialog, ToggleHandler, weld::Toggleable&, rToggle, void)
+{
+ if (mxCheckButtonNegative.get() == &rToggle)
+ maAttributes.setNegative(mxCheckButtonNegative->get_active());
+ if (mxCheckButtonMarker.get() == &rToggle)
+ maAttributes.setMarkers(mxCheckButtonMarker->get_active());
+ if (mxCheckButtonHigh.get() == &rToggle)
+ maAttributes.setHigh(mxCheckButtonHigh->get_active());
+ if (mxCheckButtonLow.get() == &rToggle)
+ maAttributes.setLow(mxCheckButtonLow->get_active());
+ if (mxCheckButtonFirst.get() == &rToggle)
+ maAttributes.setFirst(mxCheckButtonFirst->get_active());
+ if (mxCheckButtonLast.get() == &rToggle)
+ maAttributes.setLast(mxCheckButtonLast->get_active());
+ if (mxCheckDisplayXAxis.get() == &rToggle)
+ maAttributes.setDisplayXAxis(mxCheckDisplayXAxis->get_active());
+ if (mxCheckDisplayHidden.get() == &rToggle)
+ maAttributes.setDisplayHidden(mxCheckDisplayHidden->get_active());
+ if (mxCheckRightToLeft.get() == &rToggle)
+ maAttributes.setRightToLeft(mxCheckRightToLeft->get_active());
+}
+
+IMPL_LINK_NOARG(SparklineDialog, SelectSparklineType, weld::ComboBox&, void)
+{
+ switch (mxType->get_active())
+ {
+ case 0:
+ maAttributes.setType(sc::SparklineType::Line);
+ break;
+ case 1:
+ maAttributes.setType(sc::SparklineType::Column);
+ break;
+ case 2:
+ maAttributes.setType(sc::SparklineType::Stacked);
+ break;
+ }
+ switch (mxDisplayEmptyGap->get_active())
+ {
+ case 1:
+ maAttributes.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Gap);
+ break;
+ case 2:
+ maAttributes.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Zero);
+ break;
+ case 3:
+ maAttributes.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Span);
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SparklineDialog, SpinLineWidthChanged, weld::SpinButton&, void)
+{
+ double value = mxSpinLineWidth->get_value() / 100.0;
+ maAttributes.setLineWeight(value);
+}
+
+IMPL_LINK(SparklineDialog, SpinCustomChanged, weld::FormattedSpinButton&, rFormatted, void)
+{
+ if (mxSpinCustomMin.get() == &rFormatted)
+ {
+ maAttributes.setManualMin(rFormatted.GetFormatter().GetValue());
+ }
+ else if (mxSpinCustomMax.get() == &rFormatted)
+ {
+ maAttributes.setManualMax(rFormatted.GetFormatter().GetValue());
+ }
+}
+
+IMPL_LINK(SparklineDialog, ComboValueChanged, weld::ComboBox&, rComboBox, void)
+{
+ int nActive = rComboBox.get_active();
+
+ if (mxComboMinAxisType.get() == &rComboBox)
+ {
+ switch (nActive)
+ {
+ case 0:
+ maAttributes.setMinAxisType(sc::AxisType::Individual);
+ mxSpinCustomMin->set_sensitive(false);
+ break;
+ case 1:
+ maAttributes.setMinAxisType(sc::AxisType::Group);
+ mxSpinCustomMin->set_sensitive(false);
+ break;
+ case 2:
+ maAttributes.setMinAxisType(sc::AxisType::Custom);
+ mxSpinCustomMin->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+ }
+ else if (mxComboMaxAxisType.get() == &rComboBox)
+ {
+ switch (nActive)
+ {
+ case 0:
+ maAttributes.setMaxAxisType(sc::AxisType::Individual);
+ mxSpinCustomMax->set_sensitive(false);
+ break;
+ case 1:
+ maAttributes.setMaxAxisType(sc::AxisType::Group);
+ mxSpinCustomMax->set_sensitive(false);
+ break;
+ case 2:
+ maAttributes.setMaxAxisType(sc::AxisType::Custom);
+ mxSpinCustomMax->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+bool SparklineDialog::checkValidInputOutput()
+{
+ if (mbEditMode)
+ return true;
+
+ if (!maInputRange.IsValid() || !maOutputRange.IsValid())
+ return false;
+
+ sc::RangeOrientation eInputOrientation = sc::RangeOrientation::Unknown;
+ if (maOutputRange.aStart.Col() == maOutputRange.aEnd.Col())
+ {
+ sal_Int32 nOutputRowSize = maOutputRange.aEnd.Row() - maOutputRange.aStart.Row();
+ eInputOrientation = sc::calculateOrientation(nOutputRowSize, maInputRange);
+ }
+ else if (maOutputRange.aStart.Row() == maOutputRange.aEnd.Row())
+ {
+ sal_Int32 nOutputColSize = maOutputRange.aEnd.Col() - maOutputRange.aStart.Col();
+ eInputOrientation = sc::calculateOrientation(nOutputColSize, maInputRange);
+ }
+
+ return eInputOrientation != sc::RangeOrientation::Unknown;
+}
+
+void SparklineDialog::perform()
+{
+ maAttributes.setColorSeries(mxColorSeries->GetSelectedEntry().getComplexColor());
+ maAttributes.setColorNegative(mxColorNegative->GetSelectedEntry().getComplexColor());
+ maAttributes.setColorMarkers(mxColorMarker->GetSelectedEntry().getComplexColor());
+ maAttributes.setColorHigh(mxColorHigh->GetSelectedEntry().getComplexColor());
+ maAttributes.setColorLow(mxColorLow->GetSelectedEntry().getComplexColor());
+ maAttributes.setColorFirst(mxColorFirst->GetSelectedEntry().getComplexColor());
+ maAttributes.setColorLast(mxColorLast->GetSelectedEntry().getComplexColor());
+
+ auto& rDocFunc = mrViewData.GetDocShell()->GetDocFunc();
+
+ if (mpSparklineGroup)
+ {
+ rDocFunc.ChangeSparklineGroupAttributes(mpSparklineGroup, maAttributes);
+ }
+ else
+ {
+ auto pNewSparklineGroup = std::make_shared<sc::SparklineGroup>(maAttributes);
+ rDocFunc.InsertSparklines(maInputRange, maOutputRange, pNewSparklineGroup);
+ }
+}
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dialogs/searchresults.cxx b/sc/source/ui/dialogs/searchresults.cxx
new file mode 100644
index 0000000000..4ea08c1d49
--- /dev/null
+++ b/sc/source/ui/dialogs/searchresults.cxx
@@ -0,0 +1,287 @@
+/* -*- 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 <o3tl/safeint.hxx>
+#include <searchresults.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/srchdlg.hxx>
+#include <dociter.hxx>
+#include <document.hxx>
+#include <tabvwsh.hxx>
+#include <strings.hrc>
+#include <sc.hrc>
+#include <scresid.hxx>
+
+namespace sc {
+
+SearchResultsDlg::SearchResultsDlg(SfxBindings* _pBindings, weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/scalc/ui/searchresults.ui", "SearchResultsDialog")
+ , aSkipped(ScResId(SCSTR_SKIPPED))
+ , mpBindings(_pBindings)
+ , mpDoc(nullptr)
+ , mbSorted(false)
+ , mxList(m_xBuilder->weld_tree_view("results"))
+ , mxSearchResults(m_xBuilder->weld_label("lbSearchResults"))
+ , mxShowDialog(m_xBuilder->weld_check_button("cbShow"))
+{
+ mxList->set_size_request(mxList->get_approximate_digit_width() * 50, mxList->get_height_rows(15));
+ mxShowDialog->connect_toggled(LINK(this, SearchResultsDlg, OnShowToggled));
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(mxList->get_approximate_digit_width() * 10),
+ o3tl::narrowing<int>(mxList->get_approximate_digit_width() * 10)
+ };
+ mxList->set_column_fixed_widths(aWidths);
+ mxList->connect_changed(LINK(this, SearchResultsDlg, ListSelectHdl));
+ mxList->connect_column_clicked(LINK(this, SearchResultsDlg, HeaderBarClick));
+}
+
+SearchResultsDlg::~SearchResultsDlg()
+{
+ // tdf#133807 if the search dialog is shown then re-present that dialog
+ // when this results dialog is dismissed
+ SfxViewFrame* pViewFrame = mpBindings->GetDispatcher()->GetFrame();
+ if (!pViewFrame)
+ return;
+ SfxChildWindow* pChildWindow = pViewFrame->GetChildWindow(
+ SvxSearchDialogWrapper::GetChildWindowId());
+ if (!pChildWindow)
+ return;
+ SvxSearchDialog* pSearchDlg = static_cast<SvxSearchDialog*>(pChildWindow->GetController().get());
+ if (!pSearchDlg)
+ return;
+ pSearchDlg->Present();
+}
+
+namespace
+{
+ class ListWrapper {
+ weld::TreeView& mrList;
+ public:
+ size_t mnCount = 0;
+ static const size_t mnMaximum = 1000;
+ ListWrapper(weld::TreeView& rList)
+ : mrList(rList)
+ {
+ mrList.clear();
+ mrList.freeze();
+ }
+ ~ListWrapper()
+ {
+ mrList.thaw();
+ }
+ void Insert(const OUString &rTabName,
+ const ScAddress &rPos,
+ formula::FormulaGrammar::AddressConvention eConvention,
+ const OUString &rText)
+ {
+ if (mnCount++ < mnMaximum)
+ {
+ mrList.append_text(rTabName);
+ int nPos = mrList.n_children() - 1;
+ mrList.set_text(nPos, rPos.Format(ScRefFlags::ADDR_ABS,
+ nullptr, eConvention), 1);
+ mrList.set_text(nPos, rText, 2);
+ }
+ }
+ };
+}
+
+void SearchResultsDlg::FillResults( ScDocument& rDoc, const ScRangeList &rMatchedRanges, bool bCellNotes,
+ bool bEmptyCells, bool bMatchedRangesWereClamped )
+{
+ ListWrapper aList(*mxList);
+ std::vector<OUString> aTabNames = rDoc.GetAllTableNames();
+ SCTAB nTabCount = aTabNames.size();
+
+ // tdf#92160 - too many results blow the widget's mind
+ size_t nMatchMax = rMatchedRanges.size();
+ if (nMatchMax > ListWrapper::mnMaximum)
+ nMatchMax = ListWrapper::mnMaximum;
+
+ if (bCellNotes || bEmptyCells)
+ {
+ for (size_t i = 0, n = nMatchMax; i < n; ++i)
+ {
+ ScRange const & rRange( rMatchedRanges[i] );
+ // Bear in mind that mostly the range is one address position
+ // or a column or a row joined.
+ ScAddress aPos( rRange.aStart );
+ for ( ; aPos.Tab() <= rRange.aEnd.Tab(); aPos.IncTab())
+ {
+ if (aPos.Tab() >= nTabCount)
+ break; // can this even happen? we just searched on existing sheets ...
+ for (aPos.SetCol( rRange.aStart.Col()); aPos.Col() <= rRange.aEnd.Col(); aPos.IncCol())
+ {
+ for (aPos.SetRow( rRange.aStart.Row()); aPos.Row() <= rRange.aEnd.Row(); aPos.IncRow())
+ {
+ if (bCellNotes)
+ {
+ const ScPostIt* pNote = rDoc.GetNote( aPos);
+ if (pNote)
+ aList.Insert(aTabNames[aPos.Tab()], aPos,
+ rDoc.GetAddressConvention(),
+ pNote->GetText());
+ }
+ else // bEmptyCells
+ {
+ aList.Insert(aTabNames[aPos.Tab()], aPos,
+ rDoc.GetAddressConvention(),
+ rDoc.GetString(aPos));
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (size_t i = 0, n = nMatchMax; i < n; ++i)
+ {
+ ScCellIterator aIter(rDoc, rMatchedRanges[i]);
+ for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
+ {
+ const ScAddress& aPos = aIter.GetPos();
+ if (aPos.Tab() >= nTabCount)
+ // Out-of-bound sheet index.
+ continue;
+
+ aList.Insert(aTabNames[aPos.Tab()], aPos,
+ rDoc.GetAddressConvention(),
+ rDoc.GetString(aPos));
+ }
+ }
+ }
+
+ OUString aSearchResultsMsg;
+ if (bMatchedRangesWereClamped)
+ {
+ aSearchResultsMsg = ScResId(SCSTR_RESULTS_CLAMPED);
+ aSearchResultsMsg = aSearchResultsMsg.replaceFirst("%1", OUString::number(1000));
+ }
+ else
+ {
+ OUString aTotal(ScResId(SCSTR_TOTAL, aList.mnCount));
+ aSearchResultsMsg = aTotal.replaceFirst("%1", OUString::number(aList.mnCount));
+ if (aList.mnCount > ListWrapper::mnMaximum)
+ aSearchResultsMsg += " " + ScGlobal::ReplaceOrAppend( aSkipped, u"%1", OUString::number( ListWrapper::mnMaximum ) );
+ }
+ mxSearchResults->set_label(aSearchResultsMsg);
+
+ mpDoc = &rDoc;
+}
+
+void SearchResultsDlg::Close()
+{
+ if (mpBindings)
+ {
+ // Remove this dialog from the view frame after the dialog gets
+ // dismissed, else it would keep popping up endlessly!
+ SfxDispatcher* pDispacher = mpBindings ->GetDispatcher();
+ SfxBoolItem aItem(SID_SEARCH_RESULTS_DIALOG, false);
+ if (pDispacher)
+ {
+ pDispacher->ExecuteList(SID_SEARCH_RESULTS_DIALOG,
+ SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aItem });
+ }
+ }
+
+ SfxDialogController::Close();
+}
+
+IMPL_LINK(SearchResultsDlg, HeaderBarClick, int, nColumn, void)
+{
+ if (!mbSorted)
+ {
+ mxList->make_sorted();
+ mbSorted = true;
+ }
+
+ bool bSortAtoZ = mxList->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == mxList->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ mxList->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ int nOldSortColumn = mxList->get_sort_column();
+ if (nOldSortColumn != -1)
+ mxList->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
+ mxList->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ mxList->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+IMPL_LINK_NOARG( SearchResultsDlg, ListSelectHdl, weld::TreeView&, void )
+{
+ if (!mpDoc)
+ return;
+
+ int nEntry = mxList->get_selected_index();
+ OUString aTabStr = mxList->get_text(nEntry, 0);
+ OUString aPosStr = mxList->get_text(nEntry, 1);
+
+ SCTAB nTab = -1;
+ if (!mpDoc->GetTable(aTabStr, nTab))
+ // No sheet with specified name.
+ return;
+
+ ScAddress aPos;
+ ScRefFlags nRes = aPos.Parse(aPosStr, *mpDoc, mpDoc->GetAddressConvention());
+ if (!(nRes & ScRefFlags::VALID))
+ // Invalid address string.
+ return;
+
+ // Jump to the cell.
+ ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
+ pScViewShell->SetTabNo(nTab);
+ pScViewShell->SetCursor(aPos.Col(), aPos.Row());
+ pScViewShell->AlignToCursor(aPos.Col(), aPos.Row(), SC_FOLLOW_JUMP);
+}
+
+IMPL_STATIC_LINK( SearchResultsDlg, OnShowToggled, weld::Toggleable&, rButton, void )
+{
+ ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
+ ScViewOptions aViewOpt( pScViewShell->GetViewData().GetOptions() );
+ aViewOpt.SetOption( VOPT_SUMMARY, rButton.get_active() );
+ pScViewShell->GetViewData().SetOptions( aViewOpt );
+}
+
+SearchResultsDlgWrapper::SearchResultsDlgWrapper(
+ vcl::Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* /*pInfo*/)
+ : SfxChildWindow(_pParent, nId)
+ , m_xDialog(std::make_shared<SearchResultsDlg>(pBindings, _pParent->GetFrameWeld()))
+{
+ SetController(m_xDialog);
+}
+
+SearchResultsDlgWrapper::~SearchResultsDlgWrapper() {}
+
+SfxChildWinInfo SearchResultsDlgWrapper::GetInfo() const
+{
+ SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
+ aInfo.bVisible = false;
+ return aInfo;
+}
+
+SFX_IMPL_CHILDWINDOW_WITHID(SearchResultsDlgWrapper, SID_SEARCH_RESULTS_DIALOG);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */