/* -*- 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 ScRangeList ScStatisticsInputOutputDialog::MakeColumnRangeList(SCTAB aTab, ScAddress const & aStart, ScAddress const & aEnd) { ScRangeList aRangeList; for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++) { ScRange aColumnRange ( ScAddress(inCol, aStart.Row(), aTab), ScAddress(inCol, aEnd.Row(), aTab) ); aRangeList.push_back(aColumnRange); } return aRangeList; } ScRangeList ScStatisticsInputOutputDialog::MakeRowRangeList(SCTAB aTab, ScAddress const & aStart, ScAddress const & aEnd) { ScRangeList aRangeList; for (SCROW inRow = aStart.Row(); inRow <= aEnd.Row(); inRow++) { ScRange aRowRange ( ScAddress(aStart.Col(), inRow, aTab), ScAddress(aEnd.Col(), inRow, aTab) ); aRangeList.push_back(aRowRange); } return aRangeList; } ScStatisticsInputOutputDialog::ScStatisticsInputOutputDialog( SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, weld::Window* pParent, ScViewData& rViewData, const OUString& rUIXMLDescription, const OUString& rID) : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID) , mxInputRangeLabel(m_xBuilder->weld_label(u"input-range-label"_ustr)) , mxInputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"input-range-edit"_ustr))) , mxInputRangeButton(new formula::RefButton(m_xBuilder->weld_button(u"input-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))) , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button(u"groupedby-columns-radio"_ustr)) , mxGroupByRowsRadio(m_xBuilder->weld_radio_button(u"groupedby-rows-radio"_ustr)) , mViewData(rViewData) , mDocument(rViewData.GetDocument()) , mInputRange(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)) , mpActiveEdit(nullptr) , mCurrentAddress(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo()) , mDialogLostFocus(false) { mxInputRangeEdit->SetReferences(this, mxInputRangeLabel.get()); mxInputRangeButton->SetReferences(this, mxInputRangeEdit.get()); mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get()); mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get()); Init(); GetRangeFromSelection(); } ScStatisticsInputOutputDialog::~ScStatisticsInputOutputDialog() { } void ScStatisticsInputOutputDialog::Init() { mxButtonCancel->connect_clicked( LINK( this, ScStatisticsInputOutputDialog, ButtonClicked ) ); mxButtonOk->connect_clicked( LINK( this, ScStatisticsInputOutputDialog, ButtonClicked ) ); mxButtonOk->set_sensitive(false); Link aEditLink = LINK( this, ScStatisticsInputOutputDialog, GetEditFocusHandler ); mxInputRangeEdit->SetGetFocusHdl( aEditLink ); mxOutputRangeEdit->SetGetFocusHdl( aEditLink ); Link aButtonLink = LINK( this, ScStatisticsInputOutputDialog, GetButtonFocusHandler ); mxInputRangeButton->SetGetFocusHdl( aButtonLink ); mxOutputRangeButton->SetGetFocusHdl( aButtonLink ); aEditLink = LINK( this, ScStatisticsInputOutputDialog, LoseEditFocusHandler ); mxInputRangeEdit->SetLoseFocusHdl( aEditLink ); mxOutputRangeEdit->SetLoseFocusHdl( aEditLink ); aButtonLink = LINK( this, ScStatisticsInputOutputDialog, LoseButtonFocusHandler ); mxInputRangeButton->SetLoseFocusHdl( aButtonLink ); mxOutputRangeButton->SetLoseFocusHdl( aButtonLink ); Link aLink2 = LINK( this, ScStatisticsInputOutputDialog, RefInputModifyHandler); mxInputRangeEdit->SetModifyHdl( aLink2); mxOutputRangeEdit->SetModifyHdl( aLink2); mxOutputRangeEdit->GrabFocus(); mxGroupByColumnsRadio->connect_toggled( LINK( this, ScStatisticsInputOutputDialog, GroupByChanged ) ); mxGroupByRowsRadio->connect_toggled( LINK( this, ScStatisticsInputOutputDialog, GroupByChanged ) ); mxGroupByColumnsRadio->set_active(true); mxGroupByRowsRadio->set_active(false); } void ScStatisticsInputOutputDialog::GetRangeFromSelection() { mViewData.GetSimpleArea(mInputRange); OUString aCurrentString(mInputRange.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails)); mxInputRangeEdit->SetText(aCurrentString); } void ScStatisticsInputOutputDialog::SetActive() { if ( mDialogLostFocus ) { mDialogLostFocus = false; if( mpActiveEdit ) mpActiveEdit->GrabFocus(); } else { m_xDialog->grab_focus(); } RefInputDone(); } void ScStatisticsInputOutputDialog::SetReference( const ScRange& rReferenceRange, ScDocument& rDocument ) { if ( mpActiveEdit ) { if ( rReferenceRange.aStart != rReferenceRange.aEnd ) RefInputStart( mpActiveEdit ); OUString aReferenceString; if (mpActiveEdit == mxInputRangeEdit.get()) { mInputRange = rReferenceRange; aReferenceString = mInputRange.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails); mxInputRangeEdit->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( ScStatisticsInputOutputDialog, ButtonClicked, weld::Button&, rButton, void ) { if (&rButton == mxButtonOk.get()) { CalculateInputAndWriteToOutput(); response(RET_OK); } else response(RET_CANCEL); } IMPL_LINK(ScStatisticsInputOutputDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void) { mpActiveEdit = nullptr; if (&rCtrl == mxInputRangeEdit.get()) mpActiveEdit = mxInputRangeEdit.get(); if (&rCtrl == mxOutputRangeEdit.get()) mpActiveEdit = mxOutputRangeEdit.get(); if (mpActiveEdit) mpActiveEdit->SelectAll(); } IMPL_LINK(ScStatisticsInputOutputDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void) { mpActiveEdit = nullptr; if (&rCtrl == mxInputRangeButton.get()) mpActiveEdit = mxInputRangeEdit.get(); else if (&rCtrl == mxOutputRangeButton.get()) mpActiveEdit = mxOutputRangeEdit.get(); if (mpActiveEdit) mpActiveEdit->SelectAll(); } IMPL_LINK_NOARG(ScStatisticsInputOutputDialog, LoseEditFocusHandler, formula::RefEdit&, void) { mDialogLostFocus = !m_xDialog->has_toplevel_focus(); } IMPL_LINK_NOARG(ScStatisticsInputOutputDialog, LoseButtonFocusHandler, formula::RefButton&, void) { mDialogLostFocus = !m_xDialog->has_toplevel_focus(); } IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, GroupByChanged, weld::Toggleable&, void ) { if (mxGroupByColumnsRadio->get_active()) mGroupedBy = BY_COLUMN; else if (mxGroupByRowsRadio->get_active()) mGroupedBy = BY_ROW; ValidateDialogInput(); } IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, RefInputModifyHandler, formula::RefEdit&, void ) { if ( mpActiveEdit ) { if (mpActiveEdit == mxInputRangeEdit.get()) { ScRangeList aRangeList; bool bValid = ParseWithNames( aRangeList, mxInputRangeEdit->GetText(), mDocument); const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr; if (pRange) { mInputRange = *pRange; // Highlight the resulting range. mxInputRangeEdit->StartUpdateData(); } else { mInputRange = 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 ScStatisticsInputOutputDialog::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 ScStatisticsInputOutputDialog::InputRangesValid() { return mInputRange.IsValid() && mOutputAddress.IsValid(); } void ScStatisticsInputOutputDialog::ValidateDialogInput() { // Enable OK button if all inputs are ok. mxButtonOk->set_sensitive(InputRangesValid()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */