source: trunk/src/gui/itemviews/qlistview_p.h@ 95

Last change on this file since 95 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 16.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QLISTVIEW_P_H
43#define QLISTVIEW_P_H
44
45//
46// W A R N I N G
47// -------------
48//
49// This file is not part of the Qt API. It exists for the convenience
50// of other Qt classes. This header file may change from version to
51// version without notice, or even be removed.
52//
53// We mean it.
54//
55
56#include "private/qabstractitemview_p.h"
57#include "qrubberband.h"
58#include "qbitarray.h"
59#include "qbsptree_p.h"
60#include <limits.h>
61#include <qscrollbar.h>
62
63#ifndef QT_NO_LISTVIEW
64
65QT_BEGIN_NAMESPACE
66
67class QListViewItem
68{
69 friend class QListViewPrivate;
70 friend class QStaticListViewBase;
71 friend class QDynamicListViewBase;
72public:
73 inline QListViewItem()
74 : x(-1), y(-1), w(0), h(0), indexHint(-1), visited(0xffff) {}
75 inline QListViewItem(const QListViewItem &other)
76 : x(other.x), y(other.y), w(other.w), h(other.h),
77 indexHint(other.indexHint), visited(other.visited) {}
78 inline QListViewItem(QRect r, int i)
79 : x(r.x()), y(r.y()), w(qMin(r.width(), SHRT_MAX)), h(qMin(r.height(), SHRT_MAX)),
80 indexHint(i), visited(0xffff) {}
81 inline bool operator==(const QListViewItem &other) const {
82 return (x == other.x && y == other.y && w == other.w && h == other.h &&
83 indexHint == other.indexHint); }
84 inline bool operator!=(const QListViewItem &other) const
85 { return !(*this == other); }
86 inline bool isValid() const
87 { return (x > -1) && (y > -1) && (w > 0) && (h > 0) && (indexHint > -1); }
88 inline void invalidate()
89 { x = -1; y = -1; w = 0; h = 0; }
90 inline void resize(const QSize &size)
91 { w = qMin(size.width(), SHRT_MAX); h = qMin(size.height(), SHRT_MAX); }
92 inline void move(const QPoint &position)
93 { x = position.x(); y = position.y(); }
94 inline int width() const { return w; }
95 inline int height() const { return h; }
96private:
97 inline QRect rect() const
98 { return QRect(x, y, w, h); }
99 int x, y;
100 short w, h;
101 mutable int indexHint;
102 uint visited;
103};
104
105struct QListViewLayoutInfo
106{
107 QRect bounds;
108 QSize grid;
109 int spacing;
110 int first;
111 int last;
112 bool wrap;
113 QListView::Flow flow;
114 int max;
115};
116
117class QListView;
118class QListViewPrivate;
119
120class QCommonListViewBase
121{
122public:
123 inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q) {}
124
125 inline int spacing() const;
126 inline bool isWrapping() const;
127 inline QSize gridSize() const;
128 inline QListView::Flow flow() const;
129 inline QListView::Movement movement() const;
130
131 inline QPoint offset() const;
132 inline QPoint pressedPosition() const;
133 inline bool uniformItemSizes() const;
134 inline int column() const;
135
136 inline int verticalScrollBarValue() const;
137 inline int horizontalScrollBarValue() const;
138 inline QListView::ScrollMode verticalScrollMode() const;
139 inline QListView::ScrollMode horizontalScrollMode() const;
140
141 inline QModelIndex modelIndex(int row) const;
142 inline int rowCount() const;
143
144 inline QStyleOptionViewItemV4 viewOptions() const;
145 inline QWidget *viewport() const;
146 inline QRect clipRect() const;
147
148 inline QSize cachedItemSize() const;
149 inline QRect viewItemRect(const QListViewItem &item) const;
150 inline QSize itemSize(const QStyleOptionViewItemV2 &opt, const QModelIndex &idx) const;
151 inline QAbstractItemDelegate *delegate(const QModelIndex &idx) const;
152
153 inline bool isHidden(int row) const;
154 inline int hiddenCount() const;
155
156 inline void clearIntersections() const;
157 inline void appendToIntersections(const QModelIndex &idx) const;
158
159 inline bool isRightToLeft() const;
160
161 QListViewPrivate *dd;
162 QListView *qq;
163};
164
165// ### rename to QListModeViewBase
166class QStaticListViewBase : public QCommonListViewBase
167{
168 friend class QListViewPrivate;
169public:
170 QStaticListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
171 batchStartRow(0), batchSavedDeltaSeg(0), batchSavedPosition(0) {}
172
173 QVector<int> flowPositions;
174 QVector<int> segmentPositions;
175 QVector<int> segmentStartRows;
176 QVector<int> segmentExtents;
177
178 QSize contentsSize;
179
180 // used when laying out in batches
181 int batchStartRow;
182 int batchSavedDeltaSeg;
183 int batchSavedPosition;
184
185 bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
186
187 QPoint initStaticLayout(const QListViewLayoutInfo &info);
188 void doStaticLayout(const QListViewLayoutInfo &info);
189 void intersectingStaticSet(const QRect &area) const;
190
191 int itemIndex(const QListViewItem &item) const;
192
193 int perItemScrollingPageSteps(int length, int bounds, bool wrap) const;
194
195 int perItemScrollToValue(int index, int value, int height,
196 QAbstractItemView::ScrollHint hint,
197 Qt::Orientation orientation, bool wrap, int extent) const;
198
199 QRect mapToViewport(const QRect &rect) const;
200
201 QListViewItem indexToListViewItem(const QModelIndex &index) const;
202
203 void scrollContentsBy(int &dx, int &dy);
204
205 int verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight,
206 bool above, bool below, bool wrap, QListView::ScrollHint hint, int itemHeight) const;
207 int horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth,
208 bool leftOf, bool rightOf, bool wrap, QListView::ScrollHint hint, int itemWidth) const;
209
210 void clear();
211};
212
213// ### rename to QIconModeViewBase
214class QDynamicListViewBase : public QCommonListViewBase
215{
216 friend class QListViewPrivate;
217public:
218 QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
219 batchStartRow(0), batchSavedDeltaSeg(0) {}
220
221 QBspTree tree;
222 QVector<QListViewItem> items;
223 QBitArray moved;
224
225 QSize contentsSize;
226
227 QVector<QModelIndex> draggedItems; // indices to the tree.itemVector
228 mutable QPoint draggedItemsPos;
229
230 // used when laying out in batches
231 int batchStartRow;
232 int batchSavedDeltaSeg;
233
234 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
235 bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
236
237 void initBspTree(const QSize &contents);
238 QPoint initDynamicLayout(const QListViewLayoutInfo &info);
239 void doDynamicLayout(const QListViewLayoutInfo &info);
240 void intersectingDynamicSet(const QRect &area) const;
241
242 static void addLeaf(QVector<int> &leaf, const QRect &area,
243 uint visited, QBspTree::Data data);
244
245 void insertItem(int index);
246 void removeItem(int index);
247 void moveItem(int index, const QPoint &dest);
248
249 int itemIndex(const QListViewItem &item) const;
250
251 void createItems(int to);
252 void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const;
253 QRect itemsRect(const QVector<QModelIndex> &indexes) const;
254
255 QPoint draggedItemsDelta() const;
256 QRect draggedItemsRect() const;
257
258 QPoint snapToGrid(const QPoint &pos) const;
259
260 void scrollElasticBandBy(int dx, int dy);
261
262 QListViewItem indexToListViewItem(const QModelIndex &index) const;
263
264 void clear();
265 void updateContentsSize();
266};
267
268class QListViewPrivate: public QAbstractItemViewPrivate
269{
270 Q_DECLARE_PUBLIC(QListView)
271public:
272 QListViewPrivate();
273 ~QListViewPrivate();
274
275 void clear();
276 void prepareItemsLayout();
277
278 bool doItemsLayout(int num);
279
280 inline void intersectingSet(const QRect &area, bool doLayout = true) const {
281 if (doLayout) executePostedLayout();
282 QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized());
283 if (viewMode == QListView::ListMode) staticListView->intersectingStaticSet(a);
284 else dynamicListView->intersectingDynamicSet(a);
285 }
286
287 // ### FIXME:
288 inline void resetBatchStartRow()
289 { if (viewMode == QListView::ListMode) staticListView->batchStartRow = 0;
290 else dynamicListView->batchStartRow = 0; }
291 inline int batchStartRow() const
292 { return (viewMode == QListView::ListMode
293 ? staticListView->batchStartRow : dynamicListView->batchStartRow); }
294 inline QSize contentsSize() const
295 { return (viewMode == QListView::ListMode
296 ? staticListView->contentsSize : dynamicListView->contentsSize); }
297 inline void setContentsSize(int w, int h)
298 { if (viewMode == QListView::ListMode) staticListView->contentsSize = QSize(w, h);
299 else dynamicListView->contentsSize = QSize(w, h); }
300
301 inline int flipX(int x) const
302 { return qMax(viewport->width(), contentsSize().width()) - x; }
303 inline QPoint flipX(const QPoint &p) const
304 { return QPoint(flipX(p.x()), p.y()); }
305 inline QRect flipX(const QRect &r) const
306 { return QRect(flipX(r.x()) - r.width(), r.y(), r.width(), r.height()); }
307 inline QRect viewItemRect(const QListViewItem &item) const
308 { if (q_func()->isRightToLeft()) return flipX(item.rect()); return item.rect(); }
309
310 int itemIndex(const QListViewItem &item) const;
311 QListViewItem indexToListViewItem(const QModelIndex &index) const;
312 inline QModelIndex listViewItemToIndex(const QListViewItem &item) const
313 { return model->index(itemIndex(item), column, root); }
314
315 QRect mapToViewport(const QRect &rect, bool greedy = false) const;
316
317 QModelIndex closestIndex(const QRect &target, const QVector<QModelIndex> &candidates) const;
318 QSize itemSize(const QStyleOptionViewItem &option, const QModelIndex &index) const;
319
320 bool selectionAllowed(const QModelIndex &index) const
321 { if (viewMode == QListView::ListMode && !showElasticBand) return index.isValid(); return true; }
322
323 int horizontalScrollToValue(const QModelIndex &index, const QRect &rect, QListView::ScrollHint hint) const;
324 int verticalScrollToValue(const QModelIndex &index, const QRect &rect, QListView::ScrollHint hint) const;
325
326 QItemSelection selection(const QRect &rect) const;
327 void selectAll(QItemSelectionModel::SelectionFlags command);
328
329 inline void setGridSize(const QSize &size) { grid = size; }
330 inline QSize gridSize() const { return grid; }
331 inline void setWrapping(bool b) { wrap = b; }
332 inline bool isWrapping() const { return wrap; }
333 inline void setSpacing(int s) { space = s; }
334 inline int spacing() const { return space; }
335 inline void setSelectionRectVisible(bool visible) { showElasticBand = visible; }
336 inline bool isSelectionRectVisible() const { return showElasticBand; }
337
338 inline QModelIndex modelIndex(int row) const { return model->index(row, column, root); }
339 inline bool isHidden(int row) const { return hiddenRows.contains(model->index(row, 0, root)); }
340 inline bool isHiddenOrDisabled(int row) const { return isHidden(row) || !isIndexEnabled(modelIndex(row)); }
341
342 inline void removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const {
343 QVector<QModelIndex>::iterator it = indexes->begin();
344 while (it != indexes->end()) {
345 if (!isIndexEnabled(*it) || (*it) == current)
346 indexes->erase(it);
347 else
348 ++it;
349 }
350 }
351
352 void scrollElasticBandBy(int dx, int dy);
353
354 // ### FIXME: we only need one at a time
355 QDynamicListViewBase *dynamicListView;
356 QStaticListViewBase *staticListView;
357
358 // ### FIXME: see if we can move the members into the dynamic/static classes
359
360 bool wrap;
361 int space;
362 QSize grid;
363
364 QListView::Flow flow;
365 QListView::Movement movement;
366 QListView::ResizeMode resizeMode;
367 QListView::LayoutMode layoutMode;
368 QListView::ViewMode viewMode;
369
370 // the properties controlling the
371 // icon- or list-view modes
372 enum ModeProperties {
373 Wrap = 1,
374 Spacing = 2,
375 GridSize = 4,
376 Flow = 8,
377 Movement = 16,
378 ResizeMode = 32,
379 SelectionRectVisible = 64
380 };
381
382 uint modeProperties : 8;
383
384 QRect layoutBounds;
385
386 // used for intersecting set
387 mutable QVector<QModelIndex> intersectVector;
388
389 // timers
390 QBasicTimer batchLayoutTimer;
391
392 // used for hidden items
393 QVector<QPersistentModelIndex> hiddenRows;
394
395 int column;
396 bool uniformItemSizes;
397 mutable QSize cachedItemSize;
398 int batchSize;
399
400 QRect elasticBand;
401 bool showElasticBand;
402};
403
404// inline implementations
405
406inline int QCommonListViewBase::spacing() const { return dd->spacing(); }
407inline bool QCommonListViewBase::isWrapping() const { return dd->isWrapping(); }
408inline QSize QCommonListViewBase::gridSize() const { return dd->gridSize(); }
409inline QListView::Flow QCommonListViewBase::flow() const { return dd->flow; }
410inline QListView::Movement QCommonListViewBase::movement() const { return dd->movement; }
411
412inline QPoint QCommonListViewBase::offset() const { return dd->offset(); }
413inline QPoint QCommonListViewBase::pressedPosition() const { return dd->pressedPosition; }
414inline bool QCommonListViewBase::uniformItemSizes() const { return dd->uniformItemSizes; }
415inline int QCommonListViewBase::column() const { return dd->column; }
416
417inline int QCommonListViewBase::verticalScrollBarValue() const { return qq->verticalScrollBar()->value(); }
418inline int QCommonListViewBase::horizontalScrollBarValue() const { return qq->horizontalScrollBar()->value(); }
419inline QListView::ScrollMode QCommonListViewBase::verticalScrollMode() const { return qq->verticalScrollMode(); }
420inline QListView::ScrollMode QCommonListViewBase::horizontalScrollMode() const { return qq->horizontalScrollMode(); }
421
422inline QModelIndex QCommonListViewBase::modelIndex(int row) const
423 { return dd->model->index(row, dd->column, dd->root); }
424inline int QCommonListViewBase::rowCount() const { return dd->model->rowCount(dd->root); }
425
426inline QStyleOptionViewItemV4 QCommonListViewBase::viewOptions() const { return dd->viewOptionsV4(); }
427inline QWidget *QCommonListViewBase::viewport() const { return dd->viewport; }
428inline QRect QCommonListViewBase::clipRect() const { return dd->clipRect(); }
429
430inline QSize QCommonListViewBase::cachedItemSize() const { return dd->cachedItemSize; }
431inline QRect QCommonListViewBase::viewItemRect(const QListViewItem &item) const { return dd->viewItemRect(item); }
432inline QSize QCommonListViewBase::itemSize(const QStyleOptionViewItemV2 &opt, const QModelIndex &idx) const
433 { return dd->itemSize(opt, idx); }
434
435inline QAbstractItemDelegate *QCommonListViewBase::delegate(const QModelIndex &idx) const
436 { return dd->delegateForIndex(idx); }
437
438inline bool QCommonListViewBase::isHidden(int row) const { return dd->isHidden(row); }
439inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); }
440
441inline void QCommonListViewBase::clearIntersections() const { dd->intersectVector.clear(); }
442inline void QCommonListViewBase::appendToIntersections(const QModelIndex &idx) const { dd->intersectVector.append(idx); }
443
444inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); }
445
446QT_END_NAMESPACE
447
448#endif // QT_NO_LISTVIEW
449
450#endif // QLISTVIEW_P_H
Note: See TracBrowser for help on using the repository browser.