Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||
2 | ** | - | ||||||||||||||||||
3 | ** Copyright (C) 2015 The Qt Company Ltd. | - | ||||||||||||||||||
4 | ** Contact: http://www.qt.io/licensing/ | - | ||||||||||||||||||
5 | ** | - | ||||||||||||||||||
6 | ** This file is part of the QtWidgets module of the Qt Toolkit. | - | ||||||||||||||||||
7 | ** | - | ||||||||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL21$ | - | ||||||||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||||||||
14 | ** and conditions see http://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
15 | ** information use the contact form at http://www.qt.io/contact-us. | - | ||||||||||||||||||
16 | ** | - | ||||||||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||||||||
19 | ** General Public License version 2.1 or version 3 as published by the Free | - | ||||||||||||||||||
20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and | - | ||||||||||||||||||
21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the | - | ||||||||||||||||||
22 | ** following information to ensure the GNU Lesser General Public License | - | ||||||||||||||||||
23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and | - | ||||||||||||||||||
24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - | ||||||||||||||||||
25 | ** | - | ||||||||||||||||||
26 | ** As a special exception, The Qt Company gives you certain additional | - | ||||||||||||||||||
27 | ** rights. These rights are described in The Qt Company LGPL Exception | - | ||||||||||||||||||
28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - | ||||||||||||||||||
29 | ** | - | ||||||||||||||||||
30 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
31 | ** | - | ||||||||||||||||||
32 | ****************************************************************************/ | - | ||||||||||||||||||
33 | - | |||||||||||||||||||
34 | #include "qabstractitemdelegate.h" | - | ||||||||||||||||||
35 | - | |||||||||||||||||||
36 | #ifndef QT_NO_ITEMVIEWS | - | ||||||||||||||||||
37 | #include <qabstractitemmodel.h> | - | ||||||||||||||||||
38 | #include <qabstractitemview.h> | - | ||||||||||||||||||
39 | #include <qfontmetrics.h> | - | ||||||||||||||||||
40 | #include <qwhatsthis.h> | - | ||||||||||||||||||
41 | #include <qtooltip.h> | - | ||||||||||||||||||
42 | #include <qevent.h> | - | ||||||||||||||||||
43 | #include <qstring.h> | - | ||||||||||||||||||
44 | #include <qdebug.h> | - | ||||||||||||||||||
45 | #include <qlineedit.h> | - | ||||||||||||||||||
46 | #include <qtextedit.h> | - | ||||||||||||||||||
47 | #include <qplaintextedit.h> | - | ||||||||||||||||||
48 | #include <qapplication.h> | - | ||||||||||||||||||
49 | #include <private/qtextengine_p.h> | - | ||||||||||||||||||
50 | #include <private/qabstractitemdelegate_p.h> | - | ||||||||||||||||||
51 | - | |||||||||||||||||||
52 | #include <qpa/qplatformintegration.h> | - | ||||||||||||||||||
53 | #include <qpa/qplatformdrag.h> | - | ||||||||||||||||||
54 | #include <private/qguiapplication_p.h> | - | ||||||||||||||||||
55 | #include <private/qdnd_p.h> | - | ||||||||||||||||||
56 | - | |||||||||||||||||||
57 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
58 | - | |||||||||||||||||||
59 | /*! | - | ||||||||||||||||||
60 | \class QAbstractItemDelegate | - | ||||||||||||||||||
61 | - | |||||||||||||||||||
62 | \brief The QAbstractItemDelegate class is used to display and edit | - | ||||||||||||||||||
63 | data items from a model. | - | ||||||||||||||||||
64 | - | |||||||||||||||||||
65 | \ingroup model-view | - | ||||||||||||||||||
66 | \inmodule QtWidgets | - | ||||||||||||||||||
67 | - | |||||||||||||||||||
68 | A QAbstractItemDelegate provides the interface and common functionality | - | ||||||||||||||||||
69 | for delegates in the model/view architecture. Delegates display | - | ||||||||||||||||||
70 | individual items in views, and handle the editing of model data. | - | ||||||||||||||||||
71 | - | |||||||||||||||||||
72 | The QAbstractItemDelegate class is one of the \l{Model/View Classes} | - | ||||||||||||||||||
73 | and is part of Qt's \l{Model/View Programming}{model/view framework}. | - | ||||||||||||||||||
74 | - | |||||||||||||||||||
75 | To render an item in a custom way, you must implement paint() and | - | ||||||||||||||||||
76 | sizeHint(). The QItemDelegate class provides default implementations for | - | ||||||||||||||||||
77 | these functions; if you do not need custom rendering, subclass that | - | ||||||||||||||||||
78 | class instead. | - | ||||||||||||||||||
79 | - | |||||||||||||||||||
80 | We give an example of drawing a progress bar in items; in our case | - | ||||||||||||||||||
81 | for a package management program. | - | ||||||||||||||||||
82 | - | |||||||||||||||||||
83 | \image widgetdelegate.png | - | ||||||||||||||||||
84 | - | |||||||||||||||||||
85 | We create the \c WidgetDelegate class, which inherits from | - | ||||||||||||||||||
86 | QStyledItemDelegate. We do the drawing in the paint() function: | - | ||||||||||||||||||
87 | - | |||||||||||||||||||
88 | \snippet widgetdelegate.cpp 0 | - | ||||||||||||||||||
89 | - | |||||||||||||||||||
90 | Notice that we use a QStyleOptionProgressBar and initialize its | - | ||||||||||||||||||
91 | members. We can then use the current QStyle to draw it. | - | ||||||||||||||||||
92 | - | |||||||||||||||||||
93 | To provide custom editing, there are two approaches that can be | - | ||||||||||||||||||
94 | used. The first approach is to create an editor widget and display | - | ||||||||||||||||||
95 | it directly on top of the item. To do this you must reimplement | - | ||||||||||||||||||
96 | createEditor() to provide an editor widget, setEditorData() to populate | - | ||||||||||||||||||
97 | the editor with the data from the model, and setModelData() so that the | - | ||||||||||||||||||
98 | delegate can update the model with data from the editor. | - | ||||||||||||||||||
99 | - | |||||||||||||||||||
100 | The second approach is to handle user events directly by reimplementing | - | ||||||||||||||||||
101 | editorEvent(). | - | ||||||||||||||||||
102 | - | |||||||||||||||||||
103 | \sa {model-view-programming}{Model/View Programming}, QItemDelegate, | - | ||||||||||||||||||
104 | {Pixelator Example}, QStyledItemDelegate, QStyle | - | ||||||||||||||||||
105 | */ | - | ||||||||||||||||||
106 | - | |||||||||||||||||||
107 | /*! | - | ||||||||||||||||||
108 | \enum QAbstractItemDelegate::EndEditHint | - | ||||||||||||||||||
109 | - | |||||||||||||||||||
110 | This enum describes the different hints that the delegate can give to the | - | ||||||||||||||||||
111 | model and view components to make editing data in a model a comfortable | - | ||||||||||||||||||
112 | experience for the user. | - | ||||||||||||||||||
113 | - | |||||||||||||||||||
114 | \value NoHint There is no recommended action to be performed. | - | ||||||||||||||||||
115 | - | |||||||||||||||||||
116 | These hints let the delegate influence the behavior of the view: | - | ||||||||||||||||||
117 | - | |||||||||||||||||||
118 | \value EditNextItem The view should use the delegate to open an | - | ||||||||||||||||||
119 | editor on the next item in the view. | - | ||||||||||||||||||
120 | \value EditPreviousItem The view should use the delegate to open an | - | ||||||||||||||||||
121 | editor on the previous item in the view. | - | ||||||||||||||||||
122 | - | |||||||||||||||||||
123 | Note that custom views may interpret the concepts of next and previous | - | ||||||||||||||||||
124 | differently. | - | ||||||||||||||||||
125 | - | |||||||||||||||||||
126 | The following hints are most useful when models are used that cache | - | ||||||||||||||||||
127 | data, such as those that manipulate data locally in order to increase | - | ||||||||||||||||||
128 | performance or conserve network bandwidth. | - | ||||||||||||||||||
129 | - | |||||||||||||||||||
130 | \value SubmitModelCache If the model caches data, it should write out | - | ||||||||||||||||||
131 | cached data to the underlying data store. | - | ||||||||||||||||||
132 | \value RevertModelCache If the model caches data, it should discard | - | ||||||||||||||||||
133 | cached data and replace it with data from the | - | ||||||||||||||||||
134 | underlying data store. | - | ||||||||||||||||||
135 | - | |||||||||||||||||||
136 | Although models and views should respond to these hints in appropriate | - | ||||||||||||||||||
137 | ways, custom components may ignore any or all of them if they are not | - | ||||||||||||||||||
138 | relevant. | - | ||||||||||||||||||
139 | */ | - | ||||||||||||||||||
140 | - | |||||||||||||||||||
141 | /*! | - | ||||||||||||||||||
142 | \fn void QAbstractItemDelegate::commitData(QWidget *editor) | - | ||||||||||||||||||
143 | - | |||||||||||||||||||
144 | This signal must be emitted when the \a editor widget has completed | - | ||||||||||||||||||
145 | editing the data, and wants to write it back into the model. | - | ||||||||||||||||||
146 | */ | - | ||||||||||||||||||
147 | - | |||||||||||||||||||
148 | /*! | - | ||||||||||||||||||
149 | \fn void QAbstractItemDelegate::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) | - | ||||||||||||||||||
150 | - | |||||||||||||||||||
151 | This signal is emitted when the user has finished editing an item using | - | ||||||||||||||||||
152 | the specified \a editor. | - | ||||||||||||||||||
153 | - | |||||||||||||||||||
154 | The \a hint provides a way for the delegate to influence how the model and | - | ||||||||||||||||||
155 | view behave after editing is completed. It indicates to these components | - | ||||||||||||||||||
156 | what action should be performed next to provide a comfortable editing | - | ||||||||||||||||||
157 | experience for the user. For example, if \c EditNextItem is specified, | - | ||||||||||||||||||
158 | the view should use a delegate to open an editor on the next item in the | - | ||||||||||||||||||
159 | model. | - | ||||||||||||||||||
160 | - | |||||||||||||||||||
161 | \sa EndEditHint | - | ||||||||||||||||||
162 | */ | - | ||||||||||||||||||
163 | - | |||||||||||||||||||
164 | /*! | - | ||||||||||||||||||
165 | \fn void QAbstractItemDelegate::sizeHintChanged(const QModelIndex &index) | - | ||||||||||||||||||
166 | \since 4.4 | - | ||||||||||||||||||
167 | - | |||||||||||||||||||
168 | This signal must be emitted when the sizeHint() of \a index changed. | - | ||||||||||||||||||
169 | - | |||||||||||||||||||
170 | Views automatically connect to this signal and relayout items as necessary. | - | ||||||||||||||||||
171 | */ | - | ||||||||||||||||||
172 | - | |||||||||||||||||||
173 | - | |||||||||||||||||||
174 | /*! | - | ||||||||||||||||||
175 | Creates a new abstract item delegate with the given \a parent. | - | ||||||||||||||||||
176 | */ | - | ||||||||||||||||||
177 | QAbstractItemDelegate::QAbstractItemDelegate(QObject *parent) | - | ||||||||||||||||||
178 | : QObject(*new QAbstractItemDelegatePrivate, parent) | - | ||||||||||||||||||
179 | { | - | ||||||||||||||||||
180 | - | |||||||||||||||||||
181 | } never executed: end of block | 0 | ||||||||||||||||||
182 | - | |||||||||||||||||||
183 | /*! | - | ||||||||||||||||||
184 | \internal | - | ||||||||||||||||||
185 | - | |||||||||||||||||||
186 | Creates a new abstract item delegate with the given \a parent. | - | ||||||||||||||||||
187 | */ | - | ||||||||||||||||||
188 | QAbstractItemDelegate::QAbstractItemDelegate(QObjectPrivate &dd, QObject *parent) | - | ||||||||||||||||||
189 | : QObject(dd, parent) | - | ||||||||||||||||||
190 | { | - | ||||||||||||||||||
191 | - | |||||||||||||||||||
192 | } never executed: end of block | 0 | ||||||||||||||||||
193 | - | |||||||||||||||||||
194 | /*! | - | ||||||||||||||||||
195 | Destroys the abstract item delegate. | - | ||||||||||||||||||
196 | */ | - | ||||||||||||||||||
197 | QAbstractItemDelegate::~QAbstractItemDelegate() | - | ||||||||||||||||||
198 | { | - | ||||||||||||||||||
199 | - | |||||||||||||||||||
200 | } | - | ||||||||||||||||||
201 | - | |||||||||||||||||||
202 | /*! | - | ||||||||||||||||||
203 | \fn void QAbstractItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const = 0; | - | ||||||||||||||||||
204 | - | |||||||||||||||||||
205 | This pure abstract function must be reimplemented if you want to | - | ||||||||||||||||||
206 | provide custom rendering. Use the \a painter and style \a option to | - | ||||||||||||||||||
207 | render the item specified by the item \a index. | - | ||||||||||||||||||
208 | - | |||||||||||||||||||
209 | If you reimplement this you must also reimplement sizeHint(). | - | ||||||||||||||||||
210 | */ | - | ||||||||||||||||||
211 | - | |||||||||||||||||||
212 | /*! | - | ||||||||||||||||||
213 | \fn QSize QAbstractItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const = 0 | - | ||||||||||||||||||
214 | - | |||||||||||||||||||
215 | This pure abstract function must be reimplemented if you want to | - | ||||||||||||||||||
216 | provide custom rendering. The options are specified by \a option | - | ||||||||||||||||||
217 | and the model item by \a index. | - | ||||||||||||||||||
218 | - | |||||||||||||||||||
219 | If you reimplement this you must also reimplement paint(). | - | ||||||||||||||||||
220 | */ | - | ||||||||||||||||||
221 | - | |||||||||||||||||||
222 | /*! | - | ||||||||||||||||||
223 | Returns the editor to be used for editing the data item with the | - | ||||||||||||||||||
224 | given \a index. Note that the index contains information about the | - | ||||||||||||||||||
225 | model being used. The editor's parent widget is specified by \a parent, | - | ||||||||||||||||||
226 | and the item options by \a option. | - | ||||||||||||||||||
227 | - | |||||||||||||||||||
228 | The base implementation returns 0. If you want custom editing you | - | ||||||||||||||||||
229 | will need to reimplement this function. | - | ||||||||||||||||||
230 | - | |||||||||||||||||||
231 | The returned editor widget should have Qt::StrongFocus; | - | ||||||||||||||||||
232 | otherwise, \l{QMouseEvent}s received by the widget will propagate | - | ||||||||||||||||||
233 | to the view. The view's background will shine through unless the | - | ||||||||||||||||||
234 | editor paints its own background (e.g., with | - | ||||||||||||||||||
235 | \l{QWidget::}{setAutoFillBackground()}). | - | ||||||||||||||||||
236 | - | |||||||||||||||||||
237 | \sa destroyEditor(), setModelData(), setEditorData() | - | ||||||||||||||||||
238 | */ | - | ||||||||||||||||||
239 | QWidget *QAbstractItemDelegate::createEditor(QWidget *, | - | ||||||||||||||||||
240 | const QStyleOptionViewItem &, | - | ||||||||||||||||||
241 | const QModelIndex &) const | - | ||||||||||||||||||
242 | { | - | ||||||||||||||||||
243 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
244 | } | - | ||||||||||||||||||
245 | - | |||||||||||||||||||
246 | - | |||||||||||||||||||
247 | /*! | - | ||||||||||||||||||
248 | Called when the \a editor is no longer needed for editing the data item | - | ||||||||||||||||||
249 | with the given \a index and should be destroyed. The default behavior is a | - | ||||||||||||||||||
250 | call to deleteLater on the editor. It is possible e.g. to avoid this delete by | - | ||||||||||||||||||
251 | reimplementing this function. | - | ||||||||||||||||||
252 | - | |||||||||||||||||||
253 | \since 5.0 | - | ||||||||||||||||||
254 | \sa createEditor() | - | ||||||||||||||||||
255 | */ | - | ||||||||||||||||||
256 | void QAbstractItemDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const | - | ||||||||||||||||||
257 | { | - | ||||||||||||||||||
258 | Q_UNUSED(index); | - | ||||||||||||||||||
259 | editor->deleteLater(); | - | ||||||||||||||||||
260 | } never executed: end of block | 0 | ||||||||||||||||||
261 | - | |||||||||||||||||||
262 | /*! | - | ||||||||||||||||||
263 | Sets the contents of the given \a editor to the data for the item | - | ||||||||||||||||||
264 | at the given \a index. Note that the index contains information | - | ||||||||||||||||||
265 | about the model being used. | - | ||||||||||||||||||
266 | - | |||||||||||||||||||
267 | The base implementation does nothing. If you want custom editing | - | ||||||||||||||||||
268 | you will need to reimplement this function. | - | ||||||||||||||||||
269 | - | |||||||||||||||||||
270 | \sa setModelData() | - | ||||||||||||||||||
271 | */ | - | ||||||||||||||||||
272 | void QAbstractItemDelegate::setEditorData(QWidget *, | - | ||||||||||||||||||
273 | const QModelIndex &) const | - | ||||||||||||||||||
274 | { | - | ||||||||||||||||||
275 | // do nothing | - | ||||||||||||||||||
276 | } | - | ||||||||||||||||||
277 | - | |||||||||||||||||||
278 | /*! | - | ||||||||||||||||||
279 | Sets the data for the item at the given \a index in the \a model | - | ||||||||||||||||||
280 | to the contents of the given \a editor. | - | ||||||||||||||||||
281 | - | |||||||||||||||||||
282 | The base implementation does nothing. If you want custom editing | - | ||||||||||||||||||
283 | you will need to reimplement this function. | - | ||||||||||||||||||
284 | - | |||||||||||||||||||
285 | \sa setEditorData() | - | ||||||||||||||||||
286 | */ | - | ||||||||||||||||||
287 | void QAbstractItemDelegate::setModelData(QWidget *, | - | ||||||||||||||||||
288 | QAbstractItemModel *, | - | ||||||||||||||||||
289 | const QModelIndex &) const | - | ||||||||||||||||||
290 | { | - | ||||||||||||||||||
291 | // do nothing | - | ||||||||||||||||||
292 | } | - | ||||||||||||||||||
293 | - | |||||||||||||||||||
294 | /*! | - | ||||||||||||||||||
295 | Updates the geometry of the \a editor for the item with the given | - | ||||||||||||||||||
296 | \a index, according to the rectangle specified in the \a option. | - | ||||||||||||||||||
297 | If the item has an internal layout, the editor will be laid out | - | ||||||||||||||||||
298 | accordingly. Note that the index contains information about the | - | ||||||||||||||||||
299 | model being used. | - | ||||||||||||||||||
300 | - | |||||||||||||||||||
301 | The base implementation does nothing. If you want custom editing | - | ||||||||||||||||||
302 | you must reimplement this function. | - | ||||||||||||||||||
303 | */ | - | ||||||||||||||||||
304 | void QAbstractItemDelegate::updateEditorGeometry(QWidget *, | - | ||||||||||||||||||
305 | const QStyleOptionViewItem &, | - | ||||||||||||||||||
306 | const QModelIndex &) const | - | ||||||||||||||||||
307 | { | - | ||||||||||||||||||
308 | // do nothing | - | ||||||||||||||||||
309 | } | - | ||||||||||||||||||
310 | - | |||||||||||||||||||
311 | /*! | - | ||||||||||||||||||
312 | When editing of an item starts, this function is called with the | - | ||||||||||||||||||
313 | \a event that triggered the editing, the \a model, the \a index of | - | ||||||||||||||||||
314 | the item, and the \a option used for rendering the item. | - | ||||||||||||||||||
315 | - | |||||||||||||||||||
316 | Mouse events are sent to editorEvent() even if they don't start | - | ||||||||||||||||||
317 | editing of the item. This can, for instance, be useful if you wish | - | ||||||||||||||||||
318 | to open a context menu when the right mouse button is pressed on | - | ||||||||||||||||||
319 | an item. | - | ||||||||||||||||||
320 | - | |||||||||||||||||||
321 | The base implementation returns \c false (indicating that it has not | - | ||||||||||||||||||
322 | handled the event). | - | ||||||||||||||||||
323 | */ | - | ||||||||||||||||||
324 | bool QAbstractItemDelegate::editorEvent(QEvent *, | - | ||||||||||||||||||
325 | QAbstractItemModel *, | - | ||||||||||||||||||
326 | const QStyleOptionViewItem &, | - | ||||||||||||||||||
327 | const QModelIndex &) | - | ||||||||||||||||||
328 | { | - | ||||||||||||||||||
329 | // do nothing | - | ||||||||||||||||||
330 | return false; never executed: return false; | 0 | ||||||||||||||||||
331 | } | - | ||||||||||||||||||
332 | - | |||||||||||||||||||
333 | /*! | - | ||||||||||||||||||
334 | \obsolete | - | ||||||||||||||||||
335 | - | |||||||||||||||||||
336 | Use QFontMetrics::elidedText() instead. | - | ||||||||||||||||||
337 | - | |||||||||||||||||||
338 | \oldcode | - | ||||||||||||||||||
339 | QFontMetrics fm = ... | - | ||||||||||||||||||
340 | QString str = QAbstractItemDelegate::elidedText(fm, width, mode, text); | - | ||||||||||||||||||
341 | \newcode | - | ||||||||||||||||||
342 | QFontMetrics fm = ... | - | ||||||||||||||||||
343 | QString str = fm.elidedText(text, mode, width); | - | ||||||||||||||||||
344 | \endcode | - | ||||||||||||||||||
345 | */ | - | ||||||||||||||||||
346 | - | |||||||||||||||||||
347 | QString QAbstractItemDelegate::elidedText(const QFontMetrics &fontMetrics, int width, | - | ||||||||||||||||||
348 | Qt::TextElideMode mode, const QString &text) | - | ||||||||||||||||||
349 | { | - | ||||||||||||||||||
350 | return fontMetrics.elidedText(text, mode, width); never executed: return fontMetrics.elidedText(text, mode, width); | 0 | ||||||||||||||||||
351 | } | - | ||||||||||||||||||
352 | - | |||||||||||||||||||
353 | /*! | - | ||||||||||||||||||
354 | \since 4.3 | - | ||||||||||||||||||
355 | Whenever a help event occurs, this function is called with the \a event | - | ||||||||||||||||||
356 | \a view \a option and the \a index that corresponds to the item where the | - | ||||||||||||||||||
357 | event occurs. | - | ||||||||||||||||||
358 | - | |||||||||||||||||||
359 | Returns \c true if the delegate can handle the event; otherwise returns \c false. | - | ||||||||||||||||||
360 | A return value of true indicates that the data obtained using the index had | - | ||||||||||||||||||
361 | the required role. | - | ||||||||||||||||||
362 | - | |||||||||||||||||||
363 | For QEvent::ToolTip and QEvent::WhatsThis events that were handled successfully, | - | ||||||||||||||||||
364 | the relevant popup may be shown depending on the user's system configuration. | - | ||||||||||||||||||
365 | - | |||||||||||||||||||
366 | \sa QHelpEvent | - | ||||||||||||||||||
367 | */ | - | ||||||||||||||||||
368 | bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, | - | ||||||||||||||||||
369 | QAbstractItemView *view, | - | ||||||||||||||||||
370 | const QStyleOptionViewItem &option, | - | ||||||||||||||||||
371 | const QModelIndex &index) | - | ||||||||||||||||||
372 | { | - | ||||||||||||||||||
373 | Q_D(QAbstractItemDelegate); | - | ||||||||||||||||||
374 | Q_UNUSED(option); | - | ||||||||||||||||||
375 | - | |||||||||||||||||||
376 | if (!event || !view)
| 0 | ||||||||||||||||||
377 | return false; never executed: return false; | 0 | ||||||||||||||||||
378 | switch (event->type()) { | - | ||||||||||||||||||
379 | #ifndef QT_NO_TOOLTIP | - | ||||||||||||||||||
380 | case QEvent::ToolTip: { never executed: case QEvent::ToolTip: | 0 | ||||||||||||||||||
381 | QHelpEvent *he = static_cast<QHelpEvent*>(event); | - | ||||||||||||||||||
382 | const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
| 0 | ||||||||||||||||||
383 | const QString tooltip = d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision); | - | ||||||||||||||||||
384 | if (!tooltip.isEmpty()) {
| 0 | ||||||||||||||||||
385 | QToolTip::showText(he->globalPos(), tooltip, view); | - | ||||||||||||||||||
386 | return true; never executed: return true; | 0 | ||||||||||||||||||
387 | } | - | ||||||||||||||||||
388 | break;} never executed: break; | 0 | ||||||||||||||||||
389 | #endif | - | ||||||||||||||||||
390 | #ifndef QT_NO_WHATSTHIS | - | ||||||||||||||||||
391 | case QEvent::QueryWhatsThis: { never executed: case QEvent::QueryWhatsThis: | 0 | ||||||||||||||||||
392 | if (index.data(Qt::WhatsThisRole).isValid())
| 0 | ||||||||||||||||||
393 | return true; never executed: return true; | 0 | ||||||||||||||||||
394 | break; } never executed: break; | 0 | ||||||||||||||||||
395 | case QEvent::WhatsThis: { never executed: case QEvent::WhatsThis: | 0 | ||||||||||||||||||
396 | QHelpEvent *he = static_cast<QHelpEvent*>(event); | - | ||||||||||||||||||
397 | const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
| 0 | ||||||||||||||||||
398 | const QString whatsthis = d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision); | - | ||||||||||||||||||
399 | if (!whatsthis.isEmpty()) {
| 0 | ||||||||||||||||||
400 | QWhatsThis::showText(he->globalPos(), whatsthis, view); | - | ||||||||||||||||||
401 | return true; never executed: return true; | 0 | ||||||||||||||||||
402 | } | - | ||||||||||||||||||
403 | break ; } never executed: break ; | 0 | ||||||||||||||||||
404 | #endif | - | ||||||||||||||||||
405 | default: never executed: default: | 0 | ||||||||||||||||||
406 | break; never executed: break; | 0 | ||||||||||||||||||
407 | } | - | ||||||||||||||||||
408 | return false; never executed: return false; | 0 | ||||||||||||||||||
409 | } | - | ||||||||||||||||||
410 | - | |||||||||||||||||||
411 | /*! | - | ||||||||||||||||||
412 | \internal | - | ||||||||||||||||||
413 | - | |||||||||||||||||||
414 | This virtual method is reserved and will be used in Qt 5.1. | - | ||||||||||||||||||
415 | */ | - | ||||||||||||||||||
416 | QVector<int> QAbstractItemDelegate::paintingRoles() const | - | ||||||||||||||||||
417 | { | - | ||||||||||||||||||
418 | return QVector<int>(); never executed: return QVector<int>(); | 0 | ||||||||||||||||||
419 | } | - | ||||||||||||||||||
420 | - | |||||||||||||||||||
421 | QAbstractItemDelegatePrivate::QAbstractItemDelegatePrivate() | - | ||||||||||||||||||
422 | : QObjectPrivate() | - | ||||||||||||||||||
423 | { | - | ||||||||||||||||||
424 | } never executed: end of block | 0 | ||||||||||||||||||
425 | - | |||||||||||||||||||
426 | static bool editorHandlesKeyEvent(QWidget *editor, const QKeyEvent *event) | - | ||||||||||||||||||
427 | { | - | ||||||||||||||||||
428 | #ifndef QT_NO_TEXTEDIT | - | ||||||||||||||||||
429 | // do not filter enter / return / tab / backtab for QTextEdit or QPlainTextEdit | - | ||||||||||||||||||
430 | if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor)) {
| 0 | ||||||||||||||||||
431 | switch (event->key()) { | - | ||||||||||||||||||
432 | case Qt::Key_Tab: never executed: case Qt::Key_Tab: | 0 | ||||||||||||||||||
433 | case Qt::Key_Backtab: never executed: case Qt::Key_Backtab: | 0 | ||||||||||||||||||
434 | case Qt::Key_Enter: never executed: case Qt::Key_Enter: | 0 | ||||||||||||||||||
435 | case Qt::Key_Return: never executed: case Qt::Key_Return: | 0 | ||||||||||||||||||
436 | return true; never executed: return true; | 0 | ||||||||||||||||||
437 | - | |||||||||||||||||||
438 | default: never executed: default: | 0 | ||||||||||||||||||
439 | break; never executed: break; | 0 | ||||||||||||||||||
440 | } | - | ||||||||||||||||||
441 | } | - | ||||||||||||||||||
442 | #endif // QT_NO_TEXTEDIT | - | ||||||||||||||||||
443 | - | |||||||||||||||||||
444 | Q_UNUSED(editor); | - | ||||||||||||||||||
445 | Q_UNUSED(event); | - | ||||||||||||||||||
446 | return false; never executed: return false; | 0 | ||||||||||||||||||
447 | } | - | ||||||||||||||||||
448 | - | |||||||||||||||||||
449 | bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *event) | - | ||||||||||||||||||
450 | { | - | ||||||||||||||||||
451 | Q_Q(QAbstractItemDelegate); | - | ||||||||||||||||||
452 | - | |||||||||||||||||||
453 | QWidget *editor = qobject_cast<QWidget*>(object); | - | ||||||||||||||||||
454 | if (!editor)
| 0 | ||||||||||||||||||
455 | return false; never executed: return false; | 0 | ||||||||||||||||||
456 | if (event->type() == QEvent::KeyPress) {
| 0 | ||||||||||||||||||
457 | QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); | - | ||||||||||||||||||
458 | if (editorHandlesKeyEvent(editor, keyEvent))
| 0 | ||||||||||||||||||
459 | return false; never executed: return false; | 0 | ||||||||||||||||||
460 | - | |||||||||||||||||||
461 | if (keyEvent->matches(QKeySequence::Cancel)) {
| 0 | ||||||||||||||||||
462 | // don't commit data | - | ||||||||||||||||||
463 | emit q->closeEditor(editor, QAbstractItemDelegate::RevertModelCache); | - | ||||||||||||||||||
464 | return true; never executed: return true; | 0 | ||||||||||||||||||
465 | } | - | ||||||||||||||||||
466 | - | |||||||||||||||||||
467 | switch (keyEvent->key()) { | - | ||||||||||||||||||
468 | case Qt::Key_Tab: never executed: case Qt::Key_Tab: | 0 | ||||||||||||||||||
469 | if (tryFixup(editor)) {
| 0 | ||||||||||||||||||
470 | emit q->commitData(editor); | - | ||||||||||||||||||
471 | emit q->closeEditor(editor, QAbstractItemDelegate::EditNextItem); | - | ||||||||||||||||||
472 | } never executed: end of block | 0 | ||||||||||||||||||
473 | return true; never executed: return true; | 0 | ||||||||||||||||||
474 | case Qt::Key_Backtab: never executed: case Qt::Key_Backtab: | 0 | ||||||||||||||||||
475 | if (tryFixup(editor)) {
| 0 | ||||||||||||||||||
476 | emit q->commitData(editor); | - | ||||||||||||||||||
477 | emit q->closeEditor(editor, QAbstractItemDelegate::EditPreviousItem); | - | ||||||||||||||||||
478 | } never executed: end of block | 0 | ||||||||||||||||||
479 | return true; never executed: return true; | 0 | ||||||||||||||||||
480 | case Qt::Key_Enter: never executed: case Qt::Key_Enter: | 0 | ||||||||||||||||||
481 | case Qt::Key_Return: never executed: case Qt::Key_Return: | 0 | ||||||||||||||||||
482 | // We want the editor to be able to process the key press | - | ||||||||||||||||||
483 | // before committing the data (e.g. so it can do | - | ||||||||||||||||||
484 | // validation/fixup of the input). | - | ||||||||||||||||||
485 | if (!tryFixup(editor))
| 0 | ||||||||||||||||||
486 | return true; never executed: return true; | 0 | ||||||||||||||||||
487 | - | |||||||||||||||||||
488 | QMetaObject::invokeMethod(q, "_q_commitDataAndCloseEditor", | - | ||||||||||||||||||
489 | Qt::QueuedConnection, Q_ARG(QWidget*, editor)); | - | ||||||||||||||||||
490 | return false; never executed: return false; | 0 | ||||||||||||||||||
491 | default: never executed: default: | 0 | ||||||||||||||||||
492 | return false; never executed: return false; | 0 | ||||||||||||||||||
493 | } | - | ||||||||||||||||||
494 | } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
| 0 | ||||||||||||||||||
495 | //the Hide event will take care of he editors that are in fact complete dialogs | - | ||||||||||||||||||
496 | if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
| 0 | ||||||||||||||||||
497 | QWidget *w = QApplication::focusWidget(); | - | ||||||||||||||||||
498 | while (w) { // don't worry about focus changes internally in the editor
| 0 | ||||||||||||||||||
499 | if (w == editor)
| 0 | ||||||||||||||||||
500 | return false; never executed: return false; | 0 | ||||||||||||||||||
501 | w = w->parentWidget(); | - | ||||||||||||||||||
502 | } never executed: end of block | 0 | ||||||||||||||||||
503 | #ifndef QT_NO_DRAGANDDROP | - | ||||||||||||||||||
504 | // The window may lose focus during an drag operation. | - | ||||||||||||||||||
505 | // i.e when dragging involves the taskbar on Windows. | - | ||||||||||||||||||
506 | QPlatformDrag *platformDrag = QGuiApplicationPrivate::instance()->platformIntegration()->drag(); | - | ||||||||||||||||||
507 | if (platformDrag && platformDrag->currentDrag()) {
| 0 | ||||||||||||||||||
508 | return false; never executed: return false; | 0 | ||||||||||||||||||
509 | } | - | ||||||||||||||||||
510 | #endif | - | ||||||||||||||||||
511 | if (tryFixup(editor))
| 0 | ||||||||||||||||||
512 | emit q->commitData(editor); never executed: q->commitData(editor); | 0 | ||||||||||||||||||
513 | - | |||||||||||||||||||
514 | emit q->closeEditor(editor, QAbstractItemDelegate::NoHint); | - | ||||||||||||||||||
515 | } never executed: end of block | 0 | ||||||||||||||||||
516 | } else if (event->type() == QEvent::ShortcutOverride) { never executed: end of block
| 0 | ||||||||||||||||||
517 | if (static_cast<QKeyEvent*>(event)->matches(QKeySequence::Cancel)) {
| 0 | ||||||||||||||||||
518 | event->accept(); | - | ||||||||||||||||||
519 | return true; never executed: return true; | 0 | ||||||||||||||||||
520 | } | - | ||||||||||||||||||
521 | } never executed: end of block | 0 | ||||||||||||||||||
522 | return false; never executed: return false; | 0 | ||||||||||||||||||
523 | } | - | ||||||||||||||||||
524 | - | |||||||||||||||||||
525 | bool QAbstractItemDelegatePrivate::tryFixup(QWidget *editor) | - | ||||||||||||||||||
526 | { | - | ||||||||||||||||||
527 | #ifndef QT_NO_LINEEDIT | - | ||||||||||||||||||
528 | if (QLineEdit *e = qobject_cast<QLineEdit*>(editor)) {
| 0 | ||||||||||||||||||
529 | if (!e->hasAcceptableInput()) {
| 0 | ||||||||||||||||||
530 | if (const QValidator *validator = e->validator()) {
| 0 | ||||||||||||||||||
531 | QString text = e->text(); | - | ||||||||||||||||||
532 | validator->fixup(text); | - | ||||||||||||||||||
533 | e->setText(text); | - | ||||||||||||||||||
534 | } never executed: end of block | 0 | ||||||||||||||||||
535 | return e->hasAcceptableInput(); never executed: return e->hasAcceptableInput(); | 0 | ||||||||||||||||||
536 | } | - | ||||||||||||||||||
537 | } never executed: end of block | 0 | ||||||||||||||||||
538 | #endif // QT_NO_LINEEDIT | - | ||||||||||||||||||
539 | - | |||||||||||||||||||
540 | return true; never executed: return true; | 0 | ||||||||||||||||||
541 | } | - | ||||||||||||||||||
542 | - | |||||||||||||||||||
543 | QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision) const | - | ||||||||||||||||||
544 | { | - | ||||||||||||||||||
545 | const QLocale::FormatType formatType = (role == Qt::DisplayRole) ? QLocale::ShortFormat : QLocale::LongFormat;
| 0 | ||||||||||||||||||
546 | QString text; | - | ||||||||||||||||||
547 | switch (value.userType()) { | - | ||||||||||||||||||
548 | case QMetaType::Float: never executed: case QMetaType::Float: | 0 | ||||||||||||||||||
549 | text = locale.toString(value.toFloat()); | - | ||||||||||||||||||
550 | break; never executed: break; | 0 | ||||||||||||||||||
551 | case QVariant::Double: never executed: case QVariant::Double: | 0 | ||||||||||||||||||
552 | text = locale.toString(value.toDouble(), 'g', precision); | - | ||||||||||||||||||
553 | break; never executed: break; | 0 | ||||||||||||||||||
554 | case QVariant::Int: never executed: case QVariant::Int: | 0 | ||||||||||||||||||
555 | case QVariant::LongLong: never executed: case QVariant::LongLong: | 0 | ||||||||||||||||||
556 | text = locale.toString(value.toLongLong()); | - | ||||||||||||||||||
557 | break; never executed: break; | 0 | ||||||||||||||||||
558 | case QVariant::UInt: never executed: case QVariant::UInt: | 0 | ||||||||||||||||||
559 | case QVariant::ULongLong: never executed: case QVariant::ULongLong: | 0 | ||||||||||||||||||
560 | text = locale.toString(value.toULongLong()); | - | ||||||||||||||||||
561 | break; never executed: break; | 0 | ||||||||||||||||||
562 | case QVariant::Date: never executed: case QVariant::Date: | 0 | ||||||||||||||||||
563 | text = locale.toString(value.toDate(), formatType); | - | ||||||||||||||||||
564 | break; never executed: break; | 0 | ||||||||||||||||||
565 | case QVariant::Time: never executed: case QVariant::Time: | 0 | ||||||||||||||||||
566 | text = locale.toString(value.toTime(), formatType); | - | ||||||||||||||||||
567 | break; never executed: break; | 0 | ||||||||||||||||||
568 | case QVariant::DateTime: { never executed: case QVariant::DateTime: | 0 | ||||||||||||||||||
569 | const QDateTime dateTime = value.toDateTime(); | - | ||||||||||||||||||
570 | text = locale.toString(dateTime.date(), formatType) | - | ||||||||||||||||||
571 | + QLatin1Char(' ') | - | ||||||||||||||||||
572 | + locale.toString(dateTime.time(), formatType); | - | ||||||||||||||||||
573 | break; } never executed: break; | 0 | ||||||||||||||||||
574 | default: never executed: default: | 0 | ||||||||||||||||||
575 | text = value.toString(); | - | ||||||||||||||||||
576 | if (role == Qt::DisplayRole)
| 0 | ||||||||||||||||||
577 | text.replace(QLatin1Char('\n'), QChar::LineSeparator); never executed: text.replace(QLatin1Char('\n'), QChar::LineSeparator); | 0 | ||||||||||||||||||
578 | break; never executed: break; | 0 | ||||||||||||||||||
579 | } | - | ||||||||||||||||||
580 | return text; never executed: return text; | 0 | ||||||||||||||||||
581 | } | - | ||||||||||||||||||
582 | - | |||||||||||||||||||
583 | void QAbstractItemDelegatePrivate::_q_commitDataAndCloseEditor(QWidget *editor) | - | ||||||||||||||||||
584 | { | - | ||||||||||||||||||
585 | Q_Q(QAbstractItemDelegate); | - | ||||||||||||||||||
586 | emit q->commitData(editor); | - | ||||||||||||||||||
587 | emit q->closeEditor(editor, QAbstractItemDelegate::SubmitModelCache); | - | ||||||||||||||||||
588 | } never executed: end of block | 0 | ||||||||||||||||||
589 | - | |||||||||||||||||||
590 | QT_END_NAMESPACE | - | ||||||||||||||||||
591 | - | |||||||||||||||||||
592 | #include "moc_qabstractitemdelegate.cpp" | - | ||||||||||||||||||
593 | - | |||||||||||||||||||
594 | #endif // QT_NO_ITEMVIEWS | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |