10841af79SAndrew Rist /************************************************************** 2*aa5a148eSmseidel * 30841af79SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 40841af79SAndrew Rist * or more contributor license agreements. See the NOTICE file 50841af79SAndrew Rist * distributed with this work for additional information 60841af79SAndrew Rist * regarding copyright ownership. The ASF licenses this file 70841af79SAndrew Rist * to you under the Apache License, Version 2.0 (the 80841af79SAndrew Rist * "License"); you may not use this file except in compliance 90841af79SAndrew Rist * with the License. You may obtain a copy of the License at 10*aa5a148eSmseidel * 110841af79SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*aa5a148eSmseidel * 130841af79SAndrew Rist * Unless required by applicable law or agreed to in writing, 140841af79SAndrew Rist * software distributed under the License is distributed on an 150841af79SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 160841af79SAndrew Rist * KIND, either express or implied. See the License for the 170841af79SAndrew Rist * specific language governing permissions and limitations 180841af79SAndrew Rist * under the License. 19*aa5a148eSmseidel * 200841af79SAndrew Rist *************************************************************/ 210841af79SAndrew Rist 220841af79SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_accessibility.hxx" 26cdf0e10cSrcweir #include <accessibility/extended/accessiblelistbox.hxx> 27cdf0e10cSrcweir #include <accessibility/extended/accessiblelistboxentry.hxx> 28cdf0e10cSrcweir #include <svtools/svtreebx.hxx> 29cdf0e10cSrcweir #include <com/sun/star/awt/Point.hpp> 30cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp> 31cdf0e10cSrcweir #include <com/sun/star/awt/Size.hpp> 32cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp> 33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp> 34cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp> 35cdf0e10cSrcweir #include <tools/debug.hxx> 36cdf0e10cSrcweir #include <vcl/svapp.hxx> 37cdf0e10cSrcweir #include <toolkit/awt/vclxwindow.hxx> 38cdf0e10cSrcweir #include <toolkit/helper/convert.hxx> 39cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx> 40cdf0e10cSrcweir 41cdf0e10cSrcweir //........................................................................ 42cdf0e10cSrcweir namespace accessibility 43cdf0e10cSrcweir { 44cdf0e10cSrcweir //........................................................................ 45cdf0e10cSrcweir 46cdf0e10cSrcweir // class AccessibleListBox ----------------------------------------------------- 47cdf0e10cSrcweir 48cdf0e10cSrcweir using namespace ::com::sun::star::accessibility; 49cdf0e10cSrcweir using namespace ::com::sun::star::uno; 50cdf0e10cSrcweir using namespace ::com::sun::star::lang; 51cdf0e10cSrcweir using namespace ::com::sun::star; 52cdf0e10cSrcweir DBG_NAME(AccessibleListBox)53cdf0e10cSrcweir DBG_NAME(AccessibleListBox) 54cdf0e10cSrcweir 55cdf0e10cSrcweir // ----------------------------------------------------------------------------- 56cdf0e10cSrcweir // Ctor() and Dtor() 57cdf0e10cSrcweir // ----------------------------------------------------------------------------- 58cdf0e10cSrcweir AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) : 59cdf0e10cSrcweir 60cdf0e10cSrcweir VCLXAccessibleComponent( _rListBox.GetWindowPeer() ), 61cdf0e10cSrcweir m_xParent( _xParent ) 62cdf0e10cSrcweir { 63cdf0e10cSrcweir DBG_CTOR( AccessibleListBox, NULL ); 64cdf0e10cSrcweir } 65cdf0e10cSrcweir // ----------------------------------------------------------------------------- ~AccessibleListBox()66cdf0e10cSrcweir AccessibleListBox::~AccessibleListBox() 67cdf0e10cSrcweir { 68cdf0e10cSrcweir DBG_DTOR( AccessibleListBox, NULL ); 69cdf0e10cSrcweir if ( isAlive() ) 70cdf0e10cSrcweir { 71cdf0e10cSrcweir // increment ref count to prevent double call of Dtor 72*aa5a148eSmseidel osl_incrementInterlockedCount( &m_refCount ); 73*aa5a148eSmseidel dispose(); 74cdf0e10cSrcweir } 75cdf0e10cSrcweir } IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox,VCLXAccessibleComponent,AccessibleListBox_BASE)76cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE) 77cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE) 78cdf0e10cSrcweir // ----------------------------------------------------------------------------- 79cdf0e10cSrcweir SvTreeListBox* AccessibleListBox::getListBox() const 80cdf0e10cSrcweir { 81cdf0e10cSrcweir return static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() ); 82cdf0e10cSrcweir } 83cdf0e10cSrcweir // ----------------------------------------------------------------------------- ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)84cdf0e10cSrcweir void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) 85cdf0e10cSrcweir { 86*aa5a148eSmseidel if ( isAlive() ) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir switch ( rVclWindowEvent.GetId() ) 89cdf0e10cSrcweir { 90*aa5a148eSmseidel case VCLEVENT_CHECKBOX_TOGGLE : 91cdf0e10cSrcweir { 9221075d77SSteve Yin if ( !getListBox() || !getListBox()->HasFocus() ) 93cdf0e10cSrcweir { 9421075d77SSteve Yin return; 9521075d77SSteve Yin } 9621075d77SSteve Yin AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent); 9721075d77SSteve Yin if(!pCurOpEntry) 9821075d77SSteve Yin { 9921075d77SSteve Yin return ; 10021075d77SSteve Yin } 10121075d77SSteve Yin uno::Any aValue; 10221075d77SSteve Yin aValue <<= AccessibleStateType::CHECKED; 103*aa5a148eSmseidel 10421075d77SSteve Yin if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED ) 10521075d77SSteve Yin { 10621075d77SSteve Yin pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue ); 10721075d77SSteve Yin } 10821075d77SSteve Yin else 10921075d77SSteve Yin { 11021075d77SSteve Yin pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() ); 111cdf0e10cSrcweir } 112cdf0e10cSrcweir break; 113cdf0e10cSrcweir } 114cdf0e10cSrcweir 115cdf0e10cSrcweir case VCLEVENT_LISTBOX_SELECT : 116cdf0e10cSrcweir { 117*aa5a148eSmseidel // First send an event that tells the listeners of a 118*aa5a148eSmseidel // modified selection. The active descendant event is 119*aa5a148eSmseidel // send after that so that the receiving AT has time to 120*aa5a148eSmseidel // read the text or name of the active child. 121*aa5a148eSmseidel // NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 12221075d77SSteve Yin OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT"); 12321075d77SSteve Yin } 12421075d77SSteve Yin case VCLEVENT_LISTBOX_TREESELECT: 12521075d77SSteve Yin { 12621075d77SSteve Yin if ( getListBox() && getListBox()->HasFocus() ) 12721075d77SSteve Yin { 12821075d77SSteve Yin AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 12921075d77SSteve Yin if (pEntry) 13021075d77SSteve Yin { 13121075d77SSteve Yin pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 13221075d77SSteve Yin } 13321075d77SSteve Yin } 13421075d77SSteve Yin } 13521075d77SSteve Yin break; 13621075d77SSteve Yin case VCLEVENT_LISTBOX_TREEFOCUS: 13721075d77SSteve Yin { 13821075d77SSteve Yin SvTreeListBox* pBox = getListBox(); 13921075d77SSteve Yin sal_Bool bNeedFocus = sal_False; 14021075d77SSteve Yin if (pBox) 14121075d77SSteve Yin { 14221075d77SSteve Yin Window* pParent = ((Window*)pBox)->GetParent(); 14321075d77SSteve Yin if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW) 14421075d77SSteve Yin { 14521075d77SSteve Yin // MT: ImplGetAppSVData shouldn't be exported from VCL. 14621075d77SSteve Yin // In which scenario is this needed? 14721075d77SSteve Yin // If needed, we need to find an other solution 14821075d77SSteve Yin /* 14921075d77SSteve Yin ImplSVData* pSVData = ImplGetAppSVData(); 15021075d77SSteve Yin if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent) 15121075d77SSteve Yin bNeedFocus = sal_True; 15221075d77SSteve Yin */ 153*aa5a148eSmseidel } 15421075d77SSteve Yin } 15521075d77SSteve Yin if( pBox && (pBox->HasFocus() || bNeedFocus) ) 15621075d77SSteve Yin { 15721075d77SSteve Yin uno::Any aOldValue, aNewValue; 15821075d77SSteve Yin SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 15921075d77SSteve Yin if ( pEntry ) 16021075d77SSteve Yin { 16121075d77SSteve Yin AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 16221075d77SSteve Yin if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry) 16321075d77SSteve Yin { 16421075d77SSteve Yin aOldValue <<= uno::Any(); 16521075d77SSteve Yin aNewValue <<= m_xFocusedChild; 16621075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); 16721075d77SSteve Yin return ; 16821075d77SSteve Yin } 16921075d77SSteve Yin 17021075d77SSteve Yin aOldValue <<= m_xFocusedChild; 17121075d77SSteve Yin 17221075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 17321075d77SSteve Yin if(mi != m_mapEntry.end()) 17421075d77SSteve Yin { 17521075d77SSteve Yin OSL_ASSERT(mi->second.get() != NULL); 17621075d77SSteve Yin m_xFocusedChild = mi->second; 17721075d77SSteve Yin } 17821075d77SSteve Yin else 17921075d77SSteve Yin { 18021075d77SSteve Yin AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 18121075d77SSteve Yin m_xFocusedChild = pEntNew; 18221075d77SSteve Yin m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew)); 18321075d77SSteve Yin } 184*aa5a148eSmseidel 18521075d77SSteve Yin aNewValue <<= m_xFocusedChild; 18621075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); 18721075d77SSteve Yin } 18821075d77SSteve Yin else 18921075d77SSteve Yin { 19021075d77SSteve Yin aOldValue <<= uno::Any(); 19121075d77SSteve Yin aNewValue <<= AccessibleStateType::FOCUSED; 19221075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 19321075d77SSteve Yin } 194*aa5a148eSmseidel } 19521075d77SSteve Yin } 19621075d77SSteve Yin break; 19721075d77SSteve Yin case VCLEVENT_LISTBOX_ITEMREMOVED: 198cdf0e10cSrcweir { 199cdf0e10cSrcweir SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 200cdf0e10cSrcweir if ( pEntry ) 201cdf0e10cSrcweir { 20221075d77SSteve Yin RemoveChildEntries(pEntry); 20321075d77SSteve Yin } 20421075d77SSteve Yin else 20521075d77SSteve Yin { 20621075d77SSteve Yin // NULL means Clear() 20721075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.begin(); 20821075d77SSteve Yin for ( ; mi != m_mapEntry.end() ; ++mi) 20921075d77SSteve Yin { 21021075d77SSteve Yin uno::Any aNewValue; 21121075d77SSteve Yin uno::Any aOldValue; 212*aa5a148eSmseidel aOldValue <<= mi->second; 21321075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); 21421075d77SSteve Yin } 21521075d77SSteve Yin m_mapEntry.clear(); 216cdf0e10cSrcweir } 217*aa5a148eSmseidel 218*aa5a148eSmseidel 219cdf0e10cSrcweir } 220cdf0e10cSrcweir break; 221cdf0e10cSrcweir 222*aa5a148eSmseidel // --> OD 2009-04-01 #i92103# 223*aa5a148eSmseidel case VCLEVENT_ITEM_EXPANDED : 224*aa5a148eSmseidel case VCLEVENT_ITEM_COLLAPSED : 225*aa5a148eSmseidel { 226*aa5a148eSmseidel SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 227*aa5a148eSmseidel if ( pEntry ) 228*aa5a148eSmseidel { 229*aa5a148eSmseidel AccessibleListBoxEntry* pAccListBoxEntry = 230*aa5a148eSmseidel new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 231*aa5a148eSmseidel Reference< XAccessible > xChild = pAccListBoxEntry; 232*aa5a148eSmseidel const short nAccEvent = 233*aa5a148eSmseidel ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED ) 234*aa5a148eSmseidel ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED 235*aa5a148eSmseidel : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED; 236*aa5a148eSmseidel uno::Any aListBoxEntry; 237*aa5a148eSmseidel aListBoxEntry <<= xChild; 238*aa5a148eSmseidel NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry ); 239*aa5a148eSmseidel if ( getListBox() && getListBox()->HasFocus() ) 240*aa5a148eSmseidel { 241*aa5a148eSmseidel NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry ); 242*aa5a148eSmseidel } 243*aa5a148eSmseidel } 244*aa5a148eSmseidel } 245*aa5a148eSmseidel break; 246*aa5a148eSmseidel // <-- 247cdf0e10cSrcweir default: 248cdf0e10cSrcweir VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); 249cdf0e10cSrcweir } 250cdf0e10cSrcweir } 251cdf0e10cSrcweir } 25221075d77SSteve Yin GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)25321075d77SSteve Yin AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ) 25421075d77SSteve Yin { 25521075d77SSteve Yin SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 25621075d77SSteve Yin if ( !pEntry ) 25721075d77SSteve Yin pEntry = getListBox()->GetCurEntry(); 258*aa5a148eSmseidel 25921075d77SSteve Yin AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 26021075d77SSteve Yin if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry()) 26121075d77SSteve Yin { 26221075d77SSteve Yin AccessibleListBoxEntry *pAccCurOptionEntry =NULL; 26321075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 26421075d77SSteve Yin if (mi != m_mapEntry.end()) 26521075d77SSteve Yin { 26621075d77SSteve Yin pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get()); 26721075d77SSteve Yin } 26821075d77SSteve Yin else 26921075d77SSteve Yin { 270*aa5a148eSmseidel pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 271*aa5a148eSmseidel std::pair<MAP_ENTRY::iterator, bool> pairMi = m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry)); 27221075d77SSteve Yin mi = pairMi.first; 273*aa5a148eSmseidel } 27421075d77SSteve Yin 275*aa5a148eSmseidel uno::Any aNewValue; 27621075d77SSteve Yin aNewValue <<= mi->second;//xAcc 277*aa5a148eSmseidel NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add 278*aa5a148eSmseidel 27921075d77SSteve Yin return pAccCurOptionEntry; 28021075d77SSteve Yin } 28121075d77SSteve Yin else 28221075d77SSteve Yin { 28321075d77SSteve Yin return pEntryFocus; 28421075d77SSteve Yin } 28521075d77SSteve Yin return NULL; 28621075d77SSteve Yin } 28721075d77SSteve Yin RemoveChildEntries(SvLBoxEntry * pEntry)28821075d77SSteve Yin void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry) 28921075d77SSteve Yin { 29021075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 29121075d77SSteve Yin if ( mi != m_mapEntry.end() ) 29221075d77SSteve Yin { 29321075d77SSteve Yin uno::Any aNewValue; 29421075d77SSteve Yin uno::Any aOldValue; 295*aa5a148eSmseidel aOldValue <<= mi->second; 29621075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); 29721075d77SSteve Yin 29821075d77SSteve Yin m_mapEntry.erase(mi); 29921075d77SSteve Yin } 30021075d77SSteve Yin 30121075d77SSteve Yin SvTreeListBox* pBox = getListBox(); 30221075d77SSteve Yin SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry); 30321075d77SSteve Yin while (pEntryChild) 30421075d77SSteve Yin { 30521075d77SSteve Yin RemoveChildEntries(pEntryChild); 30621075d77SSteve Yin pEntryChild = pBox->NextSibling(pEntryChild); 307*aa5a148eSmseidel } 30821075d77SSteve Yin } 30921075d77SSteve Yin 310cdf0e10cSrcweir // ----------------------------------------------------------------------------- ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)311*aa5a148eSmseidel void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) 312*aa5a148eSmseidel { 313*aa5a148eSmseidel switch ( rVclWindowEvent.GetId() ) 314*aa5a148eSmseidel { 315*aa5a148eSmseidel case VCLEVENT_WINDOW_SHOW: 316*aa5a148eSmseidel case VCLEVENT_WINDOW_HIDE: 317*aa5a148eSmseidel { 318*aa5a148eSmseidel } 319*aa5a148eSmseidel break; 320*aa5a148eSmseidel default: 321*aa5a148eSmseidel { 322*aa5a148eSmseidel VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent ); 323*aa5a148eSmseidel } 324*aa5a148eSmseidel break; 325*aa5a148eSmseidel } 326*aa5a148eSmseidel } 327cdf0e10cSrcweir 328cdf0e10cSrcweir // ----------------------------------------------------------------------------- 329cdf0e10cSrcweir // XComponent 330cdf0e10cSrcweir // ----------------------------------------------------------------------------- disposing()331cdf0e10cSrcweir void SAL_CALL AccessibleListBox::disposing() 332cdf0e10cSrcweir { 333cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 334cdf0e10cSrcweir 33521075d77SSteve Yin m_mapEntry.clear(); 336cdf0e10cSrcweir VCLXAccessibleComponent::disposing(); 337*aa5a148eSmseidel m_xParent = NULL; 338cdf0e10cSrcweir } 339cdf0e10cSrcweir // ----------------------------------------------------------------------------- 340cdf0e10cSrcweir // XServiceInfo 341cdf0e10cSrcweir // ----------------------------------------------------------------------------- getImplementationName()342cdf0e10cSrcweir ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir return getImplementationName_Static(); 345cdf0e10cSrcweir } 346cdf0e10cSrcweir // ----------------------------------------------------------------------------- getSupportedServiceNames()347cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir return getSupportedServiceNames_Static(); 350cdf0e10cSrcweir } 351cdf0e10cSrcweir // ----------------------------------------------------------------------------- supportsService(const::rtl::OUString & _rServiceName)352cdf0e10cSrcweir sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) 353cdf0e10cSrcweir { 354cdf0e10cSrcweir Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); 355cdf0e10cSrcweir const ::rtl::OUString* pSupported = aSupported.getConstArray(); 356cdf0e10cSrcweir const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); 357cdf0e10cSrcweir for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) 358cdf0e10cSrcweir ; 359cdf0e10cSrcweir 360cdf0e10cSrcweir return pSupported != pEnd; 361cdf0e10cSrcweir } 362cdf0e10cSrcweir // ----------------------------------------------------------------------------- 363cdf0e10cSrcweir // XServiceInfo - static methods 364cdf0e10cSrcweir // ----------------------------------------------------------------------------- getSupportedServiceNames_Static(void)365cdf0e10cSrcweir Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException ) 366cdf0e10cSrcweir { 367cdf0e10cSrcweir Sequence< ::rtl::OUString > aSupported(3); 368cdf0e10cSrcweir aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); 369cdf0e10cSrcweir aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); 370cdf0e10cSrcweir aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") ); 371cdf0e10cSrcweir return aSupported; 372cdf0e10cSrcweir } 373cdf0e10cSrcweir // ----------------------------------------------------------------------------- getImplementationName_Static(void)374cdf0e10cSrcweir ::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException ) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") ); 377cdf0e10cSrcweir } 378cdf0e10cSrcweir // ----------------------------------------------------------------------------- 379cdf0e10cSrcweir // XAccessible 380cdf0e10cSrcweir // ----------------------------------------------------------------------------- getAccessibleContext()381cdf0e10cSrcweir Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext( ) throw (RuntimeException) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir ensureAlive(); 384cdf0e10cSrcweir return this; 385cdf0e10cSrcweir } 386cdf0e10cSrcweir // ----------------------------------------------------------------------------- 387cdf0e10cSrcweir // XAccessibleContext 388cdf0e10cSrcweir // ----------------------------------------------------------------------------- getAccessibleChildCount()389cdf0e10cSrcweir sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount( ) throw (RuntimeException) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 392cdf0e10cSrcweir 393cdf0e10cSrcweir ensureAlive(); 394cdf0e10cSrcweir 395*aa5a148eSmseidel sal_Int32 nCount = 0; 396*aa5a148eSmseidel SvTreeListBox* pSvTreeListBox = getListBox(); 397*aa5a148eSmseidel if ( pSvTreeListBox ) 398*aa5a148eSmseidel nCount = pSvTreeListBox->GetLevelChildCount( NULL ); 399cdf0e10cSrcweir 400*aa5a148eSmseidel return nCount; 401cdf0e10cSrcweir } 402cdf0e10cSrcweir // ----------------------------------------------------------------------------- getAccessibleChild(sal_Int32 i)403cdf0e10cSrcweir Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 406cdf0e10cSrcweir 407cdf0e10cSrcweir ensureAlive(); 408cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry(i); 409cdf0e10cSrcweir if ( !pEntry ) 410cdf0e10cSrcweir throw IndexOutOfBoundsException(); 411cdf0e10cSrcweir 41221075d77SSteve Yin // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 41321075d77SSteve Yin //return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 41421075d77SSteve Yin return new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 415cdf0e10cSrcweir } 416cdf0e10cSrcweir // ----------------------------------------------------------------------------- getAccessibleParent()417cdf0e10cSrcweir Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent( ) throw (RuntimeException) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 420cdf0e10cSrcweir 421cdf0e10cSrcweir ensureAlive(); 422cdf0e10cSrcweir return m_xParent; 423cdf0e10cSrcweir } 424cdf0e10cSrcweir // ----------------------------------------------------------------------------- getRoleType()42521075d77SSteve Yin sal_Int32 SAL_CALL AccessibleListBox::getRoleType() 42621075d77SSteve Yin { 42721075d77SSteve Yin sal_Int32 nCase = 0; 42821075d77SSteve Yin SvLBoxEntry* pEntry = getListBox()->GetEntry(0); 42921075d77SSteve Yin if ( pEntry ) 43021075d77SSteve Yin { 43121075d77SSteve Yin if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0 ) 43221075d77SSteve Yin { 43321075d77SSteve Yin nCase = 1; 43421075d77SSteve Yin return nCase; 43521075d77SSteve Yin } 43621075d77SSteve Yin } 43721075d77SSteve Yin 438*aa5a148eSmseidel sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 43921075d77SSteve Yin if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) ) 44021075d77SSteve Yin { 44121075d77SSteve Yin if( bHasButtons ) 44221075d77SSteve Yin nCase = 1; 44321075d77SSteve Yin } 44421075d77SSteve Yin else 44521075d77SSteve Yin { 44621075d77SSteve Yin if( bHasButtons ) 44721075d77SSteve Yin nCase = 2; 44821075d77SSteve Yin else 44921075d77SSteve Yin nCase = 3; 45021075d77SSteve Yin } 45121075d77SSteve Yin return nCase; 45221075d77SSteve Yin } getAccessibleRole()453cdf0e10cSrcweir sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException) 454cdf0e10cSrcweir { 45521075d77SSteve Yin if(getListBox()) 45621075d77SSteve Yin { 457*aa5a148eSmseidel short nType = getListBox()->GetAllEntriesAccessibleRoleType(); 45821075d77SSteve Yin if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE) 45921075d77SSteve Yin return AccessibleRole::TREE; 46021075d77SSteve Yin else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST) 46121075d77SSteve Yin return AccessibleRole::LIST; 46221075d77SSteve Yin } 46321075d77SSteve Yin 46421075d77SSteve Yin //o is: return AccessibleRole::TREE; 465*aa5a148eSmseidel sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 46621075d77SSteve Yin if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN)) 46721075d77SSteve Yin return AccessibleRole::LIST; 46821075d77SSteve Yin else 46921075d77SSteve Yin if(getRoleType() == 0) 47021075d77SSteve Yin return AccessibleRole::LIST; 47121075d77SSteve Yin else 47221075d77SSteve Yin return AccessibleRole::TREE; 473cdf0e10cSrcweir } 474cdf0e10cSrcweir // ----------------------------------------------------------------------------- getAccessibleDescription()475cdf0e10cSrcweir ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException) 476cdf0e10cSrcweir { 477cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 478cdf0e10cSrcweir 479cdf0e10cSrcweir ensureAlive(); 480cdf0e10cSrcweir return getListBox()->GetAccessibleDescription(); 481cdf0e10cSrcweir } 482cdf0e10cSrcweir // ----------------------------------------------------------------------------- getAccessibleName()483cdf0e10cSrcweir ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName( ) throw (RuntimeException) 484cdf0e10cSrcweir { 485cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 486cdf0e10cSrcweir 487cdf0e10cSrcweir ensureAlive(); 488cdf0e10cSrcweir return getListBox()->GetAccessibleName(); 489cdf0e10cSrcweir } 490cdf0e10cSrcweir // ----------------------------------------------------------------------------- 491cdf0e10cSrcweir // XAccessibleSelection 492cdf0e10cSrcweir // ----------------------------------------------------------------------------- selectAccessibleChild(sal_Int32 nChildIndex)493cdf0e10cSrcweir void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 494cdf0e10cSrcweir { 495*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 496cdf0e10cSrcweir 497cdf0e10cSrcweir ensureAlive(); 498cdf0e10cSrcweir 499cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); 500cdf0e10cSrcweir if ( !pEntry ) 501cdf0e10cSrcweir throw IndexOutOfBoundsException(); 502cdf0e10cSrcweir 503cdf0e10cSrcweir getListBox()->Select( pEntry, sal_True ); 504cdf0e10cSrcweir } 505cdf0e10cSrcweir // ----------------------------------------------------------------------------- isAccessibleChildSelected(sal_Int32 nChildIndex)506cdf0e10cSrcweir sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 507cdf0e10cSrcweir { 508*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 509cdf0e10cSrcweir 510cdf0e10cSrcweir ensureAlive(); 511cdf0e10cSrcweir 512cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); 513cdf0e10cSrcweir if ( !pEntry ) 514cdf0e10cSrcweir throw IndexOutOfBoundsException(); 515cdf0e10cSrcweir 516cdf0e10cSrcweir return getListBox()->IsSelected( pEntry ); 517cdf0e10cSrcweir } 518cdf0e10cSrcweir // ----------------------------------------------------------------------------- clearAccessibleSelection()519cdf0e10cSrcweir void SAL_CALL AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException) 520cdf0e10cSrcweir { 521*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 522cdf0e10cSrcweir 523cdf0e10cSrcweir ensureAlive(); 524cdf0e10cSrcweir 525*aa5a148eSmseidel sal_Int32 i, nCount = 0; 526cdf0e10cSrcweir nCount = getListBox()->GetLevelChildCount( NULL ); 527cdf0e10cSrcweir for ( i = 0; i < nCount; ++i ) 528cdf0e10cSrcweir { 529cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 530cdf0e10cSrcweir if ( getListBox()->IsSelected( pEntry ) ) 531cdf0e10cSrcweir getListBox()->Select( pEntry, sal_False ); 532cdf0e10cSrcweir } 533cdf0e10cSrcweir } 534cdf0e10cSrcweir // ----------------------------------------------------------------------------- selectAllAccessibleChildren()535cdf0e10cSrcweir void SAL_CALL AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException) 536cdf0e10cSrcweir { 537*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 538cdf0e10cSrcweir 539cdf0e10cSrcweir ensureAlive(); 540cdf0e10cSrcweir 541*aa5a148eSmseidel sal_Int32 i, nCount = 0; 542cdf0e10cSrcweir nCount = getListBox()->GetLevelChildCount( NULL ); 543cdf0e10cSrcweir for ( i = 0; i < nCount; ++i ) 544cdf0e10cSrcweir { 545cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 546cdf0e10cSrcweir if ( !getListBox()->IsSelected( pEntry ) ) 547cdf0e10cSrcweir getListBox()->Select( pEntry, sal_True ); 548cdf0e10cSrcweir } 549cdf0e10cSrcweir } 550cdf0e10cSrcweir // ----------------------------------------------------------------------------- getSelectedAccessibleChildCount()551cdf0e10cSrcweir sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException) 552cdf0e10cSrcweir { 553*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 554cdf0e10cSrcweir 555cdf0e10cSrcweir ensureAlive(); 55621075d77SSteve Yin 557*aa5a148eSmseidel 558*aa5a148eSmseidel // sal_Int32 i, nSelCount = 0, nCount = 0; 55921075d77SSteve Yin // nCount = getListBox()->GetLevelChildCount( NULL ); 56021075d77SSteve Yin // for ( i = 0; i < nCount; ++i ) 56121075d77SSteve Yin // { 56221075d77SSteve Yin // SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 56321075d77SSteve Yin // if ( getListBox()->IsSelected( pEntry ) ) 56421075d77SSteve Yin // ++nSelCount; 56521075d77SSteve Yin // } 566*aa5a148eSmseidel // return nSelCount; 56721075d77SSteve Yin 568*aa5a148eSmseidel int nTestCount = getListBox()->GetSelectionCount(); 56921075d77SSteve Yin return nTestCount; 570cdf0e10cSrcweir } 571cdf0e10cSrcweir // ----------------------------------------------------------------------------- getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572cdf0e10cSrcweir Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 573cdf0e10cSrcweir { 574*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 575cdf0e10cSrcweir 576cdf0e10cSrcweir ensureAlive(); 577cdf0e10cSrcweir 578cdf0e10cSrcweir if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) 579cdf0e10cSrcweir throw IndexOutOfBoundsException(); 580cdf0e10cSrcweir 581cdf0e10cSrcweir Reference< XAccessible > xChild; 582*aa5a148eSmseidel sal_Int32 i, nSelCount = 0, nCount = 0; 583cdf0e10cSrcweir nCount = getListBox()->GetLevelChildCount( NULL ); 584cdf0e10cSrcweir for ( i = 0; i < nCount; ++i ) 585cdf0e10cSrcweir { 586cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 587cdf0e10cSrcweir if ( getListBox()->IsSelected( pEntry ) ) 588cdf0e10cSrcweir ++nSelCount; 589cdf0e10cSrcweir 590cdf0e10cSrcweir if ( nSelCount == ( nSelectedChildIndex + 1 ) ) 591cdf0e10cSrcweir { 59221075d77SSteve Yin // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 59321075d77SSteve Yin //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 59421075d77SSteve Yin xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 595cdf0e10cSrcweir break; 596cdf0e10cSrcweir } 597cdf0e10cSrcweir } 598cdf0e10cSrcweir 599cdf0e10cSrcweir return xChild; 600cdf0e10cSrcweir } 601cdf0e10cSrcweir // ----------------------------------------------------------------------------- deselectAccessibleChild(sal_Int32 nSelectedChildIndex)602cdf0e10cSrcweir void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 603cdf0e10cSrcweir { 604*aa5a148eSmseidel ::comphelper::OExternalLockGuard aGuard( this ); 605cdf0e10cSrcweir 606cdf0e10cSrcweir ensureAlive(); 607cdf0e10cSrcweir 608cdf0e10cSrcweir SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex ); 609cdf0e10cSrcweir if ( !pEntry ) 610cdf0e10cSrcweir throw IndexOutOfBoundsException(); 611cdf0e10cSrcweir 612cdf0e10cSrcweir getListBox()->Select( pEntry, sal_False ); 613cdf0e10cSrcweir } 614cdf0e10cSrcweir // ----------------------------------------------------------------------------- FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)615cdf0e10cSrcweir void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 616cdf0e10cSrcweir { 617cdf0e10cSrcweir VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); 618cdf0e10cSrcweir if ( getListBox() && isAlive() ) 619cdf0e10cSrcweir { 620cdf0e10cSrcweir rStateSet.AddState( AccessibleStateType::FOCUSABLE ); 621cdf0e10cSrcweir rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); 622cdf0e10cSrcweir if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION ) 623cdf0e10cSrcweir rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE ); 624cdf0e10cSrcweir } 625cdf0e10cSrcweir } 626cdf0e10cSrcweir 627cdf0e10cSrcweir 628cdf0e10cSrcweir //........................................................................ 629cdf0e10cSrcweir }// namespace accessibility 630cdf0e10cSrcweir //........................................................................ 631