Add multiple search results to the tree at once.

Task-number: QTCREATORBUG-1690
This commit is contained in:
con
2010-06-25 09:16:30 +02:00
parent 1fd8672e40
commit 9c47c42232
10 changed files with 98 additions and 56 deletions

View File

@@ -68,7 +68,7 @@ static inline QString msgFound(const QString &searchTerm, int numMatches, int nu
namespace { namespace {
void runFileSearch(QFutureInterface<FileSearchResult> &future, void runFileSearch(QFutureInterface<FileSearchResultList> &future,
QString searchTerm, QString searchTerm,
FileIterator *files, FileIterator *files,
QTextDocument::FindFlags flags, QTextDocument::FindFlags flags,
@@ -96,6 +96,7 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
QFile file; QFile file;
QBuffer buffer; QBuffer buffer;
while (files->hasNext()) { while (files->hasNext()) {
FileSearchResultList results;
const QString &s = files->next(); const QString &s = files->next();
future.setProgressRange(0, files->maxProgress()); future.setProgressRange(0, files->maxProgress());
if (future.isPaused()) if (future.isPaused())
@@ -171,9 +172,9 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
int n = 0; int n = 0;
while (startOfLastLine[i] != '\n' && startOfLastLine[i] != '\r' && i < textLength && n++ < 256) while (startOfLastLine[i] != '\n' && startOfLastLine[i] != '\r' && i < textLength && n++ < 256)
res.append(startOfLastLine[i++]); res.append(startOfLastLine[i++]);
future.reportResult(FileSearchResult(s, lineNr, QString(res), results << FileSearchResult(s, lineNr, QString(res),
regionPtr - startOfLastLine, sa.length(), regionPtr - startOfLastLine, sa.length(),
QStringList())); QStringList());
++numMatches; ++numMatches;
} }
} }
@@ -181,6 +182,8 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
} }
firstChunk = false; firstChunk = false;
} }
if (!results.isEmpty())
future.reportResult(results);
++numFilesSearched; ++numFilesSearched;
if (future.isProgressUpdateNeeded()) if (future.isProgressUpdateNeeded())
future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched)); future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched));
@@ -191,7 +194,7 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
delete files; delete files;
} }
void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future, void runFileSearchRegExp(QFutureInterface<FileSearchResultList> &future,
QString searchTerm, QString searchTerm,
FileIterator *files, FileIterator *files,
QTextDocument::FindFlags flags, QTextDocument::FindFlags flags,
@@ -209,6 +212,7 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
QString str; QString str;
QTextStream stream; QTextStream stream;
while (files->hasNext()) { while (files->hasNext()) {
FileSearchResultList results;
const QString &s = files->next(); const QString &s = files->next();
future.setProgressRange(0, files->maxProgress()); future.setProgressRange(0, files->maxProgress());
if (future.isPaused()) if (future.isPaused())
@@ -235,13 +239,15 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
line = stream.readLine(); line = stream.readLine();
int pos = 0; int pos = 0;
while ((pos = expression.indexIn(line, pos)) != -1) { while ((pos = expression.indexIn(line, pos)) != -1) {
future.reportResult(FileSearchResult(s, lineNr, line, results << FileSearchResult(s, lineNr, line,
pos, expression.matchedLength(), pos, expression.matchedLength(),
expression.capturedTexts())); expression.capturedTexts());
++numMatches;
pos += expression.matchedLength(); pos += expression.matchedLength();
} }
++lineNr; ++lineNr;
} }
future.reportResult(results);
++numFilesSearched; ++numFilesSearched;
if (future.isProgressUpdateNeeded()) if (future.isProgressUpdateNeeded())
future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched)); future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched));
@@ -256,17 +262,17 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
} // namespace } // namespace
QFuture<FileSearchResult> Utils::findInFiles(const QString &searchTerm, FileIterator *files, QFuture<FileSearchResultList> Utils::findInFiles(const QString &searchTerm, FileIterator *files,
QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap) QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap)
{ {
return QtConcurrent::run<FileSearchResult, QString, FileIterator *, QTextDocument::FindFlags, QMap<QString, QString> > return QtConcurrent::run<FileSearchResultList, QString, FileIterator *, QTextDocument::FindFlags, QMap<QString, QString> >
(runFileSearch, searchTerm, files, flags, fileToContentsMap); (runFileSearch, searchTerm, files, flags, fileToContentsMap);
} }
QFuture<FileSearchResult> Utils::findInFilesRegExp(const QString &searchTerm, FileIterator *files, QFuture<FileSearchResultList> Utils::findInFilesRegExp(const QString &searchTerm, FileIterator *files,
QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap) QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap)
{ {
return QtConcurrent::run<FileSearchResult, QString, FileIterator *, QTextDocument::FindFlags, QMap<QString, QString> > return QtConcurrent::run<FileSearchResultList, QString, FileIterator *, QTextDocument::FindFlags, QMap<QString, QString> >
(runFileSearchRegExp, searchTerm, files, flags, fileToContentsMap); (runFileSearchRegExp, searchTerm, files, flags, fileToContentsMap);
} }

View File

@@ -101,10 +101,12 @@ public:
QStringList regexpCapturedTexts; QStringList regexpCapturedTexts;
}; };
QTCREATOR_UTILS_EXPORT QFuture<FileSearchResult> findInFiles(const QString &searchTerm, FileIterator *files, typedef QList<FileSearchResult> FileSearchResultList;
QTCREATOR_UTILS_EXPORT QFuture<FileSearchResultList> findInFiles(const QString &searchTerm, FileIterator *files,
QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap = QMap<QString, QString>()); QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap = QMap<QString, QString>());
QTCREATOR_UTILS_EXPORT QFuture<FileSearchResult> findInFilesRegExp(const QString &searchTerm, FileIterator *files, QTCREATOR_UTILS_EXPORT QFuture<FileSearchResultList> findInFilesRegExp(const QString &searchTerm, FileIterator *files,
QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap = QMap<QString, QString>()); QTextDocument::FindFlags flags, QMap<QString, QString> fileToContentsMap = QMap<QString, QString>());
QTCREATOR_UTILS_EXPORT QString expandRegExpReplacement(const QString &replaceText, const QStringList &capturedTexts); QTCREATOR_UTILS_EXPORT QString expandRegExpReplacement(const QString &replaceText, const QStringList &capturedTexts);

View File

@@ -39,6 +39,7 @@
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QDebug> #include <QtCore/QDebug>
using namespace Find;
using namespace Find::Internal; using namespace Find::Internal;
SearchResultTreeModel::SearchResultTreeModel(QObject *parent) SearchResultTreeModel::SearchResultTreeModel(QObject *parent)
@@ -295,16 +296,21 @@ int SearchResultTreeModel::addResultFile(const QString &fileName)
return index; return index;
} }
void SearchResultTreeModel::appendResultLine(int index, int lineNumber, const QString &rowText, void SearchResultTreeModel::appendResultLines(const QList<SearchResultItem> &items)
int searchTermStart, int searchTermLength)
{ {
if (!m_lastAddedResultFile) if (!m_lastAddedResultFile)
return; return;
QModelIndex lastFile(createIndex(m_lastAddedResultFile->rowOfItem(), 0, m_lastAddedResultFile)); QModelIndex lastFile(createIndex(m_lastAddedResultFile->rowOfItem(), 0, m_lastAddedResultFile));
beginInsertRows(lastFile, m_lastAddedResultFile->childrenCount(), m_lastAddedResultFile->childrenCount()); beginInsertRows(lastFile, m_lastAddedResultFile->childrenCount(), m_lastAddedResultFile->childrenCount() + items.count());
m_lastAddedResultFile->appendResultLine(index, lineNumber, rowText, searchTermStart, searchTermLength); foreach (const SearchResultItem &item, items) {
m_lastAddedResultFile->appendResultLine(item.index,
item.lineNumber,
item.lineText,
item.searchTermStart,
item.searchTermLength);
}
endInsertRows(); endInsertRows();
dataChanged(lastFile, lastFile); // Make sure that the number after the file name gets updated dataChanged(lastFile, lastFile); // Make sure that the number after the file name gets updated
@@ -314,15 +320,25 @@ void SearchResultTreeModel::appendResultLine(int index, int lineNumber, const QS
* Adds the search result to the list of results, creating a new file entry when * Adds the search result to the list of results, creating a new file entry when
* necessary. Returns the insertion index when a new file entry was created. * necessary. Returns the insertion index when a new file entry was created.
*/ */
int SearchResultTreeModel::addResultLine(int index, const QString &fileName, int lineNumber, const QString &rowText, QList<int> SearchResultTreeModel::addResultLines(const QList<SearchResultItem> &items)
int searchTermStart, int searchTermLength)
{ {
int insertionIndex = -1; QList<int> insertedFileIndices;
if (!m_lastAddedResultFile || (m_lastAddedResultFile->fileName() != fileName)) QList<SearchResultItem> itemSet;
insertionIndex = addResultFile(fileName); foreach (const SearchResultItem &item, items) {
if (!m_lastAddedResultFile || (m_lastAddedResultFile->fileName() != item.fileName)) {
appendResultLine(index, lineNumber, rowText, searchTermStart, searchTermLength); if (!itemSet.isEmpty()) {
return insertionIndex; appendResultLines(itemSet);
itemSet.clear();
}
insertedFileIndices << addResultFile(item.fileName);
}
itemSet << item;
}
if (!itemSet.isEmpty()) {
appendResultLines(itemSet);
itemSet.clear();
}
return insertedFileIndices;
} }
void SearchResultTreeModel::clear() void SearchResultTreeModel::clear()

View File

@@ -30,6 +30,8 @@
#ifndef SEARCHRESULTTREEMODEL_H #ifndef SEARCHRESULTTREEMODEL_H
#define SEARCHRESULTTREEMODEL_H #define SEARCHRESULTTREEMODEL_H
#include "searchresultwindow.h"
#include <QtCore/QAbstractItemModel> #include <QtCore/QAbstractItemModel>
#include <QtGui/QFont> #include <QtGui/QFont>
@@ -63,18 +65,17 @@ public:
QModelIndex next(const QModelIndex &idx) const; QModelIndex next(const QModelIndex &idx) const;
QModelIndex prev(const QModelIndex &idx) const; QModelIndex prev(const QModelIndex &idx) const;
QList<int> addResultLines(const QList<SearchResultItem> &items);
signals: signals:
void jumpToSearchResult(const QString &fileName, int lineNumber, void jumpToSearchResult(const QString &fileName, int lineNumber,
int searchTermStart, int searchTermLength); int searchTermStart, int searchTermLength);
public slots: public slots:
void clear(); void clear();
int addResultLine(int index, const QString &fileName, int lineNumber, const QString &rowText,
int searchTermStart, int searchTermLength);
private: private:
void appendResultLine(int index, int lineNumber, const QString &rowText, void appendResultLines(const QList<SearchResultItem> &items);
int searchTermStart, int searchTermLength);
int addResultFile(const QString &fileName); int addResultFile(const QString &fileName);
QVariant data(const SearchResultTextRow *row, int role) const; QVariant data(const SearchResultTextRow *row, int role) const;
QVariant data(const SearchResultFile *file, int role) const; QVariant data(const SearchResultFile *file, int role) const;

View File

@@ -66,14 +66,13 @@ void SearchResultTreeView::clear()
m_model->clear(); m_model->clear();
} }
void SearchResultTreeView::appendResultLine(int index, const QString &fileName, int lineNumber, const QString &rowText, void SearchResultTreeView::appendResultLines(const QList<SearchResultItem> &items)
int searchTermStart, int searchTermLength)
{ {
int insertionIndex = m_model->addResultLine(index, fileName, lineNumber, rowText, const QList<int> &insertedFileIndices = m_model->addResultLines(items);
searchTermStart, searchTermLength); if (m_autoExpandResults && !insertedFileIndices.isEmpty()) {
foreach (int index, insertedFileIndices)
if (m_autoExpandResults && insertionIndex != -1) setExpanded(model()->index(index, 0), true);
setExpanded(model()->index(insertionIndex, 0), true); }
} }
void SearchResultTreeView::emitJumpToSearchResult(const QModelIndex &index) void SearchResultTreeView::emitJumpToSearchResult(const QModelIndex &index)

View File

@@ -30,6 +30,8 @@
#ifndef SEARCHRESULTTREEVIEW_H #ifndef SEARCHRESULTTREEVIEW_H
#define SEARCHRESULTTREEVIEW_H #define SEARCHRESULTTREEVIEW_H
#include "searchresultwindow.h"
#include <QtGui/QTreeView> #include <QtGui/QTreeView>
namespace Find { namespace Find {
@@ -48,14 +50,13 @@ public:
void setTextEditorFont(const QFont &font); void setTextEditorFont(const QFont &font);
SearchResultTreeModel *model() const; SearchResultTreeModel *model() const;
void appendResultLines(const QList<SearchResultItem> &items);
signals: signals:
void jumpToSearchResult(int index, bool checked); void jumpToSearchResult(int index, bool checked);
public slots: public slots:
void clear(); void clear();
void appendResultLine(int index, const QString &fileName, int lineNumber, const QString &lineText,
int searchTermStart, int searchTermLength);
void emitJumpToSearchResult(const QModelIndex &index); void emitJumpToSearchResult(const QModelIndex &index);
protected: protected:

View File

@@ -89,7 +89,9 @@ struct SearchResultWindowPrivate {
}; };
SearchResultWindowPrivate::SearchResultWindowPrivate() SearchResultWindowPrivate::SearchResultWindowPrivate()
: m_currentSearch(0), m_isShowingReplaceUI(false), m_focusReplaceEdit(false) : m_currentSearch(0),
m_isShowingReplaceUI(false),
m_focusReplaceEdit(false)
{ {
} }
@@ -294,9 +296,6 @@ void SearchResultWindow::handleJumpToSearchResult(int index, bool /* checked */)
void SearchResultWindow::addResult(const QString &fileName, int lineNumber, const QString &rowText, void SearchResultWindow::addResult(const QString &fileName, int lineNumber, const QString &rowText,
int searchTermStart, int searchTermLength, const QVariant &userData) int searchTermStart, int searchTermLength, const QVariant &userData)
{ {
//qDebug()<<"###"<<fileName;
d->m_widget->setCurrentWidget(d->m_searchResultTreeView);
int index = d->m_items.size();
SearchResultItem item; SearchResultItem item;
item.fileName = fileName; item.fileName = fileName;
item.lineNumber = lineNumber; item.lineNumber = lineNumber;
@@ -304,10 +303,21 @@ void SearchResultWindow::addResult(const QString &fileName, int lineNumber, cons
item.searchTermStart = searchTermStart; item.searchTermStart = searchTermStart;
item.searchTermLength = searchTermLength; item.searchTermLength = searchTermLength;
item.userData = userData; item.userData = userData;
item.index = index; addResults(QList<SearchResultItem>() << item);
d->m_items.append(item); }
d->m_searchResultTreeView->appendResultLine(index, fileName, lineNumber, rowText, searchTermStart, searchTermLength);
if (index == 0) { void SearchResultWindow::addResults(QList<SearchResultItem> &items)
{
int index = d->m_items.size();
bool firstItems = (index == 0);
for (int i = 0; i < items.size(); ++i) {
items[i].index = index;
++index;
}
d->m_items << items;
d->m_searchResultTreeView->appendResultLines(items);
if (firstItems) {
d->m_replaceTextEdit->setEnabled(true); d->m_replaceTextEdit->setEnabled(true);
// We didn't have an item before, set the focus to the search widget // We didn't have an item before, set the focus to the search widget
d->m_focusReplaceEdit = true; d->m_focusReplaceEdit = true;

View File

@@ -53,7 +53,7 @@ struct FIND_EXPORT SearchResultItem
QString lineText; QString lineText;
int searchTermStart; int searchTermStart;
int searchTermLength; int searchTermLength;
int index; int index; // SearchResultWindow sets the index
QVariant userData; QVariant userData;
// whatever information we also need here // whatever information we also need here
}; };
@@ -109,6 +109,7 @@ public:
// search result object only lives till next startnewsearch call // search result object only lives till next startnewsearch call
SearchResult *startNewSearch(SearchMode searchOrSearchAndReplace = SearchOnly); SearchResult *startNewSearch(SearchMode searchOrSearchAndReplace = SearchOnly);
void addResults(QList<SearchResultItem> &items);
public slots: public slots:
void clearContents(); void clearContents();
void addResult(const QString &fileName, int lineNumber, const QString &lineText, void addResult(const QString &fileName, int lineNumber, const QString &lineText,

View File

@@ -93,7 +93,7 @@ void BaseFileFind::findAll(const QString &txt, QTextDocument::FindFlags findFlag
emit changed(); emit changed();
if (m_filterCombo) if (m_filterCombo)
updateComboEntries(m_filterCombo, true); updateComboEntries(m_filterCombo, true);
m_watcher.setFuture(QFuture<FileSearchResult>()); m_watcher.setFuture(QFuture<FileSearchResultList>());
SearchResult *result = m_resultWindow->startNewSearch(); SearchResult *result = m_resultWindow->startNewSearch();
connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem))); connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem)));
m_resultWindow->popup(true); m_resultWindow->popup(true);
@@ -115,7 +115,7 @@ void BaseFileFind::replaceAll(const QString &txt, QTextDocument::FindFlags findF
emit changed(); emit changed();
if (m_filterCombo) if (m_filterCombo)
updateComboEntries(m_filterCombo, true); updateComboEntries(m_filterCombo, true);
m_watcher.setFuture(QFuture<FileSearchResult>()); m_watcher.setFuture(QFuture<FileSearchResultList>());
SearchResult *result = m_resultWindow->startNewSearch(SearchResultWindow::SearchAndReplace); SearchResult *result = m_resultWindow->startNewSearch(SearchResultWindow::SearchAndReplace);
connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem))); connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem)));
connect(result, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)), connect(result, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)),
@@ -145,13 +145,19 @@ void BaseFileFind::doReplace(const QString &text,
} }
void BaseFileFind::displayResult(int index) { void BaseFileFind::displayResult(int index) {
Utils::FileSearchResult result = m_watcher.future().resultAt(index); Utils::FileSearchResultList results = m_watcher.future().resultAt(index);
m_resultWindow->addResult(result.fileName, QList<Find::SearchResultItem> items; // this conversion is stupid...
result.lineNumber, foreach (const Utils::FileSearchResult &result, results) {
result.matchingLine, Find::SearchResultItem item;
result.matchStart, item.fileName = result.fileName;
result.matchLength, item.lineNumber = result.lineNumber;
result.regexpCapturedTexts); item.lineText = result.matchingLine;
item.searchTermLength = result.matchLength;
item.searchTermStart = result.matchStart;
item.userData = result.regexpCapturedTexts;
items << item;
}
m_resultWindow->addResults(items);
if (m_resultLabel) if (m_resultLabel)
m_resultLabel->setText(tr("%1 found").arg(m_resultWindow->numberOfResults())); m_resultLabel->setText(tr("%1 found").arg(m_resultWindow->numberOfResults()));
} }

View File

@@ -92,7 +92,7 @@ private:
QWidget *createProgressWidget(); QWidget *createProgressWidget();
Find::SearchResultWindow *m_resultWindow; Find::SearchResultWindow *m_resultWindow;
QFutureWatcher<Utils::FileSearchResult> m_watcher; QFutureWatcher<Utils::FileSearchResultList> m_watcher;
bool m_isSearching; bool m_isSearching;
QLabel *m_resultLabel; QLabel *m_resultLabel;
QStringListModel m_filterStrings; QStringListModel m_filterStrings;