labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

EquationHighlighter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : EquationHighlighter.h
3  Project : LabPlot
4  --------------------------------------------------------------------
5  Copyright : (C) 2014 Alexander Semke (alexander.semke@web.de)
6  Copyright : (C) 2006 David Saxton <david@bluehaze.org>
7  Description : syntax highligher for mathematical equations
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  * This program is distributed in the hope that it will be useful, *
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21  * GNU General Public License for more details. *
22  * *
23  * You should have received a copy of the GNU General Public License *
24  * along with this program; if not, write to the Free Software *
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26  * Boston, MA 02110-1301 USA *
27  * *
28  ***************************************************************************/
29 
30 #include "EquationHighlighter.h"
32 
33 #include <QPalette>
34 #include <KTextEdit>
35 
37  : QSyntaxHighlighter(parent),
38  m_parent(parent)
39 // m_errorPosition = -1
40 {}
41 
42 void EquationHighlighter::setVariables(const QStringList& variables) {
43  m_variables = variables;
44  rehighlight();
45 }
46 
47 void EquationHighlighter::highlightBlock(const QString& text) {
48  //TODO: m_parent->checkTextValidity();
49 
50  if (text.isEmpty())
51  return;
52 
53  QTextCharFormat number;
54  QTextCharFormat function;
55  QTextCharFormat variable;
56  QTextCharFormat constant;
57  QTextCharFormat matchedParenthesis;
58 
59  QPalette palette;
60  if (qGray(palette.color(QPalette::Base).rgb()) > 160) {
61  number.setForeground(QColor(0, 0, 127));
62  function.setForeground(QColor(85, 0, 0));
63  function.setFontWeight(QFont::Bold);
64  variable.setForeground(QColor(0, 85, 0));
65  constant.setForeground(QColor(85, 0, 0));
66  matchedParenthesis.setBackground(QColor(255, 255, 183));
67  } else {
68  number.setForeground(QColor(160, 160, 255));
69  function.setForeground(QColor(255, 160, 160));
70  function.setFontWeight(QFont::Bold);
71  variable.setForeground(QColor(160, 255, 160));
72  constant.setForeground(QColor(255, 160, 160));
73  matchedParenthesis.setBackground(QColor(85, 85, 0));
74  }
75 
76  QTextCharFormat other;
77 
78  static const QStringList& functions = ExpressionParser::getInstance()->functions();
79  static const QStringList& constants = ExpressionParser::getInstance()->constants();
80 
81  for (int i = 0; i < text.length(); ++i) {
82  QString remaining = text.right(text.length() - i);
83  bool found = false;
84 
85  //variables
86  for (const QString& var: m_variables) {
87  if (remaining.startsWith(var)) {
88  QString nextChar = remaining.mid(var.length(), 1);
89  if (nextChar == " " || nextChar == ")" || nextChar == "+" || nextChar == "-"
90  || nextChar == "*" || nextChar == "/" || nextChar == "^") {
91  setFormat(i, var.length(), variable);
92  i += var.length() - 1;
93  found = true;
94  break;
95  }
96  }
97  }
98  if (found)
99  continue;
100 
101  //functions
102  for (const QString& f: functions) {
103  if (remaining.startsWith(f)) {
104  setFormat(i, f.length(), function);
105  i += f.length() - 1;
106  found = true;
107  break;
108  }
109  }
110  if (found)
111  continue;
112 
113  //constants
114  for (const QString& f: constants) {
115  if (remaining.startsWith(f)) {
116  setFormat(i, f.length(), function);
117  i += f.length() - 1;
118  found = true;
119  break;
120  }
121  }
122  if (found)
123  continue;
124 
125  //TODO
126  /*
127  ushort u = text[i].unicode();
128  bool isFraction = (u >= 0xbc && u <= 0xbe) || (u >= 0x2153 && u <= 0x215e);
129  bool isPower = (u >= 0xb2 && u <= 0xb3) || (u == 0x2070) || (u >= 0x2074 && u <= 0x2079);
130  bool isDigit = text[i].isDigit();
131  SET_NUMBER_LOCALE
132  bool isDecimalPoint = text[i] == numberLocale.decimalPoint();
133 
134  if (isFraction || isPower || isDigit || isDecimalPoint)
135  setFormat(i, 1, number);
136  else
137  setFormat(i, 1, other);
138  */
139  }
140 
141  //highlight matched brackets
142  int cursorPos = m_parent->textCursor().position();
143  if (cursorPos < 0)
144  cursorPos = 0;
145 
146  // Adjust cursorpos to allow for a bracket before the cursor position
147  if (cursorPos >= text.size())
148  cursorPos = text.size() - 1;
149  else if (cursorPos > 0 && (text[cursorPos-1] == '(' || text[cursorPos-1] == ')'))
150  cursorPos--;
151 
152  bool haveOpen = text[cursorPos] == '(';
153  bool haveClose = text[cursorPos] == ')';
154 
155  if ((haveOpen || haveClose) && m_parent->hasFocus()) {
156  // Search for the other bracket
157 
158  int inc = haveOpen ? 1 : -1; // which direction to search in
159 
160  int level = 0;
161  for (int i = cursorPos; i >= 0 && i < text.size(); i += inc) {
162  if (text[i] == ')')
163  level--;
164  else if (text[i] == '(')
165  level++;
166 
167  if (level == 0) {
168  // Matched!
169  setFormat(cursorPos, 1, matchedParenthesis);
170  setFormat(i, 1, matchedParenthesis);
171  break;
172  }
173  }
174  }
175 
176  //TODO: highlight the position of the error
177 // if (m_errorPosition != -1) {
178 // QTextCharFormat error;
179 // error.setForeground(Qt::red);
180 //
181 // setFormat(m_errorPosition, 1, error);
182 // }
183 }
184 
186  setDocument(nullptr);
187  setDocument(m_parent->document());
188 }
189 
190 /**
191 * This is used to indicate the position where the error occurred.
192 * If \p position is negative, then no error will be shown.
193 */
194 // void EquationHighlighter::setErrorPosition(int position) {
195 // m_errorPosition = position;
196 // }
void highlightBlock(const QString &text) override
void setVariables(const QStringList &)
EquationHighlighter(KTextEdit *parent)
const QStringList & constants()
const QStringList & functions()
static ExpressionParser * getInstance()