File indexing completed on 2024-12-08 03:41:11
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2003 Scott Wheeler <wheeler@kde.org> 0004 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net> 0005 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only 0008 */ 0009 0010 #ifndef KTREEWIDGETSEARCHLINE_H 0011 #define KTREEWIDGETSEARCHLINE_H 0012 0013 #include <QLineEdit> 0014 #include <kitemviews_export.h> 0015 #include <memory> 0016 0017 class QModelIndex; 0018 class QTreeWidget; 0019 class QTreeWidgetItem; 0020 0021 /** 0022 * @class KTreeWidgetSearchLine ktreewidgetsearchline.h KTreeWidgetSearchLine 0023 * 0024 * This class makes it easy to add a search line for filtering the items in 0025 * listviews based on a simple text search. 0026 * 0027 * No changes to the application other than instantiating this class with 0028 * appropriate QTreeWidgets should be needed. 0029 */ 0030 0031 class KITEMVIEWS_EXPORT KTreeWidgetSearchLine : public QLineEdit 0032 { 0033 Q_OBJECT 0034 0035 Q_PROPERTY(Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity NOTIFY caseSensitivityChanged) 0036 Q_PROPERTY(bool keepParentsVisible READ keepParentsVisible WRITE setKeepParentsVisible NOTIFY keepParentsVisibleChanged) 0037 0038 public: 0039 /** 0040 * Constructs a KTreeWidgetSearchLine with \a treeWidget being the QTreeWidget to 0041 * be filtered. 0042 * 0043 * If \a treeWidget is null then the widget will be disabled until listviews 0044 * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget(). 0045 */ 0046 explicit KTreeWidgetSearchLine(QWidget *parent = nullptr, QTreeWidget *treeWidget = nullptr); 0047 0048 /** 0049 * Constructs a KTreeWidgetSearchLine with \a treeWidgets being the list of 0050 * pointers to QTreeWidgets to be filtered. 0051 * 0052 * If \a treeWidgets is empty then the widget will be disabled until listviews 0053 * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget(). 0054 */ 0055 KTreeWidgetSearchLine(QWidget *parent, const QList<QTreeWidget *> &treeWidgets); 0056 0057 /** 0058 * Destroys the KTreeWidgetSearchLine. 0059 */ 0060 ~KTreeWidgetSearchLine() override; 0061 0062 /** 0063 * Returns true if the search is case sensitive. This defaults to false. 0064 * 0065 * @see setCaseSensitive() 0066 */ 0067 Qt::CaseSensitivity caseSensitivity() const; 0068 0069 /** 0070 * Returns the current list of columns that will be searched. If the 0071 * returned list is empty all visible columns will be searched. 0072 * 0073 * @see setSearchColumns 0074 */ 0075 QList<int> searchColumns() const; 0076 0077 /** 0078 * If this is true (the default) then the parents of matched items will also 0079 * be shown. 0080 * 0081 * @see setKeepParentsVisible() 0082 */ 0083 bool keepParentsVisible() const; 0084 0085 /** 0086 * Returns the listview that is currently filtered by the search. 0087 * If there are multiple listviews filtered, it returns 0. 0088 * 0089 * @see setTreeWidget(), treeWidgets() 0090 */ 0091 QTreeWidget *treeWidget() const; 0092 0093 /** 0094 * Returns the list of pointers to listviews that are currently filtered by 0095 * the search. 0096 * 0097 * @see setTreeWidgets(), addTreeWidget(), treeWidget() 0098 */ 0099 QList<QTreeWidget *> treeWidgets() const; 0100 0101 Q_SIGNALS: 0102 /** 0103 * This signal is emitted whenever an item gets hidden or unhidden due 0104 * to it not matching or matching the search string. 0105 */ 0106 void hiddenChanged(QTreeWidgetItem *, bool); 0107 0108 /** 0109 * This signal is emitted when user finished entering filter text or 0110 * when he made a pause long enough, after the QTreeWidget items got filtered 0111 * @param searchString is the text currently entered by the user 0112 * @since 5.0 0113 */ 0114 void searchUpdated(const QString &searchString); 0115 0116 void caseSensitivityChanged(Qt::CaseSensitivity caseSensitivity); 0117 void keepParentsVisibleChanged(bool keepParentsVisible); 0118 0119 public Q_SLOTS: 0120 /** 0121 * Adds a QTreeWidget to the list of listviews filtered by this search line. 0122 * If \a treeWidget is null then the widget will be disabled. 0123 * 0124 * @see treeWidget(), setTreeWidgets(), removeTreeWidget() 0125 */ 0126 void addTreeWidget(QTreeWidget *treeWidget); 0127 0128 /** 0129 * Removes a QTreeWidget from the list of listviews filtered by this search 0130 * line. Does nothing if \a treeWidget is 0 or is not filtered by the quick search 0131 * line. 0132 * 0133 * @see listVew(), setTreeWidgets(), addTreeWidget() 0134 */ 0135 void removeTreeWidget(QTreeWidget *treeWidget); 0136 0137 /** 0138 * Updates search to only make visible the items that match \a pattern. If 0139 * \a s is null then the line edit's text will be used. 0140 */ 0141 virtual void updateSearch(const QString &pattern = QString()); 0142 0143 /** 0144 * Make the search case sensitive or case insensitive. 0145 * 0146 * @see caseSenstivity() 0147 */ 0148 void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity); 0149 0150 /** 0151 * When a search is active on a list that's organized into a tree view if 0152 * a parent or ancesestor of an item is does not match the search then it 0153 * will be hidden and as such so too will any children that match. 0154 * 0155 * If this is set to true (the default) then the parents of matching items 0156 * will be shown. 0157 * 0158 * \warning setKeepParentsVisible(true) does not have the expected effect 0159 * on items being added to or removed from the view while a search is active. 0160 * When a new search starts afterwards the behavior will be normal. 0161 * 0162 * @see keepParentsVisible 0163 */ 0164 void setKeepParentsVisible(bool value); 0165 0166 /** 0167 * Sets the list of columns to be searched. The default is to search all, 0168 * visible columns which can be restored by passing \a columns as an empty 0169 * list. 0170 * If listviews to be filtered have different numbers or labels of columns 0171 * this method has no effect. 0172 * 0173 * @see searchColumns 0174 */ 0175 void setSearchColumns(const QList<int> &columns); 0176 0177 /** 0178 * Sets the QTreeWidget that is filtered by this search line, replacing any 0179 * previously filtered listviews. If \a treeWidget is null then the widget will be 0180 * disabled. 0181 * 0182 * @see treeWidget(), setTreeWidgets() 0183 */ 0184 void setTreeWidget(QTreeWidget *treeWidget); 0185 0186 /** 0187 * Sets QTreeWidgets that are filtered by this search line, replacing any 0188 * previously filtered listviews. If \a treeWidgets is empty then the widget will 0189 * be disabled. 0190 * 0191 * @see treeWidgets(), addTreeWidget(), setTreeWidget() 0192 */ 0193 void setTreeWidgets(const QList<QTreeWidget *> &treeWidgets); 0194 0195 protected: 0196 /** 0197 * Returns true if \a item matches the search \a pattern. This will be evaluated 0198 * based on the value of caseSensitive(). This can be overridden in 0199 * subclasses to implement more complicated matching schemes. 0200 */ 0201 virtual bool itemMatches(const QTreeWidgetItem *item, const QString &pattern) const; 0202 0203 /** 0204 * Re-implemented for internal reasons. API not affected. 0205 */ 0206 void contextMenuEvent(QContextMenuEvent *) override; 0207 0208 /** 0209 * Updates search to only make visible appropriate items in \a treeWidget. If 0210 * \a treeWidget is null then nothing is done. 0211 */ 0212 virtual void updateSearch(QTreeWidget *treeWidget); 0213 0214 /** 0215 * Connects signals of this listview to the appropriate slots of the search 0216 * line. 0217 */ 0218 virtual void connectTreeWidget(QTreeWidget *); 0219 0220 /** 0221 * Disconnects signals of a listviews from the search line. 0222 */ 0223 virtual void disconnectTreeWidget(QTreeWidget *); 0224 0225 /** 0226 * Checks columns in all listviews and decides whether choosing columns to 0227 * filter on makes any sense. 0228 * 0229 * Returns false if either of the following is true: 0230 * * there are no listviews connected, 0231 * * the listviews have different numbers of columns, 0232 * * the listviews have only one column, 0233 * * the listviews differ in column labels. 0234 * 0235 * Otherwise it returns true. 0236 * 0237 * @see setSearchColumns() 0238 */ 0239 virtual bool canChooseColumnsCheck(); 0240 0241 /** 0242 * Re-implemented for internal reasons. API not affected. 0243 */ 0244 bool event(QEvent *event) override; 0245 0246 private: 0247 friend class KTreeWidgetSearchLinePrivate; 0248 std::unique_ptr<class KTreeWidgetSearchLinePrivate> const d; 0249 0250 Q_PRIVATE_SLOT(d, void _k_rowsInserted(const QModelIndex &, int, int) const) 0251 Q_PRIVATE_SLOT(d, void _k_treeWidgetDeleted(QObject *)) 0252 Q_PRIVATE_SLOT(d, void _k_slotColumnActivated(QAction *)) 0253 Q_PRIVATE_SLOT(d, void _k_slotAllVisibleColumns()) 0254 Q_PRIVATE_SLOT(d, void _k_queueSearch(const QString &)) 0255 Q_PRIVATE_SLOT(d, void _k_activateSearch()) 0256 }; 0257 0258 #endif