/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_accessibility.hxx" #ifndef ACCESSIBILITY_EXT_ACCESSIBLETABLISTBOXTABLE_HXX_ #include "accessibility/extended/accessibletablistboxtable.hxx" #endif #include "accessibility/extended/AccessibleBrowseBoxTableCell.hxx" #include "accessibility/extended/AccessibleBrowseBoxCheckBoxCell.hxx" #include #include //........................................................................ 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() ) { 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 ); USHORT 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 ); USHORT 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 ); USHORT 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 //........................................................................