Warning, file /education/kmplot/kmplot/kparametereditor.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 "kparametereditor.h" 0015 0016 #include <QDebug> 0017 #include <QDialogButtonBox> 0018 #include <QFile> 0019 #include <QFileDialog> 0020 #include <QListWidget> 0021 #include <QPushButton> 0022 #include <QTemporaryFile> 0023 #include <QTextStream> 0024 #include <QVBoxLayout> 0025 0026 #include <KConfigGroup> 0027 #include <KIO/StoredTransferJob> 0028 #include <KJobWidgets> 0029 #include <KMessageBox> 0030 #include <kwidgetsaddons_version.h> 0031 0032 #include "maindlg.h" 0033 0034 #include <assert.h> 0035 0036 class ParameterValueList; 0037 0038 KParameterEditor::KParameterEditor(QList<Value> *l, QWidget *parent) 0039 : QDialog(parent) 0040 , m_parameter(l) 0041 { 0042 m_mainWidget = new QParameterEditor(this); 0043 setWindowTitle(i18nc("@title:window", "Parameter Editor")); 0044 QVBoxLayout *mainLayout = new QVBoxLayout; 0045 setLayout(mainLayout); 0046 mainLayout->addWidget(m_mainWidget); 0047 0048 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0049 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0050 okButton->setDefault(true); 0051 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0052 connect(buttonBox, &QDialogButtonBox::accepted, this, &KParameterEditor::accept); 0053 connect(buttonBox, &QDialogButtonBox::rejected, this, &KParameterEditor::reject); 0054 mainLayout->addWidget(buttonBox); 0055 0056 mainLayout->setContentsMargins(0, 0, 0, 0); 0057 0058 m_mainWidget->cmdNew->setIcon(QIcon::fromTheme("document-new")); 0059 m_mainWidget->cmdDelete->setIcon(QIcon::fromTheme("edit-delete")); 0060 m_mainWidget->moveUp->setIcon(QIcon::fromTheme("go-up")); 0061 m_mainWidget->moveDown->setIcon(QIcon::fromTheme("go-down")); 0062 m_mainWidget->cmdImport->setIcon(QIcon::fromTheme("document-open")); 0063 m_mainWidget->cmdExport->setIcon(QIcon::fromTheme("document-save")); 0064 0065 m_mainWidget->list->setFocusPolicy(Qt::NoFocus); 0066 0067 connect(m_mainWidget->value, &EquationEdit::upPressed, this, &KParameterEditor::prev); 0068 connect(m_mainWidget->value, &EquationEdit::downPressed, this, &KParameterEditor::next); 0069 0070 for (const Value &v : qAsConst(*m_parameter)) 0071 m_mainWidget->list->addItem(v.expression()); 0072 0073 connect(m_mainWidget->cmdNew, &QPushButton::clicked, this, &KParameterEditor::cmdNew_clicked); 0074 connect(m_mainWidget->cmdDelete, &QPushButton::clicked, this, &KParameterEditor::cmdDelete_clicked); 0075 connect(m_mainWidget->moveUp, &QPushButton::clicked, this, &KParameterEditor::moveUp); 0076 connect(m_mainWidget->moveDown, &QPushButton::clicked, this, &KParameterEditor::moveDown); 0077 connect(m_mainWidget->cmdImport, &QPushButton::clicked, this, &KParameterEditor::cmdImport_clicked); 0078 connect(m_mainWidget->cmdExport, &QPushButton::clicked, this, &KParameterEditor::cmdExport_clicked); 0079 connect(m_mainWidget->list, &QListWidget::currentItemChanged, this, &KParameterEditor::selectedConstantChanged); 0080 0081 connect(m_mainWidget->value, &EquationEdit::textEdited, this, &KParameterEditor::saveCurrentValue); 0082 connect(m_mainWidget->value, &EquationEdit::textChanged, this, &KParameterEditor::checkValueValid); 0083 connect(m_mainWidget->value, &EquationEdit::returnPressed, m_mainWidget->cmdNew, &QAbstractButton::click); 0084 0085 checkValueValid(); 0086 0087 m_mainWidget->value->setFocus(); 0088 } 0089 0090 KParameterEditor::~KParameterEditor() 0091 { 0092 } 0093 0094 void KParameterEditor::accept() 0095 { 0096 qDebug() << "saving\n"; 0097 m_parameter->clear(); 0098 QString item_text; 0099 for (int i = 0; i < m_mainWidget->list->count(); i++) { 0100 item_text = m_mainWidget->list->item(i)->text(); 0101 if (!item_text.isEmpty()) { 0102 Value value; 0103 if (value.updateExpression(item_text)) 0104 m_parameter->append(value); 0105 } 0106 } 0107 0108 QDialog::accept(); 0109 } 0110 0111 void KParameterEditor::moveUp() 0112 { 0113 int current = m_mainWidget->list->currentRow(); 0114 0115 if (current == 0) 0116 return; 0117 0118 QListWidgetItem *item = m_mainWidget->list->takeItem(current - 1); 0119 m_mainWidget->list->insertItem(current, item); 0120 } 0121 0122 void KParameterEditor::moveDown() 0123 { 0124 int current = m_mainWidget->list->currentRow(); 0125 0126 if (current == m_mainWidget->list->count() - 1) 0127 return; 0128 0129 QListWidgetItem *item = m_mainWidget->list->takeItem(current + 1); 0130 m_mainWidget->list->insertItem(current, item); 0131 } 0132 0133 void KParameterEditor::cmdNew_clicked() 0134 { 0135 QListWidgetItem *item = new QListWidgetItem(m_mainWidget->list); 0136 item->setText("0"); 0137 m_mainWidget->list->setCurrentItem(item); 0138 m_mainWidget->value->setFocus(); 0139 m_mainWidget->value->selectAll(); 0140 } 0141 0142 void KParameterEditor::prev() 0143 { 0144 int current = m_mainWidget->list->currentRow(); 0145 if (current > 0) 0146 m_mainWidget->list->setCurrentRow(current - 1); 0147 } 0148 0149 void KParameterEditor::next() 0150 { 0151 int current = m_mainWidget->list->currentRow(); 0152 if (current < m_mainWidget->list->count() - 1) 0153 m_mainWidget->list->setCurrentRow(current + 1); 0154 else 0155 cmdNew_clicked(); 0156 } 0157 0158 void KParameterEditor::selectedConstantChanged(QListWidgetItem *current) 0159 { 0160 m_mainWidget->cmdDelete->setEnabled(current != 0); 0161 m_mainWidget->value->setText(current ? current->text() : QString()); 0162 m_mainWidget->value->selectAll(); 0163 } 0164 0165 void KParameterEditor::cmdDelete_clicked() 0166 { 0167 QListWidgetItem *item = m_mainWidget->list->currentItem(); 0168 if (!item) 0169 return; 0170 0171 m_mainWidget->value->clear(); 0172 m_mainWidget->list->takeItem(m_mainWidget->list->currentRow()); 0173 delete item; 0174 0175 m_mainWidget->cmdDelete->setEnabled(m_mainWidget->list->currentItem() != 0); 0176 } 0177 0178 void KParameterEditor::saveCurrentValue() 0179 { 0180 QListWidgetItem *current = m_mainWidget->list->currentItem(); 0181 if (!current) 0182 current = new QListWidgetItem(m_mainWidget->list); 0183 0184 current->setText(m_mainWidget->value->text()); 0185 m_mainWidget->list->setCurrentItem(current); 0186 } 0187 0188 bool KParameterEditor::checkValueValid() 0189 { 0190 QString valueText = m_mainWidget->value->text(); 0191 Parser::Error error; 0192 (double)XParser::self()->eval(valueText, &error); 0193 bool valid = (error == Parser::ParseSuccess); 0194 m_mainWidget->valueInvalidLabel->setVisible(!valueText.isEmpty() && !valid); 0195 return valid; 0196 } 0197 0198 void KParameterEditor::cmdImport_clicked() 0199 { 0200 QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Open Parameter File"), QUrl(), i18n("Plain Text File (*.txt)")); 0201 if (url.isEmpty()) 0202 return; 0203 0204 if (!MainDlg::fileExists(url)) { 0205 KMessageBox::error(0, i18n("The file does not exist.")); 0206 return; 0207 } 0208 0209 bool verbose = false; 0210 QFile file; 0211 if (!url.isLocalFile()) { 0212 KIO::StoredTransferJob *transferjob = KIO::storedGet(url); 0213 KJobWidgets::setWindow(transferjob, 0); 0214 if (!transferjob->exec()) { 0215 KMessageBox::error(0, i18n("An error appeared when opening this file: %1", transferjob->errorString())); 0216 return; 0217 } 0218 QTemporaryFile tmpfile; 0219 tmpfile.setAutoRemove(false); 0220 tmpfile.open(); 0221 tmpfile.write(transferjob->data()); 0222 file.setFileName(tmpfile.fileName()); 0223 tmpfile.close(); 0224 } else 0225 file.setFileName(url.toLocalFile()); 0226 0227 if (file.open(QIODevice::ReadOnly)) { 0228 QTextStream stream(&file); 0229 QString line; 0230 for (int i = 1; !stream.atEnd(); i++) { 0231 line = stream.readLine(); 0232 if (line.isEmpty()) 0233 continue; 0234 0235 Parser::Error error; 0236 XParser::self()->eval(line, &error); 0237 if (error == Parser::ParseSuccess) { 0238 if (!checkTwoOfIt(line)) { 0239 m_mainWidget->list->addItem(line); 0240 } 0241 } else if (!verbose) { 0242 if (KMessageBox::warningContinueCancel( 0243 this, 0244 i18n("Line %1 is not a valid parameter value and will therefore not be included. Do you want to continue?", i)) 0245 == KMessageBox::Cancel) { 0246 file.close(); 0247 QFile::remove(file.fileName()); 0248 return; 0249 #if KWIDGETSADDONS_VERSION < QT_VERSION_CHECK(5, 100, 0) 0250 } else if (KMessageBox::warningYesNo(this, 0251 #else 0252 } else if (KMessageBox::warningTwoActions(this, 0253 #endif 0254 i18n("Would you like to be informed about other lines that cannot be read?"), 0255 QString(), 0256 KGuiItem(i18n("Get Informed")), 0257 KGuiItem(i18n("Ignore Information"))) 0258 #if KWIDGETSADDONS_VERSION < QT_VERSION_CHECK(5, 100, 0) 0259 == KMessageBox::No) 0260 #else 0261 == KMessageBox::SecondaryAction) 0262 #endif 0263 verbose = true; 0264 } 0265 } 0266 file.close(); 0267 } else 0268 KMessageBox::error(0, i18n("An error appeared when opening this file")); 0269 0270 if (!url.isLocalFile()) 0271 QFile::remove(file.fileName()); 0272 } 0273 0274 void KParameterEditor::cmdExport_clicked() 0275 { 0276 if (!m_mainWidget->list->count()) 0277 return; 0278 QUrl url = QFileDialog::getSaveFileUrl(this, i18n("Save File"), QUrl(), i18n("Plain Text File (*.txt)")); 0279 if (url.isEmpty()) 0280 return; 0281 0282 if (!MainDlg::fileExists(url) 0283 || KMessageBox::warningContinueCancel( 0284 this, 0285 i18n("A file named \"%1\" already exists. Are you sure you want to continue and overwrite this file?", url.toDisplayString()), 0286 i18n("Overwrite File?"), 0287 KStandardGuiItem::overwrite()) 0288 == KMessageBox::Continue) { 0289 if (!url.isLocalFile()) { 0290 QTemporaryFile tmpfile; 0291 0292 if (tmpfile.open()) { 0293 QTextStream stream(&tmpfile); 0294 for (int i = 0; i < m_mainWidget->list->count(); i++) { 0295 QListWidgetItem *it = m_mainWidget->list->item(i); 0296 stream << it->text(); 0297 if (i < m_mainWidget->list->count() - 1) 0298 stream << '\n'; // only write a new line if there are more text 0299 } 0300 stream.flush(); 0301 } else 0302 KMessageBox::error(0, i18n("An error appeared when saving this file")); 0303 0304 Q_CONSTEXPR int permission = -1; 0305 QFile file(tmpfile.fileName()); 0306 file.open(QIODevice::ReadOnly); 0307 KIO::StoredTransferJob *putjob = KIO::storedPut(file.readAll(), url, permission, KIO::JobFlag::Overwrite); 0308 if (!putjob->exec()) { 0309 KMessageBox::error(0, i18n("An error appeared when saving this file")); 0310 return; 0311 } 0312 file.close(); 0313 } else { 0314 QFile file; 0315 qDebug() << "url.path()=" << url.toLocalFile(); 0316 file.setFileName(url.toLocalFile()); 0317 if (file.open(QIODevice::WriteOnly)) { 0318 QTextStream stream(&file); 0319 for (int i = 0; i < m_mainWidget->list->count(); i++) { 0320 QListWidgetItem *it = m_mainWidget->list->item(i); 0321 stream << it->text(); 0322 if (i < m_mainWidget->list->count() - 1) 0323 stream << '\n'; // only write a new line if there are more text 0324 } 0325 file.close(); 0326 } else 0327 KMessageBox::error(0, i18n("An error appeared when saving this file")); 0328 } 0329 } 0330 } 0331 0332 bool KParameterEditor::checkTwoOfIt(const QString &text) 0333 { 0334 return !m_mainWidget->list->findItems(text, Qt::MatchExactly).isEmpty(); 0335 }