OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / cpptools / symbolsfindfilter.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
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.
18 **
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.
22 **
23 ** Other Usage
24 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "symbolsfindfilter.h"
34
35 #include "cppmodelmanager.h"
36 #include "cpptoolsconstants.h"
37
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>
45
46 #include <QtCore/QSet>
47 #include <QtCore/QRegExp>
48 #include <QtGui/QGridLayout>
49 #include <QtGui/QLabel>
50 #include <QtGui/QButtonGroup>
51
52 using namespace CppTools;
53 using namespace CppTools::Internal;
54
55 namespace {
56     const char * const SETTINGS_GROUP = "CppSymbols";
57     const char * const SETTINGS_SYMBOLTYPES = "SymbolsToSearchFor";
58     const char * const SETTINGS_SEARCHSCOPE = "SearchScope";
59
60     void runSearch(QFutureInterface<Find::SearchResultItem> &future,
61               QString txt, Find::FindFlags findFlags, CPlusPlus::Snapshot snapshot,
62               SearchSymbols *search, QSet<QString> fileNames)
63     {
64         future.setProgressRange(0, snapshot.size());
65         future.setProgressValue(0);
66         int progress = 0;
67
68         CPlusPlus::Snapshot::const_iterator it = snapshot.begin();
69
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);
80                     if (index != -1) {
81                         QStringList path = info.fullyQualifiedName.mid(0, info.fullyQualifiedName.size() - 1);
82                         Find::SearchResultItem item;
83                         item.path = path;
84                         item.text = info.symbolName;
85                         item.textMarkPos = -1;
86                         item.textMarkLength = 0;
87                         item.icon = info.icon;
88                         item.lineNumber = -1;
89                         item.userData = qVariantFromValue(info);
90                         resultItems << item;
91                     }
92                 }
93                 if (!resultItems.isEmpty())
94                     future.reportResults(resultItems);
95             }
96             ++it;
97             ++progress;
98             future.setProgressValue(progress);
99         }
100     }
101 } //namespace
102
103 SymbolsFindFilter::SymbolsFindFilter(CppModelManager *manager)
104     : m_manager(manager),
105     m_isRunning(false),
106     m_enabled(true),
107     m_symbolsToSearch(SearchSymbols::AllTypes),
108     m_scope(SearchProjectsOnly)
109 {
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)));
115
116     connect(&m_watcher, SIGNAL(finished()),
117             this, SLOT(finish()));
118     connect(&m_watcher, SIGNAL(resultsReadyAt(int,int)),
119             this, SLOT(addResults(int, int)));
120 }
121
122 QString SymbolsFindFilter::id() const
123 {
124     return QLatin1String("CppSymbols");
125 }
126
127 QString SymbolsFindFilter::displayName() const
128 {
129     return tr("C++ Symbols");
130 }
131
132 bool SymbolsFindFilter::isEnabled() const
133 {
134     return !m_isRunning && m_enabled;
135 }
136
137 bool SymbolsFindFilter::canCancel() const
138 {
139     return m_isRunning;
140 }
141
142 void SymbolsFindFilter::cancel()
143 {
144     m_watcher.cancel();
145 }
146
147 Find::FindFlags SymbolsFindFilter::supportedFindFlags() const
148 {
149     return Find::FindCaseSensitively | Find::FindRegularExpression | Find::FindWholeWords;
150 }
151
152 void SymbolsFindFilter::findAll(const QString &txt, Find::FindFlags findFlags)
153 {
154     m_isRunning = true;
155     emit changed();
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)));
159     window->popup(true);
160
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();
168         }
169     }
170
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(),
176                                                         tr("Searching"),
177                                                         Find::Constants::TASK_SEARCH);
178 }
179
180 void SymbolsFindFilter::addResults(int begin, int end)
181 {
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);
187 }
188
189 void SymbolsFindFilter::finish()
190 {
191     Find::SearchResultWindow *window = Find::SearchResultWindow::instance();
192     window->finishSearch();
193     m_isRunning = false;
194     emit changed();
195 }
196
197 void SymbolsFindFilter::openEditor(const Find::SearchResultItem &item)
198 {
199     if (!item.userData.canConvert<ModelItemInfo>())
200         return;
201     ModelItemInfo info = item.userData.value<ModelItemInfo>();
202     TextEditor::BaseTextEditorWidget::openEditorAt(info.fileName,
203                                              info.line,
204                                              info.column);
205 }
206
207 QWidget *SymbolsFindFilter::createConfigWidget()
208 {
209     return new SymbolsFindFilterConfigWidget(this);
210 }
211
212 void SymbolsFindFilter::writeSettings(QSettings *settings)
213 {
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();
218 }
219
220 void SymbolsFindFilter::readSettings(QSettings *settings)
221 {
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();
229 }
230
231 void SymbolsFindFilter::onTaskStarted(const QString &type)
232 {
233     if (type == CppTools::Constants::TASK_INDEX) {
234         m_enabled = false;
235         emit changed();
236     }
237 }
238
239 void SymbolsFindFilter::onAllTasksFinished(const QString &type)
240 {
241     if (type == CppTools::Constants::TASK_INDEX) {
242         m_enabled = true;
243         emit changed();
244     }
245 }
246
247 // #pragma mark -- SymbolsFindFilterConfigWidget
248
249 SymbolsFindFilterConfigWidget::SymbolsFindFilterConfigWidget(SymbolsFindFilter *filter)
250     : m_filter(filter)
251 {
252     connect(m_filter, SIGNAL(symbolsToSearchChanged()), this, SLOT(getState()));
253
254     QGridLayout *layout = new QGridLayout(this);
255     setLayout(layout);
256     layout->setMargin(0);
257
258     QLabel *typeLabel = new QLabel(tr("Types:"));
259     layout->addWidget(typeLabel, 0, 0);
260
261     m_typeClasses = new QCheckBox(tr("Classes"));
262     layout->addWidget(m_typeClasses, 0, 1);
263
264     m_typeMethods = new QCheckBox(tr("Methods"));
265     layout->addWidget(m_typeMethods, 0, 2);
266
267     m_typeEnums = new QCheckBox(tr("Enums"));
268     layout->addWidget(m_typeEnums, 1, 1);
269
270     m_typeDeclarations = new QCheckBox(tr("Declarations"));
271     layout->addWidget(m_typeDeclarations, 1, 2);
272
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);
278
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()));
283
284     m_searchProjectsOnly = new QRadioButton(tr("Projects only"));
285     layout->addWidget(m_searchProjectsOnly, 2, 1);
286
287     m_searchGlobal = new QRadioButton(tr("All files"));
288     layout->addWidget(m_searchGlobal, 2, 2);
289
290     m_searchGroup = new QButtonGroup(this);
291     m_searchGroup->addButton(m_searchProjectsOnly);
292     m_searchGroup->addButton(m_searchGlobal);
293
294     connect(m_searchProjectsOnly, SIGNAL(clicked(bool)),
295             this, SLOT(setState()));
296     connect(m_searchGlobal, SIGNAL(clicked(bool)),
297             this, SLOT(setState()));
298 }
299
300 void SymbolsFindFilterConfigWidget::getState()
301 {
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);
307
308     SymbolsFindFilter::SearchScope scope = m_filter->searchScope();
309     m_searchProjectsOnly->setChecked(scope == SymbolsFindFilter::SearchProjectsOnly);
310     m_searchGlobal->setChecked(scope == SymbolsFindFilter::SearchGlobal);
311 }
312
313 void SymbolsFindFilterConfigWidget::setState() const
314 {
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);
325
326     if (m_searchProjectsOnly->isChecked())
327         m_filter->setSearchScope(SymbolsFindFilter::SearchProjectsOnly);
328     else
329         m_filter->setSearchScope(SymbolsFindFilter::SearchGlobal);
330 }