Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / StatisticsDialogs / SamplingDialog.cxx
blob4c2529b42a241997e3db941ee31ee30844cfac73
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 <sfx2/dispatch.hxx>
12 #include <svl/zforlist.hxx>
13 #include <svl/undo.hxx>
15 #include "rangelst.hxx"
16 #include "scitems.hxx"
17 #include "docsh.hxx"
18 #include "document.hxx"
19 #include "uiitems.hxx"
20 #include "reffact.hxx"
21 #include "strload.hxx"
22 #include "docfunc.hxx"
23 #include "StatisticsDialogs.hrc"
25 #include <boost/random.hpp>
27 #include "SamplingDialog.hxx"
29 ScSamplingDialog::ScSamplingDialog(
30 SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
31 Window* pParent, ScViewData* pViewData ) :
32 ScAnyRefDlg ( pSfxBindings, pChildWindow, pParent,
33 "SamplingDialog", "modules/scalc/ui/samplingdialog.ui" ),
34 mpActiveEdit ( NULL ),
35 mViewData ( pViewData ),
36 mDocument ( pViewData->GetDocument() ),
37 mAddressDetails ( mDocument->GetAddressConvention(), 0, 0 ),
38 mCurrentAddress ( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ),
39 mDialogLostFocus( false )
41 get(mpInputRangeLabel, "input-range-label");
42 get(mpInputRangeEdit, "input-range-edit");
43 get(mpInputRangeButton, "input-range-button");
44 mpInputRangeEdit->SetReferences(this, mpInputRangeLabel);
45 mpInputRangeButton->SetReferences(this, mpInputRangeEdit);
47 get(mpOutputRangeLabel, "output-range-label");
48 get(mpOutputRangeEdit, "output-range-edit");
49 get(mpOutputRangeButton, "output-range-button");
50 mpOutputRangeEdit->SetReferences(this, mpOutputRangeLabel);
51 mpOutputRangeButton->SetReferences(this, mpOutputRangeEdit);
53 get(mpSampleSize, "sample-size-spin");
54 get(mpPeriod, "period-spin");
56 get(mpRandomMethodRadio, "random-method-radio");
57 get(mpPeriodicMethodRadio, "periodic-method-radio");
59 get(mpButtonOk, "ok");
61 Init();
62 GetRangeFromSelection();
65 void ScSamplingDialog::Init()
67 mpButtonOk->SetClickHdl( LINK( this, ScSamplingDialog, OkClicked ) );
68 mpButtonOk->Enable(false);
70 Link aLink = LINK( this, ScSamplingDialog, GetFocusHandler );
71 mpInputRangeEdit->SetGetFocusHdl( aLink );
72 mpInputRangeButton->SetGetFocusHdl( aLink );
73 mpOutputRangeEdit->SetGetFocusHdl( aLink );
74 mpOutputRangeButton->SetGetFocusHdl( aLink );
76 aLink = LINK( this, ScSamplingDialog, LoseFocusHandler );
77 mpInputRangeEdit->SetLoseFocusHdl( aLink );
78 mpInputRangeButton->SetLoseFocusHdl( aLink );
79 mpOutputRangeEdit->SetLoseFocusHdl( aLink );
80 mpOutputRangeButton->SetLoseFocusHdl( aLink );
82 mpSampleSize->SetModifyHdl( LINK( this, ScSamplingDialog, SamplingSizeValueModified ));
84 mpPeriodicMethodRadio->SetToggleHdl( LINK( this, ScSamplingDialog, ToggleSamplingMethod ) );
85 mpRandomMethodRadio->SetToggleHdl( LINK( this, ScSamplingDialog, ToggleSamplingMethod ) );
87 mpSampleSize->SetMin( 0 );
88 mpSampleSize->SetMax( SAL_MAX_INT64 );
90 mpOutputRangeEdit->GrabFocus();
91 mpPeriodicMethodRadio->Check(true);
93 ToggleSamplingMethod(NULL);
96 void ScSamplingDialog::GetRangeFromSelection()
98 mViewData->GetSimpleArea(mInputRange);
99 OUString aCurrentString(mInputRange.Format(SCR_ABS_3D, mDocument, mAddressDetails));
100 mpInputRangeEdit->SetText(aCurrentString);
103 ScSamplingDialog::~ScSamplingDialog()
106 void ScSamplingDialog::SetActive()
108 if ( mDialogLostFocus )
110 mDialogLostFocus = false;
111 if( mpActiveEdit )
112 mpActiveEdit->GrabFocus();
114 else
116 GrabFocus();
118 RefInputDone();
121 bool ScSamplingDialog::Close()
123 return DoClose( ScSamplingDialogWrapper::GetChildWindowId() );
126 void ScSamplingDialog::SetReference( const ScRange& rReferenceRange, ScDocument* pDocument )
128 if ( mpActiveEdit )
130 if ( rReferenceRange.aStart != rReferenceRange.aEnd )
131 RefInputStart( mpActiveEdit );
133 OUString aReferenceString;
135 if ( mpActiveEdit == mpInputRangeEdit )
137 mInputRange = rReferenceRange;
138 aReferenceString = mInputRange.Format(SCR_ABS_3D, pDocument, mAddressDetails);
139 mpInputRangeEdit->SetRefString( aReferenceString );
141 else if ( mpActiveEdit == mpOutputRangeEdit )
143 mOutputAddress = rReferenceRange.aStart;
145 sal_uInt16 nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ? SCA_ABS : SCA_ABS_3D;
146 aReferenceString = mOutputAddress.Format(nFormat, pDocument, pDocument->GetAddressConvention());
147 mpOutputRangeEdit->SetRefString( aReferenceString );
149 // Change sampling size according to output range selection
150 sal_Int64 aSelectedSampleSize = rReferenceRange.aEnd.Row() - rReferenceRange.aStart.Row() + 1;
151 if (aSelectedSampleSize > 1)
152 mpSampleSize->SetValue(aSelectedSampleSize);
153 SamplingSizeValueModified(NULL);
155 // Enable OK, Cancel if output range is set
156 mpButtonOk->Enable(!mpOutputRangeEdit->GetText().isEmpty());
161 ScRange ScSamplingDialog::PerformPeriodicSampling(ScDocShell* pDocShell)
163 ScAddress aStart = mInputRange.aStart;
164 ScAddress aEnd = mInputRange.aEnd;
166 SCTAB outTab = mOutputAddress.Tab();
167 SCCOL outCol = mOutputAddress.Col();
168 SCROW outRow = mOutputAddress.Row();
170 sal_Int64 aPeriod = mpPeriod->GetValue();
172 for (SCROW inTab = aStart.Tab(); inTab <= aEnd.Tab(); inTab++)
174 outCol = mOutputAddress.Col();
175 for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
177 sal_Int64 i = 0;
178 outRow = mOutputAddress.Row();
179 for (SCROW inRow = aStart.Row(); inRow <= aEnd.Row(); inRow++)
181 if (i % aPeriod == aPeriod - 1 ) // Sample the last of period
183 double aValue = mDocument->GetValue(ScAddress(inCol, inRow, inTab));
184 pDocShell->GetDocFunc().SetValueCell(ScAddress(outCol, outRow, outTab), aValue, true);
185 outRow++;
187 i++;
189 outCol++;
191 outTab++;
194 return ScRange(mOutputAddress, ScAddress(outTab, outRow, outTab) );
197 ScRange ScSamplingDialog::PerformRandomSampling(ScDocShell* pDocShell)
199 ScAddress aStart = mInputRange.aStart;
200 ScAddress aEnd = mInputRange.aEnd;
202 SCTAB outTab = mOutputAddress.Tab();
203 SCCOL outCol = mOutputAddress.Col();
204 SCROW outRow = mOutputAddress.Row();
206 TimeValue now;
207 osl_getSystemTime(&now);
208 boost::mt19937 seed(now.Nanosec);
209 boost::uniform_01<boost::mt19937> rng(seed);
211 SCROW inRow;
213 sal_Int64 aSampleSize = mpSampleSize->GetValue();
215 for (SCROW inTab = aStart.Tab(); inTab <= aEnd.Tab(); inTab++)
217 outCol = mOutputAddress.Col();
218 for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
220 SCROW aPopulationSize = (aEnd.Row() - aStart.Row()) + 1;
222 outRow = mOutputAddress.Row();
223 inRow = aStart.Row();
225 double aRandomValue;
227 while ((outRow - mOutputAddress.Row()) < aSampleSize)
229 aRandomValue = rng();
231 if ( (aPopulationSize - (inRow - aStart.Row())) * aRandomValue >= aSampleSize - (outRow - mOutputAddress.Row()) )
233 inRow++;
235 else
237 double aValue = mDocument->GetValue( ScAddress(inCol, inRow, inTab) );
238 pDocShell->GetDocFunc().SetValueCell(ScAddress(outCol, outRow, outTab), aValue, true);
239 inRow++;
240 outRow++;
243 outCol++;
245 outTab++;
248 return ScRange(mOutputAddress, ScAddress(outTab, outRow, outTab) );
251 void ScSamplingDialog::PerformSampling()
253 OUString aUndo( SC_STRLOAD( RID_STATISTICS_DLGS, STR_SAMPLING_UNDO_NAME));
254 ScDocShell* pDocShell = mViewData->GetDocShell();
255 svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager();
257 ScRange aModifiedRange;
259 pUndoManager->EnterListAction( aUndo, aUndo );
261 if (mpRandomMethodRadio->IsChecked())
263 aModifiedRange = PerformRandomSampling(pDocShell);
265 else if (mpPeriodicMethodRadio->IsChecked())
267 aModifiedRange = PerformPeriodicSampling(pDocShell);
270 pUndoManager->LeaveListAction();
271 pDocShell->PostPaint(aModifiedRange, PAINT_GRID);
274 IMPL_LINK( ScSamplingDialog, OkClicked, PushButton*, /*pButton*/ )
276 PerformSampling();
277 Close();
278 return 0;
281 IMPL_LINK( ScSamplingDialog, GetFocusHandler, Control*, pCtrl )
283 mpActiveEdit = NULL;
285 if( (pCtrl == (Control*) mpInputRangeEdit) || (pCtrl == (Control*) mpInputRangeButton) )
286 mpActiveEdit = mpInputRangeEdit;
287 else if( (pCtrl == (Control*) mpOutputRangeEdit) || (pCtrl == (Control*) mpOutputRangeButton) )
288 mpActiveEdit = mpOutputRangeEdit;
290 if( mpActiveEdit )
291 mpActiveEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
293 return 0;
296 IMPL_LINK_NOARG(ScSamplingDialog, LoseFocusHandler)
298 mDialogLostFocus = !IsActive();
299 return 0;
302 IMPL_LINK_NOARG(ScSamplingDialog, SamplingSizeValueModified)
304 sal_Int64 aPopulationSize = mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1;
305 if (mpSampleSize->GetValue() > aPopulationSize)
306 mpSampleSize->SetValue(aPopulationSize);
307 return 0;
310 IMPL_LINK_NOARG(ScSamplingDialog, ToggleSamplingMethod)
312 if (mpRandomMethodRadio->IsChecked())
314 mpPeriod->Enable(false);
315 mpSampleSize->Enable(true);
317 else if (mpPeriodicMethodRadio->IsChecked())
319 mpPeriod->Enable(true);
320 mpSampleSize->Enable(false);
322 return 0;
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */