xref: /trunk/main/accessibility/source/extended/AccessibleGridControlTable.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26 
27 
28 #include "accessibility/extended/AccessibleGridControlTable.hxx"
29 #include "accessibility/extended/AccessibleGridControlTableCell.hxx"
30 #include <svtools/accessibletable.hxx>
31 
32 // ============================================================================
33 
34 using ::rtl::OUString;
35 
36 using ::com::sun::star::uno::Reference;
37 using ::com::sun::star::uno::Sequence;
38 using ::com::sun::star::uno::Any;
39 
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::accessibility;
42 using namespace ::svt;
43 using namespace ::svt::table;
44 // ============================================================================
45 
46 namespace accessibility {
47 
48 // ============================================================================
49 
DBG_NAME(AccessibleGridControlTable)50 DBG_NAME( AccessibleGridControlTable )
51 
52 AccessibleGridControlTable::AccessibleGridControlTable(
53         const Reference< XAccessible >& rxParent,
54         IAccessibleTable& rTable,
55         AccessibleTableControlObjType _eType) :
56     AccessibleGridControlTableBase( rxParent, rTable, _eType )
57         ,m_pCellVector( )
58         ,m_pAccessCellVector( )
59 {
60 }
61 
~AccessibleGridControlTable()62 AccessibleGridControlTable::~AccessibleGridControlTable()
63 {
64 }
65 
66 // XAccessibleContext ---------------------------------------------------------
67 
68 Reference< XAccessible > SAL_CALL
getAccessibleChild(sal_Int32 nChildIndex)69 AccessibleGridControlTable::getAccessibleChild( sal_Int32 nChildIndex )
70 {
71     TCSolarGuard aSolarGuard;
72     ::osl::MutexGuard aGuard( getOslMutex() );
73     ensureIsAlive();
74     ensureIsValidIndex( nChildIndex );
75     sal_Int32 nCount = getAccessibleChildCount();
76     if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount)
77     {
78         m_pAccessCellVector.resize(nCount);
79         m_pCellVector.resize(nCount);
80     }
81     if(!m_pAccessCellVector[nChildIndex].is())
82     {
83         AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount(), TCTYPE_TABLECELL);
84         m_pCellVector[nChildIndex] = pCell;
85         m_pAccessCellVector[nChildIndex] = pCell;
86     }
87     return m_pAccessCellVector[nChildIndex];
88 }
89 
getAccessibleIndexInParent()90 sal_Int32 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent()
91 {
92     ensureIsAlive();
93     if(m_aTable.HasRowHeader() && m_aTable.HasColHeader())
94         return 0;
95     else if((!m_aTable.HasRowHeader() && m_aTable.HasColHeader()) || (m_aTable.HasRowHeader() && !m_aTable.HasColHeader()) )
96         return 1;
97     else
98         return 2;
99 }
100 
101 // XAccessibleComponent -------------------------------------------------------
102 
103 Reference< XAccessible > SAL_CALL
getAccessibleAtPoint(const awt::Point & rPoint)104 AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint )
105 {
106     TCSolarGuard aSolarGuard;
107     ::osl::MutexGuard aGuard( getOslMutex() );
108     ensureIsAlive();
109 
110     Reference< XAccessible > xChild;
111     sal_Int32 nRow = 0;
112     sal_Int32 nColumnPos = 0;
113     if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) )
114         xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos, TCTYPE_TABLECELL);
115     return xChild;
116 }
117 
grabFocus()118 void SAL_CALL AccessibleGridControlTable::grabFocus()
119 {
120     TCSolarGuard aSolarGuard;
121     ::osl::MutexGuard aGuard( getOslMutex() );
122     ensureIsAlive();
123     m_aTable.GrabFocus();
124 }
125 
getAccessibleKeyBinding()126 Any SAL_CALL AccessibleGridControlTable::getAccessibleKeyBinding()
127 {
128     ensureIsAlive();
129     return Any();   // no special key bindings for data table
130 }
131 
132 // XAccessibleTable -----------------------------------------------------------
133 
getAccessibleRowDescription(sal_Int32 nRow)134 OUString SAL_CALL AccessibleGridControlTable::getAccessibleRowDescription( sal_Int32 nRow )
135 {
136     TCSolarGuard aSolarGuard;
137     ::osl::MutexGuard aGuard( getOslMutex() );
138     ensureIsAlive();
139     ensureIsValidRow( nRow );
140     return m_aTable.GetRowDescription( nRow );
141 }
142 
getAccessibleColumnDescription(sal_Int32 nColumn)143 OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn )
144 {
145     TCSolarGuard aSolarGuard;
146     ::osl::MutexGuard aGuard( getOslMutex() );
147     ensureIsAlive();
148     ensureIsValidColumn( nColumn );
149     return m_aTable.GetColumnDescription( (sal_uInt16)nColumn );
150 }
151 
getAccessibleRowHeaders()152 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleRowHeaders()
153 {
154     ::osl::MutexGuard aGuard( getOslMutex() );
155     ensureIsAlive();
156     if(m_aTable.HasColHeader())
157         return implGetHeaderBar( 1 );
158     else
159         return implGetHeaderBar( 0 );
160 }
161 
getAccessibleColumnHeaders()162 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleColumnHeaders()
163 {
164     ::osl::MutexGuard aGuard( getOslMutex() );
165     ensureIsAlive();
166     return implGetHeaderBar( 0 );
167 }
168 
getSelectedAccessibleRows()169 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleRows()
170 {
171     TCSolarGuard aSolarGuard;
172     ::osl::MutexGuard aGuard( getOslMutex() );
173     ensureIsAlive();
174     Sequence< sal_Int32 > aSelSeq;
175     implGetSelectedRows( aSelSeq );
176     return aSelSeq;
177 }
178 
179 //columns aren't selectable
getSelectedAccessibleColumns()180 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns()
181 {
182     Sequence< sal_Int32 > aSelSeq(0);
183     return aSelSeq;
184 }
185 
isAccessibleRowSelected(sal_Int32 nRow)186 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleRowSelected( sal_Int32 nRow )
187 {
188     TCSolarGuard aSolarGuard;
189     ::osl::MutexGuard aGuard( getOslMutex() );
190     ensureIsAlive();
191     ensureIsValidRow( nRow );
192     sal_Bool bSelected = sal_False;
193     Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
194     for(int i=0; i<selectedRows.getLength(); i++)
195     {
196         if(nRow == selectedRows[i])
197         {
198             bSelected = sal_True;
199             continue;
200         }
201     }
202     return bSelected;
203 }
204 
205 //columns aren't selectable
isAccessibleColumnSelected(sal_Int32 nColumn)206 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleColumnSelected( sal_Int32 nColumn )
207 {
208     (void) nColumn;
209     return sal_False;
210 }
211 
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)212 Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellAt(
213         sal_Int32 nRow, sal_Int32 nColumn )
214 {
215     TCSolarGuard aSolarGuard;
216     ::osl::MutexGuard aGuard( getOslMutex() );
217     ensureIsAlive();
218     ensureIsValidAddress( nRow, nColumn );
219     sal_Int32 nCount = getAccessibleChildCount();
220     sal_Int32 nChildIndex = nRow*m_aTable.GetColumnCount() + nColumn;
221     if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount)
222     {
223         m_pAccessCellVector.resize(nCount);
224         m_pCellVector.resize(nCount);
225     }
226     if(!m_pAccessCellVector[nChildIndex].is())
227     {
228         AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumn, TCTYPE_TABLECELL);
229         m_pCellVector[nChildIndex] = pCell;
230         m_pAccessCellVector[nChildIndex] = pCell;
231     }
232     return m_pAccessCellVector[nChildIndex];
233 }
234 
isAccessibleSelected(sal_Int32 nRow,sal_Int32 nColumn)235 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected(
236         sal_Int32 nRow, sal_Int32 nColumn )
237 {
238     TCSolarGuard aSolarGuard;
239     ::osl::MutexGuard aGuard( getOslMutex() );
240     ensureIsAlive();
241     ensureIsValidAddress( nRow, nColumn );
242     (void) nColumn;
243     //selection of single cells not possible, so if row is selected, the cell will be selected too
244     return isAccessibleRowSelected(nRow);
245 }
selectAccessibleChild(sal_Int32 nChildIndex)246 void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int32 nChildIndex )
247 {
248     TCSolarGuard aSolarGuard;
249     ::osl::MutexGuard aGuard( getOslMutex() );
250     ensureIsAlive();
251     ensureIsValidIndex( nChildIndex );
252     sal_Int32 nColumns = m_aTable.GetColumnCount();
253     sal_Int32 nRow = (nChildIndex / nColumns);
254     m_aTable.SelectRow( nRow, sal_True );
255 }
isAccessibleChildSelected(sal_Int32 nChildIndex)256 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleChildSelected( sal_Int32 nChildIndex )
257 {
258     TCSolarGuard aSolarGuard;
259     ::osl::MutexGuard aGuard( getOslMutex() );
260     ensureIsAlive();
261     ensureIsValidIndex( nChildIndex );
262     sal_Int32 nColumns = m_aTable.GetColumnCount();
263     sal_Int32 nRow = (nChildIndex / nColumns);
264     return isAccessibleRowSelected(nRow);
265 }
clearAccessibleSelection()266 void SAL_CALL AccessibleGridControlTable::clearAccessibleSelection()
267 {
268     TCSolarGuard aSolarGuard;
269     ::osl::MutexGuard aGuard( getOslMutex() );
270     ensureIsAlive();
271     m_aTable.SelectAllRows( false );
272 }
selectAllAccessibleChildren()273 void SAL_CALL AccessibleGridControlTable::selectAllAccessibleChildren()
274 {
275     TCSolarGuard aSolarGuard;
276     ::osl::MutexGuard aGuard( getOslMutex() );
277     ensureIsAlive();
278     Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
279     for(int i=0;i<m_aTable.GetRowCount();i++)
280         selectedRows[i]=i;
281 }
getSelectedAccessibleChildCount()282 sal_Int32 SAL_CALL AccessibleGridControlTable::getSelectedAccessibleChildCount()
283 {
284     TCSolarGuard aSolarGuard;
285     ::osl::MutexGuard aGuard( getOslMutex() );
286     ensureIsAlive();
287     Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
288     sal_Int32 nColumns = m_aTable.GetColumnCount();
289     return selectedRows.getLength()*nColumns;
290 }
291 Reference< XAccessible > SAL_CALL
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)292 AccessibleGridControlTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
293 {
294     TCSolarGuard aSolarGuard;
295     ::osl::MutexGuard aGuard( getOslMutex() );
296     ensureIsAlive();
297     if(isAccessibleChildSelected(nSelectedChildIndex))
298         return getAccessibleChild(nSelectedChildIndex);
299     else
300         return NULL;
301 }
302 //not implemented yet, because only row selection possible
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)303 void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild(
304         sal_Int32 nSelectedChildIndex )
305 {
306     TCSolarGuard aSolarGuard;
307     ::osl::MutexGuard aGuard( getOslMutex() );
308     ensureIsAlive();
309     (void)nSelectedChildIndex;
310 }
311 // XInterface -----------------------------------------------------------------
312 
queryInterface(const uno::Type & rType)313 Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType )
314 {
315     Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) );
316     return aAny.hasValue() ?
317         aAny : AccessibleGridControlTableImplHelper1::queryInterface( rType );
318 }
319 
acquire()320 void SAL_CALL AccessibleGridControlTable::acquire() throw ()
321 {
322     AccessibleGridControlTableBase::acquire();
323 }
324 
release()325 void SAL_CALL AccessibleGridControlTable::release() throw ()
326 {
327     AccessibleGridControlTableBase::release();
328 }
329 // XServiceInfo ---------------------------------------------------------------
330 
getImplementationName()331 OUString SAL_CALL AccessibleGridControlTable::getImplementationName()
332 {
333     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTable" ) );
334 }
335 
336 // internal virtual methods ---------------------------------------------------
337 
implGetBoundingBox()338 Rectangle AccessibleGridControlTable::implGetBoundingBox()
339 {
340     Window* pParent = m_aTable.GetAccessibleParentWindow();
341     DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
342     Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent ));
343     Rectangle aTableRect( m_aTable.calcTableRect() );
344     long nX = aGridRect.Left() + aTableRect.Left();
345     long nY = aGridRect.Top() + aTableRect.Top();
346     long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
347     long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
348     Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
349     return aTable;
350 }
351 
implGetBoundingBoxOnScreen()352 Rectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen()
353 {
354     Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( NULL ));
355     Rectangle aTableRect( m_aTable.calcTableRect() );
356     long nX = aGridRect.Left() + aTableRect.Left();
357     long nY = aGridRect.Top() + aTableRect.Top();
358     long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
359     long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
360     Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
361     return aTable;
362 }
363 // internal helper methods ----------------------------------------------------
implGetHeaderBar(sal_Int32 nChildIndex)364 Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar(
365         sal_Int32 nChildIndex )
366 {
367     Reference< XAccessible > xRet;
368     Reference< XAccessibleContext > xContext( m_xParent, uno::UNO_QUERY );
369     if( xContext.is() )
370     {
371         try
372         {
373             xRet = xContext->getAccessibleChild( nChildIndex );
374         }
375         catch( lang::IndexOutOfBoundsException& )
376         {
377             DBG_ERROR( "implGetHeaderBar - wrong child index" );
378         }
379         // RuntimeException goes to caller
380     }
381     return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY );
382 }
383 
getCellVector()384 std::vector< AccessibleGridControlTableCell* >& AccessibleGridControlTable::getCellVector()
385 {
386     return m_pCellVector;
387 }
388 
getAccessibleCellVector()389 std::vector< Reference< XAccessible > >& AccessibleGridControlTable::getAccessibleCellVector()
390 {
391     return m_pAccessCellVector;
392 }
393 // ============================================================================
394 
395 } // namespace accessibility
396 
397 // ============================================================================
398