LibreOffice Module sc (master) 1
SamplingDialog.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#include <comphelper/random.hxx>
13#include <rangelst.hxx>
14#include <docsh.hxx>
15#include <document.hxx>
16#include <reffact.hxx>
17#include <docfunc.hxx>
18#include <SamplingDialog.hxx>
19#include <scresid.hxx>
20#include <strings.hrc>
21
23 weld::Window* pParent, ScViewData& rViewData)
24 : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent,
25 "modules/scalc/ui/samplingdialog.ui", "SamplingDialog")
26 , mpActiveEdit(nullptr)
27 , mViewData(rViewData)
28 , mDocument(rViewData.GetDocument())
29 , mInputRange(ScAddress::INITIALIZE_INVALID)
30 , mAddressDetails(mDocument.GetAddressConvention(), 0, 0)
31 , mOutputAddress(ScAddress::INITIALIZE_INVALID)
32 , mCurrentAddress(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo())
33 , mnLastSampleSizeValue(1)
34 , mnLastPeriodValue(1)
35 , mDialogLostFocus(false)
36 , mxInputRangeLabel(m_xBuilder->weld_label("input-range-label"))
37 , mxInputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("input-range-edit")))
38 , mxInputRangeButton(new formula::RefButton(m_xBuilder->weld_button("input-range-button")))
39 , mxOutputRangeLabel(m_xBuilder->weld_label("output-range-label"))
40 , mxOutputRangeEdit(new formula::RefEdit(m_xBuilder->weld_entry("output-range-edit")))
41 , mxOutputRangeButton(new formula::RefButton(m_xBuilder->weld_button("output-range-button")))
42 , mxSampleSize(m_xBuilder->weld_spin_button("sample-size-spin"))
43 , mxPeriod(m_xBuilder->weld_spin_button("period-spin"))
44 , mxRandomMethodRadio(m_xBuilder->weld_radio_button("random-method-radio"))
45 , mxWithReplacement(m_xBuilder->weld_check_button("with-replacement"))
46 , mxKeepOrder(m_xBuilder->weld_check_button("keep-order"))
47 , mxPeriodicMethodRadio(m_xBuilder->weld_radio_button("periodic-method-radio"))
48 , mxButtonOk(m_xBuilder->weld_button("ok"))
49 , mxButtonCancel(m_xBuilder->weld_button("cancel"))
50{
51 mxInputRangeEdit->SetReferences(this, mxInputRangeLabel.get());
52 mxInputRangeButton->SetReferences(this, mxInputRangeEdit.get());
53
54 mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get());
55 mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get());
56
57 Init();
59}
60
62{
63}
64
66{
67 mxButtonCancel->connect_clicked( LINK( this, ScSamplingDialog, ButtonClicked ) );
68 mxButtonOk->connect_clicked( LINK( this, ScSamplingDialog, ButtonClicked ) );
69 mxButtonOk->set_sensitive(false);
70
71 Link<formula::RefEdit&,void> aEditLink = LINK( this, ScSamplingDialog, GetEditFocusHandler );
72 mxInputRangeEdit->SetGetFocusHdl( aEditLink );
73 mxOutputRangeEdit->SetGetFocusHdl( aEditLink );
74 Link<formula::RefButton&,void> aButtonLink = LINK( this, ScSamplingDialog, GetButtonFocusHandler );
75 mxInputRangeButton->SetGetFocusHdl( aButtonLink );
76 mxOutputRangeButton->SetGetFocusHdl( aButtonLink );
77
78 aEditLink = LINK( this, ScSamplingDialog, LoseEditFocusHandler );
79 mxInputRangeEdit->SetLoseFocusHdl( aEditLink );
80 mxOutputRangeEdit->SetLoseFocusHdl( aEditLink );
81 aButtonLink = LINK( this, ScSamplingDialog, LoseButtonFocusHandler );
82 mxInputRangeButton->SetLoseFocusHdl( aButtonLink );
83 mxOutputRangeButton->SetLoseFocusHdl( aButtonLink );
84
85 Link<formula::RefEdit&,void> aLink2 = LINK( this, ScSamplingDialog, RefInputModifyHandler);
86 mxInputRangeEdit->SetModifyHdl( aLink2);
87 mxOutputRangeEdit->SetModifyHdl( aLink2);
88
89 mxSampleSize->connect_value_changed( LINK( this, ScSamplingDialog, SamplingSizeValueModified ));
90 mxSampleSize->set_range(1, SAL_MAX_INT32);
91 mxPeriod->connect_value_changed( LINK( this, ScSamplingDialog, PeriodValueModified ));
92 mxPeriod->set_range(1, SAL_MAX_INT32);
93
96
97 mxWithReplacement->connect_toggled( LINK( this, ScSamplingDialog, CheckHdl));
98 mxKeepOrder->connect_toggled( LINK( this, ScSamplingDialog, CheckHdl));
99
100 mxOutputRangeEdit->GrabFocus();
101 mxPeriodicMethodRadio->set_active(true);
102
104}
105
107{
110 mxInputRangeEdit->SetText(aCurrentString);
111}
112
114{
115 if ( mDialogLostFocus )
116 {
117 mDialogLostFocus = false;
118 if( mpActiveEdit )
120 }
121 else
122 {
123 m_xDialog->grab_focus();
124 }
125 RefInputDone();
126}
127
129{
131}
132
133void ScSamplingDialog::SetReference( const ScRange& rReferenceRange, ScDocument& rDocument )
134{
135 if ( mpActiveEdit )
136 {
137 if ( rReferenceRange.aStart != rReferenceRange.aEnd )
139
140 OUString aReferenceString;
141
142 if ( mpActiveEdit == mxInputRangeEdit.get() )
143 {
144 mInputRange = rReferenceRange;
145 aReferenceString = mInputRange.Format(rDocument, ScRefFlags::RANGE_ABS_3D, mAddressDetails);
146 mxInputRangeEdit->SetRefString( aReferenceString );
147
149 }
150 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
151 {
152 mOutputAddress = rReferenceRange.aStart;
153
154 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
157 aReferenceString = mOutputAddress.Format(nFormat, &rDocument, rDocument.GetAddressConvention());
158 mxOutputRangeEdit->SetRefString( aReferenceString );
159
160 // Change sampling size according to output range selection
161 sal_Int64 aSelectedSampleSize = rReferenceRange.aEnd.Row() - rReferenceRange.aStart.Row() + 1;
162 if (aSelectedSampleSize > 1)
163 mxSampleSize->set_value(aSelectedSampleSize);
164 SamplingSizeValueModified(*mxSampleSize);
165 }
166 }
167
168 // Enable OK if both, input range and output address are set.
169 // Disable if at least one is invalid.
170 mxButtonOk->set_sensitive(mInputRange.IsValid() && mOutputAddress.IsValid());
171}
172
174{
177
178 SCTAB outTab = mOutputAddress.Tab();
179 SCROW outRow = mOutputAddress.Row();
180
181 sal_Int64 aPeriod = mxPeriod->get_value();
182
183 for (SCROW inTab = aStart.Tab(); inTab <= aEnd.Tab(); inTab++)
184 {
185 SCCOL outCol = mOutputAddress.Col();
186 for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
187 {
188 sal_Int64 i = 0;
189 outRow = mOutputAddress.Row();
190 for (SCROW inRow = aStart.Row(); inRow <= aEnd.Row(); inRow++)
191 {
192 assert(aPeriod && "div-by-zero");
193 if (i % aPeriod == aPeriod - 1 ) // Sample the last of period
194 {
195 double aValue = mDocument.GetValue(ScAddress(inCol, inRow, inTab));
196 pDocShell->GetDocFunc().SetValueCell(ScAddress(outCol, outRow, outTab), aValue, true);
197 outRow++;
198 }
199 i++;
200 }
201 outCol++;
202 }
203 outTab++;
204 }
205
206 return ScRange(mOutputAddress, ScAddress(outTab, outRow, outTab) );
207}
208
210{
213
214 SCTAB outTab = mOutputAddress.Tab();
215 SCROW outRow = mOutputAddress.Row();
216
217 const sal_Int64 nSampleSize = mxSampleSize->get_value();
218
219 // This implementation groups by columns. Other options could be grouping
220 // by rows or area.
221 const sal_Int64 nPopulationSize = aEnd.Row() - aStart.Row() + 1;
222
223 const bool bWithReplacement = mxWithReplacement->get_sensitive() && mxWithReplacement->get_active();
224
225 // WOR (WithOutReplacement) can't draw more than population. Catch that in
226 // the caller.
227 assert( bWithReplacement || nSampleSize <= nPopulationSize);
228 if (!bWithReplacement && nSampleSize > nPopulationSize)
229 // Would enter an endless loop below, bail out.
230 return ScRange( mOutputAddress);
231
232 for (SCROW inTab = aStart.Tab(); inTab <= aEnd.Tab(); inTab++)
233 {
234 SCCOL outCol = mOutputAddress.Col();
235 for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
236 {
237 outRow = mOutputAddress.Row();
238 std::vector<bool> vUsed( nPopulationSize, false);
239
240 while ((outRow - mOutputAddress.Row()) < nSampleSize)
241 {
242 // [a,b] *both* inclusive
243 SCROW nRandom = comphelper::rng::uniform_int_distribution( aStart.Row(), aEnd.Row());
244
245 if (!bWithReplacement)
246 {
247 nRandom -= aStart.Row();
248 if (vUsed[nRandom])
249 {
250 // Find a nearest one, preferring forwards.
251 // Again: it's essential that the loop is entered only
252 // if nSampleSize<=nPopulationSize, which is checked
253 // above.
254 SCROW nBack = nRandom;
255 SCROW nForw = nRandom;
256 do
257 {
258 if (nForw < nPopulationSize - 1 && !vUsed[++nForw])
259 {
260 nRandom = nForw;
261 break;
262 }
263 if (nBack > 0 && !vUsed[--nBack])
264 {
265 nRandom = nBack;
266 break;
267 }
268 }
269 while (true);
270 }
271 vUsed[nRandom] = true;
272 nRandom += aStart.Row();
273 }
274
275 const double fValue = mDocument.GetValue( ScAddress(inCol, nRandom, inTab) );
276 pDocShell->GetDocFunc().SetValueCell(ScAddress(outCol, outRow, outTab), fValue, true);
277 outRow++;
278 }
279 outCol++;
280 }
281 outTab++;
282 }
283
284 return ScRange(mOutputAddress, ScAddress(outTab, outRow, outTab) );
285}
286
288{
291
292 SCTAB outTab = mOutputAddress.Tab();
293 SCROW outRow = mOutputAddress.Row();
294
295 SCROW inRow;
296
297 sal_Int64 aSampleSize = mxSampleSize->get_value();
298
299 for (SCROW inTab = aStart.Tab(); inTab <= aEnd.Tab(); inTab++)
300 {
301 SCCOL outCol = mOutputAddress.Col();
302 for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
303 {
304 SCROW aPopulationSize = (aEnd.Row() - aStart.Row()) + 1;
305
306 outRow = mOutputAddress.Row();
307 inRow = aStart.Row();
308
309 while ((outRow - mOutputAddress.Row()) < aSampleSize)
310 {
311 double aRandomValue = comphelper::rng::uniform_real_distribution();
312
313 if ( (aPopulationSize - (inRow - aStart.Row())) * aRandomValue >= aSampleSize - (outRow - mOutputAddress.Row()) )
314 {
315 inRow++;
316 }
317 else
318 {
319 double aValue = mDocument.GetValue( ScAddress(inCol, inRow, inTab) );
320 pDocShell->GetDocFunc().SetValueCell(ScAddress(outCol, outRow, outTab), aValue, true);
321 inRow++;
322 outRow++;
323 }
324 }
325 outCol++;
326 }
327 outTab++;
328 }
329
330 return ScRange(mOutputAddress, ScAddress(outTab, outRow, outTab) );
331}
332
334{
335 OUString aUndo(ScResId(STR_SAMPLING_UNDO_NAME));
336 ScDocShell* pDocShell = mViewData.GetDocShell();
337 SfxUndoManager* pUndoManager = pDocShell->GetUndoManager();
338
339 ScRange aModifiedRange;
340
341 pUndoManager->EnterListAction( aUndo, aUndo, 0, mViewData.GetViewShell()->GetViewShellId() );
342
343 if (mxRandomMethodRadio->get_active())
344 {
345 if (mxKeepOrder->get_sensitive() && mxKeepOrder->get_active())
346 aModifiedRange = PerformRandomSamplingKeepOrder(pDocShell);
347 else
348 aModifiedRange = PerformRandomSampling(pDocShell);
349 }
350 else if (mxPeriodicMethodRadio->get_active())
351 {
352 aModifiedRange = PerformPeriodicSampling(pDocShell);
353 }
354
355 pUndoManager->LeaveListAction();
356 pDocShell->PostPaint(aModifiedRange, PaintPartFlags::Grid);
357}
358
360{
361 return mInputRange.IsValid() ? mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1 : 0;
362}
363
365{
366 // Limit sample size (for WOR methods) and period if population is smaller
367 // than last known value. When enlarging the input population range the
368 // values will be adjusted up to the last known value again.
369 const sal_Int64 nPopulationSize = GetPopulationSize();
370 if (nPopulationSize <= mnLastSampleSizeValue && !mxWithReplacement->get_active())
371 mxSampleSize->set_value( nPopulationSize);
372 if (nPopulationSize <= mnLastPeriodValue)
373 mxPeriod->set_value( nPopulationSize);
374}
375
376IMPL_LINK_NOARG(ScSamplingDialog, SamplingSizeValueModified, weld::SpinButton&, void)
377{
378 if (!mxWithReplacement->get_active())
379 {
380 // For all WOR methods limit sample size to population size.
381 const sal_Int64 nPopulationSize = GetPopulationSize();
382 if (mxSampleSize->get_value() > nPopulationSize)
383 mxSampleSize->set_value(nPopulationSize);
384 }
385 mnLastSampleSizeValue = mxSampleSize->get_value();
386}
387
389{
390 // Limit period to population size.
391 const sal_Int64 nPopulationSize = GetPopulationSize();
392 if (mxPeriod->get_value() > nPopulationSize)
393 mxPeriod->set_value(nPopulationSize);
394 mnLastPeriodValue = mxPeriod->get_value();
395}
396
397IMPL_LINK( ScSamplingDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void )
398{
399 if (&rCtrl == mxInputRangeEdit.get())
400 mpActiveEdit = mxInputRangeEdit.get();
401 else if (&rCtrl == mxOutputRangeEdit.get())
402 mpActiveEdit = mxOutputRangeEdit.get();
403 else
404 mpActiveEdit = nullptr;
405
406 if (mpActiveEdit)
407 mpActiveEdit->SelectAll();
408}
409
410IMPL_LINK(ScSamplingDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void)
411{
412 if (&rCtrl == mxInputRangeButton.get())
413 mpActiveEdit = mxInputRangeEdit.get();
414 else if (&rCtrl == mxOutputRangeButton.get())
415 mpActiveEdit = mxOutputRangeEdit.get();
416 else
417 mpActiveEdit = nullptr;
418
419 if (mpActiveEdit)
420 mpActiveEdit->SelectAll();
421}
422
423
424IMPL_LINK(ScSamplingDialog, ButtonClicked, weld::Button&, rButton, void)
425{
426 if (&rButton == mxButtonOk.get())
427 {
428 PerformSampling();
429 response(RET_OK);
430 }
431 else
432 response(RET_CANCEL);
433}
434
436{
437 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
438}
439
441{
442 mDialogLostFocus = !m_xDialog->has_toplevel_focus();
443}
444
446{
447 ToggleSamplingMethod();
448}
449
451{
452 if (mxRandomMethodRadio->get_active())
453 {
454 mxPeriod->set_sensitive(false);
455 mxSampleSize->set_sensitive(true);
456 mxWithReplacement->set_sensitive(true);
457 mxKeepOrder->set_sensitive(true);
458 }
459 else if (mxPeriodicMethodRadio->get_active())
460 {
461 // WOR keeping order.
462 mxPeriod->set_sensitive(true);
463 mxSampleSize->set_sensitive(false);
464 mxWithReplacement->set_active(false);
465 mxWithReplacement->set_sensitive(false);
466 mxKeepOrder->set_active(true);
467 mxKeepOrder->set_sensitive(false);
468 }
469}
470
472{
473 // Keep both checkboxes enabled so user can easily switch between the three
474 // possible combinations (one or the other or none), just uncheck the other
475 // one if one is checked. Otherwise the other checkbox would had to be
476 // disabled until user unchecks the enabled one again, which would force
477 // user to two clicks to switch.
478 if (&rBtn == mxWithReplacement.get())
479 {
480 if (mxWithReplacement->get_active())
481 {
482 // For WR can't keep order.
483 mxKeepOrder->set_active(false);
484 }
485 else
486 {
487 // For WOR limit sample size to population size.
488 SamplingSizeValueModified(*mxSampleSize);
489 }
490 }
491 else if (&rBtn == mxKeepOrder.get())
492 {
493 if (mxKeepOrder->get_active())
494 {
495 // Keep order is always WOR.
496 mxWithReplacement->set_active(false);
497 SamplingSizeValueModified(*mxSampleSize);
498 }
499 }
500}
501
502IMPL_LINK_NOARG(ScSamplingDialog, RefInputModifyHandler, formula::RefEdit&, void)
503{
504 if ( mpActiveEdit )
505 {
506 if ( mpActiveEdit == mxInputRangeEdit.get() )
507 {
508 ScRangeList aRangeList;
509 bool bValid = ParseWithNames( aRangeList, mxInputRangeEdit->GetText(), mDocument);
510 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
511 if (pRange)
512 {
513 mInputRange = *pRange;
514 // Highlight the resulting range.
515 mxInputRangeEdit->StartUpdateData();
516
517 LimitSampleSizeAndPeriod();
518 }
519 else
520 {
522 }
523 }
524 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
525 {
526 ScRangeList aRangeList;
527 bool bValid = ParseWithNames( aRangeList, mxOutputRangeEdit->GetText(), mDocument);
528 const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
529 if (pRange)
530 {
531 mOutputAddress = pRange->aStart;
532
533 // Crop output range to top left address for Edit field.
534 if (pRange->aStart != pRange->aEnd)
535 {
536 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
539 OUString aReferenceString = mOutputAddress.Format(nFormat, &mDocument, mDocument.GetAddressConvention());
540 mxOutputRangeEdit->SetRefString( aReferenceString );
541 }
542
543 // Change sampling size according to output range selection
544 sal_Int64 aSelectedSampleSize = pRange->aEnd.Row() - pRange->aStart.Row() + 1;
545 if (aSelectedSampleSize > 1)
546 mxSampleSize->set_value(aSelectedSampleSize);
547 SamplingSizeValueModified(*mxSampleSize);
548
549 // Highlight the resulting range.
550 mxOutputRangeEdit->StartUpdateData();
551 }
552 else
553 {
554 mOutputAddress = ScAddress( ScAddress::INITIALIZE_INVALID);
555 }
556 }
557 }
558
559 // Enable OK if both, input range and output address are set.
560 mxButtonOk->set_sensitive(mInputRange.IsValid() && mOutputAddress.IsValid());
561}
562
563/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(ScSamplingDialog, SamplingSizeValueModified, weld::SpinButton &, void)
IMPL_LINK(ScSamplingDialog, GetEditFocusHandler, formula::RefEdit &, rCtrl, 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
bool SetValueCell(const ScAddress &rPos, double fVal, bool bInteraction)
Definition: docfunc.cxx:867
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
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:222
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:500
SC_DLLPUBLIC double GetValue(const ScAddress &rPos) const
Definition: document.cxx:3672
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
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:718
sal_Int64 GetPopulationSize() const
ScViewData & mViewData
ScAddress mCurrentAddress
ScAddress mOutputAddress
formula::RefEdit * mpActiveEdit
std::unique_ptr< weld::Button > mxButtonCancel
std::unique_ptr< weld::RadioButton > mxPeriodicMethodRadio
virtual void SetActive() override
sal_Int64 mnLastPeriodValue
std::unique_ptr< formula::RefEdit > mxInputRangeEdit
std::unique_ptr< weld::SpinButton > mxSampleSize
virtual void Close() override
const ScDocument & mDocument
std::unique_ptr< weld::SpinButton > mxPeriod
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
ScSamplingDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
virtual ~ScSamplingDialog() override
std::unique_ptr< weld::RadioButton > mxRandomMethodRadio
ScAddress::Details mAddressDetails
std::unique_ptr< weld::CheckButton > mxWithReplacement
ScRange PerformRandomSampling(ScDocShell *pDocShell)
std::unique_ptr< weld::Button > mxButtonOk
std::unique_ptr< formula::RefButton > mxOutputRangeButton
void LimitSampleSizeAndPeriod()
std::unique_ptr< weld::CheckButton > mxKeepOrder
ScRange PerformPeriodicSampling(ScDocShell *pDocShell)
std::unique_ptr< weld::Label > mxInputRangeLabel
ScRange PerformRandomSamplingKeepOrder(ScDocShell *pDocShell)
std::unique_ptr< formula::RefEdit > mxOutputRangeEdit
std::unique_ptr< weld::Label > mxOutputRangeLabel
std::unique_ptr< formula::RefButton > mxInputRangeButton
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
double uniform_real_distribution(double a=0.0, double b=1.0)
int uniform_int_distribution(int a, int b)
int i
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
#define SAL_MAX_INT32
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