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

0001 /***************************************************************************
0002     File                 : XYCurveDock.cpp
0003     Project              : LabPlot
0004     Description          : widget for XYCurve properties
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2010-2020 Alexander Semke (alexander.semke@web.de)
0007     Copyright            : (C) 2012-2017 Stefan Gerlach (stefan.gerlach@uni-konstanz.de)
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "XYCurveDock.h"
0031 #include "backend/worksheet/plots/cartesian/XYCurve.h"
0032 #include "backend/worksheet/Worksheet.h"
0033 #include "backend/core/AspectTreeModel.h"
0034 #include "backend/core/column/Column.h"
0035 #include "backend/core/Project.h"
0036 #include "backend/core/datatypes/Double2StringFilter.h"
0037 #include "backend/core/datatypes/DateTime2StringFilter.h"
0038 #include "commonfrontend/widgets/TreeViewComboBox.h"
0039 #include "kdefrontend/TemplateHandler.h"
0040 #include "kdefrontend/GuiTools.h"
0041 
0042 #include <QCompleter>
0043 #include <QDir>
0044 #include <QDirModel>
0045 #include <QFileDialog>
0046 #include <QImageReader>
0047 #include <QPainter>
0048 
0049 #include <KConfig>
0050 #include <KLocalizedString>
0051 
0052 /*!
0053   \class XYCurveDock
0054   \brief  Provides a widget for editing the properties of the XYCurves (2D-curves) currently selected in the project explorer.
0055 
0056   If more than one curves are set, the properties of the first column are shown. The changes of the properties are applied to all curves.
0057   The exclusions are the name, the comment and the datasets (columns) of the curves  - these properties can only be changed if there is only one single curve.
0058 
0059   \ingroup kdefrontend
0060 */
0061 
0062 XYCurveDock::XYCurveDock(QWidget* parent) : BaseDock(parent) {
0063     ui.setupUi(this);
0064 
0065     //Tab "Values"
0066     auto* gridLayout = qobject_cast<QGridLayout*>(ui.tabValues->layout());
0067     cbValuesColumn = new TreeViewComboBox(ui.tabValues);
0068     gridLayout->addWidget(cbValuesColumn, 2, 2, 1, 1);
0069 
0070     //add formats for numeric values
0071     ui.cbValuesNumericFormat->addItem(i18n("Decimal"), QVariant('f'));
0072     ui.cbValuesNumericFormat->addItem(i18n("Scientific (e)"), QVariant('e'));
0073     ui.cbValuesNumericFormat->addItem(i18n("Scientific (E)"), QVariant('E'));
0074     ui.cbValuesNumericFormat->addItem(i18n("Automatic (e)"), QVariant('g'));
0075     ui.cbValuesNumericFormat->addItem(i18n("Automatic (E)"), QVariant('G'));
0076 
0077     //add format for date, time and datetime values
0078     for (const auto& s : AbstractColumn::dateTimeFormats())
0079         ui.cbValuesDateTimeFormat->addItem(s, QVariant(s));
0080 
0081     ui.cbValuesDateTimeFormat->setEditable(true);
0082 
0083     //Tab "Filling"
0084     ui.cbFillingColorStyle->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
0085     ui.bFillingOpen->setIcon( QIcon::fromTheme("document-open") );
0086 
0087     ui.leFillingFileName->setCompleter(new QCompleter(new QDirModel, this));
0088 
0089     //Tab "Error bars"
0090     gridLayout = qobject_cast<QGridLayout*>(ui.tabErrorBars->layout());
0091 
0092     cbXErrorPlusColumn = new TreeViewComboBox(ui.tabErrorBars);
0093     gridLayout->addWidget(cbXErrorPlusColumn, 2, 2, 1, 1);
0094 
0095     cbXErrorMinusColumn = new TreeViewComboBox(ui.tabErrorBars);
0096     gridLayout->addWidget(cbXErrorMinusColumn, 3, 2, 1, 1);
0097 
0098     cbYErrorPlusColumn = new TreeViewComboBox(ui.tabErrorBars);
0099     gridLayout->addWidget(cbYErrorPlusColumn, 7, 2, 1, 1);
0100 
0101     cbYErrorMinusColumn = new TreeViewComboBox(ui.tabErrorBars);
0102     gridLayout->addWidget(cbYErrorMinusColumn, 8, 2, 1, 1);
0103 
0104     //adjust layouts in the tabs
0105     for (int i = 0; i < ui.tabWidget->count(); ++i) {
0106         auto* layout = dynamic_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout());
0107         if (!layout)
0108             continue;
0109 
0110         layout->setContentsMargins(2,2,2,2);
0111         layout->setHorizontalSpacing(2);
0112         layout->setVerticalSpacing(2);
0113     }
0114 
0115     XYCurveDock::updateLocale();
0116 
0117     //Slots
0118 
0119     //Lines
0120     connect( ui.cbLineType, SIGNAL(currentIndexChanged(int)), this, SLOT(lineTypeChanged(int)) );
0121     connect( ui.sbLineInterpolationPointsCount, SIGNAL(valueChanged(int)), this, SLOT(lineInterpolationPointsCountChanged(int)) );
0122     connect( ui.chkLineSkipGaps, SIGNAL(clicked(bool)), this, SLOT(lineSkipGapsChanged(bool)) );
0123     connect( ui.chkLineIncreasingXOnly, &QCheckBox::clicked, this, &XYCurveDock::lineIncreasingXOnlyChanged );
0124     connect( ui.cbLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(lineStyleChanged(int)) );
0125     connect( ui.kcbLineColor, SIGNAL(changed(QColor)), this, SLOT(lineColorChanged(QColor)) );
0126     connect( ui.sbLineWidth, SIGNAL(valueChanged(double)), this, SLOT(lineWidthChanged(double)) );
0127     connect( ui.sbLineOpacity, SIGNAL(valueChanged(int)), this, SLOT(lineOpacityChanged(int)) );
0128 
0129     connect( ui.cbDropLineType, SIGNAL(currentIndexChanged(int)), this, SLOT(dropLineTypeChanged(int)) );
0130     connect( ui.cbDropLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(dropLineStyleChanged(int)) );
0131     connect( ui.kcbDropLineColor, SIGNAL(changed(QColor)), this, SLOT(dropLineColorChanged(QColor)) );
0132     connect( ui.sbDropLineWidth, SIGNAL(valueChanged(double)), this, SLOT(dropLineWidthChanged(double)) );
0133     connect( ui.sbDropLineOpacity, SIGNAL(valueChanged(int)), this, SLOT(dropLineOpacityChanged(int)) );
0134 
0135     //Symbol
0136     connect( ui.cbSymbolStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsStyleChanged(int)) );
0137     connect( ui.sbSymbolSize, SIGNAL(valueChanged(double)), this, SLOT(symbolsSizeChanged(double)) );
0138     connect( ui.sbSymbolRotation, SIGNAL(valueChanged(int)), this, SLOT(symbolsRotationChanged(int)) );
0139     connect( ui.sbSymbolOpacity, SIGNAL(valueChanged(int)), this, SLOT(symbolsOpacityChanged(int)) );
0140 
0141     connect( ui.cbSymbolFillingStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsFillingStyleChanged(int)) );
0142     connect( ui.kcbSymbolFillingColor, SIGNAL(changed(QColor)), this, SLOT(symbolsFillingColorChanged(QColor)) );
0143 
0144     connect( ui.cbSymbolBorderStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsBorderStyleChanged(int)) );
0145     connect( ui.kcbSymbolBorderColor, SIGNAL(changed(QColor)), this, SLOT(symbolsBorderColorChanged(QColor)) );
0146     connect( ui.sbSymbolBorderWidth, SIGNAL(valueChanged(double)), this, SLOT(symbolsBorderWidthChanged(double)) );
0147 
0148     //Values
0149     connect( ui.cbValuesType, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesTypeChanged(int)) );
0150     connect( cbValuesColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(valuesColumnChanged(QModelIndex)) );
0151     connect( ui.cbValuesPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesPositionChanged(int)) );
0152     connect( ui.sbValuesDistance, SIGNAL(valueChanged(double)), this, SLOT(valuesDistanceChanged(double)) );
0153     connect( ui.sbValuesRotation, SIGNAL(valueChanged(int)), this, SLOT(valuesRotationChanged(int)) );
0154     connect( ui.sbValuesOpacity, SIGNAL(valueChanged(int)), this, SLOT(valuesOpacityChanged(int)) );
0155     connect(ui.cbValuesNumericFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYCurveDock::valuesNumericFormatChanged);
0156     connect(ui.sbValuesPrecision, QOverload<int>::of(&QSpinBox::valueChanged), this, &XYCurveDock::valuesPrecisionChanged);
0157     connect(ui.cbValuesDateTimeFormat, &QComboBox::currentTextChanged, this, &XYCurveDock::valuesDateTimeFormatChanged);
0158     connect(ui.leValuesPrefix, &QLineEdit::textChanged, this, &XYCurveDock::valuesPrefixChanged);
0159     connect(ui.leValuesSuffix, &QLineEdit::textChanged, this, &XYCurveDock::valuesSuffixChanged);
0160     connect( ui.kfrValuesFont, SIGNAL(fontSelected(QFont)), this, SLOT(valuesFontChanged(QFont)) );
0161     connect( ui.kcbValuesColor, SIGNAL(changed(QColor)), this, SLOT(valuesColorChanged(QColor)) );
0162 
0163     //Filling
0164     connect( ui.cbFillingPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingPositionChanged(int)) );
0165     connect( ui.cbFillingType, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingTypeChanged(int)) );
0166     connect( ui.cbFillingColorStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingColorStyleChanged(int)) );
0167     connect( ui.cbFillingImageStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingImageStyleChanged(int)) );
0168     connect( ui.cbFillingBrushStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingBrushStyleChanged(int)) );
0169     connect(ui.bFillingOpen, SIGNAL(clicked(bool)), this, SLOT(selectFile()));
0170     connect(ui.leFillingFileName, &QLineEdit::textChanged, this, &XYCurveDock::fileNameChanged);
0171     connect( ui.leFillingFileName, SIGNAL(textChanged(QString)), this, SLOT(fileNameChanged()) );
0172     connect( ui.kcbFillingFirstColor, SIGNAL(changed(QColor)), this, SLOT(fillingFirstColorChanged(QColor)) );
0173     connect( ui.kcbFillingSecondColor, SIGNAL(changed(QColor)), this, SLOT(fillingSecondColorChanged(QColor)) );
0174     connect( ui.sbFillingOpacity, SIGNAL(valueChanged(int)), this, SLOT(fillingOpacityChanged(int)) );
0175 
0176     //Error bars
0177     connect( ui.cbXErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(xErrorTypeChanged(int)) );
0178     connect( cbXErrorPlusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xErrorPlusColumnChanged(QModelIndex)) );
0179     connect( cbXErrorMinusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xErrorMinusColumnChanged(QModelIndex)) );
0180     connect( ui.cbYErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(yErrorTypeChanged(int)) );
0181     connect( cbYErrorPlusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yErrorPlusColumnChanged(QModelIndex)) );
0182     connect( cbYErrorMinusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yErrorMinusColumnChanged(QModelIndex)) );
0183     connect( ui.cbErrorBarsType, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsTypeChanged(int)) );
0184     connect( ui.sbErrorBarsCapSize, SIGNAL(valueChanged(double)), this, SLOT(errorBarsCapSizeChanged(double)) );
0185     connect( ui.cbErrorBarsStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsStyleChanged(int)) );
0186     connect( ui.kcbErrorBarsColor, SIGNAL(changed(QColor)), this, SLOT(errorBarsColorChanged(QColor)) );
0187     connect( ui.sbErrorBarsWidth, SIGNAL(valueChanged(double)), this, SLOT(errorBarsWidthChanged(double)) );
0188     connect( ui.sbErrorBarsOpacity, SIGNAL(valueChanged(int)), this, SLOT(errorBarsOpacityChanged(int)) );
0189 
0190     //template handler
0191     auto* frame = new QFrame(this);
0192     auto* layout = new QHBoxLayout(frame);
0193     layout->setContentsMargins(0, 11, 0, 11);
0194 
0195     auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::XYCurve);
0196     layout->addWidget(templateHandler);
0197     connect(templateHandler, SIGNAL(loadConfigRequested(KConfig&)), this, SLOT(loadConfigFromTemplate(KConfig&)));
0198     connect(templateHandler, SIGNAL(saveConfigRequested(KConfig&)), this, SLOT(saveConfigAsTemplate(KConfig&)));
0199     connect(templateHandler, SIGNAL(info(QString)), this, SIGNAL(info(QString)));
0200 
0201     ui.verticalLayout->addWidget(frame);
0202 
0203     retranslateUi();
0204     init();
0205 }
0206 
0207 XYCurveDock::~XYCurveDock() {
0208     if (m_aspectTreeModel)
0209         delete m_aspectTreeModel;
0210 }
0211 
0212 void XYCurveDock::setupGeneral() {
0213     QWidget* generalTab = new QWidget(ui.tabGeneral);
0214     uiGeneralTab.setupUi(generalTab);
0215     m_leName = uiGeneralTab.leName;
0216     m_leComment = uiGeneralTab.leComment;
0217     auto* layout = new QHBoxLayout(ui.tabGeneral);
0218     layout->setMargin(0);
0219     layout->addWidget(generalTab);
0220 
0221     // Tab "General"
0222     auto* gridLayout = qobject_cast<QGridLayout*>(generalTab->layout());
0223 
0224     cbXColumn = new TreeViewComboBox(generalTab);
0225     cbXColumn->useCurrentIndexText(false);
0226     gridLayout->addWidget(cbXColumn, 2, 2, 1, 1);
0227 
0228     cbYColumn = new TreeViewComboBox(generalTab);
0229     cbYColumn->useCurrentIndexText(false);
0230     gridLayout->addWidget(cbYColumn, 3, 2, 1, 1);
0231 
0232     //General
0233     connect(uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYCurveDock::nameChanged);
0234     connect(uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYCurveDock::commentChanged);
0235     connect(uiGeneralTab.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)));
0236     connect(cbXColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xColumnChanged(QModelIndex)));
0237     connect(cbYColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yColumnChanged(QModelIndex)));
0238 }
0239 
0240 void XYCurveDock::init() {
0241     m_initializing = true;
0242 
0243     //Line
0244     ui.cbLineType->addItem(i18n("None"));
0245     ui.cbLineType->addItem(i18n("Line"));
0246     ui.cbLineType->addItem(i18n("Horiz. Start"));
0247     ui.cbLineType->addItem(i18n("Vert. Start"));
0248     ui.cbLineType->addItem(i18n("Horiz. Midpoint"));
0249     ui.cbLineType->addItem(i18n("Vert. Midpoint"));
0250     ui.cbLineType->addItem(i18n("2-segments"));
0251     ui.cbLineType->addItem(i18n("3-segments"));
0252     ui.cbLineType->addItem(i18n("Cubic Spline (Natural)"));
0253     ui.cbLineType->addItem(i18n("Cubic Spline (Periodic)"));
0254     ui.cbLineType->addItem(i18n("Akima-spline (Natural)"));
0255     ui.cbLineType->addItem(i18n("Akima-spline (Periodic)"));
0256 
0257     QPainter pa;
0258     //TODO size of the icon depending on the actual height of the combobox?
0259     int iconSize = 20;
0260     QPixmap pm(iconSize, iconSize);
0261     ui.cbLineType->setIconSize(QSize(iconSize, iconSize));
0262 
0263     QPen pen(Qt::SolidPattern, 0);
0264     const QColor& color = (palette().color(QPalette::Base).lightness() < 128) ? Qt::white : Qt::black;
0265     pen.setColor(color);
0266     pa.setPen( pen );
0267 
0268     //no line
0269     pm.fill(Qt::transparent);
0270     pa.begin( &pm );
0271     pa.setPen(pen);
0272     pa.setRenderHint(QPainter::Antialiasing);
0273     pa.drawEllipse( 1,1,4,4);
0274     pa.drawEllipse( 15,15,4,4);
0275     pa.end();
0276     ui.cbLineType->setItemIcon(0, pm);
0277 
0278     //line
0279     pm.fill(Qt::transparent);
0280     pa.begin( &pm );
0281     pa.setPen(pen);
0282     pa.setRenderHint(QPainter::Antialiasing);
0283     pa.drawEllipse( 1,1,4,4);
0284     pa.drawEllipse( 15,15,4,4);
0285     pa.drawLine(3,3,17,17);
0286     pa.end();
0287     ui.cbLineType->setItemIcon(1, pm);
0288 
0289     pm.fill(Qt::transparent);
0290     pa.begin( &pm );
0291     pa.setPen(pen);
0292     pa.setRenderHint(QPainter::Antialiasing);
0293     pa.drawEllipse( 1,1,4,4);
0294     pa.drawEllipse( 15,15,4,4);
0295     pa.drawLine(3,3,17,3);
0296     pa.drawLine(17,3,17,17);
0297     pa.end();
0298     ui.cbLineType->setItemIcon(2, pm);
0299 
0300     pm.fill(Qt::transparent);
0301     pa.begin( &pm );
0302     pa.setPen(pen);
0303     pa.setRenderHint(QPainter::Antialiasing);
0304     pa.drawEllipse( 1,1,4,4);
0305     pa.drawEllipse( 15,15,4,4);
0306     pa.drawLine(3,3,3,17);
0307     pa.drawLine(3,17,17,17);
0308     pa.end();
0309     ui.cbLineType->setItemIcon(3, pm);
0310 
0311     //horizontal midpoint
0312     pm.fill(Qt::transparent);
0313     pa.begin( &pm );
0314     pa.setPen(pen);
0315     pa.setRenderHint(QPainter::Antialiasing);
0316     pa.drawEllipse( 1,1,4,4);
0317     pa.drawEllipse( 15,15,4,4);
0318     pa.drawLine(3,3,10,3);
0319     pa.drawLine(10,3,10,17);
0320     pa.drawLine(10,17,17,17);
0321     pa.end();
0322     ui.cbLineType->setItemIcon(4, pm);
0323 
0324     //vertical midpoint
0325     pm.fill(Qt::transparent);
0326     pa.begin( &pm );
0327     pa.setPen(pen);
0328     pa.setRenderHint(QPainter::Antialiasing);
0329     pa.drawEllipse( 1,1,4,4);
0330     pa.drawEllipse( 15,15,4,4);
0331     pa.drawLine(3,3,3,10);
0332     pa.drawLine(3,10,17,10);
0333     pa.drawLine(17,10,17,17);
0334     pa.end();
0335     ui.cbLineType->setItemIcon(5, pm);
0336 
0337     //2-segments
0338     pm.fill(Qt::transparent);
0339     pa.begin( &pm );
0340     pa.setPen(pen);
0341     pa.setRenderHint(QPainter::Antialiasing);
0342     pa.drawEllipse( 1,1,4,4);
0343     pa.drawEllipse( 8,8,4,4);
0344     pa.drawEllipse( 15,15,4,4);
0345     pa.drawLine(3,3,10,10);
0346     pa.end();
0347     ui.cbLineType->setItemIcon(6, pm);
0348 
0349     //3-segments
0350     pm.fill(Qt::transparent);
0351     pa.begin( &pm );
0352     pa.setPen(pen);
0353     pa.setRenderHint(QPainter::Antialiasing);
0354     pa.drawEllipse( 1,1,4,4);
0355     pa.drawEllipse( 8,8,4,4);
0356     pa.drawEllipse( 15,15,4,4);
0357     pa.drawLine(3,3,17,17);
0358     pa.end();
0359     ui.cbLineType->setItemIcon(7, pm);
0360 
0361     //natural spline
0362     pm.fill(Qt::transparent);
0363     pa.begin( &pm );
0364     pa.setPen(pen);
0365     pa.setRenderHint(QPainter::Antialiasing);
0366     pa.drawEllipse( 1,1,4,4);
0367     pa.drawEllipse( 15,15,4,4);
0368     pa.rotate(45);
0369     pa.drawArc(2*sqrt(2),-4,17*sqrt(2),20,30*16,120*16);
0370 
0371     pa.end();
0372     ui.cbLineType->setItemIcon(8, pm);
0373     ui.cbLineType->setItemIcon(9, pm);
0374     ui.cbLineType->setItemIcon(10, pm);
0375     ui.cbLineType->setItemIcon(11, pm);
0376 
0377     GuiTools::updatePenStyles(ui.cbLineStyle, Qt::black);
0378 
0379     //Drop lines
0380     ui.cbDropLineType->addItem(i18n("No Drop Lines"));
0381     ui.cbDropLineType->addItem(i18n("Drop Lines, X"));
0382     ui.cbDropLineType->addItem(i18n("Drop Lines, Y"));
0383     ui.cbDropLineType->addItem(i18n("Drop Lines, XY"));
0384     ui.cbDropLineType->addItem(i18n("Drop Lines, X, Zero Baseline"));
0385     ui.cbDropLineType->addItem(i18n("Drop Lines, X, Min Baseline"));
0386     ui.cbDropLineType->addItem(i18n("Drop Lines, X, Max Baseline"));
0387     GuiTools::updatePenStyles(ui.cbDropLineStyle, Qt::black);
0388 
0389     //Symbols
0390     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, Qt::black);
0391 
0392     ui.cbSymbolStyle->setIconSize(QSize(iconSize, iconSize));
0393     QTransform trafo;
0394     trafo.scale(15, 15);
0395 
0396     ui.cbSymbolStyle->addItem(i18n("None"));
0397     for (int i = 1; i < Symbol::stylesCount(); ++i) {
0398         const auto style = (Symbol::Style)i;
0399         pm.fill(Qt::transparent);
0400         pa.begin(&pm);
0401         pa.setPen(pen);
0402         pa.setRenderHint(QPainter::Antialiasing);
0403         pa.translate(iconSize/2,iconSize/2);
0404         pa.drawPath(trafo.map(Symbol::pathFromStyle(style)));
0405         pa.end();
0406         ui.cbSymbolStyle->addItem(QIcon(pm), Symbol::nameFromStyle(style));
0407     }
0408 
0409     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, Qt::black);
0410     m_initializing = false;
0411 
0412     //Values
0413     ui.cbValuesType->addItem(i18n("No Values"));
0414     ui.cbValuesType->addItem("x");
0415     ui.cbValuesType->addItem("y");
0416     ui.cbValuesType->addItem("x, y");
0417     ui.cbValuesType->addItem("(x, y)");
0418     ui.cbValuesType->addItem(i18n("Custom Column"));
0419 
0420     ui.cbValuesPosition->addItem(i18n("Above"));
0421     ui.cbValuesPosition->addItem(i18n("Below"));
0422     ui.cbValuesPosition->addItem(i18n("Left"));
0423     ui.cbValuesPosition->addItem(i18n("Right"));
0424 
0425     //Filling
0426     ui.cbFillingPosition->clear();
0427     ui.cbFillingPosition->addItem(i18n("None"));
0428     ui.cbFillingPosition->addItem(i18n("Above"));
0429     ui.cbFillingPosition->addItem(i18n("Below"));
0430     ui.cbFillingPosition->addItem(i18n("Zero Baseline"));
0431     ui.cbFillingPosition->addItem(i18n("Left"));
0432     ui.cbFillingPosition->addItem(i18n("Right"));
0433 
0434     ui.cbFillingType->clear();
0435     ui.cbFillingType->addItem(i18n("Color"));
0436     ui.cbFillingType->addItem(i18n("Image"));
0437     ui.cbFillingType->addItem(i18n("Pattern"));
0438 
0439     ui.cbFillingColorStyle->clear();
0440     ui.cbFillingColorStyle->addItem(i18n("Single Color"));
0441     ui.cbFillingColorStyle->addItem(i18n("Horizontal Gradient"));
0442     ui.cbFillingColorStyle->addItem(i18n("Vertical Gradient"));
0443     ui.cbFillingColorStyle->addItem(i18n("Diag. Gradient (From Top Left)"));
0444     ui.cbFillingColorStyle->addItem(i18n("Diag. Gradient (From Bottom Left)"));
0445     ui.cbFillingColorStyle->addItem(i18n("Radial Gradient"));
0446 
0447     ui.cbFillingImageStyle->clear();
0448     ui.cbFillingImageStyle->addItem(i18n("Scaled and Cropped"));
0449     ui.cbFillingImageStyle->addItem(i18n("Scaled"));
0450     ui.cbFillingImageStyle->addItem(i18n("Scaled, Keep Proportions"));
0451     ui.cbFillingImageStyle->addItem(i18n("Centered"));
0452     ui.cbFillingImageStyle->addItem(i18n("Tiled"));
0453     ui.cbFillingImageStyle->addItem(i18n("Center Tiled"));
0454     GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, Qt::SolidPattern);
0455 
0456     //Error-bars
0457     pm.fill(Qt::transparent);
0458     pa.begin( &pm );
0459     pa.setRenderHint(QPainter::Antialiasing);
0460     pa.drawLine(3,10,17,10);//vert. line
0461     pa.drawLine(10,3,10,17);//hor. line
0462     pa.end();
0463     ui.cbErrorBarsType->addItem(i18n("Bars"));
0464     ui.cbErrorBarsType->setItemIcon(0, pm);
0465 
0466     pm.fill(Qt::transparent);
0467     pa.begin( &pm );
0468     pa.setRenderHint(QPainter::Antialiasing);
0469     pa.setBrush(Qt::SolidPattern);
0470     pa.drawLine(3,10,17,10); //vert. line
0471     pa.drawLine(10,3,10,17); //hor. line
0472     pa.drawLine(7,3,13,3); //upper cap
0473     pa.drawLine(7,17,13,17); //bottom cap
0474     pa.drawLine(3,7,3,13); //left cap
0475     pa.drawLine(17,7,17,13); //right cap
0476     pa.end();
0477     ui.cbErrorBarsType->addItem(i18n("Bars with Ends"));
0478     ui.cbErrorBarsType->setItemIcon(1, pm);
0479 
0480     ui.cbXErrorType->addItem(i18n("No"));
0481     ui.cbXErrorType->addItem(i18n("Symmetric"));
0482     ui.cbXErrorType->addItem(i18n("Asymmetric"));
0483 
0484     ui.cbYErrorType->addItem(i18n("No"));
0485     ui.cbYErrorType->addItem(i18n("Symmetric"));
0486     ui.cbYErrorType->addItem(i18n("Asymmetric"));
0487 
0488     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, Qt::black);
0489 }
0490 
0491 void XYCurveDock::setModel() {
0492     m_aspectTreeModel->enablePlottableColumnsOnly(true);
0493     m_aspectTreeModel->enableShowPlotDesignation(true);
0494 
0495     QList<AspectType> list{AspectType::Folder, AspectType::Workbook, AspectType::Datapicker,
0496                            AspectType::DatapickerCurve, AspectType::Spreadsheet, AspectType::LiveDataSource,
0497                            AspectType::Column, AspectType::Worksheet, AspectType::CartesianPlot,
0498                            AspectType::XYFitCurve, AspectType::XYSmoothCurve, AspectType::CantorWorksheet};
0499 
0500     if (cbXColumn) {
0501         cbXColumn->setTopLevelClasses(list);
0502         cbYColumn->setTopLevelClasses(list);
0503     }
0504     cbValuesColumn->setTopLevelClasses(list);
0505     cbXErrorMinusColumn->setTopLevelClasses(list);
0506     cbXErrorPlusColumn->setTopLevelClasses(list);
0507     cbYErrorMinusColumn->setTopLevelClasses(list);
0508     cbYErrorPlusColumn->setTopLevelClasses(list);
0509 
0510     if (m_curve->inherits(AspectType::XYAnalysisCurve))
0511         //the model is use in the combobox for curve data sources -> allow to also select analysis curves
0512         list = {AspectType::Column, AspectType::XYCurve,
0513             AspectType::XYFitCurve, AspectType::XYIntegrationCurve, AspectType::XYInterpolationCurve,
0514             AspectType::XYSmoothCurve, AspectType::XYFourierFilterCurve, AspectType::XYFourierTransformCurve,
0515             AspectType::XYConvolution, AspectType::XYCorrelationCurve, AspectType::XYDataReductionCurve};
0516     else
0517         list = {AspectType::Column, AspectType::XYCurve};
0518 
0519     m_aspectTreeModel->setSelectableAspects(list);
0520 
0521     if (cbXColumn) {
0522         cbXColumn->setModel(m_aspectTreeModel);
0523         cbYColumn->setModel(m_aspectTreeModel);
0524     }
0525     cbValuesColumn->setModel(m_aspectTreeModel);
0526     cbXErrorMinusColumn->setModel(m_aspectTreeModel);
0527     cbXErrorPlusColumn->setModel(m_aspectTreeModel);
0528     cbYErrorMinusColumn->setModel(m_aspectTreeModel);
0529     cbYErrorPlusColumn->setModel(m_aspectTreeModel);
0530 
0531     if (cbXColumn) {
0532         QString msg = i18n("The column \"%1\" is not available. If a new column at this path is created, it will automatically be used again by this curve.");
0533         QString path = m_curve->xColumnPath().split('/').last();
0534         if (m_curve->xColumn()) {
0535             path += QString("\t ") + m_curve->xColumn()->plotDesignationString();
0536             cbXColumn->setInvalid(false);
0537         } else
0538             cbXColumn->setInvalid(true, msg.arg(m_curve->xColumnPath()));
0539         cbXColumn->setText(path);
0540 
0541         path = m_curve->yColumnPath().split('/').last();
0542         if (m_curve->yColumn()) {
0543             path += QString("\t ") + m_curve->yColumn()->plotDesignationString();
0544             cbYColumn->setInvalid(false);
0545         } else
0546             cbYColumn->setInvalid(true, msg.arg(m_curve->yColumnPath()));
0547         cbYColumn->setText(path);
0548     }
0549 
0550 
0551     //this function is called after the dock widget is initializes and the curves are set.
0552     //so, we use this function to finalize the initialization eventhough it's not related
0553     //to the actual set of the model (could also be solved by a new class XYAnalysisiCurveDock).
0554 
0555     //hide property widgets that are not relevant for analysis curves
0556     bool visible = (m_curve->type() == AspectType::XYCurve);
0557     ui.lLineType->setVisible(visible);
0558     ui.cbLineType->setVisible(visible);
0559     ui.lLineSkipGaps->setVisible(visible);
0560     ui.chkLineSkipGaps->setVisible(visible);
0561     ui.lLineIncreasingXOnly->setVisible(visible);
0562     ui.chkLineIncreasingXOnly->setVisible(visible);
0563 
0564     //remove the tab "Error bars" for analysis curves
0565     if (!visible)
0566         ui.tabWidget->removeTab(5);
0567 }
0568 
0569 /*!
0570   sets the curves. The properties of the curves in the list \c list can be edited in this widget.
0571 */
0572 void XYCurveDock::setCurves(QList<XYCurve*> list) {
0573     m_initializing = true;
0574     m_curvesList = list;
0575     m_curve = list.first();
0576     m_aspect = m_curve;
0577     Q_ASSERT(m_curve);
0578     m_aspectTreeModel = new AspectTreeModel(m_curve->project());
0579     setModel();
0580     initGeneralTab();
0581     initTabs();
0582     m_initializing = false;
0583 }
0584 
0585 void XYCurveDock::initGeneralTab() {
0586     DEBUG("XYCurveDock::initGeneralTab()");
0587     //if there are more than one curve in the list, disable the content in the tab "general"
0588     if (m_curvesList.size() == 1) {
0589         uiGeneralTab.lName->setEnabled(true);
0590         uiGeneralTab.leName->setEnabled(true);
0591         uiGeneralTab.lComment->setEnabled(true);
0592         uiGeneralTab.leComment->setEnabled(true);
0593 
0594         uiGeneralTab.lXColumn->setEnabled(true);
0595         cbXColumn->setEnabled(true);
0596         uiGeneralTab.lYColumn->setEnabled(true);
0597         cbYColumn->setEnabled(true);
0598 
0599         DEBUG("setModelIndexFromAspect()");
0600         this->setModelIndexFromAspect(cbXColumn, m_curve->xColumn());
0601         this->setModelIndexFromAspect(cbYColumn, m_curve->yColumn());
0602 
0603         uiGeneralTab.leName->setText(m_curve->name());
0604         uiGeneralTab.leComment->setText(m_curve->comment());
0605     } else {
0606         uiGeneralTab.lName->setEnabled(false);
0607         uiGeneralTab.leName->setEnabled(false);
0608         uiGeneralTab.lComment->setEnabled(false);
0609         uiGeneralTab.leComment->setEnabled(false);
0610 
0611         uiGeneralTab.lXColumn->setEnabled(false);
0612         cbXColumn->setEnabled(false);
0613         uiGeneralTab.lYColumn->setEnabled(false);
0614         cbYColumn->setEnabled(false);
0615 
0616         cbXColumn->setCurrentModelIndex(QModelIndex());
0617         cbYColumn->setCurrentModelIndex(QModelIndex());
0618 
0619         uiGeneralTab.leName->setText(QString());
0620         uiGeneralTab.leComment->setText(QString());
0621     }
0622 
0623     checkColumnAvailability(cbXColumn, m_curve->xColumn(), m_curve->xColumnPath());
0624     checkColumnAvailability(cbYColumn, m_curve->yColumn(), m_curve->yColumnPath());
0625     checkColumnAvailability(cbValuesColumn, m_curve->valuesColumn(), m_curve->valuesColumnPath());
0626     checkColumnAvailability(cbXErrorPlusColumn, m_curve->xErrorPlusColumn(), m_curve->xErrorPlusColumnPath());
0627     checkColumnAvailability(cbXErrorMinusColumn, m_curve->xErrorMinusColumn(), m_curve->xErrorMinusColumnPath());
0628     checkColumnAvailability(cbYErrorPlusColumn, m_curve->yErrorPlusColumn(), m_curve->yErrorPlusColumnPath());
0629     checkColumnAvailability(cbYErrorMinusColumn, m_curve->yErrorMinusColumn(), m_curve->yErrorMinusColumnPath());
0630 
0631     //show the properties of the first curve
0632     uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() );
0633 
0634     //Slots
0635     connect(m_curve, &XYCurve::aspectDescriptionChanged, this, &XYCurveDock::curveDescriptionChanged);
0636     connect(m_curve, &XYCurve::xColumnChanged, this, &XYCurveDock::curveXColumnChanged);
0637     connect(m_curve, &XYCurve::yColumnChanged, this, &XYCurveDock::curveYColumnChanged);
0638     connect(m_curve, QOverload<bool>::of(&XYCurve::visibilityChanged), this, &XYCurveDock::curveVisibilityChanged);
0639     DEBUG("XYCurveDock::initGeneralTab() DONE");
0640 }
0641 
0642 void XYCurveDock::initTabs() {
0643     //if there are more than one curve in the list, disable the tab "general"
0644     if (m_curvesList.size() == 1) {
0645         this->setModelIndexFromAspect(cbValuesColumn, m_curve->valuesColumn());
0646         this->setModelIndexFromAspect(cbXErrorPlusColumn, m_curve->xErrorPlusColumn());
0647         this->setModelIndexFromAspect(cbXErrorMinusColumn, m_curve->xErrorMinusColumn());
0648         this->setModelIndexFromAspect(cbYErrorPlusColumn, m_curve->yErrorPlusColumn());
0649         this->setModelIndexFromAspect(cbYErrorMinusColumn, m_curve->yErrorMinusColumn());
0650     } else {
0651         cbValuesColumn->setCurrentModelIndex(QModelIndex());
0652         cbXErrorPlusColumn->setCurrentModelIndex(QModelIndex());
0653         cbXErrorMinusColumn->setCurrentModelIndex(QModelIndex());
0654         cbYErrorPlusColumn->setCurrentModelIndex(QModelIndex());
0655         cbYErrorMinusColumn->setCurrentModelIndex(QModelIndex());
0656     }
0657 
0658     //show the properties of the first curve
0659     load();
0660 
0661     //Slots
0662 
0663     //Line-Tab
0664     connect(m_curve, SIGNAL(lineTypeChanged(XYCurve::LineType)), this, SLOT(curveLineTypeChanged(XYCurve::LineType)));
0665     connect(m_curve, SIGNAL(lineSkipGapsChanged(bool)), this, SLOT(curveLineSkipGapsChanged(bool)));
0666     connect(m_curve, &XYCurve::lineIncreasingXOnlyChanged, this, &XYCurveDock::curveLineIncreasingXOnlyChanged);
0667     connect(m_curve, SIGNAL(lineInterpolationPointsCountChanged(int)), this, SLOT(curveLineInterpolationPointsCountChanged(int)));
0668     connect(m_curve, SIGNAL(linePenChanged(QPen)), this, SLOT(curveLinePenChanged(QPen)));
0669     connect(m_curve, SIGNAL(lineOpacityChanged(qreal)), this, SLOT(curveLineOpacityChanged(qreal)));
0670     connect(m_curve, SIGNAL(dropLineTypeChanged(XYCurve::DropLineType)), this, SLOT(curveDropLineTypeChanged(XYCurve::DropLineType)));
0671     connect(m_curve, SIGNAL(dropLinePenChanged(QPen)), this, SLOT(curveDropLinePenChanged(QPen)));
0672     connect(m_curve, SIGNAL(dropLineOpacityChanged(qreal)), this, SLOT(curveDropLineOpacityChanged(qreal)));
0673 
0674     //Symbol-Tab
0675     connect(m_curve, SIGNAL(symbolsStyleChanged(Symbol::Style)), this, SLOT(curveSymbolsStyleChanged(Symbol::Style)));
0676     connect(m_curve, SIGNAL(symbolsSizeChanged(qreal)), this, SLOT(curveSymbolsSizeChanged(qreal)));
0677     connect(m_curve, SIGNAL(symbolsRotationAngleChanged(qreal)), this, SLOT(curveSymbolsRotationAngleChanged(qreal)));
0678     connect(m_curve, SIGNAL(symbolsOpacityChanged(qreal)), this, SLOT(curveSymbolsOpacityChanged(qreal)));
0679     connect(m_curve, SIGNAL(symbolsBrushChanged(QBrush)), this, SLOT(curveSymbolsBrushChanged(QBrush)));
0680     connect(m_curve, SIGNAL(symbolsPenChanged(QPen)), this, SLOT(curveSymbolsPenChanged(QPen)));
0681 
0682     //Values-Tab
0683     connect(m_curve, SIGNAL(valuesTypeChanged(XYCurve::ValuesType)), this, SLOT(curveValuesTypeChanged(XYCurve::ValuesType)));
0684     connect(m_curve, SIGNAL(valuesColumnChanged(const AbstractColumn*)), this, SLOT(curveValuesColumnChanged(const AbstractColumn*)));
0685     connect(m_curve, SIGNAL(valuesPositionChanged(XYCurve::ValuesPosition)), this, SLOT(curveValuesPositionChanged(XYCurve::ValuesPosition)));
0686     connect(m_curve, SIGNAL(valuesDistanceChanged(qreal)), this, SLOT(curveValuesDistanceChanged(qreal)));
0687     connect(m_curve, SIGNAL(valuesOpacityChanged(qreal)), this, SLOT(curveValuesOpacityChanged(qreal)));
0688     connect(m_curve, SIGNAL(valuesRotationAngleChanged(qreal)), this, SLOT(curveValuesRotationAngleChanged(qreal)));
0689     connect(m_curve, &XYCurve::valuesNumericFormatChanged, this, &XYCurveDock::curveValuesNumericFormatChanged);
0690     connect(m_curve, &XYCurve::valuesPrecisionChanged, this, &XYCurveDock::curveValuesPrecisionChanged);
0691     connect(m_curve, &XYCurve::valuesDateTimeFormatChanged, this, &XYCurveDock::curveValuesDateTimeFormatChanged);
0692     connect(m_curve, SIGNAL(valuesPrefixChanged(QString)), this, SLOT(curveValuesPrefixChanged(QString)));
0693     connect(m_curve, SIGNAL(valuesSuffixChanged(QString)), this, SLOT(curveValuesSuffixChanged(QString)));
0694     connect(m_curve, SIGNAL(valuesFontChanged(QFont)), this, SLOT(curveValuesFontChanged(QFont)));
0695     connect(m_curve, SIGNAL(valuesColorChanged(QColor)), this, SLOT(curveValuesColorChanged(QColor)));
0696 
0697     //Filling-Tab
0698     connect( m_curve, SIGNAL(fillingPositionChanged(XYCurve::FillingPosition)), this, SLOT(curveFillingPositionChanged(XYCurve::FillingPosition)) );
0699     connect( m_curve, SIGNAL(fillingTypeChanged(PlotArea::BackgroundType)), this, SLOT(curveFillingTypeChanged(PlotArea::BackgroundType)) );
0700     connect( m_curve, SIGNAL(fillingColorStyleChanged(PlotArea::BackgroundColorStyle)), this, SLOT(curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle)) );
0701     connect( m_curve, SIGNAL(fillingImageStyleChanged(PlotArea::BackgroundImageStyle)), this, SLOT(curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle)) );
0702     connect( m_curve, SIGNAL(fillingBrushStyleChanged(Qt::BrushStyle)), this, SLOT(curveFillingBrushStyleChanged(Qt::BrushStyle)) );
0703     connect( m_curve, SIGNAL(fillingFirstColorChanged(QColor&)), this, SLOT(curveFillingFirstColorChanged(QColor&)) );
0704     connect( m_curve, SIGNAL(fillingSecondColorChanged(QColor&)), this, SLOT(curveFillingSecondColorChanged(QColor&)) );
0705     connect( m_curve, SIGNAL(fillingFileNameChanged(QString&)), this, SLOT(curveFillingFileNameChanged(QString&)) );
0706     connect( m_curve, SIGNAL(fillingOpacityChanged(float)), this, SLOT(curveFillingOpacityChanged(float)) );
0707 
0708     //"Error bars"-Tab
0709     connect(m_curve, SIGNAL(xErrorTypeChanged(XYCurve::ErrorType)), this, SLOT(curveXErrorTypeChanged(XYCurve::ErrorType)));
0710     connect(m_curve, SIGNAL(xErrorPlusColumnChanged(const AbstractColumn*)), this, SLOT(curveXErrorPlusColumnChanged(const AbstractColumn*)));
0711     connect(m_curve, SIGNAL(xErrorMinusColumnChanged(const AbstractColumn*)), this, SLOT(curveXErrorMinusColumnChanged(const AbstractColumn*)));
0712     connect(m_curve, SIGNAL(yErrorTypeChanged(XYCurve::ErrorType)), this, SLOT(curveYErrorTypeChanged(XYCurve::ErrorType)));
0713     connect(m_curve, SIGNAL(yErrorPlusColumnChanged(const AbstractColumn*)), this, SLOT(curveYErrorPlusColumnChanged(const AbstractColumn*)));
0714     connect(m_curve, SIGNAL(yErrorMinusColumnChanged(const AbstractColumn*)), this, SLOT(curveYErrorMinusColumnChanged(const AbstractColumn*)));
0715     connect(m_curve, SIGNAL(errorBarsCapSizeChanged(qreal)), this, SLOT(curveErrorBarsCapSizeChanged(qreal)));
0716     connect(m_curve, SIGNAL(errorBarsTypeChanged(XYCurve::ErrorBarsType)), this, SLOT(curveErrorBarsTypeChanged(XYCurve::ErrorBarsType)));
0717     connect(m_curve, SIGNAL(errorBarsPenChanged(QPen)), this, SLOT(curveErrorBarsPenChanged(QPen)));
0718     connect(m_curve, SIGNAL(errorBarsOpacityChanged(qreal)), this, SLOT(curveErrorBarsOpacityChanged(qreal)));
0719 }
0720 
0721 void XYCurveDock::checkColumnAvailability(TreeViewComboBox* cb, const AbstractColumn* column, const QString& columnPath) {
0722     if (!cb)
0723         return;// normally it shouldn't be called
0724 
0725     // don't make the comboboxes red for initially created curves
0726     if (!column && columnPath.isEmpty()) {
0727         cb->setText("");
0728         cb->setInvalid(false);
0729         return;
0730     }
0731 
0732     if (column) {
0733         // current index text should be used
0734         cb->useCurrentIndexText(true);
0735         cb->setInvalid(false);
0736     } else {
0737         cb->useCurrentIndexText(false);
0738         cb->setInvalid(true, i18n("The column \"%1\"\nis not available anymore. It will be automatically used once it is created again.", columnPath));
0739     }
0740     cb->setText(columnPath.split('/').last());
0741 }
0742 
0743 void XYCurveDock::setModelIndexFromAspect(TreeViewComboBox* cb, const AbstractAspect* aspect) {
0744     if (aspect)
0745         cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(aspect));
0746     else
0747         cb->setCurrentModelIndex(QModelIndex());
0748 }
0749 
0750 void XYCurveDock::updateLocale() {
0751     SET_NUMBER_LOCALE
0752     ui.sbLineWidth->setLocale(numberLocale);
0753     ui.sbDropLineWidth->setLocale(numberLocale);
0754     ui.sbSymbolSize->setLocale(numberLocale);
0755     ui.sbSymbolBorderWidth->setLocale(numberLocale);
0756     ui.sbValuesDistance->setLocale(numberLocale);
0757     ui.sbErrorBarsCapSize->setLocale(numberLocale);
0758     ui.sbErrorBarsWidth->setLocale(numberLocale);
0759 }
0760 
0761 //*************************************************************
0762 //********** SLOTs for changes triggered in XYCurveDock ********
0763 //*************************************************************
0764 void XYCurveDock::retranslateUi() {
0765     ui.lLineSkipGaps->setToolTip(i18n("If checked, connect neighbour points with lines even if there are gaps (invalid or masked values) between them"));
0766     ui.chkLineSkipGaps->setToolTip(i18n("If checked, connect neighbour points with lines even if there are gaps (invalid or masked values) between them"));
0767     ui.lLineIncreasingXOnly->setToolTip(i18n("If checked, connect data points only for strictly increasing values of X"));
0768     ui.chkLineIncreasingXOnly->setToolTip(i18n("If checked, connect data points only for strictly increasing values of X"));
0769     //TODO:
0770 //  uiGeneralTab.lName->setText(i18n("Name"));
0771 //  uiGeneralTab.lComment->setText(i18n("Comment"));
0772 //  uiGeneralTab.chkVisible->setText(i18n("Visible"));
0773 //  uiGeneralTab.lXColumn->setText(i18n("x-data"));
0774 //  uiGeneralTab.lYColumn->setText(i18n("y-data"));
0775 
0776     //TODO updatePenStyles, updateBrushStyles for all comboboxes
0777 }
0778 
0779 void XYCurveDock::xColumnChanged(const QModelIndex& index) {
0780     updateValuesWidgets();
0781 
0782     if (m_initializing)
0783         return;
0784 
0785     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
0786     AbstractColumn* column = nullptr;
0787     if (aspect) {
0788         column = dynamic_cast<AbstractColumn*>(aspect);
0789         Q_ASSERT(column);
0790     }
0791 
0792     for (auto* curve : m_curvesList)
0793         curve->setXColumn(column);
0794 }
0795 
0796 void XYCurveDock::yColumnChanged(const QModelIndex& index) {
0797     updateValuesWidgets();
0798 
0799     if (m_initializing)
0800         return;
0801 
0802     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
0803     AbstractColumn* column = nullptr;
0804     if (aspect) {
0805         column = dynamic_cast<AbstractColumn*>(aspect);
0806         Q_ASSERT(column);
0807     }
0808 
0809     for (auto* curve : m_curvesList)
0810         curve->setYColumn(column);
0811 }
0812 
0813 void XYCurveDock::visibilityChanged(bool state) {
0814     if (m_initializing)
0815         return;
0816 
0817     for (auto* curve : m_curvesList)
0818         curve->setVisible(state);
0819 }
0820 
0821 // "Line"-tab
0822 void XYCurveDock::lineTypeChanged(int index) {
0823     const auto lineType = XYCurve::LineType(index);
0824 
0825     if ( lineType == XYCurve::LineType::NoLine) {
0826         ui.chkLineSkipGaps->setEnabled(false);
0827         ui.cbLineStyle->setEnabled(false);
0828         ui.kcbLineColor->setEnabled(false);
0829         ui.sbLineWidth->setEnabled(false);
0830         ui.sbLineOpacity->setEnabled(false);
0831         ui.lLineInterpolationPointsCount->hide();
0832         ui.sbLineInterpolationPointsCount->hide();
0833     } else {
0834         ui.chkLineSkipGaps->setEnabled(true);
0835         ui.cbLineStyle->setEnabled(true);
0836         ui.kcbLineColor->setEnabled(true);
0837         ui.sbLineWidth->setEnabled(true);
0838         ui.sbLineOpacity->setEnabled(true);
0839 
0840         if (lineType == XYCurve::LineType::SplineCubicNatural || lineType == XYCurve::LineType::SplineCubicPeriodic
0841                 || lineType == XYCurve::LineType::SplineAkimaNatural || lineType == XYCurve::LineType::SplineAkimaPeriodic) {
0842             ui.lLineInterpolationPointsCount->show();
0843             ui.sbLineInterpolationPointsCount->show();
0844             ui.lLineSkipGaps->hide();
0845             ui.chkLineSkipGaps->hide();
0846         } else {
0847             ui.lLineInterpolationPointsCount->hide();
0848             ui.sbLineInterpolationPointsCount->hide();
0849             ui.lLineSkipGaps->show();
0850             ui.chkLineSkipGaps->show();
0851         }
0852     }
0853 
0854     if (m_initializing)
0855         return;
0856 
0857     for (auto* curve : m_curvesList)
0858         curve->setLineType(lineType);
0859 }
0860 
0861 void XYCurveDock::lineSkipGapsChanged(bool skip) {
0862     if (m_initializing)
0863         return;
0864 
0865     for (auto* curve : m_curvesList)
0866         curve->setLineSkipGaps(skip);
0867 }
0868 
0869 void XYCurveDock::lineIncreasingXOnlyChanged(bool incr) {
0870     if (m_initializing)
0871         return;
0872 
0873     for (auto* curve : m_curvesList)
0874         curve->setLineIncreasingXOnly(incr);
0875 }
0876 
0877 void XYCurveDock::lineInterpolationPointsCountChanged(int count) {
0878     if (m_initializing)
0879         return;
0880 
0881     for (auto* curve : m_curvesList)
0882         curve->setLineInterpolationPointsCount(count);
0883 }
0884 
0885 void XYCurveDock::lineStyleChanged(int index) {
0886     if (index == -1 || m_initializing)
0887         return;
0888 
0889     const auto penStyle = Qt::PenStyle(index);
0890     QPen pen;
0891     for (auto* curve : m_curvesList) {
0892         pen = curve->linePen();
0893         pen.setStyle(penStyle);
0894         curve->setLinePen(pen);
0895     }
0896 }
0897 
0898 void XYCurveDock::lineColorChanged(const QColor& color) {
0899     if (m_initializing)
0900         return;
0901 
0902     QPen pen;
0903     for (auto* curve : m_curvesList) {
0904         pen = curve->linePen();
0905         pen.setColor(color);
0906         curve->setLinePen(pen);
0907     }
0908 
0909     m_initializing = true;
0910     GuiTools::updatePenStyles(ui.cbLineStyle, color);
0911     m_initializing = false;
0912 }
0913 
0914 void XYCurveDock::lineWidthChanged(double value) {
0915     if (m_initializing)
0916         return;
0917 
0918     QPen pen;
0919     for (auto* curve : m_curvesList) {
0920         pen = curve->linePen();
0921         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
0922         curve->setLinePen(pen);
0923     }
0924 }
0925 
0926 void XYCurveDock::lineOpacityChanged(int value) {
0927     if (m_initializing)
0928         return;
0929 
0930     qreal opacity = (float)value/100.;
0931     for (auto* curve : m_curvesList)
0932         curve->setLineOpacity(opacity);
0933 }
0934 
0935 void XYCurveDock::dropLineTypeChanged(int index) {
0936     const auto dropLineType = XYCurve::DropLineType(index);
0937 
0938     if ( dropLineType == XYCurve::DropLineType::NoDropLine) {
0939         ui.cbDropLineStyle->setEnabled(false);
0940         ui.kcbDropLineColor->setEnabled(false);
0941         ui.sbDropLineWidth->setEnabled(false);
0942         ui.sbDropLineOpacity->setEnabled(false);
0943     } else {
0944         ui.cbDropLineStyle->setEnabled(true);
0945         ui.kcbDropLineColor->setEnabled(true);
0946         ui.sbDropLineWidth->setEnabled(true);
0947         ui.sbDropLineOpacity->setEnabled(true);
0948     }
0949 
0950     if (m_initializing)
0951         return;
0952 
0953     for (auto* curve : m_curvesList)
0954         curve->setDropLineType(dropLineType);
0955 }
0956 
0957 void XYCurveDock::dropLineStyleChanged(int index) {
0958     if (index == -1 || m_initializing)
0959         return;
0960 
0961     auto penStyle = Qt::PenStyle(index);
0962     QPen pen;
0963     for (auto* curve : m_curvesList) {
0964         pen = curve->dropLinePen();
0965         pen.setStyle(penStyle);
0966         curve->setDropLinePen(pen);
0967     }
0968 }
0969 
0970 void XYCurveDock::dropLineColorChanged(const QColor& color) {
0971     if (m_initializing)
0972         return;
0973 
0974     QPen pen;
0975     for (auto* curve : m_curvesList) {
0976         pen = curve->dropLinePen();
0977         pen.setColor(color);
0978         curve->setDropLinePen(pen);
0979     }
0980 
0981     m_initializing = true;
0982     GuiTools::updatePenStyles(ui.cbDropLineStyle, color);
0983     m_initializing = false;
0984 }
0985 
0986 void XYCurveDock::dropLineWidthChanged(double value) {
0987     if (m_initializing)
0988         return;
0989 
0990     QPen pen;
0991     for (auto* curve : m_curvesList) {
0992         pen = curve->dropLinePen();
0993         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
0994         curve->setDropLinePen(pen);
0995     }
0996 }
0997 
0998 void XYCurveDock::dropLineOpacityChanged(int value) {
0999     if (m_initializing)
1000         return;
1001 
1002     qreal opacity = (float)value/100.;
1003     for (auto* curve : m_curvesList)
1004         curve->setDropLineOpacity(opacity);
1005 }
1006 
1007 //"Symbol"-tab
1008 void XYCurveDock::symbolsStyleChanged(int index) {
1009     const auto style = Symbol::Style(index);
1010 
1011     if (style == Symbol::Style::NoSymbols) {
1012         ui.sbSymbolSize->setEnabled(false);
1013         ui.sbSymbolRotation->setEnabled(false);
1014         ui.sbSymbolOpacity->setEnabled(false);
1015 
1016         ui.kcbSymbolFillingColor->setEnabled(false);
1017         ui.cbSymbolFillingStyle->setEnabled(false);
1018 
1019         ui.cbSymbolBorderStyle->setEnabled(false);
1020         ui.kcbSymbolBorderColor->setEnabled(false);
1021         ui.sbSymbolBorderWidth->setEnabled(false);
1022     } else {
1023         ui.sbSymbolSize->setEnabled(true);
1024         ui.sbSymbolRotation->setEnabled(true);
1025         ui.sbSymbolOpacity->setEnabled(true);
1026 
1027         //enable/disable the symbol filling options in the GUI depending on the currently selected symbol.
1028         if (style != Symbol::Style::Line && style != Symbol::Style::Cross) {
1029             ui.cbSymbolFillingStyle->setEnabled(true);
1030             bool noBrush = (Qt::BrushStyle(ui.cbSymbolFillingStyle->currentIndex()) == Qt::NoBrush);
1031             ui.kcbSymbolFillingColor->setEnabled(!noBrush);
1032         } else {
1033             ui.kcbSymbolFillingColor->setEnabled(false);
1034             ui.cbSymbolFillingStyle->setEnabled(false);
1035         }
1036 
1037         ui.cbSymbolBorderStyle->setEnabled(true);
1038         bool noLine = (Qt::PenStyle(ui.cbSymbolBorderStyle->currentIndex()) == Qt::NoPen);
1039         ui.kcbSymbolBorderColor->setEnabled(!noLine);
1040         ui.sbSymbolBorderWidth->setEnabled(!noLine);
1041     }
1042 
1043     if (m_initializing)
1044         return;
1045 
1046     for (auto* curve : m_curvesList)
1047         curve->setSymbolsStyle(style);
1048 }
1049 
1050 void XYCurveDock::symbolsSizeChanged(double value) {
1051     if (m_initializing)
1052         return;
1053 
1054     for (auto* curve : m_curvesList)
1055         curve->setSymbolsSize( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
1056 }
1057 
1058 void XYCurveDock::symbolsRotationChanged(int value) {
1059     if (m_initializing)
1060         return;
1061 
1062     for (auto* curve : m_curvesList)
1063         curve->setSymbolsRotationAngle(value);
1064 }
1065 
1066 void XYCurveDock::symbolsOpacityChanged(int value) {
1067     if (m_initializing)
1068         return;
1069 
1070     qreal opacity = (float)value/100.;
1071     for (auto* curve : m_curvesList)
1072         curve->setSymbolsOpacity(opacity);
1073 }
1074 
1075 void XYCurveDock::symbolsFillingStyleChanged(int index) {
1076     if (index == -1)
1077         return;
1078 
1079     const auto brushStyle = Qt::BrushStyle(index);
1080     ui.kcbSymbolFillingColor->setEnabled(!(brushStyle == Qt::NoBrush));
1081 
1082     if (m_initializing)
1083         return;
1084 
1085     QBrush brush;
1086     for (auto* curve : m_curvesList) {
1087         brush = curve->symbolsBrush();
1088         brush.setStyle(brushStyle);
1089         curve->setSymbolsBrush(brush);
1090     }
1091 }
1092 
1093 void XYCurveDock::symbolsFillingColorChanged(const QColor& color) {
1094     if (m_initializing)
1095         return;
1096 
1097     QBrush brush;
1098     for (auto* curve : m_curvesList) {
1099         brush = curve->symbolsBrush();
1100         brush.setColor(color);
1101         curve->setSymbolsBrush(brush);
1102     }
1103 
1104     m_initializing = true;
1105     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, color );
1106     m_initializing = false;
1107 }
1108 
1109 void XYCurveDock::symbolsBorderStyleChanged(int index) {
1110     if (index == -1)
1111         return;
1112 
1113     const auto penStyle = Qt::PenStyle(index);
1114     if ( penStyle == Qt::NoPen ) {
1115         ui.kcbSymbolBorderColor->setEnabled(false);
1116         ui.sbSymbolBorderWidth->setEnabled(false);
1117     } else {
1118         ui.kcbSymbolBorderColor->setEnabled(true);
1119         ui.sbSymbolBorderWidth->setEnabled(true);
1120     }
1121 
1122     if (m_initializing)
1123         return;
1124 
1125     QPen pen;
1126     for (auto* curve : m_curvesList) {
1127         pen = curve->symbolsPen();
1128         pen.setStyle(penStyle);
1129         curve->setSymbolsPen(pen);
1130     }
1131 }
1132 
1133 void XYCurveDock::symbolsBorderColorChanged(const QColor& color) {
1134     if (m_initializing)
1135         return;
1136 
1137     QPen pen;
1138     for (auto* curve : m_curvesList) {
1139         pen = curve->symbolsPen();
1140         pen.setColor(color);
1141         curve->setSymbolsPen(pen);
1142     }
1143 
1144     m_initializing = true;
1145     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, color);
1146     m_initializing = false;
1147 }
1148 
1149 void XYCurveDock::symbolsBorderWidthChanged(double value) {
1150     if (m_initializing)
1151         return;
1152 
1153     QPen pen;
1154     for (auto* curve : m_curvesList) {
1155         pen = curve->symbolsPen();
1156         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
1157         curve->setSymbolsPen(pen);
1158     }
1159 }
1160 
1161 //Values-tab
1162 
1163 /*!
1164   called when the type of the values (none, x, y, (x,y) etc.) was changed.
1165 */
1166 void XYCurveDock::valuesTypeChanged(int index) {
1167     if (m_initializing)
1168         return;
1169 
1170     this->updateValuesWidgets();
1171 
1172     const auto type = XYCurve::ValuesType(index);
1173     for (auto* curve : m_curvesList)
1174         curve->setValuesType(type);
1175 }
1176 
1177 /*!
1178   called when the custom column for the values was changed.
1179 */
1180 void XYCurveDock::valuesColumnChanged(const QModelIndex& index) {
1181     if (m_initializing)
1182         return;
1183 
1184     this->updateValuesWidgets();
1185 
1186     auto* column = static_cast<Column*>(index.internalPointer());
1187     for (auto* curve : m_curvesList)
1188         curve->setValuesColumn(column);
1189 }
1190 
1191 /*!
1192   shows the formatting properties of the column \c column.
1193   Called, when a new column for the values was selected - either by changing the type of the values (none, x, y, etc.) or
1194   by selecting a new custom column for the values.
1195 */
1196 
1197 /*!
1198   depending on the currently selected values column type (column mode) updates the widgets for the values column format,
1199   shows/hides the allowed widgets, fills the corresponding combobox with the possible entries.
1200   Called when the values column was changed.
1201 */
1202 void XYCurveDock::updateValuesWidgets() {
1203     const auto type{XYCurve::ValuesType(ui.cbValuesType->currentIndex())};
1204     bool showValues{type != XYCurve::ValuesType::NoValues};
1205 
1206     ui.cbValuesPosition->setEnabled(showValues);
1207     ui.sbValuesDistance->setEnabled(showValues);
1208     ui.sbValuesRotation->setEnabled(showValues);
1209     ui.sbValuesOpacity->setEnabled(showValues);
1210     ui.kfrValuesFont->setEnabled(showValues);
1211     ui.kcbValuesColor->setEnabled(showValues);
1212 
1213     bool hasInteger = false;
1214     bool hasNumeric = false;
1215     bool hasDateTime = false;
1216 
1217     if (type == XYCurve::ValuesType::CustomColumn) {
1218         ui.lValuesColumn->show();
1219         cbValuesColumn->show();
1220 
1221         auto* column = static_cast<Column*>(cbValuesColumn->currentModelIndex().internalPointer());
1222         if (column) {
1223             if (column->columnMode() == AbstractColumn::ColumnMode::Numeric)
1224                 hasNumeric = true;
1225             else if (column->columnMode() == AbstractColumn::ColumnMode::Integer || column->columnMode() == AbstractColumn::ColumnMode::BigInt)
1226                 hasInteger = true;
1227             else if (column->columnMode() == AbstractColumn::ColumnMode::DateTime)
1228                 hasDateTime = true;
1229         }
1230     } else {
1231         ui.lValuesColumn->hide();
1232         cbValuesColumn->hide();
1233 
1234 
1235         const AbstractColumn* xColumn = nullptr;
1236         const AbstractColumn* yColumn = nullptr;
1237         switch (type) {
1238             case XYCurve::ValuesType::NoValues:
1239                 break;
1240             case XYCurve::ValuesType::X:
1241                 xColumn = m_curve->xColumn();
1242                 break;
1243             case XYCurve::ValuesType::Y:
1244                 yColumn = m_curve->yColumn();
1245                 break;
1246             case XYCurve::ValuesType::XY:
1247             case XYCurve::ValuesType::XYBracketed:
1248                 xColumn = m_curve->xColumn();
1249                 yColumn = m_curve->yColumn();
1250                 break;
1251             case XYCurve::ValuesType::CustomColumn:
1252                 break;
1253         }
1254 
1255         hasInteger = (xColumn && (xColumn->columnMode() == AbstractColumn::ColumnMode::Integer || xColumn->columnMode() == AbstractColumn::ColumnMode::Integer))
1256                         || (yColumn && (yColumn->columnMode() == AbstractColumn::ColumnMode::Integer || yColumn->columnMode() == AbstractColumn::ColumnMode::Integer));
1257 
1258         hasNumeric = (xColumn && xColumn->columnMode() == AbstractColumn::ColumnMode::Numeric)
1259                         || (yColumn && yColumn->columnMode() == AbstractColumn::ColumnMode::Numeric);
1260 
1261         hasDateTime = (xColumn && xColumn->columnMode() == AbstractColumn::ColumnMode::DateTime)
1262                         || (yColumn && yColumn->columnMode() == AbstractColumn::ColumnMode::DateTime);
1263     }
1264 
1265     //hide all the format related widgets first and
1266     //then show only what is required depending of the column mode(s)
1267     ui.lValuesFormat->hide();
1268     ui.lValuesNumericFormat->hide();
1269     ui.cbValuesNumericFormat->hide();
1270     ui.lValuesPrecision->hide();
1271     ui.sbValuesPrecision->hide();
1272     ui.lValuesDateTimeFormat->hide();
1273     ui.cbValuesDateTimeFormat->hide();
1274 
1275     if (hasNumeric || hasInteger) {
1276         ui.lValuesFormat->show();
1277         ui.lValuesNumericFormat->show();
1278         ui.cbValuesNumericFormat->show();
1279     }
1280 
1281     //precision is only available for Numeric
1282     if (hasNumeric) {
1283         ui.lValuesPrecision->show();
1284         ui.sbValuesPrecision->show();
1285     }
1286 
1287     if (hasDateTime) {
1288         ui.lValuesFormat->show();
1289         ui.lValuesDateTimeFormat->show();
1290         ui.cbValuesDateTimeFormat->show();
1291     }
1292 }
1293 
1294 void XYCurveDock::valuesPositionChanged(int index) {
1295     if (m_initializing)
1296         return;
1297 
1298     for (auto* curve : m_curvesList)
1299         curve->setValuesPosition(XYCurve::ValuesPosition(index));
1300 }
1301 
1302 void XYCurveDock::valuesDistanceChanged(double  value) {
1303     if (m_initializing)
1304         return;
1305 
1306     for (auto* curve : m_curvesList)
1307         curve->setValuesDistance( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
1308 }
1309 
1310 void XYCurveDock::valuesRotationChanged(int value) {
1311     if (m_initializing)
1312         return;
1313 
1314     for (auto* curve : m_curvesList)
1315         curve->setValuesRotationAngle(value);
1316 }
1317 
1318 void XYCurveDock::valuesOpacityChanged(int value) {
1319     if (m_initializing)
1320         return;
1321 
1322     qreal opacity = (float)value/100.;
1323     for (auto* curve : m_curvesList)
1324         curve->setValuesOpacity(opacity);
1325 }
1326 
1327 void XYCurveDock::valuesNumericFormatChanged(int index) {
1328     if (m_initializing)
1329         return;
1330 
1331     char format = ui.cbValuesNumericFormat->itemData(index).toChar().toLatin1();
1332     for (auto* curve : m_curvesList)
1333         curve->setValuesNumericFormat(format);
1334 }
1335 
1336 void XYCurveDock::valuesDateTimeFormatChanged(const QString& format) {
1337     if (m_initializing)
1338         return;
1339 
1340     for (auto* curve : m_curvesList)
1341         curve->setValuesDateTimeFormat(format);
1342 }
1343 
1344 void XYCurveDock::valuesPrecisionChanged(int precision) {
1345     if (m_initializing)
1346         return;
1347 
1348     for (auto* curve : m_curvesList)
1349         curve->setValuesPrecision(precision);
1350 }
1351 
1352 void XYCurveDock::valuesPrefixChanged() {
1353     if (m_initializing)
1354         return;
1355 
1356     QString prefix = ui.leValuesPrefix->text();
1357     for (auto* curve : m_curvesList)
1358         curve->setValuesPrefix(prefix);
1359 }
1360 
1361 void XYCurveDock::valuesSuffixChanged() {
1362     if (m_initializing)
1363         return;
1364 
1365     QString suffix = ui.leValuesSuffix->text();
1366     for (auto* curve : m_curvesList)
1367         curve->setValuesSuffix(suffix);
1368 }
1369 
1370 void XYCurveDock::valuesFontChanged(const QFont& font) {
1371     if (m_initializing)
1372         return;
1373 
1374     QFont valuesFont = font;
1375     valuesFont.setPixelSize( Worksheet::convertToSceneUnits(font.pointSizeF(), Worksheet::Unit::Point) );
1376     for (auto* curve : m_curvesList)
1377         curve->setValuesFont(valuesFont);
1378 }
1379 
1380 void XYCurveDock::valuesColorChanged(const QColor& color) {
1381     if (m_initializing)
1382         return;
1383 
1384     for (auto* curve : m_curvesList)
1385         curve->setValuesColor(color);
1386 }
1387 
1388 //Filling-tab
1389 void XYCurveDock::fillingPositionChanged(int index) {
1390     const auto fillingPosition{XYCurve::FillingPosition(index)};
1391 
1392     bool b = (fillingPosition != XYCurve::FillingPosition::NoFilling);
1393     ui.cbFillingType->setEnabled(b);
1394     ui.cbFillingColorStyle->setEnabled(b);
1395     ui.cbFillingBrushStyle->setEnabled(b);
1396     ui.cbFillingImageStyle->setEnabled(b);
1397     ui.kcbFillingFirstColor->setEnabled(b);
1398     ui.kcbFillingSecondColor->setEnabled(b);
1399     ui.leFillingFileName->setEnabled(b);
1400     ui.bFillingOpen->setEnabled(b);
1401     ui.sbFillingOpacity->setEnabled(b);
1402 
1403     if (m_initializing)
1404         return;
1405 
1406     for (auto* curve : m_curvesList)
1407         curve->setFillingPosition(fillingPosition);
1408 }
1409 
1410 void XYCurveDock::fillingTypeChanged(int index) {
1411     const auto type = (PlotArea::BackgroundType)index;
1412 
1413     if (type == PlotArea::BackgroundType::Color) {
1414         ui.lFillingColorStyle->show();
1415         ui.cbFillingColorStyle->show();
1416         ui.lFillingImageStyle->hide();
1417         ui.cbFillingImageStyle->hide();
1418         ui.lFillingBrushStyle->hide();
1419         ui.cbFillingBrushStyle->hide();
1420 
1421         ui.lFillingFileName->hide();
1422         ui.leFillingFileName->hide();
1423         ui.bFillingOpen->hide();
1424 
1425         ui.lFillingFirstColor->show();
1426         ui.kcbFillingFirstColor->show();
1427 
1428         auto style = (PlotArea::BackgroundColorStyle) ui.cbFillingColorStyle->currentIndex();
1429         if (style == PlotArea::BackgroundColorStyle::SingleColor) {
1430             ui.lFillingFirstColor->setText(i18n("Color:"));
1431             ui.lFillingSecondColor->hide();
1432             ui.kcbFillingSecondColor->hide();
1433         } else {
1434             ui.lFillingFirstColor->setText(i18n("First color:"));
1435             ui.lFillingSecondColor->show();
1436             ui.kcbFillingSecondColor->show();
1437         }
1438     } else if (type == PlotArea::BackgroundType::Image) {
1439         ui.lFillingColorStyle->hide();
1440         ui.cbFillingColorStyle->hide();
1441         ui.lFillingImageStyle->show();
1442         ui.cbFillingImageStyle->show();
1443         ui.lFillingBrushStyle->hide();
1444         ui.cbFillingBrushStyle->hide();
1445         ui.lFillingFileName->show();
1446         ui.leFillingFileName->show();
1447         ui.bFillingOpen->show();
1448 
1449         ui.lFillingFirstColor->hide();
1450         ui.kcbFillingFirstColor->hide();
1451         ui.lFillingSecondColor->hide();
1452         ui.kcbFillingSecondColor->hide();
1453     } else if (type == PlotArea::BackgroundType::Pattern) {
1454         ui.lFillingFirstColor->setText(i18n("Color:"));
1455         ui.lFillingColorStyle->hide();
1456         ui.cbFillingColorStyle->hide();
1457         ui.lFillingImageStyle->hide();
1458         ui.cbFillingImageStyle->hide();
1459         ui.lFillingBrushStyle->show();
1460         ui.cbFillingBrushStyle->show();
1461         ui.lFillingFileName->hide();
1462         ui.leFillingFileName->hide();
1463         ui.bFillingOpen->hide();
1464 
1465         ui.lFillingFirstColor->show();
1466         ui.kcbFillingFirstColor->show();
1467         ui.lFillingSecondColor->hide();
1468         ui.kcbFillingSecondColor->hide();
1469     }
1470 
1471     if (m_initializing)
1472         return;
1473 
1474     for (auto* curve : m_curvesList)
1475         curve->setFillingType(type);
1476 }
1477 
1478 void XYCurveDock::fillingColorStyleChanged(int index) {
1479     const auto style = (PlotArea::BackgroundColorStyle)index;
1480 
1481     if (style == PlotArea::BackgroundColorStyle::SingleColor) {
1482         ui.lFillingFirstColor->setText(i18n("Color:"));
1483         ui.lFillingSecondColor->hide();
1484         ui.kcbFillingSecondColor->hide();
1485     } else {
1486         ui.lFillingFirstColor->setText(i18n("First color:"));
1487         ui.lFillingSecondColor->show();
1488         ui.kcbFillingSecondColor->show();
1489         ui.lFillingBrushStyle->hide();
1490         ui.cbFillingBrushStyle->hide();
1491     }
1492 
1493     if (m_initializing)
1494         return;
1495 
1496     for (auto* curve : m_curvesList)
1497         curve->setFillingColorStyle(style);
1498 }
1499 
1500 void XYCurveDock::fillingImageStyleChanged(int index) {
1501     if (m_initializing)
1502         return;
1503 
1504     auto style = (PlotArea::BackgroundImageStyle)index;
1505     for (auto* curve : m_curvesList)
1506         curve->setFillingImageStyle(style);
1507 }
1508 
1509 void XYCurveDock::fillingBrushStyleChanged(int index) {
1510     if (index == -1 || m_initializing)
1511         return;
1512 
1513     auto style = (Qt::BrushStyle)index;
1514     for (auto* curve : m_curvesList)
1515         curve->setFillingBrushStyle(style);
1516 }
1517 
1518 void XYCurveDock::fillingFirstColorChanged(const QColor& c) {
1519     if (m_initializing)
1520         return;
1521 
1522     for (auto* curve : m_curvesList)
1523         curve->setFillingFirstColor(c);
1524 
1525     m_initializing = true;
1526     GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, c);
1527     m_initializing = false;
1528 }
1529 
1530 void XYCurveDock::fillingSecondColorChanged(const QColor& c) {
1531     if (m_initializing)
1532         return;
1533 
1534     for (auto* curve : m_curvesList)
1535         curve->setFillingSecondColor(c);
1536 }
1537 
1538 /*!
1539     opens a file dialog and lets the user select the image file.
1540 */
1541 void XYCurveDock::selectFile() {
1542     KConfigGroup conf(KSharedConfig::openConfig(), "XYCurveDock");
1543     QString dir = conf.readEntry("LastImageDir", "");
1544 
1545     QString formats;
1546     for (const QByteArray& format : QImageReader::supportedImageFormats()) {
1547         QString f = "*." + QString(format.constData());
1548         if (f == QLatin1String("*.svg"))
1549             continue;
1550         formats.isEmpty() ? formats += f : formats += ' ' + f;
1551     }
1552 
1553     QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats));
1554     if (path.isEmpty())
1555         return; //cancel was clicked in the file-dialog
1556 
1557     int pos = path.lastIndexOf(QLatin1String("/"));
1558     if (pos != -1) {
1559         QString newDir = path.left(pos);
1560         if (newDir != dir)
1561             conf.writeEntry("LastImageDir", newDir);
1562     }
1563 
1564     ui.leFillingFileName->setText( path );
1565 
1566     for (auto* curve : m_curvesList)
1567         curve->setFillingFileName(path);
1568 }
1569 
1570 void XYCurveDock::fileNameChanged() {
1571     if (m_initializing)
1572         return;
1573 
1574     QString fileName = ui.leFillingFileName->text();
1575     for (auto* curve : m_curvesList)
1576         curve->setFillingFileName(fileName);
1577 }
1578 
1579 void XYCurveDock::fillingOpacityChanged(int value) {
1580     if (m_initializing)
1581         return;
1582 
1583     qreal opacity = (float)value/100.;
1584     for (auto* curve : m_curvesList)
1585         curve->setFillingOpacity(opacity);
1586 }
1587 
1588 //"Error bars"-Tab
1589 void XYCurveDock::xErrorTypeChanged(int index) const {
1590     if (index == 0) {
1591         //no error
1592         ui.lXErrorDataPlus->setVisible(false);
1593         cbXErrorPlusColumn->setVisible(false);
1594         ui.lXErrorDataMinus->setVisible(false);
1595         cbXErrorMinusColumn->setVisible(false);
1596     } else if (index == 1) {
1597         //symmetric error
1598         ui.lXErrorDataPlus->setVisible(true);
1599         cbXErrorPlusColumn->setVisible(true);
1600         ui.lXErrorDataMinus->setVisible(false);
1601         cbXErrorMinusColumn->setVisible(false);
1602         ui.lXErrorDataPlus->setText(i18n("Data, +-"));
1603     } else if (index == 2) {
1604         //asymmetric error
1605         ui.lXErrorDataPlus->setVisible(true);
1606         cbXErrorPlusColumn->setVisible(true);
1607         ui.lXErrorDataMinus->setVisible(true);
1608         cbXErrorMinusColumn->setVisible(true);
1609         ui.lXErrorDataPlus->setText(i18n("Data, +"));
1610     }
1611 
1612     bool b = (index!=0 || ui.cbYErrorType->currentIndex()!=0);
1613     ui.lErrorFormat->setVisible(b);
1614     ui.lErrorBarsType->setVisible(b);
1615     ui.cbErrorBarsType->setVisible(b);
1616     ui.lErrorBarsStyle->setVisible(b);
1617     ui.cbErrorBarsStyle->setVisible(b);
1618     ui.lErrorBarsColor->setVisible(b);
1619     ui.kcbErrorBarsColor->setVisible(b);
1620     ui.lErrorBarsWidth->setVisible(b);
1621     ui.sbErrorBarsWidth->setVisible(b);
1622     ui.lErrorBarsOpacity->setVisible(b);
1623     ui.sbErrorBarsOpacity->setVisible(b);
1624 
1625     if (m_initializing)
1626         return;
1627 
1628     for (auto* curve : m_curvesList)
1629         curve->setXErrorType(XYCurve::ErrorType(index));
1630 }
1631 
1632 void XYCurveDock::xErrorPlusColumnChanged(const QModelIndex& index) const {
1633     Q_UNUSED(index);
1634     if (m_initializing)
1635         return;
1636 
1637     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
1638     auto* column = dynamic_cast<AbstractColumn*>(aspect);
1639     Q_ASSERT(column);
1640 
1641     for (auto* curve : m_curvesList)
1642         curve->setXErrorPlusColumn(column);
1643 }
1644 
1645 void XYCurveDock::xErrorMinusColumnChanged(const QModelIndex& index) const {
1646     Q_UNUSED(index);
1647     if (m_initializing)
1648         return;
1649 
1650     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
1651     auto* column = dynamic_cast<AbstractColumn*>(aspect);
1652     Q_ASSERT(column);
1653 
1654     for (auto* curve : m_curvesList)
1655         curve->setXErrorMinusColumn(column);
1656 }
1657 
1658 void XYCurveDock::yErrorTypeChanged(int index) const {
1659     if (index == 0) {
1660         //no error
1661         ui.lYErrorDataPlus->setVisible(false);
1662         cbYErrorPlusColumn->setVisible(false);
1663         ui.lYErrorDataMinus->setVisible(false);
1664         cbYErrorMinusColumn->setVisible(false);
1665     } else if (index == 1) {
1666         //symmetric error
1667         ui.lYErrorDataPlus->setVisible(true);
1668         cbYErrorPlusColumn->setVisible(true);
1669         ui.lYErrorDataMinus->setVisible(false);
1670         cbYErrorMinusColumn->setVisible(false);
1671         ui.lYErrorDataPlus->setText(i18n("Data, +-"));
1672     } else if (index == 2) {
1673         //asymmetric error
1674         ui.lYErrorDataPlus->setVisible(true);
1675         cbYErrorPlusColumn->setVisible(true);
1676         ui.lYErrorDataMinus->setVisible(true);
1677         cbYErrorMinusColumn->setVisible(true);
1678         ui.lYErrorDataPlus->setText(i18n("Data, +"));
1679     }
1680 
1681     bool b = (index!=0 || ui.cbXErrorType->currentIndex()!=0);
1682     ui.lErrorFormat->setVisible(b);
1683     ui.lErrorBarsType->setVisible(b);
1684     ui.cbErrorBarsType->setVisible(b);
1685     ui.lErrorBarsStyle->setVisible(b);
1686     ui.cbErrorBarsStyle->setVisible(b);
1687     ui.lErrorBarsColor->setVisible(b);
1688     ui.kcbErrorBarsColor->setVisible(b);
1689     ui.lErrorBarsWidth->setVisible(b);
1690     ui.sbErrorBarsWidth->setVisible(b);
1691     ui.lErrorBarsOpacity->setVisible(b);
1692     ui.sbErrorBarsOpacity->setVisible(b);
1693 
1694 
1695     if (m_initializing)
1696         return;
1697 
1698     for (auto* curve : m_curvesList)
1699         curve->setYErrorType(XYCurve::ErrorType(index));
1700 }
1701 
1702 void XYCurveDock::yErrorPlusColumnChanged(const QModelIndex& index) const {
1703     Q_UNUSED(index);
1704     if (m_initializing)
1705         return;
1706 
1707     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
1708     auto* column = dynamic_cast<AbstractColumn*>(aspect);
1709     Q_ASSERT(column);
1710 
1711     for (auto* curve : m_curvesList)
1712         curve->setYErrorPlusColumn(column);
1713 }
1714 
1715 void XYCurveDock::yErrorMinusColumnChanged(const QModelIndex& index) const {
1716     Q_UNUSED(index);
1717     if (m_initializing)
1718         return;
1719 
1720     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
1721     auto* column = dynamic_cast<AbstractColumn*>(aspect);
1722     Q_ASSERT(column);
1723 
1724     for (auto* curve : m_curvesList)
1725         curve->setYErrorMinusColumn(column);
1726 }
1727 
1728 void XYCurveDock::errorBarsTypeChanged(int index) const {
1729     const auto type{XYCurve::ErrorBarsType(index)};
1730     bool b = (type == XYCurve::ErrorBarsType::WithEnds);
1731     ui.lErrorBarsCapSize->setVisible(b);
1732     ui.sbErrorBarsCapSize->setVisible(b);
1733 
1734     if (m_initializing)
1735         return;
1736 
1737     for (auto* curve : m_curvesList)
1738         curve->setErrorBarsType(type);
1739 }
1740 
1741 void XYCurveDock::errorBarsCapSizeChanged(double value) const {
1742     if (m_initializing)
1743         return;
1744 
1745     float size = Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point);
1746     for (auto* curve : m_curvesList)
1747         curve->setErrorBarsCapSize(size);
1748 }
1749 
1750 void XYCurveDock::errorBarsStyleChanged(int index) const {
1751     if (index == -1 || m_initializing)
1752         return;
1753 
1754     auto penStyle = Qt::PenStyle(index);
1755     QPen pen;
1756     for (auto* curve : m_curvesList) {
1757         pen = curve->errorBarsPen();
1758         pen.setStyle(penStyle);
1759         curve->setErrorBarsPen(pen);
1760     }
1761 }
1762 
1763 void XYCurveDock::errorBarsColorChanged(const QColor& color) {
1764     if (m_initializing)
1765         return;
1766 
1767     QPen pen;
1768     for (auto* curve : m_curvesList) {
1769         pen = curve->errorBarsPen();
1770         pen.setColor(color);
1771         curve->setErrorBarsPen(pen);
1772     }
1773 
1774     m_initializing = true;
1775     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, color);
1776     m_initializing = false;
1777 }
1778 
1779 void XYCurveDock::errorBarsWidthChanged(double value) const {
1780     if (m_initializing)
1781         return;
1782 
1783     QPen pen;
1784     for (auto* curve : m_curvesList) {
1785         pen = curve->errorBarsPen();
1786         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
1787         curve->setErrorBarsPen(pen);
1788     }
1789 }
1790 
1791 void XYCurveDock::errorBarsOpacityChanged(int value) const {
1792     if (m_initializing)
1793         return;
1794 
1795     qreal opacity = (float)value/100.;
1796     for (auto* curve : m_curvesList)
1797         curve->setErrorBarsOpacity(opacity);
1798 }
1799 
1800 //*************************************************************
1801 //*********** SLOTs for changes triggered in XYCurve **********
1802 //*************************************************************
1803 //General-Tab
1804 void XYCurveDock::curveDescriptionChanged(const AbstractAspect* aspect) {
1805     if (m_curve != aspect)
1806         return;
1807 
1808     m_initializing = true;
1809     if (aspect->name() != uiGeneralTab.leName->text())
1810         uiGeneralTab.leName->setText(aspect->name());
1811     else if (aspect->comment() != uiGeneralTab.leComment->text())
1812         uiGeneralTab.leComment->setText(aspect->comment());
1813     m_initializing = false;
1814 }
1815 
1816 void XYCurveDock::curveXColumnChanged(const AbstractColumn* column) {
1817     m_initializing = true;
1818     this->setModelIndexFromAspect(cbXColumn, column);
1819     cbXColumn->useCurrentIndexText(true);
1820     cbXColumn->setInvalid(false);
1821     updateValuesWidgets();
1822     m_initializing = false;
1823 }
1824 
1825 void XYCurveDock::curveYColumnChanged(const AbstractColumn* column) {
1826     m_initializing = true;
1827     this->setModelIndexFromAspect(cbYColumn, column);
1828     cbYColumn->useCurrentIndexText(true);
1829     cbYColumn->setInvalid(false);
1830     updateValuesWidgets();
1831     m_initializing = false;
1832 }
1833 
1834 void XYCurveDock::curveVisibilityChanged(bool on) {
1835     m_initializing = true;
1836     uiGeneralTab.chkVisible->setChecked(on);
1837     m_initializing = false;
1838 }
1839 
1840 //Line-Tab
1841 void XYCurveDock::curveLineTypeChanged(XYCurve::LineType type) {
1842     m_initializing = true;
1843     ui.cbLineType->setCurrentIndex( (int) type);
1844     m_initializing = false;
1845 }
1846 void XYCurveDock::curveLineSkipGapsChanged(bool skip) {
1847     m_initializing = true;
1848     ui.chkLineSkipGaps->setChecked(skip);
1849     m_initializing = false;
1850 }
1851 void XYCurveDock::curveLineIncreasingXOnlyChanged(bool incr) {
1852     m_initializing = true;
1853     ui.chkLineIncreasingXOnly->setChecked(incr);
1854     m_initializing = false;
1855 }
1856 void XYCurveDock::curveLineInterpolationPointsCountChanged(int count) {
1857     m_initializing = true;
1858     ui.sbLineInterpolationPointsCount->setValue(count);
1859     m_initializing = false;
1860 }
1861 void XYCurveDock::curveLinePenChanged(const QPen& pen) {
1862     m_initializing = true;
1863     ui.cbLineStyle->setCurrentIndex( (int)pen.style());
1864     ui.kcbLineColor->setColor( pen.color());
1865     GuiTools::updatePenStyles(ui.cbLineStyle, pen.color());
1866     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits( pen.widthF(), Worksheet::Unit::Point) );
1867     m_initializing = false;
1868 }
1869 void XYCurveDock::curveLineOpacityChanged(qreal opacity) {
1870     m_initializing = true;
1871     ui.sbLineOpacity->setValue( round(opacity*100.0) );
1872     m_initializing = false;
1873 }
1874 void XYCurveDock::curveDropLineTypeChanged(XYCurve::DropLineType type) {
1875     m_initializing = true;
1876     ui.cbDropLineType->setCurrentIndex( (int)type );
1877     m_initializing = false;
1878 }
1879 void XYCurveDock::curveDropLinePenChanged(const QPen& pen) {
1880     m_initializing = true;
1881     ui.cbDropLineStyle->setCurrentIndex( (int) pen.style());
1882     ui.kcbDropLineColor->setColor( pen.color());
1883     GuiTools::updatePenStyles(ui.cbDropLineStyle, pen.color());
1884     ui.sbDropLineWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point) );
1885     m_initializing = false;
1886 }
1887 void XYCurveDock::curveDropLineOpacityChanged(qreal opacity) {
1888     m_initializing = true;
1889     ui.sbDropLineOpacity->setValue( round(opacity*100.0) );
1890     m_initializing = false;
1891 }
1892 
1893 //Symbol-Tab
1894 void XYCurveDock::curveSymbolsStyleChanged(Symbol::Style style) {
1895     m_initializing = true;
1896     ui.cbSymbolStyle->setCurrentIndex((int)style);
1897     m_initializing = false;
1898 }
1899 void XYCurveDock::curveSymbolsSizeChanged(qreal size) {
1900     m_initializing = true;
1901     ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Unit::Point) );
1902     m_initializing = false;
1903 }
1904 void XYCurveDock::curveSymbolsRotationAngleChanged(qreal angle) {
1905     m_initializing = true;
1906     ui.sbSymbolRotation->setValue(angle);
1907     m_initializing = false;
1908 }
1909 void XYCurveDock::curveSymbolsOpacityChanged(qreal opacity) {
1910     m_initializing = true;
1911     ui.sbSymbolOpacity->setValue( round(opacity*100.0) );
1912     m_initializing = false;
1913 }
1914 void XYCurveDock::curveSymbolsBrushChanged(const QBrush& brush) {
1915     m_initializing = true;
1916     ui.cbSymbolFillingStyle->setCurrentIndex((int) brush.style());
1917     ui.kcbSymbolFillingColor->setColor(brush.color());
1918     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, brush.color());
1919     m_initializing = false;
1920 }
1921 void XYCurveDock::curveSymbolsPenChanged(const QPen& pen) {
1922     m_initializing = true;
1923     ui.cbSymbolBorderStyle->setCurrentIndex( (int) pen.style());
1924     ui.kcbSymbolBorderColor->setColor( pen.color());
1925     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, pen.color());
1926     ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point));
1927     m_initializing = false;
1928 }
1929 
1930 //Values-Tab
1931 void XYCurveDock::curveValuesTypeChanged(XYCurve::ValuesType type) {
1932     m_initializing = true;
1933     ui.cbValuesType->setCurrentIndex((int) type);
1934     m_initializing = false;
1935 }
1936 void XYCurveDock::curveValuesColumnChanged(const AbstractColumn* column) {
1937     m_initializing = true;
1938     this->setModelIndexFromAspect(cbValuesColumn, column);
1939     m_initializing = false;
1940 }
1941 void XYCurveDock::curveValuesPositionChanged(XYCurve::ValuesPosition position) {
1942     m_initializing = true;
1943     ui.cbValuesPosition->setCurrentIndex((int) position);
1944     m_initializing = false;
1945 }
1946 void XYCurveDock::curveValuesDistanceChanged(qreal distance) {
1947     m_initializing = true;
1948     ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(distance, Worksheet::Unit::Point) );
1949     m_initializing = false;
1950 }
1951 void XYCurveDock::curveValuesRotationAngleChanged(qreal angle) {
1952     m_initializing = true;
1953     ui.sbValuesRotation->setValue(angle);
1954     m_initializing = false;
1955 }
1956 void XYCurveDock::curveValuesNumericFormatChanged(char format) {
1957     m_initializing = true;
1958     ui.cbValuesNumericFormat->setCurrentIndex(ui.cbValuesNumericFormat->findData(format));
1959     m_initializing = false;
1960 }
1961 void XYCurveDock::curveValuesPrecisionChanged(int precision) {
1962     m_initializing = true;
1963     ui.sbValuesPrecision->setValue(precision);
1964     m_initializing = false;
1965 }
1966 void XYCurveDock::curveValuesDateTimeFormatChanged(const QString& format) {
1967     m_initializing = true;
1968     ui.cbValuesDateTimeFormat->setCurrentText(format);
1969     m_initializing = false;
1970 }
1971 void XYCurveDock::curveValuesOpacityChanged(qreal opacity) {
1972     m_initializing = true;
1973     ui.sbValuesOpacity->setValue( round(opacity*100.0) );
1974     m_initializing = false;
1975 }
1976 void XYCurveDock::curveValuesPrefixChanged(const QString& prefix) {
1977     m_initializing = true;
1978     ui.leValuesPrefix->setText(prefix);
1979     m_initializing = false;
1980 }
1981 void XYCurveDock::curveValuesSuffixChanged(const QString& suffix) {
1982     m_initializing = true;
1983     ui.leValuesSuffix->setText(suffix);
1984     m_initializing = false;
1985 }
1986 void XYCurveDock::curveValuesFontChanged(QFont font) {
1987     m_initializing = true;
1988     font.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)) );
1989     ui.kfrValuesFont->setFont(font);
1990     m_initializing = false;
1991 }
1992 void XYCurveDock::curveValuesColorChanged(QColor color) {
1993     m_initializing = true;
1994     ui.kcbValuesColor->setColor(color);
1995     m_initializing = false;
1996 }
1997 
1998 //Filling
1999 void XYCurveDock::curveFillingPositionChanged(XYCurve::FillingPosition position) {
2000     m_initializing = true;
2001     ui.cbFillingPosition->setCurrentIndex((int)position);
2002     m_initializing = false;
2003 }
2004 void XYCurveDock::curveFillingTypeChanged(PlotArea::BackgroundType type) {
2005     m_initializing = true;
2006     ui.cbFillingType->setCurrentIndex(static_cast<int>(type));
2007     m_initializing = false;
2008 }
2009 void XYCurveDock::curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle style) {
2010     m_initializing = true;
2011     ui.cbFillingColorStyle->setCurrentIndex(static_cast<int>(style));
2012     m_initializing = false;
2013 }
2014 void XYCurveDock::curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle style) {
2015     m_initializing = true;
2016     ui.cbFillingImageStyle->setCurrentIndex(static_cast<int>(style));
2017     m_initializing = false;
2018 }
2019 void XYCurveDock::curveFillingBrushStyleChanged(Qt::BrushStyle style) {
2020     m_initializing = true;
2021     ui.cbFillingBrushStyle->setCurrentIndex(style);
2022     m_initializing = false;
2023 }
2024 void XYCurveDock::curveFillingFirstColorChanged(QColor& color) {
2025     m_initializing = true;
2026     ui.kcbFillingFirstColor->setColor(color);
2027     GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, color);
2028     m_initializing = false;
2029 }
2030 void XYCurveDock::curveFillingSecondColorChanged(QColor& color) {
2031     m_initializing = true;
2032     ui.kcbFillingSecondColor->setColor(color);
2033     m_initializing = false;
2034 }
2035 void XYCurveDock::curveFillingFileNameChanged(QString& filename) {
2036     m_initializing = true;
2037     ui.leFillingFileName->setText(filename);
2038     m_initializing = false;
2039 }
2040 void XYCurveDock::curveFillingOpacityChanged(float opacity) {
2041     m_initializing = true;
2042     ui.sbFillingOpacity->setValue( round(opacity*100.0) );
2043     m_initializing = false;
2044 }
2045 
2046 //"Error bars"-Tab
2047 void XYCurveDock::curveXErrorTypeChanged(XYCurve::ErrorType type) {
2048     m_initializing = true;
2049     ui.cbXErrorType->setCurrentIndex((int) type);
2050     m_initializing = false;
2051 }
2052 void XYCurveDock::curveXErrorPlusColumnChanged(const AbstractColumn* column) {
2053     m_initializing = true;
2054     this->setModelIndexFromAspect(cbXErrorPlusColumn, column);
2055     m_initializing = false;
2056 }
2057 void XYCurveDock::curveXErrorMinusColumnChanged(const AbstractColumn* column) {
2058     m_initializing = true;
2059     this->setModelIndexFromAspect(cbXErrorMinusColumn, column);
2060     m_initializing = false;
2061 }
2062 void XYCurveDock::curveYErrorTypeChanged(XYCurve::ErrorType type) {
2063     m_initializing = true;
2064     ui.cbYErrorType->setCurrentIndex((int) type);
2065     m_initializing = false;
2066 }
2067 void XYCurveDock::curveYErrorPlusColumnChanged(const AbstractColumn* column) {
2068     m_initializing = true;
2069     this->setModelIndexFromAspect(cbYErrorPlusColumn, column);
2070     m_initializing = false;
2071 }
2072 
2073 void XYCurveDock::curveYErrorMinusColumnChanged(const AbstractColumn* column) {
2074     m_initializing = true;
2075     this->setModelIndexFromAspect(cbYErrorMinusColumn, column);
2076     m_initializing = false;
2077 }
2078 void XYCurveDock::curveErrorBarsCapSizeChanged(qreal size) {
2079     m_initializing = true;
2080     ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Unit::Point) );
2081     m_initializing = false;
2082 }
2083 void XYCurveDock::curveErrorBarsTypeChanged(XYCurve::ErrorBarsType type) {
2084     m_initializing = true;
2085     ui.cbErrorBarsType->setCurrentIndex(static_cast<int>(type));
2086     m_initializing = false;
2087 }
2088 void XYCurveDock::curveErrorBarsPenChanged(const QPen& pen) {
2089     m_initializing = true;
2090     ui.cbErrorBarsStyle->setCurrentIndex( (int) pen.style());
2091     ui.kcbErrorBarsColor->setColor( pen.color());
2092     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, pen.color());
2093     ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point) );
2094     m_initializing = false;
2095 }
2096 void XYCurveDock::curveErrorBarsOpacityChanged(qreal opacity) {
2097     m_initializing = true;
2098     ui.sbErrorBarsOpacity->setValue( round(opacity*100.0) );
2099     m_initializing = false;
2100 }
2101 
2102 //*************************************************************
2103 //************************* Settings **************************
2104 //*************************************************************
2105 void XYCurveDock::load() {
2106     //General
2107     //This data is read in XYCurveDock::setCurves().
2108 
2109     //Line
2110     ui.cbLineType->setCurrentIndex( (int) m_curve->lineType() );
2111     ui.chkLineSkipGaps->setChecked( m_curve->lineSkipGaps() );
2112     ui.sbLineInterpolationPointsCount->setValue( m_curve->lineInterpolationPointsCount() );
2113     ui.cbLineStyle->setCurrentIndex( (int) m_curve->linePen().style() );
2114     ui.kcbLineColor->setColor( m_curve->linePen().color() );
2115     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->linePen().widthF(), Worksheet::Unit::Point) );
2116     ui.sbLineOpacity->setValue( round(m_curve->lineOpacity()*100.0) );
2117 
2118     //Drop lines
2119     ui.cbDropLineType->setCurrentIndex( (int) m_curve->dropLineType() );
2120     ui.cbDropLineStyle->setCurrentIndex( (int) m_curve->dropLinePen().style() );
2121     ui.kcbDropLineColor->setColor( m_curve->dropLinePen().color() );
2122     ui.sbDropLineWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->dropLinePen().widthF(), Worksheet::Unit::Point) );
2123     ui.sbDropLineOpacity->setValue( round(m_curve->dropLineOpacity()*100.0) );
2124 
2125     //Symbols
2126     ui.cbSymbolStyle->setCurrentIndex( (int)m_curve->symbolsStyle() );
2127     ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(m_curve->symbolsSize(), Worksheet::Unit::Point) );
2128     ui.sbSymbolRotation->setValue( m_curve->symbolsRotationAngle() );
2129     ui.sbSymbolOpacity->setValue( round(m_curve->symbolsOpacity()*100.0) );
2130     ui.cbSymbolFillingStyle->setCurrentIndex( (int) m_curve->symbolsBrush().style() );
2131     ui.kcbSymbolFillingColor->setColor(  m_curve->symbolsBrush().color() );
2132     ui.cbSymbolBorderStyle->setCurrentIndex( (int) m_curve->symbolsPen().style() );
2133     ui.kcbSymbolBorderColor->setColor( m_curve->symbolsPen().color() );
2134     ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->symbolsPen().widthF(), Worksheet::Unit::Point) );
2135 
2136     //Values
2137     ui.cbValuesType->setCurrentIndex( (int) m_curve->valuesType() );
2138     ui.cbValuesPosition->setCurrentIndex( (int) m_curve->valuesPosition() );
2139     ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(m_curve->valuesDistance(), Worksheet::Unit::Point) );
2140     ui.sbValuesRotation->setValue( m_curve->valuesRotationAngle() );
2141     ui.sbValuesOpacity->setValue( round(m_curve->valuesOpacity()*100.0) );
2142     ui.sbValuesPrecision->setValue(m_curve->valuesPrecision());
2143     ui.cbValuesNumericFormat->setCurrentIndex(ui.cbValuesNumericFormat->findData(m_curve->valuesNumericFormat()));
2144     ui.cbValuesDateTimeFormat->setCurrentText(m_curve->valuesDateTimeFormat());
2145     ui.leValuesPrefix->setText( m_curve->valuesPrefix() );
2146     ui.leValuesSuffix->setText( m_curve->valuesSuffix() );
2147     QFont valuesFont = m_curve->valuesFont();
2148     valuesFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(valuesFont.pixelSize(), Worksheet::Unit::Point)) );
2149     ui.kfrValuesFont->setFont(valuesFont);
2150     ui.kcbValuesColor->setColor( m_curve->valuesColor() );
2151     this->updateValuesWidgets();
2152 
2153     //Filling
2154     ui.cbFillingPosition->setCurrentIndex( (int) m_curve->fillingPosition() );
2155     ui.cbFillingType->setCurrentIndex( (int)m_curve->fillingType() );
2156     ui.cbFillingColorStyle->setCurrentIndex( (int) m_curve->fillingColorStyle() );
2157     ui.cbFillingImageStyle->setCurrentIndex( (int) m_curve->fillingImageStyle() );
2158     ui.cbFillingBrushStyle->setCurrentIndex( (int) m_curve->fillingBrushStyle() );
2159     ui.leFillingFileName->setText( m_curve->fillingFileName() );
2160     ui.kcbFillingFirstColor->setColor( m_curve->fillingFirstColor() );
2161     ui.kcbFillingSecondColor->setColor( m_curve->fillingSecondColor() );
2162     ui.sbFillingOpacity->setValue( round(m_curve->fillingOpacity()*100.0) );
2163 
2164     //Error bars
2165     ui.cbXErrorType->setCurrentIndex( (int) m_curve->xErrorType() );
2166     ui.cbYErrorType->setCurrentIndex( (int) m_curve->yErrorType() );
2167     ui.cbErrorBarsType->setCurrentIndex( (int) m_curve->errorBarsType() );
2168     ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(m_curve->errorBarsCapSize(), Worksheet::Unit::Point) );
2169     ui.cbErrorBarsStyle->setCurrentIndex( (int) m_curve->errorBarsPen().style() );
2170     ui.kcbErrorBarsColor->setColor( m_curve->errorBarsPen().color() );
2171     ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->errorBarsPen().widthF(), Worksheet::Unit::Point) );
2172     ui.sbErrorBarsOpacity->setValue( round(m_curve->errorBarsOpacity()*100.0) );
2173 
2174     m_initializing = true;
2175     GuiTools::updatePenStyles(ui.cbLineStyle, ui.kcbLineColor->color());
2176     GuiTools::updatePenStyles(ui.cbDropLineStyle, ui.kcbDropLineColor->color());
2177     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, ui.kcbSymbolFillingColor->color());
2178     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, ui.kcbSymbolBorderColor->color());
2179     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, ui.kcbErrorBarsColor->color());
2180     m_initializing = false;
2181 }
2182 
2183 void XYCurveDock::loadConfigFromTemplate(KConfig& config) {
2184     //extract the name of the template from the file name
2185     QString name;
2186     int index = config.name().lastIndexOf(QLatin1String("/"));
2187     if (index != -1)
2188         name = config.name().right(config.name().size() - index - 1);
2189     else
2190         name = config.name();
2191 
2192     int size = m_curvesList.size();
2193     if (size > 1)
2194         m_curve->beginMacro(i18n("%1 xy-curves: template \"%2\" loaded", size, name));
2195     else
2196         m_curve->beginMacro(i18n("%1: template \"%2\" loaded", m_curve->name(), name));
2197 
2198     this->loadConfig(config);
2199 
2200     m_curve->endMacro();
2201 }
2202 
2203 void XYCurveDock::loadConfig(KConfig& config) {
2204     KConfigGroup group = config.group( "XYCurve" );
2205 
2206     //General
2207     //we don't load/save the settings in the general-tab, since they are not style related.
2208     //It doesn't make sense to load/save them in the template.
2209     //This data is read in XYCurveDock::setCurves().
2210 
2211     //Line
2212     ui.cbLineType->setCurrentIndex( group.readEntry("LineType", (int) m_curve->lineType()) );
2213     ui.chkLineSkipGaps->setChecked( group.readEntry("LineSkipGaps", m_curve->lineSkipGaps()) );
2214     ui.sbLineInterpolationPointsCount->setValue( group.readEntry("LineInterpolationPointsCount", m_curve->lineInterpolationPointsCount()) );
2215     ui.cbLineStyle->setCurrentIndex( group.readEntry("LineStyle", (int) m_curve->linePen().style()) );
2216     ui.kcbLineColor->setColor( group.readEntry("LineColor", m_curve->linePen().color()) );
2217     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("LineWidth", m_curve->linePen().widthF()), Worksheet::Unit::Point) );
2218     ui.sbLineOpacity->setValue( round(group.readEntry("LineOpacity", m_curve->lineOpacity())*100.0) );
2219 
2220     //Drop lines
2221     ui.cbDropLineType->setCurrentIndex( group.readEntry("DropLineType", (int) m_curve->dropLineType()) );
2222     ui.cbDropLineStyle->setCurrentIndex( group.readEntry("DropLineStyle", (int) m_curve->dropLinePen().style()) );
2223     ui.kcbDropLineColor->setColor( group.readEntry("DropLineColor", m_curve->dropLinePen().color()) );
2224     ui.sbDropLineWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("DropLineWidth", m_curve->dropLinePen().widthF()), Worksheet::Unit::Point) );
2225     ui.sbDropLineOpacity->setValue( round(group.readEntry("DropLineOpacity", m_curve->dropLineOpacity())*100.0) );
2226 
2227     //Symbols
2228     ui.cbSymbolStyle->setCurrentIndex( group.readEntry("SymbolStyle", (int)m_curve->symbolsStyle()) );
2229     ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("SymbolSize", m_curve->symbolsSize()), Worksheet::Unit::Point) );
2230     ui.sbSymbolRotation->setValue( group.readEntry("SymbolRotation", m_curve->symbolsRotationAngle()) );
2231     ui.sbSymbolOpacity->setValue( round(group.readEntry("SymbolOpacity", m_curve->symbolsOpacity())*100.0) );
2232     ui.cbSymbolFillingStyle->setCurrentIndex( group.readEntry("SymbolFillingStyle", (int) m_curve->symbolsBrush().style()) );
2233     ui.kcbSymbolFillingColor->setColor(  group.readEntry("SymbolFillingColor", m_curve->symbolsBrush().color()) );
2234     ui.cbSymbolBorderStyle->setCurrentIndex( group.readEntry("SymbolBorderStyle", (int) m_curve->symbolsPen().style()) );
2235     ui.kcbSymbolBorderColor->setColor( group.readEntry("SymbolBorderColor", m_curve->symbolsPen().color()) );
2236     ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("SymbolBorderWidth",m_curve->symbolsPen().widthF()), Worksheet::Unit::Point) );
2237 
2238     //Values
2239     ui.cbValuesType->setCurrentIndex( group.readEntry("ValuesType", (int) m_curve->valuesType()) );
2240     ui.cbValuesPosition->setCurrentIndex( group.readEntry("ValuesPosition", (int) m_curve->valuesPosition()) );
2241     ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ValuesDistance", m_curve->valuesDistance()), Worksheet::Unit::Point) );
2242     ui.sbValuesRotation->setValue( group.readEntry("ValuesRotation", m_curve->valuesRotationAngle()) );
2243     ui.sbValuesOpacity->setValue( round(group.readEntry("ValuesOpacity",m_curve->valuesOpacity())*100.0) );
2244     ui.leValuesPrefix->setText( group.readEntry("ValuesPrefix", m_curve->valuesPrefix()) );
2245     ui.leValuesSuffix->setText( group.readEntry("ValuesSuffix", m_curve->valuesSuffix()) );
2246     QFont valuesFont = m_curve->valuesFont();
2247     valuesFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(valuesFont.pixelSize(), Worksheet::Unit::Point)) );
2248     ui.kfrValuesFont->setFont( group.readEntry("ValuesFont", valuesFont) );
2249     ui.kcbValuesColor->setColor( group.readEntry("ValuesColor", m_curve->valuesColor()) );
2250 
2251     //Filling
2252     ui.cbFillingPosition->setCurrentIndex( group.readEntry("FillingPosition", (int) m_curve->fillingPosition()) );
2253     ui.cbFillingType->setCurrentIndex( group.readEntry("FillingType", (int) m_curve->fillingType()) );
2254     ui.cbFillingColorStyle->setCurrentIndex( group.readEntry("FillingColorStyle", (int) m_curve->fillingColorStyle()) );
2255     ui.cbFillingImageStyle->setCurrentIndex( group.readEntry("FillingImageStyle", (int) m_curve->fillingImageStyle()) );
2256     ui.cbFillingBrushStyle->setCurrentIndex( group.readEntry("FillingBrushStyle", (int) m_curve->fillingBrushStyle()) );
2257     ui.leFillingFileName->setText( group.readEntry("FillingFileName", m_curve->fillingFileName()) );
2258     ui.kcbFillingFirstColor->setColor( group.readEntry("FillingFirstColor", m_curve->fillingFirstColor()) );
2259     ui.kcbFillingSecondColor->setColor( group.readEntry("FillingSecondColor", m_curve->fillingSecondColor()) );
2260     ui.sbFillingOpacity->setValue( round(group.readEntry("FillingOpacity", m_curve->fillingOpacity())*100.0) );
2261 
2262     //Error bars
2263     ui.cbXErrorType->setCurrentIndex( group.readEntry("XErrorType", (int) m_curve->xErrorType()) );
2264     ui.cbYErrorType->setCurrentIndex( group.readEntry("YErrorType", (int) m_curve->yErrorType()) );
2265     ui.cbErrorBarsType->setCurrentIndex( group.readEntry("ErrorBarsType", (int) m_curve->errorBarsType()) );
2266     ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ErrorBarsCapSize", m_curve->errorBarsCapSize()), Worksheet::Unit::Point) );
2267     ui.cbErrorBarsStyle->setCurrentIndex( group.readEntry("ErrorBarsStyle", (int) m_curve->errorBarsPen().style()) );
2268     ui.kcbErrorBarsColor->setColor( group.readEntry("ErrorBarsColor", m_curve->errorBarsPen().color()) );
2269     ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ErrorBarsWidth", m_curve->errorBarsPen().widthF()), Worksheet::Unit::Point) );
2270     ui.sbErrorBarsOpacity->setValue( round(group.readEntry("ErrorBarsOpacity", m_curve->errorBarsOpacity())*100.0) );
2271 
2272     m_initializing = true;
2273     GuiTools::updatePenStyles(ui.cbLineStyle, ui.kcbLineColor->color());
2274     GuiTools::updatePenStyles(ui.cbDropLineStyle, ui.kcbDropLineColor->color());
2275     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, ui.kcbSymbolFillingColor->color());
2276     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, ui.kcbSymbolBorderColor->color());
2277     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, ui.kcbErrorBarsColor->color());
2278     GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, ui.kcbFillingFirstColor->color());
2279     m_initializing = false;
2280 }
2281 
2282 void XYCurveDock::saveConfigAsTemplate(KConfig& config) {
2283     KConfigGroup group = config.group( "XYCurve" );
2284 
2285     //General
2286     //we don't load/save the settings in the general-tab, since they are not style related.
2287     //It doesn't make sense to load/save them in the template.
2288 
2289     group.writeEntry("LineType", ui.cbLineType->currentIndex());
2290     group.writeEntry("LineSkipGaps", ui.chkLineSkipGaps->isChecked());
2291     group.writeEntry("LineInterpolationPointsCount", ui.sbLineInterpolationPointsCount->value() );
2292     group.writeEntry("LineStyle", ui.cbLineStyle->currentIndex());
2293     group.writeEntry("LineColor", ui.kcbLineColor->color());
2294     group.writeEntry("LineWidth", Worksheet::convertToSceneUnits(ui.sbLineWidth->value(), Worksheet::Unit::Point) );
2295     group.writeEntry("LineOpacity", ui.sbLineOpacity->value()/100.0);
2296 
2297     //Drop Line
2298     group.writeEntry("DropLineType", ui.cbDropLineType->currentIndex());
2299     group.writeEntry("DropLineStyle", ui.cbDropLineStyle->currentIndex());
2300     group.writeEntry("DropLineColor", ui.kcbDropLineColor->color());
2301     group.writeEntry("DropLineWidth", Worksheet::convertToSceneUnits(ui.sbDropLineWidth->value(), Worksheet::Unit::Point) );
2302     group.writeEntry("DropLineOpacity", ui.sbDropLineOpacity->value()/100.0);
2303 
2304     //Symbol
2305     group.writeEntry("SymbolStyle", ui.cbSymbolStyle->currentIndex());
2306     group.writeEntry("SymbolSize", Worksheet::convertToSceneUnits(ui.sbSymbolSize->value(),Worksheet::Unit::Point));
2307     group.writeEntry("SymbolRotation", ui.sbSymbolRotation->value());
2308     group.writeEntry("SymbolOpacity", ui.sbSymbolOpacity->value()/100.0);
2309     group.writeEntry("SymbolFillingStyle", ui.cbSymbolFillingStyle->currentIndex());
2310     group.writeEntry("SymbolFillingColor", ui.kcbSymbolFillingColor->color());
2311     group.writeEntry("SymbolBorderStyle", ui.cbSymbolBorderStyle->currentIndex());
2312     group.writeEntry("SymbolBorderColor", ui.kcbSymbolBorderColor->color());
2313     group.writeEntry("SymbolBorderWidth", Worksheet::convertToSceneUnits(ui.sbSymbolBorderWidth->value(), Worksheet::Unit::Point));
2314 
2315     //Values
2316     group.writeEntry("ValuesType", ui.cbValuesType->currentIndex());
2317     group.writeEntry("ValuesPosition", ui.cbValuesPosition->currentIndex());
2318     group.writeEntry("ValuesDistance", Worksheet::convertToSceneUnits(ui.sbValuesDistance->value(), Worksheet::Unit::Point));
2319     group.writeEntry("ValuesRotation", ui.sbValuesRotation->value());
2320     group.writeEntry("ValuesOpacity", ui.sbValuesOpacity->value()/100.0);
2321     group.writeEntry("valuesNumericFormat", ui.cbValuesNumericFormat->currentText());
2322     group.writeEntry("valuesPrecision", ui.sbValuesPrecision->value());
2323     group.writeEntry("valuesDateTimeFormat", ui.cbValuesDateTimeFormat->currentText());
2324     group.writeEntry("ValuesPrefix", ui.leValuesPrefix->text());
2325     group.writeEntry("ValuesSuffix", ui.leValuesSuffix->text());
2326     group.writeEntry("ValuesFont", ui.kfrValuesFont->font());
2327     group.writeEntry("ValuesColor", ui.kcbValuesColor->color());
2328 
2329     //Filling
2330     group.writeEntry("FillingPosition", ui.cbFillingPosition->currentIndex());
2331     group.writeEntry("FillingType", ui.cbFillingType->currentIndex());
2332     group.writeEntry("FillingColorStyle", ui.cbFillingColorStyle->currentIndex());
2333     group.writeEntry("FillingImageStyle", ui.cbFillingImageStyle->currentIndex());
2334     group.writeEntry("FillingBrushStyle", ui.cbFillingBrushStyle->currentIndex());
2335     group.writeEntry("FillingFileName", ui.leFillingFileName->text());
2336     group.writeEntry("FillingFirstColor", ui.kcbFillingFirstColor->color());
2337     group.writeEntry("FillingSecondColor", ui.kcbFillingSecondColor->color());
2338     group.writeEntry("FillingOpacity", ui.sbFillingOpacity->value()/100.0);
2339 
2340     //Error bars
2341     group.writeEntry("XErrorType", ui.cbXErrorType->currentIndex());
2342     group.writeEntry("YErrorType", ui.cbYErrorType->currentIndex());
2343     group.writeEntry("ErrorBarsType", ui.cbErrorBarsType->currentIndex());
2344     group.writeEntry("ErrorBarsCapSize", Worksheet::convertToSceneUnits(ui.sbErrorBarsCapSize->value(), Worksheet::Unit::Point) );
2345     group.writeEntry("ErrorBarsStyle", ui.cbErrorBarsStyle->currentIndex());
2346     group.writeEntry("ErrorBarsColor", ui.kcbErrorBarsColor->color());
2347     group.writeEntry("ErrorBarsWidth", Worksheet::convertToSceneUnits(ui.sbErrorBarsWidth->value(), Worksheet::Unit::Point) );
2348     group.writeEntry("ErrorBarsOpacity", ui.sbErrorBarsOpacity->value()/100.0);
2349 
2350     config.sync();
2351 }