"Fossies" - the Fresh Open Source Software Archive

Member "labplot-2.8.2/src/kdefrontend/dockwidgets/CartesianPlotDock.cpp" (24 Feb 2021, 69250 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 "CartesianPlotDock.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                 : CartesianPlotDock.cpp
    3     Project              : LabPlot
    4     Description          : widget for cartesian plot properties
    5     --------------------------------------------------------------------
    6     Copyright            : (C) 2011-2020 by Alexander Semke (alexander.semke@web.de)
    7     Copyright            : (C) 2012-2013 by 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 "CartesianPlotDock.h"
   31 #include "backend/worksheet/plots/PlotArea.h"
   32 #include "backend/worksheet/plots/cartesian/XYCurve.h"
   33 #include "backend/core/column/Column.h"
   34 
   35 #include "kdefrontend/widgets/LabelWidget.h"
   36 #include "kdefrontend/GuiTools.h"
   37 #include "kdefrontend/TemplateHandler.h"
   38 #include "kdefrontend/ThemeHandler.h"
   39 
   40 #include <QCompleter>
   41 #include <QPainter>
   42 #include <QTimer>
   43 #include <QDir>
   44 #include <QDirModel>
   45 #include <QFileDialog>
   46 #include <QImageReader>
   47 #include <QButtonGroup>
   48 #include <QIntValidator>
   49 
   50 /*!
   51   \class CartesianPlotDock
   52   \brief  Provides a widget for editing the properties of the cartesian plot currently selected in the project explorer.
   53 
   54   \ingroup kdefrontend
   55 */
   56 
   57 CartesianPlotDock::CartesianPlotDock(QWidget* parent) : BaseDock(parent) {
   58     ui.setupUi(this);
   59     m_leName = ui.leName;
   60     m_leComment = ui.leComment;
   61 
   62     //"General"-tab
   63     auto* rangeButtonsGroup(new QButtonGroup);
   64     rangeButtonsGroup->addButton(ui.rbRangeFirst);
   65     rangeButtonsGroup->addButton(ui.rbRangeLast);
   66     rangeButtonsGroup->addButton(ui.rbRangeFree);
   67 
   68     ui.leXMin->setValidator(new QDoubleValidator(ui.leXMin));
   69     ui.leXMax->setValidator(new QDoubleValidator(ui.leXMax));
   70     ui.leYMin->setValidator(new QDoubleValidator(ui.leYMin));
   71     ui.leYMax->setValidator(new QDoubleValidator(ui.leYMax));
   72 
   73     //"Range breaks"-tab
   74     ui.bAddXBreak->setIcon( QIcon::fromTheme("list-add") );
   75     ui.bRemoveXBreak->setIcon( QIcon::fromTheme("list-remove") );
   76     ui.cbXBreak->addItem("1");
   77 
   78     ui.bAddYBreak->setIcon( QIcon::fromTheme("list-add") );
   79     ui.bRemoveYBreak->setIcon( QIcon::fromTheme("list-remove") );
   80     ui.cbYBreak->addItem("1");
   81 
   82     //"Background"-tab
   83     ui.bOpen->setIcon( QIcon::fromTheme("document-open") );
   84     ui.leBackgroundFileName->setCompleter(new QCompleter(new QDirModel, this));
   85 
   86     //"Title"-tab
   87     auto* hboxLayout = new QHBoxLayout(ui.tabTitle);
   88     labelWidget = new LabelWidget(ui.tabTitle);
   89     hboxLayout->addWidget(labelWidget);
   90     hboxLayout->setContentsMargins(2,2,2,2);
   91     hboxLayout->setSpacing(2);
   92 
   93     //adjust layouts in the tabs
   94     for (int i = 0; i < ui.tabWidget->count(); ++i) {
   95         auto* layout = qobject_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout());
   96         if (!layout)
   97             continue;
   98 
   99         layout->setContentsMargins(2,2,2,2);
  100         layout->setHorizontalSpacing(2);
  101         layout->setVerticalSpacing(2);
  102     }
  103 
  104     // "Cursor"-tab
  105     QStringList list = {i18n("NoPen"), i18n("SolidLine"), i18n("DashLine"), i18n("DotLine"), i18n("DashDotLine"), i18n("DashDotDotLine")};
  106     ui.cbCursorLineStyle->clear();
  107     for (int i = 0; i < list.count(); i++)
  108         ui.cbCursorLineStyle->addItem(list[i], i);
  109 
  110     //Validators
  111     ui.leRangeFirst->setValidator( new QIntValidator(ui.leRangeFirst) );
  112     ui.leRangeLast->setValidator( new QIntValidator(ui.leRangeLast) );
  113     ui.leXBreakStart->setValidator( new QDoubleValidator(ui.leXBreakStart) );
  114     ui.leXBreakEnd->setValidator( new QDoubleValidator(ui.leXBreakEnd) );
  115     ui.leYBreakStart->setValidator( new QDoubleValidator(ui.leYBreakStart) );
  116     ui.leYBreakEnd->setValidator( new QDoubleValidator(ui.leYBreakEnd) );
  117 
  118     //set the current locale
  119     updateLocale();
  120 
  121     //SIGNAL/SLOT
  122     //General
  123     connect(ui.leName, &QLineEdit::textChanged, this, &CartesianPlotDock::nameChanged);
  124     connect(ui.leComment, &QLineEdit::textChanged, this, &CartesianPlotDock::commentChanged);
  125     connect(ui.chkVisible, &QCheckBox::clicked, this, &CartesianPlotDock::visibilityChanged);
  126     connect(ui.sbLeft, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged);
  127     connect(ui.sbTop, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged);
  128     connect(ui.sbWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged);
  129     connect(ui.sbHeight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged);
  130 
  131     connect(ui.leRangeFirst, &QLineEdit::textChanged, this, &CartesianPlotDock::rangeFirstChanged);
  132     connect(ui.leRangeLast, &QLineEdit::textChanged, this, &CartesianPlotDock::rangeLastChanged);
  133     connect(rangeButtonsGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), this, &CartesianPlotDock::rangeTypeChanged);
  134 
  135     connect(ui.chkAutoScaleX, &QCheckBox::stateChanged, this, &CartesianPlotDock::autoScaleXChanged);
  136     connect(ui.leXMin, &QLineEdit::textChanged, this, &CartesianPlotDock::xMinChanged);
  137     connect(ui.leXMax, &QLineEdit::textChanged, this, &CartesianPlotDock::xMaxChanged);
  138     connect(ui.dateTimeEditXMin, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::xMinDateTimeChanged);
  139     connect(ui.dateTimeEditXMax, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::xMaxDateTimeChanged);
  140     connect(ui.cbXScaling, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::xScaleChanged);
  141     connect(ui.cbXRangeFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::xRangeFormatChanged);
  142 
  143     connect(ui.chkAutoScaleY, &QCheckBox::stateChanged, this, &CartesianPlotDock::autoScaleYChanged);
  144     connect(ui.leYMin, &QLineEdit::textChanged, this, &CartesianPlotDock::yMinChanged);
  145     connect(ui.leYMax, &QLineEdit::textChanged, this, &CartesianPlotDock::yMaxChanged);
  146     connect(ui.dateTimeEditYMin, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::yMinDateTimeChanged);
  147     connect(ui.dateTimeEditYMax, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::yMaxDateTimeChanged);
  148     connect(ui.cbYScaling, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::yScaleChanged);
  149     connect(ui.cbYRangeFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::yRangeFormatChanged);
  150 
  151     //Range breaks
  152     connect(ui.chkXBreak, &QCheckBox::toggled, this, &CartesianPlotDock::toggleXBreak);
  153     connect(ui.bAddXBreak, &QPushButton::clicked, this, &CartesianPlotDock::addXBreak);
  154     connect(ui.bRemoveXBreak, &QPushButton::clicked, this, &CartesianPlotDock::removeXBreak);
  155     connect(ui.cbXBreak, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::currentXBreakChanged);
  156     connect(ui.leXBreakStart, &QLineEdit::textChanged, this, &CartesianPlotDock::xBreakStartChanged);
  157     connect(ui.leXBreakEnd, &QLineEdit::textChanged, this, &CartesianPlotDock::xBreakEndChanged);
  158     connect(ui.sbXBreakPosition, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::xBreakPositionChanged);
  159     connect(ui.cbXBreakStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::xBreakStyleChanged);
  160 
  161     connect(ui.chkYBreak, &QCheckBox::toggled, this, &CartesianPlotDock::toggleYBreak);
  162     connect(ui.bAddYBreak, &QPushButton::clicked, this, &CartesianPlotDock::addYBreak);
  163     connect(ui.bRemoveYBreak, &QPushButton::clicked, this, &CartesianPlotDock::removeYBreak);
  164     connect(ui.cbYBreak, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::currentYBreakChanged);
  165     connect(ui.leYBreakStart, &QLineEdit::textChanged, this, &CartesianPlotDock::yBreakStartChanged);
  166     connect(ui.leYBreakEnd, &QLineEdit::textChanged, this, &CartesianPlotDock::yBreakEndChanged);
  167     connect(ui.sbYBreakPosition, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::yBreakPositionChanged);
  168     connect(ui.cbYBreakStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::yBreakStyleChanged);
  169 
  170     //Background
  171     connect(ui.cbBackgroundType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundTypeChanged);
  172     connect(ui.cbBackgroundColorStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundColorStyleChanged);
  173     connect(ui.cbBackgroundImageStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundImageStyleChanged);
  174     connect(ui.cbBackgroundBrushStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundBrushStyleChanged);
  175     connect(ui.bOpen, &QPushButton::clicked, this, &CartesianPlotDock::selectFile);
  176     connect(ui.leBackgroundFileName, &QLineEdit::textChanged, this, &CartesianPlotDock::fileNameChanged);
  177     connect(ui.kcbBackgroundFirstColor, &KColorButton::changed, this, &CartesianPlotDock::backgroundFirstColorChanged);
  178     connect(ui.kcbBackgroundSecondColor, &KColorButton::changed, this, &CartesianPlotDock::backgroundSecondColorChanged);
  179     connect(ui.sbBackgroundOpacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::backgroundOpacityChanged);
  180 
  181     //Border
  182     connect(ui.cbBorderStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::borderStyleChanged);
  183     connect(ui.kcbBorderColor, &KColorButton::changed, this, &CartesianPlotDock::borderColorChanged);
  184     connect(ui.sbBorderWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::borderWidthChanged);
  185     connect(ui.sbBorderCornerRadius, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::borderCornerRadiusChanged);
  186     connect(ui.sbBorderOpacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::borderOpacityChanged);
  187 
  188     //Padding
  189     connect(ui.sbPaddingHorizontal, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::horizontalPaddingChanged);
  190     connect(ui.sbPaddingVertical, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::verticalPaddingChanged);
  191     connect(ui.sbPaddingRight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::rightPaddingChanged);
  192     connect(ui.sbPaddingBottom, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::bottomPaddingChanged);
  193     connect(ui.cbPaddingSymmetric, &QCheckBox::toggled, this, &CartesianPlotDock::symmetricPaddingChanged);
  194 
  195     // Cursor
  196     connect(ui.sbCursorLineWidth, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::cursorLineWidthChanged);
  197     connect(ui.kcbCursorLineColor, &KColorButton::changed, this, &CartesianPlotDock::cursorLineColorChanged);
  198     connect(ui.cbCursorLineStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::cursorLineStyleChanged);
  199 
  200     //theme and template handlers
  201     auto* frame = new QFrame(this);
  202     auto* layout = new QHBoxLayout(frame);
  203     layout->setContentsMargins(0, 11, 0, 11);
  204 
  205     m_themeHandler = new ThemeHandler(this);
  206     layout->addWidget(m_themeHandler);
  207     connect(m_themeHandler, &ThemeHandler::loadThemeRequested, this, &CartesianPlotDock::loadTheme);
  208     connect(m_themeHandler, &ThemeHandler::info, this, &CartesianPlotDock::info);
  209 
  210     auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::CartesianPlot);
  211     layout->addWidget(templateHandler);
  212     connect(templateHandler, &TemplateHandler::loadConfigRequested, this, &CartesianPlotDock::loadConfigFromTemplate);
  213     connect(templateHandler, &TemplateHandler::saveConfigRequested, this, &CartesianPlotDock::saveConfigAsTemplate);
  214     connect(templateHandler, &TemplateHandler::info, this, &CartesianPlotDock::info);
  215 
  216     ui.verticalLayout->addWidget(frame);
  217 
  218     //TODO: activate the tab again once the functionality is implemented
  219     ui.tabWidget->removeTab(2);
  220 
  221     init();
  222 }
  223 
  224 void CartesianPlotDock::init() {
  225     this->retranslateUi();
  226 
  227     GuiTools::updatePenStyles(ui.cbCursorLineStyle, Qt::black);
  228 
  229     /*
  230      //TODO: activate later once range breaking is implemented
  231     //create icons for the different styles for scale breaking
  232     QPainter pa;
  233     pa.setPen( QPen(Qt::SolidPattern, 0) );
  234     QPixmap pm(20, 20);
  235     ui.cbXBreakStyle->setIconSize( QSize(20,20) );
  236     ui.cbYBreakStyle->setIconSize( QSize(20,20) );
  237 
  238     //simple
  239     pm.fill(Qt::transparent);
  240     pa.begin( &pm );
  241     pa.setRenderHint(QPainter::Antialiasing);
  242     pa.setBrush(Qt::SolidPattern);
  243     pa.drawLine(3,10,8,10);
  244     pa.drawLine(12,10,17,10);
  245     pa.end();
  246     ui.cbXBreakStyle->setItemIcon(0, pm);
  247     ui.cbYBreakStyle->setItemIcon(0, pm);
  248 
  249     //vertical
  250     pm.fill(Qt::transparent);
  251     pa.begin( &pm );
  252     pa.setRenderHint(QPainter::Antialiasing);
  253     pa.setBrush(Qt::SolidPattern);
  254     pa.drawLine(3,10,8,10);
  255     pa.drawLine(12,10,17,10);
  256     pa.drawLine(8,14,8,6);
  257     pa.drawLine(12,14,12,6);
  258     pa.end();
  259     ui.cbXBreakStyle->setItemIcon(1, pm);
  260     ui.cbYBreakStyle->setItemIcon(1, pm);
  261 
  262     //sloped
  263     pm.fill(Qt::transparent);
  264     pa.begin( &pm );
  265     pa.setRenderHint(QPainter::Antialiasing);
  266     pa.setBrush(Qt::SolidPattern);
  267     pa.drawLine(3,10,8,10);
  268     pa.drawLine(12,10,17,10);
  269     pa.drawLine(6,14,10,6);
  270     pa.drawLine(10,14,14,6);
  271     pa.end();
  272     ui.cbXBreakStyle->setItemIcon(2, pm);
  273     ui.cbYBreakStyle->setItemIcon(2, pm);
  274     */
  275 }
  276 
  277 void CartesianPlotDock::setPlots(QList<CartesianPlot*> list) {
  278     m_initializing = true;
  279     m_plotList = list;
  280     m_plot = list.first();
  281     m_aspect = list.first();
  282 
  283     QList<TextLabel*> labels;
  284     for (auto* plot : list)
  285         labels.append(plot->title());
  286 
  287     labelWidget->setLabels(labels);
  288 
  289     //if there is more then one plot in the list, disable the name and comment fields in the tab "general"
  290     if (list.size() == 1) {
  291         ui.lName->setEnabled(true);
  292         ui.leName->setEnabled(true);
  293         ui.lComment->setEnabled(true);
  294         ui.leComment->setEnabled(true);
  295 
  296         ui.leName->setText(m_plot->name());
  297         ui.leComment->setText(m_plot->comment());
  298     } else {
  299         ui.lName->setEnabled(false);
  300         ui.leName->setEnabled(false);
  301         ui.lComment->setEnabled(false);
  302         ui.leComment->setEnabled(false);
  303 
  304         ui.leName->setText(QString());
  305         ui.leComment->setText(QString());
  306     }
  307 
  308     symmetricPaddingChanged(m_plot->symmetricPadding());
  309 
  310     ui.leName->setStyleSheet("");
  311     ui.leName->setToolTip("");
  312 
  313     //show the properties of the first plot
  314     this->load();
  315 
  316     //update active widgets
  317     m_themeHandler->setCurrentTheme(m_plot->theme());
  318 
  319     //Deactivate the geometry related widgets, if the worksheet layout is active.
  320     //Currently, a plot can only be a child of the worksheet itself, so we only need to ask the parent aspect (=worksheet).
  321     //TODO redesign this, if the hierarchy will be changend in future (a plot is a child of a new object group/container or so)
  322     auto* w = dynamic_cast<Worksheet*>(m_plot->parentAspect());
  323     if (w) {
  324         bool b = (w->layout() == Worksheet::Layout::NoLayout);
  325         ui.sbTop->setEnabled(b);
  326         ui.sbLeft->setEnabled(b);
  327         ui.sbWidth->setEnabled(b);
  328         ui.sbHeight->setEnabled(b);
  329         connect(w, &Worksheet::layoutChanged, this, &CartesianPlotDock::layoutChanged);
  330     }
  331 
  332     //SIGNALs/SLOTs
  333     connect(m_plot, &CartesianPlot::aspectDescriptionChanged, this, &CartesianPlotDock::plotDescriptionChanged);
  334     connect(m_plot, &CartesianPlot::rectChanged, this, &CartesianPlotDock::plotRectChanged);
  335     connect(m_plot, &CartesianPlot::rangeTypeChanged, this, &CartesianPlotDock::plotRangeTypeChanged);
  336     connect(m_plot, &CartesianPlot::rangeFirstValuesChanged, this, &CartesianPlotDock::plotRangeFirstValuesChanged);
  337     connect(m_plot, &CartesianPlot::rangeLastValuesChanged, this, &CartesianPlotDock::plotRangeLastValuesChanged);
  338     connect(m_plot, &CartesianPlot::xAutoScaleChanged, this, &CartesianPlotDock::plotXAutoScaleChanged);
  339     connect(m_plot, &CartesianPlot::xMinChanged, this, &CartesianPlotDock::plotXMinChanged);
  340     connect(m_plot, &CartesianPlot::xMaxChanged, this, &CartesianPlotDock::plotXMaxChanged);
  341     connect(m_plot, &CartesianPlot::xScaleChanged, this, &CartesianPlotDock::plotXScaleChanged);
  342     connect(m_plot, &CartesianPlot::xRangeFormatChanged, this, &CartesianPlotDock::plotXRangeFormatChanged);
  343     connect(m_plot, &CartesianPlot::yAutoScaleChanged, this, &CartesianPlotDock::plotYAutoScaleChanged);
  344     connect(m_plot, &CartesianPlot::yMinChanged, this, &CartesianPlotDock::plotYMinChanged);
  345     connect(m_plot, &CartesianPlot::yMaxChanged, this, &CartesianPlotDock::plotYMaxChanged);
  346     connect(m_plot, &CartesianPlot::yScaleChanged, this, &CartesianPlotDock::plotYScaleChanged);
  347     connect(m_plot, &CartesianPlot::yRangeFormatChanged, this, &CartesianPlotDock::plotYRangeFormatChanged);
  348     connect(m_plot, &CartesianPlot::visibleChanged, this, &CartesianPlotDock::plotVisibleChanged);
  349 
  350     //range breaks
  351     connect(m_plot, &CartesianPlot::xRangeBreakingEnabledChanged, this, &CartesianPlotDock::plotXRangeBreakingEnabledChanged);
  352     connect(m_plot, &CartesianPlot::xRangeBreaksChanged, this, &CartesianPlotDock::plotXRangeBreaksChanged);
  353     connect(m_plot, &CartesianPlot::yRangeBreakingEnabledChanged, this, &CartesianPlotDock::plotYRangeBreakingEnabledChanged);
  354     connect(m_plot, &CartesianPlot::yRangeBreaksChanged, this, &CartesianPlotDock::plotYRangeBreaksChanged);
  355 
  356     // Plot Area
  357     connect(m_plot->plotArea(), &PlotArea::backgroundTypeChanged, this, &CartesianPlotDock::plotBackgroundTypeChanged);
  358     connect(m_plot->plotArea(), &PlotArea::backgroundColorStyleChanged, this, &CartesianPlotDock::plotBackgroundColorStyleChanged);
  359     connect(m_plot->plotArea(), &PlotArea::backgroundImageStyleChanged, this, &CartesianPlotDock::plotBackgroundImageStyleChanged);
  360     connect(m_plot->plotArea(), &PlotArea::backgroundBrushStyleChanged, this, &CartesianPlotDock::plotBackgroundBrushStyleChanged);
  361     connect(m_plot->plotArea(), &PlotArea::backgroundFirstColorChanged, this, &CartesianPlotDock::plotBackgroundFirstColorChanged);
  362     connect(m_plot->plotArea(), &PlotArea::backgroundSecondColorChanged, this, &CartesianPlotDock::plotBackgroundSecondColorChanged);
  363     connect(m_plot->plotArea(), &PlotArea::backgroundFileNameChanged, this, &CartesianPlotDock::plotBackgroundFileNameChanged);
  364     connect(m_plot->plotArea(), &PlotArea::backgroundOpacityChanged, this, &CartesianPlotDock::plotBackgroundOpacityChanged);
  365     connect(m_plot->plotArea(), &PlotArea::borderPenChanged, this, &CartesianPlotDock::plotBorderPenChanged);
  366     connect(m_plot->plotArea(), &PlotArea::borderOpacityChanged, this, &CartesianPlotDock::plotBorderOpacityChanged);
  367     connect(m_plot, &CartesianPlot::horizontalPaddingChanged, this, &CartesianPlotDock::plotHorizontalPaddingChanged);
  368     connect(m_plot, &CartesianPlot::verticalPaddingChanged, this, &CartesianPlotDock::plotVerticalPaddingChanged);
  369     connect(m_plot, &CartesianPlot::rightPaddingChanged, this, &CartesianPlotDock::plotRightPaddingChanged);
  370     connect(m_plot, &CartesianPlot::bottomPaddingChanged, this, &CartesianPlotDock::plotBottomPaddingChanged);
  371     connect(m_plot, &CartesianPlot::symmetricPaddingChanged, this, &CartesianPlotDock::plotSymmetricPaddingChanged);
  372 
  373     m_initializing = false;
  374 }
  375 
  376 void CartesianPlotDock::activateTitleTab() {
  377     ui.tabWidget->setCurrentWidget(ui.tabTitle);
  378 }
  379 
  380 /*
  381  * updates the locale in the widgets. called when the application settins are changed.
  382  */
  383 void CartesianPlotDock::updateLocale() {
  384     SET_NUMBER_LOCALE
  385 
  386     //update the QSpinBoxes
  387     ui.sbLeft->setLocale(numberLocale);
  388     ui.sbTop->setLocale(numberLocale);
  389     ui.sbWidth->setLocale(numberLocale);
  390     ui.sbHeight->setLocale(numberLocale);
  391     ui.sbBorderWidth->setLocale(numberLocale);
  392     ui.sbBorderCornerRadius->setLocale(numberLocale);
  393     ui.sbPaddingHorizontal->setLocale(numberLocale);
  394     ui.sbPaddingVertical->setLocale(numberLocale);
  395     ui.sbPaddingRight->setLocale(numberLocale);
  396     ui.sbPaddingBottom->setLocale(numberLocale);
  397 
  398     //update the QLineEdits, avoid the change events
  399     if (m_plot) {
  400         Lock lock(m_initializing);
  401         ui.leRangeFirst->setText(numberLocale.toString(m_plot->rangeFirstValues()));
  402         ui.leRangeLast->setText(numberLocale.toString(m_plot->rangeLastValues()));
  403         ui.leXMin->setText(numberLocale.toString(m_plot->xMin()));
  404         ui.leXMax->setText(numberLocale.toString(m_plot->xMax()));
  405         ui.leYMin->setText(numberLocale.toString(m_plot->yMin()));
  406         ui.leYMax->setText(numberLocale.toString(m_plot->yMax()));
  407     }
  408 
  409     //update the title label
  410     labelWidget->updateLocale();
  411 }
  412 
  413 void CartesianPlotDock::updateUnits() {
  414     const KConfigGroup group = KSharedConfig::openConfig()->group(QLatin1String("Settings_General"));
  415     BaseDock::Units units = (BaseDock::Units)group.readEntry("Units", static_cast<int>(Units::Metric));
  416     if (units == m_units)
  417         return;
  418 
  419     m_units = units;
  420     Lock lock(m_initializing);
  421     QString suffix;
  422     if (m_units == Units::Metric) {
  423         //convert from imperial to metric
  424         m_worksheetUnit = Worksheet::Unit::Centimeter;
  425         suffix = QLatin1String(" cm");
  426         ui.sbLeft->setValue(ui.sbLeft->value()*2.54);
  427         ui.sbTop->setValue(ui.sbTop->value()*2.54);
  428         ui.sbWidth->setValue(ui.sbWidth->value()*2.54);
  429         ui.sbHeight->setValue(ui.sbHeight->value()*2.54);
  430         ui.sbBorderCornerRadius->setValue(ui.sbBorderCornerRadius->value()*2.54);
  431         ui.sbPaddingHorizontal->setValue(ui.sbPaddingHorizontal->value()*2.54);
  432         ui.sbPaddingVertical->setValue(ui.sbPaddingVertical->value()*2.54);
  433         ui.sbPaddingRight->setValue(ui.sbPaddingRight->value()*2.54);
  434         ui.sbPaddingBottom->setValue(ui.sbPaddingBottom->value()*2.54);
  435     } else {
  436         //convert from metric to imperial
  437         m_worksheetUnit = Worksheet::Unit::Inch;
  438         suffix = QLatin1String(" in");
  439         ui.sbLeft->setValue(ui.sbLeft->value()/2.54);
  440         ui.sbTop->setValue(ui.sbTop->value()/2.54);
  441         ui.sbWidth->setValue(ui.sbWidth->value()/2.54);
  442         ui.sbHeight->setValue(ui.sbHeight->value()/2.54);
  443         ui.sbBorderCornerRadius->setValue(ui.sbBorderCornerRadius->value()/2.54);
  444         ui.sbPaddingHorizontal->setValue(ui.sbPaddingHorizontal->value()/2.54);
  445         ui.sbPaddingVertical->setValue(ui.sbPaddingVertical->value()/2.54);
  446         ui.sbPaddingRight->setValue(ui.sbPaddingRight->value()/2.54);
  447         ui.sbPaddingBottom->setValue(ui.sbPaddingBottom->value()/2.54);
  448     }
  449 
  450     ui.sbLeft->setSuffix(suffix);
  451     ui.sbTop->setSuffix(suffix);
  452     ui.sbWidth->setSuffix(suffix);
  453     ui.sbHeight->setSuffix(suffix);
  454     ui.sbBorderCornerRadius->setSuffix(suffix);
  455     ui.sbPaddingHorizontal->setSuffix(suffix);
  456     ui.sbPaddingVertical->setSuffix(suffix);
  457     ui.sbPaddingRight->setSuffix(suffix);
  458     ui.sbPaddingBottom->setSuffix(suffix);
  459 
  460     labelWidget->updateUnits();
  461 }
  462 
  463 //************************************************************
  464 //**** SLOTs for changes triggered in CartesianPlotDock ******
  465 //************************************************************
  466 void CartesianPlotDock::retranslateUi() {
  467     Lock lock(m_initializing);
  468 
  469     //general
  470     ui.cbXRangeFormat->addItem(i18n("Numeric"));
  471     ui.cbXRangeFormat->addItem(i18n("Date and Time"));
  472     ui.cbYRangeFormat->addItem(i18n("Numeric"));
  473     ui.cbYRangeFormat->addItem(i18n("Date and Time"));
  474 
  475     ui.cbXScaling->addItem( i18n("linear") );
  476     ui.cbXScaling->addItem( i18n("log(x)") );
  477     ui.cbXScaling->addItem( i18n("log2(x)") );
  478     ui.cbXScaling->addItem( i18n("ln(x)") );
  479     ui.cbXScaling->addItem( i18n("log(abs(x))") );
  480     ui.cbXScaling->addItem( i18n("log2(abs(x))") );
  481     ui.cbXScaling->addItem( i18n("ln(abs(x))") );
  482 
  483     ui.cbYScaling->addItem( i18n("linear") );
  484     ui.cbYScaling->addItem( i18n("log(y)") );
  485     ui.cbYScaling->addItem( i18n("log2(y)") );
  486     ui.cbYScaling->addItem( i18n("ln(y)") );
  487     ui.cbYScaling->addItem( i18n("log(abs(y))") );
  488     ui.cbYScaling->addItem( i18n("log2(abs(y))") );
  489     ui.cbYScaling->addItem( i18n("ln(abs(y))") );
  490 
  491     //scale breakings
  492     ui.cbXBreakStyle->addItem( i18n("Simple") );
  493     ui.cbXBreakStyle->addItem( i18n("Vertical") );
  494     ui.cbXBreakStyle->addItem( i18n("Sloped") );
  495 
  496     ui.cbYBreakStyle->addItem( i18n("Simple") );
  497     ui.cbYBreakStyle->addItem( i18n("Vertical") );
  498     ui.cbYBreakStyle->addItem( i18n("Sloped") );
  499 
  500     //plot area
  501     ui.cbBackgroundType->addItem(i18n("Color"));
  502     ui.cbBackgroundType->addItem(i18n("Image"));
  503     ui.cbBackgroundType->addItem(i18n("Pattern"));
  504 
  505     ui.cbBackgroundColorStyle->addItem(i18n("Single Color"));
  506     ui.cbBackgroundColorStyle->addItem(i18n("Horizontal Gradient"));
  507     ui.cbBackgroundColorStyle->addItem(i18n("Vertical Gradient"));
  508     ui.cbBackgroundColorStyle->addItem(i18n("Diag. Gradient (From Top Left)"));
  509     ui.cbBackgroundColorStyle->addItem(i18n("Diag. Gradient (From Bottom Left)"));
  510     ui.cbBackgroundColorStyle->addItem(i18n("Radial Gradient"));
  511 
  512     ui.cbBackgroundImageStyle->addItem(i18n("Scaled and Cropped"));
  513     ui.cbBackgroundImageStyle->addItem(i18n("Scaled"));
  514     ui.cbBackgroundImageStyle->addItem(i18n("Scaled, Keep Proportions"));
  515     ui.cbBackgroundImageStyle->addItem(i18n("Centered"));
  516     ui.cbBackgroundImageStyle->addItem(i18n("Tiled"));
  517     ui.cbBackgroundImageStyle->addItem(i18n("Center Tiled"));
  518 
  519     GuiTools::updatePenStyles(ui.cbBorderStyle, Qt::black);
  520     GuiTools::updateBrushStyles(ui.cbBackgroundBrushStyle, Qt::SolidPattern);
  521 
  522     QString suffix;
  523     if (m_units == Units::Metric)
  524         suffix = QLatin1String(" cm");
  525     else
  526         suffix = QLatin1String(" in");
  527 
  528     ui.sbLeft->setSuffix(suffix);
  529     ui.sbTop->setSuffix(suffix);
  530     ui.sbWidth->setSuffix(suffix);
  531     ui.sbHeight->setSuffix(suffix);
  532     ui.sbBorderCornerRadius->setSuffix(suffix);
  533     ui.sbPaddingHorizontal->setSuffix(suffix);
  534     ui.sbPaddingVertical->setSuffix(suffix);
  535     ui.sbPaddingRight->setSuffix(suffix);
  536     ui.sbPaddingBottom->setSuffix(suffix);
  537 }
  538 
  539 // "General"-tab
  540 void CartesianPlotDock::visibilityChanged(bool state) {
  541     if (m_initializing)
  542         return;
  543 
  544     for (auto* plot : m_plotList)
  545         plot->setVisible(state);
  546 }
  547 
  548 void CartesianPlotDock::geometryChanged() {
  549     if (m_initializing)
  550         return;
  551 
  552     double x = Worksheet::convertToSceneUnits(ui.sbLeft->value(), m_worksheetUnit);
  553     double y = Worksheet::convertToSceneUnits(ui.sbTop->value(), m_worksheetUnit);
  554     double w = Worksheet::convertToSceneUnits(ui.sbWidth->value(), m_worksheetUnit);
  555     double h = Worksheet::convertToSceneUnits(ui.sbHeight->value(), m_worksheetUnit);
  556 
  557     QRectF rect(x, y, w, h);
  558     m_plot->setRect(rect);
  559 }
  560 
  561 /*!
  562     Called when the layout in the worksheet gets changed.
  563     Enables/disables the geometry widgets if the layout was deactivated/activated.
  564     Shows the new geometry values of the first plot if the layout was activated.
  565  */
  566 void CartesianPlotDock::layoutChanged(Worksheet::Layout layout) {
  567     bool b = (layout == Worksheet::Layout::NoLayout);
  568     ui.sbTop->setEnabled(b);
  569     ui.sbLeft->setEnabled(b);
  570     ui.sbWidth->setEnabled(b);
  571     ui.sbHeight->setEnabled(b);
  572 }
  573 
  574 void CartesianPlotDock::rangeTypeChanged() {
  575     CartesianPlot::RangeType type;
  576     if (ui.rbRangeFirst->isChecked()) {
  577         ui.leRangeFirst->setEnabled(true);
  578         ui.leRangeLast->setEnabled(false);
  579         type = CartesianPlot::RangeType::First;
  580     } else if (ui.rbRangeLast->isChecked()) {
  581         ui.leRangeFirst->setEnabled(false);
  582         ui.leRangeLast->setEnabled(true);
  583         type = CartesianPlot::RangeType::Last;
  584     } else {
  585         ui.leRangeFirst->setEnabled(false);
  586         ui.leRangeLast->setEnabled(false);
  587         type = CartesianPlot::RangeType::Free;
  588     }
  589 
  590     if (m_initializing)
  591         return;
  592 
  593     for (auto* plot : m_plotList)
  594         plot->setRangeType(type);
  595 }
  596 
  597 void CartesianPlotDock::rangeFirstChanged(const QString& text) {
  598     if (m_initializing)
  599         return;
  600 
  601     const int value = text.toInt();
  602     for (auto* plot : m_plotList)
  603         plot->setRangeFirstValues(value);
  604 }
  605 
  606 void CartesianPlotDock::rangeLastChanged(const QString& text) {
  607     if (m_initializing)
  608         return;
  609 
  610     const int value = text.toInt();
  611     for (auto* plot : m_plotList)
  612         plot->setRangeLastValues(value);
  613 }
  614 
  615 void CartesianPlotDock::autoScaleXChanged(int state) {
  616     bool checked = (state == Qt::Checked);
  617     ui.cbXRangeFormat->setEnabled(!checked);
  618     ui.leXMin->setEnabled(!checked);
  619     ui.leXMax->setEnabled(!checked);
  620     ui.dateTimeEditXMin->setEnabled(!checked);
  621     ui.dateTimeEditXMax->setEnabled(!checked);
  622 
  623     if (m_initializing)
  624         return;
  625 
  626     for (auto* plot : m_plotList)
  627         plot->setAutoScaleX(checked);
  628 }
  629 
  630 void CartesianPlotDock::xMinChanged(const QString& value) {
  631     if (m_initializing)
  632         return;
  633 
  634     const Lock lock(m_initializing);
  635     bool ok;
  636     SET_NUMBER_LOCALE
  637     const double xMin = numberLocale.toDouble(value, &ok);
  638     if (ok) {
  639         for (auto* plot : m_plotList)
  640             plot->setXMin(xMin);
  641     }
  642 }
  643 
  644 void CartesianPlotDock::xMaxChanged(const QString& value) {
  645     if (m_initializing)
  646         return;
  647 
  648     const Lock lock(m_initializing);
  649     bool ok;
  650     SET_NUMBER_LOCALE
  651     const double xMax = numberLocale.toDouble(value, &ok);
  652     if (ok) {
  653         for (auto* plot : m_plotList)
  654             plot->setXMax(xMax);
  655     }
  656 }
  657 
  658 void CartesianPlotDock::xMinDateTimeChanged(const QDateTime& dateTime) {
  659     if (m_initializing)
  660         return;
  661 
  662     quint64 value = dateTime.toMSecsSinceEpoch();
  663     for (auto* plot : m_plotList)
  664         plot->setXMin(value);
  665 }
  666 
  667 void CartesianPlotDock::xMaxDateTimeChanged(const QDateTime& dateTime) {
  668     if (m_initializing)
  669         return;
  670 
  671     quint64 value = dateTime.toMSecsSinceEpoch();
  672     for (auto* plot : m_plotList)
  673         plot->setXMax(value);
  674 }
  675 
  676 /*!
  677     called on scale changes (linear, log) for the x-axis
  678  */
  679 void CartesianPlotDock::xScaleChanged(int index) {
  680     if (m_initializing)
  681         return;
  682 
  683     auto scale = static_cast<CartesianPlot::Scale>(index);
  684     for (auto* plot : m_plotList)
  685         plot->setXScale(scale);
  686 }
  687 
  688 void CartesianPlotDock::xRangeFormatChanged(int index) {
  689     bool numeric = (index == 0);
  690 
  691     ui.lXMin->setVisible(numeric);
  692     ui.leXMin->setVisible(numeric);
  693     ui.lXMax->setVisible(numeric);
  694     ui.leXMax->setVisible(numeric);
  695 
  696     ui.lXMinDateTime->setVisible(!numeric);
  697     ui.dateTimeEditXMin->setVisible(!numeric);
  698     ui.lXMaxDateTime->setVisible(!numeric);
  699     ui.dateTimeEditXMax->setVisible(!numeric);
  700 
  701     if (m_initializing)
  702         return;
  703 
  704     auto format = (CartesianPlot::RangeFormat)index;
  705     for (auto* plot : m_plotList)
  706         plot->setXRangeFormat(format);
  707 }
  708 
  709 void CartesianPlotDock::autoScaleYChanged(int state) {
  710     bool checked = (state == Qt::Checked);
  711     ui.cbYRangeFormat->setEnabled(!checked);
  712     ui.leYMin->setEnabled(!checked);
  713     ui.leYMax->setEnabled(!checked);
  714     ui.dateTimeEditYMin->setEnabled(!checked);
  715     ui.dateTimeEditYMax->setEnabled(!checked);
  716 
  717     if (m_initializing)
  718         return;
  719 
  720     for (auto* plot : m_plotList)
  721         plot->setAutoScaleY(checked);
  722 }
  723 
  724 void CartesianPlotDock::yMinChanged(const QString& value) {
  725     if (m_initializing)
  726         return;
  727 
  728     const Lock lock(m_initializing);
  729     bool ok;
  730     SET_NUMBER_LOCALE
  731     const double yMin = numberLocale.toDouble(value, &ok);
  732     if (ok) {
  733         for (auto* plot : m_plotList)
  734             plot->setYMin(yMin);
  735     }
  736 }
  737 
  738 void CartesianPlotDock::yMaxChanged(const QString& value) {
  739     if (m_initializing)
  740         return;
  741 
  742     const Lock lock(m_initializing);
  743     bool ok;
  744     SET_NUMBER_LOCALE
  745     const double yMax = numberLocale.toDouble(value, &ok);
  746     if (ok) {
  747         for (auto* plot : m_plotList)
  748             plot->setYMax(yMax);
  749     }
  750 }
  751 
  752 void CartesianPlotDock::yMinDateTimeChanged(const QDateTime& dateTime) {
  753     if (m_initializing)
  754         return;
  755 
  756     quint64 value = dateTime.toMSecsSinceEpoch();
  757     for (auto* plot : m_plotList)
  758         plot->setXMin(value);
  759 }
  760 
  761 void CartesianPlotDock::yMaxDateTimeChanged(const QDateTime& dateTime) {
  762     if (m_initializing)
  763         return;
  764 
  765     quint64 value = dateTime.toMSecsSinceEpoch();
  766     for (auto* plot : m_plotList)
  767         plot->setXMax(value);
  768 }
  769 
  770 /*!
  771     called on scale changes (linear, log) for the y-axis
  772  */
  773 void CartesianPlotDock::yScaleChanged(int index) {
  774     if (m_initializing)
  775         return;
  776 
  777     auto scale = static_cast<CartesianPlot::Scale>(index);
  778     for (auto* plot : m_plotList)
  779         plot->setYScale(scale);
  780 }
  781 
  782 void CartesianPlotDock::yRangeFormatChanged(int index) {
  783     bool numeric = (index == 0);
  784 
  785     ui.lYMin->setVisible(numeric);
  786     ui.leYMin->setVisible(numeric);
  787     ui.lYMax->setVisible(numeric);
  788     ui.leYMax->setVisible(numeric);
  789 
  790     ui.lYMinDateTime->setVisible(!numeric);
  791     ui.dateTimeEditYMin->setVisible(!numeric);
  792     ui.lYMaxDateTime->setVisible(!numeric);
  793     ui.dateTimeEditYMax->setVisible(!numeric);
  794 
  795     if (m_initializing)
  796         return;
  797 
  798     auto format = (CartesianPlot::RangeFormat)index;
  799     for (auto* plot : m_plotList)
  800         plot->setYRangeFormat(format);
  801 }
  802 
  803 // "Range Breaks"-tab
  804 
  805 // x-range breaks
  806 void CartesianPlotDock::toggleXBreak(bool b) {
  807     ui.frameXBreakEdit->setEnabled(b);
  808     ui.leXBreakStart->setEnabled(b);
  809     ui.leXBreakEnd->setEnabled(b);
  810     ui.sbXBreakPosition->setEnabled(b);
  811     ui.cbXBreakStyle->setEnabled(b);
  812 
  813     if (m_initializing)
  814         return;
  815 
  816     for (auto* plot : m_plotList)
  817         plot->setXRangeBreakingEnabled(b);
  818 }
  819 
  820 void CartesianPlotDock::addXBreak() {
  821     ui.bRemoveXBreak->setVisible(true);
  822 
  823     CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks();
  824     CartesianPlot::RangeBreak b;
  825     breaks.list<<b;
  826     breaks.lastChanged = breaks.list.size() - 1;
  827     for (auto* plot : m_plotList)
  828         plot->setXRangeBreaks(breaks);
  829 
  830     ui.cbXBreak->addItem(QString::number(ui.cbXBreak->count() + 1));
  831     ui.cbXBreak->setCurrentIndex(ui.cbXBreak->count()-1);
  832 }
  833 
  834 void CartesianPlotDock::removeXBreak() {
  835     ui.bRemoveXBreak->setVisible(m_plot->xRangeBreaks().list.size()>1);
  836     int index = ui.cbXBreak->currentIndex();
  837     CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks();
  838     breaks.list.takeAt(index);
  839     breaks.lastChanged = -1;
  840     for (auto* plot : m_plotList)
  841         plot->setXRangeBreaks(breaks);
  842 
  843     ui.cbXBreak->clear();
  844     for (int i = 1; i <= breaks.list.size(); ++i)
  845         ui.cbXBreak->addItem(QString::number(i));
  846 
  847     if (index < ui.cbXBreak->count()-1)
  848         ui.cbXBreak->setCurrentIndex(index);
  849     else
  850         ui.cbXBreak->setCurrentIndex(ui.cbXBreak->count()-1);
  851 
  852     ui.bRemoveXBreak->setVisible(ui.cbXBreak->count()!=1);
  853 }
  854 
  855 void CartesianPlotDock::currentXBreakChanged(int index) {
  856     if (m_initializing)
  857         return;
  858 
  859     if (index == -1)
  860         return;
  861 
  862     m_initializing = true;
  863     SET_NUMBER_LOCALE
  864     const CartesianPlot::RangeBreak rangeBreak = m_plot->xRangeBreaks().list.at(index);
  865     QString str = std::isnan(rangeBreak.start) ? QString() : numberLocale.toString(rangeBreak.start);
  866     ui.leXBreakStart->setText(str);
  867     str = std::isnan(rangeBreak.end) ? QString() : numberLocale.toString(rangeBreak.end);
  868     ui.leXBreakEnd->setText(str);
  869     ui.sbXBreakPosition->setValue(rangeBreak.position*100);
  870     ui.cbXBreakStyle->setCurrentIndex((int)rangeBreak.style);
  871     m_initializing = false;
  872 }
  873 
  874 void CartesianPlotDock::xBreakStartChanged() {
  875     if (m_initializing)
  876         return;
  877 
  878     int index = ui.cbXBreak->currentIndex();
  879     CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks();
  880     breaks.list[index].start = ui.leXBreakStart->text().toDouble();
  881     breaks.lastChanged = index;
  882 
  883     for (auto* plot : m_plotList)
  884         plot->setXRangeBreaks(breaks);
  885 }
  886 
  887 void CartesianPlotDock::xBreakEndChanged() {
  888     if (m_initializing)
  889         return;
  890 
  891     int index = ui.cbXBreak->currentIndex();
  892     CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks();
  893     breaks.list[index].end = ui.leXBreakEnd->text().toDouble();
  894     breaks.lastChanged = index;
  895 
  896     for (auto* plot : m_plotList)
  897         plot->setXRangeBreaks(breaks);
  898 }
  899 
  900 void CartesianPlotDock::xBreakPositionChanged(int value) {
  901     if (m_initializing)
  902         return;
  903 
  904     int index = ui.cbXBreak->currentIndex();
  905     CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks();
  906     breaks.list[index].position = (float)value/100.;
  907     breaks.lastChanged = index;
  908 
  909     for (auto* plot : m_plotList)
  910         plot->setXRangeBreaks(breaks);
  911 }
  912 
  913 void CartesianPlotDock::xBreakStyleChanged(int styleIndex) {
  914     if (m_initializing)
  915         return;
  916 
  917     int index = ui.cbXBreak->currentIndex();
  918     auto style = CartesianPlot::RangeBreakStyle(styleIndex);
  919     CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks();
  920     breaks.list[index].style = style;
  921     breaks.lastChanged = index;
  922 
  923     for (auto* plot : m_plotList)
  924         plot->setXRangeBreaks(breaks);
  925 }
  926 
  927 // y-range breaks
  928 void CartesianPlotDock::toggleYBreak(bool b) {
  929     ui.frameYBreakEdit->setEnabled(b);
  930     ui.leYBreakStart->setEnabled(b);
  931     ui.leYBreakEnd->setEnabled(b);
  932     ui.sbYBreakPosition->setEnabled(b);
  933     ui.cbYBreakStyle->setEnabled(b);
  934 
  935     if (m_initializing)
  936         return;
  937 
  938     for (auto* plot : m_plotList)
  939         plot->setYRangeBreakingEnabled(b);
  940 }
  941 
  942 void CartesianPlotDock::addYBreak() {
  943     ui.bRemoveYBreak->setVisible(true);
  944 
  945     CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks();
  946     CartesianPlot::RangeBreak b;
  947     breaks.list << b;
  948     breaks.lastChanged = breaks.list.size() - 1;
  949     for (auto* plot : m_plotList)
  950         plot->setYRangeBreaks(breaks);
  951 
  952     ui.cbYBreak->addItem(QString::number(ui.cbYBreak->count() + 1));
  953     ui.cbYBreak->setCurrentIndex(ui.cbYBreak->count()-1);
  954 }
  955 
  956 void CartesianPlotDock::removeYBreak() {
  957     ui.bRemoveYBreak->setVisible(m_plot->yRangeBreaks().list.size() > 1);
  958     int index = ui.cbYBreak->currentIndex();
  959     CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks();
  960     breaks.list.takeAt(index);
  961     breaks.lastChanged = -1;
  962     for (auto* plot : m_plotList)
  963         plot->setYRangeBreaks(breaks);
  964 
  965     ui.cbYBreak->clear();
  966     for (int i = 1; i <= breaks.list.size(); ++i)
  967         ui.cbYBreak->addItem(QString::number(i));
  968 
  969     if (index < ui.cbYBreak->count()-1)
  970         ui.cbYBreak->setCurrentIndex(index);
  971     else
  972         ui.cbYBreak->setCurrentIndex(ui.cbYBreak->count()-1);
  973 
  974     ui.bRemoveYBreak->setVisible(ui.cbYBreak->count() != 1);
  975 }
  976 
  977 void CartesianPlotDock::currentYBreakChanged(int index) {
  978     if (m_initializing)
  979         return;
  980 
  981     if (index == -1)
  982         return;
  983 
  984     m_initializing = true;
  985     SET_NUMBER_LOCALE
  986     const CartesianPlot::RangeBreak rangeBreak = m_plot->yRangeBreaks().list.at(index);
  987     QString str = std::isnan(rangeBreak.start) ? QString() : numberLocale.toString(rangeBreak.start);
  988     ui.leYBreakStart->setText(str);
  989     str = std::isnan(rangeBreak.end) ? QString() : numberLocale.toString(rangeBreak.end);
  990     ui.leYBreakEnd->setText(str);
  991     ui.sbYBreakPosition->setValue(rangeBreak.position*100);
  992     ui.cbYBreakStyle->setCurrentIndex((int)rangeBreak.style);
  993     m_initializing = false;
  994 }
  995 
  996 void CartesianPlotDock::yBreakStartChanged() {
  997     if (m_initializing)
  998         return;
  999 
 1000     int index = ui.cbYBreak->currentIndex();
 1001     CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks();
 1002     breaks.list[index].start = ui.leYBreakStart->text().toDouble();
 1003     breaks.lastChanged = index;
 1004 
 1005     for (auto* plot : m_plotList)
 1006         plot->setYRangeBreaks(breaks);
 1007 }
 1008 
 1009 void CartesianPlotDock::yBreakEndChanged() {
 1010     if (m_initializing)
 1011         return;
 1012 
 1013     int index = ui.cbYBreak->currentIndex();
 1014     CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks();
 1015     breaks.list[index].end = ui.leYBreakEnd->text().toDouble();
 1016     breaks.lastChanged = index;
 1017 
 1018     for (auto* plot : m_plotList)
 1019         plot->setYRangeBreaks(breaks);
 1020 }
 1021 
 1022 void CartesianPlotDock::yBreakPositionChanged(int value) {
 1023     if (m_initializing)
 1024         return;
 1025 
 1026     int index = ui.cbYBreak->currentIndex();
 1027     CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks();
 1028     breaks.list[index].position = (float)value/100.;
 1029     breaks.lastChanged = index;
 1030 
 1031     for (auto* plot : m_plotList)
 1032         plot->setYRangeBreaks(breaks);
 1033 }
 1034 
 1035 void CartesianPlotDock::yBreakStyleChanged(int styleIndex) {
 1036     if (m_initializing)
 1037         return;
 1038 
 1039     int index = ui.cbYBreak->currentIndex();
 1040     auto style = CartesianPlot::RangeBreakStyle(styleIndex);
 1041     CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks();
 1042     breaks.list[index].style = style;
 1043     breaks.lastChanged = index;
 1044 
 1045     for (auto* plot : m_plotList)
 1046         plot->setYRangeBreaks(breaks);
 1047 }
 1048 
 1049 // "Plot area"-tab
 1050 void CartesianPlotDock::backgroundTypeChanged(int index) {
 1051     auto type = (PlotArea::BackgroundType)index;
 1052 
 1053     if (type == PlotArea::BackgroundType::Color) {
 1054         ui.lBackgroundColorStyle->show();
 1055         ui.cbBackgroundColorStyle->show();
 1056         ui.lBackgroundImageStyle->hide();
 1057         ui.cbBackgroundImageStyle->hide();
 1058         ui.lBackgroundBrushStyle->hide();
 1059         ui.cbBackgroundBrushStyle->hide();
 1060 
 1061         ui.lBackgroundFileName->hide();
 1062         ui.leBackgroundFileName->hide();
 1063         ui.bOpen->hide();
 1064 
 1065         ui.lBackgroundFirstColor->show();
 1066         ui.kcbBackgroundFirstColor->show();
 1067 
 1068         auto style = (PlotArea::BackgroundColorStyle) ui.cbBackgroundColorStyle->currentIndex();
 1069         if (style == PlotArea::BackgroundColorStyle::SingleColor) {
 1070             ui.lBackgroundFirstColor->setText(i18n("Color:"));
 1071             ui.lBackgroundSecondColor->hide();
 1072             ui.kcbBackgroundSecondColor->hide();
 1073         } else {
 1074             ui.lBackgroundFirstColor->setText(i18n("First color:"));
 1075             ui.lBackgroundSecondColor->show();
 1076             ui.kcbBackgroundSecondColor->show();
 1077         }
 1078     } else if (type == PlotArea::BackgroundType::Image) {
 1079         ui.lBackgroundColorStyle->hide();
 1080         ui.cbBackgroundColorStyle->hide();
 1081         ui.lBackgroundImageStyle->show();
 1082         ui.cbBackgroundImageStyle->show();
 1083         ui.lBackgroundBrushStyle->hide();
 1084         ui.cbBackgroundBrushStyle->hide();
 1085         ui.lBackgroundFileName->show();
 1086         ui.leBackgroundFileName->show();
 1087         ui.bOpen->show();
 1088 
 1089         ui.lBackgroundFirstColor->hide();
 1090         ui.kcbBackgroundFirstColor->hide();
 1091         ui.lBackgroundSecondColor->hide();
 1092         ui.kcbBackgroundSecondColor->hide();
 1093     } else if (type == PlotArea::BackgroundType::Pattern) {
 1094         ui.lBackgroundFirstColor->setText(i18n("Color:"));
 1095         ui.lBackgroundColorStyle->hide();
 1096         ui.cbBackgroundColorStyle->hide();
 1097         ui.lBackgroundImageStyle->hide();
 1098         ui.cbBackgroundImageStyle->hide();
 1099         ui.lBackgroundBrushStyle->show();
 1100         ui.cbBackgroundBrushStyle->show();
 1101         ui.lBackgroundFileName->hide();
 1102         ui.leBackgroundFileName->hide();
 1103         ui.bOpen->hide();
 1104 
 1105         ui.lBackgroundFirstColor->show();
 1106         ui.kcbBackgroundFirstColor->show();
 1107         ui.lBackgroundSecondColor->hide();
 1108         ui.kcbBackgroundSecondColor->hide();
 1109     }
 1110 
 1111     if (m_initializing)
 1112         return;
 1113 
 1114     for (auto* plot : m_plotList)
 1115         plot->plotArea()->setBackgroundType(type);
 1116 }
 1117 
 1118 void CartesianPlotDock::backgroundColorStyleChanged(int index) {
 1119     auto style = (PlotArea::BackgroundColorStyle)index;
 1120 
 1121     if (style == PlotArea::BackgroundColorStyle::SingleColor) {
 1122         ui.lBackgroundFirstColor->setText(i18n("Color:"));
 1123         ui.lBackgroundSecondColor->hide();
 1124         ui.kcbBackgroundSecondColor->hide();
 1125     } else {
 1126         ui.lBackgroundFirstColor->setText(i18n("First color:"));
 1127         ui.lBackgroundSecondColor->show();
 1128         ui.kcbBackgroundSecondColor->show();
 1129         ui.lBackgroundBrushStyle->hide();
 1130         ui.cbBackgroundBrushStyle->hide();
 1131     }
 1132 
 1133     if (m_initializing)
 1134         return;
 1135 
 1136     for (auto* plot : m_plotList)
 1137         plot->plotArea()->setBackgroundColorStyle(style);
 1138 }
 1139 
 1140 void CartesianPlotDock::backgroundImageStyleChanged(int index) {
 1141     if (m_initializing)
 1142         return;
 1143 
 1144     auto style = (PlotArea::BackgroundImageStyle)index;
 1145     for (auto* plot : m_plotList)
 1146         plot->plotArea()->setBackgroundImageStyle(style);
 1147 }
 1148 
 1149 void CartesianPlotDock::backgroundBrushStyleChanged(int index) {
 1150     if (m_initializing)
 1151         return;
 1152 
 1153     auto style = (Qt::BrushStyle)index;
 1154     for (auto* plot : m_plotList)
 1155         plot->plotArea()->setBackgroundBrushStyle(style);
 1156 }
 1157 
 1158 void CartesianPlotDock::backgroundFirstColorChanged(const QColor& c) {
 1159     if (m_initializing)
 1160         return;
 1161 
 1162     for (auto* plot : m_plotList)
 1163         plot->plotArea()->setBackgroundFirstColor(c);
 1164 }
 1165 
 1166 void CartesianPlotDock::backgroundSecondColorChanged(const QColor& c) {
 1167     if (m_initializing)
 1168         return;
 1169 
 1170     for (auto* plot : m_plotList)
 1171         plot->plotArea()->setBackgroundSecondColor(c);
 1172 }
 1173 
 1174 /*!
 1175     opens a file dialog and lets the user select the image file.
 1176 */
 1177 void CartesianPlotDock::selectFile() {
 1178     KConfigGroup conf(KSharedConfig::openConfig(), "CartesianPlotDock");
 1179     QString dir = conf.readEntry("LastImageDir", "");
 1180 
 1181     QString formats;
 1182     for (const auto& format : QImageReader::supportedImageFormats()) {
 1183         QString f = "*." + QString(format.constData());
 1184         if (f == QLatin1String("*.svg"))
 1185             continue;
 1186         formats.isEmpty() ? formats += f : formats += ' ' + f;
 1187     }
 1188 
 1189     QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats));
 1190     if (path.isEmpty())
 1191         return; //cancel was clicked in the file-dialog
 1192 
 1193     int pos = path.lastIndexOf(QLatin1String("/"));
 1194     if (pos != -1) {
 1195         QString newDir{path.left(pos)};
 1196         if (newDir != dir)
 1197             conf.writeEntry("LastImageDir", newDir);
 1198     }
 1199 
 1200     ui.leBackgroundFileName->setText(path);
 1201 
 1202     for (auto* plot : m_plotList)
 1203         plot->plotArea()->setBackgroundFileName(path);
 1204 }
 1205 
 1206 void CartesianPlotDock::fileNameChanged() {
 1207     if (m_initializing)
 1208         return;
 1209 
 1210     const QString& fileName = ui.leBackgroundFileName->text();
 1211     bool invalid = (!fileName.isEmpty() && !QFile::exists(fileName));
 1212     GuiTools::highlight(ui.leBackgroundFileName, invalid);
 1213 
 1214     for (auto* plot : m_plotList)
 1215         plot->plotArea()->setBackgroundFileName(fileName);
 1216 }
 1217 
 1218 void CartesianPlotDock::backgroundOpacityChanged(int value) {
 1219     if (m_initializing)
 1220         return;
 1221 
 1222     qreal opacity = (float)value/100.;
 1223     for (auto* plot : m_plotList)
 1224         plot->plotArea()->setBackgroundOpacity(opacity);
 1225 }
 1226 
 1227 // "Border"-tab
 1228 void CartesianPlotDock::borderStyleChanged(int index) {
 1229     if (m_initializing)
 1230         return;
 1231 
 1232     auto penStyle = Qt::PenStyle(index);
 1233     QPen pen;
 1234     for (auto* plot : m_plotList) {
 1235         pen = plot->plotArea()->borderPen();
 1236         pen.setStyle(penStyle);
 1237         plot->plotArea()->setBorderPen(pen);
 1238     }
 1239 }
 1240 
 1241 void CartesianPlotDock::borderColorChanged(const QColor& color) {
 1242     if (m_initializing)
 1243         return;
 1244 
 1245     QPen pen;
 1246     for (auto* plot : m_plotList) {
 1247         pen = plot->plotArea()->borderPen();
 1248         pen.setColor(color);
 1249         plot->plotArea()->setBorderPen(pen);
 1250     }
 1251 
 1252     m_initializing = true;
 1253     GuiTools::updatePenStyles(ui.cbBorderStyle, color);
 1254     m_initializing = false;
 1255 }
 1256 
 1257 void CartesianPlotDock::borderWidthChanged(double value) {
 1258     if (m_initializing)
 1259         return;
 1260 
 1261     QPen pen;
 1262     for (auto* plot : m_plotList) {
 1263         pen = plot->plotArea()->borderPen();
 1264         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
 1265         plot->plotArea()->setBorderPen(pen);
 1266     }
 1267 }
 1268 
 1269 void CartesianPlotDock::borderCornerRadiusChanged(double value) {
 1270     if (m_initializing)
 1271         return;
 1272 
 1273     for (auto* plot : m_plotList)
 1274         plot->plotArea()->setBorderCornerRadius(Worksheet::convertToSceneUnits(value, m_worksheetUnit));
 1275 }
 1276 
 1277 void CartesianPlotDock::borderOpacityChanged(int value) {
 1278     if (m_initializing)
 1279         return;
 1280 
 1281     qreal opacity = (float)value/100.;
 1282     for (auto* plot : m_plotList)
 1283         plot->plotArea()->setBorderOpacity(opacity);
 1284 }
 1285 
 1286 void CartesianPlotDock::symmetricPaddingChanged(bool checked) {
 1287     ui.lPaddingHorizontalRight->setVisible(!checked);
 1288     ui.sbPaddingRight->setVisible(!checked);
 1289     ui.lPaddingVerticalDown->setVisible(!checked);
 1290     ui.sbPaddingBottom->setVisible(!checked);
 1291 
 1292     if (checked) {
 1293         ui.lPaddingHorizontal->setText(i18n("Horizontal:"));
 1294         ui.lPaddingVertical->setText(i18n("Vertical:"));
 1295     } else {
 1296         ui.lPaddingHorizontal->setText(i18n("Left:"));
 1297         ui.lPaddingVertical->setText(i18n("Top:"));
 1298     }
 1299 
 1300     if (m_initializing)
 1301         return;
 1302 
 1303     for (auto* plot : m_plotList)
 1304         plot->setSymmetricPadding(checked);
 1305 
 1306     if (checked) {
 1307         rightPaddingChanged(ui.sbPaddingHorizontal->value());
 1308         bottomPaddingChanged(ui.sbPaddingVertical->value());
 1309     }
 1310 }
 1311 
 1312 void CartesianPlotDock::horizontalPaddingChanged(double value) {
 1313     if (m_initializing)
 1314         return;
 1315     double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit);
 1316     for (auto* plot : m_plotList)
 1317         plot->setHorizontalPadding(padding);
 1318 
 1319     if (m_plot->symmetricPadding()) {
 1320         for (auto* plot: m_plotList)
 1321             plot->setRightPadding(padding);
 1322     }
 1323 }
 1324 
 1325 void CartesianPlotDock::rightPaddingChanged(double value) {
 1326     if (m_initializing)
 1327         return;
 1328     double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit);
 1329     for (auto* plot : m_plotList)
 1330         plot->setRightPadding(padding);
 1331 }
 1332 
 1333 void CartesianPlotDock::verticalPaddingChanged(double value) {
 1334     if (m_initializing)
 1335         return;
 1336 
 1337     // TODO: find better solution (set spinbox range). When plot->rect().width() does change?
 1338     double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit);
 1339     for (auto* plot : m_plotList)
 1340         plot->setVerticalPadding(padding);
 1341 
 1342     if (m_plot->symmetricPadding()) {
 1343         for (auto* plot: m_plotList)
 1344             plot->setBottomPadding(padding);
 1345     }
 1346 }
 1347 
 1348 void CartesianPlotDock::bottomPaddingChanged(double value) {
 1349     if (m_initializing)
 1350         return;
 1351     double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit);
 1352     for (auto* plot : m_plotList)
 1353         plot->setBottomPadding(padding);
 1354 }
 1355 
 1356 void CartesianPlotDock::cursorLineWidthChanged(int width) {
 1357     if (m_initializing)
 1358         return;
 1359 
 1360     for (auto* plot : m_plotList) {
 1361         QPen pen = plot->cursorPen();
 1362         pen.setWidthF( Worksheet::convertToSceneUnits(width, Worksheet::Unit::Point) );
 1363         plot->setCursorPen(pen);
 1364     }
 1365 }
 1366 
 1367 void CartesianPlotDock::cursorLineColorChanged(const QColor& color) {
 1368     if (m_initializing)
 1369         return;
 1370 
 1371     for (auto* plot : m_plotList) {
 1372         QPen pen = plot->cursorPen();
 1373         pen.setColor(color);
 1374         plot->setCursorPen(pen);
 1375     }
 1376 
 1377     m_initializing = true;
 1378     GuiTools::updatePenStyles(ui.cbCursorLineStyle, color);
 1379     m_initializing = false;
 1380 }
 1381 
 1382 void CartesianPlotDock::cursorLineStyleChanged(int index) {
 1383     if (m_initializing)
 1384         return;
 1385 
 1386     if (index > 5)
 1387         return;
 1388 
 1389     for (auto* plot : m_plotList) {
 1390         QPen pen = plot->cursorPen();
 1391         pen.setStyle(static_cast<Qt::PenStyle>(index));
 1392         plot->setCursorPen(pen);
 1393     }
 1394 }
 1395 
 1396 //*************************************************************
 1397 //****** SLOTs for changes triggered in CartesianPlot *********
 1398 //*************************************************************
 1399 //general
 1400 void CartesianPlotDock::plotDescriptionChanged(const AbstractAspect* aspect) {
 1401     if (m_plot != aspect)
 1402         return;
 1403 
 1404     m_initializing = true;
 1405     if (aspect->name() != ui.leName->text())
 1406         ui.leName->setText(aspect->name());
 1407     else if (aspect->comment() != ui.leComment->text())
 1408         ui.leComment->setText(aspect->comment());
 1409     m_initializing = false;
 1410 }
 1411 
 1412 void CartesianPlotDock::plotRectChanged(QRectF& rect) {
 1413     m_initializing = true;
 1414     ui.sbLeft->setValue(Worksheet::convertFromSceneUnits(rect.x(), m_worksheetUnit));
 1415     ui.sbTop->setValue(Worksheet::convertFromSceneUnits(rect.y(), m_worksheetUnit));
 1416     ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(rect.width(), m_worksheetUnit));
 1417     ui.sbHeight->setValue(Worksheet::convertFromSceneUnits(rect.height(), m_worksheetUnit));
 1418     m_initializing = false;
 1419 }
 1420 
 1421 void CartesianPlotDock::plotRangeTypeChanged(CartesianPlot::RangeType type) {
 1422     m_initializing = true;
 1423     switch (type) {
 1424     case CartesianPlot::RangeType::Free:
 1425         ui.rbRangeFree->setChecked(true);
 1426         break;
 1427     case CartesianPlot::RangeType::First:
 1428         ui.rbRangeFirst->setChecked(true);
 1429         break;
 1430     case CartesianPlot::RangeType::Last:
 1431         ui.rbRangeLast->setChecked(true);
 1432         break;
 1433     }
 1434     m_initializing = false;
 1435 }
 1436 
 1437 void CartesianPlotDock::plotRangeFirstValuesChanged(int value) {
 1438     m_initializing = true;
 1439     SET_NUMBER_LOCALE
 1440     ui.leRangeFirst->setText(numberLocale.toString(value));
 1441     m_initializing = false;
 1442 }
 1443 
 1444 void CartesianPlotDock::plotRangeLastValuesChanged(int value) {
 1445     m_initializing = true;
 1446     SET_NUMBER_LOCALE
 1447     ui.leRangeLast->setText(numberLocale.toString(value));
 1448     m_initializing = false;
 1449 }
 1450 
 1451 void CartesianPlotDock::plotXAutoScaleChanged(bool value) {
 1452     m_initializing = true;
 1453     ui.chkAutoScaleX->setChecked(value);
 1454     m_initializing = false;
 1455 }
 1456 
 1457 void CartesianPlotDock::plotXMinChanged(double value) {
 1458     if (m_initializing)
 1459         return;
 1460     const Lock lock(m_initializing);
 1461     SET_NUMBER_LOCALE
 1462     ui.leXMin->setText(numberLocale.toString(value));
 1463     ui.dateTimeEditXMin->setDateTime(QDateTime::fromMSecsSinceEpoch(value));
 1464 }
 1465 
 1466 void CartesianPlotDock::plotXMaxChanged(double value) {
 1467     if (m_initializing)
 1468         return;
 1469     const Lock lock(m_initializing);
 1470     SET_NUMBER_LOCALE
 1471     ui.leXMax->setText(numberLocale.toString(value));
 1472     ui.dateTimeEditXMax->setDateTime( QDateTime::fromMSecsSinceEpoch(value) );
 1473 }
 1474 
 1475 void CartesianPlotDock::plotXScaleChanged(CartesianPlot::Scale scale) {
 1476     m_initializing = true;
 1477     ui.cbXScaling->setCurrentIndex(static_cast<int>(scale));
 1478     m_initializing = false;
 1479 }
 1480 
 1481 void CartesianPlotDock::plotXRangeFormatChanged(CartesianPlot::RangeFormat format) {
 1482     m_initializing = true;
 1483     ui.cbXRangeFormat->setCurrentIndex(static_cast<int>(format));
 1484     m_initializing = false;
 1485 }
 1486 
 1487 void CartesianPlotDock::plotYAutoScaleChanged(bool value) {
 1488     m_initializing = true;
 1489     ui.chkAutoScaleY->setChecked(value);
 1490     m_initializing = false;
 1491 }
 1492 
 1493 void CartesianPlotDock::plotYMinChanged(double value) {
 1494     if (m_initializing)
 1495         return;
 1496     const Lock lock(m_initializing);
 1497     SET_NUMBER_LOCALE
 1498     ui.leYMin->setText(numberLocale.toString(value));
 1499     ui.dateTimeEditYMin->setDateTime( QDateTime::fromMSecsSinceEpoch(value) );
 1500 }
 1501 
 1502 void CartesianPlotDock::plotYMaxChanged(double value) {
 1503     if (m_initializing)
 1504         return;
 1505     const Lock lock(m_initializing);
 1506     SET_NUMBER_LOCALE
 1507     ui.leYMax->setText(numberLocale.toString(value));
 1508     ui.dateTimeEditYMax->setDateTime( QDateTime::fromMSecsSinceEpoch(value) );
 1509 }
 1510 
 1511 void CartesianPlotDock::plotYScaleChanged(CartesianPlot::Scale scale) {
 1512     m_initializing = true;
 1513     ui.cbYScaling->setCurrentIndex(static_cast<int>(scale));
 1514     m_initializing = false;
 1515 }
 1516 
 1517 void CartesianPlotDock::plotYRangeFormatChanged(CartesianPlot::RangeFormat format) {
 1518     m_initializing = true;
 1519     ui.cbYRangeFormat->setCurrentIndex(static_cast<int>(format));
 1520     m_initializing = false;
 1521 }
 1522 
 1523 void CartesianPlotDock::plotVisibleChanged(bool on) {
 1524     m_initializing = true;
 1525     ui.chkVisible->setChecked(on);
 1526     m_initializing = false;
 1527 }
 1528 
 1529 //range breaks
 1530 void CartesianPlotDock::plotXRangeBreakingEnabledChanged(bool on) {
 1531     m_initializing = true;
 1532     ui.chkXBreak->setChecked(on);
 1533     m_initializing = false;
 1534 }
 1535 
 1536 void CartesianPlotDock::plotXRangeBreaksChanged(const CartesianPlot::RangeBreaks& breaks) {
 1537     Q_UNUSED(breaks);
 1538 }
 1539 
 1540 void CartesianPlotDock::plotYRangeBreakingEnabledChanged(bool on) {
 1541     m_initializing = true;
 1542     ui.chkYBreak->setChecked(on);
 1543     m_initializing = false;
 1544 }
 1545 
 1546 void CartesianPlotDock::plotYRangeBreaksChanged(const CartesianPlot::RangeBreaks& breaks) {
 1547     Q_UNUSED(breaks);
 1548 }
 1549 
 1550 //background
 1551 void CartesianPlotDock::plotBackgroundTypeChanged(PlotArea::BackgroundType type) {
 1552     m_initializing = true;
 1553     ui.cbBackgroundType->setCurrentIndex(static_cast<int>(type));
 1554     m_initializing = false;
 1555 }
 1556 
 1557 void CartesianPlotDock::plotBackgroundColorStyleChanged(PlotArea::BackgroundColorStyle style) {
 1558     m_initializing = true;
 1559     ui.cbBackgroundColorStyle->setCurrentIndex(static_cast<int>(style));
 1560     m_initializing = false;
 1561 }
 1562 
 1563 void CartesianPlotDock::plotBackgroundImageStyleChanged(PlotArea::BackgroundImageStyle style) {
 1564     m_initializing = true;
 1565     ui.cbBackgroundImageStyle->setCurrentIndex(static_cast<int>(style));
 1566     m_initializing = false;
 1567 }
 1568 
 1569 void CartesianPlotDock::plotBackgroundBrushStyleChanged(Qt::BrushStyle style) {
 1570     m_initializing = true;
 1571     ui.cbBackgroundBrushStyle->setCurrentIndex(style);
 1572     m_initializing = false;
 1573 }
 1574 
 1575 void CartesianPlotDock::plotBackgroundFirstColorChanged(QColor& color) {
 1576     m_initializing = true;
 1577     ui.kcbBackgroundFirstColor->setColor(color);
 1578     m_initializing = false;
 1579 }
 1580 
 1581 void CartesianPlotDock::plotBackgroundSecondColorChanged(QColor& color) {
 1582     m_initializing = true;
 1583     ui.kcbBackgroundSecondColor->setColor(color);
 1584     m_initializing = false;
 1585 }
 1586 
 1587 void CartesianPlotDock::plotBackgroundFileNameChanged(QString& filename) {
 1588     m_initializing = true;
 1589     ui.leBackgroundFileName->setText(filename);
 1590     m_initializing = false;
 1591 }
 1592 
 1593 void CartesianPlotDock::plotBackgroundOpacityChanged(float opacity) {
 1594     m_initializing = true;
 1595     ui.sbBackgroundOpacity->setValue( round(opacity*100.0) );
 1596     m_initializing = false;
 1597 }
 1598 
 1599 void CartesianPlotDock::plotBorderPenChanged(QPen& pen) {
 1600     m_initializing = true;
 1601     if (ui.cbBorderStyle->currentIndex() != pen.style())
 1602         ui.cbBorderStyle->setCurrentIndex(pen.style());
 1603     if (ui.kcbBorderColor->color() != pen.color())
 1604         ui.kcbBorderColor->setColor(pen.color());
 1605     if (ui.sbBorderWidth->value() != pen.widthF())
 1606         ui.sbBorderWidth->setValue(Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point));
 1607     m_initializing = false;
 1608 }
 1609 
 1610 void CartesianPlotDock::plotBorderCornerRadiusChanged(float value) {
 1611     m_initializing = true;
 1612     ui.sbBorderCornerRadius->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
 1613     m_initializing = false;
 1614 }
 1615 
 1616 void CartesianPlotDock::plotBorderOpacityChanged(float value) {
 1617     m_initializing = true;
 1618     float v = (float)value*100.;
 1619     ui.sbBorderOpacity->setValue(v);
 1620     m_initializing = false;
 1621 }
 1622 
 1623 void CartesianPlotDock::plotHorizontalPaddingChanged(float value) {
 1624     m_initializing = true;
 1625     ui.sbPaddingHorizontal->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
 1626     m_initializing = false;
 1627 }
 1628 
 1629 void CartesianPlotDock::plotVerticalPaddingChanged(float value) {
 1630     m_initializing = true;
 1631     ui.sbPaddingVertical->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
 1632     m_initializing = false;
 1633 }
 1634 
 1635 void CartesianPlotDock::plotRightPaddingChanged(double value) {
 1636     m_initializing = true;
 1637     ui.sbPaddingRight->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
 1638     m_initializing = false;
 1639 }
 1640 
 1641 void CartesianPlotDock::plotBottomPaddingChanged(double value) {
 1642     m_initializing = true;
 1643     ui.sbPaddingBottom->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
 1644     m_initializing = false;
 1645 }
 1646 
 1647 void CartesianPlotDock::plotSymmetricPaddingChanged(bool symmetric) {
 1648     m_initializing = true;
 1649     ui.cbPaddingSymmetric->setChecked(symmetric);
 1650     m_initializing = false;
 1651 }
 1652 
 1653 void CartesianPlotDock::plotCursorPenChanged(const QPen& pen) {
 1654     m_initializing = true;
 1655     ui.sbCursorLineWidth->setValue(Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point));
 1656     ui.kcbCursorLineColor->setColor(pen.color());
 1657     ui.cbCursorLineStyle->setCurrentIndex(pen.style());
 1658     m_initializing = false;
 1659 }
 1660 
 1661 //*************************************************************
 1662 //******************** SETTINGS *******************************
 1663 //*************************************************************
 1664 void CartesianPlotDock::loadConfigFromTemplate(KConfig& config) {
 1665     //extract the name of the template from the file name
 1666     QString name;
 1667     int index = config.name().lastIndexOf(QLatin1String("/"));
 1668     if (index != -1)
 1669         name = config.name().right(config.name().size() - index - 1);
 1670     else
 1671         name = config.name();
 1672 
 1673     int size = m_plotList.size();
 1674     if (size > 1)
 1675         m_plot->beginMacro(i18n("%1 cartesian plots: template \"%2\" loaded", size, name));
 1676     else
 1677         m_plot->beginMacro(i18n("%1: template \"%2\" loaded", m_plot->name(), name));
 1678 
 1679     this->loadConfig(config);
 1680 
 1681     m_plot->endMacro();
 1682 }
 1683 
 1684 void CartesianPlotDock::load() {
 1685     //General-tab
 1686     ui.chkVisible->setChecked(m_plot->isVisible());
 1687     ui.sbLeft->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().x(), m_worksheetUnit));
 1688     ui.sbTop->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().y(), m_worksheetUnit));
 1689     ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().width(), m_worksheetUnit));
 1690     ui.sbHeight->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().height(), m_worksheetUnit));
 1691 
 1692     switch (m_plot->rangeType()) {
 1693     case CartesianPlot::RangeType::Free:
 1694         ui.rbRangeFree->setChecked(true);
 1695         break;
 1696     case CartesianPlot::RangeType::First:
 1697         ui.rbRangeFirst->setChecked(true);
 1698         break;
 1699     case CartesianPlot::RangeType::Last:
 1700         ui.rbRangeLast->setChecked(true);
 1701         break;
 1702     }
 1703     rangeTypeChanged();
 1704     SET_NUMBER_LOCALE
 1705     ui.leRangeFirst->setText( numberLocale.toString(m_plot->rangeFirstValues()) );
 1706     ui.leRangeLast->setText( numberLocale.toString(m_plot->rangeLastValues()) );
 1707 
 1708     ui.chkAutoScaleX->setChecked(m_plot->autoScaleX());
 1709     ui.leXMin->setText(numberLocale.toString(m_plot->xMin()));
 1710     ui.leXMax->setText(numberLocale.toString(m_plot->xMax()));
 1711     ui.dateTimeEditXMin->setDisplayFormat(m_plot->xRangeDateTimeFormat());
 1712     ui.dateTimeEditXMax->setDisplayFormat(m_plot->xRangeDateTimeFormat());
 1713     ui.dateTimeEditXMin->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->xMin()));
 1714     ui.dateTimeEditXMax->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->xMax()));
 1715     ui.cbXScaling->setCurrentIndex( (int) m_plot->xScale() );
 1716     ui.cbXRangeFormat->setCurrentIndex( (int) m_plot->xRangeFormat() );
 1717 
 1718     ui.chkAutoScaleY->setChecked(m_plot->autoScaleY());
 1719     ui.leYMin->setText(numberLocale.toString(m_plot->yMin()));
 1720     ui.leYMax->setText(numberLocale.toString(m_plot->yMax()));
 1721     ui.dateTimeEditYMin->setDisplayFormat(m_plot->yRangeDateTimeFormat());
 1722     ui.dateTimeEditYMax->setDisplayFormat(m_plot->yRangeDateTimeFormat());
 1723     ui.dateTimeEditYMin->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->yMin()));
 1724     ui.dateTimeEditYMax->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->yMax()));
 1725     ui.cbYScaling->setCurrentIndex( (int)m_plot->yScale() );
 1726     ui.cbYRangeFormat->setCurrentIndex( (int) m_plot->yRangeFormat() );
 1727 
 1728     //Title
 1729     labelWidget->load();
 1730 
 1731     //x-range breaks, show the first break
 1732     ui.chkXBreak->setChecked(m_plot->xRangeBreakingEnabled());
 1733     this->toggleXBreak(m_plot->xRangeBreakingEnabled());
 1734     ui.bRemoveXBreak->setVisible(m_plot->xRangeBreaks().list.size() > 1);
 1735     ui.cbXBreak->clear();
 1736     if (!m_plot->xRangeBreaks().list.isEmpty()) {
 1737         for (int i = 1; i <= m_plot->xRangeBreaks().list.size(); ++i)
 1738             ui.cbXBreak->addItem(QString::number(i));
 1739     } else
 1740         ui.cbXBreak->addItem("1");
 1741     ui.cbXBreak->setCurrentIndex(0);
 1742 
 1743     //y-range breaks, show the first break
 1744     ui.chkYBreak->setChecked(m_plot->yRangeBreakingEnabled());
 1745     this->toggleYBreak(m_plot->yRangeBreakingEnabled());
 1746     ui.bRemoveYBreak->setVisible(m_plot->yRangeBreaks().list.size() > 1);
 1747     ui.cbYBreak->clear();
 1748     if (!m_plot->yRangeBreaks().list.isEmpty()) {
 1749         for (int i = 1; i <= m_plot->yRangeBreaks().list.size(); ++i)
 1750             ui.cbYBreak->addItem(QString::number(i));
 1751     } else
 1752         ui.cbYBreak->addItem("1");
 1753     ui.cbYBreak->setCurrentIndex(0);
 1754 
 1755     //"Plot Area"-tab
 1756     //Background
 1757     ui.cbBackgroundType->setCurrentIndex( (int)m_plot->plotArea()->backgroundType() );
 1758     backgroundTypeChanged(ui.cbBackgroundType->currentIndex());
 1759     ui.cbBackgroundColorStyle->setCurrentIndex( (int) m_plot->plotArea()->backgroundColorStyle() );
 1760     ui.cbBackgroundImageStyle->setCurrentIndex( (int) m_plot->plotArea()->backgroundImageStyle() );
 1761     ui.cbBackgroundBrushStyle->setCurrentIndex( (int) m_plot->plotArea()->backgroundBrushStyle() );
 1762     ui.leBackgroundFileName->setText( m_plot->plotArea()->backgroundFileName() );
 1763     ui.kcbBackgroundFirstColor->setColor( m_plot->plotArea()->backgroundFirstColor() );
 1764     ui.kcbBackgroundSecondColor->setColor( m_plot->plotArea()->backgroundSecondColor() );
 1765     ui.sbBackgroundOpacity->setValue( round(m_plot->plotArea()->backgroundOpacity()*100.0) );
 1766 
 1767     //highlight the text field for the background image red if an image is used and cannot be found
 1768     const QString& fileName = m_plot->plotArea()->backgroundFileName();
 1769     bool invalid = (!fileName.isEmpty() && !QFile::exists(fileName));
 1770     GuiTools::highlight(ui.leBackgroundFileName, invalid);
 1771 
 1772     //Padding
 1773     ui.sbPaddingHorizontal->setValue( Worksheet::convertFromSceneUnits(m_plot->horizontalPadding(), m_worksheetUnit) );
 1774     ui.sbPaddingVertical->setValue( Worksheet::convertFromSceneUnits(m_plot->verticalPadding(), m_worksheetUnit) );
 1775     ui.sbPaddingRight->setValue(Worksheet::convertFromSceneUnits(m_plot->rightPadding(), m_worksheetUnit));
 1776     ui.sbPaddingBottom->setValue(Worksheet::convertFromSceneUnits(m_plot->bottomPadding(), m_worksheetUnit));
 1777     ui.cbPaddingSymmetric->setChecked(m_plot->symmetricPadding());
 1778 
 1779     //Border
 1780     ui.kcbBorderColor->setColor( m_plot->plotArea()->borderPen().color() );
 1781     ui.cbBorderStyle->setCurrentIndex( (int) m_plot->plotArea()->borderPen().style() );
 1782     ui.sbBorderWidth->setValue( Worksheet::convertFromSceneUnits(m_plot->plotArea()->borderPen().widthF(), Worksheet::Unit::Point) );
 1783     ui.sbBorderCornerRadius->setValue( Worksheet::convertFromSceneUnits(m_plot->plotArea()->borderCornerRadius(), m_worksheetUnit) );
 1784     ui.sbBorderOpacity->setValue( round(m_plot->plotArea()->borderOpacity()*100) );
 1785     GuiTools::updatePenStyles(ui.cbBorderStyle, ui.kcbBorderColor->color());
 1786 
 1787     // Cursor
 1788     QPen pen = m_plot->cursorPen();
 1789     ui.cbCursorLineStyle->setCurrentIndex(pen.style());
 1790     ui.kcbCursorLineColor->setColor(pen.color());
 1791     ui.sbCursorLineWidth->setValue(pen.width());
 1792     GuiTools::updatePenStyles(ui.cbCursorLineStyle, pen.color());
 1793 }
 1794 
 1795 void CartesianPlotDock::loadConfig(KConfig& config) {
 1796     KConfigGroup group = config.group("CartesianPlot");
 1797 
 1798     //General
 1799     //we don't load/save the settings in the general-tab, since they are not style related.
 1800     //It doesn't make sense to load/save them in the template.
 1801     //This data is read in CartesianPlotDock::setPlots().
 1802 
 1803     //Title
 1804     KConfigGroup plotTitleGroup = config.group("CartesianPlotTitle");
 1805     labelWidget->loadConfig(plotTitleGroup);
 1806 
 1807     //Scale breakings
 1808     //TODO
 1809 
 1810     //Background-tab
 1811     ui.cbBackgroundType->setCurrentIndex( group.readEntry("BackgroundType", (int) m_plot->plotArea()->backgroundType()) );
 1812     ui.cbBackgroundColorStyle->setCurrentIndex( group.readEntry("BackgroundColorStyle", (int) m_plot->plotArea()->backgroundColorStyle()) );
 1813     ui.cbBackgroundImageStyle->setCurrentIndex( group.readEntry("BackgroundImageStyle", (int) m_plot->plotArea()->backgroundImageStyle()) );
 1814     ui.cbBackgroundBrushStyle->setCurrentIndex( group.readEntry("BackgroundBrushStyle", (int) m_plot->plotArea()->backgroundBrushStyle()) );
 1815     ui.leBackgroundFileName->setText( group.readEntry("BackgroundFileName", m_plot->plotArea()->backgroundFileName()) );
 1816     ui.kcbBackgroundFirstColor->setColor( group.readEntry("BackgroundFirstColor", m_plot->plotArea()->backgroundFirstColor()) );
 1817     ui.kcbBackgroundSecondColor->setColor( group.readEntry("BackgroundSecondColor", m_plot->plotArea()->backgroundSecondColor()) );
 1818     ui.sbBackgroundOpacity->setValue( round(group.readEntry("BackgroundOpacity", m_plot->plotArea()->backgroundOpacity())*100.0) );
 1819     ui.sbPaddingHorizontal->setValue(Worksheet::convertFromSceneUnits(group.readEntry("HorizontalPadding", m_plot->horizontalPadding()), m_worksheetUnit));
 1820     ui.sbPaddingVertical->setValue(Worksheet::convertFromSceneUnits(group.readEntry("VerticalPadding", m_plot->verticalPadding()), m_worksheetUnit));
 1821     ui.sbPaddingRight->setValue(Worksheet::convertFromSceneUnits(group.readEntry("RightPadding", m_plot->rightPadding()), m_worksheetUnit));
 1822     ui.sbPaddingBottom->setValue(Worksheet::convertFromSceneUnits(group.readEntry("BottomPadding", m_plot->bottomPadding()), m_worksheetUnit));
 1823     ui.cbPaddingSymmetric->setChecked(group.readEntry("SymmetricPadding", m_plot->symmetricPadding()));
 1824 
 1825     //Border-tab
 1826     ui.kcbBorderColor->setColor( group.readEntry("BorderColor", m_plot->plotArea()->borderPen().color()) );
 1827     ui.cbBorderStyle->setCurrentIndex( group.readEntry("BorderStyle", (int) m_plot->plotArea()->borderPen().style()) );
 1828     ui.sbBorderWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("BorderWidth", m_plot->plotArea()->borderPen().widthF()), Worksheet::Unit::Point) );
 1829     ui.sbBorderCornerRadius->setValue( Worksheet::convertFromSceneUnits(group.readEntry("BorderCornerRadius", m_plot->plotArea()->borderCornerRadius()), m_worksheetUnit) );
 1830     ui.sbBorderOpacity->setValue( group.readEntry("BorderOpacity", m_plot->plotArea()->borderOpacity())*100 );
 1831 
 1832     m_initializing = true;
 1833     GuiTools::updatePenStyles(ui.cbBorderStyle, ui.kcbBorderColor->color());
 1834     GuiTools::updatePenStyles(ui.cbCursorLineStyle, m_plot->cursorPen().color());
 1835     m_initializing = false;
 1836 }
 1837 
 1838 void CartesianPlotDock::saveConfigAsTemplate(KConfig& config) {
 1839     KConfigGroup group = config.group("CartesianPlot");
 1840 
 1841     //General
 1842     //we don't load/save the settings in the general-tab, since they are not style related.
 1843     //It doesn't make sense to load/save them in the template.
 1844 
 1845     //Title
 1846     KConfigGroup plotTitleGroup = config.group("CartesianPlotTitle");
 1847     labelWidget->saveConfig(plotTitleGroup);
 1848 
 1849     //Scale breakings
 1850     //TODO
 1851 
 1852     //Background
 1853     group.writeEntry("BackgroundType", ui.cbBackgroundType->currentIndex());
 1854     group.writeEntry("BackgroundColorStyle", ui.cbBackgroundColorStyle->currentIndex());
 1855     group.writeEntry("BackgroundImageStyle", ui.cbBackgroundImageStyle->currentIndex());
 1856     group.writeEntry("BackgroundBrushStyle", ui.cbBackgroundBrushStyle->currentIndex());
 1857     group.writeEntry("BackgroundFileName", ui.leBackgroundFileName->text());
 1858     group.writeEntry("BackgroundFirstColor", ui.kcbBackgroundFirstColor->color());
 1859     group.writeEntry("BackgroundSecondColor", ui.kcbBackgroundSecondColor->color());
 1860     group.writeEntry("BackgroundOpacity", ui.sbBackgroundOpacity->value()/100.0);
 1861     group.writeEntry("HorizontalPadding", Worksheet::convertToSceneUnits(ui.sbPaddingHorizontal->value(), m_worksheetUnit));
 1862     group.writeEntry("VerticalPadding", Worksheet::convertToSceneUnits(ui.sbPaddingVertical->value(), m_worksheetUnit));
 1863     group.writeEntry("RightPadding", Worksheet::convertToSceneUnits(ui.sbPaddingRight->value(), m_worksheetUnit));
 1864     group.writeEntry("BottomPadding", Worksheet::convertToSceneUnits(ui.sbPaddingBottom->value(), m_worksheetUnit));
 1865     group.writeEntry("SymmetricPadding", ui.cbPaddingSymmetric->isChecked());
 1866 
 1867     //Border
 1868     group.writeEntry("BorderStyle", ui.cbBorderStyle->currentIndex());
 1869     group.writeEntry("BorderColor", ui.kcbBorderColor->color());
 1870     group.writeEntry("BorderWidth", Worksheet::convertToSceneUnits(ui.sbBorderWidth->value(), Worksheet::Unit::Point));
 1871     group.writeEntry("BorderCornerRadius", Worksheet::convertToSceneUnits(ui.sbBorderCornerRadius->value(), m_worksheetUnit));
 1872     group.writeEntry("BorderOpacity", ui.sbBorderOpacity->value()/100.0);
 1873 
 1874     config.sync();
 1875 }
 1876 
 1877 void CartesianPlotDock::loadTheme(const QString& theme) {
 1878     for (auto* plot : m_plotList)
 1879         plot->setTheme(theme);
 1880 }
 1881 
 1882 void CartesianPlotDock::saveTheme(KConfig& config) const {
 1883     if (!m_plotList.isEmpty())
 1884         m_plotList.at(0)->saveTheme(config);
 1885 }