summaryrefslogtreecommitdiff
path: root/src/plugins/cppeditor
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@digia.com>2014-05-23 13:55:03 -0400
committerNikolai Kosjar <nikolai.kosjar@digia.com>2014-06-13 18:04:52 +0200
commit4ecadb38a07e6bccb4fce74341eece23ef4f37d8 (patch)
treec88d9b570484b01d5508d703e13568ef1fa238e7 /src/plugins/cppeditor
parenteaecac2fd91de739d87e232807349589f5beb5ef (diff)
downloadqt-creator-4ecadb38a07e6bccb4fce74341eece23ef4f37d8.tar.gz
CppEditor: Extract CppEditorOutline
Change-Id: I3b41f91f17ce9fb24796f2f6bff353fb3c6177ec Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp239
-rw-r--r--src/plugins/cppeditor/cppeditor.h23
-rw-r--r--src/plugins/cppeditor/cppeditor.pro2
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs1
-rw-r--r--src/plugins/cppeditor/cppeditoroutline.cpp282
-rw-r--r--src/plugins/cppeditor/cppeditoroutline.h100
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.cpp16
-rw-r--r--src/plugins/cppeditor/cppoutline.cpp8
-rw-r--r--src/plugins/cppeditor/cppoutline.h2
9 files changed, 426 insertions, 247 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index c9922814df..26e0eb8f0f 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -31,6 +31,7 @@
#include "cppautocompleter.h"
#include "cppeditorconstants.h"
+#include "cppeditoroutline.h"
#include "cppeditorplugin.h"
#include "cppfollowsymbolundercursor.h"
#include "cpphighlighter.h"
@@ -67,7 +68,6 @@
#include <texteditor/refactoroverlay.h>
#include <utils/qtcassert.h>
-#include <utils/treeviewcombobox.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/BackwardsScanner.h>
@@ -79,13 +79,11 @@
#include <QMenu>
#include <QPointer>
#include <QSignalMapper>
-#include <QSortFilterProxyModel>
#include <QTextEdit>
#include <QTimer>
#include <QToolButton>
enum {
- UPDATE_OUTLINE_INTERVAL = 500,
UPDATE_USES_INTERVAL = 500,
UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL = 200
};
@@ -96,31 +94,6 @@ using namespace CppEditor::Internal;
namespace {
-class OverviewProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- OverviewProxyModel(CPlusPlus::OverviewModel *sourceModel, QObject *parent) :
- QSortFilterProxyModel(parent),
- m_sourceModel(sourceModel)
- {
- setSourceModel(m_sourceModel);
- }
-
- bool filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const
- {
- // ignore generated symbols, e.g. by macro expansion (Q_OBJECT)
- const QModelIndex sourceIndex = m_sourceModel->index(sourceRow, 0, sourceParent);
- CPlusPlus::Symbol *symbol = m_sourceModel->symbolFromIndex(sourceIndex);
- if (symbol && symbol->isGenerated())
- return false;
-
- return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
- }
-private:
- CPlusPlus::OverviewModel *m_sourceModel;
-};
-
class CanonicalSymbol
{
public:
@@ -398,6 +371,14 @@ bool handleDoxygenContinuation(QTextCursor &cursor,
return false;
}
+QTimer *newSingleShotTimer(QObject *parent, int msecInterval)
+{
+ QTimer *timer = new QTimer(parent);
+ timer->setSingleShot(true);
+ timer->setInterval(msecInterval);
+ return timer;
+}
+
} // end of anonymous namespace
namespace CppEditor {
@@ -419,21 +400,14 @@ class CPPEditorWidgetPrivate
public:
CPPEditorWidgetPrivate(CPPEditorWidget *q);
- QTimer *newSingleShowTimer(int msecInterval);
-
public:
CPPEditorWidget *q;
QPointer<CppTools::CppModelManagerInterface> m_modelManager;
CPPEditorDocument *m_cppEditorDocument;
- Utils::TreeViewComboBox *m_outlineCombo;
- CPlusPlus::OverviewModel *m_outlineModel;
- QModelIndex m_outlineModelIndex;
- QSortFilterProxyModel *m_proxyModel;
- QAction *m_sortAction;
- QTimer *m_updateOutlineTimer;
- QTimer *m_updateOutlineIndexTimer;
+ CppEditorOutline *m_cppEditorOutline;
+
QTimer *m_updateUsesTimer;
QTimer *m_updateFunctionDeclDefLinkTimer;
QHash<int, QTextCharFormat> m_semanticHighlightFormatMap;
@@ -463,6 +437,7 @@ CPPEditorWidgetPrivate::CPPEditorWidgetPrivate(CPPEditorWidget *q)
: q(q)
, m_modelManager(CppModelManagerInterface::instance())
, m_cppEditorDocument(qobject_cast<CPPEditorDocument *>(q->baseTextDocument()))
+ , m_cppEditorOutline(new CppEditorOutline(q))
, m_localRenaming(q)
, m_highlightRevision(0)
, m_referencesRevision(0)
@@ -474,14 +449,6 @@ CPPEditorWidgetPrivate::CPPEditorWidgetPrivate(CPPEditorWidget *q)
{
}
-QTimer *CPPEditorWidgetPrivate::newSingleShowTimer(int msecInterval)
-{
- QTimer *timer = new QTimer(q);
- timer->setSingleShot(true);
- timer->setInterval(msecInterval);
- return timer;
-}
-
CPPEditorWidget::CPPEditorWidget(QWidget *parent)
: TextEditor::BaseTextEditorWidget(new CPPEditorDocument(), parent)
{
@@ -547,6 +514,11 @@ CPPEditorDocument *CPPEditorWidget::cppEditorDocument() const
return d->m_cppEditorDocument;
}
+CppEditorOutline *CPPEditorWidget::outline() const
+{
+ return d->m_cppEditorOutline;
+}
+
TextEditor::BaseTextEditor *CPPEditorWidget::createEditor()
{
CPPEditor *editable = new CPPEditor(this);
@@ -556,49 +528,15 @@ TextEditor::BaseTextEditor *CPPEditorWidget::createEditor()
void CPPEditorWidget::createToolBar(CPPEditor *editor)
{
- d->m_outlineCombo = new Utils::TreeViewComboBox;
- d->m_outlineCombo->setMinimumContentsLength(22);
-
- // Make the combo box prefer to expand
- QSizePolicy policy = d->m_outlineCombo->sizePolicy();
- policy.setHorizontalPolicy(QSizePolicy::Expanding);
- d->m_outlineCombo->setSizePolicy(policy);
- d->m_outlineCombo->setMaxVisibleItems(40);
-
- d->m_outlineModel = new OverviewModel(this);
- d->m_proxyModel = new OverviewProxyModel(d->m_outlineModel, this);
- if (CppEditorPlugin::instance()->sortedOutline())
- d->m_proxyModel->sort(0, Qt::AscendingOrder);
- else
- d->m_proxyModel->sort(-1, Qt::AscendingOrder); // don't sort yet, but set column for sortedOutline()
- d->m_proxyModel->setDynamicSortFilter(true);
- d->m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- d->m_outlineCombo->setModel(d->m_proxyModel);
-
- d->m_outlineCombo->setContextMenuPolicy(Qt::ActionsContextMenu);
- d->m_sortAction = new QAction(tr("Sort Alphabetically"), d->m_outlineCombo);
- d->m_sortAction->setCheckable(true);
- d->m_sortAction->setChecked(sortedOutline());
- connect(d->m_sortAction, SIGNAL(toggled(bool)),
- CppEditorPlugin::instance(), SLOT(setSortedOutline(bool)));
- d->m_outlineCombo->addAction(d->m_sortAction);
-
- d->m_updateOutlineTimer = d->newSingleShowTimer(UPDATE_OUTLINE_INTERVAL);
- connect(d->m_updateOutlineTimer, SIGNAL(timeout()), this, SLOT(updateOutlineNow()));
-
- d->m_updateOutlineIndexTimer = d->newSingleShowTimer(UPDATE_OUTLINE_INTERVAL);
- connect(d->m_updateOutlineIndexTimer, SIGNAL(timeout()), this, SLOT(updateOutlineIndexNow()));
-
- d->m_updateUsesTimer = d->newSingleShowTimer(UPDATE_USES_INTERVAL);
+ d->m_updateUsesTimer = newSingleShotTimer(this, UPDATE_USES_INTERVAL);
connect(d->m_updateUsesTimer, SIGNAL(timeout()), this, SLOT(updateUsesNow()));
- d->m_updateFunctionDeclDefLinkTimer = d->newSingleShowTimer(UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
+ d->m_updateFunctionDeclDefLinkTimer = newSingleShotTimer(this, UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
connect(d->m_updateFunctionDeclDefLinkTimer, SIGNAL(timeout()),
this, SLOT(updateFunctionDeclDefLinkNow()));
- connect(d->m_outlineCombo, SIGNAL(activated(int)), this, SLOT(jumpToOutlineElement()));
- connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateOutlineIndex()));
- connect(d->m_outlineCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateOutlineToolTip()));
+ connect(this, SIGNAL(cursorPositionChanged()),
+ d->m_cppEditorOutline, SLOT(updateIndex()));
// set up slots to document changes
connect(document(), SIGNAL(contentsChange(int,int,int)),
@@ -619,7 +557,7 @@ void CPPEditorWidget::createToolBar(CPPEditor *editor)
updatePreprocessorButtonTooltip();
connect(d->m_preprocessorButton, SIGNAL(clicked()), this, SLOT(showPreProcessorWidget()));
editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, d->m_preprocessorButton);
- editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, d->m_outlineCombo);
+ editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, d->m_cppEditorOutline->widget());
}
void CPPEditorWidget::paste()
@@ -650,7 +588,7 @@ void CPPEditorWidget::selectAll()
/// file in this editor is updated.
void CPPEditorWidget::onDocumentUpdated()
{
- d->m_updateOutlineTimer->start();
+ d->m_cppEditorOutline->update();
}
const Macro *CPPEditorWidget::findCanonicalMacro(const QTextCursor &cursor, Document::Ptr doc) const
@@ -855,65 +793,6 @@ void CPPEditorWidget::updatePreprocessorButtonTooltip()
d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
}
-void CPPEditorWidget::jumpToOutlineElement()
-{
- QModelIndex modelIndex = d->m_outlineCombo->view()->currentIndex();
- QModelIndex sourceIndex = d->m_proxyModel->mapToSource(modelIndex);
- Symbol *symbol = d->m_outlineModel->symbolFromIndex(sourceIndex);
- if (!symbol)
- return;
-
- const Link &link = linkToSymbol(symbol);
- gotoLine(link.targetLine, link.targetColumn);
- Core::EditorManager::activateEditor(editor());
-}
-
-void CPPEditorWidget::setSortedOutline(bool sort)
-{
- if (sort != sortedOutline()) {
- if (sort)
- d->m_proxyModel->sort(0, Qt::AscendingOrder);
- else
- d->m_proxyModel->sort(-1, Qt::AscendingOrder);
- bool block = d->m_sortAction->blockSignals(true);
- d->m_sortAction->setChecked(d->m_proxyModel->sortColumn() == 0);
- d->m_sortAction->blockSignals(block);
- updateOutlineIndexNow();
- }
-}
-
-bool CPPEditorWidget::sortedOutline() const
-{
- return (d->m_proxyModel->sortColumn() == 0);
-}
-
-void CPPEditorWidget::updateOutlineNow()
-{
- if (!d->m_modelManager)
- return;
-
- const Snapshot snapshot = d->m_modelManager->snapshot();
- Document::Ptr document = snapshot.document(baseTextDocument()->filePath());
-
- if (!document)
- return;
-
- if (document->editorRevision() != editorRevision()) {
- d->m_updateOutlineTimer->start();
- return;
- }
-
- d->m_outlineModel->rebuild(document);
-
- d->m_outlineCombo->view()->expandAll();
- updateOutlineIndexNow();
-}
-
-void CPPEditorWidget::updateOutlineIndex()
-{
- d->m_updateOutlineIndexTimer->start();
-}
-
QList<QTextEdit::ExtraSelection> CPPEditorWidget::createSelectionsFromUses(
const QList<SemanticInfo::Use> &uses)
{
@@ -943,37 +822,6 @@ QList<QTextEdit::ExtraSelection> CPPEditorWidget::createSelectionsFromUses(
return result;
}
-void CPPEditorWidget::updateOutlineIndexNow()
-{
- if (!d->m_outlineModel->document())
- return;
-
- if (d->m_outlineModel->document()->editorRevision() != editorRevision()) {
- d->m_updateOutlineIndexTimer->start();
- return;
- }
-
- d->m_updateOutlineIndexTimer->stop();
-
- d->m_outlineModelIndex = QModelIndex(); //invalidate
- QModelIndex comboIndex = outlineModelIndex();
-
- if (comboIndex.isValid()) {
- bool blocked = d->m_outlineCombo->blockSignals(true);
-
- d->m_outlineCombo->setCurrentIndex(d->m_proxyModel->mapFromSource(comboIndex));
-
- updateOutlineToolTip();
-
- d->m_outlineCombo->blockSignals(blocked);
- }
-}
-
-void CPPEditorWidget::updateOutlineToolTip()
-{
- d->m_outlineCombo->setToolTip(d->m_outlineCombo->currentText());
-}
-
void CPPEditorWidget::updateUses()
{
// Block premature semantic info calculation when editor is created.
@@ -1125,23 +973,6 @@ SemanticInfo CPPEditorWidget::semanticInfo() const
return d->m_lastSemanticInfo;
}
-CPlusPlus::OverviewModel *CPPEditorWidget::outlineModel() const
-{
- return d->m_outlineModel;
-}
-
-QModelIndex CPPEditorWidget::outlineModelIndex()
-{
- if (!d->m_outlineModelIndex.isValid()) {
- int line = 0, column = 0;
- convertPosition(position(), &line, &column);
- d->m_outlineModelIndex = indexForPosition(line, column);
- emit outlineModelIndexChanged(d->m_outlineModelIndex);
- }
-
- return d->m_outlineModelIndex;
-}
-
bool CPPEditorWidget::event(QEvent *e)
{
switch (e->type()) {
@@ -1415,28 +1246,6 @@ void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
updateFunctionDeclDefLink();
}
-QModelIndex CPPEditorWidget::indexForPosition(int line, int column,
- const QModelIndex &rootIndex) const
-{
- QModelIndex lastIndex = rootIndex;
-
- const int rowCount = d->m_outlineModel->rowCount(rootIndex);
- for (int row = 0; row < rowCount; ++row) {
- const QModelIndex index = d->m_outlineModel->index(row, 0, rootIndex);
- Symbol *symbol = d->m_outlineModel->symbolFromIndex(index);
- if (symbol && symbol->line() > unsigned(line))
- break;
- lastIndex = index;
- }
-
- if (lastIndex != rootIndex) {
- // recurse
- lastIndex = indexForPosition(line, column, lastIndex);
- }
-
- return lastIndex;
-}
-
TextEditor::IAssistInterface *CPPEditorWidget::createAssistInterface(
TextEditor::AssistKind kind,
TextEditor::AssistReason reason) const
@@ -1722,5 +1531,3 @@ void CPPEditorWidget::showPreProcessorWidget()
} // namespace Internal
} // namespace CppEditor
-
-#include <cppeditor.moc>
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 11384c1c0e..71109d3b73 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -43,10 +43,7 @@
#include <QScopedPointer>
-namespace CPlusPlus {
-class OverviewModel;
-class Symbol;
-}
+namespace CPlusPlus { class Symbol; }
namespace CppTools {
class SemanticInfo;
@@ -56,6 +53,7 @@ class CommentsSettings;
namespace CppEditor {
namespace Internal {
+class CppEditorOutline;
class CPPEditorWidget;
class CPPEditorWidgetPrivate;
class FollowSymbolUnderCursor;
@@ -93,12 +91,10 @@ public:
~CPPEditorWidget();
CPPEditorDocument *cppEditorDocument() const;
+ CppEditorOutline *outline() const;
CppTools::SemanticInfo semanticInfo() const;
- CPlusPlus::OverviewModel *outlineModel() const;
- QModelIndex outlineModelIndex();
-
QSharedPointer<FunctionDeclDefLink> declDefLink() const;
void applyDeclDefLinkChanges(bool jumpToMatch);
@@ -108,16 +104,12 @@ public:
FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests
-signals:
- void outlineModelIndexChanged(const QModelIndex &index);
-
public slots:
void paste() QTC_OVERRIDE;
void cut() QTC_OVERRIDE;
void selectAll() QTC_OVERRIDE;
void unCommentSelection() QTC_OVERRIDE;
- void setSortedOutline(bool sort);
void switchDeclarationDefinition(bool inNextSplit);
void showPreProcessorWidget();
@@ -147,11 +139,6 @@ protected slots:
void slotCodeStyleSettingsChanged(const QVariant &) QTC_OVERRIDE;
private slots:
- void jumpToOutlineElement();
- void updateOutlineNow();
- void updateOutlineIndex();
- void updateOutlineIndexNow();
- void updateOutlineToolTip();
void updateUses();
void updateUsesNow();
void updateFunctionDeclDefLink();
@@ -192,14 +179,10 @@ private:
QTextCharFormat textCharFormat(TextEditor::TextStyle category);
void markSymbols(const QTextCursor &tc, const CppTools::SemanticInfo &info);
- bool sortedOutline() const;
QList<QTextEdit::ExtraSelection> createSelectionsFromUses(
const QList<TextEditor::HighlightingResult> &uses);
- QModelIndex indexForPosition(int line, int column,
- const QModelIndex &rootIndex = QModelIndex()) const;
-
bool handleDocumentationComment(QKeyEvent *e);
bool isStartOfDoxygenComment(const QTextCursor &cursor) const;
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index bcaeea8628..6e8ff5552b 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -10,6 +10,7 @@ HEADERS += \
cppeditordocument.h \
cppeditorconstants.h \
cppeditorenums.h \
+ cppeditoroutline.h \
cppeditorplugin.h \
cppelementevaluator.h \
cppfilewizard.h \
@@ -40,6 +41,7 @@ SOURCES += \
cppcodemodelinspectordialog.cpp \
cppeditor.cpp \
cppeditordocument.cpp \
+ cppeditoroutline.cpp \
cppeditorplugin.cpp \
cppelementevaluator.cpp \
cppfilewizard.cpp \
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index 6a55755d8a..8a80874ef2 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -28,6 +28,7 @@ QtcPlugin {
"cppeditorconstants.h",
"cppeditordocument.cpp", "cppeditordocument.h",
"cppeditorenums.h",
+ "cppeditoroutline.cpp", "cppeditoroutline.h",
"cppeditorplugin.cpp", "cppeditorplugin.h",
"cppelementevaluator.cpp", "cppelementevaluator.h",
"cppfilewizard.cpp", "cppfilewizard.h",
diff --git a/src/plugins/cppeditor/cppeditoroutline.cpp b/src/plugins/cppeditor/cppeditoroutline.cpp
new file mode 100644
index 0000000000..5342704774
--- /dev/null
+++ b/src/plugins/cppeditor/cppeditoroutline.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "cppeditoroutline.h"
+
+#include "cppeditor.h"
+#include "cppeditorplugin.h"
+
+#include <cpptools/cppmodelmanagerinterface.h>
+
+#include <cplusplus/OverviewModel.h>
+#include <utils/treeviewcombobox.h>
+
+#include <QSortFilterProxyModel>
+#include <QTimer>
+
+/*!
+ \class CppEditor::Internal::CppEditorOutline
+ \brief A helper class of CPPEditorWidget that provides the outline model
+ and widget, e.g. for the editor's tool bar.
+
+ \internal
+
+ The caller is responsible for deleting the widget returned by widget().
+
+ \sa CppEditor::Internal::CPPEditorWidget
+ */
+
+enum { UpdateOutlineIntervalInMs = 500 };
+
+namespace {
+
+class OverviewProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ OverviewProxyModel(CPlusPlus::OverviewModel *sourceModel, QObject *parent)
+ : QSortFilterProxyModel(parent)
+ , m_sourceModel(sourceModel)
+ {
+ setSourceModel(m_sourceModel);
+ }
+
+ bool filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const
+ {
+ // Ignore generated symbols, e.g. by macro expansion (Q_OBJECT)
+ const QModelIndex sourceIndex = m_sourceModel->index(sourceRow, 0, sourceParent);
+ CPlusPlus::Symbol *symbol = m_sourceModel->symbolFromIndex(sourceIndex);
+ if (symbol && symbol->isGenerated())
+ return false;
+
+ return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
+ }
+private:
+ CPlusPlus::OverviewModel *m_sourceModel;
+};
+
+QTimer *newSingleShotTimer(QObject *parent, int msInternal)
+{
+ QTimer *timer = new QTimer(parent);
+ timer->setSingleShot(true);
+ timer->setInterval(msInternal);
+ return timer;
+}
+
+} // anonymous namespace
+
+namespace CppEditor {
+namespace Internal {
+
+CppEditorOutline::CppEditorOutline(CPPEditorWidget *editorWidget)
+ : QObject(editorWidget)
+ , m_editorWidget(editorWidget)
+ , m_combo(new Utils::TreeViewComboBox)
+ , m_model(new CPlusPlus::OverviewModel(this))
+ , m_proxyModel(new OverviewProxyModel(m_model, this))
+{
+ // Set up proxy model
+ if (CppEditorPlugin::instance()->sortedOutline())
+ m_proxyModel->sort(0, Qt::AscendingOrder);
+ else
+ m_proxyModel->sort(-1, Qt::AscendingOrder); // don't sort yet, but set column for sortedOutline()
+ m_proxyModel->setDynamicSortFilter(true);
+ m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+
+ // Set up combo box
+ m_combo->setModel(m_proxyModel);
+
+ m_combo->setMinimumContentsLength(22);
+ QSizePolicy policy = m_combo->sizePolicy();
+ policy.setHorizontalPolicy(QSizePolicy::Expanding);
+ m_combo->setSizePolicy(policy);
+ m_combo->setMaxVisibleItems(40);
+
+ m_combo->setContextMenuPolicy(Qt::ActionsContextMenu);
+ m_sortAction = new QAction(tr("Sort Alphabetically"), m_combo);
+ m_sortAction->setCheckable(true);
+ m_sortAction->setChecked(isSorted());
+ connect(m_sortAction, SIGNAL(toggled(bool)),
+ CppEditorPlugin::instance(), SLOT(setSortedOutline(bool)));
+ m_combo->addAction(m_sortAction);
+
+ connect(m_combo, SIGNAL(activated(int)), this, SLOT(gotoSymbolInEditor()));
+ connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateToolTip()));
+
+ // Set up timers
+ m_updateTimer = newSingleShotTimer(this, UpdateOutlineIntervalInMs);
+ connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateNow()));
+
+ m_updateIndexTimer = newSingleShotTimer(this, UpdateOutlineIntervalInMs);
+ connect(m_updateIndexTimer, SIGNAL(timeout()), this, SLOT(updateIndexNow()));
+}
+
+void CppEditorOutline::update()
+{
+ m_updateTimer->start();
+}
+
+bool CppEditorOutline::isSorted() const
+{
+ return m_proxyModel->sortColumn() == 0;
+}
+
+void CppEditorOutline::setSorted(bool sort)
+{
+ if (sort != isSorted()) {
+ if (sort)
+ m_proxyModel->sort(0, Qt::AscendingOrder);
+ else
+ m_proxyModel->sort(-1, Qt::AscendingOrder);
+ bool block = m_sortAction->blockSignals(true);
+ m_sortAction->setChecked(m_proxyModel->sortColumn() == 0);
+ m_sortAction->blockSignals(block);
+ updateIndexNow();
+ }
+}
+
+CPlusPlus::OverviewModel *CppEditorOutline::model() const
+{
+ return m_model;
+}
+
+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;
+}
+
+void CppEditorOutline::updateNow()
+{
+ CppTools::CppModelManagerInterface *cmmi = CppTools::CppModelManagerInterface::instance();
+ if (!cmmi)
+ return;
+
+ const CPlusPlus::Snapshot snapshot = cmmi->snapshot();
+ const QString filePath = m_editorWidget->baseTextDocument()->filePath();
+ CPlusPlus::Document::Ptr document = snapshot.document(filePath);
+ if (!document)
+ return;
+
+ if (document->editorRevision() != (unsigned) m_editorWidget->document()->revision()) {
+ m_updateTimer->start();
+ return;
+ }
+
+ m_model->rebuild(document);
+
+ m_combo->view()->expandAll();
+ updateIndexNow();
+}
+
+void CppEditorOutline::updateIndex()
+{
+ m_updateIndexTimer->start();
+}
+
+void CppEditorOutline::updateIndexNow()
+{
+ if (!m_model->document())
+ return;
+
+ const unsigned revision = m_editorWidget->document()->revision();
+ if (m_model->document()->editorRevision() != revision) {
+ m_updateIndexTimer->start();
+ return;
+ }
+
+ m_updateIndexTimer->stop();
+
+ m_modelIndex = QModelIndex(); //invalidate
+ QModelIndex comboIndex = modelIndex();
+
+ if (comboIndex.isValid()) {
+ bool blocked = m_combo->blockSignals(true);
+ m_combo->setCurrentIndex(m_proxyModel->mapFromSource(comboIndex));
+ updateToolTip();
+ m_combo->blockSignals(blocked);
+ }
+}
+
+void CppEditorOutline::updateToolTip()
+{
+ m_combo->setToolTip(m_combo->currentText());
+}
+
+void CppEditorOutline::gotoSymbolInEditor()
+{
+ const QModelIndex modelIndex = m_combo->view()->currentIndex();
+ const QModelIndex sourceIndex = m_proxyModel->mapToSource(modelIndex);
+ CPlusPlus::Symbol *symbol = m_model->symbolFromIndex(sourceIndex);
+ if (!symbol)
+ return;
+
+ const TextEditor::BaseTextEditorWidget::Link &link = CPPEditorWidget::linkToSymbol(symbol);
+ m_editorWidget->gotoLine(link.targetLine, link.targetColumn);
+ Core::EditorManager::activateEditor(m_editorWidget->editor());
+}
+
+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);
+ CPlusPlus::Symbol *symbol = m_model->symbolFromIndex(index);
+ if (symbol && symbol->line() > unsigned(line))
+ break;
+ lastIndex = index;
+ }
+
+ if (lastIndex != rootIndex) {
+ // recurse
+ lastIndex = indexForPosition(line, column, lastIndex);
+ }
+
+ return lastIndex;
+}
+
+} // namespace Internal
+} // namespace CppEditor
+
+#include <cppeditoroutline.moc>
diff --git a/src/plugins/cppeditor/cppeditoroutline.h b/src/plugins/cppeditor/cppeditoroutline.h
new file mode 100644
index 0000000000..126c8710ed
--- /dev/null
+++ b/src/plugins/cppeditor/cppeditoroutline.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CPPEDITOROUTLINE_H
+#define CPPEDITOROUTLINE_H
+
+#include <QModelIndex>
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QSortFilterProxyModel;
+class QTimer;
+QT_END_NAMESPACE
+
+namespace CPlusPlus { class OverviewModel; }
+namespace Utils { class TreeViewComboBox; }
+
+namespace CppEditor {
+namespace Internal {
+
+class CPPEditorWidget;
+
+class CppEditorOutline : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(CppEditorOutline)
+
+public:
+ explicit CppEditorOutline(CPPEditorWidget *editorWidget);
+
+ void update();
+
+ CPlusPlus::OverviewModel *model() const;
+ QModelIndex modelIndex();
+
+ QWidget *widget() const; // Must be deleted by client.
+
+signals:
+ void modelIndexChanged(const QModelIndex &index);
+
+public slots:
+ void updateIndex();
+ void setSorted(bool sort);
+
+private slots:
+ void updateNow();
+ void updateIndexNow();
+ void updateToolTip();
+ void gotoSymbolInEditor();
+
+private:
+ CppEditorOutline();
+
+ bool isSorted() const;
+ QModelIndex indexForPosition(int line, int column,
+ const QModelIndex &rootIndex = QModelIndex()) const;
+
+private:
+ CPPEditorWidget *m_editorWidget;
+
+ Utils::TreeViewComboBox *m_combo; // Not owned
+ CPlusPlus::OverviewModel *m_model;
+ QSortFilterProxyModel *m_proxyModel;
+ QModelIndex m_modelIndex;
+ QAction *m_sortAction;
+ QTimer *m_updateTimer;
+ QTimer *m_updateIndexTimer;
+};
+
+} // namespace Internal
+} // namespace CppEditor
+
+#endif // CPPEDITOROUTLINE_H
diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp
index d8202e5bfd..cd0b053fa3 100644
--- a/src/plugins/cppeditor/cppeditorplugin.cpp
+++ b/src/plugins/cppeditor/cppeditorplugin.cpp
@@ -30,19 +30,19 @@
#include "cppeditorplugin.h"
#include "cppclasswizard.h"
-#include "cppeditor.h"
+#include "cppcodemodelinspectordialog.h"
#include "cppeditorconstants.h"
+#include "cppeditor.h"
+#include "cppeditoroutline.h"
#include "cppfilewizard.h"
+#include "cpphighlighterfactory.h"
#include "cpphoverhandler.h"
-#include "cppoutline.h"
-#include "cpptypehierarchy.h"
#include "cppincludehierarchy.h"
-#include "cppsnippetprovider.h"
+#include "cppoutline.h"
#include "cppquickfixassistant.h"
#include "cppquickfixes.h"
-#include "cpphighlighterfactory.h"
-
-#include "cppcodemodelinspectordialog.h"
+#include "cppsnippetprovider.h"
+#include "cpptypehierarchy.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -135,7 +135,7 @@ void CppEditorPlugin::initializeEditor(CPPEditorWidget *editor)
// function combo box sorting
connect(this, SIGNAL(outlineSortingChanged(bool)),
- editor, SLOT(setSortedOutline(bool)));
+ editor->outline(), SLOT(setSorted(bool)));
}
void CppEditorPlugin::setSortedOutline(bool sorted)
diff --git a/src/plugins/cppeditor/cppoutline.cpp b/src/plugins/cppeditor/cppoutline.cpp
index 0410af60f8..31c6cdee69 100644
--- a/src/plugins/cppeditor/cppoutline.cpp
+++ b/src/plugins/cppeditor/cppoutline.cpp
@@ -29,6 +29,8 @@
#include "cppoutline.h"
+#include "cppeditoroutline.h"
+
#include <cplusplus/OverviewModel.h>
#include <coreplugin/find/treeviewfind.h>
@@ -92,7 +94,7 @@ CppOutlineWidget::CppOutlineWidget(CPPEditorWidget *editor) :
TextEditor::IOutlineWidget(),
m_editor(editor),
m_treeView(new CppOutlineTreeView(this)),
- m_model(m_editor->outlineModel()),
+ m_model(m_editor->outline()->model()),
m_proxyModel(new CppOutlineFilterModel(m_model, this)),
m_enableCursorSync(true),
m_blockCursorSync(false)
@@ -109,7 +111,7 @@ CppOutlineWidget::CppOutlineWidget(CPPEditorWidget *editor) :
connect(m_model, SIGNAL(modelReset()), this, SLOT(modelUpdated()));
modelUpdated();
- connect(m_editor, SIGNAL(outlineModelIndexChanged(QModelIndex)),
+ connect(m_editor->outline(), SIGNAL(modelIndexChanged(QModelIndex)),
this, SLOT(updateSelectionInTree(QModelIndex)));
connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(updateSelectionInText(QItemSelection)));
@@ -126,7 +128,7 @@ void CppOutlineWidget::setCursorSynchronization(bool syncWithCursor)
{
m_enableCursorSync = syncWithCursor;
if (m_enableCursorSync)
- updateSelectionInTree(m_editor->outlineModelIndex());
+ updateSelectionInTree(m_editor->outline()->modelIndex());
}
void CppOutlineWidget::modelUpdated()
diff --git a/src/plugins/cppeditor/cppoutline.h b/src/plugins/cppeditor/cppoutline.h
index 29969dc197..12ca590c14 100644
--- a/src/plugins/cppeditor/cppoutline.h
+++ b/src/plugins/cppeditor/cppoutline.h
@@ -38,6 +38,8 @@
#include <QSortFilterProxyModel>
+namespace CPlusPlus { class OverviewModel; }
+
namespace CppEditor {
namespace Internal {