File indexing completed on 2025-10-19 03:37:34

0001 /*
0002     File                 : CartesianPlotLegendDock.cpp
0003     Project              : LabPlot
0004     Description          : widget for cartesian plot legend properties
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2013-2023 Alexander Semke <alexander.semke@web.de>
0007     SPDX-FileCopyrightText: 2024 Stefan Gerlach <stefan.gerlach@uni.kn>
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #include "CartesianPlotLegendDock.h"
0013 #include "backend/core/Settings.h"
0014 #include "backend/worksheet/Worksheet.h"
0015 #include "backend/worksheet/plots/PlotArea.h"
0016 #include "kdefrontend/GuiTools.h"
0017 #include "kdefrontend/TemplateHandler.h"
0018 #include "kdefrontend/widgets/BackgroundWidget.h"
0019 #include "kdefrontend/widgets/LabelWidget.h"
0020 #include "kdefrontend/widgets/LineWidget.h"
0021 
0022 #include <KLocalizedString>
0023 
0024 #include <gsl/gsl_const_cgs.h>
0025 
0026 /*!
0027   \class CartesianPlotLegendDock
0028   \brief  Provides a widget for editing the properties of the cartesian plot legend currently selected in the project explorer.
0029 
0030   \ingroup kdefrontend
0031 */
0032 CartesianPlotLegendDock::CartesianPlotLegendDock(QWidget* parent)
0033     : BaseDock(parent) {
0034     ui.setupUi(this);
0035     setBaseWidgets(ui.leName, ui.teComment);
0036     setVisibilityWidgets(ui.chkVisible);
0037 
0038     //"Title"-tab
0039     auto hboxLayout = new QHBoxLayout(ui.tabTitle);
0040     labelWidget = new LabelWidget(ui.tabTitle);
0041     labelWidget->setGeometryAvailable(false);
0042     labelWidget->setBorderAvailable(false);
0043     hboxLayout->addWidget(labelWidget);
0044     hboxLayout->setContentsMargins(2, 2, 2, 2);
0045     hboxLayout->setSpacing(2);
0046 
0047     //"Background"-tab
0048     auto* gridLayout = static_cast<QGridLayout*>(ui.tabBackground->layout());
0049     backgroundWidget = new BackgroundWidget(ui.tabBackground);
0050     gridLayout->addWidget(backgroundWidget, 1, 0, 1, 3);
0051 
0052     borderLineWidget = new LineWidget(ui.tabBackground);
0053     gridLayout->addWidget(borderLineWidget, 4, 0, 1, 3);
0054 
0055     // adjust layouts in the tabs
0056     for (int i = 0; i < ui.tabWidget->count(); ++i) {
0057         auto layout = dynamic_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout());
0058         if (!layout)
0059             continue;
0060 
0061         layout->setContentsMargins(2, 2, 2, 2);
0062         layout->setHorizontalSpacing(2);
0063         layout->setVerticalSpacing(2);
0064     }
0065 
0066     CartesianPlotLegendDock::updateLocale();
0067 
0068     // SIGNAL/SLOT
0069 
0070     // General
0071     connect(ui.chbLock, &QCheckBox::clicked, this, &CartesianPlotLegendDock::lockChanged);
0072     connect(ui.kfrLabelFont, &KFontRequester::fontSelected, this, &CartesianPlotLegendDock::labelFontChanged);
0073     connect(ui.kcbLabelColor, &KColorButton::changed, this, &CartesianPlotLegendDock::labelColorChanged);
0074     connect(ui.cbOrder, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotLegendDock::labelOrderChanged);
0075     connect(ui.sbLineSymbolWidth, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::lineSymbolWidthChanged);
0076 
0077     connect(ui.chbBindLogicalPos, &QCheckBox::clicked, this, &CartesianPlotLegendDock::bindingChanged);
0078     connect(ui.cbPositionX, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotLegendDock::positionXChanged);
0079     connect(ui.cbPositionY, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotLegendDock::positionYChanged);
0080     connect(ui.sbPositionX, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::customPositionXChanged);
0081     connect(ui.sbPositionY, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::customPositionYChanged);
0082 
0083     connect(ui.cbHorizontalAlignment, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &CartesianPlotLegendDock::horizontalAlignmentChanged);
0084     connect(ui.cbVerticalAlignment, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &CartesianPlotLegendDock::verticalAlignmentChanged);
0085     connect(ui.sbRotation, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotLegendDock::rotationChanged);
0086 
0087     // Border
0088     connect(ui.sbBorderCornerRadius, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::borderCornerRadiusChanged);
0089 
0090     // Layout
0091     connect(ui.sbLayoutTopMargin, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutTopMarginChanged);
0092     connect(ui.sbLayoutBottomMargin, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutBottomMarginChanged);
0093     connect(ui.sbLayoutLeftMargin, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutLeftMarginChanged);
0094     connect(ui.sbLayoutRightMargin, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutRightMarginChanged);
0095     connect(ui.sbLayoutHorizontalSpacing, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutHorizontalSpacingChanged);
0096     connect(ui.sbLayoutVerticalSpacing, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutVerticalSpacingChanged);
0097     connect(ui.sbLayoutColumnCount, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotLegendDock::layoutColumnCountChanged);
0098 
0099     // template handler
0100     auto* frame = new QFrame(this);
0101     auto* layout = new QHBoxLayout(frame);
0102     layout->setContentsMargins(0, 11, 0, 11);
0103 
0104     auto* templateHandler = new TemplateHandler(this, QLatin1String("CartesianPlotLegend"));
0105     layout->addWidget(templateHandler);
0106     connect(templateHandler, &TemplateHandler::loadConfigRequested, this, &CartesianPlotLegendDock::loadConfigFromTemplate);
0107     connect(templateHandler, &TemplateHandler::saveConfigRequested, this, &CartesianPlotLegendDock::saveConfigAsTemplate);
0108     connect(templateHandler, &TemplateHandler::info, this, &CartesianPlotLegendDock::info);
0109 
0110     ui.verticalLayout->addWidget(frame);
0111 
0112     init();
0113 }
0114 
0115 void CartesianPlotLegendDock::init() {
0116     this->retranslateUi();
0117 }
0118 
0119 void CartesianPlotLegendDock::setLegends(QList<CartesianPlotLegend*> list) {
0120     CONDITIONAL_LOCK_RETURN;
0121     m_legendList = list;
0122     m_legend = list.first();
0123     setAspects(list);
0124 
0125     // show the properties of the first curve
0126     this->load();
0127 
0128     // on the very first start the column count shown in UI is 1.
0129     // if the this count for m_legend is also 1 then the slot layoutColumnCountChanged is not called
0130     // and we need to disable the "order" widgets here.
0131     ui.lOrder->setVisible(m_legend->layoutColumnCount() != 1);
0132     ui.cbOrder->setVisible(m_legend->layoutColumnCount() != 1);
0133 
0134     // SIGNALs/SLOTs
0135     // General
0136     connect(m_legend, &CartesianPlotLegend::labelFontChanged, this, &CartesianPlotLegendDock::legendLabelFontChanged);
0137     connect(m_legend, &CartesianPlotLegend::labelColorChanged, this, &CartesianPlotLegendDock::legendLabelColorChanged);
0138     connect(m_legend, &CartesianPlotLegend::labelColumnMajorChanged, this, &CartesianPlotLegendDock::legendLabelOrderChanged);
0139     connect(m_legend, &CartesianPlotLegend::positionChanged, this, &CartesianPlotLegendDock::legendPositionChanged);
0140     connect(m_legend, &CartesianPlotLegend::positionLogicalChanged, this, &CartesianPlotLegendDock::legendPositionLogicalChanged);
0141     connect(m_legend, &CartesianPlotLegend::horizontalAlignmentChanged, this, &CartesianPlotLegendDock::legendHorizontalAlignmentChanged);
0142     connect(m_legend, &CartesianPlotLegend::verticalAlignmentChanged, this, &CartesianPlotLegendDock::legendVerticalAlignmentChanged);
0143     connect(m_legend, &CartesianPlotLegend::rotationAngleChanged, this, &CartesianPlotLegendDock::legendRotationAngleChanged);
0144     connect(m_legend, &CartesianPlotLegend::lineSymbolWidthChanged, this, &CartesianPlotLegendDock::legendLineSymbolWidthChanged);
0145     connect(m_legend, &CartesianPlotLegend::lockChanged, this, &CartesianPlotLegendDock::legendLockChanged);
0146 
0147     // layout
0148     connect(m_legend, &CartesianPlotLegend::layoutTopMarginChanged, this, &CartesianPlotLegendDock::legendLayoutTopMarginChanged);
0149     connect(m_legend, &CartesianPlotLegend::layoutBottomMarginChanged, this, &CartesianPlotLegendDock::legendLayoutBottomMarginChanged);
0150     connect(m_legend, &CartesianPlotLegend::layoutLeftMarginChanged, this, &CartesianPlotLegendDock::legendLayoutLeftMarginChanged);
0151     connect(m_legend, &CartesianPlotLegend::layoutRightMarginChanged, this, &CartesianPlotLegendDock::legendLayoutRightMarginChanged);
0152     connect(m_legend, &CartesianPlotLegend::layoutVerticalSpacingChanged, this, &CartesianPlotLegendDock::legendLayoutVerticalSpacingChanged);
0153     connect(m_legend, &CartesianPlotLegend::layoutHorizontalSpacingChanged, this, &CartesianPlotLegendDock::legendLayoutHorizontalSpacingChanged);
0154     connect(m_legend, &CartesianPlotLegend::layoutColumnCountChanged, this, &CartesianPlotLegendDock::legendLayoutColumnCountChanged);
0155 }
0156 
0157 void CartesianPlotLegendDock::activateTitleTab() const {
0158     ui.tabWidget->setCurrentWidget(ui.tabTitle);
0159 }
0160 
0161 /*
0162  * updates the locale in the widgets. called when the application settins are changed.
0163  */
0164 void CartesianPlotLegendDock::updateLocale() {
0165     const auto numberLocale = QLocale();
0166     ui.sbLineSymbolWidth->setLocale(numberLocale);
0167     ui.sbPositionX->setLocale(numberLocale);
0168     ui.sbPositionY->setLocale(numberLocale);
0169     ui.sbPositionXLogical->setLocale(numberLocale);
0170     ui.sbPositionYLogical->setLocale(numberLocale);
0171     ui.sbBorderCornerRadius->setLocale(numberLocale);
0172     ui.sbLayoutTopMargin->setLocale(numberLocale);
0173     ui.sbLayoutBottomMargin->setLocale(numberLocale);
0174     ui.sbLayoutLeftMargin->setLocale(numberLocale);
0175     ui.sbLayoutRightMargin->setLocale(numberLocale);
0176     borderLineWidget->updateLocale();
0177 }
0178 
0179 void CartesianPlotLegendDock::updateUnits() {
0180     const KConfigGroup group = Settings::group(QStringLiteral("Settings_General"));
0181     BaseDock::Units units = (BaseDock::Units)group.readEntry("Units", static_cast<int>(Units::Metric));
0182     if (units == m_units)
0183         return;
0184 
0185     m_units = units;
0186     CONDITIONAL_LOCK_RETURN;
0187     QString suffix;
0188     auto xPosition = ui.cbPositionX->currentIndex();
0189     auto yPosition = ui.cbPositionY->currentIndex();
0190     if (m_units == Units::Metric) {
0191         // convert from imperial to metric
0192         m_worksheetUnit = Worksheet::Unit::Centimeter;
0193         suffix = QLatin1String(" cm");
0194         ui.sbLineSymbolWidth->setValue(ui.sbLineSymbolWidth->value() * GSL_CONST_CGS_INCH);
0195         if (xPosition != static_cast<int>(WorksheetElement::HorizontalPosition::Relative))
0196             ui.sbPositionX->setValue(ui.sbPositionX->value() * GSL_CONST_CGS_INCH);
0197         if (yPosition != static_cast<int>(WorksheetElement::VerticalPosition::Relative))
0198             ui.sbPositionY->setValue(ui.sbPositionY->value() * GSL_CONST_CGS_INCH);
0199         ui.sbBorderCornerRadius->setValue(ui.sbBorderCornerRadius->value() * GSL_CONST_CGS_INCH);
0200         ui.sbLayoutTopMargin->setValue(ui.sbLayoutTopMargin->value() * GSL_CONST_CGS_INCH);
0201         ui.sbLayoutBottomMargin->setValue(ui.sbLayoutBottomMargin->value() * GSL_CONST_CGS_INCH);
0202         ui.sbLayoutLeftMargin->setValue(ui.sbLayoutLeftMargin->value() * GSL_CONST_CGS_INCH);
0203         ui.sbLayoutRightMargin->setValue(ui.sbLayoutRightMargin->value() * GSL_CONST_CGS_INCH);
0204         ui.sbLayoutHorizontalSpacing->setValue(ui.sbLayoutHorizontalSpacing->value() * GSL_CONST_CGS_INCH);
0205         ui.sbLayoutVerticalSpacing->setValue(ui.sbLayoutVerticalSpacing->value() * GSL_CONST_CGS_INCH);
0206     } else {
0207         // convert from metric to imperial
0208         m_worksheetUnit = Worksheet::Unit::Inch;
0209         suffix = QLatin1String(" in");
0210         ui.sbLineSymbolWidth->setValue(ui.sbLineSymbolWidth->value() / GSL_CONST_CGS_INCH);
0211         if (xPosition != static_cast<int>(WorksheetElement::HorizontalPosition::Relative))
0212             ui.sbPositionX->setValue(ui.sbPositionX->value() / GSL_CONST_CGS_INCH);
0213         if (yPosition != static_cast<int>(WorksheetElement::VerticalPosition::Relative))
0214             ui.sbPositionY->setValue(ui.sbPositionY->value() / GSL_CONST_CGS_INCH);
0215         ui.sbBorderCornerRadius->setValue(ui.sbBorderCornerRadius->value() / GSL_CONST_CGS_INCH);
0216         ui.sbLayoutTopMargin->setValue(ui.sbLayoutTopMargin->value() / GSL_CONST_CGS_INCH);
0217         ui.sbLayoutBottomMargin->setValue(ui.sbLayoutBottomMargin->value() / GSL_CONST_CGS_INCH);
0218         ui.sbLayoutLeftMargin->setValue(ui.sbLayoutLeftMargin->value() / GSL_CONST_CGS_INCH);
0219         ui.sbLayoutRightMargin->setValue(ui.sbLayoutRightMargin->value() / GSL_CONST_CGS_INCH);
0220         ui.sbLayoutHorizontalSpacing->setValue(ui.sbLayoutHorizontalSpacing->value() / GSL_CONST_CGS_INCH);
0221         ui.sbLayoutVerticalSpacing->setValue(ui.sbLayoutVerticalSpacing->value() / GSL_CONST_CGS_INCH);
0222     }
0223 
0224     ui.sbLineSymbolWidth->setSuffix(suffix);
0225     if (xPosition != static_cast<int>(WorksheetElement::HorizontalPosition::Relative))
0226         ui.sbPositionX->setSuffix(suffix);
0227     if (yPosition != static_cast<int>(WorksheetElement::VerticalPosition::Relative))
0228         ui.sbPositionY->setSuffix(suffix);
0229     ui.sbBorderCornerRadius->setSuffix(suffix);
0230     ui.sbLayoutTopMargin->setSuffix(suffix);
0231     ui.sbLayoutBottomMargin->setSuffix(suffix);
0232     ui.sbLayoutLeftMargin->setSuffix(suffix);
0233     ui.sbLayoutRightMargin->setSuffix(suffix);
0234     ui.sbLayoutHorizontalSpacing->setSuffix(suffix);
0235     ui.sbLayoutVerticalSpacing->setSuffix(suffix);
0236 
0237     labelWidget->updateUnits();
0238 }
0239 
0240 //************************************************************
0241 //** SLOTs for changes triggered in CartesianPlotLegendDock **
0242 //************************************************************
0243 void CartesianPlotLegendDock::retranslateUi() {
0244     CONDITIONAL_LOCK_RETURN;
0245 
0246     ui.cbOrder->addItem(i18n("Column Major"));
0247     ui.cbOrder->addItem(i18n("Row Major"));
0248 
0249     // Positioning and alignment
0250     ui.cbPositionX->addItem(i18n("Left"));
0251     ui.cbPositionX->addItem(i18n("Center"));
0252     ui.cbPositionX->addItem(i18n("Right"));
0253     ui.cbPositionX->addItem(i18n("Relative to plot"));
0254 
0255     ui.cbPositionY->addItem(i18n("Top"));
0256     ui.cbPositionY->addItem(i18n("Center"));
0257     ui.cbPositionY->addItem(i18n("Bottom"));
0258     ui.cbPositionY->addItem(i18n("Relative to plot"));
0259 
0260     ui.cbHorizontalAlignment->addItem(i18n("Left"));
0261     ui.cbHorizontalAlignment->addItem(i18n("Center"));
0262     ui.cbHorizontalAlignment->addItem(i18n("Right"));
0263 
0264     ui.cbVerticalAlignment->addItem(i18n("Top"));
0265     ui.cbVerticalAlignment->addItem(i18n("Center"));
0266     ui.cbVerticalAlignment->addItem(i18n("Bottom"));
0267 
0268     QString suffix;
0269     if (m_units == Units::Metric)
0270         suffix = QLatin1String(" cm");
0271     else
0272         suffix = QLatin1String(" in");
0273 
0274     ui.sbLineSymbolWidth->setSuffix(suffix);
0275     ui.sbPositionX->setSuffix(suffix);
0276     ui.sbPositionY->setSuffix(suffix);
0277     ui.sbBorderCornerRadius->setSuffix(suffix);
0278     ui.sbLayoutTopMargin->setSuffix(suffix);
0279     ui.sbLayoutBottomMargin->setSuffix(suffix);
0280     ui.sbLayoutLeftMargin->setSuffix(suffix);
0281     ui.sbLayoutRightMargin->setSuffix(suffix);
0282     ui.sbLayoutHorizontalSpacing->setSuffix(suffix);
0283     ui.sbLayoutVerticalSpacing->setSuffix(suffix);
0284 }
0285 
0286 // "General"-tab
0287 void CartesianPlotLegendDock::lockChanged(bool locked) {
0288     CONDITIONAL_LOCK_RETURN;
0289 
0290     for (auto* legend : m_legendList)
0291         legend->setLock(locked);
0292 }
0293 
0294 // General
0295 void CartesianPlotLegendDock::labelFontChanged(const QFont& font) {
0296     CONDITIONAL_LOCK_RETURN;
0297 
0298     QFont labelsFont = font;
0299     labelsFont.setPointSize(Worksheet::convertToSceneUnits(font.pointSizeF(), Worksheet::Unit::Point));
0300     for (auto* legend : m_legendList)
0301         legend->setLabelFont(labelsFont);
0302 }
0303 
0304 void CartesianPlotLegendDock::labelColorChanged(const QColor& color) {
0305     CONDITIONAL_LOCK_RETURN;
0306 
0307     for (auto* legend : m_legendList)
0308         legend->setLabelColor(color);
0309 }
0310 
0311 void CartesianPlotLegendDock::labelOrderChanged(const int index) {
0312     CONDITIONAL_LOCK_RETURN;
0313 
0314     bool columnMajor = (index == 0);
0315     for (auto* legend : m_legendList)
0316         legend->setLabelColumnMajor(columnMajor);
0317 }
0318 
0319 void CartesianPlotLegendDock::lineSymbolWidthChanged(double value) {
0320     CONDITIONAL_RETURN_NO_LOCK;
0321 
0322     for (auto* legend : m_legendList)
0323         legend->setLineSymbolWidth(Worksheet::convertToSceneUnits(value, m_worksheetUnit));
0324 }
0325 
0326 /*!
0327     called when legend's current horizontal position relative to its parent (left, center, right, relative) is changed.
0328 */
0329 void CartesianPlotLegendDock::positionXChanged(int index) {
0330     CONDITIONAL_LOCK_RETURN;
0331 
0332     auto position = m_legend->position();
0333     auto oldHorizontalPosition = position.horizontalPosition;
0334     position.horizontalPosition = CartesianPlotLegend::HorizontalPosition(index);
0335     double x = 0.;
0336     if (position.horizontalPosition == WorksheetElement::HorizontalPosition::Relative) {
0337         switch (oldHorizontalPosition) {
0338         case WorksheetElement::HorizontalPosition::Left:
0339         case WorksheetElement::HorizontalPosition::Relative:
0340             break;
0341         case WorksheetElement::HorizontalPosition::Center:
0342             x = 0.5;
0343             break;
0344         case WorksheetElement::HorizontalPosition::Right:
0345             x = 1.0;
0346         }
0347         ui.sbPositionX->setSuffix(QStringLiteral(" %"));
0348     } else {
0349         if (m_units == Units::Metric)
0350             ui.sbPositionX->setSuffix(QStringLiteral(" cm"));
0351         else
0352             ui.sbPositionX->setSuffix(QStringLiteral(" in"));
0353     }
0354 
0355     position.point.setX(x);
0356     ui.sbPositionX->setValue(100. * x);
0357 
0358     for (auto* legend : m_legendList)
0359         legend->setPosition(position);
0360 }
0361 
0362 /*!
0363     called when legend's current vertical position relative to its parent (top, center, bottom, custom) is changed.
0364 */
0365 void CartesianPlotLegendDock::positionYChanged(int index) {
0366     CONDITIONAL_LOCK_RETURN;
0367 
0368     CartesianPlotLegend::PositionWrapper position = m_legend->position();
0369     auto oldVerticalPosition = position.verticalPosition;
0370     position.verticalPosition = CartesianPlotLegend::VerticalPosition(index);
0371     double y = 0.;
0372     if (position.verticalPosition == WorksheetElement::VerticalPosition::Relative) {
0373         switch (oldVerticalPosition) {
0374         case WorksheetElement::VerticalPosition::Top:
0375         case WorksheetElement::VerticalPosition::Relative:
0376             break;
0377         case WorksheetElement::VerticalPosition::Center:
0378             y = 0.5;
0379             break;
0380         case WorksheetElement::VerticalPosition::Bottom:
0381             y = 1.0;
0382         }
0383         ui.sbPositionY->setSuffix(QStringLiteral(" %"));
0384     } else {
0385         if (m_units == Units::Metric)
0386             ui.sbPositionY->setSuffix(QStringLiteral(" cm"));
0387         else
0388             ui.sbPositionY->setSuffix(QStringLiteral(" in"));
0389     }
0390 
0391     position.point.setY(y);
0392     ui.sbPositionY->setValue(100. * y);
0393 
0394     for (auto* legend : m_legendList)
0395         legend->setPosition(position);
0396 }
0397 
0398 void CartesianPlotLegendDock::customPositionXChanged(double value) {
0399     CONDITIONAL_RETURN_NO_LOCK;
0400 
0401     for (auto* legend : m_legendList) {
0402         auto position = legend->position();
0403         if (position.horizontalPosition == WorksheetElement::HorizontalPosition::Relative)
0404             position.point.setX(value / 100.);
0405         else
0406             position.point.setX(Worksheet::convertToSceneUnits(value, m_worksheetUnit));
0407         legend->setPosition(position);
0408     }
0409 }
0410 
0411 void CartesianPlotLegendDock::customPositionYChanged(double value) {
0412     CONDITIONAL_RETURN_NO_LOCK;
0413 
0414     for (auto* legend : m_legendList) {
0415         auto position = legend->position();
0416         if (position.verticalPosition == WorksheetElement::VerticalPosition::Relative)
0417             position.point.setY(value / 100.);
0418         else
0419             position.point.setY(Worksheet::convertToSceneUnits(value, m_worksheetUnit));
0420         legend->setPosition(position);
0421     }
0422 }
0423 void CartesianPlotLegendDock::horizontalAlignmentChanged(int index) {
0424     CONDITIONAL_LOCK_RETURN;
0425 
0426     for (auto* legend : m_legendList)
0427         legend->setHorizontalAlignment(WorksheetElement::HorizontalAlignment(index));
0428 }
0429 
0430 void CartesianPlotLegendDock::verticalAlignmentChanged(int index) {
0431     CONDITIONAL_LOCK_RETURN;
0432 
0433     for (auto* legend : m_legendList)
0434         legend->setVerticalAlignment(WorksheetElement::VerticalAlignment(index));
0435 }
0436 
0437 void CartesianPlotLegendDock::rotationChanged(int value) {
0438     CONDITIONAL_LOCK_RETURN;
0439 
0440     for (auto* legend : m_legendList)
0441         legend->setRotationAngle(value);
0442 }
0443 
0444 /*!
0445  * \brief CartesianPlotLegendDock::bindingChanged
0446  * Bind CartesianPlotLegend to the cartesian plot coords or not
0447  * \param checked
0448  */
0449 void CartesianPlotLegendDock::bindingChanged(bool checked) {
0450     // widgets for positioning using absolute plot distances
0451     ui.lPositionX->setVisible(!checked);
0452     ui.cbPositionX->setVisible(!checked);
0453     ui.sbPositionX->setVisible(!checked);
0454 
0455     ui.lPositionY->setVisible(!checked);
0456     ui.cbPositionY->setVisible(!checked);
0457     ui.sbPositionY->setVisible(!checked);
0458 
0459     // widgets for positioning using logical plot coordinates
0460     const auto* plot = static_cast<const CartesianPlot*>(m_legend->parent(AspectType::CartesianPlot));
0461     if (plot && plot->xRangeFormatDefault() == RangeT::Format::DateTime) {
0462         ui.lPositionXLogicalDateTime->setVisible(checked);
0463         ui.dtePositionXLogical->setVisible(checked);
0464 
0465         ui.lPositionXLogical->setVisible(false);
0466         ui.sbPositionXLogical->setVisible(false);
0467     } else {
0468         ui.lPositionXLogicalDateTime->setVisible(false);
0469         ui.dtePositionXLogical->setVisible(false);
0470 
0471         ui.lPositionXLogical->setVisible(checked);
0472         ui.sbPositionXLogical->setVisible(checked);
0473     }
0474 
0475     ui.lPositionYLogical->setVisible(checked);
0476     ui.sbPositionYLogical->setVisible(checked);
0477 
0478     CONDITIONAL_LOCK_RETURN;
0479 
0480     for (auto* legend : m_legendList)
0481         legend->setCoordinateBindingEnabled(checked);
0482 }
0483 
0484 // "Border"-tab
0485 void CartesianPlotLegendDock::borderCornerRadiusChanged(double value) {
0486     CONDITIONAL_RETURN_NO_LOCK;
0487 
0488     for (auto* legend : m_legendList)
0489         legend->setBorderCornerRadius(Worksheet::convertToSceneUnits(value, m_worksheetUnit));
0490 }
0491 
0492 // Layout
0493 void CartesianPlotLegendDock::layoutTopMarginChanged(double margin) {
0494     CONDITIONAL_RETURN_NO_LOCK;
0495 
0496     for (auto* legend : m_legendList)
0497         legend->setLayoutTopMargin(Worksheet::convertToSceneUnits(margin, m_worksheetUnit));
0498 }
0499 
0500 void CartesianPlotLegendDock::layoutBottomMarginChanged(double margin) {
0501     CONDITIONAL_RETURN_NO_LOCK;
0502 
0503     for (auto* legend : m_legendList)
0504         legend->setLayoutBottomMargin(Worksheet::convertToSceneUnits(margin, m_worksheetUnit));
0505 }
0506 
0507 void CartesianPlotLegendDock::layoutLeftMarginChanged(double margin) {
0508     CONDITIONAL_RETURN_NO_LOCK;
0509 
0510     for (auto* legend : m_legendList)
0511         legend->setLayoutLeftMargin(Worksheet::convertToSceneUnits(margin, m_worksheetUnit));
0512 }
0513 
0514 void CartesianPlotLegendDock::layoutRightMarginChanged(double margin) {
0515     CONDITIONAL_RETURN_NO_LOCK;
0516 
0517     for (auto* legend : m_legendList)
0518         legend->setLayoutRightMargin(Worksheet::convertToSceneUnits(margin, m_worksheetUnit));
0519 }
0520 
0521 void CartesianPlotLegendDock::layoutHorizontalSpacingChanged(double spacing) {
0522     CONDITIONAL_RETURN_NO_LOCK;
0523 
0524     for (auto* legend : m_legendList)
0525         legend->setLayoutHorizontalSpacing(Worksheet::convertToSceneUnits(spacing, m_worksheetUnit));
0526 }
0527 
0528 void CartesianPlotLegendDock::layoutVerticalSpacingChanged(double spacing) {
0529     CONDITIONAL_RETURN_NO_LOCK;
0530 
0531     for (auto* legend : m_legendList)
0532         legend->setLayoutVerticalSpacing(Worksheet::convertToSceneUnits(spacing, m_worksheetUnit));
0533 }
0534 
0535 void CartesianPlotLegendDock::layoutColumnCountChanged(int count) {
0536     ui.lOrder->setVisible(count != 1);
0537     ui.cbOrder->setVisible(count != 1);
0538 
0539     CONDITIONAL_LOCK_RETURN;
0540 
0541     for (auto* legend : m_legendList)
0542         legend->setLayoutColumnCount(count);
0543 }
0544 
0545 //*************************************************************
0546 //**** SLOTs for changes triggered in CartesianPlotLegend *****
0547 //*************************************************************
0548 // General
0549 void CartesianPlotLegendDock::legendLabelFontChanged(QFont& font) {
0550     CONDITIONAL_LOCK_RETURN;
0551     // we need to set the font size in points for KFontRequester
0552     QFont f(font);
0553     f.setPointSizeF(round(Worksheet::convertFromSceneUnits(f.pixelSize(), Worksheet::Unit::Point)));
0554     ui.kfrLabelFont->setFont(f);
0555 }
0556 
0557 void CartesianPlotLegendDock::legendLabelColorChanged(QColor& color) {
0558     CONDITIONAL_LOCK_RETURN;
0559     ui.kcbLabelColor->setColor(color);
0560 }
0561 
0562 void CartesianPlotLegendDock::legendLabelOrderChanged(bool b) {
0563     CONDITIONAL_LOCK_RETURN;
0564     if (b)
0565         ui.cbOrder->setCurrentIndex(0); // column major
0566     else
0567         ui.cbOrder->setCurrentIndex(1); // row major
0568 }
0569 
0570 void CartesianPlotLegendDock::legendLineSymbolWidthChanged(float value) {
0571     CONDITIONAL_LOCK_RETURN;
0572     ui.sbLineSymbolWidth->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0573 }
0574 
0575 void CartesianPlotLegendDock::legendHorizontalAlignmentChanged(TextLabel::HorizontalAlignment index) {
0576     CONDITIONAL_LOCK_RETURN;
0577     ui.cbHorizontalAlignment->setCurrentIndex(static_cast<int>(index));
0578 }
0579 
0580 void CartesianPlotLegendDock::legendVerticalAlignmentChanged(TextLabel::VerticalAlignment index) {
0581     CONDITIONAL_LOCK_RETURN;
0582     ui.cbVerticalAlignment->setCurrentIndex(static_cast<int>(index));
0583 }
0584 
0585 // called when anchor changes
0586 void CartesianPlotLegendDock::legendPositionChanged(const CartesianPlotLegend::PositionWrapper& position) {
0587     CONDITIONAL_LOCK_RETURN;
0588 
0589     ui.cbPositionX->setCurrentIndex(static_cast<int>(position.horizontalPosition));
0590     ui.cbPositionY->setCurrentIndex(static_cast<int>(position.verticalPosition));
0591     if (position.horizontalPosition == WorksheetElement::HorizontalPosition::Relative) {
0592         ui.sbPositionX->setValue(position.point.x() * 100.);
0593         ui.sbPositionX->setSuffix(QStringLiteral(" %"));
0594     } else
0595         ui.sbPositionX->setValue(Worksheet::convertFromSceneUnits(position.point.x(), m_worksheetUnit));
0596 
0597     if (position.verticalPosition == WorksheetElement::VerticalPosition::Relative) {
0598         ui.sbPositionY->setValue(position.point.y() * 100.);
0599         ui.sbPositionY->setSuffix(QStringLiteral(" %"));
0600     } else
0601         ui.sbPositionY->setValue(Worksheet::convertFromSceneUnits(position.point.y(), m_worksheetUnit));
0602 }
0603 
0604 // called when position relative to anchor changes (aka. position.point)
0605 void CartesianPlotLegendDock::legendPositionLogicalChanged(QPointF pos) {
0606     CONDITIONAL_LOCK_RETURN;
0607     ui.sbPositionXLogical->setValue(pos.x());
0608     ui.dtePositionXLogical->setMSecsSinceEpochUTC(pos.x());
0609     ui.sbPositionYLogical->setValue(pos.y());
0610     // TODO: why not ui.dtePositionYLogical->setMSecsSinceEpochUTC(pos.y());
0611 }
0612 
0613 void CartesianPlotLegendDock::legendRotationAngleChanged(qreal angle) {
0614     CONDITIONAL_LOCK_RETURN;
0615     ui.sbRotation->setValue(angle);
0616 }
0617 
0618 void CartesianPlotLegendDock::legendLockChanged(bool on) {
0619     CONDITIONAL_LOCK_RETURN;
0620     ui.chbLock->setChecked(on);
0621 }
0622 
0623 // Border
0624 void CartesianPlotLegendDock::legendBorderCornerRadiusChanged(float value) {
0625     CONDITIONAL_LOCK_RETURN;
0626     ui.sbBorderCornerRadius->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0627 }
0628 
0629 // Layout
0630 void CartesianPlotLegendDock::legendLayoutTopMarginChanged(float value) {
0631     CONDITIONAL_LOCK_RETURN;
0632     ui.sbLayoutTopMargin->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0633 }
0634 
0635 void CartesianPlotLegendDock::legendLayoutBottomMarginChanged(float value) {
0636     CONDITIONAL_LOCK_RETURN;
0637     ui.sbLayoutBottomMargin->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0638 }
0639 
0640 void CartesianPlotLegendDock::legendLayoutLeftMarginChanged(float value) {
0641     CONDITIONAL_LOCK_RETURN;
0642     ui.sbLayoutLeftMargin->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0643 }
0644 
0645 void CartesianPlotLegendDock::legendLayoutRightMarginChanged(float value) {
0646     CONDITIONAL_LOCK_RETURN;
0647     ui.sbLayoutRightMargin->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0648 }
0649 
0650 void CartesianPlotLegendDock::legendLayoutVerticalSpacingChanged(float value) {
0651     CONDITIONAL_LOCK_RETURN;
0652     ui.sbLayoutVerticalSpacing->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0653 }
0654 
0655 void CartesianPlotLegendDock::legendLayoutHorizontalSpacingChanged(float value) {
0656     CONDITIONAL_LOCK_RETURN;
0657     ui.sbLayoutHorizontalSpacing->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit));
0658 }
0659 
0660 void CartesianPlotLegendDock::legendLayoutColumnCountChanged(int value) {
0661     CONDITIONAL_LOCK_RETURN;
0662     ui.sbLayoutColumnCount->setValue(value);
0663 }
0664 
0665 //*************************************************************
0666 //******************** SETTINGS *******************************
0667 //*************************************************************
0668 void CartesianPlotLegendDock::load() {
0669     // General-tab
0670 
0671     // Format
0672     // we need to set the font size in points for KFontRequester
0673     QFont font = m_legend->labelFont();
0674     font.setPointSizeF(std::round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)));
0675     ui.kfrLabelFont->setFont(font);
0676 
0677     ui.kcbLabelColor->setColor(m_legend->labelColor());
0678     bool columnMajor = m_legend->labelColumnMajor();
0679     if (columnMajor)
0680         ui.cbOrder->setCurrentIndex(0); // column major
0681     else
0682         ui.cbOrder->setCurrentIndex(1); // row major
0683 
0684     ui.sbLineSymbolWidth->setValue(Worksheet::convertFromSceneUnits(m_legend->lineSymbolWidth(), m_worksheetUnit));
0685 
0686     // Geometry
0687 
0688     // widgets for positioning using absolute plot distances
0689     ui.cbPositionX->setCurrentIndex((int)m_legend->position().horizontalPosition);
0690     // positionXChanged(ui.cbPositionX->currentIndex());
0691     if (m_legend->position().horizontalPosition == WorksheetElement::HorizontalPosition::Relative) {
0692         ui.sbPositionX->setValue(m_legend->position().point.x() * 100);
0693         ui.sbPositionX->setSuffix(QStringLiteral(" %"));
0694     } else
0695         ui.sbPositionX->setValue(Worksheet::convertFromSceneUnits(m_legend->position().point.x(), m_worksheetUnit));
0696     ui.cbPositionY->setCurrentIndex((int)m_legend->position().verticalPosition);
0697     // positionYChanged(ui.cbPositionY->currentIndex());
0698     if (m_legend->position().verticalPosition == WorksheetElement::VerticalPosition::Relative) {
0699         ui.sbPositionY->setValue(m_legend->position().point.y() * 100);
0700         ui.sbPositionY->setSuffix(QStringLiteral(" %"));
0701     } else
0702         ui.sbPositionY->setValue(Worksheet::convertFromSceneUnits(m_legend->position().point.y(), m_worksheetUnit));
0703 
0704     ui.cbHorizontalAlignment->setCurrentIndex((int)m_legend->horizontalAlignment());
0705     ui.cbVerticalAlignment->setCurrentIndex((int)m_legend->verticalAlignment());
0706 
0707     // widgets for positioning using logical plot coordinates
0708     bool allowLogicalCoordinates = (m_legend->plot() != nullptr);
0709     ui.lBindLogicalPos->setVisible(allowLogicalCoordinates);
0710     ui.chbBindLogicalPos->setVisible(allowLogicalCoordinates);
0711 
0712     if (allowLogicalCoordinates) {
0713         const auto* plot = static_cast<const CartesianPlot*>(m_legend->plot());
0714         if (plot->xRangeFormatDefault() == RangeT::Format::Numeric) {
0715             ui.lPositionXLogical->show();
0716             ui.sbPositionXLogical->show();
0717             ui.lPositionXLogicalDateTime->hide();
0718             ui.dtePositionXLogical->hide();
0719 
0720             ui.sbPositionXLogical->setValue(m_legend->positionLogical().x());
0721             ui.sbPositionYLogical->setValue(m_legend->positionLogical().y());
0722         } else { // DateTime
0723             ui.lPositionXLogical->hide();
0724             ui.sbPositionXLogical->hide();
0725             ui.lPositionXLogicalDateTime->show();
0726             ui.dtePositionXLogical->show();
0727 
0728             ui.dtePositionXLogical->setDisplayFormat(plot->rangeDateTimeFormat(Dimension::X));
0729             ui.dtePositionXLogical->setMSecsSinceEpochUTC(m_legend->positionLogical().x());
0730         }
0731 
0732         ui.chbBindLogicalPos->setChecked(m_legend->coordinateBindingEnabled());
0733         bindingChanged(m_legend->coordinateBindingEnabled());
0734     } else {
0735         ui.lPositionXLogical->hide();
0736         ui.sbPositionXLogical->hide();
0737         ui.lPositionYLogical->hide();
0738         ui.sbPositionYLogical->hide();
0739         ui.lPositionXLogicalDateTime->hide();
0740         ui.dtePositionXLogical->hide();
0741     }
0742 
0743     ui.sbRotation->setValue(m_legend->rotationAngle());
0744     ui.chbLock->setChecked(m_legend->isLocked());
0745     ui.chkVisible->setChecked(m_legend->isVisible());
0746 
0747     // legend title, background and border line
0748     QList<Background*> backgrounds;
0749     QList<TextLabel*> labels;
0750     QList<Line*> borderLines;
0751     for (auto* legend : m_legendList) {
0752         labels << legend->title();
0753         backgrounds << legend->background();
0754         borderLines << legend->borderLine();
0755     }
0756 
0757     labelWidget->setLabels(labels);
0758     backgroundWidget->setBackgrounds(backgrounds);
0759     borderLineWidget->setLines(borderLines);
0760 
0761     // Border
0762     ui.sbBorderCornerRadius->setValue(Worksheet::convertFromSceneUnits(m_legend->borderCornerRadius(), m_worksheetUnit));
0763 
0764     // Layout
0765     ui.sbLayoutTopMargin->setValue(Worksheet::convertFromSceneUnits(m_legend->layoutTopMargin(), m_worksheetUnit));
0766     ui.sbLayoutBottomMargin->setValue(Worksheet::convertFromSceneUnits(m_legend->layoutBottomMargin(), m_worksheetUnit));
0767     ui.sbLayoutLeftMargin->setValue(Worksheet::convertFromSceneUnits(m_legend->layoutLeftMargin(), m_worksheetUnit));
0768     ui.sbLayoutRightMargin->setValue(Worksheet::convertFromSceneUnits(m_legend->layoutRightMargin(), m_worksheetUnit));
0769     ui.sbLayoutHorizontalSpacing->setValue(Worksheet::convertFromSceneUnits(m_legend->layoutHorizontalSpacing(), m_worksheetUnit));
0770     ui.sbLayoutVerticalSpacing->setValue(Worksheet::convertFromSceneUnits(m_legend->layoutVerticalSpacing(), m_worksheetUnit));
0771 
0772     ui.sbLayoutColumnCount->setValue(m_legend->layoutColumnCount());
0773 }
0774 
0775 void CartesianPlotLegendDock::loadConfigFromTemplate(KConfig& config) {
0776     auto name = TemplateHandler::templateName(config);
0777     int size = m_legendList.size();
0778     if (size > 1)
0779         m_legend->beginMacro(i18n("%1 cartesian plot legends: template \"%2\" loaded", size, name));
0780     else
0781         m_legend->beginMacro(i18n("%1: template \"%2\" loaded", m_legend->name(), name));
0782 
0783     this->loadConfig(config);
0784 
0785     m_legend->endMacro();
0786 }
0787 
0788 void CartesianPlotLegendDock::loadConfig(KConfig& config) {
0789     KConfigGroup group = config.group(QStringLiteral("CartesianPlotLegend"));
0790 
0791     // General-tab
0792 
0793     // Format
0794     // we need to set the font size in points for KFontRequester
0795     QFont font = m_legend->labelFont();
0796     font.setPointSizeF(std::round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)));
0797     ui.kfrLabelFont->setFont(group.readEntry(QStringLiteral("LabelFont"), font));
0798 
0799     ui.kcbLabelColor->setColor(group.readEntry(QStringLiteral("LabelColor"), m_legend->labelColor()));
0800 
0801     bool columnMajor = group.readEntry(QStringLiteral("LabelColumMajor"), m_legend->labelColumnMajor());
0802     if (columnMajor)
0803         ui.cbOrder->setCurrentIndex(0); // column major
0804     else
0805         ui.cbOrder->setCurrentIndex(1); // row major
0806 
0807     ui.sbLineSymbolWidth->setValue(
0808         group.readEntry(QStringLiteral("LineSymbolWidth"), Worksheet::convertFromSceneUnits(m_legend->lineSymbolWidth(), m_worksheetUnit)));
0809 
0810     // Geometry
0811     ui.cbPositionX->setCurrentIndex(group.readEntry(QStringLiteral("PositionX"), (int)m_legend->position().horizontalPosition));
0812     ui.sbPositionX->setValue(
0813         Worksheet::convertFromSceneUnits(group.readEntry(QStringLiteral("PositionXValue"), m_legend->position().point.x()), m_worksheetUnit));
0814     ui.cbPositionY->setCurrentIndex(group.readEntry(QStringLiteral("PositionY"), (int)m_legend->position().verticalPosition));
0815     ui.sbPositionY->setValue(
0816         Worksheet::convertFromSceneUnits(group.readEntry(QStringLiteral("PositionYValue"), m_legend->position().point.y()), m_worksheetUnit));
0817     ui.sbRotation->setValue(group.readEntry(QStringLiteral("Rotation"), (int)m_legend->rotationAngle()));
0818 
0819     ui.chkVisible->setChecked(group.readEntry(QStringLiteral("Visible"), m_legend->isVisible()));
0820 
0821     // Background-tab
0822     backgroundWidget->loadConfig(group);
0823 
0824     // Border
0825     borderLineWidget->loadConfig(group);
0826     ui.sbBorderCornerRadius->setValue(
0827         Worksheet::convertFromSceneUnits(group.readEntry(QStringLiteral("BorderCornerRadius"), m_legend->borderCornerRadius()), m_worksheetUnit));
0828 
0829     // Layout
0830     ui.sbLayoutTopMargin->setValue(
0831         group.readEntry(QStringLiteral("LayoutTopMargin"), Worksheet::convertFromSceneUnits(m_legend->layoutTopMargin(), m_worksheetUnit)));
0832     ui.sbLayoutBottomMargin->setValue(
0833         group.readEntry(QStringLiteral("LayoutBottomMargin"), Worksheet::convertFromSceneUnits(m_legend->layoutBottomMargin(), m_worksheetUnit)));
0834     ui.sbLayoutLeftMargin->setValue(
0835         group.readEntry(QStringLiteral("LayoutLeftMargin"), Worksheet::convertFromSceneUnits(m_legend->layoutLeftMargin(), m_worksheetUnit)));
0836     ui.sbLayoutRightMargin->setValue(
0837         group.readEntry(QStringLiteral("LayoutRightMargin"), Worksheet::convertFromSceneUnits(m_legend->layoutRightMargin(), m_worksheetUnit)));
0838     ui.sbLayoutHorizontalSpacing->setValue(
0839         group.readEntry(QStringLiteral("LayoutHorizontalSpacing"), Worksheet::convertFromSceneUnits(m_legend->layoutHorizontalSpacing(), m_worksheetUnit)));
0840     ui.sbLayoutVerticalSpacing->setValue(
0841         group.readEntry(QStringLiteral("LayoutVerticalSpacing"), Worksheet::convertFromSceneUnits(m_legend->layoutVerticalSpacing(), m_worksheetUnit)));
0842     ui.sbLayoutColumnCount->setValue(group.readEntry(QStringLiteral("LayoutColumnCount"), m_legend->layoutColumnCount()));
0843 
0844     // Title
0845     group = config.group(QStringLiteral("PlotLegend"));
0846     labelWidget->loadConfig(group);
0847 }
0848 
0849 void CartesianPlotLegendDock::saveConfigAsTemplate(KConfig& config) {
0850     KConfigGroup group = config.group(QStringLiteral("CartesianPlotLegend"));
0851 
0852     // General-tab
0853     // Format
0854     QFont font = m_legend->labelFont();
0855     font.setPointSizeF(Worksheet::convertFromSceneUnits(font.pointSizeF(), Worksheet::Unit::Point));
0856     group.writeEntry(QStringLiteral("LabelFont"), font);
0857     group.writeEntry(QStringLiteral("LabelColor"), ui.kcbLabelColor->color());
0858     group.writeEntry(QStringLiteral("LabelColumMajorOrder"), ui.cbOrder->currentIndex() == 0); // true for "column major", false for "row major"
0859     group.writeEntry(QStringLiteral("LineSymbolWidth"), Worksheet::convertToSceneUnits(ui.sbLineSymbolWidth->value(), m_worksheetUnit));
0860 
0861     // Geometry
0862     group.writeEntry(QStringLiteral("PositionX"), ui.cbPositionX->currentIndex());
0863     group.writeEntry(QStringLiteral("PositionXValue"), Worksheet::convertToSceneUnits(ui.sbPositionX->value(), m_worksheetUnit));
0864     group.writeEntry(QStringLiteral("PositionY"), ui.cbPositionY->currentIndex());
0865     group.writeEntry(QStringLiteral("PositionYValue"), Worksheet::convertToSceneUnits(ui.sbPositionY->value(), m_worksheetUnit));
0866     group.writeEntry(QStringLiteral("Rotation"), ui.sbRotation->value());
0867 
0868     group.writeEntry(QStringLiteral("Visible"), ui.chkVisible->isChecked());
0869 
0870     // Background
0871     backgroundWidget->saveConfig(group);
0872 
0873     // Border
0874     borderLineWidget->saveConfig(group);
0875     group.writeEntry(QStringLiteral("BorderCornerRadius"), Worksheet::convertToSceneUnits(ui.sbBorderCornerRadius->value(), m_worksheetUnit));
0876 
0877     // Layout
0878     group.writeEntry(QStringLiteral("LayoutTopMargin"), Worksheet::convertToSceneUnits(ui.sbLayoutTopMargin->value(), m_worksheetUnit));
0879     group.writeEntry(QStringLiteral("LayoutBottomMargin"), Worksheet::convertToSceneUnits(ui.sbLayoutBottomMargin->value(), m_worksheetUnit));
0880     group.writeEntry(QStringLiteral("LayoutLeftMargin"), Worksheet::convertToSceneUnits(ui.sbLayoutLeftMargin->value(), m_worksheetUnit));
0881     group.writeEntry(QStringLiteral("LayoutRightMargin"), Worksheet::convertToSceneUnits(ui.sbLayoutRightMargin->value(), m_worksheetUnit));
0882     group.writeEntry(QStringLiteral("LayoutVerticalSpacing"), Worksheet::convertToSceneUnits(ui.sbLayoutVerticalSpacing->value(), m_worksheetUnit));
0883     group.writeEntry(QStringLiteral("LayoutHorizontalSpacing"), Worksheet::convertToSceneUnits(ui.sbLayoutHorizontalSpacing->value(), m_worksheetUnit));
0884     group.writeEntry(QStringLiteral("LayoutColumnCount"), ui.sbLayoutColumnCount->value());
0885 
0886     // Title
0887     group = config.group(QStringLiteral("PlotLegend"));
0888     labelWidget->saveConfig(group);
0889 
0890     config.sync();
0891 }