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
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 {
62 text.replace(u'\n', QChar::LineSeparator);
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
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
306
314
326{
327 Q_D(const QItemDelegate);
328 return d->clipPainting;
329}
330
332{
333 Q_D(QItemDelegate);
334 d->clipPainting = clip;
335}
336
337QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) const
338{
340}
341
367 const QStyleOptionViewItem &option,
368 const QModelIndex &index) const
369{
370 Q_D(const QItemDelegate);
371 Q_ASSERT(index.isValid());
372
373 QStyleOptionViewItem opt = setOptions(index, option);
374
375 // prepare
376 painter->save();
377 if (d->clipPainting)
379
380 // get the data and the rectangles
381
383
385 QRect decorationRect;
387 if (value.isValid()) {
388 // ### we need the pixmap to call the virtual function
390 if (value.userType() == QMetaType::QIcon) {
391 d->tmp.icon = qvariant_cast<QIcon>(value);
392 d->tmp.mode = d->iconMode(option.state);
393 d->tmp.state = d->iconState(option.state);
394 const QSize size = d->tmp.icon.actualSize(option.decorationSize,
395 d->tmp.mode, d->tmp.state);
396 decorationRect = QRect(QPoint(0, 0), size);
397 } else {
398 d->tmp.icon = QIcon();
399 decorationRect = QRect(QPoint(0, 0), pixmap.size());
400 }
401 } else {
402 d->tmp.icon = QIcon();
403 decorationRect = QRect();
404 }
405
406 QRect checkRect;
409 if (value.isValid()) {
410 checkState = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
411 checkRect = doCheck(opt, opt.rect, value);
412 }
413
415 QRect displayRect;
417 if (value.isValid() && !value.isNull()) {
418 text = d->valueToText(value, opt);
419 displayRect = d->displayRect(index, opt, decorationRect, checkRect);
420 }
421
422 // do the layout
423
424 doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
425
426 // draw the item
427
429 drawCheck(painter, opt, checkRect, checkState);
430 drawDecoration(painter, opt, decorationRect, pixmap);
431 drawDisplay(painter, opt, displayRect, text);
432 drawFocus(painter, opt, displayRect);
433
434 // done
435 painter->restore();
436}
437
448QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
449 const QModelIndex &index) const
450{
451 Q_D(const QItemDelegate);
453 if (value.isValid())
454 return qvariant_cast<QSize>(value);
455 QRect decorationRect = rect(option, index, Qt::DecorationRole);
457 QRect displayRect = d->displayRect(index, option, decorationRect, checkRect);
458
459 doLayout(option, &checkRect, &decorationRect, &displayRect, true);
460
461 return (decorationRect|displayRect|checkRect).size();
462}
463
473 const QStyleOptionViewItem &,
474 const QModelIndex &index) const
475{
476 Q_D(const QItemDelegate);
477 if (!index.isValid())
478 return nullptr;
479 const QItemEditorFactory *factory = d->f;
480 if (factory == nullptr)
482 QWidget *w = factory->createEditor(index.data(Qt::EditRole).userType(), parent);
483 if (w)
484 w->setFocusPolicy(Qt::WheelFocus);
485 return w;
486}
487
499{
501 QByteArray n = editor->metaObject()->userProperty().name();
502
503 if (!n.isEmpty()) {
504 if (!v.isValid())
505 v = QVariant(editor->property(n).metaType());
506 editor->setProperty(n, v);
507 }
508}
509
523 const QModelIndex &index) const
524{
525 Q_D(const QItemDelegate);
527 Q_ASSERT(editor);
528 QByteArray n = editor->metaObject()->userProperty().name();
529 if (n.isEmpty())
530 n = d->editorFactory()->valuePropertyName(
532 if (!n.isEmpty())
533 model->setData(index, editor->property(n), Qt::EditRole);
534}
535
542 const QStyleOptionViewItem &option,
543 const QModelIndex &index) const
544{
545 if (!editor)
546 return;
547 Q_ASSERT(index.isValid());
550 QRect pixmapRect = QRect(QPoint(0, 0), option.decorationSize).intersected(pixmap.rect());
551 QRect textRect = textRectangle(nullptr, option.rect, option.font, text);
553 QStyleOptionViewItem opt = option;
554 opt.showDecorationSelected = true; // let the editor take up all available space
555 doLayout(opt, &checkRect, &pixmapRect, &textRect, false);
556 editor->setGeometry(textRect);
557}
558
566{
567 Q_D(const QItemDelegate);
568 return d->f;
569}
570
583
589void QItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
590 const QRect &rect, const QString &text) const
591{
592 Q_D(const QItemDelegate);
593
596 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
598 if (option.state & QStyle::State_Selected) {
599 painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight));
600 painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
601 } else {
602 painter->setPen(option.palette.color(cg, QPalette::Text));
603 }
604
605 if (text.isEmpty())
606 return;
607
608 if (option.state & QStyle::State_Editing) {
609 painter->save();
610 painter->setPen(option.palette.color(cg, QPalette::Text));
611 painter->drawRect(rect.adjusted(0, 0, -1, -1));
612 painter->restore();
613 }
614
615 const QStyleOptionViewItem opt = option;
616
617 const QWidget *widget = d->widget(option);
618 QStyle *style = widget ? widget->style() : QApplication::style();
619 const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1;
620 QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
621 const bool wrapText = opt.features & QStyleOptionViewItem::WrapText;
622 d->textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
623 d->textOption.setTextDirection(option.direction);
624 d->textOption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
625 d->textLayout.setTextOption(d->textOption);
626 d->textLayout.setFont(option.font);
627 d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
628
629 QSizeF textLayoutSize = d->doTextLayout(textRect.width());
630
631 if (textRect.width() < textLayoutSize.width()
632 || textRect.height() < textLayoutSize.height()) {
633 QString elided;
634 int start = 0;
635 int end = text.indexOf(QChar::LineSeparator, start);
636 if (end == -1) {
637 elided += option.fontMetrics.elidedText(text, option.textElideMode, textRect.width());
638 } else {
639 while (end != -1) {
640 elided += option.fontMetrics.elidedText(text.mid(start, end - start),
641 option.textElideMode, textRect.width());
642 elided += QChar::LineSeparator;
643 start = end + 1;
644 end = text.indexOf(QChar::LineSeparator, start);
645 }
646 //let's add the last line (after the last QChar::LineSeparator)
647 elided += option.fontMetrics.elidedText(text.mid(start),
648 option.textElideMode, textRect.width());
649 }
650 d->textLayout.setText(elided);
651 textLayoutSize = d->doTextLayout(textRect.width());
652 }
653
654 const QSize layoutSize(textRect.width(), int(textLayoutSize.height()));
655 const QRect layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment,
656 layoutSize, textRect);
657 // if we still overflow even after eliding the text, enable clipping
658 if (!hasClipping() && (textRect.width() < textLayoutSize.width()
659 || textRect.height() < textLayoutSize.height())) {
660 painter->save();
661 painter->setClipRect(layoutRect);
662 d->textLayout.draw(painter, layoutRect.topLeft(), QList<QTextLayout::FormatRange>(),
663 layoutRect);
664 painter->restore();
665 } else {
666 d->textLayout.draw(painter, layoutRect.topLeft(), QList<QTextLayout::FormatRange>(),
667 layoutRect);
668 }
669}
670
675void QItemDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
676 const QRect &rect, const QPixmap &pixmap) const
677{
678 Q_D(const QItemDelegate);
679 // if we have an icon, we ignore the pixmap
680 if (!d->tmp.icon.isNull()) {
681 d->tmp.icon.paint(painter, rect, option.decorationAlignment,
682 d->tmp.mode, d->tmp.state);
683 return;
684 }
685
686 if (pixmap.isNull() || !rect.isValid())
687 return;
688 QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment,
689 pixmap.size(), rect).topLeft();
690 if (option.state & QStyle::State_Selected) {
691 const QPixmap pm = selectedPixmap(pixmap, option.palette, option.state & QStyle::State_Enabled);
692 painter->drawPixmap(p, pm);
693 } else {
695 }
696}
697
704 const QStyleOptionViewItem &option,
705 const QRect &rect) const
706{
707 Q_D(const QItemDelegate);
708 if ((option.state & QStyle::State_HasFocus) == 0 || !rect.isValid())
709 return;
711 o.QStyleOption::operator=(option);
712 o.rect = rect;
714 o.state |= QStyle::State_Item;
717 o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected)
719 const QWidget *widget = d->widget(option);
720 QStyle *style = widget ? widget->style() : QApplication::style();
722}
723
731 const QStyleOptionViewItem &option,
732 const QRect &rect, Qt::CheckState state) const
733{
734 Q_D(const QItemDelegate);
735 if (!rect.isValid())
736 return;
737
738 QStyleOptionViewItem opt(option);
739 opt.rect = rect;
740 opt.state = opt.state & ~QStyle::State_HasFocus;
741
742 switch (state) {
743 case Qt::Unchecked:
745 break;
748 break;
749 case Qt::Checked:
751 break;
752 }
753
754 const QWidget *widget = d->widget(option);
755 QStyle *style = widget ? widget->style() : QApplication::style();
757}
758
767 const QStyleOptionViewItem &option,
768 const QModelIndex &index) const
769{
770 if (option.showDecorationSelected && (option.state & QStyle::State_Selected)) {
773 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
775
776 painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
777 } else {
779 if (value.canConvert<QBrush>()) {
780 QPointF oldBO = painter->brushOrigin();
781 painter->setBrushOrigin(option.rect.topLeft());
782 painter->fillRect(option.rect, qvariant_cast<QBrush>(value));
783 painter->setBrushOrigin(oldBO);
784 }
785 }
786}
787
788
795void QItemDelegate::doLayout(const QStyleOptionViewItem &option,
796 QRect *checkRect, QRect *pixmapRect, QRect *textRect,
797 bool hint) const
798{
799 Q_ASSERT(checkRect && pixmapRect && textRect);
800 Q_D(const QItemDelegate);
801 const QWidget *widget = d->widget(option);
802 QStyle *style = widget ? widget->style() : QApplication::style();
803 const bool hasCheck = checkRect->isValid();
804 const bool hasPixmap = pixmapRect->isValid();
805 const bool hasText = textRect->isValid();
806 const bool hasMargin = (hasText | hasPixmap | hasCheck);
807 const int frameHMargin = hasMargin ?
808 style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1 : 0;
809 const int textMargin = hasText ? frameHMargin : 0;
810 const int pixmapMargin = hasPixmap ? frameHMargin : 0;
811 const int checkMargin = hasCheck ? frameHMargin : 0;
812 const int x = option.rect.left();
813 const int y = option.rect.top();
814 int w, h;
815
816 textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding
817 if (textRect->height() == 0 && (!hasPixmap || !hint)) {
818 //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
819 textRect->setHeight(option.fontMetrics.height());
820 }
821
822 QSize pm(0, 0);
823 if (hasPixmap) {
824 pm = pixmapRect->size();
825 pm.rwidth() += 2 * pixmapMargin;
826 }
827 if (hint) {
828 h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
829 if (option.decorationPosition == QStyleOptionViewItem::Left
830 || option.decorationPosition == QStyleOptionViewItem::Right) {
831 w = textRect->width() + pm.width();
832 } else {
833 w = qMax(textRect->width(), pm.width());
834 }
835 } else {
836 w = option.rect.width();
837 h = option.rect.height();
838 }
839
840 int cw = 0;
841 QRect check;
842 if (hasCheck) {
843 cw = checkRect->width() + 2 * checkMargin;
844 if (hint) w += cw;
845 if (option.direction == Qt::RightToLeft) {
846 check.setRect(x + w - cw, y, cw, h);
847 } else {
848 check.setRect(x, y, cw, h);
849 }
850 }
851
852 // at this point w should be the *total* width
853
856 switch (option.decorationPosition) {
857 case QStyleOptionViewItem::Top: {
858 if (hasPixmap)
859 pm.setHeight(pm.height() + pixmapMargin); // add space
860 h = hint ? textRect->height() : h - pm.height();
861
862 if (option.direction == Qt::RightToLeft) {
863 decoration.setRect(x, y, w - cw, pm.height());
864 display.setRect(x, y + pm.height(), w - cw, h);
865 } else {
866 decoration.setRect(x + cw, y, w - cw, pm.height());
867 display.setRect(x + cw, y + pm.height(), w - cw, h);
868 }
869 break; }
870 case QStyleOptionViewItem::Bottom: {
871 if (hasText)
872 textRect->setHeight(textRect->height() + textMargin); // add space
873 h = hint ? textRect->height() + pm.height() : h;
874
875 if (option.direction == Qt::RightToLeft) {
876 display.setRect(x, y, w - cw, textRect->height());
877 decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
878 } else {
879 display.setRect(x + cw, y, w - cw, textRect->height());
880 decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
881 }
882 break; }
883 case QStyleOptionViewItem::Left: {
884 if (option.direction == Qt::LeftToRight) {
885 decoration.setRect(x + cw, y, pm.width(), h);
886 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
887 } else {
888 display.setRect(x, y, w - pm.width() - cw, h);
889 decoration.setRect(display.right() + 1, y, pm.width(), h);
890 }
891 break; }
892 case QStyleOptionViewItem::Right: {
893 if (option.direction == Qt::LeftToRight) {
894 display.setRect(x + cw, y, w - pm.width() - cw, h);
895 decoration.setRect(display.right() + 1, y, pm.width(), h);
896 } else {
897 decoration.setRect(x, y, pm.width(), h);
898 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
899 }
900 break; }
901 default:
902 qWarning("doLayout: decoration position is invalid");
903 decoration = *pixmapRect;
904 break;
905 }
906
907 if (!hint) { // we only need to do the internal layout if we are going to paint
908 *checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
909 checkRect->size(), check);
910 *pixmapRect = QStyle::alignedRect(option.direction, option.decorationAlignment,
911 pixmapRect->size(), decoration);
912 // the text takes up all available space, unless the decoration is not shown as selected
913 if (option.showDecorationSelected)
914 *textRect = display;
915 else
916 *textRect = QStyle::alignedRect(option.direction, option.displayAlignment,
917 textRect->size().boundedTo(display.size()), display);
918 } else {
919 *checkRect = check;
920 *pixmapRect = decoration;
921 *textRect = display;
922 }
923}
924
933QPixmap QItemDelegate::decoration(const QStyleOptionViewItem &option, const QVariant &variant) const
934{
935 Q_D(const QItemDelegate);
936 switch (variant.userType()) {
937 case QMetaType::QIcon: {
938 QIcon::Mode mode = d->iconMode(option.state);
939 QIcon::State state = d->iconState(option.state);
940 return qvariant_cast<QIcon>(variant).pixmap(option.decorationSize, mode, state); }
941 case QMetaType::QColor: {
942 static QPixmap pixmap(option.decorationSize);
943 pixmap.fill(qvariant_cast<QColor>(variant));
944 return pixmap; }
945 default:
946 break;
947 }
948
949 return qvariant_cast<QPixmap>(variant);
950}
951
952// hacky but faster version of "QString::asprintf("%d-%d", i, enabled)"
954{
955 ushort arr[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', ushort('0' + enabled) };
956 ushort *ptr = &arr[16];
957
958 while (i > 0) {
959 // hey - it's our internal representation, so use the ascii character after '9'
960 // instead of 'a' for hex
961 *(--ptr) = '0' + i % 16;
962 i >>= 4;
963 }
964
965 return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
966}
967
968
976{
977 const QString key = qPixmapSerial(pixmap.cacheKey(), enabled);
978 QPixmap pm;
979 if (!QPixmapCache::find(key, &pm)) {
981
984 color.setAlphaF(0.3f);
985
988 painter.fillRect(0, 0, img.width(), img.height(), color);
989 painter.end();
990
992 const int n = (img.sizeInBytes() >> 10) + 1;
995
997 }
998 return pm;
999}
1000
1005QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
1006 const QModelIndex &index, int role) const
1007{
1008 Q_D(const QItemDelegate);
1009 QVariant value = index.data(role);
1010 if (role == Qt::CheckStateRole)
1011 return doCheck(option, option.rect, value);
1012 if (value.isValid() && !value.isNull()) {
1013 switch (value.userType()) {
1015 break;
1016 case QMetaType::QPixmap: {
1017 const QPixmap &pixmap = qvariant_cast<QPixmap>(value);
1018 return QRect(QPoint(0, 0), pixmap.deviceIndependentSize().toSize()); }
1019 case QMetaType::QImage: {
1020 const QImage &image = qvariant_cast<QImage>(value);
1021 return QRect(QPoint(0, 0), image.deviceIndependentSize().toSize()); }
1022 case QMetaType::QIcon: {
1023 QIcon::Mode mode = d->iconMode(option.state);
1024 QIcon::State state = d->iconState(option.state);
1025 QIcon icon = qvariant_cast<QIcon>(value);
1026 QSize size = icon.actualSize(option.decorationSize, mode, state);
1027 return QRect(QPoint(0, 0), size); }
1028 case QMetaType::QColor:
1029 return QRect(QPoint(0, 0), option.decorationSize);
1030 case QMetaType::QString:
1031 default: {
1032 const QString text = d->valueToText(value, option);
1034 QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
1035 return textRectangle(nullptr,
1036 d->textLayoutBounds(option, QRect(), QRect()),
1037 fnt, text); }
1038 }
1039 }
1040 return QRect();
1041}
1042
1046QRect QItemDelegate::doCheck(const QStyleOptionViewItem &option,
1047 const QRect &bounding, const QVariant &value) const
1048{
1049 if (value.isValid()) {
1050 Q_D(const QItemDelegate);
1052 opt.QStyleOption::operator=(option);
1053 opt.rect = bounding;
1054 const QWidget *widget = d->widget(option); // cast
1055 QStyle *style = widget ? widget->style() : QApplication::style();
1057 }
1058 return QRect();
1059}
1060
1065 const QFont &font, const QString &text) const
1066{
1067 Q_D(const QItemDelegate);
1068 d->textOption.setWrapMode(QTextOption::WordWrap);
1069 d->textLayout.setTextOption(d->textOption);
1070 d->textLayout.setFont(font);
1071 d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
1072 QSizeF fpSize = d->doTextLayout(rect.width());
1073 const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height()));
1074 // ###: textRectangle should take style option as argument
1075 const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1;
1076 return QRect(0, 0, size.width() + 2 * textMargin, size.height());
1077}
1078
1108{
1109 Q_D(QItemDelegate);
1110 return d->editorEventFilter(object, event);
1111}
1112
1119 const QStyleOptionViewItem &option,
1120 const QModelIndex &index)
1121{
1122 Q_ASSERT(event);
1123 Q_ASSERT(model);
1124
1125 // make sure that the item is checkable
1126 Qt::ItemFlags flags = model->flags(index);
1128 || !(flags & Qt::ItemIsEnabled))
1129 return false;
1130
1131 // make sure that we have a check state
1133 if (!value.isValid())
1134 return false;
1135
1136 // make sure that we have the right event type
1137 if ((event->type() == QEvent::MouseButtonRelease)
1138 || (event->type() == QEvent::MouseButtonDblClick)
1139 || (event->type() == QEvent::MouseButtonPress)) {
1140 QRect checkRect = doCheck(option, option.rect, Qt::Checked);
1141 QRect emptyRect;
1142 doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
1143 QMouseEvent *me = static_cast<QMouseEvent*>(event);
1144 if (me->button() != Qt::LeftButton || !checkRect.contains(me->position().toPoint()))
1145 return false;
1146
1147 // eat the double click events inside the check rect
1148 if ((event->type() == QEvent::MouseButtonPress)
1149 || (event->type() == QEvent::MouseButtonDblClick))
1150 return true;
1151
1152 } else if (event->type() == QEvent::KeyPress) {
1153 if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
1154 && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
1155 return false;
1156 } else {
1157 return false;
1158 }
1159
1160 Qt::CheckState state = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
1162 state = ((Qt::CheckState)((state + 1) % 3));
1163 else
1166}
1167
1172QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
1173 const QStyleOptionViewItem &option) const
1174{
1175 QStyleOptionViewItem opt = option;
1176
1177 // set font
1179 if (value.isValid()){
1180 opt.font = qvariant_cast<QFont>(value).resolve(opt.font);
1182 }
1183
1184 // set text alignment
1186 if (value.isValid())
1187 opt.displayAlignment = QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(value);
1188
1189 // set foreground brush
1191 if (value.canConvert<QBrush>())
1192 opt.palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
1193
1194 // disable style animations for checkboxes etc. within itemviews (QTBUG-30146)
1195 opt.styleObject = nullptr;
1196
1197 return opt;
1198}
1199
1201
1202#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
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
void setAlphaF(float alpha)
Sets the alpha of this color to alpha.
Definition qcolor.cpp:1511
\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:22
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:1893
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:926
\inmodule QtGui
Definition qimage.h:37
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const &
Definition qimage.h:125
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:424
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:434
\inmodule QtCore
\inmodule QtGui
Definition qevent.h:196
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
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:151
ColorGroup
\value Disabled \value Active \value Inactive \value Normal synonym for Active
Definition qpalette.h:49
@ Inactive
Definition qpalette.h:49
@ Disabled
Definition qpalette.h:49
@ HighlightedText
Definition qpalette.h:53
@ Highlight
Definition qpalette.h:53
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:1437
\inmodule QtCore\reentrant
Definition qpoint.h:217
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:404
\inmodule QtCore\reentrant
Definition qpoint.h:25
\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:373
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
Definition qrect.h:170
QRect intersected(const QRect &other) const noexcept
Definition qrect.h:415
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:221
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
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:346
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr void setHeight(int h) noexcept
Sets the height of the rectangle to the given height.
Definition qrect.h:384
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:119
Qt::MouseButton button() const
Returns the button that caused the event.
Definition qevent.h:116
\inmodule QtCore
Definition qsize.h:208
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr int & rwidth() noexcept
Returns a reference to the width.
Definition qsize.h:154
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
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:129
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4517
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3824
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
\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:2202
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:2173
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:499
@ 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:65
void * data()
Returns a pointer to the contained object as a generic void* that can be written to.
int userType() const
Definition qvariant.h:339
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QStyle * style() const
Definition qwidget.cpp:2600
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:163
@ LeftButton
Definition qnamespace.h:58
@ LeftToRight
@ RightToLeft
@ WheelFocus
Definition qnamespace.h:111
@ FontRole
@ TextAlignmentRole
@ ForegroundRole
@ DecorationRole
@ BackgroundRole
@ EditRole
@ CheckStateRole
@ DisplayRole
@ SizeHintRole
@ Key_Select
@ Key_Space
Definition qnamespace.h:513
@ 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:166
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
GLuint color
[2]
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:61
unsigned short ushort
Definition qtypes.h:33
double qreal
Definition qtypes.h:187
QSqlQueryModel * model
[16]
QObject::connect nullptr
QVariant variant
[1]
QItemEditorFactory * factory
widget render & pixmap
QPainter painter(this)
[7]