File indexing completed on 2024-04-28 05:49:12

0001 /*
0002     SPDX-FileCopyrightText: 2011-21 Kåre Särs <kare.sars@iki.fi>
0003     SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 #include "Results.h"
0008 
0009 #include "MatchProxyModel.h"
0010 #include "SearchResultsDelegate.h"
0011 
0012 #include <KSyntaxHighlighting/Theme>
0013 #include <KTextEditor/Editor>
0014 
0015 Results::Results(QWidget *parent)
0016     : QWidget(parent)
0017 {
0018     setupUi(this);
0019 
0020     treeView->setItemDelegate(new SearchResultsDelegate(treeView));
0021     treeView->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::TopEdge}));
0022     connect(treeView, &ResultsTreeView::detachClicked, this, [this] {
0023         Q_EMIT requestDetachToMainWindow(this);
0024     });
0025 
0026     MatchProxyModel *proxy = new MatchProxyModel(this);
0027     proxy->setSourceModel(&matchModel);
0028     proxy->setRecursiveFilteringEnabled(true);
0029     treeView->setModel(proxy);
0030 
0031     filterLineEdit->setVisible(false);
0032     filterLineEdit->setPlaceholderText(i18n("Filter..."));
0033 
0034     connect(filterLineEdit, &QLineEdit::textChanged, this, [this, proxy](const QString &text) {
0035         proxy->setFilterText(text);
0036         QTimer::singleShot(10, treeView, &QTreeView::expandAll);
0037     });
0038 
0039     auto updateColors = [this](KTextEditor::Editor *e) {
0040         if (!e) {
0041             return;
0042         }
0043         const auto theme = e->theme();
0044         auto search = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::SearchHighlight));
0045         auto replace = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::ReplaceHighlight));
0046         auto fg = QColor::fromRgba(theme.textColor(KSyntaxHighlighting::Theme::Normal));
0047 
0048         matchModel.setMatchColors(fg.name(QColor::HexArgb), search.name(QColor::HexArgb), replace.name(QColor::HexArgb));
0049     };
0050 
0051     auto e = KTextEditor::Editor::instance();
0052     connect(e, &KTextEditor::Editor::configChanged, this, updateColors);
0053     updateColors(e);
0054 }
0055 
0056 void Results::setFilterLineVisible(bool visible)
0057 {
0058     filterLineEdit->setVisible(visible);
0059     if (!visible) {
0060         filterLineEdit->clear();
0061     } else {
0062         filterLineEdit->setFocus();
0063     }
0064 }
0065 
0066 void Results::expandRoot()
0067 {
0068     treeView->expand(treeView->model()->index(0, 0));
0069 }
0070 
0071 MatchProxyModel *Results::model() const
0072 {
0073     return static_cast<MatchProxyModel *>(treeView->model());
0074 }
0075 
0076 bool Results::isEmpty() const
0077 {
0078     return matchModel.isEmpty();
0079 }
0080 
0081 bool Results::isMatch(const QModelIndex &index) const
0082 {
0083     Q_ASSERT(!index.isValid() || index.model() == model());
0084     return matchModel.isMatch(model()->mapToSource(index));
0085 }
0086 
0087 QModelIndex Results::firstFileMatch(KTextEditor::Document *doc) const
0088 {
0089     return model()->mapFromSource(matchModel.firstFileMatch(doc));
0090 }
0091 
0092 QModelIndex Results::closestMatchAfter(KTextEditor::Document *doc, const KTextEditor::Cursor &cursor) const
0093 {
0094     return model()->mapFromSource(matchModel.closestMatchAfter(doc, cursor));
0095 }
0096 
0097 QModelIndex Results::firstMatch() const
0098 {
0099     return model()->mapFromSource(matchModel.firstMatch());
0100 }
0101 
0102 QModelIndex Results::nextMatch(const QModelIndex &itemIndex) const
0103 {
0104     Q_ASSERT(!itemIndex.isValid() || itemIndex.model() == model());
0105     return model()->mapFromSource(matchModel.nextMatch(model()->mapToSource(itemIndex)));
0106 }
0107 
0108 QModelIndex Results::prevMatch(const QModelIndex &itemIndex) const
0109 {
0110     Q_ASSERT(!itemIndex.isValid() || itemIndex.model() == model());
0111     return model()->mapFromSource(matchModel.prevMatch(model()->mapToSource(itemIndex)));
0112 }
0113 
0114 QModelIndex Results::closestMatchBefore(KTextEditor::Document *doc, const KTextEditor::Cursor &cursor) const
0115 {
0116     return model()->mapFromSource(matchModel.closestMatchBefore(doc, cursor));
0117 }
0118 
0119 QModelIndex Results::lastMatch() const
0120 {
0121     return model()->mapFromSource(matchModel.lastMatch());
0122 }
0123 
0124 KTextEditor::Range Results::matchRange(const QModelIndex &matchIndex) const
0125 {
0126     Q_ASSERT(matchIndex.model() == model());
0127     return matchModel.matchRange(model()->mapToSource(matchIndex));
0128 }
0129 
0130 bool Results::replaceSingleMatch(KTextEditor::Document *doc, const QModelIndex &matchIndex, const QRegularExpression &regExp, const QString &replaceString)
0131 {
0132     Q_ASSERT(matchIndex.model() == model());
0133     const auto sourceIndex = model()->mapToSource(matchIndex);
0134     return matchModel.replaceSingleMatch(doc, sourceIndex, regExp, replaceString);
0135 }
0136 
0137 #include "moc_Results.cpp"