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_sw.hxx"
26 #include <vos/mutex.hxx>
27 #include <rtl/uuid.h>
28 #include <rtl/ustrbuf.hxx>
29
30 #include <list>
31 #include <set>
32 #include <com/sun/star/accessibility/AccessibleRole.hpp>
33 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
36 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
37 #include <unotools/accessiblestatesethelper.hxx>
38 #include <vcl/svapp.hxx>
39 #include <frmfmt.hxx>
40 #include <tabfrm.hxx>
41 #include <rowfrm.hxx>
42 #include <cellfrm.hxx>
43 #include <swtable.hxx>
44 #include <crsrsh.hxx>
45 #include <viscrs.hxx>
46 #include <hints.hxx>
47 #include <fesh.hxx>
48 #include <accfrmobjslist.hxx>
49 #include <accmap.hxx>
50 #include <access.hrc>
51 #include <acctable.hxx>
52 #include <rowfrm.hxx>
53 #include <layfrm.hxx>
54 #include <com/sun/star/accessibility/XAccessibleText.hpp>
55
56 #include <editeng/brshitem.hxx>
57 #include <swatrset.hxx>
58 #include <frmatr.hxx>
59
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::accessibility;
62 using ::rtl::OUString;
63 using ::rtl::OUStringBuffer;
64 using namespace ::sw::access;
65
66 const sal_Char sServiceName[] = "com.sun.star.table.AccessibleTableView";
67 const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleTableView";
68
69 typedef ::std::less < sal_Int32 > Int32Less_Impl;
70 typedef ::std::set < sal_Int32, Int32Less_Impl > Int32Set_Impl;
71
72 typedef ::std::pair < sal_Int32, sal_Int32 > Int32Pair_Impl;
73 typedef ::std::list < Int32Pair_Impl > Int32PairList_Impl;
74
75 const unsigned int SELECTION_WITH_NUM = 10;
76
77 class SwAccTableSelHander_Impl
78 {
79 public:
80 virtual void Unselect( sal_Int32 nRowOrCol, sal_Int32 nExt ) = 0;
81 };
82
83
84 //------------------------------------------------------------------------------
85
86 class SwAccessibleTableData_Impl
87 {
88 SwAccessibleMap& mrAccMap;
89 Int32Set_Impl maRows;
90 Int32Set_Impl maColumns;
91 Int32PairList_Impl maExtents; // cell extends for event processing only
92 Point maTabFrmPos;
93 const SwTabFrm *mpTabFrm;
94 sal_Bool mbIsInPagePreview;
95 bool mbOnlyTableColumnHeader;
96
97 void CollectData( const SwFrm *pFrm );
98 void CollectColumnHeaderData( const SwFrm *pFrm );
99 void CollectRowHeaderData( const SwFrm *pFrm );
100 void CollectExtents( const SwFrm *pFrm );
101
102 sal_Bool FindCell( const Point& rPos, const SwFrm *pFrm ,
103 sal_Bool bExact, const SwFrm *& rFrm ) const;
104
105 void GetSelection( const Point& rTabPos, const SwRect& rArea,
106 const SwSelBoxes& rSelBoxes, const SwFrm *pFrm,
107 SwAccTableSelHander_Impl& rSelHdl,
108 sal_Bool bColumns ) const;
109
110 // --> OD 2007-06-27 #i77106#
IncludeRow(const SwFrm & rFrm) const111 inline bool IncludeRow( const SwFrm& rFrm ) const
112 {
113 return !mbOnlyTableColumnHeader ||
114 mpTabFrm->IsInHeadline( rFrm );
115 }
116 // <--
117 public:
118 // --> OD 2007-06-27 #i77106#
119 // add third optional parameter <bOnlyTableColumnHeader>, default value <false>
120 SwAccessibleTableData_Impl( SwAccessibleMap& rAccMap,
121 const SwTabFrm *pTabFrm,
122 sal_Bool bIsInPagePreview,
123 bool bOnlyTableColumnHeader = false );
124 // <--
125
GetRows() const126 const Int32Set_Impl& GetRows() const { return maRows; }
GetColumns() const127 const Int32Set_Impl& GetColumns() const { return maColumns; }
128
129 inline Int32Set_Impl::const_iterator GetRowIter( sal_Int32 nRow ) const;
130 inline Int32Set_Impl::const_iterator GetColumnIter( sal_Int32 nCol ) const;
131
132 const SwFrm *GetCell( sal_Int32 nRow, sal_Int32 nColumn, sal_Bool bExact,
133 SwAccessibleTable *pThis ) const;
134 const SwFrm *GetCellAtPos( sal_Int32 nLeft, sal_Int32 nTop,
135 sal_Bool bExact ) const;
136 inline sal_Int32 GetRowCount() const;
137 inline sal_Int32 GetColumnCount() const;
138 sal_Bool CompareExtents( const SwAccessibleTableData_Impl& r ) const;
139
140 void GetSelection( sal_Int32 nStart, sal_Int32 nEnd,
141 const SwSelBoxes& rSelBoxes,
142 SwAccTableSelHander_Impl& rSelHdl,
143 sal_Bool bColumns ) const;
144
145 void CheckRowAndCol( sal_Int32 nRow, sal_Int32 nCol,
146 SwAccessibleTable *pThis ) const;
147
148 void GetRowColumnAndExtent( const SwRect& rBox,
149 sal_Int32& rRow, sal_Int32& rColumn,
150 sal_Int32& rRowExtent,
151 sal_Int32& rColumnExtent ) const;
152
GetTablePos() const153 const Point& GetTablePos() const { return maTabFrmPos; }
SetTablePos(const Point & rPos)154 void SetTablePos( const Point& rPos ) { maTabFrmPos = rPos; }
155 };
156
CollectData(const SwFrm * pFrm)157 void SwAccessibleTableData_Impl::CollectData( const SwFrm *pFrm )
158 {
159 const SwAccessibleChildSList aList( *pFrm, mrAccMap );
160 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
161 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
162 while( aIter != aEndIter )
163 {
164 const SwAccessibleChild& rLower = *aIter;
165 const SwFrm *pLower = rLower.GetSwFrm();
166 if( pLower )
167 {
168 if( pLower->IsRowFrm() )
169 {
170 // --> OD 2007-06-27 #i77106#
171 if ( IncludeRow( *pLower ) )
172 {
173 maRows.insert( pLower->Frm().Top() - maTabFrmPos.Y() );
174 CollectData( pLower );
175 }
176 // <--
177 }
178 else if( pLower->IsCellFrm() &&
179 rLower.IsAccessible( mbIsInPagePreview ) )
180 {
181 maColumns.insert( pLower->Frm().Left() - maTabFrmPos.X() );
182 }
183 else
184 {
185 CollectData( pLower );
186 }
187 }
188 ++aIter;
189 }
190 }
191
CollectRowHeaderData(const SwFrm * pFrm)192 void SwAccessibleTableData_Impl::CollectRowHeaderData( const SwFrm *pFrm )
193 {
194 const SwAccessibleChildSList aList( *pFrm, mrAccMap );
195 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
196 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
197 while( aIter != aEndIter )
198 {
199 const SwAccessibleChild& rLower = *aIter;
200 const SwFrm *pLower = rLower.GetSwFrm();
201 if( pLower )
202 {
203 if( pLower->IsRowFrm() )
204 {
205
206 const SwTableLine* pLine = ((SwRowFrm*)pLower)->GetTabLine();
207 while( pLine->GetUpper() )
208 pLine = pLine->GetUpper()->GetUpper();
209
210 // Headerline?
211 //if(mpTabFrm->GetTable()->GetTabLines()[ 0 ] != pLine)
212 //return ;
213
214 maRows.insert( pLower->Frm().Top() - maTabFrmPos.Y() );
215
216 CollectRowHeaderData( pLower );
217
218
219 }
220 else if( pLower->IsCellFrm() &&
221 rLower.IsAccessible( mbIsInPagePreview ) )
222 {
223 //Added by yanjun. Can't find the "GetRowHeaderFlag" function(Need vefiry).
224 //if(((SwCellFrm*)pLower)->GetRowHeaderFlag())
225 // maColumns.insert( pLower->Frm().Left() - maTabFrmPos.X() );
226 }
227 else
228 {
229 CollectRowHeaderData( pLower );
230 }
231 }
232 ++aIter;
233 }
234 }
235
CollectColumnHeaderData(const SwFrm * pFrm)236 void SwAccessibleTableData_Impl::CollectColumnHeaderData( const SwFrm *pFrm )
237 {
238 const SwAccessibleChildSList aList( *pFrm, mrAccMap );
239 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
240 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
241 while( aIter != aEndIter )
242 {
243 const SwAccessibleChild& rLower = *aIter;
244 const SwFrm *pLower = rLower.GetSwFrm();
245 if( pLower )
246 {
247 if( pLower->IsRowFrm() )
248 {
249
250 const SwTableLine* pLine = ((SwRowFrm*)pLower)->GetTabLine();
251 while( pLine->GetUpper() )
252 pLine = pLine->GetUpper()->GetUpper();
253
254 // Headerline?
255 //if(mpTabFrm->GetTable()->GetTabLines()[ 0 ] != pLine)
256 //return ;
257
258 //if the current line is now header line, then return ;
259 sal_Int16 iCurrentRowIndex = mpTabFrm->GetTable()->GetTabLines().GetPos( pLine);
260 if(iCurrentRowIndex >= mpTabFrm->GetTable()->_GetRowsToRepeat())
261 return ;
262
263 maRows.insert( pLower->Frm().Top() - maTabFrmPos.Y() );
264
265 CollectColumnHeaderData( pLower );
266
267
268 }
269 else if( pLower->IsCellFrm() &&
270 rLower.IsAccessible( mbIsInPagePreview ) )
271 {
272 maColumns.insert( pLower->Frm().Left() - maTabFrmPos.X() );
273 }
274 else
275 {
276 CollectColumnHeaderData( pLower );
277 }
278 }
279 ++aIter;
280 }
281 }
CollectExtents(const SwFrm * pFrm)282 void SwAccessibleTableData_Impl::CollectExtents( const SwFrm *pFrm )
283 {
284 const SwAccessibleChildSList aList( *pFrm, mrAccMap );
285 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
286 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
287 while( aIter != aEndIter )
288 {
289 const SwAccessibleChild& rLower = *aIter;
290 const SwFrm *pLower = rLower.GetSwFrm();
291 if( pLower )
292 {
293 if( pLower->IsCellFrm() &&
294 rLower.IsAccessible( mbIsInPagePreview ) )
295 {
296 sal_Int32 nRow, nCol;
297 Int32Pair_Impl aCellExtents;
298 GetRowColumnAndExtent( pLower->Frm(), nRow, nCol,
299 aCellExtents.first,
300 aCellExtents.second );
301
302 maExtents.push_back( aCellExtents );
303 }
304 else
305 {
306 // --> OD 2007-06-27 #i77106#
307 if ( !pLower->IsRowFrm() ||
308 IncludeRow( *pLower ) )
309 {
310 CollectExtents( pLower );
311 }
312 // <--
313 }
314 }
315 ++aIter;
316 }
317 }
318
FindCell(const Point & rPos,const SwFrm * pFrm,sal_Bool bExact,const SwFrm * & rRet) const319 sal_Bool SwAccessibleTableData_Impl::FindCell(
320 const Point& rPos, const SwFrm *pFrm, sal_Bool bExact,
321 const SwFrm *& rRet ) const
322 {
323 sal_Bool bFound = sal_False;
324
325 const SwAccessibleChildSList aList( *pFrm, mrAccMap );
326 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
327 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
328 while( !bFound && aIter != aEndIter )
329 {
330 const SwAccessibleChild& rLower = *aIter;
331 const SwFrm *pLower = rLower.GetSwFrm();
332 ASSERT( pLower, "child should be a frame" );
333 if( pLower )
334 {
335 if( rLower.IsAccessible( mbIsInPagePreview ) )
336 {
337 ASSERT( pLower->IsCellFrm(), "lower is not a cell frame" );
338 const SwRect& rFrm = pLower->Frm();
339 if( rFrm.Right() >= rPos.X() && rFrm.Bottom() >= rPos.Y() )
340 {
341 // We have found the cell
342 ASSERT( rFrm.Left() <= rPos.X() && rFrm.Top() <= rPos.Y(),
343 "find frame moved to far!" );
344 bFound = sal_True;
345 if( !bExact ||
346 (rFrm.Top() == rPos.Y() && rFrm.Left() == rPos.Y() ) )
347 {
348 rRet = pLower;
349 }
350 }
351 }
352 else
353 {
354 // --> OD 2007-06-27 #i77106#
355 if ( !pLower->IsRowFrm() ||
356 IncludeRow( *pLower ) )
357 {
358 bFound = FindCell( rPos, pLower, bExact, rRet );
359 }
360 // <--
361 }
362 }
363 ++aIter;
364 }
365
366 return bFound;
367 }
368
GetSelection(const Point & rTabPos,const SwRect & rArea,const SwSelBoxes & rSelBoxes,const SwFrm * pFrm,SwAccTableSelHander_Impl & rSelHdl,sal_Bool bColumns) const369 void SwAccessibleTableData_Impl::GetSelection(
370 const Point& rTabPos,
371 const SwRect& rArea,
372 const SwSelBoxes& rSelBoxes,
373 const SwFrm *pFrm,
374 SwAccTableSelHander_Impl& rSelHdl,
375 sal_Bool bColumns ) const
376 {
377 const SwAccessibleChildSList aList( *pFrm, mrAccMap );
378 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
379 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
380 while( aIter != aEndIter )
381 {
382 const SwAccessibleChild& rLower = *aIter;
383 const SwFrm *pLower = rLower.GetSwFrm();
384 ASSERT( pLower, "child should be a frame" );
385 const SwRect& rBox = rLower.GetBox( mrAccMap );
386 if( pLower && rBox.IsOver( rArea ) )
387 {
388 if( rLower.IsAccessible( mbIsInPagePreview ) )
389 {
390 ASSERT( pLower->IsCellFrm(), "lower is not a cell frame" );
391 const SwCellFrm *pCFrm =
392 static_cast < const SwCellFrm * >( pLower );
393 SwTableBox *pBox =
394 const_cast< SwTableBox *>( pCFrm->GetTabBox() ); //SVPtrArr!
395 if( !rSelBoxes.Seek_Entry( pBox ) )
396 {
397 const Int32Set_Impl rRowsOrCols =
398 bColumns ? maColumns : maRows;
399
400 sal_Int32 nPos = bColumns ? (rBox.Left() - rTabPos.X())
401 : (rBox.Top() - rTabPos.Y());
402 Int32Set_Impl::const_iterator aSttRowOrCol(
403 rRowsOrCols.lower_bound( nPos ) );
404 sal_Int32 nRowOrCol =
405 static_cast< sal_Int32 >( ::std::distance(
406 rRowsOrCols.begin(), aSttRowOrCol ) );
407
408 nPos = bColumns ? (rBox.Right() - rTabPos.X())
409 : (rBox.Bottom() - rTabPos.Y());
410 Int32Set_Impl::const_iterator aEndRowOrCol(
411 rRowsOrCols.upper_bound( nPos ) );
412 sal_Int32 nExt =
413 static_cast< sal_Int32 >( ::std::distance(
414 aSttRowOrCol, aEndRowOrCol ) );
415
416 rSelHdl.Unselect( nRowOrCol, nExt );
417 }
418 }
419 else
420 {
421 // --> OD 2007-06-27 #i77106#
422 if ( !pLower->IsRowFrm() ||
423 IncludeRow( *pLower ) )
424 {
425 GetSelection( rTabPos, rArea, rSelBoxes, pLower, rSelHdl,
426 bColumns );
427 }
428 // <--
429 }
430 }
431 ++aIter;
432 }
433 }
434
GetCell(sal_Int32 nRow,sal_Int32 nColumn,sal_Bool,SwAccessibleTable * pThis) const435 const SwFrm *SwAccessibleTableData_Impl::GetCell(
436 sal_Int32 nRow, sal_Int32 nColumn, sal_Bool,
437 SwAccessibleTable *pThis ) const
438 {
439 CheckRowAndCol( nRow, nColumn, pThis );
440
441 Int32Set_Impl::const_iterator aSttCol( GetColumnIter( nColumn ) );
442 Int32Set_Impl::const_iterator aSttRow( GetRowIter( nRow ) );
443 const SwFrm *pCellFrm = GetCellAtPos( *aSttCol, *aSttRow, sal_False );
444
445 return pCellFrm;
446 }
447
GetSelection(sal_Int32 nStart,sal_Int32 nEnd,const SwSelBoxes & rSelBoxes,SwAccTableSelHander_Impl & rSelHdl,sal_Bool bColumns) const448 void SwAccessibleTableData_Impl::GetSelection(
449 sal_Int32 nStart, sal_Int32 nEnd,
450 const SwSelBoxes& rSelBoxes,
451 SwAccTableSelHander_Impl& rSelHdl,
452 sal_Bool bColumns ) const
453 {
454 SwRect aArea( mpTabFrm->Frm() );
455 Point aPos( aArea.Pos() );
456
457 const Int32Set_Impl& rRowsOrColumns = bColumns ? maColumns : maRows;
458 if( nStart > 0 )
459 {
460 Int32Set_Impl::const_iterator aStt( rRowsOrColumns.begin() );
461 ::std::advance( aStt,
462 static_cast< Int32Set_Impl::difference_type >( nStart ) );
463 if( bColumns )
464 aArea.Left( *aStt + aPos.X() );
465 else
466 aArea.Top( *aStt + aPos.Y() );
467 }
468 if( nEnd < static_cast< sal_Int32 >( rRowsOrColumns.size() ) )
469 {
470 Int32Set_Impl::const_iterator aEnd( rRowsOrColumns.begin() );
471 ::std::advance( aEnd,
472 static_cast< Int32Set_Impl::difference_type >( nEnd ) );
473 if( bColumns )
474 aArea.Right( *aEnd + aPos.X() - 1 );
475 else
476 aArea.Bottom( *aEnd + aPos.Y() - 1 );
477 }
478
479 GetSelection( aPos, aArea, rSelBoxes, mpTabFrm, rSelHdl, bColumns );
480 }
481
GetCellAtPos(sal_Int32 nLeft,sal_Int32 nTop,sal_Bool bExact) const482 const SwFrm *SwAccessibleTableData_Impl::GetCellAtPos(
483 sal_Int32 nLeft, sal_Int32 nTop, sal_Bool bExact ) const
484 {
485 Point aPos( mpTabFrm->Frm().Pos() );
486 aPos.Move( nLeft, nTop );
487 const SwFrm *pRet = 0;
488 FindCell( aPos, mpTabFrm, bExact, pRet );
489
490 return pRet;
491 }
492
GetRowCount() const493 inline sal_Int32 SwAccessibleTableData_Impl::GetRowCount() const
494 {
495 sal_Int32 count = static_cast< sal_Int32 >( maRows.size() ) ;
496 count = (count <=0)? 1:count;
497 return count;
498 }
499
GetColumnCount() const500 inline sal_Int32 SwAccessibleTableData_Impl::GetColumnCount() const
501 {
502 return static_cast< sal_Int32 >( maColumns.size() );
503 }
504
CompareExtents(const SwAccessibleTableData_Impl & rCmp) const505 sal_Bool SwAccessibleTableData_Impl::CompareExtents(
506 const SwAccessibleTableData_Impl& rCmp ) const
507 {
508 if( maExtents.size() != rCmp.maExtents.size() )
509 return sal_False;
510
511 Int32PairList_Impl::const_iterator aIter( maExtents.begin() );
512 Int32PairList_Impl::const_iterator aEndIter( maExtents.end() );
513 Int32PairList_Impl::const_iterator aCmpIter( rCmp.maExtents.begin() );
514 while( aIter != aEndIter )
515 {
516 if( *aIter != *aCmpIter )
517 return sal_False;
518
519 ++aIter;
520 ++aCmpIter;
521 }
522
523 return sal_True;
524 }
525
SwAccessibleTableData_Impl(SwAccessibleMap & rAccMap,const SwTabFrm * pTabFrm,sal_Bool bIsInPagePreview,bool bOnlyTableColumnHeader)526 SwAccessibleTableData_Impl::SwAccessibleTableData_Impl( SwAccessibleMap& rAccMap,
527 const SwTabFrm *pTabFrm,
528 sal_Bool bIsInPagePreview,
529 bool bOnlyTableColumnHeader )
530 : mrAccMap( rAccMap )
531 , maTabFrmPos( pTabFrm->Frm().Pos() )
532 , mpTabFrm( pTabFrm )
533 , mbIsInPagePreview( bIsInPagePreview )
534 , mbOnlyTableColumnHeader( bOnlyTableColumnHeader )
535 {
536 CollectData( mpTabFrm );
537 CollectExtents( mpTabFrm );
538 }
539
GetRowIter(sal_Int32 nRow) const540 inline Int32Set_Impl::const_iterator SwAccessibleTableData_Impl::GetRowIter(
541 sal_Int32 nRow ) const
542 {
543 Int32Set_Impl::const_iterator aCol( GetRows().begin() );
544 if( nRow > 0 )
545 {
546 ::std::advance( aCol,
547 static_cast< Int32Set_Impl::difference_type >( nRow ) );
548 }
549 return aCol;
550 }
551
GetColumnIter(sal_Int32 nColumn) const552 inline Int32Set_Impl::const_iterator SwAccessibleTableData_Impl::GetColumnIter(
553 sal_Int32 nColumn ) const
554 {
555 Int32Set_Impl::const_iterator aCol = GetColumns().begin();
556 if( nColumn > 0 )
557 {
558 ::std::advance( aCol,
559 static_cast< Int32Set_Impl::difference_type >( nColumn ) );
560 }
561 return aCol;
562 }
563
CheckRowAndCol(sal_Int32 nRow,sal_Int32 nCol,SwAccessibleTable * pThis) const564 void SwAccessibleTableData_Impl::CheckRowAndCol(
565 sal_Int32 nRow, sal_Int32 nCol, SwAccessibleTable *pThis ) const
566 {
567 if( ( nRow < 0 || nRow >= static_cast< sal_Int32 >( maRows.size() ) ) ||
568 ( nCol < 0 || nCol >= static_cast< sal_Int32 >( maColumns.size() ) ) )
569 {
570 uno::Reference < XAccessibleTable > xThis( pThis );
571 lang::IndexOutOfBoundsException aExcept(
572 OUString( RTL_CONSTASCII_USTRINGPARAM(
573 "row or column index out of range") ),
574 xThis );
575 throw aExcept;
576 }
577 }
578
GetRowColumnAndExtent(const SwRect & rBox,sal_Int32 & rRow,sal_Int32 & rColumn,sal_Int32 & rRowExtent,sal_Int32 & rColumnExtent) const579 void SwAccessibleTableData_Impl::GetRowColumnAndExtent(
580 const SwRect& rBox,
581 sal_Int32& rRow, sal_Int32& rColumn,
582 sal_Int32& rRowExtent, sal_Int32& rColumnExtent ) const
583 {
584 Int32Set_Impl::const_iterator aStt(
585 maRows.lower_bound( rBox.Top() - maTabFrmPos.Y() ) );
586 Int32Set_Impl::const_iterator aEnd(
587 maRows.upper_bound( rBox.Bottom() - maTabFrmPos.Y() ) );
588 rRow =
589 static_cast< sal_Int32 >( ::std::distance( maRows.begin(), aStt ) );
590 rRowExtent =
591 static_cast< sal_Int32 >( ::std::distance( aStt, aEnd ) );
592
593 aStt = maColumns.lower_bound( rBox.Left() - maTabFrmPos.X() );
594 aEnd = maColumns.upper_bound( rBox.Right() - maTabFrmPos.X() );
595 rColumn =
596 static_cast< sal_Int32 >( ::std::distance( maColumns.begin(), aStt ) );
597 rColumnExtent =
598 static_cast< sal_Int32 >( ::std::distance( aStt, aEnd ) );
599 }
600
601 //------------------------------------------------------------------------------
602
603 class SwAccSingleTableSelHander_Impl : public SwAccTableSelHander_Impl
604 {
605 sal_Bool bSelected;
606
607 public:
608
609 inline SwAccSingleTableSelHander_Impl();
610
IsSelected() const611 inline sal_Bool IsSelected() const { return bSelected; }
612
613 virtual void Unselect( sal_Int32, sal_Int32 );
614 };
615
SwAccSingleTableSelHander_Impl()616 inline SwAccSingleTableSelHander_Impl::SwAccSingleTableSelHander_Impl() :
617 bSelected( sal_True )
618 {
619 }
620
Unselect(sal_Int32,sal_Int32)621 void SwAccSingleTableSelHander_Impl::Unselect( sal_Int32, sal_Int32 )
622 {
623 bSelected = sal_False;
624 }
625
626 //------------------------------------------------------------------------------
627
628 class SwAccAllTableSelHander_Impl : public SwAccTableSelHander_Impl
629
630 {
631 ::std::vector< sal_Bool > aSelected;
632 sal_Int32 nCount;
633
634 public:
635
636 inline SwAccAllTableSelHander_Impl( sal_Int32 nSize );
637
638 uno::Sequence < sal_Int32 > GetSelSequence();
639
640 virtual void Unselect( sal_Int32 nRowOrCol, sal_Int32 nExt );
641 virtual ~SwAccAllTableSelHander_Impl();
642 };
643
~SwAccAllTableSelHander_Impl()644 SwAccAllTableSelHander_Impl::~SwAccAllTableSelHander_Impl()
645 {
646 }
647
SwAccAllTableSelHander_Impl(sal_Int32 nSize)648 inline SwAccAllTableSelHander_Impl::SwAccAllTableSelHander_Impl( sal_Int32 nSize ) :
649 aSelected( nSize, sal_True ),
650 nCount( nSize )
651 {
652 }
653
GetSelSequence()654 uno::Sequence < sal_Int32 > SwAccAllTableSelHander_Impl::GetSelSequence()
655 {
656 ASSERT( nCount >= 0, "underflow" );
657 uno::Sequence < sal_Int32 > aRet( nCount );
658 sal_Int32 *pRet = aRet.getArray();
659 sal_Int32 nPos = 0;
660 size_t nSize = aSelected.size();
661 for( size_t i=0; i < nSize && nPos < nCount; i++ )
662 {
663 if( aSelected[i] )
664 {
665 *pRet++ = i;
666 nPos++;
667 }
668 }
669
670 ASSERT( nPos == nCount, "count is wrong" );
671
672 return aRet;
673 }
674
Unselect(sal_Int32 nRowOrCol,sal_Int32 nExt)675 void SwAccAllTableSelHander_Impl::Unselect( sal_Int32 nRowOrCol,
676 sal_Int32 nExt )
677 {
678 ASSERT( static_cast< size_t >( nRowOrCol ) < aSelected.size(),
679 "index to large" );
680 ASSERT( static_cast< size_t >( nRowOrCol+nExt ) <= aSelected.size(),
681 "extent to large" );
682 while( nExt )
683 {
684 if( aSelected[static_cast< size_t >( nRowOrCol )] )
685 {
686 aSelected[static_cast< size_t >( nRowOrCol )] = sal_False;
687 nCount--;
688 }
689 nExt--;
690 nRowOrCol++;
691 }
692 }
693
694 //------------------------------------------------------------------------------
695
GetSelBoxes() const696 const SwSelBoxes *SwAccessibleTable::GetSelBoxes() const
697 {
698 const SwSelBoxes *pSelBoxes = 0;
699 const SwCrsrShell *pCSh = GetCrsrShell();
700 if( (pCSh != NULL) && pCSh->IsTableMode() )
701 {
702 pSelBoxes = &pCSh->GetTableCrsr()->GetBoxes();
703 }
704
705 return pSelBoxes;
706 }
707
FireTableChangeEvent(const SwAccessibleTableData_Impl & rTableData)708 void SwAccessibleTable::FireTableChangeEvent(
709 const SwAccessibleTableData_Impl& rTableData )
710 {
711 AccessibleTableModelChange aModelChange;
712 aModelChange.Type = AccessibleTableModelChangeType::UPDATE;
713 aModelChange.FirstRow = 0;
714 aModelChange.LastRow = rTableData.GetRowCount() - 1;
715 aModelChange.FirstColumn = 0;
716 aModelChange.LastColumn = rTableData.GetColumnCount() - 1;
717
718 AccessibleEventObject aEvent;
719 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
720 aEvent.NewValue <<= aModelChange;
721
722 FireAccessibleEvent( aEvent );
723 }
724
725
GetTableBox(sal_Int32 nChildIndex) const726 const SwTableBox* SwAccessibleTable::GetTableBox( sal_Int32 nChildIndex ) const
727 {
728 DBG_ASSERT( nChildIndex >= 0, "Illegal child index." );
729 // --> OD 2007-06-27 #i77106#
730 DBG_ASSERT( nChildIndex < const_cast<SwAccessibleTable*>(this)->getAccessibleChildCount(), "Illegal child index." );
731 // <--
732
733 const SwTableBox* pBox = NULL;
734
735 // get table box for 'our' table cell
736 SwAccessibleChild aCell( GetChild( *(const_cast<SwAccessibleMap*>(GetMap())), nChildIndex ) );
737 if( aCell.GetSwFrm() )
738 {
739 const SwFrm* pChildFrm = aCell.GetSwFrm();
740 if( (pChildFrm != NULL) && pChildFrm->IsCellFrm() )
741 {
742 const SwCellFrm* pCellFrm =
743 static_cast<const SwCellFrm*>( pChildFrm );
744 pBox = pCellFrm->GetTabBox();
745 }
746 }
747
748 DBG_ASSERT( pBox != NULL, "We need the table box." );
749 return pBox;
750 }
751
IsChildSelected(sal_Int32 nChildIndex) const752 sal_Bool SwAccessibleTable::IsChildSelected( sal_Int32 nChildIndex ) const
753 {
754 sal_Bool bRet = sal_False;
755 const SwSelBoxes* pSelBoxes = GetSelBoxes();
756 if( pSelBoxes )
757 {
758 const SwTableBox* pBox = GetTableBox( nChildIndex );
759 DBG_ASSERT( pBox != NULL, "We need the table box." );
760 bRet = pSelBoxes->Seek_Entry( const_cast<SwTableBox*>( pBox ) );
761 }
762
763 return bRet;
764 }
765
GetIndexOfSelectedChild(sal_Int32 nSelectedChildIndex) const766 sal_Int32 SwAccessibleTable::GetIndexOfSelectedChild(
767 sal_Int32 nSelectedChildIndex ) const
768 {
769 // iterate over all children to n-th isAccessibleChildSelected()
770 // --> OD 2007-06-27 #i77106#
771 sal_Int32 nChildren = const_cast<SwAccessibleTable*>(this)->getAccessibleChildCount();
772 // <--
773 if( nSelectedChildIndex >= nChildren )
774 return -1L;
775
776 sal_Int32 n = 0;
777 while( n < nChildren )
778 {
779 if( IsChildSelected( n ) )
780 {
781 if( 0 == nSelectedChildIndex )
782 break;
783 else
784 --nSelectedChildIndex;
785 }
786 ++n;
787 }
788
789 return n < nChildren ? n : -1L;
790 }
791
GetStates(::utl::AccessibleStateSetHelper & rStateSet)792 void SwAccessibleTable::GetStates(
793 ::utl::AccessibleStateSetHelper& rStateSet )
794 {
795 SwAccessibleContext::GetStates( rStateSet );
796 //Solution:Add resizable state to table
797 rStateSet.AddState( AccessibleStateType::RESIZABLE );
798 // MULTISELECTABLE
799 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
800 SwCrsrShell* pCrsrShell = GetCrsrShell();
801 if( pCrsrShell )
802 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
803 }
804
SwAccessibleTable(SwAccessibleMap * pInitMap,const SwTabFrm * pTabFrm)805 SwAccessibleTable::SwAccessibleTable(
806 SwAccessibleMap* pInitMap,
807 const SwTabFrm* pTabFrm ) :
808 SwAccessibleContext( pInitMap, AccessibleRole::TABLE, pTabFrm ),
809 mpTableData( 0 )
810 {
811 vos::OGuard aGuard(Application::GetSolarMutex());
812
813 const SwFrmFmt *pFrmFmt = pTabFrm->GetFmt();
814 const_cast< SwFrmFmt * >( pFrmFmt )->Add( this );
815 const String& rName = pFrmFmt->GetName();
816
817 OUStringBuffer aBuffer( rName.Len() + 4 );
818 aBuffer.append( OUString(rName) );
819 aBuffer.append( static_cast<sal_Unicode>( '-' ) );
820 aBuffer.append( static_cast<sal_Int32>( pTabFrm->GetPhyPageNum() ) );
821
822 SetName( aBuffer.makeStringAndClear() );
823
824 OUString sArg1( static_cast< const SwTabFrm * >( GetFrm() )
825 ->GetFmt()->GetName() );
826 OUString sArg2( GetFormattedPageNumber() );
827
828 sDesc = GetResource( STR_ACCESS_TABLE_DESC, &sArg1, &sArg2 );
829 UpdateTableData();
830 }
831
~SwAccessibleTable()832 SwAccessibleTable::~SwAccessibleTable()
833 {
834 vos::OGuard aGuard(Application::GetSolarMutex());
835
836 delete mpTableData;
837 }
838
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)839 void SwAccessibleTable::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
840 {
841 sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
842 const SwTabFrm *pTabFrm = static_cast< const SwTabFrm * >( GetFrm() );
843 switch( nWhich )
844 {
845 case RES_NAME_CHANGED:
846 if( pTabFrm )
847 {
848 const SwFrmFmt *pFrmFmt = pTabFrm->GetFmt();
849 ASSERT( pFrmFmt == GetRegisteredIn(), "invalid frame" );
850
851 OUString sOldName( GetName() );
852
853 const String& rNewTabName = pFrmFmt->GetName();
854 OUStringBuffer aBuffer( rNewTabName.Len() + 4 );
855 aBuffer.append( OUString(rNewTabName) );
856 aBuffer.append( static_cast<sal_Unicode>( '-' ) );
857 aBuffer.append( static_cast<sal_Int32>( pTabFrm->GetPhyPageNum() ) );
858
859 SetName( aBuffer.makeStringAndClear() );
860 if( sOldName != GetName() )
861 {
862 AccessibleEventObject aEvent;
863 aEvent.EventId = AccessibleEventId::NAME_CHANGED;
864 aEvent.OldValue <<= sOldName;
865 aEvent.NewValue <<= GetName();
866 FireAccessibleEvent( aEvent );
867 }
868
869 OUString sOldDesc( sDesc );
870 OUString sArg1( rNewTabName );
871 OUString sArg2( GetFormattedPageNumber() );
872
873 sDesc = GetResource( STR_ACCESS_TABLE_DESC, &sArg1, &sArg2 );
874 if( sDesc != sOldDesc )
875 {
876 AccessibleEventObject aEvent;
877 aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
878 aEvent.OldValue <<= sOldDesc;
879 aEvent.NewValue <<= sDesc;
880 FireAccessibleEvent( aEvent );
881 }
882 }
883 break;
884
885 case RES_OBJECTDYING:
886 // mba: it seems that this class intentionally does not call code in base class SwClient
887 if( pOld && ( GetRegisteredIn() == static_cast< SwModify *>( static_cast< const SwPtrMsgPoolItem * >( pOld )->pObject ) ) )
888 GetRegisteredInNonConst()->Remove( this );
889 break;
890
891 default:
892 // mba: former call to base class method removed as it is meant to handle only RES_OBJECTDYING
893 break;
894 }
895 }
896
queryInterface(const uno::Type & rType)897 uno::Any SwAccessibleTable::queryInterface( const uno::Type& rType )
898 {
899 uno::Any aRet;
900 if ( rType == ::getCppuType( static_cast< uno::Reference< XAccessibleTable > * >( 0 ) ) )
901 {
902 uno::Reference<XAccessibleTable> xThis( this );
903 aRet <<= xThis;
904 }
905 else if ( rType == ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) ) )
906 {
907 uno::Reference<XAccessibleSelection> xSelection( this );
908 aRet <<= xSelection;
909 }
910 else if ( rType == ::getCppuType((uno::Reference<XAccessibleTableSelection> *)0) )
911 {
912 uno::Reference<XAccessibleTableSelection> xTableExtent( this );
913 aRet <<= xTableExtent;
914 }
915 else
916 {
917 aRet = SwAccessibleContext::queryInterface(rType);
918 }
919
920 return aRet;
921 }
922
923 //====== XTypeProvider ====================================================
getTypes()924 uno::Sequence< uno::Type > SAL_CALL SwAccessibleTable::getTypes()
925 {
926 uno::Sequence< uno::Type > aTypes( SwAccessibleContext::getTypes() );
927
928 sal_Int32 nIndex = aTypes.getLength();
929 aTypes.realloc( nIndex + 2 );
930
931 uno::Type* pTypes = aTypes.getArray();
932 pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) );
933 pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleTable > * >( 0 ) );
934
935 return aTypes;
936 }
937
getImplementationId()938 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleTable::getImplementationId()
939 {
940 vos::OGuard aGuard(Application::GetSolarMutex());
941 static uno::Sequence< sal_Int8 > aId( 16 );
942 static sal_Bool bInit = sal_False;
943 if(!bInit)
944 {
945 rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
946 bInit = sal_True;
947 }
948 return aId;
949 }
950
951 // --> OD 2007-06-28 #i77106#
CreateNewTableData()952 SwAccessibleTableData_Impl* SwAccessibleTable::CreateNewTableData()
953 {
954 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( GetFrm() );
955 return new SwAccessibleTableData_Impl( *GetMap(), pTabFrm, IsInPagePreview() );
956 }
957 // <--
958
UpdateTableData()959 void SwAccessibleTable::UpdateTableData()
960 {
961 // --> OD 2007-06-28 #i77106# - usage of new method <CreateNewTableData()>
962 delete mpTableData;
963 mpTableData = CreateNewTableData();
964 // <--
965 }
966
ClearTableData()967 void SwAccessibleTable::ClearTableData()
968 {
969 delete mpTableData;
970 mpTableData = 0;
971 }
972
getAccessibleDescription(void)973 OUString SAL_CALL SwAccessibleTable::getAccessibleDescription (void)
974 {
975 vos::OGuard aGuard(Application::GetSolarMutex());
976
977 CHECK_FOR_DEFUNC( XAccessibleContext )
978
979 return sDesc;
980 }
981
getAccessibleRowCount()982 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRowCount()
983 {
984 vos::OGuard aGuard(Application::GetSolarMutex());
985
986 CHECK_FOR_DEFUNC( XAccessibleTable )
987
988 return GetTableData().GetRowCount();
989 }
990
getAccessibleColumnCount()991 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumnCount( )
992 {
993 vos::OGuard aGuard(Application::GetSolarMutex());
994
995 CHECK_FOR_DEFUNC( XAccessibleTable )
996
997 return GetTableData().GetColumnCount();
998 }
999
getAccessibleRowDescription(sal_Int32 nRow)1000 OUString SAL_CALL SwAccessibleTable::getAccessibleRowDescription(
1001 sal_Int32 nRow )
1002 {
1003 // --> OD 2010-03-10 #i87532#
1004 // determine table cell in <nRow>th row and in first column of row header table
1005 // and return its text content.
1006 OUString sRowDesc;
1007
1008 GetTableData().CheckRowAndCol(nRow, 0, this);
1009
1010 uno::Reference< XAccessibleTable > xTableRowHeader = getAccessibleRowHeaders();
1011 if ( xTableRowHeader.is() )
1012 {
1013 uno::Reference< XAccessible > xRowHeaderCell =
1014 xTableRowHeader->getAccessibleCellAt( nRow, 0 );
1015 ASSERT( xRowHeaderCell.is(),
1016 "<SwAccessibleTable::getAccessibleRowDescription(..)> - missing row header cell -> serious issue." );
1017 uno::Reference< XAccessibleContext > xRowHeaderCellContext =
1018 xRowHeaderCell->getAccessibleContext();
1019 const sal_Int32 nCellChildCount( xRowHeaderCellContext->getAccessibleChildCount() );
1020 for ( sal_Int32 nChildIndex = 0; nChildIndex < nCellChildCount; ++nChildIndex )
1021 {
1022 uno::Reference< XAccessible > xChild = xRowHeaderCellContext->getAccessibleChild( nChildIndex );
1023 uno::Reference< XAccessibleText > xChildText( xChild, uno::UNO_QUERY );
1024 if ( xChildText.is() )
1025 {
1026 sRowDesc = sRowDesc + xChildText->getText();
1027 }
1028 }
1029 }
1030
1031 return sRowDesc;
1032 // <--
1033 }
1034
getAccessibleColumnDescription(sal_Int32 nColumn)1035 OUString SAL_CALL SwAccessibleTable::getAccessibleColumnDescription(
1036 sal_Int32 nColumn )
1037 {
1038 // --> OD 2010-03-10 #i87532#
1039 // determine table cell in first row and in <nColumn>th column of column header table
1040 // and return its text content.
1041 OUString sColumnDesc;
1042
1043 GetTableData().CheckRowAndCol(0, nColumn, this);
1044
1045 uno::Reference< XAccessibleTable > xTableColumnHeader = getAccessibleColumnHeaders();
1046 if ( xTableColumnHeader.is() )
1047 {
1048 uno::Reference< XAccessible > xColumnHeaderCell =
1049 xTableColumnHeader->getAccessibleCellAt( 0, nColumn );
1050 ASSERT( xColumnHeaderCell.is(),
1051 "<SwAccessibleTable::getAccessibleColumnDescription(..)> - missing column header cell -> serious issue." );
1052 uno::Reference< XAccessibleContext > xColumnHeaderCellContext =
1053 xColumnHeaderCell->getAccessibleContext();
1054 const sal_Int32 nCellChildCount( xColumnHeaderCellContext->getAccessibleChildCount() );
1055 for ( sal_Int32 nChildIndex = 0; nChildIndex < nCellChildCount; ++nChildIndex )
1056 {
1057 uno::Reference< XAccessible > xChild = xColumnHeaderCellContext->getAccessibleChild( nChildIndex );
1058 uno::Reference< XAccessibleText > xChildText( xChild, uno::UNO_QUERY );
1059 if ( xChildText.is() )
1060 {
1061 sColumnDesc = sColumnDesc + xChildText->getText();
1062 }
1063 }
1064 }
1065
1066 return sColumnDesc;
1067 // <--
1068 }
1069
getAccessibleRowExtentAt(sal_Int32 nRow,sal_Int32 nColumn)1070 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRowExtentAt(
1071 sal_Int32 nRow, sal_Int32 nColumn )
1072 {
1073 sal_Int32 nExtend = -1;
1074
1075 vos::OGuard aGuard(Application::GetSolarMutex());
1076
1077 CHECK_FOR_DEFUNC( XAccessibleTable )
1078
1079 UpdateTableData();
1080 GetTableData().CheckRowAndCol( nRow, nColumn, this );
1081
1082 Int32Set_Impl::const_iterator aSttCol(
1083 GetTableData().GetColumnIter( nColumn ) );
1084 Int32Set_Impl::const_iterator aSttRow(
1085 GetTableData().GetRowIter( nRow ) );
1086 const SwFrm *pCellFrm = GetTableData().GetCellAtPos( *aSttCol, *aSttRow,
1087 sal_False );
1088 if( pCellFrm )
1089 {
1090 sal_Int32 nBottom = pCellFrm->Frm().Bottom();
1091 nBottom -= GetFrm()->Frm().Top();
1092 Int32Set_Impl::const_iterator aEndRow(
1093 GetTableData().GetRows().upper_bound( nBottom ) );
1094 nExtend =
1095 static_cast< sal_Int32 >( ::std::distance( aSttRow, aEndRow ) );
1096 }
1097
1098 return nExtend;
1099 }
1100
getAccessibleColumnExtentAt(sal_Int32 nRow,sal_Int32 nColumn)1101 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumnExtentAt(
1102 sal_Int32 nRow, sal_Int32 nColumn )
1103 {
1104 sal_Int32 nExtend = -1;
1105
1106 vos::OGuard aGuard(Application::GetSolarMutex());
1107
1108 CHECK_FOR_DEFUNC( XAccessibleTable )
1109 UpdateTableData();
1110
1111 GetTableData().CheckRowAndCol( nRow, nColumn, this );
1112
1113 Int32Set_Impl::const_iterator aSttCol(
1114 GetTableData().GetColumnIter( nColumn ) );
1115 Int32Set_Impl::const_iterator aSttRow(
1116 GetTableData().GetRowIter( nRow ) );
1117 const SwFrm *pCellFrm = GetTableData().GetCellAtPos( *aSttCol, *aSttRow,
1118 sal_False );
1119 if( pCellFrm )
1120 {
1121 sal_Int32 nRight = pCellFrm->Frm().Right();
1122 nRight -= GetFrm()->Frm().Left();
1123 Int32Set_Impl::const_iterator aEndCol(
1124 GetTableData().GetColumns().upper_bound( nRight ) );
1125 nExtend =
1126 static_cast< sal_Int32 >( ::std::distance( aSttCol, aEndCol ) );
1127 }
1128
1129 return nExtend;
1130 }
1131
1132 uno::Reference< XAccessibleTable > SAL_CALL
getAccessibleRowHeaders()1133 SwAccessibleTable::getAccessibleRowHeaders( )
1134 {
1135 // Row headers aren't supported
1136 return uno::Reference< XAccessibleTable >();
1137 }
1138
1139 uno::Reference< XAccessibleTable > SAL_CALL
getAccessibleColumnHeaders()1140 SwAccessibleTable::getAccessibleColumnHeaders( )
1141 {
1142 // MT IA2: Which one should win nowadys???
1143 /*
1144 // IA2 version:
1145 uno::Reference< XAccessibleTable > xRet;
1146 SwTabFrm* pTabFrm =( SwTabFrm*)( GetFrm() );
1147 if (pTabFrm)
1148 {
1149 if(pTabFrm->GetTable()->_GetRowsToRepeat() > 0)
1150 {
1151 //for errata table header
1152 SwAccessibleTableData_Impl *mpHeadTableData = new SwAccessibleTableData_Impl( pTabFrm, sal_False, sal_True);
1153 //for errata table header
1154 SwAccessibleTable *pHeadAccessibleTable = new SwAccessibleTable(GetMap(),pTabFrm);
1155 pHeadAccessibleTable->SetTableData(mpHeadTableData);
1156 xRet = pHeadAccessibleTable;
1157 }
1158 }
1159 return xRet;
1160 */
1161 // --> OD 2010-03-10 #i87532#
1162 // assure that return accessible object is empty, if no column header exists.
1163 SwAccessibleTableColHeaders* pTableColHeaders =
1164 new SwAccessibleTableColHeaders( GetMap(), static_cast< const SwTabFrm *>( GetFrm() ) );
1165 uno::Reference< XAccessibleTable > xTableColumnHeaders( pTableColHeaders );
1166 if ( pTableColHeaders->getAccessibleChildCount() <= 0 )
1167 {
1168 return uno::Reference< XAccessibleTable >();
1169 }
1170
1171 return xTableColumnHeaders;
1172 // <--
1173 }
1174
getSelectedAccessibleRows()1175 uno::Sequence< sal_Int32 > SAL_CALL SwAccessibleTable::getSelectedAccessibleRows()
1176 {
1177 vos::OGuard aGuard(Application::GetSolarMutex());
1178
1179 CHECK_FOR_DEFUNC( XAccessibleTable )
1180
1181 const SwSelBoxes *pSelBoxes = GetSelBoxes();
1182 if( pSelBoxes )
1183 {
1184 sal_Int32 nRows = GetTableData().GetRowCount();
1185 SwAccAllTableSelHander_Impl aSelRows( nRows );
1186
1187 GetTableData().GetSelection( 0, nRows, *pSelBoxes, aSelRows,
1188 sal_False );
1189
1190 return aSelRows.GetSelSequence();
1191 }
1192 else
1193 {
1194 return uno::Sequence< sal_Int32 >( 0 );
1195 }
1196 }
1197
getSelectedAccessibleColumns()1198 uno::Sequence< sal_Int32 > SAL_CALL SwAccessibleTable::getSelectedAccessibleColumns()
1199 {
1200 vos::OGuard aGuard(Application::GetSolarMutex());
1201
1202 CHECK_FOR_DEFUNC( XAccessibleTable )
1203
1204 const SwSelBoxes *pSelBoxes = GetSelBoxes();
1205 if( pSelBoxes )
1206 {
1207 sal_Int32 nCols = GetTableData().GetColumnCount();
1208 SwAccAllTableSelHander_Impl aSelCols( nCols );
1209
1210 GetTableData().GetSelection( 0, nCols, *pSelBoxes, aSelCols, sal_True );
1211
1212 return aSelCols.GetSelSequence();
1213 }
1214 else
1215 {
1216 return uno::Sequence< sal_Int32 >( 0 );
1217 }
1218 }
1219
isAccessibleRowSelected(sal_Int32 nRow)1220 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleRowSelected( sal_Int32 nRow )
1221 {
1222 vos::OGuard aGuard(Application::GetSolarMutex());
1223
1224 CHECK_FOR_DEFUNC( XAccessibleTable )
1225
1226 GetTableData().CheckRowAndCol( nRow, 0, this );
1227
1228 sal_Bool bRet;
1229 const SwSelBoxes *pSelBoxes = GetSelBoxes();
1230 if( pSelBoxes )
1231 {
1232 SwAccSingleTableSelHander_Impl aSelRow;
1233 GetTableData().GetSelection( nRow, nRow+1, *pSelBoxes, aSelRow,
1234 sal_False );
1235 bRet = aSelRow.IsSelected();
1236 }
1237 else
1238 {
1239 bRet = sal_False;
1240 }
1241
1242 return bRet;
1243 }
1244
isAccessibleColumnSelected(sal_Int32 nColumn)1245 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleColumnSelected(
1246 sal_Int32 nColumn )
1247 {
1248 vos::OGuard aGuard(Application::GetSolarMutex());
1249
1250 CHECK_FOR_DEFUNC( XAccessibleTable )
1251
1252 GetTableData().CheckRowAndCol( 0, nColumn, this );
1253
1254 sal_Bool bRet;
1255 const SwSelBoxes *pSelBoxes = GetSelBoxes();
1256 if( pSelBoxes )
1257 {
1258 SwAccSingleTableSelHander_Impl aSelCol;
1259
1260 GetTableData().GetSelection( nColumn, nColumn+1, *pSelBoxes, aSelCol,
1261 sal_True );
1262 bRet = aSelCol.IsSelected();
1263 }
1264 else
1265 {
1266 bRet = sal_False;
1267 }
1268
1269 return bRet;
1270 }
1271
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)1272 uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleCellAt(
1273 sal_Int32 nRow, sal_Int32 nColumn )
1274 {
1275 uno::Reference< XAccessible > xRet;
1276
1277 vos::OGuard aGuard(Application::GetSolarMutex());
1278
1279 CHECK_FOR_DEFUNC( XAccessibleTable )
1280
1281 const SwFrm *pCellFrm =
1282 GetTableData().GetCell( nRow, nColumn, sal_False, this );
1283 if( pCellFrm )
1284 xRet = GetMap()->GetContext( pCellFrm, sal_True );
1285
1286 return xRet;
1287 }
1288
getAccessibleCaption()1289 uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleCaption()
1290 {
1291 // captions aren't supported
1292 return uno::Reference< XAccessible >();
1293 }
1294
getAccessibleSummary()1295 uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleSummary()
1296 {
1297 // summaries aren't supported
1298 return uno::Reference< XAccessible >();
1299 }
1300
isAccessibleSelected(sal_Int32 nRow,sal_Int32 nColumn)1301 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleSelected(
1302 sal_Int32 nRow, sal_Int32 nColumn )
1303 {
1304 sal_Bool bRet = sal_False;
1305
1306 vos::OGuard aGuard(Application::GetSolarMutex());
1307
1308 CHECK_FOR_DEFUNC( XAccessibleTable )
1309
1310 const SwFrm *pFrm =
1311 GetTableData().GetCell( nRow, nColumn, sal_False, this );
1312 if( pFrm && pFrm->IsCellFrm() )
1313 {
1314 const SwSelBoxes *pSelBoxes = GetSelBoxes();
1315 if( pSelBoxes )
1316 {
1317 const SwCellFrm *pCFrm = static_cast < const SwCellFrm * >( pFrm );
1318 SwTableBox *pBox =
1319 const_cast< SwTableBox *>( pCFrm->GetTabBox() ); //SVPtrArr!
1320 bRet = pSelBoxes->Seek_Entry( pBox );
1321 }
1322 }
1323
1324 return bRet;
1325 }
1326
getAccessibleIndex(sal_Int32 nRow,sal_Int32 nColumn)1327 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleIndex(
1328 sal_Int32 nRow, sal_Int32 nColumn )
1329 {
1330 sal_Int32 nRet = -1;
1331
1332 vos::OGuard aGuard(Application::GetSolarMutex());
1333
1334 CHECK_FOR_DEFUNC( XAccessibleTable )
1335
1336 SwAccessibleChild aCell( GetTableData().GetCell( nRow, nColumn, sal_False, this ));
1337 if ( aCell.IsValid() )
1338 {
1339 nRet = GetChildIndex( *(GetMap()), aCell );
1340 }
1341
1342 return nRet;
1343 }
1344
getAccessibleRow(sal_Int32 nChildIndex)1345 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRow( sal_Int32 nChildIndex )
1346 {
1347 sal_Int32 nRet = -1;
1348
1349 vos::OGuard aGuard(Application::GetSolarMutex());
1350
1351 CHECK_FOR_DEFUNC( XAccessibleTable )
1352
1353 // --> OD 2007-06-27 #i77106#
1354 if ( ( nChildIndex < 0 ) ||
1355 ( nChildIndex >= getAccessibleChildCount() ) )
1356 {
1357 throw lang::IndexOutOfBoundsException();
1358 }
1359 // <--
1360
1361 SwAccessibleChild aCell( GetChild( *(GetMap()), nChildIndex ) );
1362 if ( aCell.GetSwFrm() )
1363 {
1364 sal_Int32 nTop = aCell.GetSwFrm()->Frm().Top();
1365 nTop -= GetFrm()->Frm().Top();
1366 Int32Set_Impl::const_iterator aRow(
1367 GetTableData().GetRows().lower_bound( nTop ) );
1368 nRet = static_cast< sal_Int32 >( ::std::distance(
1369 GetTableData().GetRows().begin(), aRow ) );
1370 }
1371 else
1372 {
1373 ASSERT( !aCell.IsValid(), "SwAccessibleTable::getAccessibleColumn:"
1374 "aCell not expected to be valid.");
1375
1376 throw lang::IndexOutOfBoundsException();
1377 }
1378
1379 return nRet;
1380 }
1381
getAccessibleColumn(sal_Int32 nChildIndex)1382 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumn(
1383 sal_Int32 nChildIndex )
1384 {
1385 sal_Int32 nRet = -1;
1386
1387 vos::OGuard aGuard(Application::GetSolarMutex());
1388
1389 CHECK_FOR_DEFUNC( XAccessibleTable )
1390
1391 // --> OD 2007-06-27 #i77106#
1392 if ( ( nChildIndex < 0 ) ||
1393 ( nChildIndex >= getAccessibleChildCount() ) )
1394 {
1395 throw lang::IndexOutOfBoundsException();
1396 }
1397 // <--
1398
1399 SwAccessibleChild aCell( GetChild( *(GetMap()), nChildIndex ) );
1400 if ( aCell.GetSwFrm() )
1401 {
1402 sal_Int32 nLeft = aCell.GetSwFrm()->Frm().Left();
1403 nLeft -= GetFrm()->Frm().Left();
1404 Int32Set_Impl::const_iterator aCol(
1405 GetTableData().GetColumns().lower_bound( nLeft ) );
1406 nRet = static_cast< sal_Int32 >( ::std::distance(
1407 GetTableData().GetColumns().begin(), aCol ) );
1408 }
1409 else
1410 {
1411 ASSERT( !aCell.IsValid(), "SwAccessibleTable::getAccessibleColumn:"
1412 "aCell not expected to be valid.");
1413
1414 throw lang::IndexOutOfBoundsException();
1415 }
1416
1417 return nRet;
1418 }
1419
1420
getImplementationName()1421 OUString SAL_CALL SwAccessibleTable::getImplementationName()
1422 {
1423 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
1424 }
1425
supportsService(const OUString & sTestServiceName)1426 sal_Bool SAL_CALL SwAccessibleTable::supportsService(
1427 const OUString& sTestServiceName)
1428 {
1429 return sTestServiceName.equalsAsciiL( sServiceName,
1430 sizeof(sServiceName)-1 ) ||
1431 sTestServiceName.equalsAsciiL( sAccessibleServiceName,
1432 sizeof(sAccessibleServiceName)-1 );
1433 }
1434
getSupportedServiceNames()1435 uno::Sequence< OUString > SAL_CALL SwAccessibleTable::getSupportedServiceNames()
1436 {
1437 uno::Sequence< OUString > aRet(2);
1438 OUString* pArray = aRet.getArray();
1439 pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) );
1440 pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
1441 return aRet;
1442 }
1443
InvalidatePosOrSize(const SwRect & rOldBox)1444 void SwAccessibleTable::InvalidatePosOrSize( const SwRect& rOldBox )
1445 {
1446 vos::OGuard aGuard(Application::GetSolarMutex());
1447
1448 //need to update children
1449 SwAccessibleTableData_Impl *pNewTableData = CreateNewTableData();
1450 if( !pNewTableData->CompareExtents( GetTableData() ) )
1451 {
1452 delete mpTableData;
1453 mpTableData = pNewTableData;
1454 FireTableChangeEvent(*mpTableData);
1455 }
1456 if( HasTableData() )
1457 GetTableData().SetTablePos( GetFrm()->Frm().Pos() );
1458
1459 SwAccessibleContext::InvalidatePosOrSize( rOldBox );
1460 }
1461
Dispose(sal_Bool bRecursive)1462 void SwAccessibleTable::Dispose( sal_Bool bRecursive )
1463 {
1464 vos::OGuard aGuard(Application::GetSolarMutex());
1465
1466 if( GetRegisteredIn() )
1467 GetRegisteredInNonConst()->Remove( this );
1468
1469 SwAccessibleContext::Dispose( bRecursive );
1470 }
1471
DisposeChild(const SwAccessibleChild & rChildFrmOrObj,sal_Bool bRecursive)1472 void SwAccessibleTable::DisposeChild( const SwAccessibleChild& rChildFrmOrObj,
1473 sal_Bool bRecursive )
1474 {
1475 vos::OGuard aGuard(Application::GetSolarMutex());
1476
1477 const SwFrm *pFrm = rChildFrmOrObj.GetSwFrm();
1478 ASSERT( pFrm, "frame expected" );
1479 if( HasTableData() )
1480 {
1481 FireTableChangeEvent( GetTableData() );
1482 ClearTableData();
1483 }
1484
1485 // There are two reason why this method has been called. The first one
1486 // is there is no context for pFrm. The method is them called by
1487 // the map, and we have to call our superclass.
1488 // The other situation is that we have been call by a call to get notified
1489 // about its change. We then must not call the superclass
1490 uno::Reference< XAccessible > xAcc( GetMap()->GetContext( pFrm, sal_False ) );
1491 if( !xAcc.is() )
1492 SwAccessibleContext::DisposeChild( rChildFrmOrObj, bRecursive );
1493 }
1494
InvalidateChildPosOrSize(const SwAccessibleChild & rChildFrmOrObj,const SwRect & rOldBox)1495 void SwAccessibleTable::InvalidateChildPosOrSize( const SwAccessibleChild& rChildFrmOrObj,
1496 const SwRect& rOldBox )
1497 {
1498 vos::OGuard aGuard(Application::GetSolarMutex());
1499
1500 if( HasTableData() )
1501 {
1502 ASSERT( !HasTableData() ||
1503 GetFrm()->Frm().Pos() == GetTableData().GetTablePos(),
1504 "table has invalid position" );
1505 if( HasTableData() )
1506 {
1507 // --> OD 2007-06-28 #i77106#
1508 SwAccessibleTableData_Impl *pNewTableData = CreateNewTableData();
1509 // <--
1510 if( !pNewTableData->CompareExtents( GetTableData() ) )
1511 {
1512 if(pNewTableData->GetRowCount()!= mpTableData->GetRowCount())
1513 {
1514 Int32Set_Impl::const_iterator aSttCol( GetTableData().GetColumnIter( 0 ) );
1515 Int32Set_Impl::const_iterator aSttRow( GetTableData().GetRowIter( 1 ) );
1516 const SwFrm *pCellFrm = GetTableData().GetCellAtPos( *aSttCol, *aSttRow, sal_False );
1517 Int32Set_Impl::const_iterator aSttCol2( pNewTableData->GetColumnIter( 0 ) );
1518 Int32Set_Impl::const_iterator aSttRow2( pNewTableData->GetRowIter( 0 ) );
1519 const SwFrm *pCellFrm2 = pNewTableData->GetCellAtPos( *aSttCol2, *aSttRow2, sal_False );
1520
1521 if(pCellFrm == pCellFrm2)
1522 {
1523 AccessibleTableModelChange aModelChange;
1524 aModelChange.Type = AccessibleTableModelChangeType::UPDATE;
1525 aModelChange.FirstRow = 0;
1526 aModelChange.LastRow = mpTableData->GetRowCount() - 1;
1527 aModelChange.FirstColumn = 0;
1528 aModelChange.LastColumn = mpTableData->GetColumnCount() - 1;
1529
1530 AccessibleEventObject aEvent;
1531 aEvent.EventId = AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED;
1532 aEvent.NewValue <<= aModelChange;
1533
1534 FireAccessibleEvent( aEvent );
1535 }
1536 }
1537 else
1538 FireTableChangeEvent( GetTableData() );
1539 ClearTableData();
1540 mpTableData = pNewTableData;
1541 }
1542 else
1543 {
1544 delete pNewTableData;
1545 }
1546 }
1547 }
1548
1549 // --> OD 2010-02-18 #i013961# - always call super class method
1550 SwAccessibleContext::InvalidateChildPosOrSize( rChildFrmOrObj, rOldBox );
1551 // <--
1552 }
1553
1554
1555 //
1556 // XAccessibleSelection
1557 //
1558
selectAccessibleChild(sal_Int32 nChildIndex)1559 void SAL_CALL SwAccessibleTable::selectAccessibleChild(
1560 sal_Int32 nChildIndex )
1561 {
1562 vos::OGuard aGuard(Application::GetSolarMutex());
1563 CHECK_FOR_DEFUNC( XAccessibleTable );
1564
1565 // --> OD 2007-06-27 #i77106#
1566 if( (nChildIndex < 0) || (nChildIndex >= getAccessibleChildCount()) )
1567 // <--
1568 throw lang::IndexOutOfBoundsException();
1569
1570 // preliminaries: get 'our' table box, and get the cursor shell
1571 const SwTableBox* pBox = GetTableBox( nChildIndex );
1572 DBG_ASSERT( pBox != NULL, "We need the table box." );
1573
1574 SwCrsrShell* pCrsrShell = GetCrsrShell();
1575 if( pCrsrShell == NULL )
1576 return;
1577
1578 // --> OD 2004-11-16 #111714# - assure, that child, indentified by the given
1579 // index, isn't already selected.
1580 if ( IsChildSelected( nChildIndex ) )
1581 {
1582 return;
1583 }
1584 // <--
1585
1586 // now we can start to do the work: check whether we already have
1587 // a table selection (in 'our' table). If so, extend the
1588 // selection, else select the current cell.
1589
1590 // if we have a selection in a table, check if it's in the
1591 // same table that we're trying to select in
1592 const SwTableNode* pSelectedTable = pCrsrShell->IsCrsrInTbl();
1593 if( pSelectedTable != NULL )
1594 {
1595 // get top-most table line
1596 const SwTableLine* pUpper = pBox->GetUpper();
1597 while( pUpper->GetUpper() != NULL )
1598 pUpper = pUpper->GetUpper()->GetUpper();
1599 sal_uInt16 nPos =
1600 pSelectedTable->GetTable().GetTabLines().GetPos( pUpper );
1601 if( nPos == USHRT_MAX )
1602 pSelectedTable = NULL;
1603 }
1604
1605 // create the new selection
1606 const SwStartNode* pStartNode = pBox->GetSttNd();
1607 if( pSelectedTable == NULL || !pCrsrShell->GetTblCrs() )
1608 {
1609 // if we're in the wrong table, or there's no table selection
1610 // at all, then select the current table cell.
1611 // SwPaM* pPaM = pCrsrShell->GetCrsr();
1612 // pPaM->DeleteMark();
1613 // *(pPaM->GetPoint()) = SwPosition( *pStartNode );
1614 // pPaM->Move( fnMoveForward, fnGoNode );
1615 // // pCrsrShell->SelTblBox();
1616
1617 pCrsrShell->StartAction();
1618 // Set cursor into current cell. This deletes any table cursor.
1619 SwPaM aPaM( *pStartNode );
1620 aPaM.Move( fnMoveForward, fnGoNode );
1621 Select( aPaM );
1622 // Move cursor to the end of the table creating a selection and a table
1623 // cursor.
1624 pCrsrShell->SetMark();
1625 pCrsrShell->MoveTable( fnTableCurr, fnTableEnd );
1626 // now set the cursor into the cell again.
1627 SwPaM *pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs()
1628 : pCrsrShell->GetCrsr();
1629 *pPaM->GetPoint() = *pPaM->GetMark();
1630 pCrsrShell->EndAction();
1631 // we now have one cell selected!
1632 }
1633 else
1634 {
1635 // if the cursor is already in this table,
1636 // expand the current selection (i.e., set
1637 // point to new position; keep mark)
1638 SwPaM aPaM( *pStartNode );
1639 aPaM.Move( fnMoveForward, fnGoNode );
1640 aPaM.SetMark();
1641 const SwPaM *pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs()
1642 : pCrsrShell->GetCrsr();
1643 *(aPaM.GetMark()) = *pPaM->GetMark();
1644 Select( aPaM );
1645
1646 // if only one box is selected, we select this one in
1647 // order to maintain our table selection
1648 // if( aPaM.GetPoint()->nNode.GetNode().FindTableBoxStartNode() ==
1649 // aPaM.GetMark()->nNode.GetNode().FindTableBoxStartNode() )
1650 // {
1651 // // pCrsrShell->SelTblBox();
1652 // }
1653 // else
1654 // {
1655 // finally; set the selection. This will call UpdateCursor
1656 // on the cursor shell, too.
1657 // pCrsrShell->KillPams();
1658 // pCrsrShell->SetSelection( aPaM );
1659 // }
1660 }
1661 }
1662
1663
isAccessibleChildSelected(sal_Int32 nChildIndex)1664 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleChildSelected(
1665 sal_Int32 nChildIndex )
1666 {
1667 vos::OGuard aGuard(Application::GetSolarMutex());
1668 CHECK_FOR_DEFUNC( XAccessibleTable );
1669
1670 // --> OD 2007-06-27 #i77106#
1671 if( (nChildIndex < 0) || (nChildIndex >= getAccessibleChildCount()) )
1672 // <--
1673 throw lang::IndexOutOfBoundsException();
1674
1675 return IsChildSelected( nChildIndex );
1676 }
1677
clearAccessibleSelection()1678 void SAL_CALL SwAccessibleTable::clearAccessibleSelection( )
1679 {
1680 vos::OGuard aGuard(Application::GetSolarMutex());
1681
1682 CHECK_FOR_DEFUNC( XAccessibleTable );
1683
1684 SwCrsrShell* pCrsrShell = GetCrsrShell();
1685 if( pCrsrShell != NULL )
1686 {
1687 pCrsrShell->StartAction();
1688 pCrsrShell->ClearMark();
1689 pCrsrShell->EndAction();
1690 }
1691 }
1692
selectAllAccessibleChildren()1693 void SAL_CALL SwAccessibleTable::selectAllAccessibleChildren( )
1694 {
1695 // first clear selection, then select first and last child
1696 clearAccessibleSelection();
1697 selectAccessibleChild( 0 );
1698 // --> OD 2007-06-27 #i77106#
1699 selectAccessibleChild( getAccessibleChildCount()-1 );
1700 // <--
1701 }
1702
getSelectedAccessibleChildCount()1703 sal_Int32 SAL_CALL SwAccessibleTable::getSelectedAccessibleChildCount( )
1704 {
1705 vos::OGuard aGuard(Application::GetSolarMutex());
1706 CHECK_FOR_DEFUNC( XAccessibleTable );
1707
1708 // iterate over all children and count isAccessibleChildSelected()
1709 sal_Int32 nCount = 0;
1710
1711 // --> OD 2007-06-27 #i71106#
1712 sal_Int32 nChildren = getAccessibleChildCount();
1713 // <--
1714 for( sal_Int32 n = 0; n < nChildren; n++ )
1715 if( IsChildSelected( n ) )
1716 nCount++;
1717
1718 return nCount;
1719 }
1720
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)1721 uno::Reference<XAccessible> SAL_CALL SwAccessibleTable::getSelectedAccessibleChild(
1722 sal_Int32 nSelectedChildIndex )
1723 {
1724 vos::OGuard aGuard(Application::GetSolarMutex());
1725 CHECK_FOR_DEFUNC( XAccessibleTable );
1726
1727 // paremter checking (part 1): index lower 0
1728 if( nSelectedChildIndex < 0 )
1729 throw lang::IndexOutOfBoundsException();
1730
1731 sal_Int32 nChildIndex = GetIndexOfSelectedChild( nSelectedChildIndex );
1732
1733 // parameter checking (part 2): index higher than selected children?
1734 if( nChildIndex < 0 )
1735 throw lang::IndexOutOfBoundsException();
1736
1737 // --> OD 2007-06-28 #i77106#
1738 if ( nChildIndex >= getAccessibleChildCount() )
1739 {
1740 throw lang::IndexOutOfBoundsException();
1741 }
1742 // <--
1743
1744 return getAccessibleChild( nChildIndex );
1745 }
1746
1747 // --> OD 2004-11-16 #111714# - index has to be treated as global child index.
deselectAccessibleChild(sal_Int32 nChildIndex)1748 void SAL_CALL SwAccessibleTable::deselectAccessibleChild(
1749 sal_Int32 nChildIndex )
1750 {
1751 vos::OGuard aGuard(Application::GetSolarMutex());
1752 CHECK_FOR_DEFUNC( XAccessibleTable );
1753
1754 SwCrsrShell* pCrsrShell = GetCrsrShell();
1755
1756 // --> OD 2004-11-16 #111714# - index has to be treated as global child index
1757 if ( !pCrsrShell )
1758 throw lang::IndexOutOfBoundsException();
1759
1760 // assure, that given child index is in bounds.
1761 // --> OD 2007-06-27 #i77106#
1762 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
1763 // <--
1764 throw lang::IndexOutOfBoundsException();
1765
1766 // assure, that child, identified by the given index, is selected.
1767 if ( !IsChildSelected( nChildIndex ) )
1768 return;
1769 // <--
1770
1771 const SwTableBox* pBox = GetTableBox( nChildIndex );
1772 DBG_ASSERT( pBox != NULL, "We need the table box." );
1773
1774 // If we unselect point, then set cursor to mark. If we clear another
1775 // selected box, then set cursor to point.
1776 // reduce selection to mark.
1777 SwPaM *pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs()
1778 : pCrsrShell->GetCrsr();
1779 sal_Bool bDeselectPoint =
1780 pBox->GetSttNd() ==
1781 pPaM->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1782
1783 SwPaM aPaM( bDeselectPoint ? *pPaM->GetMark() : *pPaM->GetPoint() );
1784
1785 pCrsrShell->StartAction();
1786
1787 // Set cursor into either point or mark
1788 Select( aPaM );
1789 // Move cursor to the end of the table creating a selection and a table
1790 // cursor.
1791 pCrsrShell->SetMark();
1792 pCrsrShell->MoveTable( fnTableCurr, fnTableEnd );
1793 // now set the cursor into the cell again.
1794 pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs()
1795 : pCrsrShell->GetCrsr();
1796 *pPaM->GetPoint() = *pPaM->GetMark();
1797 pCrsrShell->EndAction();
1798 }
1799
SetTableData(SwAccessibleTableData_Impl * mpNewTableData)1800 void SwAccessibleTable::SetTableData(SwAccessibleTableData_Impl* mpNewTableData)
1801 {
1802 mpTableData = mpNewTableData;
1803 }
1804
getBackground()1805 sal_Int32 SAL_CALL SwAccessibleTable::getBackground()
1806 {
1807 const SvxBrushItem &rBack = GetFrm()->GetAttrSet()->GetBackground();
1808 sal_uInt32 crBack = rBack.GetColor().GetColor();
1809
1810 if (COL_AUTO == crBack)
1811 {
1812 uno::Reference<XAccessible> xAccDoc = getAccessibleParent();
1813 if (xAccDoc.is())
1814 {
1815 uno::Reference<XAccessibleComponent> xCompoentDoc(xAccDoc,uno::UNO_QUERY);
1816 if (xCompoentDoc.is())
1817 {
1818 crBack = (sal_uInt32)xCompoentDoc->getBackground();
1819 }
1820 }
1821 }
1822 return crBack;
1823 }
1824
FireSelectionEvent()1825 void SwAccessibleTable::FireSelectionEvent( )
1826 {
1827 AccessibleEventObject aEvent;
1828
1829 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
1830
1831 // int nRemove = m_vecCellRemove.size();
1832 // int nAdd = m_vecCellAdd.size();
1833
1834 VEC_CELL::iterator vi = m_vecCellRemove.begin();
1835 for (; vi != m_vecCellRemove.end() ; ++vi)
1836 {
1837 SwAccessibleContext *pAccCell = const_cast<SwAccessibleContext *>(*vi);
1838 OSL_ASSERT(pAccCell != NULL );
1839 pAccCell->FireAccessibleEvent(aEvent);
1840 }
1841
1842 if (m_vecCellAdd.size() <= SELECTION_WITH_NUM)
1843 {
1844 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD;
1845 vi = m_vecCellAdd.begin();
1846 for (; vi != m_vecCellAdd.end() ; ++vi)
1847 {
1848 SwAccessibleContext *pAccCell = const_cast<SwAccessibleContext *>(*vi);
1849 OSL_ASSERT(pAccCell != NULL );
1850 pAccCell->FireAccessibleEvent(aEvent);
1851 }
1852 return ;
1853 }
1854 else
1855 {
1856 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1857 FireAccessibleEvent(aEvent);
1858 }
1859 }
1860
ClearSelectionCellCache()1861 void SwAccessibleTable::ClearSelectionCellCache()
1862 {
1863 m_vecCellAdd.clear();
1864 m_vecCellRemove.clear();
1865 }
1866
AddSelectionCell(const SwAccessibleContext * pAccCell,sal_Bool bAddOrRemove)1867 void SwAccessibleTable::AddSelectionCell(const SwAccessibleContext* pAccCell ,sal_Bool bAddOrRemove)
1868 {
1869 if (bAddOrRemove)
1870 {
1871 m_vecCellAdd.push_back(pAccCell);
1872 }
1873 else
1874 {
1875 m_vecCellRemove.push_back(pAccCell);
1876 }
1877 }
1878
1879 //===== XAccessibleTableSelection ============================================
selectRow(sal_Int32 row)1880 sal_Bool SAL_CALL SwAccessibleTable::selectRow( sal_Int32 row )
1881 {
1882 if( isAccessibleColumnSelected( row ) )
1883 return sal_True;
1884
1885 long lCol, lColumnCount, lChildIndex;
1886 lColumnCount = getAccessibleColumnCount();
1887 for(lCol = 0; lCol < lColumnCount; lCol ++)
1888 {
1889 lChildIndex = getAccessibleIndex(row, lCol);
1890 selectAccessibleChild(lChildIndex);
1891 }
1892
1893 return sal_True;
1894 }
selectColumn(sal_Int32 column)1895 sal_Bool SAL_CALL SwAccessibleTable::selectColumn( sal_Int32 column )
1896 {
1897 if( isAccessibleColumnSelected( column ) )
1898 return sal_True;
1899
1900 long lRow, lRowCount, lChildIndex;
1901 lRowCount = getAccessibleRowCount();
1902
1903 for(lRow = 0; lRow < lRowCount; lRow ++)
1904 {
1905 lChildIndex = getAccessibleIndex(lRow, column);
1906 selectAccessibleChild(lChildIndex);
1907 }
1908 return sal_True;
1909 }
unselectRow(sal_Int32 row)1910 sal_Bool SAL_CALL SwAccessibleTable::unselectRow( sal_Int32 row )
1911 {
1912 if( isAccessibleSelected( row , 0 ) && isAccessibleSelected( row , getAccessibleColumnCount()-1 ) )
1913 {
1914 SwCrsrShell* pCrsrShell = GetCrsrShell();
1915 if( pCrsrShell != NULL )
1916 {
1917 pCrsrShell->StartAction();
1918 pCrsrShell->ClearMark();
1919 pCrsrShell->EndAction();
1920 return sal_True;
1921 }
1922 }
1923 return sal_True;
1924 }
unselectColumn(sal_Int32 column)1925 sal_Bool SAL_CALL SwAccessibleTable::unselectColumn( sal_Int32 column )
1926 {
1927 if( isAccessibleSelected( 0 , column ) && isAccessibleSelected( getAccessibleRowCount()-1,column))
1928 {
1929 SwCrsrShell* pCrsrShell = GetCrsrShell();
1930 if( pCrsrShell != NULL )
1931 {
1932 pCrsrShell->StartAction();
1933 pCrsrShell->ClearMark();
1934 pCrsrShell->EndAction();
1935 return sal_True;
1936 }
1937 }
1938 return sal_True;
1939 }
1940 // --> OD 2007-06-28 #i77106#
1941 // implementation of class <SwAccessibleTableColHeaders>
SwAccessibleTableColHeaders(SwAccessibleMap * pMap2,const SwTabFrm * pTabFrm)1942 SwAccessibleTableColHeaders::SwAccessibleTableColHeaders( SwAccessibleMap *pMap2,
1943 const SwTabFrm *pTabFrm )
1944 : SwAccessibleTable( pMap2, pTabFrm )
1945 {
1946 vos::OGuard aGuard(Application::GetSolarMutex());
1947
1948 const SwFrmFmt *pFrmFmt = pTabFrm->GetFmt();
1949 const_cast< SwFrmFmt * >( pFrmFmt )->Add( this );
1950 const String& rName = pFrmFmt->GetName();
1951
1952 OUStringBuffer aBuffer( rName.Len() + 15 + 6 );
1953 aBuffer.append( OUString(rName) );
1954 aBuffer.append( String::CreateFromAscii("-ColumnHeaders-") );
1955 aBuffer.append( static_cast<sal_Int32>( pTabFrm->GetPhyPageNum() ) );
1956
1957 SetName( aBuffer.makeStringAndClear() );
1958
1959 OUStringBuffer aBuffer2( rName.Len() + 14 );
1960 aBuffer2.append( OUString(rName) );
1961 aBuffer2.append( String::CreateFromAscii("-ColumnHeaders") );
1962 OUString sArg1( aBuffer2.makeStringAndClear() );
1963 OUString sArg2( GetFormattedPageNumber() );
1964
1965 OUString sDesc2 = GetResource( STR_ACCESS_TABLE_DESC, &sArg1, &sArg2 );
1966 SetDesc( sDesc2 );
1967
1968 // --> OD 2008-03-10 #i85634#
1969 NotRegisteredAtAccessibleMap();
1970 // <--
1971 }
1972
CreateNewTableData()1973 SwAccessibleTableData_Impl* SwAccessibleTableColHeaders::CreateNewTableData()
1974 {
1975 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( GetFrm() );
1976 return new SwAccessibleTableData_Impl( *(GetMap()), pTabFrm, IsInPagePreview(), true );
1977 }
1978
1979
Modify(const SfxPoolItem *,const SfxPoolItem *)1980 void SwAccessibleTableColHeaders::Modify( const SfxPoolItem * /*pOld*/, const SfxPoolItem * /*pNew*/ )
1981 {
1982 }
1983
1984 //===== XInterface ======================================================
queryInterface(const uno::Type & aType)1985 uno::Any SAL_CALL SwAccessibleTableColHeaders::queryInterface( const uno::Type& aType )
1986 {
1987 return SwAccessibleTable::queryInterface( aType );
1988 }
1989
1990 //===== XAccessibleContext ==============================================
getAccessibleChildCount(void)1991 sal_Int32 SAL_CALL SwAccessibleTableColHeaders::getAccessibleChildCount(void)
1992 {
1993 vos::OGuard aGuard(Application::GetSolarMutex());
1994
1995 CHECK_FOR_DEFUNC( XAccessibleContext )
1996
1997 sal_Int32 nCount = 0;
1998
1999 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( GetFrm() );
2000 const SwAccessibleChildSList aVisList( GetVisArea(), *pTabFrm, *(GetMap()) );
2001 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
2002 while( aIter != aVisList.end() )
2003 {
2004 const SwAccessibleChild& rLower = *aIter;
2005 if( rLower.IsAccessible( IsInPagePreview() ) )
2006 {
2007 nCount++;
2008 }
2009 else if( rLower.GetSwFrm() )
2010 {
2011 // There are no unaccessible SdrObjects that count
2012 if ( !rLower.GetSwFrm()->IsRowFrm() ||
2013 pTabFrm->IsInHeadline( *(rLower.GetSwFrm()) ) )
2014 {
2015 nCount += SwAccessibleFrame::GetChildCount( *(GetMap()),
2016 GetVisArea(),
2017 rLower.GetSwFrm(),
2018 IsInPagePreview() );
2019 }
2020 }
2021 ++aIter;
2022 }
2023
2024 return nCount;
2025 }
2026
2027 uno::Reference< XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)2028 SwAccessibleTableColHeaders::getAccessibleChild (sal_Int32 nIndex)
2029 {
2030 if ( nIndex < 0 || nIndex >= getAccessibleChildCount() )
2031 {
2032 throw lang::IndexOutOfBoundsException();
2033 }
2034
2035 return SwAccessibleTable::getAccessibleChild( nIndex );
2036 }
2037
2038 //===== XAccessibleTable ================================================
2039 uno::Reference< XAccessibleTable >
getAccessibleRowHeaders()2040 SAL_CALL SwAccessibleTableColHeaders::getAccessibleRowHeaders()
2041 {
2042 return uno::Reference< XAccessibleTable >();
2043 }
2044
2045 uno::Reference< XAccessibleTable >
getAccessibleColumnHeaders()2046 SAL_CALL SwAccessibleTableColHeaders::getAccessibleColumnHeaders()
2047 {
2048 return uno::Reference< XAccessibleTable >();
2049 }
2050
2051 //===== XServiceInfo ====================================================
2052
getImplementationName(void)2053 ::rtl::OUString SAL_CALL SwAccessibleTableColHeaders::getImplementationName (void)
2054 {
2055 static const sal_Char sImplName[] = "com.sun.star.comp.Writer.SwAccessibleTableColumnHeadersView";
2056 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplName));
2057 }
2058