summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/styles/qfusionstyle.cpp8
-rw-r--r--src/widgets/widgets/qcombobox.cpp59
-rw-r--r--src/widgets/widgets/qcombobox_p.h7
3 files changed, 69 insertions, 5 deletions
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index 49b3703189..03d083bbf1 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -1590,7 +1590,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
(option->styleObject && option->styleObject->property("_q_isComboBoxPopupItem").toBool()))
ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
- if (!ignoreCheckMark) {
+ if (!ignoreCheckMark || menuItem->state & (State_On | State_Off)) {
// Check, using qreal and QRectF to avoid error accumulation
const qreal boxMargin = dpiScaled(3.5, option);
const qreal boxWidth = checkcol - 2 * boxMargin;
@@ -1601,7 +1601,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (checkable) {
if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
// Radio button
- if (checked || sunken) {
+ if (menuItem->state & State_On || checked || sunken) {
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(Qt::NoPen);
@@ -1617,8 +1617,10 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QStyleOptionButton box;
box.QStyleOption::operator=(*option);
box.rect = checkRect;
- if (checked)
+ if (checked || menuItem->state & State_On)
box.state |= State_On;
+ else
+ box.state |= State_Off;
proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
}
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 19b442f477..4cfa5554e4 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -129,7 +129,15 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
if (option.state & QStyle::State_Selected)
menuOption.state |= QStyle::State_Selected;
menuOption.checkType = QStyleOptionMenuItem::NonExclusive;
- menuOption.checked = mCombo->currentIndex() == index.row();
+ // a valid checkstate means that the model has checkable items
+ const QVariant checkState = index.data(Qt::CheckStateRole);
+ if (!checkState.isValid()) {
+ menuOption.checked = mCombo->currentIndex() == index.row();
+ } else {
+ menuOption.checked = qvariant_cast<int>(checkState) == Qt::Checked;
+ menuOption.state |= qvariant_cast<int>(checkState) == Qt::Checked
+ ? QStyle::State_On : QStyle::State_Off;
+ }
if (QComboBoxDelegate::isSeparator(index))
menuOption.menuItemType = QStyleOptionMenuItem::Separator;
else
@@ -179,6 +187,55 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
return menuOption;
}
+bool QComboMenuDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+ Q_ASSERT(event);
+ Q_ASSERT(model);
+
+ // make sure that the item is checkable
+ Qt::ItemFlags flags = model->flags(index);
+ if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
+ || !(flags & Qt::ItemIsEnabled))
+ return false;
+
+ // make sure that we have a check state
+ const QVariant checkState = index.data(Qt::CheckStateRole);
+ if (!checkState.isValid())
+ return false;
+
+ // make sure that we have the right event type
+ if ((event->type() == QEvent::MouseButtonRelease)
+ || (event->type() == QEvent::MouseButtonDblClick)
+ || (event->type() == QEvent::MouseButtonPress)) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ if (me->button() != Qt::LeftButton)
+ return false;
+
+ if ((event->type() == QEvent::MouseButtonPress)
+ || (event->type() == QEvent::MouseButtonDblClick)) {
+ pressedIndex = index.row();
+ return false;
+ }
+
+ if (index.row() != pressedIndex)
+ return false;
+ pressedIndex = -1;
+
+ } else if (event->type() == QEvent::KeyPress) {
+ if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
+ && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
+ return false;
+ } else {
+ return false;
+ }
+
+ // we don't support user-tristate items in QComboBox (not implemented in any style)
+ Qt::CheckState newState = (static_cast<Qt::CheckState>(checkState.toInt()) == Qt::Checked)
+ ? Qt::Unchecked : Qt::Checked;
+ return model->setData(index, newState, Qt::CheckStateRole);
+}
+
#if QT_CONFIG(completer)
void QComboBoxPrivate::_q_completerActivated(const QModelIndex &index)
{
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index c79406eafd..7a3fcf6e0f 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -266,7 +266,9 @@ class Q_AUTOTEST_EXPORT QComboMenuDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
- QComboMenuDelegate(QObject *parent, QComboBox *cmb) : QAbstractItemDelegate(parent), mCombo(cmb) {}
+ QComboMenuDelegate(QObject *parent, QComboBox *cmb)
+ : QAbstractItemDelegate(parent), mCombo(cmb), pressedIndex(-1)
+ {}
protected:
void paint(QPainter *painter,
@@ -282,11 +284,14 @@ protected:
return mCombo->style()->sizeFromContents(
QStyle::CT_MenuItem, &opt, option.rect.size(), mCombo);
}
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index) override;
private:
QStyleOptionMenuItem getStyleOption(const QStyleOptionViewItem &option,
const QModelIndex &index) const;
QComboBox *mCombo;
+ int pressedIndex;
};
// ### Qt6: QStyledItemDelegate ?