File indexing completed on 2025-03-09 03:34:35
0001 /* 0002 File : LineWidget.cpp 0003 Project : LabPlot 0004 Description : line settings widget 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2022-2024 Alexander Semke <alexander.semke@web.de> 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "LineWidget.h" 0011 #include "kdefrontend/GuiTools.h" 0012 #include "kdefrontend/dockwidgets/BaseDock.h" 0013 0014 #include <KConfigGroup> 0015 #include <QPainter> 0016 #include <QTimer> 0017 0018 /*! 0019 \class LineWidget 0020 \brief Widget for editing the properties of a Line object, mostly used in an appropriate dock widget. 0021 0022 \ingroup kdefrontend 0023 */ 0024 LineWidget::LineWidget(QWidget* parent) 0025 : QWidget(parent) { 0026 ui.setupUi(this); 0027 0028 ui.sbWidth->setMinimum(0); 0029 0030 connect(ui.cbType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LineWidget::typeChanged); 0031 connect(ui.cbStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LineWidget::styleChanged); 0032 connect(ui.kcbColor, &KColorButton::changed, this, &LineWidget::colorChangedSlot); 0033 connect(ui.sbWidth, QOverload<double>::of(&NumberSpinBox::valueChanged), this, &LineWidget::widthChanged); 0034 connect(ui.sbOpacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &LineWidget::opacityChanged); 0035 } 0036 0037 void LineWidget::setLines(const QList<Line*>& lines) { 0038 CONDITIONAL_LOCK_RETURN; 0039 m_lines = lines; 0040 m_line = m_lines.first(); 0041 m_prefix = m_line->prefix(); 0042 0043 if (m_line->histogramLineTypeAvailable()) { 0044 ui.lType->show(); 0045 ui.cbType->show(); 0046 0047 if (ui.cbType->count() == 0) { 0048 ui.cbType->addItem(i18n("None")); 0049 ui.cbType->addItem(i18n("Bars")); 0050 ui.cbType->addItem(i18n("Envelope")); 0051 ui.cbType->addItem(i18n("Drop Lines")); 0052 ui.cbType->addItem(i18n("Half-Bars")); 0053 } 0054 } else if (m_prefix == QLatin1String("DropLine")) { 0055 ui.lType->show(); 0056 ui.cbType->show(); 0057 0058 if (ui.cbType->count() == 0) { 0059 ui.cbType->addItem(i18n("No Drop Lines")); 0060 ui.cbType->addItem(i18n("Drop Lines, X")); 0061 ui.cbType->addItem(i18n("Drop Lines, Y")); 0062 ui.cbType->addItem(i18n("Drop Lines, XY")); 0063 ui.cbType->addItem(i18n("Drop Lines, X, Zero Baseline")); 0064 ui.cbType->addItem(i18n("Drop Lines, X, Min Baseline")); 0065 ui.cbType->addItem(i18n("Drop Lines, X, Max Baseline")); 0066 } 0067 } else { 0068 ui.lType->hide(); 0069 ui.cbType->hide(); 0070 } 0071 0072 load(); 0073 0074 connect(m_line, &Line::histogramLineTypeChanged, this, &LineWidget::histogramLineTypeChanged); 0075 connect(m_line, &Line::dropLineTypeChanged, this, &LineWidget::dropLineTypeChanged); 0076 connect(m_line, &Line::styleChanged, this, &LineWidget::lineStyleChanged); 0077 connect(m_line, &Line::colorChanged, this, &LineWidget::lineColorChanged); 0078 connect(m_line, &Line::widthChanged, this, &LineWidget::lineWidthChanged); 0079 connect(m_line, &Line::opacityChanged, this, &LineWidget::lineOpacityChanged); 0080 } 0081 0082 void LineWidget::showEvent(QShowEvent* event) { 0083 QWidget::showEvent(event); 0084 adjustLayout(); 0085 } 0086 0087 /*! 0088 * this functions adjusts the width of the first column in the layout of LineWidget 0089 * to the width of the first column in the layout of the parent widget 0090 * which LineWidget is being embedded into. 0091 */ 0092 void LineWidget::adjustLayout() { 0093 auto* parentGridLayout = dynamic_cast<QGridLayout*>(parentWidget()->layout()); 0094 if (!parentGridLayout) 0095 return; 0096 0097 auto* parentWidget = parentGridLayout->itemAtPosition(0, 0)->widget(); 0098 if (!parentWidget) 0099 return; 0100 0101 auto* gridLayout = static_cast<QGridLayout*>(layout()); 0102 auto* widget = gridLayout->itemAtPosition(2, 0)->widget(); // use the third line, the first two are optional and not always visible 0103 0104 if (parentWidget->width() >= widget->width()) { 0105 gridLayout->activate(); 0106 widget->setMinimumWidth(parentWidget->width()); 0107 updateGeometry(); 0108 } else { 0109 parentGridLayout->activate(); 0110 parentWidget->setMinimumWidth(widget->width()); 0111 this->parentWidget()->updateGeometry(); 0112 } 0113 } 0114 0115 void LineWidget::setEnabled(bool enabled) { 0116 ui.cbStyle->setEnabled(enabled); 0117 ui.kcbColor->setEnabled(enabled); 0118 ui.sbWidth->setEnabled(enabled); 0119 ui.sbOpacity->setEnabled(enabled); 0120 } 0121 0122 void LineWidget::updateLocale() { 0123 const auto numberLocale = QLocale(); 0124 ui.sbWidth->setLocale(numberLocale); 0125 } 0126 0127 //************************************************************* 0128 //******** SLOTs for changes triggered in LineWidget ********** 0129 //************************************************************* 0130 void LineWidget::typeChanged(int index) { 0131 bool enabled = true; 0132 if (m_line->histogramLineTypeAvailable()) { 0133 const auto type = Histogram::LineType(index); 0134 enabled = (type != Histogram::NoLine); 0135 0136 if (!m_initializing) { 0137 for (auto* line : m_lines) 0138 line->setHistogramLineType(type); 0139 } 0140 } else if (m_prefix == QLatin1String("DropLine")) { 0141 auto type = static_cast<XYCurve::DropLineType>(index); 0142 enabled = (type != XYCurve::DropLineType::NoDropLine); 0143 0144 if (!m_initializing) { 0145 for (auto* line : m_lines) 0146 line->setDropLineType(type); 0147 } 0148 } 0149 0150 ui.cbStyle->setEnabled(enabled); 0151 ui.kcbColor->setEnabled(enabled); 0152 ui.sbWidth->setEnabled(enabled); 0153 ui.sbOpacity->setEnabled(enabled); 0154 0155 // TODO 0156 // const bool fillingEnabled = (lineType == Histogram::LineType::Bars || lineType == Histogram::LineType::Envelope); 0157 // backgroundWidget->setEnabled(fillingEnabled); 0158 } 0159 0160 void LineWidget::styleChanged(int index) { 0161 CONDITIONAL_LOCK_RETURN; 0162 auto style = static_cast<Qt::PenStyle>(index); 0163 for (auto* line : m_lines) 0164 line->setStyle(style); 0165 } 0166 0167 void LineWidget::colorChangedSlot(const QColor& color) { 0168 CONDITIONAL_LOCK_RETURN; 0169 for (auto* line : m_lines) 0170 line->setColor(color); 0171 0172 GuiTools::updatePenStyles(ui.cbStyle, color); 0173 } 0174 0175 void LineWidget::widthChanged(double value) { 0176 CONDITIONAL_RETURN_NO_LOCK; 0177 0178 const double width = Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point); 0179 for (auto* line : m_lines) 0180 line->setWidth(width); 0181 } 0182 0183 void LineWidget::opacityChanged(int value) { 0184 CONDITIONAL_LOCK_RETURN; 0185 double opacity = static_cast<double>(value) / 100.; 0186 for (auto* line : m_lines) 0187 line->setOpacity(opacity); 0188 } 0189 0190 //************************************************************* 0191 //*********** SLOTs for changes triggered in Line ************* 0192 //************************************************************* 0193 void LineWidget::histogramLineTypeChanged(Histogram::LineType type) { 0194 CONDITIONAL_LOCK_RETURN; 0195 ui.cbType->setCurrentIndex(static_cast<int>(type)); 0196 } 0197 0198 void LineWidget::dropLineTypeChanged(XYCurve::DropLineType type) { 0199 CONDITIONAL_LOCK_RETURN; 0200 ui.cbType->setCurrentIndex(static_cast<int>(type)); 0201 } 0202 0203 void LineWidget::lineStyleChanged(Qt::PenStyle style) { 0204 CONDITIONAL_LOCK_RETURN; 0205 ui.cbStyle->setCurrentIndex(static_cast<int>(style)); 0206 } 0207 0208 void LineWidget::lineColorChanged(const QColor& color) { 0209 Q_EMIT colorChanged(color); 0210 0211 CONDITIONAL_LOCK_RETURN; 0212 ui.kcbColor->setColor(color); 0213 } 0214 0215 void LineWidget::lineWidthChanged(double width) { 0216 CONDITIONAL_LOCK_RETURN; 0217 ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(width, Worksheet::Unit::Point)); 0218 } 0219 0220 void LineWidget::lineOpacityChanged(double value) { 0221 CONDITIONAL_LOCK_RETURN; 0222 ui.sbOpacity->setValue(round(value * 100)); 0223 } 0224 0225 //********************************************************** 0226 //******************** SETTINGS **************************** 0227 //********************************************************** 0228 void LineWidget::load() { 0229 if (m_line->histogramLineTypeAvailable()) 0230 ui.cbType->setCurrentIndex(static_cast<int>(m_line->histogramLineType())); 0231 else if (m_prefix == QLatin1String("DropLine")) 0232 ui.cbType->setCurrentIndex(static_cast<int>(m_line->dropLineType())); 0233 0234 setColor(m_line->color()); 0235 ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(m_line->width(), Worksheet::Unit::Point)); 0236 ui.sbOpacity->setValue(round(m_line->opacity() * 100)); 0237 GuiTools::updatePenStyles(ui.cbStyle, ui.kcbColor->color()); 0238 ui.cbStyle->setCurrentIndex(static_cast<int>(m_line->style())); 0239 } 0240 0241 void LineWidget::loadConfig(const KConfigGroup& group) { 0242 if (m_line->histogramLineTypeAvailable()) 0243 ui.cbType->setCurrentIndex(group.readEntry(m_prefix + QStringLiteral("Type"), static_cast<int>(m_line->histogramLineType()))); 0244 else if (m_prefix == QLatin1String("DropLine")) 0245 ui.cbType->setCurrentIndex(group.readEntry("DropLineType", static_cast<int>(m_line->dropLineType()))); 0246 0247 ui.cbStyle->setCurrentIndex(group.readEntry(m_prefix + QStringLiteral("Style"), static_cast<int>(m_line->style()))); 0248 setColor(group.readEntry(m_prefix + QStringLiteral("Color"), m_line->color())); 0249 ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(group.readEntry(m_prefix + QStringLiteral("Width"), m_line->width()), Worksheet::Unit::Point)); 0250 ui.sbOpacity->setValue(group.readEntry(m_prefix + QStringLiteral("Opacity"), m_line->opacity()) * 100); 0251 GuiTools::updatePenStyles(ui.cbStyle, ui.kcbColor->color()); 0252 } 0253 0254 void LineWidget::saveConfig(KConfigGroup& group) const { 0255 if (m_line->histogramLineTypeAvailable() || m_prefix == QLatin1String("DropLine")) 0256 group.writeEntry(m_prefix + QStringLiteral("Type"), ui.cbType->currentIndex()); 0257 0258 group.writeEntry(m_prefix + QStringLiteral("Style"), ui.cbStyle->currentIndex()); 0259 group.writeEntry(m_prefix + QStringLiteral("Color"), ui.kcbColor->color()); 0260 group.writeEntry(m_prefix + QStringLiteral("Width"), Worksheet::convertToSceneUnits(ui.sbWidth->value(), Worksheet::Unit::Point)); 0261 group.writeEntry(m_prefix + QStringLiteral("Opacity"), ui.sbOpacity->value() / 100.0); 0262 } 0263 0264 void LineWidget::setColor(const QColor& color) { 0265 ui.kcbColor->setColor(color); 0266 }