Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qabstractitemdelegate.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
7#include <qabstractitemview.h>
8#include <qfontmetrics.h>
9#if QT_CONFIG(whatsthis)
10#include <qwhatsthis.h>
11#endif
12#if QT_CONFIG(tooltip)
13#include <qtooltip.h>
14#endif
15#include <qevent.h>
16#include <qstring.h>
17#include <qdebug.h>
18#if QT_CONFIG(lineedit)
19#include <qlineedit.h>
20#endif
21#if QT_CONFIG(textedit)
22#include <qtextedit.h>
23#include <qplaintextedit.h>
24#endif
25#include <qapplication.h>
26#include <qvalidator.h>
27#include <qjsonvalue.h>
28#include <private/qtextengine_p.h>
29#include <private/qabstractitemdelegate_p.h>
30
31#include <qpa/qplatformintegration.h>
32#if QT_CONFIG(draganddrop)
33#include <qpa/qplatformdrag.h>
34#include <private/qdnd_p.h>
35#endif
36#include <private/qguiapplication_p.h>
37
39
163
174
182
221 const QStyleOptionViewItem &,
222 const QModelIndex &) const
223{
224 return nullptr;
225}
226
227
238{
240 editor->deleteLater();
241}
242
254 const QModelIndex &) const
255{
256 // do nothing
257}
258
270 const QModelIndex &) const
271{
272 // do nothing
273}
274
286 const QStyleOptionViewItem &,
287 const QModelIndex &) const
288{
289 // do nothing
290}
291
307 const QStyleOptionViewItem &,
308 const QModelIndex &)
309{
310 // do nothing
311 return false;
312}
313
331 const QStyleOptionViewItem &option,
332 const QModelIndex &index)
333{
334 if (!event || !view)
335 return false;
338 switch (event->type()) {
339#if QT_CONFIG(tooltip)
340 case QEvent::ToolTip: {
342 QHelpEvent *he = static_cast<QHelpEvent*>(event);
343 const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
344 const QString tooltip = index.isValid() ?
345 d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
346 QString();
347 QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
348 event->setAccepted(!tooltip.isEmpty());
349 break;
350 }
351#endif
352#if QT_CONFIG(whatsthis)
354 event->setAccepted(index.data(Qt::WhatsThisRole).isValid());
355 break;
356 case QEvent::WhatsThis: {
358 QHelpEvent *he = static_cast<QHelpEvent*>(event);
359 const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
360 const QString whatsthis = index.isValid() ?
361 d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision) :
362 QString();
363 QWhatsThis::showText(he->globalPos(), whatsthis, view);
364 event->setAccepted(!whatsthis.isEmpty());
365 break;
366 }
367#endif
368 case QEvent::None:
369 default:
370 break;
371 }
372 return event->isAccepted();
373}
374
381{
382 return QList<int>();
383}
384
389
390static bool editorHandlesKeyEvent(QWidget *editor, const QKeyEvent *event)
391{
392#if QT_CONFIG(textedit)
393 // do not filter enter / return / tab / backtab for QTextEdit or QPlainTextEdit
394 if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor)) {
395 switch (event->key()) {
396 case Qt::Key_Tab:
397 case Qt::Key_Backtab:
398 case Qt::Key_Enter:
399 case Qt::Key_Return:
400 return true;
401
402 default:
403 break;
404 }
405 }
406#endif // QT_CONFIG(textedit)
407
408 Q_UNUSED(editor);
410 return false;
411}
412
414{
416
417 QWidget *editor = qobject_cast<QWidget*>(object);
418 if (!editor)
419 return false;
420 if (event->type() == QEvent::KeyPress) {
421 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
422 if (editorHandlesKeyEvent(editor, keyEvent))
423 return false;
424
425#ifndef QT_NO_SHORTCUT
426 if (keyEvent->matches(QKeySequence::Cancel)) {
427 // don't commit data
428 emit q->closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
429 return true;
430 }
431#endif
432
433 switch (keyEvent->key()) {
434 case Qt::Key_Tab:
435 if (tryFixup(editor)) {
436 emit q->commitData(editor);
437 emit q->closeEditor(editor, QAbstractItemDelegate::EditNextItem);
438 }
439 return true;
440 case Qt::Key_Backtab:
441 if (tryFixup(editor)) {
442 emit q->commitData(editor);
443 emit q->closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
444 }
445 return true;
446 case Qt::Key_Enter:
447 case Qt::Key_Return:
448 // We want the editor to be able to process the key press
449 // before committing the data (e.g. so it can do
450 // validation/fixup of the input).
451 if (!tryFixup(editor))
452 return true;
453
454 QMetaObject::invokeMethod(q, "_q_commitDataAndCloseEditor",
456 return false;
457 default:
458 return false;
459 }
460 } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
461 //the Hide event will take care of he editors that are in fact complete dialogs
462 if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
464 while (w) { // don't worry about focus changes internally in the editor
465 if (w == editor)
466 return false;
467 w = w->parentWidget();
468 }
469#if QT_CONFIG(draganddrop)
470 // The window may lose focus during an drag operation.
471 // i.e when dragging involves the taskbar on Windows.
472 QPlatformDrag *platformDrag = QGuiApplicationPrivate::instance()->platformIntegration()->drag();
473 if (platformDrag && platformDrag->currentDrag()) {
474 return false;
475 }
476#endif
477 if (tryFixup(editor))
478 emit q->commitData(editor);
479
480 // If the application loses focus while editing, then the focus needs to go back
481 // to the itemview when the editor closes. This ensures that when the application
482 // is active again it will have the focus on the itemview as expected.
483 QWidget *editorParent = editor->parentWidget();
484 const bool manuallyFixFocus = (event->type() == QEvent::FocusOut) && !editor->hasFocus() &&
485 editorParent &&
486 (static_cast<QFocusEvent *>(event)->reason() == Qt::ActiveWindowFocusReason);
487 emit q->closeEditor(editor, QAbstractItemDelegate::NoHint);
488 if (manuallyFixFocus)
489 editorParent->setFocus();
490 }
491#ifndef QT_NO_SHORTCUT
492 } else if (event->type() == QEvent::ShortcutOverride) {
493 if (static_cast<QKeyEvent*>(event)->matches(QKeySequence::Cancel)) {
494 event->accept();
495 return true;
496 }
497#endif
498 }
499 return false;
500}
501
503{
504#if QT_CONFIG(lineedit)
505 if (QLineEdit *e = qobject_cast<QLineEdit*>(editor)) {
506 if (!e->hasAcceptableInput()) {
507#if QT_CONFIG(validator)
508 if (const QValidator *validator = e->validator()) {
509 QString text = e->text();
510 validator->fixup(text);
511 e->setText(text);
512 }
513#endif
514 return e->hasAcceptableInput();
515 }
516 }
517#endif
518#if QT_CONFIG(spinbox)
519 // Give a chance to the spinbox to interpret the text and emit
520 // the appropriate signals before committing data.
521 if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(editor)) {
522 if (!sb->keyboardTracking())
523 sb->interpretText();
524 }
525#else
526 Q_UNUSED(editor);
527#endif // QT_CONFIG(lineedit)
528
529 return true;
530}
531
533{
536 switch (value.userType()) {
537 case QMetaType::Float:
538 text = locale.toString(value.toFloat());
539 break;
540 case QMetaType::Double:
541 text = locale.toString(value.toDouble(), 'g', precision);
542 break;
543 case QMetaType::Int:
544 case QMetaType::LongLong:
545 text = locale.toString(value.toLongLong());
546 break;
547 case QMetaType::UInt:
548 case QMetaType::ULongLong:
549 text = locale.toString(value.toULongLong());
550 break;
551 case QMetaType::QDate:
552 text = locale.toString(value.toDate(), formatType);
553 break;
554 case QMetaType::QTime:
555 text = locale.toString(value.toTime(), formatType);
556 break;
557 case QMetaType::QDateTime:
558 text = locale.toString(value.toDateTime(), formatType);
559 break;
560 case QMetaType::QJsonValue: {
561 const QJsonValue val = value.toJsonValue();
562 if (val.isBool()) {
563 text = QVariant(val.toBool()).toString();
564 break;
565 }
566 if (val.isDouble()) {
567 text = locale.toString(val.toDouble(), 'g', precision);
568 break;
569 }
570 // val is a string (or null) here
572 }
573 default: {
574 text = value.toString();
575 if (role == Qt::DisplayRole)
576 text.replace(u'\n', QChar::LineSeparator);
577 break;
578 }
579 }
580 return text;
581}
582
584{
586 emit q->commitData(editor);
587 emit q->closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
588}
589
591
592#include "moc_qabstractitemdelegate.cpp"
QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision=6) const
void _q_commitDataAndCloseEditor(QWidget *editor)
bool editorEventFilter(QObject *object, QEvent *event)
The QAbstractItemDelegate class is used to display and edit data items from a model.
virtual ~QAbstractItemDelegate()
Destroys the abstract item delegate.
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
Returns the editor to be used for editing the data item with the given index.
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
Updates the geometry of the editor for the item with the given index, according to the rectangle spec...
virtual QList< int > paintingRoles() const
virtual void destroyEditor(QWidget *editor, const QModelIndex &index) const
Called when the editor is no longer needed for editing the data item with the given index and should ...
virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
When editing of an item starts, this function is called with the event that triggered the editing,...
QAbstractItemDelegate(QObject *parent=nullptr)
Creates a new abstract item delegate with the given parent.
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const
Sets the contents of the given editor to the data for the item at the given index.
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
Sets the data for the item at the given index in the model to the contents of the given editor.
virtual bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
The QAbstractItemView class provides the basic functionality for item view classes.
The QAbstractSpinBox class provides a spinbox and a line edit to display values.
static QWidget * focusWidget()
Returns the application widget that has the keyboard input focus, or \nullptr if no widget in this ap...
\inmodule QtCore
Definition qcoreevent.h:45
@ QueryWhatsThis
Definition qcoreevent.h:169
@ ShortcutOverride
Definition qcoreevent.h:158
@ FocusOut
Definition qcoreevent.h:67
@ KeyPress
Definition qcoreevent.h:64
@ WhatsThis
Definition qcoreevent.h:148
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
static QGuiApplicationPrivate * instance()
The QHelpEvent class provides an event that is used to request helpful information about a particular...
Definition qevent.h:788
\inmodule QtCore\reentrant
Definition qjsonvalue.h:25
The QKeyEvent class describes a key event.
Definition qevent.h:424
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:434
The QLineEdit widget is a one-line text editor.
Definition qlineedit.h:28
@ LongFormat
Definition qlocale.h:875
@ ShortFormat
Definition qlocale.h:875
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:348
The QPlatformDrag class provides an abstraction for drag.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3824
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static void showText(const QPoint &pos, const QString &text, QWidget *w=nullptr, const QRect &rect={}, int msecShowTime=-1)
Shows text as a tool tip, with the global position pos as the point of interest.
Definition qtooltip.cpp:439
The QValidator class provides validation of input text.
Definition qvalidator.h:24
\inmodule QtCore
Definition qvariant.h:65
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
static void showText(const QPoint &pos, const QString &text, QWidget *w=nullptr)
Shows text as a "What's This?" window, at global position pos.
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QString text
Combined button and popup list for selecting options.
ItemDataRole
@ WhatsThisRole
@ ToolTipRole
@ DisplayRole
@ Key_Tab
Definition qnamespace.h:664
@ Key_Return
Definition qnamespace.h:667
@ Key_Enter
Definition qnamespace.h:668
@ Key_Backtab
Definition qnamespace.h:665
@ QueuedConnection
@ ActiveWindowFocusReason
static bool editorHandlesKeyEvent(QWidget *editor, const QKeyEvent *event)
#define Q_FALLTHROUGH()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
struct _cl_event * event
GLuint GLfloat * val
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint GLenum option
GLenum GLint GLint * precision
#define emit
#define Q_UNUSED(x)
QWidget * qobject_cast< QWidget * >(QObject *o)
Definition qwidget.h:786
QQuickView * view
[0]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...