1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <sfx2/dispatch.hxx>
12 #include <svl/zforlist.hxx>
13 #include <svl/undo.hxx>
15 #include "formulacell.hxx"
16 #include "rangelst.hxx"
17 #include "scitems.hxx"
19 #include "document.hxx"
20 #include "uiitems.hxx"
21 #include "reffact.hxx"
22 #include "scresid.hxx"
23 #include "docfunc.hxx"
24 #include "strload.hxx"
26 #include "StatisticsTwoVariableDialog.hxx"
28 ScStatisticsTwoVariableDialog::ScStatisticsTwoVariableDialog(
29 SfxBindings
* pSfxBindings
, SfxChildWindow
* pChildWindow
,
30 vcl::Window
* pParent
, ScViewData
* pViewData
, const OUString
& rID
, const OUString
& rUIXMLDescription
) :
31 ScAnyRefDlg ( pSfxBindings
, pChildWindow
, pParent
, rID
, rUIXMLDescription
),
32 mViewData ( pViewData
),
33 mDocument ( pViewData
->GetDocument() ),
34 mVariable1Range ( ScAddress::INITIALIZE_INVALID
),
35 mVariable2Range ( ScAddress::INITIALIZE_INVALID
),
36 mAddressDetails ( mDocument
->GetAddressConvention(), 0, 0 ),
37 mOutputAddress ( ScAddress::INITIALIZE_INVALID
),
38 mGroupedBy ( BY_COLUMN
),
39 mpActiveEdit ( NULL
),
40 mCurrentAddress ( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() ),
41 mDialogLostFocus( false )
43 get(mpVariable1RangeLabel
, "variable1-range-label");
44 get(mpVariable1RangeEdit
, "variable1-range-edit");
45 get(mpVariable1RangeButton
, "variable1-range-button");
46 mpVariable1RangeEdit
->SetReferences(this, mpVariable1RangeLabel
);
47 mpVariable1RangeButton
->SetReferences(this, mpVariable1RangeEdit
);
49 get(mpVariable2RangeLabel
, "variable2-range-label");
50 get(mpVariable2RangeEdit
, "variable2-range-edit");
51 get(mpVariable2RangeButton
, "variable2-range-button");
52 mpVariable2RangeEdit
->SetReferences(this, mpVariable2RangeLabel
);
53 mpVariable2RangeButton
->SetReferences(this, mpVariable2RangeEdit
);
55 get(mpOutputRangeLabel
, "output-range-label");
56 get(mpOutputRangeEdit
, "output-range-edit");
57 get(mpOutputRangeButton
, "output-range-button");
58 mpOutputRangeEdit
->SetReferences(this, mpOutputRangeLabel
);
59 mpOutputRangeButton
->SetReferences(this, mpOutputRangeEdit
);
61 get(mpButtonOk
, "ok");
63 get(mpGroupByColumnsRadio
, "groupedby-columns-radio");
64 get(mpGroupByRowsRadio
, "groupedby-rows-radio");
67 GetRangeFromSelection();
70 ScStatisticsTwoVariableDialog::~ScStatisticsTwoVariableDialog()
75 void ScStatisticsTwoVariableDialog::dispose()
77 mpVariable1RangeLabel
.clear();
78 mpVariable1RangeEdit
.clear();
79 mpVariable1RangeButton
.clear();
80 mpVariable2RangeLabel
.clear();
81 mpVariable2RangeEdit
.clear();
82 mpVariable2RangeButton
.clear();
83 mpOutputRangeLabel
.clear();
84 mpOutputRangeEdit
.clear();
85 mpOutputRangeButton
.clear();
87 mpGroupByColumnsRadio
.clear();
88 mpGroupByRowsRadio
.clear();
90 ScAnyRefDlg::dispose();
93 void ScStatisticsTwoVariableDialog::Init()
95 mpButtonOk
->SetClickHdl( LINK( this, ScStatisticsTwoVariableDialog
, OkClicked
) );
96 mpButtonOk
->Enable(false);
98 Link
<> aLink
= LINK( this, ScStatisticsTwoVariableDialog
, GetFocusHandler
);
99 mpVariable1RangeEdit
->SetGetFocusHdl( aLink
);
100 mpVariable1RangeButton
->SetGetFocusHdl( aLink
);
101 mpVariable2RangeEdit
->SetGetFocusHdl( aLink
);
102 mpVariable2RangeButton
->SetGetFocusHdl( aLink
);
103 mpOutputRangeEdit
->SetGetFocusHdl( aLink
);
104 mpOutputRangeButton
->SetGetFocusHdl( aLink
);
106 aLink
= LINK( this, ScStatisticsTwoVariableDialog
, LoseFocusHandler
);
107 mpVariable1RangeEdit
->SetLoseFocusHdl( aLink
);
108 mpVariable1RangeButton
->SetLoseFocusHdl( aLink
);
109 mpVariable2RangeEdit
->SetLoseFocusHdl( aLink
);
110 mpVariable2RangeButton
->SetLoseFocusHdl( aLink
);
111 mpOutputRangeEdit
->SetLoseFocusHdl( aLink
);
112 mpOutputRangeButton
->SetLoseFocusHdl( aLink
);
114 aLink
= LINK( this, ScStatisticsTwoVariableDialog
, RefInputModifyHandler
);
115 mpVariable1RangeEdit
->SetModifyHdl( aLink
);
116 mpVariable2RangeEdit
->SetModifyHdl( aLink
);
117 mpOutputRangeEdit
->SetModifyHdl( aLink
);
119 mpOutputRangeEdit
->GrabFocus();
121 mpGroupByColumnsRadio
->SetToggleHdl( LINK( this, ScStatisticsTwoVariableDialog
, GroupByChanged
) );
122 mpGroupByRowsRadio
->SetToggleHdl( LINK( this, ScStatisticsTwoVariableDialog
, GroupByChanged
) );
124 mpGroupByColumnsRadio
->Check(true);
125 mpGroupByRowsRadio
->Check(false);
128 void ScStatisticsTwoVariableDialog::GetRangeFromSelection()
130 OUString aCurrentString
;
132 ScRange aCurrentRange
;
133 mViewData
->GetSimpleArea(aCurrentRange
);
135 if (aCurrentRange
.aEnd
.Col() - aCurrentRange
.aStart
.Col() == 1)
137 mVariable1Range
= aCurrentRange
;
138 mVariable1Range
.aEnd
.SetCol(mVariable1Range
.aStart
.Col());
139 aCurrentString
= mVariable1Range
.Format(SCR_ABS_3D
, mDocument
, mAddressDetails
);
140 mpVariable1RangeEdit
->SetText(aCurrentString
);
142 mVariable2Range
= aCurrentRange
;
143 mVariable2Range
.aStart
.SetCol(mVariable2Range
.aEnd
.Col());
144 aCurrentString
= mVariable2Range
.Format(SCR_ABS_3D
, mDocument
, mAddressDetails
);
145 mpVariable2RangeEdit
->SetText(aCurrentString
);
149 mVariable1Range
= aCurrentRange
;
150 aCurrentString
= mVariable1Range
.Format(SCR_ABS_3D
, mDocument
, mAddressDetails
);
151 mpVariable1RangeEdit
->SetText(aCurrentString
);
155 void ScStatisticsTwoVariableDialog::SetActive()
157 if ( mDialogLostFocus
)
159 mDialogLostFocus
= false;
161 mpActiveEdit
->GrabFocus();
170 void ScStatisticsTwoVariableDialog::SetReference( const ScRange
& rReferenceRange
, ScDocument
* pDocument
)
172 if ( mpActiveEdit
!= nullptr )
174 if ( rReferenceRange
.aStart
!= rReferenceRange
.aEnd
)
175 RefInputStart( mpActiveEdit
);
177 OUString aReferenceString
;
179 if ( mpActiveEdit
== mpVariable1RangeEdit
)
181 mVariable1Range
= rReferenceRange
;
182 aReferenceString
= mVariable1Range
.Format(SCR_ABS_3D
, pDocument
, mAddressDetails
);
183 mpVariable1RangeEdit
->SetRefString(aReferenceString
);
185 else if ( mpActiveEdit
== mpVariable2RangeEdit
)
187 mVariable2Range
= rReferenceRange
;
188 aReferenceString
= mVariable2Range
.Format(SCR_ABS_3D
, pDocument
, mAddressDetails
);
189 mpVariable2RangeEdit
->SetRefString(aReferenceString
);
191 else if ( mpActiveEdit
== mpOutputRangeEdit
)
193 mOutputAddress
= rReferenceRange
.aStart
;
195 sal_uInt16 nFormat
= ( mOutputAddress
.Tab() == mCurrentAddress
.Tab() ) ? SCA_ABS
: SCA_ABS_3D
;
196 aReferenceString
= mOutputAddress
.Format(nFormat
, pDocument
, pDocument
->GetAddressConvention());
197 mpOutputRangeEdit
->SetRefString( aReferenceString
);
201 // Enable OK if all ranges are set.
202 if (mVariable1Range
.IsValid() && mVariable2Range
.IsValid() && mOutputAddress
.IsValid())
203 mpButtonOk
->Enable();
205 mpButtonOk
->Disable();
208 IMPL_LINK( ScStatisticsTwoVariableDialog
, OkClicked
, PushButton
*, /*pButton*/ )
210 CalculateInputAndWriteToOutput();
215 IMPL_LINK( ScStatisticsTwoVariableDialog
, GetFocusHandler
, Control
*, pCtrl
)
218 if( pCtrl
== mpVariable1RangeEdit
219 || pCtrl
== mpVariable1RangeButton
)
221 mpActiveEdit
= mpVariable1RangeEdit
;
223 else if( pCtrl
== mpVariable2RangeEdit
224 || pCtrl
== mpVariable2RangeButton
)
226 mpActiveEdit
= mpVariable2RangeEdit
;
228 else if( pCtrl
== mpOutputRangeEdit
229 || pCtrl
== mpOutputRangeButton
)
231 mpActiveEdit
= mpOutputRangeEdit
;
235 mpActiveEdit
->SetSelection( Selection( 0, SELECTION_MAX
) );
240 IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog
, LoseFocusHandler
)
242 mDialogLostFocus
= !IsActive();
246 IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog
, GroupByChanged
)
248 if (mpGroupByColumnsRadio
->IsChecked())
249 mGroupedBy
= BY_COLUMN
;
250 else if (mpGroupByRowsRadio
->IsChecked())
256 IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog
, RefInputModifyHandler
)
260 if ( mpActiveEdit
== mpVariable1RangeEdit
)
262 ScRangeList aRangeList
;
263 bool bValid
= ParseWithNames( aRangeList
, mpVariable1RangeEdit
->GetText(), mDocument
);
264 const ScRange
* pRange
= (bValid
&& aRangeList
.size() == 1) ? aRangeList
[0] : nullptr;
267 mVariable1Range
= *pRange
;
268 // Highlight the resulting range.
269 mpVariable1RangeEdit
->StartUpdateData();
273 mVariable1Range
= ScRange( ScAddress::INITIALIZE_INVALID
);
276 else if ( mpActiveEdit
== mpVariable2RangeEdit
)
278 ScRangeList aRangeList
;
279 bool bValid
= ParseWithNames( aRangeList
, mpVariable2RangeEdit
->GetText(), mDocument
);
280 const ScRange
* pRange
= (bValid
&& aRangeList
.size() == 1) ? aRangeList
[0] : nullptr;
283 mVariable2Range
= *pRange
;
284 // Highlight the resulting range.
285 mpVariable2RangeEdit
->StartUpdateData();
289 mVariable2Range
= ScRange( ScAddress::INITIALIZE_INVALID
);
292 else if ( mpActiveEdit
== mpOutputRangeEdit
)
294 ScRangeList aRangeList
;
295 bool bValid
= ParseWithNames( aRangeList
, mpOutputRangeEdit
->GetText(), mDocument
);
296 const ScRange
* pRange
= (bValid
&& aRangeList
.size() == 1) ? aRangeList
[0] : nullptr;
299 mOutputAddress
= pRange
->aStart
;
301 // Crop output range to top left address for Edit field.
302 if (pRange
->aStart
!= pRange
->aEnd
)
304 sal_uInt16 nFormat
= ( mOutputAddress
.Tab() == mCurrentAddress
.Tab() ) ? SCA_ABS
: SCA_ABS_3D
;
305 OUString aReferenceString
= mOutputAddress
.Format(nFormat
, mDocument
, mDocument
->GetAddressConvention());
306 mpOutputRangeEdit
->SetRefString( aReferenceString
);
309 // Highlight the resulting range.
310 mpOutputRangeEdit
->StartUpdateData();
314 mOutputAddress
= ScAddress( ScAddress::INITIALIZE_INVALID
);
319 // Enable OK if all ranges are set.
320 if (mVariable1Range
.IsValid() && mVariable2Range
.IsValid() && mOutputAddress
.IsValid())
321 mpButtonOk
->Enable();
323 mpButtonOk
->Disable();
328 void ScStatisticsTwoVariableDialog::CalculateInputAndWriteToOutput()
330 OUString
aUndo(SC_STRLOAD(RID_STATISTICS_DLGS
, GetUndoNameId()));
331 ScDocShell
* pDocShell
= mViewData
->GetDocShell();
332 svl::IUndoManager
* pUndoManager
= pDocShell
->GetUndoManager();
333 pUndoManager
->EnterListAction( aUndo
, aUndo
);
335 ScRange aOutputRange
= ApplyOutput(pDocShell
);
337 pUndoManager
->LeaveListAction();
338 pDocShell
->PostPaint( aOutputRange
, PAINT_GRID
);
341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */