LibreOffice Module sc (master) 1
StatisticsTwoVariableDialog.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 */
10
11#include <svl/undo.hxx>
12
13#include <rangelst.hxx>
14#include <docsh.hxx>
15#include <document.hxx>
16#include <scresid.hxx>
17#include <tabvwsh.hxx>
18
20
22 SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
23 weld::Window* pParent, ScViewData& rViewData, const OUString& rUIXMLDescription, const OString& rID)
24 : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID)
25 , mxVariable1RangeLabel(m_xBuilder->weld_label("variable1-range-label"))
26 , mxVariable1RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("variable1-range-edit")))
27 , mxVariable1RangeButton(new formula::RefButton(m_xBuilder->weld_button("variable1-range-button")))
28 , mxVariable2RangeLabel(m_xBuilder->weld_label("variable2-range-label"))
29 , mxVariable2RangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("variable2-range-edit")))
30 , mxVariable2RangeButton(new formula::RefButton(m_xBuilder->weld_button("variable2-range-button")))
31 , mxOutputRangeLabel(m_xBuilder->weld_label("output-range-label"))
32 , mxOutputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("output-range-edit")))
33 , mxOutputRangeButton(new formula::RefButton(m_xBuilder->weld_button("output-range-button")))
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("ok"))
42 , mxButtonCancel(m_xBuilder->weld_button("cancel"))
43 , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button("groupedby-columns-radio"))
44 , mxGroupByRowsRadio(m_xBuilder->weld_radio_button("groupedby-rows-radio"))
45 , mpActiveEdit(nullptr)
46 , mCurrentAddress(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() )
47 , mDialogLostFocus(false)
48{
49 mxVariable1RangeEdit->SetReferences(this, mxVariable1RangeLabel.get());
50 mxVariable1RangeButton->SetReferences(this, mxVariable1RangeEdit.get());
51
52 mxVariable2RangeEdit->SetReferences(this, mxVariable2RangeLabel.get());
53 mxVariable2RangeButton->SetReferences(this, mxVariable2RangeEdit.get());
54
55 mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get());
56 mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get());
57
58 Init();
60}
61
63{
64}
65
67{
68 mxButtonCancel->connect_clicked( LINK( this, ScStatisticsTwoVariableDialog, ButtonClicked ) );
69 mxButtonOk->connect_clicked( LINK( this, ScStatisticsTwoVariableDialog, ButtonClicked ) );
70 mxButtonOk->set_sensitive(false);
71
72 Link<formula::RefEdit&,void> aEditLink = LINK( this, ScStatisticsTwoVariableDialog, GetEditFocusHandler );
73 mxVariable1RangeEdit->SetGetFocusHdl( aEditLink );
74 mxVariable2RangeEdit->SetGetFocusHdl( aEditLink );
75 mxOutputRangeEdit->SetGetFocusHdl( aEditLink );
76
77 Link<formula::RefButton&,void> aButtonLink = LINK( this, ScStatisticsTwoVariableDialog, GetButtonFocusHandler );
78 mxVariable1RangeButton->SetGetFocusHdl( aButtonLink );
79 mxVariable2RangeButton->SetGetFocusHdl( aButtonLink );
80 mxOutputRangeButton->SetGetFocusHdl( aButtonLink );
81
82 aEditLink = LINK( this, ScStatisticsTwoVariableDialog, LoseEditFocusHandler );
83 mxVariable1RangeEdit->SetLoseFocusHdl( aEditLink );
84 mxVariable2RangeEdit->SetLoseFocusHdl( aEditLink );
85 mxOutputRangeEdit->SetLoseFocusHdl( aEditLink );
86
87 aButtonLink = LINK( this, ScStatisticsTwoVariableDialog, LoseButtonFocusHandler );
88 mxVariable1RangeButton->SetLoseFocusHdl( aButtonLink );
89 mxVariable2RangeButton->SetLoseFocusHdl( aButtonLink );
90 mxOutputRangeButton->SetLoseFocusHdl( aButtonLink );
91
92 Link<formula::RefEdit&,void> aLink2 = LINK( this, ScStatisticsTwoVariableDialog, RefInputModifyHandler);
93 mxVariable1RangeEdit->SetModifyHdl( aLink2);
94 mxVariable2RangeEdit->SetModifyHdl( aLink2);
95 mxOutputRangeEdit->SetModifyHdl( aLink2);
96
97 mxOutputRangeEdit->GrabFocus();
98
99 mxGroupByColumnsRadio->connect_toggled( LINK( this, ScStatisticsTwoVariableDialog, GroupByChanged ) );
100 mxGroupByRowsRadio->connect_toggled( LINK( this, ScStatisticsTwoVariableDialog, GroupByChanged ) );
101
102 mxGroupByColumnsRadio->set_active(true);
103 mxGroupByRowsRadio->set_active(false);
104}
105
107{
108 OUString aCurrentString;
109
110 ScRange aCurrentRange;
111 mViewData.GetSimpleArea(aCurrentRange);
112
113 if (aCurrentRange.aEnd.Col() - aCurrentRange.aStart.Col() == 1)
114 {
115 mVariable1Range = aCurrentRange;
118 mxVariable1RangeEdit->SetText(aCurrentString);
119
120 mVariable2Range = aCurrentRange;
123 mxVariable2RangeEdit->SetText(aCurrentString);
124 }
125 else
126 {
127 mVariable1Range = aCurrentRange;
129 mxVariable1RangeEdit->SetText(aCurrentString);
130 }
131}
132
134{
135 if ( mDialogLostFocus )
136 {
137 mDialogLostFocus = false;
138 if( mpActiveEdit )
140 }
141 else
142 {
143 m_xDialog->grab_focus();
144 }
145 RefInputDone();
146}
147
148void ScStatisticsTwoVariableDialog::SetReference( const ScRange& rReferenceRange, ScDocument& rDocument )
149{
150 if ( mpActiveEdit != nullptr )
151 {
152 if ( rReferenceRange.aStart != rReferenceRange.aEnd )
154
155 OUString aReferenceString;
156
157 if ( mpActiveEdit == mxVariable1RangeEdit.get() )
158 {
159 mVariable1Range = rReferenceRange;
160 aReferenceString = mVariable1Range.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
161 mxVariable1RangeEdit->SetRefString(aReferenceString);
162 }
163 else if ( mpActiveEdit == mxVariable2RangeEdit.get() )
164 {
165 mVariable2Range = rReferenceRange;
166 aReferenceString = mVariable2Range.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
167 mxVariable2RangeEdit->SetRefString(aReferenceString);
168 }
169 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
170 {
171 mOutputAddress = rReferenceRange.aStart;
172
173 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
176 aReferenceString = mOutputAddress.Format(nFormat, &rDocument, rDocument.GetAddressConvention());
177 mxOutputRangeEdit->SetRefString( aReferenceString );
178 }
179 }
180
182}
183
184IMPL_LINK( ScStatisticsTwoVariableDialog, ButtonClicked, weld::Button&, rButton, void )
185{
186 if (&rButton == mxButtonOk.get())
187 {
188 CalculateInputAndWriteToOutput();
189 response(RET_OK);
190 }
191 else
192 response(RET_CANCEL);
193}
194
195IMPL_LINK(ScStatisticsTwoVariableDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void)
196{
197 mpActiveEdit = nullptr;
198 if (&rCtrl == mxVariable1RangeEdit.get())
199 {
200 mpActiveEdit = mxVariable1RangeEdit.get();
201 }
202 else if (&rCtrl == mxVariable2RangeEdit.get())
203 {
204 mpActiveEdit = mxVariable2RangeEdit.get();
205 }
206 else if (&rCtrl == mxOutputRangeEdit.get())
207 {
208 mpActiveEdit = mxOutputRangeEdit.get();
209 }
210
211 if( mpActiveEdit )
212 mpActiveEdit->SelectAll();
213}
214
215IMPL_LINK( ScStatisticsTwoVariableDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void )
216{
217 mpActiveEdit = nullptr;
218 if (&rCtrl == mxVariable1RangeButton.get())
219 {
220 mpActiveEdit = mxVariable1RangeEdit.get();
221 }
222 else if (&rCtrl == mxVariable2RangeButton.get())
223 {
224 mpActiveEdit = mxVariable2RangeEdit.get();
225 }
226 else if (&rCtrl == mxOutputRangeButton.get())
227 {
228 mpActiveEdit = mxOutputRangeEdit.get();
229 }
230
231 if( mpActiveEdit )
232 mpActiveEdit->SelectAll();
233}
234
236{
237 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
238}
239
241{
242 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
243}
244
246{
247 if (mxGroupByColumnsRadio->get_active())
248 mGroupedBy = BY_COLUMN;
249 else if (mxGroupByRowsRadio->get_active())
250 mGroupedBy = BY_ROW;
251
252 ValidateDialogInput();
253}
254
256{
257 if ( mpActiveEdit )
258 {
259 if (mpActiveEdit == mxVariable1RangeEdit.get())
260 {
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)
265 {
266 mVariable1Range = *pRange;
267 // Highlight the resulting range.
268 mxVariable1RangeEdit->StartUpdateData();
269 }
270 else
271 {
272 mVariable1Range = ScRange( ScAddress::INITIALIZE_INVALID);
273 }
274 }
275 else if ( mpActiveEdit == mxVariable2RangeEdit.get() )
276 {
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)
281 {
282 mVariable2Range = *pRange;
283 // Highlight the resulting range.
284 mxVariable2RangeEdit->StartUpdateData();
285 }
286 else
287 {
288 mVariable2Range = ScRange( ScAddress::INITIALIZE_INVALID);
289 }
290 }
291 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
292 {
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)
297 {
298 mOutputAddress = pRange->aStart;
299
300 // Crop output range to top left address for Edit field.
301 if (pRange->aStart != pRange->aEnd)
302 {
303 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
306 OUString aReferenceString = mOutputAddress.Format(nFormat, &mDocument, mDocument.GetAddressConvention());
307 mxOutputRangeEdit->SetRefString( aReferenceString );
308 }
309
310 // Highlight the resulting range.
311 mxOutputRangeEdit->StartUpdateData();
312 }
313 else
314 {
315 mOutputAddress = ScAddress( ScAddress::INITIALIZE_INVALID);
316 }
317 }
318 }
319
320 ValidateDialogInput();
321}
322
324{
325 OUString aUndo(ScResId(GetUndoNameId()));
326 ScDocShell* pDocShell = mViewData.GetDocShell();
327 SfxUndoManager* pUndoManager = pDocShell->GetUndoManager();
328 pUndoManager->EnterListAction( aUndo, aUndo, 0, mViewData.GetViewShell()->GetViewShellId() );
329
330 ScRange aOutputRange = ApplyOutput(pDocShell);
331
332 pUndoManager->LeaveListAction();
333 pDocShell->PostPaint( aOutputRange, PaintPartFlags::Grid );
334}
335
337{
339}
340
342{
343 // Enable OK button if all inputs are ok.
344 mxButtonOk->set_sensitive(InputRangesValid());
345}
346
347/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(ScStatisticsTwoVariableDialog, LoseEditFocusHandler, formula::RefEdit &, void)
IMPL_LINK(ScStatisticsTwoVariableDialog, ButtonClicked, weld::Button &, rButton, void)
ScRefFlags
Definition: address.hxx:158
Reference< XExecutableDialog > m_xDialog
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
bool IsValid() const
Definition: address.hxx:305
@ INITIALIZE_INVALID
Definition: address.hxx:221
SCCOL Col() const
Definition: address.hxx:279
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2945
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:500
size_t size() const
Definition: rangelst.hxx:89
OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2170
ScAddress aEnd
Definition: address.hxx:498
bool IsValid() const
Definition: address.hxx:544
ScAddress aStart
Definition: address.hxx:497
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:749
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:779
std::unique_ptr< formula::RefEdit > mxVariable2RangeEdit
std::unique_ptr< weld::Button > mxButtonCancel
std::unique_ptr< formula::RefEdit > mxVariable1RangeEdit
std::unique_ptr< weld::Button > mxButtonOk
std::unique_ptr< formula::RefButton > mxOutputRangeButton
std::unique_ptr< weld::RadioButton > mxGroupByRowsRadio
std::unique_ptr< weld::Label > mxOutputRangeLabel
std::unique_ptr< formula::RefButton > mxVariable1RangeButton
std::unique_ptr< weld::RadioButton > mxGroupByColumnsRadio
virtual ScRange ApplyOutput(ScDocShell *pDocShell)=0
std::unique_ptr< formula::RefEdit > mxOutputRangeEdit
std::unique_ptr< formula::RefButton > mxVariable2RangeButton
virtual TranslateId GetUndoNameId()=0
ScStatisticsTwoVariableDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData, const OUString &rUIXMLDescription, const OString &rID)
std::unique_ptr< weld::Label > mxVariable1RangeLabel
std::unique_ptr< weld::Label > mxVariable2RangeLabel
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1181
size_t LeaveListAction()
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
ViewShellId GetViewShellId() const override
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
RET_OK
RET_CANCEL