File indexing completed on 2024-05-12 15:28:03

0001 /***************************************************************************
0002     File             : XYCorrelationCurveDock.cpp
0003     Project          : LabPlot
0004     --------------------------------------------------------------------
0005     Copyright        : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn)
0006     Description      : widget for editing properties of correlation curves
0007 
0008  ***************************************************************************/
0009 
0010 /***************************************************************************
0011  *                                                                         *
0012  *  This program is free software; you can redistribute it and/or modify   *
0013  *  it under the terms of the GNU General Public License as published by   *
0014  *  the Free Software Foundation; either version 2 of the License, or      *
0015  *  (at your option) any later version.                                    *
0016  *                                                                         *
0017  *  This program is distributed in the hope that it will be useful,        *
0018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0020  *  GNU General Public License for more details.                           *
0021  *                                                                         *
0022  *   You should have received a copy of the GNU General Public License     *
0023  *   along with this program; if not, write to the Free Software           *
0024  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0025  *   Boston, MA  02110-1301  USA                                           *
0026  *                                                                         *
0027  ***************************************************************************/
0028 
0029 #include "XYCorrelationCurveDock.h"
0030 #include "backend/core/AspectTreeModel.h"
0031 #include "backend/core/Project.h"
0032 #include "backend/worksheet/plots/cartesian/XYCorrelationCurve.h"
0033 #include "commonfrontend/widgets/TreeViewComboBox.h"
0034 
0035 #include <KConfigGroup>
0036 #include <KSharedConfig>
0037 
0038 #include <QMenu>
0039 #include <QWidgetAction>
0040 #include <QStandardItemModel>
0041 
0042 extern "C" {
0043 #include "backend/nsl/nsl_corr.h"
0044 }
0045 
0046 /*!
0047   \class XYCorrelationCurveDock
0048  \brief  Provides a widget for editing the properties of the XYCorrelationCurves
0049         (2D-curves defined by a correlation) currently selected in
0050         the project explorer.
0051 
0052   If more then one curves are set, the properties of the first column are shown.
0053   The changes of the properties are applied to all curves.
0054   The exclusions are the name, the comment and the datasets (columns) of
0055   the curves  - these properties can only be changed if there is only one single curve.
0056 
0057   \ingroup kdefrontend
0058 */
0059 
0060 XYCorrelationCurveDock::XYCorrelationCurveDock(QWidget* parent) : XYCurveDock(parent) {
0061 }
0062 
0063 /*!
0064  *  // Tab "General"
0065  */
0066 void XYCorrelationCurveDock::setupGeneral() {
0067     DEBUG("XYCorrelationCurveDock::setupGeneral()");
0068     QWidget* generalTab = new QWidget(ui.tabGeneral);
0069     uiGeneralTab.setupUi(generalTab);
0070     m_leName = uiGeneralTab.leName;
0071     m_leComment = uiGeneralTab.leComment;
0072 
0073     auto* gridLayout = static_cast<QGridLayout*>(generalTab->layout());
0074     gridLayout->setContentsMargins(2,2,2,2);
0075     gridLayout->setHorizontalSpacing(2);
0076     gridLayout->setVerticalSpacing(2);
0077 
0078     uiGeneralTab.cbDataSourceType->addItem(i18n("Spreadsheet"));
0079     uiGeneralTab.cbDataSourceType->addItem(i18n("XY-Curve"));
0080 
0081     cbDataSourceCurve = new TreeViewComboBox(generalTab);
0082     gridLayout->addWidget(cbDataSourceCurve, 5, 2, 1, 3);
0083     cbXDataColumn = new TreeViewComboBox(generalTab);
0084     gridLayout->addWidget(cbXDataColumn, 6, 2, 1, 3);
0085     cbYDataColumn = new TreeViewComboBox(generalTab);
0086     gridLayout->addWidget(cbYDataColumn, 8, 2, 1, 3);
0087     cbY2DataColumn = new TreeViewComboBox(generalTab);
0088     gridLayout->addWidget(cbY2DataColumn, 9, 2, 1, 3);
0089 
0090     uiGeneralTab.sbMin->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
0091     uiGeneralTab.sbMax->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
0092 
0093     for (int i = 0; i < NSL_CORR_TYPE_COUNT; i++)
0094         uiGeneralTab.cbType->addItem(i18n(nsl_corr_type_name[i]));
0095     // nsl_corr_method_type not exposed to user
0096     for (int i = 0; i < NSL_CORR_NORM_COUNT; i++)
0097         uiGeneralTab.cbNorm->addItem(i18n(nsl_corr_norm_name[i]));
0098 
0099     uiGeneralTab.pbRecalculate->setIcon(QIcon::fromTheme("run-build"));
0100 
0101     auto* layout = new QHBoxLayout(ui.tabGeneral);
0102     layout->setMargin(0);
0103     layout->addWidget(generalTab);
0104 
0105     DEBUG("XYCorrelationCurveDock::setupGeneral() DONE");
0106 
0107     //Slots
0108     connect(uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYCorrelationCurveDock::nameChanged );
0109     connect(uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYCorrelationCurveDock::commentChanged );
0110     connect(uiGeneralTab.chkVisible, &QCheckBox::clicked, this, &XYCorrelationCurveDock::visibilityChanged);
0111     connect(uiGeneralTab.cbDataSourceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYCorrelationCurveDock::dataSourceTypeChanged);
0112     connect(uiGeneralTab.sbSamplingInterval, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYCorrelationCurveDock::samplingIntervalChanged);
0113     connect(uiGeneralTab.cbAutoRange, &QCheckBox::clicked, this, &XYCorrelationCurveDock::autoRangeChanged);
0114     connect(uiGeneralTab.sbMin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYCorrelationCurveDock::xRangeMinChanged);
0115     connect(uiGeneralTab.sbMax, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &XYCorrelationCurveDock::xRangeMaxChanged);
0116     connect(uiGeneralTab.cbType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYCorrelationCurveDock::typeChanged);
0117     connect(uiGeneralTab.cbNorm, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYCorrelationCurveDock::normChanged);
0118     connect(uiGeneralTab.pbRecalculate, &QPushButton::clicked, this, &XYCorrelationCurveDock::recalculateClicked);
0119 
0120     connect(cbDataSourceCurve, &TreeViewComboBox::currentModelIndexChanged, this, &XYCorrelationCurveDock::dataSourceCurveChanged);
0121     connect(cbXDataColumn, &TreeViewComboBox::currentModelIndexChanged, this, &XYCorrelationCurveDock::xDataColumnChanged);
0122     connect(cbYDataColumn, &TreeViewComboBox::currentModelIndexChanged, this, &XYCorrelationCurveDock::yDataColumnChanged);
0123     connect(cbY2DataColumn, &TreeViewComboBox::currentModelIndexChanged, this, &XYCorrelationCurveDock::y2DataColumnChanged);
0124 }
0125 
0126 void XYCorrelationCurveDock::initGeneralTab() {
0127     DEBUG("XYCorrelationCurveDock::initGeneralTab()");
0128     //if there are more then one curve in the list, disable the tab "general"
0129     if (m_curvesList.size() == 1) {
0130         uiGeneralTab.lName->setEnabled(true);
0131         uiGeneralTab.leName->setEnabled(true);
0132         uiGeneralTab.lComment->setEnabled(true);
0133         uiGeneralTab.leComment->setEnabled(true);
0134 
0135         uiGeneralTab.leName->setText(m_curve->name());
0136         uiGeneralTab.leComment->setText(m_curve->comment());
0137     } else {
0138         uiGeneralTab.lName->setEnabled(false);
0139         uiGeneralTab.leName->setEnabled(false);
0140         uiGeneralTab.lComment->setEnabled(false);
0141         uiGeneralTab.leComment->setEnabled(false);
0142 
0143         uiGeneralTab.leName->setText(QString());
0144         uiGeneralTab.leComment->setText(QString());
0145     }
0146 
0147     auto* analysisCurve = dynamic_cast<XYAnalysisCurve*>(m_curve);
0148     checkColumnAvailability(cbXDataColumn, analysisCurve->xDataColumn(), analysisCurve->xDataColumnPath());
0149     checkColumnAvailability(cbYDataColumn, analysisCurve->yDataColumn(), analysisCurve->yDataColumnPath());
0150     checkColumnAvailability(cbY2DataColumn, analysisCurve->y2DataColumn(), analysisCurve->y2DataColumnPath());
0151 
0152     //show the properties of the first curve
0153     m_correlationCurve = dynamic_cast<XYCorrelationCurve*>(m_curve);
0154 
0155     // hide x-Range per default
0156     uiGeneralTab.lXRange->setEnabled(false);
0157     uiGeneralTab.cbAutoRange->setEnabled(false);
0158 
0159     uiGeneralTab.cbDataSourceType->setCurrentIndex(static_cast<int>(m_correlationCurve->dataSourceType()));
0160     this->dataSourceTypeChanged(uiGeneralTab.cbDataSourceType->currentIndex());
0161     XYCurveDock::setModelIndexFromAspect(cbDataSourceCurve, m_correlationCurve->dataSourceCurve());
0162     XYCurveDock::setModelIndexFromAspect(cbXDataColumn, m_correlationCurve->xDataColumn());
0163     XYCurveDock::setModelIndexFromAspect(cbYDataColumn, m_correlationCurve->yDataColumn());
0164     XYCurveDock::setModelIndexFromAspect(cbY2DataColumn, m_correlationCurve->y2DataColumn());
0165     uiGeneralTab.sbSamplingInterval->setValue(m_correlationData.samplingInterval);
0166     uiGeneralTab.cbAutoRange->setChecked(m_correlationData.autoRange);
0167     uiGeneralTab.sbMin->setValue(m_correlationData.xRange.first());
0168     uiGeneralTab.sbMax->setValue(m_correlationData.xRange.last());
0169     this->autoRangeChanged();
0170     y2DataColumnChanged(cbY2DataColumn->currentModelIndex());
0171 
0172     // settings
0173     uiGeneralTab.cbType->setCurrentIndex(m_correlationData.type);
0174     //m_correlationData.method not used
0175     uiGeneralTab.cbNorm->setCurrentIndex(m_correlationData.normalize);
0176 
0177     this->showCorrelationResult();
0178 
0179     uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() );
0180 
0181     //Slots
0182     connect(m_correlationCurve, &XYCorrelationCurve::aspectDescriptionChanged, this, &XYCorrelationCurveDock::curveDescriptionChanged);
0183     connect(m_correlationCurve, &XYCorrelationCurve::dataSourceTypeChanged, this, &XYCorrelationCurveDock::curveDataSourceTypeChanged);
0184     connect(m_correlationCurve, &XYCorrelationCurve::dataSourceCurveChanged, this, &XYCorrelationCurveDock::curveDataSourceCurveChanged);
0185     connect(m_correlationCurve, &XYCorrelationCurve::xDataColumnChanged, this, &XYCorrelationCurveDock::curveXDataColumnChanged);
0186     connect(m_correlationCurve, &XYCorrelationCurve::yDataColumnChanged, this, &XYCorrelationCurveDock::curveYDataColumnChanged);
0187     connect(m_correlationCurve, &XYCorrelationCurve::y2DataColumnChanged, this, &XYCorrelationCurveDock::curveY2DataColumnChanged);
0188     connect(m_correlationCurve, &XYCorrelationCurve::correlationDataChanged, this, &XYCorrelationCurveDock::curveCorrelationDataChanged);
0189     connect(m_correlationCurve, &XYCorrelationCurve::sourceDataChanged, this, &XYCorrelationCurveDock::enableRecalculate);
0190     connect(m_correlationCurve, QOverload<bool>::of(&XYCurve::visibilityChanged), this, &XYCorrelationCurveDock::curveVisibilityChanged);
0191 }
0192 
0193 void XYCorrelationCurveDock::setModel() {
0194     DEBUG("XYCorrelationCurveDock::setModel()");
0195     QList<AspectType> list{AspectType::Folder, AspectType::Datapicker, AspectType::Worksheet,
0196                            AspectType::CartesianPlot, AspectType::XYCurve, AspectType::XYAnalysisCurve};
0197     cbDataSourceCurve->setTopLevelClasses(list);
0198 
0199     QList<const AbstractAspect*> hiddenAspects;
0200     for (auto* curve : m_curvesList)
0201         hiddenAspects << curve;
0202     cbDataSourceCurve->setHiddenAspects(hiddenAspects);
0203 
0204     list = {AspectType::Folder, AspectType::Workbook, AspectType::Datapicker, AspectType::DatapickerCurve,
0205             AspectType::Spreadsheet, AspectType::LiveDataSource, AspectType::Column,
0206             AspectType::Worksheet, AspectType::CartesianPlot, AspectType::XYCorrelationCurve
0207            };
0208     cbXDataColumn->setTopLevelClasses(list);
0209     cbYDataColumn->setTopLevelClasses(list);
0210     cbY2DataColumn->setTopLevelClasses(list);
0211 
0212     cbDataSourceCurve->setModel(m_aspectTreeModel);
0213     cbXDataColumn->setModel(m_aspectTreeModel);
0214     cbYDataColumn->setModel(m_aspectTreeModel);
0215     cbY2DataColumn->setModel(m_aspectTreeModel);
0216 
0217     XYCurveDock::setModel();
0218     DEBUG("XYCorrelationCurveDock::setModel() DONE");
0219 }
0220 
0221 /*!
0222   sets the curves. The properties of the curves in the list \c list can be edited in this widget.
0223 */
0224 void XYCorrelationCurveDock::setCurves(QList<XYCurve*> list) {
0225     m_initializing = true;
0226     m_curvesList = list;
0227     m_curve = list.first();
0228     m_correlationCurve = dynamic_cast<XYCorrelationCurve*>(m_curve);
0229     m_aspectTreeModel = new AspectTreeModel(m_curve->project());
0230     this->setModel();
0231     m_correlationData = m_correlationCurve->correlationData();
0232 
0233     SET_NUMBER_LOCALE
0234     uiGeneralTab.sbSamplingInterval->setLocale(numberLocale);
0235     uiGeneralTab.sbMin->setLocale(numberLocale);
0236     uiGeneralTab.sbMax->setLocale(numberLocale);
0237 
0238     initGeneralTab();
0239     initTabs();
0240     m_initializing = false;
0241 
0242     //hide the "skip gaps" option after the curves were set
0243     ui.lLineSkipGaps->hide();
0244     ui.chkLineSkipGaps->hide();
0245 }
0246 
0247 //*************************************************************
0248 //**** SLOTs for changes triggered in XYCorrelationCurveDock **
0249 //*************************************************************
0250 void XYCorrelationCurveDock::dataSourceTypeChanged(int index) {
0251     auto type = (XYAnalysisCurve::DataSourceType)index;
0252     if (type == XYAnalysisCurve::DataSourceType::Spreadsheet) {
0253         uiGeneralTab.lDataSourceCurve->hide();
0254         cbDataSourceCurve->hide();
0255         uiGeneralTab.lXColumn->show();
0256         cbXDataColumn->show();
0257         uiGeneralTab.lYColumn->show();
0258         cbYDataColumn->show();
0259         uiGeneralTab.lY2Column->show();
0260         cbY2DataColumn->show();
0261         uiGeneralTab.lSamplingInterval->show();
0262         uiGeneralTab.l2SamplingInterval->show();
0263         uiGeneralTab.sbSamplingInterval->show();
0264     } else {
0265         uiGeneralTab.lDataSourceCurve->show();
0266         cbDataSourceCurve->show();
0267         uiGeneralTab.lXColumn->hide();
0268         cbXDataColumn->hide();
0269         uiGeneralTab.lYColumn->hide();
0270         cbYDataColumn->hide();
0271         uiGeneralTab.lY2Column->hide();
0272         cbY2DataColumn->hide();
0273         uiGeneralTab.lSamplingInterval->hide();
0274         uiGeneralTab.l2SamplingInterval->hide();
0275         uiGeneralTab.sbSamplingInterval->hide();
0276     }
0277 
0278     if (m_initializing)
0279         return;
0280 
0281     for (auto* curve : m_curvesList)
0282         dynamic_cast<XYCorrelationCurve*>(curve)->setDataSourceType(type);
0283 }
0284 
0285 void XYCorrelationCurveDock::dataSourceCurveChanged(const QModelIndex& index) {
0286     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
0287     auto* dataSourceCurve = dynamic_cast<XYCurve*>(aspect);
0288 
0289     if (m_initializing)
0290         return;
0291 
0292     for (auto* curve : m_curvesList)
0293         dynamic_cast<XYCorrelationCurve*>(curve)->setDataSourceCurve(dataSourceCurve);
0294 }
0295 
0296 void XYCorrelationCurveDock::xDataColumnChanged(const QModelIndex& index) {
0297     DEBUG("XYCorrelationCurveDock::xDataColumnChanged()");
0298     if (m_initializing)
0299         return;
0300 
0301     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
0302     auto* column = dynamic_cast<AbstractColumn*>(aspect);
0303 
0304     for (auto* curve : m_curvesList)
0305         dynamic_cast<XYCorrelationCurve*>(curve)->setXDataColumn(column);
0306 
0307     if (column != nullptr) {
0308         if (uiGeneralTab.cbAutoRange->isChecked()) {
0309             uiGeneralTab.sbMin->setValue(column->minimum());
0310             uiGeneralTab.sbMax->setValue(column->maximum());
0311         }
0312     }
0313 
0314     cbXDataColumn->useCurrentIndexText(true);
0315     cbXDataColumn->setInvalid(false);
0316 }
0317 
0318 void XYCorrelationCurveDock::yDataColumnChanged(const QModelIndex& index) {
0319     if (m_initializing)
0320         return;
0321     DEBUG("yDataColumnChanged()");
0322 
0323     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
0324     auto* column = dynamic_cast<AbstractColumn*>(aspect);
0325 
0326     for (auto* curve : m_curvesList)
0327         dynamic_cast<XYCorrelationCurve*>(curve)->setYDataColumn(column);
0328 
0329     cbYDataColumn->useCurrentIndexText(true);
0330     cbYDataColumn->setInvalid(false);
0331 }
0332 
0333 void XYCorrelationCurveDock::y2DataColumnChanged(const QModelIndex& index) {
0334     if (m_initializing)
0335         return;
0336     DEBUG("y2DataColumnChanged()");
0337 
0338     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
0339     auto* column = dynamic_cast<AbstractColumn*>(aspect);
0340 
0341     for (auto* curve : m_curvesList)
0342         dynamic_cast<XYCorrelationCurve*>(curve)->setY2DataColumn(column);
0343 
0344     cbY2DataColumn->useCurrentIndexText(true);
0345     cbY2DataColumn->setInvalid(false);
0346 }
0347 
0348 void XYCorrelationCurveDock::samplingIntervalChanged() {
0349     double samplingInterval =  uiGeneralTab.sbSamplingInterval->value();
0350     m_correlationData.samplingInterval = samplingInterval;
0351 
0352     enableRecalculate();
0353 }
0354 
0355 void XYCorrelationCurveDock::autoRangeChanged() {
0356     bool autoRange = uiGeneralTab.cbAutoRange->isChecked();
0357     m_correlationData.autoRange = autoRange;
0358 
0359     if (autoRange) {
0360         uiGeneralTab.lMin->setEnabled(false);
0361         uiGeneralTab.sbMin->setEnabled(false);
0362         uiGeneralTab.lMax->setEnabled(false);
0363         uiGeneralTab.sbMax->setEnabled(false);
0364 
0365         const AbstractColumn* xDataColumn = nullptr;
0366         if (m_correlationCurve->dataSourceType() == XYAnalysisCurve::DataSourceType::Spreadsheet)
0367             xDataColumn = m_correlationCurve->xDataColumn();
0368         else {
0369             if (m_correlationCurve->dataSourceCurve())
0370                 xDataColumn = m_correlationCurve->dataSourceCurve()->xColumn();
0371         }
0372 
0373         if (xDataColumn) {
0374             uiGeneralTab.sbMin->setValue(xDataColumn->minimum());
0375             uiGeneralTab.sbMax->setValue(xDataColumn->maximum());
0376         }
0377     } else {
0378         uiGeneralTab.lMin->setEnabled(true);
0379         uiGeneralTab.sbMin->setEnabled(true);
0380         uiGeneralTab.lMax->setEnabled(true);
0381         uiGeneralTab.sbMax->setEnabled(true);
0382     }
0383 
0384 }
0385 void XYCorrelationCurveDock::xRangeMinChanged() {
0386     double xMin = uiGeneralTab.sbMin->value();
0387 
0388     m_correlationData.xRange.first() = xMin;
0389     enableRecalculate();
0390 }
0391 
0392 void XYCorrelationCurveDock::xRangeMaxChanged() {
0393     double xMax = uiGeneralTab.sbMax->value();
0394 
0395     m_correlationData.xRange.last() = xMax;
0396     enableRecalculate();
0397 }
0398 
0399 void XYCorrelationCurveDock::typeChanged() {
0400     auto type = (nsl_corr_type_type) uiGeneralTab.cbType->currentIndex();
0401     m_correlationData.type = type;
0402 
0403     enableRecalculate();
0404 }
0405 
0406 void XYCorrelationCurveDock::normChanged() {
0407     auto norm = (nsl_corr_norm_type) uiGeneralTab.cbNorm->currentIndex();
0408     m_correlationData.normalize = norm;
0409 
0410     enableRecalculate();
0411 }
0412 
0413 void XYCorrelationCurveDock::recalculateClicked() {
0414     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
0415 
0416     for (auto* curve : m_curvesList)
0417         dynamic_cast<XYCorrelationCurve*>(curve)->setCorrelationData(m_correlationData);
0418 
0419     uiGeneralTab.pbRecalculate->setEnabled(false);
0420     emit info(i18n("Correlation status: %1", m_correlationCurve->correlationResult().status));
0421     QApplication::restoreOverrideCursor();
0422 }
0423 
0424 void XYCorrelationCurveDock::enableRecalculate() const {
0425     DEBUG("XYCorrelationCurveDock::enableRecalculate()");
0426     if (m_initializing)
0427         return;
0428 
0429     bool hasSourceData = false;
0430     //no correlation possible without y-data and y2-data
0431     if (m_correlationCurve->dataSourceType() == XYAnalysisCurve::DataSourceType::Spreadsheet) {
0432         AbstractAspect* aspectY = static_cast<AbstractAspect*>(cbYDataColumn->currentModelIndex().internalPointer());
0433         AbstractAspect* aspectY2 = static_cast<AbstractAspect*>(cbY2DataColumn->currentModelIndex().internalPointer());
0434         hasSourceData = (aspectY != nullptr && aspectY2 != nullptr);
0435         if (aspectY) {
0436             cbYDataColumn->useCurrentIndexText(true);
0437             cbYDataColumn->setInvalid(false);
0438         }
0439         if (aspectY2) {
0440             cbY2DataColumn->useCurrentIndexText(true);
0441             cbY2DataColumn->setInvalid(false);
0442         }
0443     } else {
0444          hasSourceData = (m_correlationCurve->dataSourceCurve() != nullptr);
0445     }
0446 
0447     uiGeneralTab.pbRecalculate->setEnabled(hasSourceData);
0448 }
0449 
0450 /*!
0451  * show the result and details of the correlation
0452  */
0453 void XYCorrelationCurveDock::showCorrelationResult() {
0454     const XYCorrelationCurve::CorrelationResult& correlationResult = m_correlationCurve->correlationResult();
0455     if (!correlationResult.available) {
0456         uiGeneralTab.teResult->clear();
0457         return;
0458     }
0459 
0460     QString str = i18n("status: %1", correlationResult.status) + "<br>";
0461 
0462     if (!correlationResult.valid) {
0463         uiGeneralTab.teResult->setText(str);
0464         return; //result is not valid, there was an error which is shown in the status-string, nothing to show more.
0465     }
0466 
0467     SET_NUMBER_LOCALE
0468     if (correlationResult.elapsedTime > 1000)
0469         str += i18n("calculation time: %1 s", numberLocale.toString(correlationResult.elapsedTime/1000)) + "<br>";
0470     else
0471         str += i18n("calculation time: %1 ms", numberLocale.toString(correlationResult.elapsedTime)) + "<br>";
0472 
0473     str += "<br><br>";
0474 
0475     uiGeneralTab.teResult->setText(str);
0476 
0477     //enable the "recalculate"-button if the source data was changed since the last correlation
0478     uiGeneralTab.pbRecalculate->setEnabled(m_correlationCurve->isSourceDataChangedSinceLastRecalc());
0479 }
0480 
0481 //*************************************************************
0482 //*********** SLOTs for changes triggered in XYCurve **********
0483 //*************************************************************
0484 //General-Tab
0485 void XYCorrelationCurveDock::curveDescriptionChanged(const AbstractAspect* aspect) {
0486     if (m_curve != aspect)
0487         return;
0488 
0489     m_initializing = true;
0490     if (aspect->name() != uiGeneralTab.leName->text())
0491         uiGeneralTab.leName->setText(aspect->name());
0492     else if (aspect->comment() != uiGeneralTab.leComment->text())
0493         uiGeneralTab.leComment->setText(aspect->comment());
0494     m_initializing = false;
0495 }
0496 
0497 void XYCorrelationCurveDock::curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType type) {
0498     m_initializing = true;
0499     uiGeneralTab.cbDataSourceType->setCurrentIndex(static_cast<int>(type));
0500     m_initializing = false;
0501 }
0502 
0503 void XYCorrelationCurveDock::curveDataSourceCurveChanged(const XYCurve* curve) {
0504     m_initializing = true;
0505     XYCurveDock::setModelIndexFromAspect(cbDataSourceCurve, curve);
0506     m_initializing = false;
0507 }
0508 
0509 void XYCorrelationCurveDock::curveXDataColumnChanged(const AbstractColumn* column) {
0510     DEBUG("XYCorrelationCurveDock::curveXDataColumnChanged()");
0511     m_initializing = true;
0512     XYCurveDock::setModelIndexFromAspect(cbXDataColumn, column);
0513     if (column != nullptr) {
0514         DEBUG("X Column available");
0515         uiGeneralTab.lXRange->setEnabled(true);
0516         uiGeneralTab.cbAutoRange->setEnabled(true);
0517         uiGeneralTab.lSamplingInterval->setEnabled(false);
0518         uiGeneralTab.l2SamplingInterval->setEnabled(false);
0519         uiGeneralTab.sbSamplingInterval->setEnabled(false);
0520     } else {
0521         DEBUG("X Column not available");
0522         uiGeneralTab.lXRange->setEnabled(false);
0523         uiGeneralTab.cbAutoRange->setEnabled(false);
0524         uiGeneralTab.lSamplingInterval->setEnabled(true);
0525         uiGeneralTab.l2SamplingInterval->setEnabled(true);
0526         uiGeneralTab.sbSamplingInterval->setEnabled(true);
0527     }
0528     m_initializing = false;
0529 }
0530 
0531 void XYCorrelationCurveDock::curveYDataColumnChanged(const AbstractColumn* column) {
0532     DEBUG("XYCorrelationCurveDock::curveYDataColumnChanged()");
0533     m_initializing = true;
0534     XYCurveDock::setModelIndexFromAspect(cbYDataColumn, column);
0535     m_initializing = false;
0536 }
0537 
0538 void XYCorrelationCurveDock::curveY2DataColumnChanged(const AbstractColumn* column) {
0539     DEBUG("XYCorrelationCurveDock::curveY2DataColumnChanged()");
0540     m_initializing = true;
0541     XYCurveDock::setModelIndexFromAspect(cbY2DataColumn, column);
0542     m_initializing = false;
0543 }
0544 
0545 void XYCorrelationCurveDock::curveCorrelationDataChanged(const XYCorrelationCurve::CorrelationData& correlationData) {
0546     m_initializing = true;
0547     m_correlationData = correlationData;
0548 
0549     this->showCorrelationResult();
0550     m_initializing = false;
0551 }
0552 
0553 void XYCorrelationCurveDock::dataChanged() {
0554     this->enableRecalculate();
0555 }
0556 
0557 void XYCorrelationCurveDock::curveVisibilityChanged(bool on) {
0558     m_initializing = true;
0559     uiGeneralTab.chkVisible->setChecked(on);
0560     m_initializing = false;
0561 }