cppeditor.h 9.15 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
31
32
33
#ifndef CPPEDITOR_H
#define CPPEDITOR_H

#include "cppeditorenums.h"
34
#include "cppquickfix.h"
con's avatar
con committed
35
#include <cplusplus/CppDocument.h>
Roberto Raggi's avatar
Roberto Raggi committed
36
#include <cplusplus/LookupContext.h>
con's avatar
con committed
37
38
#include <texteditor/basetexteditor.h>

Roberto Raggi's avatar
Roberto Raggi committed
39
40
41
42
#include <QtCore/QThread>
#include <QtCore/QMutex>
#include <QtCore/QWaitCondition>

con's avatar
con committed
43
44
QT_BEGIN_NAMESPACE
class QComboBox;
45
class QSortFilterProxyModel;
con's avatar
con committed
46
47
48
49
50
QT_END_NAMESPACE

namespace CPlusPlus {
class OverviewModel;
class Symbol;
51
class TokenCache;
con's avatar
con committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
}

namespace CppTools {
class CppModelManagerInterface;
}

namespace TextEditor {
class FontSettings;
}

namespace CppEditor {
namespace Internal {

class CPPEditor;
Roberto Raggi's avatar
Roberto Raggi committed
66
67
68
69
70
71
72
73
74
75
class SemanticHighlighter;

class SemanticInfo
{
public:
    struct Use {
        unsigned line;
        unsigned column;
        unsigned length;

76
77
        Use(unsigned line = 0, unsigned column = 0, unsigned length = 0)
            : line(line), column(column), length(length) {}
Roberto Raggi's avatar
Roberto Raggi committed
78
79
80
81
82
83
    };

    typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap;
    typedef QHashIterator<CPlusPlus::Symbol *, QList<Use> > LocalUseIterator;

    SemanticInfo()
Roberto Raggi's avatar
Roberto Raggi committed
84
        : revision(0), hasQ(false), hasD(false), forced(false)
Roberto Raggi's avatar
Roberto Raggi committed
85
86
    { }

87
    unsigned revision;
88
89
    bool hasQ: 1;
    bool hasD: 1;
Roberto Raggi's avatar
Roberto Raggi committed
90
    bool forced: 1;
Roberto Raggi's avatar
Roberto Raggi committed
91
92
93
    CPlusPlus::Snapshot snapshot; // ### remove
    CPlusPlus::Document::Ptr doc; // ### remove
    CPlusPlus::LookupContext context;
Roberto Raggi's avatar
Roberto Raggi committed
94
95
    LocalUseMap localUses; // ### rename
    QList<Use> typeUsages;
Roberto Raggi's avatar
Roberto Raggi committed
96
    QList<CPlusPlus::Document::DiagnosticMessage> diagnosticMessages;
Roberto Raggi's avatar
Roberto Raggi committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
};

class SemanticHighlighter: public QThread
{
    Q_OBJECT

public:
    SemanticHighlighter(QObject *parent = 0);
    virtual ~SemanticHighlighter();

    void abort();

    struct Source
    {
        CPlusPlus::Snapshot snapshot;
        QString fileName;
        QString code;
        int line;
        int column;
        int revision;
Roberto Raggi's avatar
Roberto Raggi committed
117
        bool force;
Roberto Raggi's avatar
Roberto Raggi committed
118
119

        Source()
Roberto Raggi's avatar
Roberto Raggi committed
120
            : line(0), column(0), revision(0), force(false)
Roberto Raggi's avatar
Roberto Raggi committed
121
122
123
124
125
126
127
128
129
        { }

        Source(const CPlusPlus::Snapshot &snapshot,
               const QString &fileName,
               const QString &code,
               int line, int column,
               int revision)
            : snapshot(snapshot), fileName(fileName),
              code(code), line(line), column(column),
Roberto Raggi's avatar
Roberto Raggi committed
130
              revision(revision), force(false)
Roberto Raggi's avatar
Roberto Raggi committed
131
132
133
134
        { }

        void clear()
        {
135
            snapshot = CPlusPlus::Snapshot();
Roberto Raggi's avatar
Roberto Raggi committed
136
137
138
139
140
            fileName.clear();
            code.clear();
            line = 0;
            column = 0;
            revision = 0;
Roberto Raggi's avatar
Roberto Raggi committed
141
            force = false;
Roberto Raggi's avatar
Roberto Raggi committed
142
143
144
        }
    };

145
    SemanticInfo semanticInfo(const Source &source);
Roberto Raggi's avatar
Roberto Raggi committed
146
147
148
149

    void rehighlight(const Source &source);

Q_SIGNALS:
150
    void changed(const CppEditor::Internal::SemanticInfo &semanticInfo);
Roberto Raggi's avatar
Roberto Raggi committed
151
152
153
154

protected:
    virtual void run();

155
156
157
private:
    bool isOutdated();

Roberto Raggi's avatar
Roberto Raggi committed
158
159
160
161
162
private:
    QMutex m_mutex;
    QWaitCondition m_condition;
    bool m_done;
    Source m_source;
163
    SemanticInfo m_lastSemanticInfo;
Roberto Raggi's avatar
Roberto Raggi committed
164
};
con's avatar
con committed
165
166
167
168
169
170
171
172
173
174

class CPPEditorEditable : public TextEditor::BaseTextEditorEditable
{
    Q_OBJECT
public:
    CPPEditorEditable(CPPEditor *);
    QList<int> context() const;

    bool duplicateSupported() const { return true; }
    Core::IEditor *duplicate(QWidget *parent);
175
    QString id() const;
con's avatar
con committed
176

con's avatar
con committed
177
    bool isTemporary() const { return false; }
dt's avatar
dt committed
178
    virtual bool open(const QString & fileName);
dt's avatar
dt committed
179

con's avatar
con committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
private:
    QList<int> m_context;
};

class CPPEditor : public TextEditor::BaseTextEditor
{
    Q_OBJECT

public:
    typedef TextEditor::TabSettings TabSettings;

    CPPEditor(QWidget *parent);
    ~CPPEditor();
    void unCommentSelection();

195
    unsigned editorRevision() const;
196
    bool isOutdated() const;
Roberto Raggi's avatar
Roberto Raggi committed
197
198
    SemanticInfo semanticInfo() const;

mae's avatar
mae committed
199
200
201
    virtual void paste(); // reimplemented from BaseTextEditor
    virtual void cut(); // reimplemented from BaseTextEditor

202
203
    CPlusPlus::TokenCache *tokenCache() const;

Roberto Raggi's avatar
Roberto Raggi committed
204
public Q_SLOTS:
con's avatar
con committed
205
    virtual void setFontSettings(const TextEditor::FontSettings &);
206
    void setSortedMethodOverview(bool sort);
con's avatar
con committed
207
208
    void switchDeclarationDefinition();
    void jumpToDefinition();
209
    void renameSymbolUnderCursor();
210
211
    void renameUsages();
    void findUsages();
212
    void renameUsagesNow();
213
    void hideRenameNotification();
con's avatar
con committed
214
215

protected:
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
216
    bool event(QEvent *e);
217
    void contextMenuEvent(QContextMenuEvent *);
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
218
    void keyPressEvent(QKeyEvent *);
219

con's avatar
con committed
220
221
    TextEditor::BaseTextEditorEditable *createEditableInterface();

222
    // These override BaseTextEditor
223
    virtual bool isElectricCharacter(const QChar &ch) const;
224

225
226
    virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text,
                                        const QChar &la, int *skippedChars) const;
con's avatar
con committed
227

228
229
230
231
232
233
    virtual QString insertParagraphSeparator(const QTextCursor &tc) const;

    virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
                                              const QString &textToInsert = QString()) const;

    virtual bool isInComment(const QTextCursor &cursor) const;
234

Christian Kamm's avatar
Christian Kamm committed
235
236
    const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
                                               CPlusPlus::Document::Ptr doc) const;
237

Roberto Raggi's avatar
Roberto Raggi committed
238
private Q_SLOTS:
con's avatar
con committed
239
240
241
    void updateFileName();
    void jumpToMethod(int index);
    void updateMethodBoxIndex();
Roberto Raggi's avatar
Roberto Raggi committed
242
    void updateMethodBoxIndexNow();
243
    void updateMethodBoxToolTip();
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
244
245
    void updateUses();
    void updateUsesNow();
con's avatar
con committed
246
    void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
247
    void onContentsChanged(int position, int charsRemoved, int charsAdded);
con's avatar
con committed
248

Roberto Raggi's avatar
Roberto Raggi committed
249
    void semanticRehighlight();
250
    void updateSemanticInfo(const CppEditor::Internal::SemanticInfo &semanticInfo);
Roberto Raggi's avatar
Roberto Raggi committed
251

252
253
    void performQuickFix(int index);

con's avatar
con committed
254
private:
255
256
257
    bool showWarningMessage() const;
    void setShowWarningMessage(bool showWarningMessage);

258
    void markSymbols(CPlusPlus::Symbol *canonicalSymbol, const SemanticInfo &info);
259
    bool sortedMethodOverview() const;
260
    CPlusPlus::Symbol *findDefinition(CPlusPlus::Symbol *symbol, const CPlusPlus::Snapshot &snapshot);
con's avatar
con committed
261
262
    virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);

263
264
265
    TextEditor::ITextEditor *openCppEditorAt(const QString &fileName, int line,
                                             int column = 0);

Roberto Raggi's avatar
Roberto Raggi committed
266
    SemanticHighlighter::Source currentSource(bool force = false);
Roberto Raggi's avatar
Roberto Raggi committed
267

268
    void highlightUses(const QList<SemanticInfo::Use> &uses,
269
                       const SemanticInfo &semanticInfo,
270
271
                       QList<QTextEdit::ExtraSelection> *selections);

con's avatar
con committed
272
273
    void createToolBar(CPPEditorEditable *editable);

274
275
276
277
278
279
280
281
282
    enum EditOperation {
        DeleteChar,
        DeletePreviousChar,
        InsertText
    };
    void inAllRenameSelections(EditOperation operation,
                               const QTextEdit::ExtraSelection &currentRenameSelection,
                               QTextCursor cursor,
                               const QString &text = QString());
mae's avatar
mae committed
283
284
    void startRename();
    void finishRename();
285
286
    void abortRename();

287
288
    Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
    bool openLink(const Link &link) { return openCppEditorAt(link); }
289
    bool openCppEditorAt(const Link &);
290

291
    static Link linkToSymbol(CPlusPlus::Symbol *symbol);
con's avatar
con committed
292
293
294
295
296
297

    CppTools::CppModelManagerInterface *m_modelManager;

    QList<int> m_contexts;
    QComboBox *m_methodCombo;
    CPlusPlus::OverviewModel *m_overviewModel;
298
299
    QSortFilterProxyModel *m_proxyModel;
    QAction *m_sortAction;
Roberto Raggi's avatar
Roberto Raggi committed
300
    QTimer *m_updateMethodBoxTimer;
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
301
    QTimer *m_updateUsesTimer;
302
    QTextCharFormat m_occurrencesFormat;
Roberto Raggi's avatar
Roberto Raggi committed
303
    QTextCharFormat m_occurrencesUnusedFormat;
304
    QTextCharFormat m_occurrenceRenameFormat;
Roberto Raggi's avatar
Roberto Raggi committed
305
    QTextCharFormat m_typeFormat;
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
306
307
308

    QList<QTextEdit::ExtraSelection> m_renameSelections;
    int m_currentRenameSelection;
mae's avatar
mae committed
309
310
311
    bool m_inRename, m_inRenameChanged, m_firstRenameChange;
    QTextCursor m_currentRenameSelectionBegin;
    QTextCursor m_currentRenameSelectionEnd;
Roberto Raggi's avatar
Roberto Raggi committed
312
313

    SemanticHighlighter *m_semanticHighlighter;
Roberto Raggi's avatar
Roberto Raggi committed
314
    SemanticInfo m_lastSemanticInfo;
315
    QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes;
Roberto Raggi's avatar
Roberto Raggi committed
316
    bool m_initialized;
con's avatar
con committed
317
318
};

Roberto Raggi's avatar
Roberto Raggi committed
319

con's avatar
con committed
320
321
322
323
} // namespace Internal
} // namespace CppEditor

#endif // CPPEDITOR_H