LibreOffice Module sc (master) 1
FourierAnalysisDialog.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 */
10
11#include <docsh.hxx>
12#include <reffact.hxx>
15#include <scresid.hxx>
16#include <strings.hrc>
17#include <o3tl/safeint.hxx>
18
20 SfxChildWindow* pChildWindow,
21 weld::Window* pParent, ScViewData& rViewData)
22 : ScStatisticsInputOutputDialog(pSfxBindings, pChildWindow, pParent, rViewData,
23 "modules/scalc/ui/fourieranalysisdialog.ui",
24 "FourierAnalysisDialog")
25 , maLabelAddr(ScAddress::INITIALIZE_INVALID)
26 , maActualInputRange(ScAddress::INITIALIZE_INVALID)
27 , mnLen(0)
28 , mfMinMag(0.0)
29 , mbUse3DAddresses(false)
30 , mbGroupedByColumn(true)
31 , mbWithLabels(false)
32 , mbInverse(false)
33 , mbPolar(false)
34 , mxWithLabelsCheckBox(m_xBuilder->weld_check_button("withlabels-check"))
35 , mxInverseCheckBox(m_xBuilder->weld_check_button("inverse-check"))
36 , mxPolarCheckBox(m_xBuilder->weld_check_button("polar-check"))
37 , mxMinMagnitudeField(m_xBuilder->weld_spin_button("minmagnitude-spin"))
38 , mxErrorMessage(m_xBuilder->weld_label("error-message"))
39{
40 m_xDialog->set_title(ScResId(STR_FOURIER_ANALYSIS));
41
42 mxWithLabelsCheckBox->connect_toggled(LINK(this, ScFourierAnalysisDialog, CheckBoxHdl));
43}
44
46
48{
50}
51
52TranslateId ScFourierAnalysisDialog::GetUndoNameId() { return STR_FOURIER_ANALYSIS_UNDO_NAME; }
53
55{
56 getOptions();
60 FormulaTemplate aTemplate(&mDocument);
62
63 aOutput.writeBoldString(mbInverse ? ScResId(STR_INVERSE_FOURIER_TRANSFORM)
64 : ScResId(STR_FOURIER_TRANSFORM));
65 aOutput.newLine();
66 OUString aLabel;
68 if (aLabel.startsWith("="))
69 aOutput.writeFormula(aLabel);
70 else
71 aOutput.writeString(aLabel);
72
73 aOutput.newLine();
74 // Components header
75 if (!mbPolar)
76 {
77 aOutput.writeString(ScResId(STR_REAL_PART));
78 aOutput.nextColumn();
79 aOutput.writeString(ScResId(STR_IMAGINARY_PART));
80 }
81 else
82 {
83 aOutput.writeString(ScResId(STR_MAGNITUDE_PART));
84 aOutput.nextColumn();
85 aOutput.writeString(ScResId(STR_PHASE_PART));
86 }
87
88 aOutput.newLine();
89 aTemplate.autoReplaceRange("%INPUTRANGE%", maActualInputRange);
90
91 OUString aFormula;
92 genFormula(aFormula);
93
94 aTemplate.setTemplate(aFormula);
95 aOutput.writeMatrixFormula(aTemplate.getTemplate(), 2, mnLen);
96
97 return ScRange(aOutput.mMinimumAddress, aOutput.mMaximumAddress);
98}
99
101{
102 if (!mInputRange.IsValid())
103 {
104 mxErrorMessage->set_label(ScResId(STR_MESSAGE_INVALID_INPUT_RANGE));
105 return false;
106 }
107
108 if (!mOutputAddress.IsValid())
109 {
110 mxErrorMessage->set_label(ScResId(STR_MESSAGE_INVALID_OUTPUT_ADDR));
111 return false;
112 }
113
115
117 mbWithLabels = mxWithLabelsCheckBox->get_active();
118
120
121 SCSIZE nRows = mInputRange.aEnd.Row() - mInputRange.aStart.Row() + 1;
122 SCSIZE nCols = mInputRange.aEnd.Col() - mInputRange.aStart.Col() + 1;
123
124 SCSIZE nLen = mbGroupedByColumn ? nRows : nCols;
125 SCSIZE nComponents = mbGroupedByColumn ? nCols : nRows;
126
127 if (nComponents > 2)
128 {
129 OUString aMsg = mbGroupedByColumn ? ScResId(STR_MESSAGE_INVALID_NUMCOLS)
130 : ScResId(STR_MESSAGE_INVALID_NUMROWS);
131 mxErrorMessage->set_label(aMsg);
132 return false;
133 }
134
135 if (mbWithLabels && nLen < 2)
136 {
137 mxErrorMessage->set_label(ScResId(STR_MESSAGE_NODATA_IN_RANGE));
138 return false;
139 }
140
141 // Include space for writing the title, label and Real/Imaginary/Magnitude/Phase heading.
142 SCSIZE nLastOutputRow = mOutputAddress.Row() + nLen + 2;
143 if (mbWithLabels)
144 --nLastOutputRow;
145
146 if (nLastOutputRow > o3tl::make_unsigned(mDocument.MaxRow()))
147 {
148 mxErrorMessage->set_label(ScResId(STR_MESSAGE_OUTPUT_TOO_LONG));
149 return false;
150 }
151
152 ScAddress aActualStart(mInputRange.aStart);
153
154 if (mbWithLabels)
155 {
157 aActualStart.IncRow();
158 else
159 aActualStart.IncCol();
160
161 if (nComponents == 1)
163 else
164 mbWithLabels = false;
165
166 mnLen = nLen - 1;
167 }
168 else
169 {
170 mnLen = nLen;
171 }
172
174 mxErrorMessage->set_label("");
175
176 return true;
177}
178
180{
181 mbInverse = mxInverseCheckBox->get_active();
182 mbPolar = mxPolarCheckBox->get_active();
183
184 sal_Int32 nDeciBels = static_cast<sal_Int32>(mxMinMagnitudeField->get_value());
185 if (nDeciBels <= -150)
186 mfMinMag = 0.0;
187 else
188 mfMinMag = pow(10.0, static_cast<double>(nDeciBels) / 10.0);
189}
190
192{
193 if (mbWithLabels)
194 {
195 rLabel = "="
199
200 return;
201 }
202
203 OUString aDataSrc(mInputRange.Format(
206
207 rLabel = ScResId(STR_INPUT_DATA_RANGE) + " : " + aDataSrc;
208 return;
209}
210
212{
213 static constexpr OUStringLiteral aSep(u";");
214
215 if (!mbPolar)
216 {
217 rFormula = "FOURIER(%INPUTRANGE%;" + OUString::boolean(mbGroupedByColumn) + aSep
218 + OUString::boolean(mbInverse) + ")";
219 return;
220 }
221
222 rFormula = "FOURIER(%INPUTRANGE%;" + OUString::boolean(mbGroupedByColumn) + aSep
223 + OUString::boolean(mbInverse) + ";true;" + OUString::number(mfMinMag) + ")";
224}
225
227{
228 ValidateDialogInput();
229}
230
231/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(ScFourierAnalysisDialog, CheckBoxHdl, weld::Toggleable &, void)
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
Reference< XExecutableDialog > m_xDialog
void writeMatrixFormula(const OUString &aFormula, SCCOL nCols=1, SCROW nRows=1)
void writeFormula(const OUString &aFormula)
void writeBoldString(const OUString &aString)
void writeString(const OUString &aString)
void setTemplate(const OUString &aTemplate)
void autoReplaceRange(const OUString &aVariable, const ScRange &rRange)
SCTAB Tab() const
Definition: address.hxx:283
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:316
bool IsValid() const
Definition: address.hxx:305
SCROW Row() const
Definition: address.hxx:274
void IncRow(SCROW nDelta=1)
Definition: address.hxx:312
SCCOL Col() const
Definition: address.hxx:279
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
ScFourierAnalysisDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
virtual ScRange ApplyOutput(ScDocShell *pDocShell) override
virtual ~ScFourierAnalysisDialog() override
virtual void Close() override
std::unique_ptr< weld::Label > mxErrorMessage
void getDataLabel(OUString &rLabel)
std::unique_ptr< weld::CheckButton > mxPolarCheckBox
void genFormula(OUString &rFormula)
virtual TranslateId GetUndoNameId() override
virtual bool InputRangesValid() override
std::unique_ptr< weld::CheckButton > mxInverseCheckBox
std::unique_ptr< weld::SpinButton > mxMinMagnitudeField
std::unique_ptr< weld::CheckButton > mxWithLabelsCheckBox
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...
Definition: address.cxx:2170
void PutInOrder()
Definition: address.hxx:622
ScAddress aEnd
Definition: address.hxx:498
bool IsValid() const
Definition: address.hxx:544
ScAddress aStart
Definition: address.hxx:497
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:714
static Grammar mergeToGrammar(const Grammar eGrammar, const AddressConvention eConv)
float u
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
formula::FormulaGrammar::AddressConvention eConv
Definition: address.hxx:225
OUString aLabel