Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / accessibility / source / extended / AccessibleGridControl.cxx
blobace45d2c8c3ebb3ca7a5752e633ea50ef406bd29
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "accessibility/extended/AccessibleGridControl.hxx"
21 #include "accessibility/extended/AccessibleGridControlTable.hxx"
22 #include "accessibility/extended/AccessibleGridControlHeader.hxx"
23 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
24 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
25 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
26 #include <svtools/accessibletable.hxx>
27 #include <comphelper/types.hxx>
28 #include <toolkit/helper/vclunohelper.hxx>
30 // ============================================================================
32 namespace accessibility
35 // ============================================================================
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::lang;
40 using namespace ::com::sun::star::accessibility;
41 using namespace ::svt;
42 using namespace ::svt::table;
44 // ============================================================================
45 class AccessibleGridControl_Impl
47 public:
48 /// the XAccessible which created the AccessibleGridControl
49 WeakReference< XAccessible > m_aCreator;
51 /** The data table child. */
52 Reference<
53 ::com::sun::star::accessibility::XAccessible > m_xTable;
54 AccessibleGridControlTable* m_pTable;
56 /** The header bar for rows. */
57 Reference<
58 ::com::sun::star::accessibility::XAccessible > m_xRowHeaderBar;
59 AccessibleGridControlHeader* m_pRowHeaderBar;
61 /** The header bar for columns (first row of the table). */
62 Reference<
63 ::com::sun::star::accessibility::XAccessible > m_xColumnHeaderBar;
64 AccessibleGridControlHeader* m_pColumnHeaderBar;
66 /** The table cell child. */
67 Reference<
68 ::com::sun::star::accessibility::XAccessible > m_xCell;
69 AccessibleGridControlTableCell* m_pCell;
73 AccessibleGridControl::AccessibleGridControl(
74 const Reference< XAccessible >& _rxParent, const Reference< XAccessible >& _rxCreator,
75 IAccessibleTable& _rTable )
76 : AccessibleGridControlBase( _rxParent, _rTable, TCTYPE_GRIDCONTROL )
78 m_pImpl.reset( new AccessibleGridControl_Impl() );
79 m_pImpl->m_aCreator = _rxCreator;
82 // -----------------------------------------------------------------------------
83 AccessibleGridControl::~AccessibleGridControl()
86 // -----------------------------------------------------------------------------
88 void SAL_CALL AccessibleGridControl::disposing()
90 ::osl::MutexGuard aGuard( getOslMutex() );
92 m_pImpl->m_pTable = NULL;
93 m_pImpl->m_pColumnHeaderBar = NULL;
94 m_pImpl->m_pRowHeaderBar = NULL;
95 m_pImpl->m_pCell = NULL;
96 m_pImpl->m_aCreator = Reference< XAccessible >();
98 Reference< XAccessible > xTable = m_pImpl->m_xTable;
100 Reference< XComponent > xComp( m_pImpl->m_xTable, UNO_QUERY );
101 if ( xComp.is() )
103 xComp->dispose();
105 Reference< XAccessible > xCell = m_pImpl->m_xCell;
107 Reference< XComponent > xCellComp( m_pImpl->m_xCell, UNO_QUERY );
108 if ( xCellComp.is() )
110 xCellComp->dispose();
113 ::comphelper::disposeComponent(m_pImpl->m_xRowHeaderBar);
114 ::comphelper::disposeComponent(m_pImpl->m_xColumnHeaderBar);
115 AccessibleGridControlBase::disposing();
117 // -----------------------------------------------------------------------------
119 // XAccessibleContext ---------------------------------------------------------
121 sal_Int32 SAL_CALL AccessibleGridControl::getAccessibleChildCount()
122 throw ( uno::RuntimeException )
124 SolarMutexGuard aSolarGuard;
125 ::osl::MutexGuard aGuard( getOslMutex() );
126 ensureIsAlive();
127 return m_aTable.GetAccessibleControlCount();
129 // -----------------------------------------------------------------------------
131 Reference< XAccessible > SAL_CALL
132 AccessibleGridControl::getAccessibleChild( sal_Int32 nChildIndex )
133 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
135 SolarMutexGuard aSolarGuard;
136 ::osl::MutexGuard aGuard( getOslMutex() );
138 if (nChildIndex<0 || nChildIndex>=getAccessibleChildCount())
139 throw IndexOutOfBoundsException();
141 Reference< XAccessible > xChild;
142 if (isAlive())
144 if(nChildIndex == 0 && m_aTable.HasColHeader())
146 if(!m_pImpl->m_xColumnHeaderBar.is())
148 AccessibleGridControlHeader* pColHeaderBar = new AccessibleGridControlHeader(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_COLUMNHEADERBAR);
149 m_pImpl->m_xColumnHeaderBar = pColHeaderBar;
151 xChild = m_pImpl->m_xColumnHeaderBar;
153 else if(m_aTable.HasRowHeader() && (nChildIndex == 1 || nChildIndex == 0))
155 if(!m_pImpl->m_xRowHeaderBar.is())
157 AccessibleGridControlHeader* pRowHeaderBar = new AccessibleGridControlHeader(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_ROWHEADERBAR);
158 m_pImpl->m_xRowHeaderBar = pRowHeaderBar;
160 xChild = m_pImpl->m_xRowHeaderBar;
162 else
164 if(!m_pImpl->m_xTable.is())
166 AccessibleGridControlTable* pTable = new AccessibleGridControlTable(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_TABLE);
167 m_pImpl->m_xTable = pTable;
168 m_pImpl->m_pTable = pTable;
170 xChild = m_pImpl->m_xTable;
173 return xChild;
175 // -----------------------------------------------------------------------------
177 sal_Int16 SAL_CALL AccessibleGridControl::getAccessibleRole()
178 throw ( uno::RuntimeException )
180 ensureIsAlive();
181 return AccessibleRole::PANEL;
183 // -----------------------------------------------------------------------------
185 // XAccessibleComponent -------------------------------------------------------
187 Reference< XAccessible > SAL_CALL
188 AccessibleGridControl::getAccessibleAtPoint( const awt::Point& rPoint )
189 throw ( uno::RuntimeException )
191 SolarMutexGuard aSolarGuard;
192 ::osl::MutexGuard aGuard( getOslMutex() );
193 ensureIsAlive();
195 Reference< XAccessible > xChild;
196 sal_Int32 nIndex = 0;
197 if( m_aTable.ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) )
198 xChild = m_aTable.CreateAccessibleControl( nIndex );
199 else
201 // try whether point is in one of the fixed children
202 // (table, header bars, corner control)
203 Point aPoint( VCLPoint( rPoint ) );
204 for( nIndex = 0; (nIndex < 3) && !xChild.is(); ++nIndex )
206 Reference< XAccessible > xCurrChild( implGetFixedChild( nIndex ) );
207 Reference< XAccessibleComponent >
208 xCurrChildComp( xCurrChild, uno::UNO_QUERY );
210 if( xCurrChildComp.is() &&
211 VCLRectangle( xCurrChildComp->getBounds() ).IsInside( aPoint ) )
212 xChild = xCurrChild;
215 return xChild;
217 // -----------------------------------------------------------------------------
219 void SAL_CALL AccessibleGridControl::grabFocus()
220 throw ( uno::RuntimeException )
222 SolarMutexGuard aSolarGuard;
223 ::osl::MutexGuard aGuard( getOslMutex() );
224 ensureIsAlive();
225 m_aTable.GrabFocus();
227 // -----------------------------------------------------------------------------
229 Any SAL_CALL AccessibleGridControl::getAccessibleKeyBinding()
230 throw ( uno::RuntimeException )
232 ensureIsAlive();
233 return Any();
235 // -----------------------------------------------------------------------------
237 // XServiceInfo ---------------------------------------------------------------
239 OUString SAL_CALL AccessibleGridControl::getImplementationName()
240 throw ( uno::RuntimeException )
242 return OUString( "com.sun.star.accessibility.AccessibleGridControl" );
244 // -----------------------------------------------------------------------------
246 // internal virtual methods ---------------------------------------------------
248 Rectangle AccessibleGridControl::implGetBoundingBox()
250 Window* pParent = m_aTable.GetAccessibleParentWindow();
251 OSL_ENSURE( pParent, "implGetBoundingBox - missing parent window" );
252 return m_aTable.GetWindowExtentsRelative( pParent );
254 // -----------------------------------------------------------------------------
256 Rectangle AccessibleGridControl::implGetBoundingBoxOnScreen()
258 return m_aTable.GetWindowExtentsRelative( NULL );
260 // internal helper methods ----------------------------------------------------
262 Reference< XAccessible > AccessibleGridControl::implGetTable()
264 if( !m_pImpl->m_xTable.is() )
266 m_pImpl->m_pTable = createAccessibleTable();
267 m_pImpl->m_xTable = m_pImpl->m_pTable;
269 return m_pImpl->m_xTable;
271 // -----------------------------------------------------------------------------
273 Reference< XAccessible >
274 AccessibleGridControl::implGetHeaderBar( AccessibleTableControlObjType eObjType )
276 Reference< XAccessible > xRet;
277 Reference< XAccessible >* pxMember = NULL;
279 if( eObjType == TCTYPE_ROWHEADERBAR )
280 pxMember = &m_pImpl->m_xRowHeaderBar;
281 else if( eObjType == TCTYPE_COLUMNHEADERBAR )
282 pxMember = &m_pImpl->m_xColumnHeaderBar;
284 if( pxMember )
286 if( !pxMember->is() )
288 AccessibleGridControlHeader* pHeaderBar = new AccessibleGridControlHeader(
289 (Reference< XAccessible >)m_pImpl->m_aCreator, m_aTable, eObjType );
291 if ( TCTYPE_COLUMNHEADERBAR == eObjType)
292 m_pImpl->m_pColumnHeaderBar = pHeaderBar;
293 else
294 m_pImpl->m_pRowHeaderBar = pHeaderBar;
296 *pxMember = pHeaderBar;
298 xRet = *pxMember;
300 return xRet;
302 // -----------------------------------------------------------------------------
303 Reference< XAccessible >
304 AccessibleGridControl::implGetFixedChild( sal_Int32 nChildIndex )
306 Reference< XAccessible > xRet;
307 switch( nChildIndex )
309 case TCINDEX_COLUMNHEADERBAR:
310 xRet = implGetHeaderBar( TCTYPE_COLUMNHEADERBAR );
311 break;
312 case TCINDEX_ROWHEADERBAR:
313 xRet = implGetHeaderBar( TCTYPE_ROWHEADERBAR );
314 break;
315 case TCINDEX_TABLE:
316 xRet = implGetTable();
317 break;
319 return xRet;
321 // -----------------------------------------------------------------------------
322 AccessibleGridControlTable* AccessibleGridControl::createAccessibleTable()
324 Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator;
325 OSL_ENSURE( xCreator.is(), "accessibility/extended/AccessibleGirdControl::createAccessibleTable: my creator died - how this?" );
326 return new AccessibleGridControlTable( xCreator, m_aTable, TCTYPE_TABLE );
328 // -----------------------------------------------------------------------------
329 void AccessibleGridControl::commitCellEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
331 sal_Int32 nChildCount = getAccessibleChildCount();
332 if(nChildCount != 0)
334 for(sal_Int32 i=0;i<nChildCount;i++)
336 Reference< XAccessible > xAccessible = getAccessibleChild(i);
337 com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessibleContext > xAccessibleChild = xAccessible->getAccessibleContext();
338 if(m_pImpl->m_xTable == xAccessible)
340 std::vector< AccessibleGridControlTableCell* > xCellCont = m_pImpl->m_pTable->getCellVector();
341 int nIndex = m_aTable.GetCurrentRow()*m_aTable.GetColumnCount()+m_aTable.GetCurrentColumn();
342 if(!xCellCont.empty() && xCellCont[nIndex])
344 m_pImpl->m_pCell = xCellCont[nIndex];
345 m_pImpl->m_pCell->commitEvent( _nEventId, _rNewValue, _rOldValue );
350 else
352 if ( m_pImpl->m_xTable.is() )
353 m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
357 void AccessibleGridControl::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
359 if ( m_pImpl->m_xTable.is() )
361 if(_nEventId == AccessibleEventId::ACTIVE_DESCENDANT_CHANGED)
363 Reference< XAccessible > xChild = m_pImpl->m_pTable->getAccessibleChild(m_aTable.GetCurrentRow()*m_aTable.GetColumnCount()+m_aTable.GetCurrentColumn());
364 m_pImpl->m_pTable->commitEvent(_nEventId, makeAny(xChild),_rOldValue);
366 else if(_nEventId == AccessibleEventId::TABLE_MODEL_CHANGED)
368 AccessibleTableModelChange aChange;
369 if(_rNewValue >>= aChange)
371 if(aChange.Type == AccessibleTableModelChangeType::DELETE)
373 std::vector< AccessibleGridControlTableCell* >::iterator m_pCell = m_pImpl->m_pTable->getCellVector().begin();
374 std::vector< Reference< XAccessible > >::iterator m_xAccessibleVector = m_pImpl->m_pTable->getAccessibleCellVector().begin();
375 int nColCount = m_aTable.GetColumnCount();
376 m_pImpl->m_pTable->getCellVector().erase(m_pCell+nColCount*aChange.FirstRow, m_pCell+nColCount*aChange.LastRow );
377 m_pImpl->m_pTable->getAccessibleCellVector().erase(m_xAccessibleVector+nColCount*aChange.FirstRow, m_xAccessibleVector+nColCount*aChange.LastRow);
378 m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
380 else
381 m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
384 else
385 m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
388 // ============================================================================
389 // = AccessibleGridControlAccess
390 // ============================================================================
392 // -----------------------------------------------------------------------------
393 AccessibleGridControlAccess::AccessibleGridControlAccess( const Reference< XAccessible >& _rxParent, IAccessibleTable& _rTable )
394 :m_xParent( _rxParent )
395 ,m_rTable( _rTable )
396 ,m_pContext( NULL )
400 // -----------------------------------------------------------------------------
401 AccessibleGridControlAccess::~AccessibleGridControlAccess()
405 // -----------------------------------------------------------------------------
406 void AccessibleGridControlAccess::dispose()
408 ::osl::MutexGuard aGuard( m_aMutex );
410 m_pContext = NULL;
411 ::comphelper::disposeComponent( m_xContext );
414 // -----------------------------------------------------------------------------
415 Reference< XAccessibleContext > SAL_CALL AccessibleGridControlAccess::getAccessibleContext() throw ( RuntimeException )
417 ::osl::MutexGuard aGuard( m_aMutex );
419 OSL_ENSURE( ( m_pContext && m_xContext.is() ) || ( !m_pContext && !m_xContext.is() ),
420 "accessibility/extended/AccessibleGridControlAccess::getAccessibleContext: inconsistency!" );
422 // if the context died meanwhile (we're no listener, so it won't tell us explicitily when this happens),
423 // then reset an re-create.
424 if ( m_pContext && !m_pContext->isAlive() )
425 m_xContext = m_pContext = NULL;
427 if ( !m_xContext.is() )
428 m_xContext = m_pContext = new AccessibleGridControl( m_xParent, this, m_rTable );
430 return m_xContext;
433 // -----------------------------------------------------------------------------
434 bool AccessibleGridControlAccess::isContextAlive() const
436 return ( NULL != m_pContext ) && m_pContext->isAlive();
439 // ============================================================================
441 } // namespace accessibility
443 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */