VirtualBox

Changeset 64813 in vbox


Ignore:
Timestamp:
Dec 8, 2016 6:08:21 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
112196
Message:

FE/Qt: bugref:6899: Accessibility support (step 156): Basic accessibility interface for UIMenuBarEditorWidget.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.cpp

    r64713 r64813  
    2121
    2222/* Qt includes: */
     23# include <QAccessibleWidget>
    2324# include <QHBoxLayout>
     25# include <QMenu>
     26# include <QMenuBar>
     27# include <QMetaEnum>
     28# include <QPainter>
    2429# include <QPaintEvent>
    25 # include <QMetaEnum>
    26 # include <QMenuBar>
    27 # include <QPainter>
    28 # include <QMenu>
     30# include <QStyleOptionToolButton>
    2931# ifndef VBOX_WS_MAC
    3032#  include <QCheckBox>
     
    4446#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    4547
     48/* Forward declarations: */
     49class UIAccessibilityInterfaceForUIMenuBarEditorButton;
     50
     51
     52/** Menu-bar editor button segment types. */
     53enum UIMenuBarEditorSegment
     54{
     55    UIMenuBarEditorSegment_Button,
     56    UIMenuBarEditorSegment_Menu,
     57    UIMenuBarEditorSegment_Max,
     58};
     59
     60
     61/** QAccessibleWidget extension used as an accessibility interface for UIMenuBarEditor button segments. */
     62class UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment : public QAccessibleInterface
     63{
     64public:
     65
     66    /** Constructs an accessibility interface.
     67      * @param  pParent   Brings the parent interface we are linked to.
     68      * @param  enmIndex  Brings the index of segment we are referring to. */
     69    UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment(UIAccessibilityInterfaceForUIMenuBarEditorButton *pParent,
     70                                                            UIMenuBarEditorSegment enmIndex);
     71
     72    /** Returns whether the interface is valid. */
     73    virtual bool isValid() const /* override */ { return true; }
     74
     75    /** Returns the wrapped object. */
     76    virtual QObject *object() const /* override */ { return 0; }
     77    /** Returns the parent. */
     78    virtual QAccessibleInterface *parent() const /* override */;
     79
     80    /** Returns the number of children. */
     81    virtual int childCount() const /* override */ { return 0; }
     82    /** Returns the child with the passed @a iIndex. */
     83    virtual QAccessibleInterface *child(int /* iIndex */) const /* override */ { return 0; }
     84    /** Returns the child at position QPoint(@a x, @a y). */
     85    virtual QAccessibleInterface *childAt(int /* x */, int /* y */) const /* override */ { return 0; }
     86    /** Returns the index of the passed @a pChild. */
     87    virtual int indexOfChild(const QAccessibleInterface * /* pChild */) const /* override */ { return -1; }
     88
     89    /** Returns the rect. */
     90    virtual QRect rect() const /* override */;
     91
     92    /** Defines a @a strText for the passed @a enmTextRole. */
     93    virtual void setText(QAccessible::Text /* enmTextRole */, const QString & /* strText */) /* override */ {}
     94    /** Returns a text for the passed @a enmTextRole. */
     95    virtual QString text(QAccessible::Text /* enmTextRole */) const /* override */;
     96
     97    /** Returns the role. */
     98    virtual QAccessible::Role role() const /* override */ { return QAccessible::Button; }
     99    /** Returns the state. */
     100    virtual QAccessible::State state() const /* override */ { return QAccessible::State(); }
     101
     102private:
     103
     104    /** Holds the parent interface we are linked to. */
     105    UIAccessibilityInterfaceForUIMenuBarEditorButton *m_pParent;
     106    /** Holds the index of segment we are referring to. */
     107    const UIMenuBarEditorSegment m_enmIndex;
     108};
     109
     110
     111/** QAccessibleWidget extension used as an accessibility interface for UIMenuBarEditor buttons. */
     112class UIAccessibilityInterfaceForUIMenuBarEditorButton : public QAccessibleWidget
     113{
     114public:
     115
     116    /** Returns an accessibility interface for passed @a strClassname and @a pObject. */
     117    static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject);
     118
     119    /** Constructs an accessibility interface passing @a pWidget to the base-class. */
     120    UIAccessibilityInterfaceForUIMenuBarEditorButton(QWidget *pWidget);
     121    /** Destructs an accessibility interface. */
     122    ~UIAccessibilityInterfaceForUIMenuBarEditorButton();
     123
     124    /** Returns the number of children. */
     125    virtual int childCount() const /* override */;
     126    /** Returns the child with the passed @a iIndex. */
     127    virtual QAccessibleInterface *child(int iIndex) const /* override */;
     128
     129    /** Returns the role. */
     130    virtual QAccessible::Role role() const /* override */;
     131
     132    /** Returns the rect of sub-element @a enmSegment. */
     133    QRect subRect(UIMenuBarEditorSegment enmSegment) const;
     134    /** Returns the text of sub-element @a enmSegment. */
     135    QString subText(UIMenuBarEditorSegment enmSegment) const;
     136
     137private:
     138
     139    /** Returns corresponding toolbar button. */
     140    QToolButton *button() const { return qobject_cast<QToolButton*>(widget()); }
     141
     142    /** Holds the map of instances of sub-element interfaces. */
     143    QMap<UIMenuBarEditorSegment, UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment*> m_elements;
     144};
     145
     146
     147/*********************************************************************************************************************************
     148*   Class UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment implementation.                                                *
     149*********************************************************************************************************************************/
     150
     151UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment(
     152        UIAccessibilityInterfaceForUIMenuBarEditorButton *pParent,
     153        UIMenuBarEditorSegment enmIndex)
     154    : m_pParent(pParent)
     155    , m_enmIndex(enmIndex)
     156{
     157}
     158
     159QAccessibleInterface *UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::parent() const
     160{
     161    return m_pParent;
     162}
     163
     164QRect UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::rect() const
     165{
     166    return m_pParent->subRect(m_enmIndex);
     167}
     168
     169QString UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::text(QAccessible::Text /* enmTextRole */) const
     170{
     171    return m_pParent->subText(m_enmIndex);
     172}
     173
     174
     175/*********************************************************************************************************************************
     176*   Class UIAccessibilityInterfaceForUIMenuBarEditorButton implementation.                                                       *
     177*********************************************************************************************************************************/
     178
     179/* static */
     180QAccessibleInterface *UIAccessibilityInterfaceForUIMenuBarEditorButton::pFactory(const QString &strClassname, QObject *pObject)
     181{
     182    /* Creating toolbar button accessibility interface: */
     183    if (   pObject
     184        && strClassname == QLatin1String("QToolButton")
     185        && pObject->property("Belongs to") == "UIMenuBarEditorWidget")
     186        return new UIAccessibilityInterfaceForUIMenuBarEditorButton(qobject_cast<QWidget*>(pObject));
     187
     188    /* Null by default: */
     189    return 0;
     190}
     191
     192UIAccessibilityInterfaceForUIMenuBarEditorButton::UIAccessibilityInterfaceForUIMenuBarEditorButton(QWidget *pWidget)
     193    : QAccessibleWidget(pWidget, QAccessible::Button)
     194{
     195    /* Prepare button with popup menu: */
     196    if (button()->popupMode() == QToolButton::MenuButtonPopup)
     197    {
     198        for (int iIndex = 0; iIndex < (int)UIMenuBarEditorSegment_Max; ++iIndex)
     199            m_elements[(UIMenuBarEditorSegment)iIndex] =
     200                new UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment(this, (UIMenuBarEditorSegment)iIndex);
     201    }
     202}
     203
     204UIAccessibilityInterfaceForUIMenuBarEditorButton::~UIAccessibilityInterfaceForUIMenuBarEditorButton()
     205{
     206    /* Cleanup button with popup menu: */
     207    qDeleteAll(m_elements);
     208    m_elements.clear();
     209}
     210
     211int UIAccessibilityInterfaceForUIMenuBarEditorButton::childCount() const
     212{
     213    /* Sanity check: */
     214    AssertPtrReturn(button(), 0);
     215
     216    /* Return child count for a button with popup menu: */
     217    if (button()->popupMode() == QToolButton::MenuButtonPopup)
     218        return UIMenuBarEditorSegment_Max;
     219
     220    /* Call to base-class: */
     221    return QAccessibleWidget::childCount();
     222}
     223
     224QAccessibleInterface *UIAccessibilityInterfaceForUIMenuBarEditorButton::child(int iIndex) const
     225{
     226    /* Sanity check: */
     227    AssertPtrReturn(button(), 0);
     228    AssertReturn(iIndex >= 0 && iIndex < childCount(), 0);
     229
     230    /* Return the child with the passed iIndex for a button with popup menu: */
     231    if (button()->popupMode() == QToolButton::MenuButtonPopup)
     232        return m_elements.value((UIMenuBarEditorSegment)iIndex);
     233
     234    /* Call to base-class: */
     235    return QAccessibleWidget::child(iIndex);
     236}
     237
     238QAccessible::Role UIAccessibilityInterfaceForUIMenuBarEditorButton::role() const
     239{
     240    /* Sanity check: */
     241    AssertPtrReturn(button(), QAccessibleWidget::role());
     242
     243    /* Return role for button with popup menu: */
     244    if (button()->popupMode() == QToolButton::MenuButtonPopup)
     245        return QAccessible::ToolBar;
     246
     247    /* Call to base-class: */
     248    return QAccessibleWidget::role();
     249}
     250
     251QRect UIAccessibilityInterfaceForUIMenuBarEditorButton::subRect(UIMenuBarEditorSegment enmSegment) const
     252{
     253    /* Sanity check: */
     254    AssertReturn(button()->popupMode() == QToolButton::MenuButtonPopup, QRect());
     255
     256    /* Return the rect of segment with the passed enmIndex for a button with popup menu: */
     257    switch (enmSegment)
     258    {
     259        case UIMenuBarEditorSegment_Button:
     260        {
     261            QStyleOptionToolButton options;
     262            options.initFrom(button());
     263            options.features |= QStyleOptionToolButton::MenuButtonPopup;
     264            QRect rect = button()->style()->subControlRect(QStyle::CC_ToolButton, &options, QStyle::SC_ToolButton);
     265            rect.moveTo(button()->mapToGlobal(rect.topLeft()));
     266            return rect;
     267        }
     268        case UIMenuBarEditorSegment_Menu:
     269        {
     270            QStyleOptionToolButton options;
     271            options.initFrom(button());
     272            options.features |= QStyleOptionToolButton::MenuButtonPopup;
     273            QRect rect = button()->style()->subControlRect(QStyle::CC_ToolButton, &options, QStyle::SC_ToolButtonMenu);
     274            rect.moveTo(button()->mapToGlobal(rect.topLeft()));
     275            return rect;
     276        }
     277        default:
     278            break;
     279    }
     280
     281    /* Null rect by default: */
     282    return QRect();
     283}
     284
     285QString UIAccessibilityInterfaceForUIMenuBarEditorButton::subText(UIMenuBarEditorSegment enmSegment) const
     286{
     287    /* Sanity check: */
     288    AssertReturn(button()->popupMode() == QToolButton::MenuButtonPopup, QString());
     289
     290    /* Return the text of segment with the passed enmIndex for a button with popup menu: */
     291    switch (enmSegment)
     292    {
     293        case UIMenuBarEditorSegment_Button:
     294            return UIMenuBarEditorWidget::tr("Toggle menu %1").arg(QAccessibleWidget::text(QAccessible::Description));
     295        case UIMenuBarEditorSegment_Menu:
     296            return UIMenuBarEditorWidget::tr("Popup menu %1").arg(QAccessibleWidget::text(QAccessible::Description));
     297        default:
     298            break;
     299    }
     300
     301    /* Null string by default: */
     302    return QString();
     303}
     304
     305
     306/*********************************************************************************************************************************
     307*   Class UIMenuBarEditorWidget implementation.                                                                                  *
     308*********************************************************************************************************************************/
    46309
    47310UIMenuBarEditorWidget::UIMenuBarEditorWidget(QWidget *pParent,
     
    601864        return;
    602865
     866    /* Install tool-bar button accessibility interface factory: */
     867    QAccessible::installFactory(UIAccessibilityInterfaceForUIMenuBarEditorButton::pFactory);
     868
    603869    /* Create main-layout: */
    604870    m_pMainLayout = new QHBoxLayout(this);
     
    731997            {
    732998                /* Configure named menu tool-button: */
     999                pNamedMenuToolButton->setProperty("Belongs to", "UIMenuBarEditorWidget");
    7331000                pNamedMenuToolButton->setPopupMode(QToolButton::MenuButtonPopup);
    7341001                pNamedMenuToolButton->setAutoRaise(true);
     1002                /* Update the accessibility interface to take "Belongs to" into account: */
     1003                QAccessibleInterface *pInterface = QAccessible::queryAccessibleInterface(pNamedMenuToolButton);
     1004                if (pInterface)
     1005                {
     1006                    QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(pInterface));
     1007                    QAccessible::queryAccessibleInterface(pNamedMenuToolButton); // <= new one, proper..
     1008                }
    7351009                /* Create spacing after named menu tool-button: */
    7361010                QWidget *pSpacing = new QWidget;
     
    7751049            {
    7761050                /* Configure copied menu tool-button: */
     1051                pCopiedMenuToolButton->setProperty("Belongs to", "UIMenuBarEditorWidget");
    7771052                pCopiedMenuToolButton->setPopupMode(QToolButton::MenuButtonPopup);
    7781053                pCopiedMenuToolButton->setAutoRaise(true);
     1054                /* Update the accessibility interface to take "Belongs to" into account: */
     1055                QAccessibleInterface *pInterface = QAccessible::queryAccessibleInterface(pCopiedMenuToolButton);
     1056                if (pInterface)
     1057                {
     1058                    QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(pInterface));
     1059                    QAccessible::queryAccessibleInterface(pCopiedMenuToolButton); // <= new one, proper..
     1060                }
    7791061                /* Create spacing after copied menu tool-button: */
    7801062                QWidget *pSpacing = new QWidget;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette