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 .
20 #include "scitems.hxx"
21 #include "AccessiblePreviewTable.hxx"
22 #include "AccessiblePreviewCell.hxx"
23 #include "AccessiblePreviewHeaderCell.hxx"
24 #include "AccessibilityHints.hxx"
25 #include "prevwsh.hxx"
26 #include "miscuno.hxx"
27 #include "prevloc.hxx"
29 #include "document.hxx"
30 #include "scresid.hxx"
33 #include <com/sun/star/accessibility/AccessibleRole.hpp>
34 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <vcl/window.hxx>
38 #include <vcl/svapp.hxx>
39 #include <svl/smplhint.hxx>
40 #include <unotools/accessiblestatesethelper.hxx>
41 #include <comphelper/sequence.hxx>
42 #include <comphelper/servicehelper.hxx>
44 using namespace ::com::sun::star
;
45 using namespace ::com::sun::star::accessibility
;
47 //===== internal ============================================================
49 ScAccessiblePreviewTable::ScAccessiblePreviewTable( const ::com::sun::star::uno::Reference
<
50 ::com::sun::star::accessibility::XAccessible
>& rxParent
,
51 ScPreviewShell
* pViewShell
, sal_Int32 nIndex
) :
52 ScAccessibleContextBase( rxParent
, AccessibleRole::TABLE
),
53 mpViewShell( pViewShell
),
58 mpViewShell
->AddAccessibilityObject(*this);
61 ScAccessiblePreviewTable::~ScAccessiblePreviewTable()
63 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper
.bInDispose
)
65 // increment refcount to prevent double call off dtor
66 osl_atomic_increment( &m_refCount
);
71 void SAL_CALL
ScAccessiblePreviewTable::disposing()
73 SolarMutexGuard aGuard
;
76 mpViewShell
->RemoveAccessibilityObject(*this);
81 DELETEZ (mpTableInfo
);
83 ScAccessibleContextBase::disposing();
86 //===== SfxListener =====================================================
88 void ScAccessiblePreviewTable::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
90 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
93 sal_uLong nId
= pSimpleHint
->GetId();
94 if ( nId
== SFX_HINT_DATACHANGED
)
96 // column / row layout may change with any document change,
97 // so it must be invalidated
98 DELETEZ( mpTableInfo
);
100 else if (pSimpleHint
->GetId() == SC_HINT_ACC_VISAREACHANGED
)
102 AccessibleEventObject aEvent
;
103 aEvent
.EventId
= AccessibleEventId::VISIBLE_DATA_CHANGED
;
104 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
105 CommitChange(aEvent
);
109 ScAccessibleContextBase::Notify(rBC
, rHint
);
112 //===== XInterface =====================================================
114 uno::Any SAL_CALL
ScAccessiblePreviewTable::queryInterface( uno::Type
const & rType
)
115 throw (uno::RuntimeException
, std::exception
)
117 uno::Any
aAny (ScAccessiblePreviewTableImpl::queryInterface(rType
));
118 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
121 void SAL_CALL
ScAccessiblePreviewTable::acquire()
124 ScAccessibleContextBase::acquire();
127 void SAL_CALL
ScAccessiblePreviewTable::release()
130 ScAccessibleContextBase::release();
133 //===== XAccessibleTable ================================================
135 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowCount()
136 throw (uno::RuntimeException
, std::exception
)
138 SolarMutexGuard aGuard
;
145 nRet
= mpTableInfo
->GetRows();
149 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnCount()
150 throw (uno::RuntimeException
, std::exception
)
152 SolarMutexGuard aGuard
;
159 nRet
= mpTableInfo
->GetCols();
163 OUString SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowDescription( sal_Int32 nRow
)
164 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
166 SolarMutexGuard aGuard
;
168 if ( nRow
< 0 || (mpTableInfo
&& nRow
>= mpTableInfo
->GetRows()) )
169 throw lang::IndexOutOfBoundsException();
174 OUString SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnDescription( sal_Int32 nColumn
)
175 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
177 SolarMutexGuard aGuard
;
179 if ( nColumn
< 0 || (mpTableInfo
&& nColumn
>= mpTableInfo
->GetCols()) )
180 throw lang::IndexOutOfBoundsException();
185 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
186 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
188 SolarMutexGuard aGuard
;
194 if ( mpViewShell
&& mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 &&
195 nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
197 const ScPreviewColRowInfo
& rColInfo
= mpTableInfo
->GetColInfo()[nColumn
];
198 const ScPreviewColRowInfo
& rRowInfo
= mpTableInfo
->GetRowInfo()[nRow
];
200 if ( rColInfo
.bIsHeader
|| rRowInfo
.bIsHeader
)
202 // header cells only span a single cell
206 ScDocument
& rDoc
= mpViewShell
->GetDocument();
207 const ScMergeAttr
* pItem
= static_cast<const ScMergeAttr
*>(rDoc
.GetAttr(
208 static_cast<SCCOL
>(rColInfo
.nDocIndex
), static_cast<SCROW
>(rRowInfo
.nDocIndex
), mpTableInfo
->GetTab(), ATTR_MERGE
));
209 if ( pItem
&& pItem
->GetRowMerge() > 0 )
210 nRows
= pItem
->GetRowMerge();
214 throw lang::IndexOutOfBoundsException();
219 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
220 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
222 SolarMutexGuard aGuard
;
227 sal_Int32 nColumns
= 1;
228 if ( mpViewShell
&& mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 &&
229 nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
231 const ScPreviewColRowInfo
& rColInfo
= mpTableInfo
->GetColInfo()[nColumn
];
232 const ScPreviewColRowInfo
& rRowInfo
= mpTableInfo
->GetRowInfo()[nRow
];
234 if ( rColInfo
.bIsHeader
|| rRowInfo
.bIsHeader
)
236 // header cells only span a single cell
240 ScDocument
& rDoc
= mpViewShell
->GetDocument();
241 const ScMergeAttr
* pItem
= static_cast<const ScMergeAttr
*>(rDoc
.GetAttr(
242 static_cast<SCCOL
>(rColInfo
.nDocIndex
), static_cast<SCROW
>(rRowInfo
.nDocIndex
), mpTableInfo
->GetTab(), ATTR_MERGE
));
243 if ( pItem
&& pItem
->GetColMerge() > 0 )
244 nColumns
= pItem
->GetColMerge();
248 throw lang::IndexOutOfBoundsException();
253 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleRowHeaders() throw (uno::RuntimeException
, std::exception
)
259 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumnHeaders() throw (uno::RuntimeException
, std::exception
)
265 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessiblePreviewTable::getSelectedAccessibleRows() throw (uno::RuntimeException
, std::exception
)
267 // in the page preview, there is no selection
268 return uno::Sequence
<sal_Int32
>(0);
271 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessiblePreviewTable::getSelectedAccessibleColumns() throw (uno::RuntimeException
, std::exception
)
273 // in the page preview, there is no selection
274 return uno::Sequence
<sal_Int32
>(0);
277 sal_Bool SAL_CALL
ScAccessiblePreviewTable::isAccessibleRowSelected( sal_Int32 nRow
)
278 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
280 // in the page preview, there is no selection
282 SolarMutexGuard aGuard
;
284 if ( nRow
< 0 || (mpTableInfo
&& nRow
>= mpTableInfo
->GetRows()) )
285 throw lang::IndexOutOfBoundsException();
290 sal_Bool SAL_CALL
ScAccessiblePreviewTable::isAccessibleColumnSelected( sal_Int32 nColumn
)
291 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
293 // in the page preview, there is no selection
295 SolarMutexGuard aGuard
;
297 if ( nColumn
< 0 || (mpTableInfo
&& nColumn
>= mpTableInfo
->GetCols()) )
298 throw lang::IndexOutOfBoundsException();
303 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleCellAt( sal_Int32 nRow
, sal_Int32 nColumn
)
304 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
306 SolarMutexGuard aGuard
;
311 uno::Reference
<XAccessible
> xRet
;
312 if ( mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 && nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
314 // index iterates horizontally
315 long nNewIndex
= nRow
* mpTableInfo
->GetCols() + nColumn
;
317 const ScPreviewColRowInfo
& rColInfo
= mpTableInfo
->GetColInfo()[nColumn
];
318 const ScPreviewColRowInfo
& rRowInfo
= mpTableInfo
->GetRowInfo()[nRow
];
320 ScAddress
aCellPos( static_cast<SCCOL
>(rColInfo
.nDocIndex
), static_cast<SCROW
>(rRowInfo
.nDocIndex
), mpTableInfo
->GetTab() );
321 if ( rColInfo
.bIsHeader
|| rRowInfo
.bIsHeader
)
323 const bool bRotatedColHeader
= rRowInfo
.bIsHeader
;
324 const bool bRotatedRowHeader
= rColInfo
.bIsHeader
;
325 ScAccessiblePreviewHeaderCell
* pHeaderCell
= new ScAccessiblePreviewHeaderCell(this, mpViewShell
, aCellPos
,
326 bRotatedColHeader
, bRotatedRowHeader
, nNewIndex
);
332 ScAccessiblePreviewCell
* pCell
= new ScAccessiblePreviewCell( this, mpViewShell
, aCellPos
, nNewIndex
);
339 throw lang::IndexOutOfBoundsException();
344 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleCaption() throw (uno::RuntimeException
, std::exception
)
350 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleSummary() throw (uno::RuntimeException
, std::exception
)
356 sal_Bool SAL_CALL
ScAccessiblePreviewTable::isAccessibleSelected( sal_Int32 nRow
, sal_Int32 nColumn
)
357 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
359 // in the page preview, there is no selection
360 SolarMutexGuard aGuard
;
365 if ( mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 && nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
367 // index iterates horizontally
370 throw lang::IndexOutOfBoundsException();
375 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
)
376 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
378 SolarMutexGuard aGuard
;
384 if ( mpTableInfo
&& nColumn
>= 0 && nRow
>= 0 && nColumn
< mpTableInfo
->GetCols() && nRow
< mpTableInfo
->GetRows() )
386 // index iterates horizontally
387 nRet
= nRow
* mpTableInfo
->GetCols() + nColumn
;
390 throw lang::IndexOutOfBoundsException();
395 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleRow( sal_Int32 nChildIndex
)
396 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
398 SolarMutexGuard aGuard
;
404 if ( mpTableInfo
&& nChildIndex
>= 0 && nChildIndex
< static_cast<sal_Int32
>(mpTableInfo
->GetRows()) * mpTableInfo
->GetCols() )
406 nRow
= nChildIndex
/ mpTableInfo
->GetCols();
409 throw lang::IndexOutOfBoundsException();
414 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleColumn( sal_Int32 nChildIndex
)
415 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
417 SolarMutexGuard aGuard
;
423 if ( mpTableInfo
&& nChildIndex
>= 0 && nChildIndex
< static_cast<sal_Int32
>(mpTableInfo
->GetRows()) * mpTableInfo
->GetCols() )
425 nCol
= nChildIndex
% static_cast<sal_Int32
>(mpTableInfo
->GetCols());
428 throw lang::IndexOutOfBoundsException();
433 //===== XAccessibleComponent ============================================
435 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleAtPoint( const awt::Point
& aPoint
)
436 throw (uno::RuntimeException
, std::exception
)
438 uno::Reference
<XAccessible
> xRet
;
439 if (containsPoint(aPoint
))
441 SolarMutexGuard aGuard
;
448 SCCOL nCols
= mpTableInfo
->GetCols();
449 SCROW nRows
= mpTableInfo
->GetRows();
450 const ScPreviewColRowInfo
* pColInfo
= mpTableInfo
->GetColInfo();
451 const ScPreviewColRowInfo
* pRowInfo
= mpTableInfo
->GetRowInfo();
453 Rectangle
aScreenRect(GetBoundingBox());
455 awt::Point aMovedPoint
= aPoint
;
456 aMovedPoint
.X
+= aScreenRect
.Left();
457 aMovedPoint
.Y
+= aScreenRect
.Top();
459 if ( nCols
> 0 && nRows
> 0 && aMovedPoint
.X
>= pColInfo
[0].nPixelStart
&& aMovedPoint
.Y
>= pRowInfo
[0].nPixelStart
)
462 while ( nColIndex
< nCols
&& aMovedPoint
.X
> pColInfo
[nColIndex
].nPixelEnd
)
465 while ( nRowIndex
< nRows
&& aMovedPoint
.Y
> pRowInfo
[nRowIndex
].nPixelEnd
)
467 if ( nColIndex
< nCols
&& nRowIndex
< nRows
)
471 xRet
= getAccessibleCellAt( nRowIndex
, nColIndex
);
473 catch (uno::Exception
&)
484 void SAL_CALL
ScAccessiblePreviewTable::grabFocus() throw (uno::RuntimeException
, std::exception
)
486 SolarMutexGuard aGuard
;
488 if (getAccessibleParent().is())
490 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
491 if (xAccessibleComponent
.is())
492 xAccessibleComponent
->grabFocus();
496 //===== XAccessibleContext ==============================================
498 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleChildCount()
499 throw (uno::RuntimeException
, std::exception
)
501 SolarMutexGuard aGuard
;
508 nRet
= static_cast<sal_Int32
>(mpTableInfo
->GetCols()) * mpTableInfo
->GetRows();
512 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleChild( sal_Int32 nIndex
)
513 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
515 SolarMutexGuard aGuard
;
520 uno::Reference
<XAccessible
> xRet
;
523 long nColumns
= mpTableInfo
->GetCols();
526 // nCol, nRow are within the visible table, not the document
527 long nCol
= nIndex
% nColumns
;
528 long nRow
= nIndex
/ nColumns
;
530 xRet
= getAccessibleCellAt( nRow
, nCol
);
535 throw lang::IndexOutOfBoundsException();
540 sal_Int32 SAL_CALL
ScAccessiblePreviewTable::getAccessibleIndexInParent() throw (uno::RuntimeException
, std::exception
)
545 uno::Reference
< XAccessibleStateSet
> SAL_CALL
ScAccessiblePreviewTable::getAccessibleStateSet()
546 throw (uno::RuntimeException
, std::exception
)
548 SolarMutexGuard aGuard
;
549 uno::Reference
<XAccessibleStateSet
> xParentStates
;
550 if (getAccessibleParent().is())
552 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
553 xParentStates
= xParentContext
->getAccessibleStateSet();
555 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
556 if (IsDefunc(xParentStates
))
557 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
560 pStateSet
->AddState(AccessibleStateType::MANAGES_DESCENDANTS
);
561 pStateSet
->AddState(AccessibleStateType::ENABLED
);
562 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
564 pStateSet
->AddState(AccessibleStateType::SHOWING
);
566 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
571 //===== XServiceInfo ====================================================
573 OUString SAL_CALL
ScAccessiblePreviewTable::getImplementationName() throw(uno::RuntimeException
, std::exception
)
575 return OUString("ScAccessiblePreviewTable");
578 uno::Sequence
<OUString
> SAL_CALL
ScAccessiblePreviewTable::getSupportedServiceNames()
579 throw(uno::RuntimeException
, std::exception
)
581 uno::Sequence
< OUString
> aSequence
= ScAccessibleContextBase::getSupportedServiceNames();
582 sal_Int32
nOldSize(aSequence
.getLength());
583 aSequence
.realloc(nOldSize
+ 1);
585 aSequence
[nOldSize
] = "com.sun.star.table.AccessibleTableView";
590 //===== XTypeProvider ===================================================
592 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessiblePreviewTable::getTypes()
593 throw (uno::RuntimeException
, std::exception
)
595 return comphelper::concatSequences(ScAccessiblePreviewTableImpl::getTypes(), ScAccessibleContextBase::getTypes());
598 uno::Sequence
<sal_Int8
> SAL_CALL
ScAccessiblePreviewTable::getImplementationId()
599 throw(uno::RuntimeException
, std::exception
)
601 return css::uno::Sequence
<sal_Int8
>();
604 //==== internal =========================================================
606 OUString SAL_CALL
ScAccessiblePreviewTable::createAccessibleDescription()
607 throw (uno::RuntimeException
)
609 OUString
sDesc(ScResId(STR_ACC_TABLE_DESCR
));
613 OUString SAL_CALL
ScAccessiblePreviewTable::createAccessibleName()
614 throw (uno::RuntimeException
, std::exception
)
616 OUString
sName(SC_RESSTR(STR_ACC_TABLE_NAME
));
625 if (mpViewShell
->GetDocument().GetName( mpTableInfo
->GetTab(), sCoreName
))
626 sName
= sName
.replaceFirst("%1", sCoreName
);
633 Rectangle
ScAccessiblePreviewTable::GetBoundingBoxOnScreen() const throw (uno::RuntimeException
, std::exception
)
635 Rectangle
aCellRect(GetBoundingBox());
638 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
641 Rectangle aRect
= pWindow
->GetWindowExtentsRelative(NULL
);
642 aCellRect
.setX(aCellRect
.getX() + aRect
.getX());
643 aCellRect
.setY(aCellRect
.getY() + aRect
.getY());
649 Rectangle
ScAccessiblePreviewTable::GetBoundingBox() const
650 throw (uno::RuntimeException
, std::exception
)
657 SCCOL nColumns
= mpTableInfo
->GetCols();
658 SCROW nRows
= mpTableInfo
->GetRows();
659 if ( nColumns
> 0 && nRows
> 0 )
661 const ScPreviewColRowInfo
* pColInfo
= mpTableInfo
->GetColInfo();
662 const ScPreviewColRowInfo
* pRowInfo
= mpTableInfo
->GetRowInfo();
664 aRect
= Rectangle( pColInfo
[0].nPixelStart
,
665 pRowInfo
[0].nPixelStart
,
666 pColInfo
[nColumns
-1].nPixelEnd
,
667 pRowInfo
[nRows
-1].nPixelEnd
);
673 bool ScAccessiblePreviewTable::IsDefunc( const uno::Reference
<XAccessibleStateSet
>& rxParentStates
)
675 return ScAccessibleContextBase::IsDefunc() || (mpViewShell
== NULL
) || !getAccessibleParent().is() ||
676 (rxParentStates
.is() && rxParentStates
->contains(AccessibleStateType::DEFUNC
));
679 void ScAccessiblePreviewTable::FillTableInfo() const
681 if ( mpViewShell
&& !mpTableInfo
)
684 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
686 aOutputSize
= pWindow
->GetOutputSizePixel();
688 Rectangle
aVisRect( aPoint
, aOutputSize
);
690 mpTableInfo
= new ScPreviewTableInfo
;
691 mpViewShell
->GetLocationData().GetTableInfo( aVisRect
, *mpTableInfo
);
695 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */