forked from qt-creator/qt-creator
CppEditor: remove dependencies between different outline views
Change-Id: If371811ac236c971d21815ef8738df5a169865e3 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -140,18 +140,6 @@ bool CppEditorOutline::isSorted() const
|
|||||||
return m_proxyModel->sortColumn() == 0;
|
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
|
QWidget *CppEditorOutline::widget() const
|
||||||
{
|
{
|
||||||
return m_combo;
|
return m_combo;
|
||||||
@@ -184,8 +172,9 @@ void CppEditorOutline::updateIndexNow()
|
|||||||
|
|
||||||
m_updateIndexTimer->stop();
|
m_updateIndexTimer->stop();
|
||||||
|
|
||||||
m_modelIndex = QModelIndex(); //invalidate
|
int line = 0, column = 0;
|
||||||
QModelIndex comboIndex = modelIndex();
|
m_editorWidget->convertPosition(m_editorWidget->position(), &line, &column);
|
||||||
|
QModelIndex comboIndex = m_model->indexForPosition(line, column);
|
||||||
|
|
||||||
if (comboIndex.isValid()) {
|
if (comboIndex.isValid()) {
|
||||||
QSignalBlocker blocker(m_combo);
|
QSignalBlocker blocker(m_combo);
|
||||||
@@ -214,41 +203,6 @@ void CppEditorOutline::gotoSymbolInEditor()
|
|||||||
emit m_editorWidget->activateEditor();
|
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
|
} // namespace CppEditor::Internal
|
||||||
|
|
||||||
#include <cppeditoroutline.moc>
|
#include <cppeditoroutline.moc>
|
||||||
|
@@ -53,13 +53,8 @@ class CppEditorOutline : public QObject
|
|||||||
public:
|
public:
|
||||||
explicit CppEditorOutline(CppEditorWidget *editorWidget);
|
explicit CppEditorOutline(CppEditorWidget *editorWidget);
|
||||||
|
|
||||||
QModelIndex modelIndex();
|
|
||||||
|
|
||||||
QWidget *widget() const; // Must be deleted by client.
|
QWidget *widget() const; // Must be deleted by client.
|
||||||
|
|
||||||
signals:
|
|
||||||
void modelIndexChanged(const QModelIndex &index);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateIndex();
|
void updateIndex();
|
||||||
|
|
||||||
@@ -72,8 +67,6 @@ private:
|
|||||||
CppEditorOutline();
|
CppEditorOutline();
|
||||||
|
|
||||||
bool isSorted() const;
|
bool isSorted() const;
|
||||||
QModelIndex indexForPosition(int line, int column,
|
|
||||||
const QModelIndex &rootIndex = QModelIndex()) const;
|
|
||||||
|
|
||||||
OverviewModel *m_model = nullptr; // Not owned
|
OverviewModel *m_model = nullptr; // Not owned
|
||||||
|
|
||||||
@@ -81,7 +74,6 @@ private:
|
|||||||
|
|
||||||
Utils::TreeViewComboBox *m_combo = nullptr; // Not owned
|
Utils::TreeViewComboBox *m_combo = nullptr; // Not owned
|
||||||
QSortFilterProxyModel *m_proxyModel = nullptr;
|
QSortFilterProxyModel *m_proxyModel = nullptr;
|
||||||
QModelIndex m_modelIndex;
|
|
||||||
QAction *m_sortAction = nullptr;
|
QAction *m_sortAction = nullptr;
|
||||||
QTimer *m_updateIndexTimer = nullptr;
|
QTimer *m_updateIndexTimer = nullptr;
|
||||||
};
|
};
|
||||||
|
@@ -597,11 +597,6 @@ CppEditorDocument *CppEditorWidget::cppEditorDocument() const
|
|||||||
return d->m_cppEditorDocument;
|
return d->m_cppEditorDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
CppEditorOutline *CppEditorWidget::outline() const
|
|
||||||
{
|
|
||||||
return d->m_cppEditorOutline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppEditorWidget::paste()
|
void CppEditorWidget::paste()
|
||||||
{
|
{
|
||||||
if (d->m_localRenaming.handlePaste())
|
if (d->m_localRenaming.handlePaste())
|
||||||
|
@@ -57,7 +57,6 @@ public:
|
|||||||
~CppEditorWidget() override;
|
~CppEditorWidget() override;
|
||||||
|
|
||||||
Internal::CppEditorDocument *cppEditorDocument() const;
|
Internal::CppEditorDocument *cppEditorDocument() const;
|
||||||
Internal::CppEditorOutline *outline() const;
|
|
||||||
|
|
||||||
bool isSemanticInfoValidExceptLocalUses() const;
|
bool isSemanticInfoValidExceptLocalUses() const;
|
||||||
bool isSemanticInfoValid() const;
|
bool isSemanticInfoValid() const;
|
||||||
|
@@ -99,13 +99,13 @@ Qt::DropActions CppOutlineFilterModel::supportedDragActions() const
|
|||||||
CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) :
|
CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) :
|
||||||
m_editor(editor),
|
m_editor(editor),
|
||||||
m_treeView(new CppOutlineTreeView(this)),
|
m_treeView(new CppOutlineTreeView(this)),
|
||||||
|
m_model(&m_editor->cppEditorDocument()->outlineModel()),
|
||||||
|
m_proxyModel(new CppOutlineFilterModel(*m_model, this)),
|
||||||
m_enableCursorSync(true),
|
m_enableCursorSync(true),
|
||||||
m_blockCursorSync(false),
|
m_blockCursorSync(false),
|
||||||
m_sorted(false)
|
m_sorted(false)
|
||||||
{
|
{
|
||||||
OverviewModel *model = &m_editor->cppEditorDocument()->outlineModel();
|
m_proxyModel->setSourceModel(m_model);
|
||||||
m_proxyModel = new CppOutlineFilterModel(*model, this);
|
|
||||||
m_proxyModel->setSourceModel(model);
|
|
||||||
|
|
||||||
auto *layout = new QVBoxLayout;
|
auto *layout = new QVBoxLayout;
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
@@ -117,13 +117,19 @@ CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) :
|
|||||||
m_treeView->setSortingEnabled(true);
|
m_treeView->setSortingEnabled(true);
|
||||||
setFocusProxy(m_treeView);
|
setFocusProxy(m_treeView);
|
||||||
|
|
||||||
connect(model, &QAbstractItemModel::modelReset, this, &CppOutlineWidget::modelUpdated);
|
connect(m_model, &QAbstractItemModel::modelReset, this, &CppOutlineWidget::modelUpdated);
|
||||||
modelUpdated();
|
modelUpdated();
|
||||||
|
|
||||||
connect(m_editor->outline(), &CppEditorOutline::modelIndexChanged,
|
|
||||||
this, &CppOutlineWidget::updateSelectionInTree);
|
|
||||||
connect(m_treeView, &QAbstractItemView::activated,
|
connect(m_treeView, &QAbstractItemView::activated,
|
||||||
this, &CppOutlineWidget::onItemActivated);
|
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
|
QList<QAction*> CppOutlineWidget::filterMenuActions() const
|
||||||
@@ -135,7 +141,7 @@ void CppOutlineWidget::setCursorSynchronization(bool syncWithCursor)
|
|||||||
{
|
{
|
||||||
m_enableCursorSync = syncWithCursor;
|
m_enableCursorSync = syncWithCursor;
|
||||||
if (m_enableCursorSync)
|
if (m_enableCursorSync)
|
||||||
updateSelectionInTree(m_editor->outline()->modelIndex());
|
updateIndexNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppOutlineWidget::isSorted() const
|
bool CppOutlineWidget::isSorted() const
|
||||||
@@ -164,17 +170,37 @@ void CppOutlineWidget::modelUpdated()
|
|||||||
m_treeView->expandAll();
|
m_treeView->expandAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppOutlineWidget::updateSelectionInTree(const QModelIndex &index)
|
void CppOutlineWidget::updateIndex()
|
||||||
|
{
|
||||||
|
m_updateIndexTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppOutlineWidget::updateIndexNow()
|
||||||
{
|
{
|
||||||
if (!syncCursor())
|
if (!syncCursor())
|
||||||
return;
|
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;
|
m_blockCursorSync = true;
|
||||||
|
QModelIndex proxyIndex = m_proxyModel->mapFromSource(index);
|
||||||
m_treeView->setCurrentIndex(proxyIndex);
|
m_treeView->setCurrentIndex(proxyIndex);
|
||||||
m_treeView->scrollTo(proxyIndex);
|
m_treeView->scrollTo(proxyIndex);
|
||||||
m_blockCursorSync = false;
|
m_blockCursorSync = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)
|
void CppOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include <utils/navigationtreeview.h>
|
#include <utils/navigationtreeview.h>
|
||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace CppEditor {
|
namespace CppEditor {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -75,7 +76,8 @@ public:
|
|||||||
QVariantMap settings() const override;
|
QVariantMap settings() const override;
|
||||||
private:
|
private:
|
||||||
void modelUpdated();
|
void modelUpdated();
|
||||||
void updateSelectionInTree(const QModelIndex &index);
|
void updateIndex();
|
||||||
|
void updateIndexNow();
|
||||||
void updateTextCursor(const QModelIndex &index);
|
void updateTextCursor(const QModelIndex &index);
|
||||||
void onItemActivated(const QModelIndex &index);
|
void onItemActivated(const QModelIndex &index);
|
||||||
bool syncCursor();
|
bool syncCursor();
|
||||||
@@ -83,7 +85,9 @@ private:
|
|||||||
private:
|
private:
|
||||||
CppEditorWidget *m_editor;
|
CppEditorWidget *m_editor;
|
||||||
CppOutlineTreeView *m_treeView;
|
CppOutlineTreeView *m_treeView;
|
||||||
|
OverviewModel * const m_model;
|
||||||
QSortFilterProxyModel *m_proxyModel;
|
QSortFilterProxyModel *m_proxyModel;
|
||||||
|
QTimer m_updateIndexTimer;
|
||||||
|
|
||||||
bool m_enableCursorSync;
|
bool m_enableCursorSync;
|
||||||
bool m_blockCursorSync;
|
bool m_blockCursorSync;
|
||||||
|
@@ -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
|
} // namespace CppEditor::Internal
|
||||||
|
@@ -70,6 +70,8 @@ public:
|
|||||||
using Range = std::pair<Utils::LineColumn, Utils::LineColumn>;
|
using Range = std::pair<Utils::LineColumn, Utils::LineColumn>;
|
||||||
Range rangeFromIndex(const QModelIndex &sourceIndex) const;
|
Range rangeFromIndex(const QModelIndex &sourceIndex) const;
|
||||||
|
|
||||||
|
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = {}) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void rebuild();
|
void rebuild();
|
||||||
CPlusPlus::Symbol *symbolFromIndex(const QModelIndex &index) const;
|
CPlusPlus::Symbol *symbolFromIndex(const QModelIndex &index) const;
|
||||||
|
Reference in New Issue
Block a user