tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / StatisticsDialogs / StatisticsTwoVariableDialog.cxx
blobc0fcbc751dbcdb3350d2b0070d3e77bc3442e8e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
11 #include <svl/undo.hxx>
13 #include <rangelst.hxx>
14 #include <docsh.hxx>
15 #include <document.hxx>
16 #include <scresid.hxx>
17 #include <tabvwsh.hxx>
19 #include <StatisticsTwoVariableDialog.hxx>
21 ScStatisticsTwoVariableDialog::ScStatisticsTwoVariableDialog(
22 SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
23 weld::Window* pParent, ScViewData& rViewData, const OUString& rUIXMLDescription, const OUString& rID)
24 : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID)
25 , mxVariable1RangeLabel(m_xBuilder->weld_label(u"variable1-range-label"_ustr))
26 , mxVariable1RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"variable1-range-edit"_ustr)))
27 , mxVariable1RangeButton(new formula::RefButton(m_xBuilder->weld_button(u"variable1-range-button"_ustr)))
28 , mxVariable2RangeLabel(m_xBuilder->weld_label(u"variable2-range-label"_ustr))
29 , mxVariable2RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"variable2-range-edit"_ustr)))
30 , mxVariable2RangeButton(new formula::RefButton(m_xBuilder->weld_button(u"variable2-range-button"_ustr)))
31 , mxOutputRangeLabel(m_xBuilder->weld_label(u"output-range-label"_ustr))
32 , mxOutputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"output-range-edit"_ustr)))
33 , mxOutputRangeButton(new formula::RefButton(m_xBuilder->weld_button(u"output-range-button"_ustr)))
34 , mViewData(rViewData)
35 , mDocument(rViewData.GetDocument())
36 , mVariable1Range(ScAddress::INITIALIZE_INVALID)
37 , mVariable2Range(ScAddress::INITIALIZE_INVALID)
38 , mAddressDetails(mDocument.GetAddressConvention(), 0, 0 )
39 , mOutputAddress(ScAddress::INITIALIZE_INVALID)
40 , mGroupedBy(BY_COLUMN)
41 , mxButtonOk(m_xBuilder->weld_button(u"ok"_ustr))
42 , mxButtonCancel(m_xBuilder->weld_button(u"cancel"_ustr))
43 , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button(u"groupedby-columns-radio"_ustr))
44 , mxGroupByRowsRadio(m_xBuilder->weld_radio_button(u"groupedby-rows-radio"_ustr))
45 , mpActiveEdit(nullptr)
46 , mCurrentAddress(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() )
47 , mDialogLostFocus(false)
49 mxVariable1RangeEdit->SetReferences(this, mxVariable1RangeLabel.get());
50 mxVariable1RangeButton->SetReferences(this, mxVariable1RangeEdit.get());
52 mxVariable2RangeEdit->SetReferences(this, mxVariable2RangeLabel.get());
53 mxVariable2RangeButton->SetReferences(this, mxVariable2RangeEdit.get());
55 mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get());
56 mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get());
58 Init();
59 GetRangeFromSelection();
62 ScStatisticsTwoVariableDialog::~ScStatisticsTwoVariableDialog()
66 void ScStatisticsTwoVariableDialog::Init()
68 mxButtonCancel->connect_clicked( LINK( this, ScStatisticsTwoVariableDialog, ButtonClicked ) );
69 mxButtonOk->connect_clicked( LINK( this, ScStatisticsTwoVariableDialog, ButtonClicked ) );
70 mxButtonOk->set_sensitive(false);
72 Link<formula::RefEdit&,void> aEditLink = LINK( this, ScStatisticsTwoVariableDialog, GetEditFocusHandler );
73 mxVariable1RangeEdit->SetGetFocusHdl( aEditLink );
74 mxVariable2RangeEdit->SetGetFocusHdl( aEditLink );
75 mxOutputRangeEdit->SetGetFocusHdl( aEditLink );
77 Link<formula::RefButton&,void> aButtonLink = LINK( this, ScStatisticsTwoVariableDialog, GetButtonFocusHandler );
78 mxVariable1RangeButton->SetGetFocusHdl( aButtonLink );
79 mxVariable2RangeButton->SetGetFocusHdl( aButtonLink );
80 mxOutputRangeButton->SetGetFocusHdl( aButtonLink );
82 aEditLink = LINK( this, ScStatisticsTwoVariableDialog, LoseEditFocusHandler );
83 mxVariable1RangeEdit->SetLoseFocusHdl( aEditLink );
84 mxVariable2RangeEdit->SetLoseFocusHdl( aEditLink );
85 mxOutputRangeEdit->SetLoseFocusHdl( aEditLink );
87 aButtonLink = LINK( this, ScStatisticsTwoVariableDialog, LoseButtonFocusHandler );
88 mxVariable1RangeButton->SetLoseFocusHdl( aButtonLink );
89 mxVariable2RangeButton->SetLoseFocusHdl( aButtonLink );
90 mxOutputRangeButton->SetLoseFocusHdl( aButtonLink );
92 Link<formula::RefEdit&,void> aLink2 = LINK( this, ScStatisticsTwoVariableDialog, RefInputModifyHandler);
93 mxVariable1RangeEdit->SetModifyHdl( aLink2);
94 mxVariable2RangeEdit->SetModifyHdl( aLink2);
95 mxOutputRangeEdit->SetModifyHdl( aLink2);
97 mxOutputRangeEdit->GrabFocus();
99 mxGroupByColumnsRadio->connect_toggled( LINK( this, ScStatisticsTwoVariableDialog, GroupByChanged ) );
100 mxGroupByRowsRadio->connect_toggled( LINK( this, ScStatisticsTwoVariableDialog, GroupByChanged ) );
102 mxGroupByColumnsRadio->set_active(true);
103 mxGroupByRowsRadio->set_active(false);
106 void ScStatisticsTwoVariableDialog::GetRangeFromSelection()
108 OUString aCurrentString;
110 ScRange aCurrentRange;
111 mViewData.GetSimpleArea(aCurrentRange);
113 if (aCurrentRange.aEnd.Col() - aCurrentRange.aStart.Col() == 1)
115 mVariable1Range = aCurrentRange;
116 mVariable1Range.aEnd.SetCol(mVariable1Range.aStart.Col());
117 aCurrentString = mVariable1Range.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
118 mxVariable1RangeEdit->SetText(aCurrentString);
120 mVariable2Range = aCurrentRange;
121 mVariable2Range.aStart.SetCol(mVariable2Range.aEnd.Col());
122 aCurrentString = mVariable2Range.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
123 mxVariable2RangeEdit->SetText(aCurrentString);
125 else
127 mVariable1Range = aCurrentRange;
128 aCurrentString = mVariable1Range.Format(mDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
129 mxVariable1RangeEdit->SetText(aCurrentString);
133 void ScStatisticsTwoVariableDialog::SetActive()
135 if ( mDialogLostFocus )
137 mDialogLostFocus = false;
138 if( mpActiveEdit )
139 mpActiveEdit->GrabFocus();
141 else
143 m_xDialog->grab_focus();
145 RefInputDone();
148 void ScStatisticsTwoVariableDialog::SetReference( const ScRange& rReferenceRange, ScDocument& rDocument )
150 if ( mpActiveEdit != nullptr )
152 if ( rReferenceRange.aStart != rReferenceRange.aEnd )
153 RefInputStart( mpActiveEdit );
155 OUString aReferenceString;
157 if ( mpActiveEdit == mxVariable1RangeEdit.get() )
159 mVariable1Range = rReferenceRange;
160 aReferenceString = mVariable1Range.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
161 mxVariable1RangeEdit->SetRefString(aReferenceString);
163 else if ( mpActiveEdit == mxVariable2RangeEdit.get() )
165 mVariable2Range = rReferenceRange;
166 aReferenceString = mVariable2Range.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
167 mxVariable2RangeEdit->SetRefString(aReferenceString);
169 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
171 mOutputAddress = rReferenceRange.aStart;
173 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
174 ScRefFlags::ADDR_ABS :
175 ScRefFlags::ADDR_ABS_3D;
176 aReferenceString = mOutputAddress.Format(nFormat, &rDocument, rDocument.GetAddressConvention());
177 mxOutputRangeEdit->SetRefString( aReferenceString );
181 ValidateDialogInput();
184 IMPL_LINK( ScStatisticsTwoVariableDialog, ButtonClicked, weld::Button&, rButton, void )
186 if (&rButton == mxButtonOk.get())
188 CalculateInputAndWriteToOutput();
189 response(RET_OK);
191 else
192 response(RET_CANCEL);
195 IMPL_LINK(ScStatisticsTwoVariableDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void)
197 mpActiveEdit = nullptr;
198 if (&rCtrl == mxVariable1RangeEdit.get())
200 mpActiveEdit = mxVariable1RangeEdit.get();
202 else if (&rCtrl == mxVariable2RangeEdit.get())
204 mpActiveEdit = mxVariable2RangeEdit.get();
206 else if (&rCtrl == mxOutputRangeEdit.get())
208 mpActiveEdit = mxOutputRangeEdit.get();
211 if( mpActiveEdit )
212 mpActiveEdit->SelectAll();
215 IMPL_LINK( ScStatisticsTwoVariableDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void )
217 mpActiveEdit = nullptr;
218 if (&rCtrl == mxVariable1RangeButton.get())
220 mpActiveEdit = mxVariable1RangeEdit.get();
222 else if (&rCtrl == mxVariable2RangeButton.get())
224 mpActiveEdit = mxVariable2RangeEdit.get();
226 else if (&rCtrl == mxOutputRangeButton.get())
228 mpActiveEdit = mxOutputRangeEdit.get();
231 if( mpActiveEdit )
232 mpActiveEdit->SelectAll();
235 IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, LoseEditFocusHandler, formula::RefEdit&, void )
237 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
240 IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, LoseButtonFocusHandler, formula::RefButton&, void )
242 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
245 IMPL_LINK_NOARG(ScStatisticsTwoVariableDialog, GroupByChanged, weld::Toggleable&, void)
247 if (mxGroupByColumnsRadio->get_active())
248 mGroupedBy = BY_COLUMN;
249 else if (mxGroupByRowsRadio->get_active())
250 mGroupedBy = BY_ROW;
252 ValidateDialogInput();
255 IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, RefInputModifyHandler, formula::RefEdit&, void )
257 if ( mpActiveEdit )
259 if (mpActiveEdit == mxVariable1RangeEdit.get())
261 ScRangeList aRangeList;
262 bool bValid = ParseWithNames( aRangeList, mxVariable1RangeEdit->GetText(), mDocument);
263 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
264 if (pRange)
266 mVariable1Range = *pRange;
267 // Highlight the resulting range.
268 mxVariable1RangeEdit->StartUpdateData();
270 else
272 mVariable1Range = ScRange( ScAddress::INITIALIZE_INVALID);
275 else if ( mpActiveEdit == mxVariable2RangeEdit.get() )
277 ScRangeList aRangeList;
278 bool bValid = ParseWithNames( aRangeList, mxVariable2RangeEdit->GetText(), mDocument);
279 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
280 if (pRange)
282 mVariable2Range = *pRange;
283 // Highlight the resulting range.
284 mxVariable2RangeEdit->StartUpdateData();
286 else
288 mVariable2Range = ScRange( ScAddress::INITIALIZE_INVALID);
291 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
293 ScRangeList aRangeList;
294 bool bValid = ParseWithNames( aRangeList, mxOutputRangeEdit->GetText(), mDocument);
295 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
296 if (pRange)
298 mOutputAddress = pRange->aStart;
300 // Crop output range to top left address for Edit field.
301 if (pRange->aStart != pRange->aEnd)
303 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
304 ScRefFlags::ADDR_ABS :
305 ScRefFlags::ADDR_ABS_3D;
306 OUString aReferenceString = mOutputAddress.Format(nFormat, &mDocument, mDocument.GetAddressConvention());
307 mxOutputRangeEdit->SetRefString( aReferenceString );
310 // Highlight the resulting range.
311 mxOutputRangeEdit->StartUpdateData();
313 else
315 mOutputAddress = ScAddress( ScAddress::INITIALIZE_INVALID);
320 ValidateDialogInput();
323 void ScStatisticsTwoVariableDialog::CalculateInputAndWriteToOutput()
325 OUString aUndo(ScResId(GetUndoNameId()));
326 ScDocShell* pDocShell = mViewData.GetDocShell();
327 SfxUndoManager* pUndoManager = pDocShell->GetUndoManager();
328 pUndoManager->EnterListAction( aUndo, aUndo, 0, mViewData.GetViewShell()->GetViewShellId() );
330 ScRange aOutputRange = ApplyOutput(pDocShell);
332 pUndoManager->LeaveListAction();
333 pDocShell->PostPaint( aOutputRange, PaintPartFlags::Grid );
336 bool ScStatisticsTwoVariableDialog::InputRangesValid()
338 return mVariable1Range.IsValid() && mVariable2Range.IsValid() && mOutputAddress.IsValid();
341 void ScStatisticsTwoVariableDialog::ValidateDialogInput()
343 // Enable OK button if all inputs are ok.
344 mxButtonOk->set_sensitive(InputRangesValid());
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */