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;
|
||||
}
|
||||
|
||||
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>
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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())
|
||||
|
@@ -57,7 +57,6 @@ public:
|
||||
~CppEditorWidget() override;
|
||||
|
||||
Internal::CppEditorDocument *cppEditorDocument() const;
|
||||
Internal::CppEditorOutline *outline() const;
|
||||
|
||||
bool isSemanticInfoValidExceptLocalUses() const;
|
||||
bool isSemanticInfoValid() const;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CppOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user