source: trunk/src/gui/itemviews/qabstractitemdelegate.cpp@ 318

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

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

File size: 13.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#include "qabstractitemdelegate.h"
43
44#ifndef QT_NO_ITEMVIEWS
45#include <qabstractitemmodel.h>
46#include <qabstractitemview.h>
47#include <qfontmetrics.h>
48#include <qwhatsthis.h>
49#include <qtooltip.h>
50#include <qevent.h>
51#include <qstring.h>
52#include <qdebug.h>
53#include <private/qtextengine_p.h>
54
55QT_BEGIN_NAMESPACE
56
57/*!
58 \class QAbstractItemDelegate
59
60 \brief The QAbstractItemDelegate class is used to display and edit
61 data items from a model.
62
63 \ingroup model-view
64 \mainclass
65
66 A QAbstractItemDelegate provides the interface and common functionality
67 for delegates in the model/view architecture. Delegates display
68 individual items in views, and handle the editing of model data.
69
70 The QAbstractItemDelegate class is one of the \l{Model/View Classes}
71 and is part of Qt's \l{Model/View Programming}{model/view framework}.
72
73 To render an item in a custom way, you must implement paint() and
74 sizeHint(). The QItemDelegate class provides default implementations for
75 these functions; if you do not need custom rendering, subclass that
76 class instead.
77
78 We give an example of drawing a progress bar in items; in our case
79 for a package management program.
80
81 \image widgetdelegate.png
82
83 We create the \c WidgetDelegate class, which inherits from
84 QStyledItemDelegate. We do the drawing in the paint() function:
85
86 \snippet doc/src/snippets/widgetdelegate.cpp 0
87
88 Notice that we use a QStyleOptionProgressBar and initialize its
89 members. We can then use the current QStyle to draw it.
90
91 To provide custom editing, there are two approaches that can be
92 used. The first approach is to create an editor widget and display
93 it directly on top of the item. To do this you must reimplement
94 createEditor() to provide an editor widget, setEditorData() to populate
95 the editor with the data from the model, and setModelData() so that the
96 delegate can update the model with data from the editor.
97
98 The second approach is to handle user events directly by reimplementing
99 editorEvent().
100
101 \sa {model-view-programming}{Model/View Programming}, QItemDelegate,
102 {Pixelator Example}, QStyledItemDelegate, QStyle
103*/
104
105/*!
106 \enum QAbstractItemDelegate::EndEditHint
107
108 This enum describes the different hints that the delegate can give to the
109 model and view components to make editing data in a model a comfortable
110 experience for the user.
111
112 \value NoHint There is no recommended action to be performed.
113
114 These hints let the delegate influence the behavior of the view:
115
116 \value EditNextItem The view should use the delegate to open an
117 editor on the next item in the view.
118 \value EditPreviousItem The view should use the delegate to open an
119 editor on the previous item in the view.
120
121 Note that custom views may interpret the concepts of next and previous
122 differently.
123
124 The following hints are most useful when models are used that cache
125 data, such as those that manipulate data locally in order to increase
126 performance or conserve network bandwidth.
127
128 \value SubmitModelCache If the model caches data, it should write out
129 cached data to the underlying data store.
130 \value RevertModelCache If the model caches data, it should discard
131 cached data and replace it with data from the
132 underlying data store.
133
134 Although models and views should respond to these hints in appropriate
135 ways, custom components may ignore any or all of them if they are not
136 relevant.
137*/
138
139/*!
140 \fn void QAbstractItemDelegate::commitData(QWidget *editor)
141
142 This signal must be emitted when the \a editor widget has completed
143 editing the data, and wants to write it back into the model.
144*/
145
146/*!
147 \fn void QAbstractItemDelegate::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
148
149 This signal is emitted when the user has finished editing an item using
150 the specified \a editor.
151
152 The \a hint provides a way for the delegate to influence how the model and
153 view behave after editing is completed. It indicates to these components
154 what action should be performed next to provide a comfortable editing
155 experience for the user. For example, if \c EditNextItem is specified,
156 the view should use a delegate to open an editor on the next item in the
157 model.
158
159 \sa EndEditHint
160*/
161
162/*!
163 \fn void QAbstractItemDelegate::sizeHintChanged(const QModelIndex &index)
164 \since 4.4
165
166 This signal must be emitted when the sizeHint() of \a index changed.
167
168 Views automatically connect to this signal and relayout items as necessary.
169*/
170
171
172/*!
173 Creates a new abstract item delegate with the given \a parent.
174*/
175QAbstractItemDelegate::QAbstractItemDelegate(QObject *parent)
176 : QObject(parent)
177{
178
179}
180
181/*!
182 \internal
183
184 Creates a new abstract item delegate with the given \a parent.
185*/
186QAbstractItemDelegate::QAbstractItemDelegate(QObjectPrivate &dd, QObject *parent)
187 : QObject(dd, parent)
188{
189
190}
191
192/*!
193 Destroys the abstract item delegate.
194*/
195QAbstractItemDelegate::~QAbstractItemDelegate()
196{
197
198}
199
200/*!
201 \fn void QAbstractItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const = 0;
202
203 This pure abstract function must be reimplemented if you want to
204 provide custom rendering. Use the \a painter and style \a option to
205 render the item specified by the item \a index.
206
207 If you reimplement this you must also reimplement sizeHint().
208*/
209
210/*!
211 \fn QSize QAbstractItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const = 0
212
213 This pure abstract function must be reimplemented if you want to
214 provide custom rendering. The options are specified by \a option
215 and the model item by \a index.
216
217 If you reimplement this you must also reimplement paint().
218*/
219
220/*!
221 Returns the editor to be used for editing the data item with the
222 given \a index. Note that the index contains information about the
223 model being used. The editor's parent widget is specified by \a parent,
224 and the item options by \a option.
225
226 The base implementation returns 0. If you want custom editing you
227 will need to reimplement this function.
228
229 The returned editor widget should have Qt::StrongFocus;
230 otherwise, \l{QMouseEvent}s received by the widget will propagate
231 to the view. The view's background will shine through unless the
232 editor paints its own background (e.g., with
233 \l{QWidget::}{setAutoFillBackground()}).
234
235 \sa setModelData() setEditorData()
236*/
237QWidget *QAbstractItemDelegate::createEditor(QWidget *,
238 const QStyleOptionViewItem &,
239 const QModelIndex &) const
240{
241 return 0;
242}
243
244/*!
245 Sets the contents of the given \a editor to the data for the item
246 at the given \a index. Note that the index contains information
247 about the model being used.
248
249 The base implementation does nothing. If you want custom editing
250 you will need to reimplement this function.
251
252 \sa setModelData()
253*/
254void QAbstractItemDelegate::setEditorData(QWidget *,
255 const QModelIndex &) const
256{
257 // do nothing
258}
259
260/*!
261 Sets the data for the item at the given \a index in the \a model
262 to the contents of the given \a editor.
263
264 The base implementation does nothing. If you want custom editing
265 you will need to reimplement this function.
266
267 \sa setEditorData()
268*/
269void QAbstractItemDelegate::setModelData(QWidget *,
270 QAbstractItemModel *,
271 const QModelIndex &) const
272{
273 // do nothing
274}
275
276/*!
277 Updates the geometry of the \a editor for the item with the given
278 \a index, according to the rectangle specified in the \a option.
279 If the item has an internal layout, the editor will be laid out
280 accordingly. Note that the index contains information about the
281 model being used.
282
283 The base implementation does nothing. If you want custom editing
284 you must reimplement this function.
285*/
286void QAbstractItemDelegate::updateEditorGeometry(QWidget *,
287 const QStyleOptionViewItem &,
288 const QModelIndex &) const
289{
290 // do nothing
291}
292
293/*!
294 Whenever an event occurs, this function is called with the \a event
295 \a model \a option and the \a index that corresponds to the item being edited.
296
297 The base implementation returns false (indicating that it has not
298 handled the event).
299*/
300bool QAbstractItemDelegate::editorEvent(QEvent *,
301 QAbstractItemModel *,
302 const QStyleOptionViewItem &,
303 const QModelIndex &)
304{
305 // do nothing
306 return false;
307}
308
309/*!
310 \obsolete
311
312 Use QFontMetrics::elidedText() instead.
313
314 \oldcode
315 QFontMetrics fm = ...
316 QString str = QAbstractItemDelegate::elidedText(fm, width, mode, text);
317 \newcode
318 QFontMetrics fm = ...
319 QString str = fm.elidedText(text, mode, width);
320 \endcode
321*/
322
323QString QAbstractItemDelegate::elidedText(const QFontMetrics &fontMetrics, int width,
324 Qt::TextElideMode mode, const QString &text)
325{
326 return fontMetrics.elidedText(text, mode, width);
327}
328
329/*!
330 \since 4.3
331 Whenever a help event occurs, this function is called with the \a event
332 \a view \a option and the \a index that corresponds to the item where the
333 event occurs.
334
335 Returns true if the delegate can handle the event; otherwise returns false.
336 A return value of true indicates that the data obtained using the index had
337 the required role.
338
339 For QEvent::ToolTip and QEvent::WhatsThis events that were handled successfully,
340 the relevant popup may be shown depending on the user's system configuration.
341
342 \sa QHelpEvent
343*/
344// ### Qt 5: Make this a virtual non-slot function
345bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
346 QAbstractItemView *view,
347 const QStyleOptionViewItem &option,
348 const QModelIndex &index)
349{
350 Q_UNUSED(option);
351
352 if (!event || !view)
353 return false;
354 switch (event->type()) {
355#ifndef QT_NO_TOOLTIP
356 case QEvent::ToolTip: {
357 QHelpEvent *he = static_cast<QHelpEvent*>(event);
358 QVariant tooltip = index.data(Qt::ToolTipRole);
359 if (qVariantCanConvert<QString>(tooltip)) {
360 QToolTip::showText(he->globalPos(), tooltip.toString(), view);
361 return true;
362 }
363 break;}
364#endif
365#ifndef QT_NO_WHATSTHIS
366 case QEvent::QueryWhatsThis: {
367 if (index.data(Qt::WhatsThisRole).isValid())
368 return true;
369 break; }
370 case QEvent::WhatsThis: {
371 QHelpEvent *he = static_cast<QHelpEvent*>(event);
372 QVariant whatsthis = index.data(Qt::WhatsThisRole);
373 if (qVariantCanConvert<QString>(whatsthis)) {
374 QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view);
375 return true;
376 }
377 break ; }
378#endif
379 default:
380 break;
381 }
382 return false;
383}
384
385QT_END_NAMESPACE
386
387#endif // QT_NO_ITEMVIEWS
Note: See TracBrowser for help on using the repository browser.