15 #include <document.hxx>
17 #include <docfunc.hxx>
20 #include <strings.hrc>
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"))
135 if ( rReferenceRange.
aStart != rReferenceRange.
aEnd )
138 OUString aReferenceString;
159 sal_Int64 aSelectedSampleSize = rReferenceRange.
aEnd.
Row() - rReferenceRange.
aStart.
Row() + 1;
160 if (aSelectedSampleSize > 1)
179 sal_Int64 aPeriod =
mxPeriod->get_value();
181 for (
SCROW inTab = aStart.
Tab(); inTab <= aEnd.
Tab(); inTab++)
184 for (
SCCOL inCol = aStart.
Col(); inCol <= aEnd.
Col(); inCol++)
188 for (
SCROW inRow = aStart.
Row(); inRow <= aEnd.
Row(); inRow++)
190 assert(aPeriod &&
"div-by-zero");
191 if (i % aPeriod == aPeriod - 1 )
215 const sal_Int64 nSampleSize =
mxSampleSize->get_value();
219 const sal_Int64 nPopulationSize = aEnd.
Row() - aStart.
Row() + 1;
225 assert( bWithReplacement || nSampleSize <= nPopulationSize);
226 if (!bWithReplacement && nSampleSize > nPopulationSize)
230 for (
SCROW inTab = aStart.
Tab(); inTab <= aEnd.
Tab(); inTab++)
233 for (
SCCOL inCol = aStart.
Col(); inCol <= aEnd.
Col(); inCol++)
236 std::vector<bool> vUsed( nPopulationSize,
false);
243 if (!bWithReplacement)
245 nRandom -= aStart.
Row();
252 SCROW nBack = nRandom;
253 SCROW nForw = nRandom;
256 if (nForw < nPopulationSize - 1 && !vUsed[++nForw])
261 if (nBack > 0 && !vUsed[--nBack])
269 vUsed[nRandom] =
true;
270 nRandom += aStart.
Row();
297 for (
SCROW inTab = aStart.
Tab(); inTab <= aEnd.
Tab(); inTab++)
300 for (
SCCOL inCol = aStart.
Col(); inCol <= aEnd.
Col(); inCol++)
302 SCROW aPopulationSize = (aEnd.
Row() - aStart.
Row()) + 1;
305 inRow = aStart.
Row();
311 if ( (aPopulationSize - (inRow - aStart.
Row())) * aRandomValue >= aSampleSize - (outRow -
mOutputAddress.
Row()) )
333 OUString aUndo(
ScResId(STR_SAMPLING_UNDO_NAME));
368 if (nPopulationSize <= mnLastSampleSizeValue && !mxWithReplacement->get_active())
371 mxPeriod->set_value( nPopulationSize);
376 if (!mxWithReplacement->get_active())
379 const sal_Int64 nPopulationSize = GetPopulationSize();
380 if (mxSampleSize->get_value() > nPopulationSize)
381 mxSampleSize->set_value(nPopulationSize);
383 mnLastSampleSizeValue = mxSampleSize->get_value();
389 const sal_Int64 nPopulationSize = GetPopulationSize();
390 if (mxPeriod->get_value() > nPopulationSize)
391 mxPeriod->set_value(nPopulationSize);
392 mnLastPeriodValue = mxPeriod->get_value();
397 if (&rCtrl == mxInputRangeEdit.get())
398 mpActiveEdit = mxInputRangeEdit.get();
399 else if (&rCtrl == mxOutputRangeEdit.get())
400 mpActiveEdit = mxOutputRangeEdit.get();
402 mpActiveEdit =
nullptr;
405 mpActiveEdit->SelectAll();
410 if (&rCtrl == mxInputRangeButton.get())
411 mpActiveEdit = mxInputRangeEdit.get();
412 else if (&rCtrl == mxOutputRangeButton.get())
413 mpActiveEdit = mxOutputRangeEdit.get();
415 mpActiveEdit =
nullptr;
418 mpActiveEdit->SelectAll();
424 if (&rButton == mxButtonOk.get())
435 mDialogLostFocus = !
m_xDialog->has_toplevel_focus();
440 mDialogLostFocus = !
m_xDialog->has_toplevel_focus();
445 ToggleSamplingMethod();
476 if (&rBtn == mxWithReplacement.get())
478 if (mxWithReplacement->get_active())
481 mxKeepOrder->set_active(
false);
486 SamplingSizeValueModified(*mxSampleSize);
489 else if (&rBtn == mxKeepOrder.get())
491 if (mxKeepOrder->get_active())
494 mxWithReplacement->set_active(
false);
495 SamplingSizeValueModified(*mxSampleSize);
504 if ( mpActiveEdit == mxInputRangeEdit.get() )
507 bool bValid = ParseWithNames( aRangeList, mxInputRangeEdit->GetText(), mDocument);
508 const ScRange* pRange = (bValid && aRangeList.
size() == 1) ? &aRangeList[0] :
nullptr;
511 mInputRange = *pRange;
513 mxInputRangeEdit->StartUpdateData();
515 LimitSampleSizeAndPeriod();
522 else if ( mpActiveEdit == mxOutputRangeEdit.get() )
525 bool bValid = ParseWithNames( aRangeList, mxOutputRangeEdit->GetText(), mDocument);
526 const ScRange* pRange = (bValid && aRangeList.
size() == 1) ? &aRangeList[0] :
nullptr;
529 mOutputAddress = pRange->aStart;
532 if (pRange->aStart != pRange->aEnd)
534 ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
537 OUString aReferenceString = mOutputAddress.Format(nFormat, &mDocument, mDocument.GetAddressConvention());
538 mxOutputRangeEdit->SetRefString( aReferenceString );
542 sal_Int64 aSelectedSampleSize = pRange->aEnd.Row() - pRange->aStart.Row() + 1;
543 if (aSelectedSampleSize > 1)
544 mxSampleSize->set_value(aSelectedSampleSize);
545 SamplingSizeValueModified(*mxSampleSize);
548 mxOutputRangeEdit->StartUpdateData();
558 mxButtonOk->set_sensitive(mInputRange.IsValid() && mOutputAddress.IsValid());
#define LINK(Instance, Class, Member)
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
IMPL_LINK(ScSamplingDialog, GetEditFocusHandler, formula::RefEdit &, rCtrl, void)
void LimitSampleSizeAndPeriod()
ScDocShell * GetDocShell() const
std::unique_ptr< weld::CheckButton > mxKeepOrder
sal_Int64 GetPopulationSize() const
ScSamplingDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
const ScDocument & mDocument
ScRange PerformRandomSampling(ScDocShell *pDocShell)
std::unique_ptr< weld::Label > mxOutputRangeLabel
std::unique_ptr< weld::Label > mxInputRangeLabel
std::unique_ptr< weld::CheckButton > mxWithReplacement
void ToggleSamplingMethod()
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
virtual SfxUndoManager * GetUndoManager() override
virtual void Close() override
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
ScRange PerformPeriodicSampling(ScDocShell *pDocShell)
SC_DLLPUBLIC double GetValue(const ScAddress &rPos) const
ScTabViewShell * GetViewShell() const
virtual ~ScSamplingDialog() override
virtual void SetActive() override
bool SetValueCell(const ScAddress &rPos, double fVal, bool bInteraction)
SC_DLLPUBLIC 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...
std::unique_ptr< weld::SpinButton > mxSampleSize
OUString ScResId(const char *pId)
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
IMPL_LINK_NOARG(ScSamplingDialog, SamplingSizeValueModified, weld::SpinButton &, void)
virtual void RefInputDone(bool bForced=false) override
formula::RefEdit * mpActiveEdit
ScAddress mCurrentAddress
ScAddress::Details mAddressDetails
std::unique_ptr< formula::RefEdit > mxInputRangeEdit
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
double uniform_real_distribution(double a=0.0, double b=1.0)
std::unique_ptr< weld::SpinButton > mxPeriod
std::unique_ptr< weld::RadioButton > mxPeriodicMethodRadio
std::unique_ptr< weld::RadioButton > mxRandomMethodRadio
void GetRangeFromSelection()
int uniform_int_distribution(int a, int b)
Reference< XExecutableDialog > m_xDialog
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
std::unique_ptr< weld::Button > mxButtonOk
ScRange PerformRandomSamplingKeepOrder(ScDocShell *pDocShell)
std::unique_ptr< weld::Button > mxButtonCancel
sal_Int64 mnLastPeriodValue
bool DoClose(sal_uInt16 nId)
std::unique_ptr< formula::RefButton > mxOutputRangeButton
std::unique_ptr< formula::RefEdit > mxOutputRangeEdit
std::unique_ptr< formula::RefButton > mxInputRangeButton
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
ViewShellId GetViewShellId() const override
static sal_uInt16 GetChildWindowId()