LibreOffice Module sw (master) 1
accmap.cxx
Go to the documentation of this file.
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 <rtl/ref.hxx>
22#include <utility>
23#include <vcl/window.hxx>
24#include <svx/svdmodel.hxx>
25#include <svx/unomod.hxx>
26#include <algorithm>
27#include <map>
28#include <unordered_map>
29#include <list>
30#include <vector>
31#include <accmap.hxx>
32#include "acccontext.hxx"
33#include "accdoc.hxx"
34#include <strings.hrc>
35#include "accpreview.hxx"
36#include "accpage.hxx"
37#include "accpara.hxx"
38#include "accheaderfooter.hxx"
39#include "accfootnote.hxx"
40#include "acctextframe.hxx"
41#include "accgraphic.hxx"
42#include "accembedded.hxx"
43#include "acccell.hxx"
44#include "acctable.hxx"
45#include <fesh.hxx>
46#include <istype.hxx>
47#include <rootfrm.hxx>
48#include <txtfrm.hxx>
49#include <hffrm.hxx>
50#include <ftnfrm.hxx>
51#include <cellfrm.hxx>
52#include <tabfrm.hxx>
53#include <pagefrm.hxx>
54#include <flyfrm.hxx>
55#include <ndtyp.hxx>
59#include <svx/SvxShapeTypes.hxx>
60#include <svx/svdpage.hxx>
61#include <com/sun/star/accessibility/AccessibleEventId.hpp>
62#include <com/sun/star/accessibility/AccessibleStateType.hpp>
63#include <com/sun/star/accessibility/AccessibleRole.hpp>
64#include <com/sun/star/beans/XPropertySet.hpp>
65#include <com/sun/star/document/XShapeEventBroadcaster.hpp>
68#include <pagepreviewlayout.hxx>
69#include <dcontact.hxx>
70#include <svx/svdmark.hxx>
71#include <doc.hxx>
72#include <drawdoc.hxx>
73#include <pam.hxx>
74#include <ndtxt.hxx>
75#include <dflyobj.hxx>
76#include <prevwpage.hxx>
77#include <calbck.hxx>
78#include <undobj.hxx>
80#include <tools/debug.hxx>
81
82using namespace ::com::sun::star;
83using namespace ::com::sun::star::accessibility;
84using namespace ::sw::access;
85
87{
88public:
89 typedef const SwFrame * key_type;
90 typedef uno::WeakReference < XAccessible > mapped_type;
91 typedef std::pair<const key_type,mapped_type> value_type;
92 typedef std::map<key_type, mapped_type>::iterator iterator;
93 typedef std::map<key_type, mapped_type>::const_iterator const_iterator;
94private:
95 std::map <key_type, mapped_type> maMap;
96public:
97
98#if OSL_DEBUG_LEVEL > 0
100#endif
101
103#if OSL_DEBUG_LEVEL > 0
104 : mbLocked( false )
105#endif
106 {}
107
108 iterator begin() { return maMap.begin(); }
109 iterator end() { return maMap.end(); }
110 bool empty() const { return maMap.empty(); }
111 void clear() { maMap.clear(); }
112 iterator find(const key_type& key) { return maMap.find(key); }
113 template<class... Args>
114 std::pair<iterator,bool> emplace(Args&&... args) { return maMap.emplace(std::forward<Args>(args)...); }
115 iterator erase(const_iterator const & pos) { return maMap.erase(pos); }
116};
117
118namespace {
119
120class SwDrawModellListener_Impl : public SfxListener,
121 public ::cppu::WeakImplHelper< document::XShapeEventBroadcaster >
122{
123 mutable ::osl::Mutex maListenerMutex;
125 std::unordered_multimap<css::uno::Reference< css::drawing::XShape >, css::uno::Reference< css::document::XShapeEventListener >> maShapeListeners;
126 SdrModel *mpDrawModel;
127protected:
128 virtual ~SwDrawModellListener_Impl() override;
129
130public:
131 explicit SwDrawModellListener_Impl( SdrModel *pDrawModel );
132
133 // css::document::XEventBroadcaster
134 virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) override;
135 virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) override;
136 // css::document::XShapeEventBroadcaster
137 virtual void SAL_CALL addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override;
138 virtual void SAL_CALL removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override;
139
140 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
141 void Dispose();
142};
143
144}
145
146SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) :
147 maEventListeners( maListenerMutex ),
148 mpDrawModel( pDrawModel )
149{
150 StartListening( *mpDrawModel );
151}
152
153SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
154{
155 Dispose();
156}
157
158void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener )
159{
160 maEventListeners.addInterface( xListener );
161}
162
163void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
164{
165 maEventListeners.removeInterface( xListener );
166}
167
168void SAL_CALL SwDrawModellListener_Impl::addShapeEventListener(
169 const css::uno::Reference< css::drawing::XShape >& xShape,
170 const uno::Reference< document::XShapeEventListener >& xListener )
171{
172 assert(xShape.is() && "no shape?");
173 osl::MutexGuard aGuard(maListenerMutex);
174 maShapeListeners.emplace(xShape, xListener);
175}
176
177void SAL_CALL SwDrawModellListener_Impl::removeShapeEventListener(
178 const css::uno::Reference< css::drawing::XShape >& xShape,
179 const uno::Reference< document::XShapeEventListener >& xListener )
180{
181 osl::MutexGuard aGuard(maListenerMutex);
182 auto [itBegin, itEnd] = maShapeListeners.equal_range(xShape);
183 for (auto it = itBegin; it != itEnd; ++it)
184 if (it->second == xListener)
185 {
186 maShapeListeners.erase(it);
187 return;
188 }
189}
190
192 const SfxHint& rHint )
193{
194 // do not broadcast notifications for writer fly frames, because there
195 // are no shapes that need to know about them.
196 if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
197 return;
198 const SdrHint *pSdrHint = static_cast<const SdrHint*>( &rHint );
199 if (pSdrHint->GetObject() &&
200 ( dynamic_cast< const SwFlyDrawObj* >(pSdrHint->GetObject()) != nullptr ||
201 dynamic_cast< const SwVirtFlyDrawObj* >(pSdrHint->GetObject()) != nullptr ||
202 isType<SdrObject>(pSdrHint->GetObject()) ) )
203 {
204 return;
205 }
206
207 OSL_ENSURE( mpDrawModel, "draw model listener is disposed" );
208 if( !mpDrawModel )
209 return;
210
211 document::EventObject aEvent;
212 if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
213 return;
214
215 ::comphelper::OInterfaceIteratorHelper3 aIter( maEventListeners );
216 while( aIter.hasMoreElements() )
217 {
218 try
219 {
220 aIter.next()->notifyEvent( aEvent );
221 }
222 catch( uno::RuntimeException const & )
223 {
224 TOOLS_WARN_EXCEPTION("sw.a11y", "Runtime exception caught while notifying shape");
225 }
226 }
227
228 // right now, we're only handling the specific event necessary to fix this performance problem
229 if (pSdrHint->GetKind() == SdrHintKind::ObjectChange)
230 {
231 auto pSdrObject = const_cast<SdrObject*>(pSdrHint->GetObject());
232 uno::Reference<drawing::XShape> xShape(pSdrObject->getUnoShape(), uno::UNO_QUERY);
233 osl::MutexGuard aGuard(maListenerMutex);
234 auto [itBegin, itEnd] = maShapeListeners.equal_range(xShape);
235 for (auto it = itBegin; it != itEnd; ++it)
236 it->second->notifyShapeEvent(aEvent);
237 }
238}
239
240void SwDrawModellListener_Impl::Dispose()
241{
242 if (mpDrawModel != nullptr) {
243 EndListening( *mpDrawModel );
244 }
245 mpDrawModel = nullptr;
246}
247
248typedef std::pair < const SdrObject *, ::rtl::Reference < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl;
249
251{
252public:
253
254 typedef const SdrObject * key_type;
255 typedef uno::WeakReference<XAccessible> mapped_type;
256 typedef std::pair<const key_type,mapped_type> value_type;
257 typedef std::map<key_type, mapped_type>::iterator iterator;
258 typedef std::map<key_type, mapped_type>::const_iterator const_iterator;
259
260private:
261
263 std::map<key_type, mapped_type> maMap;
264
265public:
266
268 {
270 maInfo.SetWindow( pMap->GetShell()->GetWin() );
271 maInfo.SetViewForwarder( pMap );
272 uno::Reference < document::XShapeEventBroadcaster > xModelBroadcaster =
273 new SwDrawModellListener_Impl(
275 maInfo.SetModelBroadcaster( xModelBroadcaster );
276 }
277
279
280 const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; }
281
282 std::unique_ptr<SwAccessibleObjShape_Impl[]> Copy( size_t& rSize,
283 const SwFEShell *pFESh,
284 SwAccessibleObjShape_Impl **pSelShape ) const;
285
286 iterator end() { return maMap.end(); }
287 const_iterator cbegin() const { return maMap.cbegin(); }
288 const_iterator cend() const { return maMap.cend(); }
289 bool empty() const { return maMap.empty(); }
290 iterator find(const key_type& key) { return maMap.find(key); }
291 template<class... Args>
292 std::pair<iterator,bool> emplace(Args&&... args) { return maMap.emplace(std::forward<Args>(args)...); }
293 iterator erase(const_iterator const & pos) { return maMap.erase(pos); }
294};
295
297{
298 uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetModelBroadcaster() );
299 if( xBrd.is() )
300 static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose();
301}
302
303std::unique_ptr<SwAccessibleObjShape_Impl[]>
305 size_t& rSize, const SwFEShell *pFESh,
306 SwAccessibleObjShape_Impl **pSelStart ) const
307{
308 std::unique_ptr<SwAccessibleObjShape_Impl[]> pShapes;
309 SwAccessibleObjShape_Impl *pSelShape = nullptr;
310
311 size_t nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
312 rSize = maMap.size();
313
314 if( rSize > 0 )
315 {
316 pShapes.reset(new SwAccessibleObjShape_Impl[rSize]);
317
318 SwAccessibleObjShape_Impl *pShape = pShapes.get();
319 pSelShape = &(pShapes[rSize]);
320 for( const auto& rEntry : maMap )
321 {
322 const SdrObject *pObj = rEntry.first;
323 uno::Reference < XAccessible > xAcc( rEntry.second );
324 if( nSelShapes && pFESh && pFESh->IsObjSelected( *pObj ) )
325 {
326 // selected objects are inserted from the back
327 --pSelShape;
328 pSelShape->first = pObj;
329 pSelShape->second =
330 static_cast < ::accessibility::AccessibleShape* >(
331 xAcc.get() );
332 --nSelShapes;
333 }
334 else
335 {
336 pShape->first = pObj;
337 pShape->second =
338 static_cast < ::accessibility::AccessibleShape* >(
339 xAcc.get() );
340 ++pShape;
341 }
342 }
343 assert(pSelShape == pShape);
344 }
345
346 if( pSelStart )
347 *pSelStart = pSelShape;
348
349 return pShapes;
350}
351
353{
354public:
362
363private:
364 SwRect maOldBox; // the old bounds for CHILD_POS_CHANGED
365 // and POS_CHANGED
366 uno::WeakReference < XAccessible > mxAcc; // The object that fires the event
367 SwAccessibleChild maFrameOrObj; // the child for CHILD_POS_CHANGED and
368 // the same as xAcc for any other
369 // event type
370 EventType meType; // The event type
371 AccessibleStates mnStates; // check states or update caret pos
372
373public:
374 const SwFrame* mpParentFrame; // The object that fires the event
376 {
377 return CHILD_POS_CHANGED == meType && mpParentFrame != nullptr;
378 }
379
380public:
383 SwAccessibleChild aFrameOrObj )
384 : mxAcc( pA ),
385 maFrameOrObj(std::move( aFrameOrObj )),
386 meType( eT ),
388 mpParentFrame( nullptr )
389 {}
390
392 SwAccessibleChild aFrameOrObj )
393 : maFrameOrObj(std::move( aFrameOrObj )),
394 meType( eT ),
396 mpParentFrame( nullptr )
397 {
399 "wrong event constructor, DISPOSE only");
400 }
401
403 : meType( eT ),
405 mpParentFrame( nullptr )
406 {
408 "wrong event constructor, SHAPE_SELECTION only" );
409 }
410
413 SwAccessibleChild aFrameOrObj,
414 const SwRect& rR )
415 : maOldBox( rR ),
416 mxAcc( pA ),
417 maFrameOrObj(std::move( aFrameOrObj )),
418 meType( eT ),
420 mpParentFrame( nullptr )
421 {
424 "wrong event constructor, (CHILD_)POS_CHANGED only" );
425 }
426
429 SwAccessibleChild aFrameOrObj,
430 const AccessibleStates _nStates )
431 : mxAcc( pA ),
432 maFrameOrObj(std::move( aFrameOrObj )),
433 meType( eT ),
434 mnStates( _nStates ),
435 mpParentFrame( nullptr )
436 {
438 "wrong event constructor, CARET_OR_STATES only" );
439 }
440
441 SwAccessibleEvent_Impl( EventType eT, const SwFrame *pParentFrame,
442 SwAccessibleChild aFrameOrObj, const SwRect& rR ) :
443 maOldBox( rR ),
444 maFrameOrObj(std::move( aFrameOrObj )),
445 meType( eT ),
447 mpParentFrame( pParentFrame )
448 {
450 "wrong event constructor, CHILD_POS_CHANGED only" );
451 }
452
453 // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
455 {
456 meType = eT;
457 }
459 {
460 return meType;
461 }
462
464 {
465 uno::Reference < XAccessible > xTmp( mxAcc );
467 static_cast<SwAccessibleContext*>( xTmp.get() ) );
468
469 return xAccImpl;
470 }
471
472 const SwRect& GetOldBox() const
473 {
474 return maOldBox;
475 }
476 // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
477 void SetOldBox( const SwRect& rOldBox )
478 {
479 maOldBox = rOldBox;
480 }
481
482 const SwAccessibleChild& GetFrameOrObj() const
483 {
484 return maFrameOrObj;
485 }
486
487 // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
489 {
490 mnStates |= _nStates;
491 }
492
493 bool IsUpdateCursorPos() const
494 {
495 return bool(mnStates & AccessibleStates::CARET);
496 }
498 {
500 }
502 {
504 }
506 {
508 }
509
511 {
513 }
514
516 {
517 return mnStates;
518 }
519
521 {
522 return mnStates;
523 }
524};
525
527{
528 std::list<SwAccessibleEvent_Impl> maEvents;
530
531public:
533 : mbFiring( false )
534 {}
535
537 {
538 mbFiring = true;
539 }
540 bool IsFiring() const
541 {
542 return mbFiring;
543 }
544
546
547 size_t size() const { return maEvents.size(); }
548 std::list<SwAccessibleEvent_Impl>::iterator begin() { return maEvents.begin(); }
549 std::list<SwAccessibleEvent_Impl>::iterator end() { return maEvents.end(); }
550 std::list<SwAccessibleEvent_Impl>::iterator insert( const std::list<SwAccessibleEvent_Impl>::iterator& aIter,
551 const SwAccessibleEvent_Impl& rEvent )
552 {
553 return maEvents.insert( aIter, rEvent );
554 }
555 std::list<SwAccessibleEvent_Impl>::iterator erase( const std::list<SwAccessibleEvent_Impl>::iterator& aPos )
556 {
557 return maEvents.erase( aPos );
558 }
559};
560
561// see comment in SwAccessibleMap::InvalidatePosOrSize()
562// last case "else if(pParent)" for why this surprising hack exists
564{
565 size_t nSize = size();
566 if (nSize < 2 )
567 {
568 return;
569 }
571 for (auto li = begin(); li != end(); )
572 {
573 if (li->IsNoXaccParentFrame())
574 {
575 lstEvent.insert(lstEvent.end(), *li);
576 li = erase(li);
577 }
578 else
579 ++li;
580 }
581 assert(size() + lstEvent.size() == nSize);
582 maEvents.insert(end(),lstEvent.begin(),lstEvent.end());
583 assert(size() == nSize);
584}
585
586namespace {
587
588struct SwAccessibleChildFunc
589{
590 bool operator()( const SwAccessibleChild& r1,
591 const SwAccessibleChild& r2 ) const
592 {
593 const void *p1 = r1.GetSwFrame()
594 ? static_cast < const void * >( r1.GetSwFrame())
595 : ( r1.GetDrawObject()
596 ? static_cast < const void * >( r1.GetDrawObject() )
597 : static_cast < const void * >( r1.GetWindow() ) );
598 const void *p2 = r2.GetSwFrame()
599 ? static_cast < const void * >( r2.GetSwFrame())
600 : ( r2.GetDrawObject()
601 ? static_cast < const void * >( r2.GetDrawObject() )
602 : static_cast < const void * >( r2.GetWindow() ) );
603 return p1 < p2;
604 }
605};
606
607}
608
610{
611public:
612 typedef SwAccessibleChild key_type;
613 typedef std::list<SwAccessibleEvent_Impl>::iterator mapped_type;
614 typedef std::pair<const key_type,mapped_type> value_type;
615 typedef SwAccessibleChildFunc key_compare;
616 typedef std::map<key_type,mapped_type,key_compare>::iterator iterator;
617 typedef std::map<key_type,mapped_type,key_compare>::const_iterator const_iterator;
618private:
619 std::map <key_type,mapped_type,key_compare> maMap;
620public:
621 iterator end() { return maMap.end(); }
622 iterator find(const key_type& key) { return maMap.find(key); }
623 template<class... Args>
624 std::pair<iterator,bool> emplace(Args&&... args) { return maMap.emplace(std::forward<Args>(args)...); }
625 iterator erase(const_iterator const & pos) { return maMap.erase(pos); }
626};
627
628namespace {
629
630struct SwAccessibleParaSelection
631{
632 TextFrameIndex nStartOfSelection;
633 TextFrameIndex nEndOfSelection;
634
635 SwAccessibleParaSelection(const TextFrameIndex nStartOfSelection_,
636 const TextFrameIndex nEndOfSelection_)
637 : nStartOfSelection(nStartOfSelection_)
638 , nEndOfSelection(nEndOfSelection_)
639 {}
640};
641
642struct SwXAccWeakRefComp
643{
644 bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1,
645 const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const
646 {
647 return _rXAccWeakRef1.get() < _rXAccWeakRef2.get();
648 }
649};
650
651}
652
654{
655public:
656 typedef uno::WeakReference < XAccessible > key_type;
657 typedef SwAccessibleParaSelection mapped_type;
658 typedef std::pair<const key_type,mapped_type> value_type;
659 typedef SwXAccWeakRefComp key_compare;
660 typedef std::map<key_type,mapped_type,key_compare>::iterator iterator;
661 typedef std::map<key_type,mapped_type,key_compare>::const_iterator const_iterator;
662private:
663 std::map<key_type,mapped_type,key_compare> maMap;
664public:
665 iterator begin() { return maMap.begin(); }
666 iterator end() { return maMap.end(); }
667 iterator find(const key_type& key) { return maMap.find(key); }
668 template<class... Args>
669 std::pair<iterator,bool> emplace(Args&&... args) { return maMap.emplace(std::forward<Args>(args)...); }
670 iterator erase(const_iterator const & pos) { return maMap.erase(pos); }
671};
672
673// helper class that stores preview data
675{
676 typedef std::vector<tools::Rectangle> Rectangles;
679
682
684
699 static void AdjustLogicPgRectToVisibleArea( SwRect& _iorLogicPgSwRect,
700 const SwRect& _rPreviewPgSwRect,
701 const Size& _rPreviewWinSize );
702
703public:
705
706 void Update( const SwAccessibleMap& rAccMap,
707 const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
708 const Fraction& _rScale,
709 const SwPageFrame* _pSelectedPageFrame,
710 const Size& _rPreviewWinSize );
711
712 void InvalidateSelection( const SwPageFrame* _pSelectedPageFrame );
713
714 const SwRect& GetVisArea() const { return maVisArea;}
715
720 void AdjustMapMode( MapMode& rMapMode,
721 const Point& rPoint ) const;
722
723 const SwPageFrame *GetSelPage() const { return mpSelPage; }
724
725 void DisposePage(const SwPageFrame *pPageFrame );
726};
727
729 mpSelPage( nullptr )
730{
731}
732
734 const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
735 const Fraction& _rScale,
736 const SwPageFrame* _pSelectedPageFrame,
737 const Size& _rPreviewWinSize )
738{
739 // store preview scaling, maximal preview page size and selected page
740 maScale = _rScale;
741 mpSelPage = _pSelectedPageFrame;
742
743 // prepare loop on preview pages
744 maPreviewRects.clear();
745 maLogicRects.clear();
746 SwAccessibleChild aPage;
748
749 // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and
750 // <maVisArea>
751 for ( auto & rpPreviewPage : _rPreviewPages )
752 {
753 aPage = rpPreviewPage->pPage;
754
755 // add preview page rectangle to <maPreviewRects>
756 tools::Rectangle aPreviewPgRect( rpPreviewPage->aPreviewWinPos, rpPreviewPage->aPageSize );
757 maPreviewRects.push_back( aPreviewPgRect );
758
759 // add logic page rectangle to <maLogicRects>
760 SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) );
761 tools::Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() );
762 maLogicRects.push_back( aLogicPgRect );
763 // union visible area with visible part of logic page rectangle
764 if ( rpPreviewPage->bVisible )
765 {
766 if ( !rpPreviewPage->pPage->IsEmptyPage() )
767 {
768 AdjustLogicPgRectToVisibleArea( aLogicPgSwRect,
769 SwRect( aPreviewPgRect ),
770 _rPreviewWinSize );
771 }
772 if ( maVisArea.IsEmpty() )
773 maVisArea = aLogicPgSwRect;
774 else
775 maVisArea.Union( aLogicPgSwRect );
776 }
777 }
778}
779
780void SwAccPreviewData::InvalidateSelection( const SwPageFrame* _pSelectedPageFrame )
781{
782 mpSelPage = _pSelectedPageFrame;
783 assert(mpSelPage);
784}
785
786namespace {
787
788struct ContainsPredicate
789{
790 const Point& mrPoint;
791 explicit ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {}
792 bool operator() ( const tools::Rectangle& rRect ) const
793 {
794 return rRect.Contains( mrPoint );
795 }
796};
797
798}
799
801 const Point& rPoint ) const
802{
803 // adjust scale
804 rMapMode.SetScaleX( maScale );
805 rMapMode.SetScaleY( maScale );
806
807 // find proper rectangle
808 Rectangles::const_iterator aBegin = maLogicRects.begin();
809 Rectangles::const_iterator aEnd = maLogicRects.end();
810 Rectangles::const_iterator aFound = std::find_if( aBegin, aEnd,
811 ContainsPredicate( rPoint ) );
812
813 if( aFound != aEnd )
814 {
815 // found! set new origin
816 Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft();
817 aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft();
818 rMapMode.SetOrigin( aPoint );
819 }
820 // else: don't adjust MapMode
821}
822
824{
825 if( mpSelPage == pPageFrame )
826 mpSelPage = nullptr;
827}
828
829// adjust logic page rectangle to its visible part
831 SwRect& _iorLogicPgSwRect,
832 const SwRect& _rPreviewPgSwRect,
833 const Size& _rPreviewWinSize )
834{
835 // determine preview window rectangle
836 const SwRect aPreviewWinSwRect( Point( 0, 0 ), _rPreviewWinSize );
837 // calculate visible preview page rectangle
838 SwRect aVisPreviewPgSwRect( _rPreviewPgSwRect );
839 aVisPreviewPgSwRect.Intersection( aPreviewWinSwRect );
840 // adjust logic page rectangle
841 SwTwips nTmpDiff;
842 // left
843 nTmpDiff = aVisPreviewPgSwRect.Left() - _rPreviewPgSwRect.Left();
844 _iorLogicPgSwRect.AddLeft( nTmpDiff );
845 // top
846 nTmpDiff = aVisPreviewPgSwRect.Top() - _rPreviewPgSwRect.Top();
847 _iorLogicPgSwRect.AddTop( nTmpDiff );
848 // right
849 nTmpDiff = _rPreviewPgSwRect.Right() - aVisPreviewPgSwRect.Right();
850 _iorLogicPgSwRect.AddRight( - nTmpDiff );
851 // bottom
852 nTmpDiff = _rPreviewPgSwRect.Bottom() - aVisPreviewPgSwRect.Bottom();
853 _iorLogicPgSwRect.AddBottom( - nTmpDiff );
854}
855
856static bool AreInSameTable( const uno::Reference< XAccessible >& rAcc,
857 const SwFrame *pFrame )
858{
859 bool bRet = false;
860
861 if( pFrame && pFrame->IsCellFrame() && rAcc.is() )
862 {
863 // Is it in the same table? We check that
864 // by comparing the last table frame in the
865 // follow chain, because that's cheaper than
866 // searching the first one.
867 SwAccessibleContext *pAccImpl =
868 static_cast< SwAccessibleContext *>( rAcc.get() );
869 if( pAccImpl->GetFrame()->IsCellFrame() )
870 {
871 const SwTabFrame *pTabFrame1 = pAccImpl->GetFrame()->FindTabFrame();
872 if (pTabFrame1)
873 {
874 while (pTabFrame1->GetFollow())
875 pTabFrame1 = pTabFrame1->GetFollow();
876 }
877
878 const SwTabFrame *pTabFrame2 = pFrame->FindTabFrame();
879 if (pTabFrame2)
880 {
881 while (pTabFrame2->GetFollow())
882 pTabFrame2 = pTabFrame2->GetFollow();
883 }
884
885 bRet = (pTabFrame1 == pTabFrame2);
886 }
887 }
888
889 return bRet;
890}
891
893{
895 if (!xAccImpl.is() && rEvent.mpParentFrame != nullptr)
896 {
898 mpFrameMap->find( rEvent.mpParentFrame );
899 if( aIter != mpFrameMap->end() )
900 {
901 uno::Reference < XAccessible > xAcc( (*aIter).second );
902 if (xAcc.is())
903 {
904 uno::Reference < XAccessibleContext > xContext(xAcc,uno::UNO_QUERY);
905 if (xContext.is() && xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
906 {
907 xAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
908 }
909 }
910 }
911 }
913 {
915 }
916 else if( xAccImpl.is() && xAccImpl->GetFrame() )
917 {
918 if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE &&
919 rEvent.IsInvalidateTextAttrs() )
920 {
921 xAccImpl->InvalidateAttr();
922 }
923 switch( rEvent.GetType() )
924 {
926 xAccImpl->InvalidateContent();
927 break;
929 xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() );
930 break;
932 xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrameOrObj(),
933 rEvent.GetOldBox() );
934 break;
936 assert(!"dispose event has been stored");
937 break;
939 // nothing to do here - handled above
940 break;
941 default:
942 break;
943 }
945 {
946 if( rEvent.IsUpdateCursorPos() )
947 xAccImpl->InvalidateCursorPos();
948 if( rEvent.IsInvalidateStates() )
949 xAccImpl->InvalidateStates( rEvent.GetStates() );
950 if( rEvent.IsInvalidateRelation() )
951 {
952 // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and
953 // CONTENT_FLOWS_TO_RELATION_CHANGED are possible
955 {
956 xAccImpl->InvalidateRelation(
957 AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED );
958 }
960 {
961 xAccImpl->InvalidateRelation(
962 AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
963 }
964 }
965
966 if ( rEvent.IsInvalidateTextSelection() )
967 {
968 xAccImpl->InvalidateTextSelection();
969 }
970 }
971 }
972}
973
975{
976 osl::MutexGuard aGuard( maEventMutex );
977
978 if( !mpEvents )
980 if( !mpEventMap )
982
983 if( mpEvents->IsFiring() )
984 {
985 // While events are fired new ones are generated. They have to be fired
986 // now. This does not work for DISPOSE events!
987 OSL_ENSURE( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
988 "dispose event while firing events" );
989 FireEvent( rEvent );
990 }
991 else
992 {
993
995 mpEventMap->find( rEvent.GetFrameOrObj() );
996 if( aIter != mpEventMap->end() )
997 {
998 SwAccessibleEvent_Impl aEvent( *(*aIter).second );
999 assert( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE &&
1000 "dispose events should not be stored" );
1001 bool bAppendEvent = true;
1002 switch( rEvent.GetType() )
1003 {
1005 // A CARET_OR_STATES event is added to any other
1006 // event only. It is broadcasted after any other event, so the
1007 // event should be put to the back.
1008 OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1009 "invalid event combination" );
1010 aEvent.SetStates( rEvent.GetAllStates() );
1011 break;
1013 // An INVALID_CONTENT event overwrites a CARET_OR_STATES
1014 // event (but keeps its flags) and it is contained in a
1015 // POS_CHANGED event.
1016 // Therefore, the event's type has to be adapted and the event
1017 // has to be put at the end.
1018 //
1019 // fdo#56031 An INVALID_CONTENT event overwrites a INVALID_ATTR
1020 // event and overwrites its flags
1021 OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1022 "invalid event combination" );
1025 else if ( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR )
1026 {
1028 aEvent.SetStates( rEvent.GetAllStates() );
1029 }
1030
1031 break;
1033 // A pos changed event overwrites CARET_STATES (keeping its
1034 // flags) as well as INVALID_CONTENT. The old box position
1035 // has to be stored however if the old event is not a
1036 // POS_CHANGED itself.
1037 OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1038 "invalid event combination" );
1040 aEvent.SetOldBox( rEvent.GetOldBox() );
1042 break;
1044 // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED
1045 // events. The only action that needs to be done again is
1046 // to put the old event to the back. The new one cannot be used,
1047 // because we are interested in the old frame bounds.
1048 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1049 "invalid event combination" );
1050 break;
1052 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION,
1053 "invalid event combination" );
1054 break;
1056 // DISPOSE events overwrite all others. They are not stored
1057 // but executed immediately to avoid broadcasting of
1058 // nonfunctional objects. So what needs to be done here is to
1059 // remove all events for the frame in question.
1060 bAppendEvent = false;
1061 break;
1063 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR,
1064 "invalid event combination" );
1065 break;
1066 }
1067 if( bAppendEvent )
1068 {
1069 mpEvents->erase( (*aIter).second );
1070 (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent );
1071 }
1072 else
1073 {
1074 mpEvents->erase( (*aIter).second );
1075 mpEventMap->erase( aIter );
1076 }
1077 }
1078 else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
1079 {
1080 mpEventMap->emplace( rEvent.GetFrameOrObj(),
1081 mpEvents->insert( mpEvents->end(), rEvent ) );
1082 }
1083 }
1084}
1085
1087 const uno::Reference< XAccessible >& rAcc )
1088{
1089 SwAccessibleContext *pAccImpl =
1090 static_cast< SwAccessibleContext *>( rAcc.get() );
1091 assert(pAccImpl);
1092 assert(pAccImpl->GetFrame());
1093 if( GetShell()->ActionPend() )
1094 {
1096 pAccImpl,
1097 SwAccessibleChild(pAccImpl->GetFrame()),
1099 AppendEvent( aEvent );
1100 }
1101 else
1102 {
1103 FireEvents();
1104 // While firing events the current frame might have
1105 // been disposed because it moved out of the visible area.
1106 // Setting the cursor for such frames is useless and even
1107 // causes asserts.
1108 if( pAccImpl->GetFrame() )
1109 pAccImpl->InvalidateCursorPos();
1110 }
1111}
1112
1114{
1115 if( GetShell()->ActionPend() )
1116 {
1120 }
1121 else
1122 {
1123 FireEvents();
1125 }
1126}
1127
1128//This method should implement the following functions:
1129//1.find the shape objects and set the selected state.
1130//2.find the Swframe objects and set the selected state.
1131//3.find the paragraph objects and set the selected state.
1133{
1134 std::unique_ptr<SwAccessibleObjShape_Impl[]> pShapes;
1135 SwAccessibleObjShape_Impl *pSelShape = nullptr;
1136 size_t nShapes = 0;
1137
1138 const SwViewShell *pVSh = GetShell();
1139 const SwFEShell *pFESh = dynamic_cast<const SwFEShell*>(pVSh);
1140 SwPaM* pCursor = pFESh ? pFESh->GetCursor( false /* ??? */ ) : nullptr;
1141
1142 //const size_t nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1143
1144 {
1145 osl::MutexGuard aGuard( maMutex );
1146 if( mpShapeMap )
1147 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1148 }
1149
1150 bool bIsSelAll =IsDocumentSelAll();
1151
1152 if( mpShapeMap )
1153 {
1154 //Checked for shapes.
1157
1158 if( bIsSelAll)
1159 {
1160 while( aIter != aEndIter )
1161 {
1162 uno::Reference < XAccessible > xAcc( (*aIter).second );
1163 if( xAcc.is() )
1164 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1165
1166 ++aIter;
1167 }
1168 }
1169 else
1170 {
1171 while( aIter != aEndIter )
1172 {
1173 const SwFrameFormat *pFrameFormat = (*aIter).first ? ::FindFrameFormat( (*aIter).first ) : nullptr;
1174 if( !pFrameFormat )
1175 {
1176 ++aIter;
1177 continue;
1178 }
1179 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1180 const SwPosition *pPos = rAnchor.GetContentAnchor();
1181
1182 if(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
1183 {
1184 uno::Reference < XAccessible > xAcc( (*aIter).second );
1185 if(xAcc.is())
1186 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1187
1188 ++aIter;
1189 continue;
1190 }
1191
1192 if( !pPos )
1193 {
1194 ++aIter;
1195 continue;
1196 }
1197 if( pPos->GetNode().GetTextNode() )
1198 {
1199 int nIndex = pPos->GetContentIndex();
1200 bool bMarked = false;
1201 if( pCursor != nullptr )
1202 {
1203 const SwTextNode* pNode = pPos->GetNode().GetTextNode();
1204 SwTextFrame const*const pFrame(static_cast<SwTextFrame*>(pNode->getLayoutFrame(pVSh->GetLayout())));
1205 SwNodeOffset nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
1206 SwNodeOffset nLastNode;
1207 if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
1208 {
1209 nLastNode = pMerged->pLastNode->GetIndex();
1210 }
1211 else
1212 {
1213 nLastNode = nFirstNode;
1214 }
1215
1216 SwNodeOffset nHere = pNode->GetIndex();
1217
1218 for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
1219 {
1220 // ignore, if no mark
1221 if( rTmpCursor.HasMark() )
1222 {
1223 bMarked = true;
1224 // check whether nHere is 'inside' pCursor
1225 SwPosition* pStart = rTmpCursor.Start();
1226 SwNodeOffset nStartIndex = pStart->GetNodeIndex();
1227 SwPosition* pEnd = rTmpCursor.End();
1228 SwNodeOffset nEndIndex = pEnd->GetNodeIndex();
1229 if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
1230 {
1231 if( rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
1232 {
1233 if( ( ((nHere == nStartIndex) && (nIndex >= pStart->GetContentIndex())) || (nHere > nStartIndex) )
1234 &&( ((nHere == nEndIndex) && (nIndex < pEnd->GetContentIndex())) || (nHere < nEndIndex) ) )
1235 {
1236 uno::Reference < XAccessible > xAcc( (*aIter).second );
1237 if( xAcc.is() )
1238 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1239 }
1240 else
1241 {
1242 uno::Reference < XAccessible > xAcc( (*aIter).second );
1243 if( xAcc.is() )
1244 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1245 }
1246 }
1247 else if( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA )
1248 {
1249 uno::Reference<XAccessible> const xAcc((*aIter).second);
1250 if (xAcc.is())
1251 {
1252 if (IsSelectFrameAnchoredAtPara(*pPos, *pStart, *pEnd))
1253 {
1254 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1255 }
1256 else
1257 {
1258 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1259 }
1260 }
1261 }
1262 else if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
1263 {
1264 uno::Reference<XAccessible> const xAcc((*aIter).second);
1265 if (xAcc.is())
1266 {
1267 if (IsDestroyFrameAnchoredAtChar(*pPos, *pStart, *pEnd))
1268 {
1269 static_cast<::accessibility::AccessibleShape*>(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1270 }
1271 else
1272 {
1273 static_cast<::accessibility::AccessibleShape*>(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1274 }
1275 }
1276 }
1277 }
1278 }
1279 }
1280 }
1281 if( !bMarked )
1282 {
1283 SwAccessibleObjShape_Impl *pShape = pShapes.get();
1284 size_t nNumShapes = nShapes;
1285 while( nNumShapes )
1286 {
1287 if( pShape < pSelShape && (pShape->first==(*aIter).first) )
1288 {
1289 uno::Reference < XAccessible > xAcc( (*aIter).second );
1290 if(xAcc.is())
1291 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1292 }
1293 --nNumShapes;
1294 ++pShape;
1295 }
1296 }
1297 }
1298
1299 ++aIter;
1300 }//while( aIter != aEndIter )
1301 }//else
1302 }
1303
1304 pShapes.reset();
1305
1306 //Checked for FlyFrame
1307 if (mpFrameMap)
1308 {
1310 while( aIter != mpFrameMap->end() )
1311 {
1312 const SwFrame *pFrame = (*aIter).first;
1313 if(pFrame->IsFlyFrame())
1314 {
1315 uno::Reference < XAccessible > xAcc = (*aIter).second;
1316
1317 if(xAcc.is())
1318 {
1319 SwAccessibleFrameBase *pAccFrame = static_cast< SwAccessibleFrameBase * >(xAcc.get());
1320 bool bFrameChanged = pAccFrame->SetSelectedState( true );
1321 if (bFrameChanged)
1322 {
1323 const SwFlyFrame *pFlyFrame = static_cast< const SwFlyFrame * >( pFrame );
1324 const SwFrameFormat *pFrameFormat = pFlyFrame->GetFormat();
1325 if (pFrameFormat)
1326 {
1327 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1328 if( rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
1329 {
1330 uno::Reference< XAccessible > xAccParent = pAccFrame->getAccessibleParent();
1331 if (xAccParent.is())
1332 {
1333 uno::Reference< XAccessibleContext > xAccContext = xAccParent->getAccessibleContext();
1334 if(xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1335 {
1336 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xAccContext.get());
1337 if(pAccFrame->IsSelectedInDoc())
1338 {
1339 m_setParaAdd.insert(pAccPara);
1340 }
1341 else if(m_setParaAdd.count(pAccPara) == 0)
1342 {
1343 m_setParaRemove.insert(pAccPara);
1344 }
1345 }
1346 }
1347 }
1348 }
1349 }
1350 }
1351 }
1352 ++aIter;
1353 }
1354 }
1355
1356 typedef std::vector< SwAccessibleContext* > VEC_PARA;
1357 VEC_PARA vecAdd;
1358 VEC_PARA vecRemove;
1359 //Checked for Paras.
1360 bool bMarkChanged = false;
1362 if( pCursor != nullptr )
1363 {
1364 for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
1365 {
1366 if( rTmpCursor.HasMark() )
1367 {
1368 SwNodeIndex nStartIndex( rTmpCursor.Start()->GetNode() );
1369 SwNodeIndex nEndIndex( rTmpCursor.End()->GetNode() );
1370 for (; nStartIndex <= nEndIndex; ++nStartIndex)
1371 {
1372 SwFrame *pFrame = nullptr;
1373 if(nStartIndex.GetNode().IsContentNode())
1374 {
1375 SwContentNode* pCNd = static_cast<SwContentNode*>(&(nStartIndex.GetNode()));
1377 if (mapTemp.find(pFrame) != mapTemp.end())
1378 {
1379 continue; // sw_redlinehide: once is enough
1380 }
1381 }
1382 else if( nStartIndex.GetNode().IsTableNode() )
1383 {
1384 SwTableNode * pTable = static_cast<SwTableNode *>(&(nStartIndex.GetNode()));
1385 SwTableFormat* pFormat = pTable->GetTable().GetFrameFormat();
1386 pFrame = SwIterator<SwFrame, SwTableFormat>(*pFormat).First();
1387 }
1388
1389 if( pFrame && mpFrameMap)
1390 {
1391 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pFrame );
1392 if( aIter != mpFrameMap->end() )
1393 {
1394 uno::Reference < XAccessible > xAcc = (*aIter).second;
1395 bool isChanged = false;
1396 if( xAcc.is() )
1397 {
1398 isChanged = static_cast< SwAccessibleContext * >(xAcc.get())->SetSelectedState( true );
1399 }
1400 if(!isChanged)
1401 {
1402 SwAccessibleContextMap_Impl::iterator aEraseIter = mpSelectedFrameMap->find( pFrame );
1403 if(aEraseIter != mpSelectedFrameMap->end())
1404 mpSelectedFrameMap->erase(aEraseIter);
1405 }
1406 else
1407 {
1408 bMarkChanged = true;
1409 vecAdd.push_back(static_cast< SwAccessibleContext * >(xAcc.get()));
1410 }
1411
1412 mapTemp.emplace( pFrame, xAcc );
1413 }
1414 }
1415 }
1416 }
1417 }
1418 }
1419 if( !mpSelectedFrameMap )
1421 if( !mpSelectedFrameMap->empty() )
1422 {
1424 while( aIter != mpSelectedFrameMap->end() )
1425 {
1426 uno::Reference < XAccessible > xAcc = (*aIter).second;
1427 if(xAcc.is())
1428 static_cast< SwAccessibleContext * >(xAcc.get())->SetSelectedState( false );
1429 ++aIter;
1430 vecRemove.push_back(static_cast< SwAccessibleContext * >(xAcc.get()));
1431 }
1432 bMarkChanged = true;
1433 mpSelectedFrameMap->clear();
1434 }
1435
1437 while( aIter != mapTemp.end() )
1438 {
1439 mpSelectedFrameMap->emplace( (*aIter).first, (*aIter).second );
1440 ++aIter;
1441 }
1442 mapTemp.clear();
1443
1444 if( !(bMarkChanged && mpFrameMap))
1445 return;
1446
1447 for (SwAccessibleContext* pAccPara : vecAdd)
1448 {
1449 AccessibleEventObject aEvent;
1450 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1451 if (pAccPara)
1452 {
1453 pAccPara->FireAccessibleEvent( aEvent );
1454 }
1455 }
1456 for (SwAccessibleContext* pAccPara : vecRemove)
1457 {
1458 AccessibleEventObject aEvent;
1459 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
1460 if (pAccPara)
1461 {
1462 pAccPara->FireAccessibleEvent( aEvent );
1463 }
1464 }
1465}
1466
1467//Merge with DoInvalidateShapeFocus
1468void SwAccessibleMap::DoInvalidateShapeSelection(bool bInvalidateFocusMode /*=false*/)
1469{
1470 std::unique_ptr<SwAccessibleObjShape_Impl[]> pShapes;
1471 SwAccessibleObjShape_Impl *pSelShape = nullptr;
1472 size_t nShapes = 0;
1473
1474 const SwViewShell *pVSh = GetShell();
1475 const SwFEShell *pFESh = dynamic_cast<const SwFEShell*>(pVSh);
1476 const size_t nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1477
1478 //when InvalidateFocus Call this function ,and the current selected shape count is not 1 ,
1479 //return
1480 if (bInvalidateFocusMode && nSelShapes != 1)
1481 {
1482 return;
1483 }
1484 {
1485 osl::MutexGuard aGuard( maMutex );
1486 if( mpShapeMap )
1487 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1488 }
1489
1490 if( !pShapes )
1491 return;
1492
1493 typedef std::vector< ::rtl::Reference < ::accessibility::AccessibleShape > > VEC_SHAPE;
1494 VEC_SHAPE vecxShapeAdd;
1495 VEC_SHAPE vecxShapeRemove;
1496 int nCountSelectedShape=0;
1497
1498 vcl::Window *pWin = GetShell()->GetWin();
1499 bool bFocused = pWin && pWin->HasFocus();
1500 SwAccessibleObjShape_Impl *pShape = pShapes.get();
1501 int nShapeCount = nShapes;
1502 while( nShapeCount )
1503 {
1504 if (pShape->second.is() && IsInSameLevel(pShape->first, pFESh))
1505 {
1506 if( pShape < pSelShape )
1507 {
1508 if(pShape->second->ResetState( AccessibleStateType::SELECTED ))
1509 {
1510 vecxShapeRemove.push_back(pShape->second);
1511 }
1512 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1513 }
1514 }
1515 --nShapeCount;
1516 ++pShape;
1517 }
1518
1519 for (const auto& rpShape : vecxShapeRemove)
1520 {
1521 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1522 if (pAccShape)
1523 {
1524 pAccShape->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, uno::Any(), uno::Any());
1525 }
1526 }
1527
1528 pShape = pShapes.get();
1529
1530 while( nShapes )
1531 {
1532 if (pShape->second.is() && IsInSameLevel(pShape->first, pFESh))
1533 {
1534 if( pShape >= pSelShape )
1535 {
1536 //first fire focus event
1537 if( bFocused && 1 == nSelShapes )
1538 pShape->second->SetState( AccessibleStateType::FOCUSED );
1539 else
1540 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1541
1542 if(pShape->second->SetState( AccessibleStateType::SELECTED ))
1543 {
1544 vecxShapeAdd.push_back(pShape->second);
1545 }
1546 ++nCountSelectedShape;
1547 }
1548 }
1549
1550 --nShapes;
1551 ++pShape;
1552 }
1553
1554 const unsigned int SELECTION_WITH_NUM = 10;
1555 if (vecxShapeAdd.size() > SELECTION_WITH_NUM )
1556 {
1557 uno::Reference< XAccessible > xDoc = GetDocumentView( );
1558 SwAccessibleContext * pCont = static_cast<SwAccessibleContext *>(xDoc.get());
1559 if (pCont)
1560 {
1561 AccessibleEventObject aEvent;
1562 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1564 }
1565 }
1566 else
1567 {
1568 short nEventID = AccessibleEventId::SELECTION_CHANGED_ADD;
1569 if (nCountSelectedShape <= 1 && vecxShapeAdd.size() == 1 )
1570 {
1571 nEventID = AccessibleEventId::SELECTION_CHANGED;
1572 }
1573 for (const auto& rpShape : vecxShapeAdd)
1574 {
1575 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1576 if (pAccShape)
1577 {
1578 pAccShape->CommitChange(nEventID, uno::Any(), uno::Any());
1579 }
1580 }
1581 }
1582
1583 for (const auto& rpShape : vecxShapeAdd)
1584 {
1585 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1586 if (pAccShape)
1587 {
1589 SwFrameFormat *pFrameFormat = pObj ? FindFrameFormat( pObj ) : nullptr;
1590 if (pFrameFormat)
1591 {
1592 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1593 if( rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
1594 {
1595 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
1596 if (xPara.is())
1597 {
1598 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext();
1599 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1600 {
1601 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get());
1602 if (pAccPara)
1603 {
1604 m_setParaAdd.insert(pAccPara);
1605 }
1606 }
1607 }
1608 }
1609 }
1610 }
1611 }
1612 for (const auto& rpShape : vecxShapeRemove)
1613 {
1614 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1615 if (pAccShape && !pAccShape->IsDisposed())
1616 {
1617 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
1618 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext();
1619 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1620 {
1621 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get());
1622 if (m_setParaAdd.count(pAccPara) == 0 )
1623 {
1624 m_setParaRemove.insert(pAccPara);
1625 }
1626 }
1627 }
1628 }
1629}
1630
1632 mpVSh( pSh ),
1633 mbShapeSelected( false ),
1634 maDocName(SwAccessibleContext::GetResource(STR_ACCESS_DOC_NAME))
1635{
1636 pSh->GetLayout()->AddAccessibleShell();
1637}
1638
1640{
1642 uno::Reference < XAccessible > xAcc;
1643 {
1644 osl::MutexGuard aGuard( maMutex );
1645 if( mpFrameMap )
1646 {
1647 const SwRootFrame *pRootFrame = GetShell()->GetLayout();
1648 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pRootFrame );
1649 if( aIter != mpFrameMap->end() )
1650 xAcc = (*aIter).second;
1651 if( !xAcc.is() )
1652 assert(false); // let's hope this can't happen? the vcl::Window apparently owns the top-level
1653 //xAcc = new SwAccessibleDocument(shared_from_this());
1654 }
1655 }
1656
1657 if(xAcc.is())
1658 {
1659 SwAccessibleDocumentBase *const pAcc =
1660 static_cast<SwAccessibleDocumentBase *>(xAcc.get());
1661 pAcc->Dispose( true );
1662 }
1663#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
1664 if( mpFrameMap )
1665 {
1667 while( aIter != mpFrameMap->end() )
1668 {
1669 uno::Reference < XAccessible > xTmp = (*aIter).second;
1670 if( xTmp.is() )
1671 {
1672 SwAccessibleContext *pTmp = static_cast< SwAccessibleContext * >( xTmp.get() );
1673 assert(pTmp->GetMap() == nullptr); // must be disposed
1674 }
1675 ++aIter;
1676 }
1677 }
1678#endif
1679 {
1680 osl::MutexGuard aGuard( maMutex );
1681 assert((!mpFrameMap || mpFrameMap->empty()) &&
1682 "Frame map should be empty after disposing the root frame");
1683 assert((!mpShapeMap || mpShapeMap->empty()) &&
1684 "Object map should be empty after disposing the root frame");
1685 mpFrameMap.reset();
1686 mpShapeMap.reset();
1687 mvShapes.clear();
1688 mpSelectedParas.reset();
1689 }
1690
1691 mpPreview.reset();
1692
1693 {
1694 osl::MutexGuard aGuard( maEventMutex );
1695 assert(!mpEvents);
1696 assert(!mpEventMap);
1697 mpEventMap.reset();
1698 mpEvents.reset();
1699 }
1701}
1702
1703uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView_(
1704 bool bPagePreview )
1705{
1706 uno::Reference < XAccessible > xAcc;
1707 bool bSetVisArea = false;
1708
1709 {
1710 osl::MutexGuard aGuard( maMutex );
1711
1712 if( !mpFrameMap )
1713 {
1715#if OSL_DEBUG_LEVEL > 0
1716 mpFrameMap->mbLocked = false;
1717#endif
1718 }
1719
1720#if OSL_DEBUG_LEVEL > 0
1721 assert(!mpFrameMap->mbLocked);
1722 mpFrameMap->mbLocked = true;
1723#endif
1724
1725 const SwRootFrame *pRootFrame = GetShell()->GetLayout();
1726 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pRootFrame );
1727 if( aIter != mpFrameMap->end() )
1728 xAcc = (*aIter).second;
1729 if( xAcc.is() )
1730 {
1731 bSetVisArea = true; // Set VisArea when map mutex is not locked
1732 }
1733 else
1734 {
1735 if( bPagePreview )
1736 xAcc = new SwAccessiblePreview(shared_from_this());
1737 else
1738 xAcc = new SwAccessibleDocument(shared_from_this());
1739
1740 if( aIter != mpFrameMap->end() )
1741 {
1742 (*aIter).second = xAcc;
1743 }
1744 else
1745 {
1746 mpFrameMap->emplace( pRootFrame, xAcc );
1747 }
1748 }
1749
1750#if OSL_DEBUG_LEVEL > 0
1751 mpFrameMap->mbLocked = false;
1752#endif
1753 }
1754
1755 if( bSetVisArea )
1756 {
1758 static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
1759 pAcc->SetVisArea();
1760 }
1761
1762 return xAcc;
1763}
1764
1765uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
1766{
1767 return GetDocumentView_( false );
1768}
1769
1770uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
1771 const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
1772 const Fraction& _rScale,
1773 const SwPageFrame* _pSelectedPageFrame,
1774 const Size& _rPreviewWinSize )
1775{
1776 // create & update preview data object
1777 if( mpPreview == nullptr )
1778 mpPreview.reset( new SwAccPreviewData() );
1779 mpPreview->Update( *this, _rPreviewPages, _rScale, _pSelectedPageFrame, _rPreviewWinSize );
1780
1781 uno::Reference<XAccessible> xAcc = GetDocumentView_( true );
1782 return xAcc;
1783}
1784
1785uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrame *pFrame,
1786 bool bCreate )
1787{
1789 uno::Reference < XAccessible > xAcc;
1790 uno::Reference < XAccessible > xOldCursorAcc;
1791 bool bOldShapeSelected = false;
1792
1793 {
1794 osl::MutexGuard aGuard( maMutex );
1795
1796 if( !mpFrameMap && bCreate )
1798 if( mpFrameMap )
1799 {
1800 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pFrame );
1801 if( aIter != mpFrameMap->end() )
1802 xAcc = (*aIter).second;
1803
1804 if( !xAcc.is() && bCreate )
1805 {
1807 switch( pFrame->GetType() )
1808 {
1809 case SwFrameType::Txt:
1810 pAcc = new SwAccessibleParagraph(shared_from_this(),
1811 static_cast< const SwTextFrame& >( *pFrame ) );
1812 break;
1814 pAcc = new SwAccessibleHeaderFooter(shared_from_this(),
1815 static_cast< const SwHeaderFrame *>( pFrame ) );
1816 break;
1818 pAcc = new SwAccessibleHeaderFooter(shared_from_this(),
1819 static_cast< const SwFooterFrame *>( pFrame ) );
1820 break;
1821 case SwFrameType::Ftn:
1822 {
1823 const SwFootnoteFrame *pFootnoteFrame =
1824 static_cast < const SwFootnoteFrame * >( pFrame );
1825 bool bIsEndnote =
1826 SwAccessibleFootnote::IsEndnote( pFootnoteFrame );
1827 pAcc = new SwAccessibleFootnote(shared_from_this(), bIsEndnote,
1828 /*(bIsEndnote ? mnEndnote++ : mnFootnote++),*/
1829 pFootnoteFrame );
1830 }
1831 break;
1832 case SwFrameType::Fly:
1833 {
1834 const SwFlyFrame *pFlyFrame =
1835 static_cast < const SwFlyFrame * >( pFrame );
1836 switch( SwAccessibleFrameBase::GetNodeType( pFlyFrame ) )
1837 {
1838 case SwNodeType::Grf:
1839 pAcc = new SwAccessibleGraphic(shared_from_this(), pFlyFrame );
1840 break;
1841 case SwNodeType::Ole:
1842 pAcc = new SwAccessibleEmbeddedObject(shared_from_this(), pFlyFrame );
1843 break;
1844 default:
1845 pAcc = new SwAccessibleTextFrame(shared_from_this(), *pFlyFrame );
1846 break;
1847 }
1848 }
1849 break;
1850 case SwFrameType::Cell:
1851 pAcc = new SwAccessibleCell(shared_from_this(),
1852 static_cast< const SwCellFrame *>( pFrame ) );
1853 break;
1854 case SwFrameType::Tab:
1855 pAcc = new SwAccessibleTable(shared_from_this(),
1856 static_cast< const SwTabFrame *>( pFrame ) );
1857 break;
1858 case SwFrameType::Page:
1859 OSL_ENSURE( GetShell()->IsPreview(),
1860 "accessible page frames only in PagePreview" );
1861 pAcc = new SwAccessiblePage(shared_from_this(), pFrame);
1862 break;
1863 default: break;
1864 }
1865 xAcc = pAcc;
1866 assert(xAcc.is());
1867
1868 if( aIter != mpFrameMap->end() )
1869 {
1870 (*aIter).second = xAcc;
1871 }
1872 else
1873 {
1874 mpFrameMap->emplace( pFrame, xAcc );
1875 }
1876
1877 if( pAcc->HasCursor() &&
1878 !AreInSameTable( mxCursorContext, pFrame ) )
1879 {
1880 // If the new context has the focus, and if we know
1881 // another context that had the focus, then the focus
1882 // just moves from the old context to the new one. We
1883 // then have to send a focus event and a caret event for
1884 // the old context. We have to do that now,
1885 // because after we have left this method, anyone might
1886 // call getStates for the new context and will get a
1887 // focused state then. Sending the focus changes event
1888 // after that seems to be strange. However, we cannot
1889 // send a focus event for the new context now, because
1890 // no one except us knows it. In any case, we remember
1891 // the new context as the one that has the focus
1892 // currently.
1893
1894 xOldCursorAcc = mxCursorContext;
1895 mxCursorContext = xAcc;
1896
1897 bOldShapeSelected = mbShapeSelected;
1898 mbShapeSelected = false;
1899 }
1900 }
1901 }
1902 }
1903
1904 // Invalidate focus for old object when map is not locked
1905 if( xOldCursorAcc.is() )
1906 InvalidateCursorPosition( xOldCursorAcc );
1907 if( bOldShapeSelected )
1909
1910 return xAcc;
1911}
1912
1914 const SwFrame *pFrame,
1915 bool bCreate )
1916{
1917 uno::Reference < XAccessible > xAcc( GetContext( pFrame, bCreate ) );
1918
1920 static_cast< SwAccessibleContext * >( xAcc.get() ) );
1921
1922 return xAccImpl;
1923}
1924
1925uno::Reference< XAccessible> SwAccessibleMap::GetContext(
1926 const SdrObject *pObj,
1927 SwAccessibleContext *pParentImpl,
1928 bool bCreate )
1929{
1930 uno::Reference < XAccessible > xAcc;
1931 uno::Reference < XAccessible > xOldCursorAcc;
1932
1933 {
1934 osl::MutexGuard aGuard( maMutex );
1935
1936 if( !mpShapeMap && bCreate )
1937 mpShapeMap.reset(new SwAccessibleShapeMap_Impl( this ));
1938 if( mpShapeMap )
1939 {
1940 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->find( pObj );
1941 if( aIter != mpShapeMap->end() )
1942 xAcc = (*aIter).second;
1943
1944 if( !xAcc.is() && bCreate )
1945 {
1947 uno::Reference < drawing::XShape > xShape(
1948 const_cast< SdrObject * >( pObj )->getUnoShape(),
1949 uno::UNO_QUERY );
1950 if( xShape.is() )
1951 {
1952 ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
1954 uno::Reference < XAccessible > xParent( pParentImpl );
1956 xShape, xParent, this );
1957
1958 pAcc = rShapeTypeHandler.CreateAccessibleObject(
1959 aShapeInfo, mpShapeMap->GetInfo() );
1960 }
1961 xAcc = pAcc.get();
1962 assert(xAcc.is());
1963 pAcc->Init();
1964 if( aIter != mpShapeMap->end() )
1965 {
1966 (*aIter).second = xAcc;
1967 }
1968 else
1969 {
1970 mpShapeMap->emplace( pObj, xAcc );
1971 }
1972 // TODO: focus!!!
1973 AddGroupContext(pObj, xAcc);
1974 }
1975 }
1976 }
1977
1978 // Invalidate focus for old object when map is not locked
1979 if( xOldCursorAcc.is() )
1980 InvalidateCursorPosition( xOldCursorAcc );
1981
1982 return xAcc;
1983}
1984
1986{
1987 if (pFESh)
1988 return pFESh->IsObjSameLevelWithMarked(pObj);
1989 return false;
1990}
1991
1992void SwAccessibleMap::AddShapeContext(const SdrObject *pObj, uno::Reference < XAccessible > const & xAccShape)
1993{
1994 osl::MutexGuard aGuard( maMutex );
1995
1996 if( mpShapeMap )
1997 {
1998 mpShapeMap->emplace( pObj, xAccShape );
1999 }
2000
2001}
2002
2003//Added by yanjun for sym2_6407
2005{
2006 osl::MutexGuard aGuard( maMutex );
2007 // TODO: Why are sub-shapes of group shapes even added to our map?
2008 // Doesn't the AccessibleShape of the top-level shape create them
2009 // on demand anyway? Why does SwAccessibleMap need to know them?
2010 // We cannot rely on getAccessibleChild here to remove the sub-shapes
2011 // from mpShapes because the top-level shape may not only be disposed here
2012 // but also by visibility checks in svx, then it doesn't return children.
2013 if (mpShapeMap && pParentObj && pParentObj->IsGroupObject())
2014 {
2015 SdrObjList *const pChildren(pParentObj->GetSubList());
2016 for (size_t i = 0; pChildren && i < pChildren->GetObjCount(); ++i)
2017 {
2018 SdrObject *const pChild(pChildren->GetObj(i));
2019 assert(pChild);
2020 RemoveContext(pChild);
2021 }
2022 }
2023}
2024//End
2025
2026void SwAccessibleMap::AddGroupContext(const SdrObject *pParentObj, uno::Reference < XAccessible > const & xAccParent)
2027{
2028 osl::MutexGuard aGuard( maMutex );
2029 if( !mpShapeMap )
2030 return;
2031
2032 //here get all the sub list.
2033 if (!pParentObj->IsGroupObject())
2034 return;
2035
2036 if (!xAccParent.is())
2037 return;
2038
2039 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext();
2040 if (!xContext.is())
2041 return;
2042
2043 sal_Int64 nChildren = xContext->getAccessibleChildCount();
2044 for(sal_Int64 i = 0; i<nChildren; i++)
2045 {
2046 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i);
2047 if (xChild.is())
2048 {
2049 uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext();
2050 if (xChildContext.is())
2051 {
2052 short nRole = xChildContext->getAccessibleRole();
2053 if (nRole == AccessibleRole::SHAPE)
2054 {
2055 ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get());
2056 uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape();
2057 if (xShape.is())
2058 {
2060 AddShapeContext(pObj, xChild);
2061 AddGroupContext(pObj,xChild);
2062 }
2063 }
2064 }
2065 }
2066 }
2067}
2068
2070 const SdrObject *pObj,
2071 SwAccessibleContext *pParentImpl,
2072 bool bCreate )
2073{
2074 uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
2075
2077 static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
2078
2079 return xAccImpl;
2080}
2081
2083{
2084 osl::MutexGuard aGuard( maMutex );
2085
2086 if( !mpFrameMap )
2087 return;
2088
2090 mpFrameMap->find( pFrame );
2091 if( aIter == mpFrameMap->end() )
2092 return;
2093
2094 mpFrameMap->erase( aIter );
2095
2097 {
2098 SwAccessibleContextMap_Impl::iterator aSelectedIter = mpSelectedFrameMap->find(pFrame);
2099 if (aSelectedIter != mpSelectedFrameMap->end())
2100 mpSelectedFrameMap->erase(aSelectedIter);
2101 }
2102
2103 // Remove reference to old caret object. Though mxCursorContext
2104 // is a weak reference and cleared automatically, clearing it
2105 // directly makes sure to not keep a non-functional object.
2106 uno::Reference < XAccessible > xOldAcc( mxCursorContext );
2107 if( xOldAcc.is() )
2108 {
2109 SwAccessibleContext *pOldAccImpl =
2110 static_cast< SwAccessibleContext *>( xOldAcc.get() );
2111 OSL_ENSURE( pOldAccImpl->GetFrame(), "old caret context is disposed" );
2112 if( pOldAccImpl->GetFrame() == pFrame )
2113 {
2114 xOldAcc.clear(); // get an empty ref
2115 mxCursorContext = xOldAcc;
2116 }
2117 }
2118
2119 if( mpFrameMap->empty() )
2120 {
2121 mpFrameMap.reset();
2122 }
2123}
2124
2126{
2127 osl::MutexGuard aGuard( maMutex );
2128
2129 if( !mpShapeMap )
2130 return;
2131
2132 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->find( pObj );
2133 if( aIter == mpShapeMap->end() )
2134 return;
2135
2136 uno::Reference < XAccessible > xTempHold( (*aIter).second );
2137 mpShapeMap->erase( aIter );
2138 RemoveGroupContext(pObj);
2139 // The shape selection flag is not cleared, but one might do
2140 // so but has to make sure that the removed context is the one
2141 // that is selected.
2142
2143 if( mpShapeMap && mpShapeMap->empty() )
2144 {
2145 mpShapeMap.reset();
2146 }
2147}
2148
2149bool SwAccessibleMap::Contains(const SwFrame *pFrame) const
2150{
2151 return (pFrame && mpFrameMap && mpFrameMap->find(pFrame) != mpFrameMap->end());
2152}
2153
2155 const SdrObject *pObj,
2156 vcl::Window* pWindow,
2157 bool bRecursive,
2158 bool bCanSkipInvisible )
2159{
2160 SwAccessibleChild aFrameOrObj( pFrame, pObj, pWindow );
2161
2162 // Indeed, the following assert checks the frame's accessible flag,
2163 // because that's the one that is evaluated in the layout. The frame
2164 // might not be accessible anyway. That's the case for cell frames that
2165 // contain further cells.
2166 OSL_ENSURE( !aFrameOrObj.GetSwFrame() || aFrameOrObj.GetSwFrame()->IsAccessibleFrame(),
2167 "non accessible frame should be disposed" );
2168
2169 if (!(aFrameOrObj.IsAccessible(GetShell()->IsPreview())
2170 // fdo#87199 dispose the darn thing if it ever was accessible
2171 || Contains(pFrame)))
2172 return;
2173
2177 // get accessible context for frame
2178 {
2179 osl::MutexGuard aGuard( maMutex );
2180
2181 // First of all look for an accessible context for a frame
2182 if( aFrameOrObj.GetSwFrame() && mpFrameMap )
2183 {
2185 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2186 if( aIter != mpFrameMap->end() )
2187 {
2188 uno::Reference < XAccessible > xAcc( (*aIter).second );
2189 xAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
2190 }
2191 }
2192 if( !xAccImpl.is() && mpFrameMap )
2193 {
2194 // If there is none, look if the parent is accessible.
2195 const SwFrame *pParent =
2196 SwAccessibleFrame::GetParent( aFrameOrObj,
2197 GetShell()->IsPreview());
2198
2199 if( pParent )
2200 {
2202 mpFrameMap->find( pParent );
2203 if( aIter != mpFrameMap->end() )
2204 {
2205 uno::Reference < XAccessible > xAcc( (*aIter).second );
2206 xParentAccImpl =
2207 static_cast< SwAccessibleContext *>( xAcc.get() );
2208 }
2209 }
2210 }
2211 if( !xParentAccImpl.is() && !aFrameOrObj.GetSwFrame() && mpShapeMap )
2212 {
2214 mpShapeMap->find( aFrameOrObj.GetDrawObject() );
2215 if( aIter != mpShapeMap->end() )
2216 {
2217 uno::Reference < XAccessible > xAcc( (*aIter).second );
2218 xShapeAccImpl =
2219 static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
2220 }
2221 }
2222 if( pObj && GetShell()->ActionPend() &&
2223 (xParentAccImpl.is() || xShapeAccImpl.is()) )
2224 {
2225 // Keep a reference to the XShape to avoid that it
2226 // is deleted with a SwFrameFormat::SwClientNotify.
2227 uno::Reference < drawing::XShape > xShape(
2228 const_cast< SdrObject * >( pObj )->getUnoShape(),
2229 uno::UNO_QUERY );
2230 if( xShape.is() )
2231 {
2232 mvShapes.push_back( xShape );
2233 }
2234 }
2235 }
2236
2237 // remove events stored for the frame
2238 {
2239 osl::MutexGuard aGuard( maEventMutex );
2240 if( mpEvents )
2241 {
2243 mpEventMap->find( aFrameOrObj );
2244 if( aIter != mpEventMap->end() )
2245 {
2247 SwAccessibleEvent_Impl::DISPOSE, aFrameOrObj );
2249 }
2250 }
2251 }
2252
2253 // If the frame is accessible and there is a context for it, dispose
2254 // the frame. If the frame is no context for it but disposing should
2255 // take place recursive, the frame's children have to be disposed
2256 // anyway, so we have to create the context then.
2257 if( xAccImpl.is() )
2258 {
2259 xAccImpl->Dispose( bRecursive );
2260 }
2261 else if( xParentAccImpl.is() )
2262 {
2263 // If the frame is a cell frame, the table must be notified.
2264 // If we are in an action, a table model change event will
2265 // be broadcasted at the end of the action to give the table
2266 // a chance to generate a single table change event.
2267
2268 xParentAccImpl->DisposeChild( aFrameOrObj, bRecursive, bCanSkipInvisible );
2269 }
2270 else if( xShapeAccImpl.is() )
2271 {
2272 RemoveContext( aFrameOrObj.GetDrawObject() );
2273 xShapeAccImpl->dispose();
2274 }
2275
2276 if( mpPreview && pFrame && pFrame->IsPageFrame() )
2277 mpPreview->DisposePage( static_cast< const SwPageFrame *>( pFrame ) );
2278}
2279
2281 const SdrObject *pObj,
2282 vcl::Window* pWindow,
2283 const SwRect& rOldBox )
2284{
2285 SwAccessibleChild aFrameOrObj( pFrame, pObj, pWindow );
2286 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2287 return;
2288
2291 const SwFrame *pParent =nullptr;
2292 {
2293 osl::MutexGuard aGuard( maMutex );
2294
2295 if( mpFrameMap )
2296 {
2297 if( aFrameOrObj.GetSwFrame() )
2298 {
2300 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2301 if( aIter != mpFrameMap->end() )
2302 {
2303 // If there is an accessible object already it is
2304 // notified directly.
2305 uno::Reference < XAccessible > xAcc( (*aIter).second );
2306 xAccImpl =
2307 static_cast< SwAccessibleContext *>( xAcc.get() );
2308 }
2309 }
2310 if( !xAccImpl.is() )
2311 {
2312 // Otherwise we look if the parent is accessible.
2313 // If not, there is nothing to do.
2314 pParent =
2315 SwAccessibleFrame::GetParent( aFrameOrObj,
2316 GetShell()->IsPreview());
2317
2318 if( pParent )
2319 {
2321 mpFrameMap->find( pParent );
2322 if( aIter != mpFrameMap->end() )
2323 {
2324 uno::Reference < XAccessible > xAcc( (*aIter).second );
2325 xParentAccImpl =
2326 static_cast< SwAccessibleContext *>( xAcc.get() );
2327 }
2328 }
2329 }
2330 }
2331 }
2332
2333 if( xAccImpl.is() )
2334 {
2335 if( GetShell()->ActionPend() )
2336 {
2339 aFrameOrObj, rOldBox );
2341 }
2342 else
2343 {
2344 FireEvents();
2345 if (xAccImpl->GetFrame()) // not if disposed by FireEvents()
2346 {
2347 xAccImpl->InvalidatePosOrSize(rOldBox);
2348 }
2349 }
2350 }
2351 else if( xParentAccImpl.is() )
2352 {
2353 if( GetShell()->ActionPend() )
2354 {
2355 assert(pParent);
2356 // tdf#99722 faster not to buffer events that won't be sent
2357 if (!SwAccessibleChild(pParent).IsVisibleChildrenOnly()
2358 || xParentAccImpl->IsShowing(rOldBox)
2359 || xParentAccImpl->IsShowing(*this, aFrameOrObj))
2360 {
2363 xParentAccImpl.get(), aFrameOrObj, rOldBox );
2365 }
2366 }
2367 else
2368 {
2369 FireEvents();
2370 xParentAccImpl->InvalidateChildPosOrSize( aFrameOrObj,
2371 rOldBox );
2372 }
2373 }
2374 else if(pParent)
2375 {
2376/*
2377For child graphic and its parent paragraph,if split 2 graphic to 2 paragraph,
2378will delete one graphic swfrm and new create 1 graphic swfrm ,
2379then the new paragraph and the new graphic SwFrame will add .
2380but when add graphic SwFrame ,the accessible of the new Paragraph is not created yet.
2381so the new graphic accessible 'parent is NULL,
2382so run here: save the parent's SwFrame not the accessible object parent,
2383*/
2384 bool bIsValidFrame = false;
2385 bool bIsTextParent = false;
2386 if (aFrameOrObj.GetSwFrame())
2387 {
2388 if (SwFrameType::Fly == pFrame->GetType())
2389 {
2390 bIsValidFrame =true;
2391 }
2392 }
2393 else if(pObj)
2394 {
2395 if (SwFrameType::Txt == pParent->GetType())
2396 {
2397 bIsTextParent =true;
2398 }
2399 }
2400 if( bIsValidFrame || bIsTextParent )
2401 {
2402 if( GetShell()->ActionPend() )
2403 {
2406 pParent, aFrameOrObj, rOldBox );
2408 }
2409 else
2410 {
2411 OSL_ENSURE(false,"");
2412 }
2413 }
2414 }
2415}
2416
2418{
2419 SwAccessibleChild aFrameOrObj( pFrame );
2420 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2421 return;
2422
2423 uno::Reference < XAccessible > xAcc;
2424 {
2425 osl::MutexGuard aGuard( maMutex );
2426
2427 if (!mpFrameMap)
2428 return;
2429
2431 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2432 if( aIter != mpFrameMap->end() )
2433 xAcc = (*aIter).second;
2434 }
2435
2436 if( !xAcc.is() )
2437 return;
2438
2439 SwAccessibleContext *pAccImpl =
2440 static_cast< SwAccessibleContext *>( xAcc.get() );
2441 if( GetShell()->ActionPend() )
2442 {
2445 std::move(aFrameOrObj) );
2447 }
2448 else
2449 {
2450 FireEvents();
2451 pAccImpl->InvalidateContent();
2452 }
2453}
2454
2456{
2457 SwAccessibleChild aFrameOrObj( &rTextFrame );
2458 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2459 return;
2460
2461 uno::Reference < XAccessible > xAcc;
2462 {
2463 osl::MutexGuard aGuard( maMutex );
2464
2465 if (!mpFrameMap)
2466 return;
2467
2469 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2470 if( aIter != mpFrameMap->end() )
2471 xAcc = (*aIter).second;
2472 }
2473
2474 if( !xAcc.is() )
2475 return;
2476
2477 SwAccessibleContext *pAccImpl =
2478 static_cast< SwAccessibleContext *>( xAcc.get() );
2479 if( GetShell()->ActionPend() )
2480 {
2482 pAccImpl, std::move(aFrameOrObj) );
2485 }
2486 else
2487 {
2488 FireEvents();
2489 pAccImpl->InvalidateAttr();
2490 }
2491}
2492
2494{
2495 SwAccessibleChild aFrameOrObj( pFrame );
2496 bool bShapeSelected = false;
2497 const SwViewShell *pVSh = GetShell();
2498 if( auto pCSh = dynamic_cast<const SwCursorShell*>(pVSh) )
2499 {
2500 if( pCSh->IsTableMode() )
2501 {
2502 while( aFrameOrObj.GetSwFrame() && !aFrameOrObj.GetSwFrame()->IsCellFrame() )
2503 aFrameOrObj = aFrameOrObj.GetSwFrame()->GetUpper();
2504 }
2505 else if( auto pFESh = dynamic_cast<const SwFEShell*>(pVSh) )
2506 {
2507 const SwFrame *pFlyFrame = pFESh->GetSelectedFlyFrame();
2508 if( pFlyFrame )
2509 {
2510 OSL_ENSURE( !pFrame || pFrame->FindFlyFrame() == pFlyFrame,
2511 "cursor is not contained in fly frame" );
2512 aFrameOrObj = pFlyFrame;
2513 }
2514 else if( pFESh->IsObjSelected() > 0 )
2515 {
2516 bShapeSelected = true;
2517 aFrameOrObj = static_cast<const SwFrame *>( nullptr );
2518 }
2519 }
2520 }
2521
2522 OSL_ENSURE( bShapeSelected || aFrameOrObj.IsAccessible(GetShell()->IsPreview()),
2523 "frame is not accessible" );
2524
2525 uno::Reference < XAccessible > xOldAcc;
2526 uno::Reference < XAccessible > xAcc;
2527 bool bOldShapeSelected = false;
2528
2529 {
2530 osl::MutexGuard aGuard( maMutex );
2531
2532 xOldAcc = mxCursorContext;
2533 mxCursorContext = xAcc; // clear reference
2534
2535 bOldShapeSelected = mbShapeSelected;
2536 mbShapeSelected = bShapeSelected;
2537
2538 if( aFrameOrObj.GetSwFrame() && mpFrameMap )
2539 {
2541 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2542 if( aIter != mpFrameMap->end() )
2543 xAcc = (*aIter).second;
2544 else
2545 {
2546 SwRect rcEmpty;
2547 const SwTabFrame* pTabFrame = aFrameOrObj.GetSwFrame()->FindTabFrame();
2548 if (pTabFrame)
2549 {
2550 InvalidatePosOrSize(pTabFrame, nullptr, nullptr, rcEmpty);
2551 }
2552 else
2553 {
2554 InvalidatePosOrSize(aFrameOrObj.GetSwFrame(), nullptr, nullptr, rcEmpty);
2555 }
2556
2557 aIter = mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2558 if( aIter != mpFrameMap->end() )
2559 {
2560 xAcc = (*aIter).second;
2561 }
2562 }
2563
2564 // For cells, some extra thoughts are necessary,
2565 // because invalidating the cursor for one cell
2566 // invalidates the cursor for all cells of the same
2567 // table. For this reason, we don't want to
2568 // invalidate the cursor for the old cursor object
2569 // and the new one if they are within the same table,
2570 // because this would result in doing the work twice.
2571 // Moreover, we have to make sure to invalidate the
2572 // cursor even if the current cell has no accessible object.
2573 // If the old cursor objects exists and is in the same
2574 // table, it's the best choice, because using it avoids
2575 // an unnecessary cursor invalidation cycle when creating
2576 // a new object for the current cell.
2577 if( aFrameOrObj.GetSwFrame()->IsCellFrame() )
2578 {
2579 if( xOldAcc.is() &&
2580 AreInSameTable( xOldAcc, aFrameOrObj.GetSwFrame() ) )
2581 {
2582 if( xAcc.is() )
2583 xOldAcc = xAcc; // avoid extra invalidation
2584 else
2585 xAcc = xOldAcc; // make sure at least one
2586 }
2587 if( !xAcc.is() )
2588 xAcc = GetContext( aFrameOrObj.GetSwFrame() );
2589 }
2590 }
2591 else if (bShapeSelected)
2592 {
2593 const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
2594 const SdrMarkList *pMarkList = pFESh->GetMarkList();
2595 if (pMarkList != nullptr && pMarkList->GetMarkCount() == 1)
2596 {
2597 SdrObject *pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
2599 if (!pAccShapeImpl.is())
2600 {
2601 while (pObj && pObj->getParentSdrObjectFromSdrObject())
2602 {
2603 pObj = pObj->getParentSdrObjectFromSdrObject();
2604 }
2605 if (pObj != nullptr)
2606 {
2607 const SwFrame *pParent = SwAccessibleFrame::GetParent( SwAccessibleChild(pObj), GetShell()->IsPreview() );
2608 if( pParent )
2609 {
2610 ::rtl::Reference< SwAccessibleContext > xParentAccImpl = GetContextImpl(pParent,false);
2611 if (!xParentAccImpl.is())
2612 {
2613 const SwTabFrame* pTabFrame = pParent->FindTabFrame();
2614 if (pTabFrame)
2615 {
2616 //The Table should not add in acc.because the "pParent" is not add to acc .
2617 uno::Reference< XAccessible> xAccParentTab = GetContext(pTabFrame);//Should Create.
2618
2619 const SwFrame *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pTabFrame), GetShell()->IsPreview() );
2620 if (pParentRoot)
2621 {
2622 ::rtl::Reference< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,false);
2623 if(xParentAccImplRoot.is())
2624 {
2625 AccessibleEventObject aEvent;
2626 aEvent.EventId = AccessibleEventId::CHILD;
2627 aEvent.NewValue <<= xAccParentTab;
2628 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2629 }
2630 }
2631
2632 //Get "pParent" acc again.
2633 xParentAccImpl = GetContextImpl(pParent,false);
2634 }
2635 else
2636 {
2637 //directly create this acc para .
2638 xParentAccImpl = GetContextImpl(pParent);//Should Create.
2639
2640 const SwFrame *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pParent), GetShell()->IsPreview() );
2641
2642 ::rtl::Reference< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,false);
2643 if(xParentAccImplRoot.is())
2644 {
2645 AccessibleEventObject aEvent;
2646 aEvent.EventId = AccessibleEventId::CHILD;
2647 aEvent.NewValue <<= uno::Reference< XAccessible>(xParentAccImpl);
2648 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2649 }
2650 }
2651 }
2652 if (xParentAccImpl.is())
2653 {
2654 uno::Reference< XAccessible> xAccShape =
2655 GetContext(pObj,xParentAccImpl.get());
2656
2657 AccessibleEventObject aEvent;
2658 aEvent.EventId = AccessibleEventId::CHILD;
2659 aEvent.NewValue <<= xAccShape;
2660 xParentAccImpl->FireAccessibleEvent( aEvent );
2661 }
2662 }
2663 }
2664 }
2665 }
2666 }
2667 }
2668
2671 if( xOldAcc.is() && xOldAcc != xAcc )
2672 InvalidateCursorPosition( xOldAcc );
2673 if( bOldShapeSelected || bShapeSelected )
2675 if( xAcc.is() )
2677
2679
2680 for (SwAccessibleParagraph* pAccPara : m_setParaRemove)
2681 {
2682 if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0)
2683 {
2684 if(pAccPara->SetSelectedState(false))
2685 {
2686 AccessibleEventObject aEvent;
2687 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
2688 pAccPara->FireAccessibleEvent( aEvent );
2689 }
2690 }
2691 }
2692 for (SwAccessibleParagraph* pAccPara : m_setParaAdd)
2693 {
2694 if(pAccPara && pAccPara->SetSelectedState(true))
2695 {
2696 AccessibleEventObject aEvent;
2697 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
2698 pAccPara->FireAccessibleEvent( aEvent );
2699 }
2700 }
2701}
2702
2704{
2705 if(GetShell()->IsPreview())
2706 {
2707 uno::Reference<XAccessible> xAcc = GetDocumentView_( true );
2708 if (xAcc)
2709 {
2710 SwAccessiblePreview *pAccPreview = static_cast<SwAccessiblePreview *>(xAcc.get());
2711 if (pAccPreview)
2712 {
2713 pAccPreview->InvalidateFocus();
2714 return ;
2715 }
2716 }
2717 }
2718 uno::Reference < XAccessible > xAcc;
2719 {
2720 osl::MutexGuard aGuard( maMutex );
2721
2722 xAcc = mxCursorContext;
2723 }
2724
2725 if( xAcc.is() )
2726 {
2727 SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
2728 pAccImpl->InvalidateFocus();
2729 }
2730 else
2731 {
2733 }
2734}
2735
2737 const ::rtl::Reference < SwAccessibleContext >& rCursorContext )
2738{
2739 osl::MutexGuard aGuard( maMutex );
2740 uno::Reference < XAccessible > xAcc( rCursorContext );
2741 mxCursorContext = xAcc;
2742}
2743
2745{
2746 // Start with the frame or the first upper that is accessible
2747 SwAccessibleChild aFrameOrObj( _pFrame );
2748 while( aFrameOrObj.GetSwFrame() &&
2749 !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2750 aFrameOrObj = aFrameOrObj.GetSwFrame()->GetUpper();
2751 if( !aFrameOrObj.GetSwFrame() )
2752 aFrameOrObj = GetShell()->GetLayout();
2753
2754 uno::Reference< XAccessible > xAcc( GetContext( aFrameOrObj.GetSwFrame() ) );
2755 SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
2756 if( GetShell()->ActionPend() )
2757 {
2759 pAccImpl,
2760 SwAccessibleChild(pAccImpl->GetFrame()),
2763 }
2764 else
2765 {
2766 FireEvents();
2768 }
2769}
2770
2772 bool bFrom )
2773{
2774 // first, see if this frame is accessible, and if so, get the respective
2775 SwAccessibleChild aFrameOrObj( pFrame );
2776 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2777 return;
2778
2779 uno::Reference < XAccessible > xAcc;
2780 {
2781 osl::MutexGuard aGuard( maMutex );
2782
2783 if (!mpFrameMap)
2784 return;
2785
2787 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2788 if( aIter != mpFrameMap->end() )
2789 {
2790 xAcc = (*aIter).second;
2791 }
2792 }
2793
2794 // deliver event directly, or queue event
2795 if( !xAcc.is() )
2796 return;
2797
2798 SwAccessibleContext *pAccImpl =
2799 static_cast< SwAccessibleContext *>( xAcc.get() );
2800 if( GetShell()->ActionPend() )
2801 {
2803 pAccImpl, SwAccessibleChild(pFrame),
2804 ( bFrom
2808 }
2809 else
2810 {
2811 FireEvents();
2812 pAccImpl->InvalidateRelation( bFrom
2813 ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
2814 : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
2815 }
2816}
2817
2819 const SwFrame* pFollow )
2820{
2821 InvalidateRelationSet_( pMaster, false );
2822 InvalidateRelationSet_( pFollow, true );
2823}
2824
2825// invalidation of CONTENT_FLOW_FROM/_TO relation of a paragraph
2827 const bool _bFrom )
2828{
2829 InvalidateRelationSet_( &_rTextFrame, _bFrom );
2830}
2831
2832// invalidation of text selection of a paragraph
2834{
2835 // first, see if this frame is accessible, and if so, get the respective
2836 SwAccessibleChild aFrameOrObj( &_rTextFrame );
2837 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2838 return;
2839
2840 uno::Reference < XAccessible > xAcc;
2841 {
2842 osl::MutexGuard aGuard( maMutex );
2843
2844 if (!mpFrameMap)
2845 return;
2846
2848 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2849 if( aIter != mpFrameMap->end() )
2850 {
2851 xAcc = (*aIter).second;
2852 }
2853 }
2854
2855 // deliver event directly, or queue event
2856 if( !xAcc.is() )
2857 return;
2858
2859 SwAccessibleContext *pAccImpl =
2860 static_cast< SwAccessibleContext *>( xAcc.get() );
2861 if( GetShell()->ActionPend() )
2862 {
2865 pAccImpl,
2866 SwAccessibleChild( &_rTextFrame ),
2869 }
2870 else
2871 {
2872 FireEvents();
2873 pAccImpl->InvalidateTextSelection();
2874 }
2875}
2876
2877sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrame& rParentFrame,
2878 vcl::Window& rChild ) const
2879{
2880 sal_Int32 nIndex( -1 );
2881
2882 SwAccessibleChild aFrameOrObj( &rParentFrame );
2883 if( aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2884 {
2885 uno::Reference < XAccessible > xAcc;
2886 {
2887 osl::MutexGuard aGuard( maMutex );
2888
2889 if( mpFrameMap )
2890 {
2892 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2893 if( aIter != mpFrameMap->end() )
2894 {
2895 xAcc = (*aIter).second;
2896 }
2897 }
2898 }
2899
2900 if( xAcc.is() )
2901 {
2902 SwAccessibleContext *pAccImpl =
2903 static_cast< SwAccessibleContext *>( xAcc.get() );
2904
2905 nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
2906 SwAccessibleChild( &rChild ) );
2907 }
2908 }
2909
2910 return nIndex;
2911}
2912
2913void SwAccessibleMap::UpdatePreview( const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
2914 const Fraction& _rScale,
2915 const SwPageFrame* _pSelectedPageFrame,
2916 const Size& _rPreviewWinSize )
2917{
2918 assert(GetShell()->IsPreview() && "no preview?");
2919 assert(mpPreview != nullptr && "no preview data?");
2920
2921 mpPreview->Update( *this, _rPreviewPages, _rScale, _pSelectedPageFrame, _rPreviewWinSize );
2922
2923 // propagate change of VisArea through the document's
2924 // accessibility tree; this will also send appropriate scroll
2925 // events
2926 SwAccessibleContext* pDoc =
2927 GetContextImpl( GetShell()->GetLayout() ).get();
2928 static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
2929
2930 uno::Reference < XAccessible > xOldAcc;
2931 uno::Reference < XAccessible > xAcc;
2932 {
2933 osl::MutexGuard aGuard( maMutex );
2934
2935 xOldAcc = mxCursorContext;
2936
2937 const SwPageFrame *pSelPage = mpPreview->GetSelPage();
2938 if( pSelPage && mpFrameMap )
2939 {
2941 mpFrameMap->find( pSelPage );
2942 if( aIter != mpFrameMap->end() )
2943 xAcc = (*aIter).second;
2944 }
2945 }
2946
2947 if( xOldAcc.is() && xOldAcc != xAcc )
2948 InvalidateCursorPosition( xOldAcc );
2949 if( xAcc.is() )
2951}
2952
2954{
2955 assert(GetShell()->IsPreview());
2956 assert(mpPreview != nullptr);
2957
2958 mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
2959
2960 uno::Reference < XAccessible > xOldAcc;
2961 uno::Reference < XAccessible > xAcc;
2962 {
2963 osl::MutexGuard aGuard( maMutex );
2964
2965 xOldAcc = mxCursorContext;
2966
2967 const SwPageFrame *pSelPage = mpPreview->GetSelPage();
2968 if( pSelPage && mpFrameMap )
2969 {
2970 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pSelPage );
2971 if( aIter != mpFrameMap->end() )
2972 xAcc = (*aIter).second;
2973 }
2974 }
2975
2976 if( xOldAcc.is() && xOldAcc != xAcc )
2977 InvalidateCursorPosition( xOldAcc );
2978 if( xAcc.is() )
2980}
2981
2982bool SwAccessibleMap::IsPageSelected( const SwPageFrame *pPageFrame ) const
2983{
2984 return mpPreview && mpPreview->GetSelPage() == pPageFrame;
2985}
2986
2988{
2989 {
2990 osl::MutexGuard aGuard( maEventMutex );
2991 if( mpEvents )
2992 {
2993 if (mpEvents->IsFiring())
2994 {
2995 return; // prevent recursive FireEvents()
2996 }
2997
2998 mpEvents->SetFiring();
2999 mpEvents->MoveMissingXAccToEnd();
3000 for( auto const& aEvent : *mpEvents )
3002
3003 mpEventMap.reset();
3004 mpEvents.reset();
3005 }
3006 }
3007 {
3008 osl::MutexGuard aGuard( maMutex );
3009 mvShapes.clear();
3010 }
3011
3012}
3013
3015{
3017}
3018
3019// Convert a MM100 value relative to the document root into a pixel value
3020// relative to the screen!
3021Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
3022{
3023 Point aPoint = o3tl::toTwips( rPoint, o3tl::Length::mm100 );
3024 if (const vcl::Window* pWin = GetShell()->GetWin())
3025 {
3026 MapMode aMapMode;
3027 GetMapMode( aPoint, aMapMode );
3028 aPoint = pWin->LogicToPixel( aPoint, aMapMode );
3029 aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
3030 }
3031
3032 return aPoint;
3033}
3034
3036{
3037 Size aSize( o3tl::toTwips( rSize, o3tl::Length::mm100 ) );
3038 if (const OutputDevice* pWin = GetShell()->GetWin()->GetOutDev())
3039 {
3040 MapMode aMapMode;
3041 GetMapMode( Point(0,0), aMapMode );
3042 aSize = pWin->LogicToPixel( aSize, aMapMode );
3043 }
3044
3045 return aSize;
3046}
3047
3049 ::accessibility::AccessibleShape* pCurrentChild,
3050 const uno::Reference< drawing::XShape >& _rxShape,
3051 const tools::Long /*_nIndex*/,
3052 const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
3053 )
3054{
3055 const SdrObject *pObj = nullptr;
3056 {
3057 osl::MutexGuard aGuard( maMutex );
3058 if( mpShapeMap )
3059 {
3062 while( aIter != aEndIter && !pObj )
3063 {
3064 uno::Reference < XAccessible > xAcc( (*aIter).second );
3066 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3067 if( pAccShape == pCurrentChild )
3068 {
3069 pObj = (*aIter).first;
3070 }
3071 ++aIter;
3072 }
3073 }
3074 }
3075 if( !pObj )
3076 return false;
3077
3078 uno::Reference < drawing::XShape > xShape( _rxShape ); // keep reference to shape, because
3079 // we might be the only one that
3080 // holds it.
3081 // Also get keep parent.
3082 uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
3083 pCurrentChild = nullptr; // will be released by dispose
3084 A11yDispose( nullptr, pObj, nullptr );
3085
3086 {
3087 osl::MutexGuard aGuard( maMutex );
3088
3089 if( !mpShapeMap )
3090 mpShapeMap.reset(new SwAccessibleShapeMap_Impl( this ));
3091
3092 // create the new child
3093 ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
3096 xShape, xParent, this );
3098 rShapeTypeHandler.CreateAccessibleObject (
3099 aShapeInfo, mpShapeMap->GetInfo() ));
3100
3101 uno::Reference < XAccessible > xAcc( pReplacement );
3102 if( xAcc.is() )
3103 {
3104 pReplacement->Init();
3105
3106 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->find( pObj );
3107 if( aIter != mpShapeMap->end() )
3108 {
3109 (*aIter).second = xAcc;
3110 }
3111 else
3112 {
3113 mpShapeMap->emplace( pObj, xAcc );
3114 }
3115 }
3116 }
3117
3118 SwRect aEmptyRect;
3119 InvalidatePosOrSize( nullptr, pObj, nullptr, aEmptyRect );
3120
3121 return true;
3122}
3123
3124//Get the accessible control shape from the model object, here model object is with XPropertySet type
3126{
3127 if( mpShapeMap )
3128 {
3131 while( aIter != aEndIter)
3132 {
3133 uno::Reference < XAccessible > xAcc( (*aIter).second );
3135 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3136 if(pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL)
3137 {
3138 ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape);
3139 if (pCtlAccShape->GetControlModel() == pSet)
3140 return pCtlAccShape;
3141 }
3142 ++aIter;
3143 }
3144 }
3145 return nullptr;
3146}
3147
3148css::uno::Reference< XAccessible >
3149 SwAccessibleMap::GetAccessibleCaption (const css::uno::Reference< css::drawing::XShape >&)
3150{
3151 return nullptr;
3152}
3153
3154Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
3155{
3156 Point aPoint;
3157 if (const OutputDevice* pWin = GetShell()->GetWin()->GetOutDev())
3158 {
3159 MapMode aMapMode;
3160 GetMapMode( rPoint, aMapMode );
3161 aPoint = pWin->PixelToLogic( rPoint, aMapMode );
3162 }
3163 return aPoint;
3164}
3165
3167 tools::Long aRefValue, bool bToLower)
3168{
3169 tools::Long aResult = aCoarseValue;
3170
3171 if (bToLower)
3172 {
3173 if (aFineValue < aRefValue)
3174 aResult -= 1;
3175 }
3176 else
3177 {
3178 if (aFineValue > aRefValue)
3179 aResult += 1;
3180 }
3181
3182 return aResult;
3183}
3184
3186 const tools::Rectangle & rSource,
3187 const tools::Rectangle & rInGrid)
3188{
3189 rRect.SetLeft( lcl_CorrectCoarseValue(rRect.Left(), rSource.Left(),
3190 rInGrid.Left(), false) );
3191 rRect.SetTop( lcl_CorrectCoarseValue(rRect.Top(), rSource.Top(),
3192 rInGrid.Top(), false) );
3193 rRect.SetRight( lcl_CorrectCoarseValue(rRect.Right(), rSource.Right(),
3194 rInGrid.Right(), true) );
3195 rRect.SetBottom( lcl_CorrectCoarseValue(rRect.Bottom(), rSource.Bottom(),
3196 rInGrid.Bottom(), true) );
3197}
3198
3200{
3201 tools::Rectangle aRect;
3202 if (const OutputDevice* pWin = GetShell()->GetWin()->GetOutDev())
3203 {
3204 MapMode aMapMode;
3205 GetMapMode( rRect.TopLeft(), aMapMode );
3206 aRect = pWin->LogicToPixel( rRect.SVRect(), aMapMode );
3207
3208 tools::Rectangle aTmpRect = pWin->PixelToLogic( aRect, aMapMode );
3209 lcl_CorrectRectangle(aRect, rRect.SVRect(), aTmpRect);
3210 }
3211
3212 return aRect;
3213}
3214
3223void SwAccessibleMap::GetMapMode( const Point& _rPoint,
3224 MapMode& _orMapMode ) const
3225{
3226 MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
3227 if( GetShell()->IsPreview() )
3228 {
3229 assert(mpPreview != nullptr);
3230 mpPreview->AdjustMapMode( aMapMode, _rPoint );
3231 }
3232 _orMapMode = aMapMode;
3233}
3234
3235Size SwAccessibleMap::GetPreviewPageSize(sal_uInt16 const nPreviewPageNum) const
3236{
3237 assert(mpVSh->IsPreview());
3238 assert(mpPreview != nullptr);
3239 return mpVSh->PagePreviewLayout()->GetPreviewPageSizeByPageNum(nPreviewPageNum);
3240}
3241
3246std::unique_ptr<SwAccessibleSelectedParas_Impl> SwAccessibleMap::BuildSelectedParas()
3247{
3248 // no accessible contexts, no selection
3249 if ( !mpFrameMap )
3250 {
3251 return nullptr;
3252 }
3253
3254 // get cursor as an instance of its base class <SwPaM>
3255 SwPaM* pCursor( nullptr );
3256 {
3257 SwCursorShell* pCursorShell = dynamic_cast<SwCursorShell*>(GetShell());
3258 if ( pCursorShell )
3259 {
3260 SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCursorShell);
3261 if ( !pFEShell ||
3262 ( !pFEShell->IsFrameSelected() &&
3263 pFEShell->IsObjSelected() == 0 ) )
3264 {
3265 // get cursor without updating an existing table cursor.
3266 pCursor = pCursorShell->GetCursor( false );
3267 }
3268 }
3269 }
3270 // no cursor, no selection
3271 if ( !pCursor )
3272 {
3273 return nullptr;
3274 }
3275
3276 std::unique_ptr<SwAccessibleSelectedParas_Impl> pRetSelectedParas;
3277
3278 // loop on all cursors
3279 SwPaM* pRingStart = pCursor;
3280 do {
3281
3282 // for a selection the cursor has to have a mark.
3283 // for safety reasons assure that point and mark are in text nodes
3284 if ( pCursor->HasMark() &&
3285 pCursor->GetPoint()->GetNode().IsTextNode() &&
3286 pCursor->GetMark()->GetNode().IsTextNode() )
3287 {
3288 auto [pStartPos, pEndPos] = pCursor->StartEnd(); // SwPosition*
3289 // loop on all text nodes inside the selection
3290 SwNodeIndex aIdx( pStartPos->GetNode() );
3291 for ( ; aIdx.GetIndex() <= pEndPos->GetNodeIndex(); ++aIdx )
3292 {
3293 SwTextNode* pTextNode( aIdx.GetNode().GetTextNode() );
3294 if ( pTextNode )
3295 {
3296 // loop on all text frames registered at the text node.
3298 for( SwTextFrame* pTextFrame = aIter.First(); pTextFrame; pTextFrame = aIter.Next() )
3299 {
3300 uno::WeakReference < XAccessible > xWeakAcc;
3302 mpFrameMap->find( pTextFrame );
3303 if( aMapIter != mpFrameMap->end() )
3304 {
3305 xWeakAcc = (*aMapIter).second;
3306 SwAccessibleParaSelection aDataEntry(
3307 sw::FrameContainsNode(*pTextFrame, pStartPos->GetNodeIndex())
3308 ? pTextFrame->MapModelToViewPos(*pStartPos)
3309 : TextFrameIndex(0),
3310
3311 sw::FrameContainsNode(*pTextFrame, pEndPos->GetNodeIndex())
3312 ? pTextFrame->MapModelToViewPos(*pEndPos)
3314 if ( !pRetSelectedParas )
3315 {
3316 pRetSelectedParas.reset(
3318 }
3319 // sw_redlinehide: should be idempotent for multiple nodes in a merged para
3320 pRetSelectedParas->emplace( xWeakAcc, aDataEntry );
3321 }
3322 }
3323 }
3324 }
3325 }
3326
3327 // prepare next turn: get next cursor in ring
3328 pCursor = pCursor->GetNext();
3329 } while ( pCursor != pRingStart );
3330
3331 return pRetSelectedParas;
3332}
3333
3335{
3336 osl::MutexGuard aGuard( maMutex );
3337
3338 // keep previously known selected paragraphs
3339 std::unique_ptr<SwAccessibleSelectedParas_Impl> pPrevSelectedParas( std::move(mpSelectedParas) );
3340
3341 // determine currently selected paragraphs
3343
3344 // compare currently selected paragraphs with the previously selected
3345 // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
3346 // first, search for new and changed selections.
3347 // on the run remove selections from previously known ones, if they are
3348 // also in the current ones.
3349 if ( mpSelectedParas )
3350 {
3352 for ( ; aIter != mpSelectedParas->end(); ++aIter )
3353 {
3354 bool bSubmitEvent( false );
3355 if ( !pPrevSelectedParas )
3356 {
3357 // new selection
3358 bSubmitEvent = true;
3359 }
3360 else
3361 {
3363 pPrevSelectedParas->find( (*aIter).first );
3364 if ( aPrevSelected != pPrevSelectedParas->end() )
3365 {
3366 // check, if selection has changed
3367 if ( (*aIter).second.nStartOfSelection !=
3368 (*aPrevSelected).second.nStartOfSelection ||
3369 (*aIter).second.nEndOfSelection !=
3370 (*aPrevSelected).second.nEndOfSelection )
3371 {
3372 // changed selection
3373 bSubmitEvent = true;
3374 }
3375 pPrevSelectedParas->erase( aPrevSelected );
3376 }
3377 else
3378 {
3379 // new selection
3380 bSubmitEvent = true;
3381 }
3382 }
3383
3384 if ( bSubmitEvent )
3385 {
3386 uno::Reference < XAccessible > xAcc( (*aIter).first );
3387 if ( xAcc.is() )
3388 {
3390 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3391 if ( xAccImpl.is() && xAccImpl->GetFrame() )
3392 {
3393 const SwTextFrame* pTextFrame = xAccImpl->GetFrame()->DynCastTextFrame();
3394 OSL_ENSURE( pTextFrame,
3395 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexpected type of frame" );
3396 if ( pTextFrame )
3397 {
3398 InvalidateParaTextSelection( *pTextFrame );
3399 }
3400 }
3401 }
3402 }
3403 }
3404 }
3405
3406 // second, handle previous selections - after the first step the data
3407 // structure of the previously known only contains the 'old' selections
3408 if ( !pPrevSelectedParas )
3409 return;
3410
3411 SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
3412 for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
3413 {
3414 uno::Reference < XAccessible > xAcc( (*aIter).first );
3415 if ( xAcc.is() )
3416 {
3418 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3419 if ( xAccImpl.is() && xAccImpl->GetFrame() )
3420 {
3421 const SwTextFrame* pTextFrame = xAccImpl->GetFrame()->DynCastTextFrame();
3422 OSL_ENSURE( pTextFrame,
3423 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexpected type of frame" );
3424 if ( pTextFrame )
3425 {
3426 InvalidateParaTextSelection( *pTextFrame );
3427 }
3428 }
3429 }
3430 }
3431}
3432
3434{
3435 assert(!GetShell()->IsPreview() || (mpPreview != nullptr));
3436
3437 return GetShell()->IsPreview()
3438 ? mpPreview->GetVisArea()
3439 : GetShell()->VisArea();
3440}
3441
3443{
3444 return GetShell()->GetDoc()->IsPrepareSelAll();
3445}
3446
3447/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void lcl_CorrectRectangle(tools::Rectangle &rRect, const tools::Rectangle &rSource, const tools::Rectangle &rInGrid)
Definition: accmap.cxx:3185
static tools::Long lcl_CorrectCoarseValue(tools::Long aCoarseValue, tools::Long aFineValue, tools::Long aRefValue, bool bToLower)
Definition: accmap.cxx:3166
static bool AreInSameTable(const uno::Reference< XAccessible > &rAcc, const SwFrame *pFrame)
Definition: accmap.cxx:856
std::pair< const SdrObject *, ::rtl::Reference< ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl
Definition: accmap.cxx:248
AccessibleStates
Definition: accmap.hxx:71
const unsigned int SELECTION_WITH_NUM
Definition: acctable.cxx:58
AnyEventRef aEvent
virtual SwDrawModel * GetOrCreateDrawModel()=0
void SetOrigin(const Point &rOrigin)
void SetScaleY(const Fraction &rScaleY)
void SetScaleX(const Fraction &rScaleX)
SdrHintKind GetKind() const
const SdrObject * GetObject() const
size_t GetMarkCount() const
SdrMark * GetMark(size_t nNum) const
SdrObject * GetMarkedSdrObj() const
SdrObject * GetObj(size_t nNum) const
size_t GetObjCount() const
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
virtual SdrObjList * GetSubList() const
bool IsGroupObject() const
SdrObject * getParentSdrObjectFromSdrObject() const
SfxHintId GetId() const
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint)
static bool createEvent(const SdrModel *pDoc, const SdrHint *pSdrHint, css::document::EventObject &aEvent)
const SwPageFrame * mpSelPage
Definition: accmap.cxx:683
void DisposePage(const SwPageFrame *pPageFrame)
Definition: accmap.cxx:823
void AdjustMapMode(MapMode &rMapMode, const Point &rPoint) const
Adjust the MapMode so that the preview page appears at the proper position.
Definition: accmap.cxx:800
void Update(const SwAccessibleMap &rAccMap, const std::vector< std::unique_ptr< PreviewPage > > &_rPreviewPages, const Fraction &_rScale, const SwPageFrame *_pSelectedPageFrame, const Size &_rPreviewWinSize)
Definition: accmap.cxx:733
Rectangles maLogicRects
Definition: accmap.cxx:678
std::vector< tools::Rectangle > Rectangles
Definition: accmap.cxx:676
const SwRect & GetVisArea() const
Definition: accmap.cxx:714
static void AdjustLogicPgRectToVisibleArea(SwRect &_iorLogicPgSwRect, const SwRect &_rPreviewPgSwRect, const Size &_rPreviewWinSize)
adjust logic page rectangle to its visible part
Definition: accmap.cxx:830
Rectangles maPreviewRects
Definition: accmap.cxx:677
void InvalidateSelection(const SwPageFrame *_pSelectedPageFrame)
Definition: accmap.cxx:780
SwRect maVisArea
Definition: accmap.cxx:680
const SwPageFrame * GetSelPage() const
Definition: accmap.cxx:723
Fraction maScale
Definition: accmap.cxx:681
std::pair< iterator, bool > emplace(Args &&... args)
Definition: accmap.cxx:114
uno::WeakReference< XAccessible > mapped_type
Definition: accmap.cxx:90
iterator erase(const_iterator const &pos)
Definition: accmap.cxx:115
const SwFrame * key_type
Definition: accmap.cxx:89
std::map< key_type, mapped_type >::const_iterator const_iterator
Definition: accmap.cxx:93
std::map< key_type, mapped_type > maMap
Definition: accmap.cxx:95
std::map< key_type, mapped_type >::iterator iterator
Definition: accmap.cxx:92
std::pair< const key_type, mapped_type > value_type
Definition: accmap.cxx:91
iterator find(const key_type &key)
Definition: accmap.cxx:112
virtual void Dispose(bool bRecursive, bool bCanSkipInvisible=true)
void FireAccessibleEvent(css::accessibility::AccessibleEventObject &rEvent)
Definition: acccontext.cxx:440
void InvalidateRelation(sal_uInt16 nType)
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
Definition: acccontext.cxx:687
SwAccessibleMap * GetMap()
Definition: acccontext.hxx:112
bool IsSelectedInDoc() const
Definition: acccontext.hxx:350
void InvalidateTextSelection()
#i27301# - text selection has changed
void InvalidateAttr()
#i88069# - attributes has changed
void InvalidateStates(AccessibleStates _nStates)
access to an accessible Writer document
Definition: accdoc.hxx:95
std::list< SwAccessibleEvent_Impl >::iterator erase(const std::list< SwAccessibleEvent_Impl >::iterator &aPos)
Definition: accmap.cxx:555
size_t size() const
Definition: accmap.cxx:547
std::list< SwAccessibleEvent_Impl >::iterator end()
Definition: accmap.cxx:549
std::list< SwAccessibleEvent_Impl >::iterator insert(const std::list< SwAccessibleEvent_Impl >::iterator &aIter, const SwAccessibleEvent_Impl &rEvent)
Definition: accmap.cxx:550
std::list< SwAccessibleEvent_Impl > maEvents
Definition: accmap.cxx:528
std::list< SwAccessibleEvent_Impl >::iterator begin()
Definition: accmap.cxx:548
SwAccessibleChildFunc key_compare
Definition: accmap.cxx:615
iterator erase(const_iterator const &pos)
Definition: accmap.cxx:625
iterator find(const key_type &key)
Definition: accmap.cxx:622
std::map< key_type, mapped_type, key_compare > maMap
Definition: accmap.cxx:619
std::pair< const key_type, mapped_type > value_type
Definition: accmap.cxx:614
SwAccessibleChild key_type
Definition: accmap.cxx:612
std::pair< iterator, bool > emplace(Args &&... args)
Definition: accmap.cxx:624
std::map< key_type, mapped_type, key_compare >::const_iterator const_iterator
Definition: accmap.cxx:617
std::list< SwAccessibleEvent_Impl >::iterator mapped_type
Definition: accmap.cxx:613
std::map< key_type, mapped_type, key_compare >::iterator iterator
Definition: accmap.cxx:616
static bool IsEndnote(const SwFootnoteFrame *pFrame)
virtual bool SetSelectedState(bool bSelected) override
static SwNodeType GetNodeType(const SwFlyFrame *pFlyFrame)
static bool GetChildIndex(SwAccessibleMap &rAccMap, const SwRect &rVisArea, const SwFrame &rFrame, const sw::access::SwAccessibleChild &rChild, sal_Int32 &rPos, bool bInPagePreview)
Definition: accframe.cxx:138
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
const SwFrame * GetParent() const
Definition: accframe.hxx:155
virtual tools::Rectangle GetVisibleArea() const override
Definition: accmap.cxx:3014
std::unique_ptr< SwAccessibleShapeMap_Impl > mpShapeMap
Definition: accmap.hxx:95
void AddShapeContext(const SdrObject *pObj, css::uno::Reference< css::accessibility::XAccessible > const &xAccShape)
Definition: accmap.cxx:1992
void InvalidateRelationSet(const SwFrame *pMaster, const SwFrame *pFollow)
Definition: accmap.cxx:2818
o3tl::sorted_vector< SwAccessibleParagraph * > m_setParaAdd
Definition: accmap.hxx:101
void InvalidateShapeInParaSelection()
Definition: accmap.cxx:1132
tools::Rectangle CoreToPixel(const SwRect &rRect) const
Definition: accmap.cxx:3199
void InvalidatePosOrSize(const SwFrame *pFrame, const SdrObject *pObj, vcl::Window *pWindow, const SwRect &rOldFrame)
Definition: accmap.cxx:2280
std::unique_ptr< SwAccessibleSelectedParas_Impl > mpSelectedParas
Definition: accmap.hxx:106
SwViewShell * mpVSh
Definition: accmap.hxx:107
std::unique_ptr< SwAccessibleSelectedParas_Impl > BuildSelectedParas()
method to build up a new data structure of the accessible paragraphs, which have a selection
Definition: accmap.cxx:3246
std::unique_ptr< SwAccessibleContextMap_Impl > mpFrameMap
Definition: accmap.hxx:94
std::unique_ptr< SwAccessibleEventMap_Impl > mpEventMap
Definition: accmap.hxx:98
mutable::osl::Mutex maMutex
Definition: accmap.hxx:92
void UpdatePreview(const std::vector< std::unique_ptr< PreviewPage > > &_rPreviewPages, const Fraction &_rScale, const SwPageFrame *_pSelectedPageFrame, const Size &_rPreviewWinSize)
Definition: accmap.cxx:2913
void InvalidateParaTextSelection(const SwTextFrame &_rTextFrame)
invalidation of text selection of a paragraph
Definition: accmap.cxx:2833
void InvalidateCursorPosition(const css::uno::Reference< css::accessibility::XAccessible > &rAcc)
void InvalidatePreviewSelection(sal_uInt16 nSelPage)
Definition: accmap.cxx:2953
void InvalidateRelationSet_(const SwFrame *pFrame, bool bFrom)
Definition: accmap.cxx:2771
void FireEvent(const SwAccessibleEvent_Impl &rEvent)
Definition: accmap.cxx:892
::osl::Mutex maEventMutex
Definition: accmap.hxx:93
virtual css::uno::Reference< css::accessibility::XAccessible > GetAccessibleCaption(const css::uno::Reference< css::drawing::XShape > &xShape) override
Definition: accmap.cxx:3149
bool Contains(const SwFrame *pFrame) const
Definition: accmap.cxx:2149
void InvalidateEditableStates(const SwFrame *_pFrame)
Definition: accmap.cxx:2744
o3tl::sorted_vector< SwAccessibleParagraph * > m_setParaRemove
Definition: accmap.hxx:102
SwAccessibleMap(SwViewShell *pSh)
Definition: accmap.cxx:1631
void SetCursorContext(const ::rtl::Reference< SwAccessibleContext > &rCursorContext)
Definition: accmap.cxx:2736
void GetMapMode(const Point &_rPoint, MapMode &_orMapMode) const
get mapping mode for LogicToPixel and PixelToLogic conversions
Definition: accmap.cxx:3223
SwShapeList_Impl mvShapes
Definition: accmap.hxx:96
css::uno::WeakReference< css::accessibility::XAccessible > mxCursorContext
Definition: accmap.hxx:112
virtual bool ReplaceChild(::accessibility::AccessibleShape *pCurrentChild, const css::uno::Reference< css::drawing::XShape > &_rxShape, const tools::Long _nIndex, const ::accessibility::AccessibleShapeTreeInfo &_rShapeTreeInfo) override
Definition: accmap.cxx:3048
static bool IsInSameLevel(const SdrObject *pObj, const SwFEShell *pFESh)
Definition: accmap.cxx:1985
void A11yDispose(const SwFrame *pFrame, const SdrObject *pObj, vcl::Window *pWindow, bool bRecursive=false, bool bCanSkipInvisible=true)
Definition: accmap.cxx:2154
void RemoveGroupContext(const SdrObject *pParentObj)
Definition: accmap.cxx:2004
virtual bool IsDocumentSelAll() override
Definition: accmap.cxx:3442
void InvalidateAttr(const SwTextFrame &rTextFrame)
Definition: accmap.cxx:2455
virtual ~SwAccessibleMap() override
Definition: accmap.cxx:1639
std::unique_ptr< SwAccPreviewData > mpPreview
for page preview: store preview data, VisArea, and mapping of preview-to-display coordinates
Definition: accmap.hxx:110
std::unique_ptr< SwAccessibleEventList_Impl > mpEvents
Definition: accmap.hxx:97
sal_Int32 GetChildIndex(const SwFrame &rParentFrame, vcl::Window &rChild) const
Definition: accmap.cxx:2877
bool mbShapeSelected
Definition: accmap.hxx:114
css::uno::Reference< css::accessibility::XAccessible > GetDocumentView_(bool bPagePreview)
Definition: accmap.cxx:1703
void InvalidateContent(const SwFrame *pFrame)
Definition: accmap.cxx:2417
Size GetPreviewPageSize(sal_uInt16 _nPreviewPageNum) const
get size of a dedicated preview page
Definition: accmap.cxx:3235
css::uno::Reference< css::accessibility::XAccessible > GetDocumentPreview(const std::vector< std::unique_ptr< PreviewPage > > &_rPreviewPages, const Fraction &_rScale, const SwPageFrame *_pSelectedPageFrame, const Size &_rPreviewWinSize)
Definition: accmap.cxx:1770
Point PixelToCore(const Point &rPoint) const
Definition: accmap.cxx:3154
void InvalidateShapeSelection()
Definition: accmap.cxx:1113
css::uno::Reference< css::accessibility::XAccessible > GetDocumentView()
Definition: accmap.cxx:1765
void DoInvalidateShapeSelection(bool bInvalidateFocusMode=false)
Definition: accmap.cxx:1468
::rtl::Reference< SwAccessibleContext > GetContextImpl(const SwFrame *pFrame, bool bCreate=true)
Definition: accmap.cxx:1913
virtual ::accessibility::AccessibleControlShape * GetAccControlShapeFromModel(css::beans::XPropertySet *pSet) override
Definition: accmap.cxx:3125
void FireEvents()
Definition: accmap.cxx:2987
void InvalidateFocus()
Definition: accmap.cxx:2703
void AppendEvent(const SwAccessibleEvent_Impl &rEvent)
Definition: accmap.cxx:974
void InvalidateParaFlowRelation(const SwTextFrame &_rTextFrame, const bool _bFrom)
invalidation CONTENT_FLOWS_FROM/_TO relation of a paragraph
Definition: accmap.cxx:2826
const SwRect & GetVisArea() const
Definition: accmap.cxx:3433
void RemoveContext(const SwFrame *pFrame)
Definition: accmap.cxx:2082
void InvalidateTextSelectionOfAllParas()
invalidation of text selection of all paragraphs
Definition: accmap.cxx:3334
bool IsPageSelected(const SwPageFrame *pPageFrame) const
Definition: accmap.cxx:2982
std::unique_ptr< SwAccessibleContextMap_Impl > mpSelectedFrameMap
Definition: accmap.hxx:126
css::uno::Reference< css::accessibility::XAccessible > GetContext(const SwFrame *pFrame, bool bCreate=true)
Definition: accmap.cxx:1785
void AddGroupContext(const SdrObject *pParentObj, css::uno::Reference< css::accessibility::XAccessible > const &xAccParent)
Definition: accmap.cxx:2026
virtual Point LogicToPixel(const Point &rPoint) const override
Definition: accmap.cxx:3021
SwViewShell * GetShell() const
Definition: accmap.hxx:174
accessibility implementation for the page (SwPageFrame) The page is only visible in the page preview.
Definition: accpage.hxx:33
accessibility implementation for the page preview.
Definition: accpreview.hxx:34
std::map< key_type, mapped_type, key_compare >::const_iterator const_iterator
Definition: accmap.cxx:661
std::map< key_type, mapped_type, key_compare > maMap
Definition: accmap.cxx:663
std::pair< iterator, bool > emplace(Args &&... args)
Definition: accmap.cxx:669
std::map< key_type, mapped_type, key_compare >::iterator iterator
Definition: accmap.cxx:660
SwXAccWeakRefComp key_compare
Definition: accmap.cxx:659
uno::WeakReference< XAccessible > key_type
Definition: accmap.cxx:656
iterator erase(const_iterator const &pos)
Definition: accmap.cxx:670
SwAccessibleParaSelection mapped_type
Definition: accmap.cxx:657
iterator find(const key_type &key)
Definition: accmap.cxx:667
std::pair< const key_type, mapped_type > value_type
Definition: accmap.cxx:658
uno::WeakReference< XAccessible > mapped_type
Definition: accmap.cxx:255
const_iterator cend() const
Definition: accmap.cxx:288
const SdrObject * key_type
Definition: accmap.cxx:254
SwAccessibleShapeMap_Impl(SwAccessibleMap const *pMap)
Definition: accmap.cxx:267
const_iterator cbegin() const
Definition: accmap.cxx:287
std::map< key_type, mapped_type >::const_iterator const_iterator
Definition: accmap.cxx:258
std::unique_ptr< SwAccessibleObjShape_Impl[]> Copy(size_t &rSize, const SwFEShell *pFESh, SwAccessibleObjShape_Impl **pSelShape) const
Definition: accmap.cxx:304
::accessibility::AccessibleShapeTreeInfo maInfo
Definition: accmap.cxx:262
iterator find(const key_type &key)
Definition: accmap.cxx:290
std::map< key_type, mapped_type > maMap
Definition: accmap.cxx:263
const ::accessibility::AccessibleShapeTreeInfo & GetInfo() const
Definition: accmap.cxx:280
std::pair< const key_type, mapped_type > value_type
Definition: accmap.cxx:256
iterator erase(const_iterator const &pos)
Definition: accmap.cxx:293
std::map< key_type, mapped_type >::iterator iterator
Definition: accmap.cxx:257
std::pair< iterator, bool > emplace(Args &&... args)
Definition: accmap.cxx:292
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:31
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1224
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:193
bool IsPrepareSelAll() const
Definition: doc.hxx:570
bool IsObjSameLevelWithMarked(const SdrObject *pObj) const
Definition: feshview.cxx:1293
bool IsFrameSelected() const
Definition: feshview.cxx:1253
const SdrMarkList * GetMarkList() const
Definition: fesh.hxx:520
size_t IsObjSelected() const
Definition: feshview.cxx:1245
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2897
Footer in the document layout, inside a page.
Definition: hffrm.hxx:51
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:69
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:83
Style of a layout element.
Definition: frmfmt.hxx:62
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsCellFrame() const
Definition: frame.hxx:1226
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1111
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
bool IsPageFrame() const
Definition: frame.hxx:1178
SwFrameType GetType() const
Definition: frame.hxx:519
bool IsFlyFrame() const
Definition: frame.hxx:1210
Header in the document layout, inside a page.
Definition: hffrm.hxx:44
TElementType * Next()
Definition: calbck.hxx:364
TElementType * First()
Definition: calbck.hxx:356
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:171
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:876
SwNodeOffset GetIndex() const
Definition: node.hxx:296
bool IsContentNode() const
Definition: node.hxx:656
bool IsTableNode() const
Definition: node.hxx:668
bool IsTextNode() const
Definition: node.hxx:664
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:277
SwPaM * GetNext()
Definition: pam.hxx:320
const SwPosition * GetPoint() const
Definition: pam.hxx:261
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
A page of the document layout.
Definition: pagefrm.hxx:58
Size GetPreviewPageSizeByPageNum(sal_uInt16 _nPageNum) const
get size of a preview page by its physical page number
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:57
bool IsEmpty() const
Definition: swrect.hxx:304
SwRect & Union(const SwRect &rRect)
Definition: swrect.cxx:35
Point TopLeft() const
Definition: swrect.hxx:254
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Clear()
Definition: swrect.hxx:308
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
void AddLeft(const tools::Long nAdd)
Definition: swrect.cxx:125
void AddBottom(const tools::Long nAdd)
Definition: swrect.cxx:130
void AddRight(const tools::Long nAdd)
Definition: swrect.cxx:127
void AddTop(const tools::Long nAdd)
Definition: swrect.cxx:128
tools::Rectangle SVRect() const
Definition: swrect.hxx:292
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
void AddAccessibleShell()
Definition: rootfrm.hxx:390
void RemoveAccessibleShell()
Definition: rootfrm.hxx:391
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:47
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:250
const SwTable & GetTable() const
Definition: node.hxx:521
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:204
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:456
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:463
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
bool IsPreview() const
Definition: viewsh.hxx:501
SwPagePreviewLayout * PagePreviewLayout()
Definition: viewpg.cxx:35
bool ActionPend() const
Definition: viewsh.hxx:204
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
vcl::Window * GetWin() const
Definition: viewsh.hxx:346
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2821
const SwRect & VisArea() const
Definition: viewsh.cxx:630
SwDoc * GetDoc() const
Definition: viewsh.hxx:290
SdrView * GetDrawView()
Definition: vnew.cxx:373
const css::uno::Reference< css::beans::XPropertySet > & GetControlModel() const
void SetViewForwarder(const IAccessibleViewForwarder *pViewForwarder)
void SetWindow(vcl::Window *pWindow)
void SetModelBroadcaster(const css::uno::Reference< css::document::XShapeEventBroadcaster > &rxModelBroadcaster)
const css::uno::Reference< css::document::XShapeEventBroadcaster > & GetModelBroadcaster() const
const css::uno::Reference< css::drawing::XShape > & GetXShape() const
virtual bool SetState(sal_Int64 aState) override
rtl::Reference< AccessibleShape > CreateAccessibleObject(const AccessibleShapeInfo &rShapeInfo, const AccessibleShapeTreeInfo &rShapeTreeInfo) const
ShapeTypeId GetTypeId(const OUString &aServiceName) const
static ShapeTypeHandler & Instance()
size_type count(const Value &v) const
std::pair< const_iterator, bool > insert(Value &&x)
ring_container GetRingContainer()
Definition: ring.hxx:240
bool Contains(const Point &rPOINT) const
constexpr void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr void SetRight(tools::Long v)
constexpr tools::Long Right() const
constexpr void SetBottom(tools::Long v)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
bool HasFocus() const
const MapMode & GetMapMode() const
svx::diagram::Point & mrPoint
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:121
#define DBG_TESTSOLARMUTEX()
#define TOOLS_WARN_EXCEPTION(area, stream)
void Notify(SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, const SwRect *pOldRect=nullptr)
Notify the background based on the difference between old and new rectangle.
Definition: frmtool.cxx:3238
sal_Int32 nIndex
void Dispose(const T &xInterface)
NONE
int i
constexpr auto toTwips(N number, Length from)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
args
bool FrameContainsNode(SwContentFrame const &rFrame, SwNodeOffset nNodeIndex)
Definition: txtfrm.cxx:290
long Long
bool IsInvalidateRelation() const
Definition: accmap.cxx:501
SwAccessibleEvent_Impl(EventType eT, const SwFrame *pParentFrame, SwAccessibleChild aFrameOrObj, const SwRect &rR)
Definition: accmap.cxx:441
SwAccessibleEvent_Impl(EventType eT, SwAccessibleChild aFrameOrObj)
Definition: accmap.cxx:391
AccessibleStates mnStates
Definition: accmap.cxx:371
SwAccessibleEvent_Impl(EventType eT, SwAccessibleContext *pA, SwAccessibleChild aFrameOrObj, const SwRect &rR)
Definition: accmap.cxx:411
const SwAccessibleChild & GetFrameOrObj() const
Definition: accmap.cxx:482
void SetOldBox(const SwRect &rOldBox)
Definition: accmap.cxx:477
AccessibleStates GetAllStates() const
Definition: accmap.cxx:520
bool IsNoXaccParentFrame() const
Definition: accmap.cxx:375
SwAccessibleChild maFrameOrObj
Definition: accmap.cxx:367
SwAccessibleEvent_Impl(EventType eT, SwAccessibleContext *pA, SwAccessibleChild aFrameOrObj, const AccessibleStates _nStates)
Definition: accmap.cxx:427
SwAccessibleEvent_Impl(EventType eT)
Definition: accmap.cxx:402
void SetType(EventType eT)
Definition: accmap.cxx:454
AccessibleStates GetStates() const
Definition: accmap.cxx:515
const SwRect & GetOldBox() const
Definition: accmap.cxx:472
bool IsInvalidateTextSelection() const
Definition: accmap.cxx:505
SwAccessibleEvent_Impl(EventType eT, SwAccessibleContext *pA, SwAccessibleChild aFrameOrObj)
Definition: accmap.cxx:381
::rtl::Reference< SwAccessibleContext > GetContext() const
Definition: accmap.cxx:463
uno::WeakReference< XAccessible > mxAcc
Definition: accmap.cxx:366
EventType GetType() const
Definition: accmap.cxx:458
const SwFrame * mpParentFrame
Definition: accmap.cxx:374
bool IsInvalidateTextAttrs() const
Definition: accmap.cxx:510
void SetStates(AccessibleStates _nStates)
Definition: accmap.cxx:488
bool IsInvalidateStates() const
Definition: accmap.cxx:497
bool IsUpdateCursorPos() const
Definition: accmap.cxx:493
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
UNDERLYING_TYPE get() const
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:963
tools::Long SwTwips
Definition: swtypes.hxx:51
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
bool IsSelectFrameAnchoredAtPara(SwPosition const &rAnchorPos, SwPosition const &rStart, SwPosition const &rEnd, DelContentType const nDelContentType)
is a fly anchored at paragraph at rAnchorPos selected?
Definition: undobj.cxx:1647
bool IsDestroyFrameAnchoredAtChar(SwPosition const &rAnchorPos, SwPosition const &rStart, SwPosition const &rEnd, DelContentType const nDelContentType)
will DelContentIndex destroy a frame anchored at character at rAnchorPos?
Definition: undobj.cxx:1606
size_t pos