labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

XYFourierTransformCurveDock.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : XYFourierTransformCurveDock.cpp
3  Project : LabPlot
4  --------------------------------------------------------------------
5  Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn)
6  Description : widget for editing properties of Fourier transform curves
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  * This program is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  * You should have received a copy of the GNU General Public License *
23  * along with this program; if not, write to the Free Software *
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
25  * Boston, MA 02110-1301 USA *
26  * *
27  ***************************************************************************/
28 
31 #include "backend/core/Project.h"
34 
35 #include <KMessageBox>
36 
37 #include <QMenu>
38 #include <QWidgetAction>
39 
40 /*!
41  \class XYFourierTransformCurveDock
42  \brief Provides a widget for editing the properties of the XYFourierTransformCurves
43  (2D-curves defined by a Fourier transform) currently selected in
44  the project explorer.
45 
46  If more then one curves are set, the properties of the first column are shown.
47  The changes of the properties are applied to all curves.
48  The exclusions are the name, the comment and the datasets (columns) of
49  the curves - these properties can only be changed if there is only one single curve.
50 
51  \ingroup kdefrontend
52 */
53 
55 }
56 
57 /*!
58  * // Tab "General"
59  */
61  QWidget* generalTab = new QWidget(ui.tabGeneral);
62  uiGeneralTab.setupUi(generalTab);
63  m_leName = uiGeneralTab.leName;
64  m_leComment = uiGeneralTab.leComment;
65 
66  auto* gridLayout = static_cast<QGridLayout*>(generalTab->layout());
67  gridLayout->setContentsMargins(2,2,2,2);
68  gridLayout->setHorizontalSpacing(2);
69  gridLayout->setVerticalSpacing(2);
70 
71  cbXDataColumn = new TreeViewComboBox(generalTab);
72  gridLayout->addWidget(cbXDataColumn, 5, 2, 1, 2);
73  cbYDataColumn = new TreeViewComboBox(generalTab);
74  gridLayout->addWidget(cbYDataColumn, 6, 2, 1, 2);
75 
76  for (int i = 0; i < NSL_SF_WINDOW_TYPE_COUNT; i++)
77  uiGeneralTab.cbWindowType->addItem(i18n(nsl_sf_window_type_name[i]));
78  for (int i = 0; i < NSL_DFT_RESULT_TYPE_COUNT; i++)
79  uiGeneralTab.cbType->addItem(i18n(nsl_dft_result_type_name[i]));
80  for (int i = 0; i < NSL_DFT_XSCALE_COUNT; i++)
81  uiGeneralTab.cbXScale->addItem(i18n(nsl_dft_xscale_name[i]));
82 
83  //TODO: use line edits
84  uiGeneralTab.sbMin->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
85  uiGeneralTab.sbMax->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
86 
87  auto* layout = new QHBoxLayout(ui.tabGeneral);
88  layout->setMargin(0);
89  layout->addWidget(generalTab);
90 
91  //Slots
92  connect( uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYFourierTransformCurveDock::nameChanged );
93  connect( uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYFourierTransformCurveDock::commentChanged );
94  connect( uiGeneralTab.chkVisible, &QCheckBox::clicked, this, &XYFourierTransformCurveDock::visibilityChanged);
95  connect( uiGeneralTab.cbAutoRange, &QCheckBox::clicked, this, &XYFourierTransformCurveDock::autoRangeChanged);
96  connect( uiGeneralTab.sbMin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYFourierTransformCurveDock::xRangeMinChanged);
97  connect( uiGeneralTab.sbMax, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYFourierTransformCurveDock::xRangeMaxChanged);
98  connect( uiGeneralTab.cbWindowType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYFourierTransformCurveDock::windowTypeChanged);
99  connect( uiGeneralTab.cbType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYFourierTransformCurveDock::typeChanged);
100  connect( uiGeneralTab.cbTwoSided, &QCheckBox::stateChanged, this, &XYFourierTransformCurveDock::twoSidedChanged);
101  connect( uiGeneralTab.cbShifted, &QCheckBox::stateChanged, this, &XYFourierTransformCurveDock::shiftedChanged);
102  connect( uiGeneralTab.cbXScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYFourierTransformCurveDock::xScaleChanged);
103  connect( uiGeneralTab.pbRecalculate, &QPushButton::clicked, this, &XYFourierTransformCurveDock::recalculateClicked);
104 
107 }
108 
110  //if there are more then one curve in the list, disable the tab "general"
111  if (m_curvesList.size() == 1) {
112  uiGeneralTab.lName->setEnabled(true);
113  uiGeneralTab.leName->setEnabled(true);
114  uiGeneralTab.lComment->setEnabled(true);
115  uiGeneralTab.leComment->setEnabled(true);
116 
117  uiGeneralTab.leName->setText(m_curve->name());
118  uiGeneralTab.leComment->setText(m_curve->comment());
119  } else {
120  uiGeneralTab.lName->setEnabled(false);
121  uiGeneralTab.leName->setEnabled(false);
122  uiGeneralTab.lComment->setEnabled(false);
123  uiGeneralTab.leComment->setEnabled(false);
124 
125  uiGeneralTab.leName->setText(QString());
126  uiGeneralTab.leComment->setText(QString());
127  }
128 
129  auto* analysisCurve = dynamic_cast<XYAnalysisCurve*>(m_curve);
130  checkColumnAvailability(cbXDataColumn, analysisCurve->xDataColumn(), analysisCurve->xDataColumnPath());
131  checkColumnAvailability(cbYDataColumn, analysisCurve->yDataColumn(), analysisCurve->yDataColumnPath());
132 
133  //show the properties of the first curve
135 
138  uiGeneralTab.cbAutoRange->setChecked(m_transformData.autoRange);
139  uiGeneralTab.sbMin->setValue(m_transformData.xRange.first());
140  uiGeneralTab.sbMax->setValue(m_transformData.xRange.last());
141  this->autoRangeChanged();
142 
143  uiGeneralTab.cbWindowType->setCurrentIndex(m_transformData.windowType);
144  this->windowTypeChanged();
145  uiGeneralTab.cbType->setCurrentIndex(m_transformData.type);
146  this->typeChanged();
147  uiGeneralTab.cbTwoSided->setChecked(m_transformData.twoSided);
148  this->twoSidedChanged(); // show/hide shifted check box
149  uiGeneralTab.cbShifted->setChecked(m_transformData.shifted);
150  this->shiftedChanged();
151  uiGeneralTab.cbXScale->setCurrentIndex(m_transformData.xScale);
152  this->xScaleChanged();
153  this->showTransformResult();
154 
155  //enable the "recalculate"-button if the source data was changed since the last transform
157 
158  uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() );
159 
160  //Slots
167 }
168 
176 
179 
181 }
182 
183 /*!
184  sets the curves. The properties of the curves in the list \c list can be edited in this widget.
185 */
187  m_initializing = true;
188  m_curvesList = list;
189  m_curve = list.first();
190  m_aspect = m_curve;
193  this->setModel();
194  m_transformData = m_transformCurve->transformData();
195 
197  uiGeneralTab.sbMin->setLocale(numberLocale);
198  uiGeneralTab.sbMax->setLocale(numberLocale);
199 
200  initGeneralTab();
201  initTabs();
202  m_initializing = false;
203 }
204 
205 //*************************************************************
206 //**** SLOTs for changes triggered in XYFitCurveDock *****
207 //*************************************************************
208 void XYFourierTransformCurveDock::xDataColumnChanged(const QModelIndex& index) {
209  if (m_initializing)
210  return;
211 
212  auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
213  auto* column = dynamic_cast<AbstractColumn*>(aspect);
214 
215  for (auto* curve : m_curvesList)
216  dynamic_cast<XYFourierTransformCurve*>(curve)->setXDataColumn(column);
217 
218  if (column != nullptr) {
219  if (uiGeneralTab.cbAutoRange->isChecked()) {
220  uiGeneralTab.sbMin->setValue(column->minimum());
221  uiGeneralTab.sbMax->setValue(column->maximum());
222  }
223  }
224 
226  cbXDataColumn->setInvalid(false);
227 }
228 
229 void XYFourierTransformCurveDock::yDataColumnChanged(const QModelIndex& index) {
230  if (m_initializing)
231  return;
232 
233  auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
234  auto* column = dynamic_cast<AbstractColumn*>(aspect);
235 
236  for (auto* curve : m_curvesList)
237  dynamic_cast<XYFourierTransformCurve*>(curve)->setYDataColumn(column);
238 
240  cbYDataColumn->setInvalid(false);
241 }
242 
244  bool autoRange = uiGeneralTab.cbAutoRange->isChecked();
245  m_transformData.autoRange = autoRange;
246 
247  if (autoRange) {
248  uiGeneralTab.lMin->setEnabled(false);
249  uiGeneralTab.sbMin->setEnabled(false);
250  uiGeneralTab.lMax->setEnabled(false);
251  uiGeneralTab.sbMax->setEnabled(false);
253  if (m_transformCurve->xDataColumn()) {
254  uiGeneralTab.sbMin->setValue(m_transformCurve->xDataColumn()->minimum());
255  uiGeneralTab.sbMax->setValue(m_transformCurve->xDataColumn()->maximum());
256  }
257  } else {
258  uiGeneralTab.lMin->setEnabled(true);
259  uiGeneralTab.sbMin->setEnabled(true);
260  uiGeneralTab.lMax->setEnabled(true);
261  uiGeneralTab.sbMax->setEnabled(true);
262  }
263 
264 }
266  double xMin = uiGeneralTab.sbMin->value();
267 
268  m_transformData.xRange.first() = xMin;
269  uiGeneralTab.pbRecalculate->setEnabled(true);
270 }
271 
273  double xMax = uiGeneralTab.sbMax->value();
274 
275  m_transformData.xRange.last() = xMax;
276  uiGeneralTab.pbRecalculate->setEnabled(true);
277 }
278 
280  auto windowType = (nsl_sf_window_type)uiGeneralTab.cbWindowType->currentIndex();
281  m_transformData.windowType = windowType;
282 
284 }
285 
287  auto type = (nsl_dft_result_type)uiGeneralTab.cbType->currentIndex();
289 
291 }
292 
294  bool twoSided = uiGeneralTab.cbTwoSided->isChecked();
295  m_transformData.twoSided = twoSided;
296 
297  if (twoSided)
298  uiGeneralTab.cbShifted->setEnabled(true);
299  else {
300  uiGeneralTab.cbShifted->setEnabled(false);
301  uiGeneralTab.cbShifted->setChecked(false);
302  }
303 
305 }
306 
308  bool shifted = uiGeneralTab.cbShifted->isChecked();
309  m_transformData.shifted = shifted;
310 
312 }
313 
315  auto xScale = (nsl_dft_xscale)uiGeneralTab.cbXScale->currentIndex();
316  m_transformData.xScale = xScale;
317 
319 }
320 
322 
323  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
324  for (auto* curve : m_curvesList)
325  dynamic_cast<XYFourierTransformCurve*>(curve)->setTransformData(m_transformData);
326 
327  uiGeneralTab.pbRecalculate->setEnabled(false);
328  emit info(i18n("Fourier transformation status: %1", m_transformCurve->transformResult().status));
329  QApplication::restoreOverrideCursor();
330 }
331 
333  if (m_initializing)
334  return;
335 
336  //no transforming possible without the x- and y-data
337  AbstractAspect* aspectX = static_cast<AbstractAspect*>(cbXDataColumn->currentModelIndex().internalPointer());
338  AbstractAspect* aspectY = static_cast<AbstractAspect*>(cbYDataColumn->currentModelIndex().internalPointer());
339  bool data = (aspectX != nullptr && aspectY != nullptr);
340  if (aspectX) {
342  cbXDataColumn->setInvalid(false);
343  }
344  if (aspectY) {
346  cbYDataColumn->setInvalid(false);
347  }
348 
349  uiGeneralTab.pbRecalculate->setEnabled(data);
350 }
351 
352 /*!
353  * show the result and details of the transform
354  */
357  if (!transformResult.available) {
358  uiGeneralTab.teResult->clear();
359  return;
360  }
361 
362  QString str = i18n("status: %1", transformResult.status) + "<br>";
363 
364  if (!transformResult.valid) {
365  uiGeneralTab.teResult->setText(str);
366  return; //result is not valid, there was an error which is shown in the status-string, nothing to show more.
367  }
368 
370  if (transformResult.elapsedTime > 1000)
371  str += i18n("calculation time: %1 s", numberLocale.toString(transformResult.elapsedTime/1000)) + "<br>";
372  else
373  str += i18n("calculation time: %1 ms", numberLocale.toString(transformResult.elapsedTime)) + "<br>";
374 
375  str += "<br><br>";
376 
377  uiGeneralTab.teResult->setText(str);
378 }
379 
380 //*************************************************************
381 //*********** SLOTs for changes triggered in XYCurve **********
382 //*************************************************************
383 //General-Tab
385  if (m_curve != aspect)
386  return;
387 
388  m_initializing = true;
389  if (aspect->name() != uiGeneralTab.leName->text())
390  uiGeneralTab.leName->setText(aspect->name());
391  else if (aspect->comment() != uiGeneralTab.leComment->text())
392  uiGeneralTab.leComment->setText(aspect->comment());
393  m_initializing = false;
394 }
395 
397  m_initializing = true;
399  m_initializing = false;
400 }
401 
403  m_initializing = true;
405  m_initializing = false;
406 }
407 
409  m_initializing = true;
410  m_transformData = transformData;
411  uiGeneralTab.cbType->setCurrentIndex(m_transformData.type);
412  this->typeChanged();
413 
414  this->showTransformResult();
415  m_initializing = false;
416 }
417 
419  this->enableRecalculate();
420 }
421 
423  m_initializing = true;
424  uiGeneralTab.chkVisible->setChecked(on);
425  m_initializing = false;
426 }
Base class of all persistent objects in a Project.
void aspectDescriptionChanged(const AbstractAspect *)
Emitted after the name, comment or caption spec have changed.
QString name() const
QString comment() const
virtual Project * project()
Return the Project this Aspect belongs to, or 0 if it is currently not part of one.
Interface definition for data with column logic.
Represents a tree of AbstractAspect objects as a Qt item model.
QLineEdit * m_leName
Definition: BaseDock.h:68
QLineEdit * m_leComment
Definition: BaseDock.h:69
void commentChanged()
Definition: BaseDock.cpp:61
AbstractAspect * m_aspect
Definition: BaseDock.h:70
bool m_initializing
Definition: BaseDock.h:67
void nameChanged()
Definition: BaseDock.cpp:47
Provides a QTreeView in a QComboBox.
void setInvalid(bool invalid, const QString &tooltip=QString())
void setModel(QAbstractItemModel *)
QModelIndex currentModelIndex() const
void useCurrentIndexText(const bool set)
void setTopLevelClasses(const QList< AspectType > &)
void currentModelIndexChanged(const QModelIndex &)
Base class for all analysis curves.
void yDataColumnChanged(const AbstractColumn *)
void xDataColumnChanged(const AbstractColumn *)
void sourceDataChanged()
Provides a widget for editing the properties of the XYCurves (2D-curves) currently selected in the pr...
Definition: XYCurveDock.h:46
void initTabs()
XYCurve * m_curve
Definition: XYCurveDock.h:82
AspectTreeModel * m_aspectTreeModel
Definition: XYCurveDock.h:83
void info(const QString &)
virtual void setModel()
QList< XYCurve * > m_curvesList
Definition: XYCurveDock.h:81
void setModelIndexFromAspect(TreeViewComboBox *, const AbstractAspect *)
Ui::XYCurveDock ui
Definition: XYCurveDock.h:80
void visibilityChanged(bool)
void checkColumnAvailability(TreeViewComboBox *, const AbstractColumn *, const QString &columnPath)
bool isVisible() const override
Return whether the element is (at least) partially visible.
Definition: XYCurve.cpp:216
bool isSourceDataChangedSinceLastRecalc() const
Definition: XYCurve.cpp:329
void visibilityChanged()
Definition: XYCurve.cpp:902
XYFourierTransformCurve * m_transformCurve
XYFourierTransformCurve::TransformData m_transformData
void curveTransformDataChanged(const XYFourierTransformCurve::TransformData &)
Ui::XYFourierTransformCurveDockGeneralTab uiGeneralTab
void yDataColumnChanged(const QModelIndex &)
void xDataColumnChanged(const QModelIndex &)
void curveXDataColumnChanged(const AbstractColumn *)
void curveDescriptionChanged(const AbstractAspect *)
void curveYDataColumnChanged(const AbstractColumn *)
A xy-curve defined by a Fourier transform.
void transformDataChanged(const XYFourierTransformCurve::TransformData &)
const TransformResult & transformResult() const
#define SET_NUMBER_LOCALE
Definition: macros.h:75
#define i18n(m)
Definition: nsl_common.h:38
const char * nsl_dft_xscale_name[]
Definition: nsl_dft.c:39
const char * nsl_dft_result_type_name[]
Definition: nsl_dft.c:37
#define NSL_DFT_RESULT_TYPE_COUNT
Definition: nsl_dft.h:49
nsl_dft_result_type
Definition: nsl_dft.h:50
nsl_dft_xscale
Definition: nsl_dft.h:56
#define NSL_DFT_XSCALE_COUNT
Definition: nsl_dft.h:55
const char * nsl_sf_window_type_name[]
Definition: nsl_sf_window.c:34
#define NSL_SF_WINDOW_TYPE_COUNT
Definition: nsl_sf_window.h:34
nsl_sf_window_type
Definition: nsl_sf_window.h:35