Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
qitemdelegate.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
4#include "qitemdelegate.h"
5
7#include <qapplication.h>
8#include <qbrush.h>
9#include <qpainter.h>
10#include <qpalette.h>
11#include <qpoint.h>
12#include <qrect.h>
13#include <qsize.h>
14#include <qstyle.h>
15#include <qdatetime.h>
16#include <qstyleoption.h>
17#include <qevent.h>
18#include <qpixmap.h>
19#include <qbitmap.h>
20#include <qpixmapcache.h>
21#include <qitemeditorfactory.h>
22#include <qmetaobject.h>
23#include <qtextlayout.h>
24#include <private/qabstractitemdelegate_p.h>
25#include <private/qabstractitemmodel_p.h>
26#include <private/qtextengine_p.h>
27#include <qdebug.h>
28#include <qlocale.h>
29#include <qmath.h>
30
31#include <limits.h>
32
33// keep in sync with QAbstractItemDelegate::helpEvent()
34#ifndef DBL_DIG
35# define DBL_DIG 10
36#endif
37
39
41{
42 Q_DECLARE_PUBLIC(QItemDelegate)
43
44public:
46
47 inline const QItemEditorFactory *editorFactory() const
48 { return f ? f : QItemEditorFactory::defaultFactory(); }
49
50 inline QIcon::Mode iconMode(QStyle::State state) const
51 {
54 return QIcon::Normal;
55 }
56
57 inline QIcon::State iconState(QStyle::State state) const
59
61 {
63 return text;
64 }
65
66 QString valueToText(const QVariant &value, const QStyleOptionViewItem &option) const;
67
70
71 QRect displayRect(const QModelIndex &index, const QStyleOptionViewItem &option,
72 const QRect &decorationRect, const QRect &checkRect) const;
73 QRect textLayoutBounds(const QStyleOptionViewItem &option,
74 const QRect &decorationRect, const QRect &checkRect) const;
75 QSizeF doTextLayout(int lineWidth) const;
78
79 const QWidget *widget(const QStyleOptionViewItem &option) const
80 {
81 return option.widget;
82 }
83
84 // ### temporary hack until we have QStandardItemDelegate
85 mutable struct Icon {
89 } tmp;
90};
91
93 const QRect &decorationRect, const QRect &checkRect) const
94{
95 Q_Q(const QItemDelegate);
97 if (!value.isValid() || value.isNull())
98 return QRect();
99
101 const QVariant fontVal = index.data(Qt::FontRole);
102 const QFont fnt = qvariant_cast<QFont>(fontVal).resolve(option.font);
103 return q->textRectangle(nullptr,
104 textLayoutBounds(option, decorationRect, checkRect),
105 fnt, text);
106}
107
108// similar to QCommonStylePrivate::viewItemSize(Qt::DisplayRole)
110 const QRect &decorationRect, const QRect &checkRect) const
111{
112 QRect rect = option.rect;
113 const QWidget *w = widget(option);
114 QStyle *style = w ? w->style() : QApplication::style();
115 const bool wrapText = option.features & QStyleOptionViewItem::WrapText;
116 // see QItemDelegate::drawDisplay
117 const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, w) + 1;
118 switch (option.decorationPosition) {
119 case QStyleOptionViewItem::Left:
120 case QStyleOptionViewItem::Right:
121 rect.setWidth(wrapText && rect.isValid() ? rect.width() - 2 * textMargin : (QFIXED_MAX));
122 break;
123 case QStyleOptionViewItem::Top:
124 case QStyleOptionViewItem::Bottom:
125 rect.setWidth(wrapText ? option.decorationSize.width() - 2 * textMargin : (QFIXED_MAX));
126 break;
127 }
128
129 if (wrapText) {
130 if (!decorationRect.isNull())
131 rect.setWidth(rect.width() - decorationRect.width() - 2 * textMargin);
132 if (!checkRect.isNull())
133 rect.setWidth(rect.width() - checkRect.width() - 2 * textMargin);
134 // adjust height to be sure that the text fits
135 const QSizeF size = doTextLayout(rect.width());
136 rect.setHeight(qCeil(size.height()));
137 }
138
139 return rect;
140}
141
143{
144 qreal height = 0;
145 qreal widthUsed = 0;
147 while (true) {
149 if (!line.isValid())
150 break;
151 line.setLineWidth(lineWidth);
152 line.setPosition(QPointF(0, height));
153 height += line.height();
154 widthUsed = qMax(widthUsed, line.naturalTextWidth());
155 }
157 return QSizeF(widthUsed, height);
158}
159
294{
295
296}
297
303{
304}
305
317{
318 Q_D(const QItemDelegate);
319 return d->clipPainting;
320}
321
323{
324 Q_D(QItemDelegate);
325 d->clipPainting = clip;
326}
327
328QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) const
329{
331}
332
358 const QStyleOptionViewItem &option,
359 const QModelIndex &index) const
360{
361 Q_D(const QItemDelegate);
362 Q_ASSERT(index.isValid());
363
364 QStyleOptionViewItem opt = setOptions(index, option);
365
366 // prepare
367 painter->save();
368 if (d->clipPainting)
370
371 // get the data and the rectangles
372
374
376 QRect decorationRect;
378 if (value.isValid()) {
379 // ### we need the pixmap to call the virtual function
381 if (value.userType() == QMetaType::QIcon) {
382 d->tmp.icon = qvariant_cast<QIcon>(value);
383 d->tmp.mode = d->iconMode(option.state);
384 d->tmp.state = d->iconState(option.state);
385 const QSize size = d->tmp.icon.actualSize(option.decorationSize,
386 d->tmp.mode, d->tmp.state);
387 decorationRect = QRect(QPoint(0, 0), size);
388 } else {
389 d->tmp.icon = QIcon();
390 decorationRect = QRect(QPoint(0, 0), pixmap.size());
391 }
392 } else {
393 d->tmp.icon = QIcon();
394 decorationRect = QRect();
395 }
396
397 QRect checkRect;
400 if (value.isValid()) {
401 checkState = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
402 checkRect = doCheck(opt, opt.rect, value);
403 }
404
406 QRect displayRect;
408 if (value.isValid() && !value.isNull()) {
409 text = d->valueToText(value, opt);
410 displayRect = d->displayRect(index, opt, decorationRect, checkRect);
411 }
412
413 // do the layout
414
415 doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
416
417 // draw the item
418
420 drawCheck(painter, opt, checkRect, checkState);
421 drawDecoration(painter, opt, decorationRect, pixmap);
422 drawDisplay(painter, opt, displayRect, text);
423 drawFocus(painter, opt, displayRect);
424
425 // done
426 painter->restore();
427}
428
439QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
440 const QModelIndex &index) const
441{
442 Q_D(const QItemDelegate);
444 if (value.isValid())
445 return qvariant_cast<QSize>(value);
446 QRect decorationRect = rect(option, index, Qt::DecorationRole);
448 QRect displayRect = d->displayRect(index, option, decorationRect, checkRect);
449
450 doLayout(option, &checkRect, &decorationRect, &displayRect, true);
451
452 return (decorationRect|displayRect|checkRect).size();
453}
454
464 const QStyleOptionViewItem &,
465 const QModelIndex &index) const
466{
467 Q_D(const QItemDelegate);
468 if (!index.isValid())
469 return nullptr;
470 const QItemEditorFactory *factory = d->f;
471 if (factory == nullptr)
473 QWidget *w = factory->createEditor(index.data(Qt::EditRole).userType(), parent);
474 if (w)
476 return w;
477}
478
490{
492 QByteArray n = editor->metaObject()->userProperty().name();
493
494 if (!n.isEmpty()) {
495 if (!v.isValid())
496 v = QVariant(editor->property(n).metaType());
497 editor->setProperty(n, v);
498 }
499}
500
514 const QModelIndex &index) const
515{
516 Q_D(const QItemDelegate);
518 Q_ASSERT(editor);
519 QByteArray n = editor->metaObject()->userProperty().name();
520 if (n.isEmpty())
521 n = d->editorFactory()->valuePropertyName(
523 if (!n.isEmpty())
524 model->setData(index, editor->property(n), Qt::EditRole);
525}
526
533 const QStyleOptionViewItem &option,
534 const QModelIndex &index) const
535{
536 if (!editor)
537 return;
538 Q_ASSERT(index.isValid());
541 QRect pixmapRect = QRect(QPoint(0, 0), option.decorationSize).intersected(pixmap.rect());
542 QRect textRect = textRectangle(nullptr, option.rect, option.font, text);
544 QStyleOptionViewItem opt = option;
545 opt.showDecorationSelected = true; // let the editor take up all available space
546 doLayout(opt, &checkRect, &pixmapRect, &textRect, false);
547 editor->setGeometry(textRect);
548}
549
557{
558 Q_D(const QItemDelegate);
559 return d->f;
560}
561
570{
571 Q_D(QItemDelegate);
572 d->f = factory;
573}
574
580void QItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
581 const QRect &rect, const QString &text) const
582{
583 Q_D(const QItemDelegate);
584
587 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
589 if (option.state & QStyle::State_Selected) {
590 painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight));
591 painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
592 } else {
593 painter->setPen(option.palette.color(cg, QPalette::Text));
594 }
595
596 if (text.isEmpty())
597 return;
598
599 if (option.state & QStyle::State_Editing) {
600 painter->save();
601 painter->setPen(option.palette.color(cg, QPalette::Text));
602 painter->drawRect(rect.adjusted(0, 0, -1, -1));
603 painter->restore();
604 }
605
606 const QStyleOptionViewItem opt = option;
607
608 const QWidget *widget = d->widget(option);
609 QStyle *style = widget ? widget->style() : QApplication::style();
610 const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1;
611 QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
612 const bool wrapText = opt.features & QStyleOptionViewItem::WrapText;
613 d->textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
614 d->textOption.setTextDirection(option.direction);
615 d->textOption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
616 d->textLayout.setTextOption(d->textOption);
617 d->textLayout.setFont(option.font);
618 d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
619
620 QSizeF textLayoutSize = d->doTextLayout(textRect.width());
621
622 if (textRect.width() < textLayoutSize.width()
623 || textRect.height() < textLayoutSize.height()) {
624 QString elided;
625 int start = 0;
627 if (end == -1) {
628 elided += option.fontMetrics.elidedText(text, option.textElideMode, textRect.width());
629 } else {
630 while (end != -1) {
631 elided += option.fontMetrics.elidedText(text.mid(start, end - start),
632 option.textElideMode, textRect.width());
633 elided += QChar::LineSeparator;
634 start = end + 1;
636 }
637 //let's add the last line (after the last QChar::LineSeparator)
638 elided += option.fontMetrics.elidedText(text.mid(start),
639 option.textElideMode, textRect.width());
640 }
641 d->textLayout.setText(elided);
642 textLayoutSize = d->doTextLayout(textRect.width());
643 }
644
645 const QSize layoutSize(textRect.width(), int(textLayoutSize.height()));
646 const QRect layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment,
647 layoutSize, textRect);
648 // if we still overflow even after eliding the text, enable clipping
649 if (!hasClipping() && (textRect.width() < textLayoutSize.width()
650 || textRect.height() < textLayoutSize.height())) {
651 painter->save();
652 painter->setClipRect(layoutRect);
653 d->textLayout.draw(painter, layoutRect.topLeft(), QList<QTextLayout::FormatRange>(),
654 layoutRect);
655 painter->restore();
656 } else {
657 d->textLayout.draw(painter, layoutRect.topLeft(), QList<QTextLayout::FormatRange>(),
658 layoutRect);
659 }
660}
661
666void QItemDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
667 const QRect &rect, const QPixmap &pixmap) const
668{
669 Q_D(const QItemDelegate);
670 // if we have an icon, we ignore the pixmap
671 if (!d->tmp.icon.isNull()) {
672 d->tmp.icon.paint(painter, rect, option.decorationAlignment,
673 d->tmp.mode, d->tmp.state);
674 return;
675 }
676
677 if (pixmap.isNull() || !rect.isValid())
678 return;
679 QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment,
680 pixmap.size(), rect).topLeft();
681 if (option.state & QStyle::State_Selected) {
682 const QPixmap pm = selectedPixmap(pixmap, option.palette, option.state & QStyle::State_Enabled);
683 painter->drawPixmap(p, pm);
684 } else {
686 }
687}
688
695 const QStyleOptionViewItem &option,
696 const QRect &rect) const
697{
698 Q_D(const QItemDelegate);
699 if ((option.state & QStyle::State_HasFocus) == 0 || !rect.isValid())
700 return;
702 o.QStyleOption::operator=(option);
703 o.rect = rect;
705 o.state |= QStyle::State_Item;
708 o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected)
710 const QWidget *widget = d->widget(option);
711 QStyle *style = widget ? widget->style() : QApplication::style();
713}
714
722 const QStyleOptionViewItem &option,
723 const QRect &rect, Qt::CheckState state) const
724{
725 Q_D(const QItemDelegate);
726 if (!rect.isValid())
727 return;
728
729 QStyleOptionViewItem opt(option);
730 opt.rect = rect;
731 opt.state = opt.state & ~QStyle::State_HasFocus;
732
733 switch (state) {
734 case Qt::Unchecked:
736 break;
739 break;
740 case Qt::Checked:
742 break;
743 }
744
745 const QWidget *widget = d->widget(option);
746 QStyle *style = widget ? widget->style() : QApplication::style();
748}
749
758 const QStyleOptionViewItem &option,
759 const QModelIndex &index) const
760{
761 if (option.showDecorationSelected && (option.state & QStyle::State_Selected)) {
764 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
766
767 painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
768 } else {
770 if (value.canConvert<QBrush>()) {
771 QPointF oldBO = painter->brushOrigin();
772 painter->setBrushOrigin(option.rect.topLeft());
773 painter->fillRect(option.rect, qvariant_cast<QBrush>(value));
774 painter->setBrushOrigin(oldBO);
775 }
776 }
777}
778
779
786void QItemDelegate::doLayout(const QStyleOptionViewItem &option,
787 QRect *checkRect, QRect *pixmapRect, QRect *textRect,
788 bool hint) const
789{
790 Q_ASSERT(checkRect && pixmapRect && textRect);
791 Q_D(const QItemDelegate);
792 const QWidget *widget = d->widget(option);
793 QStyle *style = widget ? widget->style() : QApplication::style();
794 const bool hasCheck = checkRect->isValid();
795 const bool hasPixmap = pixmapRect->isValid();
796 const bool hasText = textRect->isValid();
797 const bool hasMargin = (hasText | hasPixmap | hasCheck);
798 const int frameHMargin = hasMargin ?
799 style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1 : 0;
800 const int textMargin = hasText ? frameHMargin : 0;
801 const int pixmapMargin = hasPixmap ? frameHMargin : 0;
802 const int checkMargin = hasCheck ? frameHMargin : 0;
803 const int x = option.rect.left();
804 const int y = option.rect.top();
805 int w, h;
806
807 textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding
808 if (textRect->height() == 0 && (!hasPixmap || !hint)) {
809 //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
810 textRect->setHeight(option.fontMetrics.height());
811 }
812
813 QSize pm(0, 0);
814 if (hasPixmap) {
815 pm = pixmapRect->size();
816 pm.rwidth() += 2 * pixmapMargin;
817 }
818 if (hint) {
819 h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
820 if (option.decorationPosition == QStyleOptionViewItem::Left
821 || option.decorationPosition == QStyleOptionViewItem::Right) {
822 w = textRect->width() + pm.width();
823 } else {
824 w = qMax(textRect->width(), pm.width());
825 }
826 } else {
827 w = option.rect.width();
828 h = option.rect.height();
829 }
830
831 int cw = 0;
832 QRect check;
833 if (hasCheck) {
834 cw = checkRect->width() + 2 * checkMargin;
835 if (hint) w += cw;
836 if (option.direction == Qt::RightToLeft) {
837 check.setRect(x + w - cw, y, cw, h);
838 } else {
839 check.setRect(x, y, cw, h);
840 }
841 }
842
843 // at this point w should be the *total* width
844
847 switch (option.decorationPosition) {
848 case QStyleOptionViewItem::Top: {
849 if (hasPixmap)
850 pm.setHeight(pm.height() + pixmapMargin); // add space
851 h = hint ? textRect->height() : h - pm.height();
852
853 if (option.direction == Qt::RightToLeft) {
854 decoration.setRect(x, y, w - cw, pm.height());
855 display.setRect(x, y + pm.height(), w - cw, h);
856 } else {
857 decoration.setRect(x + cw, y, w - cw, pm.height());
858 display.setRect(x + cw, y + pm.height(), w - cw, h);
859 }
860 break; }
861 case QStyleOptionViewItem::Bottom: {
862 if (hasText)
863 textRect->setHeight(textRect->height() + textMargin); // add space
864 h = hint ? textRect->height() + pm.height() : h;
865
866 if (option.direction == Qt::RightToLeft) {
867 display.setRect(x, y, w - cw, textRect->height());
868 decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
869 } else {
870 display.setRect(x + cw, y, w - cw, textRect->height());
871 decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
872 }
873 break; }
874 case QStyleOptionViewItem::Left: {
875 if (option.direction == Qt::LeftToRight) {
876 decoration.setRect(x + cw, y, pm.width(), h);
877 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
878 } else {
879 display.setRect(x, y, w - pm.width() - cw, h);
880 decoration.setRect(display.right() + 1, y, pm.width(), h);
881 }
882 break; }
883 case QStyleOptionViewItem::Right: {
884 if (option.direction == Qt::LeftToRight) {
885 display.setRect(x + cw, y, w - pm.width() - cw, h);
886 decoration.setRect(display.right() + 1, y, pm.width(), h);
887 } else {
888 decoration.setRect(x, y, pm.width(), h);
889 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
890 }
891 break; }
892 default:
893 qWarning("doLayout: decoration position is invalid");
894 decoration = *pixmapRect;
895 break;
896 }
897
898 if (!hint) { // we only need to do the internal layout if we are going to paint
899 *checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
900 checkRect->size(), check);
901 *pixmapRect = QStyle::alignedRect(option.direction, option.decorationAlignment,
902 pixmapRect->size(), decoration);
903 // the text takes up all available space, unless the decoration is not shown as selected
904 if (option.showDecorationSelected)
905 *textRect = display;
906 else
907 *textRect = QStyle::alignedRect(option.direction, option.displayAlignment,
909 } else {
910 *checkRect = check;
911 *pixmapRect = decoration;
912 *textRect = display;
913 }
914}
915
924QPixmap QItemDelegate::decoration(const QStyleOptionViewItem &option, const QVariant &variant) const
925{
926 Q_D(const QItemDelegate);
927 switch (variant.userType()) {
928 case QMetaType::QIcon: {
929 QIcon::Mode mode = d->iconMode(option.state);
930 QIcon::State state = d->iconState(option.state);
931 return qvariant_cast<QIcon>(variant).pixmap(option.decorationSize, mode, state); }
932 case QMetaType::QColor: {
933 static QPixmap pixmap(option.decorationSize);
934 pixmap.fill(qvariant_cast<QColor>(variant));
935 return pixmap; }
936 default:
937 break;
938 }
939
940 return qvariant_cast<QPixmap>(variant);
941}
942
943// hacky but faster version of "QString::asprintf("%d-%d", i, enabled)"
945{
946 ushort arr[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', ushort('0' + enabled) };
947 ushort *ptr = &arr[16];
948
949 while (i > 0) {
950 // hey - it's our internal representation, so use the ascii character after '9'
951 // instead of 'a' for hex
952 *(--ptr) = '0' + i % 16;
953 i >>= 4;
954 }
955
956 return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
957}
958
959
967{
968 const QString key = qPixmapSerial(pixmap.cacheKey(), enabled);
969 QPixmap pm;
970 if (!QPixmapCache::find(key, &pm)) {
971 QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
972
975 color.setAlphaF(0.3f);
976
979 painter.fillRect(0, 0, img.width(), img.height(), color);
980 painter.end();
981
983 const int n = (img.sizeInBytes() >> 10) + 1;
986
988 }
989 return pm;
990}
991
996QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
997 const QModelIndex &index, int role) const
998{
999 Q_D(const QItemDelegate);
1000 QVariant value = index.data(role);
1001 if (role == Qt::CheckStateRole)
1002 return doCheck(option, option.rect, value);
1003 if (value.isValid() && !value.isNull()) {
1004 switch (value.userType()) {
1006 break;
1007 case QMetaType::QPixmap: {
1008 const QPixmap &pixmap = qvariant_cast<QPixmap>(value);
1009 return QRect(QPoint(0, 0), pixmap.deviceIndependentSize().toSize()); }
1010 case QMetaType::QImage: {
1011 const QImage &image = qvariant_cast<QImage>(value);
1012 return QRect(QPoint(0, 0), image.deviceIndependentSize().toSize()); }
1013 case QMetaType::QIcon: {
1014 QIcon::Mode mode = d->iconMode(option.state);
1015 QIcon::State state = d->iconState(option.state);
1016 QIcon icon = qvariant_cast<QIcon>(value);
1017 QSize size = icon.actualSize(option.decorationSize, mode, state);
1018 return QRect(QPoint(0, 0), size); }
1019 case QMetaType::QColor:
1020 return QRect(QPoint(0, 0), option.decorationSize);
1021 case QMetaType::QString:
1022 default: {
1023 const QString text = d->valueToText(value, option);
1024 value = index.data(Qt::FontRole);
1025 QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
1026 return textRectangle(nullptr,
1027 d->textLayoutBounds(option, QRect(), QRect()),
1028 fnt, text); }
1029 }
1030 }
1031 return QRect();
1032}
1033
1037QRect QItemDelegate::doCheck(const QStyleOptionViewItem &option,
1038 const QRect &bounding, const QVariant &value) const
1039{
1040 if (value.isValid()) {
1041 Q_D(const QItemDelegate);
1043 opt.QStyleOption::operator=(option);
1044 opt.rect = bounding;
1045 const QWidget *widget = d->widget(option); // cast
1046 QStyle *style = widget ? widget->style() : QApplication::style();
1048 }
1049 return QRect();
1050}
1051
1056 const QFont &font, const QString &text) const
1057{
1058 Q_D(const QItemDelegate);
1059 d->textOption.setWrapMode(QTextOption::WordWrap);
1060 d->textLayout.setTextOption(d->textOption);
1061 d->textLayout.setFont(font);
1062 d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
1063 QSizeF fpSize = d->doTextLayout(rect.width());
1064 const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height()));
1065 // ###: textRectangle should take style option as argument
1066 const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1;
1067 return QRect(0, 0, size.width() + 2 * textMargin, size.height());
1068}
1069
1099{
1100 Q_D(QItemDelegate);
1101 return d->editorEventFilter(object, event);
1102}
1103
1110 const QStyleOptionViewItem &option,
1111 const QModelIndex &index)
1112{
1113 Q_ASSERT(event);
1114 Q_ASSERT(model);
1115
1116 // make sure that the item is checkable
1117 Qt::ItemFlags flags = model->flags(index);
1119 || !(flags & Qt::ItemIsEnabled))
1120 return false;
1121
1122 // make sure that we have a check state
1124 if (!value.isValid())
1125 return false;
1126
1127 // make sure that we have the right event type
1128 if ((event->type() == QEvent::MouseButtonRelease)
1129 || (event->type() == QEvent::MouseButtonDblClick)
1130 || (event->type() == QEvent::MouseButtonPress)) {
1131 QRect checkRect = doCheck(option, option.rect, Qt::Checked);
1132 QRect emptyRect;
1133 doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
1134 QMouseEvent *me = static_cast<QMouseEvent*>(event);
1135 if (me->button() != Qt::LeftButton || !checkRect.contains(me->position().toPoint()))
1136 return false;
1137
1138 // eat the double click events inside the check rect
1139 if ((event->type() == QEvent::MouseButtonPress)
1140 || (event->type() == QEvent::MouseButtonDblClick))
1141 return true;
1142
1143 } else if (event->type() == QEvent::KeyPress) {
1144 if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
1145 && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
1146 return false;
1147 } else {
1148 return false;
1149 }
1150
1151 Qt::CheckState state = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
1153 state = ((Qt::CheckState)((state + 1) % 3));
1154 else
1157}
1158
1163QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
1164 const QStyleOptionViewItem &option) const
1165{
1166 QStyleOptionViewItem opt = option;
1167
1168 // set font
1170 if (value.isValid()){
1171 opt.font = qvariant_cast<QFont>(value).resolve(opt.font);
1173 }
1174
1175 // set text alignment
1177 if (value.isValid())
1178 opt.displayAlignment = QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(value);
1179
1180 // set foreground brush
1182 if (value.canConvert<QBrush>())
1183 opt.palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
1184
1185 // disable style animations for checkboxes etc. within itemviews (QTBUG-30146)
1186 opt.styleObject = nullptr;
1187
1188 return opt;
1189}
1190
1192
1193#include "moc_qitemdelegate.cpp"
QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision=6) const
The QAbstractItemDelegate class is used to display and edit data items from a model.
virtual Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Sets the role data for the item at index to value.
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
static QStyle * style()
Returns the application's style object.
\inmodule QtGui
Definition qbrush.h:30
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qchar.h:48
@ LineSeparator
Definition qchar.h:64
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
Definition qcoreevent.h:45
@ KeyPress
Definition qcoreevent.h:64
@ MouseButtonPress
Definition qcoreevent.h:60
@ MouseButtonDblClick
Definition qcoreevent.h:62
@ MouseButtonRelease
Definition qcoreevent.h:61
\reentrant \inmodule QtGui
\reentrant
Definition qfont.h:20
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition qfont.cpp:1854
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
@ Disabled
Definition qicon.h:22
@ Selected
Definition qicon.h:22
@ Normal
Definition qicon.h:22
State
This enum describes the state for which a pixmap is intended to be used.
Definition qicon.h:23
@ Off
Definition qicon.h:23
@ On
Definition qicon.h:23
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition qicon.cpp:880
\inmodule QtGui
Definition qimage.h:37
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
const QItemEditorFactory * editorFactory() const
QString valueToText(const QVariant &value, const QStyleOptionViewItem &option) const
const QWidget * widget(const QStyleOptionViewItem &option) const
QSizeF doTextLayout(int lineWidth) const
static QString replaceNewLine(QString text)
QIcon::Mode iconMode(QStyle::State state) const
QItemEditorFactory * f
QIcon::State iconState(QStyle::State state) const
QRect displayRect(const QModelIndex &index, const QStyleOptionViewItem &option, const QRect &decorationRect, const QRect &checkRect) const
QRect textLayoutBounds(const QStyleOptionViewItem &option, const QRect &decorationRect, const QRect &checkRect) const
struct QItemDelegatePrivate::Icon tmp
The QItemDelegate class provides display and editing facilities for data items from a model.
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Renders the delegate using the given painter and style option for the item specified by index.
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Gets data from the editor widget and stores it in the specified model at the item index.
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Sets the data to be displayed and edited by the editor from the data model item specified by the mode...
virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, Qt::CheckState state) const
Renders a check indicator within the rectangle specified by rect, using the given painter and style o...
QRect textRectangle(QPainter *painter, const QRect &rect, const QFont &font, const QString &text) const
QRect rect(const QStyleOptionViewItem &option, const QModelIndex &index, int role) const
~QItemDelegate()
Destroys the item delegate.
virtual void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const
Renders the item view text within the rectangle specified by rect using the given painter and style o...
QRect doCheck(const QStyleOptionViewItem &option, const QRect &bounding, const QVariant &variant) const
void setClipping(bool clip)
static QPixmap selectedPixmap(const QPixmap &pixmap, const QPalette &palette, bool enabled)
virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
Renders the region within the rectangle specified by rect, indicating that it has the focus,...
QItemDelegate(QObject *parent=nullptr)
Constructs an item delegate with the given parent.
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
\reimp
void setItemEditorFactory(QItemEditorFactory *factory)
Sets the editor factory to be used by the item delegate to be the factory specified.
bool hasClipping() const
void doLayout(const QStyleOptionViewItem &option, QRect *checkRect, QRect *iconRect, QRect *textRect, bool hint) const
bool eventFilter(QObject *object, QEvent *event) override
Returns true if the given editor is a valid QWidget and the given event is handled; otherwise returns...
virtual void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QPixmap &pixmap) const
Renders the decoration pixmap within the rectangle specified by rect using the given painter and styl...
void drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Returns the widget used to edit the item specified by index for editing.
QItemEditorFactory * itemEditorFactory() const
Returns the editor factory used by the item delegate.
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Updates the editor for the item specified by index according to the style option given.
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
Returns the size needed by the delegate to display the item specified by index, taking into account t...
QPixmap decoration(const QStyleOptionViewItem &option, const QVariant &variant) const
QStyleOptionViewItem setOptions(const QModelIndex &index, const QStyleOptionViewItem &option) const
The QItemEditorFactory class provides widgets for editing item data in views and delegates.
static const QItemEditorFactory * defaultFactory()
Returns the default item editor factory.
virtual QWidget * createEditor(int userType, QWidget *parent) const
Creates an editor widget with the given parent for the specified userType of data,...
The QKeyEvent class describes a key event.
Definition qevent.h:423
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:433
Definition qlist.h:74
\inmodule QtCore
\inmodule QtGui
Definition qevent.h:195
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition qpainter.h:519
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation.
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setBrushOrigin(int x, int y)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qpainter.h:698
void restore()
Restores the current painter state (pops a saved state off the stack).
void setCompositionMode(CompositionMode mode)
Sets the composition mode to the given mode.
void save()
Saves the current painter state (pushes the state onto a stack).
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
QPoint brushOrigin() const
Returns the currently set brush origin.
bool end()
Ends painting.
@ CompositionMode_SourceAtop
Definition qpainter.h:107
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
void setBrush(ColorRole cr, const QBrush &brush)
Sets the brush for the given color role to the specified brush for all groups in the palette.
Definition qpalette.h:150
ColorGroup
\value Disabled \value Active \value Inactive \value Normal synonym for Active
Definition qpalette.h:48
@ Inactive
Definition qpalette.h:48
@ Disabled
Definition qpalette.h:48
@ HighlightedText
Definition qpalette.h:52
@ Highlight
Definition qpalette.h:52
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static int cacheLimit()
Returns the cache limit (in kilobytes).
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
static void setCacheLimit(int)
Sets the cache limit to n kilobytes.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition qpixmap.cpp:1445
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:394
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:372
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
Definition qrect.h:169
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition qrect.h:163
QRect intersected(const QRect &other) const noexcept
Definition qrect.h:414
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:220
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qrect.cpp:851
constexpr void setRect(int x, int y, int w, int h) noexcept
Sets the coordinates of the rectangle's top-left corner to ({x}, {y}), and its size to the given widt...
Definition qrect.h:345
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:241
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
constexpr void setHeight(int h) noexcept
Sets the height of the rectangle to the given height.
Definition qrect.h:383
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
Definition qevent.h:118
Qt::MouseButton button() const
Returns the button that caused the event.
Definition qevent.h:115
\inmodule QtCore
Definition qsize.h:207
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:321
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:324
\inmodule QtCore
Definition qsize.h:25
constexpr QSize boundedTo(const QSize &) const noexcept
Returns a size holding the minimum width and height of this size and the given otherSize.
Definition qsize.h:196
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr int & rwidth() noexcept
Returns a reference to the width.
Definition qsize.h:153
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:138
QVariant data(const QModelIndex &item, int role=Qt::DisplayRole) const override
Returns the value for the specified item and role.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3794
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
\variable QStyleOptionHeaderV2::textElideMode
ButtonFeatures features
\variable QStyleOption::palette
QFontMetrics fontMetrics
QStyle::State state
QPalette palette
QObject * styleObject
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
@ State_Editing
Definition qstyle.h:89
@ State_Item
Definition qstyle.h:87
@ State_HasFocus
Definition qstyle.h:75
@ State_Active
Definition qstyle.h:83
@ State_Off
Definition qstyle.h:70
@ State_Open
Definition qstyle.h:85
@ State_NoChange
Definition qstyle.h:71
@ State_KeyboardFocusChange
Definition qstyle.h:90
@ State_Enabled
Definition qstyle.h:67
@ State_On
Definition qstyle.h:72
@ State_Selected
Definition qstyle.h:82
static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
Transforms an alignment of Qt::AlignLeft or Qt::AlignRight without Qt::AlignAbsolute into Qt::AlignLe...
Definition qstyle.cpp:2203
static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
Returns a new rectangle of the specified size that is aligned to the given rectangle according to the...
Definition qstyle.cpp:2174
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget=nullptr) const =0
Returns the sub-area for the given element as described in the provided style option.
@ PM_FocusFrameHMargin
Definition qstyle.h:497
@ PE_FrameFocusRect
Definition qstyle.h:106
@ PE_IndicatorItemViewItemCheck
Definition qstyle.h:130
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
@ SE_ItemViewItemCheckIndicator
Definition qstyle.h:275
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
\reentrant
Definition qtextlayout.h:70
QTextLine createLine()
Returns a new text line to be laid out if there is text to be inserted into the layout; otherwise ret...
void beginLayout()
Begins the layout process.
void endLayout()
Ends the layout process.
\reentrant
\reentrant
Definition qtextoption.h:18
\inmodule QtCore
Definition qvariant.h:64
void * data()
Returns a pointer to the contained object as a generic void* that can be written to.
int userType() const
Definition qvariant.h:336
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setFocusPolicy(Qt::FocusPolicy policy)
Definition qwidget.cpp:7904
QStyle * style() const
Definition qwidget.cpp:2607
QOpenGLWidget * widget
[1]
QString text
rect
[4]
QStyleOptionButton opt
else opt state
[0]
QRect textRect
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
CheckState
@ Unchecked
@ Checked
@ PartiallyChecked
@ AlignCenter
Definition qnamespace.h:162
@ LeftButton
Definition qnamespace.h:57
@ LeftToRight
@ RightToLeft
@ WheelFocus
Definition qnamespace.h:110
@ FontRole
@ TextAlignmentRole
@ ForegroundRole
@ DecorationRole
@ BackgroundRole
@ EditRole
@ CheckStateRole
@ DisplayRole
@ SizeHintRole
@ Key_Select
@ Key_Space
Definition qnamespace.h:512
@ ItemIsUserTristate
@ ItemIsUserCheckable
@ ItemIsEnabled
Definition image.cpp:4
static QString wrapText(const QString &names, int optionNameMaxWidth, const QString &description)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define QFIXED_MAX
Definition qfixed_p.h:127
static QString qPixmapSerial(quint64 i, bool enabled)
#define DBL_DIG
#define qWarning
Definition qlogging.h:162
int qCeil(T v)
Definition qmath.h:36
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLbitfield flags
GLuint start
GLfloat n
GLint y
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
GLint void * img
Definition qopenglext.h:233
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static const struct TessellationWindingOrderTab cw[]
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
unsigned long long quint64
Definition qtypes.h:56
unsigned short ushort
Definition qtypes.h:28
double qreal
Definition qtypes.h:92
QSqlQueryModel * model
[16]
QObject::connect nullptr
QVariant variant
[1]
QItemEditorFactory * factory
widget render & pixmap
QPainter painter(this)
[7]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent