diff options
Diffstat (limited to 'accessibility/source/extended')
33 files changed, 14380 insertions, 0 deletions
diff --git a/accessibility/source/extended/AccessibleBrowseBox.cxx b/accessibility/source/extended/AccessibleBrowseBox.cxx new file mode 100644 index 000000000000..677c15513d7a --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBox.cxx @@ -0,0 +1,401 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBox.hxx" +#include "accessibility/extended/AccessibleBrowseBoxTable.hxx" +#include "accessibility/extended/AccessibleBrowseBoxHeaderBar.hxx" +#include <svtools/accessibletableprovider.hxx> +#include <comphelper/types.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +// ============================================================================ + +namespace accessibility +{ + +// ============================================================================ + +using ::rtl::OUString; + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; + +// ============================================================================ +class AccessibleBrowseBoxImpl +{ +public: + /// the XAccessible which created the AccessibleBrowseBox + WeakReference< XAccessible > m_aCreator; + + /** The data table child. */ + Reference< + ::com::sun::star::accessibility::XAccessible > mxTable; + AccessibleBrowseBoxTable* m_pTable; + + /** The header bar for rows ("handle column"). */ + Reference< + ::com::sun::star::accessibility::XAccessible > mxRowHeaderBar; + AccessibleBrowseBoxHeaderBar* m_pRowHeaderBar; + + /** The header bar for columns (first row of the table). */ + Reference< + ::com::sun::star::accessibility::XAccessible > mxColumnHeaderBar; + AccessibleBrowseBoxHeaderBar* m_pColumnHeaderBar; +}; + +// Ctor/Dtor/disposing -------------------------------------------------------- + +DBG_NAME( AccessibleBrowseBox ) + +AccessibleBrowseBox::AccessibleBrowseBox( + const Reference< XAccessible >& _rxParent, const Reference< XAccessible >& _rxCreator, + IAccessibleTableProvider& _rBrowseBox ) + : AccessibleBrowseBoxBase( _rxParent, _rBrowseBox,NULL, BBTYPE_BROWSEBOX ) +{ + DBG_CTOR( AccessibleBrowseBox, NULL ); + m_pImpl.reset( new AccessibleBrowseBoxImpl() ); + m_pImpl->m_aCreator = _rxCreator; + + m_xFocusWindow = VCLUnoHelper::GetInterface(mpBrowseBox->GetWindowInstance()); +} +// ----------------------------------------------------------------------------- +void AccessibleBrowseBox::setCreator( const Reference< XAccessible >& _rxCreator ) +{ +#if OSL_DEBUG_LEVEL > 0 + Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator; + DBG_ASSERT( !xCreator.is(), "accessibility/extended/AccessibleBrowseBox::setCreator: creator already set!" ); +#endif + m_pImpl->m_aCreator = _rxCreator; +} + +// ----------------------------------------------------------------------------- +AccessibleBrowseBox::~AccessibleBrowseBox() +{ + DBG_DTOR( AccessibleBrowseBox, NULL ); +} +// ----------------------------------------------------------------------------- + +void SAL_CALL AccessibleBrowseBox::disposing() +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + + m_pImpl->m_pTable = NULL; + m_pImpl->m_pColumnHeaderBar = NULL; + m_pImpl->m_pRowHeaderBar = NULL; + m_pImpl->m_aCreator = Reference< XAccessible >(); + + Reference< XAccessible > xTable = m_pImpl->mxTable; + + Reference< XComponent > xComp( m_pImpl->mxTable, UNO_QUERY ); + if ( xComp.is() ) + { + xComp->dispose(); + + } +//! ::comphelper::disposeComponent(m_pImpl->mxTable); + ::comphelper::disposeComponent(m_pImpl->mxRowHeaderBar); + ::comphelper::disposeComponent(m_pImpl->mxColumnHeaderBar); + + AccessibleBrowseBoxBase::disposing(); +} +// ----------------------------------------------------------------------------- + +// XAccessibleContext --------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleBrowseBox::getAccessibleChildCount() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return BBINDEX_FIRSTCONTROL + mpBrowseBox->GetAccessibleControlCount(); +} +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBox::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Reference< XAccessible > xRet; + if( nChildIndex >= 0 ) + { + if( nChildIndex < BBINDEX_FIRSTCONTROL ) + xRet = implGetFixedChild( nChildIndex ); + else + { + // additional controls + nChildIndex -= BBINDEX_FIRSTCONTROL; + if( nChildIndex < mpBrowseBox->GetAccessibleControlCount() ) + xRet = mpBrowseBox->CreateAccessibleControl( nChildIndex ); + } + } + + if( !xRet.is() ) + throw lang::IndexOutOfBoundsException(); + return xRet; +} +// ----------------------------------------------------------------------------- + +//sal_Int16 SAL_CALL AccessibleBrowseBox::getAccessibleRole() +// throw ( uno::RuntimeException ) +//{ +// ensureIsAlive(); +// return AccessibleRole::PANEL; +//} +// ----------------------------------------------------------------------------- + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Reference< XAccessible > xChild; + sal_Int32 nIndex = 0; + if( mpBrowseBox->ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) ) + xChild = mpBrowseBox->CreateAccessibleControl( nIndex ); + else + { + // try whether point is in one of the fixed children + // (table, header bars, corner control) + Point aPoint( VCLPoint( rPoint ) ); + for( nIndex = 0; (nIndex < BBINDEX_FIRSTCONTROL) && !xChild.is(); ++nIndex ) + { + Reference< XAccessible > xCurrChild( implGetFixedChild( nIndex ) ); + Reference< XAccessibleComponent > + xCurrChildComp( xCurrChild, uno::UNO_QUERY ); + + if( xCurrChildComp.is() && + VCLRectangle( xCurrChildComp->getBounds() ).IsInside( aPoint ) ) + xChild = xCurrChild; + } + } + return xChild; +} +// ----------------------------------------------------------------------------- + +void SAL_CALL AccessibleBrowseBox::grabFocus() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + mpBrowseBox->GrabFocus(); +} +// ----------------------------------------------------------------------------- + +Any SAL_CALL AccessibleBrowseBox::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return Any(); +} +// ----------------------------------------------------------------------------- + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBox::getImplementationName() + throw ( uno::RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBox" ) ); +} +// ----------------------------------------------------------------------------- + +// internal virtual methods --------------------------------------------------- + +Rectangle AccessibleBrowseBox::implGetBoundingBox() +{ + Window* pParent = mpBrowseBox->GetAccessibleParentWindow(); + DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" ); + return mpBrowseBox->GetWindowExtentsRelative( pParent ); +} +// ----------------------------------------------------------------------------- + +Rectangle AccessibleBrowseBox::implGetBoundingBoxOnScreen() +{ + return mpBrowseBox->GetWindowExtentsRelative( NULL ); +} +// ----------------------------------------------------------------------------- + +// internal helper methods ---------------------------------------------------- + +Reference< XAccessible > AccessibleBrowseBox::implGetTable() +{ + if( !m_pImpl->mxTable.is() ) + { + m_pImpl->m_pTable = createAccessibleTable(); + m_pImpl->mxTable = m_pImpl->m_pTable; + + } + return m_pImpl->mxTable; +} +// ----------------------------------------------------------------------------- + +Reference< XAccessible > +AccessibleBrowseBox::implGetHeaderBar( AccessibleBrowseBoxObjType eObjType ) +{ + Reference< XAccessible > xRet; + Reference< XAccessible >* pxMember = NULL; + + if( eObjType == BBTYPE_ROWHEADERBAR ) + pxMember = &m_pImpl->mxRowHeaderBar; + else if( eObjType == BBTYPE_COLUMNHEADERBAR ) + pxMember = &m_pImpl->mxColumnHeaderBar; + + if( pxMember ) + { + if( !pxMember->is() ) + { + AccessibleBrowseBoxHeaderBar* pHeaderBar = new AccessibleBrowseBoxHeaderBar( + (Reference< XAccessible >)m_pImpl->m_aCreator, *mpBrowseBox, eObjType ); + + if ( BBTYPE_COLUMNHEADERBAR == eObjType) + m_pImpl->m_pColumnHeaderBar = pHeaderBar; + else + m_pImpl->m_pRowHeaderBar = pHeaderBar; + + *pxMember = pHeaderBar; + } + xRet = *pxMember; + } + return xRet; +} +// ----------------------------------------------------------------------------- + +Reference< XAccessible > +AccessibleBrowseBox::implGetFixedChild( sal_Int32 nChildIndex ) +{ + Reference< XAccessible > xRet; + switch( nChildIndex ) + { + case BBINDEX_COLUMNHEADERBAR: + xRet = implGetHeaderBar( BBTYPE_COLUMNHEADERBAR ); + break; + case BBINDEX_ROWHEADERBAR: + xRet = implGetHeaderBar( BBTYPE_ROWHEADERBAR ); + break; + case BBINDEX_TABLE: + xRet = implGetTable(); + break; + } + return xRet; +} +// ----------------------------------------------------------------------------- +AccessibleBrowseBoxTable* AccessibleBrowseBox::createAccessibleTable() +{ + Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator; + DBG_ASSERT( xCreator.is(), "accessibility/extended/AccessibleBrowseBox::createAccessibleTable: my creator died - how this?" ); + return new AccessibleBrowseBoxTable( xCreator, *mpBrowseBox ); +} +// ----------------------------------------------------------------------------- +void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue) +{ + if ( m_pImpl->mxTable.is() ) + { + m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue); + } +} +// ----------------------------------------------------------------------------- +void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId, + const Any& _rNewValue, + const Any& _rOldValue,sal_Bool _bColumnHeaderBar) +{ + Reference< XAccessible > xHeaderBar = _bColumnHeaderBar ? m_pImpl->mxColumnHeaderBar : m_pImpl->mxRowHeaderBar; + AccessibleBrowseBoxHeaderBar* pHeaderBar = _bColumnHeaderBar ? m_pImpl->m_pColumnHeaderBar : m_pImpl->m_pRowHeaderBar; + if ( xHeaderBar.is() ) + pHeaderBar->commitEvent(_nEventId,_rNewValue,_rOldValue); +} + +// ============================================================================ +// = AccessibleBrowseBoxAccess +// ============================================================================ +DBG_NAME( AccessibleBrowseBoxAccess ) +// ----------------------------------------------------------------------------- +AccessibleBrowseBoxAccess::AccessibleBrowseBoxAccess( const Reference< XAccessible >& _rxParent, IAccessibleTableProvider& _rBrowseBox ) + :m_xParent( _rxParent ) + ,m_rBrowseBox( _rBrowseBox ) + ,m_pContext( NULL ) +{ + DBG_CTOR( AccessibleBrowseBoxAccess, NULL ); +} + +// ----------------------------------------------------------------------------- +AccessibleBrowseBoxAccess::~AccessibleBrowseBoxAccess() +{ + DBG_DTOR( AccessibleBrowseBoxAccess, NULL ); +} + +// ----------------------------------------------------------------------------- +void AccessibleBrowseBoxAccess::dispose() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + m_pContext = NULL; + ::comphelper::disposeComponent( m_xContext ); +} + +// ----------------------------------------------------------------------------- +Reference< XAccessibleContext > SAL_CALL AccessibleBrowseBoxAccess::getAccessibleContext() throw ( RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + DBG_ASSERT( ( m_pContext && m_xContext.is() ) || ( !m_pContext && !m_xContext.is() ), + "accessibility/extended/AccessibleBrowseBoxAccess::getAccessibleContext: inconsistency!" ); + + // if the context died meanwhile (we're no listener, so it won't tell us explicitily when this happens), + // then reset an re-create. + if ( m_pContext && !m_pContext->isAlive() ) + m_xContext = m_pContext = NULL; + + if ( !m_xContext.is() ) + m_xContext = m_pContext = new AccessibleBrowseBox( m_xParent, this, m_rBrowseBox ); + + return m_xContext; +} + +// ----------------------------------------------------------------------------- +bool AccessibleBrowseBoxAccess::isContextAlive() const +{ + return ( NULL != m_pContext ) && m_pContext->isAlive(); +} + +// ============================================================================ + +} // namespace accessibility diff --git a/accessibility/source/extended/AccessibleBrowseBoxBase.cxx b/accessibility/source/extended/AccessibleBrowseBoxBase.cxx new file mode 100644 index 000000000000..f8b43ecdced2 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxBase.cxx @@ -0,0 +1,658 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxBase.hxx" +#include <svtools/accessibletableprovider.hxx> +#include <rtl/uuid.h> +// +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblerelationsethelper.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; +using namespace ::svt; + + +// ============================================================================ + +namespace accessibility { + +using namespace com::sun::star::accessibility::AccessibleStateType; +// ============================================================================ + +// Ctor/Dtor/disposing -------------------------------------------------------- + +DBG_NAME( AccessibleBrowseBoxBase ) + +AccessibleBrowseBoxBase::AccessibleBrowseBoxBase( + const Reference< XAccessible >& rxParent, + IAccessibleTableProvider& rBrowseBox, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType eObjType ) : + AccessibleBrowseBoxImplHelper( m_aMutex ), + mxParent( rxParent ), + mpBrowseBox( &rBrowseBox ), + m_xFocusWindow(_xFocusWindow), + maName( rBrowseBox.GetAccessibleObjectName( eObjType ) ), + maDescription( rBrowseBox.GetAccessibleObjectDescription( eObjType ) ), + meObjType( eObjType ), + m_aClientId(0) +{ + DBG_CTOR( AccessibleBrowseBoxBase, NULL ); + if ( m_xFocusWindow.is() ) + m_xFocusWindow->addFocusListener( this ); +} + +AccessibleBrowseBoxBase::AccessibleBrowseBoxBase( + const Reference< XAccessible >& rxParent, + IAccessibleTableProvider& rBrowseBox, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType eObjType, + const ::rtl::OUString& rName, + const ::rtl::OUString& rDescription ) : + AccessibleBrowseBoxImplHelper( m_aMutex ), + mxParent( rxParent ), + mpBrowseBox( &rBrowseBox ), + m_xFocusWindow(_xFocusWindow), + maName( rName ), + maDescription( rDescription ), + meObjType( eObjType ), + m_aClientId(0) +{ + DBG_CTOR( AccessibleBrowseBoxBase, NULL ); + if ( m_xFocusWindow.is() ) + m_xFocusWindow->addFocusListener( this ); +} + +AccessibleBrowseBoxBase::~AccessibleBrowseBoxBase() +{ + DBG_DTOR( AccessibleBrowseBoxBase, NULL ); + + if( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } +} + +void SAL_CALL AccessibleBrowseBoxBase::disposing() +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + if ( m_xFocusWindow.is() ) + { + BBSolarGuard aSolarGuard; + m_xFocusWindow->removeFocusListener( this ); + } + + if ( getClientId( ) ) + { + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + mxParent = NULL; + mpBrowseBox = NULL; +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleParent() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return mxParent; +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getAccessibleIndexInParent() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + // -1 for child not found/no parent (according to specification) + sal_Int32 nRet = -1; + + Reference< uno::XInterface > xMeMyselfAndI( static_cast< XAccessibleContext* >( this ), uno::UNO_QUERY ); + + // iterate over parent's children and search for this object + if( mxParent.is() ) + { + Reference< XAccessibleContext > + xParentContext( mxParent->getAccessibleContext() ); + if( xParentContext.is() ) + { + Reference< uno::XInterface > xChild; + + sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); + for( sal_Int32 nChild = 0; nChild < nChildCount; ++nChild ) + { + xChild = xChild.query( xParentContext->getAccessibleChild( nChild ) ); + + if ( xMeMyselfAndI.get() == xChild.get() ) + { + nRet = nChild; + break; + } + } + } + } + return nRet; +} + +OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleDescription() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return maDescription; +} + +OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleName() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return maName; +} + +Reference< XAccessibleRelationSet > SAL_CALL +AccessibleBrowseBoxBase::getAccessibleRelationSet() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + // BrowseBox does not have relations. + return new utl::AccessibleRelationSetHelper; +} + +Reference< XAccessibleStateSet > SAL_CALL +AccessibleBrowseBoxBase::getAccessibleStateSet() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + // don't check whether alive -> StateSet may contain DEFUNC + return implCreateStateSetHelper(); +} + +lang::Locale SAL_CALL AccessibleBrowseBoxBase::getLocale() + throw ( IllegalAccessibleComponentStateException, uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + if( mxParent.is() ) + { + Reference< XAccessibleContext > + xParentContext( mxParent->getAccessibleContext() ); + if( xParentContext.is() ) + return xParentContext->getLocale(); + } + throw IllegalAccessibleComponentStateException(); +} + +// XAccessibleComponent ------------------------------------------------------- + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::containsPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + return Rectangle( Point(), getBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); +} + +awt::Rectangle SAL_CALL AccessibleBrowseBoxBase::getBounds() + throw ( uno::RuntimeException ) +{ + return AWTRectangle( getBoundingBox() ); +} + +awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocation() + throw ( uno::RuntimeException ) +{ + return AWTPoint( getBoundingBox().TopLeft() ); +} + +awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocationOnScreen() + throw ( uno::RuntimeException ) +{ + return AWTPoint( getBoundingBoxOnScreen().TopLeft() ); +} + +awt::Size SAL_CALL AccessibleBrowseBoxBase::getSize() + throw ( uno::RuntimeException ) +{ + return AWTSize( getBoundingBox().GetSize() ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::isShowing() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implIsShowing(); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::isVisible() + throw ( uno::RuntimeException ) +{ + Reference< XAccessibleStateSet > xStateSet = getAccessibleStateSet(); + return xStateSet.is() ? + xStateSet->contains( AccessibleStateType::VISIBLE ) : sal_False; +} + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::isFocusTraversable() + throw ( uno::RuntimeException ) +{ + Reference< XAccessibleStateSet > xStateSet = getAccessibleStateSet(); + return xStateSet.is() ? + xStateSet->contains( AccessibleStateType::FOCUSABLE ) : sal_False; +} + +void SAL_CALL AccessibleBrowseBoxBase::focusGained( const ::com::sun::star::awt::FocusEvent& ) throw (::com::sun::star::uno::RuntimeException) +{ + com::sun::star::uno::Any aFocused; + com::sun::star::uno::Any aEmpty; + aFocused <<= FOCUSED; + + commitEvent(AccessibleEventId::STATE_CHANGED,aFocused,aEmpty); +} +// ----------------------------------------------------------------------------- + +void SAL_CALL AccessibleBrowseBoxBase::focusLost( const ::com::sun::star::awt::FocusEvent& ) throw (::com::sun::star::uno::RuntimeException) +{ + com::sun::star::uno::Any aFocused; + com::sun::star::uno::Any aEmpty; + aFocused <<= FOCUSED; + + commitEvent(AccessibleEventId::STATE_CHANGED,aEmpty,aFocused); +} +// XAccessibleEventBroadcaster ------------------------------------------------ + +void SAL_CALL AccessibleBrowseBoxBase::addEventListener( + const Reference< XAccessibleEventListener>& _rxListener ) + throw ( uno::RuntimeException ) +{ + if ( _rxListener.is() ) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + if ( !getClientId( ) ) + setClientId( AccessibleEventNotifier::registerClient( ) ); + + AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener ); + } +} + +void SAL_CALL AccessibleBrowseBoxBase::removeEventListener( + const Reference< XAccessibleEventListener>& _rxListener ) + throw ( uno::RuntimeException ) +{ + if( _rxListener.is() && getClientId( ) ) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClient( nId ); + } + } +} + +// XTypeProvider -------------------------------------------------------------- + +Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxBase::getImplementationId() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslGlobalMutex() ); + static Sequence< sal_Int8 > aId; + implCreateUuid( aId ); + return aId; +} + +// XServiceInfo --------------------------------------------------------------- + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::supportsService( + const OUString& rServiceName ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + + Sequence< OUString > aSupportedServices( getSupportedServiceNames() ); + const OUString* pArrBegin = aSupportedServices.getConstArray(); + const OUString* pArrEnd = pArrBegin + aSupportedServices.getLength(); + const OUString* pString = pArrBegin; + + for( ; ( pString != pArrEnd ) && ( rServiceName != *pString ); ++pString ) + ; + + return pString != pArrEnd; +} + +Sequence< OUString > SAL_CALL AccessibleBrowseBoxBase::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) ); + return Sequence< OUString >( &aServiceName, 1 ); +} + +// other public methods ------------------------------------------------------- + +void AccessibleBrowseBoxBase::setAccessibleName( const OUString& rName ) +{ + ::osl::ClearableMutexGuard aGuard( getOslMutex() ); + Any aOld; + aOld <<= maName; + maName = rName; + + aGuard.clear(); + + commitEvent( + AccessibleEventId::NAME_CHANGED, + uno::makeAny( maName ), + aOld ); +} + +void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString& rDescription ) +{ + ::osl::ClearableMutexGuard aGuard( getOslMutex() ); + Any aOld; + aOld <<= maDescription; + maDescription = rDescription; + + aGuard.clear(); + + commitEvent( + AccessibleEventId::DESCRIPTION_CHANGED, + uno::makeAny( maDescription ), + aOld ); +} + +// internal virtual methods --------------------------------------------------- + +sal_Bool AccessibleBrowseBoxBase::implIsShowing() +{ + sal_Bool bShowing = sal_False; + if( mxParent.is() ) + { + Reference< XAccessibleComponent > + xParentComp( mxParent->getAccessibleContext(), uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = implGetBoundingBox().IsOver( + VCLRectangle( xParentComp->getBounds() ) ); + } + return bShowing; +} + +::utl::AccessibleStateSetHelper* AccessibleBrowseBoxBase::implCreateStateSetHelper() +{ + ::utl::AccessibleStateSetHelper* + pStateSetHelper = new ::utl::AccessibleStateSetHelper; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + // BrowseBox fills StateSet with states depending on object type + mpBrowseBox->FillAccessibleStateSet( *pStateSetHelper, getType() ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return pStateSetHelper; +} + +// internal helper methods ---------------------------------------------------- + +sal_Bool AccessibleBrowseBoxBase::isAlive() const +{ + return !rBHelper.bDisposed && !rBHelper.bInDispose && mpBrowseBox; +} + +void AccessibleBrowseBoxBase::ensureIsAlive() const + throw ( lang::DisposedException ) +{ + if( !isAlive() ) + throw lang::DisposedException(); +} + +Rectangle AccessibleBrowseBoxBase::getBoundingBox() + throw ( lang::DisposedException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Rectangle aRect = implGetBoundingBox(); + if ( 0 == aRect.Left() && 0 == aRect.Top() && 0 == aRect.Right() && 0 == aRect.Bottom() ) + { + DBG_ERRORFILE( "shit" ); + } + return aRect; +} + +Rectangle AccessibleBrowseBoxBase::getBoundingBoxOnScreen() + throw ( lang::DisposedException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Rectangle aRect = implGetBoundingBoxOnScreen(); + if ( 0 == aRect.Left() && 0 == aRect.Top() && 0 == aRect.Right() && 0 == aRect.Bottom() ) + { + DBG_ERRORFILE( "shit" ); + } + return aRect; +} + +void AccessibleBrowseBoxBase::commitEvent( + sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue ) +{ + ::osl::ClearableMutexGuard aGuard( getOslMutex() ); + if ( !getClientId( ) ) + // if we don't have a client id for the notifier, then we don't have listeners, then + // we don't need to notify anything + return; + + // build an event object + AccessibleEventObject aEvent; + aEvent.Source = *this; + aEvent.EventId = _nEventId; + aEvent.OldValue = _rOldValue; + aEvent.NewValue = _rNewValue; + + // let the notifier handle this event + + AccessibleEventNotifier::addEvent( getClientId( ), aEvent ); +} +// ----------------------------------------------------------------------------- + +void AccessibleBrowseBoxBase::implCreateUuid( Sequence< sal_Int8 >& rId ) +{ + if( !rId.hasElements() ) + { + rId.realloc( 16 ); + rtl_createUuid( reinterpret_cast< sal_uInt8* >( rId.getArray() ), 0, sal_True ); + } +} +// ----------------------------------------------------------------------------- +sal_Int16 SAL_CALL AccessibleBrowseBoxBase::getAccessibleRole() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + sal_Int16 nRole = AccessibleRole::UNKNOWN; + switch ( meObjType ) + { + case BBTYPE_ROWHEADERCELL: + nRole = AccessibleRole::ROW_HEADER; + break; + case BBTYPE_COLUMNHEADERCELL: + nRole = AccessibleRole::COLUMN_HEADER; + break; + case BBTYPE_COLUMNHEADERBAR: + case BBTYPE_ROWHEADERBAR: + case BBTYPE_TABLE: + nRole = AccessibleRole::TABLE; + break; + case BBTYPE_TABLECELL: + nRole = AccessibleRole::TABLE_CELL; + break; + case BBTYPE_BROWSEBOX: + nRole = AccessibleRole::PANEL; + break; + case BBTYPE_CHECKBOXCELL: + nRole = AccessibleRole::CHECK_BOX; + break; + } + return nRole; +} +// ----------------------------------------------------------------------------- +Any SAL_CALL AccessibleBrowseBoxBase::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + return Any(); +} +// ----------------------------------------------------------------------------- +Reference<XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleAtPoint( const ::com::sun::star::awt::Point& ) + throw ( uno::RuntimeException ) +{ + return NULL; +} +// ----------------------------------------------------------------------------- +void SAL_CALL AccessibleBrowseBoxBase::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException) +{ + m_xFocusWindow = NULL; +} +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getForeground( ) throw (::com::sun::star::uno::RuntimeException) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + sal_Int32 nColor = 0; + Window* pInst = mpBrowseBox->GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlForeground() ) + nColor = pInst->GetControlForeground().GetColor(); + else + { + Font aFont; + if ( pInst->IsControlFont() ) + aFont = pInst->GetControlFont(); + else + aFont = pInst->GetFont(); + nColor = aFont.GetColor().GetColor(); + } + } + + return nColor; +} +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getBackground( ) throw (::com::sun::star::uno::RuntimeException) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + sal_Int32 nColor = 0; + Window* pInst = mpBrowseBox->GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlBackground() ) + nColor = pInst->GetControlBackground().GetColor(); + else + nColor = pInst->GetBackground().GetColor().GetColor(); + } + + return nColor; +} + +// ============================================================================ +DBG_NAME( BrowseBoxAccessibleElement ) + +// XInterface ----------------------------------------------------------------- +IMPLEMENT_FORWARD_XINTERFACE2( BrowseBoxAccessibleElement, AccessibleBrowseBoxBase, BrowseBoxAccessibleElement_Base ) + +// XTypeProvider -------------------------------------------------------------- +IMPLEMENT_FORWARD_XTYPEPROVIDER2( BrowseBoxAccessibleElement, AccessibleBrowseBoxBase, BrowseBoxAccessibleElement_Base ) + +// XAccessible ---------------------------------------------------------------- + +Reference< XAccessibleContext > SAL_CALL BrowseBoxAccessibleElement::getAccessibleContext() throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return this; +} + +// ---------------------------------------------------------------------------- +BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const Reference< XAccessible >& rxParent, IAccessibleTableProvider& rBrowseBox, + const Reference< awt::XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType eObjType ) + :AccessibleBrowseBoxBase( rxParent, rBrowseBox, _xFocusWindow, eObjType ) +{ + DBG_CTOR( BrowseBoxAccessibleElement, NULL ); +} + +// ---------------------------------------------------------------------------- +BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const Reference< XAccessible >& rxParent, IAccessibleTableProvider& rBrowseBox, + const Reference< awt::XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType eObjType, + const ::rtl::OUString& rName, const ::rtl::OUString& rDescription ) + :AccessibleBrowseBoxBase( rxParent, rBrowseBox, _xFocusWindow, eObjType, rName, rDescription ) +{ + DBG_CTOR( BrowseBoxAccessibleElement, NULL ); +} + +// ---------------------------------------------------------------------------- +BrowseBoxAccessibleElement::~BrowseBoxAccessibleElement( ) +{ + DBG_DTOR( BrowseBoxAccessibleElement, NULL ); +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell.cxx new file mode 100644 index 000000000000..560878b544f3 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell.cxx @@ -0,0 +1,172 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxCheckBoxCell.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <svtools/accessibletableprovider.hxx> + +namespace accessibility +{ + using namespace com::sun::star::accessibility; + using namespace com::sun::star::uno; + using namespace com::sun::star::accessibility::AccessibleEventId; + using namespace ::svt; + + AccessibleCheckBoxCell::AccessibleCheckBoxCell(const Reference<XAccessible >& _rxParent, + IAccessibleTableProvider& _rBrowseBox, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos + ,const TriState& _eState, + sal_Bool _bEnabled, + sal_Bool _bIsTriState) + :AccessibleBrowseBoxCell(_rxParent, _rBrowseBox, _xFocusWindow, _nRowPos, _nColPos, BBTYPE_CHECKBOXCELL) + ,m_eState(_eState) + ,m_bEnabled(_bEnabled) + ,m_bIsTriState(_bIsTriState) + { + } + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleCheckBoxCell, AccessibleBrowseBoxCell, AccessibleCheckBoxCell_BASE ) + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleCheckBoxCell, AccessibleBrowseBoxCell, AccessibleCheckBoxCell_BASE ) + //-------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL AccessibleCheckBoxCell::getAccessibleContext( ) throw (RuntimeException) + { + ensureIsAlive(); + return this; + } + // ----------------------------------------------------------------------------- + ::utl::AccessibleStateSetHelper* AccessibleCheckBoxCell::implCreateStateSetHelper() + { + ::utl::AccessibleStateSetHelper* pStateSetHelper = + AccessibleBrowseBoxCell::implCreateStateSetHelper(); + if( isAlive() ) + { + mpBrowseBox->FillAccessibleStateSetForCell( + *pStateSetHelper, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + if ( m_eState == STATE_CHECK ) + pStateSetHelper->AddState( AccessibleStateType::CHECKED ); + } + return pStateSetHelper; + } + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + // XAccessibleValue + // ----------------------------------------------------------------------------- + + Any SAL_CALL AccessibleCheckBoxCell::getCurrentValue( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + + sal_Int32 nValue = 0; + switch( m_eState ) + { + case STATE_NOCHECK: + nValue = 0; + break; + case STATE_CHECK: + nValue = 1; + break; + case STATE_DONTKNOW: + nValue = 2; + break; + } + return makeAny(nValue); + } + + // ----------------------------------------------------------------------------- + + sal_Bool SAL_CALL AccessibleCheckBoxCell::setCurrentValue( const Any& ) throw (RuntimeException) + { + return sal_False; + } + + // ----------------------------------------------------------------------------- + + Any SAL_CALL AccessibleCheckBoxCell::getMaximumValue( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + + Any aValue; + + if ( m_bIsTriState ) + aValue <<= (sal_Int32) 2; + else + aValue <<= (sal_Int32) 1; + + return aValue; + } + + // ----------------------------------------------------------------------------- + + Any SAL_CALL AccessibleCheckBoxCell::getMinimumValue( ) throw (RuntimeException) + { + Any aValue; + aValue <<= (sal_Int32) 0; + + return aValue; + } + // ----------------------------------------------------------------------------- + // XAccessibleContext + sal_Int32 SAL_CALL AccessibleCheckBoxCell::getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException) + { + return 0; + } + // ----------------------------------------------------------------------------- + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL AccessibleCheckBoxCell::getAccessibleChild( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleCheckBoxCell::getImplementationName() throw ( ::com::sun::star::uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.TableCheckBoxCell" ) ); + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleCheckBoxCell::getAccessibleIndexInParent() + throw ( ::com::sun::star::uno::RuntimeException ) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + + return ( getRowPos() * mpBrowseBox->GetColumnCount() ) + getColumnPos(); + } + // ----------------------------------------------------------------------------- + void AccessibleCheckBoxCell::SetChecked( sal_Bool _bChecked ) + { + m_eState = _bChecked ? STATE_CHECK : STATE_NOCHECK; + Any aOldValue, aNewValue; + if ( _bChecked ) + aNewValue <<= AccessibleStateType::CHECKED; + else + aOldValue <<= AccessibleStateType::CHECKED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + } +} + diff --git a/accessibility/source/extended/AccessibleBrowseBoxHeaderBar.cxx b/accessibility/source/extended/AccessibleBrowseBoxHeaderBar.cxx new file mode 100644 index 000000000000..43d016b86588 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxHeaderBar.cxx @@ -0,0 +1,419 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxHeaderBar.hxx" +#include <svtools/accessibletableprovider.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; + +// ============================================================================ + +namespace accessibility { + +// ============================================================================ + +// Ctor/Dtor/disposing -------------------------------------------------------- + +DBG_NAME( AccessibleBrowseBoxHeaderBar ) + +AccessibleBrowseBoxHeaderBar::AccessibleBrowseBoxHeaderBar( + const Reference< XAccessible >& rxParent, + IAccessibleTableProvider& rBrowseBox, + AccessibleBrowseBoxObjType eObjType ) : + AccessibleBrowseBoxTableBase( rxParent, rBrowseBox,eObjType ) +{ + DBG_CTOR( AccessibleBrowseBoxHeaderBar, NULL ); + + DBG_ASSERT( isRowBar() || isColumnBar(), + "accessibility/extended/AccessibleBrowseBoxHeaderBar - invalid object type" ); +} + +AccessibleBrowseBoxHeaderBar::~AccessibleBrowseBoxHeaderBar() +{ + DBG_DTOR( AccessibleBrowseBoxHeaderBar, NULL ); +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxHeaderBar::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidHeaderIndex( nChildIndex ); + return implGetChild( nChildIndex, implToVCLColumnPos( nChildIndex ) ); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleIndexInParent() + throw ( uno::RuntimeException ) +{ + return isRowBar() ? BBINDEX_ROWHEADERBAR : BBINDEX_COLUMNHEADERBAR; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxHeaderBar::getAccessibleAtPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + sal_Int32 nRow = 0; + sal_uInt16 nColumnPos = 0; + sal_Bool bConverted = isRowBar() ? + mpBrowseBox->ConvertPointToRowHeader( nRow, VCLPoint( rPoint ) ) : + mpBrowseBox->ConvertPointToColumnHeader( nColumnPos, VCLPoint( rPoint ) ); + + return bConverted ? implGetChild( nRow, nColumnPos ) : Reference< XAccessible >(); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::grabFocus() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + // focus on header not supported +} + +Any SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return Any(); // no special key bindings for header +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleRowDescription( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return OUString(); // no headers in headers +} + +OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleColumnDescription( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return OUString(); // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleRowHeaders() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleColumnHeaders() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // no headers in headers +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleRows() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + // row of column header bar not selectable + if( isRowBar() ) + implGetSelectedRows( aSelSeq ); + return aSelSeq; +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleColumns() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + // column of row header bar ("handle column") not selectable + if( isColumnBar() ) + implGetSelectedColumns( aSelSeq ); + return aSelSeq; +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleRowSelected( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return isRowBar() ? implIsRowSelected( nRow ) : sal_False; +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleColumnSelected( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return isColumnBar() ? implIsColumnSelected( nColumn ) : sal_False; +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return implGetChild( nRow, implToVCLColumnPos( nColumn ) ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleSelected( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return isRowBar() ? implIsRowSelected( nRow ) : implIsColumnSelected( nColumn ); +} + +// XAccessibleSelection ------------------------------------------------------- + +void SAL_CALL AccessibleBrowseBoxHeaderBar::selectAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidHeaderIndex( nChildIndex ); + if( isRowBar() ) + implSelectRow( nChildIndex, sal_True ); + else + implSelectColumn( implToVCLColumnPos( nChildIndex ), sal_True ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleChildSelected( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + // using interface methods - no mutex + return isRowBar() ? + isAccessibleRowSelected( nChildIndex ) : + isAccessibleColumnSelected( nChildIndex ); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::clearAccessibleSelection() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + mpBrowseBox->SetNoSelection(); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::selectAllAccessibleChildren() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + // no multiselection of columns possible + if( isRowBar() ) + mpBrowseBox->SelectAll(); + else + implSelectColumn( implToVCLColumnPos( 0 ), sal_True ); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleChildCount() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return isRowBar() ? implGetSelectedRowCount() : implGetSelectedColumnCount(); +} + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxHeaderBar::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + // method may throw lang::IndexOutOfBoundsException + sal_Int32 nIndex = implGetChildIndexFromSelectedIndex( nSelectedChildIndex ); + return implGetChild( nIndex, implToVCLColumnPos( nIndex ) ); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::deselectAccessibleChild( + sal_Int32 nSelectedChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + // method may throw lang::IndexOutOfBoundsException + if ( isAccessibleChildSelected(nSelectedChildIndex) ) + { + if( isRowBar() ) + implSelectRow( nSelectedChildIndex, sal_False ); + else + implSelectColumn( implToVCLColumnPos( nSelectedChildIndex ), sal_False ); + } +} + +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleBrowseBoxHeaderBar::queryInterface( const uno::Type& rType ) + throw ( uno::RuntimeException ) +{ + Any aAny( AccessibleBrowseBoxTableBase::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleBrowseBoxHeaderBarImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::acquire() throw () +{ + AccessibleBrowseBoxTableBase::acquire(); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::release() throw () +{ + AccessibleBrowseBoxTableBase::release(); +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getImplementationName() + throw ( uno::RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBoxHeaderBar" ) ); +} + +Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxHeaderBar::getImplementationId() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslGlobalMutex() ); + static Sequence< sal_Int8 > aId; + implCreateUuid( aId ); + return aId; +} + +// internal virtual methods --------------------------------------------------- + +Rectangle AccessibleBrowseBoxHeaderBar::implGetBoundingBox() +{ + return mpBrowseBox->calcHeaderRect(isColumnBar(),sal_False); +} + +Rectangle AccessibleBrowseBoxHeaderBar::implGetBoundingBoxOnScreen() +{ + return mpBrowseBox->calcHeaderRect(isColumnBar(),sal_True); +} + +sal_Int32 AccessibleBrowseBoxHeaderBar::implGetRowCount() const +{ + // column header bar: only 1 row + return isRowBar() ? AccessibleBrowseBoxTableBase::implGetRowCount() : 1; +} + +sal_Int32 AccessibleBrowseBoxHeaderBar::implGetColumnCount() const +{ + // row header bar ("handle column"): only 1 column + return isColumnBar() ? AccessibleBrowseBoxTableBase::implGetColumnCount() : 1; +} + +// internal helper methods ---------------------------------------------------- + +Reference< XAccessible > AccessibleBrowseBoxHeaderBar::implGetChild( + sal_Int32 nRow, sal_uInt16 nColumnPos ) +{ + return isRowBar() ? + mpBrowseBox->CreateAccessibleRowHeader( nRow ) : + mpBrowseBox->CreateAccessibleColumnHeader( nColumnPos ); +} + +sal_Int32 AccessibleBrowseBoxHeaderBar::implGetChildIndexFromSelectedIndex( + sal_Int32 nSelectedChildIndex ) + throw ( lang::IndexOutOfBoundsException ) +{ + Sequence< sal_Int32 > aSelSeq; + if( isRowBar() ) + implGetSelectedRows( aSelSeq ); + else + implGetSelectedColumns( aSelSeq ); + + if( (nSelectedChildIndex < 0) || (nSelectedChildIndex >= aSelSeq.getLength()) ) + throw lang::IndexOutOfBoundsException(); + + return aSelSeq[ nSelectedChildIndex ]; +} + +void AccessibleBrowseBoxHeaderBar::ensureIsValidHeaderIndex( sal_Int32 nIndex ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( isRowBar() ) + ensureIsValidRow( nIndex ); + else + ensureIsValidColumn( nIndex ); +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx new file mode 100644 index 000000000000..44d547f8fd5b --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx @@ -0,0 +1,173 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxHeaderCell.hxx" +#include <svtools/accessibletableprovider.hxx> +#include "accessibility/extended/AccessibleBrowseBox.hxx" + +namespace accessibility +{ + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::uno; + using namespace ::svt; + +AccessibleBrowseBoxHeaderCell::AccessibleBrowseBoxHeaderCell(sal_Int32 _nColumnRowId, + const Reference< XAccessible >& rxParent, + IAccessibleTableProvider& rBrowseBox, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType eObjType) +: BrowseBoxAccessibleElement(rxParent, + rBrowseBox, + _xFocusWindow, + eObjType, + rBrowseBox.GetAccessibleObjectName( eObjType ,_nColumnRowId), + rBrowseBox.GetAccessibleObjectDescription( eObjType ,_nColumnRowId)) +, m_nColumnRowId(_nColumnRowId) +{ +} +/** Creates a new AccessibleStateSetHelper and fills it with states of the + current object. + @return + A filled AccessibleStateSetHelper. +*/ +::utl::AccessibleStateSetHelper* AccessibleBrowseBoxHeaderCell::implCreateStateSetHelper() +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ::utl::AccessibleStateSetHelper* + pStateSetHelper = new ::utl::AccessibleStateSetHelper; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + + BBSolarGuard aSolarGuard; + pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); + pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); + pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); + pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); + + sal_Bool bSelected = isRowBarCell() ? mpBrowseBox->IsRowSelected(m_nColumnRowId) : mpBrowseBox->IsColumnSelected(m_nColumnRowId); + if ( bSelected ) + pStateSetHelper->AddState( AccessibleStateType::SELECTED ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return pStateSetHelper; +} +// ----------------------------------------------------------------------------- +/** @return + The count of visible children. +*/ +sal_Int32 SAL_CALL AccessibleBrowseBoxHeaderCell::getAccessibleChildCount() + throw ( RuntimeException ) +{ + return 0; +} +// ----------------------------------------------------------------------------- + +/** @return + The XAccessible interface of the specified child. +*/ +Reference<XAccessible > SAL_CALL AccessibleBrowseBoxHeaderCell::getAccessibleChild( sal_Int32 ) + throw ( IndexOutOfBoundsException,RuntimeException ) +{ + throw IndexOutOfBoundsException(); +} +// ----------------------------------------------------------------------------- + +/** Grabs the focus to the column header. */ +void SAL_CALL AccessibleBrowseBoxHeaderCell::grabFocus() + throw ( ::com::sun::star::uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + if ( isRowBarCell() ) + mpBrowseBox->SelectRow(m_nColumnRowId); + else + mpBrowseBox->SelectColumn(static_cast<sal_uInt16>(m_nColumnRowId)); //!!! +} +// ----------------------------------------------------------------------------- +/** @return + The name of this class. +*/ +::rtl::OUString SAL_CALL AccessibleBrowseBoxHeaderCell::getImplementationName() + throw ( ::com::sun::star::uno::RuntimeException ) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBoxHeaderCell" ) ); +} +// ----------------------------------------------------------------------------- +namespace +{ + Rectangle getRectangle(IAccessibleTableProvider* _pBrowseBox,sal_Int32 _nRowColIndex, sal_Bool _bOnScreen,sal_Bool _bRowBar) + { + sal_Int32 nRow = 0; + sal_uInt16 nCol = (sal_uInt16)_nRowColIndex; + if ( _bRowBar ) + { + nRow = _nRowColIndex + 1; + nCol = 0; + } + + Rectangle aRet(_pBrowseBox->GetFieldRectPixelAbs( nRow , nCol, sal_True, _bOnScreen)); + return Rectangle(aRet.TopLeft() - Point(0,aRet.GetHeight()),aRet.GetSize()); + } +} + +Rectangle AccessibleBrowseBoxHeaderCell::implGetBoundingBox() +{ + return getRectangle(mpBrowseBox,m_nColumnRowId,sal_False,isRowBarCell()); +} +// ----------------------------------------------------------------------------- + +Rectangle AccessibleBrowseBoxHeaderCell::implGetBoundingBoxOnScreen() +{ + return getRectangle(mpBrowseBox,m_nColumnRowId,sal_True,isRowBarCell()); +} +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL AccessibleBrowseBoxHeaderCell::getAccessibleIndexInParent() + throw ( RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + sal_Int32 nIndex = m_nColumnRowId; + if ( mpBrowseBox->HasRowHeader() ) + --nIndex; + return nIndex; +} +// ----------------------------------------------------------------------------- +} // namespace accessibility +// ----------------------------------------------------------------------------- + + diff --git a/accessibility/source/extended/AccessibleBrowseBoxTable.cxx b/accessibility/source/extended/AccessibleBrowseBoxTable.cxx new file mode 100644 index 000000000000..1ac635ec6230 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxTable.cxx @@ -0,0 +1,278 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxTable.hxx" +#include <svtools/accessibletableprovider.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; + +// ============================================================================ + +namespace accessibility { + +// ============================================================================ + +// Ctor/Dtor/disposing -------------------------------------------------------- + +DBG_NAME( AccessibleBrowseBoxTable ) + +AccessibleBrowseBoxTable::AccessibleBrowseBoxTable( + const Reference< XAccessible >& rxParent, + IAccessibleTableProvider& rBrowseBox ) : + AccessibleBrowseBoxTableBase( rxParent, rBrowseBox, BBTYPE_TABLE ) +{ + DBG_CTOR( AccessibleBrowseBoxTable, NULL ); +} + +AccessibleBrowseBoxTable::~AccessibleBrowseBoxTable() +{ + DBG_DTOR( AccessibleBrowseBoxTable, NULL ); +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxTable::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return mpBrowseBox->CreateAccessibleCell( + implGetRow( nChildIndex ), (sal_Int16)implGetColumn( nChildIndex ) ); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTable::getAccessibleIndexInParent() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return BBINDEX_TABLE; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxTable::getAccessibleAtPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Reference< XAccessible > xChild; + sal_Int32 nRow = 0; + sal_uInt16 nColumnPos = 0; + if( mpBrowseBox->ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) ) + xChild = mpBrowseBox->CreateAccessibleCell( nRow, nColumnPos ); + + return xChild; +} + +void SAL_CALL AccessibleBrowseBoxTable::grabFocus() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + mpBrowseBox->GrabTableFocus(); +} + +Any SAL_CALL AccessibleBrowseBoxTable::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return Any(); // no special key bindings for data table +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxTable::getAccessibleRowDescription( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return mpBrowseBox->GetRowDescription( nRow ); +} + +OUString SAL_CALL AccessibleBrowseBoxTable::getAccessibleColumnDescription( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return mpBrowseBox->GetColumnDescription( (sal_uInt16)nColumn ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxTable::getAccessibleRowHeaders() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implGetHeaderBar( BBINDEX_ROWHEADERBAR ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxTable::getAccessibleColumnHeaders() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implGetHeaderBar( BBINDEX_COLUMNHEADERBAR ); +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxTable::getSelectedAccessibleRows() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + implGetSelectedRows( aSelSeq ); + return aSelSeq; +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxTable::getSelectedAccessibleColumns() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + implGetSelectedColumns( aSelSeq ); + return aSelSeq; +} + +sal_Bool SAL_CALL AccessibleBrowseBoxTable::isAccessibleRowSelected( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return implIsRowSelected( nRow ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxTable::isAccessibleColumnSelected( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return implIsColumnSelected( nColumn ); +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxTable::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return mpBrowseBox->CreateAccessibleCell( nRow, (sal_Int16)nColumn ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxTable::isAccessibleSelected( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return implIsRowSelected( nRow ) || implIsColumnSelected( nColumn ); +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxTable::getImplementationName() + throw ( uno::RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBoxTable" ) ); +} + +// internal virtual methods --------------------------------------------------- + +Rectangle AccessibleBrowseBoxTable::implGetBoundingBox() +{ + return mpBrowseBox->calcTableRect(sal_False); +} + +Rectangle AccessibleBrowseBoxTable::implGetBoundingBoxOnScreen() +{ + return mpBrowseBox->calcTableRect(); +} + +// internal helper methods ---------------------------------------------------- + +Reference< XAccessibleTable > AccessibleBrowseBoxTable::implGetHeaderBar( + sal_Int32 nChildIndex ) + throw ( uno::RuntimeException ) +{ + Reference< XAccessible > xRet; + Reference< XAccessibleContext > xContext( mxParent, uno::UNO_QUERY ); + if( xContext.is() ) + { + try + { + xRet = xContext->getAccessibleChild( nChildIndex ); + } + catch( lang::IndexOutOfBoundsException& ) + { + DBG_ERROR( "implGetHeaderBar - wrong child index" ); + } + // RuntimeException goes to caller + } + return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY ); +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleBrowseBoxTableBase.cxx b/accessibility/source/extended/AccessibleBrowseBoxTableBase.cxx new file mode 100644 index 000000000000..7a7aed644f5c --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxTableBase.cxx @@ -0,0 +1,355 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxTableBase.hxx" +#include <svtools/accessibletableprovider.hxx> +#include <tools/multisel.hxx> +#include <comphelper/sequence.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; + +// ============================================================================ + +namespace accessibility { + +// ============================================================================ + +// Ctor/Dtor/disposing -------------------------------------------------------- + +DBG_NAME( AccessibleBrowseBoxTableBase ) + +AccessibleBrowseBoxTableBase::AccessibleBrowseBoxTableBase( + const Reference< XAccessible >& rxParent, + IAccessibleTableProvider& rBrowseBox, + AccessibleBrowseBoxObjType eObjType ) : + BrowseBoxAccessibleElement( rxParent, rBrowseBox,NULL, eObjType ) +{ + DBG_CTOR( AccessibleBrowseBoxTableBase, NULL ); +} + +AccessibleBrowseBoxTableBase::~AccessibleBrowseBoxTableBase() +{ + DBG_DTOR( AccessibleBrowseBoxTableBase, NULL ); +} + +// XAccessibleContext --------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleChildCount() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implGetChildCount(); +} + +sal_Int16 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRole() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return AccessibleRole::TABLE; +} + +// XAccessibleTable ----------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRowCount() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implGetRowCount(); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleColumnCount() + throw ( uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implGetColumnCount(); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRowExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleColumnExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleCaption() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // not supported +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleSummary() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // not supported +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleIndex( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return implGetChildIndex( nRow, nColumn ); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRow( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetRow( nChildIndex ); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleColumn( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetColumn( nChildIndex ); +} + +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleBrowseBoxTableBase::queryInterface( const uno::Type& rType ) + throw ( uno::RuntimeException ) +{ + Any aAny( BrowseBoxAccessibleElement::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleBrowseBoxTableImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleBrowseBoxTableBase::acquire() throw () +{ + BrowseBoxAccessibleElement::acquire(); +} + +void SAL_CALL AccessibleBrowseBoxTableBase::release() throw () +{ + BrowseBoxAccessibleElement::release(); +} + +// XTypeProvider -------------------------------------------------------------- + +Sequence< uno::Type > SAL_CALL AccessibleBrowseBoxTableBase::getTypes() + throw ( uno::RuntimeException ) +{ + return ::comphelper::concatSequences( + BrowseBoxAccessibleElement::getTypes(), + AccessibleBrowseBoxTableImplHelper::getTypes() ); +} + +Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxTableBase::getImplementationId() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslGlobalMutex() ); + static Sequence< sal_Int8 > aId; + implCreateUuid( aId ); + return aId; +} + +// internal virtual methods --------------------------------------------------- + +sal_Int32 AccessibleBrowseBoxTableBase::implGetRowCount() const +{ + return mpBrowseBox->GetRowCount(); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetColumnCount() const +{ + sal_uInt16 nColumns = mpBrowseBox->GetColumnCount(); + // do not count the "handle column" + if( nColumns && implHasHandleColumn() ) + --nColumns; + return nColumns; +} + +// internal helper methods ---------------------------------------------------- + +sal_Bool AccessibleBrowseBoxTableBase::implHasHandleColumn() const +{ + return mpBrowseBox->HasRowHeader(); +} + +sal_uInt16 AccessibleBrowseBoxTableBase::implToVCLColumnPos( sal_Int32 nColumn ) const +{ + sal_uInt16 nVCLPos = 0; + if( (0 <= nColumn) && (nColumn < implGetColumnCount()) ) + { + // regard "handle column" + if( implHasHandleColumn() ) + ++nColumn; + nVCLPos = static_cast< sal_uInt16 >( nColumn ); + } + return nVCLPos; +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetChildCount() const +{ + return implGetRowCount() * implGetColumnCount(); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetRow( sal_Int32 nChildIndex ) const +{ + sal_Int32 nColumns = implGetColumnCount(); + return nColumns ? (nChildIndex / nColumns) : 0; +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetColumn( sal_Int32 nChildIndex ) const +{ + sal_Int32 nColumns = implGetColumnCount(); + return nColumns ? (nChildIndex % nColumns) : 0; +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetChildIndex( + sal_Int32 nRow, sal_Int32 nColumn ) const +{ + return nRow * implGetColumnCount() + nColumn; +} + +sal_Bool AccessibleBrowseBoxTableBase::implIsRowSelected( sal_Int32 nRow ) const +{ + return mpBrowseBox->IsRowSelected( nRow ); +} + +sal_Bool AccessibleBrowseBoxTableBase::implIsColumnSelected( sal_Int32 nColumn ) const +{ + if( implHasHandleColumn() ) + --nColumn; + return mpBrowseBox->IsColumnSelected( nColumn ); +} + +void AccessibleBrowseBoxTableBase::implSelectRow( sal_Int32 nRow, sal_Bool bSelect ) +{ + mpBrowseBox->SelectRow( nRow, bSelect, sal_True ); +} + +void AccessibleBrowseBoxTableBase::implSelectColumn( sal_Int32 nColumnPos, sal_Bool bSelect ) +{ + mpBrowseBox->SelectColumn( (sal_uInt16)nColumnPos, bSelect ); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetSelectedRowCount() const +{ + return mpBrowseBox->GetSelectedRowCount(); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetSelectedColumnCount() const +{ + return mpBrowseBox->GetSelectedColumnCount(); +} + +void AccessibleBrowseBoxTableBase::implGetSelectedRows( Sequence< sal_Int32 >& rSeq ) +{ + mpBrowseBox->GetAllSelectedRows( rSeq ); +} + +void AccessibleBrowseBoxTableBase::implGetSelectedColumns( Sequence< sal_Int32 >& rSeq ) +{ + mpBrowseBox->GetAllSelectedColumns( rSeq ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidRow( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( nRow >= implGetRowCount() ) + throw lang::IndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "row index is invalid" ) ), *this ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidColumn( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( nColumn >= implGetColumnCount() ) + throw lang::IndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("column index is invalid") ), *this ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidAddress( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException ) +{ + ensureIsValidRow( nRow ); + ensureIsValidColumn( nColumn ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidIndex( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( nChildIndex >= implGetChildCount() ) + throw lang::IndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("child index is invalid") ), *this ); +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleBrowseBoxTableCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxTableCell.cxx new file mode 100644 index 000000000000..a7392ff46e4a --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxTableCell.cxx @@ -0,0 +1,354 @@ +/************************************************************************* + * + * 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/extended/AccessibleBrowseBoxTableCell.hxx" +#include <svtools/accessibletableprovider.hxx> +#include "accessibility/extended/AccessibleBrowseBox.hxx" +#include <tools/gen.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> + +namespace accessibility +{ + namespace + { + void checkIndex_Impl( sal_Int32 _nIndex, const ::rtl::OUString& _sText ) throw (::com::sun::star::lang::IndexOutOfBoundsException) + { + if ( _nIndex >= _sText.getLength() ) + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } + + sal_Int32 getIndex_Impl( sal_Int32 _nRow, sal_uInt16 _nColumn, sal_uInt16 _nColumnCount ) + { + return _nRow * _nColumnCount + _nColumn; + } + } + using namespace ::com::sun::star::lang; + using namespace utl; + using namespace comphelper; + using ::rtl::OUString; + using ::accessibility::AccessibleBrowseBox; + using namespace ::com::sun::star::uno; + using ::com::sun::star::accessibility::XAccessible; + using namespace ::com::sun::star::accessibility; + using namespace ::svt; + + + // implementation of a table cell + ::rtl::OUString AccessibleBrowseBoxTableCell::implGetText() + { + ensureIsAlive(); + return mpBrowseBox->GetAccessibleCellText( getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + } + + ::com::sun::star::lang::Locale AccessibleBrowseBoxTableCell::implGetLocale() + { + ensureIsAlive(); + return mpBrowseBox->GetAccessible()->getAccessibleContext()->getLocale(); + } + + void AccessibleBrowseBoxTableCell::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + + AccessibleBrowseBoxTableCell::AccessibleBrowseBoxTableCell(const Reference<XAccessible >& _rxParent, + IAccessibleTableProvider& _rBrowseBox, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + sal_Int32 _nOffset ) + :AccessibleBrowseBoxCell( _rxParent, _rBrowseBox, _xFocusWindow, _nRowPos, _nColPos ) + { + m_nOffset = ( OFFSET_DEFAULT == _nOffset ) ? (sal_Int32)BBINDEX_FIRSTCONTROL : _nOffset; + sal_Int32 nIndex = getIndex_Impl( _nRowPos, _nColPos, _rBrowseBox.GetColumnCount() ); + setAccessibleName( _rBrowseBox.GetAccessibleObjectName( BBTYPE_TABLECELL, nIndex ) ); + setAccessibleDescription( _rBrowseBox.GetAccessibleObjectDescription( BBTYPE_TABLECELL, nIndex ) ); + // Need to register as event listener + Reference< XComponent > xComponent(_rxParent, UNO_QUERY); + if( xComponent.is() ) + xComponent->addEventListener(static_cast< XEventListener *> (this)); + } + + void AccessibleBrowseBoxTableCell::nameChanged( const ::rtl::OUString& rNewName, const ::rtl::OUString& rOldName ) + { + implSetName( rNewName ); + Any aOldValue, aNewValue; + aOldValue <<= rOldName; + aNewValue <<= rNewName; + commitEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } + + // XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + ::com::sun::star::uno::Any SAL_CALL AccessibleBrowseBoxTableCell::queryInterface( + const ::com::sun::star::uno::Type& rType ) + throw ( ::com::sun::star::uno::RuntimeException ) + { + Any aRet = AccessibleBrowseBoxCell::queryInterface(rType); + if ( !aRet.hasValue() ) + aRet = AccessibleTextHelper_BASE::queryInterface(rType); + return aRet; + } + + /** Aquires the object (calls acquire() on base class). */ + void SAL_CALL AccessibleBrowseBoxTableCell::acquire() throw () + { + AccessibleBrowseBoxCell::acquire(); + } + + /** Releases the object (calls release() on base class). */ + void SAL_CALL AccessibleBrowseBoxTableCell::release() throw () + { + AccessibleBrowseBoxCell::release(); + } + + ::com::sun::star::awt::Rectangle SAL_CALL AccessibleBrowseBoxTableCell::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + ::com::sun::star::awt::Rectangle aRect; + + if ( mpBrowseBox ) + { + aRect = AWTRectangle( mpBrowseBox->GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) ); + } + + return aRect; + } + + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getIndexAtPoint( const ::com::sun::star::awt::Point& _aPoint ) throw (RuntimeException) + { + //! TODO CTL bidi + // DBG_ASSERT(0,"Need to be done by base class!"); + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + return mpBrowseBox->GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) ); + } + + /** @return + The name of this class. + */ + ::rtl::OUString SAL_CALL AccessibleBrowseBoxTableCell::getImplementationName() + throw ( ::com::sun::star::uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBoxTableCell" ) ); + } + + /** @return The count of visible children. */ + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getAccessibleChildCount() + throw ( ::com::sun::star::uno::RuntimeException ) + { + return 0; + } + + /** @return The XAccessible interface of the specified child. */ + ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > SAL_CALL + AccessibleBrowseBoxTableCell::getAccessibleChild( sal_Int32 ) + throw ( ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException ) + { + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } + + /** Creates a new AccessibleStateSetHelper and fills it with states of the + current object. + @return + A filled AccessibleStateSetHelper. + */ + ::utl::AccessibleStateSetHelper* AccessibleBrowseBoxTableCell::implCreateStateSetHelper() + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ::utl::AccessibleStateSetHelper* pStateSetHelper = new ::utl::AccessibleStateSetHelper; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + + mpBrowseBox->FillAccessibleStateSetForCell( *pStateSetHelper, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return pStateSetHelper; + } + + + // XAccessible ------------------------------------------------------------ + + /** @return The XAccessibleContext interface of this object. */ + Reference< XAccessibleContext > SAL_CALL AccessibleBrowseBoxTableCell::getAccessibleContext() throw ( RuntimeException ) + { + ensureIsAlive(); + return this; + } + + // XAccessibleContext ----------------------------------------------------- + + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getAccessibleIndexInParent() + throw ( ::com::sun::star::uno::RuntimeException ) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + return /*BBINDEX_FIRSTCONTROL*/ m_nOffset + ( getRowPos() * mpBrowseBox->GetColumnCount() ) + getColumnPos(); + } + + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException) + { + return -1; + } + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + sal_Unicode SAL_CALL AccessibleBrowseBoxTableCell::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getCharacter( nIndex ); + } + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleBrowseBoxTableCell::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ::rtl::OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getCharacterCount( ); + } + + ::rtl::OUString SAL_CALL AccessibleBrowseBoxTableCell::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getSelectedText( ); + } + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getSelectionStart( ); + } + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getSelectionEnd( ); + } + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + ::rtl::OUString SAL_CALL AccessibleBrowseBoxTableCell::getText( ) throw (::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getText( ); + } + ::rtl::OUString SAL_CALL AccessibleBrowseBoxTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex ); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleBrowseBoxTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleBrowseBoxTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleBrowseBoxTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + BBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ::rtl::OUString sText = implGetText(); + checkIndex_Impl( nStartIndex, sText ); + checkIndex_Impl( nEndIndex, sText ); + + //!!! don't know how to put a string into the clipboard + return sal_False; + } + void AccessibleBrowseBoxTableCell::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + if ( _rSource.Source == mxParent ) + { + dispose(); + } + } + +} diff --git a/accessibility/source/extended/AccessibleGridControl.cxx b/accessibility/source/extended/AccessibleGridControl.cxx new file mode 100755 index 000000000000..f0aa406b62bf --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControl.cxx @@ -0,0 +1,372 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControl.hxx" +#include "accessibility/extended/AccessibleGridControlTable.hxx" +#include "accessibility/extended/AccessibleGridControlHeader.hxx" +#include <svtools/accessibletable.hxx> +#include <comphelper/types.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +// ============================================================================ + +namespace accessibility +{ + +// ============================================================================ + +using ::rtl::OUString; + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; +using namespace ::svt::table; + +// ============================================================================ +class AccessibleGridControl_Impl +{ +public: + /// the XAccessible which created the AccessibleGridControl + WeakReference< XAccessible > m_aCreator; + + /** The data table child. */ + Reference< + ::com::sun::star::accessibility::XAccessible > m_xTable; + AccessibleGridControlTable* m_pTable; + + /** The header bar for rows. */ + Reference< + ::com::sun::star::accessibility::XAccessible > m_xRowHeaderBar; + AccessibleGridControlHeader* m_pRowHeaderBar; + + /** The header bar for columns (first row of the table). */ + Reference< + ::com::sun::star::accessibility::XAccessible > m_xColumnHeaderBar; + AccessibleGridControlHeader* m_pColumnHeaderBar; +}; + +DBG_NAME( AccessibleGridControl ) + +AccessibleGridControl::AccessibleGridControl( + const Reference< XAccessible >& _rxParent, const Reference< XAccessible >& _rxCreator, + IAccessibleTable& _rTable ) + : AccessibleGridControlBase( _rxParent, _rTable, TCTYPE_GRIDCONTROL ) +{ + m_pImpl.reset( new AccessibleGridControl_Impl() ); + m_pImpl->m_aCreator = _rxCreator; +} + +// ----------------------------------------------------------------------------- +AccessibleGridControl::~AccessibleGridControl() +{ +} +// ----------------------------------------------------------------------------- + +void SAL_CALL AccessibleGridControl::disposing() +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + + m_pImpl->m_pTable = NULL; + m_pImpl->m_pColumnHeaderBar = NULL; + m_pImpl->m_pRowHeaderBar = NULL; + m_pImpl->m_aCreator = Reference< XAccessible >(); + + Reference< XAccessible > xTable = m_pImpl->m_xTable; + + Reference< XComponent > xComp( m_pImpl->m_xTable, UNO_QUERY ); + if ( xComp.is() ) + { + xComp->dispose(); + } + + AccessibleGridControlBase::disposing(); +} +// ----------------------------------------------------------------------------- + +// XAccessibleContext --------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleGridControl::getAccessibleChildCount() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return m_aTable.GetAccessibleControlCount(); +} +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControl::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + if (nChildIndex<0 || nChildIndex>=getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + if (isAlive()) + { + if(nChildIndex == 0 && m_aTable.HasColHeader()) + { + if(!m_pImpl->m_xColumnHeaderBar.is()) + { + AccessibleGridControlHeader* pColHeaderBar = new AccessibleGridControlHeader(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_COLUMNHEADERBAR); + m_pImpl->m_xColumnHeaderBar = pColHeaderBar; + } + xChild = m_pImpl->m_xColumnHeaderBar; + } + else if(m_aTable.HasRowHeader() && (nChildIndex == 1 || nChildIndex == 0)) + { + if(!m_pImpl->m_xRowHeaderBar.is()) + { + AccessibleGridControlHeader* pRowHeaderBar = new AccessibleGridControlHeader(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_ROWHEADERBAR); + m_pImpl->m_xRowHeaderBar = pRowHeaderBar; + } + xChild = m_pImpl->m_xRowHeaderBar; + } + else + { + AccessibleGridControlTable* pTable = new AccessibleGridControlTable(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_TABLE); + m_pImpl->m_xTable = pTable; + xChild = m_pImpl->m_xTable; + } + } + return xChild; +} +// ----------------------------------------------------------------------------- + +sal_Int16 SAL_CALL AccessibleGridControl::getAccessibleRole() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return AccessibleRole::PANEL; +} +// ----------------------------------------------------------------------------- + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControl::getAccessibleAtPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Reference< XAccessible > xChild; + sal_Int32 nIndex = 0; + if( m_aTable.ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) ) + xChild = m_aTable.CreateAccessibleControl( nIndex ); + else + { + // try whether point is in one of the fixed children + // (table, header bars, corner control) + Point aPoint( VCLPoint( rPoint ) ); + for( nIndex = 0; (nIndex < 3) && !xChild.is(); ++nIndex ) + { + Reference< XAccessible > xCurrChild( implGetFixedChild( nIndex ) ); + Reference< XAccessibleComponent > + xCurrChildComp( xCurrChild, uno::UNO_QUERY ); + + if( xCurrChildComp.is() && + VCLRectangle( xCurrChildComp->getBounds() ).IsInside( aPoint ) ) + xChild = xCurrChild; + } + } + return xChild; +} +// ----------------------------------------------------------------------------- + +void SAL_CALL AccessibleGridControl::grabFocus() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + m_aTable.GrabFocus(); +} +// ----------------------------------------------------------------------------- + +Any SAL_CALL AccessibleGridControl::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return Any(); +} +// ----------------------------------------------------------------------------- + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControl::getImplementationName() + throw ( uno::RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControl" ) ); +} +// ----------------------------------------------------------------------------- + +// internal virtual methods --------------------------------------------------- + +Rectangle AccessibleGridControl::implGetBoundingBox() +{ + Window* pParent = m_aTable.GetAccessibleParentWindow(); + DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" ); + return m_aTable.GetWindowExtentsRelative( pParent ); +} +// ----------------------------------------------------------------------------- + +Rectangle AccessibleGridControl::implGetBoundingBoxOnScreen() +{ + return m_aTable.GetWindowExtentsRelative( NULL ); +} +// internal helper methods ---------------------------------------------------- + +Reference< XAccessible > AccessibleGridControl::implGetTable() +{ + if( !m_pImpl->m_xTable.is() ) + { + m_pImpl->m_pTable = createAccessibleTable(); + m_pImpl->m_xTable = m_pImpl->m_pTable; + } + return m_pImpl->m_xTable; +} +// ----------------------------------------------------------------------------- + +Reference< XAccessible > +AccessibleGridControl::implGetHeaderBar( AccessibleTableControlObjType eObjType ) +{ + Reference< XAccessible > xRet; + Reference< XAccessible >* pxMember = NULL; + + if( eObjType == TCTYPE_ROWHEADERBAR ) + pxMember = &m_pImpl->m_xRowHeaderBar; + else if( eObjType == TCTYPE_COLUMNHEADERBAR ) + pxMember = &m_pImpl->m_xColumnHeaderBar; + + if( pxMember ) + { + if( !pxMember->is() ) + { + AccessibleGridControlHeader* pHeaderBar = new AccessibleGridControlHeader( + (Reference< XAccessible >)m_pImpl->m_aCreator, m_aTable, eObjType ); + + if ( TCTYPE_COLUMNHEADERBAR == eObjType) + m_pImpl->m_pColumnHeaderBar = pHeaderBar; + else + m_pImpl->m_pRowHeaderBar = pHeaderBar; + + *pxMember = pHeaderBar; + } + xRet = *pxMember; + } + return xRet; +} +// ----------------------------------------------------------------------------- +Reference< XAccessible > +AccessibleGridControl::implGetFixedChild( sal_Int32 nChildIndex ) +{ + Reference< XAccessible > xRet; + switch( nChildIndex ) + { + case TCINDEX_COLUMNHEADERBAR: + xRet = implGetHeaderBar( TCTYPE_COLUMNHEADERBAR ); + break; + case TCINDEX_ROWHEADERBAR: + xRet = implGetHeaderBar( TCTYPE_ROWHEADERBAR ); + break; + case TCINDEX_TABLE: + xRet = implGetTable(); + break; + } + return xRet; +} +// ----------------------------------------------------------------------------- +AccessibleGridControlTable* AccessibleGridControl::createAccessibleTable() +{ + Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator; + DBG_ASSERT( xCreator.is(), "accessibility/extended/AccessibleGirdControl::createAccessibleTable: my creator died - how this?" ); + return new AccessibleGridControlTable( xCreator, m_aTable, TCTYPE_TABLE ); +} +// ============================================================================ +// = AccessibleGridControlAccess +// ============================================================================ +DBG_NAME( AccessibleGridControlAccess ) +// ----------------------------------------------------------------------------- +AccessibleGridControlAccess::AccessibleGridControlAccess( const Reference< XAccessible >& _rxParent, IAccessibleTable& _rTable ) + :m_xParent( _rxParent ) + ,m_rTable( _rTable ) + ,m_pContext( NULL ) +{ +} + +// ----------------------------------------------------------------------------- +AccessibleGridControlAccess::~AccessibleGridControlAccess() +{ +} + +// ----------------------------------------------------------------------------- +void AccessibleGridControlAccess::dispose() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + m_pContext = NULL; + ::comphelper::disposeComponent( m_xContext ); +} + +// ----------------------------------------------------------------------------- +Reference< XAccessibleContext > SAL_CALL AccessibleGridControlAccess::getAccessibleContext() throw ( RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + DBG_ASSERT( ( m_pContext && m_xContext.is() ) || ( !m_pContext && !m_xContext.is() ), + "accessibility/extended/AccessibleGridControlAccess::getAccessibleContext: inconsistency!" ); + + // if the context died meanwhile (we're no listener, so it won't tell us explicitily when this happens), + // then reset an re-create. + if ( m_pContext && !m_pContext->isAlive() ) + m_xContext = m_pContext = NULL; + + if ( !m_xContext.is() ) + m_xContext = m_pContext = new AccessibleGridControl( m_xParent, this, m_rTable ); + + return m_xContext; +} + +// ----------------------------------------------------------------------------- +bool AccessibleGridControlAccess::isContextAlive() const +{ + return ( NULL != m_pContext ) && m_pContext->isAlive(); +} + +// ============================================================================ + +} // namespace accessibility diff --git a/accessibility/source/extended/AccessibleGridControlBase.cxx b/accessibility/source/extended/AccessibleGridControlBase.cxx new file mode 100755 index 000000000000..ea81bd350426 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlBase.cxx @@ -0,0 +1,535 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControlBase.hxx" +#include <svtools/accessibletable.hxx> +#include <rtl/uuid.h> +// +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblerelationsethelper.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; +using namespace ::svt; +using namespace ::svt::table; + + +// ============================================================================ + +namespace accessibility { + +using namespace com::sun::star::accessibility::AccessibleStateType; +// ============================================================================ + +DBG_NAME( AccessibleGridControlBase ) + +AccessibleGridControlBase::AccessibleGridControlBase( + const Reference< XAccessible >& rxParent, + svt::table::IAccessibleTable& rTable, + AccessibleTableControlObjType eObjType ) : + AccessibleGridControlImplHelper( m_aMutex ), + m_xParent( rxParent ), + m_aTable( rTable), + m_eObjType( eObjType ), + m_aName( rTable.GetAccessibleObjectName( eObjType, 0, 0 ) ), + m_aDescription( rTable.GetAccessibleObjectDescription( eObjType ) ), + m_aClientId(0) +{ +} + +AccessibleGridControlBase::~AccessibleGridControlBase() +{ + if( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } +} + +void SAL_CALL AccessibleGridControlBase::disposing() +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + m_xParent = NULL; +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL AccessibleGridControlBase::getAccessibleParent() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return m_xParent; +} + +sal_Int32 SAL_CALL AccessibleGridControlBase::getAccessibleIndexInParent() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + // -1 for child not found/no parent (according to specification) + sal_Int32 nRet = -1; + + Reference< uno::XInterface > xMeMyselfAndI( static_cast< XAccessibleContext* >( this ), uno::UNO_QUERY ); + + // iterate over parent's children and search for this object + if( m_xParent.is() ) + { + Reference< XAccessibleContext > + xParentContext( m_xParent->getAccessibleContext() ); + if( xParentContext.is() ) + { + Reference< uno::XInterface > xChild; + + sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); + for( sal_Int32 nChild = 0; nChild < nChildCount; ++nChild ) + { + xChild = xChild.query( xParentContext->getAccessibleChild( nChild ) ); + if ( xMeMyselfAndI.get() == xChild.get() ) + { + nRet = nChild; + break; + } + } + } + } + return nRet; +} + +OUString SAL_CALL AccessibleGridControlBase::getAccessibleDescription() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return m_aDescription; +} + +OUString SAL_CALL AccessibleGridControlBase::getAccessibleName() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return m_aName; +} + +Reference< XAccessibleRelationSet > SAL_CALL +AccessibleGridControlBase::getAccessibleRelationSet() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + // GridControl does not have relations. + return new utl::AccessibleRelationSetHelper; +} + +Reference< XAccessibleStateSet > SAL_CALL +AccessibleGridControlBase::getAccessibleStateSet() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + // don't check whether alive -> StateSet may contain DEFUNC + return implCreateStateSetHelper(); +} + +lang::Locale SAL_CALL AccessibleGridControlBase::getLocale() + throw ( IllegalAccessibleComponentStateException, uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + if( m_xParent.is() ) + { + Reference< XAccessibleContext > + xParentContext( m_xParent->getAccessibleContext() ); + if( xParentContext.is() ) + return xParentContext->getLocale(); + } + throw IllegalAccessibleComponentStateException(); +} + +// XAccessibleComponent ------------------------------------------------------- + +sal_Bool SAL_CALL AccessibleGridControlBase::containsPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + return Rectangle( Point(), getBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); +} + +awt::Rectangle SAL_CALL AccessibleGridControlBase::getBounds() + throw ( uno::RuntimeException ) +{ + return AWTRectangle( getBoundingBox() ); +} + +awt::Point SAL_CALL AccessibleGridControlBase::getLocation() + throw ( uno::RuntimeException ) +{ + return AWTPoint( getBoundingBox().TopLeft() ); +} + +awt::Point SAL_CALL AccessibleGridControlBase::getLocationOnScreen() + throw ( uno::RuntimeException ) +{ + return AWTPoint( getBoundingBoxOnScreen().TopLeft() ); +} + +awt::Size SAL_CALL AccessibleGridControlBase::getSize() + throw ( uno::RuntimeException ) +{ + return AWTSize( getBoundingBox().GetSize() ); +} + +sal_Bool SAL_CALL AccessibleGridControlBase::isShowing() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implIsShowing(); +} + +sal_Bool SAL_CALL AccessibleGridControlBase::isVisible() + throw ( uno::RuntimeException ) +{ + Reference< XAccessibleStateSet > xStateSet = getAccessibleStateSet(); + return xStateSet.is() ? + xStateSet->contains( AccessibleStateType::VISIBLE ) : sal_False; +} + +sal_Bool SAL_CALL AccessibleGridControlBase::isFocusTraversable() + throw ( uno::RuntimeException ) +{ + Reference< XAccessibleStateSet > xStateSet = getAccessibleStateSet(); + return xStateSet.is() ? + xStateSet->contains( AccessibleStateType::FOCUSABLE ) : sal_False; +} +// XAccessibleEventBroadcaster ------------------------------------------------ + +void SAL_CALL AccessibleGridControlBase::addEventListener( + const Reference< XAccessibleEventListener>& _rxListener ) + throw ( uno::RuntimeException ) +{ + if ( _rxListener.is() ) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + if ( !getClientId( ) ) + setClientId( AccessibleEventNotifier::registerClient( ) ); + + AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener ); + } +} + +void SAL_CALL AccessibleGridControlBase::removeEventListener( + const Reference< XAccessibleEventListener>& _rxListener ) + throw ( uno::RuntimeException ) +{ + if( _rxListener.is() && getClientId( ) ) + { + ::osl::MutexGuard aGuard( getOslMutex() ); + sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClient( nId ); + } + } +} + +// XTypeProvider -------------------------------------------------------------- + +Sequence< sal_Int8 > SAL_CALL AccessibleGridControlBase::getImplementationId() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslGlobalMutex() ); + static Sequence< sal_Int8 > aId; + implCreateUuid( aId ); + return aId; +} + +// XServiceInfo --------------------------------------------------------------- + +sal_Bool SAL_CALL AccessibleGridControlBase::supportsService( + const OUString& rServiceName ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + + Sequence< OUString > aSupportedServices( getSupportedServiceNames() ); + const OUString* pArrBegin = aSupportedServices.getConstArray(); + const OUString* pArrEnd = pArrBegin + aSupportedServices.getLength(); + const OUString* pString = pArrBegin; + + for( ; ( pString != pArrEnd ) && ( rServiceName != *pString ); ++pString ) + ; + return pString != pArrEnd; +} + +Sequence< OUString > SAL_CALL AccessibleGridControlBase::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) ); + return Sequence< OUString >( &aServiceName, 1 ); +} +// internal virtual methods --------------------------------------------------- + +sal_Bool AccessibleGridControlBase::implIsShowing() +{ + sal_Bool bShowing = sal_False; + if( m_xParent.is() ) + { + Reference< XAccessibleComponent > + xParentComp( m_xParent->getAccessibleContext(), uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = implGetBoundingBox().IsOver( + VCLRectangle( xParentComp->getBounds() ) ); + } + return bShowing; +} + +::utl::AccessibleStateSetHelper* AccessibleGridControlBase::implCreateStateSetHelper() +{ + ::utl::AccessibleStateSetHelper* + pStateSetHelper = new ::utl::AccessibleStateSetHelper; + + if( isAlive() ) + { + // SHOWING done with m_xParent + if( implIsShowing() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + // GridControl fills StateSet with states depending on object type + m_aTable.FillAccessibleStateSet( *pStateSetHelper, getType() ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + return pStateSetHelper; +} + +// internal helper methods ---------------------------------------------------- + +sal_Bool AccessibleGridControlBase::isAlive() const +{ + return !rBHelper.bDisposed && !rBHelper.bInDispose && &m_aTable; +} + +void AccessibleGridControlBase::ensureIsAlive() const + throw ( lang::DisposedException ) +{ + if( !isAlive() ) + throw lang::DisposedException(); +} + +Rectangle AccessibleGridControlBase::getBoundingBox() + throw ( lang::DisposedException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Rectangle aRect = implGetBoundingBox(); + if ( 0 == aRect.Left() && 0 == aRect.Top() && 0 == aRect.Right() && 0 == aRect.Bottom() ) + { + DBG_ERRORFILE( "rectangle doesn't exist" ); + } + return aRect; +} + +Rectangle AccessibleGridControlBase::getBoundingBoxOnScreen() + throw ( lang::DisposedException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Rectangle aRect = implGetBoundingBoxOnScreen(); + if ( 0 == aRect.Left() && 0 == aRect.Top() && 0 == aRect.Right() && 0 == aRect.Bottom() ) + { + DBG_ERRORFILE( "rectangle doesn't exist" ); + } + return aRect; +} + +void AccessibleGridControlBase::commitEvent( + sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue ) +{ + ::osl::ClearableMutexGuard aGuard( getOslMutex() ); + if ( !getClientId( ) ) + // if we don't have a client id for the notifier, then we don't have listeners, then + // we don't need to notify anything + return; + + // build an event object + AccessibleEventObject aEvent; + aEvent.Source = *this; + aEvent.EventId = _nEventId; + aEvent.OldValue = _rOldValue; + aEvent.NewValue = _rNewValue; + + // let the notifier handle this event + + AccessibleEventNotifier::addEvent( getClientId( ), aEvent ); +} +// ----------------------------------------------------------------------------- + +void AccessibleGridControlBase::implCreateUuid( Sequence< sal_Int8 >& rId ) +{ + if( !rId.hasElements() ) + { + rId.realloc( 16 ); + rtl_createUuid( reinterpret_cast< sal_uInt8* >( rId.getArray() ), 0, sal_True ); + } +} +// ----------------------------------------------------------------------------- +sal_Int16 SAL_CALL AccessibleGridControlBase::getAccessibleRole() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + sal_Int16 nRole = AccessibleRole::UNKNOWN; + switch ( m_eObjType ) + { + case TCTYPE_ROWHEADERCELL: + nRole = AccessibleRole::ROW_HEADER; + break; + case TCTYPE_COLUMNHEADERCELL: + nRole = AccessibleRole::COLUMN_HEADER; + break; + case TCTYPE_COLUMNHEADERBAR: + case TCTYPE_ROWHEADERBAR: + case TCTYPE_TABLE: + nRole = AccessibleRole::TABLE; + break; + case TCTYPE_TABLECELL: + nRole = AccessibleRole::TABLE_CELL; + break; + case TCTYPE_GRIDCONTROL: + nRole = AccessibleRole::PANEL; + break; + } + return nRole; +} +// ----------------------------------------------------------------------------- +Any SAL_CALL AccessibleGridControlBase::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + return Any(); +} +// ----------------------------------------------------------------------------- +Reference<XAccessible > SAL_CALL AccessibleGridControlBase::getAccessibleAtPoint( const ::com::sun::star::awt::Point& ) + throw ( uno::RuntimeException ) +{ + return NULL; +} +//// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL AccessibleGridControlBase::getForeground( ) throw (::com::sun::star::uno::RuntimeException) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + sal_Int32 nColor = 0; + Window* pInst = m_aTable.GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlForeground() ) + nColor = pInst->GetControlForeground().GetColor(); + else + { + Font aFont; + if ( pInst->IsControlFont() ) + aFont = pInst->GetControlFont(); + else + aFont = pInst->GetFont(); + nColor = aFont.GetColor().GetColor(); + } + } + return nColor; +} +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL AccessibleGridControlBase::getBackground( ) throw (::com::sun::star::uno::RuntimeException) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + sal_Int32 nColor = 0; + Window* pInst = m_aTable.GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlBackground() ) + nColor = pInst->GetControlBackground().GetColor(); + else + nColor = pInst->GetBackground().GetColor().GetColor(); + } + return nColor; +} + +//// ============================================================================ +GridControlAccessibleElement::GridControlAccessibleElement( const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable, + AccessibleTableControlObjType eObjType ) + :AccessibleGridControlBase( rxParent, rTable, eObjType ) +{ +} + +// XInterface ----------------------------------------------------------------- +IMPLEMENT_FORWARD_XINTERFACE2( GridControlAccessibleElement, AccessibleGridControlBase, GridControlAccessibleElement_Base) + +// XTypeProvider -------------------------------------------------------------- +IMPLEMENT_FORWARD_XTYPEPROVIDER2( GridControlAccessibleElement, AccessibleGridControlBase, GridControlAccessibleElement_Base ) + +// XAccessible ---------------------------------------------------------------- + +Reference< XAccessibleContext > SAL_CALL GridControlAccessibleElement::getAccessibleContext() throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return this; +} +// ---------------------------------------------------------------------------- +GridControlAccessibleElement::~GridControlAccessibleElement( ) +{ +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleGridControlHeader.cxx b/accessibility/source/extended/AccessibleGridControlHeader.cxx new file mode 100755 index 000000000000..1870eebc8e3e --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlHeader.cxx @@ -0,0 +1,284 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControlHeader.hxx" +#include "accessibility/extended/AccessibleGridControlHeaderCell.hxx" +#include "accessibility/extended/AccessibleGridControlTableCell.hxx" +#include <svtools/accessibletable.hxx> + + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; +using namespace ::svt::table; + +// ============================================================================ + +namespace accessibility { + +// ============================================================================ + +DBG_NAME( AccessibleGridControlHeader ) + +AccessibleGridControlHeader::AccessibleGridControlHeader( + const Reference< XAccessible >& rxParent, + ::svt::table::IAccessibleTable& rTable, + ::svt::table::AccessibleTableControlObjType eObjType): + AccessibleGridControlTableBase( rxParent, rTable, eObjType ) +{ + DBG_ASSERT( isRowBar() || isColumnBar(), + "accessibility/extended/AccessibleGridControlHeaderBar - invalid object type" ); +} + +AccessibleGridControlHeader::~AccessibleGridControlHeader() +{ +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlHeader::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + if (nChildIndex<0 || nChildIndex>=getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + ensureIsAlive(); + Reference< XAccessible > xChild; + if(m_eObjType == svt::table::TCTYPE_COLUMNHEADERBAR) + { + AccessibleGridControlHeaderCell* pColHeaderCell = new AccessibleGridControlHeaderCell(nChildIndex, this, m_aTable, svt::table::TCTYPE_COLUMNHEADERCELL); + xChild = pColHeaderCell; + } + else if(m_eObjType == svt::table::TCTYPE_ROWHEADERBAR) + { + AccessibleGridControlHeaderCell* pRowHeaderCell = new AccessibleGridControlHeaderCell(nChildIndex, this, m_aTable, svt::table::TCTYPE_ROWHEADERCELL); + xChild = pRowHeaderCell; + } + return xChild; +} + +sal_Int32 SAL_CALL AccessibleGridControlHeader::getAccessibleIndexInParent() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + if(m_eObjType == svt::table::TCTYPE_ROWHEADERBAR && m_aTable.HasColHeader()) + return 1; + else + return 0; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlHeader::getAccessibleAtPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + sal_Int32 nRow = 0; + sal_Int32 nColumnPos = 0; + sal_Bool bConverted = isRowBar() ? + m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) : + m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ); + + return bConverted ? implGetChild( nRow, nColumnPos ) : Reference< XAccessible >(); +} + +void SAL_CALL AccessibleGridControlHeader::grabFocus() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + // focus on header not supported +} + +Any SAL_CALL AccessibleGridControlHeader::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return Any(); // no special key bindings for header +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlHeader::getAccessibleRowDescription( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return OUString(); // no headers in headers +} + +OUString SAL_CALL AccessibleGridControlHeader::getAccessibleColumnDescription( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return OUString(); // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlHeader::getAccessibleRowHeaders() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlHeader::getAccessibleColumnHeaders() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // no headers in headers +} +//not selectable +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlHeader::getSelectedAccessibleRows() + throw ( uno::RuntimeException ) +{ + Sequence< sal_Int32 > aSelSeq(0); + return aSelSeq; +} +//columns aren't selectable +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlHeader::getSelectedAccessibleColumns() + throw ( uno::RuntimeException ) +{ + Sequence< sal_Int32 > aSelSeq(0); + return aSelSeq; +} +//row headers not selectable +sal_Bool SAL_CALL AccessibleGridControlHeader::isAccessibleRowSelected( sal_Int32 /*nRow*/ ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + return sal_False; +} +//columns aren't selectable +sal_Bool SAL_CALL AccessibleGridControlHeader::isAccessibleColumnSelected( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + (void)nColumn; + return sal_False; +} +//not implemented +Reference< XAccessible > SAL_CALL AccessibleGridControlHeader::getAccessibleCellAt( + sal_Int32 /*nRow*/, sal_Int32 /*nColumn*/ ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + return NULL; +} +// not selectable +sal_Bool SAL_CALL AccessibleGridControlHeader::isAccessibleSelected( + sal_Int32 /*nRow*/, sal_Int32 /*nColumn */) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + return sal_False; +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlHeader::getImplementationName() + throw ( uno::RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlHeader" ) ); +} + +Sequence< sal_Int8 > SAL_CALL AccessibleGridControlHeader::getImplementationId() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslGlobalMutex() ); + static Sequence< sal_Int8 > aId; + implCreateUuid( aId ); + return aId; +} + +// internal virtual methods --------------------------------------------------- + +Rectangle AccessibleGridControlHeader::implGetBoundingBox() +{ + return m_aTable.calcHeaderRect(isColumnBar()); +} + +Rectangle AccessibleGridControlHeader::implGetBoundingBoxOnScreen() +{ + return m_aTable.calcHeaderRect(isColumnBar()); +} + +sal_Int32 AccessibleGridControlHeader::implGetRowCount() const +{ + return 1; +} + +sal_Int32 AccessibleGridControlHeader::implGetColumnCount() const +{ + return 1; +} + +// internal helper methods ---------------------------------------------------- + +Reference< XAccessible > AccessibleGridControlHeader::implGetChild( + sal_Int32 nRow, sal_uInt32 nColumnPos ) +{ + Reference< XAccessible > xChild; + if(m_eObjType == svt::table::TCTYPE_COLUMNHEADERBAR) + { + AccessibleGridControlHeaderCell* pColHeaderCell = new AccessibleGridControlHeaderCell(nColumnPos, this, m_aTable, svt::table::TCTYPE_COLUMNHEADERCELL); + xChild = pColHeaderCell; + } + else if(m_eObjType == svt::table::TCTYPE_ROWHEADERBAR) + { + AccessibleGridControlHeaderCell* pRowHeaderCell = new AccessibleGridControlHeaderCell(nRow, this, m_aTable, svt::table::TCTYPE_ROWHEADERCELL); + xChild = pRowHeaderCell; + } + return xChild; +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx b/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx new file mode 100755 index 000000000000..485c57c40ae1 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControlHeaderCell.hxx" +#include <svtools/accessibletable.hxx> +#include "accessibility/extended/AccessibleGridControl.hxx" + +namespace accessibility +{ + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::uno; + using namespace ::svt; + using namespace ::svt::table; + +AccessibleGridControlHeaderCell::AccessibleGridControlHeaderCell(sal_Int32 _nColumnRowId, + const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable, + AccessibleTableControlObjType eObjType) +: AccessibleGridControlCell( rxParent, rTable, _nColumnRowId, 0, eObjType) +, m_nColumnRowId(_nColumnRowId) +{ +} +/** Creates a new AccessibleStateSetHelper and fills it with states of the + current object. + @return + A filled AccessibleStateSetHelper. +*/ +::utl::AccessibleStateSetHelper* AccessibleGridControlHeaderCell::implCreateStateSetHelper() +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ::utl::AccessibleStateSetHelper* + pStateSetHelper = new ::utl::AccessibleStateSetHelper; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + + TCSolarGuard aSolarGuard; + pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); + pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); + pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); + pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); + + if ( m_aTable.IsRowSelected(m_nColumnRowId) ) + pStateSetHelper->AddState( AccessibleStateType::SELECTED ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return pStateSetHelper; +} +// ----------------------------------------------------------------------------- +/** @return + The count of visible children. +*/ +sal_Int32 SAL_CALL AccessibleGridControlHeaderCell::getAccessibleChildCount() + throw ( RuntimeException ) +{ + return 0; +} +// ----------------------------------------------------------------------------- + +/** @return + The XAccessible interface of the specified child. +*/ +Reference<XAccessible > SAL_CALL AccessibleGridControlHeaderCell::getAccessibleChild( sal_Int32 ) + throw ( IndexOutOfBoundsException,RuntimeException ) +{ + throw IndexOutOfBoundsException(); +} +// XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + ::com::sun::star::uno::Any SAL_CALL AccessibleGridControlHeaderCell::queryInterface( + const ::com::sun::star::uno::Type& rType ) + throw ( ::com::sun::star::uno::RuntimeException ) + { + Any aRet = AccessibleGridControlCell::queryInterface(rType); + return aRet; + } + + /** Aquires the object (calls acquire() on base class). */ + void SAL_CALL AccessibleGridControlHeaderCell::acquire() throw () + { + AccessibleGridControlCell::acquire(); + } + + /** Releases the object (calls release() on base class). */ + void SAL_CALL AccessibleGridControlHeaderCell::release() throw () + { + AccessibleGridControlCell::release(); + } + /** @return The XAccessibleContext interface of this object. */ + Reference< com::sun::star::accessibility::XAccessibleContext > SAL_CALL AccessibleGridControlHeaderCell::getAccessibleContext() throw ( RuntimeException ) + { + ensureIsAlive(); + return this; + } + +// ----------------------------------------------------------------------------- + +/** Grabs the focus to the column header. */ +void SAL_CALL AccessibleGridControlHeaderCell::grabFocus() + throw ( ::com::sun::star::uno::RuntimeException ) +{ +} +// ----------------------------------------------------------------------------- +/** @return + The name of this class. +*/ +::rtl::OUString SAL_CALL AccessibleGridControlHeaderCell::getImplementationName() + throw ( ::com::sun::star::uno::RuntimeException ) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlHeaderCell" ) ); +} +// ----------------------------------------------------------------------------- +Rectangle AccessibleGridControlHeaderCell::implGetBoundingBox() +{ + return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle +} +// ----------------------------------------------------------------------------- + +Rectangle AccessibleGridControlHeaderCell::implGetBoundingBoxOnScreen() +{ + return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle +} +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL AccessibleGridControlHeaderCell::getAccessibleIndexInParent() + throw ( RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + sal_Int32 nIndex = m_nColumnRowId; + return nIndex; +} +// ----------------------------------------------------------------------------- +} // namespace accessibility +// ----------------------------------------------------------------------------- + + diff --git a/accessibility/source/extended/AccessibleGridControlTable.cxx b/accessibility/source/extended/AccessibleGridControlTable.cxx new file mode 100755 index 000000000000..406baeb2973c --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlTable.cxx @@ -0,0 +1,376 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControlTable.hxx" +#include "accessibility/extended/AccessibleGridControlTableCell.hxx" +#include <svtools/accessibletable.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; +using namespace ::svt::table; +// ============================================================================ + +namespace accessibility { + +// ============================================================================ + +DBG_NAME( AccessibleGridControlTable ) + +AccessibleGridControlTable::AccessibleGridControlTable( + const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable, + AccessibleTableControlObjType _eType) : + AccessibleGridControlTableBase( rxParent, rTable, _eType ) +{ +} + +AccessibleGridControlTable::~AccessibleGridControlTable() +{ +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlTable::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount(), TCTYPE_TABLECELL); +} + +sal_Int32 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + if(m_aTable.HasRowHeader() && m_aTable.HasColHeader()) + return 0; + else if((!m_aTable.HasRowHeader() && m_aTable.HasColHeader()) || (m_aTable.HasRowHeader() && !m_aTable.HasColHeader()) ) + return 1; + else + return 2; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint ) + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + Reference< XAccessible > xChild; + sal_Int32 nRow = 0; + sal_Int32 nColumnPos = 0; + if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) ) + xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos, TCTYPE_TABLECELL); + + return xChild; +} + +void SAL_CALL AccessibleGridControlTable::grabFocus() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + m_aTable.GrabFocus(); +} + +Any SAL_CALL AccessibleGridControlTable::getAccessibleKeyBinding() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return Any(); // no special key bindings for data table +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlTable::getAccessibleRowDescription( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return m_aTable.GetRowDescription( nRow ); +} + +OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return m_aTable.GetColumnDescription( (sal_uInt16)nColumn ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleRowHeaders() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + if(m_aTable.HasColHeader()) + return implGetHeaderBar( 1 ); + else + return implGetHeaderBar( 0 ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleColumnHeaders() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return implGetHeaderBar( 0 ); +} + +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleRows() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Sequence< sal_Int32 > aSelSeq; + implGetSelectedRows( aSelSeq ); + return aSelSeq; +} + +//columns aren't selectable +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns() + throw ( uno::RuntimeException ) +{ + Sequence< sal_Int32 > aSelSeq(0); + return aSelSeq; +} + +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleRowSelected( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidRow( nRow ); + sal_Bool bSelected = sal_False; + Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); + for(int i=0; i<selectedRows.getLength(); i++) + { + if(nRow == selectedRows[i]) + { + bSelected = sal_True; + continue; + } + } + return bSelected; +} + +//columns aren't selectable +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleColumnSelected( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + (void) nColumn; + return sal_False; +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumn, TCTYPE_TABLECELL); +} + +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + (void) nColumn; + //selection of single cells not possible, so if row is selected, the cell will be selected too + return isAccessibleRowSelected(nRow); +} +void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + sal_Int32 nColumns = m_aTable.GetColumnCount(); + sal_Int32 nRow = (nChildIndex / nColumns); + m_aTable.SelectRow( nRow, sal_True ); +} +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleChildSelected( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + sal_Int32 nColumns = m_aTable.GetColumnCount(); + sal_Int32 nRow = (nChildIndex / nColumns); + return isAccessibleRowSelected(nRow); +} +void SAL_CALL AccessibleGridControlTable::clearAccessibleSelection() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + m_aTable.SelectAllRows( false ); +} +void SAL_CALL AccessibleGridControlTable::selectAllAccessibleChildren() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); + for(int i=0;i<m_aTable.GetRowCount();i++) + selectedRows[i]=i; +} +sal_Int32 SAL_CALL AccessibleGridControlTable::getSelectedAccessibleChildCount() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); + sal_Int32 nColumns = m_aTable.GetColumnCount(); + return selectedRows.getLength()*nColumns; +} +Reference< XAccessible > SAL_CALL +AccessibleGridControlTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + if(isAccessibleChildSelected(nSelectedChildIndex)) + return getAccessibleChild(nSelectedChildIndex); + else + return NULL; +} +//not implemented yet, because only row selection possible +void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild( + sal_Int32 nSelectedChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + (void)nSelectedChildIndex; +} +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType ) + throw ( uno::RuntimeException ) +{ + Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleGridControlTableImplHelper1::queryInterface( rType ); +} + +void SAL_CALL AccessibleGridControlTable::acquire() throw () +{ + AccessibleGridControlTableBase::acquire(); +} + +void SAL_CALL AccessibleGridControlTable::release() throw () +{ + AccessibleGridControlTableBase::release(); +} +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlTable::getImplementationName() + throw ( uno::RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTable" ) ); +} + +// internal virtual methods --------------------------------------------------- + +Rectangle AccessibleGridControlTable::implGetBoundingBox() +{ + return m_aTable.calcTableRect(); +} + +Rectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen() +{ + return m_aTable.calcTableRect(); +} +// internal helper methods ---------------------------------------------------- +Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar( + sal_Int32 nChildIndex ) + throw ( uno::RuntimeException ) +{ + Reference< XAccessible > xRet; + Reference< XAccessibleContext > xContext( m_xParent, uno::UNO_QUERY ); + if( xContext.is() ) + { + try + { + xRet = xContext->getAccessibleChild( nChildIndex ); + } + catch( lang::IndexOutOfBoundsException& ) + { + DBG_ERROR( "implGetHeaderBar - wrong child index" ); + } + // RuntimeException goes to caller + } + return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY ); +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleGridControlTableBase.cxx b/accessibility/source/extended/AccessibleGridControlTableBase.cxx new file mode 100644 index 000000000000..d97feb1277ec --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlTableBase.cxx @@ -0,0 +1,291 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControlTableBase.hxx" +#include <svtools/accessibletable.hxx> +#include <tools/multisel.hxx> +#include <comphelper/sequence.hxx> + +// ============================================================================ + +using ::rtl::OUString; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::svt; +using namespace ::svt::table; + +// ============================================================================ + +namespace accessibility { + +// ============================================================================ + +DBG_NAME( AccessibleGridControlTableBase ) + +AccessibleGridControlTableBase::AccessibleGridControlTableBase( + const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable, + AccessibleTableControlObjType eObjType ) : + GridControlAccessibleElement( rxParent, rTable, eObjType ) +{ +} + +AccessibleGridControlTableBase::~AccessibleGridControlTableBase() +{ +} + +// XAccessibleContext --------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleChildCount() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + sal_Int32 nChildren = 0; + if(m_eObjType == TCTYPE_ROWHEADERBAR) + nChildren = m_aTable.GetRowCount(); + else if(m_eObjType == TCTYPE_TABLE) + nChildren = m_aTable.GetRowCount()*m_aTable.GetColumnCount(); + else if(m_eObjType == TCTYPE_COLUMNHEADERBAR) + nChildren = m_aTable.GetColumnCount(); + return nChildren; +} + +sal_Int16 SAL_CALL AccessibleGridControlTableBase::getAccessibleRole() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return AccessibleRole::TABLE; +} + +// XAccessibleTable ----------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleRowCount() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return m_aTable.GetRowCount(); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleColumnCount() + throw ( uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + return m_aTable.GetColumnCount(); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleRowExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleColumnExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlTableBase::getAccessibleCaption() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // not supported +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlTableBase::getAccessibleSummary() + throw ( uno::RuntimeException ) +{ + ensureIsAlive(); + return NULL; // not supported +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleIndex( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return implGetChildIndex( nRow, nColumn ); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleRow( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetRow( nChildIndex ); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleColumn( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) +{ + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetColumn( nChildIndex ); +} + +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleGridControlTableBase::queryInterface( const uno::Type& rType ) + throw ( uno::RuntimeException ) +{ + Any aAny( GridControlAccessibleElement::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleGridControlTableImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleGridControlTableBase::acquire() throw () +{ + GridControlAccessibleElement::acquire(); +} + +void SAL_CALL AccessibleGridControlTableBase::release() throw () +{ + GridControlAccessibleElement::release(); +} + +// XTypeProvider -------------------------------------------------------------- + +Sequence< uno::Type > SAL_CALL AccessibleGridControlTableBase::getTypes() + throw ( uno::RuntimeException ) +{ + return ::comphelper::concatSequences( + GridControlAccessibleElement::getTypes(), + AccessibleGridControlTableImplHelper::getTypes() ); +} + +Sequence< sal_Int8 > SAL_CALL AccessibleGridControlTableBase::getImplementationId() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( getOslGlobalMutex() ); + static Sequence< sal_Int8 > aId; + implCreateUuid( aId ); + return aId; +} + +// internal helper methods ---------------------------------------------------- + +sal_Int32 AccessibleGridControlTableBase::implGetChildCount() const +{ + return m_aTable.GetRowCount()*m_aTable.GetColumnCount(); +} + +sal_Int32 AccessibleGridControlTableBase::implGetRow( sal_Int32 nChildIndex ) const +{ + sal_Int32 nColumns = m_aTable.GetColumnCount(); + return nColumns ? (nChildIndex / nColumns) : 0; +} + +sal_Int32 AccessibleGridControlTableBase::implGetColumn( sal_Int32 nChildIndex ) const +{ + sal_Int32 nColumns = m_aTable.GetColumnCount(); + return nColumns ? (nChildIndex % nColumns) : 0; +} + +sal_Int32 AccessibleGridControlTableBase::implGetChildIndex( + sal_Int32 nRow, sal_Int32 nColumn ) const +{ + return nRow * m_aTable.GetColumnCount() + nColumn; +} + +void AccessibleGridControlTableBase::implGetSelectedRows( Sequence< sal_Int32 >& rSeq ) +{ + sal_Int32 const selectionCount( m_aTable.GetSelectedRowCount() ); + rSeq.realloc( selectionCount ); + for ( sal_Int32 i=0; i<selectionCount; ++i ) + rSeq[i] = m_aTable.GetSelectedRowIndex(i); +} + +void AccessibleGridControlTableBase::ensureIsValidRow( sal_Int32 nRow ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( nRow >= m_aTable.GetRowCount() ) + throw lang::IndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "row index is invalid" ) ), *this ); +} + +void AccessibleGridControlTableBase::ensureIsValidColumn( sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( nColumn >= m_aTable.GetColumnCount() ) + throw lang::IndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("column index is invalid") ), *this ); +} + +void AccessibleGridControlTableBase::ensureIsValidAddress( + sal_Int32 nRow, sal_Int32 nColumn ) + throw ( lang::IndexOutOfBoundsException ) +{ + ensureIsValidRow( nRow ); + ensureIsValidColumn( nColumn ); +} + +void AccessibleGridControlTableBase::ensureIsValidIndex( sal_Int32 nChildIndex ) + throw ( lang::IndexOutOfBoundsException ) +{ + if( nChildIndex >= implGetChildCount() ) + throw lang::IndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("child index is invalid") ), *this ); +} + +// ============================================================================ + +} // namespace accessibility + +// ============================================================================ + diff --git a/accessibility/source/extended/AccessibleGridControlTableCell.cxx b/accessibility/source/extended/AccessibleGridControlTableCell.cxx new file mode 100755 index 000000000000..43b9400e9050 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlTableCell.cxx @@ -0,0 +1,370 @@ +/************************************************************************* + * + * 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/extended/AccessibleGridControlTableCell.hxx" +#include <svtools/accessibletable.hxx> +#include "accessibility/extended/AccessibleGridControl.hxx" +#include <tools/gen.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> + +namespace accessibility +{ + namespace + { + void checkIndex_Impl( sal_Int32 _nIndex, const ::rtl::OUString& _sText ) throw (::com::sun::star::lang::IndexOutOfBoundsException) + { + if ( _nIndex >= _sText.getLength() ) + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } + + sal_Int32 getIndex_Impl( sal_Int32 _nRow, sal_uInt16 _nColumn, sal_uInt16 _nColumnCount ) + { + return _nRow * _nColumnCount + _nColumn; + } + } + using namespace ::com::sun::star::lang; + using namespace utl; + using namespace comphelper; + using ::rtl::OUString; + using ::accessibility::AccessibleGridControl; + using namespace ::com::sun::star::uno; + using ::com::sun::star::accessibility::XAccessible; + using namespace ::com::sun::star::accessibility; + using namespace ::svt; + using namespace ::svt::table; + + + // ============================================================================= + // = AccessibleGridControlCell + // ============================================================================= + // ----------------------------------------------------------------------------- + AccessibleGridControlCell::AccessibleGridControlCell( + const Reference< XAccessible >& _rxParent, IAccessibleTable& _rTable, + sal_Int32 _nRowPos, sal_uInt16 _nColPos, AccessibleTableControlObjType _eType ) + :AccessibleGridControlBase( _rxParent, _rTable, _eType ) + ,m_nRowPos( _nRowPos ) + ,m_nColPos( _nColPos ) + { + // set accessible name here, because for that we need the position of the cell + // and so the base class isn't capable of doing this + ::rtl::OUString aAccName; + if(_eType == TCTYPE_TABLECELL) + aAccName = _rTable.GetAccessibleObjectName( TCTYPE_TABLECELL, _nRowPos, _nColPos ); + else if(_eType == TCTYPE_ROWHEADERCELL) + aAccName = _rTable.GetAccessibleObjectName( TCTYPE_ROWHEADERCELL, _nRowPos, 0 ); + else if(_eType == TCTYPE_COLUMNHEADERCELL) + aAccName = _rTable.GetAccessibleObjectName( TCTYPE_COLUMNHEADERCELL, 0, _nRowPos ); + implSetName( aAccName ); + } + + // ----------------------------------------------------------------------------- + AccessibleGridControlCell::~AccessibleGridControlCell() + { + } + + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleGridControlCell::grabFocus() throw ( RuntimeException ) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + m_aTable.GoToCell( m_nColPos, m_nRowPos ); + } + //// ----------------------------------------------------------------------------- + // implementation of a table cell + ::rtl::OUString AccessibleGridControlTableCell::implGetText() + { + ensureIsAlive(); + return m_aTable.GetAccessibleCellText( getRowPos(), getColumnPos() ); + } + + ::com::sun::star::lang::Locale AccessibleGridControlTableCell::implGetLocale() + { + ensureIsAlive(); + return m_aTable.GetAccessible()->getAccessibleContext()->getLocale(); + } + + void AccessibleGridControlTableCell::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + + AccessibleGridControlTableCell::AccessibleGridControlTableCell(const Reference<XAccessible >& _rxParent, + IAccessibleTable& _rTable, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + AccessibleTableControlObjType eObjType) + :AccessibleGridControlCell( _rxParent, _rTable, _nRowPos, _nColPos, eObjType ) + { + } + + // XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + ::com::sun::star::uno::Any SAL_CALL AccessibleGridControlTableCell::queryInterface( + const ::com::sun::star::uno::Type& rType ) + throw ( ::com::sun::star::uno::RuntimeException ) + { + Any aRet = AccessibleGridControlCell::queryInterface(rType); + if ( !aRet.hasValue() ) + aRet = AccessibleTextHelper_BASE::queryInterface(rType); + return aRet; + } + + /** Aquires the object (calls acquire() on base class). */ + void SAL_CALL AccessibleGridControlTableCell::acquire() throw () + { + AccessibleGridControlCell::acquire(); + } + + /** Releases the object (calls release() on base class). */ + void SAL_CALL AccessibleGridControlTableCell::release() throw () + { + AccessibleGridControlCell::release(); + } + + ::com::sun::star::awt::Rectangle SAL_CALL AccessibleGridControlTableCell::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + ::com::sun::star::awt::Rectangle aRect; + + if ( &m_aTable ) + aRect = AWTRectangle( m_aTable.GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) ); + return aRect; + } + + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getIndexAtPoint( const ::com::sun::star::awt::Point& _aPoint ) throw (RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + return m_aTable.GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) ); + } + + /** @return + The name of this class. + */ + ::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getImplementationName() + throw ( ::com::sun::star::uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTableCell" ) ); + } + + /** @return The count of visible children. */ + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleChildCount() + throw ( ::com::sun::star::uno::RuntimeException ) + { + return 0; + } + + /** @return The XAccessible interface of the specified child. */ + ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > SAL_CALL + AccessibleGridControlTableCell::getAccessibleChild( sal_Int32 ) + throw ( ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException ) + { + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } + + /** Creates a new AccessibleStateSetHelper and fills it with states of the + current object. + @return + A filled AccessibleStateSetHelper. + */ + ::utl::AccessibleStateSetHelper* AccessibleGridControlTableCell::implCreateStateSetHelper() + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ::utl::AccessibleStateSetHelper* pStateSetHelper = new ::utl::AccessibleStateSetHelper; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + + m_aTable.FillAccessibleStateSetForCell( *pStateSetHelper, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return pStateSetHelper; + } + + + // XAccessible ------------------------------------------------------------ + + /** @return The XAccessibleContext interface of this object. */ + Reference< XAccessibleContext > SAL_CALL AccessibleGridControlTableCell::getAccessibleContext() throw ( RuntimeException ) + { + ensureIsAlive(); + return this; + } + + // XAccessibleContext ----------------------------------------------------- + + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleIndexInParent() + throw ( ::com::sun::star::uno::RuntimeException ) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + return ( getRowPos() * m_aTable.GetColumnCount() ) + getColumnPos(); + } + + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException) + { + return -1; + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + sal_Unicode SAL_CALL AccessibleGridControlTableCell::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getCharacter( nIndex ); + } + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleGridControlTableCell::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ::rtl::OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getCharacterCount( ); + } + + ::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getSelectedText( ); + } + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getSelectionStart( ); + } + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getSelectionEnd( ); + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + ::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getText( ) throw (::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getText( ); + } + ::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex ); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + TCSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ::rtl::OUString sText = implGetText(); + checkIndex_Impl( nStartIndex, sText ); + checkIndex_Impl( nEndIndex, sText ); + + //!!! don't know how to put a string into the clipboard + return sal_False; + } + + Rectangle AccessibleGridControlTableCell::implGetBoundingBox() + { + return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleGridControlTableCell::implGetBoundingBoxOnScreen() + { + return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle + } +} diff --git a/accessibility/source/extended/AccessibleToolPanelDeck.cxx b/accessibility/source/extended/AccessibleToolPanelDeck.cxx new file mode 100755 index 000000000000..6976b221a8b5 --- /dev/null +++ b/accessibility/source/extended/AccessibleToolPanelDeck.cxx @@ -0,0 +1,412 @@ +/************************************************************************* + * 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. + * + ************************************************************************/ + +#include "precompiled_accessibility.hxx" + +#include "accessibility/extended/AccessibleToolPanelDeck.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +#include <svtools/toolpanel/toolpaneldeck.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <tools/diagnose_ex.h> + +#include <boost/noncopyable.hpp> +#include <vector> + +//...................................................................................................................... +namespace accessibility +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::accessibility::XAccessible; + using ::com::sun::star::accessibility::XAccessibleContext; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::lang::IndexOutOfBoundsException; + using ::com::sun::star::lang::Locale; + using ::com::sun::star::accessibility::XAccessibleRelationSet; + using ::com::sun::star::accessibility::XAccessibleStateSet; + using ::com::sun::star::accessibility::IllegalAccessibleComponentStateException; + using ::com::sun::star::awt::XFont; + /** === end UNO using === **/ + namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole; + namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; + namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType; + + typedef ::com::sun::star::awt::Rectangle UnoRectangle; + typedef ::com::sun::star::awt::Point UnoPoint; + + //================================================================================================================== + //= AccessibleToolPanelDeck_Impl - declaration + //================================================================================================================== + class AccessibleToolPanelDeck_Impl :public ::boost::noncopyable + ,public ::svt::IToolPanelDeckListener + { + public: + AccessibleToolPanelDeck_Impl( + AccessibleToolPanelDeck& i_rAntiImpl, + const Reference< XAccessible >& i_rAccessibleParent, + ::svt::ToolPanelDeck& i_rPanelDeck + ); + + void checkDisposed(); + bool isDisposed() const { return m_pPanelDeck == NULL; } + void dispose(); + + ~AccessibleToolPanelDeck_Impl(); + + Reference< XAccessible > getOwnAccessible() const; + Reference< XAccessible > getActivePanelAccessible(); + + protected: + // IToolPanelDeckListener + virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual void PanelRemoved( const size_t i_nPosition ); + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ); + virtual void Dying(); + + public: + AccessibleToolPanelDeck& m_rAntiImpl; + Reference< XAccessible > m_xAccessibleParent; + ::svt::ToolPanelDeck* m_pPanelDeck; + + typedef ::std::vector< Reference< XAccessible > > AccessibleChildren; + Reference< XAccessible > m_xActivePanelAccessible; + }; + + //================================================================================================================== + //= MethodGuard + //================================================================================================================== + namespace + { + class MethodGuard + { + public: + MethodGuard( AccessibleToolPanelDeck_Impl& i_rImpl ) + :m_aGuard( Application::GetSolarMutex() ) + { + i_rImpl.checkDisposed(); + } + ~MethodGuard() + { + } + + void clear() + { + m_aGuard.clear(); + } + + private: + ::vos::OClearableGuard m_aGuard; + }; + } + + //================================================================================================================== + //= AccessibleToolPanelDeck_Impl - implementation + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeck_Impl::AccessibleToolPanelDeck_Impl( AccessibleToolPanelDeck& i_rAntiImpl, const Reference< XAccessible >& i_rAccessibleParent, + ::svt::ToolPanelDeck& i_rPanelDeck ) + :m_rAntiImpl( i_rAntiImpl ) + ,m_xAccessibleParent( i_rAccessibleParent ) + ,m_pPanelDeck( &i_rPanelDeck ) + ,m_xActivePanelAccessible() + { + m_pPanelDeck->AddListener( *this ); + } + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeck_Impl::~AccessibleToolPanelDeck_Impl() + { + if ( !isDisposed() ) + dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::dispose() + { + ENSURE_OR_RETURN_VOID( !isDisposed(), "disposed twice" ); + m_pPanelDeck->RemoveListener( *this ); + m_pPanelDeck = NULL; + m_xAccessibleParent.clear(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::checkDisposed() + { + if ( isDisposed() ) + throw DisposedException( ::rtl::OUString(), *&m_rAntiImpl ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > AccessibleToolPanelDeck_Impl::getOwnAccessible() const + { + Reference< XAccessible > xOwnAccessible( static_cast< XAccessible* >( m_rAntiImpl.GetVCLXWindow() ) ); + OSL_ENSURE( xOwnAccessible->getAccessibleContext() == Reference< XAccessibleContext >( &m_rAntiImpl ), + "AccessibleToolPanelDeck_Impl::getOwnAccessible: could not retrieve proper XAccessible for /myself!" ); + return xOwnAccessible; + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > AccessibleToolPanelDeck_Impl::getActivePanelAccessible() + { + ENSURE_OR_RETURN( !isDisposed(), "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: already disposed!", NULL ); + + if ( !m_xActivePanelAccessible.is() ) + { + ::boost::optional< size_t > aActivePanel( m_pPanelDeck->GetActivePanel() ); + ENSURE_OR_RETURN( !!aActivePanel, "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: this should not be called without an active panel!", NULL ); + ::svt::PToolPanel pActivePanel( m_pPanelDeck->GetPanel( *aActivePanel ) ); + ENSURE_OR_RETURN( pActivePanel.get() != NULL, "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: no active panel!", NULL ); + m_xActivePanelAccessible = pActivePanel->CreatePanelAccessible( getOwnAccessible() ); + OSL_ENSURE( m_xActivePanelAccessible.is(), "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: illegal accessible returned by the panel!" ); + } + + return m_xActivePanelAccessible; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) + { + (void)i_pPanel; + (void)i_nPosition; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::PanelRemoved( const size_t i_nPosition ) + { + (void)i_nPosition; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) + { + if ( !!i_rOldActive ) + { + if ( !m_xActivePanelAccessible.is() ) + { + // again, this might in theory happen if the XAccessible for the active panel has never before been requested. + // In this case, just say that all our children are invalid, so they all must be re-requested. + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any() ); + } + else + { + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( m_xActivePanelAccessible ), Any() ); + } + } + + m_xActivePanelAccessible.clear(); + + if ( !!i_rNewActive ) + { + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny( getActivePanelAccessible() ) ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) + { + MethodGuard aGuard( *this ); + + (void)i_rNewLayouter; + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any() ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck_Impl::Dying() + { + // the tool panel deck is dying, so dispose ourself + m_rAntiImpl.dispose(); + } + + //================================================================================================================== + //= AccessibleToolPanelDeck + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeck::AccessibleToolPanelDeck( const Reference< XAccessible >& i_rAccessibleParent, + ::svt::ToolPanelDeck& i_rPanelDeck ) + :AccessibleToolPanelDeck_Base( i_rPanelDeck.GetWindowPeer() ) + ,m_pImpl( new AccessibleToolPanelDeck_Impl( *this, i_rAccessibleParent, i_rPanelDeck ) ) + { + } + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeck::~AccessibleToolPanelDeck() + { + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Int32 SAL_CALL AccessibleToolPanelDeck::getAccessibleChildCount( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + + sal_Int32 nChildCount( m_pImpl->m_pPanelDeck->GetLayouter()->GetAccessibleChildCount() ); + + ::boost::optional< size_t > aActivePanel( m_pImpl->m_pPanelDeck->GetActivePanel() ); + if ( !!aActivePanel ) + return ++nChildCount; + + return nChildCount; + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > SAL_CALL AccessibleToolPanelDeck::getAccessibleChild( sal_Int32 i_nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + + const sal_Int32 nChildCount( getAccessibleChildCount() ); + if ( ( i_nIndex < 0 ) || ( i_nIndex >= nChildCount ) ) + throw IndexOutOfBoundsException( ::rtl::OUString(), *this ); + + // first "n" children are provided by the layouter + const size_t nLayouterCount( m_pImpl->m_pPanelDeck->GetLayouter()->GetAccessibleChildCount() ); + if ( size_t( i_nIndex ) < nLayouterCount ) + return m_pImpl->m_pPanelDeck->GetLayouter()->GetAccessibleChild( + size_t( i_nIndex ), + m_pImpl->getOwnAccessible() + ); + + // the last child is the XAccessible of the active panel + return m_pImpl->getActivePanelAccessible(); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > SAL_CALL AccessibleToolPanelDeck::getAccessibleParent( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + const Reference< XAccessible > xParent = implGetForeignControlledParent(); + if ( xParent.is() ) + return xParent; + return m_pImpl->m_xAccessibleParent; + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Int16 SAL_CALL AccessibleToolPanelDeck::getAccessibleRole( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + return AccessibleRole::PANEL; + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > SAL_CALL AccessibleToolPanelDeck::getAccessibleAtPoint( const UnoPoint& i_rPoint ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + + const ::Point aRequestedPoint( VCLUnoHelper::ConvertToVCLPoint( i_rPoint ) ); + // check the panel window itself + const ::Window& rActivePanelAnchor( m_pImpl->m_pPanelDeck->GetPanelWindowAnchor() ); + const Rectangle aPanelAnchorArea( rActivePanelAnchor.GetPosPixel(), rActivePanelAnchor.GetOutputSizePixel() ); + if ( aPanelAnchorArea.IsInside( aRequestedPoint ) ) + // note that this assumes that the Window which actually implements the concrete panel covers + // the complete area of its "anchor" Window. But this is ensured by the ToolPanelDeck implementation. + return m_pImpl->getActivePanelAccessible(); + + // check the XAccessible instances provided by the layouter + try + { + const ::svt::PDeckLayouter pLayouter( m_pImpl->m_pPanelDeck->GetLayouter() ); + ENSURE_OR_THROW( pLayouter.get() != NULL, "invalid layouter" ); + + const size_t nLayouterChildren = pLayouter->GetAccessibleChildCount(); + for ( size_t i=0; i<nLayouterChildren; ++i ) + { + const Reference< XAccessible > xLayoutItemAccessible( pLayouter->GetAccessibleChild( i, m_pImpl->getOwnAccessible() ), UNO_SET_THROW ); + const Reference< XAccessibleComponent > xLayoutItemComponent( xLayoutItemAccessible->getAccessibleContext(), UNO_QUERY_THROW ); + const ::Rectangle aLayoutItemBounds( VCLUnoHelper::ConvertToVCLRect( xLayoutItemComponent->getBounds() ) ); + if ( aLayoutItemBounds.IsInside( aRequestedPoint ) ) + return xLayoutItemAccessible; + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL AccessibleToolPanelDeck::grabFocus( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + m_pImpl->m_pPanelDeck->GrabFocus(); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL AccessibleToolPanelDeck::disposing() + { + AccessibleToolPanelDeck_Base::disposing(); + m_pImpl->dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > AccessibleToolPanelDeck::GetChildAccessible( const VclWindowEvent& i_rVclWindowEvent ) + { + // don't let the base class generate any A11Y events from VclWindowEvent, we completely manage those + // A11Y events ourself + (void)i_rVclWindowEvent; + return NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeck::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet ) + { + AccessibleToolPanelDeck_Base::FillAccessibleStateSet( i_rStateSet ); + if ( m_pImpl->isDisposed() ) + { + i_rStateSet.AddState( AccessibleStateType::DEFUNC ); + } + else + { + i_rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + } + } + +//...................................................................................................................... +} // namespace accessibility +//...................................................................................................................... diff --git a/accessibility/source/extended/AccessibleToolPanelDeckTabBar.cxx b/accessibility/source/extended/AccessibleToolPanelDeckTabBar.cxx new file mode 100644 index 000000000000..7e97e3714172 --- /dev/null +++ b/accessibility/source/extended/AccessibleToolPanelDeckTabBar.cxx @@ -0,0 +1,459 @@ +/************************************************************************* + * 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. + * + ************************************************************************/ + +#include "precompiled_accessibility.hxx" + +#include "accessibility/extended/AccessibleToolPanelDeckTabBar.hxx" +#include "accessibility/extended/AccessibleToolPanelDeckTabBarItem.hxx" +#include "accessibility/helper/accresmgr.hxx" +#include "accessibility/helper/accessiblestrings.hrc" + +/** === begin UNO includes === **/ +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +#include <svtools/toolpanel/toolpaneldeck.hxx> +#include <svtools/toolpanel/paneltabbar.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/button.hxx> +#include <vos/mutex.hxx> +#include <tools/diagnose_ex.h> + +#include <vector> + +//...................................................................................................................... +namespace accessibility +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::accessibility::XAccessible; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::lang::IndexOutOfBoundsException; + using ::com::sun::star::accessibility::XAccessibleContext; + /** === end UNO using === **/ + + namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole; + namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; + namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType; + + typedef ::com::sun::star::awt::Point UnoPoint; + typedef ::com::sun::star::awt::Size UnoSize; + typedef ::com::sun::star::awt::Rectangle UnoRectangle; + + //================================================================================================================== + //= AccessibleWrapper + //================================================================================================================== + typedef ::cppu::WeakImplHelper1< XAccessible > AccessibleWrapper_Base; + class AccessibleWrapper : public AccessibleWrapper_Base + { + public: + AccessibleWrapper( const Reference< XAccessibleContext >& i_rContext ) + :m_xContext( i_rContext ) + { + } + + // XAccessible + virtual Reference< XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (RuntimeException) + { + return m_xContext; + } + + private: + const Reference< XAccessibleContext > m_xContext; + }; + + //================================================================================================================== + //= AccessibleToolPanelTabBar_Impl + //================================================================================================================== + class AccessibleToolPanelTabBar_Impl :public ::boost::noncopyable + ,public ::svt::IToolPanelDeckListener + { + public: + AccessibleToolPanelTabBar_Impl( + AccessibleToolPanelTabBar& i_rAntiImpl, + const Reference< XAccessible >& i_rAccessibleParent, + ::svt::IToolPanelDeck& i_rPanelDeck, + ::svt::PanelTabBar& i_rTabBar + ); + ~AccessibleToolPanelTabBar_Impl(); + + void checkDisposed(); + bool isDisposed() const { return m_pPanelDeck == NULL; } + void dispose(); + + ::svt::IToolPanelDeck* getPanelDeck() const { return m_pPanelDeck; } + ::svt::PanelTabBar* getTabBar() const { return m_pTabBar; } + const Reference< XAccessible >& getAccessibleParent() const { return m_xAccessibleParent; } + Reference< XAccessible > getAccessiblePanelItem( size_t i_nPosition ); + Reference< XAccessible > getOwnAccessible() const; + + protected: + // IToolPanelDeckListener + virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual void PanelRemoved( const size_t i_nPosition ); + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ); + virtual void Dying(); + + DECL_LINK( OnWindowEvent, const VclSimpleEvent* ); + + private: + AccessibleToolPanelTabBar& m_rAntiImpl; + Reference< XAccessible > m_xAccessibleParent; + ::svt::IToolPanelDeck* m_pPanelDeck; + ::svt::PanelTabBar* m_pTabBar; + ::std::vector< Reference< XAccessible > > m_aChildren; + }; + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelTabBar_Impl::AccessibleToolPanelTabBar_Impl( AccessibleToolPanelTabBar& i_rAntiImpl, + const Reference< XAccessible >& i_rAccessibleParent, ::svt::IToolPanelDeck& i_rPanelDeck, ::svt::PanelTabBar& i_rTabBar ) + :m_rAntiImpl( i_rAntiImpl ) + ,m_xAccessibleParent( i_rAccessibleParent ) + ,m_pPanelDeck( &i_rPanelDeck ) + ,m_pTabBar( &i_rTabBar ) + ,m_aChildren() + { + m_pPanelDeck->AddListener( *this ); + m_aChildren.resize( m_pPanelDeck->GetPanelCount() ); + + const String sAccessibleDescription( TK_RES_STRING( RID_STR_ACC_DESC_PANELDECL_TABBAR ) ); + i_rTabBar.SetAccessibleName( sAccessibleDescription ); + i_rTabBar.SetAccessibleDescription( sAccessibleDescription ); + + i_rTabBar.GetScrollButton( true ).AddEventListener( LINK( this, AccessibleToolPanelTabBar_Impl, OnWindowEvent ) ); + i_rTabBar.GetScrollButton( false ).AddEventListener( LINK( this, AccessibleToolPanelTabBar_Impl, OnWindowEvent ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::checkDisposed() + { + if ( isDisposed() ) + throw DisposedException( ::rtl::OUString(), *&m_rAntiImpl ); + } + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelTabBar_Impl::~AccessibleToolPanelTabBar_Impl() + { + if ( !isDisposed() ) + dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::dispose() + { + ENSURE_OR_RETURN_VOID( !isDisposed(), "disposed twice" ); + m_pPanelDeck->RemoveListener( *this ); + m_pPanelDeck = NULL; + + m_pTabBar->GetScrollButton( true ).RemoveEventListener( LINK( this, AccessibleToolPanelTabBar_Impl, OnWindowEvent ) ); + m_pTabBar->GetScrollButton( false ).RemoveEventListener( LINK( this, AccessibleToolPanelTabBar_Impl, OnWindowEvent ) ); + m_pTabBar = NULL; + + m_xAccessibleParent.clear(); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > AccessibleToolPanelTabBar_Impl::getAccessiblePanelItem( size_t i_nPosition ) + { + ENSURE_OR_RETURN( !isDisposed(), "AccessibleToolPanelTabBar_Impl::getAccessiblePanelItem: already disposed!", NULL ); + ENSURE_OR_RETURN( i_nPosition < m_aChildren.size(), "AccessibleToolPanelTabBar_Impl::getAccessiblePanelItem: invalid index!", NULL ); + + Reference< XAccessible >& rAccessibleChild( m_aChildren[ i_nPosition ] ); + if ( !rAccessibleChild.is() ) + { + ::rtl::Reference< AccessibleToolPanelDeckTabBarItem > pAccesibleItemContext( new AccessibleToolPanelDeckTabBarItem( + getOwnAccessible(), *m_pPanelDeck, *m_pTabBar, i_nPosition ) ); + rAccessibleChild.set( new AccessibleWrapper( pAccesibleItemContext.get() ) ); + pAccesibleItemContext->lateInit( rAccessibleChild ); + } + return rAccessibleChild; + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > AccessibleToolPanelTabBar_Impl::getOwnAccessible() const + { + Reference< XAccessible > xOwnAccessible( static_cast< XAccessible* >( m_rAntiImpl.GetVCLXWindow() ) ); + OSL_ENSURE( xOwnAccessible->getAccessibleContext() == Reference< XAccessibleContext >( &m_rAntiImpl ), + "AccessibleToolPanelTabBar_Impl::getOwnAccessible: could not retrieve proper XAccessible for /myself!" ); + return xOwnAccessible; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) + { + ENSURE_OR_RETURN_VOID( i_nPosition <= m_aChildren.size(), "AccessibleToolPanelTabBar_Impl::PanelInserted: illegal position (or invalid cache!)" ); + (void)i_pPanel; + m_aChildren.insert( m_aChildren.begin() + i_nPosition, NULL ); + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny( getAccessiblePanelItem( i_nPosition ) ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::PanelRemoved( const size_t i_nPosition ) + { + ENSURE_OR_RETURN_VOID( i_nPosition < m_aChildren.size(), "AccessibleToolPanelTabBar_Impl::PanelInserted: illegal position (or invalid cache!)" ); + + const Reference< XAccessible > xOldChild( getAccessiblePanelItem( i_nPosition ) ); + m_aChildren.erase( m_aChildren.begin() + i_nPosition ); + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( xOldChild ), Any() ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) + { + (void)i_rOldActive; + (void)i_rNewActive; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) + { + (void)i_rNewLayouter; + m_rAntiImpl.dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar_Impl::Dying() + { + m_rAntiImpl.dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + IMPL_LINK( AccessibleToolPanelTabBar_Impl, OnWindowEvent, const VclSimpleEvent*, i_pEvent ) + { + ENSURE_OR_RETURN( !isDisposed(), "AccessibleToolPanelTabBar_Impl::OnWindowEvent: already disposed!", 0L ); + + const VclWindowEvent* pWindowEvent( dynamic_cast< const VclWindowEvent* >( i_pEvent ) ); + if ( !pWindowEvent ) + return 0L; + + const bool bForwardButton = ( pWindowEvent->GetWindow() == &m_pTabBar->GetScrollButton( true ) ); + const bool bBackwardButton = ( pWindowEvent->GetWindow() == &m_pTabBar->GetScrollButton( false ) ); + ENSURE_OR_RETURN( bForwardButton || bBackwardButton, "AccessibleToolPanelTabBar_Impl::OnWindowEvent: where does this come from?", 0L ); + + const bool bShow = ( i_pEvent->GetId() == VCLEVENT_WINDOW_SHOW ); + const bool bHide = ( i_pEvent->GetId() == VCLEVENT_WINDOW_HIDE ); + if ( !bShow && !bHide ) + // not interested in events other than visibility changes + return 0L; + + const Reference< XAccessible > xButtonAccessible( m_pTabBar->GetScrollButton( bForwardButton ).GetAccessible() ); + const Any aOldChild( bHide ? xButtonAccessible : Reference< XAccessible >() ); + const Any aNewChild( bShow ? xButtonAccessible : Reference< XAccessible >() ); + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldChild, aNewChild ); + + return 1L; + } + + //================================================================================================================== + //= MethodGuard + //================================================================================================================== + namespace + { + class MethodGuard + { + public: + MethodGuard( AccessibleToolPanelTabBar_Impl& i_rImpl ) + :m_aGuard( Application::GetSolarMutex() ) + { + i_rImpl.checkDisposed(); + } + ~MethodGuard() + { + } + + void clear() + { + m_aGuard.clear(); + } + + private: + ::vos::OClearableGuard m_aGuard; + }; + } + + //================================================================================================================== + //= AccessibleToolPanelTabBar + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelTabBar::AccessibleToolPanelTabBar( const Reference< XAccessible >& i_rAccessibleParent, + ::svt::IToolPanelDeck& i_rPanelDeck, ::svt::PanelTabBar& i_rTabBar ) + :AccessibleToolPanelTabBar_Base( i_rTabBar.GetWindowPeer() ) + ,m_pImpl( new AccessibleToolPanelTabBar_Impl( *this, i_rAccessibleParent, i_rPanelDeck, i_rTabBar ) ) + { + } + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelTabBar::~AccessibleToolPanelTabBar() + { + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Int32 SAL_CALL AccessibleToolPanelTabBar::getAccessibleChildCount( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + + const bool bHasScrollBack = m_pImpl->getTabBar()->GetScrollButton( false ).IsVisible(); + const bool bHasScrollForward = m_pImpl->getTabBar()->GetScrollButton( true ).IsVisible(); + + return m_pImpl->getPanelDeck()->GetPanelCount() + + ( bHasScrollBack ? 1 : 0 ) + + ( bHasScrollForward ? 1 : 0 ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > SAL_CALL AccessibleToolPanelTabBar::getAccessibleChild( sal_Int32 i_nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + + const bool bHasScrollBack = m_pImpl->getTabBar()->GetScrollButton( false ).IsVisible(); + const bool bHasScrollForward = m_pImpl->getTabBar()->GetScrollButton( true ).IsVisible(); + + const bool bScrollBackRequested = ( bHasScrollBack && ( i_nIndex == 0 ) ); + const bool bScrollForwardRequested = ( bHasScrollForward && ( i_nIndex == getAccessibleChildCount() - 1 ) ); + OSL_ENSURE( !( bScrollBackRequested && bScrollForwardRequested ), "AccessibleToolPanelTabBar::getAccessibleChild: ouch!" ); + + if ( bScrollBackRequested || bScrollForwardRequested ) + { + Reference< XAccessible > xScrollButtonAccessible( m_pImpl->getTabBar()->GetScrollButton( bScrollForwardRequested ).GetAccessible() ); + ENSURE_OR_RETURN( xScrollButtonAccessible.is(), "AccessibleToolPanelTabBar::getAccessibleChild: invalid button accessible!", NULL ); + #if OSL_DEBUG_LEVEL > 0 + Reference< XAccessibleContext > xScrollButtonContext( xScrollButtonAccessible->getAccessibleContext() ); + ENSURE_OR_RETURN( xScrollButtonContext.is(), "AccessibleToolPanelTabBar::getAccessibleChild: invalid button accessible context!", xScrollButtonAccessible ); + OSL_ENSURE( xScrollButtonContext->getAccessibleParent() == m_pImpl->getOwnAccessible(), + "AccessibleToolPanelTabBar::getAccessibleChild: wrong parent at the button's accesible!" ); + #endif + return xScrollButtonAccessible; + } + + return m_pImpl->getAccessiblePanelItem( i_nIndex - ( bHasScrollBack ? 1 : 0 ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > SAL_CALL AccessibleToolPanelTabBar::getAccessibleParent( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + return m_pImpl->getAccessibleParent(); + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Int16 SAL_CALL AccessibleToolPanelTabBar::getAccessibleRole( ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + return AccessibleRole::PAGE_TAB_LIST; + } + + //------------------------------------------------------------------------------------------------------------------ + namespace + { + bool lcl_covers( const ::Window& i_rWindow, const ::Point& i_rPoint ) + { + const Rectangle aWindowBounds( i_rWindow.GetWindowExtentsRelative( i_rWindow.GetParent() ) ); + return aWindowBounds.IsInside( i_rPoint ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > SAL_CALL AccessibleToolPanelTabBar::getAccessibleAtPoint( const UnoPoint& i_rPoint ) throw (RuntimeException) + { + MethodGuard aGuard( *m_pImpl ); + + // check the tab items + const UnoPoint aOwnScreenPos( getLocationOnScreen() ); + const ::Point aRequestedScreenPoint( i_rPoint.X + aOwnScreenPos.X, i_rPoint.Y + aOwnScreenPos.Y ); + + for ( size_t i=0; i<m_pImpl->getPanelDeck()->GetPanelCount(); ++i ) + { + const ::Rectangle aItemScreenRect( m_pImpl->getTabBar()->GetItemScreenRect(i) ); + if ( aItemScreenRect.IsInside( aRequestedScreenPoint ) ) + return m_pImpl->getAccessiblePanelItem(i); + } + + // check the scroll buttons + const ::Point aRequestedClientPoint( VCLUnoHelper::ConvertToVCLPoint( i_rPoint ) ); + + const bool bHasScrollBack = m_pImpl->getTabBar()->GetScrollButton( false ).IsVisible(); + if ( bHasScrollBack && lcl_covers( m_pImpl->getTabBar()->GetScrollButton( false ), aRequestedClientPoint ) ) + return m_pImpl->getTabBar()->GetScrollButton( false ).GetAccessible(); + + const bool bHasScrollForward = m_pImpl->getTabBar()->GetScrollButton( true ).IsVisible(); + if ( bHasScrollForward && lcl_covers( m_pImpl->getTabBar()->GetScrollButton( true ), aRequestedClientPoint ) ) + return m_pImpl->getTabBar()->GetScrollButton( true ).GetAccessible(); + + // no hit + return NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL AccessibleToolPanelTabBar::disposing() + { + AccessibleToolPanelTabBar_Base::disposing(); + m_pImpl->dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessible > AccessibleToolPanelTabBar::GetChildAccessible( const VclWindowEvent& i_rVclWindowEvent ) + { + // don't let the base class generate any A11Y events from VclWindowEvent, we completely manage those + // A11Y events ourself + (void)i_rVclWindowEvent; + return NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelTabBar::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet ) + { + AccessibleToolPanelTabBar_Base::FillAccessibleStateSet( i_rStateSet ); + i_rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + + ENSURE_OR_RETURN_VOID( !m_pImpl->isDisposed(), "AccessibleToolPanelTabBar::FillAccessibleStateSet: already disposed!" ); + if ( m_pImpl->getTabBar()->IsVertical() ) + i_rStateSet.AddState( AccessibleStateType::VERTICAL ); + else + i_rStateSet.AddState( AccessibleStateType::HORIZONTAL ); + } + +//...................................................................................................................... +} // namespace accessibility +//...................................................................................................................... diff --git a/accessibility/source/extended/AccessibleToolPanelDeckTabBarItem.cxx b/accessibility/source/extended/AccessibleToolPanelDeckTabBarItem.cxx new file mode 100644 index 000000000000..0cdfd8480457 --- /dev/null +++ b/accessibility/source/extended/AccessibleToolPanelDeckTabBarItem.cxx @@ -0,0 +1,455 @@ +/************************************************************************* + * 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. + * + ************************************************************************/ + +#include "precompiled_accessibility.hxx" + +#include "accessibility/extended/AccessibleToolPanelDeckTabBarItem.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +#include <svtools/toolpanel/toolpaneldeck.hxx> +#include <svtools/toolpanel/paneltabbar.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> + +//...................................................................................................................... +namespace accessibility +{ +//...................................................................................................................... + + typedef ::com::sun::star::awt::Rectangle UnoRectangle; + typedef ::com::sun::star::awt::Point UnoPoint; + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::accessibility::XAccessible; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::lang::IndexOutOfBoundsException; + using ::com::sun::star::accessibility::XAccessibleRelationSet; + using ::com::sun::star::accessibility::XAccessibleStateSet; + using ::com::sun::star::accessibility::XAccessibleComponent; + using ::com::sun::star::accessibility::XAccessibleExtendedComponent; + using ::com::sun::star::awt::XFont; + /** === end UNO using === **/ + + namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole; + namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType; + namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; + + //================================================================================================================== + //= AccessibleToolPanelDeckTabBarItem_Impl + //================================================================================================================== + class AccessibleToolPanelDeckTabBarItem_Impl : public ::svt::IToolPanelDeckListener + { + public: + AccessibleToolPanelDeckTabBarItem_Impl( + AccessibleToolPanelDeckTabBarItem& i_rAntiImpl, + const Reference< XAccessible >& i_rAccessibleParent, + ::svt::IToolPanelDeck& i_rPanelDeck, + ::svt::PanelTabBar& i_rTabBar, + const size_t i_nItemPos + ); + ~AccessibleToolPanelDeckTabBarItem_Impl(); + + ::svt::PanelTabBar* getTabBar() const { return m_pTabBar; } + + // IToolPanelDeckListener + virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual void PanelRemoved( const size_t i_nPosition ); + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ); + virtual void Dying(); + + public: + bool isDisposed() const { return m_pPanelDeck == NULL; } + void checkDisposed() const; + void dispose(); + + const Reference< XAccessible >& + getAccessibleParent() const { return m_xAccessibleParent; } + size_t getItemPos() const { return m_nItemPos; } + + Reference< XAccessibleComponent > getParentAccessibleComponent() const; + ::svt::IToolPanelDeck* getPanelDeck() const { return m_pPanelDeck; } + ::rtl::OUString getPanelDisplayName(); + + private: + void impl_notifyBoundRectChanges(); + void impl_notifyStateChange( const sal_Int16 i_nLostState, const sal_Int16 i_nGainedState ); + + private: + AccessibleToolPanelDeckTabBarItem& m_rAntiImpl; + Reference< XAccessible > m_xAccessibleParent; + ::svt::IToolPanelDeck* m_pPanelDeck; + ::svt::PanelTabBar* m_pTabBar; + size_t m_nItemPos; + }; + + //================================================================================================================== + //= AccessibleToolPanelDeckTabBarItem_Impl + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeckTabBarItem_Impl::AccessibleToolPanelDeckTabBarItem_Impl( AccessibleToolPanelDeckTabBarItem& i_rAntiImpl, + const Reference< XAccessible >& i_rAccessibleParent, ::svt::IToolPanelDeck& i_rPanelDeck, ::svt::PanelTabBar& i_rTabBar, + const size_t i_nItemPos ) + :m_rAntiImpl( i_rAntiImpl ) + ,m_xAccessibleParent( i_rAccessibleParent ) + ,m_pPanelDeck( &i_rPanelDeck ) + ,m_pTabBar( &i_rTabBar ) + ,m_nItemPos( i_nItemPos ) + { + m_pPanelDeck->AddListener( *this ); + } + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeckTabBarItem_Impl::~AccessibleToolPanelDeckTabBarItem_Impl() + { + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::checkDisposed() const + { + if ( isDisposed() ) + throw DisposedException( ::rtl::OUString(), *&m_rAntiImpl ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::dispose() + { + ENSURE_OR_RETURN_VOID( !isDisposed(), "AccessibleToolPanelDeckTabBarItem_Impl::dispose: disposed twice!" ); + + m_xAccessibleParent.clear(); + m_pPanelDeck->RemoveListener( *this ); + m_pPanelDeck = NULL; + m_pTabBar = NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessibleComponent > AccessibleToolPanelDeckTabBarItem_Impl::getParentAccessibleComponent() const + { + Reference< XAccessible > xAccessibleParent( m_rAntiImpl.getAccessibleParent(), UNO_QUERY_THROW ); + return Reference< XAccessibleComponent >( xAccessibleParent->getAccessibleContext(), UNO_QUERY ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString AccessibleToolPanelDeckTabBarItem_Impl::getPanelDisplayName() + { + const ::svt::PToolPanel pPanel( m_pPanelDeck->GetPanel( getItemPos() ) ); + if ( pPanel.get() == NULL ) + throw DisposedException(); + return pPanel->GetDisplayName(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::impl_notifyBoundRectChanges() + { + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any() ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::impl_notifyStateChange( const sal_Int16 i_nLostState, const sal_Int16 i_nGainedState ) + { + m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, + i_nLostState > -1 ? makeAny( i_nLostState ) : Any(), + i_nGainedState > -1 ? makeAny( i_nGainedState ) : Any() + ); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) + { + (void)i_pPanel; + if ( i_nPosition <= m_nItemPos ) + ++m_nItemPos; + impl_notifyBoundRectChanges(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::PanelRemoved( const size_t i_nPosition ) + { + if ( i_nPosition == m_nItemPos ) + { + m_rAntiImpl.dispose(); + } + else if ( i_nPosition < m_nItemPos ) + { + --m_nItemPos; + impl_notifyBoundRectChanges(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) + { + if ( m_nItemPos == i_rOldActive ) + { + impl_notifyStateChange( AccessibleStateType::ACTIVE, -1 ); + impl_notifyStateChange( AccessibleStateType::SELECTED, -1 ); + } + else if ( m_nItemPos == i_rNewActive ) + { + impl_notifyStateChange( -1, AccessibleStateType::ACTIVE ); + impl_notifyStateChange( -1, AccessibleStateType::SELECTED ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) + { + (void)i_rNewLayouter; + // if the tool panel deck has a new layouter, then the old layouter, and thus all items it was + // responsible for, died. So do we. + dispose(); + } + + //------------------------------------------------------------------------------------------------------------------ + void AccessibleToolPanelDeckTabBarItem_Impl::Dying() + { + // if the tool panel deck is dying, then its layouter dies, so should we. + dispose(); + } + + //================================================================================================================== + //= ItemMethodGuard + //================================================================================================================== + class ItemMethodGuard + { + public: + ItemMethodGuard( AccessibleToolPanelDeckTabBarItem_Impl& i_rImpl ) + :m_aGuard( Application::GetSolarMutex() ) + { + i_rImpl.checkDisposed(); + } + ~ItemMethodGuard() + { + } + + void clear() + { + m_aGuard.clear(); + } + + private: + ::vos::OClearableGuard m_aGuard; + }; + + //================================================================================================================== + //= AccessibleToolPanelDeckTabBarItem + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeckTabBarItem::AccessibleToolPanelDeckTabBarItem( const Reference< XAccessible >& i_rAccessibleParent, + ::svt::IToolPanelDeck& i_rPanelDeck, ::svt::PanelTabBar& i_rTabBar, const size_t i_nItemPos ) + :m_pImpl( new AccessibleToolPanelDeckTabBarItem_Impl( *this, i_rAccessibleParent, i_rPanelDeck, i_rTabBar, i_nItemPos ) ) + { + } + + //------------------------------------------------------------------------------------------------------------------ + AccessibleToolPanelDeckTabBarItem::~AccessibleToolPanelDeckTabBarItem() + { + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleChildCount( ) throw (RuntimeException) + { + return 0; + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) + { + (void)i; + throw IndexOutOfBoundsException( ::rtl::OUString(), *this ); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleParent( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + return m_pImpl->getAccessibleParent(); + } + + //-------------------------------------------------------------------- + sal_Int16 SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleRole( ) throw (RuntimeException) + { + return AccessibleRole::PAGE_TAB; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleDescription( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + return m_pImpl->getPanelDisplayName(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleName( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + return m_pImpl->getPanelDisplayName(); + } + + //-------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleRelationSet( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper; + return pRelationSet; + } + + //-------------------------------------------------------------------- + Reference< XAccessibleStateSet > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleStateSet( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + + ::utl::AccessibleStateSetHelper* pStateSet( new ::utl::AccessibleStateSetHelper ); + pStateSet->AddState( AccessibleStateType::FOCUSABLE ); + pStateSet->AddState( AccessibleStateType::SELECTABLE ); + pStateSet->AddState( AccessibleStateType::ICONIFIED ); + + if ( m_pImpl->getItemPos() == m_pImpl->getPanelDeck()->GetActivePanel() ) + { + pStateSet->AddState( AccessibleStateType::ACTIVE ); + pStateSet->AddState( AccessibleStateType::SELECTED ); + } + + if ( m_pImpl->getItemPos() == m_pImpl->getTabBar()->GetFocusedPanelItem() ) + pStateSet->AddState( AccessibleStateType::FOCUSED ); + + if ( m_pImpl->getTabBar()->IsEnabled() ) + pStateSet->AddState( AccessibleStateType::ENABLED ); + + if ( m_pImpl->getTabBar()->IsVisible() ) + { + pStateSet->AddState( AccessibleStateType::SHOWING ); + pStateSet->AddState( AccessibleStateType::VISIBLE ); + } + + return pStateSet; + } + + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleAtPoint( const UnoPoint& i_rLocation ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + // we do not have children ... + (void)i_rLocation; + return NULL; + } + + //-------------------------------------------------------------------- + void SAL_CALL AccessibleToolPanelDeckTabBarItem::grabFocus( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + m_pImpl->getTabBar()->FocusPanelItem( m_pImpl->getItemPos() ); + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL AccessibleToolPanelDeckTabBarItem::getForeground( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + Reference< XAccessibleComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_SET_THROW ); + return xParentComponent->getForeground(); + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL AccessibleToolPanelDeckTabBarItem::getBackground( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + Reference< XAccessibleComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_SET_THROW ); + return xParentComponent->getBackground(); + } + + //-------------------------------------------------------------------- + Reference< XFont > SAL_CALL AccessibleToolPanelDeckTabBarItem::getFont( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + Reference< XAccessibleExtendedComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_QUERY_THROW ); + // TODO: strictly, this is not correct: The TabBar implementation of the TabLayouter might use + // a different font ... + return xParentComponent->getFont(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getTitledBorderText( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + // no support + return ::rtl::OUString(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getToolTipText( ) throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + return m_pImpl->getPanelDisplayName(); + } + + //-------------------------------------------------------------------- + UnoRectangle SAL_CALL AccessibleToolPanelDeckTabBarItem::implGetBounds() throw (RuntimeException) + { + ItemMethodGuard aGuard( *m_pImpl ); + + const ::Rectangle aItemScreenRect( m_pImpl->getTabBar()->GetItemScreenRect( m_pImpl->getItemPos() ) ); + + Reference< XAccessibleComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_SET_THROW ); + const UnoPoint aParentLocation( xParentComponent->getLocationOnScreen() ); + return UnoRectangle( + aItemScreenRect.Left() - aParentLocation.X, + aItemScreenRect.Top() - aParentLocation.Y, + aItemScreenRect.GetWidth(), + aItemScreenRect.GetHeight() + ); + } + + //-------------------------------------------------------------------- + void SAL_CALL AccessibleToolPanelDeckTabBarItem::disposing() + { + ItemMethodGuard aGuard( *m_pImpl ); + m_pImpl->dispose(); + } + +//...................................................................................................................... +} // namespace accessibility +//...................................................................................................................... diff --git a/accessibility/source/extended/accessiblebrowseboxcell.cxx b/accessibility/source/extended/accessiblebrowseboxcell.cxx new file mode 100644 index 000000000000..87e47d83c600 --- /dev/null +++ b/accessibility/source/extended/accessiblebrowseboxcell.cxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * 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/extended/accessiblebrowseboxcell.hxx" +#include <svtools/accessibletableprovider.hxx> + +// ................................................................................. +namespace accessibility +{ +// ................................................................................. + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::accessibility; + using namespace ::svt; + + // ============================================================================= + // = AccessibleBrowseBoxCell + // ============================================================================= + DBG_NAME( svt_AccessibleBrowseBoxCell ) + // ----------------------------------------------------------------------------- + AccessibleBrowseBoxCell::AccessibleBrowseBoxCell( + const Reference< XAccessible >& _rxParent, IAccessibleTableProvider& _rBrowseBox, + const Reference< XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, sal_uInt16 _nColPos, AccessibleBrowseBoxObjType _eType ) + :AccessibleBrowseBoxBase( _rxParent, _rBrowseBox, _xFocusWindow, _eType ) + ,m_nRowPos( _nRowPos ) + ,m_nColPos( _nColPos ) + { + DBG_CTOR( svt_AccessibleBrowseBoxCell, NULL ); + // set accessible name here, because for that we need the position of the cell + // and so the base class isn't capable of doing this + sal_Int32 nPos = _nRowPos * _rBrowseBox.GetColumnCount() + _nColPos; + ::rtl::OUString aAccName = _rBrowseBox.GetAccessibleObjectName( BBTYPE_TABLECELL, nPos ); + implSetName( aAccName ); + } + + // ----------------------------------------------------------------------------- + AccessibleBrowseBoxCell::~AccessibleBrowseBoxCell() + { + DBG_DTOR( svt_AccessibleBrowseBoxCell, NULL ); + } + + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleBrowseBoxCell::grabFocus() throw ( RuntimeException ) + { + SolarMethodGuard aGuard( *this ); + mpBrowseBox->GoToCell( m_nRowPos, m_nColPos ); + } + // ----------------------------------------------------------------------------- + ::Rectangle AccessibleBrowseBoxCell::implGetBoundingBox() + { + return mpBrowseBox->GetFieldRectPixelAbs( m_nRowPos, m_nColPos, sal_False, sal_False ); + } + + // ----------------------------------------------------------------------------- + ::Rectangle AccessibleBrowseBoxCell::implGetBoundingBoxOnScreen() + { + return mpBrowseBox->GetFieldRectPixelAbs( m_nRowPos, m_nColPos, sal_False ); + } + +// ................................................................................. +} // namespace accessibility +// ................................................................................. + + diff --git a/accessibility/source/extended/accessibleeditbrowseboxcell.cxx b/accessibility/source/extended/accessibleeditbrowseboxcell.cxx new file mode 100644 index 000000000000..5f5472d04050 --- /dev/null +++ b/accessibility/source/extended/accessibleeditbrowseboxcell.cxx @@ -0,0 +1,273 @@ +/************************************************************************* + * + * 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/extended/accessibleeditbrowseboxcell.hxx> +#include <svtools/editbrowsebox.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> + + +// ................................................................................. +namespace accessibility +{ +// ................................................................................. + + using namespace com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::awt; + using namespace ::comphelper; + using namespace ::svt; + + DBG_NAME( acc_EditBrowseBoxTableCell ) + // ----------------------------------------------------------------------------- + EditBrowseBoxTableCell::EditBrowseBoxTableCell( + const com::sun::star::uno::Reference< XAccessible >& _rxParent, + const com::sun::star::uno::Reference< XAccessible >& _rxOwningAccessible, + const com::sun::star::uno::Reference< XAccessibleContext >& _xControlChild, + IAccessibleTableProvider& _rBrowseBox, + const Reference< XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos) + :AccessibleBrowseBoxCell( _rxParent, _rBrowseBox, _xFocusWindow, _nRowPos, _nColPos ) + ,OAccessibleContextWrapperHelper( ::comphelper::getProcessServiceFactory(), rBHelper, _xControlChild, _rxOwningAccessible, _rxParent ) + { + DBG_CTOR( acc_EditBrowseBoxTableCell, NULL ); + + aggregateProxy( m_refCount, *this ); + } + + // ----------------------------------------------------------------------------- + EditBrowseBoxTableCell::~EditBrowseBoxTableCell() + { + if ( !rBHelper.bDisposed ) + { + acquire(); // to prevent duplicate dtor calls + dispose(); + } + + DBG_DTOR( acc_EditBrowseBoxTableCell, NULL ); + } + + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EditBrowseBoxTableCell::getImplementationName() throw ( ::com::sun::star::uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.TableCellProxy" ) ); + } + + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( EditBrowseBoxTableCell, AccessibleBrowseBoxCell, OAccessibleContextWrapperHelper ) + + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( EditBrowseBoxTableCell, AccessibleBrowseBoxCell, OAccessibleContextWrapperHelper ) + + // ----------------------------------------------------------------------------- + void EditBrowseBoxTableCell::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException) + { + commitEvent( _rEvent.EventId, _rEvent.NewValue, _rEvent.OldValue ); + } + + // XAccessibleComponent + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL EditBrowseBoxTableCell::getForeground( ) throw (RuntimeException) + { + SolarMethodGuard aGuard( *this ); + Reference< XAccessibleComponent > xAccComp( m_xInnerContext, UNO_QUERY ); + if ( xAccComp.is() ) + return xAccComp->getForeground(); + return 0; + } + + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL EditBrowseBoxTableCell::getBackground( ) throw (RuntimeException) + { + SolarMethodGuard aGuard( *this ); + Reference< XAccessibleComponent > xAccComp( m_xInnerContext, UNO_QUERY ); + if ( xAccComp.is() ) + return xAccComp->getBackground(); + return 0; + } + + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL EditBrowseBoxTableCell::getAccessibleParent( ) throw (RuntimeException) + { + return m_xParentAccessible; + } + + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EditBrowseBoxTableCell::getAccessibleDescription() throw ( RuntimeException ) + { + SolarMethodGuard aGuard( *this ); + return m_xInnerContext->getAccessibleDescription(); + } + + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EditBrowseBoxTableCell::getAccessibleName() throw ( RuntimeException ) + { + SolarMethodGuard aGuard( *this ); + + // TODO: localize this! + String sName = mpBrowseBox->GetColumnDescription( ::sal::static_int_cast< sal_uInt16 >( getColumnPos() ) ); + if ( 0 == sName.Len() ) + { + sName = String::CreateFromAscii( "Column " ); + sName += String::CreateFromInt32( getColumnPos( ) ); + } + + sName += String::CreateFromAscii( ", Row " ); + sName += String::CreateFromInt32( getRowPos( ) ); + + return ::rtl::OUString( sName ); + } + + // ----------------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL EditBrowseBoxTableCell::getAccessibleRelationSet() throw ( RuntimeException ) + { + SolarMethodGuard aGuard( *this ); + return OAccessibleContextWrapperHelper::getAccessibleRelationSet( ); + } + + // ----------------------------------------------------------------------------- + Reference<XAccessibleStateSet > SAL_CALL EditBrowseBoxTableCell::getAccessibleStateSet() throw ( RuntimeException ) + { + SolarMethodGuard aGuard( *this ); + return m_xInnerContext->getAccessibleStateSet(); + // TODO: shouldn't we add an ACTIVE here? Isn't the EditBrowseBoxTableCell always ACTIVE? + } + + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL EditBrowseBoxTableCell::getAccessibleChildCount( ) throw (RuntimeException) + { + SolarMethodGuard aGuard( *this ); + return OAccessibleContextWrapperHelper::getAccessibleChildCount(); + } + + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL EditBrowseBoxTableCell::getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, RuntimeException) + { + SolarMethodGuard aGuard( *this ); + return OAccessibleContextWrapperHelper::getAccessibleChild( i ); + } + + // ----------------------------------------------------------------------------- + sal_Int16 SAL_CALL EditBrowseBoxTableCell::getAccessibleRole() throw ( RuntimeException ) + { + SolarMethodGuard aGuard( *this ); + return m_xInnerContext->getAccessibleRole( ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL EditBrowseBoxTableCell::dispose() throw( RuntimeException ) + { + // simply disambiguate. Note that the OComponentHelper base in AccessibleBrowseBoxCell + // will call our "disposing()", which will call "dispose()" on the OAccessibleContextWrapperHelper + // so there is no need to do this here. + AccessibleBrowseBoxCell::dispose(); + } + // ----------------------------------------------------------------------------- + void SAL_CALL EditBrowseBoxTableCell::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + AccessibleBrowseBoxCell::disposing( _rSource ); + OAccessibleContextWrapperHelper::disposing( _rSource ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL EditBrowseBoxTableCell::disposing() + { + SolarMethodGuard aGuard( *this, false ); + OAccessibleContextWrapperHelper::dispose(); + // TODO: do we need to dispose our inner object? The base class does this, but is it a good idea? + AccessibleBrowseBoxCell::disposing(); + } + // ============================================================================= + // = EditBrowseBoxTableCell + // ============================================================================= + DBG_NAME( EditBrowseBoxTableCellAccess ) + // ----------------------------------------------------------------------------- + EditBrowseBoxTableCellAccess::EditBrowseBoxTableCellAccess( + const Reference< XAccessible >& _rxParent, const Reference< XAccessible > _rxControlAccessible, + const Reference< XWindow >& _rxFocusWindow, + IAccessibleTableProvider& _rBrowseBox, sal_Int32 _nRowPos, sal_uInt16 _nColPos ) + :EditBrowseBoxTableCellAccess_Base( m_aMutex ) + ,m_xParent( _rxParent ) + ,m_xControlAccessible( _rxControlAccessible ) + ,m_xFocusWindow( _rxFocusWindow ) + ,m_pBrowseBox( &_rBrowseBox ) + ,m_nRowPos( _nRowPos ) + ,m_nColPos( _nColPos ) + { + DBG_CTOR( EditBrowseBoxTableCellAccess, NULL ); + } + // ----------------------------------------------------------------------------- + EditBrowseBoxTableCellAccess::~EditBrowseBoxTableCellAccess( ) + { + DBG_DTOR( EditBrowseBoxTableCellAccess, NULL ); + } + //-------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL EditBrowseBoxTableCellAccess::getAccessibleContext( ) throw (RuntimeException) + { + if ( !m_pBrowseBox || !m_xControlAccessible.is() ) + throw DisposedException(); + Reference< XAccessibleContext > xMyContext( m_aContext ); + if ( !xMyContext.is() ) + { + Reference< XAccessibleContext > xInnerContext = m_xControlAccessible->getAccessibleContext(); + Reference< XAccessible > xMe( this ); + + xMyContext = new EditBrowseBoxTableCell( m_xParent, xMe, xInnerContext, *m_pBrowseBox, m_xFocusWindow, m_nRowPos, m_nColPos ); + m_aContext = xMyContext; + } + return xMyContext; + } + //-------------------------------------------------------------------- + void SAL_CALL EditBrowseBoxTableCellAccess::disposing() + { + // dispose our context, if it still alive + Reference< XComponent > xMyContext( (Reference< XAccessibleContext >)m_aContext, UNO_QUERY ); + if ( xMyContext.is() ) + { + try + { + xMyContext->dispose(); + } + catch( const Exception& e ) + { + (void)e; + OSL_ENSURE( false, "EditBrowseBoxTableCellAccess::disposing: caught an exception while disposing the context!" ); + } + } + + m_pBrowseBox = NULL; + m_xControlAccessible.clear(); + m_aContext = Reference< XAccessibleContext >( ); + // NO dispose of the inner object there: it is the XAccessible of an window, and disposing + // it would delete the respective VCL window + } +// ................................................................................. +} // namespace accessibility +// ................................................................................. diff --git a/accessibility/source/extended/accessibleiconchoicectrl.cxx b/accessibility/source/extended/accessibleiconchoicectrl.cxx new file mode 100644 index 000000000000..3a98169c620a --- /dev/null +++ b/accessibility/source/extended/accessibleiconchoicectrl.cxx @@ -0,0 +1,372 @@ +/************************************************************************* + * + * 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/extended/accessibleiconchoicectrl.hxx" +#include "accessibility/extended/accessibleiconchoicectrlentry.hxx" +#include <svtools/ivctrl.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblestatesethelper.hxx> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <cppuhelper/typeprovider.hxx> + +//........................................................................ +namespace accessibility +{ +//........................................................................ + + // class AccessibleIconChoiceCtrl ---------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + DBG_NAME(AccessibleIconChoiceCtrl) + + // ----------------------------------------------------------------------------- + // Ctor() and Dtor() + // ----------------------------------------------------------------------------- + AccessibleIconChoiceCtrl::AccessibleIconChoiceCtrl( SvtIconChoiceCtrl& _rIconCtrl, const Reference< XAccessible >& _xParent ) : + + VCLXAccessibleComponent( _rIconCtrl.GetWindowPeer() ), + m_xParent ( _xParent ) + { + DBG_CTOR( AccessibleIconChoiceCtrl, NULL ); + } + // ----------------------------------------------------------------------------- + AccessibleIconChoiceCtrl::~AccessibleIconChoiceCtrl() + { + DBG_DTOR( AccessibleIconChoiceCtrl, NULL ); + } + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2(AccessibleIconChoiceCtrl, VCLXAccessibleComponent, AccessibleIconChoiceCtrl_BASE) + IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleIconChoiceCtrl, VCLXAccessibleComponent, AccessibleIconChoiceCtrl_BASE) + // ----------------------------------------------------------------------------- + void AccessibleIconChoiceCtrl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + if ( isAlive() ) + { + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_LISTBOX_SELECT : + { + // First send an event that tells the listeners of a + // 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() ); + SvtIconChoiceCtrl* pCtrl = getCtrl(); + if ( pCtrl && pCtrl->HasFocus() ) + { + SvxIconChoiceCtrlEntry* pEntry = static_cast< SvxIconChoiceCtrlEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_uLong nPos = pCtrl->GetEntryListPos( pEntry ); + Reference< XAccessible > xChild = new AccessibleIconChoiceCtrlEntry( *pCtrl, nPos, this ); + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + } + } + break; + } + default: + VCLXAccessibleComponent::ProcessWindowChildEvent (rVclWindowEvent); + } + } + } + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrl::disposing() + { + ::osl::MutexGuard aGuard( m_aMutex ); + + m_xParent = NULL; + } + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrl::getImplementationName() throw (RuntimeException) + { + return getImplementationName_Static(); + } + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL AccessibleIconChoiceCtrl::getSupportedServiceNames() throw (RuntimeException) + { + return getSupportedServiceNames_Static(); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleIconChoiceCtrl::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); + const ::rtl::OUString* pSupported = aSupported.getConstArray(); + const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); + for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) + ; + + return pSupported != pEnd; + } + // ----------------------------------------------------------------------------- + // XServiceInfo - static methods + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > AccessibleIconChoiceCtrl::getSupportedServiceNames_Static(void) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aSupported(3); + aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); + aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); + aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleIconChoiceControl") ); + return aSupported; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleIconChoiceCtrl::getImplementationName_Static(void) throw (RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleIconChoiceControl") ); + } + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL AccessibleIconChoiceCtrl::getAccessibleContext( ) throw (RuntimeException) + { + ensureAlive(); + return this; + } + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleIconChoiceCtrl::getAccessibleChildCount( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + return getCtrl()->GetEntryCount(); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrl::getAccessibleChild( sal_Int32 i ) throw (RuntimeException, IndexOutOfBoundsException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + SvtIconChoiceCtrl* pCtrl = getCtrl(); + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry(i); + if ( !pEntry ) + throw RuntimeException(); + + return new AccessibleIconChoiceCtrlEntry( *pCtrl, i, this ); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrl::getAccessibleParent( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + ensureAlive(); + return m_xParent; + } + // ----------------------------------------------------------------------------- + sal_Int16 SAL_CALL AccessibleIconChoiceCtrl::getAccessibleRole( ) throw (RuntimeException) + { + return AccessibleRole::TREE; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrl::getAccessibleDescription( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + return getCtrl()->GetAccessibleDescription(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrl::getAccessibleName( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + ::rtl::OUString sName = getCtrl()->GetAccessibleName(); + if ( sName.getLength() == 0 ) + sName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IconChoiceControl" ) ); + return sName; + } + // ----------------------------------------------------------------------------- + // XAccessibleSelection + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrl::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + SvtIconChoiceCtrl* pCtrl = getCtrl(); + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + pCtrl->SetCursor( pEntry ); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleIconChoiceCtrl::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + SvtIconChoiceCtrl* pCtrl = getCtrl(); + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return ( pCtrl->GetCursor() == pEntry ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrl::clearAccessibleSelection( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + getCtrl()->SetNoSelection(); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrl::selectAllAccessibleChildren( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + sal_Int32 i, nCount = 0; + SvtIconChoiceCtrl* pCtrl = getCtrl(); + nCount = pCtrl->GetEntryCount(); + for ( i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pCtrl->GetCursor() != pEntry ) + pCtrl->SetCursor( pEntry ); + } + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleIconChoiceCtrl::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + sal_Int32 i, nSelCount = 0, nCount = 0; + SvtIconChoiceCtrl* pCtrl = getCtrl(); + nCount = pCtrl->GetEntryCount(); + for ( i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pCtrl->GetCursor() == pEntry ) + ++nSelCount; + } + + return nSelCount; + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrl::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int32 i, nSelCount = 0, nCount = 0; + SvtIconChoiceCtrl* pCtrl = getCtrl(); + nCount = pCtrl->GetEntryCount(); + for ( i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pCtrl->GetCursor() == pEntry ) + ++nSelCount; + + if ( nSelCount == ( nSelectedChildIndex + 1 ) ) + { + xChild = new AccessibleIconChoiceCtrlEntry( *pCtrl, i, this ); + break; + } + } + + return xChild; + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrl::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int32 i, nSelCount = 0, nCount = 0; + SvtIconChoiceCtrl* pCtrl = getCtrl(); + nCount = pCtrl->GetEntryCount(); + bool bFound = false; + for ( i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pEntry->IsSelected() ) + { + ++nSelCount; + if ( i == nSelectedChildIndex ) + bFound = true; + } + } + + // if only one entry is selected and its index is choosen to deselect -> no selection anymore + if ( 1 == nSelCount && bFound ) + pCtrl->SetNoSelection(); + } + // ----------------------------------------------------------------------------- + void AccessibleIconChoiceCtrl::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) + { + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + if ( isAlive() ) + { + rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); + rStateSet.AddState( AccessibleStateType::SELECTABLE ); + } + } + // ----------------------------------------------------------------------------- + SvtIconChoiceCtrl* AccessibleIconChoiceCtrl::getCtrl() + { + return static_cast<SvtIconChoiceCtrl*>(GetWindow()); + } + +//........................................................................ +}// namespace accessibility +//........................................................................ + diff --git a/accessibility/source/extended/accessibleiconchoicectrlentry.cxx b/accessibility/source/extended/accessibleiconchoicectrlentry.cxx new file mode 100644 index 000000000000..e910b503ad1c --- /dev/null +++ b/accessibility/source/extended/accessibleiconchoicectrlentry.cxx @@ -0,0 +1,756 @@ +/************************************************************************* + * + * 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/extended/accessibleiconchoicectrlentry.hxx> +#include <svtools/ivctrl.hxx> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <vcl/controllayout.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/convert.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/sequence.hxx> +#include <svtools/stringtransfer.hxx> +#include <comphelper/accessibleeventnotifier.hxx> + +#define ACCESSIBLE_ACTION_COUNT 1 +#define AID_EXPAND 0 +#define AID_COLLAPSE 1 + +namespace +{ + void checkActionIndex_Impl( sal_Int32 _nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException) + { + if ( _nIndex < 0 || _nIndex >= ACCESSIBLE_ACTION_COUNT ) + // only three actions + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } +} + +//........................................................................ +namespace accessibility +{ + //........................................................................ + // class ALBSolarGuard --------------------------------------------------------- + + /** Aquire the solar mutex. */ + class ALBSolarGuard : public ::vos::OGuard + { + public: + inline ALBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {} + }; + + // class AccessibleIconChoiceCtrlEntry ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + DBG_NAME(AccessibleIconChoiceCtrlEntry) + + // ----------------------------------------------------------------------------- + // Ctor() and Dtor() + // ----------------------------------------------------------------------------- + AccessibleIconChoiceCtrlEntry::AccessibleIconChoiceCtrlEntry( SvtIconChoiceCtrl& _rIconCtrl, + sal_uLong _nPos, + const Reference< XAccessible >& _xParent ) : + + AccessibleIconChoiceCtrlEntry_BASE ( m_aMutex ), + + m_pIconCtrl ( &_rIconCtrl ), + m_nIndex ( _nPos ), + m_nClientId ( 0 ), + m_xParent ( _xParent ) + + { + osl_incrementInterlockedCount( &m_refCount ); + { + Reference< XComponent > xComp( m_xParent, UNO_QUERY ); + if ( xComp.is() ) + xComp->addEventListener( this ); + } + osl_decrementInterlockedCount( &m_refCount ); + + DBG_CTOR( AccessibleIconChoiceCtrlEntry, NULL ); + } + // ----------------------------------------------------------------------------- + void AccessibleIconChoiceCtrlEntry::disposing( const EventObject& _rSource ) +throw(RuntimeException) + { + if ( _rSource.Source == m_xParent ) + { + dispose(); + DBG_ASSERT( !m_xParent.is() && ( NULL == m_pIconCtrl ), "" ); + } + } + // ----------------------------------------------------------------------------- + AccessibleIconChoiceCtrlEntry::~AccessibleIconChoiceCtrlEntry() + { + DBG_DTOR( AccessibleIconChoiceCtrlEntry, NULL ); + + if ( IsAlive_Impl() ) + { + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } + } + #ifdef ACCESSIBLE_EVENT_NOTIFICATION_ENABLED + // (the following method is unused currently. If you need it, simply remove the #ifdef thing here and + // in the hxx) + // ----------------------------------------------------------------------------- + void AccessibleIconChoiceCtrlEntry::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 ); + } + #endif + // ----------------------------------------------------------------------------- + Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBox_Impl() const + { + Rectangle aRect; + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry ) + aRect = m_pIconCtrl->GetBoundingBox( pEntry ); + + return aRect; + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen_Impl() const + { + Rectangle aRect; + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry ) + { + aRect = m_pIconCtrl->GetBoundingBox( pEntry ); + Point aTopLeft = aRect.TopLeft(); + aTopLeft += m_pIconCtrl->GetWindowExtentsRelative( NULL ).TopLeft(); + aRect = Rectangle( aTopLeft, aRect.GetSize() ); + } + + return aRect; + } + // ----------------------------------------------------------------------------- + sal_Bool AccessibleIconChoiceCtrlEntry::IsAlive_Impl() const + { + return ( !rBHelper.bDisposed && !rBHelper.bInDispose && m_pIconCtrl ); + } + // ----------------------------------------------------------------------------- + sal_Bool AccessibleIconChoiceCtrlEntry::IsShowing_Impl() const + { + sal_Bool bShowing = sal_False; + Reference< XAccessibleContext > m_xParentContext = + m_xParent.is() ? m_xParent->getAccessibleContext() : Reference< XAccessibleContext >(); + if( m_xParentContext.is() ) + { + Reference< XAccessibleComponent > xParentComp( m_xParentContext, uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = GetBoundingBox_Impl().IsOver( VCLRectangle( xParentComp->getBounds() ) ); + } + + return bShowing; + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBox() throw ( lang::DisposedException ) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBox_Impl(); + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen() throw ( lang::DisposedException ) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBoxOnScreen_Impl(); + } + // ----------------------------------------------------------------------------- + void AccessibleIconChoiceCtrlEntry::EnsureIsAlive() const throw ( lang::DisposedException ) + { + if ( !IsAlive_Impl() ) + throw lang::DisposedException(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleIconChoiceCtrlEntry::implGetText() + { + ::rtl::OUString sRet; + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry ) + sRet = pEntry->GetDisplayText(); + return sRet; + } + // ----------------------------------------------------------------------------- + Locale AccessibleIconChoiceCtrlEntry::implGetLocale() + { + Locale aLocale; + aLocale = Application::GetSettings().GetUILocale(); + + return aLocale; + } + void AccessibleIconChoiceCtrlEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + Sequence< sal_Int8 > AccessibleIconChoiceCtrlEntry::getImplementationId() throw (RuntimeException) + { + static ::cppu::OImplementationId* pId = NULL; + + if ( !pId ) + { + ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + + if ( !pId ) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); + } + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrlEntry::disposing() + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // Send a disposing to all listeners. + if ( m_nClientId ) + { + sal_uInt32 nId = m_nClientId; + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + Reference< XComponent > xComp( m_xParent, UNO_QUERY ); + if ( xComp.is() ) + xComp->removeEventListener( this ); + + m_pIconCtrl = NULL; + m_xParent = NULL; + } + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getImplementationName() throw(RuntimeException) + { + return getImplementationName_Static(); + } + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL AccessibleIconChoiceCtrlEntry::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_Static(); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); + const ::rtl::OUString* pSupported = aSupported.getConstArray(); + const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); + for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) + ; + + return pSupported != pEnd; + } + // ----------------------------------------------------------------------------- + // XServiceInfo - static methods + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > AccessibleIconChoiceCtrlEntry::getSupportedServiceNames_Static(void) throw( RuntimeException ) + { + Sequence< ::rtl::OUString > aSupported(3); + aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); + aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); + aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleIconChoiceControlEntry") ); + return aSupported; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleIconChoiceCtrlEntry::getImplementationName_Static(void) throw( RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleIconChoiceControlEntry") ); + } + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleContext( ) throw (RuntimeException) + { + EnsureIsAlive(); + return this; + } + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChildCount( ) throw (RuntimeException) + { + return 0; // no children + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException,RuntimeException) + { + throw IndexOutOfBoundsException(); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleParent( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return m_xParent; + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleIndexInParent( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return m_nIndex; + } + // ----------------------------------------------------------------------------- + sal_Int16 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRole( ) throw (RuntimeException) + { + return AccessibleRole::LABEL; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleDescription( ) throw (RuntimeException) + { + // no description for every item + return ::rtl::OUString(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleName( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return implGetText(); + } + // ----------------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRelationSet( ) throw (RuntimeException) + { + return new utl::AccessibleRelationSetHelper; + } + // ----------------------------------------------------------------------------- + Reference< XAccessibleStateSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleStateSet( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; + Reference< XAccessibleStateSet > xStateSet = pStateSetHelper; + + if ( IsAlive_Impl() ) + { + pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); + pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); + pStateSetHelper->AddState( AccessibleStateType::ENABLED ); + pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); + if ( IsShowing_Impl() ) + { + pStateSetHelper->AddState( AccessibleStateType::SHOWING ); + pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); + } + + if ( m_pIconCtrl && m_pIconCtrl->GetCursor() == m_pIconCtrl->GetEntry( m_nIndex ) ) + pStateSetHelper->AddState( AccessibleStateType::SELECTED ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return xStateSet; + } + // ----------------------------------------------------------------------------- + Locale SAL_CALL AccessibleIconChoiceCtrlEntry::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return implGetLocale(); + } + // ----------------------------------------------------------------------------- + // XAccessibleComponent + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::containsPoint( const awt::Point& rPoint ) throw (RuntimeException) + { + return Rectangle( Point(), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException) + { + return Reference< XAccessible >(); + } + // ----------------------------------------------------------------------------- + awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getBounds( ) throw (RuntimeException) + { + return AWTRectangle( GetBoundingBox() ); + } + // ----------------------------------------------------------------------------- + awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocation( ) throw (RuntimeException) + { + return AWTPoint( GetBoundingBox().TopLeft() ); + } + // ----------------------------------------------------------------------------- + awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocationOnScreen( ) throw (RuntimeException) + { + return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); + } + // ----------------------------------------------------------------------------- + awt::Size SAL_CALL AccessibleIconChoiceCtrlEntry::getSize( ) throw (RuntimeException) + { + return AWTSize( GetBoundingBox().GetSize() ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrlEntry::grabFocus( ) throw (RuntimeException) + { + // do nothing, because no focus for each item + } + // ----------------------------------------------------------------------------- + sal_Int32 AccessibleIconChoiceCtrlEntry::getForeground( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + // ----------------------------------------------------------------------------- + sal_Int32 AccessibleIconChoiceCtrlEntry::getBackground( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + // ----------------------------------------------------------------------------- + // XAccessibleText + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterBounds( sal_Int32 _nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( ( 0 > _nIndex ) || ( getCharacterCount() <= _nIndex ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( m_pIconCtrl ) + { + Rectangle aItemRect = GetBoundingBox_Impl(); + Rectangle aCharRect = m_pIconCtrl->GetEntryCharacterBounds( m_nIndex, _nIndex ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nIndex = -1; + if ( m_pIconCtrl ) + { + ::vcl::ControlLayoutData aLayoutData; + Rectangle aItemRect = GetBoundingBox_Impl(); + m_pIconCtrl->RecordLayoutData( &aLayoutData, aItemRect ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + nIndex = aLayoutData.GetIndexForPoint( aPnt ); + + long nLen = aLayoutData.m_aUnicodeBoundRects.size(); + for ( long i = 0; i < nLen; ++i ) + { + Rectangle aRect = aLayoutData.GetCharacterBounds(i); + sal_Bool bInside = aRect.IsInside( aPnt ); + + if ( bInside ) + break; + } + } + + return nIndex; + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + String sText = getText(); + if ( ( 0 > nStartIndex ) || ( sText.Len() <= nStartIndex ) + || ( 0 > nEndIndex ) || ( sText.Len() <= nEndIndex ) ) + throw IndexOutOfBoundsException(); + + sal_Int32 nLen = nEndIndex - nStartIndex + 1; + ::svt::OStringTransfer::CopyString( sText.Copy( (sal_uInt16)nStartIndex, (sal_uInt16)nLen ), m_pIconCtrl ); + + return sal_True; + } + // ----------------------------------------------------------------------------- + // XAccessibleEventBroadcaster + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrlEntry::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) + { + if (xListener.is()) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); + } + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleIconChoiceCtrlEntry::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) + { + if (xListener.is()) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + sal_Int32 nId = m_nClientId; + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClient( nId ); + } + } + } + + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException) + { + return -1; + } + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + sal_Unicode SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getCharacter( nIndex ); + } + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + ::rtl::OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getCharacterCount( ); + } + + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getSelectedText( ); + } + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getSelectionStart( ); + } + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getSelectionEnd( ); + } + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getText( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getText( ); + } + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex ); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + + // ----------------------------------------------------------------------------- + // XAccessibleAction + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionCount( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // three actions supported + return ACCESSIBLE_ACTION_COUNT; + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Bool bRet = sal_False; + checkActionIndex_Impl( nIndex ); + EnsureIsAlive(); + + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry && !pEntry->IsSelected() ) + { + m_pIconCtrl->SetNoSelection(); + m_pIconCtrl->SetCursor( pEntry ); + bRet = sal_True; + } + + return bRet; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + checkActionIndex_Impl( nIndex ); + EnsureIsAlive(); + + static const ::rtl::OUString sActionDesc( RTL_CONSTASCII_USTRINGPARAM( "Select" ) ); + return sActionDesc; + } + // ----------------------------------------------------------------------------- + Reference< XAccessibleKeyBinding > AccessibleIconChoiceCtrlEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Reference< XAccessibleKeyBinding > xRet; + checkActionIndex_Impl( nIndex ); + // ... which key? + return xRet; + } +//........................................................................ +}// namespace accessibility +//........................................................................ + diff --git a/accessibility/source/extended/accessiblelistbox.cxx b/accessibility/source/extended/accessiblelistbox.cxx new file mode 100644 index 000000000000..b95643670985 --- /dev/null +++ b/accessibility/source/extended/accessiblelistbox.cxx @@ -0,0 +1,432 @@ +/************************************************************************* + * + * 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/extended/accessiblelistbox.hxx> +#include <accessibility/extended/accessiblelistboxentry.hxx> +#include <svtools/svtreebx.hxx> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/convert.hxx> +#include <unotools/accessiblestatesethelper.hxx> + +//........................................................................ +namespace accessibility +{ +//........................................................................ + + // class AccessibleListBox ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + DBG_NAME(AccessibleListBox) + + // ----------------------------------------------------------------------------- + // Ctor() and Dtor() + // ----------------------------------------------------------------------------- + AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) : + + VCLXAccessibleComponent( _rListBox.GetWindowPeer() ), + m_xParent( _xParent ) + { + DBG_CTOR( AccessibleListBox, NULL ); + } + // ----------------------------------------------------------------------------- + AccessibleListBox::~AccessibleListBox() + { + DBG_DTOR( AccessibleListBox, NULL ); + if ( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } + } + IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE) + IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE) + // ----------------------------------------------------------------------------- + SvTreeListBox* AccessibleListBox::getListBox() const + { + return static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() ); + } + // ----------------------------------------------------------------------------- + void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + if ( isAlive() ) + { + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_CHECKBOX_TOGGLE : + { + if ( getListBox() && getListBox()->HasFocus() ) + { + SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); + if ( !pEntry ) + pEntry = getListBox()->GetCurEntry(); + + if ( pEntry ) + { + Reference< XAccessible > xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + } + } + break; + } + + case VCLEVENT_LISTBOX_SELECT : + { + // First send an event that tells the listeners of a + // 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() ) + { + SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( 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 ); + } + } + break; + + // --> OD 2009-04-01 #i92103# + case VCLEVENT_ITEM_EXPANDED : + case VCLEVENT_ITEM_COLLAPSED : + { + SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + AccessibleListBoxEntry* pAccListBoxEntry = + new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + Reference< XAccessible > xChild = pAccListBoxEntry; + const short nAccEvent = + ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED ) + ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED + : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED; + uno::Any aListBoxEntry; + aListBoxEntry <<= xChild; + NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry ); + if ( getListBox() && getListBox()->HasFocus() ) + { + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry ); + } + } + break; + } + // <-- + } + default: + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + } + } + } + // ----------------------------------------------------------------------------- + void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) + { + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_WINDOW_SHOW: + case VCLEVENT_WINDOW_HIDE: + { + } + break; + default: + { + VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent ); + } + break; + } + } + + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBox::disposing() + { + ::osl::MutexGuard aGuard( m_aMutex ); + + VCLXAccessibleComponent::disposing(); + m_xParent = NULL; + } + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException) + { + return getImplementationName_Static(); + } + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_Static(); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); + const ::rtl::OUString* pSupported = aSupported.getConstArray(); + const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); + for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) + ; + + return pSupported != pEnd; + } + // ----------------------------------------------------------------------------- + // XServiceInfo - static methods + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException ) + { + Sequence< ::rtl::OUString > aSupported(3); + aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); + aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); + aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") ); + return aSupported; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") ); + } + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext( ) throw (RuntimeException) + { + ensureAlive(); + return this; + } + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + sal_Int32 nCount = 0; + SvTreeListBox* pSvTreeListBox = getListBox(); + if ( pSvTreeListBox ) + nCount = pSvTreeListBox->GetLevelChildCount( NULL ); + + return nCount; + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + SvLBoxEntry* pEntry = getListBox()->GetEntry(i); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + ensureAlive(); + return m_xParent; + } + // ----------------------------------------------------------------------------- + sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException) + { + return AccessibleRole::TREE; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + return getListBox()->GetAccessibleDescription(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + return getListBox()->GetAccessibleName(); + } + // ----------------------------------------------------------------------------- + // XAccessibleSelection + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + getListBox()->Select( pEntry, sal_True ); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return getListBox()->IsSelected( pEntry ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + sal_Int32 i, nCount = 0; + nCount = getListBox()->GetLevelChildCount( NULL ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); + if ( getListBox()->IsSelected( pEntry ) ) + getListBox()->Select( pEntry, sal_False ); + } + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + sal_Int32 i, nCount = 0; + nCount = getListBox()->GetLevelChildCount( NULL ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); + if ( !getListBox()->IsSelected( pEntry ) ) + getListBox()->Select( pEntry, sal_True ); + } + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + sal_Int32 i, nSelCount = 0, nCount = 0; + nCount = getListBox()->GetLevelChildCount( NULL ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); + if ( getListBox()->IsSelected( pEntry ) ) + ++nSelCount; + } + + return nSelCount; + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int32 i, nSelCount = 0, nCount = 0; + nCount = getListBox()->GetLevelChildCount( NULL ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); + if ( getListBox()->IsSelected( pEntry ) ) + ++nSelCount; + + if ( nSelCount == ( nSelectedChildIndex + 1 ) ) + { + xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + break; + } + } + + return xChild; + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + ensureAlive(); + + SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + getListBox()->Select( pEntry, sal_False ); + } + // ----------------------------------------------------------------------------- + void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) + { + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + if ( getListBox() && isAlive() ) + { + rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); + if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION ) + rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE ); + } + } + + +//........................................................................ +}// namespace accessibility +//........................................................................ + diff --git a/accessibility/source/extended/accessiblelistboxentry.cxx b/accessibility/source/extended/accessiblelistboxentry.cxx new file mode 100644 index 000000000000..939e99b10fbb --- /dev/null +++ b/accessibility/source/extended/accessiblelistboxentry.cxx @@ -0,0 +1,970 @@ +/************************************************************************* + * + * 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/extended/accessiblelistboxentry.hxx" +#include <svtools/svtreebx.hxx> +#include <svtools/stringtransfer.hxx> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <vcl/controllayout.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/convert.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#define ACCESSIBLE_ACTION_COUNT 1 + +namespace +{ + void checkActionIndex_Impl( sal_Int32 _nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException) + { + if ( _nIndex < 0 || _nIndex >= ACCESSIBLE_ACTION_COUNT ) + // only three actions + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + } +} + +//........................................................................ +namespace accessibility +{ + //........................................................................ + // class ALBSolarGuard --------------------------------------------------------- + + /** Aquire the solar mutex. */ + class ALBSolarGuard : public ::vos::OGuard + { + public: + inline ALBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {} + }; + + // class AccessibleListBoxEntry ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + DBG_NAME(AccessibleListBoxEntry) + + // ----------------------------------------------------------------------------- + // Ctor() and Dtor() + // ----------------------------------------------------------------------------- + AccessibleListBoxEntry::AccessibleListBoxEntry( SvTreeListBox& _rListBox, + SvLBoxEntry* _pEntry, + const Reference< XAccessible >& _xParent ) : + + AccessibleListBoxEntry_BASE ( m_aMutex ), + ListBoxAccessibleBase( _rListBox ), + + m_nClientId ( 0 ), + m_aParent ( _xParent ) + + { + DBG_CTOR( AccessibleListBoxEntry, NULL ); + + _rListBox.FillEntryPath( _pEntry, m_aEntryPath ); + } + // ----------------------------------------------------------------------------- + AccessibleListBoxEntry::~AccessibleListBoxEntry() + { + DBG_DTOR( AccessibleListBoxEntry, NULL ); + + if ( IsAlive_Impl() ) + { + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } + } + + // ----------------------------------------------------------------------------- + Rectangle AccessibleListBoxEntry::GetBoundingBox_Impl() const + { + Rectangle aRect; + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + aRect = getListBox()->GetBoundingRect( pEntry ); + SvLBoxEntry* pParent = getListBox()->GetParent( pEntry ); + if ( pParent ) + { + // position relative to parent entry + Point aTopLeft = aRect.TopLeft(); + aTopLeft -= getListBox()->GetBoundingRect( pParent ).TopLeft(); + aRect = Rectangle( aTopLeft, aRect.GetSize() ); + } + } + + return aRect; + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen_Impl() const + { + Rectangle aRect; + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + aRect = getListBox()->GetBoundingRect( pEntry ); + Point aTopLeft = aRect.TopLeft(); + aTopLeft += getListBox()->GetWindowExtentsRelative( NULL ).TopLeft(); + aRect = Rectangle( aTopLeft, aRect.GetSize() ); + } + + return aRect; + } + // ----------------------------------------------------------------------------- + sal_Bool AccessibleListBoxEntry::IsAlive_Impl() const + { + return ( !rBHelper.bDisposed && !rBHelper.bInDispose && isAlive() ); + } + // ----------------------------------------------------------------------------- + sal_Bool AccessibleListBoxEntry::IsShowing_Impl() const + { + Reference< XAccessible > xParent = implGetParentAccessible( ); + + sal_Bool bShowing = sal_False; + Reference< XAccessibleContext > m_xParentContext = + xParent.is() ? xParent->getAccessibleContext() : Reference< XAccessibleContext >(); + if( m_xParentContext.is() ) + { + Reference< XAccessibleComponent > xParentComp( m_xParentContext, uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = GetBoundingBox_Impl().IsOver( VCLRectangle( xParentComp->getBounds() ) ); + } + + return bShowing; + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleListBoxEntry::GetBoundingBox() throw ( lang::DisposedException ) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBox_Impl(); + } + // ----------------------------------------------------------------------------- + Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen() throw ( lang::DisposedException ) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBoxOnScreen_Impl(); + } + // ----------------------------------------------------------------------------- + void AccessibleListBoxEntry::EnsureIsAlive() const throw ( lang::DisposedException ) + { + if ( !IsAlive_Impl() ) + throw lang::DisposedException(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleListBoxEntry::implGetText() + { + ::rtl::OUString sRet; + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + sRet = getListBox()->SearchEntryText( pEntry ); + return sRet; + } + // ----------------------------------------------------------------------------- + Locale AccessibleListBoxEntry::implGetLocale() + { + Locale aLocale; + aLocale = Application::GetSettings().GetUILocale(); + + return aLocale; + } + void AccessibleListBoxEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + Sequence< sal_Int8 > AccessibleListBoxEntry::getImplementationId() throw (RuntimeException) + { + static ::cppu::OImplementationId* pId = NULL; + + if ( !pId ) + { + ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + + if ( !pId ) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); + } + + // ----------------------------------------------------------------------------- + // XComponent/ListBoxAccessibleBase + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::dispose() throw ( uno::RuntimeException ) + { + AccessibleListBoxEntry_BASE::dispose(); + } + + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::disposing() + { + ALBSolarGuard(); + ::osl::MutexGuard aGuard( m_aMutex ); + + Reference< XAccessible > xKeepAlive( this ); + + // Send a disposing to all listeners. + if ( m_nClientId ) + { + ::comphelper::AccessibleEventNotifier::TClientId nId = m_nClientId; + m_nClientId = 0; + ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + // clean up + { + + ListBoxAccessibleBase::disposing(); + } + m_aParent = WeakReference< XAccessible >(); + } + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getImplementationName() throw(RuntimeException) + { + return getImplementationName_Static(); + } + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL AccessibleListBoxEntry::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_Static(); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBoxEntry::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); + const ::rtl::OUString* pSupported = aSupported.getConstArray(); + const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); + for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) + ; + + return pSupported != pEnd; + } + // ----------------------------------------------------------------------------- + // XServiceInfo - static methods + // ----------------------------------------------------------------------------- + Sequence< ::rtl::OUString > AccessibleListBoxEntry::getSupportedServiceNames_Static(void) throw( RuntimeException ) + { + Sequence< ::rtl::OUString > aSupported(3); + aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); + aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); + aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBoxEntry") ); + return aSupported; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleListBoxEntry::getImplementationName_Static(void) throw( RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBoxEntry") ); + } + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL AccessibleListBoxEntry::getAccessibleContext( ) throw (RuntimeException) + { + EnsureIsAlive(); + return this; + } + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleChildCount( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + sal_Int32 nCount = 0; + if ( pEntry ) + nCount = getListBox()->GetLevelChildCount( pEntry ); + + return nCount; + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + SvLBoxEntry* pEntry = pParent ? getListBox()->GetEntry( pParent, i ) : NULL; + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + } + + // ----------------------------------------------------------------------------- + Reference< XAccessible > AccessibleListBoxEntry::implGetParentAccessible( ) const + { + Reference< XAccessible > xParent = (Reference< XAccessible >)m_aParent; + if ( !xParent.is() ) + { + DBG_ASSERT( m_aEntryPath.size(), "AccessibleListBoxEntry::getAccessibleParent: invalid path!" ); + if ( 1 == m_aEntryPath.size() ) + { // we're a top level entry + // -> our parent is the tree listbox itself + if ( getListBox() ) + xParent = getListBox()->GetAccessible( ); + } + else + { // we have a entry as parent -> get it's accessible + + // shorten our access path by one + ::std::deque< sal_Int32 > aParentPath( m_aEntryPath ); + aParentPath.pop_back(); + + // get the entry for this shortened access path + SvLBoxEntry* pParentEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + DBG_ASSERT( pParentEntry, "AccessibleListBoxEntry::implGetParentAccessible: could not obtain a parent entry!" ); + + if ( pParentEntry ) + xParent = new AccessibleListBoxEntry( *getListBox(), pParentEntry, NULL ); + // note that we pass NULL here as parent-accessible: + // this is allowed, as the AccessibleListBoxEntry class will create it's parent + // when needed + } + } + + return xParent; + } + + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleParent( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + return implGetParentAccessible( ); + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleIndexInParent( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + DBG_ASSERT( !m_aEntryPath.empty(), "empty path" ); + return m_aEntryPath.empty() ? -1 : m_aEntryPath.back(); + } + // ----------------------------------------------------------------------------- + sal_Int16 SAL_CALL AccessibleListBoxEntry::getAccessibleRole( ) throw (RuntimeException) + { + return AccessibleRole::LABEL; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleDescription( ) throw (RuntimeException) + { + // no description for every item + return ::rtl::OUString(); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return implGetText(); + } + // ----------------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL AccessibleListBoxEntry::getAccessibleRelationSet( ) throw (RuntimeException) + { + Reference< XAccessibleRelationSet > xRelSet; + Reference< XAccessible > xParent; + if ( m_aEntryPath.size() > 1 ) // not a root entry + xParent = implGetParentAccessible(); + if ( xParent.is() ) + { + utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; + Sequence< Reference< XInterface > > aSequence(1); + aSequence[0] = xParent; + pRelationSetHelper->AddRelation( + AccessibleRelation( AccessibleRelationType::NODE_CHILD_OF, aSequence ) ); + xRelSet = pRelationSetHelper; + } + return xRelSet; + } + // ----------------------------------------------------------------------------- + Reference< XAccessibleStateSet > SAL_CALL AccessibleListBoxEntry::getAccessibleStateSet( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; + Reference< XAccessibleStateSet > xStateSet = pStateSetHelper; + + 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 ); + getListBox()->FillAccessibleEntryStateSet( + getListBox()->GetEntryFromPath( m_aEntryPath ), *pStateSetHelper ); + } + else + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + + return xStateSet; + } + // ----------------------------------------------------------------------------- + Locale SAL_CALL AccessibleListBoxEntry::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return implGetLocale(); + } + // ----------------------------------------------------------------------------- + // XAccessibleComponent + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBoxEntry::containsPoint( const awt::Point& rPoint ) throw (RuntimeException) + { + return Rectangle( Point(), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + SvLBoxEntry* pEntry = getListBox()->GetEntry( VCLPoint( _aPoint ) ); + if ( !pEntry ) + throw RuntimeException(); + + Reference< XAccessible > xAcc; + AccessibleListBoxEntry* pAccEntry = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + Rectangle aRect = pAccEntry->GetBoundingBox_Impl(); + if ( aRect.IsInside( VCLPoint( _aPoint ) ) ) + xAcc = pAccEntry; + return xAcc; + } + // ----------------------------------------------------------------------------- + awt::Rectangle SAL_CALL AccessibleListBoxEntry::getBounds( ) throw (RuntimeException) + { + return AWTRectangle( GetBoundingBox() ); + } + // ----------------------------------------------------------------------------- + awt::Point SAL_CALL AccessibleListBoxEntry::getLocation( ) throw (RuntimeException) + { + return AWTPoint( GetBoundingBox().TopLeft() ); + } + // ----------------------------------------------------------------------------- + awt::Point SAL_CALL AccessibleListBoxEntry::getLocationOnScreen( ) throw (RuntimeException) + { + return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); + } + // ----------------------------------------------------------------------------- + awt::Size SAL_CALL AccessibleListBoxEntry::getSize( ) throw (RuntimeException) + { + return AWTSize( GetBoundingBox().GetSize() ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::grabFocus( ) throw (RuntimeException) + { + // do nothing, because no focus for each item + } + // ----------------------------------------------------------------------------- + sal_Int32 AccessibleListBoxEntry::getForeground( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + // ----------------------------------------------------------------------------- + sal_Int32 AccessibleListBoxEntry::getBackground( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + // ----------------------------------------------------------------------------- + // XAccessibleText + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + awt::Rectangle SAL_CALL AccessibleListBoxEntry::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + ::vcl::ControlLayoutData aLayoutData; + Rectangle aItemRect = GetBoundingBox(); + getListBox()->RecordLayoutData( &aLayoutData, aItemRect ); + Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBoxEntry::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + sal_Int32 nIndex = -1; + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + ::vcl::ControlLayoutData aLayoutData; + Rectangle aItemRect = GetBoundingBox(); + getListBox()->RecordLayoutData( &aLayoutData, aItemRect ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + nIndex = aLayoutData.GetIndexForPoint( aPnt ); + } + + return nIndex; + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBoxEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + String sText = getText(); + if ( ( 0 > nStartIndex ) || ( sText.Len() <= nStartIndex ) + || ( 0 > nEndIndex ) || ( sText.Len() <= nEndIndex ) ) + throw IndexOutOfBoundsException(); + + sal_Int32 nLen = nEndIndex - nStartIndex + 1; + ::svt::OStringTransfer::CopyString( sText.Copy( (sal_uInt16)nStartIndex, (sal_uInt16)nLen ), getListBox() ); + + return sal_True; + } + // ----------------------------------------------------------------------------- + // XAccessibleEventBroadcaster + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) + { + if (xListener.is()) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); + } + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) + { + if (xListener.is()) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + sal_Int32 nId = m_nClientId; + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClient( nId ); + + } + } + } + // ----------------------------------------------------------------------------- + // XAccessibleAction + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleActionCount( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // three actions supported + return ACCESSIBLE_ACTION_COUNT; + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBoxEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Bool bRet = sal_False; + checkActionIndex_Impl( nIndex ); + EnsureIsAlive(); + + SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + if ( getListBox()->IsExpanded( pEntry ) ) + getListBox()->Collapse( pEntry ); + else + getListBox()->Expand( pEntry ); + bRet = sal_True; + } + + return bRet; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + checkActionIndex_Impl( nIndex ); + EnsureIsAlive(); + + static const ::rtl::OUString sActionDesc( RTL_CONSTASCII_USTRINGPARAM( "toggleExpand" ) ); + return sActionDesc; + } + // ----------------------------------------------------------------------------- + Reference< XAccessibleKeyBinding > AccessibleListBoxEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Reference< XAccessibleKeyBinding > xRet; + checkActionIndex_Impl( nIndex ); + // ... which key? + return xRet; + } + // ----------------------------------------------------------------------------- + // XAccessibleSelection + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + getListBox()->Select( pEntry, sal_True ); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleListBoxEntry::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return getListBox()->IsSelected( pEntry ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::clearAccessibleSelection( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException(); + sal_Int32 i, nCount = 0; + nCount = getListBox()->GetLevelChildCount( pParent ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); + if ( getListBox()->IsSelected( pEntry ) ) + getListBox()->Select( pEntry, sal_False ); + } + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::selectAllAccessibleChildren( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException(); + sal_Int32 i, nCount = 0; + nCount = getListBox()->GetLevelChildCount( pParent ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); + if ( !getListBox()->IsSelected( pEntry ) ) + getListBox()->Select( pEntry, sal_True ); + } + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + sal_Int32 i, nSelCount = 0, nCount = 0; + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException(); + nCount = getListBox()->GetLevelChildCount( pParent ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); + if ( getListBox()->IsSelected( pEntry ) ) + ++nSelCount; + } + + return nSelCount; + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int32 i, nSelCount = 0, nCount = 0; + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException(); + nCount = getListBox()->GetLevelChildCount( pParent ); + for ( i = 0; i < nCount; ++i ) + { + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); + if ( getListBox()->IsSelected( pEntry ) ) + ++nSelCount; + + if ( nSelCount == ( nSelectedChildIndex + 1 ) ) + { + xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + break; + } + } + + return xChild; + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleListBoxEntry::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); + SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nSelectedChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + getListBox()->Select( pEntry, sal_False ); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException) + { + return -1; + } + sal_Bool SAL_CALL AccessibleListBoxEntry::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + sal_Unicode SAL_CALL AccessibleListBoxEntry::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getCharacter( nIndex ); + } + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleListBoxEntry::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + ::rtl::OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getCharacterCount( ); + } + + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getSelectedText( ); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getSelectionStart( ); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getSelectionEnd( ); + } + sal_Bool SAL_CALL AccessibleListBoxEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return sal_False; + } + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getText( ) throw (::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getText( ); + } + ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex ); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + ALBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } +//........................................................................ +}// namespace accessibility +//........................................................................ + diff --git a/accessibility/source/extended/accessibletabbar.cxx b/accessibility/source/extended/accessibletabbar.cxx new file mode 100644 index 000000000000..34fd7ef88d1f --- /dev/null +++ b/accessibility/source/extended/accessibletabbar.cxx @@ -0,0 +1,554 @@ +/************************************************************************* + * + * 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/extended/accessibletabbar.hxx> +#include <svtools/tabbar.hxx> +#include <accessibility/extended/accessibletabbarpagelist.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/awt/vclxfont.hxx> +#include <toolkit/helper/convert.hxx> + +#include <vector> + + +//......................................................................... +namespace accessibility +{ +//......................................................................... + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::accessibility; + using namespace ::comphelper; + + DBG_NAME( AccessibleTabBar ) + + // ---------------------------------------------------- + // class AccessibleTabBar + // ---------------------------------------------------- + + AccessibleTabBar::AccessibleTabBar( TabBar* pTabBar ) + :AccessibleTabBarBase( pTabBar ) + { + DBG_CTOR( AccessibleTabBar, NULL ); + + if ( m_pTabBar ) + m_aAccessibleChildren.assign( m_pTabBar->GetAccessibleChildWindowCount() + 1, Reference< XAccessible >() ); + } + + // ----------------------------------------------------------------------------- + + AccessibleTabBar::~AccessibleTabBar() + { + DBG_DTOR( AccessibleTabBar, NULL ); + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + Any aOldValue, aNewValue; + + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_WINDOW_ENABLED: + { + aNewValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + aNewValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VCLEVENT_WINDOW_DISABLED: + { + aOldValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + aOldValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VCLEVENT_WINDOW_GETFOCUS: + { + aNewValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VCLEVENT_WINDOW_LOSEFOCUS: + { + aOldValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VCLEVENT_WINDOW_SHOW: + { + aNewValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VCLEVENT_WINDOW_HIDE: + { + aOldValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + default: + { + AccessibleTabBarBase::ProcessWindowEvent( rVclWindowEvent ); + } + break; + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBar::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) + { + if ( m_pTabBar ) + { + if ( m_pTabBar->IsEnabled() ) + { + rStateSet.AddState( AccessibleStateType::ENABLED ); + rStateSet.AddState( AccessibleStateType::SENSITIVE ); + } + + rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + + if ( m_pTabBar->HasFocus() ) + rStateSet.AddState( AccessibleStateType::FOCUSED ); + + rStateSet.AddState( AccessibleStateType::VISIBLE ); + + if ( m_pTabBar->IsVisible() ) + rStateSet.AddState( AccessibleStateType::SHOWING ); + + if ( m_pTabBar->GetStyle() & WB_SIZEABLE ) + rStateSet.AddState( AccessibleStateType::RESIZABLE ); + } + } + + // ----------------------------------------------------------------------------- + // OCommonAccessibleComponent + // ----------------------------------------------------------------------------- + + awt::Rectangle AccessibleTabBar::implGetBounds() throw (RuntimeException) + { + awt::Rectangle aBounds; + if ( m_pTabBar ) + aBounds = AWTRectangle( Rectangle( m_pTabBar->GetPosPixel(), m_pTabBar->GetSizePixel() ) ); + + return aBounds; + } + + // ----------------------------------------------------------------------------- + // XInterface + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleTabBar, AccessibleExtendedComponentHelper_BASE, AccessibleTabBar_BASE ) + + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleTabBar, AccessibleExtendedComponentHelper_BASE, AccessibleTabBar_BASE ) + + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + + void AccessibleTabBar::disposing() + { + AccessibleTabBarBase::disposing(); + + // dispose all children + for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + Reference< XComponent > xComponent( m_aAccessibleChildren[i], UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren.clear(); + } + + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBar::getImplementationName() throw (RuntimeException) + { + return ::rtl::OUString::createFromAscii( "com.sun.star.comp.svtools.AccessibleTabBar" ); + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBar::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; + } + + // ----------------------------------------------------------------------------- + + Sequence< ::rtl::OUString > AccessibleTabBar::getSupportedServiceNames() throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames(1); + aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleTabBar" ); + return aNames; + } + + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + + Reference< XAccessibleContext > AccessibleTabBar::getAccessibleContext( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return this; + } + + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBar::getAccessibleChildCount() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return m_aAccessibleChildren.size(); + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBar::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + { + if ( m_pTabBar ) + { + sal_Int32 nCount = m_pTabBar->GetAccessibleChildWindowCount(); + + if ( i < nCount ) + { + Window* pChild = m_pTabBar->GetAccessibleChildWindow( (sal_uInt16)i ); + if ( pChild ) + xChild = pChild->GetAccessible(); + } + else if ( i == nCount ) + { + xChild = new AccessibleTabBarPageList( m_pTabBar, i ); + } + + // insert into child list + m_aAccessibleChildren[i] = xChild; + } + } + + return xChild; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBar::getAccessibleParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pTabBar ) + { + Window* pParent = m_pTabBar->GetAccessibleParentWindow(); + if ( pParent ) + xParent = pParent->GetAccessible(); + } + + return xParent; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBar::getAccessibleIndexInParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndexInParent = -1; + if ( m_pTabBar ) + { + Window* pParent = m_pTabBar->GetAccessibleParentWindow(); + if ( pParent ) + { + for ( sal_uInt16 i = 0, nCount = pParent->GetAccessibleChildWindowCount(); i < nCount; ++i ) + { + Window* pChild = pParent->GetAccessibleChildWindow( i ); + if ( pChild == static_cast< Window* >( m_pTabBar ) ) + { + nIndexInParent = i; + break; + } + } + } + } + + return nIndexInParent; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 AccessibleTabBar::getAccessibleRole( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return AccessibleRole::PANEL; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBar::getAccessibleDescription( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + ::rtl::OUString sDescription; + if ( m_pTabBar ) + sDescription = m_pTabBar->GetAccessibleDescription(); + + return sDescription; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBar::getAccessibleName( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + ::rtl::OUString sName; + if ( m_pTabBar ) + sName = m_pTabBar->GetAccessibleName(); + + return sName; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessibleRelationSet > AccessibleTabBar::getAccessibleRelationSet( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; + Reference< XAccessibleRelationSet > xSet = pRelationSetHelper; + return xSet; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessibleStateSet > AccessibleTabBar::getAccessibleStateSet( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; + Reference< XAccessibleStateSet > xSet = pStateSetHelper; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( *pStateSetHelper ); + } + else + { + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + } + + return xSet; + } + + // ----------------------------------------------------------------------------- + + Locale AccessibleTabBar::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLocale(); + } + + // ----------------------------------------------------------------------------- + // XAccessibleComponent + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBar::getAccessibleAtPoint( const awt::Point& rPoint ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xChild; + for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + Reference< XAccessible > xAcc = getAccessibleChild( i ); + if ( xAcc.is() ) + { + Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY ); + if ( xComp.is() ) + { + Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.IsInside( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBar::grabFocus( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( m_pTabBar ) + m_pTabBar->GrabFocus(); + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBar::getForeground( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + if ( m_pTabBar ) + { + if ( m_pTabBar->IsControlForeground() ) + nColor = m_pTabBar->GetControlForeground().GetColor(); + else + { + Font aFont; + if ( m_pTabBar->IsControlFont() ) + aFont = m_pTabBar->GetControlFont(); + else + aFont = m_pTabBar->GetFont(); + nColor = aFont.GetColor().GetColor(); + } + } + + return nColor; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBar::getBackground( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + if ( m_pTabBar ) + { + if ( m_pTabBar->IsControlBackground() ) + nColor = m_pTabBar->GetControlBackground().GetColor(); + else + nColor = m_pTabBar->GetBackground().GetColor().GetColor(); + } + + return nColor; + } + + // ----------------------------------------------------------------------------- + // XAccessibleExtendedComponent + // ----------------------------------------------------------------------------- + + Reference< awt::XFont > AccessibleTabBar::getFont( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + if ( m_pTabBar ) + { + Reference< awt::XDevice > xDev( m_pTabBar->GetComponentInterface(), UNO_QUERY ); + if ( xDev.is() ) + { + Font aFont; + if ( m_pTabBar->IsControlFont() ) + aFont = m_pTabBar->GetControlFont(); + else + aFont = m_pTabBar->GetFont(); + VCLXFont* pVCLXFont = new VCLXFont; + pVCLXFont->Init( *xDev.get(), aFont ); + xFont = pVCLXFont; + } + } + + return xFont; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBar::getTitledBorderText( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + ::rtl::OUString sText; + if ( m_pTabBar ) + sText = m_pTabBar->GetText(); + + return sText; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBar::getToolTipText( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + ::rtl::OUString sText; + if ( m_pTabBar ) + sText = m_pTabBar->GetQuickHelpText(); + + return sText; + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace accessibility +//......................................................................... diff --git a/accessibility/source/extended/accessibletabbarbase.cxx b/accessibility/source/extended/accessibletabbarbase.cxx new file mode 100644 index 000000000000..5c26185f6b03 --- /dev/null +++ b/accessibility/source/extended/accessibletabbarbase.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * 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/extended/accessibletabbarbase.hxx" +#ifndef ACCESSIBILITY_EXT_ACCESSIBLETABBARPAGELIST +#include "accessibility/extended/accessibletabbarpagelist.hxx" +#endif +#include <toolkit/helper/externallock.hxx> +#include <svtools/tabbar.hxx> + +//......................................................................... +namespace accessibility +{ +//......................................................................... + +AccessibleTabBarBase::AccessibleTabBarBase( TabBar* pTabBar ) : + AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() ), + m_pTabBar( 0 ) +{ + m_pExternalLock = static_cast< VCLExternalSolarLock* >( getExternalLock() ); + SetTabBarPointer( pTabBar ); +} + +AccessibleTabBarBase::~AccessibleTabBarBase() +{ + ClearTabBarPointer(); + DELETEZ( m_pExternalLock ); +} + +IMPL_LINK( AccessibleTabBarBase, WindowEventListener, VclSimpleEvent*, pEvent ) +{ + VclWindowEvent* pWinEvent = dynamic_cast< VclWindowEvent* >( pEvent ); + DBG_ASSERT( pWinEvent, "AccessibleTabBarBase::WindowEventListener - unknown window event" ); + if( pWinEvent ) + { + Window* pEventWindow = pWinEvent->GetWindow(); + DBG_ASSERT( pEventWindow, "AccessibleTabBarBase::WindowEventListener: no window!" ); + + if( ( pWinEvent->GetId() == VCLEVENT_TABBAR_PAGEREMOVED ) && + ( (sal_uInt16)(sal_IntPtr) pWinEvent->GetData() == TabBar::PAGE_NOT_FOUND ) && + ( dynamic_cast< AccessibleTabBarPageList *> (this) != NULL ) ) + { + return 0; + } + + if ( !pEventWindow->IsAccessibilityEventsSuppressed() || (pWinEvent->GetId() == VCLEVENT_OBJECT_DYING) ) + ProcessWindowEvent( *pWinEvent ); + } + return 0; +} + +void AccessibleTabBarBase::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + if( rVclWindowEvent.GetId() == VCLEVENT_OBJECT_DYING ) + ClearTabBarPointer(); +} + +// XComponent + +void AccessibleTabBarBase::disposing() +{ + AccessibleExtendedComponentHelper_BASE::disposing(); + ClearTabBarPointer(); +} + +// private + +void AccessibleTabBarBase::SetTabBarPointer( TabBar* pTabBar ) +{ + DBG_ASSERT( !m_pTabBar, "AccessibleTabBarBase::SetTabBarPointer - multiple call" ); + m_pTabBar = pTabBar; + if( m_pTabBar ) + m_pTabBar->AddEventListener( LINK( this, AccessibleTabBarBase, WindowEventListener ) ); +} + +void AccessibleTabBarBase::ClearTabBarPointer() +{ + if( m_pTabBar ) + { + m_pTabBar->RemoveEventListener( LINK( this, AccessibleTabBarBase, WindowEventListener ) ); + m_pTabBar = 0; + } +} + +//......................................................................... +} // namespace accessibility +//......................................................................... + diff --git a/accessibility/source/extended/accessibletabbarpage.cxx b/accessibility/source/extended/accessibletabbarpage.cxx new file mode 100644 index 000000000000..32dfb591a3ad --- /dev/null +++ b/accessibility/source/extended/accessibletabbarpage.cxx @@ -0,0 +1,511 @@ +/************************************************************************* + * + * 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/extended/accessibletabbarpage.hxx> +#include <svtools/tabbar.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/helper/convert.hxx> + + +//......................................................................... +namespace accessibility +{ +//......................................................................... + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + using namespace ::comphelper; + + // ----------------------------------------------------------------------------- + // class AccessibleTabBarPage + // ----------------------------------------------------------------------------- + + AccessibleTabBarPage::AccessibleTabBarPage( TabBar* pTabBar, sal_uInt16 nPageId, const Reference< XAccessible >& rxParent ) + :AccessibleTabBarBase( pTabBar ) + ,m_nPageId( nPageId ) + ,m_xParent( rxParent ) + { + m_bEnabled = IsEnabled(); + m_bShowing = IsShowing(); + m_bSelected = IsSelected(); + + if ( m_pTabBar ) + m_sPageText = m_pTabBar->GetPageText( m_nPageId ); + } + + // ----------------------------------------------------------------------------- + + AccessibleTabBarPage::~AccessibleTabBarPage() + { + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBarPage::IsEnabled() + { + OExternalLockGuard aGuard( this ); + + sal_Bool bEnabled = sal_False; + if ( m_pTabBar ) + bEnabled = m_pTabBar->IsPageEnabled( m_nPageId ); + + return bEnabled; + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBarPage::IsShowing() + { + sal_Bool bShowing = sal_False; + + if ( m_pTabBar && m_pTabBar->IsVisible() ) + bShowing = sal_True; + + return bShowing; + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBarPage::IsSelected() + { + sal_Bool bSelected = sal_False; + + if ( m_pTabBar && m_pTabBar->GetCurPageId() == m_nPageId ) + bSelected = sal_True; + + return bSelected; + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::SetEnabled( sal_Bool bEnabled ) + { + if ( m_bEnabled != bEnabled ) + { + Any aOldValue[2], aNewValue[2]; + if ( m_bEnabled ) + { + aOldValue[0] <<= AccessibleStateType::SENSITIVE; + aOldValue[1] <<= AccessibleStateType::ENABLED; + } + else + { + + aNewValue[0] <<= AccessibleStateType::ENABLED; + aNewValue[1] <<= AccessibleStateType::SENSITIVE; + } + m_bEnabled = bEnabled; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[0], aNewValue[0] ); + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[1], aNewValue[1] ); + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::SetShowing( sal_Bool bShowing ) + { + if ( m_bShowing != bShowing ) + { + Any aOldValue, aNewValue; + if ( m_bShowing ) + aOldValue <<= AccessibleStateType::SHOWING; + else + aNewValue <<= AccessibleStateType::SHOWING; + m_bShowing = bShowing; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::SetSelected( sal_Bool bSelected ) + { + if ( m_bSelected != bSelected ) + { + Any aOldValue, aNewValue; + if ( m_bSelected ) + aOldValue <<= AccessibleStateType::SELECTED; + else + aNewValue <<= AccessibleStateType::SELECTED; + m_bSelected = bSelected; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::SetPageText( const ::rtl::OUString& sPageText ) + { + if ( !m_sPageText.equals( sPageText ) ) + { + Any aOldValue, aNewValue; + aOldValue <<= m_sPageText; + aNewValue <<= sPageText; + m_sPageText = sPageText; + NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) + { + if ( IsEnabled() ) + { + rStateSet.AddState( AccessibleStateType::ENABLED ); + rStateSet.AddState( AccessibleStateType::SENSITIVE ); + } + + rStateSet.AddState( AccessibleStateType::VISIBLE ); + + if ( IsShowing() ) + rStateSet.AddState( AccessibleStateType::SHOWING ); + + rStateSet.AddState( AccessibleStateType::SELECTABLE ); + + if ( IsSelected() ) + rStateSet.AddState( AccessibleStateType::SELECTED ); + } + + // ----------------------------------------------------------------------------- + // OCommonAccessibleComponent + // ----------------------------------------------------------------------------- + + awt::Rectangle AccessibleTabBarPage::implGetBounds() throw (RuntimeException) + { + awt::Rectangle aBounds; + if ( m_pTabBar ) + { + // get bounding rectangle relative to the AccessibleTabBar + aBounds = AWTRectangle( m_pTabBar->GetPageRect( m_nPageId ) ); + + // get position of the AccessibleTabBarPageList relative to the AccessibleTabBar + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComponent.is() ) + { + awt::Point aParentLoc = xParentComponent->getLocation(); + + // calculate bounding rectangle relative to the AccessibleTabBarPageList + aBounds.X -= aParentLoc.X; + aBounds.Y -= aParentLoc.Y; + } + } + } + + return aBounds; + } + + // ----------------------------------------------------------------------------- + // XInterface + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleTabBarPage, AccessibleExtendedComponentHelper_BASE, AccessibleTabBarPage_BASE ) + + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleTabBarPage, AccessibleExtendedComponentHelper_BASE, AccessibleTabBarPage_BASE ) + + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::disposing() + { + AccessibleTabBarBase::disposing(); + m_sPageText = ::rtl::OUString(); + } + + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPage::getImplementationName() throw (RuntimeException) + { + return ::rtl::OUString::createFromAscii( "com.sun.star.comp.svtools.AccessibleTabBarPage" ); + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBarPage::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; + } + + // ----------------------------------------------------------------------------- + + Sequence< ::rtl::OUString > AccessibleTabBarPage::getSupportedServiceNames() throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames(1); + aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleTabBarPage" ); + return aNames; + } + + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + + Reference< XAccessibleContext > AccessibleTabBarPage::getAccessibleContext( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return this; + } + + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPage::getAccessibleChildCount() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return 0; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPage::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + return Reference< XAccessible >(); + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPage::getAccessibleParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return m_xParent; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPage::getAccessibleIndexInParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndexInParent = -1; + if ( m_pTabBar ) + nIndexInParent = m_pTabBar->GetPagePos( m_nPageId ); + + return nIndexInParent; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 AccessibleTabBarPage::getAccessibleRole( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return AccessibleRole::PAGE_TAB; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPage::getAccessibleDescription( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + ::rtl::OUString sDescription; + if ( m_pTabBar ) + sDescription = m_pTabBar->GetHelpText( m_nPageId ); + + return sDescription; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPage::getAccessibleName( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return m_sPageText; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessibleRelationSet > AccessibleTabBarPage::getAccessibleRelationSet( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; + Reference< XAccessibleRelationSet > xSet = pRelationSetHelper; + return xSet; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessibleStateSet > AccessibleTabBarPage::getAccessibleStateSet( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; + Reference< XAccessibleStateSet > xSet = pStateSetHelper; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( *pStateSetHelper ); + } + else + { + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + } + + return xSet; + } + + // ----------------------------------------------------------------------------- + + Locale AccessibleTabBarPage::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLocale(); + } + + // ----------------------------------------------------------------------------- + // XAccessibleComponent + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPage::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return Reference< XAccessible >(); + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPage::grabFocus( ) throw (RuntimeException) + { + // no focus + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPage::getForeground( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPage::getBackground( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + + // ----------------------------------------------------------------------------- + // XAccessibleExtendedComponent + // ----------------------------------------------------------------------------- + + Reference< awt::XFont > AccessibleTabBarPage::getFont( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPage::getTitledBorderText( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return m_sPageText; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPage::getToolTipText( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return ::rtl::OUString(); + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace accessibility +//......................................................................... diff --git a/accessibility/source/extended/accessibletabbarpagelist.cxx b/accessibility/source/extended/accessibletabbarpagelist.cxx new file mode 100644 index 000000000000..a8fce05dcff0 --- /dev/null +++ b/accessibility/source/extended/accessibletabbarpagelist.cxx @@ -0,0 +1,805 @@ +/************************************************************************* + * + * 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/extended/accessibletabbarpagelist.hxx> +#include <svtools/tabbar.hxx> +#include <accessibility/extended/accessibletabbarpage.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/helper/convert.hxx> + + +//......................................................................... +namespace accessibility +{ +//......................................................................... + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + using namespace ::comphelper; + + DBG_NAME( AccessibleTabBarPageList ) + + // ----------------------------------------------------------------------------- + // class AccessibleTabBarPageList + // ----------------------------------------------------------------------------- + + AccessibleTabBarPageList::AccessibleTabBarPageList( TabBar* pTabBar, sal_Int32 nIndexInParent ) + :AccessibleTabBarBase( pTabBar ) + ,m_nIndexInParent( nIndexInParent ) + { + DBG_CTOR( AccessibleTabBarPageList, NULL ); + if ( m_pTabBar ) + m_aAccessibleChildren.assign( m_pTabBar->GetPageCount(), Reference< XAccessible >() ); + } + + // ----------------------------------------------------------------------------- + + AccessibleTabBarPageList::~AccessibleTabBarPageList() + { + DBG_DTOR( AccessibleTabBarPageList, NULL ); + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::UpdateEnabled( sal_Int32 i, sal_Bool bEnabled ) + { + if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() ) + { + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + if ( xChild.is() ) + { + AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() ); + if ( pAccessibleTabBarPage ) + pAccessibleTabBarPage->SetEnabled( bEnabled ); + } + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::UpdateShowing( sal_Bool bShowing ) + { + for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + if ( xChild.is() ) + { + AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() ); + if ( pAccessibleTabBarPage ) + pAccessibleTabBarPage->SetShowing( bShowing ); + } + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::UpdateSelected( sal_Int32 i, sal_Bool bSelected ) + { + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + + if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() ) + { + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + if ( xChild.is() ) + { + AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() ); + if ( pAccessibleTabBarPage ) + pAccessibleTabBarPage->SetSelected( bSelected ); + } + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::UpdatePageText( sal_Int32 i ) + { + if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() ) + { + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + if ( xChild.is() ) + { + AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() ); + if ( pAccessibleTabBarPage ) + { + if ( m_pTabBar ) + { + ::rtl::OUString sPageText = m_pTabBar->GetPageText( m_pTabBar->GetPageId( (sal_uInt16)i ) ); + pAccessibleTabBarPage->SetPageText( sPageText ); + } + } + } + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::InsertChild( sal_Int32 i ) + { + if ( i >= 0 && i <= (sal_Int32)m_aAccessibleChildren.size() ) + { + // insert entry in child list + m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, Reference< XAccessible >() ); + + // send accessible child event + Reference< XAccessible > xChild( getAccessibleChild( i ) ); + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::RemoveChild( sal_Int32 i ) + { + if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() ) + { + // get the accessible of the removed page + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + + // remove entry in child list + m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i ); + + // send accessible child event + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aOldValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + Reference< XComponent > xComponent( xChild, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::MoveChild( sal_Int32 i, sal_Int32 j ) + { + if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() && + j >= 0 && j <= (sal_Int32)m_aAccessibleChildren.size() ) + { + if ( i < j ) + --j; + + // get the accessible of the moved page + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + + // remove entry in child list at old position + m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i ); + + // insert entry in child list at new position + m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + j, xChild ); + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_WINDOW_ENABLED: + { + Any aNewValue; + aNewValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue ); + aNewValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue ); + } + break; + case VCLEVENT_WINDOW_DISABLED: + { + Any aOldValue; + aOldValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() ); + aOldValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() ); + } + break; + case VCLEVENT_WINDOW_SHOW: + { + Any aOldValue, aNewValue; + aNewValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + UpdateShowing( sal_True ); + } + break; + case VCLEVENT_WINDOW_HIDE: + { + Any aOldValue, aNewValue; + aOldValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + UpdateShowing( sal_False ); + } + break; + case VCLEVENT_TABBAR_PAGEENABLED: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdateEnabled( nPagePos, sal_True ); + } + } + break; + case VCLEVENT_TABBAR_PAGEDISABLED: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdateEnabled( nPagePos, sal_False ); + } + } + break; + case VCLEVENT_TABBAR_PAGESELECTED: + { + // do nothing + } + break; + case VCLEVENT_TABBAR_PAGEACTIVATED: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdateSelected( nPagePos, sal_True ); + } + } + break; + case VCLEVENT_TABBAR_PAGEDEACTIVATED: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdateSelected( nPagePos, sal_False ); + } + } + break; + case VCLEVENT_TABBAR_PAGEINSERTED: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + InsertChild( nPagePos ); + } + } + break; + case VCLEVENT_TABBAR_PAGEREMOVED: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + + if ( nPageId == TabBar::PAGE_NOT_FOUND ) + { + for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i ) + RemoveChild( i ); + } + else + { + for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i ) + { + Reference< XAccessible > xChild( getAccessibleChild( i ) ); + if ( xChild.is() ) + { + AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() ); + if ( pAccessibleTabBarPage && pAccessibleTabBarPage->GetPageId() == nPageId ) + { + RemoveChild( i ); + break; + } + } + } + } + } + } + break; + case VCLEVENT_TABBAR_PAGEMOVED: + { + Pair* pPair = (Pair*) rVclWindowEvent.GetData(); + if ( pPair ) + MoveChild( pPair->A(), pPair->B() ); + } + break; + case VCLEVENT_TABBAR_PAGETEXTCHANGED: + { + sal_uInt16 nPageId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData(); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdatePageText( nPagePos ); + } + break; + default: + { + AccessibleTabBarBase::ProcessWindowEvent( rVclWindowEvent ); + } + break; + } + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) + { + if ( m_pTabBar ) + { + if ( m_pTabBar->IsEnabled() ) + { + rStateSet.AddState( AccessibleStateType::ENABLED ); + rStateSet.AddState( AccessibleStateType::SENSITIVE ); + } + + rStateSet.AddState( AccessibleStateType::VISIBLE ); + + if ( m_pTabBar->IsVisible() ) + rStateSet.AddState( AccessibleStateType::SHOWING ); + } + } + + // ----------------------------------------------------------------------------- + // OCommonAccessibleComponent + // ----------------------------------------------------------------------------- + + awt::Rectangle AccessibleTabBarPageList::implGetBounds() throw (RuntimeException) + { + awt::Rectangle aBounds; + if ( m_pTabBar ) + aBounds = AWTRectangle( m_pTabBar->GetPageArea() ); + + return aBounds; + } + + // ----------------------------------------------------------------------------- + // XInterface + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleTabBarPageList, AccessibleExtendedComponentHelper_BASE, AccessibleTabBarPageList_BASE ) + + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleTabBarPageList, AccessibleExtendedComponentHelper_BASE, AccessibleTabBarPageList_BASE ) + + // ----------------------------------------------------------------------------- + // XComponent + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::disposing() + { + AccessibleTabBarBase::disposing(); + + // dispose all children + for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + Reference< XComponent > xComponent( m_aAccessibleChildren[i], UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren.clear(); + } + + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPageList::getImplementationName() throw (RuntimeException) + { + return ::rtl::OUString::createFromAscii( "com.sun.star.comp.svtools.AccessibleTabBarPageList" ); + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBarPageList::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; + } + + // ----------------------------------------------------------------------------- + + Sequence< ::rtl::OUString > AccessibleTabBarPageList::getSupportedServiceNames() throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames(1); + aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleTabBarPageList" ); + return aNames; + } + + // ----------------------------------------------------------------------------- + // XAccessible + // ----------------------------------------------------------------------------- + + Reference< XAccessibleContext > AccessibleTabBarPageList::getAccessibleContext( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return this; + } + + // ----------------------------------------------------------------------------- + // XAccessibleContext + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPageList::getAccessibleChildCount() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return m_aAccessibleChildren.size(); + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPageList::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = m_pTabBar->GetPageId( (sal_uInt16)i ); + + xChild = new AccessibleTabBarPage( m_pTabBar, nPageId, this ); + + // insert into child list + m_aAccessibleChildren[i] = xChild; + } + } + + return xChild; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPageList::getAccessibleParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pTabBar ) + xParent = m_pTabBar->GetAccessible(); + + return xParent; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPageList::getAccessibleIndexInParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return m_nIndexInParent; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 AccessibleTabBarPageList::getAccessibleRole( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return AccessibleRole::PAGE_TAB_LIST; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPageList::getAccessibleDescription( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return ::rtl::OUString(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPageList::getAccessibleName( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return ::rtl::OUString(); + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessibleRelationSet > AccessibleTabBarPageList::getAccessibleRelationSet( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; + Reference< XAccessibleRelationSet > xSet = pRelationSetHelper; + return xSet; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessibleStateSet > AccessibleTabBarPageList::getAccessibleStateSet( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; + Reference< XAccessibleStateSet > xSet = pStateSetHelper; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( *pStateSetHelper ); + } + else + { + pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); + } + + return xSet; + } + + // ----------------------------------------------------------------------------- + + Locale AccessibleTabBarPageList::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLocale(); + } + + // ----------------------------------------------------------------------------- + // XAccessibleComponent + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPageList::getAccessibleAtPoint( const awt::Point& rPoint ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xChild; + for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + Reference< XAccessible > xAcc = getAccessibleChild( i ); + if ( xAcc.is() ) + { + Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY ); + if ( xComp.is() ) + { + Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.IsInside( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::grabFocus( ) throw (RuntimeException) + { + // no focus + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPageList::getForeground( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPageList::getBackground( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + + // ----------------------------------------------------------------------------- + // XAccessibleExtendedComponent + // ----------------------------------------------------------------------------- + + Reference< awt::XFont > AccessibleTabBarPageList::getFont( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPageList::getTitledBorderText( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return ::rtl::OUString(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString AccessibleTabBarPageList::getToolTipText( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return ::rtl::OUString(); + } + + // ----------------------------------------------------------------------------- + // XAccessibleSelection + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + if ( m_pTabBar ) + { + m_pTabBar->SetCurPageId( m_pTabBar->GetPageId( (sal_uInt16)nChildIndex ) ); + m_pTabBar->Update(); + m_pTabBar->ActivatePage(); + m_pTabBar->Select(); + } + } + + // ----------------------------------------------------------------------------- + + sal_Bool AccessibleTabBarPageList::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + sal_Bool bSelected = sal_False; + if ( m_pTabBar && m_pTabBar->GetCurPageId() == m_pTabBar->GetPageId( (sal_uInt16)nChildIndex ) ) + bSelected = sal_True; + + return bSelected; + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::clearAccessibleSelection( ) throw (RuntimeException) + { + // This method makes no sense in a TabBar, and so does nothing. + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::selectAllAccessibleChildren( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + selectAccessibleChild( 0 ); + } + + // ----------------------------------------------------------------------------- + + sal_Int32 AccessibleTabBarPageList::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return 1; + } + + // ----------------------------------------------------------------------------- + + Reference< XAccessible > AccessibleTabBarPageList::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + + for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ ) + { + if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) ) + { + xChild = getAccessibleChild( i ); + break; + } + } + + return xChild; + } + + // ----------------------------------------------------------------------------- + + void AccessibleTabBarPageList::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + // This method makes no sense in a TabBar, and so does nothing. + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace accessibility +//......................................................................... diff --git a/accessibility/source/extended/accessibletablistbox.cxx b/accessibility/source/extended/accessibletablistbox.cxx new file mode 100644 index 000000000000..aed68e55e482 --- /dev/null +++ b/accessibility/source/extended/accessibletablistbox.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * 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" + +#ifndef ACCESSIBILITY_EXT_ACCESSIBLETABLISTBOX_HXX_ +#include "accessibility/extended/accessibletablistbox.hxx" +#endif +#include "accessibility/extended/accessibletablistboxtable.hxx" +#include <svtools/svtabbx.hxx> +#include <comphelper/sequence.hxx> + +//........................................................................ +namespace accessibility +{ +//........................................................................ + + // class TLBSolarGuard --------------------------------------------------------- + + /** Aquire the solar mutex. */ + class TLBSolarGuard : public ::vos::OGuard + { + public: + inline TLBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {} + }; + + // class AccessibleTabListBox ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + DBG_NAME(AccessibleTabListBox) + + // ----------------------------------------------------------------------------- + // Ctor() and Dtor() + // ----------------------------------------------------------------------------- + AccessibleTabListBox::AccessibleTabListBox( const Reference< XAccessible >& rxParent, SvHeaderTabListBox& rBox ) + :AccessibleBrowseBox( rxParent, NULL, rBox ) + ,m_pTabListBox( &rBox ) + + { + DBG_CTOR( AccessibleTabListBox, NULL ); + + osl_incrementInterlockedCount( &m_refCount ); + { + setCreator( this ); + } + osl_decrementInterlockedCount( &m_refCount ); + } + + // ----------------------------------------------------------------------------- + AccessibleTabListBox::~AccessibleTabListBox() + { + DBG_DTOR( AccessibleTabListBox, NULL ); + + if ( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } + } + // ----------------------------------------------------------------------------- + AccessibleBrowseBoxTable* AccessibleTabListBox::createAccessibleTable() + { + return new AccessibleTabListBoxTable( this, *m_pTabListBox ); + } + + // XInterface ----------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleTabListBox, AccessibleBrowseBox, AccessibleTabListBox_Base ) + + // XTypeProvider -------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleTabListBox, AccessibleBrowseBox, AccessibleTabListBox_Base ) + + // XAccessibleContext --------------------------------------------------------- + + sal_Int32 SAL_CALL AccessibleTabListBox::getAccessibleChildCount() + throw ( uno::RuntimeException ) + { + return 2; // header and table + } + + // ----------------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL AccessibleTabListBox::getAccessibleContext() throw ( RuntimeException ) + { + return this; + } + + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL + AccessibleTabListBox::getAccessibleChild( sal_Int32 nChildIndex ) + throw ( IndexOutOfBoundsException, RuntimeException ) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + ensureIsAlive(); + + if ( nChildIndex < 0 || nChildIndex > 1 ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xRet; + if (nChildIndex == 0) + { + //! so far the actual implementation object only supports column headers + xRet = implGetFixedChild( ::svt::BBINDEX_COLUMNHEADERBAR ); + } + else if (nChildIndex == 1) + xRet = implGetFixedChild( ::svt::BBINDEX_TABLE ); + + if ( !xRet.is() ) + throw RuntimeException(); + + return xRet; + } + +//........................................................................ +}// namespace accessibility +//........................................................................ + diff --git a/accessibility/source/extended/accessibletablistboxtable.cxx b/accessibility/source/extended/accessibletablistboxtable.cxx new file mode 100644 index 000000000000..a87ba9586098 --- /dev/null +++ b/accessibility/source/extended/accessibletablistboxtable.cxx @@ -0,0 +1,383 @@ +/************************************************************************* + * + * 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" + +#ifndef ACCESSIBILITY_EXT_ACCESSIBLETABLISTBOXTABLE_HXX_ +#include "accessibility/extended/accessibletablistboxtable.hxx" +#endif +#include "accessibility/extended/AccessibleBrowseBoxTableCell.hxx" +#include "accessibility/extended/AccessibleBrowseBoxCheckBoxCell.hxx" +#include <svtools/svtabbx.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> + +//........................................................................ +namespace accessibility +{ +//........................................................................ + + // class TLBSolarGuard --------------------------------------------------------- + + /** Aquire the solar mutex. */ + class TLBSolarGuard : public ::vos::OGuard + { + public: + inline TLBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {} + }; + + // class AccessibleTabListBoxTable --------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + DBG_NAME(AccessibleTabListBoxTable) + + // ----------------------------------------------------------------------------- + // Ctor() and Dtor() + // ----------------------------------------------------------------------------- + AccessibleTabListBoxTable::AccessibleTabListBoxTable( const Reference< XAccessible >& rxParent, SvHeaderTabListBox& rBox ) : + + AccessibleBrowseBoxTable( rxParent, rBox ), + + m_pTabListBox ( &rBox ) + + { + DBG_CTOR( AccessibleTabListBoxTable, NULL ); + + m_pTabListBox->AddEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) ); + } + // ----------------------------------------------------------------------------- + AccessibleTabListBoxTable::~AccessibleTabListBoxTable() + { + DBG_DTOR( AccessibleTabListBoxTable, NULL ); + + if ( isAlive() ) + { + m_pTabListBox = NULL; + + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } + } + // ----------------------------------------------------------------------------- + void AccessibleTabListBoxTable::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + if ( isAlive() ) + { + sal_uLong nEventId = rVclWindowEvent.GetId(); + switch ( nEventId ) + { + case VCLEVENT_OBJECT_DYING : + { + m_pTabListBox->RemoveEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) ); + m_pTabListBox = NULL; + break; + } + + case VCLEVENT_CONTROL_GETFOCUS : + case VCLEVENT_CONTROL_LOSEFOCUS : + { + uno::Any aOldValue, aNewValue; + if ( VCLEVENT_CONTROL_GETFOCUS == nEventId ) + aNewValue <<= AccessibleStateType::FOCUSED; + else + aOldValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + break; + } + + case VCLEVENT_LISTBOX_SELECT : + { + // First send an event that tells the listeners of a + // 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. + commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + if ( m_pTabListBox && m_pTabListBox->HasFocus() ) + { + SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + sal_uInt16 nCol = m_pTabListBox->GetCurrColumn(); + Reference< XAccessible > xChild = + m_pTabListBox->CreateAccessibleCell( nRow, nCol ); + uno::Any aOldValue, aNewValue; + + if ( m_pTabListBox->IsTransientChildrenDisabled() ) + { + aNewValue <<= AccessibleStateType::FOCUSED; + TriState eState = STATE_DONTKNOW; + if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) + { + AccessibleCheckBoxCell* pCell = + static_cast< AccessibleCheckBoxCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + } + else + { + AccessibleBrowseBoxTableCell* pCell = + static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + } + } + else + { + aNewValue <<= xChild; + commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue, aOldValue ); + } + } + } + break; + } + + case VCLEVENT_CHECKBOX_TOGGLE : + { + if ( m_pTabListBox && m_pTabListBox->HasFocus() ) + { + SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + sal_uInt16 nCol = m_pTabListBox->GetCurrColumn(); + TriState eState = STATE_DONTKNOW; + if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) + { + Reference< XAccessible > xChild = + m_pTabListBox->CreateAccessibleCell( nRow, nCol ); + AccessibleCheckBoxCell* pCell = + static_cast< AccessibleCheckBoxCell* >( xChild.get() ); + pCell->SetChecked( m_pTabListBox->IsItemChecked( pEntry, nCol ) ); + } + } + } + break; + } + + case VCLEVENT_TABLECELL_NAMECHANGED : + { + if ( m_pTabListBox->IsTransientChildrenDisabled() ) + { + commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + TabListBoxEventData* pData = static_cast< TabListBoxEventData* >( rVclWindowEvent.GetData() ); + SvLBoxEntry* pEntry = pData != NULL ? pData->m_pEntry : NULL; + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + sal_uInt16 nCol = pData->m_nColumn; + Reference< XAccessible > xChild = + m_pTabListBox->CreateAccessibleCell( nRow, nCol ); + uno::Any aOldValue, aNewValue; + aOldValue <<= ::rtl::OUString( pData->m_sOldText ); + ::rtl::OUString sNewText( m_pTabListBox->GetCellText( nRow, nCol ) ); + aNewValue <<= sNewText; + TriState eState = STATE_DONTKNOW; + + if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) + { + AccessibleCheckBoxCell* pCell = + static_cast< AccessibleCheckBoxCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } + else + { + AccessibleBrowseBoxTableCell* pCell = + static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); + pCell->nameChanged( sNewText, pData->m_sOldText ); + } + } + } + break; + } + } + } + } + // ----------------------------------------------------------------------------- + IMPL_LINK( AccessibleTabListBoxTable, WindowEventListener, VclSimpleEvent*, pEvent ) + { + DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); + if ( pEvent && pEvent->ISA( VclWindowEvent ) ) + { + DBG_ASSERT( ( (VclWindowEvent*)pEvent )->GetWindow() && m_pTabListBox, "no event window" ); + ProcessWindowEvent( *(VclWindowEvent*)pEvent ); + } + return 0; + } + // helpers -------------------------------------------------------------------- + + void AccessibleTabListBoxTable::ensureValidIndex( sal_Int32 _nIndex ) const + SAL_THROW( ( IndexOutOfBoundsException ) ) + { + if ( ( _nIndex < 0 ) || ( _nIndex >= implGetCellCount() ) ) + throw IndexOutOfBoundsException(); + } + + sal_Bool AccessibleTabListBoxTable::implIsRowSelected( sal_Int32 _nRow ) const + { + return m_pTabListBox ? m_pTabListBox->IsSelected( m_pTabListBox->GetEntry( _nRow ) ) : sal_False; + } + + void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow, sal_Bool _bSelect ) + { + if ( m_pTabListBox ) + m_pTabListBox->Select( m_pTabListBox->GetEntry( _nRow ), _bSelect ); + } + + sal_Int32 AccessibleTabListBoxTable::implGetRowCount() const + { + return m_pTabListBox ? m_pTabListBox->GetEntryCount() : 0; + } + + sal_Int32 AccessibleTabListBoxTable::implGetColumnCount() const + { + return m_pTabListBox ? m_pTabListBox->GetColumnCount() : 0; + } + + sal_Int32 AccessibleTabListBoxTable::implGetSelRowCount() const + { + return m_pTabListBox ? m_pTabListBox->GetSelectionCount() : 0; + } + + sal_Int32 AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow ) const + { + if ( m_pTabListBox ) + { + sal_Int32 nRow = 0; + SvLBoxEntry* pEntry = m_pTabListBox->FirstSelected(); + while ( pEntry ) + { + ++nRow; + if ( nRow == nSelRow ) + return m_pTabListBox->GetEntryPos( pEntry ); + pEntry = m_pTabListBox->NextSelected( pEntry ); + } + } + + return 0; + } + // ----------------------------------------------------------------------------- + // XInterface & XTypeProvider + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) + IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + ::rtl::OUString AccessibleTabListBoxTable::getImplementationName (void) throw (RuntimeException) + { + return ::rtl::OUString::createFromAscii("com.sun.star.comp.svtools.AccessibleTabListBoxTable"); + } + // ----------------------------------------------------------------------------- + // XAccessibleSelection + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleTabListBoxTable::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + ensureValidIndex( nChildIndex ); + + implSelectRow( implGetRow( nChildIndex ), sal_True ); + } + // ----------------------------------------------------------------------------- + sal_Bool SAL_CALL AccessibleTabListBoxTable::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + ensureValidIndex( nChildIndex ); + + return implIsRowSelected( implGetRow( nChildIndex ) ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleTabListBoxTable::clearAccessibleSelection( ) throw (RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + + m_pTabListBox->SetNoSelection(); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleTabListBoxTable::selectAllAccessibleChildren( ) throw (RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + + m_pTabListBox->SelectAll(); + } + // ----------------------------------------------------------------------------- + sal_Int32 SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + + return implGetColumnCount() * implGetSelRowCount(); + } + // ----------------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + + sal_Int32 nRows = implGetSelRowCount(); + if ( nRows == 0 ) + throw IndexOutOfBoundsException(); + + sal_Int32 nRow = implGetSelRow( nSelectedChildIndex % nRows ); + sal_Int32 nColumn = nSelectedChildIndex / nRows; + return getAccessibleCellAt( nRow, nColumn ); + } + // ----------------------------------------------------------------------------- + void SAL_CALL AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + TLBSolarGuard aSolarGuard; + ::osl::MutexGuard aGuard( getOslMutex() ); + + ensureIsAlive(); + ensureValidIndex( nSelectedChildIndex ); + + implSelectRow( implGetRow( nSelectedChildIndex ), sal_False ); + } + +//........................................................................ +}// namespace accessibility +//........................................................................ + diff --git a/accessibility/source/extended/listboxaccessible.cxx b/accessibility/source/extended/listboxaccessible.cxx new file mode 100644 index 000000000000..8600003c2bff --- /dev/null +++ b/accessibility/source/extended/listboxaccessible.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * 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/extended/listboxaccessible.hxx> +#include <svtools/svtreebx.hxx> + +//........................................................................ +namespace accessibility +{ +//........................................................................ + + //==================================================================== + //= ListBoxAccessibleBase + //==================================================================== + //-------------------------------------------------------------------- + ListBoxAccessibleBase::ListBoxAccessibleBase( SvTreeListBox& _rWindow ) + :m_pWindow( &_rWindow ) + { + m_pWindow->AddEventListener( LINK( this, ListBoxAccessibleBase, WindowEventListener ) ); + } + + //-------------------------------------------------------------------- + ListBoxAccessibleBase::~ListBoxAccessibleBase( ) + { + if ( m_pWindow ) + { + // cannot call "dispose" here, as it is abstract, so the VTABLE of the derived class + // is not intact anymore + // so we call our "disposing" only + disposing(); + } + } + + //-------------------------------------------------------------------- + IMPL_LINK( ListBoxAccessibleBase, WindowEventListener, VclSimpleEvent*, pEvent ) + { + DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "ListBoxAccessibleBase::WindowEventListener: unexpected WindowEvent!" ); + if ( pEvent && pEvent->ISA( VclWindowEvent ) ) + { + DBG_ASSERT( static_cast< VclWindowEvent* >( pEvent )->GetWindow() , "ListBoxAccessibleBase::WindowEventListener: no event window!" ); + DBG_ASSERT( static_cast< VclWindowEvent* >( pEvent )->GetWindow() == m_pWindow, "ListBoxAccessibleBase::WindowEventListener: where did this come from?" ); + + ProcessWindowEvent( *static_cast< VclWindowEvent* >( pEvent ) ); + } + return 0; + } + + // ----------------------------------------------------------------------------- + void ListBoxAccessibleBase::disposing() + { + if ( m_pWindow ) + m_pWindow->RemoveEventListener( LINK( this, ListBoxAccessibleBase, WindowEventListener ) ); + m_pWindow = NULL; + } + + // ----------------------------------------------------------------------------- + void ListBoxAccessibleBase::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent ) + { + if ( isAlive() ) + { + switch ( _rVclWindowEvent.GetId() ) + { + case VCLEVENT_OBJECT_DYING : + { + if ( m_pWindow ) + m_pWindow->RemoveEventListener( LINK( this, ListBoxAccessibleBase, WindowEventListener ) ); + m_pWindow = NULL; + dispose(); + break; + } + } + } + } + +//........................................................................ +} // namespace accessibility +//........................................................................ diff --git a/accessibility/source/extended/makefile.mk b/accessibility/source/extended/makefile.mk new file mode 100755 index 000000000000..27f4403c8210 --- /dev/null +++ b/accessibility/source/extended/makefile.mk @@ -0,0 +1,81 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=accessibility +TARGET=extended + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +.IF "$(OS)$(COM)"=="SOLARISI" +NOOPTFILES=$(SLO)$/accessibletabbarpagelist.obj +.ENDIF # "$(OS)$(COM)"=="SOLARISI" + +SLOFILES=\ + $(SLO)$/AccessibleBrowseBoxCheckBoxCell.obj \ + $(SLO)$/AccessibleBrowseBoxBase.obj \ + $(SLO)$/AccessibleBrowseBox.obj \ + $(SLO)$/AccessibleBrowseBoxTableCell.obj \ + $(SLO)$/AccessibleBrowseBoxHeaderCell.obj \ + $(SLO)$/AccessibleBrowseBoxTableBase.obj \ + $(SLO)$/AccessibleBrowseBoxTable.obj \ + $(SLO)$/AccessibleBrowseBoxHeaderBar.obj \ + $(SLO)$/accessibleiconchoicectrl.obj \ + $(SLO)$/accessibleiconchoicectrlentry.obj \ + $(SLO)$/accessiblelistbox.obj \ + $(SLO)$/accessiblelistboxentry.obj \ + $(SLO)$/accessibletabbarbase.obj \ + $(SLO)$/accessibletabbar.obj \ + $(SLO)$/accessibletabbarpage.obj \ + $(SLO)$/accessibletabbarpagelist.obj \ + $(SLO)$/accessibletablistbox.obj \ + $(SLO)$/accessibletablistboxtable.obj \ + $(SLO)$/listboxaccessible.obj \ + $(SLO)$/accessiblebrowseboxcell.obj \ + $(SLO)$/accessibleeditbrowseboxcell.obj \ + $(SLO)$/textwindowaccessibility.obj \ + $(SLO)$/AccessibleGridControlBase.obj \ + $(SLO)$/AccessibleGridControl.obj \ + $(SLO)$/AccessibleGridControlTableBase.obj \ + $(SLO)$/AccessibleGridControlHeader.obj \ + $(SLO)$/AccessibleGridControlTableCell.obj \ + $(SLO)$/AccessibleGridControlHeaderCell.obj \ + $(SLO)$/AccessibleGridControlTable.obj \ + $(SLO)$/AccessibleToolPanelDeck.obj \ + $(SLO)$/AccessibleToolPanelDeckTabBar.obj \ + $(SLO)$/AccessibleToolPanelDeckTabBarItem.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/accessibility/source/extended/textwindowaccessibility.cxx b/accessibility/source/extended/textwindowaccessibility.cxx new file mode 100644 index 000000000000..5b669033fcfd --- /dev/null +++ b/accessibility/source/extended/textwindowaccessibility.cxx @@ -0,0 +1,2254 @@ +/************************************************************************* + * + * 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" + +#ifndef _TOOLKIT_AWT_VCLXACCESSIBLECOMPONENT_HXX_ +#include <accessibility/extended/textwindowaccessibility.hxx> +#endif +#include "comphelper/accessibleeventnotifier.hxx" +#include "unotools/accessiblerelationsethelper.hxx" +#include <unotools/accessiblestatesethelper.hxx> +#include <vcl/window.hxx> +#include <toolkit/helper/convert.hxx> + +#include <algorithm> +#include <vector> +#include <hash_map> + +namespace css = ::com::sun::star; + +namespace accessibility +{ + +// Both ::osl::Mutex and ParagraphBase implement acquire and release, and thus +// ::rtl::Reference< Paragraph > does not work. So ParagraphImpl was factored +// out and ::rtl::Reference< ParagraphImpl > is used instead. +class Paragraph: private ::osl::Mutex, public ParagraphImpl +{ +public: + inline Paragraph(::rtl::Reference< Document > const & rDocument, + Paragraphs::size_type nNumber): + ParagraphImpl(rDocument, nNumber, *this) {} +}; + +void SfxListenerGuard::startListening(::SfxBroadcaster & rNotifier) +{ + OSL_ENSURE(m_pNotifier == 0, "called more than once"); + m_pNotifier = &rNotifier; + m_rListener.StartListening(*m_pNotifier, true); +} + +void SfxListenerGuard::endListening() +{ + if (m_pNotifier != 0) + { + m_rListener.EndListening(*m_pNotifier); + m_pNotifier = 0; + } +} + +void WindowListenerGuard::startListening(::Window & rNotifier) +{ + OSL_ENSURE(m_pNotifier == 0, "called more than once"); + m_pNotifier = &rNotifier; + m_pNotifier->AddEventListener(m_aListener); +} + +void WindowListenerGuard::endListening() +{ + if (m_pNotifier != 0) + { + m_pNotifier->RemoveEventListener(m_aListener); + m_pNotifier = 0; + } +} + +ParagraphImpl::ParagraphImpl(::rtl::Reference< Document > const & rDocument, + Paragraphs::size_type nNumber, + ::osl::Mutex & rMutex): + ParagraphBase(rMutex), + m_xDocument(rDocument), + m_nNumber(nNumber), + m_nClientId(0) +{ + m_aParagraphText = m_xDocument->retrieveParagraphText(this); +} + +void +ParagraphImpl::numberChanged(bool bIncremented) +{ + if (bIncremented) + ++m_nNumber; + else + --m_nNumber; +} + +void ParagraphImpl::textChanged() +{ + ::rtl::OUString aParagraphText = implGetText(); + ::css::uno::Any aOldValue, aNewValue; + if ( implInitTextChangedEvent( m_aParagraphText, aParagraphText, aOldValue, aNewValue ) ) + { + m_aParagraphText = aParagraphText; + notifyEvent(::css::accessibility::AccessibleEventId:: + TEXT_CHANGED, + aOldValue, aNewValue); + } +} + +void ParagraphImpl::notifyEvent(::sal_Int16 nEventId, + ::css::uno::Any const & rOldValue, + ::css::uno::Any const & rNewValue) +{ + if (m_nClientId) + comphelper::AccessibleEventNotifier::addEvent( m_nClientId, ::css::accessibility::AccessibleEventObject( + static_cast< ::cppu::OWeakObject * >(this), + nEventId, rNewValue, rOldValue) ); +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessibleContext > SAL_CALL +ParagraphImpl::getAccessibleContext() throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return this; +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getAccessibleChildCount() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return 0; +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL +ParagraphImpl::getAccessibleChild(::sal_Int32) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " ParagraphImpl::getAccessibleChild")), + static_cast< ::css::uno::XWeak * >(this)); +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL +ParagraphImpl::getAccessibleParent() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->getAccessible(); +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getAccessibleIndexInParent() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveParagraphIndex(this); +} + +// virtual +::sal_Int16 SAL_CALL ParagraphImpl::getAccessibleRole() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return ::css::accessibility::AccessibleRole::PARAGRAPH; +} + +// virtual +::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleDescription() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return ::rtl::OUString(); +} + +// virtual +::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleName() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return ::rtl::OUString(); +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > +SAL_CALL ParagraphImpl::getAccessibleRelationSet() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveParagraphRelationSet( this ); +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessibleStateSet > +SAL_CALL ParagraphImpl::getAccessibleStateSet() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + + // FIXME Notification of changes (STATE_CHANGED) missing when + // m_rView.IsReadOnly() changes: + return new ::utl::AccessibleStateSetHelper( + m_xDocument->retrieveParagraphState(this)); +} + +// virtual +::css::lang::Locale SAL_CALL ParagraphImpl::getLocale() + throw (::css::accessibility::IllegalAccessibleComponentStateException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveLocale(); +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::containsPoint(::css::awt::Point const & rPoint) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + false)); + return rPoint.X >= 0 && rPoint.X < aRect.Width + && rPoint.Y >= 0 && rPoint.Y < aRect.Height; +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL +ParagraphImpl::getAccessibleAtPoint(::css::awt::Point const &) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return 0; +} + +// virtual +::css::awt::Rectangle SAL_CALL ParagraphImpl::getBounds() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveParagraphBounds(this, false); +} + +// virtual +::css::awt::Point SAL_CALL ParagraphImpl::getLocation() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + false)); + return ::css::awt::Point(aRect.X, aRect.Y); +} + +// virtual +::css::awt::Point SAL_CALL ParagraphImpl::getLocationOnScreen() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + true)); + return ::css::awt::Point(aRect.X, aRect.Y); +} + +// virtual +::css::awt::Size SAL_CALL ParagraphImpl::getSize() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + false)); + return ::css::awt::Size(aRect.Width, aRect.Height); +} + +// virtual +void SAL_CALL ParagraphImpl::grabFocus() throw (::css::uno::RuntimeException) +{ + checkDisposed(); + Window* pWindow = m_xDocument->GetWindow(); + if ( pWindow ) + { + pWindow->GrabFocus(); + } + try + { + m_xDocument->changeParagraphSelection(this, 0, 0); + } + catch (::css::lang::IndexOutOfBoundsException & rEx) + { + OSL_TRACE( + "textwindowaccessibility.cxx: ParagraphImpl::grabFocus:" + " caught unexpected %s\n", + ::rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_UTF8). + getStr()); + } +} + +// virtual +::css::uno::Any SAL_CALL ParagraphImpl::getAccessibleKeyBinding() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return ::css::uno::Any(); +} + +// virtual +::css::util::Color SAL_CALL ParagraphImpl::getForeground() + throw (::css::uno::RuntimeException) +{ + return 0; // TODO +} + +// virtual +::css::util::Color SAL_CALL ParagraphImpl::getBackground() + throw (::css::uno::RuntimeException) +{ + return 0; // TODO +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getCaretPosition() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveParagraphCaretPosition(this); +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::setCaretPosition(::sal_Int32 nIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphSelection(this, nIndex, nIndex); + return true; +} + +// virtual +::sal_Unicode SAL_CALL ParagraphImpl::getCharacter(::sal_Int32 nIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getCharacter(nIndex); +} + +// virtual +::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL +ParagraphImpl::getCharacterAttributes(::sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveCharacterAttributes( this, nIndex, aRequestedAttributes ); +} + +// virtual +::css::awt::Rectangle SAL_CALL +ParagraphImpl::getCharacterBounds(::sal_Int32 nIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + ::css::awt::Rectangle aBounds(m_xDocument->retrieveCharacterBounds(this, nIndex)); + ::css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false)); + aBounds.X -= aParaBounds.X; + aBounds.Y -= aParaBounds.Y; + return aBounds; +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getCharacterCount() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getCharacterCount(); +} + +// virtual +::sal_Int32 SAL_CALL +ParagraphImpl::getIndexAtPoint(::css::awt::Point const & rPoint) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + ::css::awt::Point aPoint(rPoint); + ::css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false)); + aPoint.X += aParaBounds.X; + aPoint.Y += aParaBounds.Y; + return m_xDocument->retrieveCharacterIndex(this, aPoint); +} + +// virtual +::rtl::OUString SAL_CALL ParagraphImpl::getSelectedText() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + + return OCommonAccessibleText::getSelectedText(); +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getSelectionStart() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getSelectionStart(); +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getSelectionEnd() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getSelectionEnd(); +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::setSelection(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphSelection(this, nStartIndex, nEndIndex); + return true; +} + +// virtual +::rtl::OUString SAL_CALL ParagraphImpl::getText() + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getText(); +} + +// virtual +::rtl::OUString SAL_CALL ParagraphImpl::getTextRange(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex); +} + +// virtual +::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getTextAtIndex(nIndex, aTextType); +} + +// virtual +::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getTextBeforeIndex(nIndex, aTextType); +} + +// virtual +::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + checkDisposed(); + return OCommonAccessibleText::getTextBehindIndex(nIndex, aTextType); +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::copyText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->copyParagraphText(this, nStartIndex, nEndIndex); + return true; +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::cutText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, true, false, + ::rtl::OUString()); + return true; +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::pasteText(::sal_Int32 nIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nIndex, nIndex, false, true, + ::rtl::OUString()); + return true; +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::deleteText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false, + ::rtl::OUString()); + return true; +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::insertText(::rtl::OUString const & rText, + ::sal_Int32 nIndex) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nIndex, nIndex, false, false, rText); + return true; +} + +// virtual +::sal_Bool SAL_CALL +ParagraphImpl::replaceText(::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, + ::rtl::OUString const & rReplacement) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false, + rReplacement); + return true; +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::setAttributes( + ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, + ::css::uno::Sequence< ::css::beans::PropertyValue > const & rAttributeSet) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphAttributes(this, nStartIndex, nEndIndex, + rAttributeSet); + return true; +} + +// virtual +::sal_Bool SAL_CALL ParagraphImpl::setText(::rtl::OUString const & rText) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, rText); + return true; +} + +// virtual +::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL +ParagraphImpl::getDefaultAttributes(const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveDefaultAttributes( this, RequestedAttributes ); +} + +// virtual +::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL +ParagraphImpl::getRunAttributes(::sal_Int32 Index, const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveRunAttributes( this, Index, RequestedAttributes ); +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getLineNumberAtIndex( ::sal_Int32 nIndex ) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + + ::sal_Int32 nLineNo = -1; + ::css::i18n::Boundary aBoundary = + m_xDocument->retrieveParagraphLineBoundary( this, nIndex, &nLineNo ); + + return nLineNo; +} + +// virtual +::css::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtLineNumber( ::sal_Int32 nLineNo ) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + checkDisposed(); + + ::css::i18n::Boundary aBoundary = + m_xDocument->retrieveParagraphBoundaryOfLine( this, nLineNo ); + + return ::css::accessibility::TextSegment( getTextRange(aBoundary.startPos, aBoundary.endPos), + aBoundary.startPos, aBoundary.endPos); +} + +// virtual +::css::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtLineWithCaret( ) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + + sal_Int32 nLineNo = getNumberOfLineWithCaret(); + + try { + return ( nLineNo >= 0 ) ? + getTextAtLineNumber( nLineNo ) : + ::css::accessibility::TextSegment(); + } catch (const ::css::lang::IndexOutOfBoundsException&) { + throw ::css::uno::RuntimeException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " ParagraphImpl::getTextAtLineWithCaret") ), + static_cast< ::css::uno::XWeak * >( this ) ); + } +} + +// virtual +::sal_Int32 SAL_CALL ParagraphImpl::getNumberOfLineWithCaret( ) + throw (::css::uno::RuntimeException) +{ + checkDisposed(); + return m_xDocument->retrieveParagraphLineWithCursor(this); +} + + +// virtual +void SAL_CALL ParagraphImpl::addEventListener( + ::css::uno::Reference< + ::css::accessibility::XAccessibleEventListener > const & rListener) + throw (::css::uno::RuntimeException) +{ + if (rListener.is()) + { + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + aGuard.clear(); + rListener->disposing(::css::lang::EventObject( + static_cast< ::cppu::OWeakObject * >(this))); + } + else + { + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, rListener ); + } + } +} + +// virtual +void SAL_CALL ParagraphImpl::removeEventListener( + ::css::uno::Reference< + ::css::accessibility::XAccessibleEventListener > const & rListener) + throw (::css::uno::RuntimeException) +{ + comphelper::AccessibleEventNotifier::TClientId nId = 0; + { + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rListener.is() && m_nClientId != 0 + && comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, rListener ) == 0) + { + nId = m_nClientId; + m_nClientId = 0; + } + } + if (nId != 0) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + comphelper::AccessibleEventNotifier::revokeClient(nId); + } +} + +// virtual +void SAL_CALL ParagraphImpl::disposing() +{ + comphelper::AccessibleEventNotifier::TClientId nId = 0; + { + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + nId = m_nClientId; + m_nClientId = 0; + } + if (nId != 0) + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(nId, *this); +} + +// virtual +::rtl::OUString ParagraphImpl::implGetText() +{ + return m_xDocument->retrieveParagraphText(this); +} + +// virtual +::css::lang::Locale ParagraphImpl::implGetLocale() +{ + return m_xDocument->retrieveLocale(); +} + +// virtual +void ParagraphImpl::implGetSelection(::sal_Int32 & rStartIndex, + ::sal_Int32 & rEndIndex) +{ + m_xDocument->retrieveParagraphSelection(this, &rStartIndex, &rEndIndex); +} + +// virtual +void ParagraphImpl::implGetParagraphBoundary( ::css::i18n::Boundary& rBoundary, + ::sal_Int32 nIndex ) +{ + ::rtl::OUString sText( implGetText() ); + ::sal_Int32 nLength = sText.getLength(); + + if ( implIsValidIndex( nIndex, nLength ) ) + { + rBoundary.startPos = 0; + rBoundary.endPos = nLength; + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } +} + +// virtual +void ParagraphImpl::implGetLineBoundary( ::css::i18n::Boundary& rBoundary, + ::sal_Int32 nIndex ) +{ + ::rtl::OUString sText( implGetText() ); + ::sal_Int32 nLength = sText.getLength(); + + if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength ) + { + ::css::i18n::Boundary aBoundary = + m_xDocument->retrieveParagraphLineBoundary( this, nIndex ); + rBoundary.startPos = aBoundary.startPos; + rBoundary.endPos = aBoundary.endPos; + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } +} + + +void ParagraphImpl::checkDisposed() +{ + ::osl::MutexGuard aGuard(rBHelper.rMutex); + if (!(rBHelper.bDisposed || rBHelper.bInDispose)) + return; + throw ::css::lang::DisposedException( + ::rtl::OUString(), static_cast< ::css::uno::XWeak * >(this)); +} + +Document::Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine, + ::TextView & rView, bool bCompoundControlChild): + VCLXAccessibleComponent(pVclXWindow), + m_xAccessible(pVclXWindow), + m_rEngine(rEngine), + m_rView(rView), + m_aEngineListener(*this), + m_aViewListener(LINK(this, Document, WindowEventHandler)), + m_bCompoundControlChild(bCompoundControlChild) +{} + +::css::lang::Locale Document::retrieveLocale() +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + return m_rEngine.GetLocale(); +} + +::sal_Int32 Document::retrieveParagraphIndex(ParagraphImpl const * pParagraph) +{ + ::osl::MutexGuard aInternalGuard(GetMutex()); + + // If a client holds on to a Paragraph that is no longer visible, it can + // happen that this Paragraph lies outside the range from m_aVisibleBegin + // to m_aVisibleEnd. In that case, return -1 instead of a valid index: + Paragraphs::iterator aPara(m_xParagraphs->begin() + + pParagraph->getNumber()); + return aPara < m_aVisibleBegin || aPara >= m_aVisibleEnd + ? -1 : static_cast< ::sal_Int32 >(aPara - m_aVisibleBegin); + // XXX numeric overflow +} + +::sal_Int64 Document::retrieveParagraphState(ParagraphImpl const * pParagraph) +{ + ::osl::MutexGuard aInternalGuard(GetMutex()); + + // If a client holds on to a Paragraph that is no longer visible, it can + // happen that this Paragraph lies outside the range from m_aVisibleBegin + // to m_aVisibleEnd. In that case, it is neither VISIBLE nor SHOWING: + ::sal_Int64 nState + = (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::ENABLED) + | (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::SENSITIVE) + | (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::FOCUSABLE) + | (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::MULTI_LINE); + if (!m_rView.IsReadOnly()) + nState |= (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::EDITABLE); + Paragraphs::iterator aPara(m_xParagraphs->begin() + + pParagraph->getNumber()); + if (aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd) + { + nState + |= (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::VISIBLE) + | (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::SHOWING); + if (aPara == m_aFocused) + nState |= (static_cast< ::sal_Int64 >(1) + << ::css::accessibility::AccessibleStateType::FOCUSED); + } + return nState; +}; + +::css::awt::Rectangle +Document::retrieveParagraphBounds(ParagraphImpl const * pParagraph, + bool bAbsolute) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + + // If a client holds on to a Paragraph that is no longer visible (as it + // scrolled out the top of the view), it can happen that this Paragraph + // lies before m_aVisibleBegin. In that case, calculate the vertical + // position of the Paragraph starting at paragraph 0, otherwise optimize + // and start at m_aVisibleBegin: + Paragraphs::iterator aPara(m_xParagraphs->begin() + + pParagraph->getNumber()); + ::sal_Int32 nPos; + Paragraphs::iterator aIt; + if (aPara < m_aVisibleBegin) + { + nPos = 0; + aIt = m_xParagraphs->begin(); + } + else + { + nPos = m_nViewOffset - m_nVisibleBeginOffset; + aIt = m_aVisibleBegin; + } + for (; aIt != aPara; ++aIt) + nPos += aIt->getHeight(); + + Point aOrig(0, 0); + if (bAbsolute) + aOrig = m_rView.GetWindow()->OutputToAbsoluteScreenPixel(aOrig); + + return ::css::awt::Rectangle( + static_cast< ::sal_Int32 >(aOrig.X()), + static_cast< ::sal_Int32 >(aOrig.Y()) + nPos - m_nViewOffset, + m_rView.GetWindow()->GetOutputSizePixel().Width(), aPara->getHeight()); + // XXX numeric overflow (3x) +} + +::rtl::OUString +Document::retrieveParagraphText(ParagraphImpl const * pParagraph) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + return m_rEngine.GetText(static_cast< ::sal_uLong >(pParagraph->getNumber())); + // numeric overflow cannot happen here +} + +void Document::retrieveParagraphSelection(ParagraphImpl const * pParagraph, + ::sal_Int32 * pBegin, + ::sal_Int32 * pEnd) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::TextSelection const & rSelection = m_rView.GetSelection(); + Paragraphs::size_type nNumber = pParagraph->getNumber(); + TextPaM aStartPaM( rSelection.GetStart() ); + TextPaM aEndPaM( rSelection.GetEnd() ); + TextPaM aMinPaM( ::std::min( aStartPaM, aEndPaM ) ); + TextPaM aMaxPaM( ::std::max( aStartPaM, aEndPaM ) ); + + if ( nNumber >= aMinPaM.GetPara() && nNumber <= aMaxPaM.GetPara() ) + { + *pBegin = nNumber > aMinPaM.GetPara() + ? 0 + : static_cast< ::sal_Int32 >( aMinPaM.GetIndex() ); + // XXX numeric overflow + *pEnd = nNumber < aMaxPaM.GetPara() + ? static_cast< ::sal_Int32 >( m_rEngine.GetText(static_cast< ::sal_uLong >(nNumber)).Len() ) + : static_cast< ::sal_Int32 >( aMaxPaM.GetIndex() ); + // XXX numeric overflow (3x) + + if ( aStartPaM > aEndPaM ) + ::std::swap( *pBegin, *pEnd ); + } + else + { + *pBegin = 0; + *pEnd = 0; + } +} + +::sal_Int32 Document::retrieveParagraphCaretPosition(ParagraphImpl const * pParagraph) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::TextSelection const & rSelection = m_rView.GetSelection(); + Paragraphs::size_type nNumber = pParagraph->getNumber(); + TextPaM aEndPaM( rSelection.GetEnd() ); + + return aEndPaM.GetPara() == nNumber + ? static_cast< ::sal_Int32 >(aEndPaM.GetIndex()) : -1; +} + +::css::awt::Rectangle +Document::retrieveCharacterBounds(ParagraphImpl const * pParagraph, + ::sal_Int32 nIndex) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + sal_Int32 nLength = m_rEngine.GetText(nNumber).Len(); + // XXX numeric overflow + if (nIndex < 0 || nIndex > nLength) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::retrieveCharacterAttributes")), + static_cast< ::css::uno::XWeak * >(this)); + ::css::awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( nIndex == nLength ) + { + aBounds = AWTRectangle( + m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, + static_cast< ::sal_uInt16 >(nIndex)))); + } + else + { + ::Rectangle aLeft( + m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, + static_cast< ::sal_uInt16 >(nIndex)))); + // XXX numeric overflow + ::Rectangle aRight( + m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, + static_cast< ::sal_uInt16 >(nIndex) + + 1))); + // XXX numeric overflow (2x) + // FIXME If the vertical extends of the two cursors do not match, assume + // nIndex is the last character on the line; the bounding box will then + // extend to m_rEnginge.GetMaxTextWidth(): + ::sal_Int32 nWidth = (aLeft.Top() == aRight.Top() + && aLeft.Bottom() == aRight.Bottom()) + ? static_cast< ::sal_Int32 >(aRight.Left() - aLeft.Left()) + : static_cast< ::sal_Int32 >(m_rEngine.GetMaxTextWidth() + - aLeft.Left()); + // XXX numeric overflow (4x) + aBounds = ::css::awt::Rectangle(static_cast< ::sal_Int32 >(aLeft.Left()), + static_cast< ::sal_Int32 >(aLeft.Top() - m_nViewOffset), + nWidth, + static_cast< ::sal_Int32 >(aLeft.Bottom() + - aLeft.Top())); + // XXX numeric overflow (4x) + } + return aBounds; +} + +::sal_Int32 Document::retrieveCharacterIndex(ParagraphImpl const * pParagraph, + ::css::awt::Point const & rPoint) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + ::TextPaM aPaM(m_rEngine.GetPaM(::Point(static_cast< long >(rPoint.X), + static_cast< long >(rPoint.Y)))); + // XXX numeric overflow (2x) + return aPaM.GetPara() == nNumber + ? static_cast< ::sal_Int32 >(aPaM.GetIndex()) : -1; + // XXX numeric overflow +} + +::css::uno::Sequence< ::css::beans::PropertyValue > +Document::retrieveCharacterAttributes( + ParagraphImpl const * pParagraph, ::sal_Int32 nIndex, + const ::css::uno::Sequence< ::rtl::OUString >& aRequestedAttributes) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + if (nIndex < 0 || nIndex >= m_rEngine.GetText(nNumber).Len()) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::retrieveCharacterAttributes")), + static_cast< ::css::uno::XWeak * >(this)); + + // retrieve default attributes + tPropValMap aCharAttrSeq; + retrieveDefaultAttributesImpl( pParagraph, aRequestedAttributes, aCharAttrSeq ); + + // retrieve run attributes + tPropValMap aRunAttrSeq; + retrieveRunAttributesImpl( pParagraph, nIndex, aRequestedAttributes, aRunAttrSeq ); + + // merge default and run attributes + for ( tPropValMap::const_iterator aRunIter = aRunAttrSeq.begin(); + aRunIter != aRunAttrSeq.end(); + ++aRunIter ) + { + aCharAttrSeq[ aRunIter->first ] = aRunIter->second; + } + + return convertHashMapToSequence( aCharAttrSeq ); +} + +void Document::retrieveDefaultAttributesImpl( + ParagraphImpl const * pParagraph, + const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes, + tPropValMap& rDefAttrSeq) +{ + // default attributes are not supported by text engine + (void) pParagraph; + (void) RequestedAttributes; + (void) rDefAttrSeq; +} + +::css::uno::Sequence< ::css::beans::PropertyValue > +Document::retrieveDefaultAttributes( + ParagraphImpl const * pParagraph, + const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); + ::osl::MutexGuard aInternalGuard( GetMutex() ); + + tPropValMap aDefAttrSeq; + retrieveDefaultAttributesImpl( pParagraph, RequestedAttributes, aDefAttrSeq ); + return convertHashMapToSequence( aDefAttrSeq ); +} + +// static +::css::uno::Sequence< ::css::beans::PropertyValue > +Document::convertHashMapToSequence(tPropValMap& rAttrSeq) +{ + ::css::uno::Sequence< ::css::beans::PropertyValue > aValues( rAttrSeq.size() ); + ::css::beans::PropertyValue* pValues = aValues.getArray(); + ::sal_Int32 i = 0; + for ( tPropValMap::const_iterator aIter = rAttrSeq.begin(); + aIter != rAttrSeq.end(); + ++aIter ) + { + pValues[i] = aIter->second; + ++i; + } + return aValues; +} + +void Document::retrieveRunAttributesImpl( + ParagraphImpl const * pParagraph, ::sal_Int32 Index, + const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes, + tPropValMap& rRunAttrSeq) +{ + ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); + ::TextPaM aPaM( nNumber, static_cast< ::sal_uInt16 >( Index ) ); + // XXX numeric overflow + // FIXME TEXTATTR_HYPERLINK ignored: + ::TextAttribFontColor const * pColor + = static_cast< ::TextAttribFontColor const * >( + m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTCOLOR ) ); + ::TextAttribFontWeight const * pWeight + = static_cast< ::TextAttribFontWeight const * >( + m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTWEIGHT ) ); + tPropValMap aRunAttrSeq; + if ( pColor ) + { + ::css::beans::PropertyValue aPropVal; + aPropVal.Name = + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ); + aPropVal.Handle = -1; + aPropVal.Value = mapFontColor( pColor->GetColor() ); + aPropVal.State = ::css::beans::PropertyState_DIRECT_VALUE; + aRunAttrSeq[ aPropVal.Name ] = aPropVal; + } + if ( pWeight ) + { + ::css::beans::PropertyValue aPropVal; + aPropVal.Name = + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ); + aPropVal.Handle = -1; + aPropVal.Value = mapFontWeight( pWeight->getFontWeight() ); + aPropVal.State = ::css::beans::PropertyState_DIRECT_VALUE; + aRunAttrSeq[ aPropVal.Name ] = aPropVal; + } + if ( RequestedAttributes.getLength() == 0 ) + { + rRunAttrSeq = aRunAttrSeq; + } + else + { + const ::rtl::OUString* pReqAttrs = RequestedAttributes.getConstArray(); + const ::sal_Int32 nLength = RequestedAttributes.getLength(); + for ( ::sal_Int32 i = 0; i < nLength; ++i ) + { + tPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] ); + if ( aIter != aRunAttrSeq.end() ) + { + rRunAttrSeq[ (*aIter).first ] = (*aIter).second; + } + } + } +} + +::css::uno::Sequence< ::css::beans::PropertyValue > +Document::retrieveRunAttributes( + ParagraphImpl const * pParagraph, ::sal_Int32 Index, + const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); + ::osl::MutexGuard aInternalGuard( GetMutex() ); + ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); + // XXX numeric overflow + if ( Index < 0 || Index >= m_rEngine.GetText(nNumber).Len() ) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::retrieveRunAttributes") ), + static_cast< ::css::uno::XWeak * >( this ) ); + + tPropValMap aRunAttrSeq; + retrieveRunAttributesImpl( pParagraph, Index, RequestedAttributes, aRunAttrSeq ); + return convertHashMapToSequence( aRunAttrSeq ); +} + +void Document::changeParagraphText(ParagraphImpl * pParagraph, + ::rtl::OUString const & rText) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + changeParagraphText(nNumber, 0, m_rEngine.GetTextLen(nNumber), false, + false, rText); + } +} + +void Document::changeParagraphText(ParagraphImpl * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd, + bool bCut, bool bPaste, + ::rtl::OUString const & rText) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).Len()) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::changeParagraphText")), + static_cast< ::css::uno::XWeak * >(this)); + changeParagraphText(nNumber, static_cast< ::sal_uInt16 >(nBegin), + static_cast< ::sal_uInt16 >(nEnd), bCut, bPaste, rText); + // XXX numeric overflow (2x) + } +} + +void Document::copyParagraphText(ParagraphImpl const * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).Len()) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::copyParagraphText")), + static_cast< ::css::uno::XWeak * >(this)); + m_rView.SetSelection( + ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)), + ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd)))); + // XXX numeric overflow (2x) + m_rView.Copy(); + } +} + +void Document::changeParagraphAttributes( + ParagraphImpl * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd, + ::css::uno::Sequence< ::css::beans::PropertyValue > const & rAttributeSet) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).Len()) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::changeParagraphAttributes")), + static_cast< ::css::uno::XWeak * >(this)); + + // FIXME The new attributes are added to any attributes already set, + // they do not replace the old attributes as required by + // XAccessibleEditableText.setAttributes: + for (::sal_Int32 i = 0; i < rAttributeSet.getLength(); ++i) + if (rAttributeSet[i].Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("CharColor"))) + m_rEngine.SetAttrib(::TextAttribFontColor( + mapFontColor(rAttributeSet[i].Value)), + nNumber, static_cast< ::sal_uInt16 >(nBegin), + static_cast< ::sal_uInt16 >(nEnd)); + // XXX numeric overflow (2x) + else if (rAttributeSet[i].Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("CharWeight"))) + m_rEngine.SetAttrib(::TextAttribFontWeight( + mapFontWeight(rAttributeSet[i].Value)), + nNumber, static_cast< ::sal_uInt16 >(nBegin), + static_cast< ::sal_uInt16 >(nEnd)); + // XXX numeric overflow (2x) + } +} + +void Document::changeParagraphSelection(ParagraphImpl * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).Len()) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::changeParagraphSelection")), + static_cast< ::css::uno::XWeak * >(this)); + m_rView.SetSelection( + ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)), + ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd)))); + // XXX numeric overflow (2x) + } +} + +::css::i18n::Boundary +Document::retrieveParagraphLineBoundary( ParagraphImpl const * pParagraph, + ::sal_Int32 nIndex, ::sal_Int32 *pLineNo ) +{ + ::css::i18n::Boundary aBoundary; + aBoundary.startPos = nIndex; + aBoundary.endPos = nIndex; + + ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); + { + ::osl::MutexGuard aInternalGuard( GetMutex() ); + ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); + if ( nIndex < 0 || nIndex > m_rEngine.GetText( nNumber ).Len() ) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::retrieveParagraphLineBoundary" ) ), + static_cast< ::css::uno::XWeak * >( this ) ); + ::sal_Int32 nLineStart = 0; + ::sal_Int32 nLineEnd = 0; + ::sal_uInt16 nLineCount = m_rEngine.GetLineCount( nNumber ); + for ( ::sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine ) + { + ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >( + m_rEngine.GetLineLen( nNumber, nLine ) ); + nLineStart = nLineEnd; + nLineEnd += nLineLength; + if ( nIndex >= nLineStart && ( ( nLine == nLineCount - 1 ) ? nIndex <= nLineEnd : nIndex < nLineEnd ) ) + { + aBoundary.startPos = nLineStart; + aBoundary.endPos = nLineEnd; + if( pLineNo ) + pLineNo[0] = nLine; + break; + } + } + } + + return aBoundary; +} + +::css::i18n::Boundary +Document::retrieveParagraphBoundaryOfLine( ParagraphImpl const * pParagraph, + ::sal_Int32 nLineNo ) +{ + ::css::i18n::Boundary aBoundary; + aBoundary.startPos = 0; + aBoundary.endPos = 0; + + ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); + { + ::osl::MutexGuard aInternalGuard( GetMutex() ); + ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); + if ( nLineNo >= m_rEngine.GetLineCount( nNumber ) ) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::retrieveParagraphBoundaryOfLine" ) ), + static_cast< ::css::uno::XWeak * >( this ) ); + ::sal_Int32 nLineStart = 0; + ::sal_Int32 nLineEnd = 0; + for ( ::sal_uInt16 nLine = 0; nLine <= nLineNo; ++nLine ) + { + ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >( + m_rEngine.GetLineLen( nNumber, nLine ) ); + nLineStart = nLineEnd; + nLineEnd += nLineLength; + } + + aBoundary.startPos = nLineStart; + aBoundary.endPos = nLineEnd; + } + + return aBoundary; +} + +sal_Int32 Document::retrieveParagraphLineWithCursor( ParagraphImpl const * pParagraph ) +{ + ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::TextSelection const & rSelection = m_rView.GetSelection(); + Paragraphs::size_type nNumber = pParagraph->getNumber(); + TextPaM aEndPaM( rSelection.GetEnd() ); + + return aEndPaM.GetPara() == nNumber + ? m_rView.GetLineNumberOfCursorInSelection() : -1; +} + + +::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > +Document::retrieveParagraphRelationSet( ParagraphImpl const * pParagraph ) +{ + ::osl::MutexGuard aInternalGuard( GetMutex() ); + + ::utl::AccessibleRelationSetHelper* pRelationSetHelper = new ::utl::AccessibleRelationSetHelper(); + ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; + + Paragraphs::iterator aPara( m_xParagraphs->begin() + pParagraph->getNumber() ); + + if ( aPara > m_aVisibleBegin && aPara < m_aVisibleEnd ) + { + ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1); + aSequence[0] = getAccessibleChild( aPara - 1 ); + ::css::accessibility::AccessibleRelation aRelation( ::css::accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM, aSequence ); + pRelationSetHelper->AddRelation( aRelation ); + } + + if ( aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd -1 ) + { + ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1); + aSequence[0] = getAccessibleChild( aPara + 1 ); + ::css::accessibility::AccessibleRelation aRelation( ::css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence ); + pRelationSetHelper->AddRelation( aRelation ); + } + + return xSet; +} + +void Document::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_WINDOW_GETFOCUS: + case VCLEVENT_WINDOW_LOSEFOCUS: + { + // #107179# if our parent is a compound control (e.g. MultiLineEdit), + // suppress the window focus events here + if ( !m_bCompoundControlChild ) + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + +// virtual +::sal_Int32 SAL_CALL Document::getAccessibleChildCount() + throw (::css::uno::RuntimeException) +{ + ::comphelper::OExternalLockGuard aGuard(this); + init(); + return m_aVisibleEnd - m_aVisibleBegin; +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL +Document::getAccessibleChild(::sal_Int32 i) + throw (::css::lang::IndexOutOfBoundsException, + ::css::uno::RuntimeException) +{ + ::comphelper::OExternalLockGuard aGuard(this); + init(); + if (i < 0 || i >= m_aVisibleEnd - m_aVisibleBegin) + throw ::css::lang::IndexOutOfBoundsException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "textwindowaccessibility.cxx:" + " Document::getAccessibleChild")), + static_cast< ::css::uno::XWeak * >(this)); + return getAccessibleChild(m_aVisibleBegin + + static_cast< Paragraphs::size_type >(i)); +} + +// virtual +::sal_Int16 SAL_CALL Document::getAccessibleRole() + throw (::css::uno::RuntimeException) +{ + return ::css::accessibility::AccessibleRole::TEXT_FRAME; +} + +// virtual +::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL +Document::getAccessibleAtPoint(::css::awt::Point const & rPoint) + throw (::css::uno::RuntimeException) +{ + ::comphelper::OExternalLockGuard aGuard(this); + init(); + if (rPoint.X >= 0 + && rPoint.X < m_rView.GetWindow()->GetOutputSizePixel().Width() + && rPoint.Y >= 0 && rPoint.Y < m_nViewHeight) + { + ::sal_Int32 nOffset = m_nViewOffset + rPoint.Y; // XXX numeric overflow + ::sal_Int32 nPos = m_nViewOffset - m_nVisibleBeginOffset; + for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd; + ++aIt) + { + nPos += aIt->getHeight(); // XXX numeric overflow + if (nOffset < nPos) + return getAccessibleChild(aIt); + } + } + return 0; +} + +// virtual +void SAL_CALL Document::disposing() +{ + m_aEngineListener.endListening(); + m_aViewListener.endListening(); + if (m_xParagraphs.get() != 0) + disposeParagraphs(); + VCLXAccessibleComponent::disposing(); +} + +// virtual +void Document::Notify(::SfxBroadcaster &, ::SfxHint const & rHint) +{ + if (rHint.ISA(::TextHint)) + { + ::TextHint const & rTextHint + = static_cast< ::TextHint const & >(rHint); + switch (rTextHint.GetId()) + { + case TEXT_HINT_PARAINSERTED: + case TEXT_HINT_PARAREMOVED: + // TEXT_HINT_PARAINSERTED and TEXT_HINT_PARAREMOVED are sent at + // "unsafe" times (when the text engine has not yet re-formatted its + // content), so that for example calling ::TextEngine::GetTextHeight + // from within the code that handles TEXT_HINT_PARAINSERTED causes + // trouble within the text engine. Therefore, these hints are just + // buffered until a following ::TextEngine::FormatDoc causes a + // TEXT_HINT_TEXTFORMATTED to come in: + case TEXT_HINT_FORMATPARA: + // ::TextEngine::FormatDoc sends a sequence of + // TEXT_HINT_FORMATPARAs, followed by an optional + // TEXT_HINT_TEXTHEIGHTCHANGED, followed in all cases by one + // TEXT_HINT_TEXTFORMATTED. Only the TEXT_HINT_FORMATPARAs contain + // the the numbers of the affected paragraphs, but they are sent + // before the changes are applied. Therefore, TEXT_HINT_FORMATPARAs + // are just buffered until another hint comes in: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + m_aParagraphNotifications.push(rTextHint); + break; + } + case TEXT_HINT_TEXTFORMATTED: + case TEXT_HINT_TEXTHEIGHTCHANGED: + case TEXT_HINT_MODIFIED: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + handleParagraphNotifications(); + break; + } + case TEXT_HINT_VIEWSCROLLED: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + handleParagraphNotifications(); + + ::sal_Int32 nOffset = static_cast< ::sal_Int32 >( + m_rView.GetStartDocPos().Y()); + // XXX numeric overflow + if (nOffset != m_nViewOffset) + { + m_nViewOffset = nOffset; + + Paragraphs::iterator aOldVisibleBegin( + m_aVisibleBegin); + Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); + + determineVisibleRange(); + + notifyVisibleRangeChanges(aOldVisibleBegin, + aOldVisibleEnd, + m_xParagraphs->end()); + } + break; + } + case TEXT_HINT_VIEWSELECTIONCHANGED: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + if (m_aParagraphNotifications.empty()) + { + handleSelectionChangeNotification(); + } + else + { + // TEXT_HINT_VIEWSELECTIONCHANGED is sometimes sent at + // "unsafe" times (when the text engine has not yet re- + // formatted its content), so that for example calling + // ::TextEngine::GetTextHeight from within the code that + // handles a previous TEXT_HINT_PARAINSERTED causes + // trouble within the text engine. Therefore, these + // hints are just buffered (along with + // TEXT_HINT_PARAINSERTED/REMOVED/FORMATPARA) until a + // following ::TextEngine::FormatDoc causes a + // TEXT_HINT_TEXTFORMATTED to come in: + m_bSelectionChangedNotification = true; + } + break; + } + } + } +} + +IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent) +{ + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_RESIZE: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + ::sal_Int32 nHeight = static_cast< ::sal_Int32 >( + m_rView.GetWindow()->GetOutputSizePixel().Height()); + // XXX numeric overflow + if (nHeight != m_nViewHeight) + { + m_nViewHeight = nHeight; + + Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin); + Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); + + determineVisibleRange(); + + notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd, + m_xParagraphs->end()); + } + break; + } + case VCLEVENT_WINDOW_GETFOCUS: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) + { + ::rtl::Reference< ParagraphImpl > xParagraph( + getParagraph(m_aFocused)); + if (xParagraph.is()) + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + STATE_CHANGED, + ::css::uno::Any(), + ::css::uno::makeAny( + ::css::accessibility::AccessibleStateType:: + FOCUSED)); + } + break; + } + case VCLEVENT_WINDOW_LOSEFOCUS: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) + { + ::rtl::Reference< ParagraphImpl > xParagraph( + getParagraph(m_aFocused)); + if (xParagraph.is()) + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + STATE_CHANGED, + ::css::uno::makeAny( + ::css::accessibility::AccessibleStateType:: + FOCUSED), + ::css::uno::Any()); + } + break; + } + } + return 0; +} + +void Document::init() +{ + if (m_xParagraphs.get() == 0) + { + ::sal_uLong nCount = m_rEngine.GetParagraphCount(); + ::std::auto_ptr< Paragraphs > p(new Paragraphs); + p->reserve(static_cast< Paragraphs::size_type >(nCount)); + // numeric overflow is harmless here + for (::sal_uLong i = 0; i < nCount; ++i) + p->push_back(ParagraphInfo(static_cast< ::sal_Int32 >( + m_rEngine.GetTextHeight(i)))); + // XXX numeric overflow + m_nViewOffset = static_cast< ::sal_Int32 >( + m_rView.GetStartDocPos().Y()); // XXX numeric overflow + m_nViewHeight = static_cast< ::sal_Int32 >( + m_rView.GetWindow()->GetOutputSizePixel().Height()); + // XXX numeric overflow + m_xParagraphs = p; + determineVisibleRange(); + m_nSelectionFirstPara = -1; + m_nSelectionFirstPos = -1; + m_nSelectionLastPara = -1; + m_nSelectionLastPos = -1; + m_aFocused = m_xParagraphs->end(); + m_bSelectionChangedNotification = false; + m_aEngineListener.startListening(m_rEngine); + m_aViewListener.startListening(*m_rView.GetWindow()); + } +} + +::rtl::Reference< ParagraphImpl > +Document::getParagraph(Paragraphs::iterator const & rIt) +{ + return static_cast< ParagraphImpl * >( + ::css::uno::Reference< ::css::accessibility::XAccessible >( + rIt->getParagraph()).get()); +} + +::css::uno::Reference< ::css::accessibility::XAccessible > +Document::getAccessibleChild(Paragraphs::iterator const & rIt) +{ + ::css::uno::Reference< ::css::accessibility::XAccessible > xParagraph( + rIt->getParagraph()); + if (!xParagraph.is()) + { + xParagraph = new Paragraph(this, rIt - m_xParagraphs->begin()); + rIt->setParagraph(xParagraph); + } + return xParagraph; +} + +void Document::determineVisibleRange() +{ + m_aVisibleBegin = m_xParagraphs->end(); + m_aVisibleEnd = m_aVisibleBegin; + ::sal_Int32 nPos = 0; + for (Paragraphs::iterator aIt = m_xParagraphs->begin();;) + { + if (aIt == m_xParagraphs->end()) + { + m_nVisibleBeginOffset = 0; + break; + } + ::sal_Int32 nOldPos = nPos; + nPos += aIt->getHeight(); // XXX numeric overflow + if (m_aVisibleBegin == m_xParagraphs->end() && nPos >= m_nViewOffset) + { + m_aVisibleBegin = aIt; + m_nVisibleBeginOffset = m_nViewOffset - nOldPos; + } + ++aIt; + if (m_aVisibleBegin != m_xParagraphs->end() + && (aIt == m_xParagraphs->end() + || nPos >= m_nViewOffset + m_nViewHeight)) + // XXX numeric overflow + { + m_aVisibleEnd = aIt; + break; + } + } +} + +void Document::notifyVisibleRangeChanges( + Paragraphs::iterator const & rOldVisibleBegin, + Paragraphs::iterator const & rOldVisibleEnd, + Paragraphs::iterator const & rInserted) +{ + // XXX Replace this code that determines which paragraphs have changed from + // invisible to visible or vice versa with a better algorithm. + {for (Paragraphs::iterator aIt(rOldVisibleBegin); aIt != rOldVisibleEnd; + ++aIt) + if (aIt != rInserted + && (aIt < m_aVisibleBegin || aIt >= m_aVisibleEnd)) + NotifyAccessibleEvent( + ::css::accessibility::AccessibleEventId:: + CHILD, + ::css::uno::makeAny(getAccessibleChild(aIt)), + ::css::uno::Any()); + } + {for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd; + ++aIt) + if (aIt == rInserted + || aIt < rOldVisibleBegin || aIt >= rOldVisibleEnd) + NotifyAccessibleEvent( + ::css::accessibility::AccessibleEventId:: + CHILD, + ::css::uno::Any(), + ::css::uno::makeAny(getAccessibleChild(aIt))); + } +} + +void +Document::changeParagraphText(::sal_uLong nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd, + bool bCut, bool bPaste, + ::rtl::OUString const & rText) +{ + m_rView.SetSelection(::TextSelection(::TextPaM(nNumber, nBegin), + ::TextPaM(nNumber, nEnd))); + if (bCut) + m_rView.Cut(); + else if (nBegin != nEnd) + m_rView.DeleteSelected(); + if (bPaste) + m_rView.Paste(); + else if (rText.getLength() != 0) + m_rView.InsertText(rText); +} + +void Document::handleParagraphNotifications() +{ + while (!m_aParagraphNotifications.empty()) + { + ::TextHint aHint(m_aParagraphNotifications.front()); + m_aParagraphNotifications.pop(); + switch (aHint.GetId()) + { + case TEXT_HINT_PARAINSERTED: + { + ::sal_uLong n = aHint.GetValue(); + OSL_ENSURE(n <= m_xParagraphs->size(), + "bad TEXT_HINT_PARAINSERTED event"); + + // Save the values of old iterators (the iterators themselves + // will get invalidated), and adjust the old values so that they + // reflect the insertion of the new paragraph: + Paragraphs::size_type nOldVisibleBegin + = m_aVisibleBegin - m_xParagraphs->begin(); + Paragraphs::size_type nOldVisibleEnd + = m_aVisibleEnd - m_xParagraphs->begin(); + Paragraphs::size_type nOldFocused + = m_aFocused - m_xParagraphs->begin(); + if (n <= nOldVisibleBegin) + ++nOldVisibleBegin; // XXX numeric overflow + if (n <= nOldVisibleEnd) + ++nOldVisibleEnd; // XXX numeric overflow + if (n <= nOldFocused) + ++nOldFocused; // XXX numeric overflow + if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionFirstPara) + ++m_nSelectionFirstPara; // XXX numeric overflow + if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionLastPara) + ++m_nSelectionLastPara; // XXX numeric overflow + + Paragraphs::iterator aIns( + m_xParagraphs->insert( + m_xParagraphs->begin() + n, + ParagraphInfo(static_cast< ::sal_Int32 >( + m_rEngine.GetTextHeight(n))))); + // XXX numeric overflow (2x) + + determineVisibleRange(); + m_aFocused = m_xParagraphs->begin() + nOldFocused; + + for (Paragraphs::iterator aIt(aIns);;) + { + ++aIt; + if (aIt == m_xParagraphs->end()) + break; + ::rtl::Reference< ParagraphImpl > xParagraph( + getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->numberChanged(true); + } + + notifyVisibleRangeChanges( + m_xParagraphs->begin() + nOldVisibleBegin, + m_xParagraphs->begin() + nOldVisibleEnd, aIns); + break; + } + case TEXT_HINT_PARAREMOVED: + { + ::sal_uLong n = aHint.GetValue(); + if (n == TEXT_PARA_ALL) + { + {for (Paragraphs::iterator aIt(m_aVisibleBegin); + aIt != m_aVisibleEnd; ++aIt) + NotifyAccessibleEvent( + ::css::accessibility::AccessibleEventId:: + CHILD, + ::css::uno::makeAny(getAccessibleChild(aIt)), + ::css::uno::Any()); + } + disposeParagraphs(); + m_xParagraphs->clear(); + determineVisibleRange(); + m_nSelectionFirstPara = -1; + m_nSelectionFirstPos = -1; + m_nSelectionLastPara = -1; + m_nSelectionLastPos = -1; + m_aFocused = m_xParagraphs->end(); + } + else + { + OSL_ENSURE(n < m_xParagraphs->size(), + "Bad TEXT_HINT_PARAREMOVED event"); + + Paragraphs::iterator aIt(m_xParagraphs->begin() + n); + // numeric overflow cannot occur + + // Save the values of old iterators (the iterators + // themselves will get invalidated), and adjust the old + // values so that they reflect the removal of the paragraph: + Paragraphs::size_type nOldVisibleBegin + = m_aVisibleBegin - m_xParagraphs->begin(); + Paragraphs::size_type nOldVisibleEnd + = m_aVisibleEnd - m_xParagraphs->begin(); + bool bWasVisible + = nOldVisibleBegin <= n && n < nOldVisibleEnd; + Paragraphs::size_type nOldFocused + = m_aFocused - m_xParagraphs->begin(); + bool bWasFocused = aIt == m_aFocused; + if (n < nOldVisibleBegin) + --nOldVisibleBegin; + if (n < nOldVisibleEnd) + --nOldVisibleEnd; + if (n < nOldFocused) + --nOldFocused; + if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionFirstPara) + --m_nSelectionFirstPara; + else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionFirstPara) + { + if (m_nSelectionFirstPara == m_nSelectionLastPara) + { + m_nSelectionFirstPara = -1; + m_nSelectionFirstPos = -1; + m_nSelectionLastPara = -1; + m_nSelectionLastPos = -1; + } + else + { + ++m_nSelectionFirstPara; + m_nSelectionFirstPos = 0; + } + } + if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionLastPara) + --m_nSelectionLastPara; + else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionLastPara) + { + OSL_ENSURE(m_nSelectionFirstPara < m_nSelectionLastPara, + "logic error"); + --m_nSelectionLastPara; + m_nSelectionLastPos = 0x7FFFFFFF; + } + + ::css::uno::Reference< ::css::accessibility::XAccessible > + xStrong; + if (bWasVisible) + xStrong = getAccessibleChild(aIt); + ::css::uno::WeakReference< + ::css::accessibility::XAccessible > xWeak( + aIt->getParagraph()); + aIt = m_xParagraphs->erase(aIt); + + determineVisibleRange(); + m_aFocused = bWasFocused ? m_xParagraphs->end() + : m_xParagraphs->begin() + nOldFocused; + + for (; aIt != m_xParagraphs->end(); ++aIt) + { + ::rtl::Reference< ParagraphImpl > xParagraph( + getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->numberChanged(false); + } + + if (bWasVisible) + NotifyAccessibleEvent( + ::css::accessibility::AccessibleEventId:: + CHILD, + ::css::uno::makeAny(getAccessibleChild(aIt)), + ::css::uno::Any()); + + ::css::uno::Reference< ::css::lang::XComponent > xComponent( + xWeak.get(), ::css::uno::UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + + notifyVisibleRangeChanges( + m_xParagraphs->begin() + nOldVisibleBegin, + m_xParagraphs->begin() + nOldVisibleEnd, + m_xParagraphs->end()); + } + break; + } + case TEXT_HINT_FORMATPARA: + { + ::sal_uLong n = aHint.GetValue(); + OSL_ENSURE(n < m_xParagraphs->size(), + "Bad TEXT_HINT_FORMATPARA event"); + + (*m_xParagraphs)[static_cast< Paragraphs::size_type >(n)]. + changeHeight(static_cast< ::sal_Int32 >( + m_rEngine.GetTextHeight(n))); + // XXX numeric overflow + Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin); + Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); + determineVisibleRange(); + notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd, + m_xParagraphs->end()); + + if (n < m_xParagraphs->size()) + { + Paragraphs::iterator aIt(m_xParagraphs->begin() + n); + ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->textChanged(); + } + break; + } + default: + OSL_ENSURE(false, "bad buffered hint"); + break; + } + } + if (m_bSelectionChangedNotification) + { + m_bSelectionChangedNotification = false; + handleSelectionChangeNotification(); + } +} + +void Document::handleSelectionChangeNotification() +{ + ::TextSelection const & rSelection = m_rView.GetSelection(); + OSL_ENSURE(rSelection.GetStart().GetPara() < m_xParagraphs->size() + && rSelection.GetEnd().GetPara() < m_xParagraphs->size(), + "bad TEXT_HINT_VIEWSELECTIONCHANGED event"); + ::sal_Int32 nNewFirstPara + = static_cast< ::sal_Int32 >(rSelection.GetStart().GetPara()); + ::sal_Int32 nNewFirstPos + = static_cast< ::sal_Int32 >(rSelection.GetStart().GetIndex()); + // XXX numeric overflow + ::sal_Int32 nNewLastPara + = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetPara()); + ::sal_Int32 nNewLastPos + = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetIndex()); + // XXX numeric overflow + + // Lose focus: + Paragraphs::iterator aIt(m_xParagraphs->begin() + nNewLastPara); + if (m_aFocused != m_xParagraphs->end() && m_aFocused != aIt + && m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) + { + ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aFocused)); + if (xParagraph.is()) + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + STATE_CHANGED, + ::css::uno::makeAny( + ::css::accessibility::AccessibleStateType::FOCUSED), + ::css::uno::Any()); + } + + // Gain focus and update cursor position: + if (aIt >= m_aVisibleBegin && aIt < m_aVisibleEnd + && (aIt != m_aFocused + || nNewLastPara != m_nSelectionLastPara + || nNewLastPos != m_nSelectionLastPos)) + { + ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt)); + if (xParagraph.is()) + { + if (aIt != m_aFocused) + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + STATE_CHANGED, + ::css::uno::Any(), + ::css::uno::makeAny( + ::css::accessibility::AccessibleStateType::FOCUSED)); + if (nNewLastPara != m_nSelectionLastPara + || nNewLastPos != m_nSelectionLastPos) + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId:: + CARET_CHANGED, + ::css::uno::makeAny< ::sal_Int32 >( + nNewLastPara == m_nSelectionLastPara + ? m_nSelectionLastPos : 0), + ::css::uno::makeAny(nNewLastPos)); + } + } + m_aFocused = aIt; + + // 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 + // empty. Only for these two ranges notifications have to be sent.) + + TextPaM aOldTextStart( static_cast< sal_uLong >( m_nSelectionFirstPara ), static_cast< sal_uInt16 >( m_nSelectionFirstPos ) ); + TextPaM aOldTextEnd( static_cast< sal_uLong >( m_nSelectionLastPara ), static_cast< sal_uInt16 >( m_nSelectionLastPos ) ); + TextPaM aNewTextStart( static_cast< sal_uLong >( nNewFirstPara ), static_cast< sal_uInt16 >( nNewFirstPos ) ); + TextPaM aNewTextEnd( static_cast< sal_uLong >( nNewLastPara ), static_cast< sal_uInt16 >( nNewLastPos ) ); + + // justify selections + justifySelection( aOldTextStart, aOldTextEnd ); + justifySelection( aNewTextStart, aNewTextEnd ); + + sal_Int32 nFirst1; + sal_Int32 nLast1; + sal_Int32 nFirst2; + sal_Int32 nLast2; + + if ( m_nSelectionFirstPara == -1 ) + { + // old selection not initialized yet => notify events only for new selection (if not empty) + nFirst1 = aNewTextStart.GetPara(); + nLast1 = aNewTextEnd.GetPara() + ( aNewTextStart != aNewTextEnd ? 1 : 0 ); + nFirst2 = 0; + nLast2 = 0; + } + else if ( aOldTextStart == aOldTextEnd && aNewTextStart == aNewTextEnd ) + { + // old an new selection empty => no events + nFirst1 = 0; + nLast1 = 0; + nFirst2 = 0; + nLast2 = 0; + } + else if ( aOldTextStart != aOldTextEnd && aNewTextStart == aNewTextEnd ) + { + // old selection not empty + new selection empty => notify events only for old selection + nFirst1 = aOldTextStart.GetPara(); + nLast1 = aOldTextEnd.GetPara() + 1; + nFirst2 = 0; + nLast2 = 0; + } + else if ( aOldTextStart == aOldTextEnd && aNewTextStart != aNewTextEnd ) + { + // old selection empty + new selection not empty => notify events only for new selection + nFirst1 = aNewTextStart.GetPara(); + nLast1 = aNewTextEnd.GetPara() + 1; + nFirst2 = 0; + nLast2 = 0; + } + else + { + // old and new selection not empty => notify events for the two ranges left and right of the overlap + ::std::vector< TextPaM > aTextPaMs(4); + aTextPaMs[0] = aOldTextStart; + aTextPaMs[1] = aOldTextEnd; + aTextPaMs[2] = aNewTextStart; + aTextPaMs[3] = aNewTextEnd; + ::std::sort( aTextPaMs.begin(), aTextPaMs.end() ); + + nFirst1 = aTextPaMs[0].GetPara(); + nLast1 = aTextPaMs[1].GetPara() + ( aTextPaMs[0] != aTextPaMs[1] ? 1 : 0 ); + + nFirst2 = aTextPaMs[2].GetPara(); + nLast2 = aTextPaMs[3].GetPara() + ( aTextPaMs[2] != aTextPaMs[3] ? 1 : 0 ); + + // adjust overlapping ranges + if ( nLast1 > nFirst2 ) + nLast1 = nFirst2; + } + + // notify selection changes + notifySelectionChange( nFirst1, nLast1 ); + notifySelectionChange( nFirst2, nLast2 ); + + m_nSelectionFirstPara = nNewFirstPara; + m_nSelectionFirstPos = nNewFirstPos; + m_nSelectionLastPara = nNewLastPara; + m_nSelectionLastPos = nNewLastPos; +} + +void Document::notifySelectionChange( sal_Int32 nFirst, sal_Int32 nLast ) +{ + if ( nFirst < nLast ) + { + Paragraphs::iterator aEnd( ::std::min( m_xParagraphs->begin() + nLast, m_aVisibleEnd ) ); + for ( Paragraphs::iterator aIt = ::std::max( m_xParagraphs->begin() + nFirst, m_aVisibleBegin ); aIt < aEnd; ++aIt ) + { + ::rtl::Reference< ParagraphImpl > xParagraph( getParagraph( aIt ) ); + if ( xParagraph.is() ) + { + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId::SELECTION_CHANGED, + ::css::uno::Any(), ::css::uno::Any() ); + xParagraph->notifyEvent( + ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED, + ::css::uno::Any(), ::css::uno::Any() ); + } + } + } +} + +void Document::justifySelection( TextPaM& rTextStart, TextPaM& rTextEnd ) +{ + if ( rTextStart > rTextEnd ) + { + TextPaM aTextPaM( rTextStart ); + rTextStart = rTextEnd; + rTextEnd = aTextPaM; + } +} + +void Document::disposeParagraphs() +{ + for (Paragraphs::iterator aIt(m_xParagraphs->begin()); + aIt != m_xParagraphs->end(); ++aIt) + { + ::css::uno::Reference< ::css::lang::XComponent > xComponent( + aIt->getParagraph().get(), ::css::uno::UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + } +} + +// static +::css::uno::Any Document::mapFontColor(::Color const & rColor) +{ + return ::css::uno::makeAny( + static_cast< ::sal_Int32 >(COLORDATA_RGB(rColor.GetColor()))); + // FIXME keep transparency? +} + +// static +::Color Document::mapFontColor(::css::uno::Any const & rColor) +{ + ::sal_Int32 nColor = 0; + rColor >>= nColor; + return ::Color(static_cast< ::ColorData >(nColor)); +} + +// static +::css::uno::Any Document::mapFontWeight(::FontWeight nWeight) +{ + // Map from ::FontWeight to ::css:awt::FontWeight, depends on order of + // elements in ::FontWeight (vcl/vclenum.hxx): + static float const aWeight[] + = { ::css::awt::FontWeight::DONTKNOW, // WEIGHT_DONTKNOW + ::css::awt::FontWeight::THIN, // WEIGHT_THIN + ::css::awt::FontWeight::ULTRALIGHT, // WEIGHT_ULTRALIGHT + ::css::awt::FontWeight::LIGHT, // WEIGHT_LIGHT + ::css::awt::FontWeight::SEMILIGHT, // WEIGHT_SEMILIGHT + ::css::awt::FontWeight::NORMAL, // WEIGHT_NORMAL + ::css::awt::FontWeight::NORMAL, // WEIGHT_MEDIUM + ::css::awt::FontWeight::SEMIBOLD, // WEIGHT_SEMIBOLD + ::css::awt::FontWeight::BOLD, // WEIGHT_BOLD + ::css::awt::FontWeight::ULTRABOLD, // WEIGHT_ULTRABOLD + ::css::awt::FontWeight::BLACK }; // WEIGHT_BLACK + return ::css::uno::makeAny(aWeight[nWeight]); +} + +// static +::FontWeight Document::mapFontWeight(::css::uno::Any const & rWeight) +{ + float nWeight = ::css::awt::FontWeight::NORMAL; + rWeight >>= nWeight; + return nWeight <= ::css::awt::FontWeight::DONTKNOW ? WEIGHT_DONTKNOW + : nWeight <= ::css::awt::FontWeight::THIN ? WEIGHT_THIN + : nWeight <= ::css::awt::FontWeight::ULTRALIGHT ? WEIGHT_ULTRALIGHT + : nWeight <= ::css::awt::FontWeight::LIGHT ? WEIGHT_LIGHT + : nWeight <= ::css::awt::FontWeight::SEMILIGHT ? WEIGHT_SEMILIGHT + : nWeight <= ::css::awt::FontWeight::NORMAL ? WEIGHT_NORMAL + : nWeight <= ::css::awt::FontWeight::SEMIBOLD ? WEIGHT_SEMIBOLD + : nWeight <= ::css::awt::FontWeight::BOLD ? WEIGHT_BOLD + : nWeight <= ::css::awt::FontWeight::ULTRABOLD ? WEIGHT_ULTRABOLD + : WEIGHT_BLACK; +} + +} + |