1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "symbolsfindfilter.h"
35 #include "cppmodelmanager.h"
36 #include "cpptoolsconstants.h"
38 #include <coreplugin/progressmanager/progressmanager.h>
39 #include <coreplugin/icore.h>
40 #include <find/textfindconstants.h>
41 #include <qtconcurrent/runextensions.h>
42 #include <projectexplorer/projectexplorer.h>
43 #include <projectexplorer/session.h>
44 #include <projectexplorer/project.h>
46 #include <QtCore/QSet>
47 #include <QtCore/QRegExp>
48 #include <QtGui/QGridLayout>
49 #include <QtGui/QLabel>
50 #include <QtGui/QButtonGroup>
52 using namespace CppTools;
53 using namespace CppTools::Internal;
56 const char * const SETTINGS_GROUP = "CppSymbols";
57 const char * const SETTINGS_SYMBOLTYPES = "SymbolsToSearchFor";
58 const char * const SETTINGS_SEARCHSCOPE = "SearchScope";
60 void runSearch(QFutureInterface<Find::SearchResultItem> &future,
61 QString txt, Find::FindFlags findFlags, CPlusPlus::Snapshot snapshot,
62 SearchSymbols *search, QSet<QString> fileNames)
64 future.setProgressRange(0, snapshot.size());
65 future.setProgressValue(0);
68 CPlusPlus::Snapshot::const_iterator it = snapshot.begin();
70 QString findString = (findFlags & Find::FindRegularExpression ? txt : QRegExp::escape(txt));
71 if (findFlags & Find::FindWholeWords)
72 findString = QString::fromLatin1("\\b%1\\b").arg(findString);
73 QRegExp matcher(findString, (findFlags & Find::FindCaseSensitively ? Qt::CaseSensitive : Qt::CaseInsensitive));
74 while (it != snapshot.end() && !future.isCanceled()) {
75 if (fileNames.isEmpty() || fileNames.contains(it.value()->fileName())) {
76 QVector<Find::SearchResultItem> resultItems;
77 QList<ModelItemInfo> modelInfos = (*search)(it.value());
78 foreach (const ModelItemInfo &info, modelInfos) {
79 int index = matcher.indexIn(info.symbolName);
81 QStringList path = info.fullyQualifiedName.mid(0, info.fullyQualifiedName.size() - 1);
82 Find::SearchResultItem item;
84 item.text = info.symbolName;
85 item.textMarkPos = -1;
86 item.textMarkLength = 0;
87 item.icon = info.icon;
89 item.userData = qVariantFromValue(info);
93 if (!resultItems.isEmpty())
94 future.reportResults(resultItems);
98 future.setProgressValue(progress);
103 SymbolsFindFilter::SymbolsFindFilter(CppModelManager *manager)
104 : m_manager(manager),
107 m_symbolsToSearch(SearchSymbols::AllTypes),
108 m_scope(SearchProjectsOnly)
110 // for disabling while parser is running
111 connect(Core::ICore::instance()->progressManager(), SIGNAL(taskStarted(QString)),
112 this, SLOT(onTaskStarted(QString)));
113 connect(Core::ICore::instance()->progressManager(), SIGNAL(allTasksFinished(QString)),
114 this, SLOT(onAllTasksFinished(QString)));
116 connect(&m_watcher, SIGNAL(finished()),
117 this, SLOT(finish()));
118 connect(&m_watcher, SIGNAL(resultsReadyAt(int,int)),
119 this, SLOT(addResults(int, int)));
122 QString SymbolsFindFilter::id() const
124 return QLatin1String("CppSymbols");
127 QString SymbolsFindFilter::displayName() const
129 return tr("C++ Symbols");
132 bool SymbolsFindFilter::isEnabled() const
134 return !m_isRunning && m_enabled;
137 bool SymbolsFindFilter::canCancel() const
142 void SymbolsFindFilter::cancel()
147 Find::FindFlags SymbolsFindFilter::supportedFindFlags() const
149 return Find::FindCaseSensitively | Find::FindRegularExpression | Find::FindWholeWords;
152 void SymbolsFindFilter::findAll(const QString &txt, Find::FindFlags findFlags)
156 Find::SearchResultWindow *window = Find::SearchResultWindow::instance();
157 Find::SearchResult *result = window->startNewSearch();
158 connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem)));
161 m_search.setSymbolsToSearchFor(m_symbolsToSearch);
162 m_search.setSeparateScope(true);
163 QSet<QString> projectFileNames;
164 if (m_scope == SymbolsFindFilter::SearchProjectsOnly) {
165 foreach (ProjectExplorer::Project *project,
166 ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projects()) {
167 projectFileNames += project->files(ProjectExplorer::Project::AllFiles).toSet();
171 m_watcher.setFuture(QtConcurrent::run<Find::SearchResultItem, QString,
172 Find::FindFlags, CPlusPlus::Snapshot,
173 SearchSymbols *, QSet<QString> >(runSearch, txt, findFlags, m_manager->snapshot(),
174 &m_search, projectFileNames));
175 Core::ICore::instance()->progressManager()->addTask(m_watcher.future(),
177 Find::Constants::TASK_SEARCH);
180 void SymbolsFindFilter::addResults(int begin, int end)
182 Find::SearchResultWindow *window = Find::SearchResultWindow::instance();
183 QList<Find::SearchResultItem> items;
184 for (int i = begin; i < end; ++i)
185 items << m_watcher.resultAt(i);
186 window->addResults(items, Find::SearchResultWindow::AddSorted);
189 void SymbolsFindFilter::finish()
191 Find::SearchResultWindow *window = Find::SearchResultWindow::instance();
192 window->finishSearch();
197 void SymbolsFindFilter::openEditor(const Find::SearchResultItem &item)
199 if (!item.userData.canConvert<ModelItemInfo>())
201 ModelItemInfo info = item.userData.value<ModelItemInfo>();
202 TextEditor::BaseTextEditorWidget::openEditorAt(info.fileName,
207 QWidget *SymbolsFindFilter::createConfigWidget()
209 return new SymbolsFindFilterConfigWidget(this);
212 void SymbolsFindFilter::writeSettings(QSettings *settings)
214 settings->beginGroup(QLatin1String(SETTINGS_GROUP));
215 settings->setValue(SETTINGS_SYMBOLTYPES, (int)m_symbolsToSearch);
216 settings->setValue(SETTINGS_SEARCHSCOPE, (int)m_scope);
217 settings->endGroup();
220 void SymbolsFindFilter::readSettings(QSettings *settings)
222 settings->beginGroup(QLatin1String(SETTINGS_GROUP));
223 m_symbolsToSearch = (SearchSymbols::SymbolTypes)settings->value(SETTINGS_SYMBOLTYPES,
224 (int)SearchSymbols::AllTypes).toInt();
225 m_scope = (SearchScope)settings->value(SETTINGS_SEARCHSCOPE,
226 (int)SearchProjectsOnly).toInt();
227 settings->endGroup();
228 emit symbolsToSearchChanged();
231 void SymbolsFindFilter::onTaskStarted(const QString &type)
233 if (type == CppTools::Constants::TASK_INDEX) {
239 void SymbolsFindFilter::onAllTasksFinished(const QString &type)
241 if (type == CppTools::Constants::TASK_INDEX) {
247 // #pragma mark -- SymbolsFindFilterConfigWidget
249 SymbolsFindFilterConfigWidget::SymbolsFindFilterConfigWidget(SymbolsFindFilter *filter)
252 connect(m_filter, SIGNAL(symbolsToSearchChanged()), this, SLOT(getState()));
254 QGridLayout *layout = new QGridLayout(this);
256 layout->setMargin(0);
258 QLabel *typeLabel = new QLabel(tr("Types:"));
259 layout->addWidget(typeLabel, 0, 0);
261 m_typeClasses = new QCheckBox(tr("Classes"));
262 layout->addWidget(m_typeClasses, 0, 1);
264 m_typeMethods = new QCheckBox(tr("Methods"));
265 layout->addWidget(m_typeMethods, 0, 2);
267 m_typeEnums = new QCheckBox(tr("Enums"));
268 layout->addWidget(m_typeEnums, 1, 1);
270 m_typeDeclarations = new QCheckBox(tr("Declarations"));
271 layout->addWidget(m_typeDeclarations, 1, 2);
273 // hacks to fix layouting:
274 typeLabel->setMinimumWidth(80);
275 typeLabel->setAlignment(Qt::AlignRight);
276 m_typeClasses->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
277 m_typeMethods->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
279 connect(m_typeClasses, SIGNAL(clicked(bool)), this, SLOT(setState()));
280 connect(m_typeMethods, SIGNAL(clicked(bool)), this, SLOT(setState()));
281 connect(m_typeEnums, SIGNAL(clicked(bool)), this, SLOT(setState()));
282 connect(m_typeDeclarations, SIGNAL(clicked(bool)), this, SLOT(setState()));
284 m_searchProjectsOnly = new QRadioButton(tr("Projects only"));
285 layout->addWidget(m_searchProjectsOnly, 2, 1);
287 m_searchGlobal = new QRadioButton(tr("All files"));
288 layout->addWidget(m_searchGlobal, 2, 2);
290 m_searchGroup = new QButtonGroup(this);
291 m_searchGroup->addButton(m_searchProjectsOnly);
292 m_searchGroup->addButton(m_searchGlobal);
294 connect(m_searchProjectsOnly, SIGNAL(clicked(bool)),
295 this, SLOT(setState()));
296 connect(m_searchGlobal, SIGNAL(clicked(bool)),
297 this, SLOT(setState()));
300 void SymbolsFindFilterConfigWidget::getState()
302 SearchSymbols::SymbolTypes symbols = m_filter->symbolsToSearch();
303 m_typeClasses->setChecked(symbols & SearchSymbols::Classes);
304 m_typeMethods->setChecked(symbols & SearchSymbols::Functions);
305 m_typeEnums->setChecked(symbols & SearchSymbols::Enums);
306 m_typeDeclarations->setChecked(symbols & SearchSymbols::Declarations);
308 SymbolsFindFilter::SearchScope scope = m_filter->searchScope();
309 m_searchProjectsOnly->setChecked(scope == SymbolsFindFilter::SearchProjectsOnly);
310 m_searchGlobal->setChecked(scope == SymbolsFindFilter::SearchGlobal);
313 void SymbolsFindFilterConfigWidget::setState() const
315 SearchSymbols::SymbolTypes symbols;
316 if (m_typeClasses->isChecked())
317 symbols |= SearchSymbols::Classes;
318 if (m_typeMethods->isChecked())
319 symbols |= SearchSymbols::Functions;
320 if (m_typeEnums->isChecked())
321 symbols |= SearchSymbols::Enums;
322 if (m_typeDeclarations->isChecked())
323 symbols |= SearchSymbols::Declarations;
324 m_filter->setSymbolsToSearch(symbols);
326 if (m_searchProjectsOnly->isChecked())
327 m_filter->setSearchScope(SymbolsFindFilter::SearchProjectsOnly);
329 m_filter->setSearchScope(SymbolsFindFilter::SearchGlobal);