1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #ifndef BASETEXTEDITOR_H
34 #define BASETEXTEDITOR_H
36 #include "itexteditor.h"
37 #include "icompletioncollector.h"
39 #include <find/ifindsupport.h>
41 #include <coreplugin/editormanager/editormanager.h>
43 #include <QtGui/QPlainTextEdit>
51 class LineColumnLabel;
55 namespace TextEditor {
57 class RefactorOverlay;
58 struct RefactorMarker;
61 class BaseTextEditorPrivate;
62 class TextEditorOverlay;
63 typedef QList<RefactorMarker> RefactorMarkers;
64 typedef QString (QString::*TransformationMethod)() const;
69 class BaseTextDocument;
72 class BehaviorSettings;
73 class CompletionSettings;
74 class DisplaySettings;
75 class StorageSettings;
78 class ExtraEncodingSettings;
80 class TEXTEDITOR_EXPORT BaseTextEditorAnimator : public QObject
85 BaseTextEditorAnimator(QObject *parent);
87 inline void setPosition(int position) { m_position = position; }
88 inline int position() const { return m_position; }
90 void setData(QFont f, QPalette pal, const QString &text);
92 void draw(QPainter *p, const QPointF &pos);
95 inline qreal value() const { return m_value; }
96 inline QPointF lastDrawPos() const { return m_lastDrawPos; }
100 bool isRunning() const;
103 void updateRequest(int position, QPointF lastPos, QRectF rect);
110 QTimeLine *m_timeline;
113 QPointF m_lastDrawPos;
121 class TEXTEDITOR_EXPORT BaseTextEditorWidget : public QPlainTextEdit
124 Q_PROPERTY(int verticalBlockSelectionFirstColumn READ verticalBlockSelectionFirstColumn)
125 Q_PROPERTY(int verticalBlockSelectionLastColumn READ verticalBlockSelectionLastColumn)
127 BaseTextEditorWidget(QWidget *parent);
128 ~BaseTextEditorWidget();
130 static ITextEditor *openEditorAt(const QString &fileName, int line, int column = 0,
131 const QString &editorId = QString(),
132 Core::EditorManager::OpenEditorFlags flags = Core::EditorManager::IgnoreNavigationHistory,
133 bool *newEditor = 0);
135 const Utils::ChangeSet &changeSet() const;
136 void setChangeSet(const Utils::ChangeSet &changeSet);
139 Core::IFile * file();
140 bool createNew(const QString &contents);
141 virtual bool open(const QString &fileName = QString());
142 QByteArray saveState() const;
143 bool restoreState(const QByteArray &state);
144 QString displayName() const;
148 void gotoLine(int line, int column = 0);
151 ITextEditor::PositionOperation posOp = ITextEditor::Current
152 , int at = -1) const;
153 void convertPosition(int pos, int *line, int *column) const;
155 BaseTextEditor *editor() const;
156 ITextMarkable *markableInterface() const;
158 QChar characterAt(int pos) const;
160 void print(QPrinter *);
162 void setSuggestedFileName(const QString &suggestedFileName);
163 QString mimeType() const;
164 virtual void setMimeType(const QString &mt);
167 void appendStandardContextMenuActions(QMenu *menu);
169 // Works only in conjunction with a syntax highlighter that puts
170 // parentheses into text block user data
171 void setParenthesesMatchingEnabled(bool b);
172 bool isParenthesesMatchingEnabled() const;
174 void setHighlightCurrentLine(bool b);
175 bool highlightCurrentLine() const;
177 void setLineNumbersVisible(bool b);
178 bool lineNumbersVisible() const;
180 void setMarksVisible(bool b);
181 bool marksVisible() const;
183 void setRequestMarkEnabled(bool b);
184 bool requestMarkEnabled() const;
186 void setLineSeparatorsAllowed(bool b);
187 bool lineSeparatorsAllowed() const;
189 void updateCodeFoldingVisible();
190 bool codeFoldingVisible() const;
192 void setCodeFoldingSupported(bool b);
193 bool codeFoldingSupported() const;
195 void setMouseNavigationEnabled(bool b);
196 bool mouseNavigationEnabled() const;
198 void setScrollWheelZoomingEnabled(bool b);
199 bool scrollWheelZoomingEnabled() const;
201 void setRevisionsVisible(bool b);
202 bool revisionsVisible() const;
204 void setVisibleWrapColumn(int column);
205 int visibleWrapColumn() const;
207 int columnCount() const;
208 int rowCount() const;
210 void setActionHack(QObject *);
211 QObject *actionHack() const;
213 void setTextCodec(QTextCodec *codec);
214 QTextCodec *textCodec() const;
216 void setReadOnly(bool b);
218 void setTextCursor(const QTextCursor &cursor);
220 void insertCodeSnippet(const QTextCursor &cursor, const QString &snippet);
222 void setBlockSelection(bool on);
223 bool hasBlockSelection() const;
225 int verticalBlockSelectionFirstColumn() const;
226 int verticalBlockSelectionLastColumn() const;
228 QRegion translatedLineRegion(int lineStart, int lineEnd) const;
230 void setIndenter(Indenter *indenter);
231 Indenter *indenter() const;
233 void setAutoCompleter(AutoCompleter *autoCompleter);
234 AutoCompleter *autoCompleter() const;
236 QPoint toolTipPosition(const QTextCursor &c) const;
239 void setDisplayName(const QString &title);
241 virtual void paste();
244 void zoomIn(int range = 1);
245 void zoomOut(int range = 1);
253 void selectEncoding();
255 void gotoBlockStart();
257 void gotoBlockStartWithSelection();
258 void gotoBlockEndWithSelection();
260 void gotoLineStart();
261 void gotoLineStartWithSelection();
263 void gotoLineEndWithSelection();
265 void gotoNextLineWithSelection();
266 void gotoPreviousLine();
267 void gotoPreviousLineWithSelection();
268 void gotoPreviousCharacter();
269 void gotoPreviousCharacterWithSelection();
270 void gotoNextCharacter();
271 void gotoNextCharacterWithSelection();
272 void gotoPreviousWord();
273 void gotoPreviousWordWithSelection();
275 void gotoNextWordWithSelection();
276 void gotoPreviousWordCamelCase();
277 void gotoPreviousWordCamelCaseWithSelection();
278 void gotoNextWordCamelCase();
279 void gotoNextWordCamelCaseWithSelection();
281 void selectBlockUp();
282 void selectBlockDown();
292 void insertLineAbove();
293 void insertLineBelow();
295 void uppercaseSelection();
296 void lowercaseSelection();
298 void cleanWhitespace();
304 void contentsChanged();
307 bool event(QEvent *e);
308 void keyPressEvent(QKeyEvent *e);
309 void wheelEvent(QWheelEvent *e);
310 void changeEvent(QEvent *e);
311 void focusInEvent(QFocusEvent *e);
312 void focusOutEvent(QFocusEvent *e);
314 void showEvent(QShowEvent *);
316 // reimplemented to support block selection
317 QMimeData *createMimeDataFromSelection() const;
318 bool canInsertFromMimeData(const QMimeData *source) const;
319 void insertFromMimeData(const QMimeData *source);
321 static QString msgTextTooLarge(quint64 size);
324 void maybeSelectLine();
327 void duplicateFrom(BaseTextEditorWidget *editor);
330 BaseTextDocument *baseTextDocument() const;
331 void setBaseTextDocument(BaseTextDocument *doc);
333 void setDefaultPath(const QString &defaultPath);
335 virtual BaseTextEditor *createEditor() = 0;
338 void editorContentsChange(int position, int charsRemoved, int charsAdded);
339 void documentAboutToBeReloaded();
340 void documentReloaded();
341 void highlightSearchResults(const QString &txt, Find::FindFlags findFlags);
342 void setFindScope(const QTextCursor &start, const QTextCursor &end, int, int);
343 bool inFindScope(const QTextCursor &cursor);
344 bool inFindScope(int selectionStart, int selectionEnd);
345 void currentEditorChanged(Core::IEditor *editor);
348 Internal::BaseTextEditorPrivate *d;
349 friend class Internal::BaseTextEditorPrivate;
350 friend class Internal::TextEditorOverlay;
351 friend class RefactorOverlay;
354 QWidget *extraArea() const;
355 virtual int extraAreaWidth(int *markWidthPtr = 0) const;
356 virtual void extraAreaPaintEvent(QPaintEvent *);
357 virtual void extraAreaLeaveEvent(QEvent *);
358 virtual void extraAreaMouseEvent(QMouseEvent *);
360 const TabSettings &tabSettings() const;
361 const DisplaySettings &displaySettings() const;
363 void markBlocksAsChanged(QList<int> blockNumbers);
365 void ensureCursorVisible();
367 enum ExtraSelectionKind {
368 CurrentLineSelection,
369 ParenthesesMatchingSelection,
370 CodeWarningsSelection,
371 CodeSemanticsSelection,
372 UndefinedSymbolSelection,
373 UnusedSymbolSelection,
376 SnippetPlaceholderSelection,
380 void setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections);
381 QList<QTextEdit::ExtraSelection> extraSelections(ExtraSelectionKind kind) const;
382 QString extraSelectionTooltip(int pos) const;
385 void setRefactorMarkers(const Internal::RefactorMarkers &markers);
387 void refactorMarkerClicked(const TextEditor::RefactorMarker &marker);
393 BlockRange() : first(0), last(-1) {}
394 BlockRange(int first_position, int last_position)
395 : first(first_position), last(last_position)
399 inline bool isNull() const { return last < first; }
402 // the blocks list must be sorted
403 void setIfdefedOutBlocks(const QList<BlockRange> &blocks);
406 virtual void format();
407 virtual void rewrapParagraph();
408 virtual void unCommentSelection();
409 virtual void setFontSettings(const TextEditor::FontSettings &);
410 void setFontSettingsIfVisible(const TextEditor::FontSettings &);
411 virtual void setTabSettings(const TextEditor::TabSettings &);
412 virtual void setDisplaySettings(const TextEditor::DisplaySettings &);
413 virtual void setBehaviorSettings(const TextEditor::BehaviorSettings &);
414 virtual void setStorageSettings(const TextEditor::StorageSettings &);
415 virtual void setCompletionSettings(const TextEditor::CompletionSettings &);
416 virtual void setExtraEncodingSettings(const TextEditor::ExtraEncodingSettings &);
419 bool viewportEvent(QEvent *event);
421 void resizeEvent(QResizeEvent *);
422 void paintEvent(QPaintEvent *);
423 void timerEvent(QTimerEvent *);
424 void mouseMoveEvent(QMouseEvent *);
425 void mousePressEvent(QMouseEvent *);
426 void mouseReleaseEvent(QMouseEvent *);
427 void leaveEvent(QEvent *);
428 void keyReleaseEvent(QKeyEvent *);
430 void dragEnterEvent(QDragEnterEvent *e);
433 void indentInsertedText(const QTextCursor &tc);
434 void indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar);
435 void reindent(QTextDocument *doc, const QTextCursor &cursor);
439 Link(const QString &fileName = QString(),
450 { return begin != end; }
452 bool operator==(const Link &other) const
453 { return begin == other.begin && end == other.end; }
455 int begin; // Link position
456 int end; // Link end position
458 QString fileName; // Target file
459 int line; // Target line
460 int column; // Target column
465 Reimplement this function to enable code navigation.
467 \a resolveTarget is set to true when the target of the link is relevant
468 (it isn't until the link is used).
470 virtual Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
473 Reimplement this function if you want to customize the way a link is
474 opened. Returns whether the link was opened successfully.
476 virtual bool openLink(const Link &link);
478 void maybeClearSomeExtraSelections(const QTextCursor &cursor);
481 virtual void slotUpdateExtraAreaWidth();
482 virtual void slotModificationChanged(bool);
483 virtual void slotUpdateRequest(const QRect &r, int dy);
484 virtual void slotCursorPositionChanged();
485 virtual void slotUpdateBlockNotify(const QTextBlock &);
488 void requestFontZoom(int zoom);
489 void requestZoomReset();
490 void requestBlockUpdate(const QTextBlock &);
493 void maybeRequestAutoCompletion(const QChar &ch);
494 void indentOrUnindent(bool doIndent);
495 void handleHomeKey(bool anchor);
496 void handleBackspaceKey();
497 void moveLineUpDown(bool up);
498 void copyLineUpDown(bool up);
499 void saveCurrentCursorPositionForNavigation();
500 void updateHighlights();
501 void updateCurrentLineHighlight();
503 void drawFoldingMarker(QPainter *painter, const QPalette &pal,
509 void drawCollapsedBlockPopup(QPainter &painter,
510 const QTextBlock &block,
514 void toggleBlockVisible(const QTextBlock &block);
517 QTextBlock foldedBlockAt(const QPoint &pos, QRect *box = 0) const;
519 void updateLink(QMouseEvent *e);
520 void showLink(const Link &);
523 void universalHelper(); // test function for development
525 bool cursorMoveKeyEvent(QKeyEvent *e);
526 bool camelCaseRight(QTextCursor &cursor, QTextCursor::MoveMode mode);
527 bool camelCaseLeft(QTextCursor &cursor, QTextCursor::MoveMode mode);
529 void transformSelection(Internal::TransformationMethod method);
533 void _q_requestAutoCompletion();
535 void handleBlockSelection(int diff_row, int diff_col);
537 // parentheses matcher
538 void _q_matchParentheses();
539 void _q_highlightBlocks();
540 void slotSelectionChanged();
541 void _q_animateUpdate(int position, QPointF lastPos, QRectF rect);
546 class TEXTEDITOR_EXPORT BaseTextEditor : public ITextEditor
551 BaseTextEditor(BaseTextEditorWidget *editorWidget);
554 friend class BaseTextEditorWidget;
555 BaseTextEditorWidget *editorWidget() const { return e; }
558 QWidget *widget() { return e; }
559 Core::IFile * file() { return e->file(); }
560 bool createNew(const QString &contents) { return e->createNew(contents); }
561 bool open(const QString &fileName = QString()) { return e->open(fileName); }
562 QString displayName() const { return e->displayName(); }
563 void setDisplayName(const QString &title) { e->setDisplayName(title); emit changed(); }
565 QByteArray saveState() const { return e->saveState(); }
566 bool restoreState(const QByteArray &state) { return e->restoreState(state); }
569 enum Side { Left, Right };
570 void insertExtraToolBarWidget(Side side, QWidget *widget);
573 int find(const QString &string) const;
574 int currentLine() const;
575 int currentColumn() const;
576 void gotoLine(int line, int column = 0) { e->gotoLine(line, column); }
577 int columnCount() const;
578 int rowCount() const;
580 int position(PositionOperation posOp = Current, int at = -1) const
581 { return e->position(posOp, at); }
582 void convertPosition(int pos, int *line, int *column) const
583 { e->convertPosition(pos, line, column); }
584 QRect cursorRect(int pos = -1) const;
586 QString contents() const;
587 QString selectedText() const;
588 QString textAt(int pos, int length) const;
589 inline QChar characterAt(int pos) const { return e->characterAt(pos); }
591 inline ITextMarkable *markableInterface() { return e->markableInterface(); }
593 void setContextHelpId(const QString &id) { m_contextHelpId = id; }
594 QString contextHelpId() const; // from IContext
596 inline void setTextCodec(QTextCodec *codec, TextCodecReason = TextCodecOtherReason) { e->setTextCodec(codec); }
597 inline QTextCodec *textCodec() const { return e->textCodec(); }
601 void remove(int length);
602 void insert(const QString &string);
603 void replace(int length, const QString &string);
604 void setCursorPosition(int pos);
605 void select(int toPos);
608 void updateCursorPosition();
611 BaseTextEditorWidget *e;
612 mutable QString m_contextHelpId;
614 QWidget *m_stretchWidget;
615 QAction *m_cursorPositionLabelAction;
616 Utils::LineColumnLabel *m_cursorPositionLabel;
619 } // namespace TextEditor
621 Q_DECLARE_METATYPE(TextEditor::BaseTextEditorWidget::Link)
623 #endif // BASETEXTEDITOR_H