xref: /AOO41X/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