diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index d28a17a33e..8f8d5599bb 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -380,7 +380,7 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow break; case UIA_ExpandCollapsePatternId: // Menu items with submenus. - if (accessible->role() == QAccessible::MenuItem + if (((accessible->role() == QAccessible::MenuItem) || (accessible->role() == QAccessible::ButtonMenu)) && accessible->childCount() > 0 && accessible->child(0)->role() == QAccessible::PopupMenu) { *pRetVal = new QWindowsUiaExpandCollapseProvider(id()); @@ -430,14 +430,13 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR case UIA_FrameworkIdPropertyId: setVariantString(QStringLiteral("Qt"), pRetVal); break; - case UIA_ControlTypePropertyId: - if (topLevelWindow) { + case UIA_ControlTypePropertyId: { + // Control type converted from role. + auto controlType = roleToControlTypeId(accessible->role()); + if (topLevelWindow && controlType == UIA_CustomControlTypeId) { // Reports a top-level widget as a window, instead of "custom". setVariantI4(UIA_WindowControlTypeId, pRetVal); } else { - // Control type converted from role. - auto controlType = roleToControlTypeId(accessible->role()); - // The native OSK should be disbled if the Qt OSK is in use, // or if disabled via application attribute. static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE"); @@ -451,6 +450,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR setVariantI4(controlType, pRetVal); } break; + } case UIA_HelpTextPropertyId: setVariantString(accessible->text(QAccessible::Help), pRetVal); break; diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp index d59da86076..57523d5493 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -109,10 +109,13 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje } else if (classname == QLatin1String("QToolButton")) { iface = new QAccessibleToolButton(widget); #endif // QT_CONFIG(toolbutton) +#if QT_CONFIG(pushbutton) + } else if (classname == QLatin1String("QPushButton")) { + iface = new QAccessiblePushButton(widget); +#endif // QT_CONFIG(pushbutton) #if QT_CONFIG(abstractbutton) } else if (classname == QLatin1String("QCheckBox") || classname == QLatin1String("QRadioButton") - || classname == QLatin1String("QPushButton") || classname == QLatin1String("QAbstractButton")) { iface = new QAccessibleButton(widget); #endif diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index 1bb4545284..feb13e292c 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -138,11 +138,6 @@ QString QAccessibleButton::text(QAccessible::Text t) const switch (t) { case QAccessible::Accelerator: { -#if QT_CONFIG(shortcut) && QT_CONFIG(pushbutton) - QPushButton *pb = qobject_cast(object()); - if (pb && pb->isDefault()) - str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText); -#endif if (str.isEmpty()) str = qt_accHotKey(button()->text()); } @@ -178,17 +173,6 @@ QAccessible::State QAccessibleButton::state() const #endif if (b->isDown()) state.pressed = true; -#if QT_CONFIG(pushbutton) - QPushButton *pb = qobject_cast(b); - if (pb) { - if (pb->isDefault()) - state.defaultButton = true; -#if QT_CONFIG(menu) - if (pb->menu()) - state.hasPopup = true; -#endif - } -#endif return state; } @@ -222,13 +206,6 @@ QAccessible::Role QAccessibleButton::role() const { QAbstractButton *ab = button(); -#if QT_CONFIG(menu) - if (QPushButton *pb = qobject_cast(ab)) { - if (pb->menu()) - return QAccessible::ButtonMenu; - } -#endif - if (ab->isCheckable()) return ab->autoExclusive() ? QAccessible::RadioButton : QAccessible::CheckBox; @@ -265,13 +242,7 @@ void QAccessibleButton::doAction(const QString &actionName) return; if (actionName == pressAction() || actionName == showMenuAction()) { -#if QT_CONFIG(menu) - QPushButton *pb = qobject_cast(object()); - if (pb && pb->menu()) - pb->showMenu(); - else -#endif - button()->animateClick(); + button()->animateClick(); } else if (actionName == toggleAction()) { button()->toggle(); } else { @@ -290,6 +261,116 @@ QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) c } #endif // QT_CONFIG(abstractbutton) +#if QT_CONFIG(pushbutton) +/*! + \class QAccessiblePushButton + \brief The QAccessiblePushButton class implements the QAccessibleInterface for push buttons. + \internal + + \ingroup accessibility +*/ + +/*! + Creates a QAccessiblePushButton object for \a w. +*/ +QAccessiblePushButton::QAccessiblePushButton(QWidget *w) +: QAccessibleButton(w) +{ + Q_ASSERT(pushButton()); +} + +/*! Returns the button. */ +QPushButton *QAccessiblePushButton::pushButton() const +{ + return qobject_cast(object()); +} + +/*! \reimp */ +QString QAccessiblePushButton::text(QAccessible::Text t) const +{ + QString str; + switch (t) { + case QAccessible::Accelerator: + { +#if QT_CONFIG(shortcut) + if (pushButton()->isDefault()) + str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText); +#endif + } + break; + default: + break; + } + if (str.isEmpty()) + str = QAccessibleButton::text(t); + return str; +} + +QAccessible::State QAccessiblePushButton::state() const +{ + QAccessible::State st = QAccessibleButton::state(); + if (pushButton()->isDefault()) + st.defaultButton = true; +#if QT_CONFIG(menu) + if (pushButton()->menu()) + st.hasPopup = true; +#endif + + return st; +} + +int QAccessiblePushButton::childCount() const +{ +#if QT_CONFIG(menu) + return pushButton()->menu() ? 1 : 0; +#else + return 0; +#endif +} + +QAccessible::Role QAccessiblePushButton::role() const +{ +#if QT_CONFIG(menu) + if (pushButton()->menu()) + return QAccessible::ButtonMenu; +#endif + + return QAccessibleButton::role(); +} + +QAccessibleInterface *QAccessiblePushButton::child(int index) const +{ +#if QT_CONFIG(menu) + if (index == 0 && pushButton()->menu()) + { + return QAccessible::queryAccessibleInterface(pushButton()->menu()); + } +#else + Q_UNUSED(index) +#endif + return nullptr; +} + +void QAccessiblePushButton::doAction(const QString &actionName) +{ + if (!widget()->isEnabled()) + return; + + if (actionName == pressAction() || + actionName == showMenuAction()) { +#if QT_CONFIG(menu) + if (pushButton()->menu()) + pushButton()->showMenu(); + else +#endif + button()->animateClick(); + } else { + QAccessibleButton::doAction(actionName); + } +} + +#endif // QT_CONFIG(pushbutton) + #if QT_CONFIG(toolbutton) /*! \class QAccessibleToolButton diff --git a/src/widgets/accessible/simplewidgets_p.h b/src/widgets/accessible/simplewidgets_p.h index 73572e3059..818b79db69 100644 --- a/src/widgets/accessible/simplewidgets_p.h +++ b/src/widgets/accessible/simplewidgets_p.h @@ -64,6 +64,7 @@ class QLineEdit; class QToolButton; class QGroupBox; class QProgressBar; +class QPushButton; #if QT_CONFIG(abstractbutton) class QAccessibleButton : public QAccessibleWidget @@ -86,6 +87,27 @@ protected: }; #endif +#if QT_CONFIG(pushbutton) +class QAccessiblePushButton : public QAccessibleButton +{ +public: + QAccessiblePushButton(QWidget *w); + + QString text(QAccessible::Text t) const override; + QAccessible::State state() const override; + QAccessible::Role role() const override; + + int childCount() const override; + QAccessibleInterface *child(int index) const override; + + // QAccessibleActionInterface + void doAction(const QString &actionName) override; + +protected: + QPushButton *pushButton() const; +}; +#endif + #if QT_CONFIG(toolbutton) class QAccessibleToolButton : public QAccessibleButton {