368void QItemDelegate::paint(QPainter *painter,
369 const QStyleOptionViewItem &option,
370 const QModelIndex &index)
const
372 Q_D(
const QItemDelegate);
373 Q_ASSERT(index.isValid());
375 QStyleOptionViewItem opt = setOptions(index, option);
380 painter->setClipRect(opt.rect);
387 QRect decorationRect;
388 value = index.data(Qt::DecorationRole);
389 if (value.isValid()) {
391 pixmap = decoration(opt, value);
392 if (value.userType() == QMetaType::QIcon) {
393 d->tmp.icon = qvariant_cast<QIcon>(value);
394 d->tmp.mode = d->iconMode(option.state);
395 d->tmp.state = d->iconState(option.state);
396 const QSize size = d->tmp.icon.actualSize(option.decorationSize,
397 d->tmp.mode, d->tmp.state);
398 decorationRect = QRect(QPoint(0, 0), size);
400 d->tmp.icon = QIcon();
401 decorationRect = QRect(QPoint(0, 0), pixmap.size());
404 d->tmp.icon = QIcon();
405 decorationRect = QRect();
409 Qt::CheckState checkState = Qt::Unchecked;
410 value = index.data(Qt::CheckStateRole);
411 if (value.isValid()) {
412 checkState = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
413 checkRect = doCheck(opt, opt.rect, value);
418 value = index.data(Qt::DisplayRole);
419 if (value.isValid() && !value.isNull()) {
420 text = d->valueToText(value, opt);
421 displayRect = d->displayRect(index, opt, decorationRect, checkRect);
426 doLayout(opt, &checkRect, &decorationRect, &displayRect,
false);
430 drawBackground(painter, opt, index);
431 drawCheck(painter, opt, checkRect, checkState);
432 drawDecoration(painter, opt, decorationRect, pixmap);
433 drawDisplay(painter, opt, displayRect, text);
434 drawFocus(painter, opt, displayRect);
543void QItemDelegate::updateEditorGeometry(QWidget *editor,
544 const QStyleOptionViewItem &option,
545 const QModelIndex &index)
const
549 Q_ASSERT(index.isValid());
550 QPixmap pixmap = decoration(option, index.data(Qt::DecorationRole));
551 QString text = QItemDelegatePrivate::replaceNewLine(index.data(Qt::DisplayRole).toString());
552 QRect pixmapRect = QRect(QPoint(0, 0), option.decorationSize).intersected(pixmap.rect());
553 QRect textRect = textRectangle(
nullptr, option.rect, option.font, text);
554 QRect checkRect = doCheck(option, textRect, index.data(Qt::CheckStateRole));
555 QStyleOptionViewItem opt = option;
556 opt.showDecorationSelected =
true;
557 doLayout(opt, &checkRect, &pixmapRect, &textRect,
false);
558 editor->setGeometry(textRect);
591void QItemDelegate::drawDisplay(QPainter *painter,
const QStyleOptionViewItem &option,
592 const QRect &rect,
const QString &text)
const
594 Q_D(
const QItemDelegate);
596 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
597 ? QPalette::Normal : QPalette::Disabled;
598 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
599 cg = QPalette::Inactive;
600 if (option.state & QStyle::State_Selected) {
601 painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight));
602 painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
604 painter->setPen(option.palette.color(cg, QPalette::Text));
610 if (option.state & QStyle::State_Editing) {
612 painter->setPen(option.palette.color(cg, QPalette::Text));
613 painter->drawRect(rect.adjusted(0, 0, -1, -1));
617 const QStyleOptionViewItem opt = option;
619 const QWidget *widget = d->widget(option);
620 QStyle *style = widget ? widget->style() : QApplication::style();
621 const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin,
nullptr, widget) + 1;
622 QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0);
623 const bool wrapText = opt.features & QStyleOptionViewItem::WrapText;
624 d->textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
625 d->textOption.setTextDirection(option.direction);
626 d->textOption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
627 d->textLayout.setTextOption(d->textOption);
628 d->textLayout.setFont(option.font);
629 d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
631 QSizeF textLayoutSize = d->doTextLayout(textRect.width());
633 if (textRect.width() < textLayoutSize.width()
634 || textRect.height() < textLayoutSize.height()) {
637 int end = text.indexOf(QChar::LineSeparator, start);
639 elided += option.fontMetrics.elidedText(text, option.textElideMode, textRect.width());
642 elided += option.fontMetrics.elidedText(text.mid(start, end - start),
643 option.textElideMode, textRect.width());
644 elided += QChar::LineSeparator;
646 end = text.indexOf(QChar::LineSeparator, start);
649 elided += option.fontMetrics.elidedText(text.mid(start),
650 option.textElideMode, textRect.width());
652 d->textLayout.setText(elided);
653 textLayoutSize = d->doTextLayout(textRect.width());
656 const QSize layoutSize(textRect.width(),
int(textLayoutSize.height()));
657 const QRect layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment,
658 layoutSize, textRect);
660 if (!hasClipping() && (textRect.width() < textLayoutSize.width()
661 || textRect.height() < textLayoutSize.height())) {
663 painter->setClipRect(layoutRect);
664 d->textLayout.draw(painter, layoutRect.topLeft(), QList<QTextLayout::FormatRange>(),
668 d->textLayout.draw(painter, layoutRect.topLeft(), QList<QTextLayout::FormatRange>(),
677void QItemDelegate::drawDecoration(QPainter *painter,
const QStyleOptionViewItem &option,
678 const QRect &rect,
const QPixmap &pixmap)
const
680 Q_D(
const QItemDelegate);
682 if (!d->tmp.icon.isNull()) {
683 d->tmp.icon.paint(painter, rect, option.decorationAlignment,
684 d->tmp.mode, d->tmp.state);
688 if (pixmap.isNull() || !rect.isValid())
690 QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment,
691 pixmap.size(), rect).topLeft();
692 if (option.state & QStyle::State_Selected) {
693 const QPixmap pm = selectedPixmap(pixmap, option.palette, option.state & QStyle::State_Enabled);
694 painter->drawPixmap(p, pm);
696 painter->drawPixmap(p, pixmap);
794void QItemDelegate::doLayout(
const QStyleOptionViewItem &option,
795 QRect *checkRect, QRect *pixmapRect, QRect *textRect,
798 Q_ASSERT(checkRect && pixmapRect && textRect);
799 Q_D(
const QItemDelegate);
800 const QWidget *widget = d->widget(option);
801 QStyle *style = widget ? widget->style() : QApplication::style();
802 const bool hasCheck = checkRect->isValid();
803 const bool hasPixmap = pixmapRect->isValid();
804 const bool hasText = textRect->isValid();
805 const bool hasMargin = (hasText | hasPixmap | hasCheck);
806 const int frameHMargin = hasMargin ?
807 style->pixelMetric(QStyle::PM_FocusFrameHMargin,
nullptr, widget) + 1 : 0;
808 const int textMargin = hasText ? frameHMargin : 0;
809 const int pixmapMargin = hasPixmap ? frameHMargin : 0;
810 const int checkMargin = hasCheck ? frameHMargin : 0;
811 const int x = option.rect.left();
812 const int y = option.rect.top();
815 textRect->adjust(-textMargin, 0, textMargin, 0);
816 if (textRect->height() == 0 && (!hasPixmap || !hint)) {
818 textRect->setHeight(option.fontMetrics.height());
823 pm = pixmapRect->size();
824 pm.rwidth() += 2 * pixmapMargin;
827 h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
828 if (option.decorationPosition == QStyleOptionViewItem::Left
829 || option.decorationPosition == QStyleOptionViewItem::Right) {
830 w = textRect->width() + pm.width();
832 w = qMax(textRect->width(), pm.width());
835 w = option.rect.width();
836 h = option.rect.height();
842 cw = checkRect->width() + 2 * checkMargin;
844 if (option.direction == Qt::RightToLeft) {
845 check.setRect(x + w - cw, y, cw, h);
847 check.setRect(x, y, cw, h);
855 switch (option.decorationPosition) {
856 case QStyleOptionViewItem::Top: {
858 pm.setHeight(pm.height() + pixmapMargin);
859 h = hint ? textRect->height() : h - pm.height();
861 if (option.direction == Qt::RightToLeft) {
862 decoration.setRect(x, y, w - cw, pm.height());
863 display.setRect(x, y + pm.height(), w - cw, h);
865 decoration.setRect(x + cw, y, w - cw, pm.height());
866 display.setRect(x + cw, y + pm.height(), w - cw, h);
869 case QStyleOptionViewItem::Bottom: {
871 textRect->setHeight(textRect->height() + textMargin);
872 h = hint ? textRect->height() + pm.height() : h;
874 if (option.direction == Qt::RightToLeft) {
875 display.setRect(x, y, w - cw, textRect->height());
876 decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
878 display.setRect(x + cw, y, w - cw, textRect->height());
879 decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
882 case QStyleOptionViewItem::Left: {
883 if (option.direction == Qt::LeftToRight) {
884 decoration.setRect(x + cw, y, pm.width(), h);
885 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
887 display.setRect(x, y, w - pm.width() - cw, h);
888 decoration.setRect(display.right() + 1, y, pm.width(), h);
891 case QStyleOptionViewItem::Right: {
892 if (option.direction == Qt::LeftToRight) {
893 display.setRect(x + cw, y, w - pm.width() - cw, h);
894 decoration.setRect(display.right() + 1, y, pm.width(), h);
896 decoration.setRect(x, y, pm.width(), h);
897 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
901 qWarning(
"doLayout: decoration position is invalid");
902 decoration = *pixmapRect;
907 *checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
908 checkRect->size(), check);
909 *pixmapRect = QStyle::alignedRect(option.direction, option.decorationAlignment,
910 pixmapRect->size(), decoration);
912 if (option.showDecorationSelected)
915 *textRect = QStyle::alignedRect(option.direction, option.displayAlignment,
916 textRect->size().boundedTo(display.size()), display);
919 *pixmapRect = decoration;
1005QRect QItemDelegate::rect(
const QStyleOptionViewItem &option,
1006 const QModelIndex &index,
int role)
const
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()) {
1014 case QMetaType::UnknownType:
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:
1032 const QString text = d->valueToText(value, option);
1033 value = index.data(Qt::FontRole);
1034 QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
1035 return textRectangle(
nullptr,
1036 d->textLayoutBounds(option, QRect(), QRect()),
1094bool QItemDelegate::editorEvent(QEvent *event,
1095 QAbstractItemModel *model,
1096 const QStyleOptionViewItem &option,
1097 const QModelIndex &index)
1103 Qt::ItemFlags flags = model->flags(index);
1104 if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
1105 || !(flags & Qt::ItemIsEnabled))
1109 QVariant value = index.data(Qt::CheckStateRole);
1110 if (!value.isValid())
1114 if ((event->type() == QEvent::MouseButtonRelease)
1115 || (event->type() == QEvent::MouseButtonDblClick)
1116 || (event->type() == QEvent::MouseButtonPress)) {
1117 QRect checkRect = doCheck(option, option.rect, Qt::Checked);
1119 doLayout(option, &checkRect, &emptyRect, &emptyRect,
false);
1120 QMouseEvent *me =
static_cast<QMouseEvent*>(event);
1121 if (me->button() != Qt::LeftButton || !checkRect.contains(me->position().toPoint()))
1125 if ((event->type() == QEvent::MouseButtonPress)
1126 || (event->type() == QEvent::MouseButtonDblClick))
1129 }
else if (event->type() == QEvent::KeyPress) {
1130 if (
static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
1131 &&
static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
1137 Qt::CheckState state = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
1138 if (flags & Qt::ItemIsUserTristate)
1139 state = ((Qt::CheckState)((state + 1) % 3));
1141 state = (state == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
1142 return model->setData(index, state, Qt::CheckStateRole);