LibreOffice Module sc (master) 1
StatisticsInputOutputDialog.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{
23 ScRangeList aRangeList;
24 for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
25 {
26 ScRange aColumnRange (
27 ScAddress(inCol, aStart.Row(), aTab),
28 ScAddress(inCol, aEnd.Row(), aTab) );
29
30 aRangeList.push_back(aColumnRange);
31 }
32 return aRangeList;
33}
34
36{
37 ScRangeList aRangeList;
38 for (SCROW inRow = aStart.Row(); inRow <= aEnd.Row(); inRow++)
39 {
40 ScRange aRowRange (
41 ScAddress(aStart.Col(), inRow, aTab),
42 ScAddress(aEnd.Col(), inRow, aTab) );
43
44 aRangeList.push_back(aRowRange);
45 }
46 return aRangeList;
47}
48
50 SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
51 weld::Window* pParent, ScViewData& rViewData, const OUString& rUIXMLDescription, const OUString& rID)
52 : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID)
53 , mxInputRangeLabel(m_xBuilder->weld_label("input-range-label"))
54 , mxInputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("input-range-edit")))
55 , mxInputRangeButton(new formula::RefButton(m_xBuilder->weld_button("input-range-button")))
56 , mxOutputRangeLabel(m_xBuilder->weld_label("output-range-label"))
57 , mxOutputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("output-range-edit")))
58 , mxOutputRangeButton(new formula::RefButton(m_xBuilder->weld_button("output-range-button")))
59 , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button("groupedby-columns-radio"))
60 , mxGroupByRowsRadio(m_xBuilder->weld_radio_button("groupedby-rows-radio"))
61 , mViewData(rViewData)
62 , mDocument(rViewData.GetDocument())
63 , mInputRange(ScAddress::INITIALIZE_INVALID)
64 , mAddressDetails(mDocument.GetAddressConvention(), 0, 0)
65 , mOutputAddress(ScAddress::INITIALIZE_INVALID)
66 , mGroupedBy(BY_COLUMN)
67 , mxButtonOk(m_xBuilder->weld_button("ok"))
68 , mxButtonCancel(m_xBuilder->weld_button("cancel"))
69 , mpActiveEdit(nullptr)
70 , mCurrentAddress(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo())
71 , mDialogLostFocus(false)
72{
73 mxInputRangeEdit->SetReferences(this, mxInputRangeLabel.get());
74 mxInputRangeButton->SetReferences(this, mxInputRangeEdit.get());
75
76 mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get());
77 mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get());
78
79 Init();
81}
82
84{
85}
86
88{
89 mxButtonCancel->connect_clicked( LINK( this, ScStatisticsInputOutputDialog, ButtonClicked ) );
90 mxButtonOk->connect_clicked( LINK( this, ScStatisticsInputOutputDialog, ButtonClicked ) );
91 mxButtonOk->set_sensitive(false);
92
93 Link<formula::RefEdit&,void> aEditLink = LINK( this, ScStatisticsInputOutputDialog, GetEditFocusHandler );
94 mxInputRangeEdit->SetGetFocusHdl( aEditLink );
95 mxOutputRangeEdit->SetGetFocusHdl( aEditLink );
96 Link<formula::RefButton&,void> aButtonLink = LINK( this, ScStatisticsInputOutputDialog, GetButtonFocusHandler );
97 mxInputRangeButton->SetGetFocusHdl( aButtonLink );
98 mxOutputRangeButton->SetGetFocusHdl( aButtonLink );
99
100 aEditLink = LINK( this, ScStatisticsInputOutputDialog, LoseEditFocusHandler );
101 mxInputRangeEdit->SetLoseFocusHdl( aEditLink );
102 mxOutputRangeEdit->SetLoseFocusHdl( aEditLink );
103 aButtonLink = LINK( this, ScStatisticsInputOutputDialog, LoseButtonFocusHandler );
104 mxInputRangeButton->SetLoseFocusHdl( aButtonLink );
105 mxOutputRangeButton->SetLoseFocusHdl( aButtonLink );
106
107 Link<formula::RefEdit&,void> aLink2 = LINK( this, ScStatisticsInputOutputDialog, RefInputModifyHandler);
108 mxInputRangeEdit->SetModifyHdl( aLink2);
109 mxOutputRangeEdit->SetModifyHdl( aLink2);
110
111 mxOutputRangeEdit->GrabFocus();
112
113 mxGroupByColumnsRadio->connect_toggled( LINK( this, ScStatisticsInputOutputDialog, GroupByChanged ) );
114 mxGroupByRowsRadio->connect_toggled( LINK( this, ScStatisticsInputOutputDialog, GroupByChanged ) );
115
116 mxGroupByColumnsRadio->set_active(true);
117 mxGroupByRowsRadio->set_active(false);
118}
119
121{
124 mxInputRangeEdit->SetText(aCurrentString);
125}
126
128{
129 if ( mDialogLostFocus )
130 {
131 mDialogLostFocus = false;
132 if( mpActiveEdit )
134 }
135 else
136 {
137 m_xDialog->grab_focus();
138 }
139 RefInputDone();
140}
141
142void ScStatisticsInputOutputDialog::SetReference( const ScRange& rReferenceRange, ScDocument& rDocument )
143{
144 if ( mpActiveEdit )
145 {
146 if ( rReferenceRange.aStart != rReferenceRange.aEnd )
148
149 OUString aReferenceString;
150
151 if (mpActiveEdit == mxInputRangeEdit.get())
152 {
153 mInputRange = rReferenceRange;
154 aReferenceString = mInputRange.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
155 mxInputRangeEdit->SetRefString( aReferenceString );
156 }
157 else if (mpActiveEdit == mxOutputRangeEdit.get())
158 {
159 mOutputAddress = rReferenceRange.aStart;
160
161 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
164 aReferenceString = mOutputAddress.Format(nFormat, &rDocument, rDocument.GetAddressConvention());
165 mxOutputRangeEdit->SetRefString( aReferenceString );
166 }
167 }
168
170}
171
172IMPL_LINK( ScStatisticsInputOutputDialog, ButtonClicked, weld::Button&, rButton, void )
173{
174 if (&rButton == mxButtonOk.get())
175 {
176 CalculateInputAndWriteToOutput();
177 response(RET_OK);
178 }
179 else
180 response(RET_CANCEL);
181}
182
183IMPL_LINK(ScStatisticsInputOutputDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void)
184{
185 mpActiveEdit = nullptr;
186
187 if (&rCtrl == mxInputRangeEdit.get())
188 mpActiveEdit = mxInputRangeEdit.get();
189 if (&rCtrl == mxOutputRangeEdit.get())
190 mpActiveEdit = mxOutputRangeEdit.get();
191
192 if (mpActiveEdit)
193 mpActiveEdit->SelectAll();
194}
195
196IMPL_LINK(ScStatisticsInputOutputDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void)
197{
198 mpActiveEdit = nullptr;
199
200 if (&rCtrl == mxInputRangeButton.get())
201 mpActiveEdit = mxInputRangeEdit.get();
202 else if (&rCtrl == mxOutputRangeButton.get())
203 mpActiveEdit = mxOutputRangeEdit.get();
204
205 if (mpActiveEdit)
206 mpActiveEdit->SelectAll();
207}
208
210{
211 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
212}
213
215{
216 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
217}
218
220{
221 if (mxGroupByColumnsRadio->get_active())
222 mGroupedBy = BY_COLUMN;
223 else if (mxGroupByRowsRadio->get_active())
224 mGroupedBy = BY_ROW;
225
226 ValidateDialogInput();
227}
228
230{
231 if ( mpActiveEdit )
232 {
233 if (mpActiveEdit == mxInputRangeEdit.get())
234 {
235 ScRangeList aRangeList;
236 bool bValid = ParseWithNames( aRangeList, mxInputRangeEdit->GetText(), mDocument);
237 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
238 if (pRange)
239 {
240 mInputRange = *pRange;
241 // Highlight the resulting range.
242 mxInputRangeEdit->StartUpdateData();
243 }
244 else
245 {
247 }
248 }
249 else if (mpActiveEdit == mxOutputRangeEdit.get())
250 {
251 ScRangeList aRangeList;
252 bool bValid = ParseWithNames( aRangeList, mxOutputRangeEdit->GetText(), mDocument);
253 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
254 if (pRange)
255 {
256 mOutputAddress = pRange->aStart;
257
258 // Crop output range to top left address for Edit field.
259 if (pRange->aStart != pRange->aEnd)
260 {
261 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
264 OUString aReferenceString = mOutputAddress.Format(nFormat, &mDocument, mDocument.GetAddressConvention());
265 mxOutputRangeEdit->SetRefString( aReferenceString );
266 }
267
268 // Highlight the resulting range.
269 mxOutputRangeEdit->StartUpdateData();
270 }
271 else
272 {
273 mOutputAddress = ScAddress( ScAddress::INITIALIZE_INVALID);
274 }
275 }
276 }
277
278 ValidateDialogInput();
279}
280
282{
283 OUString aUndo(ScResId(GetUndoNameId()));
284 ScDocShell* pDocShell = mViewData.GetDocShell();
285 SfxUndoManager* pUndoManager = pDocShell->GetUndoManager();
286 pUndoManager->EnterListAction( aUndo, aUndo, 0, mViewData.GetViewShell()->GetViewShellId() );
287
288 ScRange aOutputRange = ApplyOutput(pDocShell);
289
290 pUndoManager->LeaveListAction();
291 pDocShell->PostPaint( aOutputRange, PaintPartFlags::Grid );
292}
293
295{
297}
298
300{
301 // Enable OK button if all inputs are ok.
302 mxButtonOk->set_sensitive(InputRangesValid());
303}
304
305/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(ScStatisticsInputOutputDialog, LoseEditFocusHandler, formula::RefEdit &, void)
IMPL_LINK(ScStatisticsInputOutputDialog, ButtonClicked, weld::Button &, rButton, void)
ScRefFlags
Definition: address.hxx:158
Reference< XExecutableDialog > m_xDialog
SCTAB Tab() const
Definition: address.hxx:283
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
SCROW Row() const
Definition: address.hxx:274
@ 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:2968
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:492
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
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:745
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:775
std::unique_ptr< formula::RefButton > mxOutputRangeButton
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
std::unique_ptr< formula::RefButton > mxInputRangeButton
std::unique_ptr< weld::Button > mxButtonCancel
std::unique_ptr< weld::Label > mxInputRangeLabel
static ScRangeList MakeColumnRangeList(SCTAB aTab, ScAddress const &aStart, ScAddress const &aEnd)
std::unique_ptr< weld::RadioButton > mxGroupByColumnsRadio
virtual TranslateId GetUndoNameId()=0
virtual ScRange ApplyOutput(ScDocShell *pDocShell)=0
std::unique_ptr< formula::RefEdit > mxInputRangeEdit
ScStatisticsInputOutputDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData, const OUString &rUIXMLDescription, const OUString &rID)
std::unique_ptr< weld::Button > mxButtonOk
static ScRangeList MakeRowRangeList(SCTAB aTab, ScAddress const &aStart, ScAddress const &aEnd)
std::unique_ptr< weld::Label > mxOutputRangeLabel
std::unique_ptr< weld::RadioButton > mxGroupByRowsRadio
std::unique_ptr< formula::RefEdit > mxOutputRangeEdit
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:1182
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
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
RET_OK
RET_CANCEL