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