File indexing completed on 2024-05-12 15:27:59

0001 /***************************************************************************
0002     File                 : HistogramDock.cpp
0003     Project              : LabPlot
0004     Description          : widget for Histogram properties
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2016 Anu Mittal (anu22mittal@gmail.com)
0007     Copyright            : (C) 2018-2021 by Alexander Semke (alexander.semke@web.de)
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "HistogramDock.h"
0031 #include "backend/worksheet/plots/cartesian/Histogram.h"
0032 #include "backend/worksheet/Worksheet.h"
0033 #include "backend/worksheet/plots/cartesian/Symbol.h"
0034 #include "backend/core/AspectTreeModel.h"
0035 #include "backend/core/column/Column.h"
0036 #include "backend/core/Project.h"
0037 #include "backend/core/datatypes/Double2StringFilter.h"
0038 #include "backend/core/datatypes/DateTime2StringFilter.h"
0039 #include "commonfrontend/widgets/TreeViewComboBox.h"
0040 #include "kdefrontend/TemplateHandler.h"
0041 #include "kdefrontend/GuiTools.h"
0042 
0043 #include <QCompleter>
0044 #include <QDir>
0045 #include <QDirModel>
0046 #include <QFileDialog>
0047 #include <QImageReader>
0048 #include <QPainter>
0049 
0050 #include <KConfig>
0051 #include <KLocalizedString>
0052 
0053 /*!
0054   \class HistogramDock
0055   \brief  Provides a widget for editing the properties of the Histograms (2D-curves) currently selected in the project explorer.
0056 
0057   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.
0058   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.
0059 
0060   \ingroup kdefrontend
0061 */
0062 HistogramDock::HistogramDock(QWidget* parent) : BaseDock(parent), cbDataColumn(new TreeViewComboBox) {
0063     ui.setupUi(this);
0064     m_leName = ui.leName;
0065     m_leComment = ui.leComment;
0066 
0067     // Tab "General"
0068     auto* gridLayout = qobject_cast<QGridLayout*>(ui.tabGeneral->layout());
0069     gridLayout->addWidget(cbDataColumn, 3, 2, 1, 1);
0070 
0071     //Tab "Values"
0072     gridLayout = qobject_cast<QGridLayout*>(ui.tabValues->layout());
0073     cbValuesColumn = new TreeViewComboBox(ui.tabValues);
0074     gridLayout->addWidget(cbValuesColumn, 2, 2, 1, 1);
0075 
0076     //add formats for numeric values
0077     ui.cbValuesNumericFormat->addItem(i18n("Decimal"), QVariant('f'));
0078     ui.cbValuesNumericFormat->addItem(i18n("Scientific (e)"), QVariant('e'));
0079     ui.cbValuesNumericFormat->addItem(i18n("Scientific (E)"), QVariant('E'));
0080     ui.cbValuesNumericFormat->addItem(i18n("Automatic (e)"), QVariant('g'));
0081     ui.cbValuesNumericFormat->addItem(i18n("Automatic (E)"), QVariant('G'));
0082 
0083     //add format for date, time and datetime values
0084     for (const auto& s : AbstractColumn::dateFormats())
0085         ui.cbValuesDateTimeFormat->addItem(s, QVariant(s));
0086 
0087     for (const auto& s : AbstractColumn::timeFormats())
0088         ui.cbValuesDateTimeFormat->addItem(s, QVariant(s));
0089 
0090     for (const auto& s1 : AbstractColumn::dateFormats()) {
0091         for (const auto& s2 : AbstractColumn::timeFormats())
0092             ui.cbValuesDateTimeFormat->addItem(s1 + ' ' + s2, QVariant(s1 + ' ' + s2));
0093     }
0094 
0095     ui.cbValuesDateTimeFormat->setEditable(true);
0096 
0097     //Tab "Filling"
0098     ui.cbFillingColorStyle->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
0099     ui.bFillingOpen->setIcon( QIcon::fromTheme("document-open") );
0100 
0101     ui.leFillingFileName->setCompleter(new QCompleter(new QDirModel, this));
0102 
0103     //adjust layouts in the tabs
0104     for (int i = 0; i < ui.tabWidget->count(); ++i) {
0105         auto* layout = dynamic_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout());
0106         if (!layout)
0107             continue;
0108 
0109         layout->setContentsMargins(2,2,2,2);
0110         layout->setHorizontalSpacing(2);
0111         layout->setVerticalSpacing(2);
0112     }
0113 
0114     ui.leBinWidth->setValidator(new QDoubleValidator(ui.leBinWidth));
0115     ui.leBinRangesMin->setValidator(new QDoubleValidator(ui.leBinRangesMin));
0116     ui.leBinRangesMax->setValidator(new QDoubleValidator(ui.leBinRangesMax));
0117 
0118     //Slots
0119     //General
0120     connect(ui.leName, &QLineEdit::textChanged, this, &HistogramDock::nameChanged);
0121     connect(ui.leComment, &QLineEdit::textChanged, this, &HistogramDock::commentChanged);
0122     connect( ui.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)) );
0123     connect( cbDataColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(dataColumnChanged(QModelIndex)) );
0124     connect( ui.cbType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int)) );
0125     connect( ui.cbOrientation, SIGNAL(currentIndexChanged(int)), this, SLOT(orientationChanged(int)));
0126     connect( ui.cbBinningMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(binningMethodChanged(int)) );
0127     connect(ui.sbBinCount, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &HistogramDock::binCountChanged);
0128     connect(ui.leBinWidth, &QLineEdit::textChanged, this, &HistogramDock::binWidthChanged);
0129     connect( ui.chkAutoBinRanges, &QCheckBox::stateChanged, this, &HistogramDock::autoBinRangesChanged );
0130     connect( ui.leBinRangesMin, &QLineEdit::textChanged, this, &HistogramDock::binRangesMinChanged );
0131     connect( ui.leBinRangesMax, &QLineEdit::textChanged, this, &HistogramDock::binRangesMaxChanged );
0132     connect(ui.dteBinRangesMin, &QDateTimeEdit::dateTimeChanged, this, &HistogramDock::binRangesMinDateTimeChanged);
0133     connect(ui.dteBinRangesMax, &QDateTimeEdit::dateTimeChanged, this, &HistogramDock::binRangesMaxDateTimeChanged);
0134 
0135     //Line
0136     connect(ui.cbLineType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &HistogramDock::lineTypeChanged);
0137     connect(ui.cbLineStyle, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &HistogramDock::lineStyleChanged);
0138     connect(ui.kcbLineColor, &KColorButton::changed, this, &HistogramDock::lineColorChanged);
0139     connect(ui.sbLineWidth, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &HistogramDock::lineWidthChanged);
0140     connect(ui.sbLineOpacity, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &HistogramDock::lineOpacityChanged);
0141 
0142     //Symbol
0143     connect( ui.cbSymbolStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsStyleChanged(int)) );
0144     connect( ui.sbSymbolSize, SIGNAL(valueChanged(double)), this, SLOT(symbolsSizeChanged(double)) );
0145     connect( ui.sbSymbolRotation, SIGNAL(valueChanged(int)), this, SLOT(symbolsRotationChanged(int)) );
0146     connect( ui.sbSymbolOpacity, SIGNAL(valueChanged(int)), this, SLOT(symbolsOpacityChanged(int)) );
0147 
0148     connect( ui.cbSymbolFillingStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsFillingStyleChanged(int)) );
0149     connect( ui.kcbSymbolFillingColor, SIGNAL(changed(QColor)), this, SLOT(symbolsFillingColorChanged(QColor)) );
0150 
0151     connect( ui.cbSymbolBorderStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsBorderStyleChanged(int)) );
0152     connect( ui.kcbSymbolBorderColor, SIGNAL(changed(QColor)), this, SLOT(symbolsBorderColorChanged(QColor)) );
0153     connect( ui.sbSymbolBorderWidth, SIGNAL(valueChanged(double)), this, SLOT(symbolsBorderWidthChanged(double)) );
0154 
0155     //Values
0156     connect( ui.cbValuesType, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesTypeChanged(int)) );
0157     connect( cbValuesColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(valuesColumnChanged(QModelIndex)) );
0158     connect( ui.cbValuesPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesPositionChanged(int)) );
0159     connect( ui.sbValuesDistance, SIGNAL(valueChanged(double)), this, SLOT(valuesDistanceChanged(double)) );
0160     connect( ui.sbValuesRotation, SIGNAL(valueChanged(int)), this, SLOT(valuesRotationChanged(int)) );
0161     connect( ui.sbValuesOpacity, SIGNAL(valueChanged(int)), this, SLOT(valuesOpacityChanged(int)) );
0162     connect(ui.cbValuesNumericFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &HistogramDock::valuesNumericFormatChanged);
0163     connect(ui.sbValuesPrecision, QOverload<int>::of(&QSpinBox::valueChanged), this, &HistogramDock::valuesPrecisionChanged);
0164     connect(ui.cbValuesDateTimeFormat, &QComboBox::currentTextChanged, this, &HistogramDock::valuesDateTimeFormatChanged);
0165     connect(ui.leValuesPrefix, &QLineEdit::textChanged, this, &HistogramDock::valuesPrefixChanged);
0166     connect(ui.leValuesSuffix, &QLineEdit::textChanged, this, &HistogramDock::valuesSuffixChanged);
0167     connect( ui.kfrValuesFont, SIGNAL(fontSelected(QFont)), this, SLOT(valuesFontChanged(QFont)) );
0168     connect( ui.kcbValuesColor, SIGNAL(changed(QColor)), this, SLOT(valuesColorChanged(QColor)) );
0169 
0170     //Filling
0171     connect(ui.chkFillingEnabled, &QCheckBox::stateChanged, this, &HistogramDock::fillingEnabledChanged);
0172     connect( ui.cbFillingType, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingTypeChanged(int)) );
0173     connect( ui.cbFillingColorStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingColorStyleChanged(int)) );
0174     connect( ui.cbFillingImageStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingImageStyleChanged(int)) );
0175     connect( ui.cbFillingBrushStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingBrushStyleChanged(int)) );
0176     connect( ui.bFillingOpen, SIGNAL(clicked(bool)), this, SLOT(selectFile()));
0177     connect(ui.leFillingFileName, &QLineEdit::textChanged, this, &HistogramDock::fileNameChanged);
0178     connect( ui.leFillingFileName, SIGNAL(textChanged(QString)), this, SLOT(fileNameChanged()) );
0179     connect( ui.kcbFillingFirstColor, SIGNAL(changed(QColor)), this, SLOT(fillingFirstColorChanged(QColor)) );
0180     connect( ui.kcbFillingSecondColor, SIGNAL(changed(QColor)), this, SLOT(fillingSecondColorChanged(QColor)) );
0181     connect( ui.sbFillingOpacity, SIGNAL(valueChanged(int)), this, SLOT(fillingOpacityChanged(int)) );
0182 
0183     //Error bars
0184     connect( ui.cbErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(errorTypeChanged(int)) );
0185     connect( ui.cbErrorBarsType, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsTypeChanged(int)) );
0186     connect( ui.sbErrorBarsCapSize, SIGNAL(valueChanged(double)), this, SLOT(errorBarsCapSizeChanged(double)) );
0187     connect( ui.cbErrorBarsStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsStyleChanged(int)) );
0188     connect( ui.kcbErrorBarsColor, SIGNAL(changed(QColor)), this, SLOT(errorBarsColorChanged(QColor)) );
0189     connect( ui.sbErrorBarsWidth, SIGNAL(valueChanged(double)), this, SLOT(errorBarsWidthChanged(double)) );
0190     connect( ui.sbErrorBarsOpacity, SIGNAL(valueChanged(int)), this, SLOT(errorBarsOpacityChanged(int)) );
0191 
0192     //template handler
0193     auto* frame = new QFrame(this);
0194     auto* layout = new QHBoxLayout(frame);
0195     layout->setContentsMargins(0, 11, 0, 11);
0196 
0197     auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::Histogram);
0198     layout->addWidget(templateHandler);
0199     connect(templateHandler, &TemplateHandler::loadConfigRequested, this, &HistogramDock::loadConfigFromTemplate);
0200     connect(templateHandler, &TemplateHandler::saveConfigRequested, this, &HistogramDock::saveConfigAsTemplate);
0201     connect(templateHandler, &TemplateHandler::info, this, &HistogramDock::info);
0202 
0203     ui.verticalLayout->addWidget(frame);
0204 
0205     retranslateUi();
0206     init();
0207 
0208     //TODO: activate the tab for error-bars again once the functionality is implemented
0209     ui.tabWidget->removeTab(5);
0210 }
0211 
0212 HistogramDock::~HistogramDock() {
0213     if (m_aspectTreeModel)
0214         delete m_aspectTreeModel;
0215 }
0216 
0217 void HistogramDock::init() {
0218     //General
0219     //bins option
0220     ui.cbBinningMethod->addItem(i18n("By Number"));
0221     ui.cbBinningMethod->addItem(i18n("By Width"));
0222     ui.cbBinningMethod->addItem(i18n("Square-root"));
0223     ui.cbBinningMethod->addItem(i18n("Rice"));
0224     ui.cbBinningMethod->addItem(i18n("Sturges"));
0225     ui.cbBinningMethod->addItem(i18n("Doane"));
0226     ui.cbBinningMethod->addItem(i18n("Scott"));
0227 
0228     //histogram type
0229     ui.cbType->addItem(i18n("Ordinary Histogram"));
0230     ui.cbType->addItem(i18n("Cumulative Histogram"));
0231 //  ui.cbType->addItem(i18n("AvgShifted Histogram"));
0232 
0233     //Orientation
0234     ui.cbOrientation->addItem(i18n("Vertical"));
0235     ui.cbOrientation->addItem(i18n("Horizontal"));
0236 
0237     //Line
0238     ui.cbLineType->addItem(i18n("None"));
0239     ui.cbLineType->addItem(i18n("Bars"));
0240     ui.cbLineType->addItem(i18n("Envelope"));
0241     ui.cbLineType->addItem(i18n("Drop Lines"));
0242 
0243     GuiTools::updatePenStyles(ui.cbLineStyle, Qt::black);
0244 
0245     //Symbols
0246     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, Qt::black);
0247 
0248     QPainter pa;
0249     //TODO size of the icon depending on the actual height of the combobox?
0250     int iconSize = 20;
0251     QPixmap pm(iconSize, iconSize);
0252     ui.cbSymbolStyle->setIconSize(QSize(iconSize, iconSize));
0253     QTransform trafo;
0254     trafo.scale(15, 15);
0255 
0256     QPen pen(Qt::SolidPattern, 0);
0257     const QColor& color = (palette().color(QPalette::Base).lightness() < 128) ? Qt::white : Qt::black;
0258     pen.setColor(color);
0259     pa.setPen( pen );
0260 
0261     ui.cbSymbolStyle->addItem(i18n("None"));
0262     for (int i = 1; i < 19; ++i) {  //TODO: use enum count
0263         auto style = (Symbol::Style)i;
0264         pm.fill(Qt::transparent);
0265         pa.begin(&pm);
0266         pa.setPen(pen);
0267         pa.setRenderHint(QPainter::Antialiasing);
0268         pa.translate(iconSize/2,iconSize/2);
0269         pa.drawPath(trafo.map(Symbol::pathFromStyle(style)));
0270         pa.end();
0271         ui.cbSymbolStyle->addItem(QIcon(pm), Symbol::nameFromStyle(style));
0272     }
0273 
0274     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, Qt::black);
0275     m_initializing = false;
0276 
0277     //Values
0278     ui.cbValuesType->addItem(i18n("No Values"));
0279     ui.cbValuesType->addItem(i18n("Frequency"));
0280     ui.cbValuesType->addItem(i18n("Custom Column"));
0281 
0282     ui.cbValuesPosition->addItem(i18n("Above"));
0283     ui.cbValuesPosition->addItem(i18n("Below"));
0284     ui.cbValuesPosition->addItem(i18n("Left"));
0285     ui.cbValuesPosition->addItem(i18n("Right"));
0286 
0287     //Filling
0288     ui.cbFillingType->clear();
0289     ui.cbFillingType->addItem(i18n("Color"));
0290     ui.cbFillingType->addItem(i18n("Image"));
0291     ui.cbFillingType->addItem(i18n("Pattern"));
0292 
0293     ui.cbFillingColorStyle->clear();
0294     ui.cbFillingColorStyle->addItem(i18n("Single Color"));
0295     ui.cbFillingColorStyle->addItem(i18n("Horizontal Linear Gradient"));
0296     ui.cbFillingColorStyle->addItem(i18n("Vertical Linear Gradient"));
0297     ui.cbFillingColorStyle->addItem(i18n("Diagonal Linear Gradient (Start From Top Left)"));
0298     ui.cbFillingColorStyle->addItem(i18n("Diagonal Linear Gradient (Start From Bottom Left)"));
0299     ui.cbFillingColorStyle->addItem(i18n("Radial Gradient"));
0300 
0301     ui.cbFillingImageStyle->clear();
0302     ui.cbFillingImageStyle->addItem(i18n("Scaled and Cropped"));
0303     ui.cbFillingImageStyle->addItem(i18n("Scaled"));
0304     ui.cbFillingImageStyle->addItem(i18n("Scaled, Keep Proportions"));
0305     ui.cbFillingImageStyle->addItem(i18n("Centered"));
0306     ui.cbFillingImageStyle->addItem(i18n("Tiled"));
0307     ui.cbFillingImageStyle->addItem(i18n("Center Tiled"));
0308     GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, Qt::SolidPattern);
0309 
0310     //Error-bars
0311     pm.fill(Qt::transparent);
0312     pa.begin( &pm );
0313     pa.setRenderHint(QPainter::Antialiasing);
0314     pa.drawLine(3,10,17,10);//vert. line
0315     pa.drawLine(10,3,10,17);//hor. line
0316     pa.end();
0317     ui.cbErrorBarsType->addItem(i18n("Bars"));
0318     ui.cbErrorBarsType->setItemIcon(0, pm);
0319 
0320     pm.fill(Qt::transparent);
0321     pa.begin( &pm );
0322     pa.setRenderHint(QPainter::Antialiasing);
0323     pa.setBrush(Qt::SolidPattern);
0324     pa.drawLine(3,10,17,10); //vert. line
0325     pa.drawLine(10,3,10,17); //hor. line
0326     pa.drawLine(7,3,13,3); //upper cap
0327     pa.drawLine(7,17,13,17); //bottom cap
0328     pa.drawLine(3,7,3,13); //left cap
0329     pa.drawLine(17,7,17,13); //right cap
0330     pa.end();
0331     ui.cbErrorBarsType->addItem(i18n("Bars with Ends"));
0332     ui.cbErrorBarsType->setItemIcon(1, pm);
0333 
0334     ui.cbErrorType->addItem(i18n("No Errors"));
0335 
0336     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, Qt::black);
0337 }
0338 
0339 void HistogramDock::setModel() {
0340     m_aspectTreeModel->enablePlottableColumnsOnly(true);
0341     m_aspectTreeModel->enableShowPlotDesignation(true);
0342 
0343     QList<AspectType> list{AspectType::Folder, AspectType::Workbook, AspectType::Datapicker,
0344                            AspectType::DatapickerCurve, AspectType::Spreadsheet, AspectType::LiveDataSource,
0345                            AspectType::Column, AspectType::Worksheet, AspectType::CartesianPlot,
0346                            AspectType::XYFitCurve, AspectType::XYSmoothCurve, AspectType::CantorWorksheet};
0347 
0348     cbDataColumn->setTopLevelClasses(list);
0349     cbValuesColumn->setTopLevelClasses(list);
0350 
0351     list = {AspectType::Column};
0352     m_aspectTreeModel->setSelectableAspects(list);
0353 
0354     cbDataColumn->setModel(m_aspectTreeModel);
0355     cbValuesColumn->setModel(m_aspectTreeModel);
0356 }
0357 
0358 void HistogramDock::setCurves(QList<Histogram*> list) {
0359     m_initializing = true;
0360     m_curvesList = list;
0361     m_curve = list.first();
0362     m_aspect = list.first();
0363     Q_ASSERT(m_curve);
0364     m_aspectTreeModel = new AspectTreeModel(m_curve->project());
0365     setModel();
0366 
0367     SET_NUMBER_LOCALE
0368     ui.sbLineWidth->setLocale(numberLocale);
0369     ui.sbSymbolSize->setLocale(numberLocale);
0370     ui.sbSymbolBorderWidth->setLocale(numberLocale);
0371     ui.sbValuesDistance->setLocale(numberLocale);
0372     ui.sbErrorBarsCapSize->setLocale(numberLocale);
0373     ui.sbErrorBarsWidth->setLocale(numberLocale);
0374 
0375     //if there are more then one curve in the list, disable the content in the tab "general"
0376     if (m_curvesList.size() == 1) {
0377         ui.lName->setEnabled(true);
0378         ui.leName->setEnabled(true);
0379         ui.lComment->setEnabled(true);
0380         ui.leComment->setEnabled(true);
0381 
0382         ui.lXColumn->setEnabled(true);
0383         cbDataColumn->setEnabled(true);
0384 
0385         this->setModelIndexFromColumn(cbDataColumn, m_curve->dataColumn());
0386         this->setModelIndexFromColumn(cbValuesColumn, m_curve->valuesColumn());
0387         ui.leName->setText(m_curve->name());
0388         ui.leComment->setText(m_curve->comment());
0389     } else {
0390         ui.lName->setEnabled(false);
0391         ui.leName->setEnabled(false);
0392         ui.lComment->setEnabled(false);
0393         ui.leComment->setEnabled(false);
0394 
0395         ui.lXColumn->setEnabled(false);
0396         cbDataColumn->setEnabled(false);
0397         cbDataColumn->setCurrentModelIndex(QModelIndex());
0398         cbValuesColumn->setCurrentModelIndex(QModelIndex());
0399 
0400         ui.leName->setText(QString());
0401         ui.leComment->setText(QString());
0402     }
0403 
0404     ui.leName->setStyleSheet("");
0405     ui.leName->setToolTip("");
0406 
0407     //show the properties of the first curve
0408     ui.cbType->setCurrentIndex(m_curve->type());
0409     ui.cbOrientation->setCurrentIndex(m_curve->orientation());
0410     ui.cbBinningMethod->setCurrentIndex(m_curve->binningMethod());
0411     ui.sbBinCount->setValue(m_curve->binCount());
0412     ui.leBinWidth->setText(numberLocale.toString(m_curve->binWidth()));
0413     ui.chkAutoBinRanges->setChecked(m_curve->autoBinRanges());
0414     ui.leBinRangesMin->setText( numberLocale.toString(m_curve->binRangesMin()) );
0415     ui.leBinRangesMax->setText( numberLocale.toString(m_curve->binRangesMax()) );
0416     ui.chkVisible->setChecked( m_curve->isVisible() );
0417 
0418     //handle numeric vs. datetime widgets
0419     //TODO: we need to react on range format changes in the plot in general,
0420     //add signal-slot connection for this
0421     const auto* plot = static_cast<const CartesianPlot*>(m_curve->parent(AspectType::CartesianPlot));
0422     ui.dteBinRangesMin->setDisplayFormat(plot->xRangeDateTimeFormat());
0423     ui.dteBinRangesMax->setDisplayFormat(plot->xRangeDateTimeFormat());
0424     ui.dteBinRangesMin->setDateTime(QDateTime::fromMSecsSinceEpoch(m_curve->binRangesMin()));
0425     ui.dteBinRangesMax->setDateTime(QDateTime::fromMSecsSinceEpoch(m_curve->binRangesMax()));
0426 
0427     bool numeric = (plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric);
0428 
0429     ui.lBinRangesMin->setVisible(numeric);
0430     ui.lBinRangesMax->setVisible(numeric);
0431     ui.leBinRangesMin->setVisible(numeric);
0432     ui.leBinRangesMax->setVisible(numeric);
0433 
0434     ui.lBinRangesMinDateTime->setVisible(!numeric);
0435     ui.dteBinRangesMin->setVisible(!numeric);
0436     ui.lBinRangesMaxDateTime->setVisible(!numeric);
0437     ui.dteBinRangesMax->setVisible(!numeric);
0438 
0439     //load the remaining properties
0440     KConfig config(QString(), KConfig::SimpleConfig);
0441     loadConfig(config);
0442 
0443     //Slots
0444     //General-tab
0445     connect(m_curve, &Histogram::aspectDescriptionChanged, this, &HistogramDock::curveDescriptionChanged);
0446     connect(m_curve, &Histogram::dataColumnChanged, this, &HistogramDock::curveDataColumnChanged);
0447     connect(m_curve, &Histogram::typeChanged, this, &HistogramDock::curveTypeChanged);
0448     connect(m_curve, &Histogram::orientationChanged, this, &HistogramDock::curveOrientationChanged);
0449     connect(m_curve, &Histogram::binningMethodChanged, this, &HistogramDock::curveBinningMethodChanged);
0450     connect(m_curve, &Histogram::binCountChanged, this, &HistogramDock::curveBinCountChanged);
0451     connect(m_curve, &Histogram::binWidthChanged, this, &HistogramDock::curveBinWidthChanged);
0452     connect(m_curve, &Histogram::autoBinRangesChanged, this, &HistogramDock::curveAutoBinRangesChanged);
0453     connect(m_curve, &Histogram::binRangesMinChanged, this, &HistogramDock::curveBinRangesMinChanged);
0454     connect(m_curve, &Histogram::binRangesMaxChanged, this, &HistogramDock::curveBinRangesMaxChanged);
0455     connect(m_curve, &Histogram::visibilityChanged, this, &HistogramDock::curveVisibilityChanged);
0456 
0457     //Line-tab
0458     connect(m_curve, &Histogram::linePenChanged, this, &HistogramDock::curveLinePenChanged);
0459     connect(m_curve, &Histogram::lineOpacityChanged, this, &HistogramDock::curveLineOpacityChanged);
0460 
0461     //Symbol-Tab
0462     connect(m_curve, &Histogram::symbolsStyleChanged, this, &HistogramDock::curveSymbolsStyleChanged);
0463     connect(m_curve, &Histogram::symbolsSizeChanged, this, &HistogramDock::curveSymbolsSizeChanged);
0464     connect(m_curve, &Histogram::symbolsRotationAngleChanged, this, &HistogramDock::curveSymbolsRotationAngleChanged);
0465     connect(m_curve, &Histogram::symbolsOpacityChanged, this, &HistogramDock::curveSymbolsOpacityChanged);
0466     connect(m_curve, &Histogram::symbolsBrushChanged, this, &HistogramDock::curveSymbolsBrushChanged);
0467     connect(m_curve, &Histogram::symbolsPenChanged, this, &HistogramDock::curveSymbolsPenChanged);
0468 
0469     //Values-Tab
0470     connect(m_curve, &Histogram::valuesTypeChanged, this, &HistogramDock::curveValuesTypeChanged);
0471     connect(m_curve, &Histogram::valuesColumnChanged, this, &HistogramDock::curveValuesColumnChanged);
0472     connect(m_curve, &Histogram::valuesPositionChanged, this, &HistogramDock::curveValuesPositionChanged);
0473     connect(m_curve, &Histogram::valuesDistanceChanged, this, &HistogramDock::curveValuesDistanceChanged);
0474     connect(m_curve, &Histogram::valuesOpacityChanged, this, &HistogramDock::curveValuesOpacityChanged);
0475     connect(m_curve, &Histogram::valuesRotationAngleChanged, this, &HistogramDock::curveValuesRotationAngleChanged);
0476     connect(m_curve, &Histogram::valuesNumericFormatChanged, this, &HistogramDock::curveValuesNumericFormatChanged);
0477     connect(m_curve, &Histogram::valuesPrecisionChanged, this, &HistogramDock::curveValuesPrecisionChanged);
0478     connect(m_curve, &Histogram::valuesDateTimeFormatChanged, this, &HistogramDock::curveValuesDateTimeFormatChanged);
0479     connect(m_curve, &Histogram::valuesPrefixChanged, this, &HistogramDock::curveValuesPrefixChanged);
0480     connect(m_curve, &Histogram::valuesSuffixChanged, this, &HistogramDock::curveValuesSuffixChanged);
0481     connect(m_curve, &Histogram::valuesFontChanged, this, &HistogramDock::curveValuesFontChanged);
0482     connect(m_curve, &Histogram::valuesColorChanged, this, &HistogramDock::curveValuesColorChanged);
0483 
0484     //Filling-Tab
0485     connect( m_curve, &Histogram::fillingEnabledChanged, this, &HistogramDock::curveFillingEnabledChanged);
0486     connect( m_curve, &Histogram::fillingTypeChanged, this, &HistogramDock::curveFillingTypeChanged);
0487     connect( m_curve, &Histogram::fillingColorStyleChanged, this, &HistogramDock::curveFillingColorStyleChanged);
0488     connect( m_curve, &Histogram::fillingImageStyleChanged, this, &HistogramDock::curveFillingImageStyleChanged);
0489     connect( m_curve, &Histogram::fillingBrushStyleChanged, this, &HistogramDock::curveFillingBrushStyleChanged);
0490     connect( m_curve, &Histogram::fillingFirstColorChanged, this, &HistogramDock::curveFillingFirstColorChanged);
0491     connect( m_curve, &Histogram::fillingSecondColorChanged, this, &HistogramDock::curveFillingSecondColorChanged);
0492     connect( m_curve, &Histogram::fillingFileNameChanged, this, &HistogramDock::curveFillingFileNameChanged);
0493     connect( m_curve, &Histogram::fillingOpacityChanged, this, &HistogramDock::curveFillingOpacityChanged);
0494 
0495     //"Error bars"-Tab
0496     connect(m_curve, &Histogram::errorTypeChanged, this, &HistogramDock::curveErrorTypeChanged);
0497     connect(m_curve, &Histogram::errorBarsCapSizeChanged, this, &HistogramDock::curveErrorBarsCapSizeChanged);
0498     connect(m_curve, &Histogram::errorBarsTypeChanged, this, &HistogramDock::curveErrorBarsTypeChanged);
0499     connect(m_curve, &Histogram::errorBarsPenChanged, this, &HistogramDock::curveErrorBarsPenChanged);
0500     connect(m_curve, &Histogram::errorBarsOpacityChanged, this, &HistogramDock::curveErrorBarsOpacityChanged);
0501 
0502     m_initializing = false;
0503 }
0504 
0505 void HistogramDock::setModelIndexFromColumn(TreeViewComboBox* cb, const AbstractColumn* column) {
0506     if (column)
0507         cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(column));
0508     else
0509         cb->setCurrentModelIndex(QModelIndex());
0510 }
0511 
0512 void HistogramDock::retranslateUi() {
0513     //TODO:
0514 //  ui.lName->setText(i18n("Name"));
0515 //  ui.lComment->setText(i18n("Comment"));
0516 //  ui.chkVisible->setText(i18n("Visible"));
0517 //  ui.lXColumn->setText(i18n("x-data"));
0518 //  ui.lYColumn->setText(i18n("y-data"));
0519 
0520     //TODO updatePenStyles, updateBrushStyles for all comboboxes
0521 }
0522 
0523 //*************************************************************
0524 //**** SLOTs for changes triggered in HistogramDock *****
0525 //*************************************************************
0526 
0527 // "General"-tab
0528 void HistogramDock::visibilityChanged(bool state) {
0529     if (m_initializing)
0530         return;
0531 
0532     for (auto* curve : m_curvesList)
0533         curve->setVisible(state);
0534 }
0535 
0536 void HistogramDock::typeChanged(int index) {
0537     if (m_initializing)
0538         return;
0539 
0540     auto histogramType = Histogram::HistogramType(index);
0541     for (auto* curve : m_curvesList)
0542         curve->setType(histogramType);
0543 }
0544 
0545 void HistogramDock::dataColumnChanged(const QModelIndex& index) {
0546     if (m_initializing)
0547         return;
0548 
0549     auto aspect = static_cast<AbstractAspect*>(index.internalPointer());
0550     AbstractColumn* column(nullptr);
0551     if (aspect) {
0552         column = dynamic_cast<AbstractColumn*>(aspect);
0553         Q_ASSERT(column);
0554     }
0555 
0556     for (auto* curve : m_curvesList)
0557         curve->setDataColumn(column);
0558 }
0559 
0560 void HistogramDock::orientationChanged(int index) {
0561     if (m_initializing)
0562         return;
0563 
0564     auto orientation = Histogram::HistogramOrientation(index);
0565     for (auto* curve : m_curvesList)
0566         curve->setOrientation(orientation);
0567 }
0568 
0569 void HistogramDock::binningMethodChanged(int index) {
0570     const auto binningMethod = Histogram::BinningMethod(index);
0571     if (binningMethod == Histogram::ByNumber) {
0572         ui.lBinCount->show();
0573         ui.sbBinCount->show();
0574         ui.lBinWidth->hide();
0575         ui.leBinWidth->hide();
0576     } else if (binningMethod == Histogram::ByWidth) {
0577         ui.lBinCount->hide();
0578         ui.sbBinCount->hide();
0579         ui.lBinWidth->show();
0580         ui.leBinWidth->show();
0581     } else {
0582         ui.lBinCount->hide();
0583         ui.sbBinCount->hide();
0584         ui.lBinWidth->hide();
0585         ui.leBinWidth->hide();
0586     }
0587 
0588     if (m_initializing)
0589         return;
0590 
0591     for (auto* curve : m_curvesList)
0592         curve->setBinningMethod(binningMethod);
0593 }
0594 
0595 void HistogramDock::binCountChanged(int value) {
0596     if (m_initializing)
0597         return;
0598 
0599     for (auto* curve : m_curvesList)
0600         curve->setBinCount(value);
0601 }
0602 
0603 void HistogramDock::binWidthChanged() {
0604     if (m_initializing)
0605         return;
0606 
0607     const Lock lock(m_initializing);
0608     bool ok;
0609     SET_NUMBER_LOCALE
0610     const double width{numberLocale.toDouble(ui.leBinWidth->text(), &ok)};
0611     if (ok) {
0612         for (auto* curve : m_curvesList)
0613             curve->setBinWidth(width);
0614     }
0615 }
0616 
0617 void HistogramDock::autoBinRangesChanged(int state) {
0618     bool checked = (state == Qt::Checked);
0619     ui.leBinRangesMin->setEnabled(!checked);
0620     ui.leBinRangesMax->setEnabled(!checked);
0621     ui.dteBinRangesMin->setEnabled(!checked);
0622     ui.dteBinRangesMax->setEnabled(!checked);
0623 
0624     if (m_initializing)
0625         return;
0626 
0627     for (auto* hist : m_curvesList)
0628         hist->setAutoBinRanges(checked);
0629 }
0630 
0631 void HistogramDock::binRangesMinChanged(const QString& value) {
0632     if (m_initializing)
0633         return;
0634 
0635     const Lock lock(m_initializing);
0636     bool ok;
0637     SET_NUMBER_LOCALE
0638     const double min{numberLocale.toDouble(value, &ok)};
0639     if (ok) {
0640         for (auto* hist : m_curvesList)
0641             hist->setBinRangesMin(min);
0642     }
0643 }
0644 
0645 void HistogramDock::binRangesMaxChanged(const QString& value) {
0646     if (m_initializing)
0647         return;
0648 
0649     const Lock lock(m_initializing);
0650     bool ok;
0651     SET_NUMBER_LOCALE
0652     const double max{numberLocale.toDouble(value, &ok)};
0653     if (ok) {
0654         for (auto* hist : m_curvesList)
0655             hist->setBinRangesMax(max);
0656     }
0657 }
0658 
0659 void HistogramDock::binRangesMinDateTimeChanged(const QDateTime& dateTime) {
0660     if (m_initializing)
0661         return;
0662 
0663     quint64 min = dateTime.toMSecsSinceEpoch();
0664     for (auto* hist : m_curvesList)
0665         hist->setBinRangesMin(min);
0666 }
0667 
0668 void HistogramDock::binRangesMaxDateTimeChanged(const QDateTime& dateTime) {
0669     if (m_initializing)
0670         return;
0671 
0672     quint64 max = dateTime.toMSecsSinceEpoch();
0673     for (auto* hist : m_curvesList)
0674         hist->setBinRangesMax(max);
0675 }
0676 
0677 //Line tab
0678 void HistogramDock::lineTypeChanged(int index) {
0679     auto lineType = Histogram::LineType(index);
0680 
0681     if ( lineType == Histogram::NoLine) {
0682         ui.cbLineStyle->setEnabled(false);
0683         ui.kcbLineColor->setEnabled(false);
0684         ui.sbLineWidth->setEnabled(false);
0685         ui.sbLineOpacity->setEnabled(false);
0686     } else {
0687         ui.cbLineStyle->setEnabled(true);
0688         ui.kcbLineColor->setEnabled(true);
0689         ui.sbLineWidth->setEnabled(true);
0690         ui.sbLineOpacity->setEnabled(true);
0691     }
0692 
0693     if (m_initializing)
0694         return;
0695 
0696     for (auto* curve : m_curvesList)
0697         curve->setLineType(lineType);
0698 }
0699 
0700 void HistogramDock::lineStyleChanged(int index) {
0701     if (m_initializing)
0702         return;
0703 
0704     auto penStyle = Qt::PenStyle(index);
0705     QPen pen;
0706     for (auto* curve : m_curvesList) {
0707         pen = curve->linePen();
0708         pen.setStyle(penStyle);
0709         curve->setLinePen(pen);
0710     }
0711 }
0712 
0713 void HistogramDock::lineColorChanged(const QColor& color) {
0714     if (m_initializing)
0715         return;
0716 
0717     QPen pen;
0718     for (auto* curve : m_curvesList) {
0719         pen = curve->linePen();
0720         pen.setColor(color);
0721         curve->setLinePen(pen);
0722     }
0723 
0724     m_initializing = true;
0725     GuiTools::updatePenStyles(ui.cbLineStyle, color);
0726     m_initializing = false;
0727 }
0728 
0729 void HistogramDock::lineWidthChanged(double value) {
0730     if (m_initializing)
0731         return;
0732 
0733     QPen pen;
0734     for (auto* curve : m_curvesList) {
0735         pen = curve->linePen();
0736         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
0737         curve->setLinePen(pen);
0738     }
0739 }
0740 
0741 void HistogramDock::lineOpacityChanged(int value) {
0742     if (m_initializing)
0743         return;
0744 
0745     qreal opacity = (float)value/100.;
0746     for (auto* curve : m_curvesList)
0747         curve->setLineOpacity(opacity);
0748 }
0749 
0750 //"Symbol"-tab
0751 void HistogramDock::symbolsStyleChanged(int index) {
0752     const auto style = Symbol::Style(index);
0753 
0754     if (style == Symbol::Style::NoSymbols) {
0755         ui.sbSymbolSize->setEnabled(false);
0756         ui.sbSymbolRotation->setEnabled(false);
0757         ui.sbSymbolOpacity->setEnabled(false);
0758 
0759         ui.kcbSymbolFillingColor->setEnabled(false);
0760         ui.cbSymbolFillingStyle->setEnabled(false);
0761 
0762         ui.cbSymbolBorderStyle->setEnabled(false);
0763         ui.kcbSymbolBorderColor->setEnabled(false);
0764         ui.sbSymbolBorderWidth->setEnabled(false);
0765     } else {
0766         ui.sbSymbolSize->setEnabled(true);
0767         ui.sbSymbolRotation->setEnabled(true);
0768         ui.sbSymbolOpacity->setEnabled(true);
0769 
0770         //enable/disable the symbol filling options in the GUI depending on the currently selected symbol.
0771         if (style != Symbol::Style::Line && style != Symbol::Style::Cross) {
0772             ui.cbSymbolFillingStyle->setEnabled(true);
0773             bool noBrush = (Qt::BrushStyle(ui.cbSymbolFillingStyle->currentIndex()) == Qt::NoBrush);
0774             ui.kcbSymbolFillingColor->setEnabled(!noBrush);
0775         } else {
0776             ui.kcbSymbolFillingColor->setEnabled(false);
0777             ui.cbSymbolFillingStyle->setEnabled(false);
0778         }
0779 
0780         ui.cbSymbolBorderStyle->setEnabled(true);
0781         bool noLine = (Qt::PenStyle(ui.cbSymbolBorderStyle->currentIndex()) == Qt::NoPen);
0782         ui.kcbSymbolBorderColor->setEnabled(!noLine);
0783         ui.sbSymbolBorderWidth->setEnabled(!noLine);
0784     }
0785 
0786     if (m_initializing)
0787         return;
0788 
0789     for (auto* curve : m_curvesList)
0790         curve->setSymbolsStyle(style);
0791 }
0792 
0793 void HistogramDock::symbolsSizeChanged(double value) {
0794     if (m_initializing)
0795         return;
0796 
0797     for (auto* curve : m_curvesList)
0798         curve->setSymbolsSize( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
0799 }
0800 
0801 void HistogramDock::symbolsRotationChanged(int value) {
0802     if (m_initializing)
0803         return;
0804 
0805     for (auto* curve : m_curvesList)
0806         curve->setSymbolsRotationAngle(value);
0807 }
0808 
0809 void HistogramDock::symbolsOpacityChanged(int value) {
0810     if (m_initializing)
0811         return;
0812 
0813     qreal opacity = (float)value/100.;
0814     for (auto* curve : m_curvesList)
0815         curve->setSymbolsOpacity(opacity);
0816 }
0817 
0818 void HistogramDock::symbolsFillingStyleChanged(int index) {
0819     auto brushStyle = Qt::BrushStyle(index);
0820     ui.kcbSymbolFillingColor->setEnabled(!(brushStyle == Qt::NoBrush));
0821 
0822     if (m_initializing)
0823         return;
0824 
0825     QBrush brush;
0826     for (auto* curve : m_curvesList) {
0827         brush = curve->symbolsBrush();
0828         brush.setStyle(brushStyle);
0829         curve->setSymbolsBrush(brush);
0830     }
0831 }
0832 
0833 void HistogramDock::symbolsFillingColorChanged(const QColor& color) {
0834     if (m_initializing)
0835         return;
0836 
0837     QBrush brush;
0838     for (auto* curve : m_curvesList) {
0839         brush = curve->symbolsBrush();
0840         brush.setColor(color);
0841         curve->setSymbolsBrush(brush);
0842     }
0843 
0844     m_initializing = true;
0845     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, color );
0846     m_initializing = false;
0847 }
0848 
0849 void HistogramDock::symbolsBorderStyleChanged(int index) {
0850     auto penStyle = Qt::PenStyle(index);
0851 
0852     if ( penStyle == Qt::NoPen ) {
0853         ui.kcbSymbolBorderColor->setEnabled(false);
0854         ui.sbSymbolBorderWidth->setEnabled(false);
0855     } else {
0856         ui.kcbSymbolBorderColor->setEnabled(true);
0857         ui.sbSymbolBorderWidth->setEnabled(true);
0858     }
0859 
0860     if (m_initializing)
0861         return;
0862 
0863     QPen pen;
0864     for (auto* curve : m_curvesList) {
0865         pen = curve->symbolsPen();
0866         pen.setStyle(penStyle);
0867         curve->setSymbolsPen(pen);
0868     }
0869 }
0870 
0871 void HistogramDock::symbolsBorderColorChanged(const QColor& color) {
0872     if (m_initializing)
0873         return;
0874 
0875     QPen pen;
0876     for (auto* curve : m_curvesList) {
0877         pen = curve->symbolsPen();
0878         pen.setColor(color);
0879         curve->setSymbolsPen(pen);
0880     }
0881 
0882     m_initializing = true;
0883     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, color);
0884     m_initializing = false;
0885 }
0886 
0887 void HistogramDock::symbolsBorderWidthChanged(double value) {
0888     if (m_initializing)
0889         return;
0890 
0891     QPen pen;
0892     for (auto* curve : m_curvesList) {
0893         pen = curve->symbolsPen();
0894         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
0895         curve->setSymbolsPen(pen);
0896     }
0897 }
0898 
0899 //Values tab
0900 /*!
0901   called when the type of the values (none, x, y, (x,y) etc.) was changed.
0902 */
0903 void HistogramDock::valuesTypeChanged(int index) {
0904     if (m_initializing)
0905         return;
0906 
0907     this->updateValuesWidgets();
0908 
0909     auto valuesType = Histogram::ValuesType(index);
0910     for (auto* curve : m_curvesList)
0911         curve->setValuesType(valuesType);
0912 }
0913 
0914 /*!
0915   depending on the currently selected values column type (column mode) updates the widgets for the values column format,
0916   shows/hides the allowed widgets, fills the corresponding combobox with the possible entries.
0917   Called when the values column was changed.
0918 */
0919 void HistogramDock::updateValuesWidgets() {
0920     const auto type = Histogram::ValuesType(ui.cbValuesType->currentIndex());
0921     bool showValues = (type != Histogram::NoValues);
0922 
0923     ui.cbValuesPosition->setEnabled(showValues);
0924     ui.sbValuesDistance->setEnabled(showValues);
0925     ui.sbValuesRotation->setEnabled(showValues);
0926     ui.sbValuesOpacity->setEnabled(showValues);
0927     ui.kfrValuesFont->setEnabled(showValues);
0928     ui.kcbValuesColor->setEnabled(showValues);
0929 
0930     bool hasInteger = false;
0931     bool hasNumeric = false;
0932     bool hasDateTime = false;
0933 
0934     if (type == Histogram::ValuesCustomColumn) {
0935         ui.lValuesColumn->show();
0936         cbValuesColumn->show();
0937 
0938         auto* column = static_cast<Column*>(cbValuesColumn->currentModelIndex().internalPointer());
0939         if (column) {
0940             if (column->columnMode() == AbstractColumn::ColumnMode::Numeric)
0941                 hasNumeric = true;
0942             else if (column->columnMode() == AbstractColumn::ColumnMode::Integer || column->columnMode() == AbstractColumn::ColumnMode::BigInt)
0943                 hasInteger = true;
0944             else if (column->columnMode() == AbstractColumn::ColumnMode::DateTime)
0945                 hasDateTime = true;
0946         }
0947     } else {
0948         ui.lValuesColumn->hide();
0949         cbValuesColumn->hide();
0950 
0951         if (type == Histogram::ValuesBinEntries)
0952             hasInteger = true;
0953     }
0954 
0955     //hide all the format related widgets first and
0956     //then show only what is required depending of the column mode(s)
0957     ui.lValuesFormat->hide();
0958     ui.lValuesNumericFormat->hide();
0959     ui.cbValuesNumericFormat->hide();
0960     ui.lValuesPrecision->hide();
0961     ui.sbValuesPrecision->hide();
0962     ui.lValuesDateTimeFormat->hide();
0963     ui.cbValuesDateTimeFormat->hide();
0964 
0965     if (hasNumeric || hasInteger) {
0966         ui.lValuesFormat->show();
0967         ui.lValuesNumericFormat->show();
0968         ui.cbValuesNumericFormat->show();
0969     }
0970 
0971     //precision is only available for Numeric
0972     if (hasNumeric) {
0973         ui.lValuesPrecision->show();
0974         ui.sbValuesPrecision->show();
0975     }
0976 
0977     if (hasDateTime) {
0978         ui.lValuesFormat->show();
0979         ui.lValuesDateTimeFormat->show();
0980         ui.cbValuesDateTimeFormat->show();
0981     }
0982 }
0983 
0984 /*!
0985   called when the custom column for the values was changed.
0986 */
0987 void HistogramDock::valuesColumnChanged(const QModelIndex& index) {
0988     if (m_initializing)
0989         return;
0990 
0991     this->updateValuesWidgets();
0992 
0993     auto* column = static_cast<Column*>(index.internalPointer());
0994     for (auto* curve : m_curvesList)
0995         curve->setValuesColumn(column);
0996 }
0997 
0998 void HistogramDock::valuesPositionChanged(int index) {
0999     if (m_initializing)
1000         return;
1001 
1002     for (auto* curve : m_curvesList)
1003         curve->setValuesPosition(Histogram::ValuesPosition(index));
1004 }
1005 
1006 void HistogramDock::valuesDistanceChanged(double  value) {
1007     if (m_initializing)
1008         return;
1009 
1010     for (auto* curve : m_curvesList)
1011         curve->setValuesDistance( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
1012 }
1013 
1014 void HistogramDock::valuesRotationChanged(int value) {
1015     if (m_initializing)
1016         return;
1017 
1018     for (auto* curve : m_curvesList)
1019         curve->setValuesRotationAngle(value);
1020 }
1021 
1022 void HistogramDock::valuesOpacityChanged(int value) {
1023     if (m_initializing)
1024         return;
1025 
1026     qreal opacity = (float)value/100.;
1027     for (auto* curve : m_curvesList)
1028         curve->setValuesOpacity(opacity);
1029 }
1030 
1031 void HistogramDock::valuesNumericFormatChanged(int index) {
1032     if (m_initializing)
1033         return;
1034 
1035     char format = ui.cbValuesNumericFormat->itemData(index).toChar().toLatin1();
1036     for (auto* curve : m_curvesList)
1037         curve->setValuesNumericFormat(format);
1038 }
1039 
1040 void HistogramDock::valuesPrecisionChanged(int precision) {
1041     if (m_initializing)
1042         return;
1043 
1044     for (auto* curve : m_curvesList)
1045         curve->setValuesPrecision(precision);
1046 }
1047 
1048 void HistogramDock::valuesDateTimeFormatChanged(const QString& format) {
1049     if (m_initializing)
1050         return;
1051 
1052     for (auto* curve : m_curvesList)
1053         curve->setValuesDateTimeFormat(format);
1054 }
1055 
1056 void HistogramDock::valuesPrefixChanged() {
1057     if (m_initializing)
1058         return;
1059 
1060     QString prefix = ui.leValuesPrefix->text();
1061     for (auto* curve : m_curvesList)
1062         curve->setValuesPrefix(prefix);
1063 }
1064 
1065 void HistogramDock::valuesSuffixChanged() {
1066     if (m_initializing)
1067         return;
1068 
1069     QString suffix = ui.leValuesSuffix->text();
1070     for (auto* curve : m_curvesList)
1071         curve->setValuesSuffix(suffix);
1072 }
1073 
1074 void HistogramDock::valuesFontChanged(const QFont& font) {
1075     if (m_initializing)
1076         return;
1077 
1078     QFont valuesFont = font;
1079     valuesFont.setPixelSize( Worksheet::convertToSceneUnits(font.pointSizeF(), Worksheet::Unit::Point) );
1080     for (auto* curve : m_curvesList)
1081         curve->setValuesFont(valuesFont);
1082 }
1083 
1084 void HistogramDock::valuesColorChanged(const QColor& color) {
1085     if (m_initializing)
1086         return;
1087 
1088     for (auto* curve : m_curvesList)
1089         curve->setValuesColor(color);
1090 }
1091 
1092 //Filling-tab
1093 void HistogramDock::fillingEnabledChanged(int state) {
1094     ui.cbFillingType->setEnabled(state);
1095     ui.cbFillingColorStyle->setEnabled(state);
1096     ui.cbFillingBrushStyle->setEnabled(state);
1097     ui.cbFillingImageStyle->setEnabled(state);
1098     ui.kcbFillingFirstColor->setEnabled(state);
1099     ui.kcbFillingSecondColor->setEnabled(state);
1100     ui.leFillingFileName->setEnabled(state);
1101     ui.bFillingOpen->setEnabled(state);
1102     ui.sbFillingOpacity->setEnabled(state);
1103 
1104     if (m_initializing)
1105         return;
1106 
1107     for (auto* curve : m_curvesList)
1108         curve->setFillingEnabled(state);
1109 }
1110 
1111 void HistogramDock::fillingTypeChanged(int index) {
1112     auto type = (PlotArea::BackgroundType)index;
1113 
1114     if (type == PlotArea::BackgroundType::Color) {
1115         ui.lFillingColorStyle->show();
1116         ui.cbFillingColorStyle->show();
1117         ui.lFillingImageStyle->hide();
1118         ui.cbFillingImageStyle->hide();
1119         ui.lFillingBrushStyle->hide();
1120         ui.cbFillingBrushStyle->hide();
1121 
1122         ui.lFillingFileName->hide();
1123         ui.leFillingFileName->hide();
1124         ui.bFillingOpen->hide();
1125 
1126         ui.lFillingFirstColor->show();
1127         ui.kcbFillingFirstColor->show();
1128 
1129         auto style = (PlotArea::BackgroundColorStyle) ui.cbFillingColorStyle->currentIndex();
1130         if (style == PlotArea::BackgroundColorStyle::SingleColor) {
1131             ui.lFillingFirstColor->setText(i18n("Color:"));
1132             ui.lFillingSecondColor->hide();
1133             ui.kcbFillingSecondColor->hide();
1134         } else {
1135             ui.lFillingFirstColor->setText(i18n("First color:"));
1136             ui.lFillingSecondColor->show();
1137             ui.kcbFillingSecondColor->show();
1138         }
1139     } else if (type == PlotArea::BackgroundType::Image) {
1140         ui.lFillingColorStyle->hide();
1141         ui.cbFillingColorStyle->hide();
1142         ui.lFillingImageStyle->show();
1143         ui.cbFillingImageStyle->show();
1144         ui.lFillingBrushStyle->hide();
1145         ui.cbFillingBrushStyle->hide();
1146         ui.lFillingFileName->show();
1147         ui.leFillingFileName->show();
1148         ui.bFillingOpen->show();
1149 
1150         ui.lFillingFirstColor->hide();
1151         ui.kcbFillingFirstColor->hide();
1152         ui.lFillingSecondColor->hide();
1153         ui.kcbFillingSecondColor->hide();
1154     } else if (type == PlotArea::BackgroundType::Pattern) {
1155         ui.lFillingFirstColor->setText(i18n("Color:"));
1156         ui.lFillingColorStyle->hide();
1157         ui.cbFillingColorStyle->hide();
1158         ui.lFillingImageStyle->hide();
1159         ui.cbFillingImageStyle->hide();
1160         ui.lFillingBrushStyle->show();
1161         ui.cbFillingBrushStyle->show();
1162         ui.lFillingFileName->hide();
1163         ui.leFillingFileName->hide();
1164         ui.bFillingOpen->hide();
1165 
1166         ui.lFillingFirstColor->show();
1167         ui.kcbFillingFirstColor->show();
1168         ui.lFillingSecondColor->hide();
1169         ui.kcbFillingSecondColor->hide();
1170     }
1171 
1172     if (m_initializing)
1173         return;
1174 
1175     for (auto* curve : m_curvesList)
1176         curve->setFillingType(type);
1177 }
1178 
1179 void HistogramDock::fillingColorStyleChanged(int index) {
1180     auto style = (PlotArea::BackgroundColorStyle)index;
1181 
1182     if (style == PlotArea::BackgroundColorStyle::SingleColor) {
1183         ui.lFillingFirstColor->setText(i18n("Color:"));
1184         ui.lFillingSecondColor->hide();
1185         ui.kcbFillingSecondColor->hide();
1186     } else {
1187         ui.lFillingFirstColor->setText(i18n("First color:"));
1188         ui.lFillingSecondColor->show();
1189         ui.kcbFillingSecondColor->show();
1190         ui.lFillingBrushStyle->hide();
1191         ui.cbFillingBrushStyle->hide();
1192     }
1193 
1194     if (m_initializing)
1195         return;
1196 
1197     for (auto* curve : m_curvesList)
1198         curve->setFillingColorStyle(style);
1199 }
1200 
1201 void HistogramDock::fillingImageStyleChanged(int index) {
1202     if (m_initializing)
1203         return;
1204 
1205     auto style = (PlotArea::BackgroundImageStyle)index;
1206     for (auto* curve : m_curvesList)
1207         curve->setFillingImageStyle(style);
1208 }
1209 
1210 void HistogramDock::fillingBrushStyleChanged(int index) {
1211     if (m_initializing)
1212         return;
1213 
1214     auto style = (Qt::BrushStyle)index;
1215     for (auto* curve : m_curvesList)
1216         curve->setFillingBrushStyle(style);
1217 }
1218 
1219 void HistogramDock::fillingFirstColorChanged(const QColor& c) {
1220     if (m_initializing)
1221         return;
1222 
1223     for (auto* curve : m_curvesList)
1224         curve->setFillingFirstColor(c);
1225 }
1226 
1227 void HistogramDock::fillingSecondColorChanged(const QColor& c) {
1228     if (m_initializing)
1229         return;
1230 
1231     for (auto* curve : m_curvesList)
1232         curve->setFillingSecondColor(c);
1233 }
1234 
1235 //"Error bars"-Tab
1236 void HistogramDock::errorTypeChanged(int index) const {
1237     bool b = (index != 0);
1238     ui.lErrorData->setVisible(b);
1239     ui.lErrorFormat->setVisible(b);
1240     ui.lErrorBarsType->setVisible(b);
1241     ui.cbErrorBarsType->setVisible(b);
1242     ui.lErrorBarsStyle->setVisible(b);
1243     ui.cbErrorBarsStyle->setVisible(b);
1244     ui.lErrorBarsColor->setVisible(b);
1245     ui.kcbErrorBarsColor->setVisible(b);
1246     ui.lErrorBarsWidth->setVisible(b);
1247     ui.sbErrorBarsWidth->setVisible(b);
1248     ui.lErrorBarsOpacity->setVisible(b);
1249     ui.sbErrorBarsOpacity->setVisible(b);
1250 
1251     if (m_initializing)
1252         return;
1253 
1254     for (auto* curve : m_curvesList)
1255         curve->setErrorType(Histogram::ErrorType(index));
1256 }
1257 
1258 void HistogramDock::errorBarsTypeChanged(int index) const {
1259     auto type{XYCurve::ErrorBarsType(index)};
1260     bool b = (type == XYCurve::ErrorBarsType::WithEnds);
1261     ui.lErrorBarsCapSize->setVisible(b);
1262     ui.sbErrorBarsCapSize->setVisible(b);
1263 
1264     if (m_initializing)
1265         return;
1266 
1267     for (auto* curve : m_curvesList)
1268         curve->setErrorBarsType(type);
1269 }
1270 
1271 void HistogramDock::errorBarsCapSizeChanged(double value) const {
1272     if (m_initializing)
1273         return;
1274 
1275     double size = Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point);
1276     for (auto* curve : m_curvesList)
1277         curve->setErrorBarsCapSize(size);
1278 }
1279 
1280 void HistogramDock::errorBarsStyleChanged(int index) const {
1281     if (m_initializing)
1282         return;
1283 
1284     auto penStyle = Qt::PenStyle(index);
1285     QPen pen;
1286     for (auto* curve : m_curvesList) {
1287         pen = curve->errorBarsPen();
1288         pen.setStyle(penStyle);
1289         curve->setErrorBarsPen(pen);
1290     }
1291 }
1292 
1293 void HistogramDock::errorBarsColorChanged(const QColor& color) {
1294     if (m_initializing)
1295         return;
1296 
1297     QPen pen;
1298     for (auto* curve : m_curvesList) {
1299         pen = curve->errorBarsPen();
1300         pen.setColor(color);
1301         curve->setErrorBarsPen(pen);
1302     }
1303 
1304     m_initializing = true;
1305     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, color);
1306     m_initializing = false;
1307 }
1308 
1309 void HistogramDock::errorBarsWidthChanged(double value) const {
1310     if (m_initializing)
1311         return;
1312 
1313     QPen pen;
1314     for (auto* curve : m_curvesList) {
1315         pen = curve->errorBarsPen();
1316         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
1317         curve->setErrorBarsPen(pen);
1318     }
1319 }
1320 
1321 void HistogramDock::errorBarsOpacityChanged(int value) const {
1322     if (m_initializing)
1323         return;
1324 
1325     qreal opacity = (double)value/100.;
1326     for (auto* curve : m_curvesList)
1327         curve->setErrorBarsOpacity(opacity);
1328 }
1329 
1330 /*!
1331     opens a file dialog and lets the user select the image file.
1332 */
1333 void HistogramDock::selectFile() {
1334     KConfigGroup conf(KSharedConfig::openConfig(), "HistogramDock");
1335     QString dir = conf.readEntry("LastImageDir", "");
1336 
1337     QString formats;
1338     for (const QByteArray& format : QImageReader::supportedImageFormats()) {
1339         QString f = "*." + QString(format.constData());
1340         if (f == QLatin1String("*.svg"))
1341             continue;
1342         formats.isEmpty() ? formats += f : formats += ' ' + f;
1343     }
1344 
1345     QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats));
1346     if (path.isEmpty())
1347         return; //cancel was clicked in the file-dialog
1348 
1349     int pos = path.lastIndexOf(QLatin1String("/"));
1350     if (pos != -1) {
1351         QString newDir = path.left(pos);
1352         if (newDir != dir)
1353             conf.writeEntry("LastImageDir", newDir);
1354     }
1355 
1356     ui.leFillingFileName->setText( path );
1357 
1358     for (auto* curve : m_curvesList)
1359         curve->setFillingFileName(path);
1360 }
1361 
1362 void HistogramDock::fileNameChanged() {
1363     if (m_initializing)
1364         return;
1365 
1366     QString fileName = ui.leFillingFileName->text();
1367     for (auto* curve : m_curvesList)
1368         curve->setFillingFileName(fileName);
1369 }
1370 
1371 void HistogramDock::fillingOpacityChanged(int value) {
1372     if (m_initializing)
1373         return;
1374 
1375     qreal opacity = (double)value/100.;
1376     for (auto* curve : m_curvesList)
1377         curve->setFillingOpacity(opacity);
1378 }
1379 
1380 //*************************************************************
1381 //*********** SLOTs for changes triggered in Histogram *******
1382 //*************************************************************
1383 
1384 //General-Tab
1385 void HistogramDock::curveDescriptionChanged(const AbstractAspect* aspect) {
1386     if (m_curve != aspect)
1387         return;
1388 
1389     m_initializing = true;
1390     if (aspect->name() != ui.leName->text())
1391         ui.leName->setText(aspect->name());
1392     else if (aspect->comment() != ui.leComment->text())
1393         ui.leComment->setText(aspect->comment());
1394 
1395     m_initializing = false;
1396 }
1397 
1398 void HistogramDock::curveDataColumnChanged(const AbstractColumn* column) {
1399     m_initializing = true;
1400     this->setModelIndexFromColumn(cbDataColumn, column);
1401     m_initializing = false;
1402 }
1403 
1404 void HistogramDock::curveTypeChanged(Histogram::HistogramType type) {
1405     m_initializing = true;
1406     ui.cbType->setCurrentIndex((int)type);
1407     m_initializing = false;
1408 }
1409 
1410 void HistogramDock::curveOrientationChanged(Histogram::HistogramOrientation orientation) {
1411     m_initializing = true;
1412     ui.cbOrientation->setCurrentIndex((int)orientation);
1413     m_initializing = false;
1414 }
1415 
1416 void HistogramDock::curveBinningMethodChanged(Histogram::BinningMethod method) {
1417     m_initializing = true;
1418     ui.cbBinningMethod->setCurrentIndex((int)method);
1419     m_initializing = false;
1420 }
1421 
1422 void HistogramDock::curveBinCountChanged(int count) {
1423     m_initializing = true;
1424     ui.sbBinCount->setValue(count);
1425     m_initializing = false;
1426 }
1427 
1428 void HistogramDock::curveBinWidthChanged(double width) {
1429     if (m_initializing)return;
1430     const Lock lock(m_initializing);
1431     SET_NUMBER_LOCALE
1432     ui.leBinWidth->setText(numberLocale.toString(width));
1433 }
1434 
1435 void HistogramDock::curveAutoBinRangesChanged(bool value) {
1436     m_initializing = true;
1437     ui.chkAutoBinRanges->setChecked(value);
1438     m_initializing = false;
1439 }
1440 
1441 void HistogramDock::curveBinRangesMinChanged(double value) {
1442     if (m_initializing)return;
1443     const Lock lock(m_initializing);
1444     SET_NUMBER_LOCALE
1445     ui.leBinRangesMin->setText(numberLocale.toString(value));
1446     ui.dteBinRangesMin->setDateTime(QDateTime::fromMSecsSinceEpoch(value));
1447 }
1448 
1449 void HistogramDock::curveBinRangesMaxChanged(double value) {
1450     if (m_initializing)return;
1451     const Lock lock(m_initializing);
1452     SET_NUMBER_LOCALE
1453     ui.leBinRangesMax->setText(numberLocale.toString(value));
1454     ui.dteBinRangesMax->setDateTime(QDateTime::fromMSecsSinceEpoch(value));
1455 }
1456 
1457 //Line-Tab
1458 void HistogramDock::curveLineTypeChanged(Histogram::LineType type) {
1459     m_initializing = true;
1460     ui.cbLineType->setCurrentIndex((int)type);
1461     m_initializing = false;
1462 }
1463 void HistogramDock::curveLinePenChanged(const QPen& pen) {
1464     m_initializing = true;
1465     ui.cbLineStyle->setCurrentIndex( (int)pen.style());
1466     ui.kcbLineColor->setColor( pen.color());
1467     GuiTools::updatePenStyles(ui.cbLineStyle, pen.color());
1468     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits( pen.widthF(), Worksheet::Unit::Point) );
1469     m_initializing = false;
1470 }
1471 void HistogramDock::curveLineOpacityChanged(qreal opacity) {
1472     m_initializing = true;
1473     ui.sbLineOpacity->setValue( round(opacity*100.0) );
1474     m_initializing = false;
1475 }
1476 
1477 //Symbol-Tab
1478 void HistogramDock::curveSymbolsStyleChanged(Symbol::Style style) {
1479     m_initializing = true;
1480     ui.cbSymbolStyle->setCurrentIndex((int)style);
1481     m_initializing = false;
1482 }
1483 void HistogramDock::curveSymbolsSizeChanged(qreal size) {
1484     m_initializing = true;
1485     ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Unit::Point) );
1486     m_initializing = false;
1487 }
1488 void HistogramDock::curveSymbolsRotationAngleChanged(qreal angle) {
1489     m_initializing = true;
1490     ui.sbSymbolRotation->setValue(angle);
1491     m_initializing = false;
1492 }
1493 void HistogramDock::curveSymbolsOpacityChanged(qreal opacity) {
1494     m_initializing = true;
1495     ui.sbSymbolOpacity->setValue( round(opacity*100.0) );
1496     m_initializing = false;
1497 }
1498 void HistogramDock::curveSymbolsBrushChanged(const QBrush& brush) {
1499     m_initializing = true;
1500     ui.cbSymbolFillingStyle->setCurrentIndex((int) brush.style());
1501     ui.kcbSymbolFillingColor->setColor(brush.color());
1502     GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, brush.color());
1503     m_initializing = false;
1504 }
1505 void HistogramDock::curveSymbolsPenChanged(const QPen& pen) {
1506     m_initializing = true;
1507     ui.cbSymbolBorderStyle->setCurrentIndex( (int) pen.style());
1508     ui.kcbSymbolBorderColor->setColor( pen.color());
1509     GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, pen.color());
1510     ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point));
1511     m_initializing = false;
1512 }
1513 
1514 //Values-Tab
1515 void HistogramDock::curveValuesTypeChanged(Histogram::ValuesType type) {
1516     m_initializing = true;
1517     ui.cbValuesType->setCurrentIndex((int) type);
1518     m_initializing = false;
1519 }
1520 void HistogramDock::curveValuesColumnChanged(const AbstractColumn* column) {
1521     m_initializing = true;
1522     this->setModelIndexFromColumn(cbValuesColumn, column);
1523     m_initializing = false;
1524 }
1525 void HistogramDock::curveValuesPositionChanged(Histogram::ValuesPosition position) {
1526     m_initializing = true;
1527     ui.cbValuesPosition->setCurrentIndex((int) position);
1528     m_initializing = false;
1529 }
1530 void HistogramDock::curveValuesDistanceChanged(qreal distance) {
1531     m_initializing = true;
1532     ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(distance, Worksheet::Unit::Point) );
1533     m_initializing = false;
1534 }
1535 void HistogramDock::curveValuesRotationAngleChanged(qreal angle) {
1536     m_initializing = true;
1537     ui.sbValuesRotation->setValue(angle);
1538     m_initializing = false;
1539 }
1540 void HistogramDock::curveValuesOpacityChanged(qreal opacity) {
1541     m_initializing = true;
1542     ui.sbValuesOpacity->setValue( round(opacity*100.0) );
1543     m_initializing = false;
1544 }
1545 void HistogramDock::curveValuesNumericFormatChanged(char format) {
1546     m_initializing = true;
1547     ui.cbValuesNumericFormat->setCurrentIndex(ui.cbValuesNumericFormat->findData(format));
1548     m_initializing = false;
1549 }
1550 void HistogramDock::curveValuesPrecisionChanged(int precision) {
1551     m_initializing = true;
1552     ui.sbValuesPrecision->setValue(precision);
1553     m_initializing = false;
1554 }
1555 void HistogramDock::curveValuesDateTimeFormatChanged(const QString& format) {
1556     m_initializing = true;
1557     ui.cbValuesDateTimeFormat->setCurrentText(format);
1558     m_initializing = false;
1559 }
1560 void HistogramDock::curveValuesPrefixChanged(const QString& prefix) {
1561     m_initializing = true;
1562     ui.leValuesPrefix->setText(prefix);
1563     m_initializing = false;
1564 }
1565 void HistogramDock::curveValuesSuffixChanged(const QString& suffix) {
1566     m_initializing = true;
1567     ui.leValuesSuffix->setText(suffix);
1568     m_initializing = false;
1569 }
1570 void HistogramDock::curveValuesFontChanged(QFont font) {
1571     m_initializing = true;
1572     font.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)) );
1573     ui.kfrValuesFont->setFont(font);
1574     m_initializing = false;
1575 }
1576 void HistogramDock::curveValuesColorChanged(QColor color) {
1577     m_initializing = true;
1578     ui.kcbValuesColor->setColor(color);
1579     m_initializing = false;
1580 }
1581 
1582 void HistogramDock::curveVisibilityChanged(bool on) {
1583     m_initializing = true;
1584     ui.chkVisible->setChecked(on);
1585     m_initializing = false;
1586 }
1587 
1588 //Filling
1589 void HistogramDock::curveFillingEnabledChanged(bool status) {
1590     m_initializing = true;
1591     ui.chkFillingEnabled->setChecked(status);
1592     m_initializing = false;
1593 }
1594 void HistogramDock::curveFillingTypeChanged(PlotArea::BackgroundType type) {
1595     m_initializing = true;
1596     ui.cbFillingType->setCurrentIndex(static_cast<int>(type));
1597     m_initializing = false;
1598 }
1599 void HistogramDock::curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle style) {
1600     m_initializing = true;
1601     ui.cbFillingColorStyle->setCurrentIndex(static_cast<int>(style));
1602     m_initializing = false;
1603 }
1604 void HistogramDock::curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle style) {
1605     m_initializing = true;
1606     ui.cbFillingImageStyle->setCurrentIndex(static_cast<int>(style));
1607     m_initializing = false;
1608 }
1609 void HistogramDock::curveFillingBrushStyleChanged(Qt::BrushStyle style) {
1610     m_initializing = true;
1611     ui.cbFillingBrushStyle->setCurrentIndex(style);
1612     m_initializing = false;
1613 }
1614 void HistogramDock::curveFillingFirstColorChanged(QColor& color) {
1615     m_initializing = true;
1616     ui.kcbFillingFirstColor->setColor(color);
1617     m_initializing = false;
1618 }
1619 void HistogramDock::curveFillingSecondColorChanged(QColor& color) {
1620     m_initializing = true;
1621     ui.kcbFillingSecondColor->setColor(color);
1622     m_initializing = false;
1623 }
1624 void HistogramDock::curveFillingFileNameChanged(QString& filename) {
1625     m_initializing = true;
1626     ui.leFillingFileName->setText(filename);
1627     m_initializing = false;
1628 }
1629 void HistogramDock::curveFillingOpacityChanged(double opacity) {
1630     m_initializing = true;
1631     ui.sbFillingOpacity->setValue( round(opacity*100.0) );
1632     m_initializing = false;
1633 }
1634 
1635 //"Error bars"-Tab
1636 void HistogramDock::curveErrorTypeChanged(Histogram::ErrorType type) {
1637     m_initializing = true;
1638     ui.cbErrorType->setCurrentIndex((int)type);
1639     m_initializing = false;
1640 }
1641 void HistogramDock::curveErrorBarsCapSizeChanged(qreal size) {
1642     m_initializing = true;
1643     ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Unit::Point) );
1644     m_initializing = false;
1645 }
1646 void HistogramDock::curveErrorBarsTypeChanged(XYCurve::ErrorBarsType type) {
1647     m_initializing = true;
1648     ui.cbErrorBarsType->setCurrentIndex(static_cast<int>(type));
1649     m_initializing = false;
1650 }
1651 void HistogramDock::curveErrorBarsPenChanged(const QPen& pen) {
1652     m_initializing = true;
1653     ui.cbErrorBarsStyle->setCurrentIndex( (int) pen.style());
1654     ui.kcbErrorBarsColor->setColor( pen.color());
1655     GuiTools::updatePenStyles(ui.cbErrorBarsStyle, pen.color());
1656     ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(),Worksheet::Unit::Point) );
1657     m_initializing = false;
1658 }
1659 void HistogramDock::curveErrorBarsOpacityChanged(qreal opacity) {
1660     m_initializing = true;
1661     ui.sbErrorBarsOpacity->setValue( round(opacity*100.0) );
1662     m_initializing = false;
1663 }
1664 
1665 //*************************************************************
1666 //************************* Settings **************************
1667 //*************************************************************
1668 void HistogramDock::loadConfig(KConfig& config) {
1669     KConfigGroup group = config.group(QLatin1String("Histogram"));
1670 
1671     //General
1672     //we don't load/save the settings in the general-tab, since they are not style related.
1673     //It doesn't make sense to load/save them in the template.
1674     //This data is read in HistogramDock::setCurves().
1675 
1676     //Line
1677     ui.cbLineType->setCurrentIndex( group.readEntry("LineType", (int) m_curve->lineType()) );
1678     ui.cbLineStyle->setCurrentIndex( group.readEntry("LineStyle", (int) m_curve->linePen().style()) );
1679     ui.kcbLineColor->setColor( group.readEntry("LineColor", m_curve->linePen().color()) );
1680     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("LineWidth", m_curve->linePen().widthF()), Worksheet::Unit::Point) );
1681     ui.sbLineOpacity->setValue( round(group.readEntry("LineOpacity", m_curve->lineOpacity())*100.0) );
1682 
1683     //Symbols
1684     ui.cbSymbolStyle->setCurrentIndex( group.readEntry("SymbolStyle", (int)m_curve->symbolsStyle()) );
1685     ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("SymbolSize", m_curve->symbolsSize()), Worksheet::Unit::Point) );
1686     ui.sbSymbolRotation->setValue( group.readEntry("SymbolRotation", m_curve->symbolsRotationAngle()) );
1687     ui.sbSymbolOpacity->setValue( round(group.readEntry("SymbolOpacity", m_curve->symbolsOpacity())*100.0) );
1688     ui.cbSymbolFillingStyle->setCurrentIndex( group.readEntry("SymbolFillingStyle", (int) m_curve->symbolsBrush().style()) );
1689     ui.kcbSymbolFillingColor->setColor(  group.readEntry("SymbolFillingColor", m_curve->symbolsBrush().color()) );
1690     ui.cbSymbolBorderStyle->setCurrentIndex( group.readEntry("SymbolBorderStyle", (int) m_curve->symbolsPen().style()) );
1691     ui.kcbSymbolBorderColor->setColor( group.readEntry("SymbolBorderColor", m_curve->symbolsPen().color()) );
1692     ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("SymbolBorderWidth",m_curve->symbolsPen().widthF()), Worksheet::Unit::Point) );
1693 
1694     //Values
1695     ui.cbValuesType->setCurrentIndex( group.readEntry("ValuesType", (int) m_curve->valuesType()) );
1696     ui.cbValuesPosition->setCurrentIndex( group.readEntry("ValuesPosition", (int) m_curve->valuesPosition()) );
1697     ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ValuesDistance", m_curve->valuesDistance()), Worksheet::Unit::Point) );
1698     ui.sbValuesRotation->setValue( group.readEntry("ValuesRotation", m_curve->valuesRotationAngle()) );
1699     ui.sbValuesOpacity->setValue( round(group.readEntry("ValuesOpacity",m_curve->valuesOpacity())*100.0) );
1700     this->updateValuesWidgets();
1701     ui.leValuesPrefix->setText( group.readEntry("ValuesPrefix", m_curve->valuesPrefix()) );
1702     ui.leValuesSuffix->setText( group.readEntry("ValuesSuffix", m_curve->valuesSuffix()) );
1703     QFont valuesFont = m_curve->valuesFont();
1704     valuesFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(valuesFont.pixelSize(), Worksheet::Unit::Point)) );
1705     ui.kfrValuesFont->setFont( group.readEntry("ValuesFont", valuesFont) );
1706     ui.kcbValuesColor->setColor( group.readEntry("ValuesColor", m_curve->valuesColor()) );
1707 
1708     //Filling
1709     ui.chkFillingEnabled->setChecked( group.readEntry("FillingEnabled", m_curve->fillingEnabled()) );
1710     ui.cbFillingType->setCurrentIndex( group.readEntry("FillingType", (int) m_curve->fillingType()) );
1711     ui.cbFillingColorStyle->setCurrentIndex( group.readEntry("FillingColorStyle", (int) m_curve->fillingColorStyle()) );
1712     ui.cbFillingImageStyle->setCurrentIndex( group.readEntry("FillingImageStyle", (int) m_curve->fillingImageStyle()) );
1713     ui.cbFillingBrushStyle->setCurrentIndex( group.readEntry("FillingBrushStyle", (int) m_curve->fillingBrushStyle()) );
1714     ui.leFillingFileName->setText( group.readEntry("FillingFileName", m_curve->fillingFileName()) );
1715     ui.kcbFillingFirstColor->setColor( group.readEntry("FillingFirstColor", m_curve->fillingFirstColor()) );
1716     ui.kcbFillingSecondColor->setColor( group.readEntry("FillingSecondColor", m_curve->fillingSecondColor()) );
1717     ui.sbFillingOpacity->setValue( round(group.readEntry("FillingOpacity", m_curve->fillingOpacity())*100.0) );
1718     fillingEnabledChanged(ui.chkFillingEnabled->isChecked()); //update the box filling widgets
1719 
1720     //Error bars
1721     ui.cbErrorType->setCurrentIndex( group.readEntry("ErrorType", (int) m_curve->errorType()) );
1722     ui.cbErrorBarsType->setCurrentIndex( group.readEntry("ErrorBarsType", (int) m_curve->errorBarsType()) );
1723     ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ErrorBarsCapSize", m_curve->errorBarsCapSize()), Worksheet::Unit::Point) );
1724     ui.cbErrorBarsStyle->setCurrentIndex( group.readEntry("ErrorBarsStyle", (int) m_curve->errorBarsPen().style()) );
1725     ui.kcbErrorBarsColor->setColor( group.readEntry("ErrorBarsColor", m_curve->errorBarsPen().color()) );
1726     ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ErrorBarsWidth", m_curve->errorBarsPen().widthF()),Worksheet::Unit::Point) );
1727     ui.sbErrorBarsOpacity->setValue( round(group.readEntry("ErrorBarsOpacity", m_curve->errorBarsOpacity())*100.0) );
1728 }
1729 
1730 void HistogramDock::loadConfigFromTemplate(KConfig& config) {
1731     //extract the name of the template from the file name
1732     QString name;
1733     int index = config.name().lastIndexOf(QLatin1String("/"));
1734     if (index != -1)
1735         name = config.name().right(config.name().size() - index - 1);
1736     else
1737         name = config.name();
1738 
1739     int size = m_curvesList.size();
1740     if (size > 1)
1741         m_curve->beginMacro(i18n("%1 xy-curves: template \"%2\" loaded", size, name));
1742     else
1743         m_curve->beginMacro(i18n("%1: template \"%2\" loaded", m_curve->name(), name));
1744 
1745     this->loadConfig(config);
1746 
1747     m_curve->endMacro();
1748 }
1749 
1750 void HistogramDock::saveConfigAsTemplate(KConfig& config) {
1751     KConfigGroup group = config.group( "Histogram" );
1752 
1753     //Line
1754     group.writeEntry("LineType", ui.cbLineType->currentIndex());
1755     group.writeEntry("LineStyle", ui.cbLineStyle->currentIndex());
1756     group.writeEntry("LineColor", ui.kcbLineColor->color());
1757     group.writeEntry("LineWidth", Worksheet::convertToSceneUnits(ui.sbLineWidth->value(), Worksheet::Unit::Point));
1758     group.writeEntry("LineOpacity", ui.sbLineOpacity->value()/100.0);
1759 
1760     //Values
1761     group.writeEntry("ValuesType", ui.cbValuesType->currentIndex());
1762     group.writeEntry("ValuesPosition", ui.cbValuesPosition->currentIndex());
1763     group.writeEntry("ValuesDistance", Worksheet::convertToSceneUnits(ui.sbValuesDistance->value(), Worksheet::Unit::Point));
1764     group.writeEntry("ValuesRotation", ui.sbValuesRotation->value());
1765     group.writeEntry("ValuesOpacity", ui.sbValuesOpacity->value()/100.0);
1766     group.writeEntry("ValuesPrefix", ui.leValuesPrefix->text());
1767     group.writeEntry("ValuesSuffix", ui.leValuesSuffix->text());
1768     group.writeEntry("ValuesFont", ui.kfrValuesFont->font());
1769     group.writeEntry("ValuesColor", ui.kcbValuesColor->color());
1770 
1771     //Filling
1772     group.writeEntry("FillingEnabled", ui.chkFillingEnabled->isChecked());
1773     group.writeEntry("FillingType", ui.cbFillingType->currentIndex());
1774     group.writeEntry("FillingColorStyle", ui.cbFillingColorStyle->currentIndex());
1775     group.writeEntry("FillingImageStyle", ui.cbFillingImageStyle->currentIndex());
1776     group.writeEntry("FillingBrushStyle", ui.cbFillingBrushStyle->currentIndex());
1777     group.writeEntry("FillingFileName", ui.leFillingFileName->text());
1778     group.writeEntry("FillingFirstColor", ui.kcbFillingFirstColor->color());
1779     group.writeEntry("FillingSecondColor", ui.kcbFillingSecondColor->color());
1780     group.writeEntry("FillingOpacity", ui.sbFillingOpacity->value()/100.0);
1781 
1782     config.sync();
1783 }