diff options
-rw-r--r-- | src/gui/text/qcssparser.cpp | 32 | ||||
-rw-r--r-- | src/gui/text/qcssparser_p.h | 2 | ||||
-rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac.mm | 2 | ||||
-rw-r--r-- | src/plugins/styles/windowsvista/qwindowsvistastyle.cpp | 2 | ||||
-rw-r--r-- | src/widgets/doc/snippets/javastyle.cpp | 2 | ||||
-rw-r--r-- | src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc | 17 | ||||
-rw-r--r-- | src/widgets/itemviews/qtableview.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.cpp | 16 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout_p.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qshortcut.cpp | 74 | ||||
-rw-r--r-- | src/widgets/kernel/qshortcut.h | 60 | ||||
-rw-r--r-- | src/widgets/styles/qcommonstyle.cpp | 2 | ||||
-rw-r--r-- | src/widgets/styles/qfusionstyle.cpp | 2 | ||||
-rw-r--r-- | src/widgets/styles/qstyle.cpp | 2 | ||||
-rw-r--r-- | src/widgets/styles/qstylesheetstyle.cpp | 51 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp | 40 |
16 files changed, 271 insertions, 37 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index ce7c7610c1..793ef5774b 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -123,6 +123,7 @@ static const QCssKnownValue properties[NumProperties - 1] = { { "font-variant", FontVariant }, { "font-weight", FontWeight }, { "height", Height }, + { "icon", QtIcon }, { "image", QtImage }, { "image-position", QtImageAlignment }, { "left", Left }, @@ -1379,6 +1380,37 @@ bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size) return hit; } +bool ValueExtractor::extractIcon(QIcon *icon, QSize *size) +{ + // Find last declaration that specifies an icon + const auto declaration = std::find_if( + declarations.rbegin(), declarations.rend(), + [](const Declaration &decl) { return decl.d->propertyId == QtIcon; }); + if (declaration == declarations.rend()) + return false; + + *icon = declaration->iconValue(); + + // If the value contains a URI, try to get the size of the icon + if (declaration->d->values.isEmpty()) + return true; + + const auto &propertyValue = declaration->d->values.constFirst(); + if (propertyValue.type != Value::Uri) + return true; + + // First try to read just the size from the image without loading it + const QString url(propertyValue.variant.toString()); + QImageReader imageReader(url); + *size = imageReader.size(); + if (!size->isNull()) + return true; + + // Get the size by loading the image instead + *size = imageReader.read().size(); + return true; +} + /////////////////////////////////////////////////////////////////////////////// // Declaration QColor Declaration::colorValue(const QPalette &pal) const diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index ab85e76cf3..b8bf259dda 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -198,6 +198,7 @@ enum Property { QtLineHeightType, FontKerning, QtForegroundTextureCacheKey, + QtIcon, NumProperties }; @@ -855,6 +856,7 @@ struct Q_GUI_EXPORT ValueExtractor bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg); int extractStyleFeatures(); bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size); + bool extractIcon(QIcon *icon, QSize *size); int lengthValue(const Declaration &decl); diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 610329a350..603c6e93f3 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -2873,7 +2873,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w ret = false; break; case SH_Table_GridLineColor: - ret = int(qt_mac_toQColor(NSColor.gridColor).rgb()); + ret = int(qt_mac_toQColor(NSColor.gridColor).rgba()); break; default: ret = QCommonStyle::styleHint(sh, opt, w, hret); diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index e213d65946..345267c8fc 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -2110,7 +2110,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co break; case SH_Table_GridLineColor: if (option) - ret = int(option->palette.color(QPalette::Base).darker(118).rgb()); + ret = int(option->palette.color(QPalette::Base).darker(118).rgba()); else ret = -1; break; diff --git a/src/widgets/doc/snippets/javastyle.cpp b/src/widgets/doc/snippets/javastyle.cpp index 8657d5ed29..3d1b1e0030 100644 --- a/src/widgets/doc/snippets/javastyle.cpp +++ b/src/widgets/doc/snippets/javastyle.cpp @@ -2589,7 +2589,7 @@ int JavaStyle::styleHint(StyleHint hint, const QStyleOption *option, switch (hint) { case SH_Table_GridLineColor: { - ret = static_cast<int>(option->palette.color(QPalette::Mid).rgb()); + ret = static_cast<int>(option->palette.color(QPalette::Mid).rgba()); break; } case QStyle::SH_Menu_Scrollable: diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index c8f374a1b1..35bad6786a 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -993,6 +993,9 @@ \li Supports the \l{box model}. Supports the \l{#default-ps}{:default}, \l{#flat-ps}{:flat}, \l{#checked-ps}{:checked} pseudo states. + Since 5.15, the \l{#icon-prop}{icon} property can be set to + override the button icon. + For QPushButton with a menu, the menu indicator is styled using the \l{#menu-indicator-sub}{::menu-indicator} subcontrol. Appearance of checkable push buttons can be @@ -1946,6 +1949,20 @@ See also \l{#width-prop}{width}. \row + \li \b{\c icon} \target icon-prop + \li \l{#Url}{Url}+ + \li The icon that is used, for widgets that have an icon. + + The only widget currently supporting this property is QPushButton. + + \note It's the application's responsibilty to assign an icon to a + button (using the QAbstractButton API), and not the style's. So be + careful setting it unless your stylesheet is targeting a specific + application. + + Available since 5.15. + + \row \li \b{\c icon-size} \target icon-size-prop \li \l{#Length}{Length} \li The width and height of the icon in a widget. diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 11c5be10fd..81fceba8dc 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1431,7 +1431,7 @@ void QTableView::paintEvent(QPaintEvent *event) const bool showGrid = d->showGrid; const int gridSize = showGrid ? 1 : 0; const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this); - const QColor gridColor = static_cast<QRgb>(gridHint); + const QColor gridColor = QColor::fromRgba(static_cast<QRgb>(gridHint)); const QPen gridPen = QPen(gridColor, 0, d->gridStyle); const QHeaderView *verticalHeader = d->verticalHeader; const QHeaderView *horizontalHeader = d->horizontalHeader; diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 3ce81a390b..bd06ead6f7 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -583,18 +583,18 @@ static bool removeWidgetRecursively(QLayoutItem *li, QObject *w) } -void QLayoutPrivate::doResize(const QSize &r) +void QLayoutPrivate::doResize() { Q_Q(QLayout); - int mbh = menuBarHeightForWidth(menubar, r.width()); QWidget *mw = q->parentWidget(); QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect(); + const int mbh = menuBarHeightForWidth(menubar, rect.width()); const int mbTop = rect.top(); rect.setTop(mbTop + mbh); q->setGeometry(rect); #if QT_CONFIG(menubar) if (menubar) - menubar->setGeometry(rect.left(), mbTop, r.width(), mbh); + menubar->setGeometry(rect.left(), mbTop, rect.width(), mbh); #endif } @@ -613,12 +613,10 @@ void QLayout::widgetEvent(QEvent *e) switch (e->type()) { case QEvent::Resize: - if (d->activated) { - QResizeEvent *r = (QResizeEvent *)e; - d->doResize(r->size()); - } else { + if (d->activated) + d->doResize(); + else activate(); - } break; case QEvent::ChildRemoved: { @@ -1116,7 +1114,7 @@ bool QLayout::activate() break; } - d->doResize(mw->size()); + d->doResize(); if (md->extra) { md->extra->explicitMinSize = explMin; diff --git a/src/widgets/kernel/qlayout_p.h b/src/widgets/kernel/qlayout_p.h index 8e1d773355..2b19af48be 100644 --- a/src/widgets/kernel/qlayout_p.h +++ b/src/widgets/kernel/qlayout_p.h @@ -73,7 +73,7 @@ public: QLayoutPrivate(); void getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const; - void doResize(const QSize &); + void doResize(); void reparentChildWidgets(QWidget *mw); bool checkWidget(QWidget *widget) const; bool checkLayout(QLayout *otherLayout) const; diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index eec65c8625..d469279ea5 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -419,6 +419,76 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge \sa activated() */ +/*! + \fn template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor. +*/ +/*! + \fn template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context, Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor. + + The \a functor can be a pointer to a member function of the \a context object. + + If the \a context object is destroyed, the \a functor will not be called. +*/ +/*! + \fn template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor and + \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()} + signal to the \a FunctorAmbiguous. + + The \a functor and \a FunctorAmbiguous can be a pointer to a member + function of the \a context object. + + If the \a context object is destroyed, the \a functor and + \a FunctorAmbiguous will not be called. +*/ +/*! + \fn template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + const QObject *context2, FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor and + \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()} + signal to the \a FunctorAmbiguous. + + The \a functor can be a pointer to a member function of the + \a context1 object. + The \a FunctorAmbiguous can be a pointer to a member function of the + \a context2 object. + + If the \a context1 object is destroyed, the \a functor will not be called. + If the \a context2 object is destroyed, the \a FunctorAmbiguous + will not be called. +*/ + /* \internal Private data accessed through d-pointer. @@ -479,13 +549,13 @@ QShortcut::QShortcut(QWidget *parent) */ QShortcut::QShortcut(const QKeySequence &key, QWidget *parent, const char *member, const char *ambiguousMember, - Qt::ShortcutContext context) + Qt::ShortcutContext shortcutContext) : QShortcut(parent) { QAPP_CHECK("QShortcut"); Q_D(QShortcut); - d->sc_context = context; + d->sc_context = shortcutContext; d->sc_sequence = key; d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); if (member) diff --git a/src/widgets/kernel/qshortcut.h b/src/widgets/kernel/qshortcut.h index 6dcf4971b2..4f9c5ba0f7 100644 --- a/src/widgets/kernel/qshortcut.h +++ b/src/widgets/kernel/qshortcut.h @@ -61,9 +61,65 @@ class Q_WIDGETS_EXPORT QShortcut : public QObject Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext) public: explicit QShortcut(QWidget *parent); - QShortcut(const QKeySequence& key, QWidget *parent, + QShortcut(const QKeySequence &key, QWidget *parent, const char *member = nullptr, const char *ambiguousMember = nullptr, - Qt::ShortcutContext context = Qt::WindowShortcut); + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); +#ifdef Q_CLANG_QDOC + template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context, Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + const QObject *context2, FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); +#else + template<typename Func1> + QShortcut(const QKeySequence &key, QWidget *parent, + Func1 slot1, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, std::move(slot1)); + } + template<class Obj1, typename Func1> + QShortcut(const QKeySequence &key, QWidget *parent, + const Obj1 *object1, Func1 slot1, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + } + template<class Obj1, typename Func1, typename Func2> + QShortcut(const QKeySequence &key, QWidget *parent, + const Obj1 *object1, Func1 slot1, Func2 slot2, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + connect(this, &QShortcut::activatedAmbiguously, object1, std::move(slot2)); + } + template<class Obj1, typename Func1, class Obj2, typename Func2> + QShortcut(const QKeySequence &key, QWidget *parent, + const Obj1 *object1, Func1 slot1, + const Obj2 *object2, Func2 slot2, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + connect(this, &QShortcut::activatedAmbiguously, object2, std::move(slot2)); + } +#endif ~QShortcut(); void setKey(const QKeySequence& key); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 271b43fe89..861dd7a54c 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5143,7 +5143,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_Table_GridLineColor: if (opt) - ret = opt->palette.color(QPalette::Mid).rgb(); + ret = opt->palette.color(QPalette::Mid).rgba(); else ret = -1; break; diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index b58dc1660a..0f01a70faa 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -3733,7 +3733,7 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW return 0; case SH_Table_GridLineColor: - return option ? option->palette.window().color().darker(120).rgb() : 0; + return option ? option->palette.window().color().darker(120).rgba() : 0; case SH_MessageBox_TextInteractionFlags: return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 6cbed34c3a..d2f5ac76f9 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1835,7 +1835,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SH_LineEdit_PasswordMaskDelay Determines the delay before visible character is masked with password character, in milliseconds. This enum value was added in Qt 5.4. - \value SH_Table_GridLineColor The RGB value of the grid for a table. + \value SH_Table_GridLineColor The RGBA value of the grid for a table. \value SH_UnderlineShortcut Whether shortcuts are underlined. diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 3f57992311..0568d749c8 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -534,6 +534,7 @@ public: const QStyleSheetOutlineData *outline() const { return ou; } const QStyleSheetGeometryData *geometry() const { return geo; } const QStyleSheetPositionData *position() const { return p; } + const QStyleSheetImageData *icon() const { return iconPtr; } bool hasModification() const; @@ -569,6 +570,7 @@ public: bool hasGeometry() const { return geo != 0; } bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); } bool hasImage() const { return img != 0; } + bool hasIcon() const { return iconPtr != 0; } QSize minimumContentsSize() const { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); } @@ -628,6 +630,7 @@ public: QSharedDataPointer<QStyleSheetGeometryData> geo; QSharedDataPointer<QStyleSheetPositionData> p; QSharedDataPointer<QStyleSheetImageData> img; + QSharedDataPointer<QStyleSheetImageData> iconPtr; int clipset; QPainterPath clipPath; @@ -969,11 +972,16 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject if (v.extractPalette(&fg, &sfg, &sbg, &abg)) pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg); - QIcon icon; + QIcon imgIcon; alignment = Qt::AlignCenter; + QSize imgSize; + if (v.extractImage(&imgIcon, &alignment, &imgSize)) + img = new QStyleSheetImageData(imgIcon, alignment, imgSize); + + QIcon icon; QSize size; - if (v.extractImage(&icon, &alignment, &size)) - img = new QStyleSheetImageData(icon, alignment, size); + if (v.extractIcon(&icon, &size)) + iconPtr = new QStyleSheetImageData(icon, Qt::AlignCenter, size); int adj = -255; hasFont = v.extractFont(&font, &adj); @@ -3521,15 +3529,25 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (rule.hasFont) p->setFont(rule.font.resolve(p->font())); - if (rule.hasPosition() && rule.position()->textAlignment != 0) { - Qt::Alignment textAlignment = rule.position()->textAlignment; - QRect textRect = button->rect; + if (rule.hasPosition() || rule.hasIcon()) { uint tf = Qt::TextShowMnemonic; + QRect textRect = button->rect; + + const uint horizontalAlignMask = Qt::AlignHCenter | Qt::AlignLeft | Qt::AlignRight; const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft; - tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter; - if (!styleHint(SH_UnderlineShortcut, button, w)) - tf |= Qt::TextHideMnemonic; - if (!button->icon.isNull()) { + + if (rule.hasPosition() && rule.position()->textAlignment != 0) { + Qt::Alignment textAlignment = rule.position()->textAlignment; + tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter; + tf |= (textAlignment & horizontalAlignMask) ? (textAlignment & horizontalAlignMask) : Qt::AlignHCenter; + if (!styleHint(SH_UnderlineShortcut, button, w)) + tf |= Qt::TextHideMnemonic; + } else { + tf |= Qt::AlignVCenter | Qt::AlignHCenter; + } + + QIcon icon = rule.hasIcon() ? rule.icon()->icon : button->icon; + if (!icon.isNull()) { //Group both icon and text QRect iconRect; QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; @@ -3539,7 +3557,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (button->state & State_On) state = QIcon::On; - QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state); + QPixmap pixmap = icon.pixmap(button->iconSize, mode, state); int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); int labelWidth = pixmapWidth; @@ -3550,10 +3568,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q labelWidth += (textWidth + iconSpacing); //Determine label alignment: - if (textAlignment & Qt::AlignLeft) { /*left*/ + if (tf & Qt::AlignLeft) { /*left*/ iconRect = QRect(textRect.x(), textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); - } else if (textAlignment & Qt::AlignHCenter) { /* center */ + } else if (tf & Qt::AlignHCenter) { /* center */ iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2, textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); @@ -3565,7 +3583,9 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRect = visualRect(button->direction, textRect, iconRect); - tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead + // Left align, adjust the text-rect according to the icon instead + tf &= ~horizontalAlignMask; + tf |= Qt::AlignLeft; if (button->direction == Qt::RightToLeft) textRect.setRight(iconRect.left() - iconSpacing); @@ -3576,9 +3596,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w), pixelMetric(PM_ButtonShiftVertical, opt, w)); p->drawPixmap(iconRect, pixmap); - } else { - tf |= textAlignment; } + if (button->state & (State_On | State_Sunken)) textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w), pixelMetric(PM_ButtonShiftVertical, opt, w)); diff --git a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp index 82ab9c9c3b..aa687cfc3c 100644 --- a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp +++ b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp @@ -103,6 +103,7 @@ public slots: private slots: void cleanup(); + void pmf_connect(); void number_data(); void number(); void text_data(); @@ -203,6 +204,45 @@ void tst_QShortcut::cleanup() QVERIFY(QApplication::topLevelWidgets().size() <= 1); // The data driven tests keep a widget around } +void tst_QShortcut::pmf_connect() +{ + class MyObject : public QObject + { + public: + using QObject::QObject; + void onActivated() { ++activated; } + void onAmbiguous() { ++ambiguous; } + void reset() { activated = 0; ambiguous = 0; } + int activated = 0; + int ambiguous = 0; + } myObject; + QWidget parent; + + auto runCheck = [&myObject](QShortcut *sc, int activated, int ambiguous) + { + myObject.reset(); + sc->activated(); + sc->activatedAmbiguously(); + delete sc; + QCOMPARE(myObject.activated, activated); + QCOMPARE(myObject.ambiguous, ambiguous); + }; + + runCheck(new QShortcut(QKeySequence(), &parent, + [&myObject]() { ++myObject.activated; }), + 1, 0); + runCheck(new QShortcut(QKeySequence(), &parent, + &myObject, &MyObject::onActivated), + 1, 0); + runCheck(new QShortcut(QKeySequence(), &parent, + &myObject, &MyObject::onActivated, &MyObject::onAmbiguous), + 1, 1); + runCheck(new QShortcut(QKeySequence(), &parent, &myObject, + &MyObject::onActivated, &myObject, &MyObject::onAmbiguous), + 1, 1); +} + + Qt::KeyboardModifiers tst_QShortcut::toButtons( int key ) { Qt::KeyboardModifiers result = Qt::NoModifier; |