diff options
Diffstat (limited to 'sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx')
-rw-r--r-- | sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx b/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx new file mode 100644 index 000000000..3c0f7ce98 --- /dev/null +++ b/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx @@ -0,0 +1,347 @@ +/* -*- 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 <svl/undo.hxx> + +#include <rangelst.hxx> +#include <docsh.hxx> +#include <document.hxx> +#include <scresid.hxx> +#include <tabvwsh.hxx> + +#include <StatisticsTwoVariableDialog.hxx> + +ScStatisticsTwoVariableDialog::ScStatisticsTwoVariableDialog( + SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, + weld::Window* pParent, ScViewData& rViewData, const OUString& rUIXMLDescription, const OString& rID) + : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID) + , mxVariable1RangeLabel(m_xBuilder->weld_label("variable1-range-label")) + , mxVariable1RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("variable1-range-edit"))) + , mxVariable1RangeButton(new formula::RefButton(m_xBuilder->weld_button("variable1-range-button"))) + , mxVariable2RangeLabel(m_xBuilder->weld_label("variable2-range-label")) + , mxVariable2RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("variable2-range-edit"))) + , mxVariable2RangeButton(new formula::RefButton(m_xBuilder->weld_button("variable2-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"))) + , mViewData(rViewData) + , mDocument(rViewData.GetDocument()) + , mVariable1Range(ScAddress::INITIALIZE_INVALID) + , mVariable2Range(ScAddress::INITIALIZE_INVALID) + , mAddressDetails(mDocument.GetAddressConvention(), 0, 0 ) + , mOutputAddress(ScAddress::INITIALIZE_INVALID) + , mGroupedBy(BY_COLUMN) + , mxButtonOk(m_xBuilder->weld_button("ok")) + , mxButtonCancel(m_xBuilder->weld_button("cancel")) + , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button("groupedby-columns-radio")) + , mxGroupByRowsRadio(m_xBuilder->weld_radio_button("groupedby-rows-radio")) + , mpActiveEdit(nullptr) + , mCurrentAddress(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() ) + , mDialogLostFocus(false) +{ + mxVariable1RangeEdit->SetReferences(this, mxVariable1RangeLabel.get()); + mxVariable1RangeButton->SetReferences(this, mxVariable1RangeEdit.get()); + + mxVariable2RangeEdit->SetReferences(this, mxVariable2RangeLabel.get()); + mxVariable2RangeButton->SetReferences(this, mxVariable2RangeEdit.get()); + + mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get()); + mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get()); + + Init(); + GetRangeFromSelection(); +} + +ScStatisticsTwoVariableDialog::~ScStatisticsTwoVariableDialog() +{ +} + +void ScStatisticsTwoVariableDialog::Init() +{ + mxButtonCancel->connect_clicked( LINK( this, ScStatisticsTwoVariableDialog, ButtonClicked ) ); + mxButtonOk->connect_clicked( LINK( this, ScStatisticsTwoVariableDialog, ButtonClicked ) ); + mxButtonOk->set_sensitive(false); + + Link<formula::RefEdit&,void> aEditLink = LINK( this, ScStatisticsTwoVariableDialog, GetEditFocusHandler ); + mxVariable1RangeEdit->SetGetFocusHdl( aEditLink ); + mxVariable2RangeEdit->SetGetFocusHdl( aEditLink ); + mxOutputRangeEdit->SetGetFocusHdl( aEditLink ); + + Link<formula::RefButton&,void> aButtonLink = LINK( this, ScStatisticsTwoVariableDialog, GetButtonFocusHandler ); + mxVariable1RangeButton->SetGetFocusHdl( aButtonLink ); + mxVariable2RangeButton->SetGetFocusHdl( aButtonLink ); + mxOutputRangeButton->SetGetFocusHdl( aButtonLink ); + + aEditLink = LINK( this, ScStatisticsTwoVariableDialog, LoseEditFocusHandler ); + mxVariable1RangeEdit->SetLoseFocusHdl( aEditLink ); + mxVariable2RangeEdit->SetLoseFocusHdl( aEditLink ); + mxOutputRangeEdit->SetLoseFocusHdl( aEditLink ); + + aButtonLink = LINK( this, ScStatisticsTwoVariableDialog, LoseButtonFocusHandler ); + mxVariable1RangeButton->SetLoseFocusHdl( aButtonLink ); + mxVariable2RangeButton->SetLoseFocusHdl( aButtonLink ); + mxOutputRangeButton->SetLoseFocusHdl( aButtonLink ); + + Link<formula::RefEdit&,void> aLink2 = LINK( this, ScStatisticsTwoVariableDialog, RefInputModifyHandler); + mxVariable1RangeEdit->SetModifyHdl( aLink2); + mxVariable2RangeEdit->SetModifyHdl( aLink2); + mxOutputRangeEdit->SetModifyHdl( aLink2); + + mxOutputRangeEdit->GrabFocus(); + + mxGroupByColumnsRadio->connect_toggled( LINK( this, ScStatisticsTwoVariableDialog, GroupByChanged ) ); + mxGroupByRowsRadio->connect_toggled( LINK( this, ScStatisticsTwoVariableDialog, GroupByChanged ) ); + + mxGroupByColumnsRadio->set_active(true); + mxGroupByRowsRadio->set_active(false); +} + +void ScStatisticsTwoVariableDialog::GetRangeFromSelection() +{ + OUString aCurrentString; + + ScRange aCurrentRange; + mViewData.GetSimpleArea(aCurrentRange); + + if (aCurrentRange.aEnd.Col() - aCurrentRange.aStart.Col() == 1) + { + mVariable1Range = aCurrentRange; + mVariable1Range.aEnd.SetCol(mVariable1Range.aStart.Col()); + aCurrentString = mVariable1Range.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails); + mxVariable1RangeEdit->SetText(aCurrentString); + + mVariable2Range = aCurrentRange; + mVariable2Range.aStart.SetCol(mVariable2Range.aEnd.Col()); + aCurrentString = mVariable2Range.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails); + mxVariable2RangeEdit->SetText(aCurrentString); + } + else + { + mVariable1Range = aCurrentRange; + aCurrentString = mVariable1Range.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails); + mxVariable1RangeEdit->SetText(aCurrentString); + } +} + +void ScStatisticsTwoVariableDialog::SetActive() +{ + if ( mDialogLostFocus ) + { + mDialogLostFocus = false; + if( mpActiveEdit ) + mpActiveEdit->GrabFocus(); + } + else + { + m_xDialog->grab_focus(); + } + RefInputDone(); +} + +void ScStatisticsTwoVariableDialog::SetReference( const ScRange& rReferenceRange, ScDocument& rDocument ) +{ + if ( mpActiveEdit != nullptr ) + { + if ( rReferenceRange.aStart != rReferenceRange.aEnd ) + RefInputStart( mpActiveEdit ); + + OUString aReferenceString; + + if ( mpActiveEdit == mxVariable1RangeEdit.get() ) + { + mVariable1Range = rReferenceRange; + aReferenceString = mVariable1Range.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails); + mxVariable1RangeEdit->SetRefString(aReferenceString); + } + else if ( mpActiveEdit == mxVariable2RangeEdit.get() ) + { + mVariable2Range = rReferenceRange; + aReferenceString = mVariable2Range.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails); + mxVariable2RangeEdit->SetRefString(aReferenceString); + } + else if ( mpActiveEdit == mxOutputRangeEdit.get() ) + { + mOutputAddress = rReferenceRange.aStart; + + ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ? + ScRefFlags::ADDR_ABS : + ScRefFlags::ADDR_ABS_3D; + aReferenceString = mOutputAddress.Format(nFormat, &rDocument, rDocument.GetAddressConvention()); + mxOutputRangeEdit->SetRefString( aReferenceString ); + } + } + + ValidateDialogInput(); +} + +IMPL_LINK( ScStatisticsTwoVariableDialog, ButtonClicked, weld::Button&, rButton, void ) +{ + if (&rButton == mxButtonOk.get()) + { + CalculateInputAndWriteToOutput(); + response(RET_OK); + } + else + response(RET_CANCEL); +} + +IMPL_LINK(ScStatisticsTwoVariableDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void) +{ + mpActiveEdit = nullptr; + if (&rCtrl == mxVariable1RangeEdit.get()) + { + mpActiveEdit = mxVariable1RangeEdit.get(); + } + else if (&rCtrl == mxVariable2RangeEdit.get()) + { + mpActiveEdit = mxVariable2RangeEdit.get(); + } + else if (&rCtrl == mxOutputRangeEdit.get()) + { + mpActiveEdit = mxOutputRangeEdit.get(); + } + + if( mpActiveEdit ) + mpActiveEdit->SelectAll(); +} + +IMPL_LINK( ScStatisticsTwoVariableDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void ) +{ + mpActiveEdit = nullptr; + if (&rCtrl == mxVariable1RangeButton.get()) + { + mpActiveEdit = mxVariable1RangeEdit.get(); + } + else if (&rCtrl == mxVariable2RangeButton.get()) + { + mpActiveEdit = mxVariable2RangeEdit.get(); + } + else if (&rCtrl == mxOutputRangeButton.get()) + { + mpActiveEdit = mxOutputRangeEdit.get(); + } + + if( mpActiveEdit ) + mpActiveEdit->SelectAll(); +} + +IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, LoseEditFocusHandler, formula::RefEdit&, void ) +{ + mDialogLostFocus = !m_xDialog->has_toplevel_focus(); +} + +IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, LoseButtonFocusHandler, formula::RefButton&, void ) +{ + mDialogLostFocus = !m_xDialog->has_toplevel_focus(); +} + +IMPL_LINK_NOARG(ScStatisticsTwoVariableDialog, GroupByChanged, weld::Toggleable&, void) +{ + if (mxGroupByColumnsRadio->get_active()) + mGroupedBy = BY_COLUMN; + else if (mxGroupByRowsRadio->get_active()) + mGroupedBy = BY_ROW; + + ValidateDialogInput(); +} + +IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, RefInputModifyHandler, formula::RefEdit&, void ) +{ + if ( mpActiveEdit ) + { + if (mpActiveEdit == mxVariable1RangeEdit.get()) + { + ScRangeList aRangeList; + bool bValid = ParseWithNames( aRangeList, mxVariable1RangeEdit->GetText(), mDocument); + const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr; + if (pRange) + { + mVariable1Range = *pRange; + // Highlight the resulting range. + mxVariable1RangeEdit->StartUpdateData(); + } + else + { + mVariable1Range = ScRange( ScAddress::INITIALIZE_INVALID); + } + } + else if ( mpActiveEdit == mxVariable2RangeEdit.get() ) + { + ScRangeList aRangeList; + bool bValid = ParseWithNames( aRangeList, mxVariable2RangeEdit->GetText(), mDocument); + const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr; + if (pRange) + { + mVariable2Range = *pRange; + // Highlight the resulting range. + mxVariable2RangeEdit->StartUpdateData(); + } + else + { + mVariable2Range = ScRange( ScAddress::INITIALIZE_INVALID); + } + } + else if ( mpActiveEdit == mxOutputRangeEdit.get() ) + { + ScRangeList aRangeList; + bool bValid = ParseWithNames( aRangeList, mxOutputRangeEdit->GetText(), mDocument); + const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr; + if (pRange) + { + mOutputAddress = pRange->aStart; + + // Crop output range to top left address for Edit field. + if (pRange->aStart != pRange->aEnd) + { + ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ? + ScRefFlags::ADDR_ABS : + ScRefFlags::ADDR_ABS_3D; + OUString aReferenceString = mOutputAddress.Format(nFormat, &mDocument, mDocument.GetAddressConvention()); + mxOutputRangeEdit->SetRefString( aReferenceString ); + } + + // Highlight the resulting range. + mxOutputRangeEdit->StartUpdateData(); + } + else + { + mOutputAddress = ScAddress( ScAddress::INITIALIZE_INVALID); + } + } + } + + ValidateDialogInput(); +} + +void ScStatisticsTwoVariableDialog::CalculateInputAndWriteToOutput() +{ + OUString aUndo(ScResId(GetUndoNameId())); + ScDocShell* pDocShell = mViewData.GetDocShell(); + SfxUndoManager* pUndoManager = pDocShell->GetUndoManager(); + pUndoManager->EnterListAction( aUndo, aUndo, 0, mViewData.GetViewShell()->GetViewShellId() ); + + ScRange aOutputRange = ApplyOutput(pDocShell); + + pUndoManager->LeaveListAction(); + pDocShell->PostPaint( aOutputRange, PaintPartFlags::Grid ); +} + +bool ScStatisticsTwoVariableDialog::InputRangesValid() +{ + return mVariable1Range.IsValid() && mVariable2Range.IsValid() && mOutputAddress.IsValid(); +} + +void ScStatisticsTwoVariableDialog::ValidateDialogInput() +{ + // Enable OK button if all inputs are ok. + mxButtonOk->set_sensitive(InputRangesValid()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |