Commit 56ee714f authored by Kåre Särs's avatar Kåre Särs
Browse files

Add info row info to the results

parent 2a0d18c9
......@@ -12,12 +12,21 @@
#include <QRegularExpression>
#include <QFileInfo>
#include <QDir>
#include <algorithm> // std::count_if
#include <algorithm> // std::count_if
static const quintptr InfoItemId = 0xFFFFFFFF;
static const quintptr FileItemId = 0x7FFFFFFF;
// Model indexes
// - (0, 0, InfoItemId) (row, column, internalId)
// | - (0, 0, FileItemId)
// | | - (0, 0, 0)
// | | - (1, 0, 0)
// | - (1, 0, FileItemId)
// | | - (0, 0, 1)
// | | - (1, 0, 1)
static QUrl localFileDirUp(const QUrl &url)
{
if (!url.isLocalFile())
......@@ -35,6 +44,78 @@ MatchModel::~MatchModel()
{
}
void MatchModel::setSearchPlace(MatchModel::SearchPlaces searchPlace)
{
m_searchPlace = searchPlace;
dataChanged(createIndex(0, 0, InfoItemId), createIndex(0, 0, InfoItemId), QVector<int>(Qt::DisplayRole));
}
void MatchModel::setSearchState(MatchModel::SearchState searchState)
{
m_searchState = searchState;
dataChanged(createIndex(0, 0, InfoItemId), createIndex(0, 0, InfoItemId), QVector<int>(Qt::DisplayRole));
}
void MatchModel::setBaseSearchPath(const QString &baseSearchPath)
{
m_resultBaseDir = baseSearchPath;
dataChanged(createIndex(0, 0, InfoItemId), createIndex(0, 0, InfoItemId), QVector<int>(Qt::DisplayRole));
}
void MatchModel::setProjectName(const QString &projectName)
{
m_projectName = projectName;
dataChanged(createIndex(0, 0, InfoItemId), createIndex(0, 0, InfoItemId), QVector<int>(Qt::DisplayRole));
}
QString MatchModel::infoHtmlString() const
{
if (m_matchFiles.isEmpty()) {
return QString();
}
int matchesTotal = 0;
int checkedTotal = 0;
for (const auto &matchFile: qAsConst(m_matchFiles)) {
matchesTotal += matchFile.matches.size();
checkedTotal += std::count_if(matchFile.matches.begin(), matchFile.matches.end(), [](const MatchModel::Match &match) {return match.checked;} );
}
if (m_searchState == Searching) {
QString searchUrl = m_lastMatchUrl.toDisplayString();
if (searchUrl.size() > 73) {
return i18np("<b><i>One match found, searching: ...%2</b>", "<b><i>%1 matches found, searching: ...%2</b>", matchesTotal, searchUrl.right(70));
} else {
return i18np("<b><i>One match found, searching: %2</b>", "<b><i>%1 matches found, searching: %2</b>", matchesTotal, searchUrl);
}
}
QString checkedStr = i18np("One checked", "%1 checked", checkedTotal);
switch (m_searchPlace) {
case CurrentFile:
return i18np("<b><i>One match (%2) found in file</i></b>", "<b><i>%1 matches (%2) found in current file</i></b>", matchesTotal, checkedStr);
case MatchModel::OpenFiles:
return i18np("<b><i>One match (%2) found in open files</i></b>", "<b><i>%1 matches (%2) found in open files</i></b>", matchesTotal, checkedStr);
break;
case MatchModel::Folder:
return i18np("<b><i>One match (%3) found in folder %2</i></b>", "<b><i>%1 matches (%3) found in folder %2</i></b>", matchesTotal, m_resultBaseDir, checkedStr);
break;
case MatchModel::Project: {
return i18np("<b><i>One match (%4) found in project %2 (%3)</i></b>", "<b><i>%1 matches (%4) found in project %2 (%3)</i></b>", matchesTotal, m_projectName, m_resultBaseDir, checkedStr);
break;
}
case MatchModel::AllProjects: // "in Open Projects"
return i18np("<b><i>One match (%3) found in all open projects (common parent: %2)</i></b>", "<b><i>%1 matches (%3) found in all open projects (common parent: %2)</i></b>", matchesTotal, m_resultBaseDir, checkedStr);
break;
}
return QString();
}
void MatchModel::clear()
{
beginResetModel();
......@@ -55,6 +136,12 @@ static const int totalContectLen = 150;
/** This function is used to add a match to a new file */
void MatchModel::addMatches(const QUrl &fileUrl, const QVector<KateSearchMatch> &searchMatches)
{
m_lastMatchUrl = fileUrl;
if (searchMatches.isEmpty()) {
dataChanged(createIndex(0, 0, InfoItemId), createIndex(0, 0, InfoItemId), QVector<int>(Qt::DisplayRole));
return;
}
int fileIndex = matchFileRow(fileUrl);
if (fileIndex == -1) {
fileIndex = m_matchFiles.size();
......@@ -157,7 +244,7 @@ QVariant MatchModel::data(const QModelIndex &index, int role) const
// Info Item
switch (role) {
case Qt::DisplayRole:
return m_infoHtmlString;
return infoHtmlString();
case Qt::CheckStateRole:
return m_infoCheckState;
}
......@@ -221,8 +308,6 @@ QVariant MatchModel::data(const QModelIndex &index, int role) const
return QVariant();
}
static bool isChecked(const MatchModel::Match &match) { return match.checked; }
bool MatchModel::setFileChecked(int fileRow, bool checked)
{
if (fileRow < 0 || fileRow >= m_matchFiles.size()) return false;
......@@ -292,7 +377,7 @@ bool MatchModel::setData(const QModelIndex &itemIndex, const QVariant &, int rol
// we toggle the current value
matches[row].checked = !matches[row].checked;
int checkedCount = std::count_if(matches.begin(), matches.end(), isChecked);
int checkedCount = std::count_if(matches.begin(), matches.end(), [](const MatchModel::Match &match) {return match.checked;});
if (checkedCount == matches.size()) {
m_matchFiles[rootRow].checkState = Qt::Checked;
......@@ -326,7 +411,7 @@ Qt::ItemFlags MatchModel::flags(const QModelIndex &index) const
int MatchModel::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid()) {
return 1;
return m_matchFiles.isEmpty() ? 0 : 1;
}
if (parent.internalId() == InfoItemId) {
......
......@@ -40,6 +40,9 @@ public:
enum SearchPlaces { CurrentFile, OpenFiles, Folder, Project, AllProjects };
Q_ENUM(SearchPlaces)
enum SearchState { SearchDone, Searching, Replacing };
Q_ENUM(SearchState)
enum MatchDataRoles {
FileUrlRole = Qt::UserRole,
FileNameRole,
......@@ -56,6 +59,7 @@ public:
};
Q_ENUM(MatchDataRoles)
private:
struct Match {
int startLine = 0;
int startColumn = 0;
......@@ -75,11 +79,20 @@ public:
Qt::CheckState checkState = Qt::Checked;
};
public:
MatchModel(QObject *parent = nullptr);
~MatchModel() override;
void setMatchColors(const QColor &foreground, const QColor &background, const QColor &replaseBackground);
void setSearchPlace(MatchModel::SearchPlaces searchPlace);
void setSearchState(MatchModel::SearchState searchState);
void setBaseSearchPath(const QString &baseSearchPath);
void setProjectName(const QString &projectName);
/** This function clears all matches in all files */
void clear();
......@@ -116,6 +129,8 @@ private:
bool setFileChecked(int fileRow, bool checked);
QString infoHtmlString() const;
QVector<MatchFile> m_matchFiles;
QHash<QUrl, int> m_matchFileIndexHash;
QColor m_searchBackgroundColor;
......@@ -123,7 +138,11 @@ private:
QColor m_replaceHighlightColor;
Qt::CheckState m_infoCheckState = Qt::Checked;
QString m_infoHtmlString;
SearchPlaces m_searchPlace = CurrentFile;
SearchState m_searchState = SearchDone;
QString m_resultBaseDir;
QString m_projectName;
QUrl m_lastMatchUrl;
};
#endif
......@@ -138,10 +138,8 @@ void SearchDiskFiles::searchSingleLineRegExp(const QString &fileName)
}
// emit all matches batched
if (!matches.isEmpty()) {
const QUrl fileUrl = QUrl::fromUserInput(fileName);
emit matchesFound(fileUrl, matches);
}
const QUrl fileUrl = QUrl::fromUserInput(fileName);
emit matchesFound(fileUrl, matches);
}
void SearchDiskFiles::searchMultiLineRegExp(const QString &fileName)
......@@ -209,8 +207,6 @@ void SearchDiskFiles::searchMultiLineRegExp(const QString &fileName)
}
// emit all matches batched
if (!matches.isEmpty()) {
const QUrl fileUrl = QUrl::fromUserInput(fileName);
emit matchesFound(fileUrl, matches);
}
const QUrl fileUrl = QUrl::fromUserInput(fileName);
emit matchesFound(fileUrl, matches);
}
......@@ -1193,9 +1193,6 @@ void KatePluginSearchView::startSearch()
m_curResults->matches = 0;
disconnect(m_curResults->tree, &QTreeWidget::itemChanged, &m_updateSumaryTimer, nullptr);
m_curResults->matchModel.clear();
m_curResults->treeView->expand(m_curResults->matchModel.index(0,0));
m_ui.resultTabWidget->setTabText(m_ui.resultTabWidget->currentIndex(), m_ui.searchCombo->currentText());
m_toolView->setCursor(Qt::WaitCursor);
......@@ -1205,6 +1202,11 @@ void KatePluginSearchView::startSearch()
const bool inCurrentProject = m_ui.searchPlaceCombo->currentIndex() == MatchModel::Project;
const bool inAllOpenProjects = m_ui.searchPlaceCombo->currentIndex() == MatchModel::AllProjects;
m_curResults->matchModel.clear();
m_curResults->matchModel.setSearchPlace(static_cast<MatchModel::SearchPlaces>(m_curResults->searchPlaceIndex));
m_curResults->matchModel.setSearchState(MatchModel::Searching);
m_curResults->treeView->expand(m_curResults->matchModel.index(0,0));
if (m_ui.searchPlaceCombo->currentIndex() == MatchModel::CurrentFile) {
m_searchDiskFilesDone = true;
m_resultBaseDir.clear();
......@@ -1225,6 +1227,7 @@ void KatePluginSearchView::startSearch()
m_resultBaseDir = m_ui.folderRequester->url().path();
if (!m_resultBaseDir.isEmpty() && !m_resultBaseDir.endsWith(QLatin1Char('/')))
m_resultBaseDir += QLatin1Char('/');
m_curResults->matchModel.setBaseSearchPath(m_resultBaseDir);
addHeaderItem();
m_folderFilesList.generateList(m_ui.folderRequester->text(),
m_ui.recursiveCheckBox->isChecked(),
......@@ -1242,8 +1245,10 @@ void KatePluginSearchView::startSearch()
if (m_projectPluginView) {
if (inCurrentProject) {
m_resultBaseDir = m_projectPluginView->property("projectBaseDir").toString();
m_curResults->matchModel.setProjectName(m_projectPluginView->property("projectName").toString());
} else {
m_resultBaseDir = m_projectPluginView->property("allProjectsCommonBaseDir").toString();
m_curResults->matchModel.setProjectName(m_projectPluginView->property("projectName").toString());
}
if (!m_resultBaseDir.endsWith(QLatin1Char('/')))
......@@ -1258,6 +1263,8 @@ void KatePluginSearchView::startSearch()
files = filterFiles(projectFiles);
}
m_curResults->matchModel.setBaseSearchPath(m_resultBaseDir);
addHeaderItem();
QList<KTextEditor::Document *> openList;
......@@ -1362,6 +1369,8 @@ void KatePluginSearchView::startSearchWhileTyping()
m_curResults->matches = 0;
m_curResults->matchModel.clear();
m_curResults->matchModel.setSearchPlace(MatchModel::CurrentFile);
m_curResults->matchModel.setSearchState(MatchModel::Searching);
m_curResults->treeView->expand(m_curResults->matchModel.index(0,0));
......@@ -1442,6 +1451,9 @@ void KatePluginSearchView::searchDone()
connect(m_curResults->tree, &QTreeWidget::itemChanged, &m_updateSumaryTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
indicateMatch(m_curResults->matches > 0);
m_curResults->matchModel.setSearchState(MatchModel::SearchDone);
m_curResults = nullptr;
m_toolView->unsetCursor();
......@@ -1483,6 +1495,8 @@ void KatePluginSearchView::searchWhileTypingDone()
connect(m_curResults->tree, &QTreeWidget::itemChanged, &m_updateSumaryTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
}
m_curResults->matchModel.setSearchState(MatchModel::SearchDone);
m_curResults = nullptr;
if (focusObject) {
......
......@@ -127,9 +127,7 @@ int SearchOpenFiles::searchSingleLineRegExp(KTextEditor::Document *doc, const QR
}
// emit all matches batched
if (!matches.isEmpty()) {
emit matchesFound(doc->url(), matches);
}
emit matchesFound(doc->url(), matches);
return resultLine;
}
......@@ -207,9 +205,7 @@ int SearchOpenFiles::searchMultiLineRegExp(KTextEditor::Document *doc, const QRe
}
// emit all matches batched
if (!matches.isEmpty()) {
emit matchesFound(doc->url(), matches);
}
emit matchesFound(doc->url(), matches);
return resultLine;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment