diff options
author | David Schulz <david.schulz@qt.io> | 2022-08-15 13:06:12 +0200 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2022-08-18 06:20:10 +0000 |
commit | 5b3b1a60a1902762ad1788dbd20a21348da4e822 (patch) | |
tree | 08cb62f5280be750c7ef206ff81bf377650ca7bc | |
parent | 4a796239594f905644b3459ff93b804d473aa443 (diff) |
CppEditor: move outline model to document
This way we only have one model per document instead of one per editor.
Additionally we further separate the outline views (combobox and side
pane) from the actual model.
Change-Id: I9705716b5c9f8f19f75708ec73d7c3b3c5de586f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | src/plugins/cppeditor/cppeditordocument.cpp | 20 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditordocument.h | 7 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditoroutline.cpp | 45 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditoroutline.h | 28 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorwidget.cpp | 16 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorwidget.h | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppoutline.cpp | 7 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppoverviewmodel.cpp | 54 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppoverviewmodel.h | 16 |
9 files changed, 95 insertions, 100 deletions
diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index 2b01b86c27..cce259c2d8 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -393,6 +393,19 @@ ParseContextModel &CppEditorDocument::parseContextModel() return m_parseContextModel; } +OverviewModel &CppEditorDocument::outlineModel() +{ + return m_overviewModel; +} + +void CppEditorDocument::updateOutline() +{ + CPlusPlus::Document::Ptr document; + if (!usesClangd()) + document = CppModelManager::instance()->snapshot().document(filePath()); + m_overviewModel.update(document); +} + QFuture<CursorInfo> CppEditorDocument::cursorInfo(const CursorInfoParams ¶ms) { return processor()->cursorInfo(params); @@ -426,6 +439,8 @@ BaseEditorDocumentProcessor *CppEditorDocument::processor() auto *highlighter = qobject_cast<CppHighlighter *>(syntaxHighlighter()); highlighter->setLanguageFeatures(document->languageFeatures()); + m_overviewModel.update(usesClangd() ? nullptr : document); + // Forward signal emit cppDocumentUpdated(document); @@ -488,6 +503,11 @@ bool CppEditorDocument::save(QString *errorString, const FilePath &filePath, boo return TextEditor::TextDocument::save(errorString, filePath, autoSave); } +bool CppEditorDocument::usesClangd() const +{ + return CppModelManager::usesClangd(this); +} + void CppEditorDocument::onDiagnosticsChanged(const QString &fileName, const QString &kind) { if (FilePath::fromString(fileName) != filePath()) diff --git a/src/plugins/cppeditor/cppeditordocument.h b/src/plugins/cppeditor/cppeditordocument.h index 09d5ab96b6..3d6dcc2f6a 100644 --- a/src/plugins/cppeditor/cppeditordocument.h +++ b/src/plugins/cppeditor/cppeditordocument.h @@ -27,7 +27,7 @@ #include "baseeditordocumentprocessor.h" #include "cppcompletionassistprovider.h" -#include "cppmodelmanager.h" +#include "cppoverviewmodel.h" #include "cppparsecontext.h" #include "cppsemanticinfo.h" #include "editordocumenthandle.h" @@ -63,6 +63,8 @@ public: void scheduleProcessDocument(); ParseContextModel &parseContextModel(); + OverviewModel &outlineModel(); + void updateOutline(); QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms); TextEditor::TabSettings tabSettings() const override; @@ -71,6 +73,8 @@ public: const Utils::FilePath &filePath = Utils::FilePath(), bool autoSave = false) override; + bool usesClangd() const; + signals: void codeWarningsUpdated(unsigned contentsRevision, const QList<QTextEdit::ExtraSelection> selections, @@ -133,6 +137,7 @@ private: QScopedPointer<CppEditorDocumentHandle> m_editorDocumentHandle; ParseContextModel m_parseContextModel; + OverviewModel m_overviewModel; }; } // namespace Internal diff --git a/src/plugins/cppeditor/cppeditoroutline.cpp b/src/plugins/cppeditor/cppeditoroutline.cpp index 958ac01a7a..f2d0c7b0d6 100644 --- a/src/plugins/cppeditor/cppeditoroutline.cpp +++ b/src/plugins/cppeditor/cppeditoroutline.cpp @@ -24,9 +24,11 @@ ****************************************************************************/ #include "cppeditoroutline.h" + +#include "cppeditordocument.h" +#include "cppeditorwidget.h" #include "cppmodelmanager.h" #include "cppoverviewmodel.h" -#include "cpptoolsreuse.h" #include "cpptoolssettings.h" #include <texteditor/texteditor.h> @@ -89,14 +91,14 @@ QTimer *newSingleShotTimer(QObject *parent, int msInternal, const QString &objec namespace CppEditor::Internal { -CppEditorOutline::CppEditorOutline(TextEditor::TextEditorWidget *editorWidget) +CppEditorOutline::CppEditorOutline(CppEditorWidget *editorWidget) : QObject(editorWidget) , m_editorWidget(editorWidget) , m_combo(new Utils::TreeViewComboBox) { - m_model = std::make_unique<OverviewModel>(); + m_model = &editorWidget->cppEditorDocument()->outlineModel(); m_proxyModel = new OverviewProxyModel(*m_model, this); - m_proxyModel->setSourceModel(m_model.get()); + m_proxyModel->setSourceModel(m_model); // Set up proxy model if (CppToolsSettings::instance()->sortedEditorDocumentOutline()) @@ -126,33 +128,18 @@ CppEditorOutline::CppEditorOutline(TextEditor::TextEditorWidget *editorWidget) connect(m_combo, &QComboBox::activated, this, &CppEditorOutline::gotoSymbolInEditor); connect(m_combo, &QComboBox::currentIndexChanged, this, &CppEditorOutline::updateToolTip); + connect(m_model, &OverviewModel::modelReset, this, &CppEditorOutline::updateNow); // Set up timers - m_updateTimer = newSingleShotTimer(this, UpdateOutlineIntervalInMs, - QLatin1String("CppEditorOutline::m_updateTimer")); - connect(m_updateTimer, &QTimer::timeout, this, &CppEditorOutline::updateNow); - connect(m_model.get(), &OverviewModel::needsUpdate, this, - &CppEditorOutline::updateNow); - m_updateIndexTimer = newSingleShotTimer(this, UpdateOutlineIntervalInMs, QLatin1String("CppEditorOutline::m_updateIndexTimer")); connect(m_updateIndexTimer, &QTimer::timeout, this, &CppEditorOutline::updateIndexNow); } -void CppEditorOutline::update() -{ - m_updateTimer->start(); -} - bool CppEditorOutline::isSorted() const { return m_proxyModel->sortColumn() == 0; } -OverviewModel *CppEditorOutline::model() const -{ - return m_model.get(); -} - QModelIndex CppEditorOutline::modelIndex() { if (!m_modelIndex.isValid()) { @@ -178,19 +165,6 @@ QSharedPointer<CPlusPlus::Document> getDocument(const QString &filePath) void CppEditorOutline::updateNow() { - const QString filePath = m_editorWidget->textDocument()->filePath().toString(); - m_document = getDocument(filePath); - if (!m_document) - return; - - if (m_document->editorRevision() - != static_cast<unsigned>(m_editorWidget->document()->revision())) { - m_updateTimer->start(); - return; - } - - m_model->rebuild(m_document); - m_combo->view()->expandAll(); updateIndexNow(); } @@ -202,11 +176,8 @@ void CppEditorOutline::updateIndex() void CppEditorOutline::updateIndexNow() { - if (!m_document) - return; - const auto revision = static_cast<unsigned>(m_editorWidget->document()->revision()); - if (m_document->editorRevision() != revision) { + if (m_model->editorRevision() != revision) { m_updateIndexTimer->start(); return; } diff --git a/src/plugins/cppeditor/cppeditoroutline.h b/src/plugins/cppeditor/cppeditoroutline.h index 59870bb656..d1461075d3 100644 --- a/src/plugins/cppeditor/cppeditoroutline.h +++ b/src/plugins/cppeditor/cppeditoroutline.h @@ -41,18 +41,18 @@ QT_END_NAMESPACE namespace TextEditor { class TextEditorWidget; } namespace Utils { class TreeViewComboBox; } -namespace CppEditor::Internal { +namespace CppEditor { +class CppEditorWidget; + +namespace Internal { class CppEditorOutline : public QObject { Q_OBJECT public: - explicit CppEditorOutline(TextEditor::TextEditorWidget *editorWidget); - - void update(); + explicit CppEditorOutline(CppEditorWidget *editorWidget); - OverviewModel *model() const; QModelIndex modelIndex(); QWidget *widget() const; // Must be deleted by client. @@ -75,18 +75,16 @@ private: QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()) const; -private: - QSharedPointer<CPlusPlus::Document> m_document; - std::unique_ptr<OverviewModel> m_model; + OverviewModel *m_model = nullptr; // Not owned - TextEditor::TextEditorWidget *m_editorWidget; + CppEditorWidget *m_editorWidget = nullptr; - Utils::TreeViewComboBox *m_combo; // Not owned - QSortFilterProxyModel *m_proxyModel; + Utils::TreeViewComboBox *m_combo = nullptr; // Not owned + QSortFilterProxyModel *m_proxyModel = nullptr; QModelIndex m_modelIndex; - QAction *m_sortAction; - QTimer *m_updateTimer; - QTimer *m_updateIndexTimer; + QAction *m_sortAction = nullptr; + QTimer *m_updateIndexTimer = nullptr; }; -} // namespace CppEditor::Internal +} // namespace Internal +} // namespace CppEditor diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 15a0695d3c..214edaad5a 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -462,8 +462,6 @@ void CppEditorWidget::finalizeInitialization() this, &CppEditorWidget::onCodeWarningsUpdated); connect(d->m_cppEditorDocument, &CppEditorDocument::ifdefedOutBlocksUpdated, this, &CppEditorWidget::onIfdefedOutBlocksUpdated); - connect(d->m_cppEditorDocument, &CppEditorDocument::cppDocumentUpdated, - this, &CppEditorWidget::onCppDocumentUpdated); connect(d->m_cppEditorDocument, &CppEditorDocument::semanticInfoUpdated, this, [this](const SemanticInfo &info) { updateSemanticInfo(info); }); @@ -552,10 +550,8 @@ void CppEditorWidget::finalizeInitialization() d->m_outlineTimer.setSingleShot(true); connect(&d->m_outlineTimer, &QTimer::timeout, this, [this] { d->m_outlineAction->setVisible(d->shouldOfferOutline()); - if (d->m_outlineAction->isVisible()) { - d->m_cppEditorOutline->update(); - d->m_cppEditorOutline->updateIndex(); - } + if (d->m_outlineAction->isVisible()) + d->m_cppEditorDocument->updateOutline(); }); connect(&ClangdSettings::instance(), &ClangdSettings::changed, &d->m_outlineTimer, qOverload<>(&QTimer::start)); @@ -571,8 +567,6 @@ void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *o if (cppEditorWidget->isSemanticInfoValidExceptLocalUses()) updateSemanticInfo(cppEditorWidget->semanticInfo()); - if (d->shouldOfferOutline()) - d->m_cppEditorOutline->update(); const Id selectionKind = CodeWarningsSelection; setExtraSelections(selectionKind, cppEditorWidget->extraSelections(selectionKind)); @@ -632,12 +626,6 @@ void CppEditorWidget::selectAll() TextEditorWidget::selectAll(); } -void CppEditorWidget::onCppDocumentUpdated() -{ - if (d->shouldOfferOutline()) - d->m_cppEditorOutline->update(); -} - void CppEditorWidget::onCodeWarningsUpdated(unsigned revision, const QList<QTextEdit::ExtraSelection> selections, const RefactorMarkers &refactorMarkers) diff --git a/src/plugins/cppeditor/cppeditorwidget.h b/src/plugins/cppeditor/cppeditorwidget.h index 5f76a40e69..c1670f1caa 100644 --- a/src/plugins/cppeditor/cppeditorwidget.h +++ b/src/plugins/cppeditor/cppeditorwidget.h @@ -128,8 +128,6 @@ private: void abortDeclDefLink(); void onFunctionDeclDefLinkFound(QSharedPointer<Internal::FunctionDeclDefLink> link); - void onCppDocumentUpdated(); - void onCodeWarningsUpdated(unsigned revision, const QList<QTextEdit::ExtraSelection> selections, const TextEditor::RefactorMarkers &refactorMarkers); diff --git a/src/plugins/cppeditor/cppoutline.cpp b/src/plugins/cppeditor/cppoutline.cpp index 30c86026a1..1e298d589f 100644 --- a/src/plugins/cppeditor/cppoutline.cpp +++ b/src/plugins/cppeditor/cppoutline.cpp @@ -26,6 +26,7 @@ #include "cppoutline.h" #include "cppeditoroutline.h" +#include "cppeditordocument.h" #include "cppmodelmanager.h" #include "cppoverviewmodel.h" @@ -102,7 +103,7 @@ CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) : m_blockCursorSync(false), m_sorted(false) { - OverviewModel *model = m_editor->outline()->model(); + OverviewModel *model = &m_editor->cppEditorDocument()->outlineModel(); m_proxyModel = new CppOutlineFilterModel(*model, this); m_proxyModel->setSourceModel(model); @@ -179,8 +180,8 @@ void CppOutlineWidget::updateSelectionInTree(const QModelIndex &index) void CppOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex) { QModelIndex index = m_proxyModel->mapToSource(proxyIndex); - OverviewModel *model = m_editor->outline()->model(); - Utils::LineColumn lineColumn = model->lineColumnFromIndex(index); + Utils::LineColumn lineColumn + = m_editor->cppEditorDocument()->outlineModel().lineColumnFromIndex(index); if (!lineColumn.isValid()) return; diff --git a/src/plugins/cppeditor/cppoverviewmodel.cpp b/src/plugins/cppeditor/cppoverviewmodel.cpp index 9e032ce922..3c49b151e8 100644 --- a/src/plugins/cppeditor/cppoverviewmodel.cpp +++ b/src/plugins/cppeditor/cppoverviewmodel.cpp @@ -64,7 +64,7 @@ public: switch (role) { case Qt::DisplayRole: { - QString name = overviewModel->_overview.prettyName(symbol->name()); + QString name = overviewModel->m_overview.prettyName(symbol->name()); if (name.isEmpty()) name = QLatin1String("anonymous"); if (symbol->asObjCForwardClassDeclaration()) @@ -79,7 +79,7 @@ public: name = QLatin1String("@implementation ") + name; if (clazz->isCategory()) { - name += QString(" (%1)").arg(overviewModel->_overview.prettyName( + name += QString(" (%1)").arg(overviewModel->m_overview.prettyName( clazz->categoryName())); } } @@ -92,7 +92,7 @@ public: QStringList parameters; parameters.reserve(t->templateParameterCount()); for (int i = 0; i < t->templateParameterCount(); ++i) { - parameters.append(overviewModel->_overview.prettyName( + parameters.append(overviewModel->m_overview.prettyName( t->templateParameterAt(i)->name())); } name += QString("<%1>").arg(parameters.join(QLatin1String(", "))); @@ -105,10 +105,10 @@ public: else name = QLatin1Char('-') + name; } else if (! symbl->asScope() || symbl->asFunction()) { - QString type = overviewModel->_overview.prettyType(symbl->type()); + QString type = overviewModel->m_overview.prettyType(symbl->type()); if (Function *f = symbl->type()->asFunctionType()) { name += type; - type = overviewModel->_overview.prettyType(f->returnType()); + type = overviewModel->m_overview.prettyType(f->returnType()); } if (! type.isEmpty()) name += QLatin1String(": ") + type; @@ -117,7 +117,7 @@ public: } case Qt::EditRole: { - QString name = overviewModel->_overview.prettyName(symbol->name()); + QString name = overviewModel->m_overview.prettyName(symbol->name()); if (name.isEmpty()) name = QLatin1String("anonymous"); return name; @@ -140,25 +140,16 @@ public: CPlusPlus::Symbol *symbol = nullptr; // not owned }; - - - - -bool OverviewModel::hasDocument() const -{ - return !_cppDocument.isNull(); -} - int OverviewModel::globalSymbolCount() const { int count = 0; - if (_cppDocument) - count += _cppDocument->globalSymbolCount(); + if (m_cppDocument) + count += m_cppDocument->globalSymbolCount(); return count; } Symbol *OverviewModel::globalSymbolAt(int index) const -{ return _cppDocument->globalSymbolAt(index); } +{ return m_cppDocument->globalSymbolAt(index); } Symbol *OverviewModel::symbolFromIndex(const QModelIndex &index) const { @@ -168,6 +159,15 @@ Symbol *OverviewModel::symbolFromIndex(const QModelIndex &index) const return item ? item->symbol : nullptr; } +OverviewModel::OverviewModel(QObject *parent) + : Utils::TreeModel<>(parent) +{ + m_updateTimer = new QTimer(this); + m_updateTimer->setSingleShot(true); + m_updateTimer->setInterval(500); + connect(m_updateTimer, &QTimer::timeout, this, &OverviewModel::rebuild); +} + Qt::ItemFlags OverviewModel::flags(const QModelIndex &index) const { if (!index.isValid()) @@ -202,12 +202,24 @@ QMimeData *OverviewModel::mimeData(const QModelIndexList &indexes) const return mimeData; } -void OverviewModel::rebuild(Document::Ptr doc) +void OverviewModel::update(CPlusPlus::Document::Ptr doc) +{ + m_cppDocument = doc; + if (doc) + m_updateTimer->start(); +} + +int OverviewModel::editorRevision() +{ + return m_cppDocument ? m_cppDocument->editorRevision() : 0; +} + +void OverviewModel::rebuild() { beginResetModel(); - _cppDocument = doc; auto root = new SymbolItem; - buildTree(root, true); + if (m_cppDocument) + buildTree(root, true); setRootItem(root); endResetModel(); } diff --git a/src/plugins/cppeditor/cppoverviewmodel.h b/src/plugins/cppeditor/cppoverviewmodel.h index 0ac9787c89..436901496b 100644 --- a/src/plugins/cppeditor/cppoverviewmodel.h +++ b/src/plugins/cppeditor/cppoverviewmodel.h @@ -48,6 +48,8 @@ class OverviewModel : public Utils::TreeModel<> Q_OBJECT public: + explicit OverviewModel(QObject *parent = nullptr); + enum Role { FileNameRole = Qt::UserRole + 1, LineNumberRole @@ -58,7 +60,9 @@ public: QStringList mimeTypes() const override; QMimeData *mimeData(const QModelIndexList &indexes) const override; - void rebuild(CPlusPlus::Document::Ptr doc); + void update(CPlusPlus::Document::Ptr doc); + + int editorRevision(); bool isGenerated(const QModelIndex &sourceIndex) const; Utils::Link linkFromIndex(const QModelIndex &sourceIndex) const; @@ -66,20 +70,18 @@ public: using Range = std::pair<Utils::LineColumn, Utils::LineColumn>; Range rangeFromIndex(const QModelIndex &sourceIndex) const; -signals: - void needsUpdate(); - private: + void rebuild(); CPlusPlus::Symbol *symbolFromIndex(const QModelIndex &index) const; - bool hasDocument() const; int globalSymbolCount() const; CPlusPlus::Symbol *globalSymbolAt(int index) const; void buildTree(SymbolItem *root, bool isRoot); private: - CPlusPlus::Document::Ptr _cppDocument; - CPlusPlus::Overview _overview; + CPlusPlus::Document::Ptr m_cppDocument; + CPlusPlus::Overview m_overview; friend class SymbolItem; + QTimer *m_updateTimer = nullptr; }; } // namespace CppEditor::Internal |