File indexing completed on 2024-04-28 15:51:45

0001 /*
0002     SPDX-FileCopyrightText: 2003 Scott Wheeler <wheeler@kde.org>
0003     SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net>
0004     SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>
0005     SPDX-FileCopyrightText: 2007 Pino Toscano <pino@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-only
0008 */
0009 
0010 #ifndef KTREEVIEWSEARCHLINE_H
0011 #define KTREEVIEWSEARCHLINE_H
0012 
0013 #include <KLineEdit>
0014 
0015 class QModelIndex;
0016 class QTreeView;
0017 
0018 /**
0019  * This class makes it easy to add a search line for filtering the items in
0020  * listviews based on a simple text search.
0021  *
0022  * No changes to the application other than instantiating this class with
0023  * appropriate QTreeViews should be needed.
0024  */
0025 
0026 class KTreeViewSearchLine : public KLineEdit
0027 {
0028     Q_OBJECT
0029 
0030     Q_PROPERTY(Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity NOTIFY searchOptionsChanged)
0031 
0032 public:
0033     /**
0034      * Constructs a KTreeViewSearchLine with \a treeView being the QTreeView to
0035      * be filtered.
0036      *
0037      * If \a treeView is null then the widget will be disabled until listview
0038      * are set with setTreeView().
0039      */
0040     explicit KTreeViewSearchLine(QWidget *parent = nullptr, QTreeView *treeView = nullptr);
0041 
0042     /**
0043      * Destroys the KTreeViewSearchLine.
0044      */
0045     ~KTreeViewSearchLine() override;
0046 
0047     /**
0048      * Returns true if the search is case sensitive.  This defaults to false.
0049      *
0050      * @see setCaseSensitive()
0051      */
0052     Qt::CaseSensitivity caseSensitivity() const;
0053 
0054     /**
0055      * Returns true if the search is a regular expression search.  This defaults to false.
0056      *
0057      * @see setRegularExpression()
0058      */
0059     bool regularExpression() const;
0060 
0061     /**
0062      * Returns the listview that is currently filtered by the search.
0063      *
0064      * @see setTreeView()
0065      */
0066     QTreeView *treeView() const;
0067 
0068 public Q_SLOTS:
0069     /**
0070      * Updates search to only make visible the items that match \a pattern.  If
0071      * \a s is null then the line edit's text will be used.
0072      */
0073     virtual void updateSearch(const QString &pattern = QString());
0074 
0075     /**
0076      * Make the search case sensitive or case insensitive.
0077      *
0078      * @see caseSenstivity()
0079      */
0080     void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
0081 
0082     /**
0083      * Make the search a regular expression search or not.
0084      *
0085      * @see regularExpression()
0086      */
0087     void setRegularExpression(bool value);
0088 
0089     /**
0090      * Sets the QTreeView that is filtered by this search line, replacing any
0091      * previously filtered listviews.  If \a treeView is null then the widget will be
0092      * disabled.
0093      *
0094      * @see treeView()
0095      */
0096     void setTreeView(QTreeView *treeView);
0097 
0098 Q_SIGNALS:
0099     /**
0100      * This signal is emitted when search options have been changed. It is emitted so
0101      * that users of this class can choose to save the search options to the settings.
0102      */
0103     void searchOptionsChanged();
0104 
0105 protected:
0106     /**
0107      * Returns true if \a parentIndex matches the search \a pattern.  This will be evaluated
0108      * based on the value of caseSensitive().  This can be overridden in
0109      * subclasses to implement more complicated matching schemes.
0110      */
0111     virtual bool itemMatches(const QModelIndex &parentIndex, int row, const QString &pattern) const;
0112 
0113     /**
0114      * Re-implemented for internal reasons.  API not affected.
0115      */
0116     void contextMenuEvent(QContextMenuEvent *) override;
0117 
0118     /**
0119      * Updates search to only make visible appropriate items in \a treeView.  If
0120      * \a treeView is null then nothing is done.
0121      */
0122     virtual void updateSearch(QTreeView *treeView);
0123 
0124     /**
0125      * Connects signals of this listview to the appropriate slots of the search
0126      * line.
0127      */
0128     virtual void connectTreeView(QTreeView *);
0129 
0130     /**
0131      * Disconnects signals of a listviews from the search line.
0132      */
0133     virtual void disconnectTreeView(QTreeView *);
0134 
0135 protected Q_SLOTS:
0136     /**
0137      * When keys are pressed a new search string is created and a timer is
0138      * activated.  The most recent search is activated when this timer runs out
0139      * if another key has not yet been pressed.
0140      *
0141      * This method makes @param search the most recent search and starts the
0142      * timer.
0143      *
0144      * Together with activateSearch() this makes it such that searches are not
0145      * started until there is a short break in the users typing.
0146      *
0147      * @see activateSearch()
0148      */
0149     void queueSearch(const QString &search);
0150 
0151     /**
0152      * When the timer started with queueSearch() expires this slot is called.
0153      * If there has been another timer started then this slot does nothing.
0154      * However if there are no other pending searches this starts the list view
0155      * search.
0156      *
0157      * @see queueSearch()
0158      */
0159     void activateSearch();
0160 
0161 private:
0162     class Private;
0163     Private *const d;
0164 
0165     void rowsInserted(const QModelIndex &, int, int) const;
0166     void treeViewDeleted(QObject *);
0167 };
0168 
0169 /**
0170  * Creates a widget featuring a KTreeViewSearchLine, a label with the text
0171  * "Search" and a button to clear the search.
0172  */
0173 class KTreeViewSearchLineWidget : public QWidget
0174 {
0175     Q_OBJECT
0176 
0177 public:
0178     /**
0179      * Creates a KTreeViewSearchLineWidget for \a treeView with \a parent as the
0180      * parent.
0181      */
0182     explicit KTreeViewSearchLineWidget(QWidget *parent = nullptr, QTreeView *treeView = nullptr);
0183 
0184     /**
0185      * Destroys the KTreeViewSearchLineWidget
0186      */
0187     ~KTreeViewSearchLineWidget() override;
0188 
0189     /**
0190      * Returns a pointer to the search line.
0191      */
0192     KTreeViewSearchLine *searchLine() const;
0193 
0194 protected Q_SLOTS:
0195     /**
0196      * Creates the widgets inside of the widget.  This is called from the
0197      * constructor via a single shot timer so that it is guaranteed to run
0198      * after construction is complete.  This makes it suitable for overriding in
0199      * subclasses.
0200      */
0201     virtual void createWidgets();
0202 
0203 protected:
0204     /**
0205      * Creates the search line.  This can be useful to reimplement in cases where
0206      * a KTreeViewSearchLine subclass is used.
0207      *
0208      * It is const because it is be called from searchLine(), which to the user
0209      * doesn't conceptually alter the widget.
0210      */
0211     virtual KTreeViewSearchLine *createSearchLine(QTreeView *treeView) const;
0212 
0213 private:
0214     class Private;
0215     Private *const d;
0216 };
0217 
0218 #endif