10841af79SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 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 100841af79SAndrew Rist * 110841af79SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 120841af79SAndrew Rist * 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. 190841af79SAndrew Rist * 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 72cdf0e10cSrcweir osl_incrementInterlockedCount( &m_refCount ); 73cdf0e10cSrcweir 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 { 86cdf0e10cSrcweir if ( isAlive() ) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir switch ( rVclWindowEvent.GetId() ) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir case VCLEVENT_CHECKBOX_TOGGLE : 91cdf0e10cSrcweir { 92*21075d77SSteve Yin if ( !getListBox() || !getListBox()->HasFocus() ) 93cdf0e10cSrcweir { 94*21075d77SSteve Yin return; 95*21075d77SSteve Yin } 96*21075d77SSteve Yin AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent); 97*21075d77SSteve Yin if(!pCurOpEntry) 98*21075d77SSteve Yin { 99*21075d77SSteve Yin return ; 100*21075d77SSteve Yin } 101*21075d77SSteve Yin uno::Any aValue; 102*21075d77SSteve Yin aValue <<= AccessibleStateType::CHECKED; 103*21075d77SSteve Yin 104*21075d77SSteve Yin if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED ) 105*21075d77SSteve Yin { 106*21075d77SSteve Yin pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue ); 107*21075d77SSteve Yin } 108*21075d77SSteve Yin else 109*21075d77SSteve Yin { 110*21075d77SSteve Yin pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() ); 111cdf0e10cSrcweir } 112cdf0e10cSrcweir break; 113cdf0e10cSrcweir } 114cdf0e10cSrcweir 115cdf0e10cSrcweir case VCLEVENT_LISTBOX_SELECT : 116cdf0e10cSrcweir { 117cdf0e10cSrcweir // First send an event that tells the listeners of a 118cdf0e10cSrcweir // modified selection. The active descendant event is 119cdf0e10cSrcweir // send after that so that the receiving AT has time to 120cdf0e10cSrcweir // read the text or name of the active child. 121*21075d77SSteve Yin // NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 122*21075d77SSteve Yin OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT"); 123*21075d77SSteve Yin } 124*21075d77SSteve Yin case VCLEVENT_LISTBOX_TREESELECT: 125*21075d77SSteve Yin { 126*21075d77SSteve Yin if ( getListBox() && getListBox()->HasFocus() ) 127*21075d77SSteve Yin { 128*21075d77SSteve Yin AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 129*21075d77SSteve Yin if (pEntry) 130*21075d77SSteve Yin { 131*21075d77SSteve Yin pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 132*21075d77SSteve Yin } 133*21075d77SSteve Yin } 134*21075d77SSteve Yin } 135*21075d77SSteve Yin break; 136*21075d77SSteve Yin case VCLEVENT_LISTBOX_TREEFOCUS: 137*21075d77SSteve Yin { 138*21075d77SSteve Yin SvTreeListBox* pBox = getListBox(); 139*21075d77SSteve Yin sal_Bool bNeedFocus = sal_False; 140*21075d77SSteve Yin if (pBox) 141*21075d77SSteve Yin { 142*21075d77SSteve Yin Window* pParent = ((Window*)pBox)->GetParent(); 143*21075d77SSteve Yin if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW) 144*21075d77SSteve Yin { 145*21075d77SSteve Yin // MT: ImplGetAppSVData shouldn't be exported from VCL. 146*21075d77SSteve Yin // In which scenario is this needed? 147*21075d77SSteve Yin // If needed, we need to find an other solution 148*21075d77SSteve Yin /* 149*21075d77SSteve Yin ImplSVData* pSVData = ImplGetAppSVData(); 150*21075d77SSteve Yin if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent) 151*21075d77SSteve Yin bNeedFocus = sal_True; 152*21075d77SSteve Yin */ 153*21075d77SSteve Yin } 154*21075d77SSteve Yin } 155*21075d77SSteve Yin if( pBox && (pBox->HasFocus() || bNeedFocus) ) 156*21075d77SSteve Yin { 157*21075d77SSteve Yin uno::Any aOldValue, aNewValue; 158*21075d77SSteve Yin SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 159*21075d77SSteve Yin if ( pEntry ) 160*21075d77SSteve Yin { 161*21075d77SSteve Yin AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 162*21075d77SSteve Yin if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry) 163*21075d77SSteve Yin { 164*21075d77SSteve Yin aOldValue <<= uno::Any(); 165*21075d77SSteve Yin aNewValue <<= m_xFocusedChild; 166*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); 167*21075d77SSteve Yin return ; 168*21075d77SSteve Yin } 169*21075d77SSteve Yin 170*21075d77SSteve Yin aOldValue <<= m_xFocusedChild; 171*21075d77SSteve Yin 172*21075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 173*21075d77SSteve Yin if(mi != m_mapEntry.end()) 174*21075d77SSteve Yin { 175*21075d77SSteve Yin OSL_ASSERT(mi->second.get() != NULL); 176*21075d77SSteve Yin m_xFocusedChild = mi->second; 177*21075d77SSteve Yin } 178*21075d77SSteve Yin else 179*21075d77SSteve Yin { 180*21075d77SSteve Yin AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 181*21075d77SSteve Yin m_xFocusedChild = pEntNew; 182*21075d77SSteve Yin m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew)); 183*21075d77SSteve Yin } 184*21075d77SSteve Yin 185*21075d77SSteve Yin aNewValue <<= m_xFocusedChild; 186*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); 187*21075d77SSteve Yin } 188*21075d77SSteve Yin else 189*21075d77SSteve Yin { 190*21075d77SSteve Yin aOldValue <<= uno::Any(); 191*21075d77SSteve Yin aNewValue <<= AccessibleStateType::FOCUSED; 192*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 193*21075d77SSteve Yin } 194*21075d77SSteve Yin } 195*21075d77SSteve Yin } 196*21075d77SSteve Yin break; 197*21075d77SSteve Yin case VCLEVENT_LISTBOX_ITEMREMOVED: 198cdf0e10cSrcweir { 199cdf0e10cSrcweir SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 200cdf0e10cSrcweir if ( pEntry ) 201cdf0e10cSrcweir { 202*21075d77SSteve Yin RemoveChildEntries(pEntry); 203*21075d77SSteve Yin } 204*21075d77SSteve Yin else 205*21075d77SSteve Yin { 206*21075d77SSteve Yin // NULL means Clear() 207*21075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.begin(); 208*21075d77SSteve Yin for ( ; mi != m_mapEntry.end() ; ++mi) 209*21075d77SSteve Yin { 210*21075d77SSteve Yin uno::Any aNewValue; 211*21075d77SSteve Yin uno::Any aOldValue; 212*21075d77SSteve Yin aOldValue <<= mi->second; 213*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); 214*21075d77SSteve Yin } 215*21075d77SSteve Yin m_mapEntry.clear(); 216cdf0e10cSrcweir } 217*21075d77SSteve Yin 218*21075d77SSteve Yin 219cdf0e10cSrcweir } 220cdf0e10cSrcweir break; 221cdf0e10cSrcweir 222cdf0e10cSrcweir // --> OD 2009-04-01 #i92103# 223cdf0e10cSrcweir case VCLEVENT_ITEM_EXPANDED : 224cdf0e10cSrcweir case VCLEVENT_ITEM_COLLAPSED : 225cdf0e10cSrcweir { 226cdf0e10cSrcweir SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 227cdf0e10cSrcweir if ( pEntry ) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir AccessibleListBoxEntry* pAccListBoxEntry = 230cdf0e10cSrcweir new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 231cdf0e10cSrcweir Reference< XAccessible > xChild = pAccListBoxEntry; 232cdf0e10cSrcweir const short nAccEvent = 233cdf0e10cSrcweir ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED ) 234cdf0e10cSrcweir ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED 235cdf0e10cSrcweir : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED; 236cdf0e10cSrcweir uno::Any aListBoxEntry; 237cdf0e10cSrcweir aListBoxEntry <<= xChild; 238cdf0e10cSrcweir NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry ); 239cdf0e10cSrcweir if ( getListBox() && getListBox()->HasFocus() ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry ); 242cdf0e10cSrcweir } 243cdf0e10cSrcweir } 244cdf0e10cSrcweir } 245*21075d77SSteve Yin break; 246cdf0e10cSrcweir // <-- 247cdf0e10cSrcweir default: 248cdf0e10cSrcweir VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); 249cdf0e10cSrcweir } 250cdf0e10cSrcweir } 251cdf0e10cSrcweir } 252*21075d77SSteve Yin GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)253*21075d77SSteve Yin AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ) 254*21075d77SSteve Yin { 255*21075d77SSteve Yin SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 256*21075d77SSteve Yin if ( !pEntry ) 257*21075d77SSteve Yin pEntry = getListBox()->GetCurEntry(); 258*21075d77SSteve Yin 259*21075d77SSteve Yin AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 260*21075d77SSteve Yin if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry()) 261*21075d77SSteve Yin { 262*21075d77SSteve Yin AccessibleListBoxEntry *pAccCurOptionEntry =NULL; 263*21075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 264*21075d77SSteve Yin if (mi != m_mapEntry.end()) 265*21075d77SSteve Yin { 266*21075d77SSteve Yin pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get()); 267*21075d77SSteve Yin } 268*21075d77SSteve Yin else 269*21075d77SSteve Yin { 270*21075d77SSteve Yin pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 271*21075d77SSteve Yin std::pair<MAP_ENTRY::iterator, bool> pairMi = m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry)); 272*21075d77SSteve Yin mi = pairMi.first; 273*21075d77SSteve Yin } 274*21075d77SSteve Yin 275*21075d77SSteve Yin uno::Any aNewValue; 276*21075d77SSteve Yin aNewValue <<= mi->second;//xAcc 277*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add 278*21075d77SSteve Yin 279*21075d77SSteve Yin return pAccCurOptionEntry; 280*21075d77SSteve Yin } 281*21075d77SSteve Yin else 282*21075d77SSteve Yin { 283*21075d77SSteve Yin return pEntryFocus; 284*21075d77SSteve Yin } 285*21075d77SSteve Yin return NULL; 286*21075d77SSteve Yin } 287*21075d77SSteve Yin RemoveChildEntries(SvLBoxEntry * pEntry)288*21075d77SSteve Yin void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry) 289*21075d77SSteve Yin { 290*21075d77SSteve Yin MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 291*21075d77SSteve Yin if ( mi != m_mapEntry.end() ) 292*21075d77SSteve Yin { 293*21075d77SSteve Yin uno::Any aNewValue; 294*21075d77SSteve Yin uno::Any aOldValue; 295*21075d77SSteve Yin aOldValue <<= mi->second; 296*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); 297*21075d77SSteve Yin 298*21075d77SSteve Yin m_mapEntry.erase(mi); 299*21075d77SSteve Yin } 300*21075d77SSteve Yin 301*21075d77SSteve Yin SvTreeListBox* pBox = getListBox(); 302*21075d77SSteve Yin SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry); 303*21075d77SSteve Yin while (pEntryChild) 304*21075d77SSteve Yin { 305*21075d77SSteve Yin RemoveChildEntries(pEntryChild); 306*21075d77SSteve Yin pEntryChild = pBox->NextSibling(pEntryChild); 307*21075d77SSteve Yin } 308*21075d77SSteve Yin } 309*21075d77SSteve Yin 310cdf0e10cSrcweir // ----------------------------------------------------------------------------- ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)311cdf0e10cSrcweir void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir switch ( rVclWindowEvent.GetId() ) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir case VCLEVENT_WINDOW_SHOW: 316cdf0e10cSrcweir case VCLEVENT_WINDOW_HIDE: 317cdf0e10cSrcweir { 318cdf0e10cSrcweir } 319cdf0e10cSrcweir break; 320cdf0e10cSrcweir default: 321cdf0e10cSrcweir { 322cdf0e10cSrcweir VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent ); 323cdf0e10cSrcweir } 324cdf0e10cSrcweir break; 325cdf0e10cSrcweir } 326cdf0e10cSrcweir } 327cdf0e10cSrcweir 328cdf0e10cSrcweir // ----------------------------------------------------------------------------- 329cdf0e10cSrcweir // XComponent 330cdf0e10cSrcweir // ----------------------------------------------------------------------------- disposing()331cdf0e10cSrcweir void SAL_CALL AccessibleListBox::disposing() 332cdf0e10cSrcweir { 333cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 334cdf0e10cSrcweir 335*21075d77SSteve Yin m_mapEntry.clear(); 336cdf0e10cSrcweir VCLXAccessibleComponent::disposing(); 337cdf0e10cSrcweir 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 395cdf0e10cSrcweir sal_Int32 nCount = 0; 396cdf0e10cSrcweir SvTreeListBox* pSvTreeListBox = getListBox(); 397cdf0e10cSrcweir if ( pSvTreeListBox ) 398cdf0e10cSrcweir nCount = pSvTreeListBox->GetLevelChildCount( NULL ); 399cdf0e10cSrcweir 400cdf0e10cSrcweir 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 412*21075d77SSteve Yin // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 413*21075d77SSteve Yin //return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 414*21075d77SSteve 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()425*21075d77SSteve Yin sal_Int32 SAL_CALL AccessibleListBox::getRoleType() 426*21075d77SSteve Yin { 427*21075d77SSteve Yin sal_Int32 nCase = 0; 428*21075d77SSteve Yin SvLBoxEntry* pEntry = getListBox()->GetEntry(0); 429*21075d77SSteve Yin if ( pEntry ) 430*21075d77SSteve Yin { 431*21075d77SSteve Yin if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0 ) 432*21075d77SSteve Yin { 433*21075d77SSteve Yin nCase = 1; 434*21075d77SSteve Yin return nCase; 435*21075d77SSteve Yin } 436*21075d77SSteve Yin } 437*21075d77SSteve Yin 438*21075d77SSteve Yin sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 439*21075d77SSteve Yin if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) ) 440*21075d77SSteve Yin { 441*21075d77SSteve Yin if( bHasButtons ) 442*21075d77SSteve Yin nCase = 1; 443*21075d77SSteve Yin } 444*21075d77SSteve Yin else 445*21075d77SSteve Yin { 446*21075d77SSteve Yin if( bHasButtons ) 447*21075d77SSteve Yin nCase = 2; 448*21075d77SSteve Yin else 449*21075d77SSteve Yin nCase = 3; 450*21075d77SSteve Yin } 451*21075d77SSteve Yin return nCase; 452*21075d77SSteve Yin } getAccessibleRole()453cdf0e10cSrcweir sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException) 454cdf0e10cSrcweir { 455*21075d77SSteve Yin if(getListBox()) 456*21075d77SSteve Yin { 457*21075d77SSteve Yin short nType = getListBox()->GetAllEntriesAccessibleRoleType(); 458*21075d77SSteve Yin if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE) 459*21075d77SSteve Yin return AccessibleRole::TREE; 460*21075d77SSteve Yin else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST) 461*21075d77SSteve Yin return AccessibleRole::LIST; 462*21075d77SSteve Yin } 463*21075d77SSteve Yin 464*21075d77SSteve Yin //o is: return AccessibleRole::TREE; 465*21075d77SSteve Yin sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 466*21075d77SSteve Yin if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN)) 467*21075d77SSteve Yin return AccessibleRole::LIST; 468*21075d77SSteve Yin else 469*21075d77SSteve Yin if(getRoleType() == 0) 470*21075d77SSteve Yin return AccessibleRole::LIST; 471*21075d77SSteve Yin else 472*21075d77SSteve 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 { 495cdf0e10cSrcweir ::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 { 508cdf0e10cSrcweir ::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 { 521cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 522cdf0e10cSrcweir 523cdf0e10cSrcweir ensureAlive(); 524cdf0e10cSrcweir 525cdf0e10cSrcweir 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 { 537cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 538cdf0e10cSrcweir 539cdf0e10cSrcweir ensureAlive(); 540cdf0e10cSrcweir 541cdf0e10cSrcweir 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 { 553cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 554cdf0e10cSrcweir 555cdf0e10cSrcweir ensureAlive(); 556*21075d77SSteve Yin 557*21075d77SSteve Yin 558*21075d77SSteve Yin // sal_Int32 i, nSelCount = 0, nCount = 0; 559*21075d77SSteve Yin // nCount = getListBox()->GetLevelChildCount( NULL ); 560*21075d77SSteve Yin // for ( i = 0; i < nCount; ++i ) 561*21075d77SSteve Yin // { 562*21075d77SSteve Yin // SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 563*21075d77SSteve Yin // if ( getListBox()->IsSelected( pEntry ) ) 564*21075d77SSteve Yin // ++nSelCount; 565*21075d77SSteve Yin // } 566*21075d77SSteve Yin // return nSelCount; 567*21075d77SSteve Yin 568*21075d77SSteve Yin int nTestCount = getListBox()->GetSelectionCount(); 569*21075d77SSteve Yin return nTestCount; 570cdf0e10cSrcweir } 571cdf0e10cSrcweir // ----------------------------------------------------------------------------- getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572cdf0e10cSrcweir Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 573cdf0e10cSrcweir { 574cdf0e10cSrcweir ::comphelper::OExternalLockGuard aGuard( this ); 575cdf0e10cSrcweir 576cdf0e10cSrcweir ensureAlive(); 577cdf0e10cSrcweir 578cdf0e10cSrcweir if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) 579cdf0e10cSrcweir throw IndexOutOfBoundsException(); 580cdf0e10cSrcweir 581cdf0e10cSrcweir Reference< XAccessible > xChild; 582cdf0e10cSrcweir 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 { 592*21075d77SSteve Yin // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 593*21075d77SSteve Yin //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 594*21075d77SSteve 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 { 604cdf0e10cSrcweir ::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 //........................................................................ 631cdf0e10cSrcweir 632