Allow multiple file searches at the same time.

I.e. All Projects, Current Project, Files on File System, Current File.

Task-number: QTCREATORBUG-6101
Change-Id: Ib2ee95c5eca1ecc3ef3bf707705651471db6324a
Reviewed-by: Leandro Melo <leandro.melo@nokia.com>
This commit is contained in:
Eike Ziller
2011-12-12 15:16:49 +01:00
parent 5f6349907c
commit 3fc2ae7a49
6 changed files with 140 additions and 63 deletions

View File

@@ -582,6 +582,11 @@ QString SearchResult::textToReplace() const
return m_widget->textToReplace(); return m_widget->textToReplace();
} }
int SearchResult::count() const
{
return m_widget->count();
}
/*! /*!
\fn void SearchResult::addResult(const QString &fileName, int lineNumber, const QString &rowText, int searchTermStart, int searchTermLength, const QVariant &userData) \fn void SearchResult::addResult(const QString &fileName, int lineNumber, const QString &rowText, int searchTermStart, int searchTermLength, const QVariant &userData)
\brief Adds a single result line to the search results. \brief Adds a single result line to the search results.
@@ -599,6 +604,7 @@ void SearchResult::addResult(const QString &fileName, int lineNumber, const QStr
{ {
m_widget->addResult(fileName, lineNumber, lineText, m_widget->addResult(fileName, lineNumber, lineText,
searchTermStart, searchTermLength, userData); searchTermStart, searchTermLength, userData);
emit countChanged(m_widget->count());
} }
/*! /*!
@@ -611,6 +617,7 @@ void SearchResult::addResult(const QString &fileName, int lineNumber, const QStr
void SearchResult::addResults(const QList<SearchResultItem> &items, AddMode mode) void SearchResult::addResults(const QList<SearchResultItem> &items, AddMode mode)
{ {
m_widget->addResults(items, mode); m_widget->addResults(items, mode);
emit countChanged(m_widget->count());
} }
/*! /*!

View File

@@ -98,6 +98,7 @@ public:
void setUserData(const QVariant &data); void setUserData(const QVariant &data);
QVariant userData() const; QVariant userData() const;
QString textToReplace() const; QString textToReplace() const;
int count() const;
public slots: public slots:
void addResult(const QString &fileName, int lineNumber, const QString &lineText, void addResult(const QString &fileName, int lineNumber, const QString &lineText,
@@ -111,6 +112,7 @@ signals:
void replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems); void replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems);
void cancelled(); void cancelled();
void visibilityChanged(bool visible); void visibilityChanged(bool visible);
void countChanged(int count);
private: private:
SearchResult(Internal::SearchResultWidget *widget); SearchResult(Internal::SearchResultWidget *widget);

View File

@@ -31,6 +31,7 @@
**************************************************************************/ **************************************************************************/
#include "basefilefind.h" #include "basefilefind.h"
#include "basefilefind_p.h"
#include <aggregation/aggregate.h> #include <aggregation/aggregate.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -64,13 +65,10 @@
using namespace Utils; using namespace Utils;
using namespace Find; using namespace Find;
using namespace TextEditor; using namespace TextEditor;
using namespace TextEditor::Internal;
BaseFileFind::BaseFileFind() BaseFileFind::BaseFileFind()
: m_currentSearch(0), : m_resultLabel(0),
m_currentSearchCount(0),
m_watcher(0),
m_isSearching(false),
m_resultLabel(0),
m_filterCombo(0) m_filterCombo(0)
{ {
} }
@@ -81,13 +79,16 @@ BaseFileFind::~BaseFileFind()
bool BaseFileFind::isEnabled() const bool BaseFileFind::isEnabled() const
{ {
return !m_isSearching; return true;
} }
void BaseFileFind::cancel() void BaseFileFind::cancel()
{ {
QTC_ASSERT(m_watcher, return); SearchResult *search = qobject_cast<SearchResult *>(sender());
m_watcher->cancel(); QTC_ASSERT(search, return);
QFutureWatcher<FileSearchResultList> *watcher = watcherForSearch(search);
QTC_ASSERT(watcher, return);
watcher->cancel();
} }
QStringList BaseFileFind::fileNameFilters() const QStringList BaseFileFind::fileNameFilters() const
@@ -108,47 +109,60 @@ QStringList BaseFileFind::fileNameFilters() const
void BaseFileFind::runNewSearch(const QString &txt, Find::FindFlags findFlags, void BaseFileFind::runNewSearch(const QString &txt, Find::FindFlags findFlags,
SearchResultWindow::SearchMode searchMode) SearchResultWindow::SearchMode searchMode)
{ {
m_isSearching = true;
m_currentFindSupport = 0; m_currentFindSupport = 0;
emit changed();
if (m_filterCombo) if (m_filterCombo)
updateComboEntries(m_filterCombo, true); updateComboEntries(m_filterCombo, true);
delete m_watcher; QFutureWatcher<FileSearchResultList> *watcher = new QFutureWatcher<FileSearchResultList>();
m_watcher = new QFutureWatcher<FileSearchResultList>(); watcher->setPendingResultsLimit(1);
m_watcher->setPendingResultsLimit(1); connect(watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int)));
connect(m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int))); connect(watcher, SIGNAL(finished()), this, SLOT(searchFinished()));
connect(m_watcher, SIGNAL(finished()), this, SLOT(searchFinished())); SearchResult *search = Find::SearchResultWindow::instance()->startNewSearch(label(),
m_currentSearchCount = 0;
m_currentSearch = Find::SearchResultWindow::instance()->startNewSearch(label(),
toolTip().arg(Find::IFindFilter::descriptionForFindFlags(findFlags)), toolTip().arg(Find::IFindFilter::descriptionForFindFlags(findFlags)),
txt, searchMode, QString::fromLatin1("TextEditor")); txt, searchMode, QString::fromLatin1("TextEditor"));
m_currentSearch->setTextToReplace(txt); m_watchers.insert(watcher, search);
search->setTextToReplace(txt);
QVariantList searchParameters; QVariantList searchParameters;
searchParameters << qVariantFromValue(txt) << qVariantFromValue(findFlags); searchParameters << qVariantFromValue(txt) << qVariantFromValue(findFlags);
m_currentSearch->setUserData(searchParameters); search->setUserData(searchParameters);
connect(m_currentSearch, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem))); connect(search, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem)));
if (searchMode == SearchResultWindow::SearchAndReplace) { if (searchMode == SearchResultWindow::SearchAndReplace) {
connect(m_currentSearch, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)), connect(search, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)),
this, SLOT(doReplace(QString,QList<Find::SearchResultItem>))); this, SLOT(doReplace(QString,QList<Find::SearchResultItem>)));
} }
connect(m_currentSearch, SIGNAL(visibilityChanged(bool)), this, SLOT(hideHighlightAll(bool))); connect(search, SIGNAL(visibilityChanged(bool)), this, SLOT(hideHighlightAll(bool)));
CountingLabel *label = new CountingLabel;
connect(search, SIGNAL(countChanged(int)), label, SLOT(updateCount(int)));
Find::SearchResultWindow::instance()->popup(true); Find::SearchResultWindow::instance()->popup(true);
if (findFlags & Find::FindRegularExpression) { if (findFlags & Find::FindRegularExpression) {
m_watcher->setFuture(Utils::findInFilesRegExp(txt, files(), watcher->setFuture(Utils::findInFilesRegExp(txt, files(),
textDocumentFlagsForFindFlags(findFlags), ITextEditor::openedTextEditorsContents())); textDocumentFlagsForFindFlags(findFlags), ITextEditor::openedTextEditorsContents()));
} else { } else {
m_watcher->setFuture(Utils::findInFiles(txt, files(), watcher->setFuture(Utils::findInFiles(txt, files(),
textDocumentFlagsForFindFlags(findFlags), ITextEditor::openedTextEditorsContents())); textDocumentFlagsForFindFlags(findFlags), ITextEditor::openedTextEditorsContents()));
} }
connect(m_currentSearch, SIGNAL(cancelled()), this, SLOT(cancel())); connect(search, SIGNAL(cancelled()), this, SLOT(cancel()));
Core::FutureProgress *progress = Core::FutureProgress *progress =
Core::ICore::instance()->progressManager()->addTask(m_watcher->future(), Core::ICore::instance()->progressManager()->addTask(watcher->future(),
tr("Search"), tr("Search"),
Constants::TASK_SEARCH); Constants::TASK_SEARCH);
progress->setWidget(createProgressWidget());
progress->setWidget(label);
connect(progress, SIGNAL(clicked()), Find::SearchResultWindow::instance(), SLOT(popup())); connect(progress, SIGNAL(clicked()), Find::SearchResultWindow::instance(), SLOT(popup()));
} }
QFutureWatcher<FileSearchResultList> *BaseFileFind::watcherForSearch(SearchResult *search)
{
if (!search)
return 0;
QMapIterator<QFutureWatcher<Utils::FileSearchResultList> *, QPointer<Find::SearchResult> > it(m_watchers);
while (it.hasNext()) {
it.next();
if (it.value() == search)
return it.key();
}
return 0;
}
void BaseFileFind::findAll(const QString &txt, Find::FindFlags findFlags) void BaseFileFind::findAll(const QString &txt, Find::FindFlags findFlags)
{ {
runNewSearch(txt, findFlags, SearchResultWindow::SearchOnly); runNewSearch(txt, findFlags, SearchResultWindow::SearchOnly);
@@ -171,11 +185,15 @@ void BaseFileFind::doReplace(const QString &text,
} }
void BaseFileFind::displayResult(int index) { void BaseFileFind::displayResult(int index) {
if (!m_currentSearch) { QFutureWatcher<FileSearchResultList> *watcher =
m_watcher->cancel(); static_cast<QFutureWatcher<FileSearchResultList> *>(sender());
SearchResult *search = m_watchers.value(watcher);
if (!search) {
// search was removed from search history while the search is running
watcher->cancel();
return; return;
} }
Utils::FileSearchResultList results = m_watcher->resultAt(index); Utils::FileSearchResultList results = watcher->resultAt(index);
QList<Find::SearchResultItem> items; QList<Find::SearchResultItem> items;
foreach (const Utils::FileSearchResult &result, results) { foreach (const Utils::FileSearchResult &result, results) {
Find::SearchResultItem item; Find::SearchResultItem item;
@@ -188,36 +206,18 @@ void BaseFileFind::displayResult(int index) {
item.userData = result.regexpCapturedTexts; item.userData = result.regexpCapturedTexts;
items << item; items << item;
} }
m_currentSearch->addResults(items, Find::SearchResult::AddOrdered); search->addResults(items, Find::SearchResult::AddOrdered);
m_currentSearchCount += items.count();
if (m_resultLabel)
m_resultLabel->setText(tr("%1 found").arg(m_currentSearchCount));
} }
void BaseFileFind::searchFinished() void BaseFileFind::searchFinished()
{ {
if (m_currentSearch) QFutureWatcher<FileSearchResultList> *watcher =
m_currentSearch->finishSearch(); static_cast<QFutureWatcher<FileSearchResultList> *>(sender());
m_currentSearch = 0; SearchResult *search = m_watchers.value(watcher);
m_isSearching = false; if (search)
m_resultLabel = 0; search->finishSearch();
m_watcher->deleteLater(); m_watchers.remove(watcher);
m_watcher = 0; watcher->deleteLater();
emit changed();
}
QWidget *BaseFileFind::createProgressWidget()
{
m_resultLabel = new QLabel;
m_resultLabel->setAlignment(Qt::AlignCenter);
// ### TODO this setup should be done by style
QFont f = m_resultLabel->font();
f.setBold(true);
f.setPointSizeF(StyleHelper::sidebarFontSize());
m_resultLabel->setFont(f);
m_resultLabel->setPalette(StyleHelper::sidebarFontPalette(m_resultLabel->palette()));
m_resultLabel->setText(tr("%1 found").arg(m_currentSearchCount));
return m_resultLabel;
} }
QWidget *BaseFileFind::createPatternWidget() QWidget *BaseFileFind::createPatternWidget()
@@ -360,3 +360,20 @@ QStringList BaseFileFind::replaceAll(const QString &text,
return changes.keys(); return changes.keys();
} }
CountingLabel::CountingLabel()
{
setAlignment(Qt::AlignCenter);
// ### TODO this setup should be done by style
QFont f = font();
f.setBold(true);
f.setPointSizeF(StyleHelper::sidebarFontSize());
setFont(f);
setPalette(StyleHelper::sidebarFontPalette(palette()));
updateCount(0);
}
void CountingLabel::updateCount(int count)
{
setText(tr("%1 found").arg(count));
}

View File

@@ -99,15 +99,11 @@ private slots:
void hideHighlightAll(bool visible); void hideHighlightAll(bool visible);
private: private:
QWidget *createProgressWidget();
void runNewSearch(const QString &txt, Find::FindFlags findFlags, void runNewSearch(const QString &txt, Find::FindFlags findFlags,
Find::SearchResultWindow::SearchMode searchMode); Find::SearchResultWindow::SearchMode searchMode);
QFutureWatcher<Utils::FileSearchResultList> *watcherForSearch(Find::SearchResult *search);
QPointer<Find::SearchResult> m_currentSearch; QMap<QFutureWatcher<Utils::FileSearchResultList> *, QPointer<Find::SearchResult> > m_watchers;
int m_currentSearchCount;
QFutureWatcher<Utils::FileSearchResultList> *m_watcher;
bool m_isSearching;
QPointer<Find::IFindSupport> m_currentFindSupport; QPointer<Find::IFindSupport> m_currentFindSupport;
QLabel *m_resultLabel; QLabel *m_resultLabel;

View File

@@ -0,0 +1,54 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef BASEFILEFIND_P_H
#define BASEFILEFIND_P_H
#include <QtGui/QLabel>
namespace TextEditor {
namespace Internal {
class CountingLabel : public QLabel
{
Q_OBJECT
public:
CountingLabel();
public slots:
void updateCount(int count);
};
} // namespace Internal
} // namespace TextEditor
#endif // BASEFILEFIND_P_H

View File

@@ -224,7 +224,8 @@ HEADERS += texteditorplugin.h \
typingsettings.h \ typingsettings.h \
icodestylepreferences.h \ icodestylepreferences.h \
codestylepool.h \ codestylepool.h \
codestyleeditor.h codestyleeditor.h \
basefilefind_p.h
FORMS += \ FORMS += \
displaysettingspage.ui \ displaysettingspage.ui \