File indexing completed on 2024-12-08 12:22:38
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) 0036 Q_PROPERTY(bool keepParentsVisible READ keepParentsVisible WRITE setKeepParentsVisible) 0037 #if KITEMVIEWS_BUILD_DEPRECATED_SINCE(5, 0) 0038 Q_PROPERTY(QString clickMessage READ clickMessage WRITE setClickMessage) 0039 #endif 0040 0041 public: 0042 /** 0043 * Constructs a KTreeWidgetSearchLine with \a treeWidget being the QTreeWidget to 0044 * be filtered. 0045 * 0046 * If \a treeWidget is null then the widget will be disabled until listviews 0047 * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget(). 0048 */ 0049 explicit KTreeWidgetSearchLine(QWidget *parent = nullptr, QTreeWidget *treeWidget = nullptr); 0050 0051 /** 0052 * Constructs a KTreeWidgetSearchLine with \a treeWidgets being the list of 0053 * pointers to QTreeWidgets to be filtered. 0054 * 0055 * If \a treeWidgets is empty then the widget will be disabled until listviews 0056 * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget(). 0057 */ 0058 KTreeWidgetSearchLine(QWidget *parent, const QList<QTreeWidget *> &treeWidgets); 0059 0060 /** 0061 * Destroys the KTreeWidgetSearchLine. 0062 */ 0063 ~KTreeWidgetSearchLine() override; 0064 0065 /** 0066 * Returns true if the search is case sensitive. This defaults to false. 0067 * 0068 * @see setCaseSensitive() 0069 */ 0070 Qt::CaseSensitivity caseSensitivity() const; 0071 0072 /** 0073 * Returns the current list of columns that will be searched. If the 0074 * returned list is empty all visible columns will be searched. 0075 * 0076 * @see setSearchColumns 0077 */ 0078 QList<int> searchColumns() const; 0079 0080 /** 0081 * If this is true (the default) then the parents of matched items will also 0082 * be shown. 0083 * 0084 * @see setKeepParentsVisible() 0085 */ 0086 bool keepParentsVisible() const; 0087 0088 /** 0089 * Returns the listview that is currently filtered by the search. 0090 * If there are multiple listviews filtered, it returns 0. 0091 * 0092 * @see setTreeWidget(), treeWidgets() 0093 */ 0094 QTreeWidget *treeWidget() const; 0095 0096 /** 0097 * Returns the list of pointers to listviews that are currently filtered by 0098 * the search. 0099 * 0100 * @see setTreeWidgets(), addTreeWidget(), treeWidget() 0101 */ 0102 QList<QTreeWidget *> treeWidgets() const; 0103 0104 #if KITEMVIEWS_ENABLE_DEPRECATED_SINCE(5, 0) 0105 /** 0106 * @return the message set with setClickMessage 0107 * @deprecated since 5.0, use QLineEdit::placeholderText() instead. 0108 **/ 0109 KITEMVIEWS_DEPRECATED_VERSION(5, 0, "Use QLineEdit::placeholderText()") 0110 QString clickMessage() const 0111 { 0112 return placeholderText(); 0113 } 0114 #endif 0115 0116 #if KITEMVIEWS_ENABLE_DEPRECATED_SINCE(5, 0) 0117 /** 0118 * This makes the line edit display a grayed-out hinting text as long as 0119 * the user didn't enter any text. It is often used as indication about 0120 * the purpose of the line edit. 0121 * @deprecated since 5.0, use QLineEdit::setPlaceholderText() instead. 0122 */ 0123 KITEMVIEWS_DEPRECATED_VERSION(5, 0, "Use QLineEdit::setPlaceholderText(const QString&))") 0124 void setClickMessage(const QString &msg) 0125 { 0126 setPlaceholderText(msg); 0127 } 0128 #endif 0129 0130 Q_SIGNALS: 0131 /** 0132 * This signal is emitted whenever an item gets hidden or unhidden due 0133 * to it not matching or matching the search string. 0134 */ 0135 void hiddenChanged(QTreeWidgetItem *, bool); 0136 0137 /** 0138 * This signal is emitted when user finished entering filter text or 0139 * when he made a pause long enough, after the QTreeWidget items got filtered 0140 * @param searchString is the text currently entered by the user 0141 * @since 5.0 0142 */ 0143 void searchUpdated(const QString &searchString); 0144 0145 public Q_SLOTS: 0146 /** 0147 * Adds a QTreeWidget to the list of listviews filtered by this search line. 0148 * If \a treeWidget is null then the widget will be disabled. 0149 * 0150 * @see treeWidget(), setTreeWidgets(), removeTreeWidget() 0151 */ 0152 void addTreeWidget(QTreeWidget *treeWidget); 0153 0154 /** 0155 * Removes a QTreeWidget from the list of listviews filtered by this search 0156 * line. Does nothing if \a treeWidget is 0 or is not filtered by the quick search 0157 * line. 0158 * 0159 * @see listVew(), setTreeWidgets(), addTreeWidget() 0160 */ 0161 void removeTreeWidget(QTreeWidget *treeWidget); 0162 0163 /** 0164 * Updates search to only make visible the items that match \a pattern. If 0165 * \a s is null then the line edit's text will be used. 0166 */ 0167 virtual void updateSearch(const QString &pattern = QString()); 0168 0169 /** 0170 * Make the search case sensitive or case insensitive. 0171 * 0172 * @see caseSenstivity() 0173 */ 0174 void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity); 0175 0176 /** 0177 * When a search is active on a list that's organized into a tree view if 0178 * a parent or ancesestor of an item is does not match the search then it 0179 * will be hidden and as such so too will any children that match. 0180 * 0181 * If this is set to true (the default) then the parents of matching items 0182 * will be shown. 0183 * 0184 * \warning setKeepParentsVisible(true) does not have the expected effect 0185 * on items being added to or removed from the view while a search is active. 0186 * When a new search starts afterwards the behavior will be normal. 0187 * 0188 * @see keepParentsVisible 0189 */ 0190 void setKeepParentsVisible(bool value); 0191 0192 /** 0193 * Sets the list of columns to be searched. The default is to search all, 0194 * visible columns which can be restored by passing \a columns as an empty 0195 * list. 0196 * If listviews to be filtered have different numbers or labels of columns 0197 * this method has no effect. 0198 * 0199 * @see searchColumns 0200 */ 0201 void setSearchColumns(const QList<int> &columns); 0202 0203 /** 0204 * Sets the QTreeWidget that is filtered by this search line, replacing any 0205 * previously filtered listviews. If \a treeWidget is null then the widget will be 0206 * disabled. 0207 * 0208 * @see treeWidget(), setTreeWidgets() 0209 */ 0210 void setTreeWidget(QTreeWidget *treeWidget); 0211 0212 /** 0213 * Sets QTreeWidgets that are filtered by this search line, replacing any 0214 * previously filtered listviews. If \a treeWidgets is empty then the widget will 0215 * be disabled. 0216 * 0217 * @see treeWidgets(), addTreeWidget(), setTreeWidget() 0218 */ 0219 void setTreeWidgets(const QList<QTreeWidget *> &treeWidgets); 0220 0221 protected: 0222 /** 0223 * Returns true if \a item matches the search \a pattern. This will be evaluated 0224 * based on the value of caseSensitive(). This can be overridden in 0225 * subclasses to implement more complicated matching schemes. 0226 */ 0227 virtual bool itemMatches(const QTreeWidgetItem *item, const QString &pattern) const; 0228 0229 /** 0230 * Re-implemented for internal reasons. API not affected. 0231 */ 0232 void contextMenuEvent(QContextMenuEvent *) override; 0233 0234 /** 0235 * Updates search to only make visible appropriate items in \a treeWidget. If 0236 * \a treeWidget is null then nothing is done. 0237 */ 0238 virtual void updateSearch(QTreeWidget *treeWidget); 0239 0240 /** 0241 * Connects signals of this listview to the appropriate slots of the search 0242 * line. 0243 */ 0244 virtual void connectTreeWidget(QTreeWidget *); 0245 0246 /** 0247 * Disconnects signals of a listviews from the search line. 0248 */ 0249 virtual void disconnectTreeWidget(QTreeWidget *); 0250 0251 /** 0252 * Checks columns in all listviews and decides whether choosing columns to 0253 * filter on makes any sense. 0254 * 0255 * Returns false if either of the following is true: 0256 * * there are no listviews connected, 0257 * * the listviews have different numbers of columns, 0258 * * the listviews have only one column, 0259 * * the listviews differ in column labels. 0260 * 0261 * Otherwise it returns true. 0262 * 0263 * @see setSearchColumns() 0264 */ 0265 virtual bool canChooseColumnsCheck(); 0266 0267 /** 0268 * Re-implemented for internal reasons. API not affected. 0269 */ 0270 bool event(QEvent *event) override; 0271 0272 private: 0273 friend class KTreeWidgetSearchLinePrivate; 0274 std::unique_ptr<class KTreeWidgetSearchLinePrivate> const d; 0275 0276 Q_PRIVATE_SLOT(d, void _k_rowsInserted(const QModelIndex &, int, int) const) 0277 Q_PRIVATE_SLOT(d, void _k_treeWidgetDeleted(QObject *)) 0278 Q_PRIVATE_SLOT(d, void _k_slotColumnActivated(QAction *)) 0279 Q_PRIVATE_SLOT(d, void _k_slotAllVisibleColumns()) 0280 Q_PRIVATE_SLOT(d, void _k_queueSearch(const QString &)) 0281 Q_PRIVATE_SLOT(d, void _k_activateSearch()) 0282 }; 0283 0284 #endif