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 <sal/log.hxx>
24 #include <com/sun/star/accessibility/AccessibleRole.hpp>
25 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
26 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
27 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
28 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
29 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30 #include <o3tl/safeint.hxx>
31 #include <vcl/svapp.hxx>
34 #include <cellfrm.hxx>
35 #include <swtable.hxx>
38 #include "accfrmobjslist.hxx"
40 #include <strings.hrc>
41 #include "acctable.hxx"
43 #include <com/sun/star/accessibility/XAccessibleText.hpp>
45 #include <editeng/brushitem.hxx>
46 #include <swatrset.hxx>
49 #include <cppuhelper/supportsservice.hxx>
50 #include <cppuhelper/typeprovider.hxx>
52 using namespace ::com::sun::star
;
53 using namespace ::com::sun::star::accessibility
;
54 using namespace ::sw::access
;
56 typedef o3tl::sorted_vector
< sal_Int32
> Int32Set_Impl
;
58 const unsigned int SELECTION_WITH_NUM
= 10;
62 class SwAccTableSelHandler_Impl
65 virtual void Unselect( sal_Int32 nRowOrCol
, sal_Int32 nExt
) = 0;
68 ~SwAccTableSelHandler_Impl() {}
73 class SwAccessibleTableData_Impl
75 SwAccessibleMap
& mrAccMap
;
77 Int32Set_Impl maColumns
;
79 const SwTabFrame
*mpTabFrame
;
80 bool mbIsInPagePreview
;
81 bool mbOnlyTableColumnHeader
;
83 void CollectData( const SwFrame
*pFrame
);
85 bool FindCell( const Point
& rPos
, const SwFrame
*pFrame
,
86 bool bExact
, const SwFrame
*& rFrame
) const;
88 void GetSelection( const Point
& rTabPos
, const SwRect
& rArea
,
89 const SwSelBoxes
& rSelBoxes
, const SwFrame
*pFrame
,
90 SwAccTableSelHandler_Impl
& rSelHdl
,
91 bool bColumns
) const;
94 bool IncludeRow( const SwFrame
& rFrame
) const
96 return !mbOnlyTableColumnHeader
||
97 mpTabFrame
->IsInHeadline( rFrame
);
100 // #i77106# - add third optional parameter <bOnlyTableColumnHeader>, default value <false>
101 SwAccessibleTableData_Impl( SwAccessibleMap
& rAccMap
,
102 const SwTabFrame
*pTabFrame
,
103 bool bIsInPagePreview
,
104 bool bOnlyTableColumnHeader
= false );
106 const Int32Set_Impl
& GetRows() const { return maRows
; }
107 const Int32Set_Impl
& GetColumns() const { return maColumns
; }
109 inline Int32Set_Impl::const_iterator
GetRowIter( sal_Int32 nRow
) const;
110 inline Int32Set_Impl::const_iterator
GetColumnIter( sal_Int32 nCol
) const;
112 /// @throws lang::IndexOutOfBoundsException
113 /// @throws uno::RuntimeException
114 const SwFrame
*GetCell( sal_Int32 nRow
, sal_Int32 nColumn
, SwAccessibleTable
*pThis
) const;
115 const SwFrame
*GetCellAtPos( sal_Int32 nLeft
, sal_Int32 nTop
) const;
116 inline sal_Int32
GetRowCount() const;
117 inline sal_Int32
GetColumnCount() const;
118 bool CompareExtents( const SwAccessibleTableData_Impl
& r
) const;
120 void GetSelection( sal_Int32 nStart
, sal_Int32 nEnd
,
121 const SwSelBoxes
& rSelBoxes
,
122 SwAccTableSelHandler_Impl
& rSelHdl
,
123 bool bColumns
) const;
125 /// @throws lang::IndexOutOfBoundsException
126 void CheckRowAndCol( sal_Int32 nRow
, sal_Int32 nCol
,
127 SwAccessibleTable
*pThis
) const;
129 const Point
& GetTablePos() const { return maTabFramePos
; }
130 void SetTablePos( const Point
& rPos
) { maTabFramePos
= rPos
; }
133 void SwAccessibleTableData_Impl::CollectData( const SwFrame
*pFrame
)
135 const SwAccessibleChildSList
aList( *pFrame
, mrAccMap
);
136 SwAccessibleChildSList::const_iterator
aIter( aList
.begin() );
137 SwAccessibleChildSList::const_iterator
aEndIter( aList
.end() );
138 while( aIter
!= aEndIter
)
140 const SwAccessibleChild
& rLower
= *aIter
;
141 const SwFrame
*pLower
= rLower
.GetSwFrame();
144 if( pLower
->IsRowFrame() )
147 if ( IncludeRow( *pLower
) )
149 maRows
.insert( pLower
->getFrameArea().Top() - maTabFramePos
.getY() );
150 CollectData( pLower
);
153 else if( pLower
->IsCellFrame() &&
154 rLower
.IsAccessible( mbIsInPagePreview
) )
156 maColumns
.insert( pLower
->getFrameArea().Left() - maTabFramePos
.getX() );
160 CollectData( pLower
);
167 bool SwAccessibleTableData_Impl::FindCell(
168 const Point
& rPos
, const SwFrame
*pFrame
, bool bExact
,
169 const SwFrame
*& rRet
) const
173 const SwAccessibleChildSList
aList( *pFrame
, mrAccMap
);
174 SwAccessibleChildSList::const_iterator
aIter( aList
.begin() );
175 SwAccessibleChildSList::const_iterator
aEndIter( aList
.end() );
176 while( !bFound
&& aIter
!= aEndIter
)
178 const SwAccessibleChild
& rLower
= *aIter
;
179 const SwFrame
*pLower
= rLower
.GetSwFrame();
180 OSL_ENSURE( pLower
, "child should be a frame" );
183 if( rLower
.IsAccessible( mbIsInPagePreview
) )
185 OSL_ENSURE( pLower
->IsCellFrame(), "lower is not a cell frame" );
186 const SwRect
& rFrame
= pLower
->getFrameArea();
187 if( rFrame
.Right() >= rPos
.X() && rFrame
.Bottom() >= rPos
.Y() )
189 // We have found the cell
190 OSL_ENSURE( rFrame
.Left() <= rPos
.X() && rFrame
.Top() <= rPos
.Y(),
191 "find frame moved to far!" );
194 (rFrame
.Top() == rPos
.Y() && rFrame
.Left() == rPos
.Y() ) )
203 if ( !pLower
->IsRowFrame() ||
204 IncludeRow( *pLower
) )
206 bFound
= FindCell( rPos
, pLower
, bExact
, rRet
);
216 void SwAccessibleTableData_Impl::GetSelection(
217 const Point
& rTabPos
,
219 const SwSelBoxes
& rSelBoxes
,
220 const SwFrame
*pFrame
,
221 SwAccTableSelHandler_Impl
& rSelHdl
,
222 bool bColumns
) const
224 const SwAccessibleChildSList
aList( *pFrame
, mrAccMap
);
225 SwAccessibleChildSList::const_iterator
aIter( aList
.begin() );
226 SwAccessibleChildSList::const_iterator
aEndIter( aList
.end() );
227 while( aIter
!= aEndIter
)
229 const SwAccessibleChild
& rLower
= *aIter
;
230 const SwFrame
*pLower
= rLower
.GetSwFrame();
231 OSL_ENSURE( pLower
, "child should be a frame" );
232 const SwRect aBox
= rLower
.GetBox( mrAccMap
);
233 if( pLower
&& aBox
.Overlaps( rArea
) )
235 if( rLower
.IsAccessible( mbIsInPagePreview
) )
237 OSL_ENSURE( pLower
->IsCellFrame(), "lower is not a cell frame" );
238 const SwCellFrame
*pCFrame
=
239 static_cast < const SwCellFrame
* >( pLower
);
241 const_cast< SwTableBox
*>( pCFrame
->GetTabBox() );
242 if( rSelBoxes
.find( pBox
) == rSelBoxes
.end() )
244 const Int32Set_Impl rRowsOrCols
=
245 bColumns
? maColumns
: maRows
;
247 sal_Int32 nPos
= bColumns
? (aBox
.Left() - rTabPos
.X())
248 : (aBox
.Top() - rTabPos
.Y());
249 Int32Set_Impl::const_iterator
aSttRowOrCol(
250 rRowsOrCols
.lower_bound( nPos
) );
251 sal_Int32 nRowOrCol
=
252 static_cast< sal_Int32
>( std::distance(
253 rRowsOrCols
.begin(), aSttRowOrCol
) );
255 nPos
= bColumns
? (aBox
.Right() - rTabPos
.X())
256 : (aBox
.Bottom() - rTabPos
.Y());
257 Int32Set_Impl::const_iterator
aEndRowOrCol(
258 rRowsOrCols
.upper_bound( nPos
) );
260 static_cast< sal_Int32
>( std::distance(
261 aSttRowOrCol
, aEndRowOrCol
) );
263 rSelHdl
.Unselect( nRowOrCol
, nExt
);
269 if ( !pLower
->IsRowFrame() ||
270 IncludeRow( *pLower
) )
272 GetSelection( rTabPos
, rArea
, rSelBoxes
, pLower
, rSelHdl
,
281 const SwFrame
*SwAccessibleTableData_Impl::GetCell(
282 sal_Int32 nRow
, sal_Int32 nColumn
,
283 SwAccessibleTable
*pThis
) const
285 CheckRowAndCol( nRow
, nColumn
, pThis
);
287 Int32Set_Impl::const_iterator
aSttCol( GetColumnIter( nColumn
) );
288 Int32Set_Impl::const_iterator
aSttRow( GetRowIter( nRow
) );
289 const SwFrame
*pCellFrame
= GetCellAtPos( *aSttCol
, *aSttRow
);
294 void SwAccessibleTableData_Impl::GetSelection(
295 sal_Int32 nStart
, sal_Int32 nEnd
,
296 const SwSelBoxes
& rSelBoxes
,
297 SwAccTableSelHandler_Impl
& rSelHdl
,
298 bool bColumns
) const
300 SwRect
aArea( mpTabFrame
->getFrameArea() );
301 Point
aPos( aArea
.Pos() );
303 const Int32Set_Impl
& rRowsOrColumns
= bColumns
? maColumns
: maRows
;
306 Int32Set_Impl::const_iterator
aStt( rRowsOrColumns
.begin() );
308 static_cast< Int32Set_Impl::difference_type
>( nStart
) );
310 aArea
.Left( *aStt
+ aPos
.getX() );
312 aArea
.Top( *aStt
+ aPos
.getY() );
314 if( nEnd
< static_cast< sal_Int32
>( rRowsOrColumns
.size() ) )
316 Int32Set_Impl::const_iterator
aEnd( rRowsOrColumns
.begin() );
318 static_cast< Int32Set_Impl::difference_type
>( nEnd
) );
320 aArea
.Right( *aEnd
+ aPos
.getX() - 1 );
322 aArea
.Bottom( *aEnd
+ aPos
.getY() - 1 );
325 GetSelection( aPos
, aArea
, rSelBoxes
, mpTabFrame
, rSelHdl
, bColumns
);
328 const SwFrame
*SwAccessibleTableData_Impl::GetCellAtPos(
329 sal_Int32 nLeft
, sal_Int32 nTop
) const
331 Point
aPos( mpTabFrame
->getFrameArea().Pos() );
332 aPos
.Move( nLeft
, nTop
);
333 const SwFrame
*pRet
= nullptr;
334 FindCell( aPos
, mpTabFrame
, false/*bExact*/, pRet
);
339 inline sal_Int32
SwAccessibleTableData_Impl::GetRowCount() const
341 sal_Int32 count
= static_cast< sal_Int32
>( maRows
.size() ) ;
342 count
= (count
<=0)? 1:count
;
346 inline sal_Int32
SwAccessibleTableData_Impl::GetColumnCount() const
348 return static_cast< sal_Int32
>( maColumns
.size() );
351 bool SwAccessibleTableData_Impl::CompareExtents(
352 const SwAccessibleTableData_Impl
& rCmp
) const
354 return maRows
== rCmp
.maRows
355 && maColumns
== rCmp
.maColumns
;
358 SwAccessibleTableData_Impl::SwAccessibleTableData_Impl( SwAccessibleMap
& rAccMap
,
359 const SwTabFrame
*pTabFrame
,
360 bool bIsInPagePreview
,
361 bool bOnlyTableColumnHeader
)
362 : mrAccMap( rAccMap
)
363 , maTabFramePos( pTabFrame
->getFrameArea().Pos() )
364 , mpTabFrame( pTabFrame
)
365 , mbIsInPagePreview( bIsInPagePreview
)
366 , mbOnlyTableColumnHeader( bOnlyTableColumnHeader
)
368 CollectData( mpTabFrame
);
371 inline Int32Set_Impl::const_iterator
SwAccessibleTableData_Impl::GetRowIter(
372 sal_Int32 nRow
) const
374 Int32Set_Impl::const_iterator
aCol( GetRows().begin() );
378 static_cast< Int32Set_Impl::difference_type
>( nRow
) );
383 inline Int32Set_Impl::const_iterator
SwAccessibleTableData_Impl::GetColumnIter(
384 sal_Int32 nColumn
) const
386 Int32Set_Impl::const_iterator aCol
= GetColumns().begin();
390 static_cast< Int32Set_Impl::difference_type
>( nColumn
) );
395 void SwAccessibleTableData_Impl::CheckRowAndCol(
396 sal_Int32 nRow
, sal_Int32 nCol
, SwAccessibleTable
*pThis
) const
398 if( ( nRow
< 0 || o3tl::make_unsigned(nRow
) >= maRows
.size() ) ||
399 ( nCol
< 0 || o3tl::make_unsigned(nCol
) >= maColumns
.size() ) )
401 uno::Reference
< XAccessibleTable
> xThis( pThis
);
402 lang::IndexOutOfBoundsException
aExcept(
403 u
"row or column index out of range"_ustr
,
411 class SwAccSingleTableSelHandler_Impl
: public SwAccTableSelHandler_Impl
417 inline SwAccSingleTableSelHandler_Impl();
419 virtual ~SwAccSingleTableSelHandler_Impl() {}
421 bool IsSelected() const { return m_bSelected
; }
423 virtual void Unselect( sal_Int32
, sal_Int32
) override
;
428 inline SwAccSingleTableSelHandler_Impl::SwAccSingleTableSelHandler_Impl() :
433 void SwAccSingleTableSelHandler_Impl::Unselect( sal_Int32
, sal_Int32
)
440 class SwAccAllTableSelHandler_Impl
: public SwAccTableSelHandler_Impl
443 std::vector
< bool > m_aSelected
;
447 explicit SwAccAllTableSelHandler_Impl(sal_Int32 nSize
)
448 : m_aSelected(nSize
, true)
453 uno::Sequence
< sal_Int32
> GetSelSequence();
455 virtual void Unselect( sal_Int32 nRowOrCol
, sal_Int32 nExt
) override
;
456 virtual ~SwAccAllTableSelHandler_Impl();
461 SwAccAllTableSelHandler_Impl::~SwAccAllTableSelHandler_Impl()
465 uno::Sequence
< sal_Int32
> SwAccAllTableSelHandler_Impl::GetSelSequence()
467 OSL_ENSURE( m_nCount
>= 0, "underflow" );
468 uno::Sequence
< sal_Int32
> aRet( m_nCount
);
469 sal_Int32
*pRet
= aRet
.getArray();
471 size_t nSize
= m_aSelected
.size();
472 for( size_t i
=0; i
< nSize
&& nPos
< m_nCount
; i
++ )
481 OSL_ENSURE( nPos
== m_nCount
, "count is wrong" );
486 void SwAccAllTableSelHandler_Impl::Unselect( sal_Int32 nRowOrCol
,
489 OSL_ENSURE( o3tl::make_unsigned( nRowOrCol
) < m_aSelected
.size(),
491 OSL_ENSURE( o3tl::make_unsigned( nRowOrCol
+nExt
) <= m_aSelected
.size(),
492 "extent too large" );
495 if( m_aSelected
[static_cast< size_t >( nRowOrCol
)] )
497 m_aSelected
[static_cast< size_t >( nRowOrCol
)] = false;
505 const SwSelBoxes
*SwAccessibleTable::GetSelBoxes() const
507 const SwSelBoxes
*pSelBoxes
= nullptr;
508 const SwCursorShell
*pCSh
= GetCursorShell();
509 if( (pCSh
!= nullptr) && pCSh
->IsTableMode() )
511 pSelBoxes
= &pCSh
->GetTableCursor()->GetSelectedBoxes();
517 void SwAccessibleTable::FireTableChangeEvent(
518 const SwAccessibleTableData_Impl
& rTableData
)
520 AccessibleTableModelChange aModelChange
;
521 aModelChange
.Type
= AccessibleTableModelChangeType::UPDATE
;
522 aModelChange
.FirstRow
= 0;
523 aModelChange
.LastRow
= rTableData
.GetRowCount() - 1;
524 aModelChange
.FirstColumn
= 0;
525 aModelChange
.LastColumn
= rTableData
.GetColumnCount() - 1;
527 AccessibleEventObject aEvent
;
528 aEvent
.EventId
= AccessibleEventId::TABLE_MODEL_CHANGED
;
529 aEvent
.NewValue
<<= aModelChange
;
531 FireAccessibleEvent( aEvent
);
534 const SwTableBox
* SwAccessibleTable::GetTableBox( sal_Int64 nChildIndex
) const
536 OSL_ENSURE( nChildIndex
>= 0, "Illegal child index." );
537 OSL_ENSURE( nChildIndex
< const_cast<SwAccessibleTable
*>(this)->getAccessibleChildCount(), "Illegal child index." ); // #i77106#
539 const SwTableBox
* pBox
= nullptr;
541 // get table box for 'our' table cell
542 SwAccessibleChild
aCell( GetChild( *const_cast<SwAccessibleMap
*>(GetMap()), nChildIndex
) );
543 if( aCell
.GetSwFrame() )
545 const SwFrame
* pChildFrame
= aCell
.GetSwFrame();
546 if( (pChildFrame
!= nullptr) && pChildFrame
->IsCellFrame() )
548 const SwCellFrame
* pCellFrame
=
549 static_cast<const SwCellFrame
*>( pChildFrame
);
550 pBox
= pCellFrame
->GetTabBox();
554 OSL_ENSURE( pBox
!= nullptr, "We need the table box." );
558 bool SwAccessibleTable::IsChildSelected( sal_Int64 nChildIndex
) const
561 const SwSelBoxes
* pSelBoxes
= GetSelBoxes();
564 const SwTableBox
* pBox
= GetTableBox( nChildIndex
);
565 OSL_ENSURE( pBox
!= nullptr, "We need the table box." );
566 bRet
= pSelBoxes
->find( const_cast<SwTableBox
*>( pBox
) ) != pSelBoxes
->end();
572 sal_Int64
SwAccessibleTable::GetIndexOfSelectedChild(
573 sal_Int64 nSelectedChildIndex
) const
575 // iterate over all children to n-th isAccessibleChildSelected()
576 sal_Int64 nChildren
= const_cast<SwAccessibleTable
*>(this)->getAccessibleChildCount(); // #i77106#
577 if( nSelectedChildIndex
>= nChildren
)
581 while( n
< nChildren
)
583 if( IsChildSelected( n
) )
585 if( 0 == nSelectedChildIndex
)
588 --nSelectedChildIndex
;
593 return n
< nChildren
? n
: -1;
596 void SwAccessibleTable::GetStates( sal_Int64
& rStateSet
)
598 SwAccessibleContext::GetStates( rStateSet
);
599 //Add resizable state to table
600 rStateSet
|= AccessibleStateType::RESIZABLE
;
602 rStateSet
|= AccessibleStateType::MULTI_SELECTABLE
;
603 SwCursorShell
* pCursorShell
= GetCursorShell();
605 rStateSet
|= AccessibleStateType::MULTI_SELECTABLE
;
608 SwAccessibleTable::SwAccessibleTable(
609 std::shared_ptr
<SwAccessibleMap
> const& pInitMap
,
610 const SwTabFrame
* pTabFrame
) :
611 SwAccessibleTable_BASE( pInitMap
, AccessibleRole::TABLE
, pTabFrame
)
613 const SwFrameFormat
* pFrameFormat
= pTabFrame
->GetFormat();
614 StartListening(const_cast<SwFrameFormat
*>(pFrameFormat
)->GetNotifier());
615 SetName( pFrameFormat
->GetName() + "-" + OUString::number( pTabFrame
->GetPhyPageNum() ) );
617 const OUString
sArg1( static_cast< const SwTabFrame
* >( GetFrame() )->GetFormat()->GetName() );
618 const OUString
sArg2( GetFormattedPageNumber() );
620 m_sDesc
= GetResource( STR_ACCESS_TABLE_DESC
, &sArg1
, &sArg2
);
624 SwAccessibleTable::~SwAccessibleTable()
626 SolarMutexGuard aGuard
;
631 void SwAccessibleTable::Notify(const SfxHint
& rHint
)
633 const SwTabFrame
* pTabFrame
= static_cast<const SwTabFrame
*>(GetFrame());
634 if(rHint
.GetId() == SfxHintId::Dying
)
638 else if (rHint
.GetId() == SfxHintId::SwNameChanged
&& pTabFrame
)
640 const SwFrameFormat
*pFrameFormat
= pTabFrame
->GetFormat();
641 const OUString
sOldName( GetName() );
642 const OUString sNewTabName
= pFrameFormat
->GetName();
644 SetName( sNewTabName
+ "-" + OUString::number( pTabFrame
->GetPhyPageNum() ) );
646 if( sOldName
!= GetName() )
648 AccessibleEventObject aEvent
;
649 aEvent
.EventId
= AccessibleEventId::NAME_CHANGED
;
650 aEvent
.OldValue
<<= sOldName
;
651 aEvent
.NewValue
<<= GetName();
652 FireAccessibleEvent( aEvent
);
655 const OUString
sOldDesc( m_sDesc
);
656 const OUString
sArg2( GetFormattedPageNumber() );
658 m_sDesc
= GetResource( STR_ACCESS_TABLE_DESC
, &sNewTabName
, &sArg2
);
659 if( m_sDesc
!= sOldDesc
)
661 AccessibleEventObject aEvent
;
662 aEvent
.EventId
= AccessibleEventId::DESCRIPTION_CHANGED
;
663 aEvent
.OldValue
<<= sOldDesc
;
664 aEvent
.NewValue
<<= m_sDesc
;
665 FireAccessibleEvent( aEvent
);
671 std::unique_ptr
<SwAccessibleTableData_Impl
> SwAccessibleTable::CreateNewTableData()
673 const SwTabFrame
* pTabFrame
= static_cast<const SwTabFrame
*>( GetFrame() );
674 return std::unique_ptr
<SwAccessibleTableData_Impl
>(new SwAccessibleTableData_Impl( *GetMap(), pTabFrame
, IsInPagePreview() ));
677 void SwAccessibleTable::UpdateTableData()
679 // #i77106# - usage of new method <CreateNewTableData()>
680 mpTableData
= CreateNewTableData();
683 void SwAccessibleTable::ClearTableData()
688 OUString SAL_CALL
SwAccessibleTable::getAccessibleDescription()
690 SolarMutexGuard aGuard
;
697 sal_Int32 SAL_CALL
SwAccessibleTable::getAccessibleRowCount()
699 SolarMutexGuard aGuard
;
703 return GetTableData().GetRowCount();
706 sal_Int32 SAL_CALL
SwAccessibleTable::getAccessibleColumnCount( )
708 SolarMutexGuard aGuard
;
712 return GetTableData().GetColumnCount();
715 OUString SAL_CALL
SwAccessibleTable::getAccessibleRowDescription(
718 // #i87532# - determine table cell in <nRow>th row and
719 // in first column of row header table and return its text content.
722 GetTableData().CheckRowAndCol(nRow
, 0, this);
724 uno::Reference
< XAccessibleTable
> xTableRowHeader
= getAccessibleRowHeaders();
725 if ( xTableRowHeader
.is() )
727 uno::Reference
< XAccessible
> xRowHeaderCell
=
728 xTableRowHeader
->getAccessibleCellAt( nRow
, 0 );
729 OSL_ENSURE( xRowHeaderCell
.is(),
730 "<SwAccessibleTable::getAccessibleRowDescription(..)> - missing row header cell -> serious issue." );
731 uno::Reference
< XAccessibleContext
> xRowHeaderCellContext
=
732 xRowHeaderCell
->getAccessibleContext();
733 const sal_Int64
nCellChildCount( xRowHeaderCellContext
->getAccessibleChildCount() );
734 for ( sal_Int64 nChildIndex
= 0; nChildIndex
< nCellChildCount
; ++nChildIndex
)
736 uno::Reference
< XAccessible
> xChild
= xRowHeaderCellContext
->getAccessibleChild( nChildIndex
);
737 uno::Reference
< XAccessibleText
> xChildText( xChild
, uno::UNO_QUERY
);
738 if ( xChildText
.is() )
740 sRowDesc
+= xChildText
->getText();
748 OUString SAL_CALL
SwAccessibleTable::getAccessibleColumnDescription(
751 // #i87532# - determine table cell in first row and
752 // in <nColumn>th column of column header table and return its text content.
753 OUString sColumnDesc
;
755 GetTableData().CheckRowAndCol(0, nColumn
, this);
757 uno::Reference
< XAccessibleTable
> xTableColumnHeader
= getAccessibleColumnHeaders();
758 if ( xTableColumnHeader
.is() )
760 uno::Reference
< XAccessible
> xColumnHeaderCell
=
761 xTableColumnHeader
->getAccessibleCellAt( 0, nColumn
);
762 OSL_ENSURE( xColumnHeaderCell
.is(),
763 "<SwAccessibleTable::getAccessibleColumnDescription(..)> - missing column header cell -> serious issue." );
764 uno::Reference
< XAccessibleContext
> xColumnHeaderCellContext
=
765 xColumnHeaderCell
->getAccessibleContext();
766 const sal_Int64
nCellChildCount( xColumnHeaderCellContext
->getAccessibleChildCount() );
767 for ( sal_Int64 nChildIndex
= 0; nChildIndex
< nCellChildCount
; ++nChildIndex
)
769 uno::Reference
< XAccessible
> xChild
= xColumnHeaderCellContext
->getAccessibleChild( nChildIndex
);
770 uno::Reference
< XAccessibleText
> xChildText( xChild
, uno::UNO_QUERY
);
771 if ( xChildText
.is() )
773 sColumnDesc
+= xChildText
->getText();
781 sal_Int32 SAL_CALL
SwAccessibleTable::getAccessibleRowExtentAt(
782 sal_Int32 nRow
, sal_Int32 nColumn
)
784 sal_Int32 nExtend
= -1;
786 SolarMutexGuard aGuard
;
791 GetTableData().CheckRowAndCol( nRow
, nColumn
, this );
793 Int32Set_Impl::const_iterator
aSttCol(
794 GetTableData().GetColumnIter( nColumn
) );
795 Int32Set_Impl::const_iterator
aSttRow(
796 GetTableData().GetRowIter( nRow
) );
797 const SwFrame
*pCellFrame
= GetTableData().GetCellAtPos( *aSttCol
, *aSttRow
);
800 sal_Int32 nBottom
= pCellFrame
->getFrameArea().Bottom();
801 nBottom
-= GetFrame()->getFrameArea().Top();
802 Int32Set_Impl::const_iterator
aEndRow(
803 GetTableData().GetRows().upper_bound( nBottom
) );
805 static_cast< sal_Int32
>( std::distance( aSttRow
, aEndRow
) );
811 sal_Int32 SAL_CALL
SwAccessibleTable::getAccessibleColumnExtentAt(
812 sal_Int32 nRow
, sal_Int32 nColumn
)
814 sal_Int32 nExtend
= -1;
816 SolarMutexGuard aGuard
;
821 GetTableData().CheckRowAndCol( nRow
, nColumn
, this );
823 Int32Set_Impl::const_iterator
aSttCol(
824 GetTableData().GetColumnIter( nColumn
) );
825 Int32Set_Impl::const_iterator
aSttRow(
826 GetTableData().GetRowIter( nRow
) );
827 const SwFrame
*pCellFrame
= GetTableData().GetCellAtPos( *aSttCol
, *aSttRow
);
830 sal_Int32 nRight
= pCellFrame
->getFrameArea().Right();
831 nRight
-= GetFrame()->getFrameArea().Left();
832 Int32Set_Impl::const_iterator
aEndCol(
833 GetTableData().GetColumns().upper_bound( nRight
) );
835 static_cast< sal_Int32
>( std::distance( aSttCol
, aEndCol
) );
841 uno::Reference
< XAccessibleTable
> SAL_CALL
842 SwAccessibleTable::getAccessibleRowHeaders( )
844 // Row headers aren't supported
845 return uno::Reference
< XAccessibleTable
>();
848 uno::Reference
< XAccessibleTable
> SAL_CALL
849 SwAccessibleTable::getAccessibleColumnHeaders( )
851 SolarMutexGuard aGuard
;
853 // #i87532# - assure that return accessible object is empty,
854 // if no column header exists.
855 rtl::Reference
<SwAccessibleTableColHeaders
> pTableColHeaders
=
856 new SwAccessibleTableColHeaders(GetMap()->shared_from_this(),
857 static_cast<const SwTabFrame
*>(GetFrame()));
858 if ( pTableColHeaders
->getAccessibleChildCount() <= 0 )
860 return uno::Reference
< XAccessibleTable
>();
863 return pTableColHeaders
;
866 uno::Sequence
< sal_Int32
> SAL_CALL
SwAccessibleTable::getSelectedAccessibleRows()
868 SolarMutexGuard aGuard
;
872 const SwSelBoxes
*pSelBoxes
= GetSelBoxes();
875 sal_Int32 nRows
= GetTableData().GetRowCount();
876 SwAccAllTableSelHandler_Impl
aSelRows( nRows
);
878 GetTableData().GetSelection( 0, nRows
, *pSelBoxes
, aSelRows
,
881 return aSelRows
.GetSelSequence();
885 return uno::Sequence
< sal_Int32
>( 0 );
889 uno::Sequence
< sal_Int32
> SAL_CALL
SwAccessibleTable::getSelectedAccessibleColumns()
891 SolarMutexGuard aGuard
;
895 const SwSelBoxes
*pSelBoxes
= GetSelBoxes();
898 sal_Int32 nCols
= GetTableData().GetColumnCount();
899 SwAccAllTableSelHandler_Impl
aSelCols( nCols
);
901 GetTableData().GetSelection( 0, nCols
, *pSelBoxes
, aSelCols
, true );
903 return aSelCols
.GetSelSequence();
907 return uno::Sequence
< sal_Int32
>( 0 );
911 sal_Bool SAL_CALL
SwAccessibleTable::isAccessibleRowSelected( sal_Int32 nRow
)
913 SolarMutexGuard aGuard
;
917 GetTableData().CheckRowAndCol( nRow
, 0, this );
920 const SwSelBoxes
*pSelBoxes
= GetSelBoxes();
923 SwAccSingleTableSelHandler_Impl aSelRow
;
924 GetTableData().GetSelection( nRow
, nRow
+1, *pSelBoxes
, aSelRow
,
926 bRet
= aSelRow
.IsSelected();
936 sal_Bool SAL_CALL
SwAccessibleTable::isAccessibleColumnSelected(
939 SolarMutexGuard aGuard
;
943 GetTableData().CheckRowAndCol( 0, nColumn
, this );
946 const SwSelBoxes
*pSelBoxes
= GetSelBoxes();
949 SwAccSingleTableSelHandler_Impl aSelCol
;
951 GetTableData().GetSelection( nColumn
, nColumn
+1, *pSelBoxes
, aSelCol
,
953 bRet
= aSelCol
.IsSelected();
963 uno::Reference
< XAccessible
> SAL_CALL
SwAccessibleTable::getAccessibleCellAt(
964 sal_Int32 nRow
, sal_Int32 nColumn
)
966 uno::Reference
< XAccessible
> xRet
;
968 SolarMutexGuard aGuard
;
972 const SwFrame
*pCellFrame
=
973 GetTableData().GetCell( nRow
, nColumn
, this );
975 xRet
= GetMap()->GetContext( pCellFrame
);
980 uno::Reference
< XAccessible
> SAL_CALL
SwAccessibleTable::getAccessibleCaption()
982 // captions aren't supported
983 return uno::Reference
< XAccessible
>();
986 uno::Reference
< XAccessible
> SAL_CALL
SwAccessibleTable::getAccessibleSummary()
988 // summaries aren't supported
989 return uno::Reference
< XAccessible
>();
992 sal_Bool SAL_CALL
SwAccessibleTable::isAccessibleSelected(
993 sal_Int32 nRow
, sal_Int32 nColumn
)
997 SolarMutexGuard aGuard
;
1001 const SwFrame
*pFrame
=
1002 GetTableData().GetCell( nRow
, nColumn
, this );
1003 if( pFrame
&& pFrame
->IsCellFrame() )
1005 const SwSelBoxes
*pSelBoxes
= GetSelBoxes();
1008 const SwCellFrame
*pCFrame
= static_cast < const SwCellFrame
* >( pFrame
);
1010 const_cast< SwTableBox
*>( pCFrame
->GetTabBox() );
1011 bRet
= pSelBoxes
->find( pBox
) != pSelBoxes
->end();
1018 sal_Int64 SAL_CALL
SwAccessibleTable::getAccessibleIndex(
1019 sal_Int32 nRow
, sal_Int32 nColumn
)
1021 sal_Int32 nRet
= -1;
1023 SolarMutexGuard aGuard
;
1027 SwAccessibleChild
aCell( GetTableData().GetCell( nRow
, nColumn
, this ));
1028 if ( aCell
.IsValid() )
1030 nRet
= GetChildIndex( *(GetMap()), aCell
);
1036 sal_Int32 SAL_CALL
SwAccessibleTable::getAccessibleRow( sal_Int64 nChildIndex
)
1038 sal_Int32 nRet
= -1;
1040 SolarMutexGuard aGuard
;
1045 if ( ( nChildIndex
< 0 ) ||
1046 ( nChildIndex
>= getAccessibleChildCount() ) )
1048 throw lang::IndexOutOfBoundsException();
1051 SwAccessibleChild
aCell( GetChild( *(GetMap()), nChildIndex
) );
1052 if ( aCell
.GetSwFrame() )
1054 sal_Int32 nTop
= aCell
.GetSwFrame()->getFrameArea().Top();
1055 nTop
-= GetFrame()->getFrameArea().Top();
1056 Int32Set_Impl::const_iterator
aRow(
1057 GetTableData().GetRows().lower_bound( nTop
) );
1058 nRet
= static_cast< sal_Int32
>( std::distance(
1059 GetTableData().GetRows().begin(), aRow
) );
1063 OSL_ENSURE( !aCell
.IsValid(), "SwAccessibleTable::getAccessibleColumn:"
1064 "aCell not expected to be valid.");
1066 throw lang::IndexOutOfBoundsException();
1072 sal_Int32 SAL_CALL
SwAccessibleTable::getAccessibleColumn(
1073 sal_Int64 nChildIndex
)
1075 sal_Int32 nRet
= -1;
1077 SolarMutexGuard aGuard
;
1082 if ( ( nChildIndex
< 0 ) ||
1083 ( nChildIndex
>= getAccessibleChildCount() ) )
1085 throw lang::IndexOutOfBoundsException();
1088 SwAccessibleChild
aCell( GetChild( *(GetMap()), nChildIndex
) );
1089 if ( aCell
.GetSwFrame() )
1091 sal_Int32 nLeft
= aCell
.GetSwFrame()->getFrameArea().Left();
1092 nLeft
-= GetFrame()->getFrameArea().Left();
1093 Int32Set_Impl::const_iterator
aCol(
1094 GetTableData().GetColumns().lower_bound( nLeft
) );
1095 nRet
= static_cast< sal_Int32
>( std::distance(
1096 GetTableData().GetColumns().begin(), aCol
) );
1100 OSL_ENSURE( !aCell
.IsValid(), "SwAccessibleTable::getAccessibleColumn:"
1101 "aCell not expected to be valid.");
1103 throw lang::IndexOutOfBoundsException();
1109 OUString SAL_CALL
SwAccessibleTable::getImplementationName()
1111 return u
"com.sun.star.comp.Writer.SwAccessibleTableView"_ustr
;
1114 sal_Bool SAL_CALL
SwAccessibleTable::supportsService(
1115 const OUString
& sTestServiceName
)
1117 return cppu::supportsService(this, sTestServiceName
);
1120 uno::Sequence
< OUString
> SAL_CALL
SwAccessibleTable::getSupportedServiceNames()
1122 return { u
"com.sun.star.table.AccessibleTableView"_ustr
, sAccessibleServiceName
};
1125 void SwAccessibleTable::InvalidatePosOrSize( const SwRect
& rOldBox
)
1127 SolarMutexGuard aGuard
;
1129 //need to update children
1130 std::unique_ptr
<SwAccessibleTableData_Impl
> pNewTableData
= CreateNewTableData();
1131 if( !pNewTableData
->CompareExtents( GetTableData() ) )
1133 mpTableData
= std::move(pNewTableData
);
1134 FireTableChangeEvent(*mpTableData
);
1136 if( HasTableData() )
1137 GetTableData().SetTablePos( GetFrame()->getFrameArea().Pos() );
1139 SwAccessibleContext::InvalidatePosOrSize( rOldBox
);
1142 void SwAccessibleTable::Dispose(bool bRecursive
, bool bCanSkipInvisible
)
1144 SolarMutexGuard aGuard
;
1146 SwAccessibleContext::Dispose(bRecursive
, bCanSkipInvisible
);
1149 void SwAccessibleTable::DisposeChild( const SwAccessibleChild
& rChildFrameOrObj
,
1150 bool bRecursive
, bool bCanSkipInvisible
)
1152 SolarMutexGuard aGuard
;
1154 const SwFrame
*pFrame
= rChildFrameOrObj
.GetSwFrame();
1155 OSL_ENSURE( pFrame
, "frame expected" );
1156 if( HasTableData() )
1158 FireTableChangeEvent( GetTableData() );
1162 // There are two reason why this method has been called. The first one
1163 // is there is no context for pFrame. The method is then called by
1164 // the map, and we have to call our superclass.
1165 // The other situation is that we have been call by a call to get notified
1166 // about its change. We then must not call the superclass
1167 uno::Reference
< XAccessible
> xAcc( GetMap()->GetContext( pFrame
, false ) );
1169 SwAccessibleContext::DisposeChild( rChildFrameOrObj
, bRecursive
, bCanSkipInvisible
);
1172 void SwAccessibleTable::InvalidateChildPosOrSize( const SwAccessibleChild
& rChildFrameOrObj
,
1173 const SwRect
& rOldBox
)
1175 SolarMutexGuard aGuard
;
1177 if( HasTableData() )
1179 SAL_WARN_IF( HasTableData() &&
1180 GetFrame()->getFrameArea().Pos() != GetTableData().GetTablePos(),
1181 "sw.a11y", "table has invalid position" );
1182 if( HasTableData() )
1184 std::unique_ptr
<SwAccessibleTableData_Impl
> pNewTableData
= CreateNewTableData(); // #i77106#
1185 if( !pNewTableData
->CompareExtents( GetTableData() ) )
1187 if (pNewTableData
->GetRowCount() != mpTableData
->GetRowCount()
1188 && 1 < GetTableData().GetRowCount())
1190 Int32Set_Impl::const_iterator
aSttCol( GetTableData().GetColumnIter( 0 ) );
1191 Int32Set_Impl::const_iterator
aSttRow( GetTableData().GetRowIter( 1 ) );
1192 const SwFrame
*pCellFrame
= GetTableData().GetCellAtPos( *aSttCol
, *aSttRow
);
1193 Int32Set_Impl::const_iterator
aSttCol2( pNewTableData
->GetColumnIter( 0 ) );
1194 Int32Set_Impl::const_iterator
aSttRow2( pNewTableData
->GetRowIter( 0 ) );
1195 const SwFrame
*pCellFrame2
= pNewTableData
->GetCellAtPos( *aSttCol2
, *aSttRow2
);
1197 if(pCellFrame
== pCellFrame2
)
1199 AccessibleTableModelChange aModelChange
;
1200 aModelChange
.Type
= AccessibleTableModelChangeType::UPDATE
;
1201 aModelChange
.FirstRow
= 0;
1202 aModelChange
.LastRow
= mpTableData
->GetRowCount() - 1;
1203 aModelChange
.FirstColumn
= 0;
1204 aModelChange
.LastColumn
= mpTableData
->GetColumnCount() - 1;
1206 AccessibleEventObject aEvent
;
1207 aEvent
.EventId
= AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED
;
1208 aEvent
.NewValue
<<= aModelChange
;
1210 FireAccessibleEvent( aEvent
);
1214 FireTableChangeEvent( GetTableData() );
1216 mpTableData
= std::move(pNewTableData
);
1221 // #i013961# - always call super class method
1222 SwAccessibleContext::InvalidateChildPosOrSize( rChildFrameOrObj
, rOldBox
);
1225 // XAccessibleSelection
1227 void SAL_CALL
SwAccessibleTable::selectAccessibleChild(
1228 sal_Int64 nChildIndex
)
1230 SolarMutexGuard aGuard
;
1234 if( (nChildIndex
< 0) || (nChildIndex
>= getAccessibleChildCount()) ) // #i77106#
1235 throw lang::IndexOutOfBoundsException();
1237 // preliminaries: get 'our' table box, and get the cursor shell
1238 const SwTableBox
* pBox
= GetTableBox( nChildIndex
);
1240 SwCursorShell
* pCursorShell
= GetCursorShell();
1241 if( pCursorShell
== nullptr )
1244 // assure, that child, identified by the given index, isn't already selected.
1245 if ( IsChildSelected( nChildIndex
) )
1248 assert(pBox
!= nullptr && "We need the table box.");
1250 // now we can start to do the work: check whether we already have
1251 // a table selection (in 'our' table). If so, extend the
1252 // selection, else select the current cell.
1254 // if we have a selection in a table, check if it's in the
1255 // same table that we're trying to select in
1256 const SwTableNode
* pSelectedTable
= pCursorShell
->IsCursorInTable();
1257 if( pSelectedTable
!= nullptr )
1259 // get top-most table line
1260 const SwTableLine
* pUpper
= pBox
->GetUpper();
1261 while( pUpper
->GetUpper() != nullptr )
1262 pUpper
= pUpper
->GetUpper()->GetUpper();
1264 pSelectedTable
->GetTable().GetTabLines().GetPos( pUpper
);
1265 if( nPos
== USHRT_MAX
)
1266 pSelectedTable
= nullptr;
1269 // create the new selection
1270 const SwStartNode
* pStartNode
= pBox
->GetSttNd();
1271 if( pSelectedTable
== nullptr || !pCursorShell
->GetTableCrs() )
1273 pCursorShell
->StartAction();
1274 // Set cursor into current cell. This deletes any table cursor.
1275 SwPaM
aPaM( *pStartNode
);
1276 aPaM
.Move( fnMoveForward
, GoInNode
);
1278 // Move cursor to the end of the table creating a selection and a table
1280 pCursorShell
->SetMark();
1281 pCursorShell
->MoveTable( GotoCurrTable
, fnTableEnd
);
1282 // now set the cursor into the cell again.
1283 SwPaM
*pPaM
= pCursorShell
->GetTableCrs() ? pCursorShell
->GetTableCrs()
1284 : pCursorShell
->GetCursor();
1285 *pPaM
->GetPoint() = *pPaM
->GetMark();
1286 pCursorShell
->EndAction();
1287 // we now have one cell selected!
1291 // if the cursor is already in this table,
1292 // expand the current selection (i.e., set
1293 // point to new position; keep mark)
1294 SwPaM
aPaM( *pStartNode
);
1295 aPaM
.Move( fnMoveForward
, GoInNode
);
1297 const SwPaM
*pPaM
= pCursorShell
->GetTableCrs() ? pCursorShell
->GetTableCrs()
1298 : pCursorShell
->GetCursor();
1299 *(aPaM
.GetMark()) = *pPaM
->GetMark();
1305 sal_Bool SAL_CALL
SwAccessibleTable::isAccessibleChildSelected(
1306 sal_Int64 nChildIndex
)
1308 SolarMutexGuard aGuard
;
1312 if( (nChildIndex
< 0) || (nChildIndex
>= getAccessibleChildCount()) ) // #i77106#
1313 throw lang::IndexOutOfBoundsException();
1315 return IsChildSelected( nChildIndex
);
1318 void SAL_CALL
SwAccessibleTable::clearAccessibleSelection( )
1320 SolarMutexGuard aGuard
;
1324 SwCursorShell
* pCursorShell
= GetCursorShell();
1325 if( pCursorShell
!= nullptr )
1327 pCursorShell
->StartAction();
1328 pCursorShell
->ClearMark();
1329 pCursorShell
->EndAction();
1333 void SAL_CALL
SwAccessibleTable::selectAllAccessibleChildren( )
1335 // first clear selection, then select first and last child
1336 clearAccessibleSelection();
1337 selectAccessibleChild( 0 );
1338 selectAccessibleChild( getAccessibleChildCount()-1 ); // #i77106#
1341 sal_Int64 SAL_CALL
SwAccessibleTable::getSelectedAccessibleChildCount( )
1343 SolarMutexGuard aGuard
;
1347 // iterate over all children and count isAccessibleChildSelected()
1348 sal_Int64 nCount
= 0;
1350 sal_Int64 nChildren
= getAccessibleChildCount(); // #i71106#
1351 for( sal_Int64 n
= 0; n
< nChildren
; n
++ )
1352 if( IsChildSelected( n
) )
1358 uno::Reference
<XAccessible
> SAL_CALL
SwAccessibleTable::getSelectedAccessibleChild(
1359 sal_Int64 nSelectedChildIndex
)
1361 SolarMutexGuard aGuard
;
1365 // parameter checking (part 1): index lower 0
1366 if( nSelectedChildIndex
< 0 )
1367 throw lang::IndexOutOfBoundsException();
1369 sal_Int64 nChildIndex
= GetIndexOfSelectedChild( nSelectedChildIndex
);
1371 // parameter checking (part 2): index higher than selected children?
1372 if( nChildIndex
< 0 )
1373 throw lang::IndexOutOfBoundsException();
1376 if ( nChildIndex
>= getAccessibleChildCount() )
1378 throw lang::IndexOutOfBoundsException();
1381 return getAccessibleChild( nChildIndex
);
1384 // index has to be treated as global child index.
1385 void SAL_CALL
SwAccessibleTable::deselectAccessibleChild(
1386 sal_Int64 nChildIndex
)
1388 SolarMutexGuard aGuard
;
1392 SwCursorShell
* pCursorShell
= GetCursorShell();
1394 // index has to be treated as global child index
1395 if ( !pCursorShell
)
1396 throw lang::IndexOutOfBoundsException();
1398 // assure, that given child index is in bounds.
1399 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() ) // #i77106#
1400 throw lang::IndexOutOfBoundsException();
1402 // assure, that child, identified by the given index, is selected.
1403 if ( !IsChildSelected( nChildIndex
) )
1406 const SwTableBox
* pBox
= GetTableBox( nChildIndex
);
1407 assert(pBox
!= nullptr && "We need the table box.");
1409 // If we unselect point, then set cursor to mark. If we clear another
1410 // selected box, then set cursor to point.
1411 // reduce selection to mark.
1412 SwPaM
*pPaM
= pCursorShell
->GetTableCrs() ? pCursorShell
->GetTableCrs()
1413 : pCursorShell
->GetCursor();
1414 bool bDeselectPoint
=
1416 pPaM
->GetPoint()->GetNode().FindTableBoxStartNode();
1418 SwPaM
aPaM( bDeselectPoint
? *pPaM
->GetMark() : *pPaM
->GetPoint() );
1420 pCursorShell
->StartAction();
1422 // Set cursor into either point or mark
1424 // Move cursor to the end of the table creating a selection and a table
1426 pCursorShell
->SetMark();
1427 pCursorShell
->MoveTable( GotoCurrTable
, fnTableEnd
);
1428 // now set the cursor into the cell again.
1429 pPaM
= pCursorShell
->GetTableCrs() ? pCursorShell
->GetTableCrs()
1430 : pCursorShell
->GetCursor();
1431 *pPaM
->GetPoint() = *pPaM
->GetMark();
1432 pCursorShell
->EndAction();
1435 sal_Int32 SAL_CALL
SwAccessibleTable::getBackground()
1437 const SvxBrushItem
&rBack
= GetFrame()->GetAttrSet()->GetBackground();
1438 Color crBack
= rBack
.GetColor();
1440 if (COL_AUTO
== crBack
)
1442 uno::Reference
<XAccessible
> xAccDoc
= getAccessibleParent();
1445 uno::Reference
<XAccessibleComponent
> xComponentDoc(xAccDoc
,uno::UNO_QUERY
);
1446 if (xComponentDoc
.is())
1448 crBack
= Color(ColorTransparency
, xComponentDoc
->getBackground());
1452 return sal_Int32(crBack
);
1455 void SwAccessibleTable::FireSelectionEvent( )
1457 AccessibleEventObject aEvent
;
1459 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_REMOVE
;
1461 for (const unotools::WeakReference
<SwAccessibleContext
>& rxCell
: m_vecCellRemove
)
1463 // fdo#57197: check if the object is still alive
1464 rtl::Reference
<SwAccessibleContext
> const pAccCell(rxCell
);
1467 aEvent
.NewValue
<<= uno::Reference
<XAccessible
>(pAccCell
);
1468 FireAccessibleEvent(aEvent
);
1472 if (m_vecCellAdd
.size() <= SELECTION_WITH_NUM
)
1474 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_ADD
;
1475 for (const unotools::WeakReference
<SwAccessibleContext
>& rxCell
: m_vecCellAdd
)
1477 // fdo#57197: check if the object is still alive
1478 rtl::Reference
<SwAccessibleContext
> const pAccCell(rxCell
);
1481 aEvent
.NewValue
<<= uno::Reference
<XAccessible
>(pAccCell
);
1482 FireAccessibleEvent(aEvent
);
1488 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_WITHIN
;
1489 FireAccessibleEvent(aEvent
);
1492 m_vecCellRemove
.clear();
1493 m_vecCellAdd
.clear();
1496 void SwAccessibleTable::AddSelectionCell(
1497 SwAccessibleContext
*const pAccCell
, bool const bAddOrRemove
)
1501 m_vecCellAdd
.emplace_back(pAccCell
);
1505 m_vecCellRemove
.emplace_back(pAccCell
);
1509 // XAccessibleTableSelection
1510 sal_Bool SAL_CALL
SwAccessibleTable::selectRow( sal_Int32 row
)
1514 if( isAccessibleRowSelected( row
) )
1517 tools::Long lColumnCount
= getAccessibleColumnCount();
1518 for(tools::Long lCol
= 0; lCol
< lColumnCount
; lCol
++)
1520 sal_Int64 nChildIndex
= getAccessibleIndex(row
, lCol
);
1521 selectAccessibleChild(nChildIndex
);
1526 sal_Bool SAL_CALL
SwAccessibleTable::selectColumn( sal_Int32 column
)
1530 if( isAccessibleColumnSelected( column
) )
1533 sal_Int32 lRowCount
= getAccessibleRowCount();
1535 for(sal_Int32 lRow
= 0; lRow
< lRowCount
; lRow
++)
1537 sal_Int64 nChildIndex
= getAccessibleIndex(lRow
, column
);
1538 selectAccessibleChild(nChildIndex
);
1543 sal_Bool SAL_CALL
SwAccessibleTable::unselectRow( sal_Int32 row
)
1547 if( isAccessibleSelected( row
, 0 ) && isAccessibleSelected( row
, getAccessibleColumnCount()-1 ) )
1549 SwCursorShell
* pCursorShell
= GetCursorShell();
1550 if( pCursorShell
!= nullptr )
1552 pCursorShell
->StartAction();
1553 pCursorShell
->ClearMark();
1554 pCursorShell
->EndAction();
1561 sal_Bool SAL_CALL
SwAccessibleTable::unselectColumn( sal_Int32 column
)
1565 if( isAccessibleSelected( 0 , column
) && isAccessibleSelected( getAccessibleRowCount()-1,column
))
1567 SwCursorShell
* pCursorShell
= GetCursorShell();
1568 if( pCursorShell
!= nullptr )
1570 pCursorShell
->StartAction();
1571 pCursorShell
->ClearMark();
1572 pCursorShell
->EndAction();
1579 // #i77106# - implementation of class <SwAccessibleTableColHeaders>
1580 SwAccessibleTableColHeaders::SwAccessibleTableColHeaders(
1581 std::shared_ptr
<SwAccessibleMap
> const& pMap
,
1582 const SwTabFrame
*const pTabFrame
)
1583 : SwAccessibleTable(pMap
, pTabFrame
)
1585 SolarMutexGuard aGuard
;
1587 const SwFrameFormat
* pFrameFormat
= pTabFrame
->GetFormat();
1588 StartListening(const_cast<SwFrameFormat
*>(pFrameFormat
)->GetNotifier());
1589 const OUString aName
= pFrameFormat
->GetName() + "-ColumnHeaders";
1591 SetName( aName
+ "-" + OUString::number( pTabFrame
->GetPhyPageNum() ) );
1593 const OUString
sArg2( GetFormattedPageNumber() );
1595 SetDesc( GetResource( STR_ACCESS_TABLE_DESC
, &aName
, &sArg2
) );
1597 NotRegisteredAtAccessibleMap(); // #i85634#
1600 std::unique_ptr
<SwAccessibleTableData_Impl
> SwAccessibleTableColHeaders::CreateNewTableData()
1602 const SwTabFrame
* pTabFrame
= static_cast<const SwTabFrame
*>( GetFrame() );
1603 return std::unique_ptr
<SwAccessibleTableData_Impl
>(new SwAccessibleTableData_Impl( *(GetMap()), pTabFrame
, IsInPagePreview(), true ));
1606 void SwAccessibleTableColHeaders::Notify(const SfxHint
& )
1610 // XAccessibleContext
1611 sal_Int64 SAL_CALL
SwAccessibleTableColHeaders::getAccessibleChildCount()
1613 SolarMutexGuard aGuard
;
1617 sal_Int32 nCount
= 0;
1619 const SwTabFrame
* pTabFrame
= static_cast<const SwTabFrame
*>( GetFrame() );
1620 const SwAccessibleChildSList
aVisList( GetVisArea(), *pTabFrame
, *(GetMap()) );
1621 SwAccessibleChildSList::const_iterator
aIter( aVisList
.begin() );
1622 while( aIter
!= aVisList
.end() )
1624 const SwAccessibleChild
& rLower
= *aIter
;
1625 if( rLower
.IsAccessible( IsInPagePreview() ) )
1629 else if( rLower
.GetSwFrame() )
1631 // There are no unaccessible SdrObjects that count
1632 if ( !rLower
.GetSwFrame()->IsRowFrame() ||
1633 pTabFrame
->IsInHeadline( *(rLower
.GetSwFrame()) ) )
1635 nCount
+= SwAccessibleFrame::GetChildCount( *(GetMap()),
1637 rLower
.GetSwFrame(),
1638 IsInPagePreview() );
1647 uno::Reference
< XAccessible
> SAL_CALL
1648 SwAccessibleTableColHeaders::getAccessibleChild (sal_Int64 nIndex
)
1650 if ( nIndex
< 0 || nIndex
>= getAccessibleChildCount() )
1652 throw lang::IndexOutOfBoundsException();
1655 return SwAccessibleTable::getAccessibleChild( nIndex
);
1659 uno::Reference
< XAccessibleTable
>
1660 SAL_CALL
SwAccessibleTableColHeaders::getAccessibleRowHeaders()
1662 return uno::Reference
< XAccessibleTable
>();
1665 uno::Reference
< XAccessibleTable
>
1666 SAL_CALL
SwAccessibleTableColHeaders::getAccessibleColumnHeaders()
1668 return uno::Reference
< XAccessibleTable
>();
1673 OUString SAL_CALL
SwAccessibleTableColHeaders::getImplementationName()
1675 static constexpr OUStringLiteral sImplName
1676 = u
"com.sun.star.comp.Writer.SwAccessibleTableColumnHeadersView";
1680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */