File indexing completed on 2024-05-12 15:28:01

0001 /***************************************************************************
0002     File                 : ReferenceLineDock.cpp
0003     Project              : LabPlot
0004     Description          : Dock widget for the reference line on the plot
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2020 Alexander Semke (alexander.semke@web.de)
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *  This program is free software; you can redistribute it and/or modify   *
0012  *  it under the terms of the GNU General Public License as published by   *
0013  *  the Free Software Foundation; either version 2 of the License, or      *
0014  *  (at your option) any later version.                                    *
0015  *                                                                         *
0016  *  This program is distributed in the hope that it will be useful,        *
0017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0019  *  GNU General Public License for more details.                           *
0020  *                                                                         *
0021  *   You should have received a copy of the GNU General Public License     *
0022  *   along with this program; if not, write to the Free Software           *
0023  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0024  *   Boston, MA  02110-1301  USA                                           *
0025  *                                                                         *
0026  ***************************************************************************/
0027 
0028 #include "ReferenceLineDock.h"
0029 #include "backend/worksheet/Worksheet.h"
0030 #include "backend/worksheet/plots/cartesian/ReferenceLine.h"
0031 
0032 #include "kdefrontend/TemplateHandler.h"
0033 #include "kdefrontend/GuiTools.h"
0034 
0035 #include <KLocalizedString>
0036 #include <KConfig>
0037 
0038 ReferenceLineDock::ReferenceLineDock(QWidget* parent) : BaseDock(parent) {
0039     ui.setupUi(this);
0040     m_leName = ui.leName;
0041     m_leComment = ui.leComment;
0042 
0043     ui.cbOrientation->addItem(i18n("Horizontal"));
0044     ui.cbOrientation->addItem(i18n("Vertical"));
0045 
0046     ui.lePosition->setValidator( new QDoubleValidator(ui.lePosition) );
0047 
0048     SET_NUMBER_LOCALE
0049     ui.sbLineWidth->setLocale(numberLocale);
0050 
0051     //SLOTS
0052     //General
0053     connect(ui.leName, &QLineEdit::textChanged, this, &ReferenceLineDock::nameChanged);
0054     connect(ui.leComment, &QLineEdit::textChanged, this, &ReferenceLineDock::commentChanged);
0055 
0056     connect(ui.cbOrientation, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ReferenceLineDock::orientationChanged);
0057     connect(ui.lePosition, &QLineEdit::textChanged, this, &ReferenceLineDock::positionChanged);
0058     connect(ui.chkVisible, &QCheckBox::clicked, this, &ReferenceLineDock::visibilityChanged);
0059 
0060     connect(ui.cbLineStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ReferenceLineDock::styleChanged);
0061     connect(ui.kcbLineColor, &KColorButton::changed, this, &ReferenceLineDock::colorChanged);
0062     connect(ui.sbLineWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &ReferenceLineDock::widthChanged);
0063     connect(ui.sbLineOpacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &ReferenceLineDock::opacityChanged);
0064 
0065     m_initializing = true;
0066     GuiTools::updatePenStyles(ui.cbLineStyle, QColor(Qt::black));
0067     m_initializing = false;
0068 }
0069 
0070 void ReferenceLineDock::setReferenceLines(QList<ReferenceLine*> list) {
0071     m_initializing = true;
0072     m_linesList = list;
0073     m_line = list.first();
0074     m_aspect = list.first();
0075     Q_ASSERT(m_line);
0076 
0077     //if there is more then one point in the list, disable the comment and name widgets in "general"
0078     if (list.size() == 1) {
0079         ui.lName->setEnabled(true);
0080         ui.leName->setEnabled(true);
0081         ui.lComment->setEnabled(true);
0082         ui.leComment->setEnabled(true);
0083         ui.leName->setText(m_line->name());
0084         ui.leComment->setText(m_line->comment());
0085     } else {
0086         ui.lName->setEnabled(false);
0087         ui.leName->setEnabled(false);
0088         ui.lComment->setEnabled(false);
0089         ui.leComment->setEnabled(false);
0090         ui.leName->setText(QString());
0091         ui.leComment->setText(QString());
0092     }
0093     ui.leName->setStyleSheet("");
0094     ui.leName->setToolTip("");
0095 
0096     //show the properties of the first reference line
0097     this->load();
0098 
0099     //SIGNALs/SLOTs
0100     connect(m_line, &AbstractAspect::aspectDescriptionChanged,this, &ReferenceLineDock::lineDescriptionChanged);
0101     connect(m_line, &ReferenceLine::visibleChanged, this, &ReferenceLineDock::lineVisibilityChanged);
0102 
0103     //position
0104     connect(m_line, &ReferenceLine::orientationChanged, this, &ReferenceLineDock::lineOrientationChanged);
0105     connect(m_line, &ReferenceLine::positionChanged, this, &ReferenceLineDock::linePositionChanged);
0106 
0107     //line
0108     connect(m_line, &ReferenceLine::penChanged, this, &ReferenceLineDock::linePenChanged);
0109     connect(m_line, &ReferenceLine::opacityChanged, this, &ReferenceLineDock::lineOpacityChanged);
0110 }
0111 
0112 /*
0113  * updates the locale in the widgets. called when the application settins are changed.
0114  */
0115 void ReferenceLineDock::updateLocale() {
0116     SET_NUMBER_LOCALE
0117     ui.sbLineWidth->setLocale(numberLocale);
0118 
0119     Lock lock(m_initializing);
0120     ui.lePosition->setText(numberLocale.toString(m_line->position()));
0121 }
0122 
0123 //**********************************************************
0124 //*** SLOTs for changes triggered in ReferenceLineDock *****
0125 //**********************************************************
0126 //Position
0127 void ReferenceLineDock::orientationChanged(int index) {
0128     auto orientation{ReferenceLine::Orientation(index)};
0129     if (orientation == ReferenceLine::Orientation::Horizontal)
0130         ui.lPosition->setText(QLatin1String("y:"));
0131     else
0132         ui.lPosition->setText(QLatin1String("x:"));
0133 
0134     if (m_initializing)
0135         return;
0136 
0137     for (auto* line : m_linesList)
0138         line->setOrientation(orientation);
0139 }
0140 
0141 void ReferenceLineDock::positionChanged() {
0142     if (m_initializing)
0143         return;
0144 
0145     bool ok;
0146     SET_NUMBER_LOCALE
0147     const double pos{ numberLocale.toDouble(ui.lePosition->text(), &ok) };
0148     if (ok) {
0149         for (auto* line : m_linesList)
0150             line->setPosition(pos);
0151     }
0152 }
0153 
0154 //Line
0155 void ReferenceLineDock::styleChanged(int index) {
0156     if (m_initializing)
0157         return;
0158 
0159     const auto penStyle = Qt::PenStyle(index);
0160     QPen pen;
0161     for (auto* line : m_linesList) {
0162         pen = line->pen();
0163         pen.setStyle(penStyle);
0164         line->setPen(pen);
0165     }
0166 }
0167 
0168 void ReferenceLineDock::colorChanged(const QColor& color) {
0169     if (m_initializing)
0170         return;
0171 
0172     for (auto* line : m_linesList) {
0173         QPen pen = line->pen();
0174         pen.setColor(color);
0175         line->setPen(pen);
0176     }
0177 
0178     m_initializing = true;
0179     GuiTools::updatePenStyles(ui.cbLineStyle, color);
0180     m_initializing = false;
0181 }
0182 
0183 void ReferenceLineDock::widthChanged(double value) {
0184     if (m_initializing)
0185         return;
0186 
0187     for (auto* line : m_linesList) {
0188         QPen pen = line->pen();
0189         pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) );
0190         line->setPen(pen);
0191     }
0192 }
0193 
0194 void ReferenceLineDock::opacityChanged(int value) {
0195     if (m_initializing)
0196         return;
0197 
0198     qreal opacity = (double)value/100.;
0199     for (auto* line : m_linesList)
0200         line->setOpacity(opacity);
0201 }
0202 
0203 void ReferenceLineDock::visibilityChanged(bool state) {
0204     if (m_initializing)
0205         return;
0206 
0207     for (auto* line : m_linesList)
0208         line->setVisible(state);
0209 }
0210 
0211 //*************************************************************
0212 //******* SLOTs for changes triggered in ReferenceLine ********
0213 //*************************************************************
0214 void ReferenceLineDock::lineDescriptionChanged(const AbstractAspect* aspect) {
0215     if (m_line != aspect)
0216         return;
0217 
0218     m_initializing = true;
0219     if (aspect->name() != ui.leName->text())
0220         ui.leName->setText(aspect->name());
0221     else if (aspect->comment() != ui.leComment->text())
0222         ui.leComment->setText(aspect->comment());
0223 
0224     m_initializing = false;
0225 }
0226 
0227 void ReferenceLineDock::linePositionChanged(double position) {
0228     m_initializing = true;
0229     ui.lePosition->setText(QString::number(position));
0230     m_initializing = false;
0231 }
0232 
0233 void ReferenceLineDock::lineOrientationChanged(ReferenceLine::Orientation orientation) {
0234     m_initializing = true;
0235     ui.cbOrientation->setCurrentIndex(static_cast<int>(orientation));
0236     m_initializing = false;
0237 }
0238 
0239 void ReferenceLineDock::linePenChanged(const QPen& pen) {
0240     m_initializing = true;
0241     ui.cbLineStyle->setCurrentIndex( (int)pen.style());
0242     ui.kcbLineColor->setColor( pen.color());
0243     GuiTools::updatePenStyles(ui.cbLineStyle, pen.color());
0244     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits( pen.widthF(), Worksheet::Unit::Point) );
0245     m_initializing = false;
0246 }
0247 
0248 void ReferenceLineDock::lineOpacityChanged(qreal opacity) {
0249     m_initializing = true;
0250     ui.sbLineOpacity->setValue( round(opacity*100.0) );
0251     m_initializing = false;
0252 }
0253 
0254 void ReferenceLineDock::lineVisibilityChanged(bool on) {
0255     m_initializing = true;
0256     ui.chkVisible->setChecked(on);
0257     m_initializing = false;
0258 }
0259 
0260 //**********************************************************
0261 //******************** SETTINGS ****************************
0262 //**********************************************************
0263 void ReferenceLineDock::load() {
0264     if (!m_line)
0265         return;
0266 
0267     m_initializing = true;
0268 
0269     SET_NUMBER_LOCALE
0270     ui.cbOrientation->setCurrentIndex(static_cast<int>(m_line->orientation()));
0271     ui.lePosition->setText(numberLocale.toString(m_line->position()));
0272     ui.cbLineStyle->setCurrentIndex( (int) m_line->pen().style() );
0273     ui.kcbLineColor->setColor( m_line->pen().color() );
0274     ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(m_line->pen().widthF(), Worksheet::Unit::Point) );
0275     ui.sbLineOpacity->setValue( round(m_line->opacity()*100.0) );
0276     ui.chkVisible->setChecked( m_line->isVisible() );
0277 
0278     m_initializing = false;
0279 }