1 | /** |
2 | * This file is part of the KDE project |
3 | * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org> |
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 as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
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 KCATEGORIZEDVIEW_H |
22 | #define KCATEGORIZEDVIEW_H |
23 | |
24 | #include <QtGui/QListView> |
25 | |
26 | #include <kdeui_export.h> |
27 | |
28 | class KCategoryDrawer; |
29 | class KCategoryDrawerV2; |
30 | |
31 | /** |
32 | * @short Item view for listing items in a categorized fashion optionally |
33 | * |
34 | * KCategorizedView basically has the same functionality as QListView, only that it also lets you |
35 | * layout items in a way that they are categorized visually. |
36 | * |
37 | * For it to work you will need to set a KCategorizedSortFilterProxyModel and a KCategoryDrawer |
38 | * with methods setModel() and setCategoryDrawer() respectively. Also, the model will need to be |
39 | * flagged as categorized with KCategorizedSortFilterProxyModel::setCategorizedModel(true). |
40 | * |
41 | * The way it works (if categorization enabled): |
42 | * |
43 | * - When sorting, it does more things than QListView does. It will ask the model for the |
44 | * special role CategorySortRole (@see KCategorizedSortFilterProxyModel). This can return |
45 | * a QString or an int in order to tell the view the order of categories. In this sense, for |
46 | * instance, if we are sorting by name ascending, "A" would be before than "B". If we are |
47 | * sorting by size ascending, 512 bytes would be before 1024 bytes. This way categories are |
48 | * also sorted. |
49 | * |
50 | * - When the view has to paint, it will ask the model with the role CategoryDisplayRole |
51 | * (@see KCategorizedSortFilterProxyModel). It will for instance return "F" for "foo.pdf" if |
52 | * we are sorting by name ascending, or "Small" if a certain item has 100 bytes, for example. |
53 | * |
54 | * For drawing categories, KCategoryDrawer will be used. You can inherit this class to do your own |
55 | * drawing. |
56 | * |
57 | * @note All examples cited before talk about filesystems and such, but have present that this |
58 | * is a completely generic class, and it can be used for whatever your purpose is. For |
59 | * instance when talking about animals, you can separate them by "Mammal" and "Oviparous". In |
60 | * this very case, for example, the CategorySortRole and the CategoryDisplayRole could be the |
61 | * same ("Mammal" and "Oviparous"). |
62 | * |
63 | * @note There is a really performance boost if CategorySortRole returns an int instead of a QString. |
64 | * Have present that this role is asked (n * log n) times when sorting and compared. Comparing |
65 | * ints is always faster than comparing strings, whithout mattering how fast the string |
66 | * comparison is. Consider thinking of a way of returning ints instead of QStrings if your |
67 | * model can contain a high number of items. |
68 | * |
69 | * @warning Note that for really drawing items in blocks you will need some things to be done: |
70 | * - The model set to this view has to be (or inherit if you want to do special stuff |
71 | * in it) KCategorizedSortFilterProxyModel. |
72 | * - This model needs to be set setCategorizedModel to true. |
73 | * - Set a category drawer by calling setCategoryDrawer. |
74 | * |
75 | * @see KCategorizedSortFilterProxyModel, KCategoryDrawer |
76 | * |
77 | * @author Rafael Fernández López <ereslibre@kde.org> |
78 | */ |
79 | class KDEUI_EXPORT KCategorizedView |
80 | : public QListView |
81 | { |
82 | Q_OBJECT |
83 | Q_PROPERTY(int categorySpacing READ categorySpacing WRITE setCategorySpacing) |
84 | Q_PROPERTY(bool alternatingBlockColors READ alternatingBlockColors WRITE setAlternatingBlockColors) |
85 | Q_PROPERTY(bool collapsibleBlocks READ collapsibleBlocks WRITE setCollapsibleBlocks) |
86 | |
87 | public: |
88 | KCategorizedView(QWidget *parent = 0); |
89 | |
90 | ~KCategorizedView(); |
91 | |
92 | /** |
93 | * Reimplemented from QAbstractItemView. |
94 | */ |
95 | virtual void setModel(QAbstractItemModel *model); |
96 | |
97 | /** |
98 | * Calls to setGridSizeOwn(). |
99 | */ |
100 | void setGridSize(const QSize &size); |
101 | |
102 | /** |
103 | * @warning note that setGridSize is not virtual in the base class (QListView), so if you are |
104 | * calling to this method, make sure you have a KCategorizedView pointer around. This |
105 | * means that something like: |
106 | * @code |
107 | * QListView *lv = new KCategorizedView(); |
108 | * lv->setGridSize(mySize); |
109 | * @endcode |
110 | * |
111 | * will not call to the expected setGridSize method. Instead do something like this: |
112 | * |
113 | * @code |
114 | * QListView *lv; |
115 | * ... |
116 | * KCategorizedView *cv = qobject_cast<KCategorizedView*>(lv); |
117 | * if (cv) { |
118 | * cv->setGridSizeOwn(mySize); |
119 | * } else { |
120 | * lv->setGridSize(mySize); |
121 | * } |
122 | * @endcode |
123 | * |
124 | * @note this method will call to QListView::setGridSize among other operations. |
125 | * |
126 | * @since 4.4 |
127 | */ |
128 | void setGridSizeOwn(const QSize &size); |
129 | |
130 | /** |
131 | * Reimplemented from QAbstractItemView. |
132 | */ |
133 | virtual QRect visualRect(const QModelIndex &index) const; |
134 | |
135 | /** |
136 | * Returns the current category drawer. |
137 | */ |
138 | KCategoryDrawer *categoryDrawer() const; |
139 | |
140 | /** |
141 | * The category drawer that will be used for drawing categories. |
142 | */ |
143 | void setCategoryDrawer(KCategoryDrawer *categoryDrawer); |
144 | |
145 | /** |
146 | * @return Category spacing. The spacing between categories. |
147 | * |
148 | * @since 4.4 |
149 | */ |
150 | int categorySpacing() const; |
151 | |
152 | /** |
153 | * Stablishes the category spacing. This is the spacing between categories. |
154 | * |
155 | * @since 4.4 |
156 | */ |
157 | void setCategorySpacing(int categorySpacing); |
158 | |
159 | /** |
160 | * @return Whether blocks should be drawn with alternating colors. |
161 | * |
162 | * @since 4.4 |
163 | */ |
164 | bool alternatingBlockColors() const; |
165 | |
166 | /** |
167 | * Sets whether blocks should be drawn with alternating colors. |
168 | * |
169 | * @since 4.4 |
170 | */ |
171 | void setAlternatingBlockColors(bool enable); |
172 | |
173 | /** |
174 | * @return Whether blocks can be collapsed or not. |
175 | * |
176 | * @since 4.4 |
177 | */ |
178 | bool collapsibleBlocks() const; |
179 | |
180 | /** |
181 | * Sets whether blocks can be collapsed or not. |
182 | * |
183 | * @since 4.4 |
184 | */ |
185 | void setCollapsibleBlocks(bool enable); |
186 | |
187 | /** |
188 | * @return Block of indexes that are into @p category. |
189 | * |
190 | * @since 4.5 |
191 | */ |
192 | QModelIndexList block(const QString &category); |
193 | |
194 | /** |
195 | * @return Block of indexes that are represented by @p representative. |
196 | * |
197 | * @since 4.5 |
198 | */ |
199 | QModelIndexList block(const QModelIndex &representative); |
200 | |
201 | /** |
202 | * Reimplemented from QAbstractItemView. |
203 | */ |
204 | virtual QModelIndex indexAt(const QPoint &point) const; |
205 | |
206 | /** |
207 | * Reimplemented from QAbstractItemView. |
208 | */ |
209 | virtual void reset(); |
210 | |
211 | protected: |
212 | /** |
213 | * Reimplemented from QWidget. |
214 | */ |
215 | virtual void paintEvent(QPaintEvent *event); |
216 | |
217 | /** |
218 | * Reimplemented from QWidget. |
219 | */ |
220 | virtual void resizeEvent(QResizeEvent *event); |
221 | |
222 | /** |
223 | * Reimplemented from QAbstractItemView. |
224 | */ |
225 | virtual void setSelection(const QRect &rect, |
226 | QItemSelectionModel::SelectionFlags flags); |
227 | |
228 | /** |
229 | * Reimplemented from QWidget. |
230 | */ |
231 | virtual void mouseMoveEvent(QMouseEvent *event); |
232 | |
233 | /** |
234 | * Reimplemented from QWidget. |
235 | */ |
236 | virtual void mousePressEvent(QMouseEvent *event); |
237 | |
238 | /** |
239 | * Reimplemented from QWidget. |
240 | */ |
241 | virtual void mouseReleaseEvent(QMouseEvent *event); |
242 | |
243 | /** |
244 | * Reimplemented from QWidget. |
245 | */ |
246 | virtual void leaveEvent(QEvent *event); |
247 | |
248 | /** |
249 | * Reimplemented from QAbstractItemView. |
250 | */ |
251 | virtual void startDrag(Qt::DropActions supportedActions); |
252 | |
253 | /** |
254 | * Reimplemented from QAbstractItemView. |
255 | */ |
256 | virtual void dragMoveEvent(QDragMoveEvent *event); |
257 | |
258 | /** |
259 | * Reimplemented from QAbstractItemView. |
260 | */ |
261 | virtual void dragEnterEvent(QDragEnterEvent *event); |
262 | |
263 | /** |
264 | * Reimplemented from QAbstractItemView. |
265 | */ |
266 | virtual void dragLeaveEvent(QDragLeaveEvent *event); |
267 | |
268 | /** |
269 | * Reimplemented from QAbstractItemView. |
270 | */ |
271 | virtual void dropEvent(QDropEvent *event); |
272 | |
273 | /** |
274 | * Reimplemented from QAbstractItemView. |
275 | */ |
276 | virtual QModelIndex moveCursor(CursorAction cursorAction, |
277 | Qt::KeyboardModifiers modifiers); |
278 | |
279 | /** |
280 | * Reimplemented from QAbstractItemView. |
281 | */ |
282 | virtual void rowsAboutToBeRemoved(const QModelIndex &parent, |
283 | int start, |
284 | int end); |
285 | |
286 | /** |
287 | * Reimplemented from QAbstractItemView. |
288 | */ |
289 | virtual void updateGeometries(); |
290 | |
291 | /** |
292 | * Reimplemented from QAbstractItemView. |
293 | */ |
294 | virtual void currentChanged(const QModelIndex ¤t, |
295 | const QModelIndex &previous); |
296 | |
297 | /** |
298 | * Reimplemented from QAbstractItemView. |
299 | */ |
300 | virtual void dataChanged(const QModelIndex &topLeft, |
301 | const QModelIndex &bottomRight); |
302 | |
303 | /** |
304 | * Reimplemented from QAbstractItemView. |
305 | */ |
306 | virtual void rowsInserted(const QModelIndex &parent, |
307 | int start, |
308 | int end); |
309 | |
310 | protected Q_SLOTS: |
311 | /** |
312 | * @internal |
313 | * @warning Deprecated since 4.4. |
314 | */ |
315 | #ifndef KDE_NO_DEPRECATED |
316 | virtual KDE_DEPRECATED void rowsInsertedArtifficial(const QModelIndex &parent, |
317 | int start, |
318 | int end); |
319 | #endif |
320 | |
321 | /** |
322 | * @internal |
323 | * @warning Deprecated since 4.4. |
324 | */ |
325 | #ifndef KDE_NO_DEPRECATED |
326 | virtual KDE_DEPRECATED void rowsRemoved(const QModelIndex &parent, |
327 | int start, |
328 | int end); |
329 | #endif |
330 | |
331 | /** |
332 | * @internal |
333 | * Reposition items as needed. |
334 | */ |
335 | virtual void slotLayoutChanged(); |
336 | |
337 | private: |
338 | class Private; |
339 | Private *const d; |
340 | |
341 | Q_PRIVATE_SLOT(d, void _k_slotCollapseOrExpandClicked(QModelIndex)) |
342 | }; |
343 | |
344 | #endif // KCATEGORIZEDVIEW_H |
345 | |