xref: /trunk/main/sw/source/core/access/acctable.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_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