summaryrefslogtreecommitdiffstats
path: root/depends/groupview/include/categorizedview.h
blob: 81b1dbb1f980b63419b75eb213454b282f667a63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/**
  * This file is part of the KDE project
  * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public License
  * along with this library; see the file COPYING.LIB.  If not, write to
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
  */

#ifndef KCATEGORIZEDVIEW_H
#define KCATEGORIZEDVIEW_H

#include <QListView>

#include <groupview_config.h>

class KCategoryDrawer;

/**
  * @short Item view for listing items in a categorized fashion optionally
  *
  * KCategorizedView basically has the same functionality as QListView, only that it also lets you
  * layout items in a way that they are categorized visually.
  *
  * For it to work you will need to set a KCategorizedSortFilterProxyModel and a KCategoryDrawer
  * with methods setModel() and setCategoryDrawer() respectively. Also, the model will need to be
  * flagged as categorized with KCategorizedSortFilterProxyModel::setCategorizedModel(true).
  *
  * The way it works (if categorization enabled):
  *
  *     - When sorting, it does more things than QListView does. It will ask the model for the
  *       special role CategorySortRole (@see KCategorizedSortFilterProxyModel). This can return
  *       a QString or an int in order to tell the view the order of categories. In this sense, for
  *       instance, if we are sorting by name ascending, "A" would be before than "B". If we are
  *       sorting by size ascending, 512 bytes would be before 1024 bytes. This way categories are
  *       also sorted.
  *
  *     - When the view has to paint, it will ask the model with the role CategoryDisplayRole
  *       (@see KCategorizedSortFilterProxyModel). It will for instance return "F" for "foo.pdf" if
  *       we are sorting by name ascending, or "Small" if a certain item has 100 bytes, for example.
  *
  * For drawing categories, KCategoryDrawer will be used. You can inherit this class to do your own
  * drawing.
  *
  * @note All examples cited before talk about filesystems and such, but have present that this
  *       is a completely generic class, and it can be used for whatever your purpose is. For
  *       instance when talking about animals, you can separate them by "Mammal" and "Oviparous". In
  *       this very case, for example, the CategorySortRole and the CategoryDisplayRole could be the
  *       same ("Mammal" and "Oviparous").
  *
  * @note There is a really performance boost if CategorySortRole returns an int instead of a QString.
  *       Have present that this role is asked (n * log n) times when sorting and compared. Comparing
  *       ints is always faster than comparing strings, whithout mattering how fast the string
  *       comparison is. Consider thinking of a way of returning ints instead of QStrings if your
  *       model can contain a high number of items.
  *
  * @warning Note that for really drawing items in blocks you will need some things to be done:
  *             - The model set to this view has to be (or inherit if you want to do special stuff
  *               in it) KCategorizedSortFilterProxyModel.
  *             - This model needs to be set setCategorizedModel to true.
  *             - Set a category drawer by calling setCategoryDrawer.
  *
  * @see KCategorizedSortFilterProxyModel, KCategoryDrawer
  *
  * @author Rafael Fernández López <ereslibre@kde.org>
  */
class LIBGROUPVIEW_EXPORT KCategorizedView
	: public QListView
{
	Q_OBJECT
	Q_PROPERTY ( int categorySpacing READ categorySpacing WRITE setCategorySpacing )
	Q_PROPERTY ( bool alternatingBlockColors READ alternatingBlockColors WRITE setAlternatingBlockColors )
	Q_PROPERTY ( bool collapsibleBlocks READ collapsibleBlocks WRITE setCollapsibleBlocks )

public:
	KCategorizedView ( QWidget *parent = 0 );

	~KCategorizedView();

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void setModel ( QAbstractItemModel *model );

	/**
	  * Calls to setGridSizeOwn().
	  */
	void setGridSize ( const QSize &size );

	/**
	  * @warning note that setGridSize is not virtual in the base class (QListView), so if you are
	  *          calling to this method, make sure you have a KCategorizedView pointer around. This
	  *          means that something like:
	  * @code
	  *     QListView *lv = new KCategorizedView();
	  *     lv->setGridSize(mySize);
	  * @endcode
	  *
	  * will not call to the expected setGridSize method. Instead do something like this:
	  *
	  * @code
	  *     QListView *lv;
	  *     ...
	  *     KCategorizedView *cv = qobject_cast<KCategorizedView*>(lv);
	  *     if (cv) {
	  *         cv->setGridSizeOwn(mySize);
	  *     } else {
	  *         lv->setGridSize(mySize);
	  *     }
	  * @endcode
	  *
	  * @note this method will call to QListView::setGridSize among other operations.
	  *
	  * @since 4.4
	  */
	void setGridSizeOwn ( const QSize &size );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual QRect visualRect ( const QModelIndex &index ) const;

	/**
	  * Returns the current category drawer.
	  */
	KCategoryDrawer *categoryDrawer() const;

	/**
	  * The category drawer that will be used for drawing categories.
	  */
	void setCategoryDrawer ( KCategoryDrawer *categoryDrawer );

	/**
	  * @return Category spacing. The spacing between categories.
	  *
	  * @since 4.4
	  */
	int categorySpacing() const;

	/**
	  * Stablishes the category spacing. This is the spacing between categories.
	  *
	  * @since 4.4
	  */
	void setCategorySpacing ( int categorySpacing );

	/**
	  * @return Whether blocks should be drawn with alternating colors.
	  *
	  * @since 4.4
	  */
	bool alternatingBlockColors() const;

	/**
	  * Sets whether blocks should be drawn with alternating colors.
	  *
	  * @since 4.4
	  */
	void setAlternatingBlockColors ( bool enable );

	/**
	  * @return Whether blocks can be collapsed or not.
	  *
	  * @since 4.4
	  */
	bool collapsibleBlocks() const;

	/**
	  * Sets whether blocks can be collapsed or not.
	  *
	  * @since 4.4
	  */
	void setCollapsibleBlocks ( bool enable );

	/**
	  * @return Block of indexes that are into @p category.
	  *
	  * @since 4.5
	  */
	QModelIndexList block ( const QString &category );

	/**
	  * @return Block of indexes that are represented by @p representative.
	  *
	  * @since 4.5
	  */
	QModelIndexList block ( const QModelIndex &representative );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual QModelIndex indexAt ( const QPoint &point ) const;

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void reset();

	/**
	  * Signify that all item delegates size hints return the same fixed size
	  */
	void setUniformItemWidths(bool enable);

	/**
	  * Do all item delegate size hints return the same fixed size?
	  */
    bool uniformItemWidths() const;
	
protected:
	/**
	  * Reimplemented from QWidget.
	  */
	virtual void paintEvent ( QPaintEvent *event );

	/**
	  * Reimplemented from QWidget.
	  */
	virtual void resizeEvent ( QResizeEvent *event );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void setSelection ( const QRect &rect,
	                            QItemSelectionModel::SelectionFlags flags );

	/**
	  * Reimplemented from QWidget.
	  */
	virtual void mouseMoveEvent ( QMouseEvent *event );

	/**
	  * Reimplemented from QWidget.
	  */
	virtual void mousePressEvent ( QMouseEvent *event );

	/**
	  * Reimplemented from QWidget.
	  */
	virtual void mouseReleaseEvent ( QMouseEvent *event );

	/**
	  * Reimplemented from QWidget.
	  */
	virtual void leaveEvent ( QEvent *event );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void startDrag ( Qt::DropActions supportedActions );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void dragMoveEvent ( QDragMoveEvent *event );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void dragEnterEvent ( QDragEnterEvent *event );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void dragLeaveEvent ( QDragLeaveEvent *event );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void dropEvent ( QDropEvent *event );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual QModelIndex moveCursor ( CursorAction cursorAction,
	                                 Qt::KeyboardModifiers modifiers );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void rowsAboutToBeRemoved ( const QModelIndex &parent,
	                                    int start,
	                                    int end );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void updateGeometries();

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void currentChanged ( const QModelIndex &current,
	                              const QModelIndex &previous );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void dataChanged ( const QModelIndex &topLeft,
	                           const QModelIndex &bottomRight );

	/**
	  * Reimplemented from QAbstractItemView.
	  */
	virtual void rowsInserted ( const QModelIndex &parent,
	                            int start,
	                            int end );

protected Q_SLOTS:
	/**
	  * @internal
	  * Reposition items as needed.
	  */
	virtual void slotLayoutChanged();
	virtual void slotCollapseOrExpandClicked ( QModelIndex );

private:
	class Private;
	Private *const d;
};

#endif // KCATEGORIZEDVIEW_H