diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2013-04-17 10:58:20 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2013-04-26 12:47:06 +0200 |
commit | 0c27b276584691f05e3efc88c95014f5bb5c3fa6 (patch) | |
tree | af65cf9dc162e0579d721bf27875d01b41e406f0 /src/plugins/cpptools/cpptoolseditorsupport.h | |
parent | e8d59fb76f6c59d8a0dd1e9d6cbdcb4bcfb3c9f0 (diff) | |
download | qt-creator-0c27b276584691f05e3efc88c95014f5bb5c3fa6.tar.gz |
C++ Detach the CppEditor from code-model internals.
- Moved document update handling into CppTools.
- Moved semantic info calculation into CppTools.
- Moved semantic highlighting into CppTools.
Change-Id: I253861bf074a64b1f657f7a4a8e6583871b5285f
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Diffstat (limited to 'src/plugins/cpptools/cpptoolseditorsupport.h')
-rw-r--r-- | src/plugins/cpptools/cpptoolseditorsupport.h | 151 |
1 files changed, 121 insertions, 30 deletions
diff --git a/src/plugins/cpptools/cpptoolseditorsupport.h b/src/plugins/cpptools/cpptoolseditorsupport.h index b6e297abec..c36951c1b3 100644 --- a/src/plugins/cpptools/cpptoolseditorsupport.h +++ b/src/plugins/cpptools/cpptoolseditorsupport.h @@ -30,63 +30,154 @@ #ifndef CPPTOOLSEDITORSUPPORT_H #define CPPTOOLSEDITORSUPPORT_H +#include "cpphighlightingsupport.h" +#include "cppmodelmanager.h" +#include "cppsemanticinfo.h" + +#include <cplusplus/CppDocument.h> + +#include <QFuture> #include <QObject> #include <QPointer> -#include <QFuture> - -QT_BEGIN_NAMESPACE -class QTimer; -QT_END_NAMESPACE +#include <QTimer> namespace CPlusPlus { class AST; } namespace TextEditor { -class ITextEditor; +class BaseTextEditor; class ITextMark; } // namespace TextEditor namespace CppTools { -namespace Internal { -class CppModelManager; - -class CppEditorSupport: public QObject +/** + * \brief The CppEditorSupport class oversees the actions that happen when a C++ text editor updates + * its document. + * + * The following steps are taken: + * 1. the text editor fires a contentsChanged() signal that triggers updateDocument + * 2. update document will start a timer, or reset the timer if it was already running. This way + * subsequent updates (e.g. keypresses) get bunched together instead of running the subsequent + * actions for every key press + * 3. when the timer from step 2 fires, updateDocumentNow() is triggered. That tells the + * model-manager to update the CPlusPlus::Document by re-indexing it. + * 4. when the model-manager finishes, it fires a documentUpdated(CPlusPlus::Document::Ptr) signal, + * that is connected to onDocumentUpdated(CPlusPlus::Document::Ptr), which does 4 things: + * a) updates the ifdeffed-out blocks in the EditorUpdate + * b) calls setExtraDiagnostics with the diagnostics from the parser, which in turn calls + * onDiagnosticsChanged on the UI thread, and that schedules an editor update timer. When this + * timer fires, updateEditorNow() is called, which will apply the updates to the editor. + * c) a semantic-info recalculation is started in a future + * d) the documentUpdated() signal is emitted, which can be used by a widget to do things + * 5. semantic-info calculation from 4c is done by a future that calls recalculateSemanticInfoNow(), + * which emits semanticInfoUpdated() when it is finished. Editors can also listen in on this + * signal to do things like highlighting the local usages. + * 6. the semanticInfoUpdated() is connected to the startHighlighting() slot, which will start + * another future for doing the semantic highlighting. The highlighterStarted signal is emitted, + * with the highlighting future as a parameter, so editors can hook it up to a QFutureWatcher + * and get notifications. + * + * Both the semantic info calculation and the highlighting calculation will cancel an already running + * future. They will also check that the result of a previous step is not already outdated, meaning + * that they check the revision of the editor document to see if a user changed the document while + * the calculation was running. + */ +class CPPTOOLS_EXPORT CppEditorSupport: public QObject { Q_OBJECT public: - CppEditorSupport(CppModelManager *modelManager); + CppEditorSupport(Internal::CppModelManager *modelManager, TextEditor::BaseTextEditor *textEditor); virtual ~CppEditorSupport(); - TextEditor::ITextEditor *textEditor() const; - void setTextEditor(TextEditor::ITextEditor *textEditor); - - int updateDocumentInterval() const; - void setUpdateDocumentInterval(int updateDocumentInterval); + QString fileName() const; - QString contents(); + QString contents() const; unsigned editorRevision() const; -Q_SIGNALS: - void contentsChanged(); + void setExtraDiagnostics(const QString &key, + const QList<CPlusPlus::Document::DiagnosticMessage> &messages); + + /// Retrieve the semantic info, which will get recalculated on the current + /// thread if it is outdate. + SemanticInfo recalculateSemanticInfo(bool emitSignalWhenFinished = true); + + /// Recalculates the semantic info in a future, and will emit the semanticInfoUpdated() signal + /// when finished. + /// \param force do not check if the old semantic info is still valid + void recalculateSemanticInfoDetached(bool force = false); -private Q_SLOTS: +signals: + void documentUpdated(); + void diagnosticsChanged(); + void semanticInfoUpdated(CppTools::SemanticInfo); + void highlighterStarted(QFuture<TextEditor::HighlightingResult>, unsigned revision); + +private slots: void updateDocument(); void updateDocumentNow(); + void onDocumentUpdated(CPlusPlus::Document::Ptr doc); + void startHighlighting(); + + void onDiagnosticsChanged(); + + void updateEditor(); + void updateEditorNow(); + +private: + typedef TextEditor::BaseTextEditorWidget::BlockRange BlockRange; + struct EditorUpdates { + EditorUpdates() + : revision(-1) + {} + int revision; + QList<QTextEdit::ExtraSelection> selections; + QList<BlockRange> ifdefedOutBlocks; + }; + + enum { + UpdateDocumentDefaultInterval = 150, + UpdateEditorInterval = 300 + }; + +private: + SemanticInfo::Source currentSource(bool force); + void recalculateSemanticInfoNow(const SemanticInfo::Source &source, bool emitSignalWhenFinished, + CPlusPlus::TopLevelDeclarationProcessor *processor = 0); + void recalculateSemanticInfoDetached_helper(QFutureInterface<void> &future, + SemanticInfo::Source source); + private: - enum { UPDATE_DOCUMENT_DEFAULT_INTERVAL = 150 }; - - CppModelManager *_modelManager; - QPointer<TextEditor::ITextEditor> _textEditor; - QTimer *_updateDocumentTimer; - int _updateDocumentInterval; - unsigned _revision; - QFuture<void> _documentParser; - QString _cachedContents; + Internal::CppModelManager *m_modelManager; + QPointer<TextEditor::BaseTextEditor> m_textEditor; + QTimer *m_updateDocumentTimer; + int m_updateDocumentInterval; + unsigned m_revision; + QFuture<void> m_documentParser; + + // content caching + mutable QString m_cachedContents; + mutable int m_cachedContentsEditorRevision; + + QTimer *m_updateEditorTimer; + EditorUpdates m_editorUpdates; + + QMutex m_diagnosticsMutex; + QHash<QString, QList<CPlusPlus::Document::DiagnosticMessage> > m_allDiagnostics; + + // Semantic info: + bool m_initialized; + mutable QMutex m_lastSemanticInfoLock; + SemanticInfo m_lastSemanticInfo; + QFuture<void> m_futureSemanticInfo; + + // Highlighting: + unsigned m_lastHighlightRevision; + QFuture<TextEditor::HighlightingResult> m_highlighter; + QScopedPointer<CppTools::CppHighlightingSupport> m_highlightingSupport; }; -} // namespace Internal } // namespace CppTools #endif // CPPTOOLSEDITORSUPPORT_H |