File indexing completed on 2025-07-13 03:32:45
0001 /* 0002 File : MAtrixDock.cpp 0003 Project : LabPlot 0004 Description : widget for matrix properties 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2015 Alexander Semke <alexander.semke@web.de> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "MatrixDock.h" 0012 #include "commonfrontend/matrix/MatrixView.h" 0013 #include "kdefrontend/TemplateHandler.h" 0014 0015 #include <KConfig> 0016 #include <KConfigGroup> 0017 0018 #include <QDir> 0019 0020 /*! 0021 \class MatrixDock 0022 \brief Provides a widget for editing the properties of the matrices currently selected in the project explorer. 0023 0024 \ingroup kdefrontend 0025 */ 0026 MatrixDock::MatrixDock(QWidget* parent) 0027 : BaseDock(parent) { 0028 ui.setupUi(this); 0029 setBaseWidgets(ui.leName, ui.teComment); 0030 0031 ui.cbFormat->addItem(i18n("Decimal"), QVariant('f')); 0032 ui.cbFormat->addItem(i18n("Scientific (e)"), QVariant('e')); 0033 ui.cbFormat->addItem(i18n("Scientific (E)"), QVariant('E')); 0034 ui.cbFormat->addItem(i18n("Automatic (g)"), QVariant('g')); 0035 ui.cbFormat->addItem(i18n("Automatic (G)"), QVariant('G')); 0036 0037 ui.cbHeader->addItem(i18n("Rows and Columns")); 0038 ui.cbHeader->addItem(i18n("xy-Values")); 0039 ui.cbHeader->addItem(i18n("Rows, Columns and xy-Values")); 0040 0041 // Validators 0042 ui.leXStart->setValidator(new QDoubleValidator(ui.leXStart)); 0043 ui.leXEnd->setValidator(new QDoubleValidator(ui.leXEnd)); 0044 ui.leYStart->setValidator(new QDoubleValidator(ui.leYStart)); 0045 ui.leYEnd->setValidator(new QDoubleValidator(ui.leYEnd)); 0046 0047 connect(ui.sbColumnCount, QOverload<int>::of(&QSpinBox::valueChanged), this, &MatrixDock::columnCountChanged); 0048 connect(ui.sbRowCount, QOverload<int>::of(&QSpinBox::valueChanged), this, &MatrixDock::rowCountChanged); 0049 connect(ui.leXStart, &QLineEdit::textChanged, this, &MatrixDock::xStartChanged); 0050 connect(ui.leXEnd, &QLineEdit::textChanged, this, &MatrixDock::xEndChanged); 0051 connect(ui.leYStart, &QLineEdit::textChanged, this, &MatrixDock::yStartChanged); 0052 connect(ui.leYEnd, &QLineEdit::textChanged, this, &MatrixDock::yEndChanged); 0053 connect(ui.cbFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MatrixDock::numericFormatChanged); 0054 connect(ui.sbPrecision, QOverload<int>::of(&QSpinBox::valueChanged), this, &MatrixDock::precisionChanged); 0055 connect(ui.cbHeader, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MatrixDock::headerFormatChanged); 0056 0057 auto* templateHandler = new TemplateHandler(this, QLatin1String("Matrix")); 0058 ui.gridLayout->addWidget(templateHandler, 22, 0, 1, 4); 0059 // templateHandler->show(); 0060 connect(templateHandler, &TemplateHandler::loadConfigRequested, this, &MatrixDock::loadConfigFromTemplate); 0061 connect(templateHandler, &TemplateHandler::saveConfigRequested, this, &MatrixDock::saveConfigAsTemplate); 0062 connect(templateHandler, &TemplateHandler::info, this, &MatrixDock::info); 0063 } 0064 0065 void MatrixDock::setMatrices(QList<Matrix*> list) { 0066 CONDITIONAL_LOCK_RETURN; 0067 m_matrixList = list; 0068 m_matrix = list.first(); 0069 setAspects(list); 0070 0071 // show the properties of the first Matrix in the list, if there are >1 matrixs 0072 this->load(); 0073 0074 // undo functions 0075 0076 connect(m_matrix, &Matrix::rowCountChanged, this, &MatrixDock::matrixRowCountChanged); 0077 connect(m_matrix, &Matrix::columnCountChanged, this, &MatrixDock::matrixColumnCountChanged); 0078 0079 connect(m_matrix, &Matrix::xStartChanged, this, &MatrixDock::matrixXStartChanged); 0080 connect(m_matrix, &Matrix::xEndChanged, this, &MatrixDock::matrixXEndChanged); 0081 connect(m_matrix, &Matrix::yStartChanged, this, &MatrixDock::matrixYStartChanged); 0082 connect(m_matrix, &Matrix::yEndChanged, this, &MatrixDock::matrixYEndChanged); 0083 0084 connect(m_matrix, &Matrix::numericFormatChanged, this, &MatrixDock::matrixNumericFormatChanged); 0085 connect(m_matrix, &Matrix::precisionChanged, this, &MatrixDock::matrixPrecisionChanged); 0086 connect(m_matrix, &Matrix::headerFormatChanged, this, &MatrixDock::matrixHeaderFormatChanged); 0087 } 0088 0089 //************************************************************* 0090 //****** SLOTs for changes triggered in MatrixDock ******* 0091 //************************************************************* 0092 // mapping to the logical coordinates 0093 void MatrixDock::xStartChanged(const QString& text) { 0094 CONDITIONAL_LOCK_RETURN; 0095 0096 QString str = text.trimmed(); 0097 if (str.isEmpty()) 0098 return; 0099 bool ok; 0100 const double value{QLocale().toDouble(str, &ok)}; 0101 if (ok) { 0102 for (auto* matrix : m_matrixList) 0103 matrix->setXStart(value); 0104 } 0105 } 0106 0107 void MatrixDock::xEndChanged(const QString& text) { 0108 CONDITIONAL_LOCK_RETURN; 0109 0110 QString str = text.trimmed(); 0111 if (str.isEmpty()) 0112 return; 0113 bool ok; 0114 const double value{QLocale().toDouble(str, &ok)}; 0115 if (ok) { 0116 for (auto* matrix : m_matrixList) 0117 matrix->setXEnd(value); 0118 } 0119 } 0120 0121 void MatrixDock::yStartChanged(const QString& text) { 0122 CONDITIONAL_LOCK_RETURN; 0123 0124 QString str = text.trimmed(); 0125 if (str.isEmpty()) 0126 return; 0127 bool ok; 0128 const double value{QLocale().toDouble(str, &ok)}; 0129 if (ok) { 0130 for (auto* matrix : m_matrixList) 0131 matrix->setYStart(value); 0132 } 0133 } 0134 0135 void MatrixDock::yEndChanged(const QString& text) { 0136 CONDITIONAL_LOCK_RETURN; 0137 0138 QString str = text.trimmed(); 0139 if (str.isEmpty()) 0140 return; 0141 bool ok; 0142 const double value{QLocale().toDouble(str, &ok)}; 0143 if (ok) { 0144 for (auto* matrix : m_matrixList) 0145 matrix->setYEnd(value); 0146 } 0147 } 0148 0149 // format 0150 void MatrixDock::numericFormatChanged(int index) { 0151 CONDITIONAL_LOCK_RETURN; 0152 0153 char format = ui.cbFormat->itemData(index).toChar().toLatin1(); 0154 for (auto* matrix : m_matrixList) 0155 matrix->setNumericFormat(format); 0156 } 0157 0158 void MatrixDock::precisionChanged(int precision) { 0159 CONDITIONAL_LOCK_RETURN; 0160 0161 for (auto* matrix : m_matrixList) 0162 matrix->setPrecision(precision); 0163 } 0164 0165 void MatrixDock::headerFormatChanged(int value) { 0166 CONDITIONAL_LOCK_RETURN; 0167 0168 auto format = static_cast<Matrix::HeaderFormat>(value); 0169 for (auto* matrix : m_matrixList) 0170 matrix->setHeaderFormat(format); 0171 } 0172 0173 void MatrixDock::rowCountChanged(int rows) { 0174 CONDITIONAL_LOCK_RETURN; 0175 0176 for (auto* matrix : m_matrixList) 0177 matrix->setRowCount(rows); 0178 } 0179 0180 void MatrixDock::columnCountChanged(int columns) { 0181 CONDITIONAL_LOCK_RETURN; 0182 0183 for (auto* matrix : m_matrixList) 0184 matrix->setColumnCount(columns); 0185 } 0186 0187 //************************************************************* 0188 //******** SLOTs for changes triggered in Matrix ********* 0189 //************************************************************* 0190 // matrix dimensions 0191 void MatrixDock::matrixRowCountChanged(int count) { 0192 CONDITIONAL_LOCK_RETURN; 0193 ui.sbRowCount->setValue(count); 0194 } 0195 0196 void MatrixDock::matrixColumnCountChanged(int count) { 0197 CONDITIONAL_LOCK_RETURN; 0198 ui.sbColumnCount->setValue(count); 0199 } 0200 0201 // mapping to the logical coordinates 0202 void MatrixDock::matrixXStartChanged(double value) { 0203 CONDITIONAL_LOCK_RETURN; 0204 ui.leXStart->setText(QLocale().toString(value)); 0205 } 0206 0207 void MatrixDock::matrixXEndChanged(double value) { 0208 CONDITIONAL_LOCK_RETURN; 0209 ui.leXEnd->setText(QLocale().toString(value)); 0210 } 0211 0212 void MatrixDock::matrixYStartChanged(double value) { 0213 CONDITIONAL_LOCK_RETURN; 0214 ui.leYStart->setText(QLocale().toString(value)); 0215 } 0216 0217 void MatrixDock::matrixYEndChanged(double value) { 0218 CONDITIONAL_LOCK_RETURN; 0219 ui.leYEnd->setText(QLocale().toString(value)); 0220 } 0221 0222 // format 0223 void MatrixDock::matrixNumericFormatChanged(char format) { 0224 CONDITIONAL_LOCK_RETURN; 0225 int index = ui.cbFormat->findData((int)format); 0226 ui.cbFormat->setCurrentIndex(index); 0227 } 0228 0229 void MatrixDock::matrixPrecisionChanged(int precision) { 0230 CONDITIONAL_LOCK_RETURN; 0231 ui.sbPrecision->setValue(precision); 0232 } 0233 0234 void MatrixDock::matrixHeaderFormatChanged(Matrix::HeaderFormat format) { 0235 CONDITIONAL_LOCK_RETURN; 0236 ui.cbHeader->setCurrentIndex((int)format); 0237 } 0238 0239 //************************************************************* 0240 //******************** SETTINGS ******************************* 0241 //************************************************************* 0242 void MatrixDock::load() { 0243 // matrix dimensions 0244 ui.sbRowCount->setValue(m_matrix->rowCount()); 0245 ui.sbColumnCount->setValue(m_matrix->columnCount()); 0246 0247 // mapping to the logical coordinates 0248 const auto numberLocale = QLocale(); 0249 ui.leXStart->setText(numberLocale.toString(m_matrix->xStart())); 0250 ui.leXEnd->setText(numberLocale.toString(m_matrix->xEnd())); 0251 ui.leYStart->setText(numberLocale.toString(m_matrix->yStart())); 0252 ui.leYEnd->setText(numberLocale.toString(m_matrix->yEnd())); 0253 0254 // format 0255 ui.cbFormat->setCurrentIndex(ui.cbFormat->findData((int)m_matrix->numericFormat())); 0256 ui.sbPrecision->setValue(m_matrix->precision()); 0257 ui.cbHeader->setCurrentIndex(static_cast<int>(m_matrix->headerFormat())); 0258 } 0259 0260 void MatrixDock::loadConfigFromTemplate(KConfig& config) { 0261 auto name = TemplateHandler::templateName(config); 0262 const int size = m_matrixList.size(); 0263 if (size > 1) 0264 m_matrix->beginMacro(i18n("%1 matrices: template \"%2\" loaded", size, name)); 0265 else 0266 m_matrix->beginMacro(i18n("%1: template \"%2\" loaded", m_matrix->name(), name)); 0267 0268 this->loadConfig(config); 0269 0270 m_matrix->endMacro(); 0271 } 0272 0273 /*! 0274 loads saved matrix properties from \c config. 0275 */ 0276 void MatrixDock::loadConfig(KConfig& config) { 0277 KConfigGroup group = config.group(QStringLiteral("Matrix")); 0278 0279 // matrix dimensions 0280 ui.sbRowCount->setValue(group.readEntry(QStringLiteral("RowCount"), m_matrix->rowCount())); 0281 ui.sbColumnCount->setValue(group.readEntry(QStringLiteral("ColumnCount"), m_matrix->columnCount())); 0282 0283 // mapping to the logical coordinates 0284 const auto numberLocale = QLocale(); 0285 ui.leXStart->setText(numberLocale.toString(group.readEntry(QStringLiteral("XStart"), m_matrix->xStart()))); 0286 ui.leXEnd->setText(numberLocale.toString(group.readEntry(QStringLiteral("XEnd"), m_matrix->xEnd()))); 0287 ui.leYStart->setText(numberLocale.toString(group.readEntry(QStringLiteral("YStart"), m_matrix->yStart()))); 0288 ui.leYEnd->setText(numberLocale.toString(group.readEntry(QStringLiteral("YEnd"), m_matrix->yEnd()))); 0289 0290 // format 0291 ui.cbFormat->setCurrentIndex(ui.cbFormat->findData(group.readEntry(QStringLiteral("NumericFormat"), (int)(m_matrix->numericFormat())))); 0292 ui.sbPrecision->setValue(group.readEntry(QStringLiteral("Precision"), m_matrix->precision())); 0293 ui.cbHeader->setCurrentIndex(group.readEntry(QStringLiteral("HeaderFormat"), (int)m_matrix->headerFormat())); 0294 } 0295 0296 /*! 0297 saves matrix properties to \c config. 0298 */ 0299 void MatrixDock::saveConfigAsTemplate(KConfig& config) { 0300 KConfigGroup group = config.group(QStringLiteral("Matrix")); 0301 0302 // matrix dimensions 0303 group.writeEntry(QStringLiteral("RowCount"), ui.sbRowCount->value()); 0304 group.writeEntry(QStringLiteral("ColumnCount"), ui.sbColumnCount->value()); 0305 0306 // mapping to the logical coordinates 0307 const auto numberLocale = QLocale(); 0308 group.writeEntry(QStringLiteral("XStart"), numberLocale.toDouble(ui.leXStart->text())); 0309 group.writeEntry(QStringLiteral("XEnd"), numberLocale.toDouble(ui.leXEnd->text())); 0310 group.writeEntry(QStringLiteral("YStart"), numberLocale.toDouble(ui.leYStart->text())); 0311 group.writeEntry(QStringLiteral("YEnd"), numberLocale.toDouble(ui.leYEnd->text())); 0312 0313 // format 0314 group.writeEntry(QStringLiteral("NumericFormat"), ui.cbFormat->itemData(ui.cbFormat->currentIndex())); 0315 group.writeEntry(QStringLiteral("Precision"), ui.sbPrecision->value()); 0316 group.writeEntry(QStringLiteral("HeaderFormat"), ui.cbHeader->currentIndex()); 0317 0318 config.sync(); 0319 }