diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 1fe876451be..8cd276e9fd8 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1070,20 +1070,17 @@ void CPPEditor::updateMethodBoxIndexNow() int line = 0, column = 0; convertPosition(position(), &line, &column); - QModelIndex lastIndex; + QModelIndex m_overviewModelIndex = indexForPosition(line, column); + emit overviewModelIndexChanged(m_overviewModelIndex); - const int rc = m_overviewModel->rowCount(); - for (int row = 0; row < rc; ++row) { - const QModelIndex index = m_overviewModel->index(row, 0, QModelIndex()); - Symbol *symbol = m_overviewModel->symbolFromIndex(index); - if (symbol && symbol->line() > unsigned(line)) - break; - lastIndex = index; - } + // ComboBox only let's you select top level indexes! + QModelIndex comboIndex = indexForPosition(line, column); + while (comboIndex.parent().isValid()) + comboIndex = comboIndex.parent(); - if (lastIndex.isValid()) { + if (comboIndex.isValid()) { bool blocked = m_methodCombo->blockSignals(true); - m_methodCombo->setCurrentIndex(m_proxyModel->mapFromSource(lastIndex).row()); + m_methodCombo->setCurrentIndex(m_proxyModel->mapFromSource(comboIndex).row()); updateMethodBoxToolTip(); (void) m_methodCombo->blockSignals(blocked); } @@ -1422,6 +1419,11 @@ CPlusPlus::OverviewModel *CPPEditor::overviewModel() const return m_overviewModel; } +QModelIndex CPPEditor::overviewModelIndex() const +{ + return m_overviewModelIndex; +} + bool CPPEditor::isElectricCharacter(QChar ch) const { if (ch == QLatin1Char('{') || @@ -2166,3 +2168,24 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) return semanticInfo; } + +QModelIndex CPPEditor::indexForPosition(int line, int column, const QModelIndex &rootIndex) +{ + QModelIndex lastIndex = rootIndex; + + const int rowCount = m_overviewModel->rowCount(rootIndex); + for (int row = 0; row < rowCount; ++row) { + const QModelIndex index = m_overviewModel->index(row, 0, rootIndex); + Symbol *symbol = m_overviewModel->symbolFromIndex(index); + if (symbol && symbol->line() > unsigned(line)) + break; + lastIndex = index; + } + + if (lastIndex != rootIndex) { + // recurse + lastIndex = indexForPosition(line, column, lastIndex); + } + + return lastIndex; +} diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 76553ec5e4d..78730998b93 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -42,6 +42,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QComboBox; @@ -165,7 +166,9 @@ public: unsigned editorRevision() const; bool isOutdated() const; SemanticInfo semanticInfo() const; + CPlusPlus::OverviewModel *overviewModel() const; + QModelIndex overviewModelIndex() const; virtual void paste(); // reimplemented from BaseTextEditor virtual void cut(); // reimplemented from BaseTextEditor @@ -177,6 +180,9 @@ public: void setObjCEnabled(bool onoff); bool isObjCEnabled() const; +Q_SIGNALS: + void overviewModelIndexChanged(const QModelIndex &index); + public Q_SLOTS: virtual void setFontSettings(const TextEditor::FontSettings &); virtual void setTabSettings(const TextEditor::TabSettings &); @@ -259,12 +265,15 @@ private: bool openLink(const Link &link) { return openCppEditorAt(link); } bool openCppEditorAt(const Link &); + QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()); + static Link linkToSymbol(CPlusPlus::Symbol *symbol); CppTools::CppModelManagerInterface *m_modelManager; QComboBox *m_methodCombo; CPlusPlus::OverviewModel *m_overviewModel; + QModelIndex m_overviewModelIndex; QSortFilterProxyModel *m_proxyModel; QAction *m_sortAction; QTimer *m_updateMethodBoxTimer; diff --git a/src/plugins/cppeditor/cppoutline.cpp b/src/plugins/cppeditor/cppoutline.cpp index a1be1e756d4..6bcaa66f2c3 100644 --- a/src/plugins/cppeditor/cppoutline.cpp +++ b/src/plugins/cppeditor/cppoutline.cpp @@ -67,8 +67,8 @@ CppOutlineWidget::CppOutlineWidget(CPPEditor *editor) : connect(m_model, SIGNAL(modelReset()), this, SLOT(modelUpdated())); modelUpdated(); - connect(m_editor, SIGNAL(cursorPositionChanged()), - this, SLOT(updateSelectionInTree())); + connect(m_editor, SIGNAL(overviewModelIndexChanged(QModelIndex)), + this, SLOT(updateSelectionInTree(QModelIndex))); connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateSelectionInText(QItemSelection))); } @@ -77,24 +77,20 @@ void CppOutlineWidget::setCursorSynchronization(bool syncWithCursor) { m_enableCursorSync = syncWithCursor; if (m_enableCursorSync) - updateSelectionInTree(); + updateSelectionInTree(m_editor->overviewModelIndex()); } void CppOutlineWidget::modelUpdated() { m_treeView->expandAll(); - updateSelectionInTree(); + updateSelectionInTree(m_editor->overviewModelIndex()); } -void CppOutlineWidget::updateSelectionInTree() +void CppOutlineWidget::updateSelectionInTree(const QModelIndex &index) { if (!syncCursor()) return; - int line = m_editor->textCursor().blockNumber(); - int column = m_editor->textCursor().columnNumber(); - - QModelIndex index = indexForPosition(QModelIndex(), line, column); QModelIndex proxyIndex = m_proxyModel->mapFromSource(index); m_blockCursorSync = true; @@ -130,56 +126,6 @@ void CppOutlineWidget::updateSelectionInText(const QItemSelection &selection) } } -QModelIndex CppOutlineWidget::indexForPosition(const QModelIndex &rootIndex, int line, int column) -{ - QModelIndex result = rootIndex; - - const int rowCount = m_model->rowCount(rootIndex); - for (int row = 0; row < rowCount; ++row) { - QModelIndex index = m_model->index(row, 0, rootIndex); - CPlusPlus::Symbol *symbol = m_model->symbolFromIndex(index); - if (symbol && positionInsideSymbol(line, column, symbol)) { - // recurse to children - result = indexForPosition(index, line, column); - } - } - - return result; -} - -bool CppOutlineWidget::positionInsideSymbol(unsigned cursorLine, unsigned cursorColumn, CPlusPlus::Symbol *symbol) const -{ - if (!m_model->document()) - return false; - CPlusPlus::TranslationUnit *translationUnit = m_model->document()->translationUnit(); - - unsigned symbolStartLine = -1; - unsigned symbolStartColumn = -1; - - translationUnit->getPosition(symbol->startOffset(), &symbolStartLine, &symbolStartColumn); - - // normalize to 0 based - --symbolStartLine; - --symbolStartColumn; - - if (symbolStartLine < cursorLine - || (symbolStartLine == cursorLine && symbolStartColumn <= cursorColumn)) { - unsigned symbolEndLine = -1; - unsigned symbolEndColumn = -1; - translationUnit->getPosition(symbol->endOffset(), &symbolEndLine, &symbolEndColumn); - - // normalize to 0 based - --symbolEndLine; - --symbolEndColumn; - - if (symbolEndLine > cursorLine - || (symbolEndLine == cursorLine && symbolEndColumn >= cursorColumn)) { - return true; - } - } - return false; -} - bool CppOutlineWidget::syncCursor() { return m_enableCursorSync && !m_blockCursorSync; diff --git a/src/plugins/cppeditor/cppoutline.h b/src/plugins/cppeditor/cppoutline.h index 4174026eae8..e09d09adef6 100644 --- a/src/plugins/cppeditor/cppoutline.h +++ b/src/plugins/cppeditor/cppoutline.h @@ -39,12 +39,10 @@ public: private slots: void modelUpdated(); - void updateSelectionInTree(); + void updateSelectionInTree(const QModelIndex &index); void updateSelectionInText(const QItemSelection &selection); private: - QModelIndex indexForPosition(const QModelIndex &rootIndex, int line, int column); - bool positionInsideSymbol(unsigned cursorLine, unsigned cursorColumn, CPlusPlus::Symbol *symbol) const; bool syncCursor(); private: