1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #include "scitems.hxx"
32 #include "AccessiblePreviewTable.hxx"
33 #include "AccessiblePreviewCell.hxx"
34 #include "AccessiblePreviewHeaderCell.hxx"
35 #include "AccessibilityHints.hxx"
36 #include "prevwsh.hxx"
37 #include "unoguard.hxx"
38 #include "miscuno.hxx"
39 #include "prevloc.hxx"
40 #include "attrib.hxx"
41 #include "document.hxx"
42 #include "scresid.hxx"
43 #ifndef SC_SC_HRC
44 #include "sc.hrc"
45 #endif
46 
47 #include <com/sun/star/accessibility/AccessibleRole.hpp>
48 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
49 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
50 
51 #include <vcl/window.hxx>
52 #include <svl/smplhint.hxx>
53 #include <unotools/accessiblestatesethelper.hxx>
54 #include <comphelper/sequence.hxx>
55 
56 using namespace	::com::sun::star;
57 using namespace	::com::sun::star::accessibility;
58 
59 //=====  internal  ============================================================
60 
61 ScAccessiblePreviewTable::ScAccessiblePreviewTable( const ::com::sun::star::uno::Reference<
62 						        ::com::sun::star::accessibility::XAccessible>& rxParent,
63 							ScPreviewShell* pViewShell, sal_Int32 nIndex ) :
64 	ScAccessibleContextBase( rxParent, AccessibleRole::TABLE ),
65 	mpViewShell( pViewShell ),
66 	mnIndex( nIndex ),
67 	mpTableInfo( NULL )
68 {
69 	if (mpViewShell)
70 		mpViewShell->AddAccessibilityObject(*this);
71 }
72 
73 ScAccessiblePreviewTable::~ScAccessiblePreviewTable()
74 {
75 	if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
76 	{
77 		// increment refcount to prevent double call off dtor
78 		osl_incrementInterlockedCount( &m_refCount );
79 		dispose();
80 	}
81 }
82 
83 void SAL_CALL ScAccessiblePreviewTable::disposing()
84 {
85     ScUnoGuard aGuard;
86 	if (mpViewShell)
87 	{
88 		mpViewShell->RemoveAccessibilityObject(*this);
89 		mpViewShell = NULL;
90 	}
91 
92 	if (mpTableInfo)
93 		DELETEZ (mpTableInfo);
94 
95 	ScAccessibleContextBase::disposing();
96 }
97 
98 //=====  SfxListener  =====================================================
99 
100 void ScAccessiblePreviewTable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
101 {
102 	if (rHint.ISA( SfxSimpleHint ))
103 	{
104 		const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
105 		sal_uLong nId = rRef.GetId();
106 		if ( nId == SFX_HINT_DATACHANGED )
107 		{
108 			//	column / row layout may change with any document change,
109 			//	so it must be invalidated
110 			DELETEZ( mpTableInfo );
111 		}
112         else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
113         {
114             AccessibleEventObject aEvent;
115             aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
116 			aEvent.Source = uno::Reference< XAccessibleContext >(this);
117             CommitChange(aEvent);
118         }
119 	}
120 
121 	ScAccessibleContextBase::Notify(rBC, rHint);
122 }
123 
124 //=====  XInterface  =====================================================
125 
126 uno::Any SAL_CALL ScAccessiblePreviewTable::queryInterface( uno::Type const & rType )
127 	throw (uno::RuntimeException)
128 {
129 	uno::Any aAny (ScAccessiblePreviewTableImpl::queryInterface(rType));
130 	return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
131 }
132 
133 void SAL_CALL ScAccessiblePreviewTable::acquire()
134 	throw ()
135 {
136 	ScAccessibleContextBase::acquire();
137 }
138 
139 void SAL_CALL ScAccessiblePreviewTable::release()
140 	throw ()
141 {
142 	ScAccessibleContextBase::release();
143 }
144 
145 //=====  XAccessibleTable  ================================================
146 
147 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowCount() throw (uno::RuntimeException)
148 {
149 	ScUnoGuard aGuard;
150     IsObjectValid();
151 
152 	FillTableInfo();
153 
154 	sal_Int32 nRet = 0;
155 	if ( mpTableInfo )
156 		nRet = mpTableInfo->GetRows();
157 	return nRet;
158 }
159 
160 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnCount() throw (uno::RuntimeException)
161 {
162 	ScUnoGuard aGuard;
163     IsObjectValid();
164 
165 	FillTableInfo();
166 
167 	sal_Int32 nRet = 0;
168 	if ( mpTableInfo )
169 		nRet = mpTableInfo->GetCols();
170 	return nRet;
171 }
172 
173 rtl::OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleRowDescription( sal_Int32 nRow )
174 								throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
175 {
176     // is not supported or specified so not implemented
177 /*	ScUnoGuard aGuard;
178     IsObjectValid();
179 
180 	FillTableInfo();
181 
182 	rtl::OUString sName;
183 	if ( mpTableInfo && nRow >= 0 && nRow < mpTableInfo->GetRows() )
184 	{
185 		const ScPreviewColRowInfo& rInfo = mpTableInfo->GetRowInfo()[nRow];
186 		if ( rInfo.bIsHeader )
187 		{
188 			//!	name of column headers row?
189 
190 			sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column Headers"));
191 		}
192 		else
193 		{
194 			// normal row name
195 			sName = rtl::OUString::valueOf( (sal_Int32) ( rInfo.nDocIndex + 1 ) );
196 		}
197 	}
198 	else
199 		throw lang::IndexOutOfBoundsException();*/
200 
201 	ScUnoGuard aGuard;
202     FillTableInfo();
203     if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
204 		throw lang::IndexOutOfBoundsException();
205 
206     return rtl::OUString();
207 }
208 
209 rtl::OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnDescription( sal_Int32 nColumn )
210 								throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
211 {
212     // is not supported or specified so not implemented
213 /*	ScUnoGuard aGuard;
214     IsObjectValid();
215 
216 	FillTableInfo();
217 
218 	rtl::OUString sName;
219 	if ( mpTableInfo && nColumn >= 0 && nColumn < mpTableInfo->GetCols() )
220 	{
221 		const ScPreviewColRowInfo& rInfo = mpTableInfo->GetColInfo()[nColumn];
222 		if ( rInfo.bIsHeader )
223 		{
224 			//!	name of row headers column?
225 
226 			sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Row Headers"));
227 		}
228 		else
229 		{
230 			// normal column name
231 			sName = ScColToAlpha( rInfo.nDocIndex );
232 		}
233 	}
234 	else
235 		throw lang::IndexOutOfBoundsException();*/
236 
237     ScUnoGuard aGuard;
238 	FillTableInfo();
239 	if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
240 		throw lang::IndexOutOfBoundsException();
241 
242     return rtl::OUString();
243 }
244 
245 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
246     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
247 {
248 	ScUnoGuard aGuard;
249     IsObjectValid();
250 
251 	FillTableInfo();
252 
253 	sal_Int32 nRows = 1;
254 	if ( mpViewShell && mpTableInfo && nColumn >= 0 && nRow >= 0 &&
255 			nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
256 	{
257 		const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
258 		const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
259 
260 		if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
261 		{
262 			//	header cells only span a single cell
263 		}
264 		else
265 		{
266 			ScDocument* pDoc = mpViewShell->GetDocument();
267 			const ScMergeAttr* pItem = (const ScMergeAttr*)pDoc->GetAttr(
268 				static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
269 			if ( pItem && pItem->GetRowMerge() > 0 )
270 				nRows = pItem->GetRowMerge();
271 		}
272 	}
273 	else
274 		throw lang::IndexOutOfBoundsException();
275 
276 	return nRows;
277 }
278 
279 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
280     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
281 {
282 	ScUnoGuard aGuard;
283     IsObjectValid();
284 
285 	FillTableInfo();
286 
287 	sal_Int32 nColumns = 1;
288 	if ( mpViewShell && mpTableInfo && nColumn >= 0 && nRow >= 0 &&
289 			nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
290 	{
291 		const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
292 		const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
293 
294 		if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
295 		{
296 			//	header cells only span a single cell
297 		}
298 		else
299 		{
300 			ScDocument* pDoc = mpViewShell->GetDocument();
301 			const ScMergeAttr* pItem = (const ScMergeAttr*)pDoc->GetAttr(
302 				static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
303 			if ( pItem && pItem->GetColMerge() > 0 )
304 				nColumns = pItem->GetColMerge();
305 		}
306 	}
307 	else
308 		throw lang::IndexOutOfBoundsException();
309 
310 	return nColumns;
311 }
312 
313 uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleRowHeaders() throw (uno::RuntimeException)
314 {
315 	//! missing
316 	return NULL;
317 }
318 
319 uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnHeaders() throw (uno::RuntimeException)
320 {
321 	//! missing
322 	return NULL;
323 }
324 
325 uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleRows() throw (uno::RuntimeException)
326 {
327 	//	in the page preview, there is no selection
328     return uno::Sequence<sal_Int32>(0);
329 }
330 
331 uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleColumns() throw (uno::RuntimeException)
332 {
333 	//	in the page preview, there is no selection
334 	return uno::Sequence<sal_Int32>(0);
335 }
336 
337 sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleRowSelected( sal_Int32 nRow )
338     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
339 {
340 	//	in the page preview, there is no selection
341 
342     ScUnoGuard aGuard;
343     FillTableInfo();
344     if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
345 		throw lang::IndexOutOfBoundsException();
346 
347     return sal_False;
348 }
349 
350 sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleColumnSelected( sal_Int32 nColumn )
351     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
352 {
353 	//	in the page preview, there is no selection
354 
355     ScUnoGuard aGuard;
356 	FillTableInfo();
357 	if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
358 		throw lang::IndexOutOfBoundsException();
359 
360     return sal_False;
361 }
362 
363 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
364     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
365 {
366 	ScUnoGuard aGuard;
367     IsObjectValid();
368 
369 	FillTableInfo();
370 
371 	uno::Reference<XAccessible> xRet;
372 	if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
373 	{
374 		//	index iterates horizontally
375 		long nNewIndex = nRow * mpTableInfo->GetCols() + nColumn;
376 
377 		const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
378 		const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
379 
380 		ScAddress aCellPos( static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab() );
381 		if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
382 		{
383 			ScAccessiblePreviewHeaderCell* pHeaderCell = new ScAccessiblePreviewHeaderCell( this, mpViewShell, aCellPos,
384 										rRowInfo.bIsHeader, rColInfo.bIsHeader, nNewIndex );
385 			xRet = pHeaderCell;
386 			pHeaderCell->Init();
387 		}
388 		else
389 		{
390 			ScAccessiblePreviewCell* pCell = new ScAccessiblePreviewCell( this, mpViewShell, aCellPos, nNewIndex );
391 			xRet = pCell;
392 			pCell->Init();
393 		}
394 	}
395 
396 	if ( !xRet.is() )
397 		throw lang::IndexOutOfBoundsException();
398 
399 	return xRet;
400 }
401 
402 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCaption() throw (uno::RuntimeException)
403 {
404 	//! missing
405 	return NULL;
406 }
407 
408 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleSummary() throw (uno::RuntimeException)
409 {
410 	//! missing
411 	return NULL;
412 }
413 
414 sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
415     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
416 {
417 	//	in the page preview, there is no selection
418 	ScUnoGuard aGuard;
419     IsObjectValid();
420 
421 	FillTableInfo();
422 
423 	if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
424 	{
425 		//	index iterates horizontally
426 	}
427 	else
428 		throw lang::IndexOutOfBoundsException();
429 
430 	return sal_False;
431 }
432 
433 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
434     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
435 {
436 	ScUnoGuard aGuard;
437     IsObjectValid();
438 
439 	FillTableInfo();
440 
441 	sal_Int32 nRet = 0;
442 	if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
443 	{
444 		//	index iterates horizontally
445 		nRet = nRow * mpTableInfo->GetCols() + nColumn;
446 	}
447 	else
448 		throw lang::IndexOutOfBoundsException();
449 
450 	return nRet;
451 }
452 
453 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRow( sal_Int32 nChildIndex )
454     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
455 {
456 	ScUnoGuard aGuard;
457     IsObjectValid();
458 
459 	FillTableInfo();
460 
461 	sal_Int32 nRow = 0;
462 	if ( mpTableInfo && nChildIndex >= 0 && nChildIndex < static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
463 	{
464 		nRow = nChildIndex / mpTableInfo->GetCols();
465 	}
466 	else
467 		throw lang::IndexOutOfBoundsException();
468 
469 	return nRow;
470 }
471 
472 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumn( sal_Int32 nChildIndex )
473     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
474 {
475 	ScUnoGuard aGuard;
476     IsObjectValid();
477 
478 	FillTableInfo();
479 
480 	sal_Int32 nCol = 0;
481 	if ( mpTableInfo && nChildIndex >= 0 && nChildIndex < static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
482 	{
483 		nCol = nChildIndex % static_cast<sal_Int32>(mpTableInfo->GetCols());
484 	}
485 	else
486 		throw lang::IndexOutOfBoundsException();
487 
488 	return nCol;
489 }
490 
491 //=====  XAccessibleComponent  ============================================
492 
493 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleAtPoint( const awt::Point& aPoint )
494     							throw (uno::RuntimeException)
495 {
496     uno::Reference<XAccessible> xRet;
497     if (containsPoint(aPoint))
498     {
499 	    ScUnoGuard aGuard;
500         IsObjectValid();
501 
502 	    FillTableInfo();
503 
504 	    if ( mpTableInfo )
505 	    {
506 		    SCCOL nCols = mpTableInfo->GetCols();
507 		    SCROW nRows = mpTableInfo->GetRows();
508 		    const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
509 		    const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
510 
511             Rectangle aScreenRect(GetBoundingBox());
512 
513             awt::Point aMovedPoint = aPoint;
514             aMovedPoint.X += aScreenRect.Left();
515             aMovedPoint.Y += aScreenRect.Top();
516 
517 		    if ( nCols > 0 && nRows > 0 && aMovedPoint.X >= pColInfo[0].nPixelStart && aMovedPoint.Y >= pRowInfo[0].nPixelStart )
518 		    {
519 			    SCCOL nColIndex = 0;
520 			    while ( nColIndex < nCols && aMovedPoint.X > pColInfo[nColIndex].nPixelEnd )
521 				    ++nColIndex;
522 			    SCROW nRowIndex = 0;
523 			    while ( nRowIndex < nRows && aMovedPoint.Y > pRowInfo[nRowIndex].nPixelEnd )
524 				    ++nRowIndex;
525 			    if ( nColIndex < nCols && nRowIndex < nRows )
526 			    {
527 				    try
528 				    {
529 					    xRet = getAccessibleCellAt( nRowIndex, nColIndex );
530 				    }
531 				    catch (uno::Exception&)
532 				    {
533 				    }
534 			    }
535 		    }
536 	    }
537     }
538 
539 	return xRet;
540 }
541 
542 void SAL_CALL ScAccessiblePreviewTable::grabFocus() throw (uno::RuntimeException)
543 {
544  	ScUnoGuard aGuard;
545     IsObjectValid();
546 	if (getAccessibleParent().is())
547 	{
548 		uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
549 		if (xAccessibleComponent.is())
550 			xAccessibleComponent->grabFocus();
551 	}
552 }
553 
554 //=====  XAccessibleContext  ==============================================
555 
556 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleChildCount() throw (uno::RuntimeException)
557 {
558 	ScUnoGuard aGuard;
559     IsObjectValid();
560 
561 	FillTableInfo();
562 
563 	long nRet = 0;
564 	if ( mpTableInfo )
565 		nRet = static_cast<sal_Int32>(mpTableInfo->GetCols()) * mpTableInfo->GetRows();
566 	return nRet;
567 }
568 
569 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleChild( sal_Int32 nIndex )
570     							throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
571 {
572 	ScUnoGuard aGuard;
573     IsObjectValid();
574 
575 	FillTableInfo();
576 
577 	uno::Reference<XAccessible> xRet;
578 	if ( mpTableInfo )
579 	{
580 		long nColumns = mpTableInfo->GetCols();
581 		if ( nColumns > 0 )
582 		{
583 			// nCol, nRow are within the visible table, not the document
584 			long nCol = nIndex % nColumns;
585 			long nRow = nIndex / nColumns;
586 
587 			xRet = getAccessibleCellAt( nRow, nCol );
588 		}
589 	}
590 
591 	if ( !xRet.is() )
592 		throw lang::IndexOutOfBoundsException();
593 
594 	return xRet;
595 }
596 
597 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndexInParent() throw (uno::RuntimeException)
598 {
599 	return mnIndex;
600 }
601 
602 uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePreviewTable::getAccessibleStateSet()
603 								throw (uno::RuntimeException)
604 {
605 	ScUnoGuard aGuard;
606 	uno::Reference<XAccessibleStateSet> xParentStates;
607 	if (getAccessibleParent().is())
608 	{
609 		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
610 		xParentStates = xParentContext->getAccessibleStateSet();
611 	}
612 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
613 	if (IsDefunc(xParentStates))
614 		pStateSet->AddState(AccessibleStateType::DEFUNC);
615     else
616     {
617         pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
618 	    pStateSet->AddState(AccessibleStateType::ENABLED);
619 	    pStateSet->AddState(AccessibleStateType::OPAQUE);
620 	    if (isShowing())
621 		    pStateSet->AddState(AccessibleStateType::SHOWING);
622 	    if (isVisible())
623 		    pStateSet->AddState(AccessibleStateType::VISIBLE);
624     }
625 	return pStateSet;
626 }
627 
628 //=====  XServiceInfo  ====================================================
629 
630 rtl::OUString SAL_CALL ScAccessiblePreviewTable::getImplementationName() throw(uno::RuntimeException)
631 {
632 	return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewTable"));
633 }
634 
635 uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewTable::getSupportedServiceNames()
636 													throw(uno::RuntimeException)
637 {
638 	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
639     sal_Int32 nOldSize(aSequence.getLength());
640     aSequence.realloc(nOldSize + 1);
641     ::rtl::OUString* pNames = aSequence.getArray();
642 
643 	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleTableView"));
644 
645 	return aSequence;
646 }
647 
648 //=====  XTypeProvider  ===================================================
649 
650 uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewTable::getTypes()
651 		throw (uno::RuntimeException)
652 {
653 	return comphelper::concatSequences(ScAccessiblePreviewTableImpl::getTypes(), ScAccessibleContextBase::getTypes());
654 }
655 
656 uno::Sequence<sal_Int8> SAL_CALL ScAccessiblePreviewTable::getImplementationId()
657 													throw(uno::RuntimeException)
658 {
659 	static uno::Sequence< sal_Int8 > aId;
660 	if( aId.getLength() == 0 )
661 	{
662 		aId.realloc( 16 );
663 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
664 	}
665 	return aId;
666 }
667 
668 //====  internal  =========================================================
669 
670 ::rtl::OUString SAL_CALL ScAccessiblePreviewTable::createAccessibleDescription(void)
671 				    throw (uno::RuntimeException)
672 {
673     String sDesc(ScResId(STR_ACC_TABLE_DESCR));
674 /*    if (mpViewShell && mpViewShell->GetDocument())
675     {
676 	    FillTableInfo();
677 
678 	    if ( mpTableInfo )
679 	    {
680 	        String sCoreName;
681 	        if (mpViewShell->GetDocument()->GetName( mpTableInfo->GetTab(), sCoreName ))
682 		        sDesc.SearchAndReplaceAscii("%1", sCoreName);
683         }
684     }
685     sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
686     return rtl::OUString(sDesc);
687 }
688 
689 ::rtl::OUString SAL_CALL ScAccessiblePreviewTable::createAccessibleName(void)
690 				    throw (uno::RuntimeException)
691 {
692     String sName(ScResId(STR_ACC_TABLE_NAME));
693 
694     if (mpViewShell && mpViewShell->GetDocument())
695     {
696 	    FillTableInfo();
697 
698 	    if ( mpTableInfo )
699 	    {
700 	        String sCoreName;
701 	        if (mpViewShell->GetDocument()->GetName( mpTableInfo->GetTab(), sCoreName ))
702 		        sName.SearchAndReplaceAscii("%1", sCoreName);
703         }
704     }
705 
706     return rtl::OUString(sName);
707 }
708 
709 Rectangle ScAccessiblePreviewTable::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
710 {
711 	Rectangle aCellRect(GetBoundingBox());
712 	if (mpViewShell)
713 	{
714 		Window* pWindow = mpViewShell->GetWindow();
715 		if (pWindow)
716 		{
717 			Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
718 			aCellRect.setX(aCellRect.getX() + aRect.getX());
719 			aCellRect.setY(aCellRect.getY() + aRect.getY());
720 		}
721 	}
722 	return aCellRect;
723 }
724 
725 Rectangle ScAccessiblePreviewTable::GetBoundingBox() const throw (uno::RuntimeException)
726 {
727 	FillTableInfo();
728 
729 	Rectangle aRect;
730 	if ( mpTableInfo )
731 	{
732 		SCCOL nColumns = mpTableInfo->GetCols();
733 		SCROW nRows = mpTableInfo->GetRows();
734 		if ( nColumns > 0 && nRows > 0 )
735 		{
736 			const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
737 			const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
738 
739 			aRect = Rectangle( pColInfo[0].nPixelStart,
740 							   pRowInfo[0].nPixelStart,
741 							   pColInfo[nColumns-1].nPixelEnd,
742 							   pRowInfo[nRows-1].nPixelEnd );
743 		}
744 	}
745 	return aRect;
746 }
747 
748 sal_Bool ScAccessiblePreviewTable::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
749 {
750 	return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
751 		(rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
752 }
753 
754 void ScAccessiblePreviewTable::FillTableInfo() const
755 {
756 	if ( mpViewShell && !mpTableInfo )
757 	{
758 		Size aOutputSize;
759 		Window* pWindow = mpViewShell->GetWindow();
760 		if ( pWindow )
761 			aOutputSize = pWindow->GetOutputSizePixel();
762         Point aPoint;
763 		Rectangle aVisRect( aPoint, aOutputSize );
764 
765 		mpTableInfo = new ScPreviewTableInfo;
766 		mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
767 	}
768 }
769 
770