From ba17605d5e75dc926c3f7c61795c77d855aa3458 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Mon, 22 Jul 2013 18:35:07 +0200 Subject: Add ANOVA (analysis of variance) calculation to Statistics. Currently supported calculation is one factor ANOVA calculation. Additionally refactor "descriptive statistics" and extract common functionallity with ANOVA into StatisticsInputOutput class. Change-Id: Ib9c3083019058c63738b3e92097411ba1b428648 --- .../StatisticsDialogs/AnalysisOfVarianceDialog.cxx | 318 +++++++++++++++++++++ .../DescriptiveStatisticsDialog.cxx | 155 +--------- .../StatisticsInputOutputDialog.cxx | 178 ++++++++++++ 3 files changed, 504 insertions(+), 147 deletions(-) create mode 100644 sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx create mode 100644 sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx (limited to 'sc/source/ui/StatisticsDialogs') diff --git a/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx b/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx new file mode 100644 index 000000000000..cb00bac05615 --- /dev/null +++ b/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx @@ -0,0 +1,318 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include +#include +#include + +#include "formulacell.hxx" +#include "rangelst.hxx" +#include "scitems.hxx" +#include "docsh.hxx" +#include "document.hxx" +#include "uiitems.hxx" +#include "reffact.hxx" +#include "scresid.hxx" +#include "random.hxx" +#include "docfunc.hxx" +#include "globstr.hrc" +#include "sc.hrc" + +#include "AnalysisOfVarianceDialog.hxx" + +namespace +{ + +static const char* lclBasicStatisticsLabels[] = +{ + "Groups", "Count", "Sum", "Mean", "Variance", NULL +}; + +static const char* lclAnovaLabels[] = +{ + "Source of Variation", "SS", "df", "MS", "F", "P-value", "F critical", NULL +}; + +static const char* lclAnovaFormula[] = +{ + "=COUNT(%RANGE%)", "=SUM(%RANGE%)", "=AVERAGE(%RANGE%)", "=VAR(%RANGE%)", NULL +}; + +static const OUString lclWildcardRange("%RANGE%"); + +OUString lclCreateMultiParameterFormula( + ScRangeList& aRangeList, const OUString& aFormulaTemplate, + const OUString& aWildcard, ScDocument* pDocument, + ScAddress::Details& aAddressDetails) +{ + OUString aResult; + for (size_t i = 0; i < aRangeList.size(); i++) + { + OUString aRangeString; + aRangeList[i]->Format( aRangeString, SCR_ABS, pDocument, aAddressDetails ); + OUString aFormulaString = aFormulaTemplate.replaceAll(aWildcard, aRangeString); + aResult += aFormulaString; + if(i != aRangeList.size() - 1) // Not Last + aResult+= ";"; + } + return aResult; +} + +class CellAddressIterator +{ +public: + CellAddressIterator(ScAddress& aStartAddress) + {} + + virtual ~CellAddressIterator() + {} +}; + +} + +ScAnalysisOfVarianceDialog::ScAnalysisOfVarianceDialog( + SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, + Window* pParent, ScViewData* pViewData ) : + ScStatisticsInputOutputDialog( + pSfxBindings, pChildWindow, pParent, pViewData, + "AnalysisOfVarianceDialog", "modules/scalc/ui/analysisofvariancedialog.ui" ) +{ + get(mpAlpha, "alpha-spin"); +} + +ScAnalysisOfVarianceDialog::~ScAnalysisOfVarianceDialog() +{} + +sal_Bool ScAnalysisOfVarianceDialog::Close() +{ + return DoClose( ScAnalysisOfVarianceDialogWrapper::GetChildWindowId() ); +} + +void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( ) +{ + OUString aUndo("Analysis Of Variance"); + ScDocShell* pDocShell = mViewData->GetDocShell(); + svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager(); + pUndoManager->EnterListAction( aUndo, aUndo ); + + ScAddress aStart = mInputRange.aStart; + ScAddress aEnd = mInputRange.aEnd; + + SCTAB outTab = mOutputAddress.Tab(); + SCCOL outCol = mOutputAddress.Col(); + SCROW outRow = mOutputAddress.Row(); + + OUString aReferenceString; + ScAddress aAddress; + + for (SCROW inTab = aStart.Tab(); inTab <= aEnd.Tab(); inTab++) + { + outCol = mOutputAddress.Col(); + + // Write labels + for(sal_Int32 i = 0; lclBasicStatisticsLabels[i] != NULL; i++) + { + aAddress = ScAddress(outCol, outRow, outTab); + OUString aCalculationName(OUString::createFromAscii(lclBasicStatisticsLabels[i])); + pDocShell->GetDocFunc().SetStringCell(aAddress, aCalculationName, true); + outCol++; + } + outRow++; + + ScRangeList aRangeList; + + // Write statistic formulas for columns + for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++) + { + outCol = mOutputAddress.Col(); + aAddress = ScAddress(outCol, outRow, outTab); + OUString aGroupName = OUString("Column ") + OUString::number(inCol - aStart.Col() + 1); + pDocShell->GetDocFunc().SetStringCell(aAddress, aGroupName, true); + outCol++; + + ScRange aColumnRange ( + ScAddress(inCol, aStart.Row(), inTab), + ScAddress(inCol, aEnd.Row(), inTab) + ); + aRangeList.Append(aColumnRange); + + aColumnRange.Format( aReferenceString, SCR_ABS, mDocument, mAddressDetails ); + OUString aFormulaString; + OUString aFormulaTemplate; + + for(sal_Int32 i = 0; lclAnovaFormula[i] != NULL; i++) + { + aAddress = ScAddress(outCol, outRow, outTab); + aFormulaTemplate = OUString::createFromAscii(lclAnovaFormula[i]); + aFormulaString = aFormulaTemplate.replaceAll(lclWildcardRange, aReferenceString); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + outCol++; + } + outRow++; + } + + outRow++; // Blank row + + // Write ANOVA labels + outCol = mOutputAddress.Col(); + for(sal_Int32 i = 0; lclAnovaLabels[i] != NULL; i++) + { + aAddress = ScAddress(outCol, outRow, outTab); + OUString aCalculationName(OUString::createFromAscii(lclAnovaLabels[i])); + pDocShell->GetDocFunc().SetStringCell(aAddress, aCalculationName, true); + outCol++; + } + outRow++; + + // Between Groups + { + // Label + outCol = mOutputAddress.Col(); + aAddress = ScAddress(outCol, outRow, outTab); + pDocShell->GetDocFunc().SetStringCell(aAddress, OUString("Between Groups"), true); + outCol++; + + // Sum of Squares + aAddress = ScAddress(outCol, outRow, outTab); + OUString aReferenceTotal; + OUString aReferenceWithin; + ScAddress aAddressTotal(outCol, outRow+2, outTab); + aAddressTotal.Format( aReferenceTotal, SCR_ABS, mDocument, mAddressDetails ); + ScAddress aAddressWithin(outCol, outRow+1, outTab); + aAddressWithin.Format( aReferenceWithin, SCR_ABS, mDocument, mAddressDetails ); + OUString aFormulaString = "=" + aReferenceTotal + "-" + aReferenceWithin; + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + outCol++; + + // Degree of freedom + aAddress = ScAddress(outCol, outRow, outTab); + aAddressTotal = ScAddress(outCol, outRow+2, outTab); + aAddressTotal.Format( aReferenceTotal, SCR_ABS, mDocument, mAddressDetails ); + aAddressWithin = ScAddress(outCol, outRow+1, outTab); + aAddressWithin.Format( aReferenceWithin, SCR_ABS, mDocument, mAddressDetails ); + aFormulaString = "=" + aReferenceTotal + "-" + aReferenceWithin; + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + outCol++; + + // MS + OUString aSSRef; + ScAddress(outCol-2, outRow, outTab).Format( aSSRef, SCR_ABS, mDocument, mAddressDetails ); + OUString aDFRef; + ScAddress(outCol-1, outRow, outTab).Format( aDFRef, SCR_ABS, mDocument, mAddressDetails ); + aFormulaString = "=" + aSSRef + "/" + aDFRef; + aAddress = ScAddress(outCol, outRow, outTab); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + outCol++; + + // F + aAddress = ScAddress(outCol, outRow, outTab); + OUString aMSBetween; + ScAddress(outCol-1, outRow, outTab).Format( aMSBetween, SCR_ABS, mDocument, mAddressDetails ); + OUString aMSWithin; + ScAddress(outCol-1, outRow+1, outTab).Format( aMSWithin, SCR_ABS, mDocument, mAddressDetails ); + aFormulaString = "=" + aMSBetween + "/" + aMSWithin; + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + outCol++; + + // P-value + aAddress = ScAddress(outCol, outRow, outTab); + OUString aFValue; + ScAddress(outCol-1, outRow, outTab).Format( aFValue, SCR_ABS, mDocument, mAddressDetails ); + OUString aDFBetween; + ScAddress(outCol-3, outRow, outTab).Format( aDFBetween, SCR_ABS, mDocument, mAddressDetails ); + OUString aDFWithin; + ScAddress(outCol-3, outRow+1, outTab).Format( aDFWithin, SCR_ABS, mDocument, mAddressDetails ); + aFormulaString = "=FDIST("+ aFValue + ";" + aDFBetween + ";" + aDFWithin + ")"; + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + outCol++; + + // F critical + double aAlphaValue = mpAlpha->GetValue() / 100.0; + OUString aAlphaString = rtl::math::doubleToUString( + aAlphaValue, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, + ScGlobal::pLocaleData->getNumDecimalSep()[0], true); + aAddress = ScAddress(outCol, outRow, outTab); + aFormulaString = "=FINV(" + aAlphaString + ";" + aDFBetween + ";" + aDFWithin + ")"; + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + } + outRow++; + + // Within Groups + { + // Label + outCol = mOutputAddress.Col(); + aAddress = ScAddress(outCol, outRow, outTab); + pDocShell->GetDocFunc().SetStringCell(aAddress, OUString("Within Groups"), true); + outCol++; + + // Sum of Squares + aAddress = ScAddress(outCol, outRow, outTab); + OUString aSum("=SUM(%RANGE%)"); + OUString aDevSQ("DEVSQ(%RANGE%)"); + OUString aSSPart = lclCreateMultiParameterFormula(aRangeList, aDevSQ, lclWildcardRange, mDocument, mAddressDetails); + OUString aSS = aSum.replaceAll(lclWildcardRange, aSSPart); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aSS), true); + outCol++; + + // Degree of freedom + aAddress = ScAddress(outCol, outRow, outTab); + OUString aCountMinusOne("COUNT(%RANGE%)-1"); + OUString aDFPart = lclCreateMultiParameterFormula(aRangeList, aCountMinusOne, lclWildcardRange, mDocument, mAddressDetails); + OUString aDF = aSum.replaceAll(lclWildcardRange, aDFPart); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aDF), true); + outCol++; + + // MS + OUString aSSRef; + OUString aDFRef; + ScAddress aAddressSS(outCol-2, outRow, outTab); + aAddressSS.Format( aSSRef, SCR_ABS, mDocument, mAddressDetails ); + ScAddress aAddressDF(outCol-1, outRow, outTab); + aAddressDF.Format( aDFRef, SCR_ABS, mDocument, mAddressDetails ); + OUString aFormulaString = "=" + aSSRef + "/" + aDFRef; + aAddress = ScAddress(outCol, outRow, outTab); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); + } + outRow++; + + // Total + { + // Label + outCol = mOutputAddress.Col(); + aAddress = ScAddress(outCol, outRow, outTab); + pDocShell->GetDocFunc().SetStringCell(aAddress, OUString("Total"), true); + outCol++; + + // Sum of Squares + OUString aDevSQ("DEVSQ(%RANGE%)"); + aRangeList.Format( aReferenceString, SCR_ABS, mDocument ); + OUString aFormulaString = aDevSQ.replaceAll(lclWildcardRange, aReferenceString); + + aAddress = ScAddress(outCol, outRow, outTab); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, "=" + aFormulaString), true); + outCol++; + + // Degree of freedom + aAddress = ScAddress(outCol, outRow, outTab); + OUString aCount("COUNT(%RANGE%)"); + OUString aSumMinusOne("=SUM(%RANGE%)-1"); + OUString aDFPart = lclCreateMultiParameterFormula(aRangeList, aCount, lclWildcardRange, mDocument, mAddressDetails); + OUString aDF = aSumMinusOne.replaceAll(lclWildcardRange, aDFPart); + pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aDF), true); + } + outRow++; + } + + ScRange aOutputRange(mOutputAddress, ScAddress(outTab, outRow, outTab) ); + pUndoManager->LeaveListAction(); + pDocShell->PostPaint( aOutputRange, PAINT_GRID ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx b/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx index a37d2edf6f23..ed9d57bc75a5 100644 --- a/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx @@ -55,124 +55,27 @@ static const StatisticCalculation lclCalcDefinitions[] = { 0, NULL } }; +static const OUString lclWildcardRange("%RANGE%"); + } ScDescriptiveStatisticsDialog::ScDescriptiveStatisticsDialog( SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, Window* pParent, ScViewData* pViewData ) : - ScAnyRefDlg ( pSfxBindings, pChildWindow, pParent, - "DescriptiveStatisticsDialog", "modules/scalc/ui/descriptivestatisticsdialog.ui" ), - mViewData ( pViewData ), - mDocument ( pViewData->GetDocument() ), - mAddressDetails ( mDocument->GetAddressConvention(), 0, 0 ), - mCurrentAddress ( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ), - mDialogLostFocus( false ) -{ - get(mpInputRangeLabel, "input-range-label"); - get(mpInputRangeEdit, "input-range-edit"); - get(mpInputRangeButton, "input-range-button"); - mpInputRangeEdit->SetReferences(this, mpInputRangeLabel); - mpInputRangeButton->SetReferences(this, mpInputRangeEdit); - - get(mpOutputRangeLabel, "output-range-label"); - get(mpOutputRangeEdit, "output-range-edit"); - get(mpOutputRangeButton, "output-range-button"); - mpOutputRangeEdit->SetReferences(this, mpOutputRangeLabel); - mpOutputRangeButton->SetReferences(this, mpOutputRangeEdit); - - get(mpButtonOk, "ok"); - get(mpButtonApply, "apply"); - get(mpButtonClose, "close"); - - Init(); - GetRangeFromSelection(); -} - -void ScDescriptiveStatisticsDialog::Init() -{ - mpButtonOk->SetClickHdl( LINK( this, ScDescriptiveStatisticsDialog, OkClicked ) ); - mpButtonClose->SetClickHdl( LINK( this, ScDescriptiveStatisticsDialog, CloseClicked ) ); - mpButtonApply->SetClickHdl( LINK( this, ScDescriptiveStatisticsDialog, ApplyClicked ) ); - mpButtonOk->Enable(false); - mpButtonApply->Enable(false); - - Link aLink = LINK( this, ScDescriptiveStatisticsDialog, GetFocusHandler ); - mpInputRangeEdit->SetGetFocusHdl( aLink ); - mpInputRangeButton->SetGetFocusHdl( aLink ); - mpOutputRangeEdit->SetGetFocusHdl( aLink ); - mpOutputRangeButton->SetGetFocusHdl( aLink ); - - aLink = LINK( this, ScDescriptiveStatisticsDialog, LoseFocusHandler ); - mpInputRangeEdit->SetLoseFocusHdl( aLink ); - mpInputRangeButton->SetLoseFocusHdl( aLink ); - mpOutputRangeEdit->SetLoseFocusHdl( aLink ); - mpOutputRangeButton->SetLoseFocusHdl( aLink ); - - mpOutputRangeEdit->GrabFocus(); -} - -void ScDescriptiveStatisticsDialog::GetRangeFromSelection() -{ - OUString aCurrentString; - mViewData->GetSimpleArea(mInputRange); - mInputRange.Format(aCurrentString, SCR_ABS_3D, mDocument, mAddressDetails); - mpInputRangeEdit->SetText(aCurrentString); -} + ScStatisticsInputOutputDialog( + pSfxBindings, pChildWindow, pParent, pViewData, + "DescriptiveStatisticsDialog", "modules/scalc/ui/descriptivestatisticsdialog.ui" ) +{} ScDescriptiveStatisticsDialog::~ScDescriptiveStatisticsDialog() {} -void ScDescriptiveStatisticsDialog::SetActive() -{ - if ( mDialogLostFocus ) - { - mDialogLostFocus = false; - if( mpActiveEdit ) - mpActiveEdit->GrabFocus(); - } - else - { - GrabFocus(); - } - RefInputDone(); -} - sal_Bool ScDescriptiveStatisticsDialog::Close() { return DoClose( ScDescriptiveStatisticsDialogWrapper::GetChildWindowId() ); } -void ScDescriptiveStatisticsDialog::SetReference( const ScRange& rReferenceRange, ScDocument* pDocument ) -{ - if ( mpActiveEdit ) - { - if ( rReferenceRange.aStart != rReferenceRange.aEnd ) - RefInputStart( mpActiveEdit ); - - String aReferenceString; - - if ( mpActiveEdit == mpInputRangeEdit ) - { - mInputRange = rReferenceRange; - mInputRange.Format( aReferenceString, SCR_ABS_3D, pDocument, mAddressDetails ); - mpInputRangeEdit->SetRefString( aReferenceString ); - } - else if ( mpActiveEdit == mpOutputRangeEdit ) - { - mOutputAddress = rReferenceRange.aStart; - - sal_uInt16 nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ? SCA_ABS : SCA_ABS_3D; - mOutputAddress.Format( aReferenceString, nFormat, pDocument, pDocument->GetAddressConvention() ); - mpOutputRangeEdit->SetRefString( aReferenceString ); - - // Enable OK, Cancel if output range is set - mpButtonOk->Enable(!mpOutputRangeEdit->GetText().isEmpty()); - mpButtonApply->Enable(!mpOutputRangeEdit->GetText().isEmpty()); - } - } -} - -void ScDescriptiveStatisticsDialog::ApplyCalculationsFormulas( ) +void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( ) { OUString aUndo(SC_RESSTR(STR_DESCRIPTIVE_STATISTICS_UNDO_NAME)); ScDocShell* pDocShell = mViewData->GetDocShell(); @@ -211,7 +114,6 @@ void ScDescriptiveStatisticsDialog::ApplyCalculationsFormulas( ) ); aColumnRange.Format( aReferenceString, SCR_ABS, mDocument, mAddressDetails ); - OUString sRange("%RANGE%"); OUString aFormulaString; OUString aFormulaTemplate; @@ -219,7 +121,7 @@ void ScDescriptiveStatisticsDialog::ApplyCalculationsFormulas( ) { aAddress = ScAddress(outCol, outRow, outTab); aFormulaTemplate = OUString::createFromAscii(lclCalcDefinitions[i].aFormula); - aFormulaString = aFormulaTemplate.replaceAll(sRange, aReferenceString); + aFormulaString = aFormulaTemplate.replaceAll(lclWildcardRange, aReferenceString); pDocShell->GetDocFunc().SetFormulaCell(aAddress, new ScFormulaCell(mDocument, aAddress, aFormulaString), true); outRow++; } @@ -233,45 +135,4 @@ void ScDescriptiveStatisticsDialog::ApplyCalculationsFormulas( ) pDocShell->PostPaint( aOutputRange, PAINT_GRID ); } -IMPL_LINK( ScDescriptiveStatisticsDialog, OkClicked, PushButton*, /*pButton*/ ) -{ - ApplyClicked(NULL); - CloseClicked(NULL); - return 0; -} - - -IMPL_LINK( ScDescriptiveStatisticsDialog, ApplyClicked, PushButton*, /*pButton*/ ) -{ - ApplyCalculationsFormulas(); - return 0; -} - -IMPL_LINK( ScDescriptiveStatisticsDialog, CloseClicked, PushButton*, /*pButton*/ ) -{ - Close(); - return 0; -} - -IMPL_LINK( ScDescriptiveStatisticsDialog, GetFocusHandler, Control*, pCtrl ) -{ - mpActiveEdit = NULL; - - if( (pCtrl == (Control*) mpInputRangeEdit) || (pCtrl == (Control*) mpInputRangeButton) ) - mpActiveEdit = mpInputRangeEdit; - else if( (pCtrl == (Control*) mpOutputRangeEdit) || (pCtrl == (Control*) mpOutputRangeButton) ) - mpActiveEdit = mpOutputRangeEdit; - - if( mpActiveEdit ) - mpActiveEdit->SetSelection( Selection( 0, SELECTION_MAX ) ); - - return 0; -} - -IMPL_LINK_NOARG(ScDescriptiveStatisticsDialog, LoseFocusHandler) -{ - mDialogLostFocus = !IsActive(); - return 0; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx b/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx new file mode 100644 index 000000000000..7a01131d176f --- /dev/null +++ b/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include +#include +#include + +#include "formulacell.hxx" +#include "rangelst.hxx" +#include "scitems.hxx" +#include "docsh.hxx" +#include "document.hxx" +#include "uiitems.hxx" +#include "reffact.hxx" +#include "scresid.hxx" +#include "random.hxx" +#include "docfunc.hxx" + +#include "StatisticsInputOutputDialog.hxx" + +ScStatisticsInputOutputDialog::ScStatisticsInputOutputDialog( + SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, + Window* pParent, ScViewData* pViewData, const OString& rID, const OUString& rUIXMLDescription ) : + ScAnyRefDlg ( pSfxBindings, pChildWindow, pParent, rID, rUIXMLDescription ), + mViewData ( pViewData ), + mDocument ( pViewData->GetDocument() ), + mAddressDetails ( mDocument->GetAddressConvention(), 0, 0 ), + mCurrentAddress ( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ), + mDialogLostFocus( false ) +{ + get(mpInputRangeLabel, "input-range-label"); + get(mpInputRangeEdit, "input-range-edit"); + get(mpInputRangeButton, "input-range-button"); + mpInputRangeEdit->SetReferences(this, mpInputRangeLabel); + mpInputRangeButton->SetReferences(this, mpInputRangeEdit); + + get(mpOutputRangeLabel, "output-range-label"); + get(mpOutputRangeEdit, "output-range-edit"); + get(mpOutputRangeButton, "output-range-button"); + mpOutputRangeEdit->SetReferences(this, mpOutputRangeLabel); + mpOutputRangeButton->SetReferences(this, mpOutputRangeEdit); + + get(mpButtonOk, "ok"); + get(mpButtonApply, "apply"); + get(mpButtonClose, "close"); + + Init(); + GetRangeFromSelection(); +} + +ScStatisticsInputOutputDialog::~ScStatisticsInputOutputDialog() +{} + +void ScStatisticsInputOutputDialog::Init() +{ + mpButtonOk->SetClickHdl( LINK( this, ScStatisticsInputOutputDialog, OkClicked ) ); + mpButtonClose->SetClickHdl( LINK( this, ScStatisticsInputOutputDialog, CloseClicked ) ); + mpButtonApply->SetClickHdl( LINK( this, ScStatisticsInputOutputDialog, ApplyClicked ) ); + mpButtonOk->Enable(false); + mpButtonApply->Enable(false); + + Link aLink = LINK( this, ScStatisticsInputOutputDialog, GetFocusHandler ); + mpInputRangeEdit->SetGetFocusHdl( aLink ); + mpInputRangeButton->SetGetFocusHdl( aLink ); + mpOutputRangeEdit->SetGetFocusHdl( aLink ); + mpOutputRangeButton->SetGetFocusHdl( aLink ); + + aLink = LINK( this, ScStatisticsInputOutputDialog, LoseFocusHandler ); + mpInputRangeEdit->SetLoseFocusHdl( aLink ); + mpInputRangeButton->SetLoseFocusHdl( aLink ); + mpOutputRangeEdit->SetLoseFocusHdl( aLink ); + mpOutputRangeButton->SetLoseFocusHdl( aLink ); + + mpOutputRangeEdit->GrabFocus(); +} + +void ScStatisticsInputOutputDialog::GetRangeFromSelection() +{ + OUString aCurrentString; + mViewData->GetSimpleArea(mInputRange); + mInputRange.Format(aCurrentString, SCR_ABS_3D, mDocument, mAddressDetails); + mpInputRangeEdit->SetText(aCurrentString); +} + +void ScStatisticsInputOutputDialog::SetActive() +{ + if ( mDialogLostFocus ) + { + mDialogLostFocus = false; + if( mpActiveEdit ) + mpActiveEdit->GrabFocus(); + } + else + { + GrabFocus(); + } + RefInputDone(); +} + +void ScStatisticsInputOutputDialog::SetReference( const ScRange& rReferenceRange, ScDocument* pDocument ) +{ + if ( mpActiveEdit ) + { + if ( rReferenceRange.aStart != rReferenceRange.aEnd ) + RefInputStart( mpActiveEdit ); + + String aReferenceString; + + if ( mpActiveEdit == mpInputRangeEdit ) + { + mInputRange = rReferenceRange; + mInputRange.Format( aReferenceString, SCR_ABS_3D, pDocument, mAddressDetails ); + mpInputRangeEdit->SetRefString( aReferenceString ); + } + else if ( mpActiveEdit == mpOutputRangeEdit ) + { + mOutputAddress = rReferenceRange.aStart; + + sal_uInt16 nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ? SCA_ABS : SCA_ABS_3D; + mOutputAddress.Format( aReferenceString, nFormat, pDocument, pDocument->GetAddressConvention() ); + mpOutputRangeEdit->SetRefString( aReferenceString ); + + // Enable OK, Cancel if output range is set + mpButtonOk->Enable(!mpOutputRangeEdit->GetText().isEmpty()); + mpButtonApply->Enable(!mpOutputRangeEdit->GetText().isEmpty()); + } + } +} + +IMPL_LINK( ScStatisticsInputOutputDialog, OkClicked, PushButton*, /*pButton*/ ) +{ + ApplyClicked(NULL); + CloseClicked(NULL); + return 0; +} + + +IMPL_LINK( ScStatisticsInputOutputDialog, ApplyClicked, PushButton*, /*pButton*/ ) +{ + CalculateInputAndWriteToOutput(); + return 0; +} + +IMPL_LINK( ScStatisticsInputOutputDialog, CloseClicked, PushButton*, /*pButton*/ ) +{ + Close(); + return 0; +} + +IMPL_LINK( ScStatisticsInputOutputDialog, GetFocusHandler, Control*, pCtrl ) +{ + mpActiveEdit = NULL; + + if( (pCtrl == (Control*) mpInputRangeEdit) || (pCtrl == (Control*) mpInputRangeButton) ) + mpActiveEdit = mpInputRangeEdit; + else if( (pCtrl == (Control*) mpOutputRangeEdit) || (pCtrl == (Control*) mpOutputRangeButton) ) + mpActiveEdit = mpOutputRangeEdit; + + if( mpActiveEdit ) + mpActiveEdit->SetSelection( Selection( 0, SELECTION_MAX ) ); + + return 0; +} + +IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, LoseFocusHandler ) +{ + mDialogLostFocus = !IsActive(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit