OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / texteditor / generichighlighter / highlighter.h
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #ifndef HIGHLIGHTER_H
35 #define HIGHLIGHTER_H
36
37 #include "basetextdocumentlayout.h"
38 #include "syntaxhighlighter.h"
39
40 #include <QtCore/QString>
41 #include <QtCore/QVector>
42 #include <QtCore/QStack>
43 #include <QtCore/QSharedPointer>
44 #include <QtCore/QStringList>
45
46 #include <QtGui/QSyntaxHighlighter>
47 #include <QtGui/QTextCharFormat>
48
49 namespace TextEditor {
50
51 class TabSettings;
52
53 namespace Internal {
54
55 class Rule;
56 class Context;
57 class HighlightDefinition;
58 class ProgressData;
59
60 class Highlighter : public TextEditor::SyntaxHighlighter
61 {
62     Q_OBJECT
63
64 public:
65     Highlighter(QTextDocument *parent = 0);
66     virtual ~Highlighter();
67
68     enum TextFormatId {
69         Normal,
70         VisualWhitespace,
71         Keyword,
72         DataType,
73         Decimal,
74         BaseN,
75         Float,
76         Char,
77         String,
78         Comment,
79         Alert,
80         Error,
81         Function,
82         RegionMarker,
83         Others
84     };
85
86     void configureFormat(TextFormatId id, const QTextCharFormat &format);
87     void setTabSettings(const TabSettings &ts);
88     void setDefaultContext(const QSharedPointer<Context> &defaultContext);
89
90 protected:
91     virtual void highlightBlock(const QString &text);
92
93 private:
94
95     void setupDataForBlock(const QString &text);
96     void setupDefault();
97     void setupFromWillContinue();
98     void setupFromContinued();
99     void setupFromPersistent();
100
101     void iterateThroughRules(const QString &text,
102                              const int length,
103                              ProgressData *progress,
104                              const bool childRule,
105                              const QList<QSharedPointer<Rule> > &rules);
106
107     void assignCurrentContext();
108     bool contextChangeRequired(const QString &contextName) const;
109     void handleContextChange(const QString &contextName,
110                              const QSharedPointer<HighlightDefinition> &definition,
111                              const bool setCurrent = true);
112     void changeContext(const QString &contextName,
113                        const QSharedPointer<HighlightDefinition> &definition,
114                        const bool assignCurrent = true);
115
116     QString currentContextSequence() const;
117     void mapPersistentSequence(const QString &contextSequence);
118     void mapLeadingSequence(const QString &contextSequence);
119     void pushContextSequence(int state);
120
121     void pushDynamicContext(const QSharedPointer<Context> &baseContext);
122
123     void createWillContinueBlock();
124     void analyseConsistencyOfWillContinueBlock(const QString &text);
125
126     void applyFormat(int offset,
127                      int count,
128                      const QString &itemDataName,
129                      const QSharedPointer<HighlightDefinition> &definition);
130
131     void applyRegionBasedFolding() const;
132     void applyIndentationBasedFolding(const QString &text) const;
133     int neighbouringNonEmptyBlockIndent(QTextBlock block, const bool previous) const;
134
135     // Mapping from Kate format strings to format ids.
136     struct KateFormatMap
137     {
138         KateFormatMap();
139         QHash<QString, TextFormatId> m_ids;
140     };
141     static const KateFormatMap m_kateFormats;
142     QHash<TextFormatId, QTextCharFormat> m_creatorFormats;
143
144     struct BlockData : TextBlockUserData
145     {
146         BlockData();
147         virtual ~BlockData();
148
149         int m_foldingIndentDelta;
150         int m_originalObservableState;
151         QStack<QString> m_foldingRegions;
152         QSharedPointer<Context> m_contextToContinue;
153     };
154     BlockData *initializeBlockData();
155     static BlockData *blockData(QTextBlockUserData *userData);
156
157     // Block states are composed by the region depth (used for code folding) and what I call
158     // observable states. Observable states occupy the 12 least significant bits. They might have
159     // the following values:
160     // - Default [0]: Nothing special.
161     // - WillContinue [1]: When there is match of the LineContinue rule (backslash as the last
162     //   character).
163     // - Continued [2]: Blocks that happen after a WillContinue block and continue from their
164     //   context until the next line end.
165     // - Persistent(s) [Anything >= 3]: Correspond to persistent contexts which last until a pop
166     //   occurs due to a matching rule. Every sequence of persistent contexts seen so far is
167     //   associated with a number (incremented by a unit each time).
168     // Region depths occupy the remaining bits.
169     enum ObservableBlockState {
170         Default = 0,
171         WillContinue,
172         Continued,
173         PersistentsStart
174     };
175     int computeState(const int observableState) const;
176
177     static int extractRegionDepth(const int state);
178     static int extractObservableState(const int state);
179
180     int m_regionDepth;
181     bool m_indentationBasedFolding;
182     const TabSettings *m_tabSettings;
183
184     int m_persistentObservableStatesCounter;
185     int m_dynamicContextsCounter;
186
187     bool m_isBroken;
188
189     QSharedPointer<Context> m_defaultContext;
190     QSharedPointer<Context> m_currentContext;
191     QVector<QSharedPointer<Context> > m_contexts;
192
193     // Mapping from context sequences to the observable persistent state they represent.
194     QHash<QString, int> m_persistentObservableStates;
195     // Mapping from context sequences to the non-persistent observable state that led to them.
196     QHash<QString, int> m_leadingObservableStates;
197     // Mapping from observable persistent states to context sequences (the actual "stack").
198     QHash<int, QVector<QSharedPointer<Context> > > m_persistentContexts;
199
200     // Captures used in dynamic rules.
201     QStringList m_currentCaptures;
202 };
203
204 } // namespace Internal
205 } // namespace TextEditor
206
207 #endif // HIGHLIGHTER_H