1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "scitems.hxx"
22 #include "AccessiblePreviewTable.hxx"
23 #include "AccessiblePreviewCell.hxx"
24 #include "AccessiblePreviewHeaderCell.hxx"
25 #include "AccessibilityHints.hxx"
26 #include "prevwsh.hxx"
27 #include "miscuno.hxx"
28 #include "prevloc.hxx"
30 #include "document.hxx"
31 #include "scresid.hxx"
34 #include <com/sun/star/accessibility/AccessibleRole.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #include <vcl/window.hxx>
39 #include <vcl/svapp.hxx>
40 #include <svl/smplhint.hxx>
41 #include <unotools/accessiblestatesethelper.hxx>
42 #include <comphelper/sequence.hxx>
43 #include <comphelper/servicehelper.hxx>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::accessibility
;
48 //===== internal ============================================================
50 ScAccessiblePreviewTable::ScAccessiblePreviewTable( const ::com::sun::star::uno::Reference
<
51 ::com::sun::star::accessibility::XAccessible
>& rxParent
,
52 ScPreviewShell
* pViewShell
, sal_Int32 nIndex
) :
53 ScAccessibleContextBase( rxParent
, AccessibleRole::TABLE
),
54 mpViewShell( pViewShell
),
59 mpViewShell
->AddAccessibilityObject(*this);
62 ScAccessiblePreviewTable::~ScAccessiblePreviewTable()
64 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper
.bInDispose
)
66 // increment refcount to prevent double call off dtor
67 osl_atomic_increment( &m_refCount
);
72 void SAL_CALL
ScAccessiblePreviewTable::disposing()
74 SolarMutexGuard aGuard
;
77 mpViewShell
->RemoveAccessibilityObject(*this);
82 DELETEZ (mpTableInfo
);
84 ScAccessibleContextBase::disposing();
87 //===== SfxListener =====================================================
89 void ScAccessiblePreviewTable::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
91 if (rHint
.ISA( SfxSimpleHint
))
93 const SfxSimpleHint
& rRef
= (const SfxSimpleHint
&)rHint
;
94 sal_uLong nId
= rRef
.GetId();
95 if ( nId
== SFX_HINT_DATACHANGED
)
97 // column / row layout may change with any document change,
98 // so it must be invalidated
99 DELETEZ( mpTableInfo
);
101 else if (rRef
.GetId() == SC_HINT_ACC_VISAREACHANGED
)
103 AccessibleEventObject aEvent
;
104 aEvent
.EventId
= AccessibleEventId::VISIBLE_DATA_CHANGED
;
105 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
106 CommitChange(aEvent
);
110 ScAccessibleContextBase::Notify(rBC
, rHint
);
113 //===== XInterface =====================================================
115 uno::Any SAL_CALL
ScAccessiblePreviewTable::queryInterface( uno::Type
const & rType
)
116 throw (uno::RuntimeException
, std::exception
)
118 uno::Any
aAny (ScAccessiblePreviewTableImpl::queryInterface(rType
));
119 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
122 void SAL_CALL
ScAccessiblePreviewTable::acquire()
125 ScAccessibleContextBase::acquire();
128 void SAL_CALL
ScAccessiblePreviewTable::release()
131 ScAccessibleContextBase::release();
134 //===== XAccessibleTable ================================================
136 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowCount()
137 throw (uno::RuntimeException
, std::exception
)
139 SolarMutexGuard aGuard
;
146 nRet
= mpTableInfo
->GetRows();
150 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnCount()
151 throw (uno::RuntimeException
, std::exception
)
153 SolarMutexGuard aGuard
;
160 nRet
= mpTableInfo
->GetCols();
164 OUString SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowDescription( sal_Int32 nRow
)
165 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
167 SolarMutexGuard aGuard
;
169 if ( nRow
< 0 || (mpTableInfo
&& nRow
>= mpTableInfo
->GetRows()) )
170 throw lang::IndexOutOfBoundsException();
175 OUString SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnDescription( sal_Int32 nColumn
)
176 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
178 SolarMutexGuard aGuard
;
180 if ( nColumn
< 0 || (mpTableInfo
&& nColumn
>= mpTableInfo
->GetCols()) )
181 throw lang::IndexOutOfBoundsException();
186 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
187 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
189 SolarMutexGuard aGuard
;
195 if ( mpViewShell
&& mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 &&
196 nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
198 const ScPreviewColRowInfo
& rColInfo
= mpTableInfo
->GetColInfo()[nColumn
];
199 const ScPreviewColRowInfo
& rRowInfo
= mpTableInfo
->GetRowInfo()[nRow
];
201 if ( rColInfo
.bIsHeader
|| rRowInfo
.bIsHeader
)
203 // header cells only span a single cell
207 ScDocument
* pDoc
= mpViewShell
->GetDocument();
208 const ScMergeAttr
* pItem
= (const ScMergeAttr
*)pDoc
->GetAttr(
209 static_cast<SCCOL
>(rColInfo
.nDocIndex
), static_cast<SCROW
>(rRowInfo
.nDocIndex
), mpTableInfo
->GetTab(), ATTR_MERGE
);
210 if ( pItem
&& pItem
->GetRowMerge() > 0 )
211 nRows
= pItem
->GetRowMerge();
215 throw lang::IndexOutOfBoundsException();
220 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
221 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
223 SolarMutexGuard aGuard
;
228 sal_Int32 nColumns
= 1;
229 if ( mpViewShell
&& mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 &&
230 nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
232 const ScPreviewColRowInfo
& rColInfo
= mpTableInfo
->GetColInfo()[nColumn
];
233 const ScPreviewColRowInfo
& rRowInfo
= mpTableInfo
->GetRowInfo()[nRow
];
235 if ( rColInfo
.bIsHeader
|| rRowInfo
.bIsHeader
)
237 // header cells only span a single cell
241 ScDocument
* pDoc
= mpViewShell
->GetDocument();
242 const ScMergeAttr
* pItem
= (const ScMergeAttr
*)pDoc
->GetAttr(
243 static_cast<SCCOL
>(rColInfo
.nDocIndex
), static_cast<SCROW
>(rRowInfo
.nDocIndex
), mpTableInfo
->GetTab(), ATTR_MERGE
);
244 if ( pItem
&& pItem
->GetColMerge() > 0 )
245 nColumns
= pItem
->GetColMerge();
249 throw lang::IndexOutOfBoundsException();
254 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowHeaders() throw (uno::RuntimeException
, std::exception
)
260 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnHeaders() throw (uno::RuntimeException
, std::exception
)
266 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessiblePreviewTable::getSelectedAccessibleRows() throw (uno::RuntimeException
, std::exception
)
268 // in the page preview, there is no selection
269 return uno::Sequence
<sal_Int32
>(0);
272 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessiblePreviewTable::getSelectedAccessibleColumns() throw (uno::RuntimeException
, std::exception
)
274 // in the page preview, there is no selection
275 return uno::Sequence
<sal_Int32
>(0);
278 sal_Bool SAL_CALL
ScAccessiblePreviewTable::isAccessibleRowSelected( sal_Int32 nRow
)
279 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
281 // in the page preview, there is no selection
283 SolarMutexGuard aGuard
;
285 if ( nRow
< 0 || (mpTableInfo
&& nRow
>= mpTableInfo
->GetRows()) )
286 throw lang::IndexOutOfBoundsException();
291 sal_Bool SAL_CALL
ScAccessiblePreviewTable::isAccessibleColumnSelected( sal_Int32 nColumn
)
292 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
294 // in the page preview, there is no selection
296 SolarMutexGuard aGuard
;
298 if ( nColumn
< 0 || (mpTableInfo
&& nColumn
>= mpTableInfo
->GetCols()) )
299 throw lang::IndexOutOfBoundsException();
304 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleCellAt( sal_Int32 nRow
, sal_Int32 nColumn
)
305 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
307 SolarMutexGuard aGuard
;
312 uno::Reference
<XAccessible
> xRet
;
313 if ( mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 && nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
315 // index iterates horizontally
316 long nNewIndex
= nRow
* mpTableInfo
->GetCols() + nColumn
;
318 const ScPreviewColRowInfo
& rColInfo
= mpTableInfo
->GetColInfo()[nColumn
];
319 const ScPreviewColRowInfo
& rRowInfo
= mpTableInfo
->GetRowInfo()[nRow
];
321 ScAddress
aCellPos( static_cast<SCCOL
>(rColInfo
.nDocIndex
), static_cast<SCROW
>(rRowInfo
.nDocIndex
), mpTableInfo
->GetTab() );
322 if ( rColInfo
.bIsHeader
|| rRowInfo
.bIsHeader
)
324 ScAccessiblePreviewHeaderCell
* pHeaderCell
= new ScAccessiblePreviewHeaderCell( this, mpViewShell
, aCellPos
,
325 rRowInfo
.bIsHeader
, rColInfo
.bIsHeader
, nNewIndex
);
331 ScAccessiblePreviewCell
* pCell
= new ScAccessiblePreviewCell( this, mpViewShell
, aCellPos
, nNewIndex
);
338 throw lang::IndexOutOfBoundsException();
343 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleCaption() throw (uno::RuntimeException
, std::exception
)
349 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleSummary() throw (uno::RuntimeException
, std::exception
)
355 sal_Bool SAL_CALL
ScAccessiblePreviewTable::isAccessibleSelected( sal_Int32 nRow
, sal_Int32 nColumn
)
356 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
358 // in the page preview, there is no selection
359 SolarMutexGuard aGuard
;
364 if ( mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 && nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
366 // index iterates horizontally
369 throw lang::IndexOutOfBoundsException();
374 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
)
375 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
377 SolarMutexGuard aGuard
;
383 if ( mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 && nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
385 // index iterates horizontally
386 nRet
= nRow
* mpTableInfo
->GetCols() + nColumn
;
389 throw lang::IndexOutOfBoundsException();
394 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleRow( sal_Int32 nChildIndex
)
395 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
397 SolarMutexGuard aGuard
;
403 if ( mpTableInfo
&& nChildIndex
>= 0 && nChildIndex
< static_cast<sal_Int32
>(mpTableInfo
->GetRows()) * mpTableInfo
->GetCols() )
405 nRow
= nChildIndex
/ mpTableInfo
->GetCols();
408 throw lang::IndexOutOfBoundsException();
413 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumn( sal_Int32 nChildIndex
)
414 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
416 SolarMutexGuard aGuard
;
422 if ( mpTableInfo
&& nChildIndex
>= 0 && nChildIndex
< static_cast<sal_Int32
>(mpTableInfo
->GetRows()) * mpTableInfo
->GetCols() )
424 nCol
= nChildIndex
% static_cast<sal_Int32
>(mpTableInfo
->GetCols());
427 throw lang::IndexOutOfBoundsException();
432 //===== XAccessibleComponent ============================================
434 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleAtPoint( const awt::Point
& aPoint
)
435 throw (uno::RuntimeException
, std::exception
)
437 uno::Reference
<XAccessible
> xRet
;
438 if (containsPoint(aPoint
))
440 SolarMutexGuard aGuard
;
447 SCCOL nCols
= mpTableInfo
->GetCols();
448 SCROW nRows
= mpTableInfo
->GetRows();
449 const ScPreviewColRowInfo
* pColInfo
= mpTableInfo
->GetColInfo();
450 const ScPreviewColRowInfo
* pRowInfo
= mpTableInfo
->GetRowInfo();
452 Rectangle
aScreenRect(GetBoundingBox());
454 awt::Point aMovedPoint
= aPoint
;
455 aMovedPoint
.X
+= aScreenRect
.Left();
456 aMovedPoint
.Y
+= aScreenRect
.Top();
458 if ( nCols
> 0 && nRows
> 0 && aMovedPoint
.X
>= pColInfo
[0].nPixelStart
&& aMovedPoint
.Y
>= pRowInfo
[0].nPixelStart
)
461 while ( nColIndex
< nCols
&& aMovedPoint
.X
> pColInfo
[nColIndex
].nPixelEnd
)
464 while ( nRowIndex
< nRows
&& aMovedPoint
.Y
> pRowInfo
[nRowIndex
].nPixelEnd
)
466 if ( nColIndex
< nCols
&& nRowIndex
< nRows
)
470 xRet
= getAccessibleCellAt( nRowIndex
, nColIndex
);
472 catch (uno::Exception
&)
483 void SAL_CALL
ScAccessiblePreviewTable::grabFocus() throw (uno::RuntimeException
, std::exception
)
485 SolarMutexGuard aGuard
;
487 if (getAccessibleParent().is())
489 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
490 if (xAccessibleComponent
.is())
491 xAccessibleComponent
->grabFocus();
495 //===== XAccessibleContext ==============================================
497 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleChildCount()
498 throw (uno::RuntimeException
, std::exception
)
500 SolarMutexGuard aGuard
;
507 nRet
= static_cast<sal_Int32
>(mpTableInfo
->GetCols()) * mpTableInfo
->GetRows();
511 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleChild( sal_Int32 nIndex
)
512 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
514 SolarMutexGuard aGuard
;
519 uno::Reference
<XAccessible
> xRet
;
522 long nColumns
= mpTableInfo
->GetCols();
525 // nCol, nRow are within the visible table, not the document
526 long nCol
= nIndex
% nColumns
;
527 long nRow
= nIndex
/ nColumns
;
529 xRet
= getAccessibleCellAt( nRow
, nCol
);
534 throw lang::IndexOutOfBoundsException();
539 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleIndexInParent() throw (uno::RuntimeException
, std::exception
)
544 uno::Reference
< XAccessibleStateSet
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleStateSet()
545 throw (uno::RuntimeException
, std::exception
)
547 SolarMutexGuard aGuard
;
548 uno::Reference
<XAccessibleStateSet
> xParentStates
;
549 if (getAccessibleParent().is())
551 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
552 xParentStates
= xParentContext
->getAccessibleStateSet();
554 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
555 if (IsDefunc(xParentStates
))
556 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
559 pStateSet
->AddState(AccessibleStateType::MANAGES_DESCENDANTS
);
560 pStateSet
->AddState(AccessibleStateType::ENABLED
);
561 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
563 pStateSet
->AddState(AccessibleStateType::SHOWING
);
565 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
570 //===== XServiceInfo ====================================================
572 OUString SAL_CALL
ScAccessiblePreviewTable::getImplementationName() throw(uno::RuntimeException
, std::exception
)
574 return OUString("ScAccessiblePreviewTable");
577 uno::Sequence
<OUString
> SAL_CALL
ScAccessiblePreviewTable::getSupportedServiceNames()
578 throw(uno::RuntimeException
, std::exception
)
580 uno::Sequence
< OUString
> aSequence
= ScAccessibleContextBase::getSupportedServiceNames();
581 sal_Int32
nOldSize(aSequence
.getLength());
582 aSequence
.realloc(nOldSize
+ 1);
584 aSequence
[nOldSize
] = "com.sun.star.table.AccessibleTableView";
589 //===== XTypeProvider ===================================================
591 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessiblePreviewTable::getTypes()
592 throw (uno::RuntimeException
, std::exception
)
594 return comphelper::concatSequences(ScAccessiblePreviewTableImpl::getTypes(), ScAccessibleContextBase::getTypes());
597 uno::Sequence
<sal_Int8
> SAL_CALL
ScAccessiblePreviewTable::getImplementationId()
598 throw(uno::RuntimeException
, std::exception
)
600 return css::uno::Sequence
<sal_Int8
>();
603 //==== internal =========================================================
605 OUString SAL_CALL
ScAccessiblePreviewTable::createAccessibleDescription(void)
606 throw (uno::RuntimeException
)
608 OUString
sDesc(ScResId(STR_ACC_TABLE_DESCR
));
612 OUString SAL_CALL
ScAccessiblePreviewTable::createAccessibleName()
613 throw (uno::RuntimeException
, std::exception
)
615 OUString
sName(SC_RESSTR(STR_ACC_TABLE_NAME
));
617 if (mpViewShell
&& mpViewShell
->GetDocument())
624 if (mpViewShell
->GetDocument()->GetName( mpTableInfo
->GetTab(), sCoreName
))
625 sName
= sName
.replaceFirst("%1", sCoreName
);
632 Rectangle
ScAccessiblePreviewTable::GetBoundingBoxOnScreen() const throw (uno::RuntimeException
, std::exception
)
634 Rectangle
aCellRect(GetBoundingBox());
637 Window
* pWindow
= mpViewShell
->GetWindow();
640 Rectangle aRect
= pWindow
->GetWindowExtentsRelative(NULL
);
641 aCellRect
.setX(aCellRect
.getX() + aRect
.getX());
642 aCellRect
.setY(aCellRect
.getY() + aRect
.getY());
648 Rectangle
ScAccessiblePreviewTable::GetBoundingBox() const
649 throw (uno::RuntimeException
, std::exception
)
656 SCCOL nColumns
= mpTableInfo
->GetCols();
657 SCROW nRows
= mpTableInfo
->GetRows();
658 if ( nColumns
> 0 && nRows
> 0 )
660 const ScPreviewColRowInfo
* pColInfo
= mpTableInfo
->GetColInfo();
661 const ScPreviewColRowInfo
* pRowInfo
= mpTableInfo
->GetRowInfo();
663 aRect
= Rectangle( pColInfo
[0].nPixelStart
,
664 pRowInfo
[0].nPixelStart
,
665 pColInfo
[nColumns
-1].nPixelEnd
,
666 pRowInfo
[nRows
-1].nPixelEnd
);
672 bool ScAccessiblePreviewTable::IsDefunc( const uno::Reference
<XAccessibleStateSet
>& rxParentStates
)
674 return ScAccessibleContextBase::IsDefunc() || (mpViewShell
== NULL
) || !getAccessibleParent().is() ||
675 (rxParentStates
.is() && rxParentStates
->contains(AccessibleStateType::DEFUNC
));
678 void ScAccessiblePreviewTable::FillTableInfo() const
680 if ( mpViewShell
&& !mpTableInfo
)
683 Window
* pWindow
= mpViewShell
->GetWindow();
685 aOutputSize
= pWindow
->GetOutputSizePixel();
687 Rectangle
aVisRect( aPoint
, aOutputSize
);
689 mpTableInfo
= new ScPreviewTableInfo
;
690 mpViewShell
->GetLocationData().GetTableInfo( aVisRect
, *mpTableInfo
);
694 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */