officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu | 8 sc/Library_sc.mk | 1 sc/UIConfig_scalc.mk | 1 sc/inc/sc.hrc | 1 sc/inc/strings.hrc | 17 sc/qa/unit/screenshots/data/screenshots.txt | 1 sc/sdi/cellsh.sdi | 1 sc/sdi/scalc.sdi | 17 sc/source/ui/StatisticsDialogs/FourierAnalysisDialog.cxx | 247 +++++ sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx | 28 sc/source/ui/app/scdll.cxx | 1 sc/source/ui/inc/FourierAnalysisDialog.hxx | 60 + sc/source/ui/inc/StatisticsInputOutputDialog.hxx | 2 sc/source/ui/inc/reffact.hxx | 7 sc/source/ui/view/cellsh1.cxx | 9 sc/source/ui/view/tabvwsh.cxx | 1 sc/source/ui/view/tabvwshc.cxx | 7 sc/uiconfig/scalc/menubar/menubar.xml | 1 sc/uiconfig/scalc/ui/fourieranalysisdialog.ui | 423 ++++++++++ sc/uiconfig/scalc/ui/notebookbar.ui | 7 sc/uiconfig/scalc/ui/notebookbar_compact.ui | 7 solenv/sanitizers/ui/modules/scalc.suppr | 1 22 files changed, 837 insertions(+), 11 deletions(-)
New commits: commit 1b9f0e99f3ab0deb8ee2291b34c5c2e6a31de2d1 Author: Dennis Francis <[email protected]> AuthorDate: Tue Mar 12 18:21:34 2019 +0530 Commit: Dennis Francis <[email protected]> CommitDate: Tue Mar 26 14:33:23 2019 +0100 tdf#74664 : add Fourier analysis tool Add Fourier analysis tool to Statistics submenu. Use FOURIER() formula to do all the work here. Change-Id: Ifdaa79d8ee367f1c1f5054248e01853ffe4c6823 Reviewed-on: https://gerrit.libreoffice.org/69472 Tested-by: Jenkins Reviewed-by: Dennis Francis <[email protected]> diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu index 996d3c1f029d..3a70c4f2fb2b 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu @@ -998,6 +998,14 @@ <value>1</value> </prop> </node> + <node oor:name=".uno:FourierAnalysisDialog" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">F~ourier Analysis...</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:EditHeaderAndFooter" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">~Headers and Footers...</value> diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 9e67772d81f2..aa596d001a26 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -520,6 +520,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/ui/StatisticsDialogs/ChiSquareTestDialog \ sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog \ sc/source/ui/StatisticsDialogs/ExponentialSmoothingDialog \ + sc/source/ui/StatisticsDialogs/FourierAnalysisDialog \ sc/source/ui/StatisticsDialogs/FTestDialog \ sc/source/ui/StatisticsDialogs/MatrixComparisonGenerator \ sc/source/ui/StatisticsDialogs/MovingAverageDialog \ diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk index 68f210509c2a..a80f9d2ea791 100644 --- a/sc/UIConfig_scalc.mk +++ b/sc/UIConfig_scalc.mk @@ -128,6 +128,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\ sc/uiconfig/scalc/ui/footerdialog \ sc/uiconfig/scalc/ui/formatcellsdialog \ sc/uiconfig/scalc/ui/formulacalculationoptions \ + sc/uiconfig/scalc/ui/fourieranalysisdialog \ sc/uiconfig/scalc/ui/floatingborderstyle \ sc/uiconfig/scalc/ui/floatinglinestyle \ sc/uiconfig/scalc/ui/functionpanel \ diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 52b945ea9441..c8388a4e3c8d 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -237,6 +237,7 @@ #define SID_WINDOW_FIX_COL (SC_MESSAGE_START + 85) #define SID_COLUMN_OPERATIONS (SC_MESSAGE_START + 86) #define SID_ROW_OPERATIONS (SC_MESSAGE_START + 87) +#define SID_FOURIER_ANALYSIS_DIALOG (SC_MESSAGE_START + 88) // functions diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc index f85aa46263f2..a3392a36b20c 100644 --- a/sc/inc/strings.hrc +++ b/sc/inc/strings.hrc @@ -289,6 +289,8 @@ #define STR_CHI_SQUARE_TEST NC_("STR_CHI_SQUARE_TEST", "Test of Independence (Chi-Square)") #define STR_REGRESSION_UNDO_NAME NC_("STR_REGRESSION_UNDO_NAME", "Regression") #define STR_REGRESSION NC_("STR_REGRESSION", "Regression") +#define STR_FOURIER_ANALYSIS_UNDO_NAME NC_("STR_FOURIER_ANALYSIS_UNDO_NAME", "Fourier Analysis") +#define STR_FOURIER_ANALYSIS NC_("STR_FOURIER_ANALYSIS", "Fourier Analysis") /* Common */ #define STR_COLUMN_LABEL_TEMPLATE NC_("STR_COLUMN_LABEL_TEMPLATE", "Column %NUMBER%") #define STR_ROW_LABEL_TEMPLATE NC_("STR_ROW_LABEL_TEMPLATE", "Row %NUMBER%") @@ -307,13 +309,14 @@ #define STR_TEST_STATISTIC_LABEL NC_("STR_TEST_STATISTIC_LABEL", "Test Statistic") #define STR_LABEL_LOWER NC_("STR_LABEL_LOWER", "Lower") #define STR_LABEL_UPPER NC_("STR_LABEL_Upper", "Upper") +#define STR_MESSAGE_INVALID_INPUT_RANGE NC_("STR_MESSAGE_INVALID_INPUT_RANGE", "Input range is invalid.") +#define STR_MESSAGE_INVALID_OUTPUT_ADDR NC_("STR_MESSAGE_INVALID_OUTPUT_ADDR", "Output address is not valid.") /* RegressionDialog */ #define STR_LABEL_LINEAR NC_("STR_LABEL_LINEAR", "Linear") #define STR_LABEL_LOGARITHMIC NC_("STR_LABEL_LOGARITHMIC", "Logarithmic") #define STR_LABEL_POWER NC_("STR_LABEL_POWER", "Power") #define STR_MESSAGE_XINVALID_RANGE NC_("STR_MESSAGE_XINVALID_RANGE", "Independent variable(s) range is not valid.") #define STR_MESSAGE_YINVALID_RANGE NC_("STR_MESSAGE_YINVALID_RANGE", "Dependent variable(s) range is not valid.") -#define STR_MESSAGE_INVALID_OUTPUT_ADDR NC_("STR_MESSAGE_INVALID_OUTPUT_ADDR", "Output range is not valid.") #define STR_MESSAGE_INVALID_CONFIDENCE_LEVEL NC_("STR_MESSAGE_INVALID_CONFIDENCE_LEVEL", "Confidence level must be in the interval (0, 1).") #define STR_MESSAGE_YVARIABLE_MULTI_COLUMN NC_("STR_MESSAGE_YVARIABLE_MULTI_COLUMN", "Y variable range cannot have more than 1 column.") #define STR_MESSAGE_YVARIABLE_MULTI_ROW NC_("STR_MESSAGE_YVARIABLE_MULTI_ROW", "Y variable range cannot have more than 1 row.") @@ -350,6 +353,18 @@ #define STR_ZTEST_Z_CRITICAL_ONE_TAIL NC_("STR_ZTEST_Z_CRITICAL_ONE_TAIL", "z Critical one-tail") #define STR_ZTEST_P_TWO_TAIL NC_("STR_ZTEST_P_TWO_TAIL", "P (Z<=z) two-tail") #define STR_ZTEST_Z_CRITICAL_TWO_TAIL NC_("STR_ZTEST_Z_CRITICAL_TWO_TAIL", "z Critical two-tail") +/*Fourier Analysis*/ +#define STR_FOURIER_TRANSFORM NC_("STR_FOURIER_TRANSFORM", "Fourier Transform") +#define STR_INVERSE_FOURIER_TRANSFORM NC_("STR_INVERSE_FOURIER_TRANSFORM", "Inverse Fourier Transform") +#define STR_REAL_PART NC_("STR_REAL_PART", "Real") +#define STR_IMAGINARY_PART NC_("STR_IMAGINARY_PART", "Imaginary") +#define STR_MAGNITUDE_PART NC_("STR_MAGNITUDE_PART", "Magnitude") +#define STR_PHASE_PART NC_("STR_PHASE_PART", "Phase") +#define STR_MESSAGE_INVALID_NUMCOLS NC_("STR_MESSAGE_INVALID_NUMCOLS", "More than two columns selected in grouped by column mode.") +#define STR_MESSAGE_INVALID_NUMROWS NC_("STR_MESSAGE_INVALID_NUMROWS", "More than two rows selected in grouped by row mode.") +#define STR_MESSAGE_NODATA_IN_RANGE NC_("STR_MESSAGE_NODATA_IN_RANGE", "No data in input range.") +#define STR_MESSAGE_OUTPUT_TOO_LONG NC_("STR_MESSAGE_OUTPUT_TOO_LONG", "Output is too long to write into the sheet.") +#define STR_INPUT_DATA_RANGE NC_("STR_INPUT_DATA_RANGE", "Input data range") /*infobar for allowing links to update or not*/ #define STR_ENABLE_CONTENT NC_("STR_ENABLE_CONTENT", "Enable Content") /*Insert image dialog*/ diff --git a/sc/qa/unit/screenshots/data/screenshots.txt b/sc/qa/unit/screenshots/data/screenshots.txt index aa5553b7beab..2f795e601fa8 100644 --- a/sc/qa/unit/screenshots/data/screenshots.txt +++ b/sc/qa/unit/screenshots/data/screenshots.txt @@ -99,6 +99,7 @@ modules/scalc/ui/correlationdialog.ui modules/scalc/ui/ttestdialog.ui modules/scalc/ui/ztestdialog.ui modules/scalc/ui/chisquaretestdialog.ui +modules/scalc/ui/fourieranalysisdialog.ui modules/scalc/ui/regressiondialog.ui modules/scalc/ui/exponentialsmoothingdialog.ui modules/scalc/ui/descriptivestatisticsdialog.ui diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi index b7b279cdf0b6..4f2cd4d234b4 100644 --- a/sc/sdi/cellsh.sdi +++ b/sc/sdi/cellsh.sdi @@ -163,6 +163,7 @@ interface CellSelection SID_FTEST_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] SID_ZTEST_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] SID_CHI_SQUARE_TEST_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] + SID_FOURIER_ANALYSIS_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] SID_SEARCH_RESULTS_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] SID_MARKDATAAREA [ ExecMethod = ExecuteMove; StateMethod = GetStateCursor; ] SID_MARKARRAYFORMULA [ ExecMethod = ExecuteMove; StateMethod = GetStateCursor; ] diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 87ef5950d333..05b43341fe8e 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -2253,6 +2253,23 @@ SfxVoidItem ChiSquareTestDialog SID_CHI_SQUARE_TEST_DIALOG GroupId = SfxGroupId::Options; ] +SfxVoidItem FourierAnalysisDialog SID_FOURIER_ANALYSIS_DIALOG +() +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Options; +] + SfxVoidItem SolverDialog SID_OPENDLG_OPTSOLVER () [ diff --git a/sc/source/ui/StatisticsDialogs/FourierAnalysisDialog.cxx b/sc/source/ui/StatisticsDialogs/FourierAnalysisDialog.cxx new file mode 100644 index 000000000000..7ccabfcb0ed5 --- /dev/null +++ b/sc/source/ui/StatisticsDialogs/FourierAnalysisDialog.cxx @@ -0,0 +1,247 @@ +/* -*- 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 <sfx2/dispatch.hxx> +#include <svl/zforlist.hxx> +#include <svl/undo.hxx> + +#include <formulacell.hxx> +#include <rangelst.hxx> +#include <scitems.hxx> +#include <docsh.hxx> +#include <document.hxx> +#include <uiitems.hxx> +#include <reffact.hxx> +#include <docfunc.hxx> +#include <TableFillingAndNavigationTools.hxx> +#include <FourierAnalysisDialog.hxx> +#include <scresid.hxx> +#include <strings.hrc> + +ScFourierAnalysisDialog::ScFourierAnalysisDialog(SfxBindings* pSfxBindings, + SfxChildWindow* pChildWindow, vcl::Window* pParent, + ScViewData* pViewData) + : ScStatisticsInputOutputDialog(pSfxBindings, pChildWindow, pParent, pViewData, + "FourierAnalysisDialog", + "modules/scalc/ui/fourieranalysisdialog.ui") + , maLabelAddr(ScAddress::INITIALIZE_INVALID) + , maActualInputRange(ScAddress::INITIALIZE_INVALID) + , mnLen(0) + , mfMinMag(0.0) + , mbUse3DAddresses(false) + , mbGroupedByColumn(true) + , mbWithLabels(false) + , mbInverse(false) + , mbPolar(false) +{ + SetText(ScResId(STR_FOURIER_ANALYSIS)); + get(mpWithLabelsCheckBox, "withlabels-check"); + get(mpInverseCheckBox, "inverse-check"); + get(mpPolarCheckBox, "polar-check"); + get(mpMinMagnitudeField, "minmagnitude-spin"); + get(mpErrorMessage, "error-message"); + + mpWithLabelsCheckBox->SetToggleHdl(LINK(this, ScFourierAnalysisDialog, CheckBoxHdl)); +} + +ScFourierAnalysisDialog::~ScFourierAnalysisDialog() { disposeOnce(); } + +bool ScFourierAnalysisDialog::Close() +{ + return DoClose(ScFourierAnalysisDialogWrapper::GetChildWindowId()); +} + +void ScFourierAnalysisDialog::dispose() +{ + mpWithLabelsCheckBox.disposeAndClear(); + mpInverseCheckBox.disposeAndClear(); + mpPolarCheckBox.disposeAndClear(); + mpMinMagnitudeField.disposeAndClear(); + mpErrorMessage.disposeAndClear(); + ScStatisticsInputOutputDialog::dispose(); +} + +const char* ScFourierAnalysisDialog::GetUndoNameId() { return STR_FOURIER_ANALYSIS; } + +ScRange ScFourierAnalysisDialog::ApplyOutput(ScDocShell* pDocShell) +{ + getOptions(); + AddressWalkerWriter aOutput(mOutputAddress, pDocShell, mDocument, + formula::FormulaGrammar::mergeToGrammar( + formula::FormulaGrammar::GRAM_ENGLISH, mAddressDetails.eConv)); + FormulaTemplate aTemplate(mDocument); + aTemplate.autoReplaceUses3D(mbUse3DAddresses); + + aOutput.writeBoldString(mbInverse ? ScResId(STR_INVERSE_FOURIER_TRANSFORM) + : ScResId(STR_FOURIER_TRANSFORM)); + aOutput.newLine(); + OUString aLabel; + getDataLabel(aLabel); + if (aLabel.startsWith("=")) + aOutput.writeFormula(aLabel); + else + aOutput.writeString(aLabel); + + aOutput.newLine(); + // Components header + if (!mbPolar) + { + aOutput.writeString(ScResId(STR_REAL_PART)); + aOutput.nextColumn(); + aOutput.writeString(ScResId(STR_IMAGINARY_PART)); + } + else + { + aOutput.writeString(ScResId(STR_MAGNITUDE_PART)); + aOutput.nextColumn(); + aOutput.writeString(ScResId(STR_PHASE_PART)); + } + + aOutput.newLine(); + aTemplate.autoReplaceRange("%INPUTRANGE%", maActualInputRange); + + OUString aFormula; + genFormula(aFormula); + + aTemplate.setTemplate(aFormula); + aOutput.writeMatrixFormula(aTemplate.getTemplate(), 2, mnLen); + + return ScRange(aOutput.mMinimumAddress, aOutput.mMaximumAddress); +} + +bool ScFourierAnalysisDialog::InputRangesValid() +{ + if (!mInputRange.IsValid()) + { + mpErrorMessage->SetText(ScResId(STR_MESSAGE_INVALID_INPUT_RANGE)); + return false; + } + + if (!mOutputAddress.IsValid()) + { + mpErrorMessage->SetText(ScResId(STR_MESSAGE_INVALID_OUTPUT_ADDR)); + return false; + } + + mInputRange.PutInOrder(); + + mbGroupedByColumn = mGroupedBy == BY_COLUMN; + mbWithLabels = mpWithLabelsCheckBox->IsChecked(); + + mbUse3DAddresses = mInputRange.aStart.Tab() != mOutputAddress.Tab(); + + SCSIZE nRows = mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1; + SCSIZE nCols = mInputRange.aEnd.Col() - mInputRange.aStart.Col() + 1; + + SCSIZE nLen = mbGroupedByColumn ? nRows : nCols; + SCSIZE nComponents = mbGroupedByColumn ? nCols : nRows; + + if (nComponents > 2) + { + OUString aMsg = mbGroupedByColumn ? ScResId(STR_MESSAGE_INVALID_NUMCOLS) + : ScResId(STR_MESSAGE_INVALID_NUMROWS); + mpErrorMessage->SetText(aMsg); + return false; + } + + if (mbWithLabels && nLen < 2) + { + mpErrorMessage->SetText(ScResId(STR_MESSAGE_NODATA_IN_RANGE)); + return false; + } + + // Include space for writing the title, label and Real/Imaginary/Magnitude/Phase heading. + SCSIZE nLastOutputRow = mOutputAddress.Row() + nLen + 2; + if (mbWithLabels) + --nLastOutputRow; + + if (nLastOutputRow > MAXROW) + { + mpErrorMessage->SetText(ScResId(STR_MESSAGE_OUTPUT_TOO_LONG)); + return false; + } + + ScAddress aActualStart(mInputRange.aStart); + + if (mbWithLabels) + { + if (mbGroupedByColumn) + aActualStart.IncRow(); + else + aActualStart.IncCol(); + + if (nComponents == 1) + maLabelAddr = mInputRange.aStart; + else + mbWithLabels = false; + + mnLen = nLen - 1; + } + else + { + mnLen = nLen; + } + + maActualInputRange = ScRange(aActualStart, mInputRange.aEnd); + mpErrorMessage->SetText(""); + + return true; +} + +void ScFourierAnalysisDialog::getOptions() +{ + mbInverse = mpInverseCheckBox->IsChecked(); + mbPolar = mpPolarCheckBox->IsChecked(); + + sal_Int32 nDeciBels = static_cast<sal_Int32>(mpMinMagnitudeField->GetValue()); + if (nDeciBels <= -150) + mfMinMag = 0.0; + else + mfMinMag = pow(10.0, static_cast<double>(nDeciBels) / 10.0); +} + +void ScFourierAnalysisDialog::getDataLabel(OUString& rLabel) +{ + if (mbWithLabels) + { + rLabel = "=" + + maLabelAddr.Format(mbUse3DAddresses ? ScRefFlags::ADDR_ABS_3D + : ScRefFlags::ADDR_ABS, + mDocument, mAddressDetails); + + return; + } + + OUString aDataSrc( + mInputRange.Format(mbUse3DAddresses ? ScRefFlags::RANGE_ABS_3D : ScRefFlags::RANGE_ABS, + mDocument, mAddressDetails)); + + rLabel = ScResId(STR_INPUT_DATA_RANGE) + " : " + aDataSrc; + return; +} + +void ScFourierAnalysisDialog::genFormula(OUString& rFormula) +{ + static const OUString aSep(";"); + + if (!mbPolar) + { + rFormula = "FOURIER(%INPUTRANGE%;" + OUString::boolean(mbGroupedByColumn) + aSep + + OUString::boolean(mbInverse) + ")"; + return; + } + + rFormula = "FOURIER(%INPUTRANGE%;" + OUString::boolean(mbGroupedByColumn) + aSep + + OUString::boolean(mbInverse) + ";true;" + OUString::number(mfMinMag) + ")"; +} + +IMPL_LINK_NOARG(ScFourierAnalysisDialog, CheckBoxHdl, CheckBox&, void) { ValidateDialogInput(); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx b/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx index 7cb6e8724774..8d630ebc7e63 100644 --- a/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx @@ -180,11 +180,7 @@ void ScStatisticsInputOutputDialog::SetReference( const ScRange& rReferenceRange } } - // Enable OK if both, input range and output address are set. - if (mInputRange.IsValid() && mOutputAddress.IsValid()) - mpButtonOk->Enable(); - else - mpButtonOk->Disable(); + ValidateDialogInput(); } IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, OkClicked, Button*, void ) @@ -217,6 +213,8 @@ IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, GroupByChanged, RadioButton&, vo mGroupedBy = BY_COLUMN; else if (mpGroupByRowsRadio->IsChecked()) mGroupedBy = BY_ROW; + + ValidateDialogInput(); } IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, RefInputModifyHandler, Edit&, void ) @@ -268,11 +266,7 @@ IMPL_LINK_NOARG( ScStatisticsInputOutputDialog, RefInputModifyHandler, Edit&, vo } } - // Enable OK if both, input range and output address are set. - if (mInputRange.IsValid() && mOutputAddress.IsValid()) - mpButtonOk->Enable(); - else - mpButtonOk->Disable(); + ValidateDialogInput(); } void ScStatisticsInputOutputDialog::CalculateInputAndWriteToOutput() @@ -288,4 +282,18 @@ void ScStatisticsInputOutputDialog::CalculateInputAndWriteToOutput() pDocShell->PostPaint( aOutputRange, PaintPartFlags::Grid ); } +bool ScStatisticsInputOutputDialog::InputRangesValid() +{ + return mInputRange.IsValid() && mOutputAddress.IsValid(); +} + +void ScStatisticsInputOutputDialog::ValidateDialogInput() +{ + // Enable OK button if all inputs are ok. + if (InputRangesValid()) + mpButtonOk->Enable(); + else + mpButtonOk->Disable(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx index 69bf6a33d28a..59faba24ece2 100644 --- a/sc/source/ui/app/scdll.cxx +++ b/sc/source/ui/app/scdll.cxx @@ -227,6 +227,7 @@ void ScDLL::Init() ScFTestDialogWrapper ::RegisterChildWindow(false, pMod); ScZTestDialogWrapper ::RegisterChildWindow(false, pMod); ScChiSquareTestDialogWrapper ::RegisterChildWindow(false, pMod); + ScFourierAnalysisDialogWrapper ::RegisterChildWindow(false, pMod); // Redlining Window ScAcceptChgDlgWrapper ::RegisterChildWindow(false, pMod); diff --git a/sc/source/ui/inc/FourierAnalysisDialog.hxx b/sc/source/ui/inc/FourierAnalysisDialog.hxx new file mode 100644 index 000000000000..14e0dbf83be4 --- /dev/null +++ b/sc/source/ui/inc/FourierAnalysisDialog.hxx @@ -0,0 +1,60 @@ +/* -*- 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/. + * + */ + +#ifndef INCLUDED_SC_SOURCE_UI_INC_FOURIERANALYSISDIALOG_HXX +#define INCLUDED_SC_SOURCE_UI_INC_FOURIERANALYSISDIALOG_HXX + +#include "StatisticsInputOutputDialog.hxx" + +class ScFourierAnalysisDialog : public ScStatisticsInputOutputDialog +{ + VclPtr<CheckBox> mpWithLabelsCheckBox; + VclPtr<CheckBox> mpInverseCheckBox; + VclPtr<CheckBox> mpPolarCheckBox; + VclPtr<NumericField> mpMinMagnitudeField; + VclPtr<FixedText> mpErrorMessage; + + ScAddress maLabelAddr; + ScRange maActualInputRange; + SCSIZE mnLen; + + double mfMinMag; + + bool mbUse3DAddresses : 1; + bool mbGroupedByColumn : 1; + bool mbWithLabels : 1; + bool mbInverse : 1; + bool mbPolar : 1; + +public: + ScFourierAnalysisDialog(SfxBindings* pB, SfxChildWindow* pCW, vcl::Window* pParent, + ScViewData* pViewData); + + virtual ~ScFourierAnalysisDialog() override; + + virtual bool Close() override; + +protected: + void dispose() override; + virtual const char* GetUndoNameId() override; + virtual ScRange ApplyOutput(ScDocShell* pDocShell) override; + virtual bool InputRangesValid() override; + +private: + void getOptions(); + void getDataLabel(OUString& rLabel); + void genFormula(OUString& rFormula); + + DECL_LINK(CheckBoxHdl, CheckBox&, void); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/StatisticsInputOutputDialog.hxx b/sc/source/ui/inc/StatisticsInputOutputDialog.hxx index 849197e34eb5..b63ccd35c78e 100644 --- a/sc/source/ui/inc/StatisticsInputOutputDialog.hxx +++ b/sc/source/ui/inc/StatisticsInputOutputDialog.hxx @@ -41,6 +41,8 @@ protected: virtual ScRange ApplyOutput(ScDocShell* pDocShell) = 0; virtual const char* GetUndoNameId() = 0; + virtual bool InputRangesValid(); + void ValidateDialogInput(); // Widgets VclPtr<FixedText> mpInputRangeLabel; diff --git a/sc/source/ui/inc/reffact.hxx b/sc/source/ui/inc/reffact.hxx index 9165fc22e62c..a49f80c0de97 100644 --- a/sc/source/ui/inc/reffact.hxx +++ b/sc/source/ui/inc/reffact.hxx @@ -141,6 +141,13 @@ private: ScChiSquareTestDialogWrapper() = delete; }; +class ScFourierAnalysisDialogWrapper : + public ChildWindowWrapper<SID_FOURIER_ANALYSIS_DIALOG> +{ +private: + ScFourierAnalysisDialogWrapper() = delete; +}; + class ScAcceptChgDlgWrapper: public SfxChildWindow { public: diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 6cb83664879e..40cf98549757 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -1037,7 +1037,16 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) } break; + case SID_FOURIER_ANALYSIS_DIALOG: + { + sal_uInt16 nId = ScFourierAnalysisDialogWrapper::GetChildWindowId(); + SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame(); + SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId ); + pScMod->SetRefDialog( nId, pWnd == nullptr ); + + } + break; case SID_SEARCH_RESULTS_DIALOG: { const SfxPoolItem* pItem = nullptr; diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx index 665252f87ccb..a193d20431f4 100644 --- a/sc/source/ui/view/tabvwsh.cxx +++ b/sc/source/ui/view/tabvwsh.cxx @@ -100,6 +100,7 @@ void ScTabViewShell::InitInterface_Impl() GetStaticInterface()->RegisterChildWindow(ScFTestDialogWrapper::GetChildWindowId()); GetStaticInterface()->RegisterChildWindow(ScZTestDialogWrapper::GetChildWindowId()); GetStaticInterface()->RegisterChildWindow(ScChiSquareTestDialogWrapper::GetChildWindowId()); + GetStaticInterface()->RegisterChildWindow(ScFourierAnalysisDialogWrapper::GetChildWindowId()); GetStaticInterface()->RegisterChildWindow(ScCondFormatDlgWrapper::GetChildWindowId()); } diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx index ad2bf5a57a77..649af1829361 100644 --- a/sc/source/ui/view/tabvwshc.cxx +++ b/sc/source/ui/view/tabvwshc.cxx @@ -73,6 +73,7 @@ #include <FTestDialog.hxx> #include <ZTestDialog.hxx> #include <ChiSquareTestDialog.hxx> +#include <FourierAnalysisDialog.hxx> #include <PivotLayoutDialog.hxx> @@ -401,6 +402,12 @@ VclPtr<SfxModelessDialog> ScTabViewShell::CreateRefDialog( } break; + case SID_FOURIER_ANALYSIS_DIALOG: + { + pResult = VclPtr<ScFourierAnalysisDialog>::Create( pB, pCW, pParent, &GetViewData() ); + } + break; + case SID_OPENDLG_OPTSOLVER: { ScViewData& rViewData = GetViewData(); diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml index e9b93c238740..dca448df2b1a 100644 --- a/sc/uiconfig/scalc/menubar/menubar.xml +++ b/sc/uiconfig/scalc/menubar/menubar.xml @@ -674,6 +674,7 @@ <menu:menuitem menu:id=".uno:FTestDialog"/> <menu:menuitem menu:id=".uno:ZTestDialog"/> <menu:menuitem menu:id=".uno:ChiSquareTestDialog"/> + <menu:menuitem menu:id=".uno:FourierAnalysisDialog"/> </menu:menupopup> </menu:menu> </menu:menupopup> diff --git a/sc/uiconfig/scalc/ui/fourieranalysisdialog.ui b/sc/uiconfig/scalc/ui/fourieranalysisdialog.ui new file mode 100644 index 000000000000..6a56d3e77bb4 --- /dev/null +++ b/sc/uiconfig/scalc/ui/fourieranalysisdialog.ui @@ -0,0 +1,423 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface domain="sc"> + <requires lib="gtk+" version="3.18"/> + <requires lib="LibreOffice" version="1.0"/> + <object class="GtkAdjustment" id="adjustment1"> + <property name="lower">-150</property> + <property name="upper">150</property> + <property name="value">-150</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkDialog" id="FourierAnalysisDialog"> + <property name="can_focus">False</property> + <property name="border_width">6</property> + <property name="title" translatable="yes" context="fourieranalysisdialog|FourierAnalysisDialog">Fourier Analysis</property> + <property name="resizable">False</property> + <property name="type_hint">dialog</property> + <child> + <placeholder/> + </child> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="ok"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="cancel"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="help"> + <property name="label">gtk-help</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + <property name="secondary">True</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="framedata"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="top_padding">6</property> + <property name="bottom_padding">6</property> + <property name="left_padding">12</property> + <property name="right_padding">12</property> + <child> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkLabel" id="input-range-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="fourieranalysisdialog|input-range-label">Input range:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">input-range-edit</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="foruilo-RefEdit" id="input-range-edit"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="valign">center</property> + <property name="hexpand">True</property> + <property name="width_chars">30</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="foruilo-RefButton" id="input-range-button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="output-range-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="fourieranalysisdialog|output-range-label">Results to:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">output-range-edit</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="foruilo-RefEdit" id="output-range-edit"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="valign">center</property> + <property name="hexpand">True</property> + <property name="width_chars">30</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="foruilo-RefButton" id="output-range-button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="withlabels-check"> + <property name="label" translatable="yes" context="fourieranalysisdialog|withlabels-check">Input range has label</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="fourieranalysisdialog|label1">Data</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="top_padding">6</property> + <property name="bottom_padding">6</property> + <property name="left_padding">12</property> + <property name="right_padding">12</property> + <child> + <object class="GtkGrid" id="grid2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkRadioButton" id="groupedby-columns-radio"> + <property name="label" translatable="yes" context="fourieranalysisdialog|groupedby-columns-radio">_Columns</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="groupedby-rows-radio"> + <property name="label" translatable="yes" context="fourieranalysisdialog|groupedby-rows-radio">_Rows</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + <property name="group">groupedby-columns-radio</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="fourieranalysisdialog|label2">Grouped by</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">6</property> + <child> + <object class="GtkCheckButton" id="inverse-check"> + <property name="label" translatable="yes" context="fourieranalysisdialog|inverse-check">Inverse</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="valign">center</property> + <property name="margin_bottom">3</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="polar-check"> + <property name="label" translatable="yes" context="fourieranalysisdialog|polar-check">Output in polar form</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="valign">center</property> + <property name="margin_bottom">3</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">center</property> + <property name="margin_right">5</property> + <property name="margin_top">4</property> + <property name="label" translatable="yes" context="fourieranalysisdialog|label4">Minimum magnitude for polar form output (in dB)</property> + <property name="wrap">True</property> + <property name="mnemonic_widget">minmagnitude-spin</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="minmagnitude-spin"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="adjustment">adjustment1</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="fourieranalysisdialog|label3">Options</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="error-message"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">end</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-5">ok</action-widget> + <action-widget response="-11">help</action-widget> + </action-widgets> + </object> + <object class="GtkSizeGroup" id="sizegroup1"> + <widgets> + <widget name="input-range-label"/> + <widget name="output-range-label"/> + <widget name="groupedby-columns-radio"/> + <widget name="groupedby-rows-radio"/> + </widgets> + </object> +</interface> diff --git a/sc/uiconfig/scalc/ui/notebookbar.ui b/sc/uiconfig/scalc/ui/notebookbar.ui index ee4435c6f4ba..64dc2d982336 100644 --- a/sc/uiconfig/scalc/ui/notebookbar.ui +++ b/sc/uiconfig/scalc/ui/notebookbar.ui @@ -1701,6 +1701,13 @@ <property name="action_name">.uno:ChiSquareTestDialog</property> </object> </child> + <child> + <object class="GtkMenuItem" id="MenuStatistic-FourierAnalysisDialog"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="action_name">.uno:FourierAnalysisDialog</property> + </object> + </child> </object> <object class="GtkMenu" id="MenuTools"> <property name="visible">True</property> diff --git a/sc/uiconfig/scalc/ui/notebookbar_compact.ui b/sc/uiconfig/scalc/ui/notebookbar_compact.ui index 1301829c7932..53a2d1444341 100644 --- a/sc/uiconfig/scalc/ui/notebookbar_compact.ui +++ b/sc/uiconfig/scalc/ui/notebookbar_compact.ui @@ -1542,6 +1542,13 @@ <property name="action_name">.uno:ChiSquareTestDialog</property> </object> </child> + <child> + <object class="GtkMenuItem" id="FourierAnalysisDialogD1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="action_name">.uno:FourierAnalysisDialog</property> + </object> + </child> </object> <object class="GtkMenu" id="MenuTools"> <property name="visible">True</property> diff --git a/solenv/sanitizers/ui/modules/scalc.suppr b/solenv/sanitizers/ui/modules/scalc.suppr index 1ba13132a84e..f15bbf423067 100644 --- a/solenv/sanitizers/ui/modules/scalc.suppr +++ b/solenv/sanitizers/ui/modules/scalc.suppr @@ -69,6 +69,7 @@ sc/uiconfig/scalc/ui/doubledialog.ui://GtkEntry[@id='value'] no-labelled-by sc/uiconfig/scalc/ui/externaldata.ui://GtkTreeView[@id='ranges'] no-labelled-by sc/uiconfig/scalc/ui/externaldata.ui://GtkTreeViewColumn[@id='treeviewcolumn1'] no-labelled-by sc/uiconfig/scalc/ui/externaldata.ui://GtkLabel[@id='secondsft'] orphan-label +sc/uiconfig/scalc/ui/fourieranalysisdialog.ui://GtkLabel[@id='error-message'] orphan-label sc/uiconfig/scalc/ui/functionpanel.ui://GtkComboBoxText[@id='category'] no-labelled-by sc/uiconfig/scalc/ui/functionpanel.ui://GtkTreeView[@id='funclist:border'] no-labelled-by sc/uiconfig/scalc/ui/functionpanel.ui://GtkLabel[@id='funcdesc:border'] orphan-label _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
