/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_accessibility.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::accessibility; namespace { void checkSelection_Impl( sal_Int32 _nIndex, const ListBox& _rListBox, sal_Bool bSelected ) throw (::com::sun::star::lang::IndexOutOfBoundsException) { sal_Int32 nCount = bSelected ? (sal_Int32)_rListBox.GetSelectEntryCount() : (sal_Int32)_rListBox.GetEntryCount(); if ( _nIndex < 0 || _nIndex >= nCount ) throw ::com::sun::star::lang::IndexOutOfBoundsException(); } } VCLXAccessibleListBoxList::VCLXAccessibleListBoxList (VCLXWindow* pVCLWindow, BoxType aBoxType,const Reference< XAccessible >& _xParent) : VCLXAccessibleList (pVCLWindow, aBoxType, _xParent) { } VCLXAccessibleListBoxList::~VCLXAccessibleListBoxList (void) { } void VCLXAccessibleListBoxList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) { switch ( rVclWindowEvent.GetId() ) { case VCLEVENT_LISTBOX_SCROLLED: UpdateEntryRange_Impl(); break; case VCLEVENT_LISTBOX_SELECT: if ( !m_bDisableProcessEvent ) UpdateSelection_Impl(); break; default: VCLXAccessibleList::ProcessWindowEvent (rVclWindowEvent); } } IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleListBoxList, VCLXAccessibleList, VCLXAccessibleListBoxList_BASE) IMPLEMENT_FORWARD_XTYPEPROVIDER2(VCLXAccessibleListBoxList, VCLXAccessibleList, VCLXAccessibleListBoxList_BASE) //===== XServiceInfo ======================================================== ::rtl::OUString VCLXAccessibleListBoxList::getImplementationName (void) throw (RuntimeException) { return ::rtl::OUString::createFromAscii("com.sun.star.comp.toolkit.AccessibleListBoxList"); } Sequence< ::rtl::OUString > VCLXAccessibleListBoxList::getSupportedServiceNames (void) throw (RuntimeException) { Sequence< ::rtl::OUString > aNames = VCLXAccessibleList::getSupportedServiceNames(); sal_Int32 nLength = aNames.getLength(); aNames.realloc( nLength + 1 ); aNames[nLength] = ::rtl::OUString::createFromAscii( "com.sun.star.accessibility.AccessibleListBoxList"); return aNames; } // ----------------------------------------------------------------------------- void VCLXAccessibleListBoxList::UpdateSelection_Impl() { uno::Any aOldValue, aNewValue; { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); Reference< XAccessible > xNewAcc; ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { USHORT nPos = 0; ListItems::iterator aEnd = m_aAccessibleChildren.end(); for ( ListItems::iterator aIter = m_aAccessibleChildren.begin(); aIter != aEnd; ++aIter,++nPos) { if ( aIter->is() ) { VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( aIter->get() ); // Retrieve the item's index from the list entry. BOOL bNowSelected = pListBox->IsEntryPosSelected (nPos); if ( bNowSelected && !pItem->IsSelected() ) { xNewAcc = *aIter; aNewValue <<= xNewAcc; m_nLastSelectedPos = nPos; } pItem->SetSelected( bNowSelected ); } else { // it could happen that a child was not created before checkEntrySelected(pListBox,nPos,aNewValue,xNewAcc); } } USHORT nCount = pListBox->GetEntryCount(); if ( nPos < nCount ) // here we have to check the if any other listbox entry is selected { for (; nPos < nCount && !checkEntrySelected(pListBox,nPos,aNewValue,xNewAcc) ;++nPos ) ; } } if ( xNewAcc.is() && pListBox->HasFocus() ) { if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND ) aOldValue <<= getAccessibleChild( (sal_Int32)m_nLastSelectedPos ); aNewValue <<= xNewAcc; } } if ( aNewValue.hasValue() || aOldValue.hasValue() ) NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); } // ----------------------------------------------------------------------------- // XAccessibleSelection // ----------------------------------------------------------------------------- void SAL_CALL VCLXAccessibleListBoxList::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) { sal_Bool bNotify = sal_False; { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { checkSelection_Impl( nChildIndex, *pListBox, sal_False ); pListBox->SelectEntryPos( (USHORT)nChildIndex, TRUE ); // call the select handler, don't handle events in this time m_bDisableProcessEvent = true; pListBox->Select(); m_bDisableProcessEvent = false; bNotify = sal_True; } } if ( bNotify ) UpdateSelection_Impl(); } // ----------------------------------------------------------------------------- sal_Bool SAL_CALL VCLXAccessibleListBoxList::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); sal_Bool bRet = sal_False; ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { checkSelection_Impl( nChildIndex, *pListBox, sal_False ); bRet = pListBox->IsEntryPosSelected( (USHORT)nChildIndex ); } return bRet; } // ----------------------------------------------------------------------------- void SAL_CALL VCLXAccessibleListBoxList::clearAccessibleSelection( ) throw (RuntimeException) { sal_Bool bNotify = sal_False; { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { pListBox->SetNoSelection(); bNotify = sal_True; } } if ( bNotify ) UpdateSelection_Impl(); } // ----------------------------------------------------------------------------- void SAL_CALL VCLXAccessibleListBoxList::selectAllAccessibleChildren( ) throw (RuntimeException) { sal_Bool bNotify = sal_False; { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { USHORT nCount = pListBox->GetEntryCount(); for ( USHORT i = 0; i < nCount; ++i ) pListBox->SelectEntryPos( i, TRUE ); // call the select handler, don't handle events in this time m_bDisableProcessEvent = true; pListBox->Select(); m_bDisableProcessEvent = false; bNotify = sal_True; } } if ( bNotify ) UpdateSelection_Impl(); } // ----------------------------------------------------------------------------- sal_Int32 SAL_CALL VCLXAccessibleListBoxList::getSelectedAccessibleChildCount( ) throw (RuntimeException) { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); sal_Int32 nCount = 0; ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) nCount = pListBox->GetSelectEntryCount(); return nCount; } // ----------------------------------------------------------------------------- Reference< XAccessible > SAL_CALL VCLXAccessibleListBoxList::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { checkSelection_Impl( nSelectedChildIndex, *pListBox, sal_True ); return getAccessibleChild( (sal_Int32)pListBox->GetSelectEntryPos( (USHORT)nSelectedChildIndex ) ); } return NULL; } // ----------------------------------------------------------------------------- void SAL_CALL VCLXAccessibleListBoxList::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) { sal_Bool bNotify = sal_False; { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); if ( pListBox ) { checkSelection_Impl( nSelectedChildIndex, *pListBox, sal_False ); pListBox->SelectEntryPos( (USHORT)nSelectedChildIndex, FALSE ); // call the select handler, don't handle events in this time m_bDisableProcessEvent = true; pListBox->Select(); m_bDisableProcessEvent = false; bNotify = sal_True; } } if ( bNotify ) UpdateSelection_Impl(); } // -----------------------------------------------------------------------------