File indexing completed on 2024-04-21 03:57:40

0001 /*
0002     SPDX-FileCopyrightText: 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0003     SPDX-FileCopyrightText: 2007 Sebastian Pipping <webmaster@hartwork.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KATE_SEARCH_BAR_H
0009 #define KATE_SEARCH_BAR_H 1
0010 
0011 #include "kateviewhelpers.h"
0012 #include <ktexteditor_export.h>
0013 
0014 #include <ktexteditor/attribute.h>
0015 #include <ktexteditor/document.h>
0016 
0017 namespace KTextEditor
0018 {
0019 class ViewPrivate;
0020 }
0021 class KateViewConfig;
0022 class QVBoxLayout;
0023 class QComboBox;
0024 
0025 namespace Ui
0026 {
0027 class IncrementalSearchBar;
0028 class PowerSearchBar;
0029 }
0030 
0031 namespace KTextEditor
0032 {
0033 class MovingRange;
0034 class Message;
0035 }
0036 
0037 class KTEXTEDITOR_EXPORT KateSearchBar : public KateViewBarWidget
0038 {
0039     Q_OBJECT
0040 
0041     friend class SearchBarTest;
0042 
0043 public:
0044     enum SearchMode {
0045         // NOTE: Concrete values are important here
0046         // to work with the combobox index!
0047         MODE_PLAIN_TEXT = 0,
0048         MODE_WHOLE_WORDS = 1,
0049         MODE_ESCAPE_SEQUENCES = 2,
0050         MODE_REGEX = 3
0051     };
0052 
0053     enum MatchResult { MatchFound, MatchWrappedForward, MatchWrappedBackward, MatchMismatch, MatchNothing, MatchNeutral };
0054 
0055     enum SearchDirection { SearchForward, SearchBackward };
0056 
0057 public:
0058     explicit KateSearchBar(bool initAsPower, KTextEditor::ViewPrivate *view, KateViewConfig *config);
0059     ~KateSearchBar() override;
0060 
0061     void closed() override;
0062 
0063     bool isPower() const;
0064 
0065     QString searchPattern() const;
0066     QString replacementPattern() const;
0067 
0068     bool selectionOnly() const;
0069     bool matchCase() const;
0070 
0071     void nextMatchForSelection(KTextEditor::ViewPrivate *view, SearchDirection searchDirection);
0072 
0073 public Q_SLOTS:
0074     /**
0075      * Set the current search pattern.
0076      * @param searchPattern the search pattern
0077      */
0078     void setSearchPattern(const QString &searchPattern);
0079 
0080     /**
0081      * Set the current replacement pattern.
0082      * @param replacementPattern the replacement pattern
0083      */
0084     void setReplacementPattern(const QString &replacementPattern);
0085 
0086     void setSearchMode(SearchMode mode);
0087     void setSelectionOnly(bool selectionOnly);
0088     void setMatchCase(bool matchCase);
0089 
0090     // Called by buttons and typically <F3>/<Shift>+<F3> shortcuts
0091     void findNext();
0092     void findPrevious();
0093 
0094     // PowerMode stuff
0095     void findAll();
0096     void replaceNext();
0097     void replaceAll();
0098 
0099     // Also used by KTextEditor::ViewPrivate
0100     void enterPowerMode();
0101     void enterIncrementalMode();
0102 
0103     bool clearHighlights();
0104     void updateHighlightColors();
0105 
0106     // read write status of document changed
0107     void slotReadWriteChanged();
0108 
0109 protected:
0110     // Overridden
0111     void showEvent(QShowEvent *event) override;
0112     bool eventFilter(QObject *obj, QEvent *event) override;
0113 
0114 private Q_SLOTS:
0115     void onIncPatternChanged(const QString &pattern);
0116     void onMatchCaseToggled(bool matchCase);
0117 
0118     void onReturnPressed();
0119     void updateSelectionOnly();
0120     void updateIncInitCursor();
0121 
0122     void onPowerPatternChanged(const QString &pattern);
0123     void onPowerModeChanged(int index);
0124     void onPowerPatternContextMenuRequest();
0125     void onPowerPatternContextMenuRequest(const QPoint &);
0126     void onPowerReplacmentContextMenuRequest();
0127     void onPowerReplacmentContextMenuRequest(const QPoint &);
0128     void onPowerCancelFindOrReplace();
0129 
0130     /**
0131      * This function do the hard search & replace work in time slice steps.
0132      * When all is done @ref m_matchCounter is set and the signal
0133      * @ref findOrReplaceAllFinished() is emitted.
0134      */
0135     void findOrReplaceAll();
0136 
0137     /**
0138      * Restore needed settings when signal @ref findOrReplaceAllFinished()
0139      * was received.
0140      */
0141     void endFindOrReplaceAll();
0142 
0143 Q_SIGNALS:
0144     /**
0145      * Will emitted by @ref findOrReplaceAll() when all is done.
0146      */
0147     void findOrReplaceAllFinished();
0148 
0149 private:
0150     // Helpers
0151     bool find(SearchDirection searchDirection = SearchForward)
0152     {
0153         return findOrReplace(searchDirection, nullptr);
0154     };
0155     KTEXTEDITOR_NO_EXPORT
0156     bool findOrReplace(SearchDirection searchDirection, const QString *replacement);
0157 
0158     /**
0159      * The entry point to start a search & replace task.
0160      * Set needed member variables and call @ref findOrReplaceAll() to do the work.
0161      */
0162     KTEXTEDITOR_NO_EXPORT
0163     void beginFindOrReplaceAll(KTextEditor::Range inputRange, const QString &replacement, bool replaceMode = true);
0164     KTEXTEDITOR_NO_EXPORT
0165     void beginFindAll(KTextEditor::Range inputRange)
0166     {
0167         beginFindOrReplaceAll(inputRange, QString(), false);
0168     };
0169 
0170     KTEXTEDITOR_NO_EXPORT
0171     bool isPatternValid() const;
0172 
0173     KTEXTEDITOR_NO_EXPORT
0174     KTextEditor::SearchOptions searchOptions(SearchDirection searchDirection = SearchForward) const;
0175 
0176     KTEXTEDITOR_NO_EXPORT
0177     void highlightMatch(KTextEditor::Range range);
0178     KTEXTEDITOR_NO_EXPORT
0179     void highlightReplacement(KTextEditor::Range range);
0180     KTEXTEDITOR_NO_EXPORT
0181     void indicateMatch(MatchResult matchResult);
0182     KTEXTEDITOR_NO_EXPORT
0183     static void selectRange(KTextEditor::ViewPrivate *view, KTextEditor::Range range);
0184     KTEXTEDITOR_NO_EXPORT
0185     void selectRange2(KTextEditor::Range range);
0186 
0187     KTEXTEDITOR_NO_EXPORT
0188     QList<QString> getCapturePatterns(const QString &pattern) const;
0189     KTEXTEDITOR_NO_EXPORT
0190     void showExtendedContextMenu(bool forPattern, const QPoint &pos);
0191 
0192     KTEXTEDITOR_NO_EXPORT
0193     void givePatternFeedback();
0194     KTEXTEDITOR_NO_EXPORT
0195     void addCurrentTextToHistory(QComboBox *combo);
0196     KTEXTEDITOR_NO_EXPORT
0197     void backupConfig(bool ofPower);
0198     KTEXTEDITOR_NO_EXPORT
0199     void sendConfig();
0200 
0201     KTEXTEDITOR_NO_EXPORT
0202     void showResultMessage();
0203 
0204 private:
0205     KTextEditor::ViewPrivate *const m_view;
0206     KateViewConfig *const m_config;
0207     QList<KTextEditor::MovingRange *> m_hlRanges;
0208     QPointer<KTextEditor::Message> m_infoMessage;
0209 
0210     // Shared by both dialogs
0211     QVBoxLayout *const m_layout;
0212     QWidget *m_widget;
0213     QString m_unfinishedSearchText;
0214 
0215     // Incremental search related
0216     Ui::IncrementalSearchBar *m_incUi;
0217     KTextEditor::Cursor m_incInitCursor;
0218 
0219     // Power search related
0220     Ui::PowerSearchBar *m_powerUi = nullptr;
0221     KTextEditor::MovingRange *m_workingRange = nullptr;
0222     KTextEditor::Range m_inputRange;
0223     QString m_replacement;
0224     uint m_matchCounter = 0;
0225     bool m_replaceMode = false;
0226     bool m_cancelFindOrReplace = true;
0227     bool m_selectionChangedByUndoRedo = false;
0228     std::vector<KTextEditor::Range> m_highlightRanges;
0229 
0230     // attribute to highlight matches with
0231     KTextEditor::Attribute::Ptr highlightMatchAttribute;
0232     KTextEditor::Attribute::Ptr highlightReplacementAttribute;
0233 
0234     // Status backup
0235     bool m_incHighlightAll : 1;
0236     bool m_incFromCursor : 1;
0237     bool m_incMatchCase : 1;
0238     bool m_powerMatchCase : 1;
0239     bool m_powerFromCursor : 1;
0240     bool m_powerHighlightAll : 1;
0241     unsigned int m_powerMode : 2;
0242 };
0243 
0244 #endif // KATE_SEARCH_BAR_H