Warning, file /education/kmplot/kmplot/equationedit.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: 2006 David Saxton <david@bluehaze.org> 0005 0006 This file is part of the KDE Project. 0007 KmPlot is part of the KDE-EDU Project. 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 0011 */ 0012 0013 #include "equationedit.h" 0014 #include "xparser.h" 0015 0016 #include <QHBoxLayout> 0017 #include <QIcon> 0018 #include <QPushButton> 0019 0020 #include <assert.h> 0021 0022 #include "equationeditor.h" 0023 #include "equationeditorwidget.h" 0024 #include "equationeditwidget.h" 0025 #include "equationhighlighter.h" 0026 0027 CharMap EquationEdit::m_replaceMap; 0028 0029 EquationEdit::EquationEdit(QWidget *parent) 0030 : QWidget(parent) 0031 { 0032 m_cleaningText = false; 0033 m_settingText = false; 0034 m_forcingRehighlight = false; 0035 m_inputType = Expression; 0036 0037 m_equationEditWidget = new EquationEditWidget(this); 0038 m_highlighter = new EquationHighlighter(this); 0039 m_equation = new Equation(Equation::Cartesian, 0); 0040 m_editButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-properties")), 0, this); 0041 setFocusProxy(m_equationEditWidget); 0042 0043 connect(m_equationEditWidget, &EquationEditWidget::textChanged, this, &EquationEdit::slotTextChanged); 0044 connect(m_editButton, &QPushButton::clicked, this, &EquationEdit::invokeEquationEditor); 0045 connect(m_equationEditWidget, &EquationEditWidget::cursorPositionChanged, this, &EquationEdit::reHighlight); 0046 0047 QHBoxLayout *layout = new QHBoxLayout(this); 0048 layout->setContentsMargins(0, 0, 0, 0); 0049 layout->addWidget(m_equationEditWidget); 0050 layout->addWidget(m_editButton); 0051 } 0052 0053 void EquationEdit::setTabChain(QWidget *next) 0054 { 0055 QWidget::setTabOrder(m_equationEditWidget, m_editButton); 0056 QWidget::setTabOrder(m_editButton, next); 0057 } 0058 0059 void EquationEdit::setEquationType(Equation::Type type) 0060 { 0061 delete m_equation; 0062 m_equation = new Equation(type, 0); 0063 } 0064 0065 void EquationEdit::showEditButton(bool show) 0066 { 0067 m_editButton->setVisible(show); 0068 } 0069 0070 void EquationEdit::reHighlight() 0071 { 0072 if (m_forcingRehighlight) 0073 return; 0074 m_forcingRehighlight = true; 0075 0076 m_highlighter->setDocument(0); 0077 m_highlighter->setDocument(m_equationEditWidget->document()); 0078 0079 m_forcingRehighlight = false; 0080 } 0081 0082 void EquationEdit::invokeEquationEditor() 0083 { 0084 QPointer<EquationEditor> edit = new EquationEditor(this); 0085 edit->edit()->setInputType(m_inputType); 0086 edit->edit()->setEquationType(m_equation->type()); 0087 edit->edit()->setValidatePrefix(m_validatePrefix); 0088 edit->edit()->setText(text()); 0089 0090 edit->exec(); 0091 0092 setText(edit->text()); 0093 edit->deleteLater(); 0094 emit editingFinished(); 0095 } 0096 0097 void EquationEdit::setInputType(InputType type) 0098 { 0099 m_inputType = type; 0100 } 0101 0102 double EquationEdit::value(bool *ok) 0103 { 0104 assert(m_inputType == Expression); // Can't really get a value of a function as that requires an input 0105 0106 Parser::Error error; 0107 double value = XParser::self()->eval(text(), &error); 0108 0109 if (ok) 0110 *ok = (error == Parser::ParseSuccess); 0111 0112 return value; 0113 } 0114 0115 void EquationEdit::slotTextChanged() 0116 { 0117 if (m_forcingRehighlight) 0118 return; 0119 0120 // BEGIN tidy up mathematical characters 0121 if (m_cleaningText) 0122 return; 0123 m_cleaningText = true; 0124 0125 QTextDocument *doc = m_equationEditWidget->document(); 0126 0127 if (m_replaceMap.isEmpty()) { 0128 m_replaceMap['*'] = QChar(0x2219); 0129 m_replaceMap['-'] = MinusSymbol; 0130 m_replaceMap['|'] = AbsSymbol; 0131 } 0132 0133 QTextCursor cursor; 0134 for (CharMap::iterator i = m_replaceMap.begin(); i != m_replaceMap.end(); ++i) { 0135 int at = 0; 0136 while (!(cursor = doc->find(i.key(), at)).isNull()) { 0137 cursor.joinPreviousEditBlock(); 0138 at = cursor.position() + 1; 0139 cursor.deleteChar(); 0140 cursor.insertText(i.value()); 0141 cursor.endEditBlock(); 0142 } 0143 } 0144 0145 m_cleaningText = false; 0146 // END tidy up mathematical characters 0147 0148 emit textChanged(text()); 0149 if (!m_settingText) 0150 emit textEdited(text()); 0151 } 0152 0153 void EquationEdit::checkTextValidity() 0154 { 0155 QString text = m_validatePrefix + EquationEdit::text(); 0156 0157 Parser::Error error; 0158 int intError, errorPosition; 0159 0160 if (m_inputType == Function) { 0161 m_equation->setFstr(text, &intError, &errorPosition); 0162 error = (Parser::Error)intError; 0163 } else 0164 XParser::self()->eval(text, &error, &errorPosition); 0165 0166 if (error == Parser::ParseSuccess) 0167 setError(QString(), -1); 0168 else 0169 setError(XParser::self()->errorString(error), errorPosition - m_validatePrefix.length()); 0170 } 0171 0172 void EquationEdit::setError(const QString &message, int position) 0173 { 0174 m_equationEditWidget->setToolTip(message); 0175 m_highlighter->setErrorPosition(position); 0176 } 0177 0178 void EquationEdit::setText(const QString &text) 0179 { 0180 m_settingText = true; 0181 m_equationEditWidget->setPlainText(text); 0182 QTextCursor cursor(m_equationEditWidget->textCursor()); 0183 cursor.movePosition(QTextCursor::End); 0184 m_equationEditWidget->setTextCursor(cursor); 0185 m_settingText = false; 0186 } 0187 0188 void EquationEdit::setValidatePrefix(const QString &prefix) 0189 { 0190 m_validatePrefix = prefix; 0191 reHighlight(); 0192 } 0193 0194 void EquationEdit::wrapSelected(const QString &before, const QString &after) 0195 { 0196 QTextCursor cursor(m_equationEditWidget->textCursor()); 0197 QString newText = before + cursor.selectedText() + after; 0198 cursor.insertText(newText); 0199 cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, after.length()); 0200 m_equationEditWidget->setTextCursor(cursor); 0201 } 0202 0203 QString EquationEdit::text() const 0204 { 0205 return m_equationEditWidget->toPlainText(); 0206 } 0207 0208 void EquationEdit::clear() 0209 { 0210 m_equationEditWidget->clear(); 0211 } 0212 0213 void EquationEdit::selectAll() 0214 { 0215 m_equationEditWidget->selectAll(); 0216 } 0217 0218 void EquationEdit::insertText(const QString &text) 0219 { 0220 m_equationEditWidget->insertPlainText(text); 0221 }