source: trunk/src/gui/itemviews/qabstractitemview_p.h@ 332

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

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

File size: 14.1 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 QABSTRACTITEMVIEW_P_H
43#define QABSTRACTITEMVIEW_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 purely as an
50// implementation detail. 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/qabstractscrollarea_p.h"
57#include "private/qabstractitemmodel_p.h"
58#include "QtGui/qapplication.h"
59#include "QtCore/qdatetime.h"
60#include "QtGui/qevent.h"
61#include "QtGui/qmime.h"
62#include "QtGui/qpainter.h"
63#include "QtCore/qpair.h"
64#include "QtCore/qtimer.h"
65#include "QtCore/qtimeline.h"
66#include "QtGui/qregion.h"
67#include "QtCore/qdebug.h"
68#include "QtGui/qpainter.h"
69
70#ifndef QT_NO_ITEMVIEWS
71
72QT_BEGIN_NAMESPACE
73
74struct QEditorInfo
75{
76 QEditorInfo() : isStatic(false)
77 {
78 }
79
80 QEditorInfo(const QPersistentModelIndex &i, QWidget *e, bool b) : index(i), editor(e), isStatic(b)
81 {
82 }
83
84 QPersistentModelIndex index;
85 QPointer<QWidget> editor;
86 bool isStatic; //true when called from setIndexWidget
87
88};
89
90class QEmptyModel : public QAbstractItemModel
91{
92public:
93 explicit QEmptyModel(QObject *parent = 0) : QAbstractItemModel(parent) {}
94 QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); }
95 QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
96 int rowCount(const QModelIndex &) const { return 0; }
97 int columnCount(const QModelIndex &) const { return 0; }
98 bool hasChildren(const QModelIndex &) const { return false; }
99 QVariant data(const QModelIndex &, int) const { return QVariant(); }
100};
101
102class Q_GUI_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate
103{
104 Q_DECLARE_PUBLIC(QAbstractItemView)
105
106public:
107 QAbstractItemViewPrivate();
108 virtual ~QAbstractItemViewPrivate();
109
110 void init();
111
112 void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
113 void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
114 void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
115 void _q_columnsInserted(const QModelIndex &parent, int start, int end);
116 void _q_modelDestroyed();
117 void _q_layoutChanged();
118 void _q_fetchMore();
119
120 bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const;
121 bool shouldForwardEvent(QAbstractItemView::EditTrigger trigger, const QEvent *event) const;
122 bool shouldAutoScroll(const QPoint &pos) const;
123 void doDelayedItemsLayout(int delay = 0);
124 void interruptDelayedItemsLayout() const;
125
126 bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
127 bool droppingOnItself(QDropEvent *event, const QModelIndex &index);
128
129 QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options);
130 bool sendDelegateEvent(const QModelIndex &index, QEvent *event) const;
131 bool openEditor(const QModelIndex &index, QEvent *event);
132 void updateEditorData(const QModelIndex &topLeft, const QModelIndex &bottomRight);
133
134 QItemSelectionModel::SelectionFlags multiSelectionCommand(const QModelIndex &index,
135 const QEvent *event) const;
136 QItemSelectionModel::SelectionFlags extendedSelectionCommand(const QModelIndex &index,
137 const QEvent *event) const;
138 QItemSelectionModel::SelectionFlags contiguousSelectionCommand(const QModelIndex &index,
139 const QEvent *event) const;
140 virtual void selectAll(QItemSelectionModel::SelectionFlags command);
141
142 inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const
143 {
144 switch (selectionBehavior) {
145 case QAbstractItemView::SelectRows: return QItemSelectionModel::Rows;
146 case QAbstractItemView::SelectColumns: return QItemSelectionModel::Columns;
147 case QAbstractItemView::SelectItems: default: return QItemSelectionModel::NoUpdate;
148 }
149 }
150
151#ifndef QT_NO_DRAGANDDROP
152 QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
153 inline bool canDecode(QDropEvent *e) const {
154 QStringList modelTypes = model->mimeTypes();
155 const QMimeData *mime = e->mimeData();
156 for (int i = 0; i < modelTypes.count(); ++i)
157 if (mime->hasFormat(modelTypes.at(i))
158 && (e->dropAction() & model->supportedDropActions()))
159 return true;
160 return false;
161 }
162
163 inline void paintDropIndicator(QPainter *painter)
164 {
165 if (showDropIndicator && state == QAbstractItemView::DraggingState
166#ifndef QT_NO_CURSOR
167 && viewport->cursor().shape() != Qt::ForbiddenCursor
168#endif
169 ) {
170 QStyleOption opt;
171 opt.init(q_func());
172 opt.rect = dropIndicatorRect;
173 q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func());
174 }
175 }
176#endif
177
178 inline void releaseEditor(QWidget *editor) const {
179 if (editor) {
180 QObject::disconnect(editor, SIGNAL(destroyed(QObject*)),
181 q_func(), SLOT(editorDestroyed(QObject*)));
182 editor->removeEventFilter(itemDelegate);
183 editor->hide();
184 editor->deleteLater();
185 }
186 }
187
188 inline void executePostedLayout() const {
189 if (delayedPendingLayout && state != QAbstractItemView::CollapsingState) {
190 interruptDelayedItemsLayout();
191 const_cast<QAbstractItemView*>(q_func())->doItemsLayout();
192 }
193 }
194
195 inline void setDirtyRegion(const QRegion &visualRegion) {
196 updateRegion += visualRegion;
197 if (!updateTimer.isActive())
198 updateTimer.start(0, q_func());
199 }
200
201 inline void scrollDirtyRegion(int dx, int dy) {
202 scrollDelayOffset = QPoint(-dx, -dy);
203 updateDirtyRegion();
204 scrollDelayOffset = QPoint(0, 0);
205 }
206
207 inline void scrollContentsBy(int dx, int dy) {
208 scrollDirtyRegion(dx, dy);
209 viewport->scroll(dx, dy);
210 }
211
212 void updateDirtyRegion() {
213 updateTimer.stop();
214 viewport->update(updateRegion);
215 updateRegion = QRegion();
216 }
217
218 void clearOrRemove();
219 void checkPersistentEditorFocus();
220
221 QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r = 0) const;
222
223 inline QPoint offset() const {
224 const Q_Q(QAbstractItemView);
225 return QPoint(q->isRightToLeft() ? -q->horizontalOffset()
226 : q->horizontalOffset(), q->verticalOffset());
227 }
228
229 QEditorInfo editorForIndex(const QModelIndex &index) const;
230 inline bool hasEditor(const QModelIndex &index) const {
231 return editorForIndex(index).editor != 0;
232 }
233
234 QModelIndex indexForEditor(QWidget *editor) const;
235 void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic);
236 void removeEditor(QWidget *editor);
237
238 inline bool isAnimating() const {
239 return state == QAbstractItemView::AnimatingState;
240 }
241
242 inline QAbstractItemDelegate *delegateForIndex(const QModelIndex &index) const {
243 QAbstractItemDelegate *del;
244 if ((del = rowDelegates.value(index.row(), 0))) return del;
245 if ((del = columnDelegates.value(index.column(), 0))) return del;
246 return itemDelegate;
247 }
248
249 inline bool isIndexValid(const QModelIndex &index) const {
250 return (index.row() >= 0) && (index.column() >= 0) && (index.model() == model);
251 }
252 inline bool isIndexSelectable(const QModelIndex &index) const {
253 return (model->flags(index) & Qt::ItemIsSelectable);
254 }
255 inline bool isIndexEnabled(const QModelIndex &index) const {
256 return (model->flags(index) & Qt::ItemIsEnabled);
257 }
258 inline bool isIndexDropEnabled(const QModelIndex &index) const {
259 return (model->flags(index) & Qt::ItemIsDropEnabled);
260 }
261 inline bool isIndexDragEnabled(const QModelIndex &index) const {
262 return (model->flags(index) & Qt::ItemIsDragEnabled);
263 }
264
265 virtual bool selectionAllowed(const QModelIndex &index) const {
266 // in some views we want to go ahead with selections, even if the index is invalid
267 return isIndexValid(index) && isIndexSelectable(index);
268 }
269
270 // reimplemented from QAbstractScrollAreaPrivate
271 virtual QPoint contentsOffset() const {
272 Q_Q(const QAbstractItemView);
273 return QPoint(q->horizontalOffset(), q->verticalOffset());
274 }
275
276 /**
277 * For now, assume that we have few editors, if we need a more efficient implementation
278 * we should add a QMap<QAbstractItemDelegate*, int> member.
279 */
280 int delegateRefCount(const QAbstractItemDelegate *delegate) const
281 {
282 int ref = 0;
283 if (itemDelegate == delegate)
284 ++ref;
285
286 for (int maps = 0; maps < 2; ++maps) {
287 const QMap<int, QPointer<QAbstractItemDelegate> > *delegates = maps ? &columnDelegates : &rowDelegates;
288 for (QMap<int, QPointer<QAbstractItemDelegate> >::const_iterator it = delegates->begin();
289 it != delegates->end(); ++it) {
290 if (it.value() == delegate) {
291 ++ref;
292 // optimization, we are only interested in the ref count values 0, 1 or >=2
293 if (ref >= 2) {
294 return ref;
295 }
296 }
297 }
298 }
299 return ref;
300 }
301
302 /**
303 * return true if the index is registered as a QPersistentModelIndex
304 */
305 inline bool isPersistent(const QModelIndex &index) const
306 {
307 return static_cast<QAbstractItemModelPrivate *>(model->d_ptr)->persistent.indexes.contains(index);
308 }
309
310 QModelIndexList selectedDraggableIndexes() const;
311
312 QStyleOptionViewItemV4 viewOptionsV4() const;
313
314 QAbstractItemModel *model;
315 QPointer<QAbstractItemDelegate> itemDelegate;
316 QMap<int, QPointer<QAbstractItemDelegate> > rowDelegates;
317 QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
318 QPointer<QItemSelectionModel> selectionModel;
319
320 QAbstractItemView::SelectionMode selectionMode;
321 QAbstractItemView::SelectionBehavior selectionBehavior;
322
323 QList<QEditorInfo> editors;
324 QSet<QWidget*> persistent;
325 QWidget *currentlyCommittingEditor;
326
327 QPersistentModelIndex enteredIndex;
328 QPersistentModelIndex pressedIndex;
329 Qt::KeyboardModifiers pressedModifiers;
330 QPoint pressedPosition;
331 bool pressedAlreadySelected;
332
333 //forces the next mouseMoveEvent to send the viewportEntered signal
334 //if the mouse is over the viewport and not over an item
335 bool viewportEnteredNeeded;
336
337 QAbstractItemView::State state;
338 QAbstractItemView::EditTriggers editTriggers;
339 QAbstractItemView::EditTrigger lastTrigger;
340
341 QPersistentModelIndex root;
342 QPersistentModelIndex hover;
343
344 bool tabKeyNavigation;
345
346#ifndef QT_NO_DRAGANDDROP
347 bool showDropIndicator;
348 QRect dropIndicatorRect;
349 bool dragEnabled;
350 QAbstractItemView::DragDropMode dragDropMode;
351 bool overwrite;
352 QAbstractItemView::DropIndicatorPosition dropIndicatorPosition;
353#endif
354
355 QString keyboardInput;
356 QTime keyboardInputTime;
357
358 bool autoScroll;
359 QBasicTimer autoScrollTimer;
360 int autoScrollMargin;
361 int autoScrollCount;
362
363 bool alternatingColors;
364
365 QSize iconSize;
366 Qt::TextElideMode textElideMode;
367
368 QRegion updateRegion; // used for the internal update system
369 QPoint scrollDelayOffset;
370
371 QBasicTimer updateTimer;
372 QBasicTimer delayedEditing;
373 QBasicTimer delayedAutoScroll; //used when an item is clicked
374 QTimeLine timeline;
375
376 QAbstractItemView::ScrollMode verticalScrollMode;
377 QAbstractItemView::ScrollMode horizontalScrollMode;
378
379 bool currentIndexSet;
380
381 bool wrapItemText;
382 mutable bool delayedPendingLayout;
383
384private:
385 mutable QBasicTimer delayedLayout;
386};
387
388QT_BEGIN_INCLUDE_NAMESPACE
389#include <qvector.h>
390QT_END_INCLUDE_NAMESPACE
391
392template <typename T>
393inline int qBinarySearch(const QVector<T> &vec, const T &item, int start, int end)
394{
395 int i = (start + end + 1) >> 1;
396 while (end - start > 0) {
397 if (vec.at(i) > item)
398 end = i - 1;
399 else
400 start = i;
401 i = (start + end + 1) >> 1;
402 }
403 return i;
404}
405
406QT_END_NAMESPACE
407
408#endif // QT_NO_ITEMVIEWS
409
410#endif // QABSTRACTITEMVIEW_P_H
Note: See TracBrowser for help on using the repository browser.