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 // tdf#150708 if the old is CARET_OR_STATES then try updating it
1064 // with the additional states
1066 aEvent.SetStates(rEvent.GetAllStates());
1067 else
1068 {
1069 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR,
1070 "invalid event combination" );
1071 }
1072 break;
1073 }
1074 if( bAppendEvent )
1075 {
1076 mpEvents->erase( (*aIter).second );
1077 (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent );
1078 }
1079 else
1080 {
1081 mpEvents->erase( (*aIter).second );
1082 mpEventMap->erase( aIter );
1083 }
1084 }
1085 else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
1086 {
1087 mpEventMap->emplace( rEvent.GetFrameOrObj(),
1088 mpEvents->insert( mpEvents->end(), rEvent ) );
1089 }
1090 }
1091}
1092
1094 const uno::Reference< XAccessible >& rAcc )
1095{
1096 SwAccessibleContext *pAccImpl =
1097 static_cast< SwAccessibleContext *>( rAcc.get() );
1098 assert(pAccImpl);
1099 assert(pAccImpl->GetFrame());
1100 if( GetShell()->ActionPend() )
1101 {
1103 pAccImpl,
1104 SwAccessibleChild(pAccImpl->GetFrame()),
1106 AppendEvent( aEvent );
1107 }
1108 else
1109 {
1110 FireEvents();
1111 // While firing events the current frame might have
1112 // been disposed because it moved out of the visible area.
1113 // Setting the cursor for such frames is useless and even
1114 // causes asserts.
1115 if( pAccImpl->GetFrame() )
1116 pAccImpl->InvalidateCursorPos();
1117 }
1118}
1119
1121{
1122 if( GetShell()->ActionPend() )
1123 {
1127 }
1128 else
1129 {
1130 FireEvents();
1132 }
1133}
1134
1135//This method should implement the following functions:
1136//1.find the shape objects and set the selected state.
1137//2.find the Swframe objects and set the selected state.
1138//3.find the paragraph objects and set the selected state.
1140{
1141 std::unique_ptr<SwAccessibleObjShape_Impl[]> pShapes;
1142 SwAccessibleObjShape_Impl *pSelShape = nullptr;
1143 size_t nShapes = 0;
1144
1145 const SwViewShell *pVSh = GetShell();
1146 const SwFEShell *pFESh = dynamic_cast<const SwFEShell*>(pVSh);
1147 SwPaM* pCursor = pFESh ? pFESh->GetCursor( false /* ??? */ ) : nullptr;
1148
1149 //const size_t nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1150
1151 {
1152 osl::MutexGuard aGuard( maMutex );
1153 if( mpShapeMap )
1154 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1155 }
1156
1157 bool bIsSelAll =IsDocumentSelAll();
1158
1159 if( mpShapeMap )
1160 {
1161 //Checked for shapes.
1164
1165 if( bIsSelAll)
1166 {
1167 while( aIter != aEndIter )
1168 {
1169 uno::Reference < XAccessible > xAcc( (*aIter).second );
1170 if( xAcc.is() )
1171 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1172
1173 ++aIter;
1174 }
1175 }
1176 else
1177 {
1178 while( aIter != aEndIter )
1179 {
1180 const SwFrameFormat *pFrameFormat = (*aIter).first ? ::FindFrameFormat( (*aIter).first ) : nullptr;
1181 if( !pFrameFormat )
1182 {
1183 ++aIter;
1184 continue;
1185 }
1186 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1187 const SwNode *pAnchorNode = rAnchor.GetAnchorNode();
1188
1189 if(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
1190 {
1191 uno::Reference < XAccessible > xAcc( (*aIter).second );
1192 if(xAcc.is())
1193 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1194
1195 ++aIter;
1196 continue;
1197 }
1198
1199 if( !pAnchorNode )
1200 {
1201 ++aIter;
1202 continue;
1203 }
1204 if( pAnchorNode->GetTextNode() )
1205 {
1206 sal_Int32 nIndex = rAnchor.GetAnchorContentOffset();
1207 bool bMarked = false;
1208 if( pCursor != nullptr )
1209 {
1210 const SwTextNode* pNode = pAnchorNode->GetTextNode();
1211 SwTextFrame const*const pFrame(static_cast<SwTextFrame*>(pNode->getLayoutFrame(pVSh->GetLayout())));
1212 SwNodeOffset nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
1213 SwNodeOffset nLastNode;
1214 if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
1215 {
1216 nLastNode = pMerged->pLastNode->GetIndex();
1217 }
1218 else
1219 {
1220 nLastNode = nFirstNode;
1221 }
1222
1223 SwNodeOffset nHere = pNode->GetIndex();
1224
1225 for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
1226 {
1227 // ignore, if no mark
1228 if( rTmpCursor.HasMark() )
1229 {
1230 bMarked = true;
1231 // check whether nHere is 'inside' pCursor
1232 SwPosition* pStart = rTmpCursor.Start();
1233 SwNodeOffset nStartIndex = pStart->GetNodeIndex();
1234 SwPosition* pEnd = rTmpCursor.End();
1235 SwNodeOffset nEndIndex = pEnd->GetNodeIndex();
1236 if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
1237 {
1238 if( rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
1239 {
1240 if( ( ((nHere == nStartIndex) && (nIndex >= pStart->GetContentIndex())) || (nHere > nStartIndex) )
1241 &&( ((nHere == nEndIndex) && (nIndex < pEnd->GetContentIndex())) || (nHere < nEndIndex) ) )
1242 {
1243 uno::Reference < XAccessible > xAcc( (*aIter).second );
1244 if( xAcc.is() )
1245 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1246 }
1247 else
1248 {
1249 uno::Reference < XAccessible > xAcc( (*aIter).second );
1250 if( xAcc.is() )
1251 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1252 }
1253 }
1254 else if( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA )
1255 {
1256 uno::Reference<XAccessible> const xAcc((*aIter).second);
1257 if (xAcc.is())
1258 {
1259 if (IsSelectFrameAnchoredAtPara(*rAnchor.GetContentAnchor(), *pStart, *pEnd))
1260 {
1261 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1262 }
1263 else
1264 {
1265 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1266 }
1267 }
1268 }
1269 else if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
1270 {
1271 uno::Reference<XAccessible> const xAcc((*aIter).second);
1272 if (xAcc.is())
1273 {
1274 if (IsDestroyFrameAnchoredAtChar(*rAnchor.GetContentAnchor(), *pStart, *pEnd))
1275 {
1276 static_cast<::accessibility::AccessibleShape*>(xAcc.get())->SetState( AccessibleStateType::SELECTED );
1277 }
1278 else
1279 {
1280 static_cast<::accessibility::AccessibleShape*>(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1281 }
1282 }
1283 }
1284 }
1285 }
1286 }
1287 }
1288 if( !bMarked )
1289 {
1290 SwAccessibleObjShape_Impl *pShape = pShapes.get();
1291 size_t nNumShapes = nShapes;
1292 while( nNumShapes )
1293 {
1294 if( pShape < pSelShape && (pShape->first==(*aIter).first) )
1295 {
1296 uno::Reference < XAccessible > xAcc( (*aIter).second );
1297 if(xAcc.is())
1298 static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED );
1299 }
1300 --nNumShapes;
1301 ++pShape;
1302 }
1303 }
1304 }
1305
1306 ++aIter;
1307 }//while( aIter != aEndIter )
1308 }//else
1309 }
1310
1311 pShapes.reset();
1312
1313 //Checked for FlyFrame
1314 if (mpFrameMap)
1315 {
1317 while( aIter != mpFrameMap->end() )
1318 {
1319 const SwFrame *pFrame = (*aIter).first;
1320 if(pFrame->IsFlyFrame())
1321 {
1322 uno::Reference < XAccessible > xAcc = (*aIter).second;
1323
1324 if(xAcc.is())
1325 {
1326 SwAccessibleFrameBase *pAccFrame = static_cast< SwAccessibleFrameBase * >(xAcc.get());
1327 bool bFrameChanged = pAccFrame->SetSelectedState( true );
1328 if (bFrameChanged)
1329 {
1330 const SwFlyFrame *pFlyFrame = static_cast< const SwFlyFrame * >( pFrame );
1331 const SwFrameFormat *pFrameFormat = pFlyFrame->GetFormat();
1332 if (pFrameFormat)
1333 {
1334 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1335 if( rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
1336 {
1337 uno::Reference< XAccessible > xAccParent = pAccFrame->getAccessibleParent();
1338 if (xAccParent.is())
1339 {
1340 uno::Reference< XAccessibleContext > xAccContext = xAccParent->getAccessibleContext();
1341 if(xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1342 {
1343 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xAccContext.get());
1344 if(pAccFrame->IsSelectedInDoc())
1345 {
1346 m_setParaAdd.insert(pAccPara);
1347 }
1348 else if(m_setParaAdd.count(pAccPara) == 0)
1349 {
1350 m_setParaRemove.insert(pAccPara);
1351 }
1352 }
1353 }
1354 }
1355 }
1356 }
1357 }
1358 }
1359 ++aIter;
1360 }
1361 }
1362
1363 typedef std::vector< SwAccessibleContext* > VEC_PARA;
1364 VEC_PARA vecAdd;
1365 VEC_PARA vecRemove;
1366 //Checked for Paras.
1367 bool bMarkChanged = false;
1369 if( pCursor != nullptr )
1370 {
1371 for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
1372 {
1373 if( rTmpCursor.HasMark() )
1374 {
1375 SwNodeIndex nStartIndex( rTmpCursor.Start()->GetNode() );
1376 SwNodeIndex nEndIndex( rTmpCursor.End()->GetNode() );
1377 for (; nStartIndex <= nEndIndex; ++nStartIndex)
1378 {
1379 SwFrame *pFrame = nullptr;
1380 if(nStartIndex.GetNode().IsContentNode())
1381 {
1382 SwContentNode* pCNd = static_cast<SwContentNode*>(&(nStartIndex.GetNode()));
1384 if (mapTemp.find(pFrame) != mapTemp.end())
1385 {
1386 continue; // sw_redlinehide: once is enough
1387 }
1388 }
1389 else if( nStartIndex.GetNode().IsTableNode() )
1390 {
1391 SwTableNode * pTable = static_cast<SwTableNode *>(&(nStartIndex.GetNode()));
1392 SwTableFormat* pFormat = pTable->GetTable().GetFrameFormat();
1393 pFrame = SwIterator<SwFrame, SwTableFormat>(*pFormat).First();
1394 }
1395
1396 if( pFrame && mpFrameMap)
1397 {
1398 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pFrame );
1399 if( aIter != mpFrameMap->end() )
1400 {
1401 uno::Reference < XAccessible > xAcc = (*aIter).second;
1402 bool isChanged = false;
1403 if( xAcc.is() )
1404 {
1405 isChanged = static_cast< SwAccessibleContext * >(xAcc.get())->SetSelectedState( true );
1406 }
1407 if(!isChanged)
1408 {
1409 SwAccessibleContextMap_Impl::iterator aEraseIter = mpSelectedFrameMap->find( pFrame );
1410 if(aEraseIter != mpSelectedFrameMap->end())
1411 mpSelectedFrameMap->erase(aEraseIter);
1412 }
1413 else
1414 {
1415 bMarkChanged = true;
1416 vecAdd.push_back(static_cast< SwAccessibleContext * >(xAcc.get()));
1417 }
1418
1419 mapTemp.emplace( pFrame, xAcc );
1420 }
1421 }
1422 }
1423 }
1424 }
1425 }
1426 if( !mpSelectedFrameMap )
1428 if( !mpSelectedFrameMap->empty() )
1429 {
1431 while( aIter != mpSelectedFrameMap->end() )
1432 {
1433 uno::Reference < XAccessible > xAcc = (*aIter).second;
1434 if(xAcc.is())
1435 static_cast< SwAccessibleContext * >(xAcc.get())->SetSelectedState( false );
1436 ++aIter;
1437 vecRemove.push_back(static_cast< SwAccessibleContext * >(xAcc.get()));
1438 }
1439 bMarkChanged = true;
1440 mpSelectedFrameMap->clear();
1441 }
1442
1444 while( aIter != mapTemp.end() )
1445 {
1446 mpSelectedFrameMap->emplace( (*aIter).first, (*aIter).second );
1447 ++aIter;
1448 }
1449 mapTemp.clear();
1450
1451 if( !(bMarkChanged && mpFrameMap))
1452 return;
1453
1454 for (SwAccessibleContext* pAccPara : vecAdd)
1455 {
1456 AccessibleEventObject aEvent;
1457 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1458 if (pAccPara)
1459 {
1460 pAccPara->FireAccessibleEvent( aEvent );
1461 }
1462 }
1463 for (SwAccessibleContext* pAccPara : vecRemove)
1464 {
1465 AccessibleEventObject aEvent;
1466 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
1467 if (pAccPara)
1468 {
1469 pAccPara->FireAccessibleEvent( aEvent );
1470 }
1471 }
1472}
1473
1474//Merge with DoInvalidateShapeFocus
1475void SwAccessibleMap::DoInvalidateShapeSelection(bool bInvalidateFocusMode /*=false*/)
1476{
1477 std::unique_ptr<SwAccessibleObjShape_Impl[]> pShapes;
1478 SwAccessibleObjShape_Impl *pSelShape = nullptr;
1479 size_t nShapes = 0;
1480
1481 const SwViewShell *pVSh = GetShell();
1482 const SwFEShell *pFESh = dynamic_cast<const SwFEShell*>(pVSh);
1483 const size_t nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1484
1485 //when InvalidateFocus Call this function ,and the current selected shape count is not 1 ,
1486 //return
1487 if (bInvalidateFocusMode && nSelShapes != 1)
1488 {
1489 return;
1490 }
1491 {
1492 osl::MutexGuard aGuard( maMutex );
1493 if( mpShapeMap )
1494 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1495 }
1496
1497 if( !pShapes )
1498 return;
1499
1500 typedef std::vector< ::rtl::Reference < ::accessibility::AccessibleShape > > VEC_SHAPE;
1501 VEC_SHAPE vecxShapeAdd;
1502 VEC_SHAPE vecxShapeRemove;
1503 int nCountSelectedShape=0;
1504
1505 vcl::Window *pWin = GetShell()->GetWin();
1506 bool bFocused = pWin && pWin->HasFocus();
1507 SwAccessibleObjShape_Impl *pShape = pShapes.get();
1508 int nShapeCount = nShapes;
1509 while( nShapeCount )
1510 {
1511 if (pShape->second.is() && IsInSameLevel(pShape->first, pFESh))
1512 {
1513 if( pShape < pSelShape )
1514 {
1515 if(pShape->second->ResetState( AccessibleStateType::SELECTED ))
1516 {
1517 vecxShapeRemove.push_back(pShape->second);
1518 }
1519 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1520 }
1521 }
1522 --nShapeCount;
1523 ++pShape;
1524 }
1525
1526 for (const auto& rpShape : vecxShapeRemove)
1527 {
1528 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1529 if (pAccShape)
1530 {
1531 pAccShape->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, uno::Any(), uno::Any());
1532 }
1533 }
1534
1535 pShape = pShapes.get();
1536
1537 while( nShapes )
1538 {
1539 if (pShape->second.is() && IsInSameLevel(pShape->first, pFESh))
1540 {
1541 if( pShape >= pSelShape )
1542 {
1543 //first fire focus event
1544 if( bFocused && 1 == nSelShapes )
1545 pShape->second->SetState( AccessibleStateType::FOCUSED );
1546 else
1547 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1548
1549 if(pShape->second->SetState( AccessibleStateType::SELECTED ))
1550 {
1551 vecxShapeAdd.push_back(pShape->second);
1552 }
1553 ++nCountSelectedShape;
1554 }
1555 }
1556
1557 --nShapes;
1558 ++pShape;
1559 }
1560
1561 const unsigned int SELECTION_WITH_NUM = 10;
1562 if (vecxShapeAdd.size() > SELECTION_WITH_NUM )
1563 {
1564 uno::Reference< XAccessible > xDoc = GetDocumentView( );
1565 SwAccessibleContext * pCont = static_cast<SwAccessibleContext *>(xDoc.get());
1566 if (pCont)
1567 {
1568 AccessibleEventObject aEvent;
1569 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1571 }
1572 }
1573 else
1574 {
1575 short nEventID = AccessibleEventId::SELECTION_CHANGED_ADD;
1576 if (nCountSelectedShape <= 1 && vecxShapeAdd.size() == 1 )
1577 {
1578 nEventID = AccessibleEventId::SELECTION_CHANGED;
1579 }
1580 for (const auto& rpShape : vecxShapeAdd)
1581 {
1582 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1583 if (pAccShape)
1584 {
1585 pAccShape->CommitChange(nEventID, uno::Any(), uno::Any());
1586 }
1587 }
1588 }
1589
1590 for (const auto& rpShape : vecxShapeAdd)
1591 {
1592 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1593 if (pAccShape)
1594 {
1596 SwFrameFormat *pFrameFormat = pObj ? FindFrameFormat( pObj ) : nullptr;
1597 if (pFrameFormat)
1598 {
1599 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1600 if( rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
1601 {
1602 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
1603 if (xPara.is())
1604 {
1605 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext();
1606 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1607 {
1608 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get());
1609 if (pAccPara)
1610 {
1611 m_setParaAdd.insert(pAccPara);
1612 }
1613 }
1614 }
1615 }
1616 }
1617 }
1618 }
1619 for (const auto& rpShape : vecxShapeRemove)
1620 {
1621 ::accessibility::AccessibleShape *pAccShape = rpShape.get();
1622 if (pAccShape && !pAccShape->IsDisposed())
1623 {
1624 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
1625 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext();
1626 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1627 {
1628 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get());
1629 if (m_setParaAdd.count(pAccPara) == 0 )
1630 {
1631 m_setParaRemove.insert(pAccPara);
1632 }
1633 }
1634 }
1635 }
1636}
1637
1639 mpVSh( pSh ),
1640 mbShapeSelected( false ),
1641 maDocName(SwAccessibleContext::GetResource(STR_ACCESS_DOC_NAME))
1642{
1643 pSh->GetLayout()->AddAccessibleShell();
1644}
1645
1647{
1649 uno::Reference < XAccessible > xAcc;
1650 {
1651 osl::MutexGuard aGuard( maMutex );
1652 if( mpFrameMap )
1653 {
1654 const SwRootFrame *pRootFrame = GetShell()->GetLayout();
1655 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pRootFrame );
1656 if( aIter != mpFrameMap->end() )
1657 xAcc = (*aIter).second;
1658 if( !xAcc.is() )
1659 assert(false); // let's hope this can't happen? the vcl::Window apparently owns the top-level
1660 //xAcc = new SwAccessibleDocument(shared_from_this());
1661 }
1662 }
1663
1664 if(xAcc.is())
1665 {
1666 SwAccessibleDocumentBase *const pAcc =
1667 static_cast<SwAccessibleDocumentBase *>(xAcc.get());
1668 pAcc->Dispose( true );
1669 }
1670#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
1671 if( mpFrameMap )
1672 {
1674 while( aIter != mpFrameMap->end() )
1675 {
1676 uno::Reference < XAccessible > xTmp = (*aIter).second;
1677 if( xTmp.is() )
1678 {
1679 SwAccessibleContext *pTmp = static_cast< SwAccessibleContext * >( xTmp.get() );
1680 assert(pTmp->GetMap() == nullptr); // must be disposed
1681 }
1682 ++aIter;
1683 }
1684 }
1685#endif
1686 {
1687 osl::MutexGuard aGuard( maMutex );
1688 assert((!mpFrameMap || mpFrameMap->empty()) &&
1689 "Frame map should be empty after disposing the root frame");
1690 assert((!mpShapeMap || mpShapeMap->empty()) &&
1691 "Object map should be empty after disposing the root frame");
1692 mpFrameMap.reset();
1693 mpShapeMap.reset();
1694 mvShapes.clear();
1695 mpSelectedParas.reset();
1696 }
1697
1698 mpPreview.reset();
1699
1700 {
1701 osl::MutexGuard aGuard( maEventMutex );
1702 assert(!mpEvents);
1703 assert(!mpEventMap);
1704 mpEventMap.reset();
1705 mpEvents.reset();
1706 }
1708}
1709
1710uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView_(
1711 bool bPagePreview )
1712{
1713 uno::Reference < XAccessible > xAcc;
1714 bool bSetVisArea = false;
1715
1716 {
1717 osl::MutexGuard aGuard( maMutex );
1718
1719 if( !mpFrameMap )
1720 {
1722#if OSL_DEBUG_LEVEL > 0
1723 mpFrameMap->mbLocked = false;
1724#endif
1725 }
1726
1727#if OSL_DEBUG_LEVEL > 0
1728 assert(!mpFrameMap->mbLocked);
1729 mpFrameMap->mbLocked = true;
1730#endif
1731
1732 const SwRootFrame *pRootFrame = GetShell()->GetLayout();
1733 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pRootFrame );
1734 if( aIter != mpFrameMap->end() )
1735 xAcc = (*aIter).second;
1736 if( xAcc.is() )
1737 {
1738 bSetVisArea = true; // Set VisArea when map mutex is not locked
1739 }
1740 else
1741 {
1742 if( bPagePreview )
1743 xAcc = new SwAccessiblePreview(shared_from_this());
1744 else
1745 xAcc = new SwAccessibleDocument(shared_from_this());
1746
1747 if( aIter != mpFrameMap->end() )
1748 {
1749 (*aIter).second = xAcc;
1750 }
1751 else
1752 {
1753 mpFrameMap->emplace( pRootFrame, xAcc );
1754 }
1755 }
1756
1757#if OSL_DEBUG_LEVEL > 0
1758 mpFrameMap->mbLocked = false;
1759#endif
1760 }
1761
1762 if( bSetVisArea )
1763 {
1765 static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
1766 pAcc->SetVisArea();
1767 }
1768
1769 return xAcc;
1770}
1771
1772uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
1773{
1774 return GetDocumentView_( false );
1775}
1776
1777uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
1778 const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
1779 const Fraction& _rScale,
1780 const SwPageFrame* _pSelectedPageFrame,
1781 const Size& _rPreviewWinSize )
1782{
1783 // create & update preview data object
1784 if( mpPreview == nullptr )
1785 mpPreview.reset( new SwAccPreviewData() );
1786 mpPreview->Update( *this, _rPreviewPages, _rScale, _pSelectedPageFrame, _rPreviewWinSize );
1787
1788 uno::Reference<XAccessible> xAcc = GetDocumentView_( true );
1789 return xAcc;
1790}
1791
1792uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrame *pFrame,
1793 bool bCreate )
1794{
1796 uno::Reference < XAccessible > xAcc;
1797 uno::Reference < XAccessible > xOldCursorAcc;
1798 bool bOldShapeSelected = false;
1799
1800 {
1801 osl::MutexGuard aGuard( maMutex );
1802
1803 if( !mpFrameMap && bCreate )
1805 if( mpFrameMap )
1806 {
1807 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pFrame );
1808 if( aIter != mpFrameMap->end() )
1809 xAcc = (*aIter).second;
1810
1811 if( !xAcc.is() && bCreate )
1812 {
1814 switch( pFrame->GetType() )
1815 {
1816 case SwFrameType::Txt:
1817 pAcc = new SwAccessibleParagraph(shared_from_this(),
1818 static_cast< const SwTextFrame& >( *pFrame ) );
1819 break;
1821 pAcc = new SwAccessibleHeaderFooter(shared_from_this(),
1822 static_cast< const SwHeaderFrame *>( pFrame ) );
1823 break;
1825 pAcc = new SwAccessibleHeaderFooter(shared_from_this(),
1826 static_cast< const SwFooterFrame *>( pFrame ) );
1827 break;
1828 case SwFrameType::Ftn:
1829 {
1830 const SwFootnoteFrame *pFootnoteFrame =
1831 static_cast < const SwFootnoteFrame * >( pFrame );
1832 bool bIsEndnote =
1833 SwAccessibleFootnote::IsEndnote( pFootnoteFrame );
1834 pAcc = new SwAccessibleFootnote(shared_from_this(), bIsEndnote,
1835 /*(bIsEndnote ? mnEndnote++ : mnFootnote++),*/
1836 pFootnoteFrame );
1837 }
1838 break;
1839 case SwFrameType::Fly:
1840 {
1841 const SwFlyFrame *pFlyFrame =
1842 static_cast < const SwFlyFrame * >( pFrame );
1843 switch( SwAccessibleFrameBase::GetNodeType( pFlyFrame ) )
1844 {
1845 case SwNodeType::Grf:
1846 pAcc = new SwAccessibleGraphic(shared_from_this(), pFlyFrame );
1847 break;
1848 case SwNodeType::Ole:
1849 pAcc = new SwAccessibleEmbeddedObject(shared_from_this(), pFlyFrame );
1850 break;
1851 default:
1852 pAcc = new SwAccessibleTextFrame(shared_from_this(), *pFlyFrame );
1853 break;
1854 }
1855 }
1856 break;
1857 case SwFrameType::Cell:
1858 pAcc = new SwAccessibleCell(shared_from_this(),
1859 static_cast< const SwCellFrame *>( pFrame ) );
1860 break;
1861 case SwFrameType::Tab:
1862 pAcc = new SwAccessibleTable(shared_from_this(),
1863 static_cast< const SwTabFrame *>( pFrame ) );
1864 break;
1865 case SwFrameType::Page:
1866 OSL_ENSURE( GetShell()->IsPreview(),
1867 "accessible page frames only in PagePreview" );
1868 pAcc = new SwAccessiblePage(shared_from_this(), pFrame);
1869 break;
1870 default: break;
1871 }
1872 xAcc = pAcc;
1873 assert(xAcc.is());
1874
1875 if( aIter != mpFrameMap->end() )
1876 {
1877 (*aIter).second = xAcc;
1878 }
1879 else
1880 {
1881 mpFrameMap->emplace( pFrame, xAcc );
1882 }
1883
1884 if( pAcc->HasCursor() &&
1885 !AreInSameTable( mxCursorContext, pFrame ) )
1886 {
1887 // If the new context has the focus, and if we know
1888 // another context that had the focus, then the focus
1889 // just moves from the old context to the new one. We
1890 // then have to send a focus event and a caret event for
1891 // the old context. We have to do that now,
1892 // because after we have left this method, anyone might
1893 // call getStates for the new context and will get a
1894 // focused state then. Sending the focus changes event
1895 // after that seems to be strange. However, we cannot
1896 // send a focus event for the new context now, because
1897 // no one except us knows it. In any case, we remember
1898 // the new context as the one that has the focus
1899 // currently.
1900
1901 xOldCursorAcc = mxCursorContext;
1902 mxCursorContext = xAcc;
1903
1904 bOldShapeSelected = mbShapeSelected;
1905 mbShapeSelected = false;
1906 }
1907 }
1908 }
1909 }
1910
1911 // Invalidate focus for old object when map is not locked
1912 if( xOldCursorAcc.is() )
1913 InvalidateCursorPosition( xOldCursorAcc );
1914 if( bOldShapeSelected )
1916
1917 return xAcc;
1918}
1919
1921 const SwFrame *pFrame,
1922 bool bCreate )
1923{
1924 uno::Reference < XAccessible > xAcc( GetContext( pFrame, bCreate ) );
1925
1927 static_cast< SwAccessibleContext * >( xAcc.get() ) );
1928
1929 return xAccImpl;
1930}
1931
1932uno::Reference< XAccessible> SwAccessibleMap::GetContext(
1933 const SdrObject *pObj,
1934 SwAccessibleContext *pParentImpl,
1935 bool bCreate )
1936{
1937 uno::Reference < XAccessible > xAcc;
1938 uno::Reference < XAccessible > xOldCursorAcc;
1939
1940 {
1941 osl::MutexGuard aGuard( maMutex );
1942
1943 if( !mpShapeMap && bCreate )
1944 mpShapeMap.reset(new SwAccessibleShapeMap_Impl( this ));
1945 if( mpShapeMap )
1946 {
1947 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->find( pObj );
1948 if( aIter != mpShapeMap->end() )
1949 xAcc = (*aIter).second;
1950
1951 if( !xAcc.is() && bCreate )
1952 {
1954 uno::Reference < drawing::XShape > xShape(
1955 const_cast< SdrObject * >( pObj )->getUnoShape(),
1956 uno::UNO_QUERY );
1957 if( xShape.is() )
1958 {
1959 ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
1961 uno::Reference < XAccessible > xParent( pParentImpl );
1963 xShape, xParent, this );
1964
1965 pAcc = rShapeTypeHandler.CreateAccessibleObject(
1966 aShapeInfo, mpShapeMap->GetInfo() );
1967 }
1968 xAcc = pAcc.get();
1969 assert(xAcc.is());
1970 pAcc->Init();
1971 if( aIter != mpShapeMap->end() )
1972 {
1973 (*aIter).second = xAcc;
1974 }
1975 else
1976 {
1977 mpShapeMap->emplace( pObj, xAcc );
1978 }
1979 // TODO: focus!!!
1980 AddGroupContext(pObj, xAcc);
1981 }
1982 }
1983 }
1984
1985 // Invalidate focus for old object when map is not locked
1986 if( xOldCursorAcc.is() )
1987 InvalidateCursorPosition( xOldCursorAcc );
1988
1989 return xAcc;
1990}
1991
1993{
1994 if (pFESh)
1995 return pFESh->IsObjSameLevelWithMarked(pObj);
1996 return false;
1997}
1998
1999void SwAccessibleMap::AddShapeContext(const SdrObject *pObj, uno::Reference < XAccessible > const & xAccShape)
2000{
2001 osl::MutexGuard aGuard( maMutex );
2002
2003 if( mpShapeMap )
2004 {
2005 mpShapeMap->emplace( pObj, xAccShape );
2006 }
2007
2008}
2009
2010//Added by yanjun for sym2_6407
2012{
2013 osl::MutexGuard aGuard( maMutex );
2014 // TODO: Why are sub-shapes of group shapes even added to our map?
2015 // Doesn't the AccessibleShape of the top-level shape create them
2016 // on demand anyway? Why does SwAccessibleMap need to know them?
2017 // We cannot rely on getAccessibleChild here to remove the sub-shapes
2018 // from mpShapes because the top-level shape may not only be disposed here
2019 // but also by visibility checks in svx, then it doesn't return children.
2020 if (mpShapeMap && pParentObj && pParentObj->IsGroupObject())
2021 {
2022 SdrObjList *const pChildren(pParentObj->GetSubList());
2023 for (size_t i = 0; pChildren && i < pChildren->GetObjCount(); ++i)
2024 {
2025 SdrObject *const pChild(pChildren->GetObj(i));
2026 assert(pChild);
2027 RemoveContext(pChild);
2028 }
2029 }
2030}
2031//End
2032
2033void SwAccessibleMap::AddGroupContext(const SdrObject *pParentObj, uno::Reference < XAccessible > const & xAccParent)
2034{
2035 osl::MutexGuard aGuard( maMutex );
2036 if( !mpShapeMap )
2037 return;
2038
2039 //here get all the sub list.
2040 if (!pParentObj->IsGroupObject())
2041 return;
2042
2043 if (!xAccParent.is())
2044 return;
2045
2046 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext();
2047 if (!xContext.is())
2048 return;
2049
2050 sal_Int64 nChildren = xContext->getAccessibleChildCount();
2051 for(sal_Int64 i = 0; i<nChildren; i++)
2052 {
2053 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i);
2054 if (xChild.is())
2055 {
2056 uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext();
2057 if (xChildContext.is())
2058 {
2059 short nRole = xChildContext->getAccessibleRole();
2060 if (nRole == AccessibleRole::SHAPE)
2061 {
2062 ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get());
2063 uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape();
2064 if (xShape.is())
2065 {
2067 AddShapeContext(pObj, xChild);
2068 AddGroupContext(pObj,xChild);
2069 }
2070 }
2071 }
2072 }
2073 }
2074}
2075
2077 const SdrObject *pObj,
2078 SwAccessibleContext *pParentImpl,
2079 bool bCreate )
2080{
2081 uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
2082
2084 static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
2085
2086 return xAccImpl;
2087}
2088
2090{
2091 osl::MutexGuard aGuard( maMutex );
2092
2093 if( !mpFrameMap )
2094 return;
2095
2097 mpFrameMap->find( pFrame );
2098 if( aIter == mpFrameMap->end() )
2099 return;
2100
2101 mpFrameMap->erase( aIter );
2102
2104 {
2105 SwAccessibleContextMap_Impl::iterator aSelectedIter = mpSelectedFrameMap->find(pFrame);
2106 if (aSelectedIter != mpSelectedFrameMap->end())
2107 mpSelectedFrameMap->erase(aSelectedIter);
2108 }
2109
2110 // Remove reference to old caret object. Though mxCursorContext
2111 // is a weak reference and cleared automatically, clearing it
2112 // directly makes sure to not keep a non-functional object.
2113 uno::Reference < XAccessible > xOldAcc( mxCursorContext );
2114 if( xOldAcc.is() )
2115 {
2116 SwAccessibleContext *pOldAccImpl =
2117 static_cast< SwAccessibleContext *>( xOldAcc.get() );
2118 OSL_ENSURE( pOldAccImpl->GetFrame(), "old caret context is disposed" );
2119 if( pOldAccImpl->GetFrame() == pFrame )
2120 {
2121 xOldAcc.clear(); // get an empty ref
2122 mxCursorContext = xOldAcc;
2123 }
2124 }
2125
2126 if( mpFrameMap->empty() )
2127 {
2128 mpFrameMap.reset();
2129 }
2130}
2131
2133{
2134 osl::MutexGuard aGuard( maMutex );
2135
2136 if( !mpShapeMap )
2137 return;
2138
2139 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->find( pObj );
2140 if( aIter == mpShapeMap->end() )
2141 return;
2142
2143 uno::Reference < XAccessible > xTempHold( (*aIter).second );
2144 mpShapeMap->erase( aIter );
2145 RemoveGroupContext(pObj);
2146 // The shape selection flag is not cleared, but one might do
2147 // so but has to make sure that the removed context is the one
2148 // that is selected.
2149
2150 if( mpShapeMap && mpShapeMap->empty() )
2151 {
2152 mpShapeMap.reset();
2153 }
2154}
2155
2156bool SwAccessibleMap::Contains(const SwFrame *pFrame) const
2157{
2158 return (pFrame && mpFrameMap && mpFrameMap->find(pFrame) != mpFrameMap->end());
2159}
2160
2162 const SdrObject *pObj,
2163 vcl::Window* pWindow,
2164 bool bRecursive,
2165 bool bCanSkipInvisible )
2166{
2167 SwAccessibleChild aFrameOrObj( pFrame, pObj, pWindow );
2168
2169 // Indeed, the following assert checks the frame's accessible flag,
2170 // because that's the one that is evaluated in the layout. The frame
2171 // might not be accessible anyway. That's the case for cell frames that
2172 // contain further cells.
2173 OSL_ENSURE( !aFrameOrObj.GetSwFrame() || aFrameOrObj.GetSwFrame()->IsAccessibleFrame(),
2174 "non accessible frame should be disposed" );
2175
2176 if (!(aFrameOrObj.IsAccessible(GetShell()->IsPreview())
2177 // fdo#87199 dispose the darn thing if it ever was accessible
2178 || Contains(pFrame)))
2179 return;
2180
2184 // get accessible context for frame
2185 {
2186 osl::MutexGuard aGuard( maMutex );
2187
2188 // First of all look for an accessible context for a frame
2189 if( aFrameOrObj.GetSwFrame() && mpFrameMap )
2190 {
2192 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2193 if( aIter != mpFrameMap->end() )
2194 {
2195 uno::Reference < XAccessible > xAcc( (*aIter).second );
2196 xAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
2197 }
2198 }
2199 if( !xAccImpl.is() && mpFrameMap )
2200 {
2201 // If there is none, look if the parent is accessible.
2202 const SwFrame *pParent =
2203 SwAccessibleFrame::GetParent( aFrameOrObj,
2204 GetShell()->IsPreview());
2205
2206 if( pParent )
2207 {
2209 mpFrameMap->find( pParent );
2210 if( aIter != mpFrameMap->end() )
2211 {
2212 uno::Reference < XAccessible > xAcc( (*aIter).second );
2213 xParentAccImpl =
2214 static_cast< SwAccessibleContext *>( xAcc.get() );
2215 }
2216 }
2217 }
2218 if( !xParentAccImpl.is() && !aFrameOrObj.GetSwFrame() && mpShapeMap )
2219 {
2221 mpShapeMap->find( aFrameOrObj.GetDrawObject() );
2222 if( aIter != mpShapeMap->end() )
2223 {
2224 uno::Reference < XAccessible > xAcc( (*aIter).second );
2225 xShapeAccImpl =
2226 static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
2227 }
2228 }
2229 if( pObj && GetShell()->ActionPend() &&
2230 (xParentAccImpl.is() || xShapeAccImpl.is()) )
2231 {
2232 // Keep a reference to the XShape to avoid that it
2233 // is deleted with a SwFrameFormat::SwClientNotify.
2234 uno::Reference < drawing::XShape > xShape(
2235 const_cast< SdrObject * >( pObj )->getUnoShape(),
2236 uno::UNO_QUERY );
2237 if( xShape.is() )
2238 {
2239 mvShapes.push_back( xShape );
2240 }
2241 }
2242 }
2243
2244 // remove events stored for the frame
2245 {
2246 osl::MutexGuard aGuard( maEventMutex );
2247 if( mpEvents )
2248 {
2250 mpEventMap->find( aFrameOrObj );
2251 if( aIter != mpEventMap->end() )
2252 {
2254 SwAccessibleEvent_Impl::DISPOSE, aFrameOrObj );
2256 }
2257 }
2258 }
2259
2260 // If the frame is accessible and there is a context for it, dispose
2261 // the frame. If the frame is no context for it but disposing should
2262 // take place recursive, the frame's children have to be disposed
2263 // anyway, so we have to create the context then.
2264 if( xAccImpl.is() )
2265 {
2266 xAccImpl->Dispose( bRecursive );
2267 }
2268 else if( xParentAccImpl.is() )
2269 {
2270 // If the frame is a cell frame, the table must be notified.
2271 // If we are in an action, a table model change event will
2272 // be broadcasted at the end of the action to give the table
2273 // a chance to generate a single table change event.
2274
2275 xParentAccImpl->DisposeChild( aFrameOrObj, bRecursive, bCanSkipInvisible );
2276 }
2277 else if( xShapeAccImpl.is() )
2278 {
2279 RemoveContext( aFrameOrObj.GetDrawObject() );
2280 xShapeAccImpl->dispose();
2281 }
2282
2283 if( mpPreview && pFrame && pFrame->IsPageFrame() )
2284 mpPreview->DisposePage( static_cast< const SwPageFrame *>( pFrame ) );
2285}
2286
2288 const SdrObject *pObj,
2289 vcl::Window* pWindow,
2290 const SwRect& rOldBox )
2291{
2292 SwAccessibleChild aFrameOrObj( pFrame, pObj, pWindow );
2293 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2294 return;
2295
2298 const SwFrame *pParent =nullptr;
2299 {
2300 osl::MutexGuard aGuard( maMutex );
2301
2302 if( mpFrameMap )
2303 {
2304 if( aFrameOrObj.GetSwFrame() )
2305 {
2307 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2308 if( aIter != mpFrameMap->end() )
2309 {
2310 // If there is an accessible object already it is
2311 // notified directly.
2312 uno::Reference < XAccessible > xAcc( (*aIter).second );
2313 xAccImpl =
2314 static_cast< SwAccessibleContext *>( xAcc.get() );
2315 }
2316 }
2317 if( !xAccImpl.is() )
2318 {
2319 // Otherwise we look if the parent is accessible.
2320 // If not, there is nothing to do.
2321 pParent =
2322 SwAccessibleFrame::GetParent( aFrameOrObj,
2323 GetShell()->IsPreview());
2324
2325 if( pParent )
2326 {
2328 mpFrameMap->find( pParent );
2329 if( aIter != mpFrameMap->end() )
2330 {
2331 uno::Reference < XAccessible > xAcc( (*aIter).second );
2332 xParentAccImpl =
2333 static_cast< SwAccessibleContext *>( xAcc.get() );
2334 }
2335 }
2336 }
2337 }
2338 }
2339
2340 if( xAccImpl.is() )
2341 {
2342 if( GetShell()->ActionPend() )
2343 {
2346 aFrameOrObj, rOldBox );
2348 }
2349 else
2350 {
2351 FireEvents();
2352 if (xAccImpl->GetFrame()) // not if disposed by FireEvents()
2353 {
2354 xAccImpl->InvalidatePosOrSize(rOldBox);
2355 }
2356 }
2357 }
2358 else if( xParentAccImpl.is() )
2359 {
2360 if( GetShell()->ActionPend() )
2361 {
2362 assert(pParent);
2363 // tdf#99722 faster not to buffer events that won't be sent
2364 if (!SwAccessibleChild(pParent).IsVisibleChildrenOnly()
2365 || xParentAccImpl->IsShowing(rOldBox)
2366 || xParentAccImpl->IsShowing(*this, aFrameOrObj))
2367 {
2370 xParentAccImpl.get(), aFrameOrObj, rOldBox );
2372 }
2373 }
2374 else
2375 {
2376 FireEvents();
2377 xParentAccImpl->InvalidateChildPosOrSize( aFrameOrObj,
2378 rOldBox );
2379 }
2380 }
2381 else if(pParent)
2382 {
2383/*
2384For child graphic and its parent paragraph,if split 2 graphic to 2 paragraph,
2385will delete one graphic swfrm and new create 1 graphic swfrm ,
2386then the new paragraph and the new graphic SwFrame will add .
2387but when add graphic SwFrame ,the accessible of the new Paragraph is not created yet.
2388so the new graphic accessible 'parent is NULL,
2389so run here: save the parent's SwFrame not the accessible object parent,
2390*/
2391 bool bIsValidFrame = false;
2392 bool bIsTextParent = false;
2393 if (aFrameOrObj.GetSwFrame())
2394 {
2395 if (SwFrameType::Fly == pFrame->GetType())
2396 {
2397 bIsValidFrame =true;
2398 }
2399 }
2400 else if(pObj)
2401 {
2402 if (SwFrameType::Txt == pParent->GetType())
2403 {
2404 bIsTextParent =true;
2405 }
2406 }
2407 if( bIsValidFrame || bIsTextParent )
2408 {
2409 if( GetShell()->ActionPend() )
2410 {
2413 pParent, aFrameOrObj, rOldBox );
2415 }
2416 else
2417 {
2418 OSL_ENSURE(false,"");
2419 }
2420 }
2421 }
2422}
2423
2425{
2426 SwAccessibleChild aFrameOrObj( pFrame );
2427 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2428 return;
2429
2430 uno::Reference < XAccessible > xAcc;
2431 {
2432 osl::MutexGuard aGuard( maMutex );
2433
2434 if (!mpFrameMap)
2435 return;
2436
2438 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2439 if( aIter != mpFrameMap->end() )
2440 xAcc = (*aIter).second;
2441 }
2442
2443 if( !xAcc.is() )
2444 return;
2445
2446 SwAccessibleContext *pAccImpl =
2447 static_cast< SwAccessibleContext *>( xAcc.get() );
2448 if( GetShell()->ActionPend() )
2449 {
2452 std::move(aFrameOrObj) );
2454 }
2455 else
2456 {
2457 FireEvents();
2458 pAccImpl->InvalidateContent();
2459 }
2460}
2461
2463{
2464 SwAccessibleChild aFrameOrObj( &rTextFrame );
2465 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2466 return;
2467
2468 uno::Reference < XAccessible > xAcc;
2469 {
2470 osl::MutexGuard aGuard( maMutex );
2471
2472 if (!mpFrameMap)
2473 return;
2474
2476 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2477 if( aIter != mpFrameMap->end() )
2478 xAcc = (*aIter).second;
2479 }
2480
2481 if( !xAcc.is() )
2482 return;
2483
2484 SwAccessibleContext *pAccImpl =
2485 static_cast< SwAccessibleContext *>( xAcc.get() );
2486 if( GetShell()->ActionPend() )
2487 {
2489 pAccImpl, std::move(aFrameOrObj) );
2492 }
2493 else
2494 {
2495 FireEvents();
2496 pAccImpl->InvalidateAttr();
2497 }
2498}
2499
2501{
2502 SwAccessibleChild aFrameOrObj( pFrame );
2503 bool bShapeSelected = false;
2504 const SwViewShell *pVSh = GetShell();
2505 if( auto pCSh = dynamic_cast<const SwCursorShell*>(pVSh) )
2506 {
2507 if( pCSh->IsTableMode() )
2508 {
2509 while( aFrameOrObj.GetSwFrame() && !aFrameOrObj.GetSwFrame()->IsCellFrame() )
2510 aFrameOrObj = aFrameOrObj.GetSwFrame()->GetUpper();
2511 }
2512 else if( auto pFESh = dynamic_cast<const SwFEShell*>(pVSh) )
2513 {
2514 const SwFrame *pFlyFrame = pFESh->GetSelectedFlyFrame();
2515 if( pFlyFrame )
2516 {
2517 OSL_ENSURE( !pFrame || pFrame->FindFlyFrame() == pFlyFrame,
2518 "cursor is not contained in fly frame" );
2519 aFrameOrObj = pFlyFrame;
2520 }
2521 else if( pFESh->IsObjSelected() > 0 )
2522 {
2523 bShapeSelected = true;
2524 aFrameOrObj = static_cast<const SwFrame *>( nullptr );
2525 }
2526 }
2527 }
2528
2529 OSL_ENSURE( bShapeSelected || aFrameOrObj.IsAccessible(GetShell()->IsPreview()),
2530 "frame is not accessible" );
2531
2532 uno::Reference < XAccessible > xOldAcc;
2533 uno::Reference < XAccessible > xAcc;
2534 bool bOldShapeSelected = false;
2535
2536 {
2537 osl::MutexGuard aGuard( maMutex );
2538
2539 xOldAcc = mxCursorContext;
2540 mxCursorContext = xAcc; // clear reference
2541
2542 bOldShapeSelected = mbShapeSelected;
2543 mbShapeSelected = bShapeSelected;
2544
2545 if( aFrameOrObj.GetSwFrame() && mpFrameMap )
2546 {
2548 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2549 if( aIter != mpFrameMap->end() )
2550 xAcc = (*aIter).second;
2551 else
2552 {
2553 SwRect rcEmpty;
2554 const SwTabFrame* pTabFrame = aFrameOrObj.GetSwFrame()->FindTabFrame();
2555 if (pTabFrame)
2556 {
2557 InvalidatePosOrSize(pTabFrame, nullptr, nullptr, rcEmpty);
2558 }
2559 else
2560 {
2561 InvalidatePosOrSize(aFrameOrObj.GetSwFrame(), nullptr, nullptr, rcEmpty);
2562 }
2563
2564 aIter = mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2565 if( aIter != mpFrameMap->end() )
2566 {
2567 xAcc = (*aIter).second;
2568 }
2569 }
2570
2571 // For cells, some extra thoughts are necessary,
2572 // because invalidating the cursor for one cell
2573 // invalidates the cursor for all cells of the same
2574 // table. For this reason, we don't want to
2575 // invalidate the cursor for the old cursor object
2576 // and the new one if they are within the same table,
2577 // because this would result in doing the work twice.
2578 // Moreover, we have to make sure to invalidate the
2579 // cursor even if the current cell has no accessible object.
2580 // If the old cursor objects exists and is in the same
2581 // table, it's the best choice, because using it avoids
2582 // an unnecessary cursor invalidation cycle when creating
2583 // a new object for the current cell.
2584 if( aFrameOrObj.GetSwFrame()->IsCellFrame() )
2585 {
2586 if( xOldAcc.is() &&
2587 AreInSameTable( xOldAcc, aFrameOrObj.GetSwFrame() ) )
2588 {
2589 if( xAcc.is() )
2590 xOldAcc = xAcc; // avoid extra invalidation
2591 else
2592 xAcc = xOldAcc; // make sure at least one
2593 }
2594 if( !xAcc.is() )
2595 xAcc = GetContext( aFrameOrObj.GetSwFrame() );
2596 }
2597 }
2598 else if (bShapeSelected)
2599 {
2600 const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
2601 const SdrMarkList *pMarkList = pFESh->GetMarkList();
2602 if (pMarkList != nullptr && pMarkList->GetMarkCount() == 1)
2603 {
2604 SdrObject *pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
2606 if (!pAccShapeImpl.is())
2607 {
2608 while (pObj && pObj->getParentSdrObjectFromSdrObject())
2609 {
2610 pObj = pObj->getParentSdrObjectFromSdrObject();
2611 }
2612 if (pObj != nullptr)
2613 {
2614 const SwFrame *pParent = SwAccessibleFrame::GetParent( SwAccessibleChild(pObj), GetShell()->IsPreview() );
2615 if( pParent )
2616 {
2617 ::rtl::Reference< SwAccessibleContext > xParentAccImpl = GetContextImpl(pParent,false);
2618 if (!xParentAccImpl.is())
2619 {
2620 const SwTabFrame* pTabFrame = pParent->FindTabFrame();
2621 if (pTabFrame)
2622 {
2623 //The Table should not add in acc.because the "pParent" is not add to acc .
2624 uno::Reference< XAccessible> xAccParentTab = GetContext(pTabFrame);//Should Create.
2625
2626 const SwFrame *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pTabFrame), GetShell()->IsPreview() );
2627 if (pParentRoot)
2628 {
2629 ::rtl::Reference< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,false);
2630 if(xParentAccImplRoot.is())
2631 {
2632 AccessibleEventObject aEvent;
2633 aEvent.EventId = AccessibleEventId::CHILD;
2634 aEvent.NewValue <<= xAccParentTab;
2635 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2636 }
2637 }
2638
2639 //Get "pParent" acc again.
2640 xParentAccImpl = GetContextImpl(pParent,false);
2641 }
2642 else
2643 {
2644 //directly create this acc para .
2645 xParentAccImpl = GetContextImpl(pParent);//Should Create.
2646
2647 const SwFrame *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pParent), GetShell()->IsPreview() );
2648
2649 ::rtl::Reference< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,false);
2650 if(xParentAccImplRoot.is())
2651 {
2652 AccessibleEventObject aEvent;
2653 aEvent.EventId = AccessibleEventId::CHILD;
2654 aEvent.NewValue <<= uno::Reference< XAccessible>(xParentAccImpl);
2655 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2656 }
2657 }
2658 }
2659 if (xParentAccImpl.is())
2660 {
2661 uno::Reference< XAccessible> xAccShape =
2662 GetContext(pObj,xParentAccImpl.get());
2663
2664 AccessibleEventObject aEvent;
2665 aEvent.EventId = AccessibleEventId::CHILD;
2666 aEvent.NewValue <<= xAccShape;
2667 xParentAccImpl->FireAccessibleEvent( aEvent );
2668 }
2669 }
2670 }
2671 }
2672 }
2673 }
2674 }
2675
2678 if( xOldAcc.is() && xOldAcc != xAcc )
2679 InvalidateCursorPosition( xOldAcc );
2680 if( bOldShapeSelected || bShapeSelected )
2682 if( xAcc.is() )
2684
2686
2687 for (SwAccessibleParagraph* pAccPara : m_setParaRemove)
2688 {
2689 if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0)
2690 {
2691 if(pAccPara->SetSelectedState(false))
2692 {
2693 AccessibleEventObject aEvent;
2694 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
2695 pAccPara->FireAccessibleEvent( aEvent );
2696 }
2697 }
2698 }
2699 for (SwAccessibleParagraph* pAccPara : m_setParaAdd)
2700 {
2701 if(pAccPara && pAccPara->SetSelectedState(true))
2702 {
2703 AccessibleEventObject aEvent;
2704 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
2705 pAccPara->FireAccessibleEvent( aEvent );
2706 }
2707 }
2708}
2709
2711{
2712 if(GetShell()->IsPreview())
2713 {
2714 uno::Reference<XAccessible> xAcc = GetDocumentView_( true );
2715 if (xAcc)
2716 {
2717 SwAccessiblePreview *pAccPreview = static_cast<SwAccessiblePreview *>(xAcc.get());
2718 if (pAccPreview)
2719 {
2720 pAccPreview->InvalidateFocus();
2721 return ;
2722 }
2723 }
2724 }
2725 uno::Reference < XAccessible > xAcc;
2726 {
2727 osl::MutexGuard aGuard( maMutex );
2728
2729 xAcc = mxCursorContext;
2730 }
2731
2732 if( xAcc.is() )
2733 {
2734 SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
2735 pAccImpl->InvalidateFocus();
2736 }
2737 else
2738 {
2740 }
2741}
2742
2744 const ::rtl::Reference < SwAccessibleContext >& rCursorContext )
2745{
2746 osl::MutexGuard aGuard( maMutex );
2747 uno::Reference < XAccessible > xAcc( rCursorContext );
2748 mxCursorContext = xAcc;
2749}
2750
2752{
2753 // Start with the frame or the first upper that is accessible
2754 SwAccessibleChild aFrameOrObj( _pFrame );
2755 while( aFrameOrObj.GetSwFrame() &&
2756 !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2757 aFrameOrObj = aFrameOrObj.GetSwFrame()->GetUpper();
2758 if( !aFrameOrObj.GetSwFrame() )
2759 aFrameOrObj = GetShell()->GetLayout();
2760
2761 uno::Reference< XAccessible > xAcc( GetContext( aFrameOrObj.GetSwFrame() ) );
2762 SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
2763 if( GetShell()->ActionPend() )
2764 {
2766 pAccImpl,
2767 SwAccessibleChild(pAccImpl->GetFrame()),
2770 }
2771 else
2772 {
2773 FireEvents();
2775 }
2776}
2777
2779 bool bFrom )
2780{
2781 // first, see if this frame is accessible, and if so, get the respective
2782 SwAccessibleChild aFrameOrObj( pFrame );
2783 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2784 return;
2785
2786 uno::Reference < XAccessible > xAcc;
2787 {
2788 osl::MutexGuard aGuard( maMutex );
2789
2790 if (!mpFrameMap)
2791 return;
2792
2794 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2795 if( aIter != mpFrameMap->end() )
2796 {
2797 xAcc = (*aIter).second;
2798 }
2799 }
2800
2801 // deliver event directly, or queue event
2802 if( !xAcc.is() )
2803 return;
2804
2805 SwAccessibleContext *pAccImpl =
2806 static_cast< SwAccessibleContext *>( xAcc.get() );
2807 if( GetShell()->ActionPend() )
2808 {
2810 pAccImpl, SwAccessibleChild(pFrame),
2811 ( bFrom
2815 }
2816 else
2817 {
2818 FireEvents();
2819 pAccImpl->InvalidateRelation( bFrom
2820 ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
2821 : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
2822 }
2823}
2824
2826 const SwFrame* pFollow )
2827{
2828 InvalidateRelationSet_( pMaster, false );
2829 InvalidateRelationSet_( pFollow, true );
2830}
2831
2832// invalidation of CONTENT_FLOW_FROM/_TO relation of a paragraph
2834 const bool _bFrom )
2835{
2836 InvalidateRelationSet_( &_rTextFrame, _bFrom );
2837}
2838
2839// invalidation of text selection of a paragraph
2841{
2842 // first, see if this frame is accessible, and if so, get the respective
2843 SwAccessibleChild aFrameOrObj( &_rTextFrame );
2844 if( !aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2845 return;
2846
2847 uno::Reference < XAccessible > xAcc;
2848 {
2849 osl::MutexGuard aGuard( maMutex );
2850
2851 if (!mpFrameMap)
2852 return;
2853
2855 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2856 if( aIter != mpFrameMap->end() )
2857 {
2858 xAcc = (*aIter).second;
2859 }
2860 }
2861
2862 // deliver event directly, or queue event
2863 if( !xAcc.is() )
2864 return;
2865
2866 SwAccessibleContext *pAccImpl =
2867 static_cast< SwAccessibleContext *>( xAcc.get() );
2868 if( GetShell()->ActionPend() )
2869 {
2872 pAccImpl,
2873 SwAccessibleChild( &_rTextFrame ),
2876 }
2877 else
2878 {
2879 FireEvents();
2880 pAccImpl->InvalidateTextSelection();
2881 }
2882}
2883
2884sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrame& rParentFrame,
2885 vcl::Window& rChild ) const
2886{
2887 sal_Int32 nIndex( -1 );
2888
2889 SwAccessibleChild aFrameOrObj( &rParentFrame );
2890 if( aFrameOrObj.IsAccessible( GetShell()->IsPreview() ) )
2891 {
2892 uno::Reference < XAccessible > xAcc;
2893 {
2894 osl::MutexGuard aGuard( maMutex );
2895
2896 if( mpFrameMap )
2897 {
2899 mpFrameMap->find( aFrameOrObj.GetSwFrame() );
2900 if( aIter != mpFrameMap->end() )
2901 {
2902 xAcc = (*aIter).second;
2903 }
2904 }
2905 }
2906
2907 if( xAcc.is() )
2908 {
2909 SwAccessibleContext *pAccImpl =
2910 static_cast< SwAccessibleContext *>( xAcc.get() );
2911
2912 nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
2913 SwAccessibleChild( &rChild ) );
2914 }
2915 }
2916
2917 return nIndex;
2918}
2919
2920void SwAccessibleMap::UpdatePreview( const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
2921 const Fraction& _rScale,
2922 const SwPageFrame* _pSelectedPageFrame,
2923 const Size& _rPreviewWinSize )
2924{
2925 assert(GetShell()->IsPreview() && "no preview?");
2926 assert(mpPreview != nullptr && "no preview data?");
2927
2928 mpPreview->Update( *this, _rPreviewPages, _rScale, _pSelectedPageFrame, _rPreviewWinSize );
2929
2930 // propagate change of VisArea through the document's
2931 // accessibility tree; this will also send appropriate scroll
2932 // events
2933 SwAccessibleContext* pDoc =
2934 GetContextImpl( GetShell()->GetLayout() ).get();
2935 static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
2936
2937 uno::Reference < XAccessible > xOldAcc;
2938 uno::Reference < XAccessible > xAcc;
2939 {
2940 osl::MutexGuard aGuard( maMutex );
2941
2942 xOldAcc = mxCursorContext;
2943
2944 const SwPageFrame *pSelPage = mpPreview->GetSelPage();
2945 if( pSelPage && mpFrameMap )
2946 {
2948 mpFrameMap->find( pSelPage );
2949 if( aIter != mpFrameMap->end() )
2950 xAcc = (*aIter).second;
2951 }
2952 }
2953
2954 if( xOldAcc.is() && xOldAcc != xAcc )
2955 InvalidateCursorPosition( xOldAcc );
2956 if( xAcc.is() )
2958}
2959
2961{
2962 assert(GetShell()->IsPreview());
2963 assert(mpPreview != nullptr);
2964
2965 mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
2966
2967 uno::Reference < XAccessible > xOldAcc;
2968 uno::Reference < XAccessible > xAcc;
2969 {
2970 osl::MutexGuard aGuard( maMutex );
2971
2972 xOldAcc = mxCursorContext;
2973
2974 const SwPageFrame *pSelPage = mpPreview->GetSelPage();
2975 if( pSelPage && mpFrameMap )
2976 {
2977 SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->find( pSelPage );
2978 if( aIter != mpFrameMap->end() )
2979 xAcc = (*aIter).second;
2980 }
2981 }
2982
2983 if( xOldAcc.is() && xOldAcc != xAcc )
2984 InvalidateCursorPosition( xOldAcc );
2985 if( xAcc.is() )
2987}
2988
2989bool SwAccessibleMap::IsPageSelected( const SwPageFrame *pPageFrame ) const
2990{
2991 return mpPreview && mpPreview->GetSelPage() == pPageFrame;
2992}
2993
2995{
2996 {
2997 osl::MutexGuard aGuard( maEventMutex );
2998 if( mpEvents )
2999 {
3000 if (mpEvents->IsFiring())
3001 {
3002 return; // prevent recursive FireEvents()
3003 }
3004
3005 mpEvents->SetFiring();
3006 mpEvents->MoveMissingXAccToEnd();
3007 for( auto const& aEvent : *mpEvents )
3009
3010 mpEventMap.reset();
3011 mpEvents.reset();
3012 }
3013 }
3014 {
3015 osl::MutexGuard aGuard( maMutex );
3016 mvShapes.clear();
3017 }
3018
3019}
3020
3022{
3024}
3025
3026// Convert a MM100 value relative to the document root into a pixel value
3027// relative to the screen!
3028Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
3029{
3030 Point aPoint = o3tl::toTwips( rPoint, o3tl::Length::mm100 );
3031 if (const vcl::Window* pWin = GetShell()->GetWin())
3032 {
3033 MapMode aMapMode;
3034 GetMapMode( aPoint, aMapMode );
3035 aPoint = pWin->LogicToPixel( aPoint, aMapMode );
3036 aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
3037 }
3038
3039 return aPoint;
3040}
3041
3043{
3044 Size aSize( o3tl::toTwips( rSize, o3tl::Length::mm100 ) );
3045 if (const OutputDevice* pWin = GetShell()->GetWin()->GetOutDev())
3046 {
3047 MapMode aMapMode;
3048 GetMapMode( Point(0,0), aMapMode );
3049 aSize = pWin->LogicToPixel( aSize, aMapMode );
3050 }
3051
3052 return aSize;
3053}
3054
3056 ::accessibility::AccessibleShape* pCurrentChild,
3057 const uno::Reference< drawing::XShape >& _rxShape,
3058 const tools::Long /*_nIndex*/,
3059 const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
3060 )
3061{
3062 const SdrObject *pObj = nullptr;
3063 {
3064 osl::MutexGuard aGuard( maMutex );
3065 if( mpShapeMap )
3066 {
3069 while( aIter != aEndIter && !pObj )
3070 {
3071 uno::Reference < XAccessible > xAcc( (*aIter).second );
3073 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3074 if( pAccShape == pCurrentChild )
3075 {
3076 pObj = (*aIter).first;
3077 }
3078 ++aIter;
3079 }
3080 }
3081 }
3082 if( !pObj )
3083 return false;
3084
3085 uno::Reference < drawing::XShape > xShape( _rxShape ); // keep reference to shape, because
3086 // we might be the only one that
3087 // holds it.
3088 // Also get keep parent.
3089 uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
3090 pCurrentChild = nullptr; // will be released by dispose
3091 A11yDispose( nullptr, pObj, nullptr );
3092
3093 {
3094 osl::MutexGuard aGuard( maMutex );
3095
3096 if( !mpShapeMap )
3097 mpShapeMap.reset(new SwAccessibleShapeMap_Impl( this ));
3098
3099 // create the new child
3100 ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
3103 xShape, xParent, this );
3105 rShapeTypeHandler.CreateAccessibleObject (
3106 aShapeInfo, mpShapeMap->GetInfo() ));
3107
3108 uno::Reference < XAccessible > xAcc( pReplacement );
3109 if( xAcc.is() )
3110 {
3111 pReplacement->Init();
3112
3113 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->find( pObj );
3114 if( aIter != mpShapeMap->end() )
3115 {
3116 (*aIter).second = xAcc;
3117 }
3118 else
3119 {
3120 mpShapeMap->emplace( pObj, xAcc );
3121 }
3122 }
3123 }
3124
3125 SwRect aEmptyRect;
3126 InvalidatePosOrSize( nullptr, pObj, nullptr, aEmptyRect );
3127
3128 return true;
3129}
3130
3131//Get the accessible control shape from the model object, here model object is with XPropertySet type
3133{
3134 if( mpShapeMap )
3135 {
3138 while( aIter != aEndIter)
3139 {
3140 uno::Reference < XAccessible > xAcc( (*aIter).second );
3142 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3143 if(pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL)
3144 {
3145 ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape);
3146 if (pCtlAccShape->GetControlModel() == pSet)
3147 return pCtlAccShape;
3148 }
3149 ++aIter;
3150 }
3151 }
3152 return nullptr;
3153}
3154
3155css::uno::Reference< XAccessible >
3156 SwAccessibleMap::GetAccessibleCaption (const css::uno::Reference< css::drawing::XShape >&)
3157{
3158 return nullptr;
3159}
3160
3161Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
3162{
3163 Point aPoint;
3164 if (const OutputDevice* pWin = GetShell()->GetWin()->GetOutDev())
3165 {
3166 MapMode aMapMode;
3167 GetMapMode( rPoint, aMapMode );
3168 aPoint = pWin->PixelToLogic( rPoint, aMapMode );
3169 }
3170 return aPoint;
3171}
3172
3174 tools::Long aRefValue, bool bToLower)
3175{
3176 tools::Long aResult = aCoarseValue;
3177
3178 if (bToLower)
3179 {
3180 if (aFineValue < aRefValue)
3181 aResult -= 1;
3182 }
3183 else
3184 {
3185 if (aFineValue > aRefValue)
3186 aResult += 1;
3187 }
3188
3189 return aResult;
3190}
3191
3193 const tools::Rectangle & rSource,
3194 const tools::Rectangle & rInGrid)
3195{
3196 rRect.SetLeft( lcl_CorrectCoarseValue(rRect.Left(), rSource.Left(),
3197 rInGrid.Left(), false) );
3198 rRect.SetTop( lcl_CorrectCoarseValue(rRect.Top(), rSource.Top(),
3199 rInGrid.Top(), false) );
3200 rRect.SetRight( lcl_CorrectCoarseValue(rRect.Right(), rSource.Right(),
3201 rInGrid.Right(), true) );
3202 rRect.SetBottom( lcl_CorrectCoarseValue(rRect.Bottom(), rSource.Bottom(),
3203 rInGrid.Bottom(), true) );
3204}
3205
3207{
3208 tools::Rectangle aRect;
3209 if (const OutputDevice* pWin = GetShell()->GetWin()->GetOutDev())
3210 {
3211 MapMode aMapMode;
3212 GetMapMode( rRect.TopLeft(), aMapMode );
3213 aRect = pWin->LogicToPixel( rRect.SVRect(), aMapMode );
3214
3215 tools::Rectangle aTmpRect = pWin->PixelToLogic( aRect, aMapMode );
3216 lcl_CorrectRectangle(aRect, rRect.SVRect(), aTmpRect);
3217 }
3218
3219 return aRect;
3220}
3221
3230void SwAccessibleMap::GetMapMode( const Point& _rPoint,
3231 MapMode& _orMapMode ) const
3232{
3233 MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
3234 if( GetShell()->IsPreview() )
3235 {
3236 assert(mpPreview != nullptr);
3237 mpPreview->AdjustMapMode( aMapMode, _rPoint );
3238 }
3239 _orMapMode = aMapMode;
3240}
3241
3242Size SwAccessibleMap::GetPreviewPageSize(sal_uInt16 const nPreviewPageNum) const
3243{
3244 assert(mpVSh->IsPreview());
3245 assert(mpPreview != nullptr);
3246 return mpVSh->PagePreviewLayout()->GetPreviewPageSizeByPageNum(nPreviewPageNum);
3247}
3248
3253std::unique_ptr<SwAccessibleSelectedParas_Impl> SwAccessibleMap::BuildSelectedParas()
3254{
3255 // no accessible contexts, no selection
3256 if ( !mpFrameMap )
3257 {
3258 return nullptr;
3259 }
3260
3261 // get cursor as an instance of its base class <SwPaM>
3262 SwPaM* pCursor( nullptr );
3263 {
3264 SwCursorShell* pCursorShell = dynamic_cast<SwCursorShell*>(GetShell());
3265 if ( pCursorShell )
3266 {
3267 SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCursorShell);
3268 if ( !pFEShell ||
3269 ( !pFEShell->IsFrameSelected() &&
3270 pFEShell->IsObjSelected() == 0 ) )
3271 {
3272 // get cursor without updating an existing table cursor.
3273 pCursor = pCursorShell->GetCursor( false );
3274 }
3275 }
3276 }
3277 // no cursor, no selection
3278 if ( !pCursor )
3279 {
3280 return nullptr;
3281 }
3282
3283 std::unique_ptr<SwAccessibleSelectedParas_Impl> pRetSelectedParas;
3284
3285 // loop on all cursors
3286 SwPaM* pRingStart = pCursor;
3287 do {
3288
3289 // for a selection the cursor has to have a mark.
3290 // for safety reasons assure that point and mark are in text nodes
3291 if ( pCursor->HasMark() &&
3292 pCursor->GetPoint()->GetNode().IsTextNode() &&
3293 pCursor->GetMark()->GetNode().IsTextNode() )
3294 {
3295 auto [pStartPos, pEndPos] = pCursor->StartEnd(); // SwPosition*
3296 // loop on all text nodes inside the selection
3297 SwNodeIndex aIdx( pStartPos->GetNode() );
3298 for ( ; aIdx.GetIndex() <= pEndPos->GetNodeIndex(); ++aIdx )
3299 {
3300 SwTextNode* pTextNode( aIdx.GetNode().GetTextNode() );
3301 if ( pTextNode )
3302 {
3303 // loop on all text frames registered at the text node.
3305 for( SwTextFrame* pTextFrame = aIter.First(); pTextFrame; pTextFrame = aIter.Next() )
3306 {
3307 uno::WeakReference < XAccessible > xWeakAcc;
3309 mpFrameMap->find( pTextFrame );
3310 if( aMapIter != mpFrameMap->end() )
3311 {
3312 xWeakAcc = (*aMapIter).second;
3313 SwAccessibleParaSelection aDataEntry(
3314 sw::FrameContainsNode(*pTextFrame, pStartPos->GetNodeIndex())
3315 ? pTextFrame->MapModelToViewPos(*pStartPos)
3316 : TextFrameIndex(0),
3317
3318 sw::FrameContainsNode(*pTextFrame, pEndPos->GetNodeIndex())
3319 ? pTextFrame->MapModelToViewPos(*pEndPos)
3321 if ( !pRetSelectedParas )
3322 {
3323 pRetSelectedParas.reset(
3325 }
3326 // sw_redlinehide: should be idempotent for multiple nodes in a merged para
3327 pRetSelectedParas->emplace( xWeakAcc, aDataEntry );
3328 }
3329 }
3330 }
3331 }
3332 }
3333
3334 // prepare next turn: get next cursor in ring
3335 pCursor = pCursor->GetNext();
3336 } while ( pCursor != pRingStart );
3337
3338 return pRetSelectedParas;
3339}
3340
3342{
3343 osl::MutexGuard aGuard( maMutex );
3344
3345 // keep previously known selected paragraphs
3346 std::unique_ptr<SwAccessibleSelectedParas_Impl> pPrevSelectedParas( std::move(mpSelectedParas) );
3347
3348 // determine currently selected paragraphs
3350
3351 // compare currently selected paragraphs with the previously selected
3352 // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
3353 // first, search for new and changed selections.
3354 // on the run remove selections from previously known ones, if they are
3355 // also in the current ones.
3356 if ( mpSelectedParas )
3357 {
3359 for ( ; aIter != mpSelectedParas->end(); ++aIter )
3360 {
3361 bool bSubmitEvent( false );
3362 if ( !pPrevSelectedParas )
3363 {
3364 // new selection
3365 bSubmitEvent = true;
3366 }
3367 else
3368 {
3370 pPrevSelectedParas->find( (*aIter).first );
3371 if ( aPrevSelected != pPrevSelectedParas->end() )
3372 {
3373 // check, if selection has changed
3374 if ( (*aIter).second.nStartOfSelection !=
3375 (*aPrevSelected).second.nStartOfSelection ||
3376 (*aIter).second.nEndOfSelection !=
3377 (*aPrevSelected).second.nEndOfSelection )
3378 {
3379 // changed selection
3380 bSubmitEvent = true;
3381 }
3382 pPrevSelectedParas->erase( aPrevSelected );
3383 }
3384 else
3385 {
3386 // new selection
3387 bSubmitEvent = true;
3388 }
3389 }
3390
3391 if ( bSubmitEvent )
3392 {
3393 uno::Reference < XAccessible > xAcc( (*aIter).first );
3394 if ( xAcc.is() )
3395 {
3397 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3398 if ( xAccImpl.is() && xAccImpl->GetFrame() )
3399 {
3400 const SwTextFrame* pTextFrame = xAccImpl->GetFrame()->DynCastTextFrame();
3401 OSL_ENSURE( pTextFrame,
3402 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexpected type of frame" );
3403 if ( pTextFrame )
3404 {
3405 InvalidateParaTextSelection( *pTextFrame );
3406 }
3407 }
3408 }
3409 }
3410 }
3411 }
3412
3413 // second, handle previous selections - after the first step the data
3414 // structure of the previously known only contains the 'old' selections
3415 if ( !pPrevSelectedParas )
3416 return;
3417
3418 SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
3419 for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
3420 {
3421 uno::Reference < XAccessible > xAcc( (*aIter).first );
3422 if ( xAcc.is() )
3423 {
3425 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3426 if ( xAccImpl.is() && xAccImpl->GetFrame() )
3427 {
3428 const SwTextFrame* pTextFrame = xAccImpl->GetFrame()->DynCastTextFrame();
3429 OSL_ENSURE( pTextFrame,
3430 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexpected type of frame" );
3431 if ( pTextFrame )
3432 {
3433 InvalidateParaTextSelection( *pTextFrame );
3434 }
3435 }
3436 }
3437 }
3438}
3439
3441{
3442 assert(!GetShell()->IsPreview() || (mpPreview != nullptr));
3443
3444 return GetShell()->IsPreview()
3445 ? mpPreview->GetVisArea()
3446 : GetShell()->VisArea();
3447}
3448
3450{
3451 return GetShell()->GetDoc()->IsPrepareSelAll();
3452}
3453
3454/* 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:3192
static tools::Long lcl_CorrectCoarseValue(tools::Long aCoarseValue, tools::Long aFineValue, tools::Long aRefValue, bool bToLower)
Definition: accmap.cxx:3173
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:3021
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:1999
void InvalidateRelationSet(const SwFrame *pMaster, const SwFrame *pFollow)
Definition: accmap.cxx:2825
o3tl::sorted_vector< SwAccessibleParagraph * > m_setParaAdd
Definition: accmap.hxx:101
void InvalidateShapeInParaSelection()
Definition: accmap.cxx:1139
tools::Rectangle CoreToPixel(const SwRect &rRect) const
Definition: accmap.cxx:3206
void InvalidatePosOrSize(const SwFrame *pFrame, const SdrObject *pObj, vcl::Window *pWindow, const SwRect &rOldFrame)
Definition: accmap.cxx:2287
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:3253
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:2920
void InvalidateParaTextSelection(const SwTextFrame &_rTextFrame)
invalidation of text selection of a paragraph
Definition: accmap.cxx:2840
void InvalidateCursorPosition(const css::uno::Reference< css::accessibility::XAccessible > &rAcc)
void InvalidatePreviewSelection(sal_uInt16 nSelPage)
Definition: accmap.cxx:2960
void InvalidateRelationSet_(const SwFrame *pFrame, bool bFrom)
Definition: accmap.cxx:2778
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:3156
bool Contains(const SwFrame *pFrame) const
Definition: accmap.cxx:2156
void InvalidateEditableStates(const SwFrame *_pFrame)
Definition: accmap.cxx:2751
o3tl::sorted_vector< SwAccessibleParagraph * > m_setParaRemove
Definition: accmap.hxx:102
SwAccessibleMap(SwViewShell *pSh)
Definition: accmap.cxx:1638
void SetCursorContext(const ::rtl::Reference< SwAccessibleContext > &rCursorContext)
Definition: accmap.cxx:2743
void GetMapMode(const Point &_rPoint, MapMode &_orMapMode) const
get mapping mode for LogicToPixel and PixelToLogic conversions
Definition: accmap.cxx:3230
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:3055
static bool IsInSameLevel(const SdrObject *pObj, const SwFEShell *pFESh)
Definition: accmap.cxx:1992
void A11yDispose(const SwFrame *pFrame, const SdrObject *pObj, vcl::Window *pWindow, bool bRecursive=false, bool bCanSkipInvisible=true)
Definition: accmap.cxx:2161
void RemoveGroupContext(const SdrObject *pParentObj)
Definition: accmap.cxx:2011
virtual bool IsDocumentSelAll() override
Definition: accmap.cxx:3449
void InvalidateAttr(const SwTextFrame &rTextFrame)
Definition: accmap.cxx:2462
virtual ~SwAccessibleMap() override
Definition: accmap.cxx:1646
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:2884
bool mbShapeSelected
Definition: accmap.hxx:114
css::uno::Reference< css::accessibility::XAccessible > GetDocumentView_(bool bPagePreview)
Definition: accmap.cxx:1710
void InvalidateContent(const SwFrame *pFrame)
Definition: accmap.cxx:2424
Size GetPreviewPageSize(sal_uInt16 _nPreviewPageNum) const
get size of a dedicated preview page
Definition: accmap.cxx:3242
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:1777
Point PixelToCore(const Point &rPoint) const
Definition: accmap.cxx:3161
void InvalidateShapeSelection()
Definition: accmap.cxx:1120
css::uno::Reference< css::accessibility::XAccessible > GetDocumentView()
Definition: accmap.cxx:1772
void DoInvalidateShapeSelection(bool bInvalidateFocusMode=false)
Definition: accmap.cxx:1475
::rtl::Reference< SwAccessibleContext > GetContextImpl(const SwFrame *pFrame, bool bCreate=true)
Definition: accmap.cxx:1920
virtual ::accessibility::AccessibleControlShape * GetAccControlShapeFromModel(css::beans::XPropertySet *pSet) override
Definition: accmap.cxx:3132
void FireEvents()
Definition: accmap.cxx:2994
void InvalidateFocus()
Definition: accmap.cxx:2710
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:2833
const SwRect & GetVisArea() const
Definition: accmap.cxx:3440
void RemoveContext(const SwFrame *pFrame)
Definition: accmap.cxx:2089
void InvalidateTextSelectionOfAllParas()
invalidation of text selection of all paragraphs
Definition: accmap.cxx:3341
bool IsPageSelected(const SwPageFrame *pPageFrame) const
Definition: accmap.cxx:2989
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:1792
void AddGroupContext(const SdrObject *pParentObj, css::uno::Reference< css::accessibility::XAccessible > const &xAccParent)
Definition: accmap.cxx:2033
virtual Point LogicToPixel(const Point &rPoint) const override
Definition: accmap.cxx:3028
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:1230
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool IsPrepareSelAll() const
Definition: doc.hxx:575
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:2905
Footer in the document layout, inside a page.
Definition: hffrm.hxx:51
FlyAnchors.
Definition: fmtanchr.hxx:37
sal_Int32 GetAnchorContentOffset() const
Definition: atrfrm.cxx:1623
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:74
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1606
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
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:373
TElementType * First()
Definition: calbck.hxx:365
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
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwNodeOffset GetIndex() const
Definition: node.hxx:312
bool IsContentNode() const
Definition: node.hxx:679
bool IsTableNode() const
Definition: node.hxx:691
bool IsTextNode() const
Definition: node.hxx:687
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:83
void AddAccessibleShell()
Definition: rootfrm.hxx:392
void RemoveAccessibleShell()
Definition: rootfrm.hxx:393
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:542
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:207
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:111
bool IsPreview() const
Definition: viewsh.hxx:498
SwPagePreviewLayout * PagePreviewLayout()
Definition: viewpg.cxx:35
bool ActionPend() const
Definition: viewsh.hxx:204
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2160
vcl::Window * GetWin() const
Definition: viewsh.hxx:346
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2813
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:3249
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:1649
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:1608
size_t pos