diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sc/source/ui/dialogs | |
parent | Initial commit. (diff) | |
download | libreoffice-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.cxx | 202 | ||||
-rw-r--r-- | sc/source/ui/dialogs/SparklineDialog.cxx | 552 | ||||
-rw-r--r-- | sc/source/ui/dialogs/searchresults.cxx | 287 |
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: */ |