cppeditor.h 8.14 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 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 34 35 36
#ifndef CPPEDITOR_H
#define CPPEDITOR_H

#include "cppeditorenums.h"
#include <cplusplus/CppDocument.h>
#include <texteditor/basetexteditor.h>

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

con's avatar
con committed
41 42
QT_BEGIN_NAMESPACE
class QComboBox;
43
class QSortFilterProxyModel;
con's avatar
con committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
QT_END_NAMESPACE

namespace CPlusPlus {
class OverviewModel;
class Symbol;
}

namespace CppTools {
class CppModelManagerInterface;
}

namespace TextEditor {
class FontSettings;
}

namespace CppEditor {
namespace Internal {

class CPPEditor;
Roberto Raggi's avatar
Roberto Raggi committed
63 64 65 66 67 68 69 70 71 72
class SemanticHighlighter;

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

Roberto Raggi's avatar
Roberto Raggi committed
73
        Use()
74
                : line(0), column(0), length(0) {}
Roberto Raggi's avatar
Roberto Raggi committed
75

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

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

    typedef QHash<CPlusPlus::Identifier *, QList<Use> > ExternalUseMap;
    typedef QHashIterator<CPlusPlus::Identifier *, QList<Use> > ExternalUseIterator;

    SemanticInfo()
87
            : revision(-1)
Roberto Raggi's avatar
Roberto Raggi committed
88 89
    { }

90
    int revision;
91
    CPlusPlus::Snapshot snapshot;
Roberto Raggi's avatar
Roberto Raggi committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    CPlusPlus::Document::Ptr doc;
    LocalUseMap localUses;
    ExternalUseMap externalUses;
};

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;

        Source()
117
                : line(0), column(0), revision(0)
Roberto Raggi's avatar
Roberto Raggi committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
        { }

        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),
              revision(revision)
        { }

        void clear()
        {
            snapshot.clear();
            fileName.clear();
            code.clear();
            line = 0;
            column = 0;
            revision = 0;
        }
    };

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

    void rehighlight(const Source &source);

Q_SIGNALS:
    void changed(const SemanticInfo &semanticInfo);

protected:
    virtual void run();

151 152 153
private:
    bool isOutdated();

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

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

    bool duplicateSupported() const { return true; }
    Core::IEditor *duplicate(QWidget *parent);
    const char *kind() const;

con's avatar
con committed
173
    bool isTemporary() const { return false; }
dt's avatar
dt committed
174

con's avatar
con committed
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
private:
    QList<int> m_context;
};

class CPPEditor : public TextEditor::BaseTextEditor
{
    Q_OBJECT

public:
    typedef TextEditor::TabSettings TabSettings;

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

190 191
    void indentInsertedText(const QTextCursor &tc);

Roberto Raggi's avatar
Roberto Raggi committed
192 193
    SemanticInfo semanticInfo() const;

Roberto Raggi's avatar
Roberto Raggi committed
194
public Q_SLOTS:
con's avatar
con committed
195
    virtual void setFontSettings(const TextEditor::FontSettings &);
196
    void setSortedMethodOverview(bool sort);
con's avatar
con committed
197 198
    void switchDeclarationDefinition();
    void jumpToDefinition();
199
    void renameSymbolUnderCursor();
Roberto Raggi's avatar
Roberto Raggi committed
200
    void findReferences();
con's avatar
con committed
201 202 203 204 205 206

    void moveToPreviousToken();
    void moveToNextToken();

    void deleteStartOfToken();
    void deleteEndOfToken();
207

con's avatar
con committed
208
protected:
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
209
    bool event(QEvent *e);
210
    void contextMenuEvent(QContextMenuEvent *);
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
211
    void keyPressEvent(QKeyEvent *);
212

con's avatar
con committed
213 214
    TextEditor::BaseTextEditorEditable *createEditableInterface();

215 216
    // These override BaseTextEditor
    bool isElectricCharacter(const QChar &ch) const;
217 218
    QString autoComplete(QTextCursor &cursor, const QString &text) const;
    bool autoBackspace(QTextCursor &cursor);
219
    int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor);
220

221 222
    bool contextAllowsAutoParentheses(const QTextCursor &cursor,
                                      const QString &textToInsert = QString()) const;
con's avatar
con committed
223

224 225
    bool isInComment(const QTextCursor &cursor) const;

Roberto Raggi's avatar
Roberto Raggi committed
226
private Q_SLOTS:
con's avatar
con committed
227 228 229
    void updateFileName();
    void jumpToMethod(int index);
    void updateMethodBoxIndex();
Roberto Raggi's avatar
Roberto Raggi committed
230
    void updateMethodBoxIndexNow();
231
    void updateMethodBoxToolTip();
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
232 233
    void updateUses();
    void updateUsesNow();
con's avatar
con committed
234
    void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
235
    void reformatDocument();
236
    void onContentsChanged(int position, int charsRemoved, int charsAdded);
con's avatar
con committed
237

Roberto Raggi's avatar
Roberto Raggi committed
238 239 240
    void semanticRehighlight();
    void updateSemanticInfo(const SemanticInfo &semanticInfo);

con's avatar
con committed
241
private:
242
    bool sortedMethodOverview() const;
con's avatar
con committed
243 244 245
    CPlusPlus::Symbol *findDefinition(CPlusPlus::Symbol *symbol);
    virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);

246 247 248
    TextEditor::ITextEditor *openCppEditorAt(const QString &fileName, int line,
                                             int column = 0);

con's avatar
con committed
249 250 251 252
    int previousBlockState(QTextBlock block) const;
    QTextCursor moveToPreviousToken(QTextCursor::MoveMode mode) const;
    QTextCursor moveToNextToken(QTextCursor::MoveMode mode) const;

Roberto Raggi's avatar
Roberto Raggi committed
253 254
    SemanticHighlighter::Source currentSource();

255 256 257
    void highlightUses(const QList<SemanticInfo::Use> &uses,
                       QList<QTextEdit::ExtraSelection> *selections);

con's avatar
con committed
258 259
    void createToolBar(CPPEditorEditable *editable);

260 261 262 263 264 265 266 267 268
    enum EditOperation {
        DeleteChar,
        DeletePreviousChar,
        InsertText
    };
    void inAllRenameSelections(EditOperation operation,
                               const QTextEdit::ExtraSelection &currentRenameSelection,
                               QTextCursor cursor,
                               const QString &text = QString());
269 270
    void abortRename();

271 272
    Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
    bool openLink(const Link &link) { return openCppEditorAt(link); }
273
    bool openCppEditorAt(const Link &);
274

275
    static Link linkToSymbol(CPlusPlus::Symbol *symbol);
con's avatar
con committed
276 277 278 279 280 281

    CppTools::CppModelManagerInterface *m_modelManager;

    QList<int> m_contexts;
    QComboBox *m_methodCombo;
    CPlusPlus::OverviewModel *m_overviewModel;
282 283
    QSortFilterProxyModel *m_proxyModel;
    QAction *m_sortAction;
Roberto Raggi's avatar
Roberto Raggi committed
284
    QTimer *m_updateMethodBoxTimer;
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
285
    QTimer *m_updateUsesTimer;
286
    QTextCharFormat m_occurrencesFormat;
Roberto Raggi's avatar
Roberto Raggi committed
287
    QTextCharFormat m_occurrencesUnusedFormat;
288
    QTextCharFormat m_occurrenceRenameFormat;
Thorbjørn Lindeijer's avatar
Thorbjørn Lindeijer committed
289 290 291

    QList<QTextEdit::ExtraSelection> m_renameSelections;
    int m_currentRenameSelection;
292
    bool m_inRename;
Roberto Raggi's avatar
Roberto Raggi committed
293

294 295
    mutable bool m_allowSkippingOfBlockEnd;

Roberto Raggi's avatar
Roberto Raggi committed
296
    SemanticHighlighter *m_semanticHighlighter;
Roberto Raggi's avatar
Roberto Raggi committed
297
    SemanticInfo m_lastSemanticInfo;
con's avatar
con committed
298 299
};

Roberto Raggi's avatar
Roberto Raggi committed
300

con's avatar
con committed
301 302 303 304
} // namespace Internal
} // namespace CppEditor

#endif // CPPEDITOR_H