diff --git a/src/libs/utils/linecolumn.h b/src/libs/utils/linecolumn.h index 003ba3ef342..1be72c281de 100644 --- a/src/libs/utils/linecolumn.h +++ b/src/libs/utils/linecolumn.h @@ -51,6 +51,11 @@ public: return first.isValid() && first.line == second.line && first.column == second.column; } + friend bool operator!=(LineColumn first, LineColumn second) + { + return !(first == second); + } + public: int line = -1; int column = -1; diff --git a/src/plugins/clangcodemodel/clangoverviewmodel.cpp b/src/plugins/clangcodemodel/clangoverviewmodel.cpp index 655005bc2c4..22a2576b716 100644 --- a/src/plugins/clangcodemodel/clangoverviewmodel.cpp +++ b/src/plugins/clangcodemodel/clangoverviewmodel.cpp @@ -213,10 +213,20 @@ bool OverviewModel::isGenerated(const QModelIndex &) const TokenTreeItem *item = static_cast(itemForIndex(sourceIndex)); if (!item) return {}; - ::Utils::LineColumn lineColumn; - lineColumn.line = static_cast(item->token.line); - lineColumn.column = static_cast(item->token.column); - return lineColumn; + return ::Utils::LineColumn(static_cast(item->token.line), + static_cast(item->token.column)); +} + +OverviewModel::Range OverviewModel::rangeFromIndex(const QModelIndex &sourceIndex) const +{ + TokenTreeItem *item = static_cast(itemForIndex(sourceIndex)); + if (!item) + return {}; + const ClangBackEnd::SourceRangeContainer &range = item->token.extraInfo.cursorRange; + return std::make_pair(::Utils::LineColumn(static_cast(range.start.line), + static_cast(range.start.column)), + ::Utils::LineColumn(static_cast(range.end.line), + static_cast(range.end.column))); } } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangoverviewmodel.h b/src/plugins/clangcodemodel/clangoverviewmodel.h index 7ea3bc8206f..306b529c25a 100644 --- a/src/plugins/clangcodemodel/clangoverviewmodel.h +++ b/src/plugins/clangcodemodel/clangoverviewmodel.h @@ -61,6 +61,7 @@ public: bool isGenerated(const QModelIndex &sourceIndex) const override; ::Utils::Link linkFromIndex(const QModelIndex &sourceIndex) const override; ::Utils::LineColumn lineColumnFromIndex(const QModelIndex &sourceIndex) const override; + Range rangeFromIndex(const QModelIndex &sourceIndex) const override; private: QString m_filePath; }; diff --git a/src/plugins/cpptools/abstractoverviewmodel.h b/src/plugins/cpptools/abstractoverviewmodel.h index 6a9bbebb991..444d19e5482 100644 --- a/src/plugins/cpptools/abstractoverviewmodel.h +++ b/src/plugins/cpptools/abstractoverviewmodel.h @@ -32,6 +32,8 @@ #include +#include + namespace CPlusPlus { class Document; } namespace Utils { @@ -91,6 +93,9 @@ public: virtual Utils::Link linkFromIndex(const QModelIndex &) const = 0; virtual Utils::LineColumn lineColumnFromIndex(const QModelIndex &) const = 0; + using Range = std::pair; + virtual Range rangeFromIndex(const QModelIndex &) const = 0; + signals: void needsUpdate(); }; diff --git a/src/plugins/cpptools/cppeditoroutline.cpp b/src/plugins/cpptools/cppeditoroutline.cpp index a71e027cdc3..d7840016d59 100644 --- a/src/plugins/cpptools/cppeditoroutline.cpp +++ b/src/plugins/cpptools/cppeditoroutline.cpp @@ -263,6 +263,17 @@ void CppEditorOutline::gotoSymbolInEditor() emit m_editorWidget->activateEditor(); } +static bool contains(const AbstractOverviewModel::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 { @@ -270,8 +281,12 @@ QModelIndex CppEditorOutline::indexForPosition(int line, int column, const int rowCount = m_model->rowCount(rootIndex); for (int row = 0; row < rowCount; ++row) { const QModelIndex index = m_model->index(row, 0, rootIndex); - if (m_model->lineColumnFromIndex(index).line > line) + const AbstractOverviewModel::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; } diff --git a/src/plugins/cpptools/cppoverviewmodel.cpp b/src/plugins/cpptools/cppoverviewmodel.cpp index 590f2b6847b..8c720b75ca7 100644 --- a/src/plugins/cpptools/cppoverviewmodel.cpp +++ b/src/plugins/cpptools/cppoverviewmodel.cpp @@ -190,6 +190,12 @@ Utils::LineColumn OverviewModel::lineColumnFromIndex(const QModelIndex &sourceIn return lineColumn; } +OverviewModel::Range OverviewModel::rangeFromIndex(const QModelIndex &sourceIndex) const +{ + Utils::LineColumn lineColumn = lineColumnFromIndex(sourceIndex); + return std::make_pair(lineColumn, lineColumn); +} + void OverviewModel::buildTree(SymbolItem *root, bool isRoot) { if (!root) diff --git a/src/plugins/cpptools/cppoverviewmodel.h b/src/plugins/cpptools/cppoverviewmodel.h index 6582ca083f0..0a7870ed288 100644 --- a/src/plugins/cpptools/cppoverviewmodel.h +++ b/src/plugins/cpptools/cppoverviewmodel.h @@ -54,6 +54,7 @@ public: bool isGenerated(const QModelIndex &sourceIndex) const override; Utils::Link linkFromIndex(const QModelIndex &sourceIndex) const override; Utils::LineColumn lineColumnFromIndex(const QModelIndex &sourceIndex) const override; + Range rangeFromIndex(const QModelIndex &sourceIndex) const override; private: CPlusPlus::Symbol *symbolFromIndex(const QModelIndex &index) const;