/* -*- 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 #include #include #include #include #include #include ScStatisticsTwoVariableDialog::ScStatisticsTwoVariableDialog( SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, weld::Window* pParent, ScViewData& rViewData, const OUString& rUIXMLDescription, const OUString& rID) : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID) , mxVariable1RangeLabel(m_xBuilder->weld_label(u"variable1-range-label"_ustr)) , mxVariable1RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"variable1-range-edit"_ustr))) , mxVariable1RangeButton(new formula::RefButton(m_xBuilder->weld_button(u"variable1-range-button"_ustr))) , mxVariable2RangeLabel(m_xBuilder->weld_label(u"variable2-range-label"_ustr)) , mxVariable2RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"variable2-range-edit"_ustr))) , mxVariable2RangeButton(new formula::RefButton(m_xBuilder->weld_button(u"variable2-range-button"_ustr))) , mxOutputRangeLabel(m_xBuilder->weld_label(u"output-range-label"_ustr)) , mxOutputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"output-range-edit"_ustr))) , mxOutputRangeButton(new formula::RefButton(m_xBuilder->weld_button(u"output-range-button"_ustr))) , 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(u"ok"_ustr)) , mxButtonCancel(m_xBuilder->weld_button(u"cancel"_ustr)) , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button(u"groupedby-columns-radio"_ustr)) , mxGroupByRowsRadio(m_xBuilder->weld_radio_button(u"groupedby-rows-radio"_ustr)) , 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 aEditLink = LINK( this, ScStatisticsTwoVariableDialog, GetEditFocusHandler ); mxVariable1RangeEdit->SetGetFocusHdl( aEditLink ); mxVariable2RangeEdit->SetGetFocusHdl( aEditLink ); mxOutputRangeEdit->SetGetFocusHdl( aEditLink ); Link 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 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: */