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