From 575495b99bc65173b7f6ceeda76e31dea2ea3e36 Mon Sep 17 00:00:00 2001
From: Christian Hoenig <christian@hoenig.cc>
Date: Thu, 14 May 2009 21:08:08 +0200
Subject: [PATCH] Implement CppCurrentDocumentFilter for symbols in current
 document

---
 .../cpptools/cppcurrentdocumentfilter.cpp     | 138 ++++++++++++++++++
 .../cpptools/cppcurrentdocumentfilter.h       |  75 ++++++++++
 src/plugins/cpptools/cpptools.pro             |   2 +
 src/plugins/cpptools/cpptoolsplugin.cpp       |   2 +
 src/plugins/cpptools/searchsymbols.cpp        |  17 ++-
 src/plugins/cpptools/searchsymbols.h          |  12 +-
 6 files changed, 232 insertions(+), 14 deletions(-)
 create mode 100644 src/plugins/cpptools/cppcurrentdocumentfilter.cpp
 create mode 100644 src/plugins/cpptools/cppcurrentdocumentfilter.h

diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
new file mode 100644
index 00000000000..8d54c86ed3f
--- /dev/null
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
@@ -0,0 +1,138 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+#include "cppcurrentdocumentfilter.h"
+#include "cppmodelmanager.h"
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <cplusplus/CppDocument.h>
+
+using namespace CppTools::Internal;
+using namespace CPlusPlus;
+
+CppCurrentDocumentFilter::CppCurrentDocumentFilter(CppModelManager *manager, Core::EditorManager *editorManager)
+    : m_modelManager(manager)
+{
+    setShortcutString(".");
+    setIncludedByDefault(false);
+
+    search.setSymbolsToSearchFor(SearchSymbols::Declarations |
+                                 SearchSymbols::Enums |
+                                 SearchSymbols::Functions |
+                                 SearchSymbols::Classes);
+
+    search.setSeparateScope(true);
+
+    connect(manager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
+            this,    SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr)));
+    connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
+            this,          SLOT(onCurrentEditorChanged(Core::IEditor*)));
+    connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
+            this,          SLOT(onEditorAboutToClose(Core::IEditor*)));
+}
+
+QList<QuickOpen::FilterEntry> CppCurrentDocumentFilter::matchesFor(const QString & origEntry)
+{
+    QString entry = trimWildcards(origEntry);
+    QList<QuickOpen::FilterEntry> goodEntries;
+    QList<QuickOpen::FilterEntry> betterEntries;
+    QStringMatcher matcher(entry, Qt::CaseInsensitive);
+    const QRegExp regexp("*"+entry+"*", Qt::CaseInsensitive, QRegExp::Wildcard);
+    if (!regexp.isValid())
+        return goodEntries;
+    bool hasWildcard = (entry.contains('*') || entry.contains('?'));
+
+    if (m_currentFileName.isEmpty())
+        return goodEntries;
+
+    if (m_itemsOfCurrentDoc.isEmpty()) {
+        Snapshot snapshot = m_modelManager->snapshot();
+        Document::Ptr thisDocument = snapshot.value(m_currentFileName);
+        if (thisDocument)
+            m_itemsOfCurrentDoc = search(thisDocument);
+    }
+
+    foreach (const ModelItemInfo & info, m_itemsOfCurrentDoc)
+    {
+        if ((hasWildcard && regexp.exactMatch(info.symbolName))
+            || (!hasWildcard && matcher.indexIn(info.symbolName) != -1))
+        {
+            QString symbolName = info.symbolName;// + (info.type == ModelItemInfo::Declaration ? ";" : " {...}");
+            QVariant id = qVariantFromValue(info);
+            QuickOpen::FilterEntry filterEntry(this, symbolName, id, info.icon);
+            filterEntry.extraInfo = info.symbolType;
+
+            if (info.symbolName.startsWith(entry))
+                betterEntries.append(filterEntry);
+            else
+                goodEntries.append(filterEntry);
+        }
+    }
+
+    // entries are unsorted by design!
+
+    betterEntries += goodEntries;
+    return betterEntries;
+}
+
+void CppCurrentDocumentFilter::accept(QuickOpen::FilterEntry selection) const
+{
+    ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData);
+    TextEditor::BaseTextEditor::openEditorAt(info.fileName, info.line);
+}
+
+void CppCurrentDocumentFilter::refresh(QFutureInterface<void> &future)
+{
+    Q_UNUSED(future);
+}
+
+void CppCurrentDocumentFilter::onDocumentUpdated(Document::Ptr doc)
+{
+    if (m_currentFileName == doc->fileName()) {
+        m_itemsOfCurrentDoc.clear();
+    }
+}
+
+void CppCurrentDocumentFilter::onCurrentEditorChanged(Core::IEditor * currentEditor)
+{
+    if (currentEditor) {
+        m_currentFileName = currentEditor->file()->fileName();
+    } else {
+        m_currentFileName.clear();
+    }
+    m_itemsOfCurrentDoc.clear();
+}
+
+void CppCurrentDocumentFilter::onEditorAboutToClose(Core::IEditor * editorAboutToClose)
+{
+    if (!editorAboutToClose) return;
+    if (m_currentFileName == editorAboutToClose->file()->fileName()) {
+        m_currentFileName.clear();
+        m_itemsOfCurrentDoc.clear();
+    }
+}
diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.h b/src/plugins/cpptools/cppcurrentdocumentfilter.h
new file mode 100644
index 00000000000..70820acac3f
--- /dev/null
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.h
@@ -0,0 +1,75 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+#ifndef CPPCURRENTDOCUMENTFILTER_H
+#define CPPCURRENTDOCUMENTFILTER_H
+
+#include "searchsymbols.h"
+#include <quickopen/iquickopenfilter.h>
+
+namespace Core {
+class EditorManager;
+class IEditor;
+}
+
+namespace CppTools {
+namespace Internal {
+
+class CppModelManager;
+
+class CppCurrentDocumentFilter : public  QuickOpen::IQuickOpenFilter
+{
+    Q_OBJECT
+
+public:
+    CppCurrentDocumentFilter(CppModelManager *manager, Core::EditorManager *editorManager);
+    ~CppCurrentDocumentFilter() {}
+
+    QString trName() const { return tr("Methods in current Document"); }
+    QString name() const { return QLatin1String("Methods in current Document"); }
+    Priority priority() const { return Medium; }
+    QList<QuickOpen::FilterEntry> matchesFor(const QString &entry);
+    void accept(QuickOpen::FilterEntry selection) const;
+    void refresh(QFutureInterface<void> &future);
+
+private slots:
+    void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
+    void onCurrentEditorChanged(Core::IEditor * currentEditor);
+    void onEditorAboutToClose(Core::IEditor * currentEditor);
+
+private:
+    CppModelManager * m_modelManager;
+    QString m_currentFileName;
+    QList<ModelItemInfo> m_itemsOfCurrentDoc;
+    SearchSymbols search;
+};
+
+} // namespace Internal
+} // namespace CppTools
+
+#endif // CPPCURRENTDOCUMENTFILTER_H
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 8a943ff4b79..057503b0b9b 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -11,6 +11,7 @@ DEFINES += CPPTOOLS_LIBRARY
 HEADERS += completionsettingspage.h \
     cppclassesfilter.h \
     cppcodecompletion.h \
+    cppcurrentdocumentfilter.h \
     cppfunctionsfilter.h \
     cppmodelmanager.h \
     cppmodelmanagerinterface.h \
@@ -26,6 +27,7 @@ HEADERS += completionsettingspage.h \
 SOURCES += completionsettingspage.cpp \
     cppclassesfilter.cpp \
     cppcodecompletion.cpp \
+    cppcurrentdocumentfilter.cpp \
     cppfunctionsfilter.cpp \
     cppmodelmanager.cpp \
     cppquickopenfilter.cpp \
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index 5ea430bf42a..e2ab98a8852 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -34,6 +34,7 @@
 #include "cppclassesfilter.h"
 #include "cppcodecompletion.h"
 #include "cppfunctionsfilter.h"
+#include "cppcurrentdocumentfilter.h"
 #include "cppmodelmanager.h"
 #include "cpptoolsconstants.h"
 #include "cppquickopenfilter.h"
@@ -92,6 +93,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
     addAutoReleasedObject(quickOpenFilter);
     addAutoReleasedObject(new CppClassesFilter(m_modelManager, core->editorManager()));
     addAutoReleasedObject(new CppFunctionsFilter(m_modelManager, core->editorManager()));
+    addAutoReleasedObject(new CppCurrentDocumentFilter(m_modelManager, core->editorManager()));
     addAutoReleasedObject(new CompletionSettingsPage(m_completion));
     addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));
 
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
index d0b32341318..58c47125229 100644
--- a/src/plugins/cpptools/searchsymbols.cpp
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -128,17 +128,20 @@ bool SearchSymbols::visit(Namespace *symbol)
     return false;
 }
 
-#if 0
 bool SearchSymbols::visit(Declaration *symbol)
 {
-    if (symbol->type()->isFunction()) {
-        QString name = scopedSymbolName(symbol);
-        QString type = overview.prettyType(symbol->type());
-        appendItems(name, type, ModelItemInfo::Method, symbol->fileName());
-    }
+    if (!(symbolsToSearchFor & Declarations))
+        return false;
+
+    QString name = symbolName(symbol);
+    QString scopedName = scopedSymbolName(name);
+    QString type = overview.prettyType(symbol->type(),
+                                       separateScope ? symbol->identity() : 0);
+    appendItem(separateScope ? type : scopedName,
+               separateScope ? _scope : type,
+               ModelItemInfo::Declaration, symbol);
     return false;
 }
-#endif
 
 bool SearchSymbols::visit(Class *symbol)
 {
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
index c57dee66208..a103e550ce5 100644
--- a/src/plugins/cpptools/searchsymbols.h
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -48,7 +48,7 @@ namespace Internal {
 
 struct ModelItemInfo
 {
-    enum ItemType { Enum, Class, Method };
+    enum ItemType { Enum, Class, Method, Declaration };
 
     ModelItemInfo()
     { }
@@ -80,9 +80,10 @@ class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList<
 {
 public:
     enum SymbolType {
-        Classes   = 0x1,
-        Functions = 0x2,
-        Enums     = 0x4
+        Classes      = 0x1,
+        Functions    = 0x2,
+        Enums        = 0x4,
+        Declarations = 0x8
     };
     Q_DECLARE_FLAGS(SymbolTypes, SymbolType)
 
@@ -106,10 +107,7 @@ protected:
     virtual bool visit(CPlusPlus::Enum *symbol);
     virtual bool visit(CPlusPlus::Function *symbol);
     virtual bool visit(CPlusPlus::Namespace *symbol);
-#if 0
-    // This visit method would make function declaration be included in QuickOpen
     virtual bool visit(CPlusPlus::Declaration *symbol);
-#endif
     virtual bool visit(CPlusPlus::Class *symbol);
 
     QString scopedSymbolName(const QString &symbolName) const;
-- 
GitLab