diff options
author | Caolán McNamara <caolanm@redhat.com> | 2013-01-22 10:20:15 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-01-22 16:29:40 +0000 |
commit | 9975c632c3bd142f295fc1d9b1fd6059c3a2dbcb (patch) | |
tree | 8497185c0c4564ecefb19fcba56e65d00d76da12 /vcl | |
parent | 2a3a15fd73d119062228480c22056e9cc9e4d680 (diff) |
rework accessibility to be layout aware
Change-Id: I9f8ddfc5007dad6f090abae7e3e0a2d637da0b37
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/vcl/fixed.hxx | 6 | ||||
-rw-r--r-- | vcl/inc/vcl/layout.hxx | 7 | ||||
-rw-r--r-- | vcl/inc/vcl/window.hxx | 17 | ||||
-rw-r--r-- | vcl/inc/window.h | 2 | ||||
-rw-r--r-- | vcl/source/control/fixed.cxx | 31 | ||||
-rw-r--r-- | vcl/source/window/dlgctrl.cxx | 33 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 11 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 276 | ||||
-rw-r--r-- | vcl/source/window/window2.cxx | 25 |
9 files changed, 286 insertions, 122 deletions
diff --git a/vcl/inc/vcl/fixed.hxx b/vcl/inc/vcl/fixed.hxx index 7e1502595ddb..efa5f92f7701 100644 --- a/vcl/inc/vcl/fixed.hxx +++ b/vcl/inc/vcl/fixed.hxx @@ -38,6 +38,7 @@ class VCL_DLLPUBLIC FixedText : public Control private: sal_Int32 m_nMaxWidthChars; sal_Int32 m_nMinWidthChars; + Window *m_pMnemonicWindow; using Control::ImplInitSettings; using Window::ImplInit; @@ -55,10 +56,13 @@ protected: virtual const Color& GetCanonicalTextColor( const StyleSettings& _rStyle ) const; + virtual Window* getAccessibleRelationLabelFor() const; + public: FixedText( Window* pParent, WinBits nStyle = 0 ); FixedText( Window* pParent, const ResId& rResId ); FixedText( Window* pParent, const ResId& rResId, bool bDisableAccessibleLabelForRelation ); + ~FixedText(); virtual void Paint( const Rectangle& rRect ); virtual void Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ); @@ -75,6 +79,8 @@ public: Size CalcMinimumSize(long nMaxWidth = 0x7fffffff) const; virtual Size GetOptimalSize() const; virtual bool set_property(const rtl::OString &rKey, const rtl::OString &rValue); + void set_mnemonic_widget(Window *pWindow); + Window* get_mnemonic_widget() const { return m_pMnemonicWindow; } }; class VCL_DLLPUBLIC SelectableFixedText : public Edit diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx index 073433f462ed..2e48cd8d6ad2 100644 --- a/vcl/inc/vcl/layout.hxx +++ b/vcl/inc/vcl/layout.hxx @@ -44,6 +44,7 @@ public: protected: virtual Size calculateRequisition() const = 0; virtual void setAllocation(const Size &rAllocation) = 0; + virtual sal_uInt16 getDefaultAccessibleRole() const; private: bool m_bLayoutDirty; }; @@ -78,6 +79,7 @@ public: } virtual bool set_property(const OString &rKey, const OString &rValue); protected: + virtual sal_uInt16 getDefaultAccessibleRole() const; void accumulateMaxes(const Size &rChildSize, Size &rSize) const; Size finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const; @@ -672,6 +674,11 @@ inline bool isContainerWindow(const Window &rWindow) return (eType == WINDOW_CONTAINER || eType == WINDOW_SCROLLWINDOW); } +inline bool isContainerWindow(const Window *pWindow) +{ + return pWindow && isContainerWindow(*pWindow); +} + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index d9aa034716c9..88f39b5222f7 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -53,6 +53,7 @@ class Cursor; class DockingManager; class ScrollBar; class Bitmap; +class FixedText; class Image; class MouseEvent; class KeyEvent; @@ -571,6 +572,15 @@ protected: // FIXME: this is a hack to workaround missing layout functionality SAL_DLLPRIVATE void ImplAdjustNWFSizes(); + + // These eventually are supposed to go when everything is converted to .ui + SAL_DLLPRIVATE Window* getLegacyNonLayoutAccessibleRelationMemberOf() const; + SAL_DLLPRIVATE Window* getLegacyNonLayoutAccessibleRelationLabeledBy() const; + SAL_DLLPRIVATE Window* getLegacyNonLayoutAccessibleRelationLabelFor() const; + + // Let Label override the code part of GetAccessibleRelationLabelFor + virtual Window* getAccessibleRelationLabelFor() const; + virtual sal_uInt16 getDefaultAccessibleRole() const; public: // Single argument ctors shall be explicit. explicit Window( Window* pParent, WinBits nStyle = 0 ); @@ -1223,6 +1233,13 @@ public: void remove_from_all_size_groups(); /* + * add/remove mnemonic label + */ + void add_mnemonic_label(FixedText *pLabel); + void remove_mnemonic_label(FixedText *pLabel); + std::vector<FixedText*> list_mnemonic_labels() const; + + /* * Move this widget to be the nNewPosition'd child of its parent */ void reorderWithinParent(sal_uInt16 nNewPosition); diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 1785be28007f..53c59dcec0fc 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -43,6 +43,7 @@ struct SalPaintEvent; struct ImplDelData; struct ImplAccessibleInfos; +class FixedText; class Window; class VclSizeGroup; class VirtualDevice; @@ -285,6 +286,7 @@ public: ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > mxWindowPeer; ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxAccessible; ::boost::shared_ptr< VclSizeGroup > m_xSizeGroup; + ::std::vector< FixedText* > m_aMnemonicLabels; ImplAccessibleInfos* mpAccessibleInfos; VCLXWindow* mpVCLXWindow; Region maWinRegion; // region to 'shape' the VCL window (frame coordinates) diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx index 42b150ce885b..ca7b2e84efde 100644 --- a/vcl/source/control/fixed.cxx +++ b/vcl/source/control/fixed.cxx @@ -151,6 +151,7 @@ FixedText::FixedText( Window* pParent, WinBits nStyle ) : Control(WINDOW_FIXEDTEXT) , m_nMaxWidthChars(-1) , m_nMinWidthChars(-1) + , m_pMnemonicWindow(NULL) { ImplInit( pParent, nStyle ); } @@ -161,6 +162,7 @@ FixedText::FixedText( Window* pParent, const ResId& rResId ) : Control(WINDOW_FIXEDTEXT) , m_nMaxWidthChars(-1) , m_nMinWidthChars(-1) + , m_pMnemonicWindow(NULL) { rResId.SetRT( RSC_TEXT ); WinBits nStyle = ImplInitRes( rResId ); @@ -177,6 +179,7 @@ FixedText::FixedText( Window* pParent, const ResId& rResId, bool bDisableAccessi : Control( WINDOW_FIXEDTEXT ) , m_nMaxWidthChars(-1) , m_nMinWidthChars(-1) + , m_pMnemonicWindow(NULL) { rResId.SetRT( RSC_TEXT ); WinBits nStyle = ImplInitRes( rResId ); @@ -476,6 +479,34 @@ bool FixedText::set_property(const rtl::OString &rKey, const rtl::OString &rValu return true; } +Window* FixedText::getAccessibleRelationLabelFor() const +{ + Window *pWindow = Control::getAccessibleRelationLabelFor(); + if (pWindow) + return pWindow; + return get_mnemonic_widget(); +} + +void FixedText::set_mnemonic_widget(Window *pWindow) +{ + if (pWindow == m_pMnemonicWindow) + return; + if (m_pMnemonicWindow) + { + Window *pTempReEntryGuard = m_pMnemonicWindow; + m_pMnemonicWindow = NULL; + pTempReEntryGuard->remove_mnemonic_label(this); + } + m_pMnemonicWindow = pWindow; + if (m_pMnemonicWindow) + m_pMnemonicWindow->add_mnemonic_label(this); +} + +FixedText::~FixedText() +{ + set_mnemonic_widget(NULL); +} + SelectableFixedText::SelectableFixedText(Window* pParent, WinBits nStyle) : Edit(pParent, nStyle) { diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx index be3697ea13d6..15078a0bda17 100644 --- a/vcl/source/window/dlgctrl.cxx +++ b/vcl/source/window/dlgctrl.cxx @@ -24,6 +24,7 @@ #include <window.h> #include <vcl/event.hxx> +#include <vcl/fixed.hxx> #include <vcl/layout.hxx> #include <vcl/svapp.hxx> #include <vcl/tabpage.hxx> @@ -434,6 +435,16 @@ static Window* ImplFindAccelWindow( Window* pParent, sal_uInt16& rIndex, sal_Uni cCompareChar = xCharClass->toUpper( rtl::OUString(cCompareChar), 0, 1, rLocale )[0]; if ( cCompareChar == cCharCode ) { + if (pWindow->GetType() == WINDOW_FIXEDTEXT) + { + FixedText *pFixedText = static_cast<FixedText*>(pWindow); + Window *pMnemonicWidget = pFixedText->get_mnemonic_widget(); + SAL_WARN_IF(isContainerWindow(pFixedText->GetParent()) && !pMnemonicWidget, + "vcl.a11y", "label missing mnemonic_widget?"); + if (pMnemonicWidget) + return pMnemonicWidget; + } + // Bei Static-Controls auf das naechste Controlm weiterschalten if ( (pWindow->GetType() == WINDOW_FIXEDTEXT) || (pWindow->GetType() == WINDOW_FIXEDLINE) || @@ -1207,15 +1218,8 @@ static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window return pWindow; } -Window* Window::GetAccessibleRelationLabelFor() const +Window* Window::getLegacyNonLayoutAccessibleRelationLabelFor() const { - if ( mpWindowImpl->mbDisableAccessibleLabelForRelation ) - return NULL; - - if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow ) - return mpWindowImpl->mpAccessibleInfos->pLabelForWindow; - - Window* pWindow = NULL; Window* pFrameWindow = ImplGetFrameWindow(); @@ -1296,14 +1300,8 @@ static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Windo return pWindow; } -Window* Window::GetAccessibleRelationLabeledBy() const +Window* Window::getLegacyNonLayoutAccessibleRelationLabeledBy() const { - if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation ) - return NULL; - - if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow ) - return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow; - Window* pWindow = NULL; Window* pFrameWindow = ImplGetFrameWindow(); @@ -1332,11 +1330,8 @@ Window* Window::GetAccessibleRelationLabeledBy() const return pWindow; } -Window* Window::GetAccessibleRelationMemberOf() const +Window* Window::getLegacyNonLayoutAccessibleRelationMemberOf() const { - if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pMemberOfWindow ) - return mpWindowImpl->mpAccessibleInfos->pMemberOfWindow; - Window* pWindow = NULL; Window* pFrameWindow = GetParent(); if ( !pFrameWindow ) diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index ddf0a5bd27c6..5ebffdc884a7 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <com/sun/star/accessibility/AccessibleRole.hpp> #include <vcl/dialog.hxx> #include <vcl/layout.hxx> #include "window.h" @@ -21,6 +22,11 @@ VclContainer::VclContainer(Window *pParent, WinBits nStyle) SetBackground(); } +sal_uInt16 VclContainer::getDefaultAccessibleRole() const +{ + return com::sun::star::accessibility::AccessibleRole::PANEL; +} + Size VclContainer::GetOptimalSize() const { return calculateRequisition(); @@ -296,6 +302,11 @@ bool VclBox::set_property(const rtl::OString &rKey, const rtl::OString &rValue) return true; } +sal_uInt16 VclBox::getDefaultAccessibleRole() const +{ + return com::sun::star::accessibility::AccessibleRole::FILLER; +} + #define DEFAULT_CHILD_MIN_WIDTH 85 #define DEFAULT_CHILD_MIN_HEIGHT 27 diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 34b2d49c3568..842c94c11a34 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -29,6 +29,7 @@ #include "vcl/layout.hxx" #include "vcl/salgtype.hxx" #include "vcl/event.hxx" +#include "vcl/fixed.hxx" #include "vcl/help.hxx" #include "vcl/cursor.hxx" #include "vcl/svapp.hxx" @@ -4484,6 +4485,14 @@ Window::~Window() // remove from size-group if necessary remove_from_all_size_groups(); + // clear mnemonic labels + std::vector<FixedText*> aMnemonicLabels(list_mnemonic_labels()); + for (std::vector<FixedText*>::iterator aI = aMnemonicLabels.begin(); + aI != aMnemonicLabels.end(); ++aI) + { + remove_mnemonic_label(*aI); + } + // hide window in order to trigger the Paint-Handling Hide(); @@ -8726,134 +8735,139 @@ void Window::SetAccessibleRole( sal_uInt16 nRole ) mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole; } -sal_uInt16 Window::GetAccessibleRole() const +sal_uInt16 Window::getDefaultAccessibleRole() const { - using namespace ::com::sun::star; - - sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF; - if ( nRole == 0xFFFF ) + sal_uInt16 nRole = 0xFFFF; + switch ( GetType() ) { - switch ( GetType() ) - { - case WINDOW_MESSBOX: // MT: Would be nice to have special roles! - case WINDOW_INFOBOX: - case WINDOW_WARNINGBOX: - case WINDOW_ERRORBOX: - case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break; + case WINDOW_MESSBOX: // MT: Would be nice to have special roles! + case WINDOW_INFOBOX: + case WINDOW_WARNINGBOX: + case WINDOW_ERRORBOX: + case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break; - case WINDOW_MODELESSDIALOG: - case WINDOW_MODALDIALOG: - case WINDOW_SYSTEMDIALOG: - case WINDOW_PRINTERSETUPDIALOG: - case WINDOW_PRINTDIALOG: - case WINDOW_TABDIALOG: - case WINDOW_BUTTONDIALOG: - case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break; + case WINDOW_MODELESSDIALOG: + case WINDOW_MODALDIALOG: + case WINDOW_SYSTEMDIALOG: + case WINDOW_PRINTERSETUPDIALOG: + case WINDOW_PRINTDIALOG: + case WINDOW_TABDIALOG: + case WINDOW_BUTTONDIALOG: + case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break; - case WINDOW_PUSHBUTTON: - case WINDOW_OKBUTTON: - case WINDOW_CANCELBUTTON: - case WINDOW_HELPBUTTON: - case WINDOW_IMAGEBUTTON: - case WINDOW_MENUBUTTON: - case WINDOW_MOREBUTTON: - case WINDOW_SPINBUTTON: - case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break; + case WINDOW_PUSHBUTTON: + case WINDOW_OKBUTTON: + case WINDOW_CANCELBUTTON: + case WINDOW_HELPBUTTON: + case WINDOW_IMAGEBUTTON: + case WINDOW_MENUBUTTON: + case WINDOW_MOREBUTTON: + case WINDOW_SPINBUTTON: + case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break; - case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break; - case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break; - case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break; - case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break; + case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break; + case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break; + case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break; + case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break; - case WINDOW_IMAGERADIOBUTTON: - case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break; - case WINDOW_TRISTATEBOX: - case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break; + case WINDOW_IMAGERADIOBUTTON: + case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break; + case WINDOW_TRISTATEBOX: + case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break; - case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break; + case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break; - case WINDOW_PATTERNFIELD: - case WINDOW_NUMERICFIELD: - case WINDOW_METRICFIELD: - case WINDOW_CURRENCYFIELD: - case WINDOW_LONGCURRENCYFIELD: - case WINDOW_CALCINPUTLINE: - case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break; + case WINDOW_PATTERNFIELD: + case WINDOW_NUMERICFIELD: + case WINDOW_METRICFIELD: + case WINDOW_CURRENCYFIELD: + case WINDOW_LONGCURRENCYFIELD: + case WINDOW_CALCINPUTLINE: + case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break; - case WINDOW_PATTERNBOX: - case WINDOW_NUMERICBOX: - case WINDOW_METRICBOX: - case WINDOW_CURRENCYBOX: - case WINDOW_LONGCURRENCYBOX: - case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break; + case WINDOW_PATTERNBOX: + case WINDOW_NUMERICBOX: + case WINDOW_METRICBOX: + case WINDOW_CURRENCYBOX: + case WINDOW_LONGCURRENCYBOX: + case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break; - case WINDOW_LISTBOX: - case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break; + case WINDOW_LISTBOX: + case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break; - case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break; + case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break; - case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break; - case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break; - case WINDOW_FIXEDBITMAP: - case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break; - case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break; - case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break; + case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break; + case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break; + case WINDOW_FIXEDBITMAP: + case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break; + case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break; + case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break; - case WINDOW_SLIDER: - case WINDOW_SPLITTER: - case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break; + case WINDOW_SLIDER: + case WINDOW_SPLITTER: + case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break; - case WINDOW_DATEBOX: - case WINDOW_TIMEBOX: - case WINDOW_DATEFIELD: - case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break; - - case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break; + case WINDOW_DATEBOX: + case WINDOW_TIMEBOX: + case WINDOW_DATEFIELD: + case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break; - case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break; - case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break; + case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break; - case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break; - case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break; + case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break; + case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break; - case WINDOW_DOCKINGWINDOW: - case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME : - accessibility::AccessibleRole::PANEL; break; + case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break; + case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break; - case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame || - (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) || - (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME : - accessibility::AccessibleRole::WINDOW; break; + case WINDOW_DOCKINGWINDOW: + case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME : + accessibility::AccessibleRole::PANEL; break; - case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break; + case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame || + (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) || + (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME : + accessibility::AccessibleRole::WINDOW; break; + case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break; - case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break; - case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break; + case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break; - case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break; + case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break; + + case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break; + + case WINDOW_SCROLLWINDOW: nRole = accessibility::AccessibleRole::SCROLL_PANE; break; + + case WINDOW_WINDOW: + case WINDOW_CONTROL: + case WINDOW_BORDERWINDOW: + case WINDOW_SYSTEMCHILDWINDOW: + default: + if (ImplIsAccessibleNativeFrame() ) + nRole = accessibility::AccessibleRole::FRAME; + else if( IsScrollable() ) + nRole = accessibility::AccessibleRole::SCROLL_PANE; + else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() ) + nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenus are windows (i.e. toplevel) + else + // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead + // a WINDOW is interpreted as a top-level window, which is typically not the case + //nRole = accessibility::AccessibleRole::WINDOW; + nRole = accessibility::AccessibleRole::PANEL; + } + return nRole; +} - case WINDOW_SCROLLWINDOW: nRole = accessibility::AccessibleRole::SCROLL_PANE; break; +sal_uInt16 Window::GetAccessibleRole() const +{ + using namespace ::com::sun::star; - case WINDOW_WINDOW: - case WINDOW_CONTROL: - case WINDOW_BORDERWINDOW: - case WINDOW_SYSTEMCHILDWINDOW: - default: - if (ImplIsAccessibleNativeFrame() ) - nRole = accessibility::AccessibleRole::FRAME; - else if( IsScrollable() ) - nRole = accessibility::AccessibleRole::SCROLL_PANE; - else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() ) - nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenus are windows (i.e. toplevel) - else - // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead - // a WINDOW is interpreted as a top-level window, which is typically not the case - //nRole = accessibility::AccessibleRole::WINDOW; - nRole = accessibility::AccessibleRole::PANEL; - } - } + sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF; + if ( nRole == 0xFFFF ) + nRole = getDefaultAccessibleRole(); return nRole; } @@ -8980,6 +8994,62 @@ void Window::SetAccessibleRelationMemberOf( Window* pMemberOfWin ) mpWindowImpl->mpAccessibleInfos->pMemberOfWindow = pMemberOfWin; } +Window* Window::GetAccessibleRelationMemberOf() const +{ + if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pMemberOfWindow) + return mpWindowImpl->mpAccessibleInfos->pMemberOfWindow; + + if (!isContainerWindow(this) && !isContainerWindow(GetParent())) + return getLegacyNonLayoutAccessibleRelationMemberOf(); + + return NULL; +} + +Window* Window::getAccessibleRelationLabelFor() const +{ + if (mpWindowImpl->mbDisableAccessibleLabelForRelation) + return NULL; + + if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow) + return mpWindowImpl->mpAccessibleInfos->pLabelForWindow; + + return NULL; +} + +Window* Window::GetAccessibleRelationLabelFor() const +{ + Window* pWindow = getAccessibleRelationLabelFor(); + + if (pWindow) + return pWindow; + + if (!isContainerWindow(this) && !isContainerWindow(GetParent())) + return getLegacyNonLayoutAccessibleRelationLabelFor(); + + return NULL; +} + +Window* Window::GetAccessibleRelationLabeledBy() const +{ + if (mpWindowImpl->mbDisableAccessibleLabeledByRelation) + return NULL; + + if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow) + return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow; + + std::vector<FixedText*> m_aMnemonicLabels(list_mnemonic_labels()); + if (!m_aMnemonicLabels.empty()) + { + SAL_WARN_IF(m_aMnemonicLabels.size() != 1, "vcl.a11y", "TODO: multiple LabeledBy not handled yet"); + return m_aMnemonicLabels[0]; + } + + if (!isContainerWindow(this) && !isContainerWindow(GetParent())) + return getLegacyNonLayoutAccessibleRelationLabeledBy(); + + return NULL; +} + sal_Bool Window::IsAccessibilityEventsSuppressed( sal_Bool bTraverseParentPath ) { if( !bTraverseParentPath ) diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index 0dc6d1792a6c..906d65bb93e4 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -25,6 +25,7 @@ #include <vcl/bitmap.hxx> #include <vcl/dialog.hxx> #include <vcl/event.hxx> +#include <vcl/fixed.hxx> #include <vcl/layout.hxx> #include <vcl/timer.hxx> #include <vcl/metric.hxx> @@ -2315,4 +2316,28 @@ void Window::remove_from_all_size_groups() } } +void Window::add_mnemonic_label(FixedText *pLabel) +{ + std::vector<FixedText*>& v = mpWindowImpl->m_aMnemonicLabels; + if (std::find(v.begin(), v.end(), pLabel) != v.end()) + return; + v.push_back(pLabel); + pLabel->set_mnemonic_widget(this); +} + +void Window::remove_mnemonic_label(FixedText *pLabel) +{ + std::vector<FixedText*>& v = mpWindowImpl->m_aMnemonicLabels; + std::vector<FixedText*>::iterator aFind = std::find(v.begin(), v.end(), pLabel); + if (aFind == v.end()) + return; + v.erase(aFind); + pLabel->set_mnemonic_widget(NULL); +} + +std::vector<FixedText*> Window::list_mnemonic_labels() const +{ + return mpWindowImpl->m_aMnemonicLabels; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |