Warning, file /education/kmplot/kmplot/kconstanteditor.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 KmPlot - a math. function plotter for the KDE-Desktop 0003 0004 SPDX-FileCopyrightText: 2004 Fredrik Edemar <f_edemar@linux.se> 0005 SPDX-FileCopyrightText: 2006 David Saxton <david@bluehaze.org> 0006 0007 This file is part of the KDE Project. 0008 KmPlot is part of the KDE-EDU Project. 0009 0010 SPDX-License-Identifier: GPL-2.0-or-later 0011 0012 */ 0013 0014 #include "kconstanteditor.h" 0015 #include "kmplotio.h" 0016 #include "view.h" 0017 #include "xparser.h" 0018 0019 #include <QDebug> 0020 #include <QDialogButtonBox> 0021 #include <QStandardPaths> 0022 #include <QTimer> 0023 0024 #include <KConfigGroup> 0025 #include <KMessageBox> 0026 #include <assert.h> 0027 0028 #include "ui_constantseditor.h" 0029 class ConstantsEditorWidget : public QWidget, public Ui::ConstantsEditor 0030 { 0031 public: 0032 ConstantsEditorWidget(QWidget *parent = 0) 0033 : QWidget(parent) 0034 { 0035 setupUi(this); 0036 } 0037 }; 0038 0039 // BEGIN class KConstantEditor 0040 KConstantEditor::KConstantEditor(QWidget *parent) 0041 : QDialog(parent) 0042 { 0043 m_widget = new ConstantsEditorWidget(this); 0044 0045 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); 0046 connect(buttonBox, &QDialogButtonBox::rejected, this, &KConstantEditor::reject); 0047 QVBoxLayout *dialogLayout = new QVBoxLayout(this); 0048 dialogLayout->addWidget(m_widget); 0049 dialogLayout->addWidget(buttonBox); 0050 0051 m_widget->cmdNew->setIcon(QIcon::fromTheme("document-new")); 0052 m_widget->cmdDelete->setIcon(QIcon::fromTheme("edit-delete")); 0053 0054 setWindowTitle(i18nc("@title:window", "Constants Editor")); 0055 0056 connect(this, &KConstantEditor::finished, this, &KConstantEditor::dialogFinished); 0057 0058 m_constantValidator = new ConstantValidator(this); 0059 m_widget->nameEdit->setValidator(m_constantValidator); 0060 0061 updateConstantsList(); 0062 0063 connect(m_widget->nameEdit, &KLineEdit::textEdited, this, &KConstantEditor::constantNameEdited); 0064 connect(m_widget->valueEdit, &EquationEdit::textEdited, this, &KConstantEditor::saveCurrentConstant); 0065 0066 connect(m_widget->nameEdit, &KLineEdit::textChanged, this, &KConstantEditor::checkValueValid); 0067 connect(m_widget->valueEdit, &EquationEdit::textChanged, this, &KConstantEditor::checkValueValid); 0068 0069 connect(m_widget->cmdNew, &QPushButton::clicked, this, &KConstantEditor::cmdNew_clicked); 0070 connect(m_widget->cmdDelete, &QPushButton::clicked, this, &KConstantEditor::cmdDelete_clicked); 0071 0072 connect(m_widget->constantList, &QTreeWidget::currentItemChanged, this, &KConstantEditor::selectedConstantChanged); 0073 connect(m_widget->constantList, &QTreeWidget::itemClicked, this, &KConstantEditor::itemClicked); 0074 0075 connect(XParser::self()->constants(), &Constants::constantsChanged, this, &KConstantEditor::updateConstantsList); 0076 0077 checkValueValid(); 0078 } 0079 0080 KConstantEditor::~KConstantEditor() 0081 { 0082 } 0083 0084 void KConstantEditor::dialogFinished() 0085 { 0086 XParser::self()->reparseAllFunctions(); 0087 View::self()->drawPlot(); 0088 } 0089 0090 void KConstantEditor::updateConstantsList() 0091 { 0092 m_widget->constantList->blockSignals(true); 0093 0094 // This assumes that constants have only been added or their value changed. 0095 // (since constants can only be removed via this dialog) 0096 0097 ConstantList constants = XParser::self()->constants()->list(Constant::All); 0098 for (ConstantList::iterator it = constants.begin(); it != constants.end(); ++it) { 0099 QList<QTreeWidgetItem *> list = m_widget->constantList->findItems(it.key(), Qt::MatchExactly); 0100 if (!list.isEmpty()) 0101 init(list.first(), it.key(), it.value()); 0102 else { 0103 QTreeWidgetItem *item = new QTreeWidgetItem(m_widget->constantList); 0104 init(item, it.key(), it.value()); 0105 } 0106 } 0107 0108 m_widget->constantList->blockSignals(false); 0109 } 0110 0111 void KConstantEditor::init(QTreeWidgetItem *item, const QString &name, const Constant &constant) 0112 { 0113 item->setText(0, name); 0114 item->setText(1, constant.value.expression()); 0115 item->setData(2, Qt::CheckStateRole, (constant.type & Constant::Document) ? Qt::Checked : Qt::Unchecked); 0116 item->setData(2, Qt::ToolTipRole, i18n("Check this to have the constant exported when saving.")); 0117 // item->setData( 2, Qt::WhatsThisRole, i18n("Document constants are saved with the documents, and will be loaded again when the document is opened.") ); 0118 item->setData(3, Qt::CheckStateRole, (constant.type & Constant::Global) ? Qt::Checked : Qt::Unchecked); 0119 item->setData(3, Qt::ToolTipRole, i18n("Check this to have the constant permanently available between instances of KmPlot.")); 0120 // item->setData( 3, Qt::WhatsThisRole, i18n("Global constants are stored in KmPlot's settings. They are not lost when KmPlot is closed.") ); 0121 } 0122 0123 void KConstantEditor::cmdNew_clicked() 0124 { 0125 QTreeWidgetItem *item = new QTreeWidgetItem(m_widget->constantList); 0126 0127 init(item, XParser::self()->constants()->generateUniqueName(), Constant()); 0128 0129 m_widget->constantList->setCurrentItem(item); 0130 m_widget->nameEdit->setFocus(); 0131 } 0132 0133 void KConstantEditor::cmdDelete_clicked() 0134 { 0135 QTreeWidgetItem *item = m_widget->constantList->currentItem(); 0136 if (!item) 0137 return; 0138 0139 XParser::self()->constants()->remove(item->text(0)); 0140 0141 m_widget->nameEdit->clear(); 0142 m_widget->valueEdit->clear(); 0143 m_widget->constantList->takeTopLevelItem(m_widget->constantList->indexOfTopLevelItem(item)); 0144 delete item; 0145 0146 m_widget->cmdDelete->setEnabled(m_widget->constantList->currentItem() != 0); 0147 } 0148 0149 void KConstantEditor::selectedConstantChanged(QTreeWidgetItem *current) 0150 { 0151 m_widget->cmdDelete->setEnabled(current != 0); 0152 0153 QString name = current ? current->text(0) : QString(); 0154 QString value = current ? current->text(1) : QString(); 0155 0156 m_previousConstantName = name; 0157 m_constantValidator->setWorkingName(m_previousConstantName); 0158 0159 m_widget->nameEdit->setText(name); 0160 m_widget->valueEdit->setText(value); 0161 } 0162 0163 void KConstantEditor::constantNameEdited(const QString &newName) 0164 { 0165 QTreeWidgetItem *current = m_widget->constantList->currentItem(); 0166 if (!current) { 0167 Constant constant; 0168 constant.value.updateExpression(m_widget->valueEdit->text()); 0169 0170 current = new QTreeWidgetItem(m_widget->constantList); 0171 init(current, newName, constant); 0172 } 0173 0174 XParser::self()->constants()->remove(m_previousConstantName); 0175 0176 current->setText(0, newName); 0177 m_widget->constantList->setCurrentItem(current); // make it the current item if no item was selected before 0178 0179 m_previousConstantName = newName; 0180 0181 m_constantValidator->setWorkingName(m_previousConstantName); 0182 0183 saveCurrentConstant(); 0184 } 0185 0186 void KConstantEditor::saveCurrentConstant() 0187 { 0188 if (m_widget->nameEdit->text().isEmpty()) 0189 return; 0190 0191 QTreeWidgetItem *current = m_widget->constantList->currentItem(); 0192 assert(current); 0193 current->setText(1, m_widget->valueEdit->text()); 0194 0195 Constant constant; 0196 constant.value.updateExpression(m_widget->valueEdit->text()); 0197 0198 // update type 0199 constant.type = 0; 0200 if (current->data(2, Qt::CheckStateRole).toBool()) 0201 constant.type |= Constant::Document; 0202 if (current->data(3, Qt::CheckStateRole).toBool()) 0203 constant.type |= Constant::Global; 0204 0205 XParser::self()->constants()->add(m_widget->nameEdit->text(), constant); 0206 } 0207 0208 bool KConstantEditor::checkValueValid() 0209 { 0210 Parser::Error error; 0211 (double)XParser::self()->eval(m_widget->valueEdit->text(), &error); 0212 bool valid = (error == Parser::ParseSuccess) && m_constantValidator->isValid(m_widget->nameEdit->text()); 0213 m_widget->valueInvalidLabel->setVisible(!valid); 0214 return valid; 0215 } 0216 0217 void KConstantEditor::itemClicked() 0218 { 0219 QTimer::singleShot(0, this, &KConstantEditor::saveCurrentConstant); 0220 } 0221 // END class KConstantEditor 0222 0223 // BEGIN class ConstantValidator 0224 ConstantValidator::ConstantValidator(KConstantEditor *parent) 0225 : QValidator(parent) 0226 { 0227 } 0228 0229 bool ConstantValidator::isValid(const QString &name) const 0230 { 0231 bool correct = XParser::self()->constants()->isValidName(name); 0232 bool inUse = XParser::self()->constants()->have(name) && (m_workingName != name); 0233 0234 return correct && !inUse; 0235 } 0236 0237 QValidator::State ConstantValidator::validate(QString &input, int & /*pos*/) const 0238 { 0239 return isValid(input) ? Acceptable : Intermediate; 0240 } 0241 0242 void ConstantValidator::setWorkingName(const QString &name) 0243 { 0244 m_workingName = name; 0245 } 0246 // END class ConstantValidator