Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx
Warning:line 620, column 14
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name acctable.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/log.hxx>
21
22#include <algorithm>
23#include <vector>
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 <unotools/accessiblestatesethelper.hxx>
32#include <vcl/svapp.hxx>
33#include <frmfmt.hxx>
34#include <tabfrm.hxx>
35#include <cellfrm.hxx>
36#include <swtable.hxx>
37#include <crsrsh.hxx>
38#include <viscrs.hxx>
39#include <hints.hxx>
40#include "accfrmobjslist.hxx"
41#include <accmap.hxx>
42#include <strings.hrc>
43#include "acctable.hxx"
44
45#include <com/sun/star/accessibility/XAccessibleText.hpp>
46
47#include <editeng/brushitem.hxx>
48#include <swatrset.hxx>
49#include <frmatr.hxx>
50
51#include <cppuhelper/supportsservice.hxx>
52#include <cppuhelper/typeprovider.hxx>
53
54using namespace ::com::sun::star;
55using namespace ::com::sun::star::accessibility;
56using namespace ::sw::access;
57
58typedef o3tl::sorted_vector< sal_Int32 > Int32Set_Impl;
59
60const unsigned int SELECTION_WITH_NUM = 10;
61
62namespace {
63
64class SwAccTableSelHandler_Impl
65{
66public:
67 virtual void Unselect( sal_Int32 nRowOrCol, sal_Int32 nExt ) = 0;
68
69protected:
70 ~SwAccTableSelHandler_Impl() {}
71};
72
73}
74
75class SwAccessibleTableData_Impl
76{
77 SwAccessibleMap& mrAccMap;
78 Int32Set_Impl maRows;
79 Int32Set_Impl maColumns;
80 Point maTabFramePos;
81 const SwTabFrame *mpTabFrame;
82 bool mbIsInPagePreview;
83 bool mbOnlyTableColumnHeader;
84
85 void CollectData( const SwFrame *pFrame );
86
87 bool FindCell( const Point& rPos, const SwFrame *pFrame ,
88 bool bExact, const SwFrame *& rFrame ) const;
89
90 void GetSelection( const Point& rTabPos, const SwRect& rArea,
91 const SwSelBoxes& rSelBoxes, const SwFrame *pFrame,
92 SwAccTableSelHandler_Impl& rSelHdl,
93 bool bColumns ) const;
94
95 // #i77106#
96 bool IncludeRow( const SwFrame& rFrame ) const
97 {
98 return !mbOnlyTableColumnHeader ||
99 mpTabFrame->IsInHeadline( rFrame );
100 }
101public:
102 // #i77106# - add third optional parameter <bOnlyTableColumnHeader>, default value <false>
103 SwAccessibleTableData_Impl( SwAccessibleMap& rAccMap,
104 const SwTabFrame *pTabFrame,
105 bool bIsInPagePreview,
106 bool bOnlyTableColumnHeader = false );
107
108 const Int32Set_Impl& GetRows() const { return maRows; }
109 const Int32Set_Impl& GetColumns() const { return maColumns; }
110
111 inline Int32Set_Impl::const_iterator GetRowIter( sal_Int32 nRow ) const;
112 inline Int32Set_Impl::const_iterator GetColumnIter( sal_Int32 nCol ) const;
113
114 /// @throws lang::IndexOutOfBoundsException
115 /// @throws uno::RuntimeException
116 const SwFrame *GetCell( sal_Int32 nRow, sal_Int32 nColumn, SwAccessibleTable *pThis ) const;
117 const SwFrame *GetCellAtPos( sal_Int32 nLeft, sal_Int32 nTop ) const;
118 inline sal_Int32 GetRowCount() const;
119 inline sal_Int32 GetColumnCount() const;
120 bool CompareExtents( const SwAccessibleTableData_Impl& r ) const;
121
122 void GetSelection( sal_Int32 nStart, sal_Int32 nEnd,
123 const SwSelBoxes& rSelBoxes,
124 SwAccTableSelHandler_Impl& rSelHdl,
125 bool bColumns ) const;
126
127 /// @throws lang::IndexOutOfBoundsException
128 void CheckRowAndCol( sal_Int32 nRow, sal_Int32 nCol,
129 SwAccessibleTable *pThis ) const;
130
131 const Point& GetTablePos() const { return maTabFramePos; }
132 void SetTablePos( const Point& rPos ) { maTabFramePos = rPos; }
133};
134
135void SwAccessibleTableData_Impl::CollectData( const SwFrame *pFrame )
136{
137 const SwAccessibleChildSList aList( *pFrame, mrAccMap );
138 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
139 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
140 while( aIter != aEndIter )
141 {
142 const SwAccessibleChild& rLower = *aIter;
143 const SwFrame *pLower = rLower.GetSwFrame();
144 if( pLower )
145 {
146 if( pLower->IsRowFrame() )
147 {
148 // #i77106#
149 if ( IncludeRow( *pLower ) )
150 {
151 maRows.insert( pLower->getFrameArea().Top() - maTabFramePos.getY() );
152 CollectData( pLower );
153 }
154 }
155 else if( pLower->IsCellFrame() &&
156 rLower.IsAccessible( mbIsInPagePreview ) )
157 {
158 maColumns.insert( pLower->getFrameArea().Left() - maTabFramePos.getX() );
159 }
160 else
161 {
162 CollectData( pLower );
163 }
164 }
165 ++aIter;
166 }
167}
168
169bool SwAccessibleTableData_Impl::FindCell(
170 const Point& rPos, const SwFrame *pFrame, bool bExact,
171 const SwFrame *& rRet ) const
172{
173 bool bFound = false;
174
175 const SwAccessibleChildSList aList( *pFrame, mrAccMap );
176 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
177 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
178 while( !bFound && aIter != aEndIter )
179 {
180 const SwAccessibleChild& rLower = *aIter;
181 const SwFrame *pLower = rLower.GetSwFrame();
182 OSL_ENSURE( pLower, "child should be a frame" )do { if (true && (!(pLower))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "182" ": "), "%s", "child should be a frame"); } } while
(false)
;
183 if( pLower )
184 {
185 if( rLower.IsAccessible( mbIsInPagePreview ) )
186 {
187 OSL_ENSURE( pLower->IsCellFrame(), "lower is not a cell frame" )do { if (true && (!(pLower->IsCellFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "187" ": "), "%s", "lower is not a cell frame"); } } while
(false)
;
188 const SwRect& rFrame = pLower->getFrameArea();
189 if( rFrame.Right() >= rPos.X() && rFrame.Bottom() >= rPos.Y() )
190 {
191 // We have found the cell
192 OSL_ENSURE( rFrame.Left() <= rPos.X() && rFrame.Top() <= rPos.Y(),do { if (true && (!(rFrame.Left() <= rPos.X() &&
rFrame.Top() <= rPos.Y()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "193" ": "), "%s", "find frame moved to far!"); } } while
(false)
193 "find frame moved to far!" )do { if (true && (!(rFrame.Left() <= rPos.X() &&
rFrame.Top() <= rPos.Y()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "193" ": "), "%s", "find frame moved to far!"); } } while
(false)
;
194 bFound = true;
195 if( !bExact ||
196 (rFrame.Top() == rPos.Y() && rFrame.Left() == rPos.Y() ) )
197 {
198 rRet = pLower;
199 }
200 }
201 }
202 else
203 {
204 // #i77106#
205 if ( !pLower->IsRowFrame() ||
206 IncludeRow( *pLower ) )
207 {
208 bFound = FindCell( rPos, pLower, bExact, rRet );
209 }
210 }
211 }
212 ++aIter;
213 }
214
215 return bFound;
216}
217
218void SwAccessibleTableData_Impl::GetSelection(
219 const Point& rTabPos,
220 const SwRect& rArea,
221 const SwSelBoxes& rSelBoxes,
222 const SwFrame *pFrame,
223 SwAccTableSelHandler_Impl& rSelHdl,
224 bool bColumns ) const
225{
226 const SwAccessibleChildSList aList( *pFrame, mrAccMap );
227 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
228 SwAccessibleChildSList::const_iterator aEndIter( aList.end() );
229 while( aIter != aEndIter )
230 {
231 const SwAccessibleChild& rLower = *aIter;
232 const SwFrame *pLower = rLower.GetSwFrame();
233 OSL_ENSURE( pLower, "child should be a frame" )do { if (true && (!(pLower))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "233" ": "), "%s", "child should be a frame"); } } while
(false)
;
234 const SwRect& rBox = rLower.GetBox( mrAccMap );
235 if( pLower && rBox.IsOver( rArea ) )
236 {
237 if( rLower.IsAccessible( mbIsInPagePreview ) )
238 {
239 OSL_ENSURE( pLower->IsCellFrame(), "lower is not a cell frame" )do { if (true && (!(pLower->IsCellFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "239" ": "), "%s", "lower is not a cell frame"); } } while
(false)
;
240 const SwCellFrame *pCFrame =
241 static_cast < const SwCellFrame * >( pLower );
242 SwTableBox *pBox =
243 const_cast< SwTableBox *>( pCFrame->GetTabBox() );
244 if( rSelBoxes.find( pBox ) == rSelBoxes.end() )
245 {
246 const Int32Set_Impl rRowsOrCols =
247 bColumns ? maColumns : maRows;
248
249 sal_Int32 nPos = bColumns ? (rBox.Left() - rTabPos.X())
250 : (rBox.Top() - rTabPos.Y());
251 Int32Set_Impl::const_iterator aSttRowOrCol(
252 rRowsOrCols.lower_bound( nPos ) );
253 sal_Int32 nRowOrCol =
254 static_cast< sal_Int32 >( std::distance(
255 rRowsOrCols.begin(), aSttRowOrCol ) );
256
257 nPos = bColumns ? (rBox.Right() - rTabPos.X())
258 : (rBox.Bottom() - rTabPos.Y());
259 Int32Set_Impl::const_iterator aEndRowOrCol(
260 rRowsOrCols.upper_bound( nPos ) );
261 sal_Int32 nExt =
262 static_cast< sal_Int32 >( std::distance(
263 aSttRowOrCol, aEndRowOrCol ) );
264
265 rSelHdl.Unselect( nRowOrCol, nExt );
266 }
267 }
268 else
269 {
270 // #i77106#
271 if ( !pLower->IsRowFrame() ||
272 IncludeRow( *pLower ) )
273 {
274 GetSelection( rTabPos, rArea, rSelBoxes, pLower, rSelHdl,
275 bColumns );
276 }
277 }
278 }
279 ++aIter;
280 }
281}
282
283const SwFrame *SwAccessibleTableData_Impl::GetCell(
284 sal_Int32 nRow, sal_Int32 nColumn,
285 SwAccessibleTable *pThis ) const
286{
287 CheckRowAndCol( nRow, nColumn, pThis );
288
289 Int32Set_Impl::const_iterator aSttCol( GetColumnIter( nColumn ) );
290 Int32Set_Impl::const_iterator aSttRow( GetRowIter( nRow ) );
291 const SwFrame *pCellFrame = GetCellAtPos( *aSttCol, *aSttRow );
292
293 return pCellFrame;
294}
295
296void SwAccessibleTableData_Impl::GetSelection(
297 sal_Int32 nStart, sal_Int32 nEnd,
298 const SwSelBoxes& rSelBoxes,
299 SwAccTableSelHandler_Impl& rSelHdl,
300 bool bColumns ) const
301{
302 SwRect aArea( mpTabFrame->getFrameArea() );
303 Point aPos( aArea.Pos() );
304
305 const Int32Set_Impl& rRowsOrColumns = bColumns ? maColumns : maRows;
306 if( nStart > 0 )
307 {
308 Int32Set_Impl::const_iterator aStt( rRowsOrColumns.begin() );
309 std::advance( aStt,
310 static_cast< Int32Set_Impl::difference_type >( nStart ) );
311 if( bColumns )
312 aArea.Left( *aStt + aPos.getX() );
313 else
314 aArea.Top( *aStt + aPos.getY() );
315 }
316 if( nEnd < static_cast< sal_Int32 >( rRowsOrColumns.size() ) )
317 {
318 Int32Set_Impl::const_iterator aEnd( rRowsOrColumns.begin() );
319 std::advance( aEnd,
320 static_cast< Int32Set_Impl::difference_type >( nEnd ) );
321 if( bColumns )
322 aArea.Right( *aEnd + aPos.getX() - 1 );
323 else
324 aArea.Bottom( *aEnd + aPos.getY() - 1 );
325 }
326
327 GetSelection( aPos, aArea, rSelBoxes, mpTabFrame, rSelHdl, bColumns );
328}
329
330const SwFrame *SwAccessibleTableData_Impl::GetCellAtPos(
331 sal_Int32 nLeft, sal_Int32 nTop ) const
332{
333 Point aPos( mpTabFrame->getFrameArea().Pos() );
334 aPos.Move( nLeft, nTop );
335 const SwFrame *pRet = nullptr;
336 FindCell( aPos, mpTabFrame, false/*bExact*/, pRet );
337
338 return pRet;
339}
340
341inline sal_Int32 SwAccessibleTableData_Impl::GetRowCount() const
342{
343 sal_Int32 count = static_cast< sal_Int32 >( maRows.size() ) ;
344 count = (count <=0)? 1:count;
345 return count;
346}
347
348inline sal_Int32 SwAccessibleTableData_Impl::GetColumnCount() const
349{
350 return static_cast< sal_Int32 >( maColumns.size() );
351}
352
353bool SwAccessibleTableData_Impl::CompareExtents(
354 const SwAccessibleTableData_Impl& rCmp ) const
355{
356 return maRows == rCmp.maRows
357 && maColumns == rCmp.maColumns;
358}
359
360SwAccessibleTableData_Impl::SwAccessibleTableData_Impl( SwAccessibleMap& rAccMap,
361 const SwTabFrame *pTabFrame,
362 bool bIsInPagePreview,
363 bool bOnlyTableColumnHeader )
364 : mrAccMap( rAccMap )
365 , maTabFramePos( pTabFrame->getFrameArea().Pos() )
366 , mpTabFrame( pTabFrame )
367 , mbIsInPagePreview( bIsInPagePreview )
368 , mbOnlyTableColumnHeader( bOnlyTableColumnHeader )
369{
370 CollectData( mpTabFrame );
371}
372
373inline Int32Set_Impl::const_iterator SwAccessibleTableData_Impl::GetRowIter(
374 sal_Int32 nRow ) const
375{
376 Int32Set_Impl::const_iterator aCol( GetRows().begin() );
377 if( nRow > 0 )
378 {
379 std::advance( aCol,
380 static_cast< Int32Set_Impl::difference_type >( nRow ) );
381 }
382 return aCol;
383}
384
385inline Int32Set_Impl::const_iterator SwAccessibleTableData_Impl::GetColumnIter(
386 sal_Int32 nColumn ) const
387{
388 Int32Set_Impl::const_iterator aCol = GetColumns().begin();
389 if( nColumn > 0 )
390 {
391 std::advance( aCol,
392 static_cast< Int32Set_Impl::difference_type >( nColumn ) );
393 }
394 return aCol;
395}
396
397void SwAccessibleTableData_Impl::CheckRowAndCol(
398 sal_Int32 nRow, sal_Int32 nCol, SwAccessibleTable *pThis ) const
399{
400 if( ( nRow < 0 || nRow >= static_cast< sal_Int32 >( maRows.size() ) ) ||
401 ( nCol < 0 || nCol >= static_cast< sal_Int32 >( maColumns.size() ) ) )
402 {
403 uno::Reference < XAccessibleTable > xThis( pThis );
404 lang::IndexOutOfBoundsException aExcept(
405 "row or column index out of range",
406 xThis );
407 throw aExcept;
408 }
409}
410
411namespace {
412
413class SwAccSingleTableSelHandler_Impl : public SwAccTableSelHandler_Impl
414{
415 bool m_bSelected;
416
417public:
418
419 inline SwAccSingleTableSelHandler_Impl();
420
421 virtual ~SwAccSingleTableSelHandler_Impl() {}
422
423 bool IsSelected() const { return m_bSelected; }
424
425 virtual void Unselect( sal_Int32, sal_Int32 ) override;
426};
427
428}
429
430inline SwAccSingleTableSelHandler_Impl::SwAccSingleTableSelHandler_Impl() :
431 m_bSelected( true )
432{
433}
434
435void SwAccSingleTableSelHandler_Impl::Unselect( sal_Int32, sal_Int32 )
436{
437 m_bSelected = false;
438}
439
440namespace {
441
442class SwAccAllTableSelHandler_Impl : public SwAccTableSelHandler_Impl
443
444{
445 std::vector< bool > m_aSelected;
446 sal_Int32 m_nCount;
447
448public:
449 explicit SwAccAllTableSelHandler_Impl(sal_Int32 nSize)
450 : m_aSelected(nSize, true)
451 , m_nCount(nSize)
452 {
453 }
454
455 uno::Sequence < sal_Int32 > GetSelSequence();
456
457 virtual void Unselect( sal_Int32 nRowOrCol, sal_Int32 nExt ) override;
458 virtual ~SwAccAllTableSelHandler_Impl();
459};
460
461}
462
463SwAccAllTableSelHandler_Impl::~SwAccAllTableSelHandler_Impl()
464{
465}
466
467uno::Sequence < sal_Int32 > SwAccAllTableSelHandler_Impl::GetSelSequence()
468{
469 OSL_ENSURE( m_nCount >= 0, "underflow" )do { if (true && (!(m_nCount >= 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "469" ": "), "%s", "underflow"); } } while (false)
;
470 uno::Sequence < sal_Int32 > aRet( m_nCount );
471 sal_Int32 *pRet = aRet.getArray();
472 sal_Int32 nPos = 0;
473 size_t nSize = m_aSelected.size();
474 for( size_t i=0; i < nSize && nPos < m_nCount; i++ )
475 {
476 if( m_aSelected[i] )
477 {
478 *pRet++ = i;
479 nPos++;
480 }
481 }
482
483 OSL_ENSURE( nPos == m_nCount, "count is wrong" )do { if (true && (!(nPos == m_nCount))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "483" ": "), "%s", "count is wrong"); } } while (false)
;
484
485 return aRet;
486}
487
488void SwAccAllTableSelHandler_Impl::Unselect( sal_Int32 nRowOrCol,
489 sal_Int32 nExt )
490{
491 OSL_ENSURE( o3tl::make_unsigned( nRowOrCol ) < m_aSelected.size(),do { if (true && (!(o3tl::make_unsigned( nRowOrCol ) <
m_aSelected.size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "492" ": "), "%s", "index too large"); } } while (false)
492 "index too large" )do { if (true && (!(o3tl::make_unsigned( nRowOrCol ) <
m_aSelected.size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "492" ": "), "%s", "index too large"); } } while (false)
;
493 OSL_ENSURE( o3tl::make_unsigned( nRowOrCol+nExt ) <= m_aSelected.size(),do { if (true && (!(o3tl::make_unsigned( nRowOrCol+nExt
) <= m_aSelected.size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "494" ": "), "%s", "extent too large"); } } while (false
)
494 "extent too large" )do { if (true && (!(o3tl::make_unsigned( nRowOrCol+nExt
) <= m_aSelected.size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "494" ": "), "%s", "extent too large"); } } while (false
)
;
495 while( nExt )
496 {
497 if( m_aSelected[static_cast< size_t >( nRowOrCol )] )
498 {
499 m_aSelected[static_cast< size_t >( nRowOrCol )] = false;
500 m_nCount--;
501 }
502 nExt--;
503 nRowOrCol++;
504 }
505}
506
507const SwSelBoxes *SwAccessibleTable::GetSelBoxes() const
508{
509 const SwSelBoxes *pSelBoxes = nullptr;
510 const SwCursorShell *pCSh = GetCursorShell();
511 if( (pCSh != nullptr) && pCSh->IsTableMode() )
512 {
513 pSelBoxes = &pCSh->GetTableCursor()->GetSelectedBoxes();
514 }
515
516 return pSelBoxes;
517}
518
519void SwAccessibleTable::FireTableChangeEvent(
520 const SwAccessibleTableData_Impl& rTableData )
521{
522 AccessibleTableModelChange aModelChange;
523 aModelChange.Type = AccessibleTableModelChangeType::UPDATE;
524 aModelChange.FirstRow = 0;
525 aModelChange.LastRow = rTableData.GetRowCount() - 1;
526 aModelChange.FirstColumn = 0;
527 aModelChange.LastColumn = rTableData.GetColumnCount() - 1;
528
529 AccessibleEventObject aEvent;
530 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
531 aEvent.NewValue <<= aModelChange;
532
533 FireAccessibleEvent( aEvent );
534}
535
536const SwTableBox* SwAccessibleTable::GetTableBox( sal_Int32 nChildIndex ) const
537{
538 OSL_ENSURE( nChildIndex >= 0, "Illegal child index." )do { if (true && (!(nChildIndex >= 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "538" ": "), "%s", "Illegal child index."); } } while (false
)
;
539 OSL_ENSURE( nChildIndex < const_cast<SwAccessibleTable*>(this)->getAccessibleChildCount(), "Illegal child index." )do { if (true && (!(nChildIndex < const_cast<SwAccessibleTable
*>(this)->getAccessibleChildCount()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "539" ": "), "%s", "Illegal child index."); } } while (false
)
; // #i77106#
540
541 const SwTableBox* pBox = nullptr;
542
543 // get table box for 'our' table cell
544 SwAccessibleChild aCell( GetChild( *const_cast<SwAccessibleMap*>(GetMap()), nChildIndex ) );
545 if( aCell.GetSwFrame() )
546 {
547 const SwFrame* pChildFrame = aCell.GetSwFrame();
548 if( (pChildFrame != nullptr) && pChildFrame->IsCellFrame() )
549 {
550 const SwCellFrame* pCellFrame =
551 static_cast<const SwCellFrame*>( pChildFrame );
552 pBox = pCellFrame->GetTabBox();
553 }
554 }
555
556 OSL_ENSURE( pBox != nullptr, "We need the table box." )do { if (true && (!(pBox != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "556" ": "), "%s", "We need the table box."); } } while (
false)
;
557 return pBox;
558}
559
560bool SwAccessibleTable::IsChildSelected( sal_Int32 nChildIndex ) const
561{
562 bool bRet = false;
563 const SwSelBoxes* pSelBoxes = GetSelBoxes();
564 if( pSelBoxes )
565 {
566 const SwTableBox* pBox = GetTableBox( nChildIndex );
567 OSL_ENSURE( pBox != nullptr, "We need the table box." )do { if (true && (!(pBox != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "567" ": "), "%s", "We need the table box."); } } while (
false)
;
568 bRet = pSelBoxes->find( const_cast<SwTableBox*>( pBox ) ) != pSelBoxes->end();
569 }
570
571 return bRet;
572}
573
574sal_Int32 SwAccessibleTable::GetIndexOfSelectedChild(
575 sal_Int32 nSelectedChildIndex ) const
576{
577 // iterate over all children to n-th isAccessibleChildSelected()
578 sal_Int32 nChildren = const_cast<SwAccessibleTable*>(this)->getAccessibleChildCount(); // #i77106#
579 if( nSelectedChildIndex >= nChildren )
580 return -1;
581
582 sal_Int32 n = 0;
583 while( n < nChildren )
584 {
585 if( IsChildSelected( n ) )
586 {
587 if( 0 == nSelectedChildIndex )
588 break;
589 else
590 --nSelectedChildIndex;
591 }
592 ++n;
593 }
594
595 return n < nChildren ? n : -1;
596}
597
598void SwAccessibleTable::GetStates(
599 ::utl::AccessibleStateSetHelper& rStateSet )
600{
601 SwAccessibleContext::GetStates( rStateSet );
602 //Add resizable state to table
603 rStateSet.AddState( AccessibleStateType::RESIZABLE );
604 // MULTISELECTABLE
605 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
606 SwCursorShell* pCursorShell = GetCursorShell();
607 if( pCursorShell )
608 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
609}
610
611SwAccessibleTable::SwAccessibleTable(
612 std::shared_ptr<SwAccessibleMap> const& pInitMap,
613 const SwTabFrame* pTabFrame ) :
614 SwAccessibleContext( pInitMap, AccessibleRole::TABLE, pTabFrame )
615{
616 const SwFrameFormat* pFrameFormat = pTabFrame->GetFormat();
4
'pFrameFormat' initialized here
617 if(pFrameFormat)
5
Assuming 'pFrameFormat' is null
6
Assuming pointer value is null
7
Taking false branch
618 StartListening(const_cast<SwFrameFormat*>(pFrameFormat)->GetNotifier());
619
620 SetName( pFrameFormat->GetName() + "-" + OUString::number( pTabFrame->GetPhyPageNum() ) );
8
Called C++ object pointer is null
621
622 const OUString sArg1( static_cast< const SwTabFrame * >( GetFrame() )->GetFormat()->GetName() );
623 const OUString sArg2( GetFormattedPageNumber() );
624
625 m_sDesc = GetResource( STR_ACCESS_TABLE_DESCreinterpret_cast<char const *>("STR_ACCESS_TABLE_DESC" "\004"
u8"$(ARG1) on page $(ARG2)")
, &sArg1, &sArg2 );
626 UpdateTableData();
627}
628
629SwAccessibleTable::~SwAccessibleTable()
630{
631 SolarMutexGuard aGuard;
632
633 mpTableData.reset();
634}
635
636void SwAccessibleTable::Notify(const SfxHint& rHint)
637{
638 if(rHint.GetId() == SfxHintId::Dying)
639 {
640 EndListeningAll();
641 }
642 else if(auto pLegacyHint = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
643 {
644 const sal_uInt16 nWhich = pLegacyHint->GetWhich();
645 const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(GetFrame());
646 if(nWhich == RES_NAME_CHANGED && pTabFrame)
647 {
648 const SwFrameFormat *pFrameFormat = pTabFrame->GetFormat();
649
650 const OUString sOldName( GetName() );
651 const OUString sNewTabName = pFrameFormat->GetName();
652
653 SetName( sNewTabName + "-" + OUString::number( pTabFrame->GetPhyPageNum() ) );
654
655 if( sOldName != GetName() )
656 {
657 AccessibleEventObject aEvent;
658 aEvent.EventId = AccessibleEventId::NAME_CHANGED;
659 aEvent.OldValue <<= sOldName;
660 aEvent.NewValue <<= GetName();
661 FireAccessibleEvent( aEvent );
662 }
663
664 const OUString sOldDesc( m_sDesc );
665 const OUString sArg2( GetFormattedPageNumber() );
666
667 m_sDesc = GetResource( STR_ACCESS_TABLE_DESCreinterpret_cast<char const *>("STR_ACCESS_TABLE_DESC" "\004"
u8"$(ARG1) on page $(ARG2)")
, &sNewTabName, &sArg2 );
668 if( m_sDesc != sOldDesc )
669 {
670 AccessibleEventObject aEvent;
671 aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
672 aEvent.OldValue <<= sOldDesc;
673 aEvent.NewValue <<= m_sDesc;
674 FireAccessibleEvent( aEvent );
675 }
676 }
677 }
678}
679
680uno::Any SwAccessibleTable::queryInterface( const uno::Type& rType )
681{
682 uno::Any aRet;
683 if ( rType == cppu::UnoType<XAccessibleTable>::get() )
684 {
685 uno::Reference<XAccessibleTable> xThis( this );
686 aRet <<= xThis;
687 }
688 else if ( rType == cppu::UnoType<XAccessibleSelection>::get() )
689 {
690 uno::Reference<XAccessibleSelection> xSelection( this );
691 aRet <<= xSelection;
692 }
693 else if ( rType == cppu::UnoType<XAccessibleTableSelection>::get() )
694 {
695 uno::Reference<XAccessibleTableSelection> xTableExtent( this );
696 aRet <<= xTableExtent;
697 }
698 else
699 {
700 aRet = SwAccessibleContext::queryInterface(rType);
701 }
702
703 return aRet;
704}
705
706// XTypeProvider
707uno::Sequence< uno::Type > SAL_CALL SwAccessibleTable::getTypes()
708{
709 return cppu::OTypeCollection(
710 cppu::UnoType<XAccessibleSelection>::get(),
711 cppu::UnoType<XAccessibleTable>::get(),
712 SwAccessibleContext::getTypes() ).getTypes();
713}
714
715uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleTable::getImplementationId()
716{
717 return css::uno::Sequence<sal_Int8>();
718}
719
720// #i77106#
721std::unique_ptr<SwAccessibleTableData_Impl> SwAccessibleTable::CreateNewTableData()
722{
723 const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>( GetFrame() );
724 return std::unique_ptr<SwAccessibleTableData_Impl>(new SwAccessibleTableData_Impl( *GetMap(), pTabFrame, IsInPagePreview() ));
725}
726
727void SwAccessibleTable::UpdateTableData()
728{
729 // #i77106# - usage of new method <CreateNewTableData()>
730 mpTableData = CreateNewTableData();
731}
732
733void SwAccessibleTable::ClearTableData()
734{
735 mpTableData.reset();
736}
737
738OUString SAL_CALL SwAccessibleTable::getAccessibleDescription()
739{
740 SolarMutexGuard aGuard;
741
742 ThrowIfDisposed();
743
744 return m_sDesc;
745}
746
747sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRowCount()
748{
749 SolarMutexGuard aGuard;
750
751 ThrowIfDisposed();
752
753 return GetTableData().GetRowCount();
754}
755
756sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumnCount( )
757{
758 SolarMutexGuard aGuard;
759
760 ThrowIfDisposed();
761
762 return GetTableData().GetColumnCount();
763}
764
765OUString SAL_CALL SwAccessibleTable::getAccessibleRowDescription(
766 sal_Int32 nRow )
767{
768 // #i87532# - determine table cell in <nRow>th row and
769 // in first column of row header table and return its text content.
770 OUString sRowDesc;
771
772 GetTableData().CheckRowAndCol(nRow, 0, this);
773
774 uno::Reference< XAccessibleTable > xTableRowHeader = getAccessibleRowHeaders();
775 if ( xTableRowHeader.is() )
776 {
777 uno::Reference< XAccessible > xRowHeaderCell =
778 xTableRowHeader->getAccessibleCellAt( nRow, 0 );
779 OSL_ENSURE( xRowHeaderCell.is(),do { if (true && (!(xRowHeaderCell.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "780" ": "), "%s", "<SwAccessibleTable::getAccessibleRowDescription(..)> - missing row header cell -> serious issue."
); } } while (false)
780 "<SwAccessibleTable::getAccessibleRowDescription(..)> - missing row header cell -> serious issue." )do { if (true && (!(xRowHeaderCell.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "780" ": "), "%s", "<SwAccessibleTable::getAccessibleRowDescription(..)> - missing row header cell -> serious issue."
); } } while (false)
;
781 uno::Reference< XAccessibleContext > xRowHeaderCellContext =
782 xRowHeaderCell->getAccessibleContext();
783 const sal_Int32 nCellChildCount( xRowHeaderCellContext->getAccessibleChildCount() );
784 for ( sal_Int32 nChildIndex = 0; nChildIndex < nCellChildCount; ++nChildIndex )
785 {
786 uno::Reference< XAccessible > xChild = xRowHeaderCellContext->getAccessibleChild( nChildIndex );
787 uno::Reference< XAccessibleText > xChildText( xChild, uno::UNO_QUERY );
788 if ( xChildText.is() )
789 {
790 sRowDesc += xChildText->getText();
791 }
792 }
793 }
794
795 return sRowDesc;
796}
797
798OUString SAL_CALL SwAccessibleTable::getAccessibleColumnDescription(
799 sal_Int32 nColumn )
800{
801 // #i87532# - determine table cell in first row and
802 // in <nColumn>th column of column header table and return its text content.
803 OUString sColumnDesc;
804
805 GetTableData().CheckRowAndCol(0, nColumn, this);
806
807 uno::Reference< XAccessibleTable > xTableColumnHeader = getAccessibleColumnHeaders();
1
Calling 'SwAccessibleTable::getAccessibleColumnHeaders'
808 if ( xTableColumnHeader.is() )
809 {
810 uno::Reference< XAccessible > xColumnHeaderCell =
811 xTableColumnHeader->getAccessibleCellAt( 0, nColumn );
812 OSL_ENSURE( xColumnHeaderCell.is(),do { if (true && (!(xColumnHeaderCell.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "813" ": "), "%s", "<SwAccessibleTable::getAccessibleColumnDescription(..)> - missing column header cell -> serious issue."
); } } while (false)
813 "<SwAccessibleTable::getAccessibleColumnDescription(..)> - missing column header cell -> serious issue." )do { if (true && (!(xColumnHeaderCell.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "813" ": "), "%s", "<SwAccessibleTable::getAccessibleColumnDescription(..)> - missing column header cell -> serious issue."
); } } while (false)
;
814 uno::Reference< XAccessibleContext > xColumnHeaderCellContext =
815 xColumnHeaderCell->getAccessibleContext();
816 const sal_Int32 nCellChildCount( xColumnHeaderCellContext->getAccessibleChildCount() );
817 for ( sal_Int32 nChildIndex = 0; nChildIndex < nCellChildCount; ++nChildIndex )
818 {
819 uno::Reference< XAccessible > xChild = xColumnHeaderCellContext->getAccessibleChild( nChildIndex );
820 uno::Reference< XAccessibleText > xChildText( xChild, uno::UNO_QUERY );
821 if ( xChildText.is() )
822 {
823 sColumnDesc += xChildText->getText();
824 }
825 }
826 }
827
828 return sColumnDesc;
829}
830
831sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRowExtentAt(
832 sal_Int32 nRow, sal_Int32 nColumn )
833{
834 sal_Int32 nExtend = -1;
835
836 SolarMutexGuard aGuard;
837
838 ThrowIfDisposed();
839
840 UpdateTableData();
841 GetTableData().CheckRowAndCol( nRow, nColumn, this );
842
843 Int32Set_Impl::const_iterator aSttCol(
844 GetTableData().GetColumnIter( nColumn ) );
845 Int32Set_Impl::const_iterator aSttRow(
846 GetTableData().GetRowIter( nRow ) );
847 const SwFrame *pCellFrame = GetTableData().GetCellAtPos( *aSttCol, *aSttRow );
848 if( pCellFrame )
849 {
850 sal_Int32 nBottom = pCellFrame->getFrameArea().Bottom();
851 nBottom -= GetFrame()->getFrameArea().Top();
852 Int32Set_Impl::const_iterator aEndRow(
853 GetTableData().GetRows().upper_bound( nBottom ) );
854 nExtend =
855 static_cast< sal_Int32 >( std::distance( aSttRow, aEndRow ) );
856 }
857
858 return nExtend;
859}
860
861sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumnExtentAt(
862 sal_Int32 nRow, sal_Int32 nColumn )
863{
864 sal_Int32 nExtend = -1;
865
866 SolarMutexGuard aGuard;
867
868 ThrowIfDisposed();
869 UpdateTableData();
870
871 GetTableData().CheckRowAndCol( nRow, nColumn, this );
872
873 Int32Set_Impl::const_iterator aSttCol(
874 GetTableData().GetColumnIter( nColumn ) );
875 Int32Set_Impl::const_iterator aSttRow(
876 GetTableData().GetRowIter( nRow ) );
877 const SwFrame *pCellFrame = GetTableData().GetCellAtPos( *aSttCol, *aSttRow );
878 if( pCellFrame )
879 {
880 sal_Int32 nRight = pCellFrame->getFrameArea().Right();
881 nRight -= GetFrame()->getFrameArea().Left();
882 Int32Set_Impl::const_iterator aEndCol(
883 GetTableData().GetColumns().upper_bound( nRight ) );
884 nExtend =
885 static_cast< sal_Int32 >( std::distance( aSttCol, aEndCol ) );
886 }
887
888 return nExtend;
889}
890
891uno::Reference< XAccessibleTable > SAL_CALL
892 SwAccessibleTable::getAccessibleRowHeaders( )
893{
894 // Row headers aren't supported
895 return uno::Reference< XAccessibleTable >();
896}
897
898uno::Reference< XAccessibleTable > SAL_CALL
899 SwAccessibleTable::getAccessibleColumnHeaders( )
900{
901 SolarMutexGuard aGuard;
902
903 // #i87532# - assure that return accessible object is empty,
904 // if no column header exists.
905 SwAccessibleTableColHeaders* pTableColHeaders =
906 new SwAccessibleTableColHeaders(GetMap()->shared_from_this(),
2
Calling constructor for 'SwAccessibleTableColHeaders'
907 static_cast<const SwTabFrame *>(GetFrame()));
908 uno::Reference< XAccessibleTable > xTableColumnHeaders( pTableColHeaders );
909 if ( pTableColHeaders->getAccessibleChildCount() <= 0 )
910 {
911 return uno::Reference< XAccessibleTable >();
912 }
913
914 return xTableColumnHeaders;
915}
916
917uno::Sequence< sal_Int32 > SAL_CALL SwAccessibleTable::getSelectedAccessibleRows()
918{
919 SolarMutexGuard aGuard;
920
921 ThrowIfDisposed();
922
923 const SwSelBoxes *pSelBoxes = GetSelBoxes();
924 if( pSelBoxes )
925 {
926 sal_Int32 nRows = GetTableData().GetRowCount();
927 SwAccAllTableSelHandler_Impl aSelRows( nRows );
928
929 GetTableData().GetSelection( 0, nRows, *pSelBoxes, aSelRows,
930 false );
931
932 return aSelRows.GetSelSequence();
933 }
934 else
935 {
936 return uno::Sequence< sal_Int32 >( 0 );
937 }
938}
939
940uno::Sequence< sal_Int32 > SAL_CALL SwAccessibleTable::getSelectedAccessibleColumns()
941{
942 SolarMutexGuard aGuard;
943
944 ThrowIfDisposed();
945
946 const SwSelBoxes *pSelBoxes = GetSelBoxes();
947 if( pSelBoxes )
948 {
949 sal_Int32 nCols = GetTableData().GetColumnCount();
950 SwAccAllTableSelHandler_Impl aSelCols( nCols );
951
952 GetTableData().GetSelection( 0, nCols, *pSelBoxes, aSelCols, true );
953
954 return aSelCols.GetSelSequence();
955 }
956 else
957 {
958 return uno::Sequence< sal_Int32 >( 0 );
959 }
960}
961
962sal_Bool SAL_CALL SwAccessibleTable::isAccessibleRowSelected( sal_Int32 nRow )
963{
964 SolarMutexGuard aGuard;
965
966 ThrowIfDisposed();
967
968 GetTableData().CheckRowAndCol( nRow, 0, this );
969
970 bool bRet;
971 const SwSelBoxes *pSelBoxes = GetSelBoxes();
972 if( pSelBoxes )
973 {
974 SwAccSingleTableSelHandler_Impl aSelRow;
975 GetTableData().GetSelection( nRow, nRow+1, *pSelBoxes, aSelRow,
976 false );
977 bRet = aSelRow.IsSelected();
978 }
979 else
980 {
981 bRet = false;
982 }
983
984 return bRet;
985}
986
987sal_Bool SAL_CALL SwAccessibleTable::isAccessibleColumnSelected(
988 sal_Int32 nColumn )
989{
990 SolarMutexGuard aGuard;
991
992 ThrowIfDisposed();
993
994 GetTableData().CheckRowAndCol( 0, nColumn, this );
995
996 bool bRet;
997 const SwSelBoxes *pSelBoxes = GetSelBoxes();
998 if( pSelBoxes )
999 {
1000 SwAccSingleTableSelHandler_Impl aSelCol;
1001
1002 GetTableData().GetSelection( nColumn, nColumn+1, *pSelBoxes, aSelCol,
1003 true );
1004 bRet = aSelCol.IsSelected();
1005 }
1006 else
1007 {
1008 bRet = false;
1009 }
1010
1011 return bRet;
1012}
1013
1014uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleCellAt(
1015 sal_Int32 nRow, sal_Int32 nColumn )
1016{
1017 uno::Reference< XAccessible > xRet;
1018
1019 SolarMutexGuard aGuard;
1020
1021 ThrowIfDisposed();
1022
1023 const SwFrame *pCellFrame =
1024 GetTableData().GetCell( nRow, nColumn, this );
1025 if( pCellFrame )
1026 xRet = GetMap()->GetContext( pCellFrame );
1027
1028 return xRet;
1029}
1030
1031uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleCaption()
1032{
1033 // captions aren't supported
1034 return uno::Reference< XAccessible >();
1035}
1036
1037uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleSummary()
1038{
1039 // summaries aren't supported
1040 return uno::Reference< XAccessible >();
1041}
1042
1043sal_Bool SAL_CALL SwAccessibleTable::isAccessibleSelected(
1044 sal_Int32 nRow, sal_Int32 nColumn )
1045{
1046 bool bRet = false;
1047
1048 SolarMutexGuard aGuard;
1049
1050 ThrowIfDisposed();
1051
1052 const SwFrame *pFrame =
1053 GetTableData().GetCell( nRow, nColumn, this );
1054 if( pFrame && pFrame->IsCellFrame() )
1055 {
1056 const SwSelBoxes *pSelBoxes = GetSelBoxes();
1057 if( pSelBoxes )
1058 {
1059 const SwCellFrame *pCFrame = static_cast < const SwCellFrame * >( pFrame );
1060 SwTableBox *pBox =
1061 const_cast< SwTableBox *>( pCFrame->GetTabBox() );
1062 bRet = pSelBoxes->find( pBox ) != pSelBoxes->end();
1063 }
1064 }
1065
1066 return bRet;
1067}
1068
1069sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleIndex(
1070 sal_Int32 nRow, sal_Int32 nColumn )
1071{
1072 sal_Int32 nRet = -1;
1073
1074 SolarMutexGuard aGuard;
1075
1076 ThrowIfDisposed();
1077
1078 SwAccessibleChild aCell( GetTableData().GetCell( nRow, nColumn, this ));
1079 if ( aCell.IsValid() )
1080 {
1081 nRet = GetChildIndex( *(GetMap()), aCell );
1082 }
1083
1084 return nRet;
1085}
1086
1087sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRow( sal_Int32 nChildIndex )
1088{
1089 sal_Int32 nRet = -1;
1090
1091 SolarMutexGuard aGuard;
1092
1093 ThrowIfDisposed();
1094
1095 // #i77106#
1096 if ( ( nChildIndex < 0 ) ||
1097 ( nChildIndex >= getAccessibleChildCount() ) )
1098 {
1099 throw lang::IndexOutOfBoundsException();
1100 }
1101
1102 SwAccessibleChild aCell( GetChild( *(GetMap()), nChildIndex ) );
1103 if ( aCell.GetSwFrame() )
1104 {
1105 sal_Int32 nTop = aCell.GetSwFrame()->getFrameArea().Top();
1106 nTop -= GetFrame()->getFrameArea().Top();
1107 Int32Set_Impl::const_iterator aRow(
1108 GetTableData().GetRows().lower_bound( nTop ) );
1109 nRet = static_cast< sal_Int32 >( std::distance(
1110 GetTableData().GetRows().begin(), aRow ) );
1111 }
1112 else
1113 {
1114 OSL_ENSURE( !aCell.IsValid(), "SwAccessibleTable::getAccessibleColumn:"do { if (true && (!(!aCell.IsValid()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1115" ": "), "%s", "SwAccessibleTable::getAccessibleColumn:"
"aCell not expected to be valid."); } } while (false)
1115 "aCell not expected to be valid.")do { if (true && (!(!aCell.IsValid()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1115" ": "), "%s", "SwAccessibleTable::getAccessibleColumn:"
"aCell not expected to be valid."); } } while (false)
;
1116
1117 throw lang::IndexOutOfBoundsException();
1118 }
1119
1120 return nRet;
1121}
1122
1123sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumn(
1124 sal_Int32 nChildIndex )
1125{
1126 sal_Int32 nRet = -1;
1127
1128 SolarMutexGuard aGuard;
1129
1130 ThrowIfDisposed();
1131
1132 // #i77106#
1133 if ( ( nChildIndex < 0 ) ||
1134 ( nChildIndex >= getAccessibleChildCount() ) )
1135 {
1136 throw lang::IndexOutOfBoundsException();
1137 }
1138
1139 SwAccessibleChild aCell( GetChild( *(GetMap()), nChildIndex ) );
1140 if ( aCell.GetSwFrame() )
1141 {
1142 sal_Int32 nLeft = aCell.GetSwFrame()->getFrameArea().Left();
1143 nLeft -= GetFrame()->getFrameArea().Left();
1144 Int32Set_Impl::const_iterator aCol(
1145 GetTableData().GetColumns().lower_bound( nLeft ) );
1146 nRet = static_cast< sal_Int32 >( std::distance(
1147 GetTableData().GetColumns().begin(), aCol ) );
1148 }
1149 else
1150 {
1151 OSL_ENSURE( !aCell.IsValid(), "SwAccessibleTable::getAccessibleColumn:"do { if (true && (!(!aCell.IsValid()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1152" ": "), "%s", "SwAccessibleTable::getAccessibleColumn:"
"aCell not expected to be valid."); } } while (false)
1152 "aCell not expected to be valid.")do { if (true && (!(!aCell.IsValid()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1152" ": "), "%s", "SwAccessibleTable::getAccessibleColumn:"
"aCell not expected to be valid."); } } while (false)
;
1153
1154 throw lang::IndexOutOfBoundsException();
1155 }
1156
1157 return nRet;
1158}
1159
1160OUString SAL_CALL SwAccessibleTable::getImplementationName()
1161{
1162 return "com.sun.star.comp.Writer.SwAccessibleTableView";
1163}
1164
1165sal_Bool SAL_CALL SwAccessibleTable::supportsService(
1166 const OUString& sTestServiceName)
1167{
1168 return cppu::supportsService(this, sTestServiceName);
1169}
1170
1171uno::Sequence< OUString > SAL_CALL SwAccessibleTable::getSupportedServiceNames()
1172{
1173 return { "com.sun.star.table.AccessibleTableView", sAccessibleServiceName };
1174}
1175
1176void SwAccessibleTable::InvalidatePosOrSize( const SwRect& rOldBox )
1177{
1178 SolarMutexGuard aGuard;
1179
1180 //need to update children
1181 std::unique_ptr<SwAccessibleTableData_Impl> pNewTableData = CreateNewTableData();
1182 if( !pNewTableData->CompareExtents( GetTableData() ) )
1183 {
1184 mpTableData = std::move(pNewTableData);
1185 FireTableChangeEvent(*mpTableData);
1186 }
1187 if( HasTableData() )
1188 GetTableData().SetTablePos( GetFrame()->getFrameArea().Pos() );
1189
1190 SwAccessibleContext::InvalidatePosOrSize( rOldBox );
1191}
1192
1193void SwAccessibleTable::Dispose(bool bRecursive, bool bCanSkipInvisible)
1194{
1195 SolarMutexGuard aGuard;
1196 EndListeningAll();
1197 SwAccessibleContext::Dispose(bRecursive, bCanSkipInvisible);
1198}
1199
1200void SwAccessibleTable::DisposeChild( const SwAccessibleChild& rChildFrameOrObj,
1201 bool bRecursive, bool bCanSkipInvisible )
1202{
1203 SolarMutexGuard aGuard;
1204
1205 const SwFrame *pFrame = rChildFrameOrObj.GetSwFrame();
1206 OSL_ENSURE( pFrame, "frame expected" )do { if (true && (!(pFrame))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1206" ": "), "%s", "frame expected"); } } while (false)
;
1207 if( HasTableData() )
1208 {
1209 FireTableChangeEvent( GetTableData() );
1210 ClearTableData();
1211 }
1212
1213 // There are two reason why this method has been called. The first one
1214 // is there is no context for pFrame. The method is then called by
1215 // the map, and we have to call our superclass.
1216 // The other situation is that we have been call by a call to get notified
1217 // about its change. We then must not call the superclass
1218 uno::Reference< XAccessible > xAcc( GetMap()->GetContext( pFrame, false ) );
1219 if( !xAcc.is() )
1220 SwAccessibleContext::DisposeChild( rChildFrameOrObj, bRecursive, bCanSkipInvisible );
1221}
1222
1223void SwAccessibleTable::InvalidateChildPosOrSize( const SwAccessibleChild& rChildFrameOrObj,
1224 const SwRect& rOldBox )
1225{
1226 SolarMutexGuard aGuard;
1227
1228 if( HasTableData() )
1229 {
1230 SAL_WARN_IF( HasTableData() &&do { if (true && (HasTableData() && GetFrame(
)->getFrameArea().Pos() != GetTableData().GetTablePos())) {
switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sw.a11y"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "table has invalid position") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "table has invalid position"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "table has invalid position"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "table has invalid position") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "table has invalid position"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "table has invalid position"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1231 GetFrame()->getFrameArea().Pos() != GetTableData().GetTablePos(),do { if (true && (HasTableData() && GetFrame(
)->getFrameArea().Pos() != GetTableData().GetTablePos())) {
switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sw.a11y"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "table has invalid position") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "table has invalid position"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "table has invalid position"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "table has invalid position") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "table has invalid position"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "table has invalid position"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1232 "sw.a11y", "table has invalid position" )do { if (true && (HasTableData() && GetFrame(
)->getFrameArea().Pos() != GetTableData().GetTablePos())) {
switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sw.a11y"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "table has invalid position") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "table has invalid position"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "table has invalid position"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "table has invalid position") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "table has invalid position"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "table has invalid position"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.a11y"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1232" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1233 if( HasTableData() )
1234 {
1235 std::unique_ptr<SwAccessibleTableData_Impl> pNewTableData = CreateNewTableData(); // #i77106#
1236 if( !pNewTableData->CompareExtents( GetTableData() ) )
1237 {
1238 if (pNewTableData->GetRowCount() != mpTableData->GetRowCount()
1239 && 1 < GetTableData().GetRowCount())
1240 {
1241 Int32Set_Impl::const_iterator aSttCol( GetTableData().GetColumnIter( 0 ) );
1242 Int32Set_Impl::const_iterator aSttRow( GetTableData().GetRowIter( 1 ) );
1243 const SwFrame *pCellFrame = GetTableData().GetCellAtPos( *aSttCol, *aSttRow );
1244 Int32Set_Impl::const_iterator aSttCol2( pNewTableData->GetColumnIter( 0 ) );
1245 Int32Set_Impl::const_iterator aSttRow2( pNewTableData->GetRowIter( 0 ) );
1246 const SwFrame *pCellFrame2 = pNewTableData->GetCellAtPos( *aSttCol2, *aSttRow2 );
1247
1248 if(pCellFrame == pCellFrame2)
1249 {
1250 AccessibleTableModelChange aModelChange;
1251 aModelChange.Type = AccessibleTableModelChangeType::UPDATE;
1252 aModelChange.FirstRow = 0;
1253 aModelChange.LastRow = mpTableData->GetRowCount() - 1;
1254 aModelChange.FirstColumn = 0;
1255 aModelChange.LastColumn = mpTableData->GetColumnCount() - 1;
1256
1257 AccessibleEventObject aEvent;
1258 aEvent.EventId = AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED;
1259 aEvent.NewValue <<= aModelChange;
1260
1261 FireAccessibleEvent( aEvent );
1262 }
1263 }
1264 else
1265 FireTableChangeEvent( GetTableData() );
1266 ClearTableData();
1267 mpTableData = std::move(pNewTableData);
1268 }
1269 }
1270 }
1271
1272 // #i013961# - always call super class method
1273 SwAccessibleContext::InvalidateChildPosOrSize( rChildFrameOrObj, rOldBox );
1274}
1275
1276// XAccessibleSelection
1277
1278void SAL_CALL SwAccessibleTable::selectAccessibleChild(
1279 sal_Int32 nChildIndex )
1280{
1281 SolarMutexGuard aGuard;
1282
1283 ThrowIfDisposed();
1284
1285 if( (nChildIndex < 0) || (nChildIndex >= getAccessibleChildCount()) ) // #i77106#
1286 throw lang::IndexOutOfBoundsException();
1287
1288 // preliminaries: get 'our' table box, and get the cursor shell
1289 const SwTableBox* pBox = GetTableBox( nChildIndex );
1290 OSL_ENSURE( pBox != nullptr, "We need the table box." )do { if (true && (!(pBox != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1290" ": "), "%s", "We need the table box."); } } while
(false)
;
1291
1292 SwCursorShell* pCursorShell = GetCursorShell();
1293 if( pCursorShell == nullptr )
1294 return;
1295
1296 // assure, that child, identified by the given index, isn't already selected.
1297 if ( IsChildSelected( nChildIndex ) )
1298 {
1299 return;
1300 }
1301
1302 // now we can start to do the work: check whether we already have
1303 // a table selection (in 'our' table). If so, extend the
1304 // selection, else select the current cell.
1305
1306 // if we have a selection in a table, check if it's in the
1307 // same table that we're trying to select in
1308 const SwTableNode* pSelectedTable = pCursorShell->IsCursorInTable();
1309 if( pSelectedTable != nullptr )
1310 {
1311 // get top-most table line
1312 const SwTableLine* pUpper = pBox->GetUpper();
1313 while( pUpper->GetUpper() != nullptr )
1314 pUpper = pUpper->GetUpper()->GetUpper();
1315 sal_uInt16 nPos =
1316 pSelectedTable->GetTable().GetTabLines().GetPos( pUpper );
1317 if( nPos == USHRT_MAX(32767 *2 +1) )
1318 pSelectedTable = nullptr;
1319 }
1320
1321 // create the new selection
1322 const SwStartNode* pStartNode = pBox->GetSttNd();
1323 if( pSelectedTable == nullptr || !pCursorShell->GetTableCrs() )
1324 {
1325 pCursorShell->StartAction();
1326 // Set cursor into current cell. This deletes any table cursor.
1327 SwPaM aPaM( *pStartNode );
1328 aPaM.Move( fnMoveForward, GoInNode );
1329 Select( aPaM );
1330 // Move cursor to the end of the table creating a selection and a table
1331 // cursor.
1332 pCursorShell->SetMark();
1333 pCursorShell->MoveTable( GotoCurrTable, fnTableEnd );
1334 // now set the cursor into the cell again.
1335 SwPaM *pPaM = pCursorShell->GetTableCrs() ? pCursorShell->GetTableCrs()
1336 : pCursorShell->GetCursor();
1337 *pPaM->GetPoint() = *pPaM->GetMark();
1338 pCursorShell->EndAction();
1339 // we now have one cell selected!
1340 }
1341 else
1342 {
1343 // if the cursor is already in this table,
1344 // expand the current selection (i.e., set
1345 // point to new position; keep mark)
1346 SwPaM aPaM( *pStartNode );
1347 aPaM.Move( fnMoveForward, GoInNode );
1348 aPaM.SetMark();
1349 const SwPaM *pPaM = pCursorShell->GetTableCrs() ? pCursorShell->GetTableCrs()
1350 : pCursorShell->GetCursor();
1351 *(aPaM.GetMark()) = *pPaM->GetMark();
1352 Select( aPaM );
1353
1354 }
1355}
1356
1357sal_Bool SAL_CALL SwAccessibleTable::isAccessibleChildSelected(
1358 sal_Int32 nChildIndex )
1359{
1360 SolarMutexGuard aGuard;
1361
1362 ThrowIfDisposed();
1363
1364 if( (nChildIndex < 0) || (nChildIndex >= getAccessibleChildCount()) ) // #i77106#
1365 throw lang::IndexOutOfBoundsException();
1366
1367 return IsChildSelected( nChildIndex );
1368}
1369
1370void SAL_CALL SwAccessibleTable::clearAccessibleSelection( )
1371{
1372 SolarMutexGuard aGuard;
1373
1374 ThrowIfDisposed();
1375
1376 SwCursorShell* pCursorShell = GetCursorShell();
1377 if( pCursorShell != nullptr )
1378 {
1379 pCursorShell->StartAction();
1380 pCursorShell->ClearMark();
1381 pCursorShell->EndAction();
1382 }
1383}
1384
1385void SAL_CALL SwAccessibleTable::selectAllAccessibleChildren( )
1386{
1387 // first clear selection, then select first and last child
1388 clearAccessibleSelection();
1389 selectAccessibleChild( 0 );
1390 selectAccessibleChild( getAccessibleChildCount()-1 ); // #i77106#
1391}
1392
1393sal_Int32 SAL_CALL SwAccessibleTable::getSelectedAccessibleChildCount( )
1394{
1395 SolarMutexGuard aGuard;
1396
1397 ThrowIfDisposed();
1398
1399 // iterate over all children and count isAccessibleChildSelected()
1400 sal_Int32 nCount = 0;
1401
1402 sal_Int32 nChildren = getAccessibleChildCount(); // #i71106#
1403 for( sal_Int32 n = 0; n < nChildren; n++ )
1404 if( IsChildSelected( n ) )
1405 nCount++;
1406
1407 return nCount;
1408}
1409
1410uno::Reference<XAccessible> SAL_CALL SwAccessibleTable::getSelectedAccessibleChild(
1411 sal_Int32 nSelectedChildIndex )
1412{
1413 SolarMutexGuard aGuard;
1414
1415 ThrowIfDisposed();
1416
1417 // parameter checking (part 1): index lower 0
1418 if( nSelectedChildIndex < 0 )
1419 throw lang::IndexOutOfBoundsException();
1420
1421 sal_Int32 nChildIndex = GetIndexOfSelectedChild( nSelectedChildIndex );
1422
1423 // parameter checking (part 2): index higher than selected children?
1424 if( nChildIndex < 0 )
1425 throw lang::IndexOutOfBoundsException();
1426
1427 // #i77106#
1428 if ( nChildIndex >= getAccessibleChildCount() )
1429 {
1430 throw lang::IndexOutOfBoundsException();
1431 }
1432
1433 return getAccessibleChild( nChildIndex );
1434}
1435
1436// index has to be treated as global child index.
1437void SAL_CALL SwAccessibleTable::deselectAccessibleChild(
1438 sal_Int32 nChildIndex )
1439{
1440 SolarMutexGuard aGuard;
1441
1442 ThrowIfDisposed();
1443
1444 SwCursorShell* pCursorShell = GetCursorShell();
1445
1446 // index has to be treated as global child index
1447 if ( !pCursorShell )
1448 throw lang::IndexOutOfBoundsException();
1449
1450 // assure, that given child index is in bounds.
1451 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) // #i77106#
1452 throw lang::IndexOutOfBoundsException();
1453
1454 // assure, that child, identified by the given index, is selected.
1455 if ( !IsChildSelected( nChildIndex ) )
1456 return;
1457
1458 const SwTableBox* pBox = GetTableBox( nChildIndex );
1459 OSL_ENSURE( pBox != nullptr, "We need the table box." )do { if (true && (!(pBox != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
":" "1459" ": "), "%s", "We need the table box."); } } while
(false)
;
1460
1461 // If we unselect point, then set cursor to mark. If we clear another
1462 // selected box, then set cursor to point.
1463 // reduce selection to mark.
1464 SwPaM *pPaM = pCursorShell->GetTableCrs() ? pCursorShell->GetTableCrs()
1465 : pCursorShell->GetCursor();
1466 bool bDeselectPoint =
1467 pBox->GetSttNd() ==
1468 pPaM->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1469
1470 SwPaM aPaM( bDeselectPoint ? *pPaM->GetMark() : *pPaM->GetPoint() );
1471
1472 pCursorShell->StartAction();
1473
1474 // Set cursor into either point or mark
1475 Select( aPaM );
1476 // Move cursor to the end of the table creating a selection and a table
1477 // cursor.
1478 pCursorShell->SetMark();
1479 pCursorShell->MoveTable( GotoCurrTable, fnTableEnd );
1480 // now set the cursor into the cell again.
1481 pPaM = pCursorShell->GetTableCrs() ? pCursorShell->GetTableCrs()
1482 : pCursorShell->GetCursor();
1483 *pPaM->GetPoint() = *pPaM->GetMark();
1484 pCursorShell->EndAction();
1485}
1486
1487sal_Int32 SAL_CALL SwAccessibleTable::getBackground()
1488{
1489 const SvxBrushItem &rBack = GetFrame()->GetAttrSet()->GetBackground();
1490 Color crBack = rBack.GetColor();
1491
1492 if (COL_AUTO == crBack)
1493 {
1494 uno::Reference<XAccessible> xAccDoc = getAccessibleParent();
1495 if (xAccDoc.is())
1496 {
1497 uno::Reference<XAccessibleComponent> xComponentDoc(xAccDoc,uno::UNO_QUERY);
1498 if (xComponentDoc.is())
1499 {
1500 crBack = Color(xComponentDoc->getBackground());
1501 }
1502 }
1503 }
1504 return sal_Int32(crBack);
1505}
1506
1507void SwAccessibleTable::FireSelectionEvent( )
1508{
1509 AccessibleEventObject aEvent;
1510
1511 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
1512
1513 for (const auto& rCell : m_vecCellRemove)
1514 {
1515 // fdo#57197: check if the object is still alive
1516 uno::Reference<XAccessible> const xAcc(rCell.second);
1517 if (xAcc.is())
1518 {
1519 SwAccessibleContext *const pAccCell(rCell.first);
1520 assert(pAccCell)(static_cast <bool> (pAccCell) ? void (0) : __assert_fail
("pAccCell", "/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
, 1520, __extension__ __PRETTY_FUNCTION__))
;
1521 pAccCell->FireAccessibleEvent(aEvent);
1522 }
1523 }
1524
1525 if (m_vecCellAdd.size() <= SELECTION_WITH_NUM)
1526 {
1527 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD;
1528 for (const auto& rCell : m_vecCellAdd)
1529 {
1530 // fdo#57197: check if the object is still alive
1531 uno::Reference<XAccessible> const xAcc(rCell.second);
1532 if (xAcc.is())
1533 {
1534 SwAccessibleContext *const pAccCell(rCell.first);
1535 assert(pAccCell)(static_cast <bool> (pAccCell) ? void (0) : __assert_fail
("pAccCell", "/home/maarten/src/libreoffice/core/sw/source/core/access/acctable.cxx"
, 1535, __extension__ __PRETTY_FUNCTION__))
;
1536 pAccCell->FireAccessibleEvent(aEvent);
1537 }
1538 }
1539 return ;
1540 }
1541 else
1542 {
1543 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1544 FireAccessibleEvent(aEvent);
1545 }
1546}
1547
1548void SwAccessibleTable::AddSelectionCell(
1549 SwAccessibleContext *const pAccCell, bool const bAddOrRemove)
1550{
1551 uno::Reference<XAccessible> const xTmp(pAccCell);
1552 if (bAddOrRemove)
1553 {
1554 m_vecCellAdd.emplace_back(pAccCell, xTmp);
1555 }
1556 else
1557 {
1558 m_vecCellRemove.emplace_back(pAccCell, xTmp);
1559 }
1560}
1561
1562// XAccessibleTableSelection
1563sal_Bool SAL_CALL SwAccessibleTable::selectRow( sal_Int32 row )
1564{
1565 SolarMutexGuard g;
1566
1567 if( isAccessibleColumnSelected( row ) )
1568 return true;
1569
1570 long lColumnCount = getAccessibleColumnCount();
1571 for(long lCol = 0; lCol < lColumnCount; lCol ++)
1572 {
1573 long lChildIndex = getAccessibleIndex(row, lCol);
1574 selectAccessibleChild(lChildIndex);
1575 }
1576
1577 return true;
1578}
1579sal_Bool SAL_CALL SwAccessibleTable::selectColumn( sal_Int32 column )
1580{
1581 SolarMutexGuard g;
1582
1583 if( isAccessibleColumnSelected( column ) )
1584 return true;
1585
1586 long lRowCount = getAccessibleRowCount();
1587
1588 for(long lRow = 0; lRow < lRowCount; lRow ++)
1589 {
1590 long lChildIndex = getAccessibleIndex(lRow, column);
1591 selectAccessibleChild(lChildIndex);
1592 }
1593 return true;
1594}
1595
1596sal_Bool SAL_CALL SwAccessibleTable::unselectRow( sal_Int32 row )
1597{
1598 SolarMutexGuard g;
1599
1600 if( isAccessibleSelected( row , 0 ) && isAccessibleSelected( row , getAccessibleColumnCount()-1 ) )
1601 {
1602 SwCursorShell* pCursorShell = GetCursorShell();
1603 if( pCursorShell != nullptr )
1604 {
1605 pCursorShell->StartAction();
1606 pCursorShell->ClearMark();
1607 pCursorShell->EndAction();
1608 return true;
1609 }
1610 }
1611 return true;
1612}
1613
1614sal_Bool SAL_CALL SwAccessibleTable::unselectColumn( sal_Int32 column )
1615{
1616 SolarMutexGuard g;
1617
1618 if( isAccessibleSelected( 0 , column ) && isAccessibleSelected( getAccessibleRowCount()-1,column))
1619 {
1620 SwCursorShell* pCursorShell = GetCursorShell();
1621 if( pCursorShell != nullptr )
1622 {
1623 pCursorShell->StartAction();
1624 pCursorShell->ClearMark();
1625 pCursorShell->EndAction();
1626 return true;
1627 }
1628 }
1629 return true;
1630}
1631
1632// #i77106# - implementation of class <SwAccessibleTableColHeaders>
1633SwAccessibleTableColHeaders::SwAccessibleTableColHeaders(
1634 std::shared_ptr<SwAccessibleMap> const& pMap,
1635 const SwTabFrame *const pTabFrame)
1636 : SwAccessibleTable(pMap, pTabFrame)
3
Calling constructor for 'SwAccessibleTable'
1637{
1638 SolarMutexGuard aGuard;
1639
1640 const SwFrameFormat* pFrameFormat = pTabFrame->GetFormat();
1641 if(pFrameFormat)
1642 StartListening(const_cast<SwFrameFormat*>(pFrameFormat)->GetNotifier());
1643 const OUString aName = pFrameFormat->GetName() + "-ColumnHeaders";
1644
1645 SetName( aName + "-" + OUString::number( pTabFrame->GetPhyPageNum() ) );
1646
1647 const OUString sArg2( GetFormattedPageNumber() );
1648
1649 SetDesc( GetResource( STR_ACCESS_TABLE_DESCreinterpret_cast<char const *>("STR_ACCESS_TABLE_DESC" "\004"
u8"$(ARG1) on page $(ARG2)")
, &aName, &sArg2 ) );
1650
1651 NotRegisteredAtAccessibleMap(); // #i85634#
1652}
1653
1654std::unique_ptr<SwAccessibleTableData_Impl> SwAccessibleTableColHeaders::CreateNewTableData()
1655{
1656 const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>( GetFrame() );
1657 return std::unique_ptr<SwAccessibleTableData_Impl>(new SwAccessibleTableData_Impl( *(GetMap()), pTabFrame, IsInPagePreview(), true ));
1658}
1659
1660void SwAccessibleTableColHeaders::Notify(const SfxHint& )
1661{
1662}
1663
1664// XInterface
1665uno::Any SAL_CALL SwAccessibleTableColHeaders::queryInterface( const uno::Type& aType )
1666{
1667 return SwAccessibleTable::queryInterface( aType );
1668}
1669
1670// XAccessibleContext
1671sal_Int32 SAL_CALL SwAccessibleTableColHeaders::getAccessibleChildCount()
1672{
1673 SolarMutexGuard aGuard;
1674
1675 ThrowIfDisposed();
1676
1677 sal_Int32 nCount = 0;
1678
1679 const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>( GetFrame() );
1680 const SwAccessibleChildSList aVisList( GetVisArea(), *pTabFrame, *(GetMap()) );
1681 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
1682 while( aIter != aVisList.end() )
1683 {
1684 const SwAccessibleChild& rLower = *aIter;
1685 if( rLower.IsAccessible( IsInPagePreview() ) )
1686 {
1687 nCount++;
1688 }
1689 else if( rLower.GetSwFrame() )
1690 {
1691 // There are no unaccessible SdrObjects that count
1692 if ( !rLower.GetSwFrame()->IsRowFrame() ||
1693 pTabFrame->IsInHeadline( *(rLower.GetSwFrame()) ) )
1694 {
1695 nCount += SwAccessibleFrame::GetChildCount( *(GetMap()),
1696 GetVisArea(),
1697 rLower.GetSwFrame(),
1698 IsInPagePreview() );
1699 }
1700 }
1701 ++aIter;
1702 }
1703
1704 return nCount;
1705}
1706
1707uno::Reference< XAccessible> SAL_CALL
1708 SwAccessibleTableColHeaders::getAccessibleChild (sal_Int32 nIndex)
1709{
1710 if ( nIndex < 0 || nIndex >= getAccessibleChildCount() )
1711 {
1712 throw lang::IndexOutOfBoundsException();
1713 }
1714
1715 return SwAccessibleTable::getAccessibleChild( nIndex );
1716}
1717
1718// XAccessibleTable
1719uno::Reference< XAccessibleTable >
1720 SAL_CALL SwAccessibleTableColHeaders::getAccessibleRowHeaders()
1721{
1722 return uno::Reference< XAccessibleTable >();
1723}
1724
1725uno::Reference< XAccessibleTable >
1726 SAL_CALL SwAccessibleTableColHeaders::getAccessibleColumnHeaders()
1727{
1728 return uno::Reference< XAccessibleTable >();
1729}
1730
1731// XServiceInfo
1732
1733OUString SAL_CALL SwAccessibleTableColHeaders::getImplementationName()
1734{
1735 static const char sImplName[] = "com.sun.star.comp.Writer.SwAccessibleTableColumnHeadersView";
1736 return sImplName;
1737}
1738
1739/* vim:set shiftwidth=4 softtabstop=4 expandtab: */