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