tilde~
Puredata Qt-based GUI
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
UIScriptTextEdit.h
Go to the documentation of this file.
1 #ifndef UISCRIPTTEXTEDIT_H
2 #define UISCRIPTTEXTEDIT_H
3 
4 
5 
6 #include <QAbstractItemView>
7 #include <QCompleter>
8 #include <QPlainTextEdit>
9 #include <QScrollBar>
10 #include <QTextCursor>
11 
12 #include <QStringListModel>
13 
14 #ifdef WITH_PYTHON
15 #include "PythonQt.h"
16 #include "python/wrappers/py_wrappers.h"
17 #else
18 class PythonQtObjectPtr;
19 #endif
20 
21 namespace tilde {
26 class UIScriptTextEdit : public QPlainTextEdit {
27  Q_OBJECT
28 
29 private:
30  QCompleter* _completer;
31  #ifdef WITH_PYTHON
32  PythonQtObjectPtr _context;
33  #endif
34 public:
35  explicit UIScriptTextEdit(QPlainTextEdit* parent = 0);
36 
37  #ifdef WITH_PYTHON
38  void setContext(PythonQtObjectPtr ctx) { _context = ctx; }
39  PythonQtObjectPtr context() { return _context; }
40  #endif
41 
42 private slots:
43  //-----------------------------------------------------------------------------
44  // The code below is from PythonQt ScriptingConsole example, see header for all details
45  void insertCompletion(const QString& completion)
46  {
47  QTextCursor tc = this->textCursor();
48  tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor);
49  if (tc.selectedText() == ".") {
50  tc.insertText(QString(".") + completion);
51  } else {
52  tc = this->textCursor();
53  tc.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
54  tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
55  tc.insertText(completion);
56  this->setTextCursor(tc);
57  }
58  }
59 
60  //-----------------------------------------------------------------------------
61 
62  void handleTabCompletion()
63  {
64  QTextCursor textCursor = this->textCursor();
65  int pos = textCursor.position();
66  textCursor.setPosition(0);
67  textCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
68  int startPos = textCursor.selectionStart();
69 
70  int offset = pos - startPos;
71  QString text = textCursor.selectedText();
72 
73  QString textToComplete;
74  int cur = offset;
75  while (cur--) {
76  QChar c = text.at(cur);
77  if (c.isLetterOrNumber() || c == '.' || c == '_') {
78  textToComplete.prepend(c);
79  } else {
80  break;
81  }
82  }
83 
84  QString lookup;
85  QString compareText = textToComplete;
86  int dot = compareText.lastIndexOf('.');
87  if (dot != -1) {
88  lookup = compareText.mid(0, dot);
89  compareText = compareText.mid(dot + 1, offset);
90  }
91  if (!lookup.isEmpty() || !compareText.isEmpty()) {
92  compareText = compareText.toLower();
93  QStringList found;
94  QStringList l = PythonQt::self()->introspection(_context, lookup, PythonQt::Anything);
95  Q_FOREACH (QString n, l) {
96  if (n.toLower().startsWith(compareText)) {
97  found << n;
98  }
99  }
100 
101  if (!found.isEmpty()) {
102  _completer->setCompletionPrefix(compareText);
103  _completer->setCompletionMode(QCompleter::PopupCompletion);
104  _completer->setModel(new QStringListModel(found, _completer));
105  _completer->setCaseSensitivity(Qt::CaseInsensitive);
106  QTextCursor c = this->textCursor();
107  c.movePosition(QTextCursor::StartOfWord);
108  QRect cr = cursorRect(c);
109  cr.setWidth(_completer->popup()->sizeHintForColumn(0)
110  + _completer->popup()->verticalScrollBar()->sizeHint().width());
111  cr.translate(0, 8);
112  _completer->complete(cr);
113  } else {
114  _completer->popup()->hide();
115  }
116  } else {
117  _completer->popup()->hide();
118  }
119  }
120 
121  void keyPressEvent(QKeyEvent* event)
122  {
123 
124  if (_completer && _completer->popup()->isVisible()) {
125  // The following keys are forwarded by the completer to the widget
126  switch (event->key()) {
127  case Qt::Key_Return:
128  if (!_completer->popup()->currentIndex().isValid()) {
129  insertCompletion(_completer->currentCompletion());
130  _completer->popup()->hide();
131  event->accept();
132  }
133  event->ignore();
134  return;
135  break;
136  case Qt::Key_Enter:
137  case Qt::Key_Escape:
138  case Qt::Key_Tab:
139  case Qt::Key_Backtab:
140 
141  event->ignore();
142  return; // let the completer do default behavior
143  default:
144  break;
145  }
146  }
147 
148  // bool eventHandled = false;
149  QTextCursor textCursor = this->textCursor();
150 
151  // int key = event->key();
152  // switch (key) {
153 
154  // case Qt::Key_Left:
155 
156  // // Moving the cursor left is limited to the position
157  // // of the command prompt.
158 
159  // if (textCursor.position() <= commandPromptPosition()) {
160 
161  // QApplication::beep();
162  // eventHandled = true;
163  // }
164  // break;
165 
166  // case Qt::Key_Up:
167 
168  // // Display the previous command in the history
169  // if (_historyPosition>0) {
170  // _historyPosition--;
171  // changeHistory();
172  // }
173 
174  // eventHandled = true;
175  // break;
176 
177  // case Qt::Key_Down:
178 
179  // // Display the next command in the history
180  // if (_historyPosition+1<_history.count()) {
181  // _historyPosition++;
182  // changeHistory();
183  // }
184 
185  // eventHandled = true;
186  // break;
187 
188  // case Qt::Key_Return:
189 
190  // executeLine(event->modifiers() & Qt::ShiftModifier);
191  // eventHandled = true;
192  // break;
193 
194  // case Qt::Key_Backspace:
195 
196  // if (textCursor.hasSelection()) {
197 
198  // cut();
199  // eventHandled = true;
200 
201  // } else {
202 
203  // // Intercept backspace key event to check if
204  // // deleting a character is allowed. It is not
205  // // allowed, if the user wants to delete the
206  // // command prompt.
207 
208  // if (textCursor.position() <= commandPromptPosition()) {
209 
210  // QApplication::beep();
211  // eventHandled = true;
212  // }
213  // }
214  // break;
215 
216  // case Qt::Key_Delete:
217 
218  // cut();
219  // eventHandled = true;
220  // break;
221 
222  // default:
223 
224  // if (key >= Qt::Key_Space && key <= Qt::Key_division) {
225 
226  // if (textCursor.hasSelection() && !verifySelectionBeforeDeletion()) {
227 
228  // // The selection must not be deleted.
229  // eventHandled = true;
230 
231  // } else {
232 
233  // // The key is an input character, check if the cursor is
234  // // behind the last command prompt, else inserting the
235  // // character is not allowed.
236 
237  // int commandPromptPosition = commandPromptPosition();
238  // if (textCursor.position() < commandPromptPosition) {
239 
240  // textCursor.setPosition(commandPromptPosition);
241  // setTextCursor(textCursor);
242  // }
243  // }
244  // }
245  // }
246 
247  // if (eventHandled) {
248 
249  // _completer->popup()->hide();
250  // event->accept();
251 
252  // } else
253  //{
254 
255  QPlainTextEdit::keyPressEvent(event);
256  QString text = event->text();
257 
258  if (!text.isEmpty()) {
259  handleTabCompletion();
260  } else {
261  _completer->popup()->hide();
262  }
263  // eventHandled = true;
264  //}
265  //
266  }
267 
268  void mousePressEvent(QMouseEvent* e)
269  {
270  e->accept();
271  }
272 };
273 }
274 
275 #endif // UISCRIPTEDITOR_H
UIScriptTextEdit(QPlainTextEdit *parent=0)
Definition: UIScriptTextEdit.cpp:8
The text editor for UIScript editor widget.
Definition: UIScriptTextEdit.h:26