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