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_P_H
34 #define BASETEXTEDITOR_P_H
36 #include "basetexteditor.h"
37 #include "behaviorsettings.h"
38 #include "displaysettings.h"
39 #include "texteditoroverlay.h"
40 #include "fontsettings.h"
41 #include "refactoroverlay.h"
43 #include <utils/changeset.h>
45 #include <QtCore/QBasicTimer>
46 #include <QtCore/QSharedData>
47 #include <QtCore/QPointer>
48 #include <QtCore/QScopedPointer>
50 #include <QtGui/QPixmap>
51 #include <QtGui/QTextEdit>
53 namespace TextEditor {
55 class BaseTextDocument;
56 class TextEditorActionHandler;
60 class TEXTEDITOR_EXPORT BaseTextBlockSelection
64 bool isValid() const{ return !firstBlock.isNull() && !lastBlock.isNull(); }
65 void clear() { firstBlock = lastBlock = QTextCursor(); }
67 QTextCursor firstBlock; // defines the first block
68 QTextCursor lastBlock; // defines the last block
69 int firstVisualColumn; // defines the first visual column of the selection
70 int lastVisualColumn; // defines the last visual column of the selection
71 enum Anchor {TopLeft = 0, TopRight, BottomLeft, BottomRight} anchor;
72 BaseTextBlockSelection():firstVisualColumn(0), lastVisualColumn(0), anchor(BottomRight){}
73 void moveAnchor(int blockNumber, int visualColumn);
74 inline int anchorColumnNumber() const { return (anchor % 2) ? lastVisualColumn : firstVisualColumn; }
75 inline int anchorBlockNumber() const {
76 return (anchor <= TopRight ? firstBlock.blockNumber() : lastBlock.blockNumber()); }
77 QTextCursor selection(const TabSettings &ts) const;
78 void fromSelection(const TabSettings &ts, const QTextCursor &selection);
81 //========== Pointers with reference count ==========
83 template <class T> class QRefCountData : public QSharedData
86 QRefCountData(T *data) { m_data = data; }
88 ~QRefCountData() { delete m_data; }
93 /* MOSTLY COPIED FROM QSHAREDDATA(-POINTER) */
94 template <class T> class QRefCountPointer
97 inline T &operator*() { return d ? *(d->m_data) : 0; }
98 inline const T &operator*() const { return d ? *(d->m_data) : 0; }
99 inline T *operator->() { return d ? d->m_data : 0; }
100 inline const T *operator->() const { return d ? d->m_data : 0; }
101 inline operator T *() { return d ? d->m_data : 0; }
102 inline operator const T *() const { return d ? d->m_data : 0; }
104 inline bool operator==(const QRefCountPointer<T> &other) const { return d == other.d; }
105 inline bool operator!=(const QRefCountPointer<T> &other) const { return d != other.d; }
107 inline QRefCountPointer() { d = 0; }
108 inline ~QRefCountPointer() { if (d && !d->ref.deref()) delete d; }
110 explicit QRefCountPointer(T *data) {
112 d = new QRefCountData<T>(data);
119 inline QRefCountPointer(const QRefCountPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
120 inline QRefCountPointer<T> & operator=(const QRefCountPointer<T> &o) {
122 if (d && !d->ref.deref())
124 //todo: atomic assign of pointers
131 inline QRefCountPointer &operator=(T *o) {
132 if (d == 0 || d->m_data != o) {
133 if (d && !d->ref.deref())
135 d = new QRefCountData<T>(o);
142 inline bool operator!() const { return !d; }
148 //================BaseTextEditorPrivate==============
150 struct BaseTextEditorPrivateHighlightBlocks
154 QList<int> visualIndent;
155 inline int count() const { return visualIndent.size(); }
156 inline bool isEmpty() const { return open.isEmpty() || close.isEmpty() || visualIndent.isEmpty(); }
157 inline bool operator==(const BaseTextEditorPrivateHighlightBlocks &o) const {
158 return (open == o.open && close == o.close && visualIndent == o.visualIndent);
160 inline bool operator!=(const BaseTextEditorPrivateHighlightBlocks &o) const { return !(*this == o); }
164 class BaseTextEditorPrivate
166 BaseTextEditorPrivate(const BaseTextEditorPrivate &);
167 BaseTextEditorPrivate &operator=(const BaseTextEditorPrivate &);
170 BaseTextEditorPrivate();
171 ~BaseTextEditorPrivate();
173 void setupBasicEditActions(TextEditorActionHandler *actionHandler);
174 void setupDocumentSignals(BaseTextDocument *document);
175 void updateLineSelectionColor();
177 void print(QPrinter *printer);
179 QTextBlock m_firstVisible;
183 BaseTextEditorWidget *q;
184 bool m_contentsChanged;
185 bool m_lastCursorChangeWasInteresting;
187 QList<QTextEdit::ExtraSelection> m_syntaxHighlighterSelections;
188 QTextEdit::ExtraSelection m_lineSelection;
190 QRefCountPointer<BaseTextDocument> m_document;
191 QByteArray m_tempState;
192 QByteArray m_tempNavigationState;
194 QString m_displayName;
195 bool m_parenthesesMatchingEnabled;
196 QTimer *m_updateTimer;
198 Utils::ChangeSet m_changeSet;
200 // parentheses matcher
202 QTextCharFormat m_matchFormat;
203 QTextCharFormat m_mismatchFormat;
204 QTextCharFormat m_rangeFormat;
205 QTimer *m_parenthesesMatchingTimer;
206 // end parentheses matcher
208 QWidget *m_extraArea;
210 DisplaySettings m_displaySettings;
211 FontSettings m_fontSettings;
212 BehaviorSettings m_behaviorSettings;
214 int extraAreaSelectionAnchorBlockNumber;
215 int extraAreaToggleMarkBlockNumber;
216 int extraAreaHighlightFoldedBlockNumber;
218 TextEditorOverlay *m_overlay;
219 TextEditorOverlay *m_snippetOverlay;
220 TextEditorOverlay *m_searchResultOverlay;
221 bool snippetCheckCursor(const QTextCursor &cursor);
222 void snippetTabOrBacktab(bool forward);
223 QTextCharFormat m_occurrencesFormat;
224 QTextCharFormat m_occurrenceRenameFormat;
226 RefactorOverlay *m_refactorOverlay;
228 QBasicTimer foldedBlockTimer;
229 int visibleFoldedBlockNumber;
230 int suggestedVisibleFoldedBlockNumber;
231 void clearVisibleFoldedBlock();
232 bool m_mouseOnFoldedMarker;
233 void foldLicenseHeader();
235 QBasicTimer autoScrollTimer;
236 void updateMarksLineNumber();
237 void updateMarksBlock(const QTextBlock &block);
238 uint m_marksVisible : 1;
239 uint m_codeFoldingVisible : 1;
240 uint m_codeFoldingSupported : 1;
241 uint m_revisionsVisible : 1;
242 uint m_lineNumbersVisible : 1;
243 uint m_highlightCurrentLine : 1;
244 uint m_requestMarkEnabled : 1;
245 uint m_lineSeparatorsAllowed : 1;
246 int m_visibleWrapColumn;
248 QTextCharFormat m_linkFormat;
249 BaseTextEditorWidget::Link m_currentLink;
252 QTextCharFormat m_ifdefedOutFormat;
254 QRegExp m_searchExpr;
255 Find::FindFlags m_findFlags;
256 QTextCharFormat m_searchResultFormat;
257 QTextCharFormat m_searchScopeFormat;
258 QTextCharFormat m_currentLineFormat;
259 QTextCharFormat m_currentLineNumberFormat;
260 void highlightSearchResults(const QTextBlock &block, TextEditorOverlay *overlay);
261 QTimer *m_delayedUpdateTimer;
263 BaseTextEditor *m_editor;
265 QObject *m_actionHack;
267 QList<QTextEdit::ExtraSelection> m_extraSelections[BaseTextEditorWidget::NExtraSelectionKinds];
269 // block selection mode
270 bool m_inBlockSelectionMode;
271 void clearBlockSelection();
272 QString copyBlockSelection();
273 void removeBlockSelection(const QString &text = QString());
274 bool m_moveLineUndoHack;
276 QTextCursor m_findScopeStart;
277 QTextCursor m_findScopeEnd;
278 int m_findScopeVerticalBlockSelectionFirstColumn;
279 int m_findScopeVerticalBlockSelectionLastColumn;
281 QTextCursor m_selectBlockAnchor;
283 Internal::BaseTextBlockSelection m_blockSelection;
285 void moveCursorVisible(bool ensureVisible = true);
287 int visualIndent(const QTextBlock &block) const;
288 BaseTextEditorPrivateHighlightBlocks m_highlightBlocksInfo;
289 QTimer *m_highlightBlocksTimer;
291 int m_requestAutoCompletionRevision;
292 int m_requestAutoCompletionPosition;
293 QTimer *m_requestAutoCompletionTimer;
295 QPointer<BaseTextEditorAnimator> m_animator;
296 int m_cursorBlockNumber;
298 QScopedPointer<AutoCompleter> m_autoCompleter;
299 QScopedPointer<Indenter> m_indenter;
302 } // namespace Internal
303 } // namespace TextEditor
305 #endif // BASETEXTEDITOR_P_H