diff options
Diffstat (limited to 'accessibility/source/standard/vclxaccessiblelistboxlist.cxx')
-rw-r--r-- | accessibility/source/standard/vclxaccessiblelistboxlist.cxx | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/accessibility/source/standard/vclxaccessiblelistboxlist.cxx b/accessibility/source/standard/vclxaccessiblelistboxlist.cxx new file mode 100644 index 000000000000..df37c3239667 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblelistboxlist.cxx @@ -0,0 +1,335 @@ +/************************************************************************* + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_accessibility.hxx" +#include <accessibility/standard/vclxaccessiblelistboxlist.hxx> +#include <accessibility/standard/vclxaccessiblelistitem.hxx> +#include <accessibility/helper/listboxhelper.hxx> + +#include <algorithm> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/unohelp.hxx> + +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/convert.hxx> + +#include <comphelper/sequence.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <unotools/accessiblestatesethelper.hxx> + +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(); +} +// ----------------------------------------------------------------------------- + |