File indexing completed on 2024-05-12 15:28:00
0001 /*************************************************************************** 0002 File : MAtrixDock.cpp 0003 Project : LabPlot 0004 Description : widget for matrix properties 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2015 by Alexander Semke (alexander.semke@web.de) 0007 0008 ***************************************************************************/ 0009 0010 /*************************************************************************** 0011 * * 0012 * This program is free software; you can redistribute it and/or modify * 0013 * it under the terms of the GNU General Public License as published by * 0014 * the Free Software Foundation; either version 2 of the License, or * 0015 * (at your option) any later version. * 0016 * * 0017 * This program is distributed in the hope that it will be useful, * 0018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0020 * GNU General Public License for more details. * 0021 * * 0022 * You should have received a copy of the GNU General Public License * 0023 * along with this program; if not, write to the Free Software * 0024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0025 * Boston, MA 02110-1301 USA * 0026 * * 0027 ***************************************************************************/ 0028 0029 #include "MatrixDock.h" 0030 #include "commonfrontend/matrix/MatrixView.h" 0031 #include "kdefrontend/TemplateHandler.h" 0032 0033 #include <KConfig> 0034 0035 #include <QDir> 0036 0037 /*! 0038 \class MatrixDock 0039 \brief Provides a widget for editing the properties of the matrices currently selected in the project explorer. 0040 0041 \ingroup kdefrontend 0042 */ 0043 MatrixDock::MatrixDock(QWidget* parent): BaseDock(parent) { 0044 ui.setupUi(this); 0045 m_leName = ui.leName; 0046 m_leComment = ui.leComment; 0047 0048 ui.cbFormat->addItem(i18n("Decimal"), QVariant('f')); 0049 ui.cbFormat->addItem(i18n("Scientific (e)"), QVariant('e')); 0050 ui.cbFormat->addItem(i18n("Scientific (E)"), QVariant('E')); 0051 ui.cbFormat->addItem(i18n("Automatic (g)"), QVariant('g')); 0052 ui.cbFormat->addItem(i18n("Automatic (G)"), QVariant('G')); 0053 0054 ui.cbHeader->addItem(i18n("Rows and Columns")); 0055 ui.cbHeader->addItem(i18n("xy-Values")); 0056 ui.cbHeader->addItem(i18n("Rows, Columns and xy-Values")); 0057 0058 //Validators 0059 ui.leXStart->setValidator( new QDoubleValidator(ui.leXStart) ); 0060 ui.leXEnd->setValidator( new QDoubleValidator(ui.leXEnd) ); 0061 ui.leYStart->setValidator( new QDoubleValidator(ui.leYStart) ); 0062 ui.leYEnd->setValidator( new QDoubleValidator(ui.leYEnd) ); 0063 0064 connect(ui.leName, &QLineEdit::textChanged, this, &MatrixDock::nameChanged); 0065 connect(ui.leComment, &QLineEdit::textChanged, this, &MatrixDock::commentChanged); 0066 connect(ui.sbColumnCount, SIGNAL(valueChanged(int)), this, SLOT(columnCountChanged(int))); 0067 connect(ui.sbRowCount, SIGNAL(valueChanged(int)), this, SLOT(rowCountChanged(int))); 0068 connect(ui.leXStart, SIGNAL(returnPressed()), this, SLOT(xStartChanged())); 0069 connect(ui.leXEnd, SIGNAL(returnPressed()), this, SLOT(xEndChanged())); 0070 connect(ui.leYStart, SIGNAL(returnPressed()), this, SLOT(yStartChanged())); 0071 connect(ui.leYEnd, SIGNAL(returnPressed()), this, SLOT(yEndChanged())); 0072 connect(ui.cbFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(numericFormatChanged(int))); 0073 connect(ui.sbPrecision, SIGNAL(valueChanged(int)), this, SLOT(precisionChanged(int))); 0074 connect(ui.cbHeader, SIGNAL(currentIndexChanged(int)), this, SLOT(headerFormatChanged(int))); 0075 0076 auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::Matrix); 0077 ui.gridLayout->addWidget(templateHandler, 22, 0, 1, 4); 0078 templateHandler->show(); 0079 connect(templateHandler, SIGNAL(loadConfigRequested(KConfig&)), this, SLOT(loadConfigFromTemplate(KConfig&))); 0080 connect(templateHandler, SIGNAL(saveConfigRequested(KConfig&)), this, SLOT(saveConfigAsTemplate(KConfig&))); 0081 connect(templateHandler, SIGNAL(info(QString)), this, SIGNAL(info(QString))); 0082 } 0083 0084 void MatrixDock::setMatrices(QList<Matrix*> list) { 0085 m_initializing = true; 0086 m_matrixList = list; 0087 m_matrix = list.first(); 0088 m_aspect = list.first(); 0089 0090 if (list.size() == 1) { 0091 ui.leName->setEnabled(true); 0092 ui.leComment->setEnabled(true); 0093 0094 ui.leName->setText(m_matrix->name()); 0095 ui.leComment->setText(m_matrix->comment()); 0096 } else { 0097 //disable these fields if there is more than one matrix 0098 ui.leName->setEnabled(false); 0099 ui.leComment->setEnabled(false); 0100 0101 ui.leName->setText(QString()); 0102 ui.leComment->setText(QString()); 0103 } 0104 ui.leName->setStyleSheet(""); 0105 ui.leName->setToolTip(""); 0106 0107 //show the properties of the first Matrix in the list, if there are >1 matrixs 0108 this->load(); 0109 0110 // undo functions 0111 connect(m_matrix, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(matrixDescriptionChanged(const AbstractAspect*))); 0112 0113 connect(m_matrix, SIGNAL(rowCountChanged(int)), this, SLOT(matrixRowCountChanged(int))); 0114 connect(m_matrix, SIGNAL(columnCountChanged(int)), this, SLOT(matrixColumnCountChanged(int))); 0115 0116 connect(m_matrix, SIGNAL(xStartChanged(double)), this, SLOT(matrixXStartChanged(double))); 0117 connect(m_matrix, SIGNAL(xEndChanged(double)), this, SLOT(matrixXEndChanged(double))); 0118 connect(m_matrix, SIGNAL(yStartChanged(double)), this, SLOT(matrixYStartChanged(double))); 0119 connect(m_matrix, SIGNAL(yEndChanged(double)), this, SLOT(matrixYEndChanged(double))); 0120 0121 connect(m_matrix, SIGNAL(numericFormatChanged(char)), this, SLOT(matrixNumericFormatChanged(char))); 0122 connect(m_matrix, SIGNAL(precisionChanged(int)), this, SLOT(matrixPrecisionChanged(int))); 0123 connect(m_matrix, SIGNAL(headerFormatChanged(Matrix::HeaderFormat)), this, SLOT(matrixHeaderFormatChanged(Matrix::HeaderFormat))); 0124 0125 m_initializing = false; 0126 } 0127 0128 //************************************************************* 0129 //****** SLOTs for changes triggered in MatrixDock ******* 0130 //************************************************************* 0131 //mapping to the logical coordinates 0132 void MatrixDock::xStartChanged() { 0133 if (m_initializing) 0134 return; 0135 0136 QString str = ui.leXStart->text().trimmed(); 0137 if (str.isEmpty()) return; 0138 bool ok; 0139 SET_NUMBER_LOCALE 0140 const double value{ numberLocale.toDouble(str, &ok) }; 0141 if (ok) { 0142 for (auto* matrix : m_matrixList) 0143 matrix->setXStart(value); 0144 } 0145 } 0146 0147 void MatrixDock::xEndChanged() { 0148 if (m_initializing) 0149 return; 0150 0151 QString str = ui.leXEnd->text().trimmed(); 0152 if (str.isEmpty()) return; 0153 bool ok; 0154 SET_NUMBER_LOCALE 0155 const double value{ numberLocale.toDouble(str, &ok) }; 0156 if (ok) { 0157 for (auto* matrix : m_matrixList) 0158 matrix->setXEnd(value); 0159 } 0160 } 0161 0162 void MatrixDock::yStartChanged() { 0163 if (m_initializing) 0164 return; 0165 0166 QString str = ui.leYStart->text().trimmed(); 0167 if (str.isEmpty()) return; 0168 bool ok; 0169 SET_NUMBER_LOCALE 0170 const double value{ numberLocale.toDouble(str, &ok) }; 0171 if (ok) { 0172 for (auto* matrix : m_matrixList) 0173 matrix->setYStart(value); 0174 } 0175 } 0176 0177 void MatrixDock::yEndChanged() { 0178 if (m_initializing) 0179 return; 0180 0181 QString str = ui.leYEnd->text().trimmed(); 0182 if (str.isEmpty()) return; 0183 bool ok; 0184 SET_NUMBER_LOCALE 0185 const double value{ numberLocale.toDouble(str, &ok) }; 0186 if (ok) { 0187 for (auto* matrix : m_matrixList) 0188 matrix->setYEnd(value); 0189 } 0190 } 0191 0192 //format 0193 void MatrixDock::numericFormatChanged(int index) { 0194 if (m_initializing) 0195 return; 0196 0197 char format = ui.cbFormat->itemData(index).toChar().toLatin1(); 0198 for (auto* matrix : m_matrixList) 0199 matrix->setNumericFormat(format); 0200 } 0201 0202 void MatrixDock::precisionChanged(int precision) { 0203 if (m_initializing) 0204 return; 0205 0206 for (auto* matrix : m_matrixList) 0207 matrix->setPrecision(precision); 0208 } 0209 0210 void MatrixDock::headerFormatChanged(int value) { 0211 if (m_initializing) 0212 return; 0213 0214 auto format = (Matrix::HeaderFormat)value; 0215 for (auto* matrix : m_matrixList) 0216 matrix->setHeaderFormat(format); 0217 } 0218 0219 void MatrixDock::rowCountChanged(int rows) { 0220 if (m_initializing) 0221 return; 0222 0223 for (auto* matrix : m_matrixList) 0224 matrix->setRowCount(rows); 0225 } 0226 0227 void MatrixDock::columnCountChanged(int columns) { 0228 if (m_initializing) 0229 return; 0230 0231 for (auto* matrix : m_matrixList) 0232 matrix->setColumnCount(columns); 0233 } 0234 0235 //************************************************************* 0236 //******** SLOTs for changes triggered in Matrix ********* 0237 //************************************************************* 0238 void MatrixDock::matrixDescriptionChanged(const AbstractAspect* aspect) { 0239 if (m_matrix != aspect) 0240 return; 0241 0242 m_initializing = true; 0243 if (aspect->name() != ui.leName->text()) 0244 ui.leName->setText(aspect->name()); 0245 else if (aspect->comment() != ui.leComment->text()) 0246 ui.leComment->setText(aspect->comment()); 0247 0248 m_initializing = false; 0249 } 0250 0251 //matrix dimensions 0252 void MatrixDock::matrixRowCountChanged(int count) { 0253 m_initializing = true; 0254 ui.sbRowCount->setValue(count); 0255 m_initializing = false; 0256 } 0257 0258 void MatrixDock::matrixColumnCountChanged(int count) { 0259 m_initializing = true; 0260 ui.sbColumnCount->setValue(count); 0261 m_initializing = false; 0262 } 0263 0264 //mapping to the logical coordinates 0265 void MatrixDock::matrixXStartChanged(double value) { 0266 m_initializing = true; 0267 SET_NUMBER_LOCALE 0268 ui.leXStart->setText(numberLocale.toString(value)); 0269 m_initializing = false; 0270 } 0271 0272 void MatrixDock::matrixXEndChanged(double value) { 0273 m_initializing = true; 0274 SET_NUMBER_LOCALE 0275 ui.leXEnd->setText(numberLocale.toString(value)); 0276 m_initializing = false; 0277 } 0278 0279 void MatrixDock::matrixYStartChanged(double value) { 0280 m_initializing = true; 0281 SET_NUMBER_LOCALE 0282 ui.leYStart->setText(numberLocale.toString(value)); 0283 m_initializing = false; 0284 } 0285 0286 void MatrixDock::matrixYEndChanged(double value) { 0287 m_initializing = true; 0288 SET_NUMBER_LOCALE 0289 ui.leYEnd->setText(numberLocale.toString(value)); 0290 m_initializing = false; 0291 } 0292 0293 //format 0294 void MatrixDock::matrixNumericFormatChanged(char format) { 0295 m_initializing = true; 0296 int index = ui.cbFormat->findData((int)format); 0297 ui.cbFormat->setCurrentIndex(index); 0298 m_initializing = false; 0299 } 0300 0301 void MatrixDock::matrixPrecisionChanged(int precision) { 0302 m_initializing = true; 0303 ui.sbPrecision->setValue(precision); 0304 m_initializing = false; 0305 } 0306 0307 void MatrixDock::matrixHeaderFormatChanged(Matrix::HeaderFormat format) { 0308 m_initializing = true; 0309 ui.cbHeader->setCurrentIndex((int)format); 0310 m_initializing = false; 0311 } 0312 0313 //************************************************************* 0314 //******************** SETTINGS ******************************* 0315 //************************************************************* 0316 void MatrixDock::load() { 0317 //matrix dimensions 0318 ui.sbRowCount->setValue(m_matrix->rowCount()); 0319 ui.sbColumnCount->setValue(m_matrix->columnCount()); 0320 0321 //mapping to the logical coordinates 0322 SET_NUMBER_LOCALE 0323 ui.leXStart->setText(numberLocale.toString(m_matrix->xStart())); 0324 ui.leXEnd->setText(numberLocale.toString(m_matrix->xEnd())); 0325 ui.leYStart->setText(numberLocale.toString(m_matrix->yStart())); 0326 ui.leYEnd->setText(numberLocale.toString(m_matrix->yEnd())); 0327 0328 //format 0329 ui.cbFormat->setCurrentIndex(ui.cbFormat->findData((int)m_matrix->numericFormat())); 0330 ui.sbPrecision->setValue(m_matrix->precision()); 0331 ui.cbHeader->setCurrentIndex(static_cast<int>(m_matrix->headerFormat())); 0332 } 0333 0334 void MatrixDock::loadConfigFromTemplate(KConfig& config) { 0335 //extract the name of the template from the file name 0336 QString name; 0337 const int index = config.name().lastIndexOf(QLatin1String("/")); 0338 if (index != -1) 0339 name = config.name().right(config.name().size() - index - 1); 0340 else 0341 name = config.name(); 0342 0343 const int size = m_matrixList.size(); 0344 if (size>1) 0345 m_matrix->beginMacro(i18n("%1 matrices: template \"%2\" loaded", size, name)); 0346 else 0347 m_matrix->beginMacro(i18n("%1: template \"%2\" loaded", m_matrix->name(), name)); 0348 0349 this->loadConfig(config); 0350 0351 m_matrix->endMacro(); 0352 } 0353 0354 /*! 0355 loads saved matrix properties from \c config. 0356 */ 0357 void MatrixDock::loadConfig(KConfig& config) { 0358 KConfigGroup group = config.group("Matrix"); 0359 0360 //matrix dimensions 0361 ui.sbRowCount->setValue(group.readEntry("RowCount", m_matrix->rowCount())); 0362 ui.sbColumnCount->setValue(group.readEntry("ColumnCount", m_matrix->columnCount())); 0363 0364 //mapping to the logical coordinates 0365 SET_NUMBER_LOCALE 0366 ui.leXStart->setText( numberLocale.toString(group.readEntry("XStart", m_matrix->xStart())) ); 0367 ui.leXEnd->setText( numberLocale.toString(group.readEntry("XEnd", m_matrix->xEnd())) ); 0368 ui.leYStart->setText( numberLocale.toString(group.readEntry("YStart", m_matrix->yStart())) ); 0369 ui.leYEnd->setText( numberLocale.toString(group.readEntry("YEnd", m_matrix->yEnd())) ); 0370 0371 //format 0372 ui.cbFormat->setCurrentIndex( ui.cbFormat->findData(group.readEntry("NumericFormat", QString(m_matrix->numericFormat()))) ); 0373 ui.sbPrecision->setValue(group.readEntry("Precision", m_matrix->precision())); 0374 ui.cbHeader->setCurrentIndex(group.readEntry("HeaderFormat", (int)m_matrix->headerFormat())); 0375 } 0376 0377 /*! 0378 saves matrix properties to \c config. 0379 */ 0380 void MatrixDock::saveConfigAsTemplate(KConfig& config) { 0381 KConfigGroup group = config.group("Matrix"); 0382 0383 //matrix dimensions 0384 group.writeEntry("RowCount", ui.sbRowCount->value()); 0385 group.writeEntry("ColumnCount", ui.sbColumnCount->value()); 0386 0387 //mapping to the logical coordinates 0388 SET_NUMBER_LOCALE 0389 group.writeEntry("XStart", numberLocale.toDouble(ui.leXStart->text()) ); 0390 group.writeEntry("XEnd", numberLocale.toDouble(ui.leXEnd->text()) ); 0391 group.writeEntry("YStart", numberLocale.toDouble(ui.leYStart->text()) ); 0392 group.writeEntry("YEnd", numberLocale.toDouble(ui.leYEnd->text()) ); 0393 0394 //format 0395 group.writeEntry("NumericFormat", ui.cbFormat->itemData(ui.cbFormat->currentIndex())); 0396 group.writeEntry("Precision", ui.sbPrecision->value()); 0397 group.writeEntry("HeaderFormat", ui.cbHeader->currentIndex()); 0398 0399 config.sync(); 0400 }