1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2003 Scott Wheeler <wheeler@kde.org>
4 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net>
5 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#ifndef KTREEWIDGETSEARCHLINE_H
11#define KTREEWIDGETSEARCHLINE_H
12
13#include <QLineEdit>
14#include <kitemviews_export.h>
15#include <memory>
16
17class QModelIndex;
18class QTreeWidget;
19class QTreeWidgetItem;
20
21/*!
22 * \class KTreeWidgetSearchLine
23 * \inmodule KItemViews
24 *
25 * \brief This class makes it easy to add a search line for filtering the items in
26 * listviews based on a simple text search.
27 *
28 * No changes to the application other than instantiating this class with
29 * appropriate QTreeWidgets should be needed.
30 */
31class KITEMVIEWS_EXPORT KTreeWidgetSearchLine : public QLineEdit
32{
33 Q_OBJECT
34
35 /*!
36 * \property KTreeWidgetSearchLine::caseSensitity
37 */
38 Q_PROPERTY(Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity NOTIFY caseSensitivityChanged)
39
40 /*!
41 * \property KTreeWidgetSearchLine::keepParentsVisible
42 */
43 Q_PROPERTY(bool keepParentsVisible READ keepParentsVisible WRITE setKeepParentsVisible NOTIFY keepParentsVisibleChanged)
44
45public:
46 /*!
47 * Constructs a KTreeWidgetSearchLine with \a treeWidget being the QTreeWidget to
48 * be filtered.
49 *
50 * If \a treeWidget is null then the widget will be disabled until listviews
51 * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget().
52 */
53 explicit KTreeWidgetSearchLine(QWidget *parent = nullptr, QTreeWidget *treeWidget = nullptr);
54
55 /*!
56 * Constructs a KTreeWidgetSearchLine with \a treeWidgets being the list of
57 * pointers to QTreeWidgets to be filtered.
58 *
59 * If \a treeWidgets is empty then the widget will be disabled until listviews
60 * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget().
61 */
62 KTreeWidgetSearchLine(QWidget *parent, const QList<QTreeWidget *> &treeWidgets);
63
64 ~KTreeWidgetSearchLine() override;
65
66 /*!
67 * Returns true if the search is case sensitive. This defaults to false.
68 *
69 * \sa setCaseSensitivity()
70 */
71 Qt::CaseSensitivity caseSensitivity() const;
72
73 /*!
74 * Returns the current list of columns that will be searched. If the
75 * returned list is empty all visible columns will be searched.
76 *
77 * \sa setSearchColumns
78 */
79 QList<int> searchColumns() const;
80
81 /*!
82 * If this is true (the default) then the parents of matched items will also
83 * be shown.
84 *
85 * \sa setKeepParentsVisible()
86 */
87 bool keepParentsVisible() const;
88
89 /*!
90 * Returns the listview that is currently filtered by the search.
91 * If there are multiple listviews filtered, it returns 0.
92 *
93 * \sa setTreeWidget(), treeWidgets()
94 */
95 QTreeWidget *treeWidget() const;
96
97 /*!
98 * Returns the list of pointers to listviews that are currently filtered by
99 * the search.
100 *
101 * \sa setTreeWidgets(), addTreeWidget(), treeWidget()
102 */
103 QList<QTreeWidget *> treeWidgets() const;
104
105Q_SIGNALS:
106 /*!
107 * This signal is emitted whenever an item gets hidden or unhidden due
108 * to it not matching or matching the search string.
109 */
110 void hiddenChanged(QTreeWidgetItem *, bool);
111
112 /*!
113 * This signal is emitted when user finished entering filter text or
114 * when he made a pause long enough, after the QTreeWidget items got filtered
115 *
116 * \a searchString is the text currently entered by the user
117 * \since 5.0
118 */
119 void searchUpdated(const QString &searchString);
120
121 /*!
122 *
123 */
124 void caseSensitivityChanged(Qt::CaseSensitivity caseSensitivity);
125
126 /*!
127 *
128 */
129 void keepParentsVisibleChanged(bool keepParentsVisible);
130
131public Q_SLOTS:
132 /*!
133 * Adds a QTreeWidget to the list of listviews filtered by this search line.
134 * If \a treeWidget is null then the widget will be disabled.
135 *
136 * \sa treeWidget(), setTreeWidgets(), removeTreeWidget()
137 */
138 void addTreeWidget(QTreeWidget *treeWidget);
139
140 /*!
141 * Removes a QTreeWidget from the list of listviews filtered by this search
142 * line. Does nothing if \a treeWidget is 0 or is not filtered by the quick search
143 * line.
144 *
145 * \sa setTreeWidgets(), addTreeWidget()
146 */
147 void removeTreeWidget(QTreeWidget *treeWidget);
148
149 /*!
150 * Updates search to only make visible the items that match \a pattern. If
151 * \a s is null then the line edit's text will be used.
152 */
153 virtual void updateSearch(const QString &pattern = QString());
154
155 /*!
156 * Make the search case sensitive or case insensitive.
157 *
158 * \sa caseSensitivity()
159 */
160 void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
161
162 /*!
163 * When a search is active on a list that's organized into a tree view if
164 * a parent or ancesestor of an item is does not match the search then it
165 * will be hidden and as such so too will any children that match.
166 *
167 * If this is set to true (the default) then the parents of matching items
168 * will be shown.
169 *
170 * \warning setKeepParentsVisible(true) does not have the expected effect
171 * on items being added to or removed from the view while a search is active.
172 * When a new search starts afterwards the behavior will be normal.
173 *
174 * \sa keepParentsVisible
175 */
176 void setKeepParentsVisible(bool value);
177
178 /*!
179 * Sets the list of columns to be searched. The default is to search all,
180 * visible columns which can be restored by passing \a columns as an empty
181 * list.
182 * If listviews to be filtered have different numbers or labels of columns
183 * this method has no effect.
184 *
185 * \sa searchColumns
186 */
187 void setSearchColumns(const QList<int> &columns);
188
189 /*!
190 * Sets the QTreeWidget that is filtered by this search line, replacing any
191 * previously filtered listviews. If \a treeWidget is null then the widget will be
192 * disabled.
193 *
194 * \sa treeWidget(), setTreeWidgets()
195 */
196 void setTreeWidget(QTreeWidget *treeWidget);
197
198 /*!
199 * Sets QTreeWidgets that are filtered by this search line, replacing any
200 * previously filtered listviews. If \a treeWidgets is empty then the widget will
201 * be disabled.
202 *
203 * \sa treeWidgets(), addTreeWidget(), setTreeWidget()
204 */
205 void setTreeWidgets(const QList<QTreeWidget *> &treeWidgets);
206
207protected:
208 /*!
209 * Returns true if \a item matches the search \a pattern. This will be evaluated
210 * based on the value of caseSensitive(). This can be overridden in
211 * subclasses to implement more complicated matching schemes.
212 */
213 virtual bool itemMatches(const QTreeWidgetItem *item, const QString &pattern) const;
214
215 void contextMenuEvent(QContextMenuEvent *) override;
216
217 /*!
218 * Updates search to only make visible appropriate items in \a treeWidget.
219 *
220 * If \a treeWidget is null then nothing is done.
221 */
222 virtual void updateSearch(QTreeWidget *treeWidget);
223
224 /*!
225 * Connects signals of this listview to the appropriate slots of the search
226 * line.
227 */
228 virtual void connectTreeWidget(QTreeWidget *);
229
230 /*!
231 * Disconnects signals of a listviews from the search line.
232 */
233 virtual void disconnectTreeWidget(QTreeWidget *);
234
235 /*!
236 * Checks columns in all listviews and decides whether choosing columns to
237 * filter on makes any sense.
238 *
239 * Returns false if either of the following is true:
240 * * there are no listviews connected,
241 * * the listviews have different numbers of columns,
242 * * the listviews have only one column,
243 * * the listviews differ in column labels.
244 *
245 * Otherwise it returns true.
246 *
247 * \sa setSearchColumns()
248 */
249 virtual bool canChooseColumnsCheck();
250
251 bool event(QEvent *event) override;
252
253private:
254 friend class KTreeWidgetSearchLinePrivate;
255 std::unique_ptr<class KTreeWidgetSearchLinePrivate> const d;
256
257 Q_PRIVATE_SLOT(d, void _k_rowsInserted(const QModelIndex &, int, int) const)
258 Q_PRIVATE_SLOT(d, void _k_treeWidgetDeleted(QObject *))
259 Q_PRIVATE_SLOT(d, void _k_slotColumnActivated(QAction *))
260 Q_PRIVATE_SLOT(d, void _k_slotAllVisibleColumns())
261 Q_PRIVATE_SLOT(d, void _k_queueSearch(const QString &))
262 Q_PRIVATE_SLOT(d, void _k_activateSearch())
263};
264
265#endif
266

source code of kitemviews/src/ktreewidgetsearchline.h