File indexing completed on 2024-04-28 05:49:14
0001 /* 0002 SPDX-FileCopyrightText: 2011-21 Kåre Särs <kare.sars@iki.fi> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <KTextEditor/Command> 0010 #include <KTextEditor/Message> 0011 #include <KTextEditor/Plugin> 0012 #include <QAction> 0013 #include <ktexteditor/application.h> 0014 #include <ktexteditor/mainwindow.h> 0015 #include <ktexteditor/sessionconfiginterface.h> 0016 0017 #include <QThreadPool> 0018 #include <QTimer> 0019 #include <QTreeView> 0020 0021 #include <KXMLGUIClient> 0022 0023 #include "ui_results.h" 0024 #include "ui_search.h" 0025 0026 #include "FolderFilesList.h" 0027 #include "MatchModel.h" 0028 #include "SearchDiskFiles.h" 0029 #include "SearchOpenFiles.h" 0030 0031 class KateSearchCommand; 0032 class Results; 0033 class QPoint; 0034 namespace KTextEditor 0035 { 0036 class MovingRange; 0037 class MovingInterface; 0038 } 0039 0040 // This class keeps the focus inside the S&R plugin when pressing tab/shift+tab by overriding focusNextPrevChild() 0041 class ContainerWidget : public QWidget 0042 { 0043 Q_OBJECT 0044 public: 0045 ContainerWidget(QWidget *parent) 0046 : QWidget(parent) 0047 { 0048 } 0049 0050 Q_SIGNALS: 0051 void nextFocus(QWidget *currentWidget, bool *found, bool next); 0052 0053 protected: 0054 bool focusNextPrevChild(bool next) override; 0055 }; 0056 0057 class KatePluginSearch : public KTextEditor::Plugin 0058 { 0059 Q_OBJECT 0060 0061 public: 0062 explicit KatePluginSearch(QObject *parent = nullptr, const QVariantList & = QVariantList()); 0063 ~KatePluginSearch() override; 0064 0065 QObject *createView(KTextEditor::MainWindow *mainWindow) override; 0066 0067 private: 0068 KateSearchCommand *m_searchCommand = nullptr; 0069 }; 0070 0071 class KatePluginSearchView : public QObject, public KXMLGUIClient, public KTextEditor::SessionConfigInterface 0072 { 0073 Q_OBJECT 0074 Q_INTERFACES(KTextEditor::SessionConfigInterface) 0075 0076 public: 0077 KatePluginSearchView(KTextEditor::Plugin *plugin, KTextEditor::MainWindow *mainWindow, KTextEditor::Application *application); 0078 ~KatePluginSearchView() override; 0079 0080 void readSessionConfig(const KConfigGroup &config) override; 0081 void writeSessionConfig(KConfigGroup &config) override; 0082 0083 static void addRegexHelperActionsForReplace(QSet<QAction *> *actionList, QMenu *menu); 0084 static void regexHelperActOnAction(QAction *resultAction, const QSet<QAction *> &actionList, QLineEdit *lineEdit); 0085 0086 public Q_SLOTS: 0087 void stopClicked(); 0088 void startSearch(); 0089 void setSearchString(const QString &pattern); 0090 void navigateFolderUp(); 0091 void setCurrentFolder(); 0092 void setSearchPlace(int place); 0093 void goToNextMatch(); 0094 void goToPreviousMatch(); 0095 void setRegexMode(bool enabled); 0096 void setCaseInsensitive(bool enabled); 0097 void setExpandResults(bool enabled); 0098 0099 private: 0100 enum CopyResultType { AllExpanded, All }; 0101 enum class MatchType { NoMatch, HasMatch, InvalidRegExp }; 0102 0103 private Q_SLOTS: 0104 void openSearchView(); 0105 void handleEsc(QEvent *e); 0106 void nextFocus(QWidget *currentWidget, bool *found, bool next); 0107 0108 void addTab(); 0109 void tabCloseRequested(int index); 0110 void toggleOptions(bool show); 0111 void detachTabToMainWindow(Results *); 0112 0113 void searchContextMenu(const QPoint &pos); 0114 void replaceContextMenu(const QPoint &pos); 0115 0116 void searchPlaceChanged(); 0117 void startSearchWhileTyping(); 0118 0119 void folderFileListChanged(); 0120 0121 void matchesFound(const QUrl &url, const QList<KateSearchMatch> &searchMatches, KTextEditor::Document *doc); 0122 0123 void addRangeAndMark(KTextEditor::Document *doc, const KateSearchMatch &match, KTextEditor::Attribute::Ptr attr); 0124 0125 void searchDone(); 0126 void searchWhileTypingDone(); 0127 0128 void indicateMatch(MatchType matchType); 0129 0130 void itemSelected(const QModelIndex &item); 0131 0132 void clearMarksAndRanges(); 0133 void clearDocMarksAndRanges(KTextEditor::Document *doc); 0134 0135 void replaceSingleMatch(); 0136 void replaceChecked(); 0137 0138 void replaceDone(); 0139 0140 void updateCheckState(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles); 0141 void updateMatchMarks(); 0142 0143 void syncModelRanges(); 0144 0145 void resultTabChanged(int index); 0146 0147 void expandResults(); 0148 0149 /** 0150 * keep track if the project plugin is alive and if the project file did change 0151 */ 0152 void slotPluginViewCreated(const QString &name, QObject *pluginView); 0153 void slotPluginViewDeleted(const QString &name, QObject *pluginView); 0154 void slotProjectFileNameChanged(); 0155 0156 void copySearchToClipboard(CopyResultType type); 0157 void showExportMatchesDialog(); 0158 void customResMenuRequested(const QPoint &pos); 0159 0160 void cutSearchedLines(); 0161 void copySearchedLines(); 0162 0163 Q_SIGNALS: 0164 void searchBusy(bool busy); 0165 0166 protected: 0167 bool eventFilter(QObject *obj, QEvent *ev) override; 0168 0169 private: 0170 QList<int> getDocumentSearchMarkedLines(KTextEditor::Document *currentDocument); 0171 void setClipboardFromDocumentLines(const KTextEditor::Document *currentDocument, const QList<int> lineNumbers); 0172 0173 QStringList filterFiles(const QStringList &fileList) const; 0174 void startDiskFileSearch(const QStringList &fileList, const QRegularExpression ®, bool includeBinaryFiles); 0175 void cancelDiskFileSearch(); 0176 bool searchingDiskFiles(); 0177 0178 void updateViewColors(); 0179 0180 void onResize(const QSize &size); 0181 0182 Ui::SearchDialog m_ui{}; 0183 QWidget *m_toolView; 0184 KTextEditor::Application *m_kateApp; 0185 SearchOpenFiles m_searchOpenFiles; 0186 FolderFilesList m_folderFilesList; 0187 0188 /** 0189 * worklist for runnables, must survive thread pool below! 0190 */ 0191 SearchDiskFilesWorkList m_worklistForDiskFiles; 0192 0193 /** 0194 * threadpool for multi-threaded disk search 0195 */ 0196 QThreadPool m_searchDiskFilePool; 0197 0198 QTimer m_diskSearchDoneTimer; 0199 QTimer m_updateCheckedStateTimer; 0200 Results *m_curResults = nullptr; 0201 QTabBar *m_tabBar = nullptr; 0202 bool m_searchJustOpened = false; 0203 int m_projectSearchPlaceIndex = 0; 0204 bool m_isSearchAsYouType = false; 0205 bool m_isVerticalLayout = false; 0206 QString m_resultBaseDir; 0207 QList<KTextEditor::MovingRange *> m_matchRanges; 0208 QTimer m_changeTimer; 0209 QPointer<KTextEditor::Message> m_infoMessage; 0210 QColor m_replaceHighlightColor; 0211 KTextEditor::Attribute::Ptr m_resultAttr; 0212 0213 QHash<MatchModel::SearchPlaces, bool> m_searchAsYouType; 0214 0215 /** 0216 * current project plugin view, if any 0217 */ 0218 QObject *m_projectPluginView = nullptr; 0219 0220 /** 0221 * our main window 0222 */ 0223 KTextEditor::MainWindow *m_mainWindow; 0224 }; 0225 0226 // kate: space-indent on; indent-width 4; replace-tabs on;