diff --git a/src/plugins/cpptools/cppincludesfilter.cpp b/src/plugins/cpptools/cppincludesfilter.cpp new file mode 100644 index 00000000000..fb5b5647dae --- /dev/null +++ b/src/plugins/cpptools/cppincludesfilter.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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 "cppincludesfilter.h" + +#include "cppmodelmanager.h" + +#include +#include +#include +#include + +#include + +using namespace Core; +using namespace CppTools; +using namespace CppTools::Internal; + +namespace CppTools { +namespace Internal { + +class CppIncludesIterator : public BaseFileFilter::Iterator +{ +public: + CppIncludesIterator(CPlusPlus::Snapshot snapshot, const QSet &seedPaths); + + void toFront(); + bool hasNext() const; + QString next(); + QString filePath() const; + QString fileName() const; + +private: + void fetchMore(); + + CPlusPlus::Snapshot m_snapshot; + QSet m_paths; + QSet m_queuedPaths; + QSet m_allResultPaths; + QStringList m_resultQueue; + QString m_currentPath; +}; + +} // Internal +} // CppTools + + +CppIncludesIterator::CppIncludesIterator(CPlusPlus::Snapshot snapshot, + const QSet &seedPaths) + : m_snapshot(snapshot), + m_paths(seedPaths) +{ + toFront(); +} + +void CppIncludesIterator::toFront() +{ + m_queuedPaths = m_paths; + m_allResultPaths.clear(); + m_resultQueue.clear(); + fetchMore(); +} + +bool CppIncludesIterator::hasNext() const +{ + return !m_resultQueue.isEmpty(); +} + +QString CppIncludesIterator::next() +{ + if (m_resultQueue.isEmpty()) + return QString(); + m_currentPath = m_resultQueue.takeFirst(); + if (m_resultQueue.isEmpty()) + fetchMore(); + return m_currentPath; +} + +QString CppIncludesIterator::filePath() const +{ + return m_currentPath; +} + +QString CppIncludesIterator::fileName() const +{ + return QFileInfo(m_currentPath).fileName(); +} + +void CppIncludesIterator::fetchMore() +{ + while (!m_queuedPaths.isEmpty() && m_resultQueue.isEmpty()) { + const QString filePath = *m_queuedPaths.begin(); + m_queuedPaths.remove(filePath); + CPlusPlus::Document::Ptr doc = m_snapshot.document(filePath); + if (!doc) + continue; + foreach (const QString &includedPath, doc->includedFiles()) { + if (!m_allResultPaths.contains(includedPath)) { + m_allResultPaths.insert(includedPath); + m_queuedPaths.insert(includedPath); + m_resultQueue.append(includedPath); + } + } + } +} + +CppIncludesFilter::CppIncludesFilter() + : m_needsUpdate(true) +{ + setId("All Included C/C++ Files"); + setDisplayName(tr("All Included C/C++ Files")); + setShortcutString(QString(QLatin1Char('a'))); + setIncludedByDefault(true); + setPriority(ILocatorFilter::Low); + + connect(ProjectExplorer::ProjectExplorerPlugin::instance(), + &ProjectExplorer::ProjectExplorerPlugin::fileListChanged, + this, &CppIncludesFilter::markOutdated); + connect(CppModelManager::instance(), &CppModelManager::documentUpdated, + this, &CppIncludesFilter::markOutdated); + connect(CppModelManager::instance(), &CppModelManager::aboutToRemoveFiles, + this, &CppIncludesFilter::markOutdated); + connect(Core::DocumentModel::model(), &QAbstractItemModel::rowsInserted, + this, &CppIncludesFilter::markOutdated); + connect(Core::DocumentModel::model(), &QAbstractItemModel::rowsRemoved, + this, &CppIncludesFilter::markOutdated); + connect(Core::DocumentModel::model(), &QAbstractItemModel::dataChanged, + this, &CppIncludesFilter::markOutdated); + connect(Core::DocumentModel::model(), &QAbstractItemModel::modelReset, + this, &CppIncludesFilter::markOutdated); +} + +void CppIncludesFilter::prepareSearch(const QString &entry) +{ + Q_UNUSED(entry) + if (m_needsUpdate) { + m_needsUpdate = false; + QSet seedPaths; + foreach (ProjectExplorer::Project *project, ProjectExplorer::SessionManager::projects()) { + foreach (const QString &filePath, project->files(ProjectExplorer::Project::AllFiles)) + seedPaths.insert(filePath); + } + foreach (Core::DocumentModel::Entry *entry, Core::DocumentModel::entries()) { + if (entry) + seedPaths.insert(entry->fileName()); + } + CPlusPlus::Snapshot snapshot = CppModelManager::instance()->snapshot(); + setFileIterator(new CppIncludesIterator(snapshot, seedPaths)); + } + BaseFileFilter::prepareSearch(entry); +} + +void CppIncludesFilter::refresh(QFutureInterface &future) +{ + Q_UNUSED(future) + QTimer::singleShot(0, this, SLOT(markOutdated())); +} + +void CppIncludesFilter::markOutdated() +{ + m_needsUpdate = true; + setFileIterator(0); // clean up +} diff --git a/src/plugins/cpptools/cppincludesfilter.h b/src/plugins/cpptools/cppincludesfilter.h new file mode 100644 index 00000000000..8de49179446 --- /dev/null +++ b/src/plugins/cpptools/cppincludesfilter.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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 CPPINCLUDESFILTER_H +#define CPPINCLUDESFILTER_H + +#include + +namespace CppTools { +namespace Internal { + +class CppIncludesFilter : public Core::BaseFileFilter +{ + Q_OBJECT + +public: + CppIncludesFilter(); + + // ILocatorFilter interface +public: + void prepareSearch(const QString &entry); + void refresh(QFutureInterface &future); + +private slots: + void markOutdated(); + +private: + bool m_needsUpdate; +}; + +} // namespace Internal +} // namespace CppTools + +#endif // CPPINCLUDESFILTER_H diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index 4408a94714b..0526b14712b 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -28,6 +28,7 @@ HEADERS += \ cppfilesettingspage.h \ cppfindreferences.h \ cppfunctionsfilter.h \ + cppincludesfilter.h \ cppindexingsupport.h \ cpplocalsymbols.h \ cpplocatordata.h \ @@ -89,6 +90,7 @@ SOURCES += \ cppfilesettingspage.cpp \ cppfindreferences.cpp \ cppfunctionsfilter.cpp \ + cppincludesfilter.cpp \ cppindexingsupport.cpp \ cpplocalsymbols.cpp \ cpplocatordata.cpp \ diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 8977c85f609..8e7e0837338 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -46,6 +46,7 @@ QtcPlugin { "cppfilesettingspage.cpp", "cppfilesettingspage.h", "cppfilesettingspage.ui", "cppfindreferences.cpp", "cppfindreferences.h", "cppfunctionsfilter.cpp", "cppfunctionsfilter.h", + "cppincludesfilter.cpp", "cppincludesfilter.h", "cppindexingsupport.cpp", "cppindexingsupport.h", "cpplocalsymbols.cpp", "cpplocalsymbols.h", "cpplocatordata.cpp", "cpplocatordata.h", diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index fdd2f51de77..532ef6b02a3 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -44,6 +44,7 @@ #include "cpptoolsreuse.h" #include "cppprojectfile.h" #include "cpplocatordata.h" +#include "cppincludesfilter.h" #include #include @@ -160,6 +161,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) addAutoReleasedObject(locatorData); addAutoReleasedObject(new CppLocatorFilter(locatorData)); addAutoReleasedObject(new CppClassesFilter(locatorData)); + addAutoReleasedObject(new CppIncludesFilter); addAutoReleasedObject(new CppFunctionsFilter(locatorData)); addAutoReleasedObject(new CppCurrentDocumentFilter(modelManager, m_stringTable)); addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));