1 | /* This file is part of the KDE libraries |
2 | Copyright (c) 2003 Scott Wheeler <wheeler@kde.org> |
3 | Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net> |
4 | Copyright (c) 2006 Hamish Rodda <rodda@kde.org> |
5 | |
6 | This library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public |
8 | License version 2 as published by the Free Software Foundation. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #ifndef KTREEWIDGETSEARCHLINE_H |
22 | #define KTREEWIDGETSEARCHLINE_H |
23 | |
24 | #include <klineedit.h> |
25 | |
26 | class QModelIndex; |
27 | class QTreeWidget; |
28 | class QTreeWidgetItem; |
29 | |
30 | /** |
31 | * This class makes it easy to add a search line for filtering the items in |
32 | * listviews based on a simple text search. |
33 | * |
34 | * No changes to the application other than instantiating this class with |
35 | * appropriate QTreeWidgets should be needed. |
36 | */ |
37 | |
38 | class KDEUI_EXPORT KTreeWidgetSearchLine : public KLineEdit |
39 | { |
40 | Q_OBJECT |
41 | |
42 | Q_PROPERTY( Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity ) |
43 | Q_PROPERTY( bool keepParentsVisible READ keepParentsVisible WRITE setKeepParentsVisible ) |
44 | |
45 | |
46 | public: |
47 | /** |
48 | * Constructs a KTreeWidgetSearchLine with \a treeWidget being the QTreeWidget to |
49 | * be filtered. |
50 | * |
51 | * If \a treeWidget is null then the widget will be disabled until listviews |
52 | * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget(). |
53 | */ |
54 | explicit KTreeWidgetSearchLine( QWidget *parent = 0, QTreeWidget *treeWidget = 0 ); |
55 | |
56 | /** |
57 | * Constructs a KTreeWidgetSearchLine with \a treeWidgets being the list of |
58 | * pointers to QTreeWidgets to be filtered. |
59 | * |
60 | * If \a treeWidgets is empty then the widget will be disabled until listviews |
61 | * are set with setTreeWidget(), setTreeWidgets() or added with addTreeWidget(). |
62 | */ |
63 | KTreeWidgetSearchLine( QWidget *parent, const QList<QTreeWidget *> &treeWidgets ); |
64 | |
65 | |
66 | /** |
67 | * Destroys the KTreeWidgetSearchLine. |
68 | */ |
69 | virtual ~KTreeWidgetSearchLine(); |
70 | |
71 | /** |
72 | * Returns true if the search is case sensitive. This defaults to false. |
73 | * |
74 | * @see setCaseSensitive() |
75 | */ |
76 | Qt::CaseSensitivity caseSensitivity() const; |
77 | |
78 | /** |
79 | * Returns the current list of columns that will be searched. If the |
80 | * returned list is empty all visible columns will be searched. |
81 | * |
82 | * @see setSearchColumns |
83 | */ |
84 | QList<int> searchColumns() const; |
85 | |
86 | /** |
87 | * If this is true (the default) then the parents of matched items will also |
88 | * be shown. |
89 | * |
90 | * @see setKeepParentsVisible() |
91 | */ |
92 | bool keepParentsVisible() const; |
93 | |
94 | /** |
95 | * Returns the listview that is currently filtered by the search. |
96 | * If there are multiple listviews filtered, it returns 0. |
97 | * |
98 | * @see setTreeWidget(), treeWidgets() |
99 | */ |
100 | QTreeWidget *treeWidget() const; |
101 | |
102 | /** |
103 | * Returns the list of pointers to listviews that are currently filtered by |
104 | * the search. |
105 | * |
106 | * @see setTreeWidgets(), addTreeWidget(), treeWidget() |
107 | */ |
108 | QList<QTreeWidget *> treeWidgets() const; |
109 | |
110 | Q_SIGNALS: |
111 | /** |
112 | * This signal is emitted whenever an item gets hidden or unhidden due |
113 | * to it not matching or matching the search string. |
114 | */ |
115 | void hiddenChanged(QTreeWidgetItem *, bool); |
116 | |
117 | public Q_SLOTS: |
118 | /** |
119 | * Adds a QTreeWidget to the list of listviews filtered by this search line. |
120 | * If \a treeWidget is null then the widget will be disabled. |
121 | * |
122 | * @see treeWidget(), setTreeWidgets(), removeTreeWidget() |
123 | */ |
124 | void addTreeWidget( QTreeWidget *treeWidget ); |
125 | |
126 | /** |
127 | * Removes a QTreeWidget from the list of listviews filtered by this search |
128 | * line. Does nothing if \a treeWidget is 0 or is not filtered by the quick search |
129 | * line. |
130 | * |
131 | * @see listVew(), setTreeWidgets(), addTreeWidget() |
132 | */ |
133 | void removeTreeWidget( QTreeWidget *treeWidget ); |
134 | |
135 | /** |
136 | * Updates search to only make visible the items that match \a pattern. If |
137 | * \a s is null then the line edit's text will be used. |
138 | */ |
139 | virtual void updateSearch( const QString &pattern = QString() ); |
140 | |
141 | /** |
142 | * Make the search case sensitive or case insensitive. |
143 | * |
144 | * @see caseSenstivity() |
145 | */ |
146 | void setCaseSensitivity( Qt::CaseSensitivity caseSensitivity ); |
147 | |
148 | /** |
149 | * When a search is active on a list that's organized into a tree view if |
150 | * a parent or ancesestor of an item is does not match the search then it |
151 | * will be hidden and as such so too will any children that match. |
152 | * |
153 | * If this is set to true (the default) then the parents of matching items |
154 | * will be shown. |
155 | * |
156 | * \warning setKeepParentsVisible(true) does not have the expected effect |
157 | * on items being added to or removed from the view while a search is active. |
158 | * When a new search starts afterwards the behavior will be normal. |
159 | * |
160 | * @see keepParentsVisible |
161 | */ |
162 | void setKeepParentsVisible( bool value ); |
163 | |
164 | /** |
165 | * Sets the list of columns to be searched. The default is to search all, |
166 | * visible columns which can be restored by passing \a columns as an empty |
167 | * list. |
168 | * If listviews to be filtered have different numbers or labels of columns |
169 | * this method has no effect. |
170 | * |
171 | * @see searchColumns |
172 | */ |
173 | void setSearchColumns( const QList<int> &columns ); |
174 | |
175 | /** |
176 | * Sets the QTreeWidget that is filtered by this search line, replacing any |
177 | * previously filtered listviews. If \a treeWidget is null then the widget will be |
178 | * disabled. |
179 | * |
180 | * @see treeWidget(), setTreeWidgets() |
181 | */ |
182 | void setTreeWidget( QTreeWidget *treeWidget ); |
183 | |
184 | /** |
185 | * Sets QTreeWidgets that are filtered by this search line, replacing any |
186 | * previously filtered listviews. If \a treeWidgets is empty then the widget will |
187 | * be disabled. |
188 | * |
189 | * @see treeWidgets(), addTreeWidget(), setTreeWidget() |
190 | */ |
191 | void setTreeWidgets( const QList<QTreeWidget *> &treeWidgets ); |
192 | |
193 | |
194 | protected: |
195 | /** |
196 | * Returns true if \a item matches the search \a pattern. This will be evaluated |
197 | * based on the value of caseSensitive(). This can be overridden in |
198 | * subclasses to implement more complicated matching schemes. |
199 | */ |
200 | virtual bool itemMatches( const QTreeWidgetItem *item, const QString &pattern ) const; |
201 | |
202 | /** |
203 | * Re-implemented for internal reasons. API not affected. |
204 | */ |
205 | virtual void ( QContextMenuEvent* ); |
206 | |
207 | /** |
208 | * Updates search to only make visible appropriate items in \a treeWidget. If |
209 | * \a treeWidget is null then nothing is done. |
210 | */ |
211 | virtual void updateSearch( QTreeWidget *treeWidget ); |
212 | |
213 | /** |
214 | * Connects signals of this listview to the appropriate slots of the search |
215 | * line. |
216 | */ |
217 | virtual void connectTreeWidget( QTreeWidget* ); |
218 | |
219 | /** |
220 | * Disconnects signals of a listviews from the search line. |
221 | */ |
222 | virtual void disconnectTreeWidget( QTreeWidget* ); |
223 | |
224 | /** |
225 | * Checks columns in all listviews and decides whether choosing columns to |
226 | * filter on makes any sense. |
227 | * |
228 | * Returns false if either of the following is true: |
229 | * * there are no listviews connected, |
230 | * * the listviews have different numbers of columns, |
231 | * * the listviews have only one column, |
232 | * * the listviews differ in column labels. |
233 | * |
234 | * Otherwise it returns true. |
235 | * |
236 | * @see setSearchColumns() |
237 | */ |
238 | virtual bool canChooseColumnsCheck(); |
239 | |
240 | /** |
241 | * Re-implemented for internal reasons. API not affected. |
242 | */ |
243 | virtual bool event(QEvent *event); |
244 | private: |
245 | class Private; |
246 | Private* const d; |
247 | |
248 | Q_PRIVATE_SLOT(d, void _k_rowsInserted(const QModelIndex&, int, int) const) |
249 | Q_PRIVATE_SLOT(d, void _k_treeWidgetDeleted(QObject*)) |
250 | Q_PRIVATE_SLOT(d, void _k_slotColumnActivated(QAction*)) |
251 | Q_PRIVATE_SLOT(d, void _k_slotAllVisibleColumns()) |
252 | Q_PRIVATE_SLOT(d, void _k_queueSearch(const QString&)) |
253 | Q_PRIVATE_SLOT(d, void _k_activateSearch()) |
254 | }; |
255 | |
256 | /** |
257 | * Creates a widget featuring a KTreeWidgetSearchLine, a label with the text |
258 | * "Search" and a button to clear the search. |
259 | */ |
260 | class KDEUI_EXPORT KTreeWidgetSearchLineWidget : public QWidget |
261 | { |
262 | Q_OBJECT |
263 | |
264 | public: |
265 | /** |
266 | * Creates a KTreeWidgetSearchLineWidget for \a treeWidget with \a parent as the |
267 | * parent. |
268 | */ |
269 | explicit KTreeWidgetSearchLineWidget( QWidget *parent = 0, QTreeWidget *treeWidget = 0 ); |
270 | |
271 | /** |
272 | * Destroys the KTreeWidgetSearchLineWidget |
273 | */ |
274 | ~KTreeWidgetSearchLineWidget(); |
275 | |
276 | /** |
277 | * Returns a pointer to the search line. |
278 | */ |
279 | KTreeWidgetSearchLine *searchLine() const; |
280 | |
281 | protected Q_SLOTS: |
282 | /** |
283 | * Creates the widgets inside of the widget. This is called from the |
284 | * constructor via a single shot timer so that it it guaranteed to run |
285 | * after construction is complete. This makes it suitable for overriding in |
286 | * subclasses. |
287 | */ |
288 | virtual void createWidgets(); |
289 | |
290 | protected: |
291 | /** |
292 | * Creates the search line. This can be useful to reimplement in cases where |
293 | * a KTreeWidgetSearchLine subclass is used. |
294 | * |
295 | * It is const because it is be called from searchLine(), which to the user |
296 | * doesn't conceptually alter the widget. |
297 | */ |
298 | virtual KTreeWidgetSearchLine *createSearchLine( QTreeWidget *treeWidget ) const; |
299 | |
300 | private: |
301 | class Private; |
302 | Private* const d; |
303 | }; |
304 | |
305 | #endif |
306 | |