itom  4.1.0
codeEditor.h
1 /* ********************************************************************
2  itom software
3  URL: http://www.uni-stuttgart.de/ito
4  Copyright (C) 2020, Institut fuer Technische Optik (ITO),
5  Universitaet Stuttgart, Germany
6 
7  This file is part of itom.
8 
9  itom is free software; you can redistribute it and/or modify it
10  under the terms of the GNU Library General Public Licence as published by
11  the Free Software Foundation; either version 2 of the Licence, or (at
12  your option) any later version.
13 
14  itom is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
17  General Public Licence for more details.
18 
19  You should have received a copy of the GNU Library General Public License
20  along with itom. If not, see <http://www.gnu.org/licenses/>.
21 
22  Further hints:
23  ------------------------
24 
25  This file belongs to the code editor of itom. The code editor is
26  in major parts a fork / rewritten version of the python-based source
27  code editor PyQode from Colin Duquesnoy and others
28  (see https://github.com/pyQode). PyQode itself is licensed under
29  the MIT License (MIT).
30 
31  Some parts of the code editor of itom are also inspired by the
32  source code editor of the Spyder IDE (https://github.com/spyder-ide),
33  also licensed under the MIT License and developed by the Spyder Project
34  Contributors.
35 
36 *********************************************************************** */
37 
38 #ifndef CODEEDITOR_H
39 #define CODEEDITOR_H
40 
41 #include <qplaintextedit.h>
42 #include <qcolor.h>
43 #include <qset.h>
44 #include <qpair.h>
45 #include <qtextobject.h>
46 #include <qevent.h>
47 #include <qpoint.h>
48 
49 #include "textDecoration.h"
50 #include "syntaxHighlighter/syntaxHighlighterBase.h"
51 
52 class QMenu; //forward declaration
53 class QMimeData; //forward declaration
54 
55 namespace ito {
56 
58 {
59  int topPosition;
60  int lineNumber;
61  QTextBlock textBlock;
62 };
63 
64 class PanelsManager; //forward declaration
65 class TextDecorationsManager; //forward declaration
66 class DelayJobRunnerBase; //forward declaration
67 class ModesManager; //forward declaration
68 class SyntaxHighlighterBase; //forward declaration
69 class TextBlockUserData;
70 
71 
72 
73 /*
74 The editor widget is a simple extension to QPlainTextEdit.
75 It adds a few utility signals/methods and introduces the concepts of
76 **Managers, Modes and Panels**.
77 A **mode/panel** is an editor extension that, once added to a CodeEdit
78 instance, may modify its behaviour and appearance:
79  * **Modes** are simple objects which connect to the editor signals to
80  append new behaviours (such as automatic indentation, code completion,
81  syntax checking,...)
82  * **Panels** are the combination of a **Mode** and a **QWidget**.
83  They are displayed in the CodeEdit's content margins.
84  When you install a Panel on a CodeEdit, you can choose to install it in
85  one of the four following zones:
86  .. image:: _static/editor_widget.png
87  :align: center
88  :width: 600
89  :height: 450
90 A **manager** is an object that literally manage a specific aspect of
91 :class:`pyqode.core.api.CodeEdit`. There are managers to manage the list of
92 modes/panels, to open/save file and to control the backend:
93  - :attr:`pyqode.core.api.CodeEdit.file`:
94  File manager. Use it to open/save files or access the opened file
95  attribute.
96  - :attr:`pyqode.core.api.CodeEdit.backend`:
97  Backend manager. Use it to start/stop the backend or send a work
98  request.
99  - :attr:`pyqode.core.api.CodeEdit.modes`:
100  Modes manager. Use it to append/remove modes on the editor.
101  - :attr:`pyqode.core.api.CodeEdit.panels`:
102  Modes manager. Use it to append/remove panels on the editor.
103 Starting from version 2.1, CodeEdit defines the
104 :attr:`pyqode.core.api.CodeEdit.mimetypes` class attribute that can be used
105 by IDE to determine which editor to use for a given mime type. This
106 property is a list of supported mimetypes. An empty list means the
107 CodeEdit is generic. **Code editors specialised for a specific language
108 should define the mime types they support!**
109 */
110 class CodeEditor : public QPlainTextEdit
111 {
112  Q_OBJECT
113 public:
114 
115  enum EdgeMode
116  {
120  };
121 
122  CodeEditor(QWidget *parent = NULL, bool createDefaultActions = true);
123  virtual ~CodeEditor();
124 
125  bool useSpacesInsteadOfTabs() const;
126  void setUseSpacesInsteadOfTabs(bool value);
127 
128  bool selectLineOnCopyEmpty() const;
129  void setSelectLineOnCopyEmpty(bool value);
130 
131  bool showContextMenu() const;
132  void setShowContextMenu(bool value);
133 
134  bool showWhitespaces() const;
135  void setShowWhitespaces(bool value);
136 
137  QString fontName() const;
138  void setFontName(const QString& value);
139 
140  int fontSize() const;
141  void setFontSize(int fontSize);
142 
143  int zoomLevel() const;
144  void setZoomLevel(int value);
145 
146  int tabLength() const;
147  void setTabLength(int value);
148 
149  QColor background() const;
150  void setBackground(const QColor &value);
151 
152  QColor foreground() const;
153  void setForeground(const QColor &value);
154 
155  QColor selectionForeground() const;
156  void setSelectionForeground(const QColor &value);
157 
158  QColor selectionBackground() const;
159  void setSelectionBackground(const QColor &value);
160 
161  QColor whitespacesForeground() const;
162  void setWhitespacesForeground(const QColor &value);
163 
164  bool saveOnFocusOut() const;
165  void setSaveOnFocusOut(bool value);
166 
167  EdgeMode edgeMode() const;
168  void setEdgeMode(EdgeMode mode);
169 
170  int edgeColumn() const;
171  void setEdgeColumn(int column);
172 
173  QColor edgeColor() const;
174  void setEdgeColor(const QColor &color);
175 
176  bool showIndentationGuides() const;
177  void setShowIndentationGuides(bool value);
178 
179  QColor indentationGuidesColor() const;
180  void setIndentationGuidesColor(const QColor &color);
181 
182  QList<VisibleBlock> visibleBlocks() const;
183  bool dirty() const;
184 
185  int firstVisibleLine() const;
186  void setFirstVisibleLine(int line);
187 
188  bool isModified() const;
189  void setModified(bool modified);
190 
191  QString wordSeparators() const { return m_wordSeparators; }
192 
193  bool isUndoAvailable() const { return m_undoAvailable; }
194  bool isRedoAvailable() const { return m_redoAvailable; }
195 
196  void setMouseCursor(const QCursor &cursor);
197 
198  void cursorPosition(int &line, int &column) const;
199 
200  void setViewportMargins(int left, int top, int right, int bottom);
201 
202  PanelsManager* panels() const;
203  TextDecorationsManager* decorations() const;
204  ModesManager* modes() const;
205 
206  SyntaxHighlighterBase *syntaxHighlighter() const;
207 
208  int currentLineNumber() const;
209  int currentColumnNumber() const;
210  int lineNbrFromPosition(int yPos) const;
211  int lineCount() const;
212  int lineLength(int line) const;
213  QTextCursor selectWholeLine(int line = -1, bool applySelection = true);
214  QTextCursor selectLines(int start = 0, int end = -1, bool applySelection = true);
215  QPair<int,int> selectionRange() const; //start, end
216  void getSelection(int *lineFrom, int *indexFrom, int *lineTo, int *indexTo);
217  void setSelection(int lineFrom, int indexFrom, int lineTo, int indexTo);
218  bool hasSelectedText() const;
219  int linePosFromNumber(int lineNumber) const;
220  void lineIndexFromPosition(const QPoint &pos, int *line, int *column) const;
221  void lineIndexFromPosition(int pos, int *line, int *column) const;
222  void getCursorPosition(int *line, int *column) const;
223  QTextCursor setCursorPosition(int line, int column, bool applySelection = true);
224  void unfoldCursorPosition(); //make sures, that the line of the current cursor is unfold
225  void ensureLineVisible(int line);
226  QTextCursor gotoLine(int line, int column, bool move = true);
227 
228  void removeSelectedText();
229 
230  bool findFirst(const QString &expr, bool re, bool cs, bool wo, bool wrap, \
231  bool forward = true, int line = -1, int index = -1, bool show = true);
232  bool findNext();
233  void replace(const QString &text);
234 
235  void endUndoAction() { textCursor().endEditBlock(); }
236  void beginUndoAction() { textCursor().beginEditBlock(); }
237 
238  QString selectedText() const;
239  int length() const { return toPlainText().size(); }
240  int positionFromLineIndex(int line, int column) const;
241 
242  int lineIndent(int lineNumber = -1) const;
243  int lineIndent(const QTextBlock *lineNbr) const;
244  QString lineText(int lineIdx) const;
245  void markWholeDocDirty();
246  void callResizeEvent(QResizeEvent *evt) { resizeEvent(evt); }
247 
248  virtual QString codeText(int &/*line*/, int &/*column*/) const { return toPlainText(); } //usually this is the same than toPlainText(), however in the console widget, the codeText() contains all the history of input code within this session!
249 
250  void indent();
251  void unindent();
252 
253  virtual void cut();
254  virtual void copy();
255 
256  void resetStylesheet();
257  void rehighlight();
258  void rehighlightBlock(int lineFromIdx, int lineToIdx /*=-1*/);
259 
260  void showTooltip(const QPoint &pos, const QString &tooltip);
261  void showTooltip(const QPoint &pos, const QString &tooltip, const TextDecoration::Ptr &senderDeco);
262 
263  void setPlainText(const QString &text, const QString &mimeType = "", const QString &encoding = "");
264  void insertAt(const QString &text, int line, int index);
265  void append(const QString &text);
266 
267  bool isCommentOrString(const QTextCursor &cursor, const QList<StyleItem::StyleType> &formats = QList<StyleItem::StyleType>());
268  bool isCommentOrString(const QTextBlock &block, const QList<StyleItem::StyleType> &formats = QList<StyleItem::StyleType>());
269  bool isNumber(const QTextCursor &cursor) const;
270  bool isNumber(const QTextBlock &block) const;
271 
272  QTextCursor wordUnderCursor(bool selectWholeWord) const;
273  QTextCursor wordUnderCursor(const QTextCursor &cursor, bool selectWholeWord) const;
274  QString wordAtPosition(int line, int index, bool selectWholeWord) const;
275  QTextCursor wordUnderMouseCursor() const;
276 
277  TextBlockUserData* getTextBlockUserData(int lineIndex, bool createIfNotExist = true);
278  TextBlockUserData* getTextBlockUserData(QTextBlock &block, bool createIfNotExist = true);
279  QSet<TextBlockUserData*>& textBlockUserDataList() { return m_textBlockUserDataList; }
280  const QSet<TextBlockUserData*>& textBlockUserDataList() const { return m_textBlockUserDataList; }
281  const TextBlockUserData* getConstTextBlockUserData(int lineIndex) const;
282 
283  virtual bool removeTextBlockUserData(TextBlockUserData* userData);
284 
285  bool bookmarksAvailable() const;
286  bool breakpointsAvailable() const;
287 
288  void callWheelEvent(QWheelEvent *e);
289 
290  void reportPositionAsGoBackNavigationItem(const QTextCursor &cursor, const QString &reason) const;
291 
292 protected:
294  {
295  CursorPosition() : editorUID(-1) {};
296  CursorPosition(const QTextCursor &textCursor, int UID = -1) : cursor(textCursor), editorUID(UID) {};
297 
298  void invalidate() { cursor = QTextCursor(); editorUID = -1; }
299 
300  QTextCursor cursor;
301  int editorUID;
302  };
303 
304  CodeEditor &operator =(const CodeEditor &) { return *this; };
305 
306  QMenu *contextMenu() const { return m_pContextMenu; }
307 
308  void showTooltipDelayJobRunner(QList<QVariant> args);
309 
310  void initSettings();
311  void initStyle();
312 
313  QString previousLineText() const;
314  QString currentLineText() const;
315 
316  void setWhitespacesFlags(bool show);
317  void updateTabStopAndIndentationWidth();
318 
319  void updateVisibleBlocks();
320 
321  void doHomeKey(QEvent *event = NULL, bool select = false);
322 
323  QTextCursor moveCursorTo(int line) const;
324 
325  virtual void reportGoBackNavigationCursorMovement(const CursorPosition &cursor, const QString &origin) const;
326 
327  virtual void contextMenuAboutToShow(int contextMenuLine);
328 
329  virtual void resizeEvent(QResizeEvent *e);
330  virtual void closeEvent(QCloseEvent *e);
331  virtual void keyPressEvent(QKeyEvent *e);
332  virtual void keyReleaseEvent(QKeyEvent *e);
333  virtual void mouseDoubleClickEvent(QMouseEvent *e);
334  virtual void mousePressEvent(QMouseEvent *e);
335  virtual void mouseReleaseEvent(QMouseEvent *e);
336  virtual void mouseMoveEvent(QMouseEvent* e);
337  virtual void showEvent(QShowEvent *e);
338  virtual void paintEvent(QPaintEvent *e);
339  virtual void wheelEvent(QWheelEvent *e);
340  virtual void contextMenuEvent(QContextMenuEvent *e);
341 
342  virtual void focusInEvent(QFocusEvent *e);
343  virtual void focusOutEvent(QFocusEvent *e);
344 
345  virtual bool eventFilter(QObject *obj, QEvent *e);
346 
347  virtual bool keyPressInternalEvent(QKeyEvent *e) { return true; };
348 
349 private:
350  struct FindOptions
351  {
352  FindOptions() : valid(false), forward(true) {};
353  bool valid;
354  QString expr;
355  bool re;
356  bool cs;
357  bool wo;
358  bool wrap;
359  bool forward;
360  bool show;
361  };
362 
363  FindOptions m_lastFindOptions;
364  bool m_showCtxMenu;
365  int m_defaultFontSize;
366  bool m_useSpacesInsteadOfTabs;
367  QColor m_whitespacesForeground;
368  QColor m_selBackground;
369  QColor m_selForeground;
370  QColor m_background;
371  QColor m_foreground;
372  bool m_showWhitespaces;
373  int m_tabLength;
374  int m_zoomLevel;
375  int m_fontSize;
376  QString m_fontFamily;
377  bool m_selectLineOnCopyEmpty;
378  QString m_wordSeparators;
379  QPoint m_lastMousePos;
380  int m_prevTooltipBlockNbr;
381  int m_indentationBarWidth;
382  int m_minLineJumpsForGoBackNavigationReport;
383 
384  EdgeMode m_edgeMode;
385  int m_edgeColumn;
386  QColor m_edgeColor;
387 
388  bool m_showIndentationGuides;
389  QColor m_indentationGuidesColor;
390 
391  bool m_redoAvailable;
392  bool m_undoAvailable;
393 
394  //flags/working variables
395  QList<VisibleBlock> m_visibleBlocks;
396  QSet<TextBlockUserData*> m_textBlockUserDataList;
397 
398  QMenu *m_pContextMenu;
399 
400  PanelsManager *m_pPanels;
401  TextDecorationsManager *m_pDecorations;
402  ModesManager *m_pModes;
403 
404  DelayJobRunnerBase *m_pTooltipsRunner;
405 
406 private slots:
407  void emitDirtyChanged(bool state);
408  void setUndoAvailable(bool available);
409  void setRedoAvailable(bool available);
410 
411 signals:
412  void dirtyChanged(bool state); //Signal emitted when the dirty state changed
413  void painted(QPaintEvent *e);
414  void keyPressed(QKeyEvent *e);
415  void keyReleased(QKeyEvent *e);
416  void postKeyPressed(QKeyEvent *e); // Signal emitted at the end of the key_pressed event
417  void mouseDoubleClicked(QMouseEvent *e); // Signal emitted when a mouse double click event occured
418  void mousePressed(QMouseEvent *e); // Signal emitted when a mouse button is pressed
419  void mouseReleased(QMouseEvent *e); //Signal emitted when a key is released
420  void mouseMoved(QMouseEvent *e); // Signal emitted when the mouse_moved
421  void mouseWheelActivated(QWheelEvent *e);
422 
423  void focusedIn(QFocusEvent *e); //Signal emitted when focusInEvent is is called
424 
425  void indentRequested(); //Signal emitted when the user press the TAB key
426  void unindentRequested(); //Signal emitted when the user press the BACK-TAB (Shift+TAB) key
427 
428  void updateRequest();
429 
430  void updateActions();
431 
432  void newTextSet();
433 };
434 
435 } //end namespace ito
436 
437 #endif
Definition: codeEditor.h:293
The background color of characters after the column limit is changed to the color set by setEdgeColor...
Definition: codeEditor.h:119
Definition: textBlockUserData.h:55
Definition: codeEditor.h:110
EdgeMode
Definition: codeEditor.h:115
Definition: syntaxHighlighterBase.h:59
Definition: apiFunctionsGraph.cpp:39
Definition: modesManager.h:55
Definition: textDecorationsManager.h:56
Definition: panelsManager.h:64
Definition: codeEditor.h:57
Definition: delayJobRunner.h:54
void newTextSet()
Signal emitted when a new text is set on the widget.
A vertical line is drawn at the column set by setEdgeColumn(). This is recommended for monospace font...
Definition: codeEditor.h:118
Definition: codeEditor.h:350
Long lines are not marked.
Definition: codeEditor.h:117