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 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #ifndef KLISTVIEWSEARCHLINE_H |
21 | #define KLISTVIEWSEARCHLINE_H |
22 | |
23 | #include <kde3support_export.h> |
24 | #include <klineedit.h> |
25 | #include <khbox.h> |
26 | |
27 | class K3ListView; |
28 | class Q3ListViewItem; |
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 K3ListViews should be needed. |
36 | */ |
37 | |
38 | class KDE3SUPPORT_EXPORT K3ListViewSearchLine : public KLineEdit |
39 | { |
40 | Q_OBJECT |
41 | |
42 | public: |
43 | |
44 | /** |
45 | * Constructs a K3ListViewSearchLine with \a listView being the K3ListView to |
46 | * be filtered. |
47 | * |
48 | * If \a listView is null then the widget will be disabled until listviews |
49 | * are set with setListView(), setListViews() or added with addListView(). |
50 | */ |
51 | K3ListViewSearchLine(QWidget *parent = 0, K3ListView *listView = 0); |
52 | |
53 | /** |
54 | * Constructs a K3ListViewSearchLine with \a listViews being the list of |
55 | * pointers to K3ListViews to be filtered. |
56 | * |
57 | * If \a listViews is empty then the widget will be disabled until listviews |
58 | * are set with setListView(), setListViews() or added with addListView(). |
59 | */ |
60 | K3ListViewSearchLine(QWidget *parent, |
61 | const QList<K3ListView *> &listViews); |
62 | |
63 | |
64 | /** |
65 | * Destroys the K3ListViewSearchLine. |
66 | */ |
67 | virtual ~K3ListViewSearchLine(); |
68 | |
69 | /** |
70 | * Returns true if the search is case sensitive. This defaults to false. |
71 | * |
72 | * @see setCaseSensitive() |
73 | */ |
74 | bool caseSensitive() const; |
75 | |
76 | /** |
77 | * Returns the current list of columns that will be searched. If the |
78 | * returned list is empty all visible columns will be searched. |
79 | * |
80 | * @see setSearchColumns |
81 | */ |
82 | QList<int> searchColumns() const; |
83 | |
84 | /** |
85 | * If this is true (the default) then the parents of matched items will also |
86 | * be shown. |
87 | * |
88 | * @see setKeepParentsVisible() |
89 | */ |
90 | bool keepParentsVisible() const; |
91 | |
92 | /** |
93 | * Returns the listview that is currently filtered by the search. |
94 | * If there are multiple listviews filtered, it returns 0. |
95 | * |
96 | * @see setListView(), listViews() |
97 | */ |
98 | K3ListView *listView() const; |
99 | |
100 | /** |
101 | * Returns the list of pointers to listviews that are currently filtered by |
102 | * the search. |
103 | * |
104 | * @see setListViews(), addListView(), listView() |
105 | */ |
106 | const QList<K3ListView *> &listViews() const; |
107 | |
108 | public Q_SLOTS: |
109 | /** |
110 | * Adds a K3ListView to the list of listviews filtered by this search line. |
111 | * If \a lv is null then the widget will be disabled. |
112 | * |
113 | * @see listView(), setListViews(), removeListView() |
114 | */ |
115 | void addListView(K3ListView *lv); |
116 | |
117 | /** |
118 | * Removes a K3ListView from the list of listviews filtered by this search |
119 | * line. Does nothing if \a lv is 0 or is not filtered by the quick search |
120 | * line. |
121 | * |
122 | * @see listVew(), setListViews(), addListView() |
123 | */ |
124 | void removeListView(K3ListView *lv); |
125 | |
126 | /** |
127 | * Updates search to only make visible the items that match \a s. If |
128 | * \a s is null then the line edit's text will be used. |
129 | */ |
130 | virtual void updateSearch(const QString &s = QString()); |
131 | |
132 | /** |
133 | * Make the search case sensitive or case insensitive. |
134 | * |
135 | * @see caseSenstive() |
136 | */ |
137 | void setCaseSensitive(bool cs); |
138 | |
139 | /** |
140 | * When a search is active on a list that's organized into a tree view if |
141 | * a parent or ancesestor of an item is does not match the search then it |
142 | * will be hidden and as such so too will any children that match. |
143 | * |
144 | * If this is set to true (the default) then the parents of matching items |
145 | * will be shown. |
146 | * |
147 | * @see keepParentsVisible |
148 | */ |
149 | void setKeepParentsVisible(bool v); |
150 | |
151 | /** |
152 | * Sets the list of columns to be searched. The default is to search all, |
153 | * visible columns which can be restored by passing \a columns as an empty |
154 | * list. |
155 | * If listviews to be filtered have different numbers or labels of columns |
156 | * this method has no effect. |
157 | * |
158 | * @see searchColumns |
159 | */ |
160 | void setSearchColumns(const QList<int> &columns); |
161 | |
162 | /** |
163 | * Sets the K3ListView that is filtered by this search line, replacing any |
164 | * previously filtered listviews. If \a lv is null then the widget will be |
165 | * disabled. |
166 | * |
167 | * @see listView(), setListViews() |
168 | */ |
169 | void setListView(K3ListView *lv); |
170 | |
171 | /** |
172 | * Sets K3ListViews that are filtered by this search line, replacing any |
173 | * previously filtered listviews. If \a lvs is empty then the widget will |
174 | * be disabled. |
175 | * |
176 | * @see listViews(), addListView(), setListView() |
177 | */ |
178 | void setListViews(const QList<K3ListView *> &lv); |
179 | |
180 | |
181 | protected: |
182 | |
183 | /** |
184 | * Returns true if \a item matches the search \a s. This will be evaluated |
185 | * based on the value of caseSensitive(). This can be overridden in |
186 | * subclasses to implement more complicated matching schemes. |
187 | */ |
188 | virtual bool itemMatches(const Q3ListViewItem *item, const QString &s) const; |
189 | |
190 | /** |
191 | * Re-implemented for internal reasons. API not affected. |
192 | */ |
193 | virtual void ( QContextMenuEvent*e ); |
194 | |
195 | /** |
196 | * Updates search to only make visible appropriate items in \a listView. If |
197 | * \a listView is null then nothing is done. |
198 | */ |
199 | virtual void updateSearch(K3ListView *listView); |
200 | |
201 | /** |
202 | * Connects signals of this listview to the appropriate slots of the search |
203 | * line. |
204 | */ |
205 | virtual void connectListView(K3ListView *); |
206 | /** |
207 | * Disconnects signals of a listviews from the search line. |
208 | */ |
209 | virtual void disconnectListView(K3ListView *); |
210 | |
211 | /** |
212 | * Checks columns in all listviews and decides whether choosing columns to |
213 | * filter on makes any sense. |
214 | * |
215 | * Returns false if either of the following is true: |
216 | * * there are no listviews connected, |
217 | * * the listviews have different numbers of columns, |
218 | * * the listviews have only one column, |
219 | * * the listviews differ in column labels. |
220 | * |
221 | * Otherwise it returns true. |
222 | * |
223 | * @see setSearchColumns() |
224 | */ |
225 | virtual bool canChooseColumnsCheck(); |
226 | |
227 | protected Q_SLOTS: |
228 | /** |
229 | * When keys are pressed a new search string is created and a timer is |
230 | * activated. The most recent search is activated when this timer runs out |
231 | * if another key has not yet been pressed. |
232 | * |
233 | * This method makes @param search the most recent search and starts the |
234 | * timer. |
235 | * |
236 | * Together with activateSearch() this makes it such that searches are not |
237 | * started until there is a short break in the users typing. |
238 | * |
239 | * @see activateSearch() |
240 | */ |
241 | void queueSearch(const QString &search); |
242 | |
243 | /** |
244 | * When the timer started with queueSearch() expires this slot is called. |
245 | * If there has been another timer started then this slot does nothing. |
246 | * However if there are no other pending searches this starts the list view |
247 | * search. |
248 | * |
249 | * @see queueSearch() |
250 | */ |
251 | void activateSearch(); |
252 | |
253 | private: |
254 | |
255 | /** |
256 | * This is used after changing the list of listviews. If choosing columns |
257 | * doesn't make sense, it forces filtering over all columns. |
258 | * |
259 | * @see canChooseColumnsCheck() |
260 | */ |
261 | void checkColumns(); |
262 | |
263 | /** |
264 | * This is used in case parent items of matching items shouldn't be |
265 | * visible. It hides all items that don't match the search string. |
266 | */ |
267 | void checkItemParentsNotVisible(K3ListView *listView); |
268 | |
269 | /** |
270 | * This is used in case parent items of matching items should be visible. |
271 | * It makes a recursive call to all children. It returns true if at least |
272 | * one item in the subtree with the given root item is visible. |
273 | */ |
274 | bool checkItemParentsVisible(Q3ListViewItem *item, Q3ListViewItem *highestHiddenParent = 0); |
275 | |
276 | private Q_SLOTS: |
277 | void itemAdded(Q3ListViewItem *item) const; |
278 | void listViewDeleted( QObject *listView ); |
279 | void searchColumnsMenuActivated(QAction*); |
280 | |
281 | private: |
282 | class K3ListViewSearchLinePrivate; |
283 | K3ListViewSearchLinePrivate *d; |
284 | }; |
285 | |
286 | /** |
287 | * Creates a widget featuring a K3ListViewSearchLine, a label with the text |
288 | * "Search" and a button to clear the search. |
289 | */ |
290 | class KDE3SUPPORT_EXPORT K3ListViewSearchLineWidget : public KHBox |
291 | { |
292 | Q_OBJECT |
293 | |
294 | public: |
295 | /** |
296 | * Creates a K3ListViewSearchLineWidget for \a listView with \a parent as the |
297 | * parent with and \a name. |
298 | */ |
299 | K3ListViewSearchLineWidget(K3ListView *listView = 0, QWidget *parent = 0); |
300 | |
301 | /** |
302 | * Destroys the K3ListViewSearchLineWidget |
303 | */ |
304 | ~K3ListViewSearchLineWidget(); |
305 | |
306 | /** |
307 | * Creates the search line. This can be useful to reimplement in cases where |
308 | * a K3ListViewSearchLine subclass is used. |
309 | */ |
310 | virtual K3ListViewSearchLine *createSearchLine(K3ListView *listView); |
311 | |
312 | /** |
313 | * Returns a pointer to the search line. |
314 | */ |
315 | K3ListViewSearchLine *searchLine() const; |
316 | |
317 | protected Q_SLOTS: |
318 | /** |
319 | * Creates the widgets inside of the widget. This is called from the |
320 | * constructor via a single shot timer so that it it guaranteed to run |
321 | * after construction is complete. This makes it suitable for overriding in |
322 | * subclasses. |
323 | */ |
324 | virtual void createWidgets(); |
325 | |
326 | private: |
327 | class K3ListViewSearchLineWidgetPrivate; |
328 | K3ListViewSearchLineWidgetPrivate *d; |
329 | }; |
330 | |
331 | #endif |
332 | |