1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <sfx2/dispatch.hxx>
12 #include <svl/zforlist.hxx>
13 #include <svl/undo.hxx>
15 #include "rangelst.hxx"
16 #include "scitems.hxx"
18 #include "document.hxx"
19 #include "uiitems.hxx"
20 #include "reffact.hxx"
21 #include "strload.hxx"
23 #include "docfunc.hxx"
24 #include "StatisticsDialogs.hrc"
26 #include <boost/random.hpp>
27 #include <boost/random/uniform_real_distribution.hpp>
28 #include <boost/random/uniform_int_distribution.hpp>
29 #include <boost/random/binomial_distribution.hpp>
30 #include <boost/random/normal_distribution.hpp>
31 #include <boost/random/cauchy_distribution.hpp>
32 #include <boost/random/bernoulli_distribution.hpp>
33 #include <boost/random/binomial_distribution.hpp>
34 #include <boost/random/chi_squared_distribution.hpp>
35 #include <boost/random/geometric_distribution.hpp>
36 #include <boost/random/negative_binomial_distribution.hpp>
38 #include "RandomNumberGeneratorDialog.hxx"
43 static const sal_Int64 DIST_UNIFORM
= 0;
44 static const sal_Int64 DIST_NORMAL
= 1;
45 static const sal_Int64 DIST_CAUCHY
= 2;
46 static const sal_Int64 DIST_BERNOULLI
= 3;
47 static const sal_Int64 DIST_BINOMIAL
= 4;
48 static const sal_Int64 DIST_CHI_SQUARED
= 5;
49 static const sal_Int64 DIST_GEOMETRIC
= 6;
50 static const sal_Int64 DIST_NEGATIVE_BINOMIAL
= 7;
51 static const sal_Int64 DIST_UNIFORM_INTEGER
= 8;
53 static const sal_Int64 PERCISION
= 10000;
54 static const sal_Int64 DIGITS
= 4;
57 ScRandomNumberGeneratorDialog::ScRandomNumberGeneratorDialog(
58 SfxBindings
* pSfxBindings
, SfxChildWindow
* pChildWindow
,
59 Window
* pParent
, ScViewData
* pViewData
) :
60 ScAnyRefDlg ( pSfxBindings
, pChildWindow
, pParent
,
61 "RandomNumberGeneratorDialog", "modules/scalc/ui/randomnumbergenerator.ui" ),
62 mViewData ( pViewData
),
63 mDocument ( pViewData
->GetDocument() ),
64 mAddressDetails ( mDocument
->GetAddressConvention(), 0, 0 ),
65 mDialogLostFocus( false )
67 get(mpInputRangeText
, "cell-range-label");
68 get(mpInputRangeEdit
, "cell-range-edit");
69 get(mpInputRangeButton
, "cell-range-button");
70 mpInputRangeEdit
->SetReferences(this, mpInputRangeText
);
71 mpInputRangeButton
->SetReferences(this, mpInputRangeEdit
);
73 get(mpParameter1Value
, "parameter1-spin");
74 get(mpParameter1Text
, "parameter1-label");
75 get(mpParameter2Value
, "parameter2-spin");
76 get(mpParameter2Text
, "parameter2-label");
78 get(mpEnableSeed
, "enable-seed-check");
79 get(mpSeed
, "seed-spin");
81 get(mpDistributionCombo
, "distribution-combo");
83 get(mpButtonOk
, "ok");
84 get(mpButtonApply
, "apply");
85 get(mpButtonClose
, "close");
88 GetRangeFromSelection();
91 void ScRandomNumberGeneratorDialog::Init()
93 mpButtonOk
->SetClickHdl( LINK( this, ScRandomNumberGeneratorDialog
, OkClicked
) );
94 mpButtonClose
->SetClickHdl( LINK( this, ScRandomNumberGeneratorDialog
, CloseClicked
) );
95 mpButtonApply
->SetClickHdl( LINK( this, ScRandomNumberGeneratorDialog
, ApplyClicked
) );
97 Link aLink
= LINK( this, ScRandomNumberGeneratorDialog
, GetFocusHandler
);
98 mpInputRangeEdit
->SetGetFocusHdl( aLink
);
99 mpInputRangeButton
->SetGetFocusHdl( aLink
);
101 aLink
= LINK( this, ScRandomNumberGeneratorDialog
, LoseFocusHandler
);
102 mpInputRangeEdit
->SetLoseFocusHdl ( aLink
);
103 mpInputRangeButton
->SetLoseFocusHdl ( aLink
);
105 mpParameter1Value
->SetModifyHdl( LINK( this, ScRandomNumberGeneratorDialog
, Parameter1ValueModified
));
106 mpParameter2Value
->SetModifyHdl( LINK( this, ScRandomNumberGeneratorDialog
, Parameter2ValueModified
));
108 mpDistributionCombo
->SetSelectHdl( LINK( this, ScRandomNumberGeneratorDialog
, DistributionChanged
));
110 mpEnableSeed
->SetToggleHdl( LINK( this, ScRandomNumberGeneratorDialog
, SeedCheckChanged
));
112 DistributionChanged(NULL
);
113 SeedCheckChanged(NULL
);
116 void ScRandomNumberGeneratorDialog::GetRangeFromSelection()
118 mViewData
->GetSimpleArea(mInputRange
);
119 OUString
aCurrentString(mInputRange
.Format(SCR_ABS_3D
, mDocument
, mAddressDetails
));
120 mpInputRangeEdit
->SetText( aCurrentString
);
123 ScRandomNumberGeneratorDialog::~ScRandomNumberGeneratorDialog()
126 void ScRandomNumberGeneratorDialog::SetActive()
128 if ( mDialogLostFocus
)
130 mDialogLostFocus
= false;
131 if( mpInputRangeEdit
)
132 mpInputRangeEdit
->GrabFocus();
141 sal_Bool
ScRandomNumberGeneratorDialog::Close()
143 return DoClose( ScRandomNumberGeneratorDialogWrapper::GetChildWindowId() );
146 void ScRandomNumberGeneratorDialog::SetReference( const ScRange
& rReferenceRange
, ScDocument
* pDocument
)
148 if ( mpInputRangeEdit
->IsEnabled() )
150 if ( rReferenceRange
.aStart
!= rReferenceRange
.aEnd
)
151 RefInputStart( mpInputRangeEdit
);
153 mInputRange
= rReferenceRange
;
155 OUString
aReferenceString(mInputRange
.Format(SCR_ABS_3D
, pDocument
, mAddressDetails
));
156 mpInputRangeEdit
->SetRefString( aReferenceString
);
160 void ScRandomNumberGeneratorDialog::SelectGeneratorAndGenerateNumbers()
162 sal_Int16 aSelectedIndex
= mpDistributionCombo
-> GetSelectEntryPos();
163 sal_Int64 aSelectedId
= (sal_Int64
) mpDistributionCombo
->GetEntryData(aSelectedIndex
);
165 sal_uInt32 seedValue
;
167 if( mpEnableSeed
->IsChecked() )
169 seedValue
= mpSeed
->GetValue();
174 osl_getSystemTime(&now
);
175 seedValue
= now
.Nanosec
;
178 boost::mt19937
seed(seedValue
);
180 sal_Int64 parameterInteger1
= mpParameter1Value
->GetValue();
181 sal_Int64 parameterInteger2
= mpParameter2Value
->GetValue();
183 double parameter1
= parameterInteger1
/ static_cast<double>(PERCISION
);
184 double parameter2
= parameterInteger2
/ static_cast<double>(PERCISION
);
190 boost::random::uniform_real_distribution
<> distribution(parameter1
, parameter2
);
191 boost::variate_generator
<boost::mt19937
&, boost::random::uniform_real_distribution
<> > rng(seed
, distribution
);
192 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_UNIFORM_REAL
));
195 case DIST_UNIFORM_INTEGER
:
197 boost::random::uniform_int_distribution
<> distribution(parameterInteger1
, parameterInteger2
);
198 boost::variate_generator
<boost::mt19937
&, boost::random::uniform_int_distribution
<> > rng(seed
, distribution
);
199 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_UNIFORM_INTEGER
));
204 boost::random::normal_distribution
<> distribution(parameter1
, parameter2
);
205 boost::variate_generator
<boost::mt19937
&, boost::random::normal_distribution
<> > rng(seed
, distribution
);
206 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_NORMAL
));
211 boost::random::cauchy_distribution
<> distribution(parameter1
);
212 boost::variate_generator
<boost::mt19937
&, boost::random::cauchy_distribution
<> > rng(seed
, distribution
);
213 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_CAUCHY
));
218 boost::random::bernoulli_distribution
<> distribution(parameter1
);
219 boost::variate_generator
<boost::mt19937
&, boost::random::bernoulli_distribution
<> > rng(seed
, distribution
);
220 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_BERNOULLI
));
225 boost::random::binomial_distribution
<> distribution(parameterInteger2
, parameter1
);
226 boost::variate_generator
<boost::mt19937
&, boost::random::binomial_distribution
<> > rng(seed
, distribution
);
227 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_BINOMIAL
));
230 case DIST_NEGATIVE_BINOMIAL
:
232 boost::random::negative_binomial_distribution
<> distribution(parameterInteger2
, parameter1
);
233 boost::variate_generator
<boost::mt19937
&, boost::random::negative_binomial_distribution
<> > rng(seed
, distribution
);
234 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_NEGATIVE_BINOMIAL
));
237 case DIST_CHI_SQUARED
:
239 boost::random::chi_squared_distribution
<> distribution(parameter1
);
240 boost::variate_generator
<boost::mt19937
&, boost::random::chi_squared_distribution
<> > rng(seed
, distribution
);
241 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_CHI_SQUARED
));
246 boost::random::geometric_distribution
<> distribution(parameter1
);
247 boost::variate_generator
<boost::mt19937
&, boost::random::geometric_distribution
<> > rng(seed
, distribution
);
248 GenerateNumbers(rng
, SC_STRLOAD( RID_STATISTICS_DLGS
, STR_DISTRIBUTION_GEOMETRIC
));
255 void ScRandomNumberGeneratorDialog::GenerateNumbers(RNG randomGenerator
, OUString aDistributionName
)
257 OUString aUndo
= SC_STRLOAD( RID_STATISTICS_DLGS
, STR_UNDO_DISTRIBUTION_TEMPLATE
);
258 aUndo
= aUndo
.replaceAll("$(DISTRIBUTION)", aDistributionName
);
260 ScDocShell
* pDocShell
= mViewData
->GetDocShell();
261 svl::IUndoManager
* pUndoManager
= pDocShell
->GetUndoManager();
262 pUndoManager
->EnterListAction( aUndo
, aUndo
);
264 SCROW nRowStart
= mInputRange
.aStart
.Row();
265 SCROW nRowEnd
= mInputRange
.aEnd
.Row();
266 SCCOL nColStart
= mInputRange
.aStart
.Col();
267 SCCOL nColEnd
= mInputRange
.aEnd
.Col();
268 SCTAB nTabStart
= mInputRange
.aStart
.Tab();
269 SCTAB nTabEnd
= mInputRange
.aEnd
.Tab();
271 for (SCROW nTab
= nTabStart
; nTab
<= nTabEnd
; nTab
++)
273 for (SCROW nRow
= nRowStart
; nRow
<= nRowEnd
; nRow
++)
275 for (SCCOL nCol
= nColStart
; nCol
<= nColEnd
; nCol
++)
277 pDocShell
->GetDocFunc().SetValueCell(ScAddress(nCol
, nRow
, nTab
), randomGenerator(), true);
282 pUndoManager
->LeaveListAction();
284 pDocShell
->PostPaint( mInputRange
, PAINT_GRID
);
287 IMPL_LINK( ScRandomNumberGeneratorDialog
, OkClicked
, PushButton
*, /*pButton*/ )
295 IMPL_LINK( ScRandomNumberGeneratorDialog
, ApplyClicked
, PushButton
*, /*pButton*/ )
297 SelectGeneratorAndGenerateNumbers();
301 IMPL_LINK( ScRandomNumberGeneratorDialog
, CloseClicked
, PushButton
*, /*pButton*/ )
307 IMPL_LINK( ScRandomNumberGeneratorDialog
, GetFocusHandler
, Control
*, pCtrl
)
311 if( (pCtrl
== (Control
*) mpInputRangeEdit
) || (pCtrl
== (Control
*) mpInputRangeButton
) )
312 pEdit
= mpInputRangeEdit
;
315 pEdit
->SetSelection( Selection( 0, SELECTION_MAX
) );
320 IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog
, LoseFocusHandler
)
322 mDialogLostFocus
= !IsActive();
326 IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog
, Parameter1ValueModified
)
328 sal_Int16 aSelectedIndex
= mpDistributionCombo
-> GetSelectEntryPos();
329 sal_Int64 aSelectedId
= (sal_Int64
) mpDistributionCombo
->GetEntryData(aSelectedIndex
);
330 if (aSelectedId
== DIST_UNIFORM
||
331 aSelectedId
== DIST_UNIFORM_INTEGER
)
333 sal_Int64 min
= mpParameter1Value
->GetValue();
334 sal_Int64 max
= mpParameter2Value
->GetValue();
337 mpParameter2Value
->SetValue(min
);
343 IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog
, Parameter2ValueModified
)
345 sal_Int16 aSelectedIndex
= mpDistributionCombo
-> GetSelectEntryPos();
346 sal_Int64 aSelectedId
= (sal_Int64
) mpDistributionCombo
->GetEntryData(aSelectedIndex
);
347 if (aSelectedId
== DIST_UNIFORM
||
348 aSelectedId
== DIST_UNIFORM_INTEGER
)
350 sal_Int64 min
= mpParameter1Value
->GetValue();
351 sal_Int64 max
= mpParameter2Value
->GetValue();
354 mpParameter1Value
->SetValue(max
);
360 IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog
, SeedCheckChanged
)
362 mpSeed
->Enable(mpEnableSeed
->IsChecked());
366 IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog
, DistributionChanged
)
368 sal_Int16 aSelectedIndex
= mpDistributionCombo
-> GetSelectEntryPos();
369 sal_Int64 aSelectedId
= (sal_Int64
) mpDistributionCombo
->GetEntryData(aSelectedIndex
);
371 mpParameter1Value
->SetMin( SAL_MIN_INT64
);
372 mpParameter1Value
->SetMax( SAL_MAX_INT64
);
373 mpParameter2Value
->SetMin( SAL_MIN_INT64
);
374 mpParameter2Value
->SetMax( SAL_MAX_INT64
);
376 mpParameter1Value
->SetDecimalDigits(DIGITS
);
377 mpParameter1Value
->SetSpinSize(PERCISION
);
379 mpParameter2Value
->SetDecimalDigits(DIGITS
);
380 mpParameter2Value
->SetSpinSize(PERCISION
);
386 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_MINIMUM
));
387 mpParameter2Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_MAXIMUM
));
388 mpParameter2Text
->Show();
389 mpParameter2Value
->Show();
392 case DIST_UNIFORM_INTEGER
:
394 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_MINIMUM
));
395 mpParameter1Value
->SetDecimalDigits(0);
396 mpParameter1Value
->SetSpinSize(1);
398 mpParameter2Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_MAXIMUM
));
399 mpParameter2Value
->SetDecimalDigits(0);
400 mpParameter2Value
->SetSpinSize(1);
402 mpParameter2Text
->Show();
403 mpParameter2Value
->Show();
408 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_MEAN
));
409 mpParameter2Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_DEVIATION
));
410 mpParameter2Text
->Show();
411 mpParameter2Value
->Show();
416 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_MEDIAN
));
417 mpParameter2Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_SIGMA
));
418 mpParameter2Text
->Show();
419 mpParameter2Value
->Show();
425 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_PROBABILITY
));
426 mpParameter1Value
->SetMin( 0 );
427 mpParameter1Value
->SetMax( PERCISION
);
428 mpParameter1Value
->SetSpinSize(1000);
430 mpParameter2Text
->Hide();
431 mpParameter2Value
->Hide();
435 case DIST_NEGATIVE_BINOMIAL
:
437 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_PROBABILITY
));
438 mpParameter1Value
->SetMin( 0 );
439 mpParameter1Value
->SetMax( PERCISION
);
440 mpParameter1Value
->SetSpinSize(1000);
442 mpParameter2Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_NUMBER_OF_TRIALS
));
443 mpParameter2Value
->SetDecimalDigits(0);
444 mpParameter2Value
->SetSpinSize(1);
445 mpParameter2Value
->SetMin(0);
447 mpParameter2Text
->Show();
448 mpParameter2Value
->Show();
451 case DIST_CHI_SQUARED
:
453 mpParameter1Text
->SetText( SC_STRLOAD( RID_STATISTICS_DLGS
, STR_RNG_PARAMETER_STANDARD_NU_VALUE
));
455 mpParameter2Text
->Hide();
456 mpParameter2Value
->Hide();
463 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */