12#include <rtl/math.hxx>
17#include <document.hxx>
30const sal_Int64 DIST_UNIFORM = 0;
31const sal_Int64 DIST_NORMAL = 1;
32const sal_Int64 DIST_CAUCHY = 2;
33const sal_Int64 DIST_BERNOULLI = 3;
34const sal_Int64 DIST_BINOMIAL = 4;
35const sal_Int64 DIST_CHI_SQUARED = 5;
36const sal_Int64 DIST_GEOMETRIC = 6;
37const sal_Int64 DIST_NEGATIVE_BINOMIAL = 7;
38const sal_Int64 DIST_UNIFORM_INTEGER = 8;
41const sal_Int64 DIGITS = 4;
49 "modules/scalc/ui/randomnumbergenerator.ui",
50 "RandomNumberGeneratorDialog")
51 , mrViewData(rViewData)
52 , mrDoc(rViewData.GetDocument())
53 , mbDialogLostFocus(false)
54 , mxInputRangeText(m_xBuilder->weld_label(
"cell-range-label"))
55 , mxInputRangeEdit(new
formula::RefEdit(m_xBuilder->weld_entry(
"cell-range-edit")))
56 , mxInputRangeButton(new
formula::RefButton(m_xBuilder->weld_button(
"cell-range-button")))
57 , mxDistributionCombo(m_xBuilder->weld_combo_box(
"distribution-combo"))
58 , mxParameter1Text(m_xBuilder->weld_label(
"parameter1-label"))
59 , mxParameter1Value(m_xBuilder->weld_spin_button(
"parameter1-spin"))
60 , mxParameter2Text(m_xBuilder->weld_label(
"parameter2-label"))
61 , mxParameter2Value(m_xBuilder->weld_spin_button(
"parameter2-spin"))
62 , mxSeed(m_xBuilder->weld_spin_button(
"seed-spin"))
63 , mxEnableSeed(m_xBuilder->weld_check_button(
"enable-seed-check"))
64 , mxDecimalPlaces(m_xBuilder->weld_spin_button(
"decimal-places-spin"))
65 , mxEnableRounding(m_xBuilder->weld_check_button(
"enable-rounding-check"))
66 , mxButtonApply(m_xBuilder->weld_button(
"apply"))
67 , mxButtonOk(m_xBuilder->weld_button(
"ok"))
68 , mxButtonClose(m_xBuilder->weld_button(
"close"))
138 if ( rReferenceRange.
aStart != rReferenceRange.
aEnd )
157 sal_uInt32 seedValue;
161 seedValue =
mxSeed->get_value();
166 osl_getSystemTime(&
now);
167 seedValue =
now.Nanosec;
170 std::mt19937 seed(seedValue);
175 double parameter1 = parameterInteger1 /
static_cast<double>(
PRECISION);
176 double parameter2 = parameterInteger2 /
static_cast<double>(
PRECISION);
178 std::optional<sal_Int8> aDecimalPlaces;
188 std::uniform_real_distribution<> distribution(parameter1, parameter2);
189 auto rng = std::bind(distribution, seed);
193 case DIST_UNIFORM_INTEGER:
195 std::uniform_int_distribution<sal_Int64> distribution(parameterInteger1, parameterInteger2);
196 auto rng = std::bind(distribution, seed);
197 GenerateNumbers(rng, STR_DISTRIBUTION_UNIFORM_INTEGER, aDecimalPlaces);
202 std::normal_distribution<> distribution(parameter1, parameter2);
203 auto rng = std::bind(distribution, seed);
209 std::cauchy_distribution<> distribution(parameter1);
210 auto rng = std::bind(distribution, seed);
216 std::bernoulli_distribution distribution(parameter1);
217 auto rng = std::bind(distribution, seed);
223 std::binomial_distribution<> distribution(parameterInteger2, parameter1);
224 auto rng = std::bind(distribution, seed);
228 case DIST_NEGATIVE_BINOMIAL:
230 std::negative_binomial_distribution<> distribution(parameterInteger2, parameter1);
231 auto rng = std::bind(distribution, seed);
232 GenerateNumbers(rng, STR_DISTRIBUTION_NEGATIVE_BINOMIAL, aDecimalPlaces);
235 case DIST_CHI_SQUARED:
237 std::chi_squared_distribution<> distribution(parameter1);
238 auto rng = std::bind(distribution, seed);
244 std::geometric_distribution<> distribution(parameter1);
245 auto rng = std::bind(distribution, seed);
255 OUString aUndo =
ScResId(STR_UNDO_DISTRIBUTION_TEMPLATE);
256 OUString aDistributionName =
ScResId(pDistributionStringId);
257 aUndo = aUndo.replaceAll(
"$(DISTRIBUTION)", aDistributionName);
270 std::vector<double> aVals;
271 aVals.reserve(nRowEnd - nRowStart + 1);
273 for (
SCROW nTab = nTabStart; nTab <= nTabEnd; ++nTab)
275 for (
SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
280 for (
SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
284 aVals.push_back(rtl::math::round(randomGenerator(), *aDecimalPlaces));
286 aVals.push_back(randomGenerator());
300 ApplyClicked(*mxButtonApply);
301 CloseClicked(*mxButtonClose);
306 SelectGeneratorAndGenerateNumbers();
316 mxInputRangeEdit->SelectAll();
321 mxInputRangeEdit->SelectAll();
326 mbDialogLostFocus = !
m_xDialog->has_toplevel_focus();
331 mbDialogLostFocus = !
m_xDialog->has_toplevel_focus();
337 bool bValid = ParseWithNames( aRangeList, mxInputRangeEdit->GetText(), mrDoc);
338 const ScRange* pRange = (bValid && aRangeList.
size() == 1) ? &aRangeList[0] :
nullptr;
341 maInputRange = *pRange;
342 mxButtonApply->set_sensitive(
true);
343 mxButtonOk->set_sensitive(
true);
345 mxInputRangeEdit->StartUpdateData();
350 mxButtonApply->set_sensitive(
false);
351 mxButtonOk->set_sensitive(
false);
357 sal_Int64 aSelectedId = mxDistributionCombo->get_active_id().toInt64();
358 if (aSelectedId == DIST_UNIFORM ||
359 aSelectedId == DIST_UNIFORM_INTEGER)
361 sal_Int64
min = mxParameter1Value->get_value();
362 sal_Int64
max = mxParameter2Value->get_value();
365 mxParameter2Value->set_value(
min);
372 sal_Int64 aSelectedId = mxDistributionCombo->get_active_id().toInt64();
373 if (aSelectedId == DIST_UNIFORM ||
374 aSelectedId == DIST_UNIFORM_INTEGER)
376 sal_Int64
min = mxParameter1Value->get_value();
377 sal_Int64
max = mxParameter2Value->get_value();
380 mxParameter1Value->set_value(
max);
387 mxSeed->set_sensitive(mxEnableSeed->get_active());
388 mxDecimalPlaces->set_sensitive(mxEnableRounding->get_active());
393 sal_Int64 aSelectedId = mxDistributionCombo->get_active_id().toInt64();
398 mxParameter1Value->set_digits(DIGITS);
401 mxParameter2Value->set_digits(DIGITS);
408 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_MINIMUM));
409 mxParameter2Text->set_label(
ScResId(STR_RNG_PARAMETER_MAXIMUM));
410 mxParameter2Text->show();
411 mxParameter2Value->show();
414 case DIST_UNIFORM_INTEGER:
416 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_MINIMUM));
417 mxParameter1Value->set_digits(0);
418 mxParameter1Value->set_increments(1, 10);
420 mxParameter2Text->set_label(
ScResId(STR_RNG_PARAMETER_MAXIMUM));
421 mxParameter2Value->set_digits(0);
422 mxParameter2Value->set_increments(1, 10);
424 mxParameter2Text->show();
425 mxParameter2Value->show();
430 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_MEAN));
431 mxParameter2Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_DEVIATION));
432 mxParameter2Text->show();
433 mxParameter2Value->show();
438 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_MEDIAN));
439 mxParameter2Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_SIGMA));
440 mxParameter2Text->show();
441 mxParameter2Value->show();
447 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_PROBABILITY));
448 mxParameter1Value->set_range(0,
PRECISION);
449 mxParameter1Value->set_increments(1000, 10000);
451 mxParameter2Text->hide();
452 mxParameter2Value->hide();
456 case DIST_NEGATIVE_BINOMIAL:
458 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_PROBABILITY));
459 mxParameter1Value->set_range(0,
PRECISION);
460 mxParameter1Value->set_increments(1000, 10000);
462 mxParameter2Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_NUMBER_OF_TRIALS));
463 mxParameter2Value->set_digits(0);
464 mxParameter2Value->set_increments(1, 10);
465 mxParameter2Value->set_min(0);
467 mxParameter2Text->show();
468 mxParameter2Value->show();
471 case DIST_CHI_SQUARED:
473 mxParameter1Text->set_label(
ScResId(STR_RNG_PARAMETER_STANDARD_NU_VALUE));
475 mxParameter2Text->hide();
476 mxParameter2Value->hide();
IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog, OkClicked, weld::Button &, void)
Reference< XExecutableDialog > m_xDialog
static sal_uInt16 GetChildWindowId()
void SetValueCells(const ScAddress &rPos, const std::vector< double > &aVals, bool bInteraction)
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
virtual SfxUndoManager * GetUndoManager() override
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
std::unique_ptr< weld::CheckButton > mxEnableSeed
std::unique_ptr< weld::Button > mxButtonApply
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
std::unique_ptr< weld::CheckButton > mxEnableRounding
std::unique_ptr< weld::ComboBox > mxDistributionCombo
std::unique_ptr< weld::Label > mxInputRangeText
std::unique_ptr< weld::Button > mxButtonOk
std::unique_ptr< weld::SpinButton > mxParameter2Value
std::unique_ptr< weld::Button > mxButtonClose
std::unique_ptr< weld::SpinButton > mxDecimalPlaces
std::unique_ptr< weld::SpinButton > mxParameter1Value
void GetRangeFromSelection()
std::unique_ptr< formula::RefButton > mxInputRangeButton
virtual void Close() override
void SelectGeneratorAndGenerateNumbers()
virtual void SetActive() override
std::unique_ptr< formula::RefEdit > mxInputRangeEdit
ScRandomNumberGeneratorDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
void GenerateNumbers(RNG &randomGenerator, TranslateId pDistributionStringId, const std::optional< sal_Int8 > aDecimalPlaces)
virtual ~ScRandomNumberGeneratorDialog() override
std::unique_ptr< weld::SpinButton > mxSeed
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...
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
virtual void RefInputDone(bool bForced=false) override
bool DoClose(sal_uInt16 nId)
ScDocShell * GetDocShell() const
ScTabViewShell * GetViewShell() const
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
ViewShellId GetViewShellId() const override
#define LINK(Instance, Class, Member)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
OUString ScResId(TranslateId aId)