1 | /* |
2 | SPDX-FileCopyrightText: 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de> |
3 | SPDX-FileCopyrightText: 2007 Sebastian Pipping <webmaster@hartwork.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef KATE_SEARCH_BAR_H |
9 | #define KATE_SEARCH_BAR_H 1 |
10 | |
11 | #include "kateviewhelpers.h" |
12 | #include <ktexteditor_export.h> |
13 | |
14 | #include <ktexteditor/attribute.h> |
15 | #include <ktexteditor/document.h> |
16 | |
17 | namespace KTextEditor |
18 | { |
19 | class ViewPrivate; |
20 | } |
21 | class KateViewConfig; |
22 | class QVBoxLayout; |
23 | class QComboBox; |
24 | |
25 | namespace Ui |
26 | { |
27 | class IncrementalSearchBar; |
28 | class PowerSearchBar; |
29 | } |
30 | |
31 | namespace KTextEditor |
32 | { |
33 | class MovingRange; |
34 | class Message; |
35 | } |
36 | |
37 | class KTEXTEDITOR_EXPORT KateSearchBar : public KateViewBarWidget |
38 | { |
39 | Q_OBJECT |
40 | |
41 | friend class SearchBarTest; |
42 | |
43 | public: |
44 | enum SearchMode { |
45 | // NOTE: Concrete values are important here |
46 | // to work with the combobox index! |
47 | MODE_PLAIN_TEXT = 0, |
48 | MODE_WHOLE_WORDS = 1, |
49 | MODE_ESCAPE_SEQUENCES = 2, |
50 | MODE_REGEX = 3 |
51 | }; |
52 | |
53 | enum MatchResult { MatchFound, MatchWrappedForward, MatchWrappedBackward, MatchMismatch, MatchNothing, MatchNeutral }; |
54 | |
55 | enum SearchDirection { SearchForward, SearchBackward }; |
56 | |
57 | public: |
58 | explicit KateSearchBar(bool initAsPower, KTextEditor::ViewPrivate *view, KateViewConfig *config); |
59 | ~KateSearchBar() override; |
60 | |
61 | void closed() override; |
62 | |
63 | bool isPower() const; |
64 | |
65 | QString searchPattern() const; |
66 | QString replacementPattern() const; |
67 | |
68 | bool selectionOnly() const; |
69 | bool matchCase() const; |
70 | |
71 | void nextMatchForSelection(KTextEditor::ViewPrivate *view, SearchDirection searchDirection); |
72 | |
73 | public Q_SLOTS: |
74 | /** |
75 | * Set the current search pattern. |
76 | * @param searchPattern the search pattern |
77 | */ |
78 | void setSearchPattern(const QString &searchPattern); |
79 | |
80 | /** |
81 | * Set the current replacement pattern. |
82 | * @param replacementPattern the replacement pattern |
83 | */ |
84 | void setReplacementPattern(const QString &replacementPattern); |
85 | |
86 | void setSearchMode(SearchMode mode); |
87 | void setSelectionOnly(bool selectionOnly); |
88 | void setMatchCase(bool matchCase); |
89 | |
90 | // Called by buttons and typically <F3>/<Shift>+<F3> shortcuts |
91 | void findNext(); |
92 | void findPrevious(); |
93 | |
94 | // PowerMode stuff |
95 | void findAll(); |
96 | void replaceNext(); |
97 | void replaceAll(); |
98 | |
99 | // Also used by KTextEditor::ViewPrivate |
100 | void enterPowerMode(); |
101 | void enterIncrementalMode(); |
102 | |
103 | bool clearHighlights(); |
104 | void updateHighlightColors(); |
105 | |
106 | // read write status of document changed |
107 | void slotReadWriteChanged(); |
108 | |
109 | protected: |
110 | // Overridden |
111 | void showEvent(QShowEvent *event) override; |
112 | bool eventFilter(QObject *obj, QEvent *event) override; |
113 | |
114 | private Q_SLOTS: |
115 | void onIncPatternChanged(const QString &pattern); |
116 | void onMatchCaseToggled(bool matchCase); |
117 | |
118 | void onReturnPressed(); |
119 | void updateSelectionOnly(); |
120 | void updateIncInitCursor(); |
121 | |
122 | void onPowerPatternChanged(const QString &pattern); |
123 | void onPowerModeChanged(int index); |
124 | void (); |
125 | void (const QPoint &); |
126 | void (); |
127 | void (const QPoint &); |
128 | void onPowerCancelFindOrReplace(); |
129 | |
130 | /** |
131 | * This function do the hard search & replace work in time slice steps. |
132 | * When all is done @ref m_matchCounter is set and the signal |
133 | * @ref findOrReplaceAllFinished() is emitted. |
134 | */ |
135 | void findOrReplaceAll(); |
136 | |
137 | /** |
138 | * Restore needed settings when signal @ref findOrReplaceAllFinished() |
139 | * was received. |
140 | */ |
141 | void endFindOrReplaceAll(); |
142 | |
143 | Q_SIGNALS: |
144 | /** |
145 | * Will emitted by @ref findOrReplaceAll() when all is done. |
146 | */ |
147 | void findOrReplaceAllFinished(); |
148 | |
149 | private: |
150 | // Helpers |
151 | bool find(SearchDirection searchDirection = SearchForward) |
152 | { |
153 | return findOrReplace(searchDirection, replacement: nullptr); |
154 | }; |
155 | KTEXTEDITOR_NO_EXPORT |
156 | bool findOrReplace(SearchDirection searchDirection, const QString *replacement); |
157 | |
158 | /** |
159 | * The entry point to start a search & replace task. |
160 | * Set needed member variables and call @ref findOrReplaceAll() to do the work. |
161 | */ |
162 | KTEXTEDITOR_NO_EXPORT |
163 | void beginFindOrReplaceAll(KTextEditor::Range inputRange, const QString &replacement, bool replaceMode = true); |
164 | KTEXTEDITOR_NO_EXPORT |
165 | void beginFindAll(KTextEditor::Range inputRange) |
166 | { |
167 | beginFindOrReplaceAll(inputRange, replacement: QString(), replaceMode: false); |
168 | }; |
169 | |
170 | KTEXTEDITOR_NO_EXPORT |
171 | bool isPatternValid() const; |
172 | |
173 | KTEXTEDITOR_NO_EXPORT |
174 | KTextEditor::SearchOptions searchOptions(SearchDirection searchDirection = SearchForward) const; |
175 | |
176 | KTEXTEDITOR_NO_EXPORT |
177 | void highlightMatch(KTextEditor::Range range); |
178 | KTEXTEDITOR_NO_EXPORT |
179 | void highlightReplacement(KTextEditor::Range range); |
180 | KTEXTEDITOR_NO_EXPORT |
181 | void indicateMatch(MatchResult matchResult); |
182 | KTEXTEDITOR_NO_EXPORT |
183 | static void selectRange(KTextEditor::ViewPrivate *view, KTextEditor::Range range); |
184 | KTEXTEDITOR_NO_EXPORT |
185 | void selectRange2(KTextEditor::Range range); |
186 | |
187 | KTEXTEDITOR_NO_EXPORT |
188 | QList<QString> getCapturePatterns(const QString &pattern) const; |
189 | KTEXTEDITOR_NO_EXPORT |
190 | void (bool forPattern, const QPoint &pos); |
191 | |
192 | KTEXTEDITOR_NO_EXPORT |
193 | void givePatternFeedback(); |
194 | KTEXTEDITOR_NO_EXPORT |
195 | void addCurrentTextToHistory(QComboBox *combo); |
196 | KTEXTEDITOR_NO_EXPORT |
197 | void backupConfig(bool ofPower); |
198 | KTEXTEDITOR_NO_EXPORT |
199 | void sendConfig(); |
200 | |
201 | KTEXTEDITOR_NO_EXPORT |
202 | void showResultMessage(); |
203 | |
204 | private: |
205 | KTextEditor::ViewPrivate *const m_view; |
206 | KateViewConfig *const m_config; |
207 | QList<KTextEditor::MovingRange *> m_hlRanges; |
208 | QPointer<KTextEditor::Message> m_infoMessage; |
209 | |
210 | // Shared by both dialogs |
211 | QVBoxLayout *const m_layout; |
212 | QWidget *m_widget; |
213 | QString m_unfinishedSearchText; |
214 | |
215 | // Incremental search related |
216 | Ui::IncrementalSearchBar *m_incUi; |
217 | KTextEditor::Cursor m_incInitCursor; |
218 | |
219 | // Power search related |
220 | Ui::PowerSearchBar *m_powerUi = nullptr; |
221 | KTextEditor::MovingRange *m_workingRange = nullptr; |
222 | KTextEditor::Range m_inputRange; |
223 | QString m_replacement; |
224 | uint m_matchCounter = 0; |
225 | bool m_replaceMode = false; |
226 | bool m_cancelFindOrReplace = true; |
227 | bool m_selectionChangedByUndoRedo = false; |
228 | std::vector<KTextEditor::Range> m_highlightRanges; |
229 | |
230 | // attribute to highlight matches with |
231 | KTextEditor::Attribute::Ptr highlightMatchAttribute; |
232 | KTextEditor::Attribute::Ptr highlightReplacementAttribute; |
233 | |
234 | // Status backup |
235 | bool m_incHighlightAll : 1; |
236 | bool m_incFromCursor : 1; |
237 | bool m_incMatchCase : 1; |
238 | bool m_powerMatchCase : 1; |
239 | bool m_powerFromCursor : 1; |
240 | bool m_powerHighlightAll : 1; |
241 | unsigned int m_powerMode : 2; |
242 | }; |
243 | |
244 | #endif // KATE_SEARCH_BAR_H |
245 | |