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/.
12 #include <reffact.hxx>
13 #include <TableFillingAndNavigationTools.hxx>
14 #include <FourierAnalysisDialog.hxx>
15 #include <scresid.hxx>
16 #include <strings.hrc>
17 #include <o3tl/safeint.hxx>
19 ScFourierAnalysisDialog::ScFourierAnalysisDialog(SfxBindings
* pSfxBindings
,
20 SfxChildWindow
* pChildWindow
,
21 weld::Window
* pParent
, ScViewData
& rViewData
)
22 : ScStatisticsInputOutputDialog(pSfxBindings
, pChildWindow
, pParent
, rViewData
,
23 u
"modules/scalc/ui/fourieranalysisdialog.ui"_ustr
,
24 u
"FourierAnalysisDialog"_ustr
)
25 , maLabelAddr(ScAddress::INITIALIZE_INVALID
)
26 , maActualInputRange(ScAddress::INITIALIZE_INVALID
)
29 , mbUse3DAddresses(false)
30 , mbGroupedByColumn(true)
34 , mxWithLabelsCheckBox(m_xBuilder
->weld_check_button(u
"withlabels-check"_ustr
))
35 , mxInverseCheckBox(m_xBuilder
->weld_check_button(u
"inverse-check"_ustr
))
36 , mxPolarCheckBox(m_xBuilder
->weld_check_button(u
"polar-check"_ustr
))
37 , mxMinMagnitudeField(m_xBuilder
->weld_spin_button(u
"minmagnitude-spin"_ustr
))
38 , mxErrorMessage(m_xBuilder
->weld_label(u
"error-message"_ustr
))
40 m_xDialog
->set_title(ScResId(STR_FOURIER_ANALYSIS
));
42 mxWithLabelsCheckBox
->connect_toggled(LINK(this, ScFourierAnalysisDialog
, CheckBoxHdl
));
45 ScFourierAnalysisDialog::~ScFourierAnalysisDialog() {}
47 void ScFourierAnalysisDialog::Close()
49 DoClose(ScFourierAnalysisDialogWrapper::GetChildWindowId());
52 TranslateId
ScFourierAnalysisDialog::GetUndoNameId() { return STR_FOURIER_ANALYSIS_UNDO_NAME
; }
54 ScRange
ScFourierAnalysisDialog::ApplyOutput(ScDocShell
* pDocShell
)
57 AddressWalkerWriter
aOutput(mOutputAddress
, pDocShell
, mDocument
,
58 formula::FormulaGrammar::mergeToGrammar(
59 formula::FormulaGrammar::GRAM_ENGLISH
, mAddressDetails
.eConv
));
60 FormulaTemplate
aTemplate(&mDocument
);
61 aTemplate
.autoReplaceUses3D(mbUse3DAddresses
);
63 aOutput
.writeBoldString(mbInverse
? ScResId(STR_INVERSE_FOURIER_TRANSFORM
)
64 : ScResId(STR_FOURIER_TRANSFORM
));
68 if (aLabel
.startsWith("="))
69 aOutput
.writeFormula(aLabel
);
71 aOutput
.writeString(aLabel
);
77 aOutput
.writeString(ScResId(STR_REAL_PART
));
79 aOutput
.writeString(ScResId(STR_IMAGINARY_PART
));
83 aOutput
.writeString(ScResId(STR_MAGNITUDE_PART
));
85 aOutput
.writeString(ScResId(STR_PHASE_PART
));
89 aTemplate
.autoReplaceRange(u
"%INPUTRANGE%"_ustr
, maActualInputRange
);
94 aTemplate
.setTemplate(aFormula
);
95 aOutput
.writeMatrixFormula(aTemplate
.getTemplate(), 2, mnLen
);
97 return ScRange(aOutput
.mMinimumAddress
, aOutput
.mMaximumAddress
);
100 bool ScFourierAnalysisDialog::InputRangesValid()
102 if (!mInputRange
.IsValid())
104 mxErrorMessage
->set_label(ScResId(STR_MESSAGE_INVALID_INPUT_RANGE
));
108 if (!mOutputAddress
.IsValid())
110 mxErrorMessage
->set_label(ScResId(STR_MESSAGE_INVALID_OUTPUT_ADDR
));
114 mInputRange
.PutInOrder();
116 mbGroupedByColumn
= mGroupedBy
== BY_COLUMN
;
117 mbWithLabels
= mxWithLabelsCheckBox
->get_active();
119 mbUse3DAddresses
= mInputRange
.aStart
.Tab() != mOutputAddress
.Tab();
121 SCSIZE nRows
= mInputRange
.aEnd
.Row() - mInputRange
.aStart
.Row() + 1;
122 SCSIZE nCols
= mInputRange
.aEnd
.Col() - mInputRange
.aStart
.Col() + 1;
124 SCSIZE nLen
= mbGroupedByColumn
? nRows
: nCols
;
125 SCSIZE nComponents
= mbGroupedByColumn
? nCols
: nRows
;
129 OUString aMsg
= mbGroupedByColumn
? ScResId(STR_MESSAGE_INVALID_NUMCOLS
)
130 : ScResId(STR_MESSAGE_INVALID_NUMROWS
);
131 mxErrorMessage
->set_label(aMsg
);
135 if (mbWithLabels
&& nLen
< 2)
137 mxErrorMessage
->set_label(ScResId(STR_MESSAGE_NODATA_IN_RANGE
));
141 // Include space for writing the title, label and Real/Imaginary/Magnitude/Phase heading.
142 SCSIZE nLastOutputRow
= mOutputAddress
.Row() + nLen
+ 2;
146 if (nLastOutputRow
> o3tl::make_unsigned(mDocument
.MaxRow()))
148 mxErrorMessage
->set_label(ScResId(STR_MESSAGE_OUTPUT_TOO_LONG
));
152 ScAddress
aActualStart(mInputRange
.aStart
);
156 if (mbGroupedByColumn
)
157 aActualStart
.IncRow();
159 aActualStart
.IncCol();
161 if (nComponents
== 1)
162 maLabelAddr
= mInputRange
.aStart
;
164 mbWithLabels
= false;
173 maActualInputRange
= ScRange(aActualStart
, mInputRange
.aEnd
);
174 mxErrorMessage
->set_label(u
""_ustr
);
179 void ScFourierAnalysisDialog::getOptions()
181 mbInverse
= mxInverseCheckBox
->get_active();
182 mbPolar
= mxPolarCheckBox
->get_active();
184 sal_Int32 nDeciBels
= static_cast<sal_Int32
>(mxMinMagnitudeField
->get_value());
185 if (nDeciBels
<= -150)
188 mfMinMag
= pow(10.0, static_cast<double>(nDeciBels
) / 10.0);
191 void ScFourierAnalysisDialog::getDataLabel(OUString
& rLabel
)
196 + maLabelAddr
.Format(mbUse3DAddresses
? ScRefFlags::ADDR_ABS_3D
197 : ScRefFlags::ADDR_ABS
,
198 &mDocument
, mAddressDetails
);
203 OUString
aDataSrc(mInputRange
.Format(
204 mDocument
, mbUse3DAddresses
? ScRefFlags::RANGE_ABS_3D
: ScRefFlags::RANGE_ABS
,
207 rLabel
= ScResId(STR_INPUT_DATA_RANGE
) + " : " + aDataSrc
;
211 void ScFourierAnalysisDialog::genFormula(OUString
& rFormula
)
213 static constexpr OUString
aSep(u
";"_ustr
);
217 rFormula
= "FOURIER(%INPUTRANGE%;" + OUString::boolean(mbGroupedByColumn
) + aSep
218 + OUString::boolean(mbInverse
) + ")";
222 rFormula
= "FOURIER(%INPUTRANGE%;" + OUString::boolean(mbGroupedByColumn
) + aSep
223 + OUString::boolean(mbInverse
) + ";true;" + OUString::number(mfMinMag
) + ")";
226 IMPL_LINK_NOARG(ScFourierAnalysisDialog
, CheckBoxHdl
, weld::Toggleable
&, void)
228 ValidateDialogInput();
231 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */