35#include <QTextCharFormat>
37#include <QAbstractItemView>
38#include <QStandardItemModel>
39#include <QStringListModel>
47#include "../Expression.h"
48#include "../ExprNode.h"
49#include "../ExprFunc.h"
50#include "../ExprBuiltins.h"
72 QString newText =
exprTe->toPlainText();
76 exprTe->insertPlainText(newText);
93 : QWidget(parent), _updatingText(0), errorHeight(0) {
99 setWindowTitle(
"Expression Editor");
100 setMinimumHeight(100);
106 QVBoxLayout* exprAndErrors =
new QVBoxLayout;
107 exprAndErrors->setMargin(0);
108 setLayout(exprAndErrors);
112 exprTe->setMinimumHeight(50);
116 while (QFontMetrics(QFont(
"Liberation Sans", fontsize)).width(
"abcdef") < 38 && fontsize < 20) fontsize++;
117 while (QFontMetrics(QFont(
"Liberation Sans", fontsize)).width(
"abcdef") > 44 && fontsize > 3) fontsize--;
119 exprTe->setFont(QFont(
"Liberation Sans", fontsize));
121 exprAndErrors->addWidget(
exprTe);
125 errorWidget->setSelectionMode(QAbstractItemView::SingleSelection);
126 errorWidget->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum));
136 connect(
controls, SIGNAL(insertString(
const std::string&)), SLOT(
insertStr(
const std::string&)));
143 QListWidgetItem* item =
errorWidget->item(selected);
144 int start = item->data(Qt::UserRole).toInt();
145 int end = item->data(Qt::UserRole + 1).toInt();
146 QTextCursor cursor =
exprTe->textCursor();
147 cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
148 cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, start);
149 cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, end - start + 1);
150 exprTe->setTextCursor(cursor);
186 QTreeView* treePopup =
new QTreeView;
188 treePopup->setRootIsDecorated(
false);
189 treePopup->setMinimumWidth(300);
190 treePopup->setMinimumHeight(50);
191 treePopup->setItemsExpandable(
true);
194 completer->setCompletionMode(QCompleter::PopupCompletion);
195 completer->setCaseSensitivity(Qt::CaseInsensitive);
205 QTextEdit::focusInEvent(e);
210 QTextEdit::focusInEvent(e);
215 QTextEdit::mousePressEvent(event);
220 QTextEdit::mouseDoubleClickEvent(event);
229 QTextEdit::paintEvent(event);
233 if (event->modifiers() == Qt::ControlModifier) {
234 if (event->delta() > 0)
236 else if (event->delta() < 0)
239 return QTextEdit::wheelEvent(event);
244 if (e->key() == Qt::Key_Return && e->modifiers() == Qt::ControlModifier) {
247 }
else if (e->key() == Qt::Key_F4) {
259 case Qt::Key_Backtab:
268 bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E);
270 QTextEdit::keyPressEvent(e);
272 const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
273 if (!
completer || (ctrlOrShift && e->text().isEmpty()))
return;
275 bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
278 QTextCursor tc = textCursor();
279 tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
280 QString line = tc.selectedText();
283 static QRegExp completion(
"^(?:.*[^A-Za-z0-9_$])?((?:\\$[A-Za-z0-9_]*)|[A-Za-z]+[A-Za-z0-9_]*)$");
284 int index = completion.indexIn(line);
285 QString completionPrefix;
286 if (
index != -1 && !line.contains(
'#')) {
287 completionPrefix = completion.cap(1);
292 if (!isShortcut && (hasModifier || e->text().isEmpty() || completionPrefix.length() < 1 ||
index == -1)) {
297 if (completionPrefix !=
completer->completionPrefix()) {
298 completer->setCompletionPrefix(completionPrefix);
303 QRect cr = cursorRect();
304 cr.setWidth(
completer->popup()->sizeHintForColumn(0) +
completer->popup()->sizeHintForColumn(1) +
305 completer->popup()->verticalScrollBar()->sizeHint().width());
313 static QRegExp inFunction(
"^(?:.*[^A-Za-z0-9_$])?([A-Za-z0-9_]+)\\([^()]*$");
314 int index2 = inFunction.indexIn(line);
316 QString functionName = inFunction.cap(1);
318 QString tip =
"<b>" + tips[0] +
"</b>";
319 for (
int i = 1; i < tips.size(); i++) {
320 tip +=
"<br>" + tips[i];
330 QMenu* menu = createStandardContextMenu();
332 if (!menu->actions().empty()) {
333 QAction*
f = menu->actions().first();
335 menu->insertSeparator(
f);
338 menu->exec(event->globalPos());
344 if (
string ==
"")
return;
348 QRect cr = cursorRect();
350 cr.setWidth(cr.width() * 3);
355 _tip =
new ExprPopupDoc(
this, mapToGlobal(cr.bottomLeft()) + QPoint(0, 6),
string);
364 QTextCursor tc = textCursor();
365 int extra = completion.length() -
completer->completionPrefix().length();
366 tc.movePosition(QTextCursor::Left);
367 tc.movePosition(QTextCursor::EndOfWord);
368 tc.insertText(completion.right(extra));
369 if (completion[0] !=
'$') tc.insertText(
"(");
380 exprTe->moveCursor(QTextCursor::Start);
381 if (doApply) emit
apply();
389 QListWidgetItem* item =
new QListWidgetItem((
"Error: " + error).c_str(),
errorWidget);
390 item->setData(Qt::UserRole, startPos);
391 item->setData(Qt::UserRole + 1, endPos);
394 const char* c = error.c_str();
397 if (*c ==
'\n') lines++;
std::vector< QString > local_variables
QString getDocString(const QString &s)
void syncExtras(const ExprCompletionModel &otherModel)
void addVariable(const QString &str, const QString &comment)
void addFunction(const QString &function, const QString &docString)
bool rebuildControls(const QString &expressionText, std::vector< QString > &variables)
Rebuild the controls given the new expressionText. Return any local variables found.
void updateText(const int id, QString &text)
Request new text, given taking into account control id's new values.
void insertStr(const std::string &str)
void appendStr(const std::string &str)
QListWidget * errorWidget
void registerExtraVariable(const std::string &name, const std::string &docString)
void clearExtraCompleters()
ExprControlCollection * controls
ExprEditor(QWidget *parent, ExprControlCollection *controls)
void replaceExtras(const ExprCompletionModel &completer)
void registerExtraFunction(const std::string &name, const std::string &docString)
QTimer * controlRebuildTimer
void controlChanged(int id)
void setExpr(const std::string &expression, const bool apply=false)
void addError(const int startPos, const int endPos, const std::string &error)
void fixStyle(const QPalette &palette)
void textChanged(int id, const QString &text)
void textChangedCB(const QString &text)
ExprLineEdit(int id, QWidget *parent)
void showTip(const QString &string)
void contextMenuEvent(QContextMenuEvent *event)
ExprTextEdit(QWidget *parent=0)
void insertCompletion(const QString &completion)
void focusInEvent(QFocusEvent *e)
void wheelEvent(QWheelEvent *e)
ExprCompletionModel * completionModel
QStyle * lastStyleForHighlighter
virtual void keyPressEvent(QKeyEvent *e)
void mousePressEvent(QMouseEvent *event)
QAction * _popupEnabledAction
ExprHighlighter * highlighter
void focusOutEvent(QFocusEvent *e)
void paintEvent(QPaintEvent *e)
void mouseDoubleClickEvent(QMouseEvent *event)
For a multi line expression
The result is computed int int< br >< div style="margin-left: 40px;"> Picks values randomly between loRange and hiRange based on supplied index(which is automatically hashed).  
with numParticles numAttributes A variable block contains variable names and types but doesn t care what the values are< pre > void f(const std::string &s, MyParticleData *p, int outputDim=3)