CppEditor: remove dependencies between different outline views

Change-Id: If371811ac236c971d21815ef8738df5a169865e3
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-08-17 13:26:49 +02:00
parent 7c7fdf6460
commit 33001a866f
8 changed files with 84 additions and 77 deletions

View File

@@ -140,18 +140,6 @@ bool CppEditorOutline::isSorted() const
return m_proxyModel->sortColumn() == 0;
}
QModelIndex CppEditorOutline::modelIndex()
{
if (!m_modelIndex.isValid()) {
int line = 0, column = 0;
m_editorWidget->convertPosition(m_editorWidget->position(), &line, &column);
m_modelIndex = indexForPosition(line, column);
emit modelIndexChanged(m_modelIndex);
}
return m_modelIndex;
}
QWidget *CppEditorOutline::widget() const
{
return m_combo;
@@ -184,8 +172,9 @@ void CppEditorOutline::updateIndexNow()
m_updateIndexTimer->stop();
m_modelIndex = QModelIndex(); //invalidate
QModelIndex comboIndex = modelIndex();
int line = 0, column = 0;
m_editorWidget->convertPosition(m_editorWidget->position(), &line, &column);
QModelIndex comboIndex = m_model->indexForPosition(line, column);
if (comboIndex.isValid()) {
QSignalBlocker blocker(m_combo);
@@ -214,41 +203,6 @@ void CppEditorOutline::gotoSymbolInEditor()
emit m_editorWidget->activateEditor();
}
static bool contains(const OverviewModel::Range &range, int line, int column)
{
if (line < range.first.line || line > range.second.line)
return false;
if (line == range.first.line && column < range.first.column)
return false;
if (line == range.second.line && column > range.second.column)
return false;
return true;
}
QModelIndex CppEditorOutline::indexForPosition(int line, int column,
const QModelIndex &rootIndex) const
{
QModelIndex lastIndex = rootIndex;
const int rowCount = m_model->rowCount(rootIndex);
for (int row = 0; row < rowCount; ++row) {
const QModelIndex index = m_model->index(row, 0, rootIndex);
const OverviewModel::Range range = m_model->rangeFromIndex(index);
if (range.first.line > line)
break;
// Skip ranges that do not include current line and column.
if (range.second != range.first && !contains(range, line, column))
continue;
lastIndex = index;
}
if (lastIndex != rootIndex) {
// recurse
lastIndex = indexForPosition(line, column, lastIndex);
}
return lastIndex;
}
} // namespace CppEditor::Internal
#include <cppeditoroutline.moc>

View File

@@ -53,13 +53,8 @@ class CppEditorOutline : public QObject
public:
explicit CppEditorOutline(CppEditorWidget *editorWidget);
QModelIndex modelIndex();
QWidget *widget() const; // Must be deleted by client.
signals:
void modelIndexChanged(const QModelIndex &index);
public slots:
void updateIndex();
@@ -72,8 +67,6 @@ private:
CppEditorOutline();
bool isSorted() const;
QModelIndex indexForPosition(int line, int column,
const QModelIndex &rootIndex = QModelIndex()) const;
OverviewModel *m_model = nullptr; // Not owned
@@ -81,7 +74,6 @@ private:
Utils::TreeViewComboBox *m_combo = nullptr; // Not owned
QSortFilterProxyModel *m_proxyModel = nullptr;
QModelIndex m_modelIndex;
QAction *m_sortAction = nullptr;
QTimer *m_updateIndexTimer = nullptr;
};

View File

@@ -597,11 +597,6 @@ CppEditorDocument *CppEditorWidget::cppEditorDocument() const
return d->m_cppEditorDocument;
}
CppEditorOutline *CppEditorWidget::outline() const
{
return d->m_cppEditorOutline;
}
void CppEditorWidget::paste()
{
if (d->m_localRenaming.handlePaste())

View File

@@ -57,7 +57,6 @@ public:
~CppEditorWidget() override;
Internal::CppEditorDocument *cppEditorDocument() const;
Internal::CppEditorOutline *outline() const;
bool isSemanticInfoValidExceptLocalUses() const;
bool isSemanticInfoValid() const;

View File

@@ -99,13 +99,13 @@ Qt::DropActions CppOutlineFilterModel::supportedDragActions() const
CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) :
m_editor(editor),
m_treeView(new CppOutlineTreeView(this)),
m_model(&m_editor->cppEditorDocument()->outlineModel()),
m_proxyModel(new CppOutlineFilterModel(*m_model, this)),
m_enableCursorSync(true),
m_blockCursorSync(false),
m_sorted(false)
{
OverviewModel *model = &m_editor->cppEditorDocument()->outlineModel();
m_proxyModel = new CppOutlineFilterModel(*model, this);
m_proxyModel->setSourceModel(model);
m_proxyModel->setSourceModel(m_model);
auto *layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
@@ -117,13 +117,19 @@ CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) :
m_treeView->setSortingEnabled(true);
setFocusProxy(m_treeView);
connect(model, &QAbstractItemModel::modelReset, this, &CppOutlineWidget::modelUpdated);
connect(m_model, &QAbstractItemModel::modelReset, this, &CppOutlineWidget::modelUpdated);
modelUpdated();
connect(m_editor->outline(), &CppEditorOutline::modelIndexChanged,
this, &CppOutlineWidget::updateSelectionInTree);
connect(m_treeView, &QAbstractItemView::activated,
this, &CppOutlineWidget::onItemActivated);
connect(editor, &QPlainTextEdit::cursorPositionChanged, this, [this] {
if (m_model->rootItem()->hasChildren())
updateIndex();
});
m_updateIndexTimer.setSingleShot(true);
m_updateIndexTimer.setInterval(500);
connect(&m_updateIndexTimer, &QTimer::timeout, this, &CppOutlineWidget::updateIndexNow);
}
QList<QAction*> CppOutlineWidget::filterMenuActions() const
@@ -135,7 +141,7 @@ void CppOutlineWidget::setCursorSynchronization(bool syncWithCursor)
{
m_enableCursorSync = syncWithCursor;
if (m_enableCursorSync)
updateSelectionInTree(m_editor->outline()->modelIndex());
updateIndexNow();
}
bool CppOutlineWidget::isSorted() const
@@ -164,17 +170,37 @@ void CppOutlineWidget::modelUpdated()
m_treeView->expandAll();
}
void CppOutlineWidget::updateSelectionInTree(const QModelIndex &index)
void CppOutlineWidget::updateIndex()
{
m_updateIndexTimer.start();
}
void CppOutlineWidget::updateIndexNow()
{
if (!syncCursor())
return;
QModelIndex proxyIndex = m_proxyModel->mapFromSource(index);
const auto revision = static_cast<unsigned>(m_editor->document()->revision());
if (m_model->editorRevision() != revision) {
m_editor->cppEditorDocument()->updateOutline();
m_updateIndexTimer.start();
return;
}
m_updateIndexTimer.stop();
int line = 0, column = 0;
m_editor->convertPosition(m_editor->position(), &line, &column);
QModelIndex index = m_model->indexForPosition(line, column);
if (index.isValid()) {
m_blockCursorSync = true;
QModelIndex proxyIndex = m_proxyModel->mapFromSource(index);
m_treeView->setCurrentIndex(proxyIndex);
m_treeView->scrollTo(proxyIndex);
m_blockCursorSync = false;
}
m_blockCursorSync = true;
m_treeView->setCurrentIndex(proxyIndex);
m_treeView->scrollTo(proxyIndex);
m_blockCursorSync = false;
}
void CppOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)

View File

@@ -33,6 +33,7 @@
#include <utils/navigationtreeview.h>
#include <QSortFilterProxyModel>
#include <QTimer>
namespace CppEditor {
namespace Internal {
@@ -75,7 +76,8 @@ public:
QVariantMap settings() const override;
private:
void modelUpdated();
void updateSelectionInTree(const QModelIndex &index);
void updateIndex();
void updateIndexNow();
void updateTextCursor(const QModelIndex &index);
void onItemActivated(const QModelIndex &index);
bool syncCursor();
@@ -83,7 +85,9 @@ private:
private:
CppEditorWidget *m_editor;
CppOutlineTreeView *m_treeView;
OverviewModel * const m_model;
QSortFilterProxyModel *m_proxyModel;
QTimer m_updateIndexTimer;
bool m_enableCursorSync;
bool m_blockCursorSync;

View File

@@ -290,4 +290,39 @@ void OverviewModel::buildTree(SymbolItem *root, bool isRoot)
}
}
static bool contains(const OverviewModel::Range &range, int line, int column)
{
if (line < range.first.line || line > range.second.line)
return false;
if (line == range.first.line && column < range.first.column)
return false;
if (line == range.second.line && column > range.second.column)
return false;
return true;
}
QModelIndex OverviewModel::indexForPosition(int line, int column,
const QModelIndex &rootIndex) const
{
QModelIndex lastIndex = rootIndex;
const int rowCount = this->rowCount(rootIndex);
for (int row = 0; row < rowCount; ++row) {
const QModelIndex index = this->index(row, 0, rootIndex);
const OverviewModel::Range range = rangeFromIndex(index);
if (range.first.line > line)
break;
// Skip ranges that do not include current line and column.
if (range.second != range.first && !contains(range, line, column))
continue;
lastIndex = index;
}
if (lastIndex != rootIndex) {
// recurse
lastIndex = indexForPosition(line, column, lastIndex);
}
return lastIndex;
}
} // namespace CppEditor::Internal

View File

@@ -70,6 +70,8 @@ public:
using Range = std::pair<Utils::LineColumn, Utils::LineColumn>;
Range rangeFromIndex(const QModelIndex &sourceIndex) const;
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = {}) const;
private:
void rebuild();
CPlusPlus::Symbol *symbolFromIndex(const QModelIndex &index) const;