diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp index 13f3883ae868f1081be0cf13729b88182d197ade..38f01c0028fd8e26fa89513251fd58407e5ab391 100644 --- a/src/libs/utils/filesearch.cpp +++ b/src/libs/utils/filesearch.cpp @@ -208,6 +208,8 @@ void runFileSearch(QFutureInterface<FileSearchResultList> &future, if (!future.isCanceled()) future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched)); delete files; + if (future.isPaused()) + future.waitForResume(); } void runFileSearchRegExp(QFutureInterface<FileSearchResultList> &future, @@ -290,6 +292,8 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResultList> &future, if (!future.isCanceled()) future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched)); delete files; + if (future.isPaused()) + future.waitForResume(); } } // namespace diff --git a/src/plugins/coreplugin/infobar.cpp b/src/plugins/coreplugin/infobar.cpp index f0e8e39b5f7bd8e634ae325832b7cb89dc6d17c3..6e3c78fdcb3643261eb6d77834fdc3b95ab57b48 100644 --- a/src/plugins/coreplugin/infobar.cpp +++ b/src/plugins/coreplugin/infobar.cpp @@ -66,6 +66,13 @@ void InfoBarEntry::setCancelButtonInfo(QObject *_object, const char *_member) cancelButtonPressMember = _member; } +void InfoBarEntry::setCancelButtonInfo(const QString &_cancelButtonText, QObject *_object, const char *_member) +{ + cancelButtonText = _cancelButtonText; + cancelObject = _object; + cancelButtonPressMember = _member; +} + void InfoBar::addInfo(const InfoBarEntry &info) { @@ -169,15 +176,22 @@ void InfoBarDisplay::update() } QToolButton *infoWidgetCloseButton = new QToolButton; - infoWidgetCloseButton->setAutoRaise(true); - infoWidgetCloseButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_CLEAR))); - infoWidgetCloseButton->setToolTip(tr("Close")); infoWidgetCloseButton->setProperty("infoId", info.id); - connect(infoWidgetCloseButton, SIGNAL(clicked()), SLOT(cancelButtonClicked())); + // need to connect to cancelObjectbefore connecting to cancelButtonClicked, + // because the latter removes the button and with it any connect if (info.cancelObject) connect(infoWidgetCloseButton, SIGNAL(clicked()), info.cancelObject, info.cancelButtonPressMember); + connect(infoWidgetCloseButton, SIGNAL(clicked()), SLOT(cancelButtonClicked())); + + if (info.cancelButtonText.isEmpty()) { + infoWidgetCloseButton->setAutoRaise(true); + infoWidgetCloseButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_CLEAR))); + infoWidgetCloseButton->setToolTip(tr("Close")); + } else { + infoWidgetCloseButton->setText(info.cancelButtonText); + } hbox->addWidget(infoWidgetCloseButton); diff --git a/src/plugins/coreplugin/infobar.h b/src/plugins/coreplugin/infobar.h index 43be05cbf75ecdd9ddb74cb0334f67bed314e7d1..4bdd92438350e9d34386f7f96a6c4e1670c6e828 100644 --- a/src/plugins/coreplugin/infobar.h +++ b/src/plugins/coreplugin/infobar.h @@ -53,6 +53,7 @@ public: InfoBarEntry(const InfoBarEntry &other) { *this = other; } void setCustomButtonInfo(const QString &_buttonText, QObject *_object, const char *_member); void setCancelButtonInfo(QObject *_object, const char *_member); + void setCancelButtonInfo(const QString &_cancelButtonText, QObject *_object, const char *_member); private: QString id; @@ -60,6 +61,7 @@ private: QString buttonText; QObject *object; const char *buttonPressMember; + QString cancelButtonText; QObject *cancelObject; const char *cancelButtonPressMember; friend class InfoBar; diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index a5d59f30c6c7e1bd09fe65ccb07888773c3572de..98a907b3f3e038cbe0b64c02ffb58abf5f254edf 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -113,6 +113,8 @@ public: QList<Usage> operator()(const QString &fileName) { QList<Usage> usages; + if (future->isPaused()) + future->waitForResume(); if (future->isCanceled()) return usages; const Identifier *symbolId = symbol->identifier(); @@ -145,6 +147,8 @@ public: usages = process.usages(); } + if (future->isPaused()) + future->waitForResume(); return usages; } }; @@ -252,6 +256,7 @@ void CppFindReferences::findUsages(CPlusPlus::Symbol *symbol, search->setTextToReplace(replacement); connect(search, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)), SLOT(onReplaceButtonClicked(QString,QList<Find::SearchResultItem>))); + connect(search, SIGNAL(paused(bool)), this, SLOT(setPaused(bool))); search->setSearchAgainSupported(true); connect(search, SIGNAL(searchAgainRequested()), this, SLOT(searchAgain())); CppFindReferencesParameters parameters; @@ -293,7 +298,7 @@ void CppFindReferences::findAll_helper(Find::SearchResult *search) Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching"), CppTools::Constants::TASK_SEARCH); - connect(progress, SIGNAL(clicked()), Find::SearchResultWindow::instance(), SLOT(popup())); + connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } void CppFindReferences::onReplaceButtonClicked(const QString &text, @@ -511,6 +516,16 @@ void CppFindReferences::cancel() watcher->cancel(); } +void CppFindReferences::setPaused(bool paused) +{ + Find::SearchResult *search = qobject_cast<Find::SearchResult *>(sender()); + QTC_ASSERT(search, return); + QFutureWatcher<Usage> *watcher = m_watchers.key(search); + QTC_ASSERT(watcher, return); + if (!paused || watcher->isRunning()) // guard against pausing when the search is finished + watcher->setPaused(paused); +} + void CppFindReferences::openEditor(const Find::SearchResultItem &item) { if (item.path.size() > 0) { @@ -545,6 +560,8 @@ public: QList<Usage> operator()(const QString &fileName) { QList<Usage> usages; + if (future->isPaused()) + future->waitForResume(); if (future->isCanceled()) return usages; @@ -566,6 +583,8 @@ public: } } + if (future->isPaused()) + future->waitForResume(); return usages; } @@ -638,6 +657,7 @@ void CppFindReferences::findMacroUses(const Macro ¯o) connect(search, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem))); connect(search, SIGNAL(cancelled()), this, SLOT(cancel())); + connect(search, SIGNAL(paused(bool)), this, SLOT(setPaused(bool))); const Snapshot snapshot = _modelManager->snapshot(); const CppModelManagerInterface::WorkingCopy workingCopy = _modelManager->workingCopy(); @@ -662,7 +682,7 @@ void CppFindReferences::findMacroUses(const Macro ¯o) Core::ProgressManager *progressManager = Core::ICore::progressManager(); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching"), CppTools::Constants::TASK_SEARCH); - connect(progress, SIGNAL(clicked()), Find::SearchResultWindow::instance(), SLOT(popup())); + connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } DependencyTable CppFindReferences::updateDependencyTable(CPlusPlus::Snapshot snapshot) diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h index 5d13f12cf0c8100e154f56ce5a651655b00fc989..dfa7c114d0db6869a092daf16a8c29430367f702 100644 --- a/src/plugins/cpptools/cppfindreferences.h +++ b/src/plugins/cpptools/cppfindreferences.h @@ -89,6 +89,7 @@ private Q_SLOTS: void displayResults(int first, int last); void searchFinished(); void cancel(); + void setPaused(bool paused); void openEditor(const Find::SearchResultItem &item); void onReplaceButtonClicked(const QString &text, const QList<Find::SearchResultItem> &items); void searchAgain(); diff --git a/src/plugins/cpptools/symbolsfindfilter.cpp b/src/plugins/cpptools/symbolsfindfilter.cpp index 4356af9a221d2a9006b5fa0a5c0ec0febb75db53..f2c56b180f51393089602997929e9d83da12df90 100644 --- a/src/plugins/cpptools/symbolsfindfilter.cpp +++ b/src/plugins/cpptools/symbolsfindfilter.cpp @@ -36,6 +36,7 @@ #include "cpptoolsconstants.h" #include <coreplugin/progressmanager/progressmanager.h> +#include <coreplugin/progressmanager/futureprogress.h> #include <coreplugin/icore.h> #include <find/textfindconstants.h> #include <utils/runextensions.h> @@ -77,7 +78,11 @@ namespace { findString = QString::fromLatin1("\\b%1\\b").arg(findString); QRegExp matcher(findString, (parameters.flags & Find::FindCaseSensitively ? Qt::CaseSensitive : Qt::CaseInsensitive)); - while (it != snapshot.end() && !future.isCanceled()) { + while (it != snapshot.end()) { + if (future.isPaused()) + future.waitForResume(); + if (future.isCanceled()) + break; if (fileNames.isEmpty() || fileNames.contains(it.value()->fileName())) { QVector<Find::SearchResultItem> resultItems; QList<ModelItemInfo> modelInfos = search(it.value()); @@ -104,6 +109,8 @@ namespace { ++progress; future.setProgressValue(progress); } + if (future.isPaused()) + future.waitForResume(); } } //namespace @@ -144,6 +151,16 @@ void SymbolsFindFilter::cancel() watcher->cancel(); } +void SymbolsFindFilter::setPaused(bool paused) +{ + Find::SearchResult *search = qobject_cast<Find::SearchResult *>(sender()); + QTC_ASSERT(search, return); + QFutureWatcher<Find::SearchResultItem> *watcher = m_watchers.key(search); + QTC_ASSERT(watcher, return); + if (!paused || watcher->isRunning()) // guard against pausing when the search is finished + watcher->setPaused(paused); +} + Find::FindFlags SymbolsFindFilter::supportedFindFlags() const { return Find::FindCaseSensitively | Find::FindRegularExpression | Find::FindWholeWords; @@ -157,6 +174,7 @@ void SymbolsFindFilter::findAll(const QString &txt, Find::FindFlags findFlags) connect(search, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem))); connect(search, SIGNAL(cancelled()), this, SLOT(cancel())); + connect(search, SIGNAL(paused(bool)), this, SLOT(setPaused(bool))); connect(search, SIGNAL(searchAgainRequested()), this, SLOT(searchAgain())); connect(this, SIGNAL(enabledChanged(bool)), search, SLOT(setSearchAgainEnabled(bool))); window->popup(true); @@ -190,9 +208,10 @@ void SymbolsFindFilter::startSearch(Find::SearchResult *search) watcher->setFuture(QtConcurrent::run<Find::SearchResultItem, SymbolsFindParameters, CPlusPlus::Snapshot, QSet<QString> >(runSearch, parameters, m_manager->snapshot(), projectFileNames)); - Core::ICore::progressManager()->addTask(watcher->future(), + Core::FutureProgress *progress = Core::ICore::progressManager()->addTask(watcher->future(), tr("Searching"), Find::Constants::TASK_SEARCH); + connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } void SymbolsFindFilter::addResults(int begin, int end) diff --git a/src/plugins/cpptools/symbolsfindfilter.h b/src/plugins/cpptools/symbolsfindfilter.h index 478cf556854c77cff3cabdd1e3156fd7198ee54d..77fc2f5a1ddbfbf0b724514ed7792f510ba99559 100644 --- a/src/plugins/cpptools/symbolsfindfilter.h +++ b/src/plugins/cpptools/symbolsfindfilter.h @@ -87,6 +87,7 @@ private slots: void addResults(int begin, int end); void finish(); void cancel(); + void setPaused(bool paused); void onTaskStarted(const QString &type); void onAllTasksFinished(const QString &type); void searchAgain(); diff --git a/src/plugins/find/searchresultwidget.cpp b/src/plugins/find/searchresultwidget.cpp index e3c08be56d260eecec86d6b925e149487450c7cf..918527364ba721433841654b6632027043429e0a 100644 --- a/src/plugins/find/searchresultwidget.cpp +++ b/src/plugins/find/searchresultwidget.cpp @@ -47,6 +47,10 @@ #include <QVBoxLayout> #include <QHBoxLayout> +static const int SEARCHRESULT_WARNING_LIMIT = 200000; +static const char UNDO_WARNING_ID[] = "warninglabel"; +static const char SIZE_WARNING_ID[] = "sizeWarningLabel"; + namespace Find { namespace Internal { @@ -77,6 +81,8 @@ using namespace Find::Internal; SearchResultWidget::SearchResultWidget(QWidget *parent) : QWidget(parent), m_count(0), + m_sizeWarningActive(false), + m_sizeWarningOverridden(false), m_isShowingReplaceUI(false), m_searchAgainSupported(false) { @@ -182,6 +188,12 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : connect(m_replaceButton, SIGNAL(clicked()), this, SLOT(handleReplaceButton())); } +SearchResultWidget::~SearchResultWidget() +{ + if (m_sizeWarningActive) + cancelAfterSizeWarning(); +} + void SearchResultWidget::setInfo(const QString &label, const QString &toolTip, const QString &term) { m_label->setText(label); @@ -210,9 +222,10 @@ void SearchResultWidget::addResults(const QList<SearchResultItem> &items, Search bool firstItems = (m_count == 0); m_count += items.size(); m_searchResultTreeView->addResults(items, mode); + updateMatchesFoundLabel(); if (firstItems) { if (showWarningMessage()) { - Core::InfoBarEntry info(QLatin1String("warninglabel"), tr("This change cannot be undone.")); + Core::InfoBarEntry info(QLatin1String(UNDO_WARNING_ID), tr("This change cannot be undone.")); info.setCustomButtonInfo(tr("Do not warn again"), this, SLOT(hideNoUndoWarning())); m_infoBar.addInfo(info); } @@ -227,10 +240,21 @@ void SearchResultWidget::addResults(const QList<SearchResultItem> &items, Search } m_searchResultTreeView->selectionModel()->select(m_searchResultTreeView->model()->index(0, 0, QModelIndex()), QItemSelectionModel::Select); emit navigateStateChanged(); + } else if (m_count > SEARCHRESULT_WARNING_LIMIT && !m_sizeWarningOverridden && !m_sizeWarningActive) { + m_sizeWarningActive = true; + emit paused(true); + Core::InfoBarEntry info(QLatin1String(SIZE_WARNING_ID), + tr("The search resulted in more than %1 items, do you still want to continue?") + .arg(SEARCHRESULT_WARNING_LIMIT)); + info.setCancelButtonInfo(tr("Cancel"), this, SLOT(cancelAfterSizeWarning())); + info.setCustomButtonInfo(tr("Continue"), this, SLOT(continueAfterSizeWarning())); + m_infoBar.addInfo(info); + emit requestPopup(false/*no focus*/); } - updateMatchesFoundLabel(); } + + int SearchResultWidget::count() const { return m_count; @@ -345,6 +369,10 @@ void SearchResultWidget::restart() m_replaceButton->setEnabled(false); m_searchResultTreeView->clear(); m_count = 0; + if (m_sizeWarningActive) + m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_sizeWarningActive = false; + m_sizeWarningOverridden = false; m_cancelButton->setVisible(true); m_searchAgainButton->setVisible(false); m_messageWidget->setVisible(false); @@ -365,6 +393,10 @@ void SearchResultWidget::setSearchAgainEnabled(bool enabled) void SearchResultWidget::finishSearch(bool canceled) { + if (m_sizeWarningActive) + m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_sizeWarningActive = false; + m_sizeWarningOverridden = false; m_replaceTextEdit->setEnabled(m_count > 0); m_replaceButton->setEnabled(m_count > 0); m_cancelButton->setVisible(false); @@ -372,10 +404,32 @@ void SearchResultWidget::finishSearch(bool canceled) m_searchAgainButton->setVisible(m_searchAgainSupported); } +void SearchResultWidget::sendRequestPopup() +{ + emit requestPopup(true/*focus*/); +} + void SearchResultWidget::hideNoUndoWarning() { setShowWarningMessage(false); - m_infoBar.clear(); + m_infoBar.removeInfo(QLatin1String(UNDO_WARNING_ID)); +} + +void SearchResultWidget::continueAfterSizeWarning() +{ + m_sizeWarningOverridden = true; + m_sizeWarningActive = false; + m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + emit paused(false); +} + +void SearchResultWidget::cancelAfterSizeWarning() +{ + m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_sizeWarningOverridden = true; + m_sizeWarningActive = false; + emit cancelled(); + emit paused(false); } void SearchResultWidget::handleJumpToSearchResult(const SearchResultItem &item) @@ -396,7 +450,10 @@ void SearchResultWidget::handleReplaceButton() void SearchResultWidget::cancel() { m_cancelButton->setVisible(false); - emit cancelled(); + if (m_sizeWarningActive) + cancelAfterSizeWarning(); + else + emit cancelled(); } void SearchResultWidget::searchAgain() diff --git a/src/plugins/find/searchresultwidget.h b/src/plugins/find/searchresultwidget.h index 55a4efef65bcaed6ba681b370234b7dbb46a6943..4b1e9432ad5fd39ee6bd3047b2b7027fb7887898 100644 --- a/src/plugins/find/searchresultwidget.h +++ b/src/plugins/find/searchresultwidget.h @@ -53,6 +53,7 @@ class SearchResultWidget : public QWidget Q_OBJECT public: explicit SearchResultWidget(QWidget *parent = 0); + ~SearchResultWidget(); void setInfo(const QString &label, const QString &toolTip, const QString &term); @@ -91,19 +92,24 @@ public: public slots: void finishSearch(bool canceled); + void sendRequestPopup(); signals: void activated(const Find::SearchResultItem &item); void replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems); void searchAgainRequested(); void cancelled(); + void paused(bool paused); void restarted(); void visibilityChanged(bool visible); + void requestPopup(bool focus); void navigateStateChanged(); private slots: void hideNoUndoWarning(); + void continueAfterSizeWarning(); + void cancelAfterSizeWarning(); void handleJumpToSearchResult(const SearchResultItem &item); void handleReplaceButton(); void cancel(); @@ -117,6 +123,8 @@ private: SearchResultTreeView *m_searchResultTreeView; int m_count; + bool m_sizeWarningActive; + bool m_sizeWarningOverridden; QString m_dontAskAgainGroup; QFrame *m_messageWidget; Core::InfoBar m_infoBar; diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp index f867d9782ebfe260bbdf90d09aee13b534754030..df91619e7ebf4b64fefaa4766962c908a789b0ad 100644 --- a/src/plugins/find/searchresultwindow.cpp +++ b/src/plugins/find/searchresultwindow.cpp @@ -86,6 +86,7 @@ namespace Internal { SearchResultWindowPrivate(SearchResultWindow *window); bool isSearchVisible() const; int visibleSearchIndex() const; + void setCurrentIndex(int index, bool focus); SearchResultWindow *q; QList<Internal::SearchResultWidget *> m_searchResultWidgets; @@ -102,6 +103,7 @@ namespace Internal { public slots: void setCurrentIndex(int index); void moveWidgetToTop(); + void popupRequested(bool focus); }; SearchResultWindowPrivate::SearchResultWindowPrivate(SearchResultWindow *window) @@ -119,7 +121,7 @@ namespace Internal { return m_currentIndex - 1; } - void SearchResultWindowPrivate::setCurrentIndex(int index) + void SearchResultWindowPrivate::setCurrentIndex(int index, bool focus) { if (isSearchVisible()) m_searchResultWidgets.at(visibleSearchIndex())->notifyVisibilityChanged(false); @@ -127,16 +129,23 @@ namespace Internal { m_widget->setCurrentIndex(index); m_recentSearchesBox->setCurrentIndex(index); if (!isSearchVisible()) { - m_widget->currentWidget()->setFocus(); + if (focus) + m_widget->currentWidget()->setFocus(); m_expandCollapseButton->setEnabled(false); } else { - m_searchResultWidgets.at(visibleSearchIndex())->setFocusInternally(); + if (focus) + m_searchResultWidgets.at(visibleSearchIndex())->setFocusInternally(); m_searchResultWidgets.at(visibleSearchIndex())->notifyVisibilityChanged(true); m_expandCollapseButton->setEnabled(true); } q->navigateStateChanged(); } + void SearchResultWindowPrivate::setCurrentIndex(int index) + { + setCurrentIndex(index, true/*focus*/); + } + void SearchResultWindowPrivate::moveWidgetToTop() { SearchResultWidget *widget = qobject_cast<SearchResultWidget *>(sender()); @@ -170,6 +179,15 @@ namespace Internal { ++m_currentIndex; } } + + void SearchResultWindowPrivate::popupRequested(bool focus) + { + SearchResultWidget *widget = qobject_cast<SearchResultWidget *>(sender()); + QTC_ASSERT(widget, return); + int internalIndex = m_searchResultWidgets.indexOf(widget) + 1/*account for "new search" entry*/; + setCurrentIndex(internalIndex, focus); + q->popup(focus); + } } using namespace Find::Internal; @@ -367,8 +385,9 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label, { if (d->m_searchResults.size() >= MAX_SEARCH_HISTORY) { d->m_searchResultWidgets.last()->notifyVisibilityChanged(false); - delete d->m_searchResults.takeLast(); + // widget first, because that might send interesting signals to SearchResult delete d->m_searchResultWidgets.takeLast(); + delete d->m_searchResults.takeLast(); d->m_recentSearchesBox->removeItem(d->m_recentSearchesBox->count()-1); if (d->m_currentIndex >= d->m_recentSearchesBox->count()) { // temporarily set the index to the last existing @@ -380,6 +399,7 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label, d->m_widget->insertWidget(1, widget); connect(widget, SIGNAL(navigateStateChanged()), this, SLOT(navigateStateChanged())); connect(widget, SIGNAL(restarted()), d, SLOT(moveWidgetToTop())); + connect(widget, SIGNAL(requestPopup(bool)), d, SLOT(popupRequested(bool))); widget->setTextEditorFont(d->m_font); widget->setShowReplaceUI(searchOrSearchAndReplace != SearchOnly); widget->setAutoExpandResults(d->m_expandCollapseAction->isChecked()); @@ -584,6 +604,8 @@ SearchResult::SearchResult(SearchResultWidget *widget) this, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>))); connect(widget, SIGNAL(cancelled()), this, SIGNAL(cancelled())); + connect(widget, SIGNAL(paused(bool)), + this, SIGNAL(paused(bool))); connect(widget, SIGNAL(visibilityChanged(bool)), this, SIGNAL(visibilityChanged(bool))); connect(widget, SIGNAL(searchAgainRequested()), @@ -697,6 +719,14 @@ void SearchResult::setSearchAgainEnabled(bool enabled) m_widget->setSearchAgainEnabled(enabled); } +/*! + * \brief Pops up the search result panel with this search. + */ +void SearchResult::popup() +{ + m_widget->sendRequestPopup(); +} + } // namespace Find #include "searchresultwindow.moc" diff --git a/src/plugins/find/searchresultwindow.h b/src/plugins/find/searchresultwindow.h index 15db74c590ebb9ecc8378567618116ed0fcd9091..707aee9495daae7f44d787d4366e9bebc8127475 100644 --- a/src/plugins/find/searchresultwindow.h +++ b/src/plugins/find/searchresultwindow.h @@ -109,11 +109,13 @@ public slots: void setTextToReplace(const QString &textToReplace); void restart(); void setSearchAgainEnabled(bool enabled); + void popup(); signals: void activated(const Find::SearchResultItem &item); void replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems); void cancelled(); + void paused(bool paused); void visibilityChanged(bool visible); void countChanged(int count); void searchAgainRequested(); diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp index 5931634ba14bbff02fb21644a623fcbeee4dbd8a..72e8f4ca000fc9180c64532532eecf0327dcaae0 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.cpp +++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp @@ -698,18 +698,23 @@ class ProcessFile: public std::unary_function<QString, QList<FindReferences::Usa typedef FindReferences::Usage Usage; QString name; const ObjectValue *scope; + QFutureInterface<Usage> *future; public: ProcessFile(const ContextPtr &context, QString name, - const ObjectValue *scope) - : context(context), name(name), scope(scope) + const ObjectValue *scope, + QFutureInterface<Usage> *future) + : context(context), name(name), scope(scope), future(future) { } QList<Usage> operator()(const QString &fileName) { QList<Usage> usages; - + if (future->isPaused()) + future->waitForResume(); + if (future->isCanceled()) + return usages; Document::Ptr doc = context->snapshot().document(fileName); if (!doc) return usages; @@ -719,7 +724,8 @@ public: FindUsages::Result results = findUsages(name, scope); foreach (const AST::SourceLocation &loc, results) usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); - + if (future->isPaused()) + future->waitForResume(); return usages; } }; @@ -730,18 +736,23 @@ class SearchFileForType: public std::unary_function<QString, QList<FindReference typedef FindReferences::Usage Usage; QString name; const ObjectValue *scope; + QFutureInterface<Usage> *future; public: SearchFileForType(const ContextPtr &context, - QString name, - const ObjectValue *scope) - : context(context), name(name), scope(scope) + QString name, + const ObjectValue *scope, + QFutureInterface<Usage> *future) + : context(context), name(name), scope(scope), future(future) { } QList<Usage> operator()(const QString &fileName) { QList<Usage> usages; - + if (future->isPaused()) + future->waitForResume(); + if (future->isCanceled()) + return usages; Document::Ptr doc = context->snapshot().document(fileName); if (!doc) return usages; @@ -751,7 +762,8 @@ public: FindTypeUsages::Result results = findUsages(name, scope); foreach (const AST::SourceLocation &loc, results) usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); - + if (future->isPaused()) + future->waitForResume(); return usages; } }; @@ -857,7 +869,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future, return; future.reportResult(searchStarting); - SearchFileForType process(context, name, typeValue); + SearchFileForType process(context, name, typeValue, &future); UpdateUI reduce(&future); QtConcurrent::blockingMappedReduced<QList<FindReferences::Usage> > (files, process, reduce); @@ -872,7 +884,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future, searchStarting.lineText.prepend(scope->className() + QLatin1Char('.')); future.reportResult(searchStarting); - ProcessFile process(context, name, scope); + ProcessFile process(context, name, scope, &future); UpdateUI reduce(&future); QtConcurrent::blockingMappedReduced<QList<FindReferences::Usage> > (files, process, reduce); @@ -930,13 +942,14 @@ void FindReferences::displayResults(int first, int last) connect(m_currentSearch, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem))); connect(m_currentSearch, SIGNAL(cancelled()), this, SLOT(cancel())); + connect(m_currentSearch, SIGNAL(paused(bool)), this, SLOT(setPaused(bool))); Find::SearchResultWindow::instance()->popup(true); Core::ProgressManager *progressManager = Core::ICore::progressManager(); Core::FutureProgress *progress = progressManager->addTask( m_watcher.future(), tr("Searching"), QmlJSEditor::Constants::TASK_SEARCH); - connect(progress, SIGNAL(clicked()), Find::SearchResultWindow::instance(), SLOT(popup())); + connect(progress, SIGNAL(clicked()), m_currentSearch, SLOT(popup())); ++first; } @@ -968,6 +981,12 @@ void FindReferences::cancel() m_watcher.cancel(); } +void FindReferences::setPaused(bool paused) +{ + if (!paused || m_watcher.isRunning()) // guard against pausing when the search is finished + m_watcher.setPaused(paused); +} + void FindReferences::openEditor(const Find::SearchResultItem &item) { if (item.path.size() > 0) { diff --git a/src/plugins/qmljseditor/qmljsfindreferences.h b/src/plugins/qmljseditor/qmljsfindreferences.h index a525979651d26087f131c302fcd024e4b5af53dd..4ee3c988f526d9a22d128efeb93dbb83cd55e4f8 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.h +++ b/src/plugins/qmljseditor/qmljsfindreferences.h @@ -87,6 +87,7 @@ private Q_SLOTS: void displayResults(int first, int last); void searchFinished(); void cancel(); + void setPaused(bool paused); void openEditor(const Find::SearchResultItem &item); void onReplaceButtonClicked(const QString &text, const QList<Find::SearchResultItem> &items); diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index 9676009dcf2724e75639095e22a42e81127b0eee..75c25741d7cb28a3be09881997adc233561c335e 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -91,6 +91,16 @@ void BaseFileFind::cancel() watcher->cancel(); } +void BaseFileFind::setPaused(bool paused) +{ + SearchResult *search = qobject_cast<SearchResult *>(sender()); + QTC_ASSERT(search, return); + QFutureWatcher<FileSearchResultList> *watcher = m_watchers.key(search); + QTC_ASSERT(watcher, return); + if (!paused || watcher->isRunning()) // guard against pausing when the search is finished + watcher->setPaused(paused); +} + QStringList BaseFileFind::fileNameFilters() const { QStringList filters; @@ -130,6 +140,7 @@ void BaseFileFind::runNewSearch(const QString &txt, Find::FindFlags findFlags, } connect(search, SIGNAL(visibilityChanged(bool)), this, SLOT(hideHighlightAll(bool))); connect(search, SIGNAL(cancelled()), this, SLOT(cancel())); + connect(search, SIGNAL(paused(bool)), this, SLOT(setPaused(bool))); connect(search, SIGNAL(searchAgainRequested()), this, SLOT(searchAgain())); connect(this, SIGNAL(enabledChanged(bool)), search, SLOT(setSearchAgainEnabled(bool))); runSearch(search); @@ -162,7 +173,7 @@ void BaseFileFind::runSearch(Find::SearchResult *search) tr("Search"), QLatin1String(Constants::TASK_SEARCH)); progress->setWidget(label); - connect(progress, SIGNAL(clicked()), Find::SearchResultWindow::instance(), SLOT(popup())); + connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } void BaseFileFind::findAll(const QString &txt, Find::FindFlags findFlags) diff --git a/src/plugins/texteditor/basefilefind.h b/src/plugins/texteditor/basefilefind.h index 8c22311898fade6878a43bbf88617c7c45e5e612..fe8d3aa9804e5adbb72af6af8d5ed3b913d76641 100644 --- a/src/plugins/texteditor/basefilefind.h +++ b/src/plugins/texteditor/basefilefind.h @@ -95,6 +95,7 @@ private slots: void displayResult(int index); void searchFinished(); void cancel(); + void setPaused(bool paused); void openEditor(const Find::SearchResultItem &item); void doReplace(const QString &txt, const QList<Find::SearchResultItem> &items);