forked from qt-creator/qt-creator
Add multiple search results to the tree at once.
Task-number: QTCREATORBUG-1690
This commit is contained in:
@@ -68,7 +68,7 @@ static inline QString msgFound(const QString &searchTerm, int numMatches, int nu
|
||||
|
||||
namespace {
|
||||
|
||||
void runFileSearch(QFutureInterface<FileSearchResult> &future,
|
||||
void runFileSearch(QFutureInterface<FileSearchResultList> &future,
|
||||
QString searchTerm,
|
||||
FileIterator *files,
|
||||
QTextDocument::FindFlags flags,
|
||||
@@ -96,6 +96,7 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
|
||||
QFile file;
|
||||
QBuffer buffer;
|
||||
while (files->hasNext()) {
|
||||
FileSearchResultList results;
|
||||
const QString &s = files->next();
|
||||
future.setProgressRange(0, files->maxProgress());
|
||||
if (future.isPaused())
|
||||
@@ -171,9 +172,9 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
|
||||
int n = 0;
|
||||
while (startOfLastLine[i] != '\n' && startOfLastLine[i] != '\r' && i < textLength && n++ < 256)
|
||||
res.append(startOfLastLine[i++]);
|
||||
future.reportResult(FileSearchResult(s, lineNr, QString(res),
|
||||
results << FileSearchResult(s, lineNr, QString(res),
|
||||
regionPtr - startOfLastLine, sa.length(),
|
||||
QStringList()));
|
||||
QStringList());
|
||||
++numMatches;
|
||||
}
|
||||
}
|
||||
@@ -181,6 +182,8 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
|
||||
}
|
||||
firstChunk = false;
|
||||
}
|
||||
if (!results.isEmpty())
|
||||
future.reportResult(results);
|
||||
++numFilesSearched;
|
||||
if (future.isProgressUpdateNeeded())
|
||||
future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched));
|
||||
@@ -191,7 +194,7 @@ void runFileSearch(QFutureInterface<FileSearchResult> &future,
|
||||
delete files;
|
||||
}
|
||||
|
||||
void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
|
||||
void runFileSearchRegExp(QFutureInterface<FileSearchResultList> &future,
|
||||
QString searchTerm,
|
||||
FileIterator *files,
|
||||
QTextDocument::FindFlags flags,
|
||||
@@ -209,6 +212,7 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
|
||||
QString str;
|
||||
QTextStream stream;
|
||||
while (files->hasNext()) {
|
||||
FileSearchResultList results;
|
||||
const QString &s = files->next();
|
||||
future.setProgressRange(0, files->maxProgress());
|
||||
if (future.isPaused())
|
||||
@@ -235,13 +239,15 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
|
||||
line = stream.readLine();
|
||||
int pos = 0;
|
||||
while ((pos = expression.indexIn(line, pos)) != -1) {
|
||||
future.reportResult(FileSearchResult(s, lineNr, line,
|
||||
results << FileSearchResult(s, lineNr, line,
|
||||
pos, expression.matchedLength(),
|
||||
expression.capturedTexts()));
|
||||
expression.capturedTexts());
|
||||
++numMatches;
|
||||
pos += expression.matchedLength();
|
||||
}
|
||||
++lineNr;
|
||||
}
|
||||
future.reportResult(results);
|
||||
++numFilesSearched;
|
||||
if (future.isProgressUpdateNeeded())
|
||||
future.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, numMatches, numFilesSearched));
|
||||
@@ -256,17 +262,17 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
|
||||
} // 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,10 +101,12 @@ public:
|
||||
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>());
|
||||
|
||||
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>());
|
||||
|
||||
QTCREATOR_UTILS_EXPORT QString expandRegExpReplacement(const QString &replaceText, const QStringList &capturedTexts);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
using namespace Find;
|
||||
using namespace Find::Internal;
|
||||
|
||||
SearchResultTreeModel::SearchResultTreeModel(QObject *parent)
|
||||
@@ -295,16 +296,21 @@ int SearchResultTreeModel::addResultFile(const QString &fileName)
|
||||
return index;
|
||||
}
|
||||
|
||||
void SearchResultTreeModel::appendResultLine(int index, int lineNumber, const QString &rowText,
|
||||
int searchTermStart, int searchTermLength)
|
||||
void SearchResultTreeModel::appendResultLines(const QList<SearchResultItem> &items)
|
||||
{
|
||||
if (!m_lastAddedResultFile)
|
||||
return;
|
||||
|
||||
QModelIndex lastFile(createIndex(m_lastAddedResultFile->rowOfItem(), 0, m_lastAddedResultFile));
|
||||
|
||||
beginInsertRows(lastFile, m_lastAddedResultFile->childrenCount(), m_lastAddedResultFile->childrenCount());
|
||||
m_lastAddedResultFile->appendResultLine(index, lineNumber, rowText, searchTermStart, searchTermLength);
|
||||
beginInsertRows(lastFile, m_lastAddedResultFile->childrenCount(), m_lastAddedResultFile->childrenCount() + items.count());
|
||||
foreach (const SearchResultItem &item, items) {
|
||||
m_lastAddedResultFile->appendResultLine(item.index,
|
||||
item.lineNumber,
|
||||
item.lineText,
|
||||
item.searchTermStart,
|
||||
item.searchTermLength);
|
||||
}
|
||||
endInsertRows();
|
||||
|
||||
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
|
||||
* 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,
|
||||
int searchTermStart, int searchTermLength)
|
||||
QList<int> SearchResultTreeModel::addResultLines(const QList<SearchResultItem> &items)
|
||||
{
|
||||
int insertionIndex = -1;
|
||||
if (!m_lastAddedResultFile || (m_lastAddedResultFile->fileName() != fileName))
|
||||
insertionIndex = addResultFile(fileName);
|
||||
|
||||
appendResultLine(index, lineNumber, rowText, searchTermStart, searchTermLength);
|
||||
return insertionIndex;
|
||||
QList<int> insertedFileIndices;
|
||||
QList<SearchResultItem> itemSet;
|
||||
foreach (const SearchResultItem &item, items) {
|
||||
if (!m_lastAddedResultFile || (m_lastAddedResultFile->fileName() != item.fileName)) {
|
||||
if (!itemSet.isEmpty()) {
|
||||
appendResultLines(itemSet);
|
||||
itemSet.clear();
|
||||
}
|
||||
insertedFileIndices << addResultFile(item.fileName);
|
||||
}
|
||||
itemSet << item;
|
||||
}
|
||||
if (!itemSet.isEmpty()) {
|
||||
appendResultLines(itemSet);
|
||||
itemSet.clear();
|
||||
}
|
||||
return insertedFileIndices;
|
||||
}
|
||||
|
||||
void SearchResultTreeModel::clear()
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#ifndef SEARCHRESULTTREEMODEL_H
|
||||
#define SEARCHRESULTTREEMODEL_H
|
||||
|
||||
#include "searchresultwindow.h"
|
||||
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QFont>
|
||||
|
||||
@@ -63,18 +65,17 @@ public:
|
||||
QModelIndex next(const QModelIndex &idx) const;
|
||||
QModelIndex prev(const QModelIndex &idx) const;
|
||||
|
||||
QList<int> addResultLines(const QList<SearchResultItem> &items);
|
||||
|
||||
signals:
|
||||
void jumpToSearchResult(const QString &fileName, int lineNumber,
|
||||
int searchTermStart, int searchTermLength);
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
int addResultLine(int index, const QString &fileName, int lineNumber, const QString &rowText,
|
||||
int searchTermStart, int searchTermLength);
|
||||
|
||||
private:
|
||||
void appendResultLine(int index, int lineNumber, const QString &rowText,
|
||||
int searchTermStart, int searchTermLength);
|
||||
void appendResultLines(const QList<SearchResultItem> &items);
|
||||
int addResultFile(const QString &fileName);
|
||||
QVariant data(const SearchResultTextRow *row, int role) const;
|
||||
QVariant data(const SearchResultFile *file, int role) const;
|
||||
|
||||
@@ -66,14 +66,13 @@ void SearchResultTreeView::clear()
|
||||
m_model->clear();
|
||||
}
|
||||
|
||||
void SearchResultTreeView::appendResultLine(int index, const QString &fileName, int lineNumber, const QString &rowText,
|
||||
int searchTermStart, int searchTermLength)
|
||||
void SearchResultTreeView::appendResultLines(const QList<SearchResultItem> &items)
|
||||
{
|
||||
int insertionIndex = m_model->addResultLine(index, fileName, lineNumber, rowText,
|
||||
searchTermStart, searchTermLength);
|
||||
|
||||
if (m_autoExpandResults && insertionIndex != -1)
|
||||
setExpanded(model()->index(insertionIndex, 0), true);
|
||||
const QList<int> &insertedFileIndices = m_model->addResultLines(items);
|
||||
if (m_autoExpandResults && !insertedFileIndices.isEmpty()) {
|
||||
foreach (int index, insertedFileIndices)
|
||||
setExpanded(model()->index(index, 0), true);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchResultTreeView::emitJumpToSearchResult(const QModelIndex &index)
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#ifndef SEARCHRESULTTREEVIEW_H
|
||||
#define SEARCHRESULTTREEVIEW_H
|
||||
|
||||
#include "searchresultwindow.h"
|
||||
|
||||
#include <QtGui/QTreeView>
|
||||
|
||||
namespace Find {
|
||||
@@ -48,14 +50,13 @@ public:
|
||||
void setTextEditorFont(const QFont &font);
|
||||
|
||||
SearchResultTreeModel *model() const;
|
||||
void appendResultLines(const QList<SearchResultItem> &items);
|
||||
|
||||
signals:
|
||||
void jumpToSearchResult(int index, bool checked);
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
void appendResultLine(int index, const QString &fileName, int lineNumber, const QString &lineText,
|
||||
int searchTermStart, int searchTermLength);
|
||||
void emitJumpToSearchResult(const QModelIndex &index);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -89,7 +89,9 @@ struct 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,
|
||||
int searchTermStart, int searchTermLength, const QVariant &userData)
|
||||
{
|
||||
//qDebug()<<"###"<<fileName;
|
||||
d->m_widget->setCurrentWidget(d->m_searchResultTreeView);
|
||||
int index = d->m_items.size();
|
||||
SearchResultItem item;
|
||||
item.fileName = fileName;
|
||||
item.lineNumber = lineNumber;
|
||||
@@ -304,10 +303,21 @@ void SearchResultWindow::addResult(const QString &fileName, int lineNumber, cons
|
||||
item.searchTermStart = searchTermStart;
|
||||
item.searchTermLength = searchTermLength;
|
||||
item.userData = userData;
|
||||
item.index = index;
|
||||
d->m_items.append(item);
|
||||
d->m_searchResultTreeView->appendResultLine(index, fileName, lineNumber, rowText, searchTermStart, searchTermLength);
|
||||
if (index == 0) {
|
||||
addResults(QList<SearchResultItem>() << item);
|
||||
}
|
||||
|
||||
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);
|
||||
// We didn't have an item before, set the focus to the search widget
|
||||
d->m_focusReplaceEdit = true;
|
||||
|
||||
@@ -53,7 +53,7 @@ struct FIND_EXPORT SearchResultItem
|
||||
QString lineText;
|
||||
int searchTermStart;
|
||||
int searchTermLength;
|
||||
int index;
|
||||
int index; // SearchResultWindow sets the index
|
||||
QVariant userData;
|
||||
// whatever information we also need here
|
||||
};
|
||||
@@ -109,6 +109,7 @@ public:
|
||||
// search result object only lives till next startnewsearch call
|
||||
SearchResult *startNewSearch(SearchMode searchOrSearchAndReplace = SearchOnly);
|
||||
|
||||
void addResults(QList<SearchResultItem> &items);
|
||||
public slots:
|
||||
void clearContents();
|
||||
void addResult(const QString &fileName, int lineNumber, const QString &lineText,
|
||||
|
||||
@@ -93,7 +93,7 @@ void BaseFileFind::findAll(const QString &txt, QTextDocument::FindFlags findFlag
|
||||
emit changed();
|
||||
if (m_filterCombo)
|
||||
updateComboEntries(m_filterCombo, true);
|
||||
m_watcher.setFuture(QFuture<FileSearchResult>());
|
||||
m_watcher.setFuture(QFuture<FileSearchResultList>());
|
||||
SearchResult *result = m_resultWindow->startNewSearch();
|
||||
connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(Find::SearchResultItem)));
|
||||
m_resultWindow->popup(true);
|
||||
@@ -115,7 +115,7 @@ void BaseFileFind::replaceAll(const QString &txt, QTextDocument::FindFlags findF
|
||||
emit changed();
|
||||
if (m_filterCombo)
|
||||
updateComboEntries(m_filterCombo, true);
|
||||
m_watcher.setFuture(QFuture<FileSearchResult>());
|
||||
m_watcher.setFuture(QFuture<FileSearchResultList>());
|
||||
SearchResult *result = m_resultWindow->startNewSearch(SearchResultWindow::SearchAndReplace);
|
||||
connect(result, SIGNAL(activated(Find::SearchResultItem)), this, SLOT(openEditor(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) {
|
||||
Utils::FileSearchResult result = m_watcher.future().resultAt(index);
|
||||
m_resultWindow->addResult(result.fileName,
|
||||
result.lineNumber,
|
||||
result.matchingLine,
|
||||
result.matchStart,
|
||||
result.matchLength,
|
||||
result.regexpCapturedTexts);
|
||||
Utils::FileSearchResultList results = m_watcher.future().resultAt(index);
|
||||
QList<Find::SearchResultItem> items; // this conversion is stupid...
|
||||
foreach (const Utils::FileSearchResult &result, results) {
|
||||
Find::SearchResultItem item;
|
||||
item.fileName = result.fileName;
|
||||
item.lineNumber = result.lineNumber;
|
||||
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)
|
||||
m_resultLabel->setText(tr("%1 found").arg(m_resultWindow->numberOfResults()));
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ private:
|
||||
QWidget *createProgressWidget();
|
||||
|
||||
Find::SearchResultWindow *m_resultWindow;
|
||||
QFutureWatcher<Utils::FileSearchResult> m_watcher;
|
||||
QFutureWatcher<Utils::FileSearchResultList> m_watcher;
|
||||
bool m_isSearching;
|
||||
QLabel *m_resultLabel;
|
||||
QStringListModel m_filterStrings;
|
||||
|
||||
Reference in New Issue
Block a user