"Fossies" - the Fresh Open Source Software Archive

Member "labplot-2.8.2/src/kdefrontend/dockwidgets/XYCurveDock.cpp" (24 Feb 2021, 89958 Bytes) of package /linux/privat/labplot-2.8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "XYCurveDock.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8.1_vs_2.8.2.

    1 /***************************************************************************
    2     File                 : XYCurveDock.cpp
    3     Project              : LabPlot
    4     Description          : widget for XYCurve properties
    5     --------------------------------------------------------------------
    6     Copyright            : (C) 2010-2020 Alexander Semke (alexander.semke@web.de)
    7     Copyright            : (C) 2012-2017 Stefan Gerlach (stefan.gerlach@uni-konstanz.de)
    8 
    9  ***************************************************************************/
   10 
   11 /***************************************************************************
   12  *                                                                         *
   13  *  This program is free software; you can redistribute it and/or modify   *
   14  *  it under the terms of the GNU General Public License as published by   *
   15  *  the Free Software Foundation; either version 2 of the License, or      *
   16  *  (at your option) any later version.                                    *
   17  *                                                                         *
   18  *  This program is distributed in the hope that it will be useful,        *
   19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
   20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
   21  *  GNU General Public License for more details.                           *
   22  *                                                                         *
   23  *   You should have received a copy of the GNU General Public License     *
   24  *   along with this program; if not, write to the Free Software           *
   25  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
   26  *   Boston, MA  02110-1301  USA                                           *
   27  *                                                                         *
   28  ***************************************************************************/
   29 
   30 #include "XYCurveDock.h"
   31 #include "backend/worksheet/plots/cartesian/XYCurve.h"
   32 #include "backend/worksheet/Worksheet.h"
   33 #include "backend/core/AspectTreeModel.h"
   34 #include "backend/core/column/Column.h"
   35 #include "backend/core/Project.h"
   36 #include "backend/core/datatypes/Double2StringFilter.h"
   37 #include "backend/core/datatypes/DateTime2StringFilter.h"
   38 #include "commonfrontend/widgets/TreeViewComboBox.h"
   39 #include "kdefrontend/TemplateHandler.h"
   40 #include "kdefrontend/GuiTools.h"
   41 
   42 #include <QCompleter>
   43 #include <QDir>
   44 #include <QDirModel>
   45 #include <QFileDialog>
   46 #include <QImageReader>
   47 #include <QPainter>
   48 
   49 #include <KConfig>
   50 #include <KLocalizedString>
   51 
   52 /*!
   53   \class XYCurveDock
   54   \brief  Provides a widget for editing the properties of the XYCurves (2D-curves) currently selected in the project explorer.
   55 
   56   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.
   57   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.
   58 
   59   \ingroup kdefrontend
   60 */
   61 
   62 XYCurveDock::XYCurveDock(QWidget* parent) : BaseDock(parent) {
   63     ui.setupUi(this);
   64 
   65     //Tab "Values"
   66     auto* gridLayout = qobject_cast<QGridLayout*>(ui.tabValues->layout());
   67     cbValuesColumn = new TreeViewComboBox(ui.tabValues);
   68     gridLayout->addWidget(cbValuesColumn, 2, 2, 1, 1);
   69 
   70     //add formats for numeric values
   71     ui.cbValuesNumericFormat->addItem(i18n("Decimal"), QVariant('f'));
   72     ui.cbValuesNumericFormat->addItem(i18n("Scientific (e)"), QVariant('e'));
   73     ui.cbValuesNumericFormat->addItem(i18n("Scientific (E)"), QVariant('E'));
   74     ui.cbValuesNumericFormat->addItem(i18n("Automatic (e)"), QVariant('g'));
   75     ui.cbValuesNumericFormat->addItem(i18n("Automatic (E)"), QVariant('G'));
   76 
   77     //add format for date, time and datetime values
   78     for (const auto& s : AbstractColumn::dateTimeFormats())
   79         ui.cbValuesDateTimeFormat->addItem(s, QVariant(s));
   80 
   81     ui.cbValuesDateTimeFormat->setEditable(true);
   82 
   83     //Tab "Filling"
   84     ui.cbFillingColorStyle->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
   85     ui.bFillingOpen->setIcon( QIcon::fromTheme("document-open") );
   86 
   87     ui.leFillingFileName->setCompleter(new QCompleter(new QDirModel, this));
   88 
   89     //Tab "Error bars"
   90     gridLayout = qobject_cast<QGridLayout*>(ui.tabErrorBars->layout());
   91 
   92     cbXErrorPlusColumn = new TreeViewComboBox(ui.tabErrorBars);
   93     gridLayout->addWidget(cbXErrorPlusColumn, 2, 2, 1, 1);
   94 
   95     cbXErrorMinusColumn = new TreeViewComboBox(ui.tabErrorBars);
   96     gridLayout->addWidget(cbXErrorMinusColumn, 3, 2, 1, 1);
   97 
   98     cbYErrorPlusColumn = new TreeViewComboBox(ui.tabErrorBars);
   99     gridLayout->addWidget(cbYErrorPlusColumn, 7, 2, 1, 1);
  100 
  101     cbYErrorMinusColumn = new TreeViewComboBox(ui.tabErrorBars);
  102     gridLayout->addWidget(cbYErrorMinusColumn, 8, 2, 1, 1);
  103 
  104     //adjust layouts in the tabs
  105     for (int i = 0; i < ui.tabWidget->count(); ++i) {
  106         auto* layout = dynamic_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout());
  107         if (!layout)
  108             continue;
  109 
  110         layout->setContentsMargins(2,2,2,2);
  111         layout->setHorizontalSpacing(2);
  112         layout->setVerticalSpacing(2);
  113     }
  114 
  115     XYCurveDock::updateLocale();
  116 
  117     //Slots
  118 
  119     //Lines
  120     connect( ui.cbLineType, SIGNAL(currentIndexChanged(int)), this, SLOT(lineTypeChanged(int)) );
  121     connect( ui.sbLineInterpolationPointsCount, SIGNAL(valueChanged(int)), this, SLOT(lineInterpolationPointsCountChanged(int)) );
  122     connect( ui.chkLineSkipGaps, SIGNAL(clicked(bool)), this, SLOT(lineSkipGapsChanged(bool)) );
  123     connect( ui.chkLineIncreasingXOnly, &QCheckBox::clicked, this, &XYCurveDock::lineIncreasingXOnlyChanged );
  124     connect( ui.cbLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(lineStyleChanged(int)) );
  125     connect( ui.kcbLineColor, SIGNAL(changed(QColor)), this, SLOT(lineColorChanged(QColor)) );
  126     connect( ui.sbLineWidth, SIGNAL(valueChanged(double)), this, SLOT(lineWidthChanged(double)) );
  127     connect( ui.sbLineOpacity, SIGNAL(valueChanged(int)), this, SLOT(lineOpacityChanged(int)) );
  128 
  129     connect( ui.cbDropLineType, SIGNAL(currentIndexChanged(int)), this, SLOT(dropLineTypeChanged(int)) );
  130     connect( ui.cbDropLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(dropLineStyleChanged(int)) );
  131     connect( ui.kcbDropLineColor, SIGNAL(changed(QColor)), this, SLOT(dropLineColorChanged(QColor)) );
  132     connect( ui.sbDropLineWidth, SIGNAL(valueChanged(double)), this, SLOT(dropLineWidthChanged(double)) );
  133     connect( ui.sbDropLineOpacity, SIGNAL(valueChanged(int)), this, SLOT(dropLineOpacityChanged(int)) );
  134 
  135     //Symbol
  136     connect( ui.cbSymbolStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsStyleChanged(int)) );
  137     connect( ui.sbSymbolSize, SIGNAL(valueChanged(double)), this, SLOT(symbolsSizeChanged(double)) );
  138     connect( ui.sbSymbolRotation, SIGNAL(valueChanged(int)), this, SLOT(symbolsRotationChanged(int)) );
  139     connect( ui.sbSymbolOpacity, SIGNAL(valueChanged(int)), this, SLOT(symbolsOpacityChanged(int)) );
  140 
  141     connect( ui.cbSymbolFillingStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsFillingStyleChanged(int)) );
  142     connect( ui.kcbSymbolFillingColor, SIGNAL(changed(QColor)), this, SLOT(symbolsFillingColorChanged(QColor)) );
  143 
  144     connect( ui.cbSymbolBorderStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsBorderStyleChanged(int)) );
  145     connect( ui.kcbSymbolBorderColor, SIGNAL(changed(QColor)), this, SLOT(symbolsBorderColorChanged(QColor)) );
  146     connect( ui.sbSymbolBorderWidth, SIGNAL(valueChanged(double)), this, SLOT(symbolsBorderWidthChanged(double)) );
  147 
  148     //Values
  149     connect( ui.cbValuesType, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesTypeChanged(int)) );
  150     connect( cbValuesColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(valuesColumnChanged(QModelIndex)) );
  151     connect( ui.cbValuesPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesPositionChanged(int)) );
  152     connect( ui.sbValuesDistance, SIGNAL(valueChanged(double)), this, SLOT(valuesDistanceChanged(double)) );
  153     connect( ui.sbValuesRotation, SIGNAL(valueChanged(int)), this, SLOT(valuesRotationChanged(int)) );
  154     connect( ui.sbValuesOpacity, SIGNAL(valueChanged(int)), this, SLOT(valuesOpacityChanged(int)) );
  155     connect(ui.cbValuesNumericFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYCurveDock::valuesNumericFormatChanged);
  156     connect(ui.sbValuesPrecision, QOverload<int>::of(&QSpinBox::valueChanged), this, &XYCurveDock::valuesPrecisionChanged);
  157     connect(ui.cbValuesDateTimeFormat, &QComboBox::currentTextChanged, this, &XYCurveDock::valuesDateTimeFormatChanged);
  158     connect(ui.leValuesPrefix, &QLineEdit::textChanged, this, &XYCurveDock::valuesPrefixChanged);
  159     connect(ui.leValuesSuffix, &QLineEdit::textChanged, this, &XYCurveDock::valuesSuffixChanged);
  160     connect( ui.kfrValuesFont, SIGNAL(fontSelected(QFont)), this, SLOT(valuesFontChanged(QFont)) );
  161     connect( ui.kcbValuesColor, SIGNAL(changed(QColor)), this, SLOT(valuesColorChanged(QColor)) );
  162 
  163     //Filling
  164     connect( ui.cbFillingPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingPositionChanged(int)) );
  165     connect( ui.cbFillingType, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingTypeChanged(int)) );
  166     connect( ui.cbFillingColorStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingColorStyleChanged(int)) );
  167     connect( ui.cbFillingImageStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingImageStyleChanged(int)) );
  168     connect( ui.cbFillingBrushStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingBrushStyleChanged(int)) );
  169     connect(ui.bFillingOpen, SIGNAL(clicked(bool)), this, SLOT(selectFile()));
  170     connect(ui.leFillingFileName, &QLineEdit::textChanged, this, &XYCurveDock::fileNameChanged);
  171     connect( ui.leFillingFileName, SIGNAL(textChanged(QString)), this, SLOT(fileNameChanged()) );
  172     connect( ui.kcbFillingFirstColor, SIGNAL(changed(QColor)), this, SLOT(fillingFirstColorChanged(QColor)) );
  173     connect( ui.kcbFillingSecondColor, SIGNAL(changed(QColor)), this, SLOT(fillingSecondColorChanged(QColor)) );
  174     connect( ui.sbFillingOpacity, SIGNAL(valueChanged(int)), this, SLOT(fillingOpacityChanged(int)) );
  175 
  176     //Error bars
  177     connect( ui.cbXErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(xErrorTypeChanged(int)) );
  178     connect( cbXErrorPlusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xErrorPlusColumnChanged(QModelIndex)) );
  179     connect( cbXErrorMinusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xErrorMinusColumnChanged(QModelIndex)) );
  180     connect( ui.cbYErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(yErrorTypeChanged(int)) );
  181     connect( cbYErrorPlusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yErrorPlusColumnChanged(QModelIndex)) );
  182     connect( cbYErrorMinusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yErrorMinusColumnChanged(QModelIndex)) );
  183     connect( ui.cbErrorBarsType, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsTypeChanged(int)) );
  184     connect( ui.sbErrorBarsCapSize, SIGNAL(valueChanged(double)), this, SLOT(errorBarsCapSizeChanged(double)) );
  185     connect( ui.cbErrorBarsStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsStyleChanged(int)) );
  186     connect( ui.kcbErrorBarsColor, SIGNAL(changed(QColor)), this, SLOT(errorBarsColorChanged(QColor)) );
  187     connect( ui.sbErrorBarsWidth, SIGNAL(valueChanged(double)), this, SLOT(errorBarsWidthChanged(double)) );
  188     connect( ui.sbErrorBarsOpacity, SIGNAL(valueChanged(int)), this, SLOT(errorBarsOpacityChanged(int)) );
  189 
  190     //template handler
  191     auto* frame = new QFrame(this);
  192     auto* layout = new QHBoxLayout(frame);
  193     layout->setContentsMargins(0, 11, 0, 11);
  194 
  195     auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::XYCurve);
  196     layout->addWidget(templateHandler);
  197     connect(templateHandler, SIGNAL(loadConfigRequested(KConfig&)), this, SLOT(loadConfigFromTemplate(KConfig&)));
  198     connect(templateHandler, SIGNAL(saveConfigRequested(KConfig&)), this, SLOT(saveConfigAsTemplate(KConfig&)));
  199     connect(templateHandler, SIGNAL(info(QString)), this, SIGNAL(info(QString)));
  200 
  201     ui.verticalLayout->addWidget(frame);
  202 
  203     retranslateUi();
  204     init();
  205 }
  206 
  207 XYCurveDock::~XYCurveDock() {
  208     if (m_aspectTreeModel)
  209         delete m_aspectTreeModel;
  210 }
  211 
  212 void XYCurveDock::setupGeneral() {
  213     QWidget* generalTab = new QWidget(ui.tabGeneral);
  214     uiGeneralTab.setupUi(generalTab);
  215     m_leName = uiGeneralTab.leName;
  216     m_leComment = uiGeneralTab.leComment;
  217     auto* layout = new QHBoxLayout(ui.tabGeneral);
  218     layout->setMargin(0);
  219     layout->addWidget(generalTab);
  220 
  221     // Tab "General"
  222     auto* gridLayout = qobject_cast<QGridLayout*>(generalTab->layout());
  223 
  224     cbXColumn = new TreeViewComboBox(generalTab);
  225     cbXColumn->useCurrentIndexText(false);
  226     gridLayout->addWidget(cbXColumn, 2, 2, 1, 1);
  227 
  228     cbYColumn = new TreeViewComboBox(generalTab);
  229     cbYColumn->useCurrentIndexText(false);
  230     gridLayout->addWidget(cbYColumn, 3, 2, 1, 1);
  231 
  232     //General
  233     connect(uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYCurveDock::nameChanged);
  234     connect(uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYCurveDock::commentChanged);
  235     connect(uiGeneralTab.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)));
  236     connect(cbXColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xColumnChanged(QModelIndex)));
  237     connect(cbYColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yColumnChanged(QModelIndex)));
  238 }
  239 
  240 void XYCurveDock::init() {
  241     m_initializing = true;
  242 
  243     //Line
  244     ui.cbLineType->addItem(i18n("None"));
  245     ui.cbLineType->addItem(i18n("Line"));
  246     ui.cbLineType->addItem(i18n("Horiz. Start"));
  247     ui.cbLineType->addItem(i18n("Vert. Start"));
  248     ui.cbLineType->addItem(i18n("Horiz. Midpoint"));
  249     ui.cbLineType->addItem(i18n("Vert. Midpoint"));
  250     ui.cbLineType->addItem(i18n("2-segments"));
  251     ui.cbLineType->addItem(i18n("3-segments"));
  252     ui.cbLineType->addItem(i18n("Cubic Spline (Natural)"));
  253     ui.cbLineType->addItem(i18n("Cubic Spline (Periodic)"));
  254     ui.cbLineType->addItem(i18n("Akima-spline (Natural)"));
  255     ui.cbLineType->addItem(i18n("Akima-spline (Periodic)"));
  256 
  257     QPainter pa;
  258     //TODO size of the icon depending on the actual height of the combobox?
  259     int iconSize = 20;
  260     QPixmap pm(iconSize, iconSize);
  261     ui.cbLineType->setIconSize(QSize(iconSize, iconSize));
  262 
  263     QPen pen(Qt::SolidPattern, 0);
  264     const QColor& color = (palette().color(QPalette::Base).lightness() < 128) ? Qt::white : Qt::black;
  265     pen.setColor(color);
  266     pa.setPen( pen );
  267 
  268     //no line
  269     pm.fill(Qt::transparent);
  270     pa.begin( &pm );
  271     pa.setPen(pen);
  272     pa.setRenderHint(QPainter::Antialiasing);
  273     pa.drawEllipse( 1,1,4,4);
  274     pa.drawEllipse( 15,15,4,4);
  275     pa.end();
  276     ui.cbLineType->setItemIcon(0, pm);
  277 
  278     //line
  279     pm.fill(Qt::transparent);
  280     pa.begin( &pm );
  281     pa.setPen(pen);
  282     pa.setRenderHint(QPainter::Antialiasing);
  283     pa.drawEllipse( 1,1,4,4);
  284     pa.drawEllipse( 15,15,4,4);
  285     pa.drawLine(3,3,17,17);
  286     pa.end();
  287     ui.cbLineType->setItemIcon(1, pm);
  288 
  289     pm.fill(Qt::transparent);
  290     pa.begin( &pm );
  291     pa.setPen(pen);
  292     pa.setRenderHint(QPainter::Antialiasing);
  293     pa.drawEllipse( 1,1,4,4);
  294     pa.drawEllipse( 15,15,4,4);
  295     pa.drawLine(3,3,17,3);
  296     pa.drawLine(17,3,17,17);
  297     pa.end();
  298     ui.cbLineType->setItemIcon(2, pm);
  299 
  300     pm.fill(Qt::transparent);
  301     pa.begin( &pm );
  302     pa.setPen(pen);
  303     pa.setRenderHint(QPainter::Antialiasing);
  304     pa.drawEllipse( 1,1,4,4);
  305     pa.drawEllipse( 15,15,4,4);
  306     pa.drawLine(3,3,3,17);
  307     pa.drawLine(3,17,17,17);
  308     pa.end();
  309     ui.cbLineType->setItemIcon(3, pm);
  310 
  311     //horizontal midpoint
  312     pm.fill(Qt::transparent);
  313     pa.begin( &pm );
  314     pa.setPen(pen);
  315     pa.setRenderHint(QPainter::Antialiasing);
  316     pa.drawEllipse( 1,1,4,4);
  317     pa.drawEllipse( 15,15,4,4);
  318     pa.drawLine(3,3,10,3);
  319     pa.drawLine(10,3,10,17);
  320     pa.drawLine(10,17,17,17);
  321     pa.end();
  322     ui.cbLineType->setItemIcon(4, pm);
  323 
  324     //vertical midpoint
  325     pm.fill(Qt::transparent);
  326     pa.begin( &pm );
  327     pa.setPen(pen);
  328     pa.setRenderHint(QPainter::Antialiasing);
  329     pa.drawEllipse( 1,1,4,4);
  330     pa.drawEllipse( 15,15,4,4);
  331     pa.drawLine(3,3,3,10);
  332     pa.drawLine(3,10,17,10);
  333     pa.drawLine(17,10,17,17);
  334     pa.end();
  335     ui.cbLineType->setItemIcon(5, pm);
  336 
  337     //2-segments
  338     pm.fill(Qt::transparent);
  339     pa.begin( &pm );
  340     pa.setPen(pen);
  341     pa.setRenderHint(QPainter::Antialiasing);
  342     pa.drawEllipse( 1,1,4,4);
  343     pa.drawEllipse( 8,8,4,4);
  344     pa.drawEllipse( 15,15,4,4);
  345     pa.drawLine(3,3,10,10);
  346     pa.end();
  347     ui.cbLineType->setItemIcon(6, pm);
  348 
  349     //3-segments
  350     pm.fill(Qt::transparent);
  351     pa.begin( &pm );
  352     pa.setPen(pen);
  353     pa.setRenderHint(QPainter::Antialiasing);
  354     pa.drawEllipse( 1,1,4,4);
  355     pa.drawEllipse( 8,8,4,4);
  356     pa.drawEllipse( 15,15,4,4);
  357     pa.drawLine(3,3,17,17);
  358     pa.end();
  359     ui.cbLineType->setItemIcon(7, pm);
  360 
  361     //natural spline
  362     pm.fill(Qt::transparent);
  363     pa.begin( &pm );
  364     pa.setPen(pen);
  365     pa.setRenderHint(QPainter::Antialiasing);
  366     pa.drawEllipse( 1,1,4,4);
  367     pa.drawEllipse( 15,15,4,4);
  368     pa.rotate(45);
  369     pa.drawArc(2*sqrt(2),-4,17*sqrt(2),20,30*16,120*16);
  370 
  371     pa.end();
  372     ui.cbLineType->setItemIcon(8, pm);
  373     ui.cbLineType->setItemIcon(9, pm);
  374     ui.cbLineType->setItemIcon(10, pm);
  375     ui.cbLineType->setItemIcon(11, pm);
  376 
  377     GuiTools::updatePenStyles(ui.cbLineStyle, Qt::black);
  378 
  379     //Drop lines
  380     ui.cbDropLineType->addItem(i18n("No Drop Lines"));
  381     ui.cbDropLineType->addItem(i18n("Drop Lines, X"));
  382     ui.cbDropLineType->addItem(i18n("Drop Lines, Y"));
  383     ui.cbDropLineType->addItem(i18n("Drop Lines, XY"));
  384     ui.cbDropLineType->addItem(i18n("Drop Lines, X, Zero Baseline"));
  385     ui.cbDropLineType->addItem(i18n("Drop Lines, X, Min Baseline"));
  386     ui.cbDropLineType->addItem(i18n("Drop Lines, X, Max Baseline"));
  387     GuiTools::updatePenStyles(ui.cbDropLineStyle, Qt::black);
  388 
  389     //Symbols
  390     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, Qt::black);
  391 
  392     ui.cbSymbolStyle->setIconSize(QSize(iconSize, iconSize));
  393     QTransform trafo;
  394     trafo.scale(15, 15);
  395 
  396     ui.cbSymbolStyle->addItem(i18n("None"));
  397     for (int i = 1; i < Symbol::stylesCount(); ++i) {
  398         const auto style = (Symbol::Style)i;
  399         pm.fill(Qt::transparent);
  400         pa.begin(&pm);
  401         pa.setPen(pen);
  402         pa.setRenderHint(QPainter::Antialiasing);
  403         pa.translate(iconSize/2,iconSize/2);
  404         pa.drawPath(trafo.map(Symbol::pathFromStyle(style)));
  405         pa.end();
  406         ui.cbSymbolStyle->addItem(QIcon(pm), Symbol::nameFromStyle(style));
  407     }
  408 
  409     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, Qt::black);
  410     m_initializing = false;
  411 
  412     //Values
  413     ui.cbValuesType->addItem(i18n("No Values"));
  414     ui.cbValuesType->addItem("x");
  415     ui.cbValuesType->addItem("y");
  416     ui.cbValuesType->addItem("x, y");
  417     ui.cbValuesType->addItem("(x, y)");
  418     ui.cbValuesType->addItem(i18n("Custom Column"));
  419 
  420     ui.cbValuesPosition->addItem(i18n("Above"));
  421     ui.cbValuesPosition->addItem(i18n("Below"));
  422     ui.cbValuesPosition->addItem(i18n("Left"));
  423     ui.cbValuesPosition->addItem(i18n("Right"));
  424 
  425     //Filling
  426     ui.cbFillingPosition->clear();
  427     ui.cbFillingPosition->addItem(i18n("None"));
  428     ui.cbFillingPosition->addItem(i18n("Above"));
  429     ui.cbFillingPosition->addItem(i18n("Below"));
  430     ui.cbFillingPosition->addItem(i18n("Zero Baseline"));
  431     ui.cbFillingPosition->addItem(i18n("Left"));
  432     ui.cbFillingPosition->addItem(i18n("Right"));
  433 
  434     ui.cbFillingType->clear();
  435     ui.cbFillingType->addItem(i18n("Color"));
  436     ui.cbFillingType->addItem(i18n("Image"));
  437     ui.cbFillingType->addItem(i18n("Pattern"));
  438 
  439     ui.cbFillingColorStyle->clear();
  440     ui.cbFillingColorStyle->addItem(i18n("Single Color"));
  441     ui.cbFillingColorStyle->addItem(i18n("Horizontal Gradient"));
  442     ui.cbFillingColorStyle->addItem(i18n("Vertical Gradient"));
  443     ui.cbFillingColorStyle->addItem(i18n("Diag. Gradient (From Top Left)"));
  444     ui.cbFillingColorStyle->addItem(i18n("Diag. Gradient (From Bottom Left)"));
  445     ui.cbFillingColorStyle->addItem(i18n("Radial Gradient"));
  446 
  447     ui.cbFillingImageStyle->clear();
  448     ui.cbFillingImageStyle->addItem(i18n("Scaled and Cropped"));
  449     ui.cbFillingImageStyle->addItem(i18n("Scaled"));
  450     ui.cbFillingImageStyle->addItem(i18n("Scaled, Keep Proportions"));
  451     ui.cbFillingImageStyle->addItem(i18n("Centered"));
  452     ui.cbFillingImageStyle->addItem(i18n("Tiled"));
  453     ui.cbFillingImageStyle->addItem(i18n("Center Tiled"));
  454     GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, Qt::SolidPattern);
  455 
  456     //Error-bars
  457     pm.fill(Qt::transparent);
  458     pa.begin( &pm );
  459     pa.setRenderHint(QPainter::Antialiasing);
  460     pa.drawLine(3,10,17,10);//vert. line
  461     pa.drawLine(10,3,10,17);//hor. line
  462     pa.end();
  463     ui.cbErrorBarsType->addItem(i18n("Bars"));
  464     ui.cbErrorBarsType->setItemIcon(0, pm);
  465 
  466     pm.fill(Qt::transparent);
  467     pa.begin( &pm );
  468     pa.setRenderHint(QPainter::Antialiasing);
  469     pa.setBrush(Qt::SolidPattern);
  470     pa.drawLine(3,10,17,10); //vert. line
  471     pa.drawLine(10,3,10,17); //hor. line
  472     pa.drawLine(7,3,13,3); //upper cap
  473     pa.drawLine(7,17,13,17); //bottom cap
  474     pa.drawLine(3,7,3,13); //left cap
  475     pa.drawLine(17,7,17,13); //right cap
  476     pa.end();
  477     ui.cbErrorBarsType->addItem(i18n("Bars with Ends"));
  478     ui.cbErrorBarsType->setItemIcon(1, pm);
  479 
  480     ui.cbXErrorType->addItem(i18n("No"));
  481     ui.cbXErrorType->addItem(i18n("Symmetric"));
  482     ui.cbXErrorType->addItem(i18n("Asymmetric"));
  483 
  484     ui.cbYErrorType->addItem(i18n("No"));
  485     ui.cbYErrorType->addItem(i18n("Symmetric"));
  486     ui.cbYErrorType->addItem(i18n("Asymmetric"));
  487 
  488     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, Qt::black);
  489 }
  490 
  491 void XYCurveDock::setModel() {
  492     m_aspectTreeModel->enablePlottableColumnsOnly(true);
  493     m_aspectTreeModel->enableShowPlotDesignation(true);
  494 
  495     QList<AspectType> list{AspectType::Folder, AspectType::Workbook, AspectType::Datapicker,
  496                            AspectType::DatapickerCurve, AspectType::Spreadsheet, AspectType::LiveDataSource,
  497                            AspectType::Column, AspectType::Worksheet, AspectType::CartesianPlot,
  498                            AspectType::XYFitCurve, AspectType::XYSmoothCurve, AspectType::CantorWorksheet};
  499 
  500     if (cbXColumn) {
  501         cbXColumn->setTopLevelClasses(list);
  502         cbYColumn->setTopLevelClasses(list);
  503     }
  504     cbValuesColumn->setTopLevelClasses(list);
  505     cbXErrorMinusColumn->setTopLevelClasses(list);
  506     cbXErrorPlusColumn->setTopLevelClasses(list);
  507     cbYErrorMinusColumn->setTopLevelClasses(list);
  508     cbYErrorPlusColumn->setTopLevelClasses(list);
  509 
  510     if (m_curve->inherits(AspectType::XYAnalysisCurve))
  511         //the model is use in the combobox for curve data sources -> allow to also select analysis curves
  512         list = {AspectType::Column, AspectType::XYCurve,
  513             AspectType::XYFitCurve, AspectType::XYIntegrationCurve, AspectType::XYInterpolationCurve,
  514             AspectType::XYSmoothCurve, AspectType::XYFourierFilterCurve, AspectType::XYFourierTransformCurve,
  515             AspectType::XYConvolution, AspectType::XYCorrelationCurve, AspectType::XYDataReductionCurve};
  516     else
  517         list = {AspectType::Column, AspectType::XYCurve};
  518 
  519     m_aspectTreeModel->setSelectableAspects(list);
  520 
  521     if (cbXColumn) {
  522         cbXColumn->setModel(m_aspectTreeModel);
  523         cbYColumn->setModel(m_aspectTreeModel);
  524     }
  525     cbValuesColumn->setModel(m_aspectTreeModel);
  526     cbXErrorMinusColumn->setModel(m_aspectTreeModel);
  527     cbXErrorPlusColumn->setModel(m_aspectTreeModel);
  528     cbYErrorMinusColumn->setModel(m_aspectTreeModel);
  529     cbYErrorPlusColumn->setModel(m_aspectTreeModel);
  530 
  531     if (cbXColumn) {
  532         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.");
  533         QString path = m_curve->xColumnPath().split('/').last();
  534         if (m_curve->xColumn()) {
  535             path += QString("\t ") + m_curve->xColumn()->plotDesignationString();
  536             cbXColumn->setInvalid(false);
  537         } else
  538             cbXColumn->setInvalid(true, msg.arg(m_curve->xColumnPath()));
  539         cbXColumn->setText(path);
  540 
  541         path = m_curve->yColumnPath().split('/').last();
  542         if (m_curve->yColumn()) {
  543             path += QString("\t ") + m_curve->yColumn()->plotDesignationString();
  544             cbYColumn->setInvalid(false);
  545         } else
  546             cbYColumn->setInvalid(true, msg.arg(m_curve->yColumnPath()));
  547         cbYColumn->setText(path);
  548     }
  549 
  550 
  551     //this function is called after the dock widget is initializes and the curves are set.
  552     //so, we use this function to finalize the initialization eventhough it's not related
  553     //to the actual set of the model (could also be solved by a new class XYAnalysisiCurveDock).
  554 
  555     //hide property widgets that are not relevant for analysis curves
  556     bool visible = (m_curve->type() == AspectType::XYCurve);
  557     ui.lLineType->setVisible(visible);
  558     ui.cbLineType->setVisible(visible);
  559     ui.lLineSkipGaps->setVisible(visible);
  560     ui.chkLineSkipGaps->setVisible(visible);
  561     ui.lLineIncreasingXOnly->setVisible(visible);
  562     ui.chkLineIncreasingXOnly->setVisible(visible);
  563 
  564     //remove the tab "Error bars" for analysis curves
  565     if (!visible)
  566         ui.tabWidget->removeTab(5);
  567 }
  568 
  569 /*!
  570   sets the curves. The properties of the curves in the list \c list can be edited in this widget.
  571 */
  572 void XYCurveDock::setCurves(QList<XYCurve*> list) {
  573     m_initializing = true;
  574     m_curvesList = list;
  575     m_curve = list.first();
  576     m_aspect = m_curve;
  577     Q_ASSERT(m_curve);
  578     m_aspectTreeModel = new AspectTreeModel(m_curve->project());
  579     setModel();
  580     initGeneralTab();
  581     initTabs();
  582     m_initializing = false;
  583 }
  584 
  585 void XYCurveDock::initGeneralTab() {
  586     DEBUG("XYCurveDock::initGeneralTab()");
  587     //if there are more than one curve in the list, disable the content in the tab "general"
  588     if (m_curvesList.size() == 1) {
  589         uiGeneralTab.lName->setEnabled(true);
  590         uiGeneralTab.leName->setEnabled(true);
  591         uiGeneralTab.lComment->setEnabled(true);
  592         uiGeneralTab.leComment->setEnabled(true);
  593 
  594         uiGeneralTab.lXColumn->setEnabled(true);
  595         cbXColumn->setEnabled(true);
  596         uiGeneralTab.lYColumn->setEnabled(true);
  597         cbYColumn->setEnabled(true);
  598 
  599         DEBUG("setModelIndexFromAspect()");
  600         this->setModelIndexFromAspect(cbXColumn, m_curve->xColumn());
  601         this->setModelIndexFromAspect(cbYColumn, m_curve->yColumn());
  602 
  603         uiGeneralTab.leName->setText(m_curve->name());
  604         uiGeneralTab.leComment->setText(m_curve->comment());
  605     } else {
  606         uiGeneralTab.lName->setEnabled(false);
  607         uiGeneralTab.leName->setEnabled(false);
  608         uiGeneralTab.lComment->setEnabled(false);
  609         uiGeneralTab.leComment->setEnabled(false);
  610 
  611         uiGeneralTab.lXColumn->setEnabled(false);
  612         cbXColumn->setEnabled(false);
  613         uiGeneralTab.lYColumn->setEnabled(false);
  614         cbYColumn->setEnabled(false);
  615 
  616         cbXColumn->setCurrentModelIndex(QModelIndex());
  617         cbYColumn->setCurrentModelIndex(QModelIndex());
  618 
  619         uiGeneralTab.leName->setText(QString());
  620         uiGeneralTab.leComment->setText(QString());
  621     }
  622 
  623     checkColumnAvailability(cbXColumn, m_curve->xColumn(), m_curve->xColumnPath());
  624     checkColumnAvailability(cbYColumn, m_curve->yColumn(), m_curve->yColumnPath());
  625     checkColumnAvailability(cbValuesColumn, m_curve->valuesColumn(), m_curve->valuesColumnPath());
  626     checkColumnAvailability(cbXErrorPlusColumn, m_curve->xErrorPlusColumn(), m_curve->xErrorPlusColumnPath());
  627     checkColumnAvailability(cbXErrorMinusColumn, m_curve->xErrorMinusColumn(), m_curve->xErrorMinusColumnPath());
  628     checkColumnAvailability(cbYErrorPlusColumn, m_curve->yErrorPlusColumn(), m_curve->yErrorPlusColumnPath());
  629     checkColumnAvailability(cbYErrorMinusColumn, m_curve->yErrorMinusColumn(), m_curve->yErrorMinusColumnPath());
  630 
  631     //show the properties of the first curve
  632     uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() );
  633 
  634     //Slots
  635     connect(m_curve, &XYCurve::aspectDescriptionChanged, this, &XYCurveDock::curveDescriptionChanged);
  636     connect(m_curve, &XYCurve::xColumnChanged, this, &XYCurveDock::curveXColumnChanged);
  637     connect(m_curve, &XYCurve::yColumnChanged, this, &XYCurveDock::curveYColumnChanged);
  638     connect(m_curve, QOverload<bool>::of(&XYCurve::visibilityChanged), this, &XYCurveDock::curveVisibilityChanged);
  639     DEBUG("XYCurveDock::initGeneralTab() DONE");
  640 }
  641 
  642 void XYCurveDock::initTabs() {
  643     //if there are more than one curve in the list, disable the tab "general"
  644     if (m_curvesList.size() == 1) {
  645         this->setModelIndexFromAspect(cbValuesColumn, m_curve->valuesColumn());
  646         this->setModelIndexFromAspect(cbXErrorPlusColumn, m_curve->xErrorPlusColumn());
  647         this->setModelIndexFromAspect(cbXErrorMinusColumn, m_curve->xErrorMinusColumn());
  648         this->setModelIndexFromAspect(cbYErrorPlusColumn, m_curve->yErrorPlusColumn());
  649         this->setModelIndexFromAspect(cbYErrorMinusColumn, m_curve->yErrorMinusColumn());
  650     } else {
  651         cbValuesColumn->setCurrentModelIndex(QModelIndex());
  652         cbXErrorPlusColumn->setCurrentModelIndex(QModelIndex());
  653         cbXErrorMinusColumn->setCurrentModelIndex(QModelIndex());
  654         cbYErrorPlusColumn->setCurrentModelIndex(QModelIndex());
  655         cbYErrorMinusColumn->setCurrentModelIndex(QModelIndex());
  656     }
  657 
  658     //show the properties of the first curve
  659     load();
  660 
  661     //Slots
  662 
  663     //Line-Tab
  664     connect(m_curve, SIGNAL(lineTypeChanged(XYCurve::LineType)), this, SLOT(curveLineTypeChanged(XYCurve::LineType)));
  665     connect(m_curve, SIGNAL(lineSkipGapsChanged(bool)), this, SLOT(curveLineSkipGapsChanged(bool)));
  666     connect(m_curve, &XYCurve::lineIncreasingXOnlyChanged, this, &XYCurveDock::curveLineIncreasingXOnlyChanged);
  667     connect(m_curve, SIGNAL(lineInterpolationPointsCountChanged(int)), this, SLOT(curveLineInterpolationPointsCountChanged(int)));
  668     connect(m_curve, SIGNAL(linePenChanged(QPen)), this, SLOT(curveLinePenChanged(QPen)));
  669     connect(m_curve, SIGNAL(lineOpacityChanged(qreal)), this, SLOT(curveLineOpacityChanged(qreal)));
  670     connect(m_curve, SIGNAL(dropLineTypeChanged(XYCurve::DropLineType)), this, SLOT(curveDropLineTypeChanged(XYCurve::DropLineType)));
  671     connect(m_curve, SIGNAL(dropLinePenChanged(QPen)), this, SLOT(curveDropLinePenChanged(QPen)));
  672     connect(m_curve, SIGNAL(dropLineOpacityChanged(qreal)), this, SLOT(curveDropLineOpacityChanged(qreal)));
  673 
  674     //Symbol-Tab
  675     connect(m_curve, SIGNAL(symbolsStyleChanged(Symbol::Style)), this, SLOT(curveSymbolsStyleChanged(Symbol::Style)));
  676     connect(m_curve, SIGNAL(symbolsSizeChanged(qreal)), this, SLOT(curveSymbolsSizeChanged(qreal)));
  677     connect(m_curve, SIGNAL(symbolsRotationAngleChanged(qreal)), this, SLOT(curveSymbolsRotationAngleChanged(qreal)));
  678     connect(m_curve, SIGNAL(symbolsOpacityChanged(qreal)), this, SLOT(curveSymbolsOpacityChanged(qreal)));
  679     connect(m_curve, SIGNAL(symbolsBrushChanged(QBrush)), this, SLOT(curveSymbolsBrushChanged(QBrush)));
  680     connect(m_curve, SIGNAL(symbolsPenChanged(QPen)), this, SLOT(curveSymbolsPenChanged(QPen)));
  681 
  682     //Values-Tab
  683     connect(m_curve, SIGNAL(valuesTypeChanged(XYCurve::ValuesType)), this, SLOT(curveValuesTypeChanged(XYCurve::ValuesType)));
  684     connect(m_curve, SIGNAL(valuesColumnChanged(const AbstractColumn*)), this, SLOT(curveValuesColumnChanged(const AbstractColumn*)));
  685     connect(m_curve, SIGNAL(valuesPositionChanged(XYCurve::ValuesPosition)), this, SLOT(curveValuesPositionChanged(XYCurve::ValuesPosition)));
  686     connect(m_curve, SIGNAL(valuesDistanceChanged(qreal)), this, SLOT(curveValuesDistanceChanged(qreal)));
  687     connect(m_curve, SIGNAL(valuesOpacityChanged(qreal)), this, SLOT(curveValuesOpacityChanged(qreal)));
  688     connect(m_curve, SIGNAL(valuesRotationAngleChanged(qreal)), this, SLOT(curveValuesRotationAngleChanged(qreal)));
  689     connect(m_curve, &XYCurve::valuesNumericFormatChanged, this, &XYCurveDock::curveValuesNumericFormatChanged);
  690     connect(m_curve, &XYCurve::valuesPrecisionChanged, this, &XYCurveDock::curveValuesPrecisionChanged);
  691     connect(m_curve, &XYCurve::valuesDateTimeFormatChanged, this, &XYCurveDock::curveValuesDateTimeFormatChanged);
  692     connect(m_curve, SIGNAL(valuesPrefixChanged(QString)), this, SLOT(curveValuesPrefixChanged(QString)));
  693     connect(m_curve, SIGNAL(valuesSuffixChanged(QString)), this, SLOT(curveValuesSuffixChanged(QString)));
  694     connect(m_curve, SIGNAL(valuesFontChanged(QFont)), this, SLOT(curveValuesFontChanged(QFont)));
  695     connect(m_curve, SIGNAL(valuesColorChanged(QColor)), this, SLOT(curveValuesColorChanged(QColor)));
  696 
  697     //Filling-Tab
  698     connect( m_curve, SIGNAL(fillingPositionChanged(XYCurve::FillingPosition)), this, SLOT(curveFillingPositionChanged(XYCurve::FillingPosition)) );
  699     connect( m_curve, SIGNAL(fillingTypeChanged(PlotArea::BackgroundType)), this, SLOT(curveFillingTypeChanged(PlotArea::BackgroundType)) );
  700     connect( m_curve, SIGNAL(fillingColorStyleChanged(PlotArea::BackgroundColorStyle)), this, SLOT(curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle)) );
  701     connect( m_curve, SIGNAL(fillingImageStyleChanged(PlotArea::BackgroundImageStyle)), this, SLOT(curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle)) );
  702     connect( m_curve, SIGNAL(fillingBrushStyleChanged(Qt::BrushStyle)), this, SLOT(curveFillingBrushStyleChanged(Qt::BrushStyle)) );
  703     connect( m_curve, SIGNAL(fillingFirstColorChanged(QColor&)), this, SLOT(curveFillingFirstColorChanged(QColor&)) );
  704     connect( m_curve, SIGNAL(fillingSecondColorChanged(QColor&)), this, SLOT(curveFillingSecondColorChanged(QColor&)) );
  705     connect( m_curve, SIGNAL(fillingFileNameChanged(QString&)), this, SLOT(curveFillingFileNameChanged(QString&)) );
  706     connect( m_curve, SIGNAL(fillingOpacityChanged(float)), this, SLOT(curveFillingOpacityChanged(float)) );
  707 
  708     //"Error bars"-Tab
  709     connect(m_curve, SIGNAL(xErrorTypeChanged(XYCurve::ErrorType)), this, SLOT(curveXErrorTypeChanged(XYCurve::ErrorType)));
  710     connect(m_curve, SIGNAL(xErrorPlusColumnChanged(const AbstractColumn*)), this, SLOT(curveXErrorPlusColumnChanged(const AbstractColumn*)));
  711     connect(m_curve, SIGNAL(xErrorMinusColumnChanged(const AbstractColumn*)), this, SLOT(curveXErrorMinusColumnChanged(const AbstractColumn*)));
  712     connect(m_curve, SIGNAL(yErrorTypeChanged(XYCurve::ErrorType)), this, SLOT(curveYErrorTypeChanged(XYCurve::ErrorType)));
  713     connect(m_curve, SIGNAL(yErrorPlusColumnChanged(const AbstractColumn*)), this, SLOT(curveYErrorPlusColumnChanged(const AbstractColumn*)));
  714     connect(m_curve, SIGNAL(yErrorMinusColumnChanged(const AbstractColumn*)), this, SLOT(curveYErrorMinusColumnChanged(const AbstractColumn*)));
  715     connect(m_curve, SIGNAL(errorBarsCapSizeChanged(qreal)), this, SLOT(curveErrorBarsCapSizeChanged(qreal)));
  716     connect(m_curve, SIGNAL(errorBarsTypeChanged(XYCurve::ErrorBarsType)), this, SLOT(curveErrorBarsTypeChanged(XYCurve::ErrorBarsType)));
  717     connect(m_curve, SIGNAL(errorBarsPenChanged(QPen)), this, SLOT(curveErrorBarsPenChanged(QPen)));
  718     connect(m_curve, SIGNAL(errorBarsOpacityChanged(qreal)), this, SLOT(curveErrorBarsOpacityChanged(qreal)));
  719 }
  720 
  721 void XYCurveDock::checkColumnAvailability(TreeViewComboBox* cb, const AbstractColumn* column, const QString& columnPath) {
  722     if (!cb)
  723         return;// normally it shouldn't be called
  724 
  725     // don't make the comboboxes red for initially created curves
  726     if (!column && columnPath.isEmpty()) {
  727         cb->setText("");
  728         cb->setInvalid(false);
  729         return;
  730     }
  731 
  732     if (column) {
  733         // current index text should be used
  734         cb->useCurrentIndexText(true);
  735         cb->setInvalid(false);
  736     } else {
  737         cb->useCurrentIndexText(false);
  738         cb->setInvalid(true, i18n("The column \"%1\"\nis not available anymore. It will be automatically used once it is created again.", columnPath));
  739     }
  740     cb->setText(columnPath.split('/').last());
  741 }
  742 
  743 void XYCurveDock::setModelIndexFromAspect(TreeViewComboBox* cb, const AbstractAspect* aspect) {
  744     if (aspect)
  745         cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(aspect));
  746     else
  747         cb->setCurrentModelIndex(QModelIndex());
  748 }
  749 
  750 void XYCurveDock::updateLocale() {
  751     SET_NUMBER_LOCALE
  752     ui.sbLineWidth->setLocale(numberLocale);
  753     ui.sbDropLineWidth->setLocale(numberLocale);
  754     ui.sbSymbolSize->setLocale(numberLocale);
  755     ui.sbSymbolBorderWidth->setLocale(numberLocale);
  756     ui.sbValuesDistance->setLocale(numberLocale);
  757     ui.sbErrorBarsCapSize->setLocale(numberLocale);
  758     ui.sbErrorBarsWidth->setLocale(numberLocale);
  759 }
  760 
  761 //*************************************************************
  762 //********** SLOTs for changes triggered in XYCurveDock ********
  763 //*************************************************************
  764 void XYCurveDock::retranslateUi() {
  765     ui.lLineSkipGaps->setToolTip(i18n("If checked, connect neighbour points with lines even if there are gaps (invalid or masked values) between them"));
  766     ui.chkLineSkipGaps->setToolTip(i18n("If checked, connect neighbour points with lines even if there are gaps (invalid or masked values) between them"));
  767     ui.lLineIncreasingXOnly->setToolTip(i18n("If checked, connect data points only for strictly increasing values of X"));
  768     ui.chkLineIncreasingXOnly->setToolTip(i18n("If checked, connect data points only for strictly increasing values of X"));
  769     //TODO:
  770 //  uiGeneralTab.lName->setText(i18n("Name"));
  771 //  uiGeneralTab.lComment->setText(i18n("Comment"));
  772 //  uiGeneralTab.chkVisible->setText(i18n("Visible"));
  773 //  uiGeneralTab.lXColumn->setText(i18n("x-data"));
  774 //  uiGeneralTab.lYColumn->setText(i18n("y-data"));
  775 
  776     //TODO updatePenStyles, updateBrushStyles for all comboboxes
  777 }
  778 
  779 void XYCurveDock::xColumnChanged(const QModelIndex& index) {
  780     updateValuesWidgets();
  781 
  782     if (m_initializing)
  783         return;
  784 
  785     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
  786     AbstractColumn* column = nullptr;
  787     if (aspect) {
  788         column = dynamic_cast<AbstractColumn*>(aspect);
  789         Q_ASSERT(column);
  790     }
  791 
  792     for (auto* curve : m_curvesList)
  793         curve->setXColumn(column);
  794 }
  795 
  796 void XYCurveDock::yColumnChanged(const QModelIndex& index) {
  797     updateValuesWidgets();
  798 
  799     if (m_initializing)
  800         return;
  801 
  802     auto* aspect = static_cast<AbstractAspect*>(index.internalPointer());
  803     AbstractColumn* column = nullptr;
  804     if (aspect) {
  805         column = dynamic_cast<AbstractColumn*>(aspect);
  806         Q_ASSERT(column);
  807     }
  808 
  809     for (auto* curve : m_curvesList)
  810         curve->setYColumn(column);
  811 }
  812 
  813 void XYCurveDock::visibilityChanged(bool state) {
  814     if (m_initializing)
  815         return;
  816 
  817     for (auto* curve : m_curvesList)
  818         curve->setVisible(state);
  819 }
  820 
  821 // "Line"-tab
  822 void XYCurveDock::lineTypeChanged(int index) {
  823     const auto lineType = XYCurve::LineType(index);
  824 
  825     if ( lineType == XYCurve::LineType::NoLine) {
  826         ui.chkLineSkipGaps->setEnabled(false);
  827         ui.cbLineStyle->setEnabled(false);
  828         ui.kcbLineColor->setEnabled(false);
  829         ui.sbLineWidth->setEnabled(false);
  830         ui.sbLineOpacity->setEnabled(false);
  831         ui.lLineInterpolationPointsCount->hide();
  832         ui.sbLineInterpolationPointsCount->hide();
  833     } else {
  834         ui.chkLineSkipGaps->setEnabled(true);
  835         ui.cbLineStyle->setEnabled(true);
  836         ui.kcbLineColor->setEnabled(true);
  837         ui.sbLineWidth->setEnabled(true);
  838         ui.sbLineOpacity->setEnabled(true);
  839 
  840         if (lineType == XYCurve::LineType::SplineCubicNatural || lineType == XYCurve::LineType::SplineCubicPeriodic
  841                 || lineType == XYCurve::LineType::SplineAkimaNatural || lineType == XYCurve::LineType::SplineAkimaPeriodic) {
  842             ui.lLineInterpolationPointsCount->show();
  843             ui.sbLineInterpolationPointsCount->show();
  844             ui.lLineSkipGaps->hide();
  845             ui.chkLineSkipGaps->hide();
  846         } else {
  847             ui.lLineInterpolationPointsCount->hide();
  848             ui.sbLineInterpolationPointsCount->hide();
  849             ui.lLineSkipGaps->show();
  850             ui.chkLineSkipGaps->show();
  851         }
  852     }
  853 
  854     if (m_initializing)
  855         return;
  856 
  857     for (auto* curve : m_curvesList)
  858         curve->setLineType(lineType);
  859 }
  860 
  861 void XYCurveDock::lineSkipGapsChanged(bool skip) {
  862     if (m_initializing)
  863         return;
  864 
  865     for (auto* curve : m_curvesList)
  866         curve->setLineSkipGaps(skip);
  867 }
  868 
  869 void XYCurveDock::lineIncreasingXOnlyChanged(bool incr) {
  870     if (m_initializing)
  871         return;
  872 
  873     for (auto* curve : m_curvesList)
  874         curve->setLineIncreasingXOnly(incr);
  875 }
  876 
  877 void XYCurveDock::lineInterpolationPointsCountChanged(int count) {
  878     if (m_initializing)
  879         return;
  880 
  881     for (auto* curve : m_curvesList)
  882         curve->setLineInterpolationPointsCount(count);
  883 }
  884 
  885 void XYCurveDock::lineStyleChanged(int index) {
  886     if (index == -1 || m_initializing)
  887         return;
  888 
  889     const auto penStyle = Qt::PenStyle(index);
  890     QPen pen;
  891     for (auto* curve : m_curvesList) {
  892         pen = curve->linePen();
  893         pen.setStyle(penStyle);
  894         curve->setLinePen(pen);
  895     }
  896 }
  897 
  898 void XYCurveDock::lineColorChanged(const QColor& color) {
  899     if (m_initializing)
  900         return;
  901 
  902     QPen pen;
  903     for (auto* curve : m_curvesList) {
  904         pen = curve->linePen();
  905         pen.setColor(color);
  906         curve->setLinePen(pen);
  907     }
  908 
  909     m_initializing = true;
  910     GuiTools::updatePenStyles(ui.cbLineStyle, color);
  911     m_initializing = false;
  912 }
  913 
  914 void XYCurveDock::lineWidthChanged(double value) {
  915     if (m_initializing)
  916         return;
  917 
  918     QPen pen;
  919     for (auto* curve : m_curvesList) {
  920         pen = curve->linePen();
  921         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
  922         curve->setLinePen(pen);
  923     }
  924 }
  925 
  926 void XYCurveDock::lineOpacityChanged(int value) {
  927     if (m_initializing)
  928         return;
  929 
  930     qreal opacity = (float)value/100.;
  931     for (auto* curve : m_curvesList)
  932         curve->setLineOpacity(opacity);
  933 }
  934 
  935 void XYCurveDock::dropLineTypeChanged(int index) {
  936     const auto dropLineType = XYCurve::DropLineType(index);
  937 
  938     if ( dropLineType == XYCurve::DropLineType::NoDropLine) {
  939         ui.cbDropLineStyle->setEnabled(false);
  940         ui.kcbDropLineColor->setEnabled(false);
  941         ui.sbDropLineWidth->setEnabled(false);
  942         ui.sbDropLineOpacity->setEnabled(false);
  943     } else {
  944         ui.cbDropLineStyle->setEnabled(true);
  945         ui.kcbDropLineColor->setEnabled(true);
  946         ui.sbDropLineWidth->setEnabled(true);
  947         ui.sbDropLineOpacity->setEnabled(true);
  948     }
  949 
  950     if (m_initializing)
  951         return;
  952 
  953     for (auto* curve : m_curvesList)
  954         curve->setDropLineType(dropLineType);
  955 }
  956 
  957 void XYCurveDock::dropLineStyleChanged(int index) {
  958     if (index == -1 || m_initializing)
  959         return;
  960 
  961     auto penStyle = Qt::PenStyle(index);
  962     QPen pen;
  963     for (auto* curve : m_curvesList) {
  964         pen = curve->dropLinePen();
  965         pen.setStyle(penStyle);
  966         curve->setDropLinePen(pen);
  967     }
  968 }
  969 
  970 void XYCurveDock::dropLineColorChanged(const QColor& color) {
  971     if (m_initializing)
  972         return;
  973 
  974     QPen pen;
  975     for (auto* curve : m_curvesList) {
  976         pen = curve->dropLinePen();
  977         pen.setColor(color);
  978         curve->setDropLinePen(pen);
  979     }
  980 
  981     m_initializing = true;
  982     GuiTools::updatePenStyles(ui.cbDropLineStyle, color);
  983     m_initializing = false;
  984 }
  985 
  986 void XYCurveDock::dropLineWidthChanged(double value) {
  987     if (m_initializing)
  988         return;
  989 
  990     QPen pen;
  991     for (auto* curve : m_curvesList) {
  992         pen = curve->dropLinePen();
  993         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
  994         curve->setDropLinePen(pen);
  995     }
  996 }
  997 
  998 void XYCurveDock::dropLineOpacityChanged(int value) {
  999     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 }