nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / ui / Accessibility / AccessiblePreviewTable.cxx
blobaced9a883d984ded09b5c4a440312794b51d2314
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <prevwsh.hxx>
25 #include <prevloc.hxx>
26 #include <attrib.hxx>
27 #include <document.hxx>
28 #include <scresid.hxx>
29 #include <strings.hrc>
30 #include <strings.hxx>
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/lang/IndexOutOfBoundsException.hpp>
37 #include <vcl/window.hxx>
38 #include <vcl/svapp.hxx>
39 #include <svl/hint.hxx>
40 #include <unotools/accessiblestatesethelper.hxx>
41 #include <comphelper/sequence.hxx>
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::accessibility;
46 //===== internal ============================================================
48 ScAccessiblePreviewTable::ScAccessiblePreviewTable( const css::uno::Reference<css::accessibility::XAccessible>& rxParent,
49 ScPreviewShell* pViewShell, sal_Int32 nIndex ) :
50 ScAccessibleContextBase( rxParent, AccessibleRole::TABLE ),
51 mpViewShell( pViewShell ),
52 mnIndex( nIndex )
54 if (mpViewShell)
55 mpViewShell->AddAccessibilityObject(*this);
58 ScAccessiblePreviewTable::~ScAccessiblePreviewTable()
60 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
62 // increment refcount to prevent double call off dtor
63 osl_atomic_increment( &m_refCount );
64 dispose();
68 void SAL_CALL ScAccessiblePreviewTable::disposing()
70 SolarMutexGuard aGuard;
71 if (mpViewShell)
73 mpViewShell->RemoveAccessibilityObject(*this);
74 mpViewShell = nullptr;
77 mpTableInfo.reset();
79 ScAccessibleContextBase::disposing();
82 //===== SfxListener =====================================================
84 void ScAccessiblePreviewTable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
86 const SfxHintId nId = rHint.GetId();
87 if ( nId == SfxHintId::DataChanged )
89 // column / row layout may change with any document change,
90 // so it must be invalidated
91 mpTableInfo.reset();
93 else if (nId == SfxHintId::ScAccVisAreaChanged)
95 AccessibleEventObject aEvent;
96 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
97 aEvent.Source = uno::Reference< XAccessibleContext >(this);
98 CommitChange(aEvent);
101 ScAccessibleContextBase::Notify(rBC, rHint);
104 //===== XInterface =====================================================
106 uno::Any SAL_CALL ScAccessiblePreviewTable::queryInterface( uno::Type const & rType )
108 uno::Any aAny (ScAccessiblePreviewTableImpl::queryInterface(rType));
109 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
112 void SAL_CALL ScAccessiblePreviewTable::acquire()
113 throw ()
115 ScAccessibleContextBase::acquire();
118 void SAL_CALL ScAccessiblePreviewTable::release()
119 throw ()
121 ScAccessibleContextBase::release();
124 //===== XAccessibleTable ================================================
126 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowCount()
128 SolarMutexGuard aGuard;
129 IsObjectValid();
131 FillTableInfo();
133 sal_Int32 nRet = 0;
134 if ( mpTableInfo )
135 nRet = mpTableInfo->GetRows();
136 return nRet;
139 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnCount()
141 SolarMutexGuard aGuard;
142 IsObjectValid();
144 FillTableInfo();
146 sal_Int32 nRet = 0;
147 if ( mpTableInfo )
148 nRet = mpTableInfo->GetCols();
149 return nRet;
152 OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleRowDescription( sal_Int32 nRow )
154 SolarMutexGuard aGuard;
155 FillTableInfo();
156 if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
157 throw lang::IndexOutOfBoundsException();
159 return OUString();
162 OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnDescription( sal_Int32 nColumn )
164 SolarMutexGuard aGuard;
165 FillTableInfo();
166 if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
167 throw lang::IndexOutOfBoundsException();
169 return OUString();
172 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
174 SolarMutexGuard aGuard;
175 IsObjectValid();
177 FillTableInfo();
179 sal_Int32 nRows = 1;
180 if ( !mpViewShell || !mpTableInfo || nColumn < 0 || nRow < 0 ||
181 nColumn >= mpTableInfo->GetCols() || nRow >= mpTableInfo->GetRows() )
182 throw lang::IndexOutOfBoundsException();
184 const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
185 const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
187 if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
189 // header cells only span a single cell
191 else
193 ScDocument& rDoc = mpViewShell->GetDocument();
194 const ScMergeAttr* pItem = rDoc.GetAttr(
195 static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
196 if ( pItem && pItem->GetRowMerge() > 0 )
197 nRows = pItem->GetRowMerge();
200 return nRows;
203 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
205 SolarMutexGuard aGuard;
206 IsObjectValid();
208 FillTableInfo();
210 sal_Int32 nColumns = 1;
211 if ( !mpViewShell || !mpTableInfo || nColumn < 0 || nRow < 0 ||
212 nColumn >= mpTableInfo->GetCols() || nRow >= mpTableInfo->GetRows() )
213 throw lang::IndexOutOfBoundsException();
215 const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
216 const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
218 if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
220 // header cells only span a single cell
222 else
224 ScDocument& rDoc = mpViewShell->GetDocument();
225 const ScMergeAttr* pItem = rDoc.GetAttr(
226 static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
227 if ( pItem && pItem->GetColMerge() > 0 )
228 nColumns = pItem->GetColMerge();
231 return nColumns;
234 uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleRowHeaders()
236 //! missing
237 return nullptr;
240 uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnHeaders()
242 //! missing
243 return nullptr;
246 uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleRows()
248 // in the page preview, there is no selection
249 return uno::Sequence<sal_Int32>(0);
252 uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleColumns()
254 // in the page preview, there is no selection
255 return uno::Sequence<sal_Int32>(0);
258 sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleRowSelected( sal_Int32 nRow )
260 // in the page preview, there is no selection
262 SolarMutexGuard aGuard;
263 FillTableInfo();
264 if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
265 throw lang::IndexOutOfBoundsException();
267 return false;
270 sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleColumnSelected( sal_Int32 nColumn )
272 // in the page preview, there is no selection
274 SolarMutexGuard aGuard;
275 FillTableInfo();
276 if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
277 throw lang::IndexOutOfBoundsException();
279 return false;
282 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
284 SolarMutexGuard aGuard;
285 IsObjectValid();
287 FillTableInfo();
289 uno::Reference<XAccessible> xRet;
290 if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
292 // index iterates horizontally
293 tools::Long nNewIndex = nRow * mpTableInfo->GetCols() + nColumn;
295 const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
296 const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
298 ScAddress aCellPos( static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab() );
299 if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
301 const bool bRotatedColHeader = rRowInfo.bIsHeader;
302 const bool bRotatedRowHeader = rColInfo.bIsHeader;
303 rtl::Reference<ScAccessiblePreviewHeaderCell> pHeaderCell(new ScAccessiblePreviewHeaderCell(this, mpViewShell, aCellPos,
304 bRotatedColHeader, bRotatedRowHeader, nNewIndex));
305 xRet = pHeaderCell.get();
306 pHeaderCell->Init();
308 else
310 rtl::Reference<ScAccessiblePreviewCell> pCell(new ScAccessiblePreviewCell( this, mpViewShell, aCellPos, nNewIndex ));
311 xRet = pCell.get();
312 pCell->Init();
316 if ( !xRet.is() )
317 throw lang::IndexOutOfBoundsException();
319 return xRet;
322 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCaption()
324 //! missing
325 return nullptr;
328 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleSummary()
330 //! missing
331 return nullptr;
334 sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
336 // in the page preview, there is no selection
337 SolarMutexGuard aGuard;
338 IsObjectValid();
340 FillTableInfo();
342 if ( !mpTableInfo || nColumn < 0 || nRow < 0 || nColumn >= mpTableInfo->GetCols() || nRow >= mpTableInfo->GetRows() )
343 throw lang::IndexOutOfBoundsException();
345 // index iterates horizontally
346 return false;
349 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
351 SolarMutexGuard aGuard;
352 IsObjectValid();
354 FillTableInfo();
356 if ( !mpTableInfo || nColumn < 0 || nRow < 0 || nColumn >= mpTableInfo->GetCols() || nRow >= mpTableInfo->GetRows() )
357 throw lang::IndexOutOfBoundsException();
359 // index iterates horizontally
360 sal_Int32 nRet = nRow * mpTableInfo->GetCols() + nColumn;
361 return nRet;
364 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRow( sal_Int32 nChildIndex )
366 SolarMutexGuard aGuard;
367 IsObjectValid();
369 FillTableInfo();
371 if ( !mpTableInfo || nChildIndex < 0 || nChildIndex >= static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
372 throw lang::IndexOutOfBoundsException();
374 sal_Int32 nRow = nChildIndex / mpTableInfo->GetCols();
375 return nRow;
378 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumn( sal_Int32 nChildIndex )
380 SolarMutexGuard aGuard;
381 IsObjectValid();
383 FillTableInfo();
385 if ( !mpTableInfo || nChildIndex < 0 || nChildIndex >= static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
386 throw lang::IndexOutOfBoundsException();
388 sal_Int32 nCol = nChildIndex % static_cast<sal_Int32>(mpTableInfo->GetCols());
389 return nCol;
392 //===== XAccessibleComponent ============================================
394 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleAtPoint( const awt::Point& aPoint )
396 uno::Reference<XAccessible> xRet;
397 if (containsPoint(aPoint))
399 SolarMutexGuard aGuard;
400 IsObjectValid();
402 FillTableInfo();
404 if ( mpTableInfo )
406 SCCOL nCols = mpTableInfo->GetCols();
407 SCROW nRows = mpTableInfo->GetRows();
408 const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
409 const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
411 tools::Rectangle aScreenRect(GetBoundingBox());
413 awt::Point aMovedPoint = aPoint;
414 aMovedPoint.X += aScreenRect.Left();
415 aMovedPoint.Y += aScreenRect.Top();
417 if ( nCols > 0 && nRows > 0 && aMovedPoint.X >= pColInfo[0].nPixelStart && aMovedPoint.Y >= pRowInfo[0].nPixelStart )
419 SCCOL nColIndex = 0;
420 while ( nColIndex < nCols && aMovedPoint.X > pColInfo[nColIndex].nPixelEnd )
421 ++nColIndex;
422 SCROW nRowIndex = 0;
423 while ( nRowIndex < nRows && aMovedPoint.Y > pRowInfo[nRowIndex].nPixelEnd )
424 ++nRowIndex;
425 if ( nColIndex < nCols && nRowIndex < nRows )
429 xRet = getAccessibleCellAt( nRowIndex, nColIndex );
431 catch (uno::Exception&)
439 return xRet;
442 void SAL_CALL ScAccessiblePreviewTable::grabFocus()
444 SolarMutexGuard aGuard;
445 IsObjectValid();
446 if (getAccessibleParent().is())
448 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
449 if (xAccessibleComponent.is())
450 xAccessibleComponent->grabFocus();
454 //===== XAccessibleContext ==============================================
456 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleChildCount()
458 SolarMutexGuard aGuard;
459 IsObjectValid();
461 FillTableInfo();
463 tools::Long nRet = 0;
464 if ( mpTableInfo )
465 nRet = static_cast<sal_Int32>(mpTableInfo->GetCols()) * mpTableInfo->GetRows();
466 return nRet;
469 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleChild( sal_Int32 nIndex )
471 SolarMutexGuard aGuard;
472 IsObjectValid();
474 FillTableInfo();
476 uno::Reference<XAccessible> xRet;
477 if ( mpTableInfo )
479 sal_Int32 nColumns = mpTableInfo->GetCols();
480 if ( nColumns > 0 )
482 // nCol, nRow are within the visible table, not the document
483 sal_Int32 nCol = nIndex % nColumns;
484 sal_Int32 nRow = nIndex / nColumns;
486 xRet = getAccessibleCellAt( nRow, nCol );
490 if ( !xRet.is() )
491 throw lang::IndexOutOfBoundsException();
493 return xRet;
496 sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndexInParent()
498 return mnIndex;
501 uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePreviewTable::getAccessibleStateSet()
503 SolarMutexGuard aGuard;
504 uno::Reference<XAccessibleStateSet> xParentStates;
505 if (getAccessibleParent().is())
507 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
508 xParentStates = xParentContext->getAccessibleStateSet();
510 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
511 if (IsDefunc(xParentStates))
512 pStateSet->AddState(AccessibleStateType::DEFUNC);
513 else
515 pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
516 pStateSet->AddState(AccessibleStateType::ENABLED);
517 pStateSet->AddState(AccessibleStateType::OPAQUE);
518 if (isShowing())
519 pStateSet->AddState(AccessibleStateType::SHOWING);
520 if (isVisible())
521 pStateSet->AddState(AccessibleStateType::VISIBLE);
523 return pStateSet;
526 //===== XServiceInfo ====================================================
528 OUString SAL_CALL ScAccessiblePreviewTable::getImplementationName()
530 return "ScAccessiblePreviewTable";
533 uno::Sequence<OUString> SAL_CALL ScAccessiblePreviewTable::getSupportedServiceNames()
535 uno::Sequence< OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
536 sal_Int32 nOldSize(aSequence.getLength());
537 aSequence.realloc(nOldSize + 1);
539 aSequence[nOldSize] = "com.sun.star.table.AccessibleTableView";
541 return aSequence;
544 //===== XTypeProvider ===================================================
546 uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewTable::getTypes()
548 return comphelper::concatSequences(ScAccessiblePreviewTableImpl::getTypes(), ScAccessibleContextBase::getTypes());
551 uno::Sequence<sal_Int8> SAL_CALL ScAccessiblePreviewTable::getImplementationId()
553 return css::uno::Sequence<sal_Int8>();
556 //==== internal =========================================================
558 OUString ScAccessiblePreviewTable::createAccessibleDescription()
560 return STR_ACC_TABLE_DESCR;
563 OUString ScAccessiblePreviewTable::createAccessibleName()
565 OUString sName(ScResId(STR_ACC_TABLE_NAME));
567 if (mpViewShell)
569 FillTableInfo();
571 if ( mpTableInfo )
573 OUString sCoreName;
574 if (mpViewShell->GetDocument().GetName( mpTableInfo->GetTab(), sCoreName ))
575 sName = sName.replaceFirst("%1", sCoreName);
579 return sName;
582 tools::Rectangle ScAccessiblePreviewTable::GetBoundingBoxOnScreen() const
584 tools::Rectangle aCellRect(GetBoundingBox());
585 if (mpViewShell)
587 vcl::Window* pWindow = mpViewShell->GetWindow();
588 if (pWindow)
590 tools::Rectangle aRect = pWindow->GetWindowExtentsRelative(nullptr);
591 aCellRect.setX(aCellRect.getX() + aRect.getX());
592 aCellRect.setY(aCellRect.getY() + aRect.getY());
595 return aCellRect;
598 tools::Rectangle ScAccessiblePreviewTable::GetBoundingBox() const
600 FillTableInfo();
602 tools::Rectangle aRect;
603 if ( mpTableInfo )
605 SCCOL nColumns = mpTableInfo->GetCols();
606 SCROW nRows = mpTableInfo->GetRows();
607 if ( nColumns > 0 && nRows > 0 )
609 const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
610 const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
612 aRect = tools::Rectangle( pColInfo[0].nPixelStart,
613 pRowInfo[0].nPixelStart,
614 pColInfo[nColumns-1].nPixelEnd,
615 pRowInfo[nRows-1].nPixelEnd );
618 return aRect;
621 bool ScAccessiblePreviewTable::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
623 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == nullptr) || !getAccessibleParent().is() ||
624 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
627 void ScAccessiblePreviewTable::FillTableInfo() const
629 if ( mpViewShell && !mpTableInfo )
631 Size aOutputSize;
632 vcl::Window* pWindow = mpViewShell->GetWindow();
633 if ( pWindow )
634 aOutputSize = pWindow->GetOutputSizePixel();
635 tools::Rectangle aVisRect( Point(), aOutputSize );
637 mpTableInfo.reset( new ScPreviewTableInfo );
638 mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
642 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */