From efb23f29983f87104a684e7fab00b84fc59d131d Mon Sep 17 00:00:00 2001 From: Steve Yin Date: Mon, 25 Nov 2013 15:24:55 +0000 Subject: Integrate branch of IAccessible2 (cherry picked from commit e2f90c93c97f3cf137c348ed302c6470f398aa70) Change-Id: I44ce0d69f3e7364038b00b1ba0f0d27e60132a37 WaE: Prevent uninitialized variable warnings. (cherry picked from commit b989f4074ea70729d527b307bfbe49e01a0d3646) --- .../accessibility/extended/accessiblelistbox.hxx | 19 +- .../extended/accessiblelistboxentry.hxx | 31 +- .../extended/accessibletablistboxtable.hxx | 2 + .../extended/textwindowaccessibility.hxx | 9 + .../accessibility/helper/IComboListBoxHelper.hxx | 1 + .../inc/accessibility/helper/accessiblestrings.hrc | 13 +- .../inc/accessibility/helper/listboxhelper.hxx | 5 + .../standard/accessiblemenubasecomponent.hxx | 2 + .../standard/accessiblemenuitemcomponent.hxx | 2 + .../accessibility/standard/vclxaccessiblebox.hxx | 22 +- .../accessibility/standard/vclxaccessiblelist.hxx | 12 +- .../standard/vclxaccessiblelistitem.hxx | 5 +- .../accessibility/standard/vclxaccessiblemenu.hxx | 3 + .../standard/vclxaccessiblescrollbar.hxx | 4 + .../extended/AccessibleBrowseBoxHeaderCell.cxx | 1 + .../extended/accessibleeditbrowseboxcell.cxx | 9 +- .../source/extended/accessibleiconchoicectrl.cxx | 31 +- .../extended/accessibleiconchoicectrlentry.cxx | 3 +- .../source/extended/accessiblelistbox.cxx | 254 +++++++++++-- .../source/extended/accessiblelistboxentry.cxx | 347 +++++++++++++++-- .../source/extended/accessibletablistboxtable.cxx | 57 +++ .../source/extended/textwindowaccessibility.cxx | 410 ++++++++++++++++++++- accessibility/source/helper/accessiblestrings.src | 50 ++- .../source/helper/characterattributeshelper.cxx | 1 + .../standard/accessiblemenubasecomponent.cxx | 14 +- .../standard/accessiblemenuitemcomponent.cxx | 19 +- .../source/standard/vclxaccessiblebox.cxx | 235 +++++++++++- .../source/standard/vclxaccessiblebutton.cxx | 10 + .../source/standard/vclxaccessiblecheckbox.cxx | 5 +- .../source/standard/vclxaccessiblelist.cxx | 356 +++++++++++++++--- .../source/standard/vclxaccessiblelistitem.cxx | 11 +- .../source/standard/vclxaccessiblemenu.cxx | 10 + .../source/standard/vclxaccessiblemenuitem.cxx | 17 +- .../source/standard/vclxaccessibleradiobutton.cxx | 2 +- .../source/standard/vclxaccessiblescrollbar.cxx | 20 +- .../source/standard/vclxaccessibletabcontrol.cxx | 2 - .../standard/vclxaccessibletextcomponent.cxx | 52 +++ .../source/standard/vclxaccessibletoolbox.cxx | 45 ++- .../source/standard/vclxaccessibletoolboxitem.cxx | 40 +- 39 files changed, 1945 insertions(+), 186 deletions(-) diff --git a/accessibility/inc/accessibility/extended/accessiblelistbox.hxx b/accessibility/inc/accessibility/extended/accessiblelistbox.hxx index 33147add2197..9354e48511a9 100644 --- a/accessibility/inc/accessibility/extended/accessiblelistbox.hxx +++ b/accessibility/inc/accessibility/extended/accessiblelistbox.hxx @@ -26,14 +26,16 @@ #include #include +#include // class AccessibleListBox ----------------------------------------------- class SvTreeListBox; - +class SvTreeListEntry; //........................................................................ namespace accessibility { + class AccessibleListBoxEntry; //........................................................................ typedef ::cppu::ImplHelper2< ::com::sun::star::accessibility::XAccessible @@ -62,6 +64,8 @@ namespace accessibility SvTreeListBox* getListBox() const; + void RemoveChildEntries(SvTreeListEntry*); + public: /** OAccessibleBase needs a valid view @param _rListBox @@ -107,6 +111,19 @@ namespace accessibility sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // IA2 CWS + sal_Int32 SAL_CALL getRoleType(); + +private: + + typedef std::map< SvTreeListEntry*, ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > > MAP_ENTRY; + MAP_ENTRY m_mapEntry; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > m_xFocusedChild; + + accessibility::AccessibleListBoxEntry* GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ); + }; //........................................................................ diff --git a/accessibility/inc/accessibility/extended/accessiblelistboxentry.hxx b/accessibility/inc/accessibility/extended/accessiblelistboxentry.hxx index 0ff3de306e6c..4eff637f39ab 100644 --- a/accessibility/inc/accessibility/extended/accessiblelistboxentry.hxx +++ b/accessibility/inc/accessibility/extended/accessiblelistboxentry.hxx @@ -31,9 +31,11 @@ #include #include #include -#include +#include +#include #include #include +#include #include #include "accessibility/extended/listboxaccessible.hxx" @@ -55,7 +57,7 @@ namespace accessibility //........................................................................ // class AccessibleListBoxEntry ------------------------------------------ - +/* typedef ::cppu::WeakAggComponentImplHelper8< ::com::sun::star::accessibility::XAccessible , ::com::sun::star::accessibility::XAccessibleContext , ::com::sun::star::accessibility::XAccessibleComponent @@ -64,6 +66,16 @@ namespace accessibility , ::com::sun::star::accessibility::XAccessibleSelection , ::com::sun::star::accessibility::XAccessibleText , ::com::sun::star::lang::XServiceInfo > AccessibleListBoxEntry_BASE; +*/ + typedef ::cppu::WeakAggComponentImplHelper9< ::com::sun::star::accessibility::XAccessible + , ::com::sun::star::accessibility::XAccessibleContext + , ::com::sun::star::accessibility::XAccessibleComponent + , ::com::sun::star::accessibility::XAccessibleEventBroadcaster + , ::com::sun::star::accessibility::XAccessibleAction + , ::com::sun::star::accessibility::XAccessibleSelection + , ::com::sun::star::accessibility::XAccessibleText + , ::com::sun::star::accessibility::XAccessibleValue + , ::com::sun::star::lang::XServiceInfo > AccessibleListBoxEntry_BASE; /** the class AccessibleListBoxEntry represents the class for an accessible object of a listbox entry */ class AccessibleListBoxEntry:public ::comphelper::OBaseMutex @@ -76,6 +88,8 @@ namespace accessibility private: /** The treelistbox control */ ::std::deque< sal_Int32 > m_aEntryPath; + SvTreeListEntry* m_pSvLBoxEntry; // Needed for a11y focused item... + protected: /// client id in the AccessibleEventNotifier queue @@ -94,6 +108,8 @@ namespace accessibility Rectangle GetBoundingBoxOnScreen() throw ( ::com::sun::star::lang::DisposedException ); void EnsureIsAlive() const throw ( ::com::sun::star::lang::DisposedException ); + void NotifyAccessibleEvent( sal_Int16 _nEventId, const ::com::sun::star::uno::Any& _aOldValue, const ::com::sun::star::uno::Any& _aNewValue ); + protected: virtual ~AccessibleListBoxEntry(); @@ -122,6 +138,9 @@ namespace accessibility const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _xParent ); + SvTreeListEntry* GetSvLBoxEntry() const { return m_pSvLBoxEntry; } + + protected: // XTypeProvider virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); @@ -199,9 +218,15 @@ namespace accessibility sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); - + virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL setCurrentValue( const ::com::sun::star::uno::Any& aNumber ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getMaximumValue( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getMinimumValue( ) throw (::com::sun::star::uno::RuntimeException); private: ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > implGetParentAccessible( ) const; + SvTreeListEntry* GetRealChild(sal_Int32 nIndex); + public: + sal_Int32 SAL_CALL getRoleType(); }; //........................................................................ diff --git a/accessibility/inc/accessibility/extended/accessibletablistboxtable.hxx b/accessibility/inc/accessibility/extended/accessibletablistboxtable.hxx index 7b84ceab410b..7d97b77bcfc7 100644 --- a/accessibility/inc/accessibility/extended/accessibletablistboxtable.hxx +++ b/accessibility/inc/accessibility/extended/accessibletablistboxtable.hxx @@ -39,6 +39,8 @@ class AccessibleTabListBoxTable : public AccessibleBrowseBoxTable, public Access private: SvHeaderTabListBox* m_pTabListBox; + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > m_xCurChild; + void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); DECL_LINK( WindowEventListener, VclSimpleEvent* ); diff --git a/accessibility/inc/accessibility/extended/textwindowaccessibility.hxx b/accessibility/inc/accessibility/extended/textwindowaccessibility.hxx index b707c8c179ad..a4d4ec708887 100644 --- a/accessibility/inc/accessibility/extended/textwindowaccessibility.hxx +++ b/accessibility/inc/accessibility/extended/textwindowaccessibility.hxx @@ -48,6 +48,10 @@ #include #include +#include "svtools/svtools.hrc" +#include +#include +#include #include #include #include @@ -571,6 +575,9 @@ private: SAL_CALL getAccessibleAtPoint(css::awt::Point const & rPoint) throw (css::uno::RuntimeException); + virtual void FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ); + virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ); + // ??? Will be called with both the external (Solar) and internal mutex // locked: virtual void SAL_CALL disposing(); @@ -622,6 +629,8 @@ private: void handleSelectionChangeNotification(); void notifySelectionChange( sal_Int32 nFirst, sal_Int32 nLast ); + ::sal_Int32 getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos); + void sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId); void justifySelection( TextPaM& rTextStart, TextPaM& rTextEnd ); diff --git a/accessibility/inc/accessibility/helper/IComboListBoxHelper.hxx b/accessibility/inc/accessibility/helper/IComboListBoxHelper.hxx index 357166c27a7b..a4a88e6c194a 100644 --- a/accessibility/inc/accessibility/helper/IComboListBoxHelper.hxx +++ b/accessibility/inc/accessibility/helper/IComboListBoxHelper.hxx @@ -43,6 +43,7 @@ namespace accessibility virtual Rectangle GetBoundingRectangle( sal_uInt16 nItem ) const = 0; virtual Rectangle GetWindowExtentsRelative( Window* pRelativeWindow ) = 0; virtual bool IsActive() const = 0; + virtual bool IsEnabled() const = 0; virtual bool IsEntryVisible( sal_uInt16 nPos ) const = 0; virtual sal_uInt16 GetDisplayLineCount() const = 0; virtual void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const = 0; diff --git a/accessibility/inc/accessibility/helper/accessiblestrings.hrc b/accessibility/inc/accessibility/helper/accessiblestrings.hrc index 4df9a814e8b4..03815d8dd3c0 100644 --- a/accessibility/inc/accessibility/helper/accessiblestrings.hrc +++ b/accessibility/inc/accessibility/helper/accessiblestrings.hrc @@ -35,7 +35,18 @@ #define RID_STR_ACC_ACTION_DECLINE ( RID_TK_ACC_START + 4 ) #define RID_STR_ACC_ACTION_INCBLOCK ( RID_TK_ACC_START + 5 ) #define RID_STR_ACC_ACTION_DECBLOCK ( RID_TK_ACC_START + 6 ) - +#define RID_STR_ACC_NAME_PREVIEW ( RID_TK_ACC_START + 7 ) + +#define STR_SVT_ACC_ACTION_EXPAND ( RID_TK_ACC_START + 8 ) +#define STR_SVT_ACC_ACTION_COLLAPSE ( RID_TK_ACC_START + 9 ) +#define STR_SVT_ACC_LISTENTRY_SELCTED_STATE ( RID_TK_ACC_START + 10 ) + +#define RID_STR_ACC_ACTION_CHECK ( RID_TK_ACC_START + 11 ) +#define RID_STR_ACC_ACTION_UNCHECK ( RID_TK_ACC_START + 12 ) +#define RID_STR_ACC_ACTION_DOUBLE_CLICK ( RID_TK_ACC_START + 13 ) +#define RID_STR_ACC_SCROLLBAR_NAME_VERTICAL ( RID_TK_ACC_START + 14 ) +#define RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL ( RID_TK_ACC_START + 15 ) +#define RID_STR_ACC_PANEL_DESCRIPTION ( RID_TK_ACC_START + 16 ) #define RID_STR_ACC_NAME_BROWSEBUTTON ( RID_TK_ACC_START + 100 ) #define RID_STR_ACC_DESC_PANELDECL_TABBAR ( RID_TK_ACC_START + 101 ) diff --git a/accessibility/inc/accessibility/helper/listboxhelper.hxx b/accessibility/inc/accessibility/helper/listboxhelper.hxx index 8da885dd7e76..f42bc266bba0 100644 --- a/accessibility/inc/accessibility/helper/listboxhelper.hxx +++ b/accessibility/inc/accessibility/helper/listboxhelper.hxx @@ -86,6 +86,11 @@ public: return m_aComboListBox.IsActive(); } // ----------------------------------------------------------------------------- + virtual bool IsEnabled() const + { + return m_aComboListBox.IsEnabled(); + } + // ----------------------------------------------------------------------------- virtual bool IsEntryVisible( sal_uInt16 nPos ) const { sal_uInt16 nTopEntry = m_aComboListBox.GetTopEntry(); diff --git a/accessibility/inc/accessibility/standard/accessiblemenubasecomponent.hxx b/accessibility/inc/accessibility/standard/accessiblemenubasecomponent.hxx index fbc1a62892e6..e9e745a46c2f 100644 --- a/accessibility/inc/accessibility/standard/accessiblemenubasecomponent.hxx +++ b/accessibility/inc/accessibility/standard/accessiblemenubasecomponent.hxx @@ -103,6 +103,8 @@ protected: virtual sal_Bool IsHighlighted(); sal_Bool IsChildHighlighted(); + virtual sal_Bool IsMenuHideDisabledEntries(); + void SelectChild( sal_Int32 i ); void DeSelectAll(); sal_Bool IsChildSelected( sal_Int32 i ); diff --git a/accessibility/inc/accessibility/standard/accessiblemenuitemcomponent.hxx b/accessibility/inc/accessibility/standard/accessiblemenuitemcomponent.hxx index b70b537e22fa..830532af5de3 100644 --- a/accessibility/inc/accessibility/standard/accessiblemenuitemcomponent.hxx +++ b/accessibility/inc/accessibility/standard/accessiblemenuitemcomponent.hxx @@ -49,6 +49,8 @@ protected: void SetItemText( const OUString& sItemText ); OUString GetItemText(); + virtual sal_Bool IsMenuHideDisabledEntries(); + virtual void FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ); // OCommonAccessibleComponent diff --git a/accessibility/inc/accessibility/standard/vclxaccessiblebox.hxx b/accessibility/inc/accessibility/standard/vclxaccessiblebox.hxx index 9b8e37f92efc..9e6cfa89daa0 100644 --- a/accessibility/inc/accessibility/standard/vclxaccessiblebox.hxx +++ b/accessibility/inc/accessibility/standard/vclxaccessiblebox.hxx @@ -24,11 +24,13 @@ #include #include #include -#include +#include +#include -typedef ::cppu::ImplHelper2< +typedef ::cppu::ImplHelper3< ::com::sun::star::accessibility::XAccessible, + ::com::sun::star::accessibility::XAccessibleValue, ::com::sun::star::accessibility::XAccessibleAction > VCLXAccessibleBox_BASE; @@ -121,7 +123,22 @@ public: */ virtual void SAL_CALL disposing (void); + //===== XAccessibleValue ================================================ + virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL setCurrentValue( + const ::com::sun::star::uno::Any& aNumber ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Any SAL_CALL getMaximumValue( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Any SAL_CALL getMinimumValue( ) + throw (::com::sun::star::uno::RuntimeException); + bool IsDropDownBox() {return m_bIsDropDownBox;}; + BoxType GetBoxType() { return m_aBoxType;}; protected: /** Specifies whether the box is a combo box or a list box. List boxes have multi selection. @@ -162,6 +179,7 @@ protected: virtual void ProcessWindowChildEvent (const VclWindowEvent& rVclWindowEvent); virtual void ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent); + virtual void FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ); private: /// Index in parent. This is settable from the outside. diff --git a/accessibility/inc/accessibility/standard/vclxaccessiblelist.hxx b/accessibility/inc/accessibility/standard/vclxaccessiblelist.hxx index 29a8f100fc2f..ba0f2b7b5331 100644 --- a/accessibility/inc/accessibility/standard/vclxaccessiblelist.hxx +++ b/accessibility/inc/accessibility/standard/vclxaccessiblelist.hxx @@ -68,6 +68,7 @@ public: /** Process some of the events and delegate the rest to the base classes. */ virtual void ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent); + virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ); /** Called on reception of selection events this method checks all known list items for a possible change in their selection state and @@ -135,7 +136,14 @@ public: virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); - + sal_Bool IsInDropDown(); + void HandleDropOpen(); + virtual void ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent, bool b_IsDropDownList); + void UpdateSelection_Acc (::rtl::OUString sTextOfSelectedItem, bool b_IsDropDownList); + void UpdateSelection_Impl_Acc (bool b_IsDropDownList); + + void UpdateFocus_Impl_Acc ( sal_uInt16 nPos, bool b_IsDropDownList) ; + void NotifyListItem(::com::sun::star::uno::Any& val); protected: BoxType m_aBoxType; ::accessibility::IComboListBoxHelper* m_pListBoxHelper; @@ -147,7 +155,7 @@ protected: sal_uInt16 m_nLastSelectedPos; bool m_bDisableProcessEvent; bool m_bVisible; - + sal_uInt16 m_nCurSelectedPos; /// The currently selected item. diff --git a/accessibility/inc/accessibility/standard/vclxaccessiblelistitem.hxx b/accessibility/inc/accessibility/standard/vclxaccessiblelistitem.hxx index 885d3e48fdc7..1bd28d7ad864 100644 --- a/accessibility/inc/accessibility/standard/vclxaccessiblelistitem.hxx +++ b/accessibility/inc/accessibility/standard/vclxaccessiblelistitem.hxx @@ -83,9 +83,9 @@ private: @param _aNewValue is the new value */ - void NotifyAccessibleEvent( sal_Int16 _nEventId, + /*void NotifyAccessibleEvent( sal_Int16 _nEventId, const ::com::sun::star::uno::Any& _aOldValue, - const ::com::sun::star::uno::Any& _aNewValue ); + const ::com::sun::star::uno::Any& _aNewValue );*/ protected: virtual ~VCLXAccessibleListItem(); @@ -111,6 +111,7 @@ public: sal_Int32 _nIndexInParent, const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _xParent ); + void NotifyAccessibleEvent( sal_Int16 _nEventId, const ::com::sun::star::uno::Any& _aOldValue, const ::com::sun::star::uno::Any& _aNewValue ); inline sal_Bool IsSelected() const { return m_bSelected; } void SetSelected( sal_Bool _bSelected ); diff --git a/accessibility/inc/accessibility/standard/vclxaccessiblemenu.hxx b/accessibility/inc/accessibility/standard/vclxaccessiblemenu.hxx index 5f1bc4b9b6eb..9e017ecaa01a 100644 --- a/accessibility/inc/accessibility/standard/vclxaccessiblemenu.hxx +++ b/accessibility/inc/accessibility/standard/vclxaccessiblemenu.hxx @@ -70,6 +70,9 @@ public: virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleAction + virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); }; #endif // ACCESSIBILITY_STANDARD_VCLXACCESSIBLEMENU_HXX diff --git a/accessibility/inc/accessibility/standard/vclxaccessiblescrollbar.hxx b/accessibility/inc/accessibility/standard/vclxaccessiblescrollbar.hxx index f8396a30f039..f26ef23da7bd 100644 --- a/accessibility/inc/accessibility/standard/vclxaccessiblescrollbar.hxx +++ b/accessibility/inc/accessibility/standard/vclxaccessiblescrollbar.hxx @@ -69,6 +69,10 @@ public: virtual sal_Bool SAL_CALL setCurrentValue( const ::com::sun::star::uno::Any& aNumber ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Any SAL_CALL getMaximumValue( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Any SAL_CALL getMinimumValue( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException); + }; #endif // ACCESSIBILITY_STANDARD_VCLXACCESSIBLESCROLLBAR_HXX diff --git a/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx index 925aa5538930..270f05704c9f 100644 --- a/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx +++ b/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx @@ -61,6 +61,7 @@ AccessibleBrowseBoxHeaderCell::AccessibleBrowseBoxHeaderCell(sal_Int32 _nColumnR pStateSetHelper->AddState( AccessibleStateType::SHOWING ); SolarMutexGuard aSolarGuard; + mpBrowseBox->FillAccessibleStateSet( *pStateSetHelper, getType() ); pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); diff --git a/accessibility/source/extended/accessibleeditbrowseboxcell.cxx b/accessibility/source/extended/accessibleeditbrowseboxcell.cxx index 3c601c67ab8e..5adf32b80aa3 100644 --- a/accessibility/source/extended/accessibleeditbrowseboxcell.cxx +++ b/accessibility/source/extended/accessibleeditbrowseboxcell.cxx @@ -119,12 +119,9 @@ namespace accessibility SolarMethodGuard aGuard( *this ); // TODO: localize this! - OUStringBuffer sName(mpBrowseBox->GetColumnDescription( ::sal::static_int_cast< sal_uInt16 >( getColumnPos() ) )); - if ( sName.isEmpty() ) - { - sName.appendAscii("Column "); - sName.append(getColumnPos()); - } + OUStringBuffer sName; + sName.appendAscii("Column "); + sName.append(getColumnPos()-1); sName.appendAscii(", Row "); sName.append(getRowPos()); diff --git a/accessibility/source/extended/accessibleiconchoicectrl.cxx b/accessibility/source/extended/accessibleiconchoicectrl.cxx index 869ec89571f4..460ee4dafa75 100644 --- a/accessibility/source/extended/accessibleiconchoicectrl.cxx +++ b/accessibility/source/extended/accessibleiconchoicectrl.cxx @@ -69,11 +69,36 @@ namespace accessibility // modified selection. The active descendant event is // send after that so that the receiving AT has time to // read the text or name of the active child. - NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); +// NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + + if ( getCtrl() && getCtrl()->HasFocus() ) + { + SvxIconChoiceCtrlEntry* pEntry = static_cast< SvxIconChoiceCtrlEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_uLong nPos = getCtrl()->GetEntryListPos( pEntry ); + Reference< XAccessible > xChild = new AccessibleIconChoiceCtrlEntry( *getCtrl(), nPos, this ); + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOldValue, aNewValue ); + + } + } + break; + } + case VCLEVENT_WINDOW_GETFOCUS : + { SvtIconChoiceCtrl* pCtrl = getCtrl(); if ( pCtrl && pCtrl->HasFocus() ) { SvxIconChoiceCtrlEntry* pEntry = static_cast< SvxIconChoiceCtrlEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry == NULL ) + { + sal_uLong nPos=0; + pEntry = getCtrl()->GetSelectedEntry ( nPos ); + } if ( pEntry ) { sal_uLong nPos = pCtrl->GetEntryListPos( pEntry ); @@ -81,6 +106,7 @@ namespace accessibility uno::Any aOldValue, aNewValue; aNewValue <<= xChild; NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOldValue, aNewValue ); } } break; @@ -174,7 +200,8 @@ namespace accessibility // ----------------------------------------------------------------------------- sal_Int16 SAL_CALL AccessibleIconChoiceCtrl::getAccessibleRole( ) throw (RuntimeException) { - return AccessibleRole::TREE; + //return AccessibleRole::TREE; + return AccessibleRole::LIST; } // ----------------------------------------------------------------------------- OUString SAL_CALL AccessibleIconChoiceCtrl::getAccessibleDescription( ) throw (RuntimeException) diff --git a/accessibility/source/extended/accessibleiconchoicectrlentry.cxx b/accessibility/source/extended/accessibleiconchoicectrlentry.cxx index d36c8a989aa4..2217d828c100 100644 --- a/accessibility/source/extended/accessibleiconchoicectrlentry.cxx +++ b/accessibility/source/extended/accessibleiconchoicectrlentry.cxx @@ -307,7 +307,8 @@ throw(RuntimeException) // ----------------------------------------------------------------------------- sal_Int16 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRole( ) throw (RuntimeException) { - return AccessibleRole::LABEL; + //return AccessibleRole::LABEL; + return AccessibleRole::LIST_ITEM; } // ----------------------------------------------------------------------------- OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleDescription( ) throw (RuntimeException) diff --git a/accessibility/source/extended/accessiblelistbox.cxx b/accessibility/source/extended/accessiblelistbox.cxx index 63dc7add5905..2ebeb9d89591 100644 --- a/accessibility/source/extended/accessiblelistbox.cxx +++ b/accessibility/source/extended/accessiblelistbox.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -79,19 +80,25 @@ namespace accessibility { case VCLEVENT_CHECKBOX_TOGGLE : { - if ( getListBox() && getListBox()->HasFocus() ) + if ( !getListBox() || !getListBox()->HasFocus() ) { - SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); - if ( !pEntry ) - pEntry = getListBox()->GetCurEntry(); + return; + } + AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent); + if(!pCurOpEntry) + { + return ; + } + uno::Any aValue; + aValue <<= AccessibleStateType::CHECKED; - if ( pEntry ) - { - Reference< XAccessible > xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); - uno::Any aOldValue, aNewValue; - aNewValue <<= xChild; - NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); - } + if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED ) + { + pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue ); + } + else + { + pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() ); } break; } @@ -102,16 +109,101 @@ namespace accessibility // modified selection. The active descendant event is // send after that so that the receiving AT has time to // read the text or name of the active child. - NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); - if ( getListBox() && getListBox()->HasFocus() ) + OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT"); + } + + case VCLEVENT_LISTBOX_TREESELECT: + { + if ( getListBox() && getListBox()->HasFocus() ) + { + AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); + if (pEntry) + { + pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } + } + } + break; + case VCLEVENT_LISTBOX_TREEFOCUS: + { + SvTreeListBox* pBox = getListBox(); + sal_Bool bNeedFocus = sal_False; + if (pBox) + { + Window* pParent = ((Window*)pBox)->GetParent(); + if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW) + { + // MT: ImplGetAppSVData shouldn't be exported from VCL. + // In which scenario is this needed? + // If needed, we need to find an other solution + /* + ImplSVData* pSVData = ImplGetAppSVData(); + if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent) + bNeedFocus = sal_True; + */ + } + } + if( pBox && (pBox->HasFocus() || bNeedFocus) ) + { + uno::Any aOldValue, aNewValue; + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); + if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry) + { + aOldValue <<= uno::Any(); + aNewValue <<= m_xFocusedChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + return ; + } + + aOldValue <<= m_xFocusedChild; + + MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); + if(mi != m_mapEntry.end()) + { + OSL_ASSERT(mi->second.get() != NULL); + m_xFocusedChild = mi->second; + } + else + { + AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); + m_xFocusedChild = pEntNew; + m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew)); + } + + aNewValue <<= m_xFocusedChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + } + else + { + aOldValue <<= uno::Any(); + aNewValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + } + break; + case VCLEVENT_LISTBOX_ITEMREMOVED: { SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); if ( pEntry ) { - Reference< XAccessible > xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); - uno::Any aOldValue, aNewValue; - aNewValue <<= xChild; - NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + RemoveChildEntries(pEntry); + } + else + { + // NULL means Clear() + MAP_ENTRY::iterator mi = m_mapEntry.begin(); + for ( ; mi != m_mapEntry.end() ; ++mi) + { + uno::Any aNewValue; + uno::Any aOldValue; + aOldValue <<= mi->second; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + m_mapEntry.clear(); } } break; @@ -138,14 +230,71 @@ namespace accessibility NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry ); } } - break; - } } + break; default: VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); } } } + + AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ) + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( !pEntry ) + pEntry = getListBox()->GetCurEntry(); + + AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); + if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry()) + { + AccessibleListBoxEntry *pAccCurOptionEntry =NULL; + MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); + if (mi != m_mapEntry.end()) + { + pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get()); + } + else + { + pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); + std::pair pairMi = m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry)); + mi = pairMi.first; + } + + uno::Any aNewValue; + aNewValue <<= mi->second;//xAcc + NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add + + return pAccCurOptionEntry; + } + else + { + return pEntryFocus; + } + return NULL; + } + + void AccessibleListBox::RemoveChildEntries(SvTreeListEntry* pEntry) + { + MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); + if ( mi != m_mapEntry.end() ) + { + uno::Any aNewValue; + uno::Any aOldValue; + aOldValue <<= mi->second; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + m_mapEntry.erase(mi); + } + + SvTreeListBox* pBox = getListBox(); + SvTreeListEntry* pEntryChild = pBox->FirstChild(pEntry); + while (pEntryChild) + { + RemoveChildEntries(pEntryChild); + pEntryChild = pBox->NextSibling(pEntryChild); + } + } + // ----------------------------------------------------------------------------- void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) { @@ -171,6 +320,7 @@ namespace accessibility { ::osl::MutexGuard aGuard( m_aMutex ); + m_mapEntry.clear(); VCLXAccessibleComponent::disposing(); m_xParent = NULL; } @@ -241,7 +391,9 @@ namespace accessibility if ( !pEntry ) throw IndexOutOfBoundsException(); - return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + // Solution: Set the parameter of the parent to null to let entry determine the parent by itself + //return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + return new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); } // ----------------------------------------------------------------------------- Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent( ) throw (RuntimeException) @@ -252,9 +404,54 @@ namespace accessibility return m_xParent; } // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBox::getRoleType() + { + sal_Int32 nCase = 0; + SvTreeListEntry* pEntry = getListBox()->GetEntry(0); + if ( pEntry ) + { + if( pEntry->HasChildrenOnDemand() || getListBox()->GetChildCount(pEntry) > 0 ) + { + nCase = 1; + return nCase; + } + } + + sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) ) + { + if( bHasButtons ) + nCase = 1; + } + else + { + if( bHasButtons ) + nCase = 2; + else + nCase = 3; + } + return nCase; + } sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException) { - return AccessibleRole::TREE; + if(getListBox()) + { + short nType = getListBox()->GetAllEntriesAccessibleRoleType(); + if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE) + return AccessibleRole::TREE; + else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST) + return AccessibleRole::LIST; + } + + //o is: return AccessibleRole::TREE; + sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN)) + return AccessibleRole::LIST; + else + if(getRoleType() == 0) + return AccessibleRole::LIST; + else + return AccessibleRole::TREE; } // ----------------------------------------------------------------------------- OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException) @@ -337,16 +534,7 @@ namespace accessibility ensureAlive(); - sal_Int32 nSelCount = 0; - sal_Int32 nCount = getListBox()->GetLevelChildCount( NULL ); - for ( sal_Int32 i = 0; i < nCount; ++i ) - { - SvTreeListEntry* pEntry = getListBox()->GetEntry( i ); - if ( getListBox()->IsSelected( pEntry ) ) - ++nSelCount; - } - - return nSelCount; + return getListBox()->GetSelectionCount(); } // ----------------------------------------------------------------------------- Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) @@ -369,7 +557,9 @@ namespace accessibility if ( nSelCount == ( nSelectedChildIndex + 1 ) ) { - xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + // Solution: Set the parameter of the parent to null to let entry determine the parent by itself + //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); break; } } diff --git a/accessibility/source/extended/accessiblelistboxentry.cxx b/accessibility/source/extended/accessiblelistboxentry.cxx index 6bc4baa00848..851158f5193a 100644 --- a/accessibility/source/extended/accessiblelistboxentry.cxx +++ b/accessibility/source/extended/accessiblelistboxentry.cxx @@ -20,6 +20,7 @@ #include "accessibility/extended/accessiblelistboxentry.hxx" #include #include +#include #include #include #include @@ -38,7 +39,9 @@ #include #include #include - +#include +#include +#include #define ACCESSIBLE_ACTION_COUNT 1 namespace @@ -60,6 +63,7 @@ namespace accessibility using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star; + using namespace ::comphelper; // ----------------------------------------------------------------------------- // Ctor() and Dtor() @@ -71,6 +75,7 @@ namespace accessibility AccessibleListBoxEntry_BASE ( m_aMutex ), ListBoxAccessibleBase( _rListBox ), + m_pSvLBoxEntry ( _pEntry ), m_nClientId ( 0 ), m_aParent ( _xParent ) @@ -88,6 +93,19 @@ namespace accessibility } } + // IA2 CWS + void AccessibleListBoxEntry::NotifyAccessibleEvent( sal_Int16 _nEventId, + const ::com::sun::star::uno::Any& _aOldValue, + const ::com::sun::star::uno::Any& _aNewValue ) + { + Reference< uno::XInterface > xSource( *this ); + AccessibleEventObject aEventObj( xSource, _nEventId, _aNewValue, _aOldValue ); + + if (m_nClientId) + comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEventObj ); + } + + // ----------------------------------------------------------------------------- Rectangle AccessibleListBoxEntry::GetBoundingBox_Impl() const { @@ -175,7 +193,7 @@ namespace accessibility OUString sRet; SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); if ( pEntry ) - sRet = getListBox()->SearchEntryText( pEntry ); + sRet = getListBox()->SearchEntryTextWithHeadTitle( pEntry ); return sRet; } // ----------------------------------------------------------------------------- @@ -309,8 +327,7 @@ namespace accessibility ::osl::MutexGuard aGuard( m_aMutex ); EnsureIsAlive(); - SvTreeListEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); - SvTreeListEntry* pEntry = pParent ? getListBox()->GetEntry( pParent, i ) : NULL; + SvTreeListEntry* pEntry = GetRealChild(i); if ( !pEntry ) throw IndexOutOfBoundsException(); @@ -341,6 +358,8 @@ namespace accessibility SvTreeListEntry* pParentEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); OSL_ENSURE( pParentEntry, "AccessibleListBoxEntry::implGetParentAccessible: could not obtain a parent entry!" ); + if ( pParentEntry ) + pParentEntry = getListBox()->GetParent(pParentEntry); if ( pParentEntry ) xParent = new AccessibleListBoxEntry( *getListBox(), pParentEntry, NULL ); // note that we pass NULL here as parent-accessible: @@ -370,15 +389,103 @@ namespace accessibility return m_aEntryPath.empty() ? -1 : m_aEntryPath.back(); } // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBoxEntry::getRoleType() + { + sal_Int32 nCase = 0; + SvTreeListEntry* pEntry = getListBox()->GetEntry(0); + if ( pEntry ) + { + if( pEntry->HasChildrenOnDemand() || getListBox()->GetChildCount(pEntry) > 0 ) + { + nCase = 1; + return nCase; + } + } + + sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) ) + { + if( bHasButtons ) + nCase = 1; + } + else + { + if( bHasButtons ) + nCase = 2; + else + nCase = 3; + } + return nCase; + } + // ----------------------------------------------------------------------------- sal_Int16 SAL_CALL AccessibleListBoxEntry::getAccessibleRole( ) throw (RuntimeException) { - return AccessibleRole::LABEL; + SvTreeListBox* pBox = getListBox(); + if(pBox) + { + short nType = pBox->GetAllEntriesAccessibleRoleType(); + if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE) + return AccessibleRole::TREE_ITEM; + else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST) + return AccessibleRole::LIST_ITEM; + } + + sal_uInt16 treeFlag = pBox->GetTreeFlags(); + if(treeFlag & TREEFLAG_CHKBTN ) + { + SvTreeListEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath ); + SvButtonState eState = pBox->GetCheckButtonState( pEntry ); + switch( eState ) + { + case SV_BUTTON_CHECKED: + case SV_BUTTON_UNCHECKED: + return AccessibleRole::CHECK_BOX; + case SV_BUTTON_TRISTATE: + default: + return AccessibleRole::LABEL; + } + } + else + { + + if(getRoleType() == 0) + return AccessibleRole::LIST_ITEM; + else + //o is: return AccessibleRole::LABEL; + return AccessibleRole::TREE_ITEM; + } } // ----------------------------------------------------------------------------- OUString SAL_CALL AccessibleListBoxEntry::getAccessibleDescription( ) throw (RuntimeException) { - // no description for every item - return OUString(); + SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if( getAccessibleRole() == AccessibleRole::TREE_ITEM ) + { + return getListBox()->GetEntryLongDescription( pEntry ); + } + //want to cout the real column nubmer in the list box. + sal_uInt16 iRealItemCount = 0; + sal_uInt16 iCount = 0; + sal_uInt16 iTotleItemCount = pEntry->ItemCount(); + SvLBoxItem* pItem; + while( iCount < iTotleItemCount ) + { + pItem = pEntry->GetItem( iCount ); + if ( pItem->GetType() == SV_ITEM_ID_LBOXSTRING && + !static_cast( pItem )->GetText().isEmpty() ) + { + iRealItemCount++; + } + iCount++; + } + if(iRealItemCount<=1 ) + { + return OUString(); + } + else + { + return getListBox()->SearchEntryTextWithHeadTitle( pEntry ); + } } // ----------------------------------------------------------------------------- OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName( ) throw (RuntimeException) @@ -386,7 +493,19 @@ namespace accessibility ::osl::MutexGuard aGuard( m_aMutex ); EnsureIsAlive(); - return implGetText(); + + OUString sRet(implGetText()); + + SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + + OUString altText = getListBox()->GetEntryAltText( pEntry ); + if (!altText.isEmpty()) + { + sRet += " "; + sRet += altText; + } + + return sRet; } // ----------------------------------------------------------------------------- Reference< XAccessibleRelationSet > SAL_CALL AccessibleListBoxEntry::getAccessibleRelationSet( ) throw (RuntimeException) @@ -416,14 +535,25 @@ namespace accessibility if ( IsAlive_Impl() ) { - pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); - pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); - pStateSetHelper->AddState( AccessibleStateType::ENABLED ); - pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); - if ( getListBox()->IsInplaceEditingEnabled() ) - pStateSetHelper->AddState( AccessibleStateType::EDITABLE ); - if ( IsShowing_Impl() ) - pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + switch(getAccessibleRole()) + { + case AccessibleRole::LABEL: + pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); + pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); + pStateSetHelper->AddState( AccessibleStateType::ENABLED ); + if ( getListBox()->IsInplaceEditingEnabled() ) + pStateSetHelper->AddState( AccessibleStateType::EDITABLE ); + if ( IsShowing_Impl() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + break; + case AccessibleRole::CHECK_BOX: + pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); + pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); + pStateSetHelper->AddState( AccessibleStateType::ENABLED ); + if ( IsShowing_Impl() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + break; + } getListBox()->FillAccessibleEntryStateSet( getListBox()->GetEntryFromPath( m_aEntryPath ), *pStateSetHelper ); } @@ -558,6 +688,7 @@ namespace accessibility SolarMutexGuard aSolarGuard; ::osl::MutexGuard aGuard( m_aMutex ); EnsureIsAlive(); + if(aPoint.X==0 && aPoint.Y==0) return 0; sal_Int32 nIndex = -1; SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); @@ -632,7 +763,20 @@ namespace accessibility ::osl::MutexGuard aGuard( m_aMutex ); // three actions supported - return ACCESSIBLE_ACTION_COUNT; + SvTreeListBox* pBox = getListBox(); + sal_uInt16 treeFlag = pBox->GetTreeFlags(); + sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + if( (treeFlag & TREEFLAG_CHKBTN) && !bHasButtons) + { + sal_Int16 role = getAccessibleRole(); + if ( role == AccessibleRole::CHECK_BOX ) + return 2; + else if ( role == AccessibleRole::LABEL ) + return 0; + } + else + return ACCESSIBLE_ACTION_COUNT; + return 0; } // ----------------------------------------------------------------------------- sal_Bool SAL_CALL AccessibleListBoxEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) @@ -644,14 +788,30 @@ namespace accessibility checkActionIndex_Impl( nIndex ); EnsureIsAlive(); - SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); - if ( pEntry ) + sal_uInt16 treeFlag = getListBox()->GetTreeFlags(); + if( nIndex == 0 && (treeFlag & TREEFLAG_CHKBTN) ) { - if ( getListBox()->IsExpanded( pEntry ) ) - getListBox()->Collapse( pEntry ); - else - getListBox()->Expand( pEntry ); - bRet = sal_True; + if(getAccessibleRole() == AccessibleRole::CHECK_BOX) + { + SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + SvButtonState state = getListBox()->GetCheckButtonState( pEntry ); + if ( state == SV_BUTTON_CHECKED ) + getListBox()->SetCheckButtonState(pEntry, (SvButtonState)SV_BMP_UNCHECKED); + else if (state == SV_BMP_UNCHECKED) + getListBox()->SetCheckButtonState(pEntry, (SvButtonState)SV_BUTTON_CHECKED); + } + } + else if( (nIndex == 1 && (treeFlag & TREEFLAG_CHKBTN) ) || (nIndex == 0) ) + { + SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + if ( getListBox()->IsExpanded( pEntry ) ) + getListBox()->Collapse( pEntry ); + else + getListBox()->Expand( pEntry ); + bRet = sal_True; + } } return bRet; @@ -666,7 +826,36 @@ namespace accessibility EnsureIsAlive(); static const OUString sActionDesc( "toggleExpand" ); - return sActionDesc; + static const OUString sActionDesc1( "Check" ); + static const OUString sActionDesc2( "UnCheck" ); + // sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + SvTreeListEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + SvButtonState state = getListBox()->GetCheckButtonState( pEntry ); + sal_uInt16 treeFlag = getListBox()->GetTreeFlags(); + if(nIndex == 0 && (treeFlag & TREEFLAG_CHKBTN)) + { + if(getAccessibleRole() == AccessibleRole::CHECK_BOX) + { + if ( state == SV_BUTTON_CHECKED ) + return sActionDesc2; + else if (state == SV_BMP_UNCHECKED) + return sActionDesc1; + } + else + { + //Sometimes, a List or Tree may have both checkbox and label at the same time + return OUString(); + } + }else if( (nIndex == 1 && (treeFlag & TREEFLAG_CHKBTN)) || nIndex == 0 ) + { + if( pEntry->HasChildren() || pEntry->HasChildrenOnDemand() ) + return getListBox()->IsExpanded( pEntry ) ? \ + OUString(TK_RES_STRING(STR_SVT_ACC_ACTION_COLLAPSE)) : + OUString(TK_RES_STRING(STR_SVT_ACC_ACTION_EXPAND)); + return OUString(); + + } + throw IndexOutOfBoundsException(); } // ----------------------------------------------------------------------------- Reference< XAccessibleKeyBinding > AccessibleListBoxEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) @@ -688,8 +877,7 @@ namespace accessibility EnsureIsAlive(); - SvTreeListEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); - SvTreeListEntry* pEntry = getListBox()->GetEntry( pParent, nChildIndex ); + SvTreeListEntry* pEntry = GetRealChild(nChildIndex); if ( !pEntry ) throw IndexOutOfBoundsException(); @@ -930,6 +1118,111 @@ namespace accessibility return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); } + // ----------------------------------------------------------------------------- + // XAccessibleValue + // ----------------------------------------------------------------------------- + + Any AccessibleListBoxEntry::getCurrentValue( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + Any aValue; + sal_Int32 level = ((sal_Int32) m_aEntryPath.size() - 1); + level = level < 0 ? 0: level; + aValue <<= level; + return aValue; + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleListBoxEntry::setCurrentValue( const Any& aNumber ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + + sal_Bool bReturn = sal_False; + SvTreeListBox* pBox = getListBox(); + if(getAccessibleRole() == AccessibleRole::CHECK_BOX) + { + SvTreeListEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + sal_Int32 nValue(0), nValueMin(0), nValueMax(0); + aNumber >>= nValue; + getMinimumValue() >>= nValueMin; + getMaximumValue() >>= nValueMax; + + if ( nValue < nValueMin ) + nValue = nValueMin; + else if ( nValue > nValueMax ) + nValue = nValueMax; + + pBox->SetCheckButtonState(pEntry, (SvButtonState) nValue ); + bReturn = sal_True; + } + } + + return bReturn; + } + + // ----------------------------------------------------------------------------- + + Any AccessibleListBoxEntry::getMaximumValue( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Any aValue; + // SvTreeListBox* pBox = getListBox(); + switch(getAccessibleRole()) + { + case AccessibleRole::CHECK_BOX: + aValue <<= (sal_Int32)1; + break; + case AccessibleRole::LABEL: + default: + break; + } + + return aValue; + } + + // ----------------------------------------------------------------------------- + + Any AccessibleListBoxEntry::getMinimumValue( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Any aValue; + // SvTreeListBox* pBox = getListBox(); + switch(getAccessibleRole()) + { + case AccessibleRole::CHECK_BOX: + aValue <<= (sal_Int32)0; + break; + case AccessibleRole::LABEL: + default: + break; + } + + return aValue; + } + + // ----------------------------------------------------------------------------- + + SvTreeListEntry* AccessibleListBoxEntry::GetRealChild(sal_Int32 nIndex) + { + SvTreeListEntry* pEntry = NULL; + SvTreeListEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + if (pParent) + { + pEntry = getListBox()->GetEntry( pParent, nIndex ); + if ( !pEntry && getAccessibleChildCount() > 0 ) + { + getListBox()->RequestingChildren(pParent); + pEntry = getListBox()->GetEntry( pParent, nIndex ); + } + } + return pEntry; + } //........................................................................ }// namespace accessibility //........................................................................ diff --git a/accessibility/source/extended/accessibletablistboxtable.cxx b/accessibility/source/extended/accessibletablistboxtable.cxx index a33c9f1ea774..a61e37a01fe4 100644 --- a/accessibility/source/extended/accessibletablistboxtable.cxx +++ b/accessibility/source/extended/accessibletablistboxtable.cxx @@ -131,6 +131,63 @@ namespace accessibility } break; } + case VCLEVENT_WINDOW_GETFOCUS : + { + uno::Any aOldValue, aNewValue; + aNewValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + break; + + } + case VCLEVENT_WINDOW_LOSEFOCUS : + { + uno::Any aOldValue, aNewValue; + aOldValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + break; + } + case VCLEVENT_LISTBOX_TREESELECT: + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if (pEntry) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + Reference< XAccessible > xChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() ); + TriState eState = STATE_DONTKNOW; + if ( m_pTabListBox->IsCellCheckBox( nRow, m_pTabListBox->GetCurrColumn(), eState ) ) + { + AccessibleCheckBoxCell* pCell = static_cast< AccessibleCheckBoxCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } + else + { + AccessibleBrowseBoxTableCell* pCell = static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } + } + } + break; + case VCLEVENT_LISTBOX_TREEFOCUS: + { + if ( m_pTabListBox && m_pTabListBox->HasFocus() ) + { + uno::Any aOldValue, aNewValue; + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + m_xCurChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() ); + aNewValue <<= m_xCurChild; + commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue ,aOldValue); + } + else + { + aNewValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue ,aOldValue); + } + } + } + break; case VCLEVENT_CHECKBOX_TOGGLE : { diff --git a/accessibility/source/extended/textwindowaccessibility.cxx b/accessibility/source/extended/textwindowaccessibility.cxx index 171204a76e20..1278248f98d2 100644 --- a/accessibility/source/extended/textwindowaccessibility.cxx +++ b/accessibility/source/extended/textwindowaccessibility.cxx @@ -30,6 +30,8 @@ namespace accessibility { + ::sal_Int32 getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos); + void sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId); // Both ::osl::Mutex and ParagraphBase implement acquire and release, and thus // ::rtl::Reference< Paragraph > does not work. So ParagraphImpl was factored @@ -1002,16 +1004,114 @@ Document::retrieveCharacterBounds(ParagraphImpl const * pParagraph, // XXX numeric overflow } +struct IndexCompare +{ + const ::css::beans::PropertyValue* pValues; + IndexCompare( const ::css::beans::PropertyValue* pVals ) : pValues(pVals) {} + bool operator() ( const sal_Int32& a, const sal_Int32& b ) const + { + return (pValues[a].Name < pValues[b].Name) ? true : false; + } +}; + css::uno::Sequence< css::beans::PropertyValue > Document::retrieveCharacterAttributes( ParagraphImpl const * pParagraph, ::sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes) { ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + + Font aFont = m_rEngine.GetFont(); + const sal_Int32 AttributeCount = 9; + sal_Int32 i = 0; + ::css::uno::Sequence< ::css::beans::PropertyValue > aAttribs( AttributeCount ); + //character background color + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharBackColor")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = mapFontColor( aFont.GetFillColor() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character color + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharColor")); + aAttribs[i].Handle = -1; + //aAttribs[i].Value = mapFontColor( aFont.GetColor() ); + aAttribs[i].Value = mapFontColor( m_rEngine.GetTextColor() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character font name + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontName")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (::rtl::OUString)aFont.GetName() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character height + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHeight")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetHeight() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character posture + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetItalic() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character relief + /*{ + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharRelief")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetRelief() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + }*/ + //character strikeout + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharStrikeout")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetStrikeout() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character underline + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetUnderline() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character weight + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (float)aFont.GetWeight() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + //character alignment + { + aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaAdjust")); + aAttribs[i].Handle = -1; + aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)m_rEngine.GetTextAlign() ); + aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE; + i++; + } + ::osl::MutexGuard aInternalGuard(GetMutex()); ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); // XXX numeric overflow - if (nIndex < 0 || nIndex >= m_rEngine.GetText(nNumber).getLength()) + // nIndex can be equal to getLength(); + if (nIndex < 0 || nIndex > m_rEngine.GetText(nNumber).getLength()) throw css::lang::IndexOutOfBoundsException( "textwindowaccessibility.cxx:" " Document::retrieveCharacterAttributes", @@ -1033,7 +1133,31 @@ Document::retrieveCharacterAttributes( aCharAttrSeq[ aRunIter->first ] = aRunIter->second; } - return convertHashMapToSequence( aCharAttrSeq ); + ::css::beans::PropertyValue* pValues = aAttribs.getArray(); + for (i = 0; i < AttributeCount; i++,pValues++) + { + aCharAttrSeq[ pValues->Name ] = *pValues; + } + + ::css::uno::Sequence< ::css::beans::PropertyValue > aRes = convertHashMapToSequence( aCharAttrSeq ); + + // sort the attributes + sal_Int32 nLength = aRes.getLength(); + const ::css::beans::PropertyValue* pPairs = aRes.getConstArray(); + sal_Int32* pIndices = new sal_Int32[nLength]; + for( i = 0; i < nLength; i++ ) + pIndices[i] = i; + std::sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) ); + // create sorted sequences accoring to index array + ::css::uno::Sequence< ::css::beans::PropertyValue > aNewValues( nLength ); + ::css::beans::PropertyValue* pNewValues = aNewValues.getArray(); + for( i = 0; i < nLength; i++ ) + { + pNewValues[i] = pPairs[pIndices[i]]; + } + delete[] pIndices; + + return aNewValues; } void Document::retrieveDefaultAttributesImpl( @@ -1388,7 +1512,8 @@ void Document::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) { // #107179# if our parent is a compound control (e.g. MultiLineEdit), // suppress the window focus events here - if ( !m_bCompoundControlChild ) +// IAccessible2 implementation 2009 + //if ( !m_bCompoundControlChild ) VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); } break; @@ -1453,7 +1578,26 @@ Document::getAccessibleAtPoint(css::awt::Point const & rPoint) } return 0; } +void Document::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + if (!m_rView.IsReadOnly()) + rStateSet.AddState( ::css::accessibility::AccessibleStateType::EDITABLE ); +} +void Document::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) +{ + if( getAccessibleParent()->getAccessibleContext()->getAccessibleRole() == ::css::accessibility::AccessibleRole::SCROLL_PANE ) + { + ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1); + aSequence[0] = getAccessibleParent(); + rRelationSet.AddRelation( ::css::accessibility::AccessibleRelation( ::css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); + } + else + { + VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet); + } +} // virtual void SAL_CALL Document::disposing() { @@ -1596,9 +1740,25 @@ IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent) ::osl::MutexGuard aInternalGuard(GetMutex()); if (!isAlive()) break; - - if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) + //to enable the PARAGRAPH to get focus for multiline edit + ::sal_Int32 count = getAccessibleChildCount(); + ::sal_Bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1; + if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty) { + Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused; + ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aTemp)); + if (xParagraph.is()) + { + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + STATE_CHANGED, + ::css::uno::Any(), + ::css::uno::makeAny( + ::css::accessibility::AccessibleStateType:: + FOCUSED)); + } + } + /* ::rtl::Reference< ParagraphImpl > xParagraph( getParagraph(m_aFocused)); if (xParagraph.is()) @@ -1609,7 +1769,7 @@ IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent) css::uno::makeAny( css::accessibility::AccessibleStateType:: FOCUSED)); - } + */ break; } case VCLEVENT_WINDOW_LOSEFOCUS: @@ -1617,7 +1777,24 @@ IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent) ::osl::MutexGuard aInternalGuard(GetMutex()); if (!isAlive()) break; + //to enable the PARAGRAPH to get focus for multiline edit + ::sal_Int32 count = getAccessibleChildCount(); + ::sal_Bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1; + if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty) + { + Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused; + ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aTemp)); + if (xParagraph.is()) + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + STATE_CHANGED, + ::css::uno::makeAny( + ::css::accessibility::AccessibleStateType:: + FOCUSED), + ::css::uno::Any()); + } + /* if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) { ::rtl::Reference< ParagraphImpl > xParagraph( @@ -1631,6 +1808,7 @@ IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent) FOCUSED), css::uno::Any()); } + */ break; } } @@ -1987,6 +2165,124 @@ void Document::handleParagraphNotifications() } } +::sal_Int32 Document::getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos) +{ + if (m_nSelectionFirstPara == -1) + return -1; + ::sal_Int32 Osp = m_nSelectionFirstPara, Osl = m_nSelectionFirstPos, Oep = m_nSelectionLastPara, Oel = m_nSelectionLastPos; + ::sal_Int32 Nsp = nNewFirstPara, Nsl = nNewFirstPos, Nep = nNewLastPara, Nel = nNewLastPos; + TextPaM Ns(Nsp, sal_uInt16(Nsl)); + TextPaM Ne(Nep, sal_uInt16(Nel)); + TextPaM Os(Osp, sal_uInt16(Osl)); + TextPaM Oe(Oep, sal_uInt16(Oel)); + + if (Os == Oe && Ns == Ne) + { + //only caret moves. + return 1; + } + else if (Os == Oe && Ns != Ne) + { + //old has no selection but new has selection + return 2; + } + else if (Os != Oe && Ns == Ne) + { + //old has selection but new has no selection. + return 3; + } + else if (Os != Oe && Ns != Ne && Osp == Nsp && Osl == Nsl) + { + //both old and new have selections. + if (Oep == Nep ) + { + //Send text_selection_change event on Nep + + return 4; + } + else if (Oep < Nep) + { + //all the following examples like 1,2->1,3 means that old start select para is 1, old end select para is 2, + // then press shift up, the new start select para is 1, new end select para is 3; + //for example, 1, 2 -> 1, 3; 4,1 -> 4, 7; 4,1 -> 4, 2; 4,4->4,5 + if (Nep >= Nsp) + { + // 1, 2 -> 1, 3; 4, 1 -> 4, 7; 4,4->4,5; + if (Oep < Osp) + { + // 4,1 -> 4,7; + return 5; + } + else if (Oep >= Osp) + { + // 1, 2 -> 1, 3; 4,4->4,5; + return 6; + } + } + else + { + // 4,1 -> 4,2, + if (Oep < Osp) + { + // 4,1 -> 4,2, + return 7; + } + else if (Oep >= Osp) + { + // no such condition. Oep > Osp = Nsp > Nep + } + } + } + else if (Oep > Nep) + { + // 3,2 -> 3,1; 4,7 -> 4,1; 4, 7 -> 4,6; 4,4 -> 4,3 + if (Nep >= Nsp) + { + // 4,7 -> 4,6 + if (Oep <= Osp) + { + //no such condition, Oep Osp) + { + // 4,7 ->4,6 + return 8; + } + } + else + { + // 3,2 -> 3,1, 4,7 -> 4,1; 4,4->4,3 + if (Oep <= Osp) + { + // 3,2 -> 3,1; 4,4->4,3 + return 9; + } + else if (Oep > Osp) + { + // 4,7 -> 4,1 + return 10; + } + } + } + } + return -1; +} + + +void Document::sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId) +{ + Paragraphs::iterator aEnd = ::std::min(m_xParagraphs->begin() + end + 1, m_aVisibleEnd); + for (Paragraphs::iterator aIt = ::std::max(m_xParagraphs->begin() + start, m_aVisibleBegin); + aIt < aEnd; ++aIt) + { + ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->notifyEvent( + nEventId, + ::css::uno::Any(), ::css::uno::Any()); + } +} + void Document::handleSelectionChangeNotification() { ::TextSelection const & rSelection = m_rView.GetSelection(); @@ -2028,7 +2324,11 @@ void Document::handleSelectionChangeNotification() ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt)); if (xParagraph.is()) { - if (aIt != m_aFocused) + //disable the first event when user types in empty field. + ::sal_Int32 count = getAccessibleChildCount(); + ::sal_Bool bEmpty = count > 1; + //if (aIt != m_aFocused) + if (aIt != m_aFocused && bEmpty) xParagraph->notifyEvent( css::accessibility::AccessibleEventId:: STATE_CHANGED, @@ -2048,6 +2348,100 @@ void Document::handleSelectionChangeNotification() } m_aFocused = aIt; + ::sal_Int32 nMin; + ::sal_Int32 nMax; + ::sal_Int32 ret = getSelectionType(nNewFirstPara, nNewFirstPos, nNewLastPara, nNewLastPos); + switch (ret) + { + case -1: + { + //no event + } + break; + case 1: + { + //only caret moved, already handled in above + } + break; + case 2: + { + //old has no selection but new has selection + nMin = ::std::min(nNewFirstPara, nNewLastPara); + nMax = ::std::max(nNewFirstPara, nNewLastPara); + sendEvent(nMin, nMax, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nMin, nMax, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 3: + { + //old has selection but new has no selection. + nMin = ::std::min(m_nSelectionFirstPara, m_nSelectionLastPara); + nMax = ::std::max(m_nSelectionFirstPara, m_nSelectionLastPara); + sendEvent(nMin, nMax, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nMin, nMax, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 4: + { + //Send text_selection_change event on Nep + sendEvent(nNewLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 5: + { + // 4, 1 -> 4, 7 + sendEvent(m_nSelectionLastPara, m_nSelectionFirstPara-1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nNewFirstPara+1, nNewLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 6: + { + // 1, 2 -> 1, 4; 4,4->4,5; + sendEvent(m_nSelectionLastPara+1, nNewLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 7: + { + // 4,1 -> 4,3, + sendEvent(m_nSelectionLastPara +1, nNewLastPara , ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 8: + { + // 4,7 ->4,5; + sendEvent(nNewLastPara + 1, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 9: + { + // 3,2 -> 3,1; 4,4->4,3 + sendEvent(nNewLastPara, m_nSelectionLastPara - 1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + case 10: + { + // 4,7 -> 4,1 + sendEvent(m_nSelectionFirstPara + 1, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nNewLastPara, nNewFirstPara - 1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + } + break; + default: + break; + } + + /* // Update both old and new selection. (Regardless of how the two selections // look like, there will always be two ranges to the left and right of the // overlap---the overlap and/or the range to the right of it possibly being @@ -2123,7 +2517,7 @@ void Document::handleSelectionChangeNotification() // notify selection changes notifySelectionChange( nFirst1, nLast1 ); notifySelectionChange( nFirst2, nLast2 ); - + */ m_nSelectionFirstPara = nNewFirstPara; m_nSelectionFirstPos = nNewFirstPos; m_nSelectionLastPara = nNewLastPara; diff --git a/accessibility/source/helper/accessiblestrings.src b/accessibility/source/helper/accessiblestrings.src index df426ad23d54..f112af3b48bb 100644 --- a/accessibility/source/helper/accessiblestrings.src +++ b/accessibility/source/helper/accessiblestrings.src @@ -19,10 +19,9 @@ #include - String RID_STR_ACC_ACTION_CLICK { - Text = "click"; + Text = "press"; }; String RID_STR_ACC_ACTION_TOGGLEPOPUP @@ -60,6 +59,53 @@ String RID_STR_ACC_NAME_BROWSEBUTTON Text [ en-US ] = "Browse"; }; +String STR_SVT_ACC_ACTION_EXPAND +{ + Text [ en-US ] = "Expand" ; +}; + +String STR_SVT_ACC_ACTION_COLLAPSE +{ + Text [ en-US ] = "Collapse"; +}; + +String STR_SVT_ACC_LISTENTRY_SELCTED_STATE +{ + Text [ en-US ] = "(Selected)"; +}; + +String RID_STR_ACC_NAME_PREVIEW +{ + Text [ en-US ] = "Preview"; +}; + +String RID_STR_ACC_ACTION_CHECK +{ + Text [ en-US ] = "Check"; +}; +String RID_STR_ACC_ACTION_UNCHECK +{ + Text [ en-US ] = "Uncheck"; +}; +String RID_STR_ACC_ACTION_DOUBLE_CLICK +{ + Text [ en-US ] = "Double click"; +}; + +String RID_STR_ACC_SCROLLBAR_NAME_VERTICAL +{ + Text [ en-US ] = "Vertical scroll bar"; +}; +String RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL +{ + Text [ en-US ] = "Horizontal scroll bar"; +}; + +String RID_STR_ACC_PANEL_DESCRIPTION +{ + Text [ en-US ] = "Please press enter to go into child control for more operations"; +}; + String RID_STR_ACC_DESC_PANELDECL_TABBAR { Text [ en-US ] = "Panel Deck Tab Bar"; diff --git a/accessibility/source/helper/characterattributeshelper.cxx b/accessibility/source/helper/characterattributeshelper.cxx index 8180cd9ad0e7..9f40168c1b78 100644 --- a/accessibility/source/helper/characterattributeshelper.cxx +++ b/accessibility/source/helper/characterattributeshelper.cxx @@ -38,6 +38,7 @@ CharacterAttributesHelper::CharacterAttributesHelper( const Font& rFont, sal_Int m_aAttributeMap.insert( AttributeMap::value_type( OUString( "CharStrikeout" ), makeAny( (sal_Int16) rFont.GetStrikeout() ) ) ); m_aAttributeMap.insert( AttributeMap::value_type( OUString( "CharUnderline" ), makeAny( (sal_Int16) rFont.GetUnderline() ) ) ); m_aAttributeMap.insert( AttributeMap::value_type( OUString( "CharWeight" ), makeAny( (float) rFont.GetWeight() ) ) ); + m_aAttributeMap.insert( AttributeMap::value_type( OUString( "CharPosture" ), makeAny( (sal_Int16)rFont.GetItalic() ) ) ); } diff --git a/accessibility/source/standard/accessiblemenubasecomponent.cxx b/accessibility/source/standard/accessiblemenubasecomponent.cxx index 48118edfc48e..b4d4dd953cf7 100644 --- a/accessibility/source/standard/accessiblemenubasecomponent.cxx +++ b/accessibility/source/standard/accessiblemenubasecomponent.cxx @@ -125,15 +125,20 @@ void OAccessibleMenuBaseComponent::SetEnabled( sal_Bool bEnabled ) { if ( m_bEnabled != bEnabled ) { + sal_Int16 nStateType=AccessibleStateType::ENABLED; + if (IsMenuHideDisabledEntries()) + { + nStateType = AccessibleStateType::VISIBLE; + } Any aOldValue[2], aNewValue[2]; if ( m_bEnabled ) { aOldValue[0] <<= AccessibleStateType::SENSITIVE; - aOldValue[1] <<= AccessibleStateType::ENABLED; + aOldValue[1] <<= nStateType; } else { - aNewValue[0] <<= AccessibleStateType::ENABLED; + aNewValue[0] <<= nStateType; aNewValue[1] <<= AccessibleStateType::SENSITIVE; } m_bEnabled = bEnabled; @@ -763,4 +768,9 @@ Reference< XAccessibleStateSet > OAccessibleMenuBaseComponent::getAccessibleStat // ----------------------------------------------------------------------------- +sal_Bool OAccessibleMenuBaseComponent::IsMenuHideDisabledEntries() +{ + return sal_False; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/accessiblemenuitemcomponent.cxx b/accessibility/source/standard/accessiblemenuitemcomponent.cxx index e458e95de2ee..04f531ec6e52 100644 --- a/accessibility/source/standard/accessiblemenuitemcomponent.cxx +++ b/accessibility/source/standard/accessiblemenuitemcomponent.cxx @@ -234,7 +234,8 @@ OUString OAccessibleMenuItemComponent::GetItemText() void OAccessibleMenuItemComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) { - if ( IsEnabled() ) + sal_Bool bEnabled = IsEnabled(); + if ( bEnabled ) { rStateSet.AddState( AccessibleStateType::ENABLED ); rStateSet.AddState( AccessibleStateType::SENSITIVE ); @@ -242,10 +243,10 @@ void OAccessibleMenuItemComponent::FillAccessibleStateSet( utl::AccessibleStateS if ( IsVisible() ) { - rStateSet.AddState( AccessibleStateType::VISIBLE ); rStateSet.AddState( AccessibleStateType::SHOWING ); + if( !IsMenuHideDisabledEntries() || bEnabled ) + rStateSet.AddState( AccessibleStateType::VISIBLE ); } - rStateSet.AddState( AccessibleStateType::OPAQUE ); } @@ -492,4 +493,16 @@ OUString OAccessibleMenuItemComponent::getToolTipText( ) throw (RuntimeExceptio // ----------------------------------------------------------------------------- +sal_Bool OAccessibleMenuItemComponent::IsMenuHideDisabledEntries() +{ + if (m_pParent ) + { + if( m_pParent->GetMenuFlags() & MENU_FLAG_HIDEDISABLEDENTRIES) + { + return sal_True; + } + } + return sal_False; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblebox.cxx b/accessibility/source/standard/vclxaccessiblebox.cxx index 6676b15e3159..2f40002e3147 100644 --- a/accessibility/source/standard/vclxaccessiblebox.cxx +++ b/accessibility/source/standard/vclxaccessiblebox.cxx @@ -110,11 +110,98 @@ void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEven { switch ( rVclWindowEvent.GetId() ) { + case VCLEVENT_LISTBOX_SELECT: + case VCLEVENT_LISTBOX_FOCUSITEMCHANGED: + + { + // Forward the call to the list child. + VCLXAccessibleList* pList = static_cast(m_xList.get()); + if ( pList == NULL ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = static_cast(m_xList.get()); + } + if ( pList != NULL ) + { + pList->ProcessWindowEvent (rVclWindowEvent, m_bIsDropDownBox); + if(m_bIsDropDownBox) + { + NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any()); + Any aOldValue; + Any aNewValue; + aOldValue <<= AccessibleStateType::INDETERMINATE; + NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); + + } + } + break; + } case VCLEVENT_DROPDOWN_OPEN: + { + VCLXAccessibleList* pList = static_cast(m_xList.get()); + if ( pList == NULL ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = static_cast(m_xList.get()); + } + if ( pList != NULL ) + { + pList->ProcessWindowEvent (rVclWindowEvent); + pList->HandleDropOpen(); + } + break; + } case VCLEVENT_DROPDOWN_CLOSE: + { + VCLXAccessibleList* pList = static_cast(m_xList.get()); + if ( pList == NULL ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = static_cast(m_xList.get()); + } + if ( pList != NULL ) + { + pList->ProcessWindowEvent (rVclWindowEvent); + } + Window* pWindow = GetWindow(); + if( pWindow && (pWindow->HasFocus() || pWindow->HasChildPathFocus()) ) + { + Any aOldValue, aNewValue; + aNewValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + } + case VCLEVENT_COMBOBOX_SELECT: + { + VCLXAccessibleList* pList = static_cast(m_xList.get()); + if (pList != NULL) + { + Reference xText (m_xText->getAccessibleContext(), UNO_QUERY); + if ( xText.is() ) + { + ::rtl::OUString sText = xText->getSelectedText(); + if ( !sText.getLength() ) + sText = xText->getText(); + pList->UpdateSelection_Acc (sText, m_bIsDropDownBox); + //if(m_bIsDropDownBox && !pList->IsInDropDown()) + if (m_bIsDropDownBox || ( !m_bIsDropDownBox && m_aBoxType==COMBOBOX)) + NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any()); + + Any aOldValue; + Any aNewValue; + aOldValue <<= AccessibleStateType::INDETERMINATE; + NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); + + } + } + break; + } + //case VCLEVENT_DROPDOWN_OPEN: + //case VCLEVENT_DROPDOWN_CLOSE: case VCLEVENT_LISTBOX_DOUBLECLICK: case VCLEVENT_LISTBOX_SCROLLED: - case VCLEVENT_LISTBOX_SELECT: + //case VCLEVENT_LISTBOX_SELECT: case VCLEVENT_LISTBOX_ITEMADDED: case VCLEVENT_LISTBOX_ITEMREMOVED: case VCLEVENT_COMBOBOX_ITEMADDED: @@ -133,7 +220,7 @@ void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEven break; } - case VCLEVENT_COMBOBOX_SELECT: + //case VCLEVENT_COMBOBOX_SELECT: case VCLEVENT_COMBOBOX_DESELECT: { // Selection is handled by VCLXAccessibleList which operates on @@ -157,6 +244,7 @@ void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEven case VCLEVENT_EDIT_MODIFY: case VCLEVENT_EDIT_SELECTIONCHANGED: + // case VCLEVENT_EDIT_CARETCHANGED: // Modify/Selection events are handled by the combo box instead of // directly by the edit field (Why?). Therefore, delegate this // call to the edit field. @@ -171,7 +259,30 @@ void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEven } } break; - + /* + // MT: Not sending VCLEVENT_LISTBOX_STATEUPDATE, see comment in ListBox::SelectEntryPos + case VCLEVENT_LISTBOX_STATEUPDATE: + { + // Need to update the INDETERMINATE state sometimes + if (m_bIsDropDownBox && m_aBoxType==LISTBOX) + { + sal_Int32 nSelectedEntryCount = 0; + ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); + if (pListBox != NULL && pListBox->GetEntryCount() > 0) + { + nSelectedEntryCount = pListBox->GetSelectEntryCount(); + Any aOldValue; + Any aNewValue; + if ( nSelectedEntryCount == 0) + aNewValue <<= AccessibleStateType::INDETERMINATE; + else + aOldValue <<= AccessibleStateType::INDETERMINATE; + NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); + } + } + break; + } + */ default: VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); } @@ -250,7 +361,11 @@ Reference SAL_CALL VCLXAccessibleBox::getAccessibleChild (sal_Int32 { ComboBox* pComboBox = static_cast(GetWindow()); if (pComboBox!=NULL && pComboBox->GetSubEdit()!=NULL) + //Set the edit's acc name the same as parent + { + pComboBox->GetSubEdit()->SetAccessibleName(getAccessibleName()); m_xText = pComboBox->GetSubEdit()->GetAccessible(); + } } else if (m_bIsDropDownBox) m_xText = new VCLXAccessibleTextField (GetVCLXWindow(),this); @@ -269,7 +384,11 @@ sal_Int16 SAL_CALL VCLXAccessibleBox::getAccessibleRole (void) throw (RuntimeExc // Return the role COMBO_BOX for both VCL combo boxes and // VCL list boxes in DropDown-Mode else PANEL. // This way the Java bridge has not to handle both independently. - return m_bIsDropDownBox ? AccessibleRole::COMBO_BOX : AccessibleRole::PANEL; + //return m_bIsDropDownBox ? AccessibleRole::COMBO_BOX : AccessibleRole::PANEL; + if (m_bIsDropDownBox || (!m_bIsDropDownBox && m_aBoxType == COMBOBOX )) + return AccessibleRole::COMBO_BOX; + else + return AccessibleRole::PANEL; } sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleIndexInParent (void) @@ -290,7 +409,7 @@ sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleActionCount (void) // There is one action for drop down boxes (toggle popup) and none for // the other boxes. - return m_bIsDropDownBox ? 1 : 0; + return m_bIsDropDownBox ? 0 : 1; } sal_Bool SAL_CALL VCLXAccessibleBox::doAccessibleAction (sal_Int32 nIndex) @@ -337,7 +456,11 @@ OUString SAL_CALL VCLXAccessibleBox::getAccessibleActionDescription (sal_Int32 n ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); if (nIndex<0 || nIndex>=getAccessibleActionCount()) throw ::com::sun::star::lang::IndexOutOfBoundsException(); - return TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); + //Solution:When combo_box,it should not has action information. + //return TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); + if (m_aBoxType == LISTBOX) + return ::rtl::OUString(); + return m_bIsDropDownBox?::rtl::OUString():TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); } Reference< XAccessibleKeyBinding > VCLXAccessibleBox::getAccessibleActionKeyBinding( sal_Int32 nIndex ) @@ -361,4 +484,104 @@ void SAL_CALL VCLXAccessibleBox::disposing (void) VCLXAccessibleComponent::disposing(); } +// ===== XAccessibleValue =============================================== +Any VCLXAccessibleBox::getCurrentValue( ) + throw( RuntimeException ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + Any aAny; + if( m_xList.is() && m_xText.is()) + { + // VCLXAccessibleList* pList = static_cast(m_xList.get()); + Reference xText (m_xText->getAccessibleContext(), UNO_QUERY); + if ( xText.is() ) + { + ::rtl::OUString sText = xText->getText(); + aAny <<= sText; + } + } + if (m_aBoxType == LISTBOX && m_bIsDropDownBox && m_xList.is() ) + { + + VCLXAccessibleList* pList = static_cast(m_xList.get()); + if(pList->IsInDropDown()) + { + if(pList->getSelectedAccessibleChildCount()>0) + { + Reference xName (pList->getSelectedAccessibleChild((sal_Int32)(0)), UNO_QUERY); + if(xName.is()) + { + aAny <<= xName->getAccessibleName(); + } + } + } + } + + return aAny; +} + +sal_Bool VCLXAccessibleBox::setCurrentValue( const Any& aNumber ) + throw( RuntimeException ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::rtl::OUString fValue; + sal_Bool bValid = (aNumber >>= fValue); + if( bValid ) + { + + } + return bValid; + +} + +Any VCLXAccessibleBox::getMaximumValue( ) + throw( RuntimeException ) +{ + Any aAny; + return aAny; +} + +Any VCLXAccessibleBox::getMinimumValue( ) + throw( RuntimeException ) +{ + Any aAny; + return aAny; +} + +// Set the INDETERMINATE state when there is no selected item for combobox +void VCLXAccessibleBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet(rStateSet); + if (m_aBoxType == COMBOBOX ) + { + ::rtl::OUString sText; + sal_Int32 nEntryCount = 0; + ComboBox* pComboBox = static_cast(GetWindow()); + if (pComboBox != NULL) + { + Edit* pSubEdit = pComboBox->GetSubEdit(); + if ( pSubEdit) + sText = pSubEdit->GetText(); + nEntryCount = pComboBox->GetEntryCount(); + } + if (sText.getLength() == 0 && nEntryCount >0) + rStateSet.AddState(AccessibleStateType::INDETERMINATE); + } + else if (m_aBoxType == LISTBOX && m_bIsDropDownBox == true) + { + sal_Int32 nSelectedEntryCount = 0; + ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); + if (pListBox != NULL && pListBox->GetEntryCount() > 0) + { + nSelectedEntryCount = pListBox->GetSelectEntryCount(); + if ( nSelectedEntryCount == 0) + rStateSet.AddState(AccessibleStateType::INDETERMINATE); + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblebutton.cxx b/accessibility/source/standard/vclxaccessiblebutton.cxx index 9b6c653e57f9..d3509018a901 100644 --- a/accessibility/source/standard/vclxaccessiblebutton.cxx +++ b/accessibility/source/standard/vclxaccessiblebutton.cxx @@ -95,6 +95,16 @@ void VCLXAccessibleButton::FillAccessibleStateSet( utl::AccessibleStateSetHelper if ( pButton->IsPressed() ) rStateSet.AddState( AccessibleStateType::PRESSED ); + + // IA2 CWS: If the button has a poppup menu,it should has the state EXPANDABLE + if( pButton->GetType() == WINDOW_MENUBUTTON ) + { + rStateSet.AddState( AccessibleStateType::EXPANDABLE ); + } + if( pButton->GetStyle() & WB_DEFBUTTON ) + { + rStateSet.AddState( AccessibleStateType::DEFAULT ); + } } } diff --git a/accessibility/source/standard/vclxaccessiblecheckbox.cxx b/accessibility/source/standard/vclxaccessiblecheckbox.cxx index d3b72f6cb22f..fa59bcd4cf62 100644 --- a/accessibility/source/standard/vclxaccessiblecheckbox.cxx +++ b/accessibility/source/standard/vclxaccessiblecheckbox.cxx @@ -230,7 +230,10 @@ OUString VCLXAccessibleCheckBox::getAccessibleActionDescription ( sal_Int32 nInd if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) throw IndexOutOfBoundsException(); - return OUString( TK_RES_STRING( RID_STR_ACC_ACTION_CLICK ) ); + if(IsChecked()) + return TK_RES_STRING( RID_STR_ACC_ACTION_UNCHECK ); + else + return TK_RES_STRING( RID_STR_ACC_ACTION_CHECK ); } // ----------------------------------------------------------------------------- diff --git a/accessibility/source/standard/vclxaccessiblelist.cxx b/accessibility/source/standard/vclxaccessiblelist.cxx index d5c1bc86726d..bc9b71c90bec 100644 --- a/accessibility/source/standard/vclxaccessiblelist.cxx +++ b/accessibility/source/standard/vclxaccessiblelist.cxx @@ -21,9 +21,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -60,6 +62,7 @@ VCLXAccessibleList::VCLXAccessibleList (VCLXWindow* pVCLWindow, BoxType aBoxType m_nLastSelectedPos ( LISTBOX_ENTRY_NOTFOUND ), m_bDisableProcessEvent ( false ), m_bVisible ( true ), + m_nCurSelectedPos ( LISTBOX_ENTRY_NOTFOUND ), m_xParent ( _xParent ) { // Because combo boxes and list boxes don't have a common interface for @@ -84,6 +87,7 @@ VCLXAccessibleList::VCLXAccessibleList (VCLXWindow* pVCLWindow, BoxType aBoxType } } UpdateVisibleLineCount(); + m_nCurSelectedPos=m_pListBoxHelper->GetSelectEntryPos(); sal_uInt16 nCount = static_cast(getAccessibleChildCount()); m_aAccessibleChildren.reserve(nCount); @@ -179,6 +183,211 @@ void VCLXAccessibleList::notifyVisibleStates(sal_Bool _bSetNew ) } } // ----------------------------------------------------------------------------- +void VCLXAccessibleList::UpdateSelection_Acc (::rtl::OUString sTextOfSelectedItem, bool b_IsDropDownList) +{ + if ( m_aBoxType == COMBOBOX ) + { + ComboBox* pBox = static_cast(GetWindow()); + if ( pBox != NULL ) + { + // Find the index of the selected item inside the VCL control... + sal_uInt16 nIndex = pBox->GetEntryPos(sTextOfSelectedItem); + // ...and then find the associated accessibility object. + if ( nIndex == LISTBOX_ENTRY_NOTFOUND ) + nIndex = 0; + UpdateSelection_Impl_Acc(b_IsDropDownList); + } + } +} + +// ----------------------------------------------------------------------------- +void VCLXAccessibleList::UpdateSelection_Impl_Acc(bool b_IsDropDownList) +{ + uno::Any aOldValue, aNewValue; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + Reference< XAccessible > xNewAcc; + if ( m_pListBoxHelper ) + { + sal_uInt16 i=0; + m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND; + for ( ListItems::iterator aIter = m_aAccessibleChildren.begin(); + aIter != m_aAccessibleChildren.end(); ++aIter,++i) + { + Reference< XAccessible > xHold = *aIter; + if ( xHold.is() ) + { + VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() ); + // Retrieve the item's index from the list entry. + sal_Bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i); + if (bNowSelected) + m_nCurSelectedPos = i; + + if ( bNowSelected && !pItem->IsSelected() ) + { + xNewAcc = *aIter; + aNewValue <<= xNewAcc; + } + else if ( pItem->IsSelected() ) + m_nLastSelectedPos = i; + + pItem->SetSelected( bNowSelected ); + } + else + { // it could happen that a child was not created before + checkEntrySelected(i,aNewValue,xNewAcc); + } + } + sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount(); + if ( i < nCount ) // here we have to check the if any other listbox entry is selected + { + for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i ) + ; + } + if ( xNewAcc.is() && GetWindow()->HasFocus() ) + { + if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND ) + aOldValue <<= getAccessibleChild( (sal_Int32)m_nLastSelectedPos ); + aNewValue <<= xNewAcc; + } + } + } + if (m_aBoxType == COMBOBOX && b_IsDropDownList) + { + //VCLXAccessibleDropDownComboBox + //when in list is dropped down, xText = NULL + if (m_pListBoxHelper->IsInDropDown()) + { + if ( aNewValue.hasValue() || aOldValue.hasValue() ) + { + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + + NotifyListItem(aNewValue); + + } + } + } + else if (m_aBoxType == COMBOBOX && !b_IsDropDownList) + { + //VCLXAccessibleComboBox + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, uno::Any(), uno::Any() ); + } + else if (m_aBoxType == LISTBOX && b_IsDropDownList) + { + //VCLXAccessibleDropdownListBox + //when in list is dropped down, xText = NULL + if (m_pListBoxHelper->IsInDropDown()) + { + if ( aNewValue.hasValue() || aOldValue.hasValue() ) + { + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + + NotifyListItem(aNewValue); + } + } + } + else if (m_aBoxType == LISTBOX && !b_IsDropDownList) + { + if ( aNewValue.hasValue()) + { + NotifyListItem(aNewValue); + } + } +} + +void VCLXAccessibleList::NotifyListItem(::com::sun::star::uno::Any& val) +{ + Reference< XAccessible > xCurItem; + val >>= xCurItem; + if (xCurItem.is()) + { + VCLXAccessibleListItem* pCurItem = static_cast< VCLXAccessibleListItem* >(xCurItem.get()); + if (pCurItem) + { + pCurItem->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED,Any(),Any()); + } + } +} + +void VCLXAccessibleList::UpdateFocus_Impl_Acc (sal_uInt16 nPos ,bool b_IsDropDownList) +{ + if (!(m_aBoxType == LISTBOX && !b_IsDropDownList)) + { + return ; + } + Reference xChild= CreateChild(nPos); + if ( !xChild.is() ) + { + return ; + } + m_nCurSelectedPos = nPos; + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); +} + +// ----------------------------------------------------------------------------- +void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent, bool b_IsDropDownList) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_LISTBOX_SELECT: + if ( !m_bDisableProcessEvent ) + UpdateSelection_Impl_Acc(b_IsDropDownList); + break; + case VCLEVENT_LISTBOX_FOCUSITEMCHANGED: + if ( !m_bDisableProcessEvent ) + UpdateFocus_Impl_Acc((sal_uInt16)reinterpret_cast(rVclWindowEvent.GetData()),b_IsDropDownList); + break; + case VCLEVENT_WINDOW_GETFOCUS: + break; + case VCLEVENT_CONTROL_GETFOCUS: + { + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + if (m_aBoxType == COMBOBOX && b_IsDropDownList) + { + //VCLXAccessibleDropDownComboBox + } + else if (m_aBoxType == LISTBOX && b_IsDropDownList) + { + } + else if ( m_aBoxType == LISTBOX && !b_IsDropDownList) + { + if ( m_pListBoxHelper ) + { + uno::Any aOldValue, + aNewValue; + sal_uInt16 nPos = m_nCurSelectedPos; //m_pListBoxHelper->GetSelectEntryPos(); + + if ( nPos == LISTBOX_ENTRY_NOTFOUND ) + nPos = m_pListBoxHelper->GetTopEntry(); + if ( nPos != LISTBOX_ENTRY_NOTFOUND ) + aNewValue <<= CreateChild(nPos); + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + } + } + } + break; + default: + break; + } + +} +// ----------------------------------------------------------------------------- void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) { // Create a reference to this object to prevent an early release of the @@ -198,10 +407,6 @@ void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEve UpdateEntryRange_Impl(); break; - case VCLEVENT_LISTBOX_SELECT: - if ( !m_bDisableProcessEvent ) - UpdateSelection_Impl(); - break; // The selection events VCLEVENT_COMBOBOX_SELECT and // VCLEVENT_COMBOBOX_DESELECT are not handled here because here we // have no access to the edit field. Its text is necessary to @@ -227,20 +432,29 @@ void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEve rVclWindowEvent.GetData())); break; case VCLEVENT_CONTROL_GETFOCUS: - VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); - if ( m_pListBoxHelper ) { - uno::Any aOldValue, - aNewValue; - sal_uInt16 nPos = m_pListBoxHelper->GetSelectEntryPos(); - if ( nPos == LISTBOX_ENTRY_NOTFOUND ) - nPos = m_pListBoxHelper->GetTopEntry(); - if ( nPos != LISTBOX_ENTRY_NOTFOUND ) - aNewValue <<= CreateChild(nPos); - - NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, - aOldValue, - aNewValue ); + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + // Added by IBM Symphony Acc team to handle the list item focus when List control get focus + sal_Bool b_IsDropDownList = sal_True; + if (m_pListBoxHelper) + b_IsDropDownList = ((m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN); + if ( m_aBoxType == LISTBOX && !b_IsDropDownList ) + { + if ( m_pListBoxHelper ) + { + uno::Any aOldValue, + aNewValue; + sal_uInt16 nPos = m_nCurSelectedPos; + + if ( nPos == LISTBOX_ENTRY_NOTFOUND ) + nPos = m_pListBoxHelper->GetTopEntry(); + if ( nPos != LISTBOX_ENTRY_NOTFOUND ) + aNewValue <<= CreateChild(nPos); + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + } + } } break; @@ -248,6 +462,24 @@ void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEve VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); } } + + void VCLXAccessibleList::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) +{ + ListBox* pBox = static_cast(GetWindow()); + if( m_aBoxType == LISTBOX ) + { + if (m_pListBoxHelper && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) != WB_DROPDOWN) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); + aSequence[0] = pBox->GetAccessible(); + rRelationSet.AddRelation( com::sun::star::accessibility::AccessibleRelation( com::sun::star::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); + } + } + else + { + VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet); + } +} // ----------------------------------------------------------------------------- /** To find out which item is currently selected and to update the SELECTED @@ -304,13 +536,7 @@ Reference VCLXAccessibleList::CreateChild (sal_Int32 i) { xChild = m_aAccessibleChildren[nPos]; // check if position is empty and can be used else we have to adjust all entries behind this - if ( xChild.is() ) - { - ListItems::iterator aIter = m_aAccessibleChildren.begin() + nPos; - ::std::mem_fun_t aTemp(&VCLXAccessibleListItem::IncrementIndexInParent); - adjustEntriesIndexInParent( aIter, aTemp); - } - else + if (!xChild.is()) { xChild = new VCLXAccessibleListItem(m_pListBoxHelper, i, this); m_aAccessibleChildren[nPos] = xChild; @@ -323,6 +549,8 @@ Reference VCLXAccessibleList::CreateChild (sal_Int32 i) bool bNowSelected = false; if ( m_pListBoxHelper ) bNowSelected = m_pListBoxHelper->IsEntryPosSelected ((sal_uInt16)i); + if (bNowSelected) + m_nCurSelectedPos = sal_uInt16(i); VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(xChild.get()); pItem->SetSelected( bNowSelected ); @@ -339,27 +567,9 @@ Reference VCLXAccessibleList::CreateChild (sal_Int32 i) } // ----------------------------------------------------------------------------- -void VCLXAccessibleList::HandleChangedItemList (bool bItemInserted, sal_Int32 nIndex) +void VCLXAccessibleList::HandleChangedItemList (bool /*bItemInserted*/, sal_Int32 /*nIndex*/) { - if ( !bItemInserted ) - { - if ( nIndex == -1 ) // special handling here - { - clearItems(); - } - else - { - if ( nIndex >= 0 && static_cast(nIndex) < m_aAccessibleChildren.size() ) - { - ListItems::iterator aIter = m_aAccessibleChildren.erase(m_aAccessibleChildren.begin()+nIndex); - ::std::mem_fun_t aTemp(&VCLXAccessibleListItem::DecrementIndexInParent); - adjustEntriesIndexInParent( aIter, aTemp ); - } - } - } - else - getAccessibleChild(nIndex); - + clearItems(); NotifyAccessibleEvent ( AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); @@ -406,7 +616,7 @@ Reference SAL_CALL VCLXAccessibleList::getAccessibleChild (sal_Int3 Reference< XAccessible > xChild; // search for the child - if ( static_cast(i) >= m_aAccessibleChildren.size() ) + if ( i >= static_cast(m_aAccessibleChildren.size()) ) xChild = CreateChild (i); else { @@ -591,6 +801,7 @@ void VCLXAccessibleList::UpdateSelection_Impl(sal_uInt16) if ( m_pListBoxHelper ) { sal_uInt16 i=0; + m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND; for ( ListItems::iterator aIter = m_aAccessibleChildren.begin(); aIter != m_aAccessibleChildren.end(); ++aIter,++i) { @@ -600,6 +811,8 @@ void VCLXAccessibleList::UpdateSelection_Impl(sal_uInt16) VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() ); // Retrieve the item's index from the list entry. sal_Bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i); + if (bNowSelected) + m_nCurSelectedPos = i; if ( bNowSelected && !pItem->IsSelected() ) { @@ -630,14 +843,19 @@ void VCLXAccessibleList::UpdateSelection_Impl(sal_uInt16) } } } - - if ( aNewValue.hasValue() || aOldValue.hasValue() ) - NotifyAccessibleEvent( - AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, - aOldValue, - aNewValue ); - - NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + if (!m_pListBoxHelper->IsInDropDown()) + { + } + else + { + if ( aNewValue.hasValue() || aOldValue.hasValue() ) + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + //the SELECTION_CHANGED is not necessary + //NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } } // ----------------------------------------------------------------------------- @@ -798,10 +1016,8 @@ awt::Rectangle VCLXAccessibleList::implGetBounds() throw (uno::RuntimeException) if ( pBox ) { Size aSize = pBox->GetSubEdit()->GetSizePixel(); - aBounds.X += aSize.Height(); - aBounds.Y += aSize.Width(); + aBounds.Y += aSize.Height(); aBounds.Height -= aSize.Height(); - aBounds.Width -= aSize.Width(); } } } @@ -829,13 +1045,37 @@ awt::Point VCLXAccessibleList::getLocationOnScreen( ) throw (uno::RuntimeExcept ComboBox* pBox = static_cast(GetWindow()); if ( pBox ) { - aPos.X += pBox->GetSubEdit()->GetSizePixel().Height(); - aPos.Y += pBox->GetSubEdit()->GetSizePixel().Width(); + aPos.Y += pBox->GetSubEdit()->GetSizePixel().Height(); } } } return aPos; } + // ----------------------------------------------------------------------------- +sal_Bool VCLXAccessibleList::IsInDropDown() +{ + return m_pListBoxHelper->IsInDropDown(); +} + +// ----------------------------------------------------------------------------- + +void VCLXAccessibleList::HandleDropOpen() +{ + if ( !m_bDisableProcessEvent ) + UpdateSelection_Impl(); + if (m_nCurSelectedPos != LISTBOX_ENTRY_NOTFOUND && + m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND) + { + Reference< XAccessible > xChild = getAccessibleChild(m_nCurSelectedPos); + if(xChild.is()) + { + uno::Any aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, uno::Any(), aNewValue ); + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblelistitem.cxx b/accessibility/source/standard/vclxaccessiblelistitem.cxx index 1a9471ce967a..d4b2408f97d5 100644 --- a/accessibility/source/standard/vclxaccessiblelistitem.cxx +++ b/accessibility/source/standard/vclxaccessiblelistitem.cxx @@ -300,9 +300,14 @@ Reference< XAccessibleStateSet > SAL_CALL VCLXAccessibleListItem::getAccessibleS if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) { pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); - pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); - pStateSetHelper->AddState( AccessibleStateType::ENABLED ); - pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); + + if(m_pListBoxHelper->IsEnabled()) + { + pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); + pStateSetHelper->AddState( AccessibleStateType::ENABLED ); + pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); + } + if ( m_bSelected ) pStateSetHelper->AddState( AccessibleStateType::SELECTED ); if ( m_bVisible ) diff --git a/accessibility/source/standard/vclxaccessiblemenu.cxx b/accessibility/source/standard/vclxaccessiblemenu.cxx index 625a0db49416..3ccbf7c2cfe1 100644 --- a/accessibility/source/standard/vclxaccessiblemenu.cxx +++ b/accessibility/source/standard/vclxaccessiblemenu.cxx @@ -242,4 +242,14 @@ void VCLXAccessibleMenu::deselectAccessibleChild( sal_Int32 nChildIndex ) throw // ----------------------------------------------------------------------------- +OUString VCLXAccessibleMenu::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) + throw IndexOutOfBoundsException(); + + return OUString( ); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblemenuitem.cxx b/accessibility/source/standard/vclxaccessiblemenuitem.cxx index dc36a48f71ce..a8f76edb4f3f 100644 --- a/accessibility/source/standard/vclxaccessiblemenuitem.cxx +++ b/accessibility/source/standard/vclxaccessiblemenuitem.cxx @@ -185,8 +185,19 @@ Sequence< OUString > VCLXAccessibleMenuItem::getSupportedServiceNames() throw (R sal_Int16 VCLXAccessibleMenuItem::getAccessibleRole( ) throw (RuntimeException) { OExternalLockGuard aGuard( this ); - - return AccessibleRole::MENU_ITEM; + // IA2 CWS. MT: We had the aditional roles in UAA for ever, but never used them anywhere. + // Looks reasonable, but need to verify in Orca and VoiceOver. + sal_Int16 nRole = AccessibleRole::MENU_ITEM; + if ( m_pParent ) + { + sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos ); + MenuItemBits nItemBits = m_pParent->GetItemBits(nItemId); + if( nItemBits & MIB_RADIOCHECK) + nRole = AccessibleRole::RADIO_MENU_ITEM; + else if( nItemBits & MIB_CHECKABLE) + nRole = AccessibleRole::CHECK_MENU_ITEM; + } + return nRole; } // ----------------------------------------------------------------------------- @@ -449,7 +460,7 @@ OUString VCLXAccessibleMenuItem::getAccessibleActionDescription ( sal_Int32 nInd if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) throw IndexOutOfBoundsException(); - return OUString( TK_RES_STRING( RID_STR_ACC_ACTION_CLICK ) ); + return TK_RES_STRING( RID_STR_ACC_ACTION_SELECT ); } // ----------------------------------------------------------------------------- diff --git a/accessibility/source/standard/vclxaccessibleradiobutton.cxx b/accessibility/source/standard/vclxaccessibleradiobutton.cxx index 2c6df31227c8..7e8b948ad3c9 100644 --- a/accessibility/source/standard/vclxaccessibleradiobutton.cxx +++ b/accessibility/source/standard/vclxaccessibleradiobutton.cxx @@ -189,7 +189,7 @@ OUString VCLXAccessibleRadioButton::getAccessibleActionDescription ( sal_Int32 n if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) throw IndexOutOfBoundsException(); - return OUString( TK_RES_STRING( RID_STR_ACC_ACTION_CLICK ) ); + return TK_RES_STRING( RID_STR_ACC_ACTION_SELECT ); } // ----------------------------------------------------------------------------- diff --git a/accessibility/source/standard/vclxaccessiblescrollbar.cxx b/accessibility/source/standard/vclxaccessiblescrollbar.cxx index c87cdc4c6831..3ef392199f41 100644 --- a/accessibility/source/standard/vclxaccessiblescrollbar.cxx +++ b/accessibility/source/standard/vclxaccessiblescrollbar.cxx @@ -79,7 +79,8 @@ void VCLXAccessibleScrollBar::FillAccessibleStateSet( utl::AccessibleStateSetHel VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); if ( pVCLXScrollBar ) { - rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + // IA2 CWS: scroll bar should not have FOCUSABLE state. + // rStateSet.AddState( AccessibleStateType::FOCUSABLE ); if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::HORIZONTAL ) rStateSet.AddState( AccessibleStateType::HORIZONTAL ); else if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::VERTICAL ) @@ -266,4 +267,21 @@ Any VCLXAccessibleScrollBar::getMinimumValue( ) throw (RuntimeException) // ----------------------------------------------------------------------------- +OUString VCLXAccessibleScrollBar::getAccessibleName( ) throw (uno::RuntimeException) +{ + OExternalLockGuard aGuard( this ); + + OUString aName; + VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); + if ( pVCLXScrollBar ) + { + if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::HORIZONTAL ) + aName = TK_RES_STRING( RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL ); + else if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::VERTICAL ) + aName = TK_RES_STRING( RID_STR_ACC_SCROLLBAR_NAME_VERTICAL ); + } + return aName; +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletabcontrol.cxx b/accessibility/source/standard/vclxaccessibletabcontrol.cxx index a40796bead2c..ecd6a9df48d1 100644 --- a/accessibility/source/standard/vclxaccessibletabcontrol.cxx +++ b/accessibility/source/standard/vclxaccessibletabcontrol.cxx @@ -75,8 +75,6 @@ void VCLXAccessibleTabControl::UpdateFocused() void VCLXAccessibleTabControl::UpdateSelected( sal_Int32 i, bool bSelected ) { - NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); - if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() ) { Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); diff --git a/accessibility/source/standard/vclxaccessibletextcomponent.cxx b/accessibility/source/standard/vclxaccessibletextcomponent.cxx index e186c6bf22c9..aa43522af607 100644 --- a/accessibility/source/standard/vclxaccessibletextcomponent.cxx +++ b/accessibility/source/standard/vclxaccessibletextcomponent.cxx @@ -184,9 +184,61 @@ Sequence< PropertyValue > VCLXAccessibleTextComponent::getCharacterAttributes( s if ( GetWindow() ) { Font aFont = GetWindow()->GetControlFont(); + sal_Int32 nBackColor = GetWindow()->GetControlBackground().GetColor(); sal_Int32 nColor = GetWindow()->GetControlForeground().GetColor(); + + // MT: Code with default font was introduced with the IA2 CWS, but I am not convinced that this is the correct font... + // Decide what to do when we have a concrete issue. + /* + Font aDefaultVCLFont; + OutputDevice* pDev = Application::GetDefaultDevice(); + if ( pDev ) + { + aDefaultVCLFont = pDev->GetSettings().GetStyleSettings().GetAppFont(); + if ( !aFont.GetName().Len() ) + { + String aDefaultName = aDefaultVCLFont.GetName(); + aFont.SetName( aDefaultName ); + } + if ( !aFont.GetHeight() ) + { + aFont.SetHeight( aDefaultVCLFont.GetHeight() ); + } + if ( aFont.GetWeight() == WEIGHT_DONTKNOW ) + { + aFont.SetWeight( aDefaultVCLFont.GetWeight() ); + } + + //if nColor is -1, it may indicate that the default color black is using. + if ( nColor == -1) + { + nColor = aDefaultVCLFont.GetColor().GetColor(); + } + } + */ + + // MT: Adjustment stuff was introduced with the IA2 CWS, but adjustment is not a character attribute... + // In case we reintroduce it, use adjustment as extra parameter for the CharacterAttributesHelper... + /* + WinBits aBits = GetWindow()->GetStyle(); + sal_Int16 nAdjust = -1; + if ( aBits & WB_LEFT ) + { + nAdjust = style::ParagraphAdjust_LEFT; + } + else if ( aBits & WB_RIGHT ) + { + nAdjust = style::ParagraphAdjust_RIGHT; + } + else if ( aBits & WB_CENTER ) + { + nAdjust = style::ParagraphAdjust_CENTER; + } + */ + ::std::auto_ptr< CharacterAttributesHelper > pHelper( new CharacterAttributesHelper( aFont, nBackColor, nColor ) ); + aValues = pHelper->GetCharacterAttributes( aRequestedAttributes ); } diff --git a/accessibility/source/standard/vclxaccessibletoolbox.cxx b/accessibility/source/standard/vclxaccessibletoolbox.cxx index 452083eed455..4492fde91d86 100644 --- a/accessibility/source/standard/vclxaccessibletoolbox.cxx +++ b/accessibility/source/standard/vclxaccessibletoolbox.cxx @@ -195,7 +195,7 @@ VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( sal_Int32 _nPos, { ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos ); // returns only toolbox buttons, not windows - if ( aIter != m_aAccessibleChildren.end() && !aIter->second.is()) + if ( aIter != m_aAccessibleChildren.end() && aIter->second.is()) pItem = static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() ); } @@ -271,11 +271,14 @@ void VCLXAccessibleToolBox::ReleaseFocus_Impl( sal_Int32 _nPos ) } } // ----------------------------------------------------------------------------- -void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 ) +void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 _nPos ) { ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() ); if ( pToolBox ) { + sal_uInt16 nFocusId = pToolBox->GetItemId( (sal_uInt16)_nPos ); + VCLXAccessibleToolBoxItem* pFocusItem = NULL; + for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin(); aIter != m_aAccessibleChildren.end(); ++aIter ) { @@ -284,7 +287,12 @@ void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 ) VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() ); pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) ); + if ( nItemId == nFocusId ) + pFocusItem = pItem; } + //Solution:If the position is not a child item,the focus should not be called + if ( pFocusItem && (sal_uInt16)_nPos != TOOLBOX_ITEM_NOTFOUND ) + pFocusItem->SetFocus( sal_True ); } } // ----------------------------------------------------------------------------- @@ -525,23 +533,41 @@ void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindow // to prevent an early release of the toolbox (VCLEVENT_OBJECT_DYING) Reference< XAccessibleContext > xTemp = this; + ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() ); switch ( rVclWindowEvent.GetId() ) { case VCLEVENT_TOOLBOX_CLICK: + case VCLEVENT_TOOLBOX_SELECT: { if ( rVclWindowEvent.GetData() ) { UpdateChecked_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() ); UpdateIndeterminate_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() ); } + else if( pToolBox->GetItemPos(pToolBox->GetCurItemId()) != TOOLBOX_ITEM_NOTFOUND ) + { + UpdateChecked_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) ); + UpdateIndeterminate_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) ); + } break; } case VCLEVENT_TOOLBOX_DOUBLECLICK: case VCLEVENT_TOOLBOX_ACTIVATE: case VCLEVENT_TOOLBOX_DEACTIVATE: - case VCLEVENT_TOOLBOX_SELECT: + //case VCLEVENT_TOOLBOX_SELECT: break; - + // IA2 CWS. MT: Still using VCLEVENT_TOOLBOX_CLICK, see comment in vcl/source/window/toolbox2.cxx + /* + case VCLEVENT_TOOLBOX_ITEMUPDATED: + { + if ( rVclWindowEvent.GetData() ) + { + UpdateChecked_Impl( TOOLBOX_ITEM_NOTFOUND ); + UpdateIndeterminate_Impl( (sal_Int32)rVclWindowEvent.GetData() ); + } + break; + } + */ case VCLEVENT_TOOLBOX_HIGHLIGHT: UpdateFocus_Impl(); break; @@ -551,7 +577,6 @@ void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindow break; case VCLEVENT_TOOLBOX_ITEMADDED : -// UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), VCLEVENT_TOOLBOX_ITEMADDED == rVclWindowEvent.GetId() ); UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), sal_True ); break; @@ -598,14 +623,14 @@ void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindow case VCLEVENT_OBJECT_DYING : { // if this toolbox is a subtoolbox, we have to relese it from its parent - ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() ); - if ( pToolBox && pToolBox->GetParent() && - pToolBox->GetParent()->GetType() == WINDOW_TOOLBOX ) + ToolBox* pBox = static_cast< ToolBox* >( GetWindow() ); + if ( pBox && pBox->GetParent() && + pBox->GetParent()->GetType() == WINDOW_TOOLBOX ) { VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >( - pToolBox->GetParent()->GetAccessible()->getAccessibleContext().get() ); + pBox->GetParent()->GetAccessible()->getAccessibleContext().get() ); if ( pParent ) - pParent->ReleaseSubToolBox( pToolBox ); + pParent->ReleaseSubToolBox( pBox ); } // dispose all items diff --git a/accessibility/source/standard/vclxaccessibletoolboxitem.cxx b/accessibility/source/standard/vclxaccessibletoolboxitem.cxx index 04889bf0f2d9..f63f0e4bb89c 100644 --- a/accessibility/source/standard/vclxaccessibletoolboxitem.cxx +++ b/accessibility/source/standard/vclxaccessibletoolboxitem.cxx @@ -87,6 +87,10 @@ VCLXAccessibleToolBoxItem::VCLXAccessibleToolBoxItem( ToolBox* _pToolBox, sal_In else if (( ( nBits & TIB_CHECKABLE ) == TIB_CHECKABLE ) || ( ( nBits & TIB_AUTOCHECK ) == TIB_AUTOCHECK ) ) m_nRole = AccessibleRole::TOGGLE_BUTTON; + else if ( (nBits & TIB_DROPDOWN) == TIB_DROPDOWN ) + { + m_nRole = AccessibleRole::BUTTON_DROPDOWN; + } else if ( m_pToolBox->GetItemWindow( m_nItemId ) ) m_nRole = AccessibleRole::PANEL; break; @@ -121,6 +125,18 @@ OUString VCLXAccessibleToolBoxItem::GetText( bool _bAsName ) if ( m_pToolBox && m_nItemId > 0 && ( _bAsName || m_pToolBox->GetButtonType() != BUTTON_SYMBOL ) ) { sRet = m_pToolBox->GetItemText( m_nItemId ); + if (sRet.isEmpty()) + { + Window* pItemWindow = m_pToolBox->GetItemWindow( m_nItemId ); + if ( m_nRole == AccessibleRole::PANEL && pItemWindow && pItemWindow->GetAccessible().is() && + pItemWindow->GetAccessible()->getAccessibleContext().is() ) + { + OUString sWinText = pItemWindow->GetAccessible()->getAccessibleContext()->getAccessibleName(); + if (!sWinText.isEmpty()) + sRet = sWinText; + } + } + } return sRet; } @@ -142,6 +158,8 @@ void VCLXAccessibleToolBoxItem::SetFocus( sal_Bool _bFocus ) // ----------------------------------------------------------------------------- void VCLXAccessibleToolBoxItem::SetChecked( sal_Bool _bCheck ) { + if( m_nRole == AccessibleRole::PANEL) + return; if ( m_bIsChecked != _bCheck ) { Any aOldValue; @@ -340,11 +358,17 @@ OUString SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleDescription( ) throw { OExternalLockGuard aGuard( this ); - OUString sDescription; - if ( m_pToolBox ) - sDescription = m_pToolBox->GetHelpText( m_nItemId ); - - return sDescription; + if (m_nRole == AccessibleRole::PANEL && getAccessibleChildCount() > 0) + { + return TK_RES_STRING( RID_STR_ACC_PANEL_DESCRIPTION ); + } + else + { + OUString sDescription; + if ( m_pToolBox ) + sDescription = m_pToolBox->GetHelpText( m_nItemId ); + return sDescription; + } } // ----------------------------------------------------------------------------- OUString SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleName( ) throw (RuntimeException) @@ -374,11 +398,11 @@ Reference< XAccessibleStateSet > SAL_CALL VCLXAccessibleToolBoxItem::getAccessib if ( m_pToolBox && !rBHelper.bDisposed && !rBHelper.bInDispose ) { pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); - if ( m_bIsChecked ) + if ( m_bIsChecked && m_nRole != AccessibleRole::PANEL ) pStateSetHelper->AddState( AccessibleStateType::CHECKED ); if ( m_bIndeterminate ) pStateSetHelper->AddState( AccessibleStateType::INDETERMINATE ); - if ( m_pToolBox->IsItemEnabled( m_nItemId ) ) + if ( m_pToolBox->IsEnabled() && m_pToolBox->IsItemEnabled( m_nItemId ) ) { pStateSetHelper->AddState( AccessibleStateType::ENABLED ); pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); @@ -644,6 +668,8 @@ Any VCLXAccessibleToolBoxItem::getCurrentValue( ) throw (RuntimeException) if ( m_pToolBox ) aValue <<= (sal_Int32)m_pToolBox->IsItemChecked( m_nItemId ); + if( m_nRole == AccessibleRole::PANEL ) + aValue <<= (sal_Int32)0; return aValue; } // ----------------------------------------------------------------------------- -- cgit v1.2.3