Commit 426ea782 authored by Kåre Särs's avatar Kåre Särs
Browse files

Re-add copying of results to clipboard.

parent 79d9ac74
......@@ -80,54 +80,6 @@ void MatchModel::setProjectName(const QString &projectName)
if (!m_infoUpdateTimer.isActive()) m_infoUpdateTimer.start();
}
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();
......@@ -466,6 +418,66 @@ static QString nbsFormated(int number, int width)
return str;
}
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();
}
QString MatchModel::fileToHtmlString(const MatchFile &matchFile) const
{
QString path = matchFile.fileUrl.isLocalFile() ? localFileDirUp(matchFile.fileUrl).path() : matchFile.fileUrl.url();
if (!path.isEmpty() && !path.endsWith(QLatin1Char('/'))) {
path += QLatin1Char('/');
}
QString tmpStr = QStringLiteral("%1<b>%2: %3</b>").arg(path, matchFile.fileUrl.fileName()).arg(matchFile.matches.size());
return tmpStr;
}
QString MatchModel::matchToHtmlString(const Match &match) const
{
QString pre =match.preMatchStr.toHtmlEscaped();
......@@ -494,19 +506,89 @@ QString MatchModel::matchToHtmlString(const Match &match) const
return displayText;
}
QString MatchModel::fileItemToHtmlString(const MatchFile &matchFile) const
QString MatchModel::infoToPlainText() 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("One match found, searching: ...%2", "%1 matches found, searching: ...%2", matchesTotal, searchUrl.right(70));
} else {
return i18np("One match found, searching: %2", "%1 matches found, searching: %2", matchesTotal, searchUrl);
}
}
QString checkedStr = i18np("One checked", "%1 checked", checkedTotal);
switch (m_searchPlace) {
case CurrentFile:
return i18np("One match (%2) found in file", "%1 matches (%2) found in current file", matchesTotal, checkedStr);
case MatchModel::OpenFiles:
return i18np("One match (%2) found in open files", "%1 matches (%2) found in open files", matchesTotal, checkedStr);
break;
case MatchModel::Folder:
return i18np("One match (%3) found in folder %2", "%1 matches (%3) found in folder %2", matchesTotal, m_resultBaseDir, checkedStr);
break;
case MatchModel::Project: {
return i18np("One match (%4) found in project %2 (%3)", "%1 matches (%4) found in project %2 (%3)", matchesTotal, m_projectName, m_resultBaseDir, checkedStr);
break;
}
case MatchModel::AllProjects: // "in Open Projects"
return i18np("One match (%3) found in all open projects (common parent: %2)", "%1 matches (%3) found in all open projects (common parent: %2)", matchesTotal, m_resultBaseDir, checkedStr);
break;
}
return QString();
}
QString MatchModel::fileToPlainText(const MatchFile &matchFile) const
{
QString path = matchFile.fileUrl.isLocalFile() ? localFileDirUp(matchFile.fileUrl).path() : matchFile.fileUrl.url();
if (!path.isEmpty() && !path.endsWith(QLatin1Char('/'))) {
path += QLatin1Char('/');
}
QString tmpStr = QStringLiteral("%1<b>%2: %3</b>").arg(path, matchFile.fileUrl.fileName()).arg(matchFile.matches.size());
QString tmpStr = QStringLiteral("%1%2: %3").arg(path, matchFile.fileUrl.fileName()).arg(matchFile.matches.size());
return tmpStr;
}
QString MatchModel::matchToPlainText(const Match &match) const
{
QString pre =match.preMatchStr;
QString matchStr = match.matchStr;
matchStr.replace(QLatin1Char('\n'), QStringLiteral("\\n"));
QString replaceStr = match.replaceText;
if (!replaceStr.isEmpty()) {
matchStr = QLatin1String("----") + matchStr + QLatin1String("----");
matchStr += QLatin1String("++++") + replaceStr + QLatin1String("++++");
}
QString post = match.postMatchStr;
// (line:col)[space][space] ...Line text pre [highlighted match] Line text post....
QString displayText = QStringLiteral("(%1:%2) ")
.arg(match.range.start().line() + 1, 3)
.arg(match.range.start().column() + 1, 3) + pre + matchStr + post;
return displayText;
}
bool MatchModel::isMatch(const QModelIndex &itemIndex) const
{
if (!itemIndex.isValid()) return false;
......@@ -648,6 +730,8 @@ QVariant MatchModel::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
return infoHtmlString();
case PlainTextRole:
return infoToPlainText();
case Qt::CheckStateRole:
return m_infoCheckState;
}
......@@ -663,11 +747,13 @@ QVariant MatchModel::data(const QModelIndex &index, int role) const
// File item
switch (role) {
case Qt::DisplayRole:
return fileItemToHtmlString(m_matchFiles[fileRow]);
return fileToHtmlString(m_matchFiles[fileRow]);
case Qt::CheckStateRole:
return m_matchFiles[fileRow].checkState;
case FileUrlRole:
return m_matchFiles[fileRow].fileUrl;
case PlainTextRole:
return fileToPlainText(m_matchFiles[fileRow]);
}
}
else if (matchRow < m_matchFiles[fileRow].matches.size()) {
......@@ -700,6 +786,8 @@ QVariant MatchModel::data(const QModelIndex &index, int role) const
return !match.replaceText.isEmpty();
case ReplaceTextRole:
return match.replaceText;
case PlainTextRole:
return matchToPlainText(match);
}
}
else {
......
......@@ -59,7 +59,8 @@ public:
MatchRole,
PostMatchRole,
ReplacedRole,
ReplaceTextRole
ReplaceTextRole,
PlainTextRole
};
Q_ENUM(MatchDataRoles)
......@@ -150,12 +151,15 @@ private:
bool replaceMatch(KTextEditor::Document *doc, const QModelIndex &matchIndex, const QRegularExpression &regExp, const QString &replaceString);
QString infoHtmlString() const;
QString fileToHtmlString(const MatchFile &matchFile) const;
QString matchToHtmlString(const Match &match) const;
QString fileItemToHtmlString(const MatchFile &matchFile) const;
bool setFileChecked(int fileRow, bool checked);
QString infoToPlainText() const;
QString fileToPlainText(const MatchFile &matchFile) const;
QString matchToPlainText(const Match &match) const;
QString infoHtmlString() const;
bool setFileChecked(int fileRow, bool checked);
Match *matchFromIndex(const QModelIndex &matchIndex);
......
......@@ -1870,108 +1870,58 @@ void KatePluginSearchView::onResize(const QSize &size)
}
}
void KatePluginSearchView::customResMenuRequested(const QPoint &/*pos*/)
void KatePluginSearchView::customResMenuRequested(const QPoint &pos)
{
// FIXME QTreeWidget *tree = qobject_cast<QTreeWidget *>(sender());
// if (tree == nullptr) {
// return;
// }
// QMenu *menu = new QMenu(tree);
//
// QAction *copyAll = new QAction(i18n("Copy all"), tree);
// copyAll->setShortcut(QKeySequence::Copy);
// copyAll->setShortcutVisibleInContextMenu(true);
// menu->addAction(copyAll);
//
// QAction *copyExpanded = new QAction(i18n("Copy expanded"), tree);
// menu->addAction(copyExpanded);
//
// menu->popup(tree->viewport()->mapToGlobal(pos));
//
// connect(copyAll, &QAction::triggered, this, [this](bool) { copySearchToClipboard(All); });
// connect(copyExpanded, &QAction::triggered, this, [this](bool) { copySearchToClipboard(AllExpanded); });
QTreeView *tree = qobject_cast<QTreeView *>(sender());
if (tree == nullptr) {
return;
}
QMenu *menu = new QMenu(tree);
QAction *copyAll = new QAction(i18n("Copy all"), tree);
copyAll->setShortcut(QKeySequence::Copy);
copyAll->setShortcutVisibleInContextMenu(true);
menu->addAction(copyAll);
QAction *copyExpanded = new QAction(i18n("Copy expanded"), tree);
menu->addAction(copyExpanded);
menu->popup(tree->viewport()->mapToGlobal(pos));
connect(copyAll, &QAction::triggered, this, [this](bool) { copySearchToClipboard(All); });
connect(copyExpanded, &QAction::triggered, this, [this](bool) { copySearchToClipboard(AllExpanded); });
}
// FIXME static QString copySearchSummary(const QTreeWidgetItem *summaryItem)
// {
// if (summaryItem) {
// int matches = 0;
// for (int i = 0; i < summaryItem->childCount(); ++i) {
// matches += summaryItem->child(i)->childCount();
// }
// return i18np("A total of %1 match found\n", "A total of %1 matches found\n", matches);
// }
// return QString();
// }
// FIXME static QString copySearchMatchFile(QTreeWidgetItem *fileItem)
// {
// if (fileItem) {
// QUrl url(fileItem->data(0, ReplaceMatches::FileUrlRole).toString());
// int matches = fileItem->childCount();
// return i18np("%1 match found in: %2\n", "%1 matches found in: %2\n", matches, url.toLocalFile());
// }
// return QString();
// }
//
// static QString copySearchMatch(QTreeWidgetItem *matchItem)
// {
// if (matchItem) {
// int startLine = matchItem->data(0, ReplaceMatches::StartLineRole).toInt();
// int startColumn = matchItem->data(0, ReplaceMatches::StartColumnRole).toInt();
// QString match = matchItem->data(0, ReplaceMatches::PreMatchRole).toString();
// match += matchItem->data(0, ReplaceMatches::MatchRole).toString();
// match += matchItem->data(0, ReplaceMatches::PostMatchRole).toString();
// return i18n("\tLine: %1 column: %2: %3\n", startLine, startColumn, match);
// }
// return QString();
// }
void KatePluginSearchView::copySearchToClipboard(CopyResultType /*copyType*/)
void KatePluginSearchView::copySearchToClipboard(CopyResultType copyType)
{
// FIXME Results *res = qobject_cast<Results *>(m_ui.resultTabWidget->currentWidget());
// if (!res) {
// return;
// }
// if (res->tree->topLevelItemCount() == 0) {
// return;
// }
//
// QString clipboard;
//
// QTreeWidgetItem *currentItem = res->tree->topLevelItem(0);
//
// QTreeWidgetItem *parent = currentItem->parent();
// if (currentItem->childCount() == 0) {
// // this is probably a single match
// if (parent) {
// clipboard += copySearchMatchFile(parent);
// clipboard += copySearchMatch(currentItem);
// } else {
// clipboard = i18n("No matches found\n");
// }
// } else {
// if (parent) {
// clipboard += copySearchSummary(parent);
// clipboard += copySearchMatchFile(currentItem);
// } else {
// clipboard += m_isSearchAsYouType ? copySearchMatchFile(currentItem) : copySearchSummary(currentItem);
// }
//
// for (int i = 0; i < currentItem->childCount() && (currentItem->isExpanded() || copyType == All); ++i) {
// QTreeWidgetItem *child = currentItem->child(i);
// if (child->childCount() == 0) {
// clipboard += copySearchMatch(child);
// } else {
// clipboard += copySearchMatchFile(child);
// for (int j = 0; j < child->childCount() && (child->isExpanded() || copyType == All); ++j) {
// QTreeWidgetItem *grandChild = child->child(j);
// clipboard += copySearchMatch(grandChild);
// }
// }
// }
// }
// QApplication::clipboard()->setText(clipboard);
Results *res = qobject_cast<Results *>(m_ui.resultTabWidget->currentWidget());
if (!res) {
return;
}
if (res->matchModel.rowCount() == 0) {
return;
}
QString clipboard;
QModelIndex rootIndex = res->matchModel.index(0, 0);
clipboard = rootIndex.data(MatchModel::PlainTextRole).toString();
int fileCount = res->matchModel.rowCount(rootIndex);
for (int i = 0; i < fileCount; ++i) {
QModelIndex fileIndex = res->matchModel.index(i, 0, rootIndex);
if (res->treeView->isExpanded(fileIndex) || copyType == All) {
clipboard += QLatin1String("\n") + fileIndex.data(MatchModel::PlainTextRole).toString();
int matchCount = res->matchModel.rowCount(fileIndex);
for (int j=0; j<matchCount; ++j) {
QModelIndex matchIndex = res->matchModel.index(j, 0, fileIndex);
clipboard += QLatin1String("\n") + matchIndex.data(MatchModel::PlainTextRole).toString();
}
}
}
clipboard += QLatin1String("\n");
QApplication::clipboard()->setText(clipboard);
}
bool KatePluginSearchView::eventFilter(QObject *obj, QEvent *event)
......
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