qmljseditor.h 6.92 KB
Newer Older
1
2
3
4
5
6
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**
** Commercial Usage
**
** 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.
**
** GNU Lesser General Public License Usage
**
** 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.
**
** 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.
27
28
29
**
**************************************************************************/

30
31
#ifndef QMLJSEDITOR_H
#define QMLJSEDITOR_H
32

33
34
#include <qmljs/qmljsdocument.h>
#include <qmljs/qmljsscanner.h>
35
#include <texteditor/basetexteditor.h>
36

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

41
42
43
44
45
46
QT_BEGIN_NAMESPACE
class QComboBox;
class QTimer;
QT_END_NAMESPACE

namespace Core {
47
class ICore;
48
49
}

50
namespace QmlJSEditor {
51

Roberto Raggi's avatar
Roberto Raggi committed
52
class ModelManagerInterface;
53

54
55
namespace Internal {

56
class Highlighter;
57
class QmlJSTextEditor;
58

59
class QmlJSEditorEditable : public TextEditor::BaseTextEditorEditable
60
{
61
    Q_OBJECT
62

63
public:
64
    QmlJSEditorEditable(QmlJSTextEditor *);
65
    QList<int> context() const;
66

67
68
    bool duplicateSupported() const { return true; }
    Core::IEditor *duplicate(QWidget *parent);
69
    QString id() const;
70
    bool isTemporary() const { return false; }
71
    virtual bool open(const QString & fileName);
72
73

private:
74
    QList<int> m_context;
75
76
77
78
79
};


struct Declaration
{
80
81
82
83
84
85
86
87
88
89
90
91
    QString text;
    int startLine;
    int startColumn;
    int endLine;
    int endColumn;

    Declaration()
        : startLine(0),
        startColumn(0),
        endLine(0),
        endColumn(0)
    { }
92
93
};

94
95
96
97
98
99
class Range
{
public:
    Range(): ast(0) {}

public: // attributes
100
    QmlJS::AST::Node *ast;
101
102
103
104
105
106
107
108
109
    QTextCursor begin;
    QTextCursor end;
};

class SemanticInfo
{
public:
    SemanticInfo() {}

110
111
    int revision() const;

112
    // Returns the declaring member
113
    QmlJS::AST::Node *declaringMember(int cursorPosition) const;
114

115
116
117
    // Returns the AST node under cursor
    QmlJS::AST::Node *nodeUnderCursor(int cursorPosition) const;

118
119
120
    // Returns the list of nodes that enclose the given position.
    QList<QmlJS::AST::Node *> astPath(int cursorPosition) const;

121
122
public: // attributes
    QmlJS::Document::Ptr document;
123
    QmlJS::Snapshot snapshot;
124
    QList<Range> ranges;
125
    QHash<QString, QList<QmlJS::AST::SourceLocation> > idLocations;
126
    QList<Declaration> declarations;
Christian Kamm's avatar
Christian Kamm committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

    // these are in addition to the parser messages in the document
    QList<QmlJS::DiagnosticMessage> semanticMessages;
};

class SemanticHighlighter: public QThread
{
    Q_OBJECT

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

    void abort();

    struct Source
    {
        QmlJS::Snapshot snapshot;
        QString fileName;
        QString code;
        int line;
        int column;
        int revision;
        bool force;

        Source()
            : line(0), column(0), revision(0), force(false)
        { }

        Source(const QmlJS::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), force(false)
        { }

        void clear()
        {
            snapshot = QmlJS::Snapshot();
            fileName.clear();
            code.clear();
            line = 0;
            column = 0;
            revision = 0;
            force = false;
        }
    };

    void rehighlight(const Source &source);

Q_SIGNALS:
181
    void changed(const QmlJSEditor::Internal::SemanticInfo &semanticInfo);
Christian Kamm's avatar
Christian Kamm committed
182
183
184
185
186
187
188
189
190
191
192
193
194
195

protected:
    virtual void run();

private:
    bool isOutdated();
    SemanticInfo semanticInfo(const Source &source);

private:
    QMutex m_mutex;
    QWaitCondition m_condition;
    bool m_done;
    Source m_source;
    SemanticInfo m_lastSemanticInfo;
196
197
};

198
class QmlJSTextEditor : public TextEditor::BaseTextEditor
199
{
200
    Q_OBJECT
201
202

public:
203
    typedef QList<int> Context;
204

205
206
    QmlJSTextEditor(QWidget *parent = 0);
    ~QmlJSTextEditor();
207

208
    virtual void unCommentSelection();
209

210
211
    SemanticInfo semanticInfo() const;
    int documentRevision() const;
212

213
public slots:
214
    void followSymbolUnderCursor();
215
    virtual void setFontSettings(const TextEditor::FontSettings &);
216
217

private slots:
218
    void onDocumentUpdated(QmlJS::Document::Ptr doc);
219

220
221
222
223
224
225
    void updateDocument();
    void updateDocumentNow();
    void jumpToMethod(int index);
    void updateMethodBoxIndex();
    void updateMethodBoxToolTip();
    void updateFileName();
226

227
228
229
    void updateUses();
    void updateUsesNow();

230
231
    // refactoring ops
    void renameIdUnderCursor();
Roberto Raggi's avatar
Roberto Raggi committed
232

Christian Kamm's avatar
Christian Kamm committed
233
    void semanticRehighlight();
234
    void updateSemanticInfo(const QmlJSEditor::Internal::SemanticInfo &semanticInfo);
Christian Kamm's avatar
Christian Kamm committed
235

236
protected:
237
238
    void contextMenuEvent(QContextMenuEvent *e);
    TextEditor::BaseTextEditorEditable *createEditableInterface();
239
    void createToolBar(QmlJSEditorEditable *editable);
240
    TextEditor::BaseTextEditor::Link findLinkAt(const QTextCursor &cursor, bool resolveTarget = true);
241

242
243
244
245
246
247
    //// brace matching
    virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
    virtual bool isInComment(const QTextCursor &cursor) const;
    virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text, const QChar &la, int *skippedChars) const;
    virtual QString insertParagraphSeparator(const QTextCursor &tc) const;

248
private:
249
250
    virtual bool isElectricCharacter(const QChar &ch) const;
    virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);
251
    bool isClosingBrace(const QList<QmlJS::Token> &tokens) const;
252

253
    QString wordUnderCursor() const;
Roberto Raggi's avatar
Roberto Raggi committed
254

Christian Kamm's avatar
Christian Kamm committed
255
256
    SemanticHighlighter::Source currentSource(bool force = false);

257
    const Context m_context;
258

259
    QTimer *m_updateDocumentTimer;
260
    QTimer *m_updateUsesTimer;
261
    QComboBox *m_methodCombo;
Roberto Raggi's avatar
Roberto Raggi committed
262
    ModelManagerInterface *m_modelManager;
263
    QTextCharFormat m_occurrencesFormat;
264
265
    QTextCharFormat m_occurrencesUnusedFormat;
    QTextCharFormat m_occurrenceRenameFormat;
266

Christian Kamm's avatar
Christian Kamm committed
267
    SemanticHighlighter *m_semanticHighlighter;
268
    SemanticInfo m_semanticInfo;
269
270
271
};

} // namespace Internal
272
} // namespace QmlJSEditor
273

274
#endif // QMLJSEDITOR_H