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)  

XYInterpolationCurveDock.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : XYInterpolationCurveDock.cpp
3  Project : LabPlot
4  --------------------------------------------------------------------
5  Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn)
6  Copyright : (C) 20016-2017 Alexander Semke (alexander.semke@web.de)
7  Description : widget for editing properties of interpolation curves
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  * This program is distributed in the hope that it will be useful, *
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21  * GNU General Public License for more details. *
22  * *
23  * You should have received a copy of the GNU General Public License *
24  * along with this program; if not, write to the Free Software *
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26  * Boston, MA 02110-1301 USA *
27  * *
28  ***************************************************************************/
29 
32 #include "backend/core/Project.h"
35 
36 #include <QMenu>
37 #include <QWidgetAction>
38 #include <QStandardItemModel>
39 
40 extern "C" {
41 #include <gsl/gsl_interp.h> // gsl_interp types
42 }
43 #include <cmath> // isnan
44 
45 /*!
46  \class XYInterpolationCurveDock
47  \brief Provides a widget for editing the properties of the XYInterpolationCurves
48  (2D-curves defined by an interpolation) currently selected in
49  the project explorer.
50 
51  If more then one curves are set, the properties of the first column are shown.
52  The changes of the properties are applied to all curves.
53  The exclusions are the name, the comment and the datasets (columns) of
54  the curves - these properties can only be changed if there is only one single curve.
55 
56  \ingroup kdefrontend
57 */
58 
60 }
61 
62 /*!
63  * // Tab "General"
64  */
66  QWidget* generalTab = new QWidget(ui.tabGeneral);
67  uiGeneralTab.setupUi(generalTab);
68  m_leName = uiGeneralTab.leName;
69  m_leComment = uiGeneralTab.leComment;
70 
71  auto* gridLayout = static_cast<QGridLayout*>(generalTab->layout());
72  gridLayout->setContentsMargins(2,2,2,2);
73  gridLayout->setHorizontalSpacing(2);
74  gridLayout->setVerticalSpacing(2);
75 
76  uiGeneralTab.cbDataSourceType->addItem(i18n("Spreadsheet"));
77  uiGeneralTab.cbDataSourceType->addItem(i18n("XY-Curve"));
78 
79  cbDataSourceCurve = new TreeViewComboBox(generalTab);
80  gridLayout->addWidget(cbDataSourceCurve, 5, 2, 1, 2);
81  cbXDataColumn = new TreeViewComboBox(generalTab);
82  gridLayout->addWidget(cbXDataColumn, 6, 2, 1, 2);
83  cbYDataColumn = new TreeViewComboBox(generalTab);
84  gridLayout->addWidget(cbYDataColumn, 7, 2, 1, 2);
85 
86  for (int i = 0; i < NSL_INTERP_TYPE_COUNT; i++)
87  uiGeneralTab.cbType->addItem(i18n(nsl_interp_type_name[i]));
88 #if GSL_MAJOR_VERSION < 2
89  // disable Steffen spline item
90  const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(uiGeneralTab.cbType->model());
91  QStandardItem* item = model->item(nsl_interp_type_steffen);
92  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
93 #endif
94  for (int i = 0; i < NSL_INTERP_PCH_VARIANT_COUNT; i++)
95  uiGeneralTab.cbVariant->addItem(i18n(nsl_interp_pch_variant_name[i]));
96  for (int i = 0; i < NSL_INTERP_EVALUATE_COUNT; i++)
97  uiGeneralTab.cbEval->addItem(i18n(nsl_interp_evaluate_name[i]));
98 
99  uiGeneralTab.cbPointsMode->addItem(i18n("Auto (5x data points)"));
100  uiGeneralTab.cbPointsMode->addItem(i18n("Multiple of data points"));
101  uiGeneralTab.cbPointsMode->addItem(i18n("Custom"));
102 
103  //TODO: use line edits
104  uiGeneralTab.sbMin->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
105  uiGeneralTab.sbMax->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
106 
107  uiGeneralTab.pbRecalculate->setIcon(QIcon::fromTheme("run-build"));
108 
109  auto* layout = new QHBoxLayout(ui.tabGeneral);
110  layout->setMargin(0);
111  layout->addWidget(generalTab);
112 
113  //Slots
114  connect( uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYInterpolationCurveDock::nameChanged );
115  connect( uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYInterpolationCurveDock::commentChanged );
116  connect(uiGeneralTab.chkVisible, &QCheckBox::clicked, this, &XYInterpolationCurveDock::visibilityChanged);
117  connect(uiGeneralTab.cbDataSourceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYInterpolationCurveDock::dataSourceTypeChanged);
118  connect(uiGeneralTab.cbAutoRange, &QCheckBox::clicked, this, &XYInterpolationCurveDock::autoRangeChanged);
119  connect(uiGeneralTab.sbMin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYInterpolationCurveDock::xRangeMinChanged);
120  connect(uiGeneralTab.sbMax, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYInterpolationCurveDock::xRangeMaxChanged);
121  connect(uiGeneralTab.dateTimeEditMin, &QDateTimeEdit::dateTimeChanged, this, &XYInterpolationCurveDock::xRangeMinDateTimeChanged);
122  connect(uiGeneralTab.dateTimeEditMax, &QDateTimeEdit::dateTimeChanged, this, &XYInterpolationCurveDock::xRangeMaxDateTimeChanged);
123  connect(uiGeneralTab.cbType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYInterpolationCurveDock::typeChanged);
124  connect(uiGeneralTab.cbVariant, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYInterpolationCurveDock::variantChanged);
125  //TODO: use line edits?
126  connect(uiGeneralTab.sbTension, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYInterpolationCurveDock::tensionChanged);
127  connect(uiGeneralTab.sbContinuity, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYInterpolationCurveDock::continuityChanged);
128  connect(uiGeneralTab.sbBias, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYInterpolationCurveDock::biasChanged);
129  connect(uiGeneralTab.cbEval, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYInterpolationCurveDock::evaluateChanged);
130  // double?
131  connect(uiGeneralTab.sbPoints, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYInterpolationCurveDock::numberOfPointsChanged);
132  connect(uiGeneralTab.cbPointsMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYInterpolationCurveDock::pointsModeChanged);
133  connect(uiGeneralTab.pbRecalculate, &QPushButton::clicked, this, &XYInterpolationCurveDock::recalculateClicked);
134 
138 }
139 
141  //if there are more then one curve in the list, disable the tab "general"
142  if (m_curvesList.size() == 1) {
143  uiGeneralTab.lName->setEnabled(true);
144  uiGeneralTab.leName->setEnabled(true);
145  uiGeneralTab.lComment->setEnabled(true);
146  uiGeneralTab.leComment->setEnabled(true);
147 
148  uiGeneralTab.leName->setText(m_curve->name());
149  uiGeneralTab.leComment->setText(m_curve->comment());
150  } else {
151  uiGeneralTab.lName->setEnabled(false);
152  uiGeneralTab.leName->setEnabled(false);
153  uiGeneralTab.lComment->setEnabled(false);
154  uiGeneralTab.leComment->setEnabled(false);
155 
156  uiGeneralTab.leName->setText(QString());
157  uiGeneralTab.leComment->setText(QString());
158  }
159 
160  //show the properties of the first curve
164 
165  //data source
166  uiGeneralTab.cbDataSourceType->setCurrentIndex(static_cast<int>(m_interpolationCurve->dataSourceType()));
167  this->dataSourceTypeChanged(uiGeneralTab.cbDataSourceType->currentIndex());
171 
172  //range widgets
173  const auto* plot = static_cast<const CartesianPlot*>(m_interpolationCurve->parentAspect());
174  m_dateTimeRange = (plot->xRangeFormat() != CartesianPlot::RangeFormat::Numeric);
175  if (!m_dateTimeRange) {
176  uiGeneralTab.sbMin->setValue(m_interpolationData.xRange.first());
177  uiGeneralTab.sbMax->setValue(m_interpolationData.xRange.last());
178  } else {
179  uiGeneralTab.dateTimeEditMin->setDateTime( QDateTime::fromMSecsSinceEpoch(m_interpolationData.xRange.first()) );
180  uiGeneralTab.dateTimeEditMax->setDateTime( QDateTime::fromMSecsSinceEpoch(m_interpolationData.xRange.last()) );
181  }
182 
183  uiGeneralTab.lMin->setVisible(!m_dateTimeRange);
184  uiGeneralTab.sbMin->setVisible(!m_dateTimeRange);
185  uiGeneralTab.lMax->setVisible(!m_dateTimeRange);
186  uiGeneralTab.sbMax->setVisible(!m_dateTimeRange);
187  uiGeneralTab.lMinDateTime->setVisible(m_dateTimeRange);
188  uiGeneralTab.dateTimeEditMin->setVisible(m_dateTimeRange);
189  uiGeneralTab.lMaxDateTime->setVisible(m_dateTimeRange);
190  uiGeneralTab.dateTimeEditMax->setVisible(m_dateTimeRange);
191 
192  //auto range
193  uiGeneralTab.cbAutoRange->setChecked(m_interpolationData.autoRange);
194  this->autoRangeChanged();
195 
196  // update list of selectable types
198 
199  uiGeneralTab.cbType->setCurrentIndex(m_interpolationData.type);
201  uiGeneralTab.cbVariant->setCurrentIndex(m_interpolationData.variant);
203  uiGeneralTab.sbTension->setValue(m_interpolationData.tension);
204  uiGeneralTab.sbContinuity->setValue(m_interpolationData.continuity);
205  uiGeneralTab.sbBias->setValue(m_interpolationData.bias);
206  uiGeneralTab.cbEval->setCurrentIndex(m_interpolationData.evaluate);
207 
209  uiGeneralTab.sbPoints->setValue(m_interpolationData.npoints/5.);
210  else
211  uiGeneralTab.sbPoints->setValue(m_interpolationData.npoints);
212  uiGeneralTab.cbPointsMode->setCurrentIndex(static_cast<int>(m_interpolationData.pointsMode));
213 
214  this->showInterpolationResult();
215 
216  uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() );
217 
218  //Slots
226 }
227 
232 
233  QList<const AbstractAspect*> hiddenAspects;
234  for (auto* curve : m_curvesList)
235  hiddenAspects << curve;
236  cbDataSourceCurve->setHiddenAspects(hiddenAspects);
237 
242  };
245 
249 
251 }
252 
253 /*!
254  sets the curves. The properties of the curves in the list \c list can be edited in this widget.
255 */
257  m_initializing = true;
258  m_curvesList = list;
259  m_curve = list.first();
260  m_aspect = m_curve;
262  Q_ASSERT(m_interpolationCurve);
264  this->setModel();
265  m_interpolationData = m_interpolationCurve->interpolationData();
266 
268  uiGeneralTab.sbMin->setLocale(numberLocale);
269  uiGeneralTab.sbMax->setLocale(numberLocale);
270  uiGeneralTab.sbTension->setLocale(numberLocale);
271  uiGeneralTab.sbContinuity->setLocale(numberLocale);
272  uiGeneralTab.sbBias->setLocale(numberLocale);
273  uiGeneralTab.sbPoints->setLocale(numberLocale);
274 
275  initGeneralTab();
276  initTabs();
277  m_initializing = false;
278 
279  //hide the "skip gaps" option after the curves were set
280  ui.lLineSkipGaps->hide();
281  ui.chkLineSkipGaps->hide();
282 }
283 
284 //*************************************************************
285 //**** SLOTs for changes triggered in XYFitCurveDock *****
286 //*************************************************************
288  const auto type = (XYAnalysisCurve::DataSourceType)index;
290  uiGeneralTab.lDataSourceCurve->hide();
291  cbDataSourceCurve->hide();
292  uiGeneralTab.lXColumn->show();
293  cbXDataColumn->show();
294  uiGeneralTab.lYColumn->show();
295  cbYDataColumn->show();
296  } else {
297  uiGeneralTab.lDataSourceCurve->show();
298  cbDataSourceCurve->show();
299  uiGeneralTab.lXColumn->hide();
300  cbXDataColumn->hide();
301  uiGeneralTab.lYColumn->hide();
302  cbYDataColumn->hide();
303  }
304 
305  if (m_initializing)
306  return;
307 
308  for (XYCurve* curve: m_curvesList)
309  dynamic_cast<XYInterpolationCurve*>(curve)->setDataSourceType(type);
310 }
311 
312 void XYInterpolationCurveDock::dataSourceCurveChanged(const QModelIndex& index) {
313  auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
314  auto* dataSourceCurve = dynamic_cast<XYCurve*>(aspect);
315 
316  // disable types that need more data points
317  if (dataSourceCurve)
318  this->updateSettings(dataSourceCurve->xColumn());
319 
320  if (m_initializing)
321  return;
322 
323  for (XYCurve* curve: m_curvesList)
324  dynamic_cast<XYInterpolationCurve*>(curve)->setDataSourceCurve(dataSourceCurve);
325 }
326 
327 void XYInterpolationCurveDock::xDataColumnChanged(const QModelIndex& index) {
328  auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
329  AbstractColumn* column = nullptr;
330  if (aspect) {
331  column = dynamic_cast<AbstractColumn*>(aspect);
332  Q_ASSERT(column);
333  }
334 
335  this->updateSettings(column);
336 
337  if (m_initializing)
338  return;
339 
340  for (XYCurve* curve: m_curvesList)
341  dynamic_cast<XYInterpolationCurve*>(curve)->setXDataColumn(column);
342 
344  cbXDataColumn->setInvalid(false);
345 }
346 
348  if (!column)
349  return;
350 
351  // disable types that need more data points
352  if (uiGeneralTab.cbAutoRange->isChecked()) {
353  uiGeneralTab.sbMin->setValue(column->minimum());
354  uiGeneralTab.sbMax->setValue(column->maximum());
355  }
356 
357  unsigned int n = 0;
358  for (int row = 0; row < column->rowCount(); row++)
359  if (!std::isnan(column->valueAt(row)) && !column->isMasked(row))
360  n++;
361  dataPoints = n;
363  pointsModeChanged(uiGeneralTab.cbPointsMode->currentIndex());
364 
365  const auto* model = qobject_cast<const QStandardItemModel*>(uiGeneralTab.cbType->model());
366  QStandardItem* item = model->item(nsl_interp_type_polynomial);
367  if (dataPoints < gsl_interp_type_min_size(gsl_interp_polynomial) || dataPoints > 100) { // not good for many points
368  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
369  if (uiGeneralTab.cbType->currentIndex() == nsl_interp_type_polynomial)
370  uiGeneralTab.cbType->setCurrentIndex(0);
371  }
372  else
373  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
374 
375  item = model->item(nsl_interp_type_cspline);
376  if (dataPoints < gsl_interp_type_min_size(gsl_interp_cspline)) {
377  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
378  if (uiGeneralTab.cbType->currentIndex() == nsl_interp_type_cspline)
379  uiGeneralTab.cbType->setCurrentIndex(0);
380  }
381  else
382  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
383 
384  item = model->item(nsl_interp_type_cspline_periodic);
385  if (dataPoints < gsl_interp_type_min_size(gsl_interp_cspline_periodic)) {
386  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
387  if (uiGeneralTab.cbType->currentIndex() == nsl_interp_type_cspline_periodic)
388  uiGeneralTab.cbType->setCurrentIndex(0);
389  }
390  else
391  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
392 
393  item = model->item(nsl_interp_type_akima);
394  if (dataPoints < gsl_interp_type_min_size(gsl_interp_akima)) {
395  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
396  if (uiGeneralTab.cbType->currentIndex() == nsl_interp_type_akima)
397  uiGeneralTab.cbType->setCurrentIndex(0);
398  }
399  else
400  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
401 
402  item = model->item(nsl_interp_type_akima_periodic);
403  if (dataPoints < gsl_interp_type_min_size(gsl_interp_akima_periodic)) {
404  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
405  if (uiGeneralTab.cbType->currentIndex() == nsl_interp_type_akima_periodic)
406  uiGeneralTab.cbType->setCurrentIndex(0);
407  }
408  else
409  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
410 
411 #if GSL_MAJOR_VERSION >= 2
412  item = model->item(nsl_interp_type_steffen);
413  if (dataPoints < gsl_interp_type_min_size(gsl_interp_steffen)) {
414  item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
415  if (uiGeneralTab.cbType->currentIndex() == nsl_interp_type_steffen)
416  uiGeneralTab.cbType->setCurrentIndex(0);
417  }
418  else
419  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
420 #endif
421  // own types work with 2 or more data points
422 }
423 
424 void XYInterpolationCurveDock::yDataColumnChanged(const QModelIndex& index) {
425  if (m_initializing)
426  return;
427 
428  auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
429  AbstractColumn* column = nullptr;
430  if (aspect) {
431  column = dynamic_cast<AbstractColumn*>(aspect);
432  Q_ASSERT(column);
433  }
434 
435  for (XYCurve* curve: m_curvesList)
436  dynamic_cast<XYInterpolationCurve*>(curve)->setYDataColumn(column);
437 
439  cbYDataColumn->setInvalid(false);
440 }
441 
443  bool autoRange = uiGeneralTab.cbAutoRange->isChecked();
444  m_interpolationData.autoRange = autoRange;
445 
446  uiGeneralTab.lMin->setEnabled(!autoRange);
447  uiGeneralTab.sbMin->setEnabled(!autoRange);
448  uiGeneralTab.lMax->setEnabled(!autoRange);
449  uiGeneralTab.sbMax->setEnabled(!autoRange);
450  uiGeneralTab.lMinDateTime->setEnabled(!autoRange);
451  uiGeneralTab.dateTimeEditMin->setEnabled(!autoRange);
452  uiGeneralTab.lMaxDateTime->setEnabled(!autoRange);
453  uiGeneralTab.dateTimeEditMax->setEnabled(!autoRange);
454 
455  if (autoRange) {
456  const AbstractColumn* xDataColumn = nullptr;
458  xDataColumn = m_interpolationCurve->xDataColumn();
459  else {
460  if (m_interpolationCurve->dataSourceCurve())
461  xDataColumn = m_interpolationCurve->dataSourceCurve()->xColumn();
462  }
463 
464  if (xDataColumn) {
465  if (!m_dateTimeRange) {
466  uiGeneralTab.sbMin->setValue(xDataColumn->minimum());
467  uiGeneralTab.sbMax->setValue(xDataColumn->maximum());
468  } else {
469  uiGeneralTab.dateTimeEditMin->setDateTime(QDateTime::fromMSecsSinceEpoch(xDataColumn->minimum()));
470  uiGeneralTab.dateTimeEditMax->setDateTime(QDateTime::fromMSecsSinceEpoch(xDataColumn->maximum()));
471  }
472  }
473  }
474 }
475 
477  m_interpolationData.xRange.first() = value;
478  uiGeneralTab.pbRecalculate->setEnabled(true);
479 }
480 
482  m_interpolationData.xRange.last() = value;
483  uiGeneralTab.pbRecalculate->setEnabled(true);
484 }
485 
486 void XYInterpolationCurveDock::xRangeMinDateTimeChanged(const QDateTime& dateTime) {
487  if (m_initializing)
488  return;
489 
490  m_interpolationData.xRange.first() = dateTime.toMSecsSinceEpoch();
491  uiGeneralTab.pbRecalculate->setEnabled(true);
492 }
493 
494 void XYInterpolationCurveDock::xRangeMaxDateTimeChanged(const QDateTime& dateTime) {
495  if (m_initializing)
496  return;
497 
498  m_interpolationData.xRange.last() = dateTime.toMSecsSinceEpoch();
499  uiGeneralTab.pbRecalculate->setEnabled(true);
500 }
501 
503  const auto type = (nsl_interp_type)index;
505 
506  switch (type) {
507  case nsl_interp_type_pch:
508  uiGeneralTab.lVariant->show();
509  uiGeneralTab.cbVariant->show();
510  break;
521  uiGeneralTab.lVariant->hide();
522  uiGeneralTab.cbVariant->hide();
523  uiGeneralTab.cbVariant->setCurrentIndex(nsl_interp_pch_variant_finite_difference);
524  uiGeneralTab.lParameter->hide();
525  uiGeneralTab.lTension->hide();
526  uiGeneralTab.sbTension->hide();
527  uiGeneralTab.lContinuity->hide();
528  uiGeneralTab.sbContinuity->hide();
529  uiGeneralTab.lBias->hide();
530  uiGeneralTab.sbBias->hide();
531  }
532 
533  uiGeneralTab.pbRecalculate->setEnabled(true);
534 }
535 
537  const auto variant = (nsl_interp_pch_variant)index;
539 
540  switch (variant) {
542  uiGeneralTab.lParameter->hide();
543  uiGeneralTab.lTension->hide();
544  uiGeneralTab.sbTension->hide();
545  uiGeneralTab.lContinuity->hide();
546  uiGeneralTab.sbContinuity->hide();
547  uiGeneralTab.lBias->hide();
548  uiGeneralTab.sbBias->hide();
549  break;
551  uiGeneralTab.lParameter->show();
552  uiGeneralTab.lTension->show();
553  uiGeneralTab.sbTension->show();
554  uiGeneralTab.sbTension->setEnabled(false);
555  uiGeneralTab.sbTension->setValue(0.0);
556  uiGeneralTab.lContinuity->hide();
557  uiGeneralTab.sbContinuity->hide();
558  uiGeneralTab.lBias->hide();
559  uiGeneralTab.sbBias->hide();
560  break;
562  uiGeneralTab.lParameter->show();
563  uiGeneralTab.lTension->show();
564  uiGeneralTab.sbTension->show();
565  uiGeneralTab.sbTension->setEnabled(true);
566  uiGeneralTab.lContinuity->hide();
567  uiGeneralTab.sbContinuity->hide();
568  uiGeneralTab.lBias->hide();
569  uiGeneralTab.sbBias->hide();
570  break;
572  uiGeneralTab.lParameter->show();
573  uiGeneralTab.lTension->show();
574  uiGeneralTab.sbTension->show();
575  uiGeneralTab.sbTension->setEnabled(true);
576  uiGeneralTab.lContinuity->show();
577  uiGeneralTab.sbContinuity->show();
578  uiGeneralTab.lBias->show();
579  uiGeneralTab.sbBias->show();
580  break;
581  }
582 
583  uiGeneralTab.pbRecalculate->setEnabled(true);
584 }
585 
588  uiGeneralTab.pbRecalculate->setEnabled(true);
589 }
590 
593  uiGeneralTab.pbRecalculate->setEnabled(true);
594 }
595 
597  m_interpolationData.bias = value;
598  uiGeneralTab.pbRecalculate->setEnabled(true);
599 }
600 
603  uiGeneralTab.pbRecalculate->setEnabled(true);
604 }
605 
607  const auto mode = (XYInterpolationCurve::PointsMode)index;
608 
609  switch (mode) {
611  uiGeneralTab.sbPoints->setEnabled(false);
612  uiGeneralTab.sbPoints->setDecimals(0);
613  uiGeneralTab.sbPoints->setSingleStep(1.0);
614  uiGeneralTab.sbPoints->setValue(5*dataPoints);
615  break;
617  uiGeneralTab.sbPoints->setEnabled(true);
619  uiGeneralTab.sbPoints->setDecimals(2);
620  uiGeneralTab.sbPoints->setValue(uiGeneralTab.sbPoints->value()/(double)dataPoints);
621  uiGeneralTab.sbPoints->setSingleStep(0.01);
622  }
623  break;
625  uiGeneralTab.sbPoints->setEnabled(true);
627  uiGeneralTab.sbPoints->setDecimals(0);
628  uiGeneralTab.sbPoints->setSingleStep(1.0);
629  uiGeneralTab.sbPoints->setValue(uiGeneralTab.sbPoints->value()*dataPoints);
630  }
631  break;
632  }
633 
635 }
636 
638  m_interpolationData.npoints = uiGeneralTab.sbPoints->value();
639  if (uiGeneralTab.cbPointsMode->currentIndex() == static_cast<int>(XYInterpolationCurve::PointsMode::Multiple))
641 
642  // warn if points is smaller than data points
643  QPalette palette = uiGeneralTab.sbPoints->palette();
645  palette.setColor(QPalette::Text, Qt::red);
646  else
647  palette.setColor(QPalette::Text, Qt::black);
648  uiGeneralTab.sbPoints->setPalette(palette);
649 
651 }
652 
654  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
655 
656  for (XYCurve* curve: m_curvesList)
657  dynamic_cast<XYInterpolationCurve*>(curve)->setInterpolationData(m_interpolationData);
658 
659  uiGeneralTab.pbRecalculate->setEnabled(false);
660  emit info(i18n("Interpolation status: %1", m_interpolationCurve->interpolationResult().status));
661  QApplication::restoreOverrideCursor();
662 }
663 
665  if (m_initializing)
666  return;
667 
668  //no interpolation possible without the x- and y-data
669  bool hasSourceData = false;
671  AbstractAspect* aspectX = static_cast<AbstractAspect*>(cbXDataColumn->currentModelIndex().internalPointer());
672  AbstractAspect* aspectY = static_cast<AbstractAspect*>(cbYDataColumn->currentModelIndex().internalPointer());
673  hasSourceData = (aspectX != nullptr && aspectY != nullptr);
674  if (aspectX) {
676  cbXDataColumn->setInvalid(false);
677  }
678  if (aspectY) {
680  cbYDataColumn->setInvalid(false);
681  }
682  } else {
683  hasSourceData = (m_interpolationCurve->dataSourceCurve() != nullptr);
684  }
685 
686  uiGeneralTab.pbRecalculate->setEnabled(hasSourceData);
687 }
688 
689 /*!
690  * show the result and details of the interpolation
691  */
693  const auto& interpolationResult = m_interpolationCurve->interpolationResult();
694  if (!interpolationResult.available) {
695  uiGeneralTab.teResult->clear();
696  return;
697  }
698 
699  QString str = i18n("status: %1", interpolationResult.status) + "<br>";
700 
701  if (!interpolationResult.valid) {
702  uiGeneralTab.teResult->setText(str);
703  return; //result is not valid, there was an error which is shown in the status-string, nothing to show more.
704  }
705 
707  if (interpolationResult.elapsedTime > 1000)
708  str += i18n("calculation time: %1 s", numberLocale.toString(interpolationResult.elapsedTime/1000)) + "<br>";
709  else
710  str += i18n("calculation time: %1 ms", numberLocale.toString(interpolationResult.elapsedTime)) + "<br>";
711 
712  str += "<br><br>";
713 
714  uiGeneralTab.teResult->setText(str);
715 
716  //enable the "recalculate"-button if the source data was changed since the last interpolation
718 }
719 
720 //*************************************************************
721 //*********** SLOTs for changes triggered in XYCurve **********
722 //*************************************************************
723 //General-Tab
725  if (m_curve != aspect)
726  return;
727 
728  m_initializing = true;
729  if (aspect->name() != uiGeneralTab.leName->text())
730  uiGeneralTab.leName->setText(aspect->name());
731  else if (aspect->comment() != uiGeneralTab.leComment->text())
732  uiGeneralTab.leComment->setText(aspect->comment());
733  m_initializing = false;
734 }
735 
737  m_initializing = true;
738  uiGeneralTab.cbDataSourceType->setCurrentIndex(static_cast<int>(type));
739  m_initializing = false;
740 }
741 
743  m_initializing = true;
745  m_initializing = false;
746 }
747 
749  m_initializing = true;
751  m_initializing = false;
752 }
753 
755  m_initializing = true;
757  m_initializing = false;
758 }
759 
761  m_initializing = true;
763  uiGeneralTab.cbType->setCurrentIndex(m_interpolationData.type);
765 
766  this->showInterpolationResult();
767  m_initializing = false;
768 }
769 
771  this->enableRecalculate();
772 }
static const QRgb black
Definition: ImageEditor.cpp:38
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
AbstractAspect * parentAspect() const
Return my parent Aspect or 0 if I currently don't have one.
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.
virtual double valueAt(int row) const
Return the double value in row 'row'.
bool isMasked(int row) const
Return whether a certain row is masked.
virtual int rowCount() const =0
Return the data vector size.
virtual double maximum(int count=0) const
virtual double minimum(int count=0) const
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
A xy-plot.
Definition: CartesianPlot.h:58
Provides a QTreeView in a QComboBox.
void setInvalid(bool invalid, const QString &tooltip=QString())
void setModel(QAbstractItemModel *)
void setHiddenAspects(const QList< const AbstractAspect * > &)
QModelIndex currentModelIndex() const
void useCurrentIndexText(const bool set)
void setTopLevelClasses(const QList< AspectType > &)
void currentModelIndexChanged(const QModelIndex &)
void yDataColumnChanged(const AbstractColumn *)
void dataSourceTypeChanged(XYAnalysisCurve::DataSourceType)
void dataSourceCurveChanged(const XYCurve *)
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)
A 2D-curve, provides an interface for editing many properties of the curve.
Definition: XYCurve.h:46
bool isVisible() const override
Return whether the element is (at least) partially visible.
Definition: XYCurve.cpp:216
bool isSourceDataChangedSinceLastRecalc() const
Definition: XYCurve.cpp:329
XYInterpolationCurve * m_interpolationCurve
void curveDataSourceCurveChanged(const XYCurve *)
TreeViewComboBox * cbDataSourceCurve
void curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType)
void curveYDataColumnChanged(const AbstractColumn *)
void curveDescriptionChanged(const AbstractAspect *)
void curveXDataColumnChanged(const AbstractColumn *)
void setCurves(QList< XYCurve * >)
XYInterpolationCurve::InterpolationData m_interpolationData
Ui::XYInterpolationCurveDockGeneralTab uiGeneralTab
void updateSettings(const AbstractColumn *)
void xDataColumnChanged(const QModelIndex &)
void xRangeMinDateTimeChanged(const QDateTime &)
void xRangeMaxDateTimeChanged(const QDateTime &)
void curveInterpolationDataChanged(const XYInterpolationCurve::InterpolationData &)
void dataSourceCurveChanged(const QModelIndex &)
void yDataColumnChanged(const QModelIndex &)
A xy-curve defined by an interpolation.
void interpolationDataChanged(const XYInterpolationCurve::InterpolationData &)
const InterpolationResult & interpolationResult() const
#define SET_NUMBER_LOCALE
Definition: macros.h:75
class Origin::Variant variant
@ Text
Definition: OriginObj.h:45
#define i18n(m)
Definition: nsl_common.h:38
const char * nsl_interp_pch_variant_name[]
Definition: nsl_interp.c:34
const char * nsl_interp_type_name[]
Definition: nsl_interp.c:31
const char * nsl_interp_evaluate_name[]
Definition: nsl_interp.c:35
#define NSL_INTERP_EVALUATE_COUNT
Definition: nsl_interp.h:43
#define NSL_INTERP_TYPE_COUNT
Definition: nsl_interp.h:32
nsl_interp_evaluate
Definition: nsl_interp.h:44
nsl_interp_pch_variant
Definition: nsl_interp.h:39
@ nsl_interp_pch_variant_kochanek_bartels
Definition: nsl_interp.h:40
@ nsl_interp_pch_variant_finite_difference
Definition: nsl_interp.h:39
@ nsl_interp_pch_variant_catmull_rom
Definition: nsl_interp.h:39
@ nsl_interp_pch_variant_cardinal
Definition: nsl_interp.h:39
#define NSL_INTERP_PCH_VARIANT_COUNT
Definition: nsl_interp.h:38
nsl_interp_type
Definition: nsl_interp.h:33
@ nsl_interp_type_akima_periodic
Definition: nsl_interp.h:34
@ nsl_interp_type_polynomial
Definition: nsl_interp.h:33
@ nsl_interp_type_akima
Definition: nsl_interp.h:34
@ nsl_interp_type_cspline_periodic
Definition: nsl_interp.h:33
@ nsl_interp_type_linear
Definition: nsl_interp.h:33
@ nsl_interp_type_rational
Definition: nsl_interp.h:35
@ nsl_interp_type_cosine
Definition: nsl_interp.h:34
@ nsl_interp_type_pch
Definition: nsl_interp.h:35
@ nsl_interp_type_cspline
Definition: nsl_interp.h:33
@ nsl_interp_type_exponential
Definition: nsl_interp.h:35
@ nsl_interp_type_steffen
Definition: nsl_interp.h:34
XYInterpolationCurve::PointsMode pointsMode