1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accmap.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <vos/ref.hxx>
36 #include <cppuhelper/weakref.hxx>
37 #include <vcl/window.hxx>
38 #include <svx/svdmodel.hxx>
39 #include <svx/unomod.hxx>
40 #include <tools/debug.hxx>
45 #ifndef _ACCCONTEXT_HXX
46 #include <acccontext.hxx>
49 #include <accpreview.hxx>
50 #include <accpage.hxx>
51 #include <accpara.hxx>
52 #include <accheaderfooter.hxx>
53 #include <accfootnote.hxx>
54 #include <acctextframe.hxx>
55 #include <accgraphic.hxx>
56 #include <accembedded.hxx>
57 #include <acccell.hxx>
58 #include <acctable.hxx>
60 #include <rootfrm.hxx>
64 #include <cellfrm.hxx>
66 #include <pagefrm.hxx>
68 #ifndef IDOCUMENTDRAWMODELACCESS_HXX_INCLUDED
69 #include <IDocumentDrawModelAccess.hxx>
71 #include <svx/ShapeTypeHandler.hxx>
72 #include <vcl/svapp.hxx>
73 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
74 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
75 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
76 #include <cppuhelper/implbase1.hxx>
77 // OD 15.01.2003 #103492#
78 #include <pagepreviewlayout.hxx>
79 // --> OD 2005-12-13 #i27301#
84 using namespace ::com::sun::star
;
85 using namespace ::com::sun::star::accessibility
;
86 using ::rtl::OUString
;
90 sal_Bool
operator()( const SwFrm
* p1
,
91 const SwFrm
* p2
) const
97 typedef ::std::map
< const SwFrm
*, uno::WeakReference
< XAccessible
>, SwFrmFunc
> _SwAccessibleContextMap_Impl
;
99 class SwAccessibleContextMap_Impl
: public _SwAccessibleContextMap_Impl
107 SwAccessibleContextMap_Impl()
109 : mbLocked( sal_False
)
115 //------------------------------------------------------------------------------
116 class SwDrawModellListener_Impl
: public SfxListener
,
117 public ::cppu::WeakImplHelper1
< document::XEventBroadcaster
>
119 mutable ::osl::Mutex maListenerMutex
;
120 ::cppu::OInterfaceContainerHelper maEventListeners
;
121 SdrModel
*mpDrawModel
;
123 virtual ~SwDrawModellListener_Impl();
126 SwDrawModellListener_Impl( SdrModel
*pDrawModel
);
129 virtual void SAL_CALL
addEventListener( const uno::Reference
< document::XEventListener
>& xListener
) throw (uno::RuntimeException
);
130 virtual void SAL_CALL
removeEventListener( const uno::Reference
< document::XEventListener
>& xListener
) throw (uno::RuntimeException
);
132 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
);
136 SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel
*pDrawModel
) :
137 maEventListeners( maListenerMutex
),
138 mpDrawModel( pDrawModel
)
140 StartListening( *mpDrawModel
);
143 SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
145 EndListening( *mpDrawModel
);
148 void SAL_CALL
SwDrawModellListener_Impl::addEventListener( const uno::Reference
< document::XEventListener
>& xListener
) throw (uno::RuntimeException
)
150 maEventListeners
.addInterface( xListener
);
153 void SAL_CALL
SwDrawModellListener_Impl::removeEventListener( const uno::Reference
< document::XEventListener
>& xListener
) throw (uno::RuntimeException
)
155 maEventListeners
.removeInterface( xListener
);
158 void SwDrawModellListener_Impl::Notify( SfxBroadcaster
& /*rBC*/,
159 const SfxHint
& rHint
)
161 // do not broadcast notifications for writer fly frames, because there
162 // are no shapes that need to know about them.
163 // OD 01.07.2003 #110554# - correct condition in order not to broadcast
164 // notifications for writer fly frames.
165 // OD 01.07.2003 #110554# - do not broadcast notifications for plane
166 // <SdrObject>objects
167 const SdrHint
*pSdrHint
= PTR_CAST( SdrHint
, &rHint
);
169 ( pSdrHint
->GetObject() &&
170 ( pSdrHint
->GetObject()->ISA(SwFlyDrawObj
) ||
171 pSdrHint
->GetObject()->ISA(SwVirtFlyDrawObj
) ||
172 IS_TYPE(SdrObject
,pSdrHint
->GetObject()) ) ) )
177 ASSERT( mpDrawModel
, "draw model listener is disposed" );
181 document::EventObject aEvent
;
182 if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel
, pSdrHint
, aEvent
) )
185 ::cppu::OInterfaceIteratorHelper
aIter( maEventListeners
);
186 while( aIter
.hasMoreElements() )
188 uno::Reference
< document::XEventListener
> xListener( aIter
.next(),
192 xListener
->notifyEvent( aEvent
);
194 catch( uno::RuntimeException
const & r
)
197 #if OSL_DEBUG_LEVEL > 1
198 ByteString
aError( "Runtime exception caught while notifying shape.:\n" );
199 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
200 DBG_ERROR( aError
.GetBuffer() );
206 void SwDrawModellListener_Impl::Dispose()
211 //------------------------------------------------------------------------------
214 sal_Bool
operator()( const SdrObject
* p1
,
215 const SdrObject
* p2
) const
220 typedef ::std::map
< const SdrObject
*, uno::WeakReference
< XAccessible
>, SwShapeFunc
> _SwAccessibleShapeMap_Impl
;
221 typedef ::std::pair
< const SdrObject
*, ::vos::ORef
< ::accessibility::AccessibleShape
> > SwAccessibleObjShape_Impl
;
223 class SwAccessibleShapeMap_Impl
: public _SwAccessibleShapeMap_Impl
226 ::accessibility::AccessibleShapeTreeInfo maInfo
;
233 SwAccessibleShapeMap_Impl( SwAccessibleMap
*pMap
)
235 : mbLocked( sal_False
)
238 maInfo
.SetSdrView( pMap
->GetShell()->GetDrawView() );
239 maInfo
.SetWindow( pMap
->GetShell()->GetWin() );
240 maInfo
.SetViewForwarder( pMap
);
241 // --> OD 2005-08-08 #i52858# - method name changed
242 uno::Reference
< document::XEventBroadcaster
> xModelBroadcaster
=
243 new SwDrawModellListener_Impl(
244 pMap
->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() );
246 maInfo
.SetControllerBroadcaster( xModelBroadcaster
);
249 ~SwAccessibleShapeMap_Impl();
251 const ::accessibility::AccessibleShapeTreeInfo
& GetInfo() const { return maInfo
; }
253 SwAccessibleObjShape_Impl
*Copy( size_t& rSize
,
254 const SwFEShell
*pFESh
= 0,
255 SwAccessibleObjShape_Impl
**pSelShape
= 0 ) const;
258 SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl()
260 uno::Reference
< document::XEventBroadcaster
> xBrd( maInfo
.GetControllerBroadcaster() );
262 static_cast < SwDrawModellListener_Impl
* >( xBrd
.get() )->Dispose();
265 SwAccessibleObjShape_Impl
266 *SwAccessibleShapeMap_Impl::Copy(
267 size_t& rSize
, const SwFEShell
*pFESh
,
268 SwAccessibleObjShape_Impl
**pSelStart
) const
270 SwAccessibleObjShape_Impl
*pShapes
= 0;
271 SwAccessibleObjShape_Impl
*pSelShape
= 0;
273 sal_uInt16 nSelShapes
= pFESh
? pFESh
->IsObjSelected() : 0;
279 new SwAccessibleObjShape_Impl
[rSize
];
281 const_iterator aIter
= begin();
282 const_iterator aEndIter
= end();
284 SwAccessibleObjShape_Impl
*pShape
= pShapes
;
285 pSelShape
= &(pShapes
[rSize
]);
286 while( aIter
!= aEndIter
)
288 const SdrObject
*pObj
= (*aIter
).first
;
289 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
290 if( nSelShapes
&& pFESh
->IsObjSelected( *pObj
) )
292 // selected objects are inserted from the back
294 pSelShape
->first
= pObj
;
296 static_cast < ::accessibility::AccessibleShape
* >(
302 pShape
->first
= pObj
;
304 static_cast < ::accessibility::AccessibleShape
* >(
310 ASSERT( pSelShape
== pShape
, "copying shapes went wrong!" );
314 *pSelStart
= pSelShape
;
319 //------------------------------------------------------------------------------
320 struct SwAccessibleEvent_Impl
323 enum EventType
{ CARET_OR_STATES
,
332 SwRect maOldBox
; // the old bounds for CHILD_POS_CHANGED
334 uno::WeakReference
< XAccessible
> mxAcc
; // The object that fires the event
335 SwFrmOrObj maFrmOrObj
; // the child for CHILD_POS_CHANGED and
336 // the same as xAcc for any other
338 EventType meType
; // The event type
339 // --> OD 2005-12-12 #i27301# - use new type definition for <mnStates>
340 tAccessibleStates mnStates
; // check states or update caret pos
343 SwAccessibleEvent_Impl
& operator==( const SwAccessibleEvent_Impl
& );
346 SwAccessibleEvent_Impl( EventType eT
,
347 SwAccessibleContext
*pA
,
348 const SwFrmOrObj
& rFrmOrObj
)
350 maFrmOrObj( rFrmOrObj
),
355 SwAccessibleEvent_Impl( EventType eT
,
356 const SwFrmOrObj
& rFrmOrObj
)
357 : maFrmOrObj( rFrmOrObj
),
361 ASSERT( SwAccessibleEvent_Impl::DISPOSE
== meType
,
362 "wrong event constructor, DISPOSE only" );
365 SwAccessibleEvent_Impl( EventType eT
)
369 ASSERT( SwAccessibleEvent_Impl::SHAPE_SELECTION
== meType
,
370 "wrong event constructor, SHAPE_SELECTION only" );
373 SwAccessibleEvent_Impl( EventType eT
,
374 SwAccessibleContext
*pA
,
375 const SwFrmOrObj
& rFrmOrObj
,
379 maFrmOrObj( rFrmOrObj
),
383 ASSERT( SwAccessibleEvent_Impl::CHILD_POS_CHANGED
== meType
||
384 SwAccessibleEvent_Impl::POS_CHANGED
== meType
,
385 "wrong event constructor, (CHILD_)POS_CHANGED only" );
388 // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates>
389 SwAccessibleEvent_Impl( EventType eT
,
390 SwAccessibleContext
*pA
,
391 const SwFrmOrObj
& rFrmOrObj
,
392 const tAccessibleStates _nStates
)
394 maFrmOrObj( rFrmOrObj
),
398 ASSERT( SwAccessibleEvent_Impl::CARET_OR_STATES
== meType
,
399 "wrong event constructor, CARET_OR_STATES only" );
402 // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
403 inline void SetType( EventType eT
)
407 inline EventType
GetType() const
412 inline ::vos::ORef
< SwAccessibleContext
> GetContext() const
414 uno::Reference
< XAccessible
> xTmp( mxAcc
);
415 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
416 static_cast<SwAccessibleContext
*>( xTmp
.get() ) );
421 inline const SwRect
& GetOldBox() const
425 // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
426 inline void SetOldBox( const SwRect
& rOldBox
)
431 inline const SwFrmOrObj
& GetFrmOrObj() const
436 // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
437 // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates>
438 inline void SetStates( tAccessibleStates _nStates
)
440 mnStates
|= _nStates
;
444 inline sal_Bool
IsUpdateCursorPos() const
446 return (mnStates
& ACC_STATE_CARET
) != 0;
448 inline sal_Bool
IsInvalidateStates() const
450 return (mnStates
& ACC_STATE_MASK
) != 0;
452 inline sal_Bool
IsInvalidateRelation() const
454 return (mnStates
& ACC_STATE_RELATION_MASK
) != 0;
456 // --> OD 2005-12-12 #i27301# - new event TEXT_SELECTION_CHANGED
457 inline sal_Bool
IsInvalidateTextSelection() const
459 return ( mnStates
& ACC_STATE_TEXT_SELECTION_CHANGED
) != 0;
462 // --> OD 2009-01-07 #i88069# - new event TEXT_ATTRIBUTE_CHANGED
463 inline sal_Bool
IsInvalidateTextAttrs() const
465 return ( mnStates
& ACC_STATE_TEXT_ATTRIBUTE_CHANGED
) != 0;
468 // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates>
470 inline tAccessibleStates
GetStates() const
472 return mnStates
& ACC_STATE_MASK
;
475 // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates>
477 inline tAccessibleStates
GetAllStates() const
484 //------------------------------------------------------------------------------
485 typedef ::std::list
< SwAccessibleEvent_Impl
> _SwAccessibleEventList_Impl
;
487 class SwAccessibleEventList_Impl
: public _SwAccessibleEventList_Impl
493 SwAccessibleEventList_Impl()
494 : mbFiring( sal_False
)
497 inline void SetFiring()
501 inline sal_Bool
IsFiring() const
507 //------------------------------------------------------------------------------
508 // The shape list is filled if an accessible shape is destroyed. It
509 // simply keeps a reference to the accessible shape's XShape. These
510 // references are destroyed within the EndAction when firing events,
511 // There are twp reason for this. First of all, a new accessible shape
512 // for the XShape might be created soon. It's then cheaper if the XShape
513 // still exists. The other reason are situations where an accessible shape
514 // is destroyed within an SwFrmFmt::Modify. In this case, destryoing
515 // the XShape at the same time (indirectly by destroying the accessible
516 // shape) leads to an assert, because a client of the Modify is destroyed
517 // within a Modify call.
519 typedef ::std::list
< uno::Reference
< drawing::XShape
> > _SwShapeList_Impl
;
521 class SwShapeList_Impl
: public _SwShapeList_Impl
525 SwShapeList_Impl() {}
529 //------------------------------------------------------------------------------
530 struct SwFrmOrObjFunc
532 sal_Bool
operator()( const SwFrmOrObj
& r1
,
533 const SwFrmOrObj
& r2
) const
535 const void *p1
= r1
.GetSwFrm()
536 ? static_cast < const void * >( r1
.GetSwFrm())
537 : static_cast < const void * >( r1
.GetSdrObject() );
538 const void *p2
= r2
.GetSwFrm()
539 ? static_cast < const void * >( r2
.GetSwFrm())
540 : static_cast < const void * >( r2
.GetSdrObject() );
544 typedef ::std::map
< SwFrmOrObj
, SwAccessibleEventList_Impl::iterator
,
545 SwFrmOrObjFunc
> _SwAccessibleEventMap_Impl
;
547 class SwAccessibleEventMap_Impl
: public _SwAccessibleEventMap_Impl
551 //------------------------------------------------------------------------------
552 // --> OD 2005-12-13 #i27301# - map containing the accessible paragraph, which
553 // have a selection. Needed to keep this information to submit corresponding
554 // TEXT_SELECTION_CHANGED events.
555 struct SwAccessibleParaSelection
557 xub_StrLen nStartOfSelection
;
558 xub_StrLen nEndOfSelection
;
560 SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection
,
561 const xub_StrLen _nEndOfSelection
)
562 : nStartOfSelection( _nStartOfSelection
),
563 nEndOfSelection( _nEndOfSelection
)
567 struct SwXAccWeakRefComp
569 sal_Bool
operator()( const uno::WeakReference
<XAccessible
>& _rXAccWeakRef1
,
570 const uno::WeakReference
<XAccessible
>& _rXAccWeakRef2
) const
572 return _rXAccWeakRef1
.get() < _rXAccWeakRef2
.get();
576 typedef ::std::map
< uno::WeakReference
< XAccessible
>,
577 SwAccessibleParaSelection
,
578 SwXAccWeakRefComp
> _SwAccessibleSelectedParas_Impl
;
580 class SwAccessibleSelectedParas_Impl
: public _SwAccessibleSelectedParas_Impl
583 //------------------------------------------------------------------------------
584 static sal_Bool
AreInSameTable( const uno::Reference
< XAccessible
>& rAcc
,
587 sal_Bool bRet
= sal_False
;
589 if( pFrm
&& pFrm
->IsCellFrm() && rAcc
.is() )
591 // Is it in the same table? We check that
592 // by comparing the last table frame in the
593 // follow chain, because that's cheaper than
594 // searching the first one.
595 SwAccessibleContext
*pAccImpl
=
596 static_cast< SwAccessibleContext
*>( rAcc
.get() );
597 if( pAccImpl
->GetFrm()->IsCellFrm() )
599 const SwTabFrm
*pTabFrm1
= pAccImpl
->GetFrm()->FindTabFrm();
600 while( pTabFrm1
->GetFollow() )
601 pTabFrm1
= pTabFrm1
->GetFollow();
603 const SwTabFrm
*pTabFrm2
= pFrm
->FindTabFrm();
604 while( pTabFrm2
->GetFollow() )
605 pTabFrm2
= pTabFrm2
->GetFollow();
607 bRet
= (pTabFrm1
== pTabFrm2
);
614 void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl
& rEvent
)
616 ::vos::ORef
< SwAccessibleContext
> xAccImpl( rEvent
.GetContext() );
617 if( SwAccessibleEvent_Impl::SHAPE_SELECTION
== rEvent
.GetType() )
619 DoInvalidateShapeSelection();
621 else if( xAccImpl
.isValid() && xAccImpl
->GetFrm() )
623 // --> OD 2009-01-07 #i88069#
624 if ( rEvent
.GetType() != SwAccessibleEvent_Impl::DISPOSE
&&
625 rEvent
.IsInvalidateTextAttrs() )
627 xAccImpl
->InvalidateAttr();
630 switch( rEvent
.GetType() )
632 case SwAccessibleEvent_Impl::INVALID_CONTENT
:
633 xAccImpl
->InvalidateContent();
635 case SwAccessibleEvent_Impl::POS_CHANGED
:
636 xAccImpl
->InvalidatePosOrSize( rEvent
.GetOldBox() );
638 case SwAccessibleEvent_Impl::CHILD_POS_CHANGED
:
639 xAccImpl
->InvalidateChildPosOrSize( rEvent
.GetFrmOrObj(),
640 rEvent
.GetOldBox() );
642 case SwAccessibleEvent_Impl::DISPOSE
:
643 ASSERT( xAccImpl
.isValid(),
644 "dispose event has been stored" );
646 // --> OD 2009-01-06 #i88069#
647 case SwAccessibleEvent_Impl::INVALID_ATTR
:
648 // nothing to do here - handled above
654 if( SwAccessibleEvent_Impl::DISPOSE
!= rEvent
.GetType() )
656 if( rEvent
.IsUpdateCursorPos() )
657 xAccImpl
->InvalidateCursorPos();
658 if( rEvent
.IsInvalidateStates() )
659 xAccImpl
->InvalidateStates( rEvent
.GetStates() );
660 if( rEvent
.IsInvalidateRelation() )
662 // --> OD 2005-12-01 #i27138#
663 // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and
664 // CONTENT_FLOWS_TO_RELATION_CHANGED are possible
665 if ( rEvent
.GetAllStates() & ACC_STATE_RELATION_FROM
)
667 xAccImpl
->InvalidateRelation(
668 AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
);
670 if ( rEvent
.GetAllStates() & ACC_STATE_RELATION_TO
)
672 xAccImpl
->InvalidateRelation(
673 AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED
);
677 // --> OD 2005-12-12 #i27301# - submit event TEXT_SELECTION_CHANGED
678 if ( rEvent
.IsInvalidateTextSelection() )
680 xAccImpl
->InvalidateTextSelection();
687 void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl
& rEvent
)
689 vos::OGuard
aGuard( maEventMutex
);
692 mpEvents
= new SwAccessibleEventList_Impl
;
694 mpEventMap
= new SwAccessibleEventMap_Impl
;
696 if( mpEvents
->IsFiring() )
698 // While events are fired new ones are generated. They have to be fired
699 // now. This does not work for DISPOSE events!
700 ASSERT( rEvent
.GetType() != SwAccessibleEvent_Impl::DISPOSE
,
701 "dispose event while firing events" );
707 SwAccessibleEventMap_Impl::iterator aIter
=
708 mpEventMap
->find( rEvent
.GetFrmOrObj() );
709 if( aIter
!= mpEventMap
->end() )
711 SwAccessibleEvent_Impl
aEvent( *(*aIter
).second
);
712 ASSERT( aEvent
.GetType() != SwAccessibleEvent_Impl::DISPOSE
,
713 "dispose events should not be stored" );
714 sal_Bool bAppendEvent
= sal_True
;
715 switch( rEvent
.GetType() )
717 case SwAccessibleEvent_Impl::CARET_OR_STATES
:
718 // A CARET_OR_STATES event is added to any other
719 // event only. It is broadcasted after any other event, so the
720 // event should be put to the back.
721 ASSERT( aEvent
.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED
,
722 "invalid event combination" );
723 aEvent
.SetStates( rEvent
.GetAllStates() );
725 case SwAccessibleEvent_Impl::INVALID_CONTENT
:
726 // An INVALID_CONTENT event overwrites a CARET_OR_STATES
727 // event (but keeps its flags) and it is contained in a
728 // POS_CHANGED event.
729 // Therefor, the event's type has to be adapted and the event
730 // has to be put at the end.
731 ASSERT( aEvent
.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED
,
732 "invalid event combination" );
733 if( aEvent
.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES
)
734 aEvent
.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT
);
736 case SwAccessibleEvent_Impl::POS_CHANGED
:
737 // A pos changed event overwrites CARET_STATES (keeping its
738 // flags) as well as INVALID_CONTENT. The old box position
739 // has to be stored however if the old event is not a
740 // POS_CHANGED itself.
741 ASSERT( aEvent
.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED
,
742 "invalid event combination" );
743 if( aEvent
.GetType() != SwAccessibleEvent_Impl::POS_CHANGED
)
744 aEvent
.SetOldBox( rEvent
.GetOldBox() );
745 aEvent
.SetType( SwAccessibleEvent_Impl::POS_CHANGED
);
747 case SwAccessibleEvent_Impl::CHILD_POS_CHANGED
:
748 // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED
749 // events. The only action that needs to be done again is
750 // to put the old event to the back. The new one cannot be used,
751 // because we are interested in the old frame bounds.
752 ASSERT( aEvent
.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED
,
753 "invalid event combination" );
755 case SwAccessibleEvent_Impl::SHAPE_SELECTION
:
756 ASSERT( aEvent
.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION
,
757 "invalid event combination" );
759 case SwAccessibleEvent_Impl::DISPOSE
:
760 // DISPOSE events overwrite all others. They are not stored
761 // but executed immediatly to avoid broadcasting of
762 // defunctional objects. So what needs to be done here is to
763 // remove all events for the frame in question.
764 bAppendEvent
= sal_False
;
766 // --> OD 2009-01-06 #i88069#
767 case SwAccessibleEvent_Impl::INVALID_ATTR
:
768 ASSERT( aEvent
.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR
,
769 "invalid event combination" );
775 mpEvents
->erase( (*aIter
).second
);
776 (*aIter
).second
= mpEvents
->insert( mpEvents
->end(), aEvent
);
780 mpEvents
->erase( (*aIter
).second
);
781 mpEventMap
->erase( aIter
);
784 else if( SwAccessibleEvent_Impl::DISPOSE
!= rEvent
.GetType() )
786 SwAccessibleEventMap_Impl::value_type
aEntry( rEvent
.GetFrmOrObj(),
787 mpEvents
->insert( mpEvents
->end(), rEvent
) );
788 mpEventMap
->insert( aEntry
);
793 void SwAccessibleMap::InvalidateCursorPosition(
794 const uno::Reference
< XAccessible
>& rAcc
)
796 SwAccessibleContext
*pAccImpl
=
797 static_cast< SwAccessibleContext
*>( rAcc
.get() );
798 ASSERT( pAccImpl
, "no caret context" );
799 ASSERT( pAccImpl
->GetFrm(), "caret context is disposed" );
800 if( GetShell()->ActionPend() )
802 SwAccessibleEvent_Impl
aEvent(
803 SwAccessibleEvent_Impl::CARET_OR_STATES
, pAccImpl
,
804 pAccImpl
->GetFrm(), ACC_STATE_CARET
);
805 AppendEvent( aEvent
);
810 // While firing events the current frame might have
811 // been disposed because it moved out of the vis area.
812 // Setting the cursor for such frames is useless and even
814 if( pAccImpl
->GetFrm() )
815 pAccImpl
->InvalidateCursorPos();
819 void SwAccessibleMap::InvalidateShapeSelection()
821 if( GetShell()->ActionPend() )
823 SwAccessibleEvent_Impl
aEvent(
824 SwAccessibleEvent_Impl::SHAPE_SELECTION
);
825 AppendEvent( aEvent
);
830 DoInvalidateShapeSelection();
834 void SwAccessibleMap::DoInvalidateShapeSelection()
836 SwAccessibleObjShape_Impl
*pShapes
= 0;
837 SwAccessibleObjShape_Impl
*pSelShape
= 0;
840 const ViewShell
*pVSh
= GetShell();
841 const SwFEShell
*pFESh
= pVSh
->ISA( SwFEShell
) ?
842 static_cast< const SwFEShell
* >( pVSh
) : 0;
843 sal_uInt16 nSelShapes
= pFESh
? pFESh
->IsObjSelected() : 0;
846 vos::OGuard
aGuard( maMutex
);
848 pShapes
= mpShapeMap
->Copy( nShapes
, pFESh
, &pSelShape
);
853 ::std::list
< const SwFrm
* > aParents
;
854 Window
*pWin
= GetShell()->GetWin();
855 sal_Bool bFocused
= pWin
&& pWin
->HasFocus();
856 SwAccessibleObjShape_Impl
*pShape
= pShapes
;
859 if( pShape
->second
.isValid() )
862 if( pShape
>= pSelShape
)
865 pShape
->second
->SetState( AccessibleStateType::SELECTED
);
866 if( bFocused
&& 1 == nSelShapes
)
867 pShape
->second
->SetState( AccessibleStateType::FOCUSED
);
869 pShape
->second
->ResetState( AccessibleStateType::FOCUSED
);
874 pShape
->second
->ResetState( AccessibleStateType::SELECTED
);
875 pShape
->second
->ResetState( AccessibleStateType::FOCUSED
);
879 SwFrmOrObj
aFrmOrObj( pShape
->first
);
881 SwAccessibleFrame::GetParent( aFrmOrObj
,
882 GetShell()->IsPreView() );
883 aParents
.push_back( aParent
.GetSwFrm() );
890 if( aParents
.size() > 0 )
892 ::std::list
< const SwFrm
* >::const_iterator aIter
= aParents
.begin();
893 ::std::list
< const SwFrm
* >::const_iterator aEndIter
= aParents
.end();
894 while( aIter
!= aEndIter
)
896 ::vos::ORef
< SwAccessibleContext
> xParentAccImpl
;
898 vos::OGuard
aGuard( maMutex
);
901 SwAccessibleContextMap_Impl::const_iterator aMapIter
=
902 mpFrmMap
->find( *aIter
);
903 if( aMapIter
!= mpFrmMap
->end() )
905 uno::Reference
< XAccessible
> xAcc( (*aMapIter
).second
);
907 static_cast< SwAccessibleContext
*>( xAcc
.get() );
911 if( xParentAccImpl
.isValid() )
913 AccessibleEventObject aEvent
;
914 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED
;
915 xParentAccImpl
->FireAccessibleEvent( aEvent
);
926 void SwAccessibleMap::DoInvalidateShapeFocus()
928 const ViewShell
*pVSh
= GetShell();
929 const SwFEShell
*pFESh
= pVSh
->ISA( SwFEShell
) ?
930 static_cast< const SwFEShell
* >( pVSh
) : 0;
931 sal_uInt16 nSelShapes
= pFESh
? pFESh
->IsObjSelected() : 0;
933 if( nSelShapes
!= 1 )
936 SwAccessibleObjShape_Impl
*pShapes
= 0;
937 SwAccessibleObjShape_Impl
*pSelShape
= 0;
942 vos::OGuard
aGuard( maMutex
);
944 pShapes
= mpShapeMap
->Copy( nShapes
, pFESh
, &pSelShape
);
949 Window
*pWin
= GetShell()->GetWin();
950 sal_Bool bFocused
= pWin
&& pWin
->HasFocus();
951 SwAccessibleObjShape_Impl
*pShape
= pShapes
;
954 if( pShape
->second
.isValid() )
956 if( bFocused
&& pShape
>= pSelShape
)
957 pShape
->second
->SetState( AccessibleStateType::FOCUSED
);
959 pShape
->second
->ResetState( AccessibleStateType::FOCUSED
);
971 SwAccessibleMap::SwAccessibleMap( ViewShell
*pSh
) :
977 // --> OD 2005-12-13 #i27301#
978 mpSelectedParas( 0 ),
985 mbShapeSelected( sal_False
)
987 pSh
->GetLayout()->AddAccessibleShell();
990 SwAccessibleMap::~SwAccessibleMap()
992 uno::Reference
< XAccessible
> xAcc
;
994 vos::OGuard
aGuard( maMutex
);
997 const SwRootFrm
*pRootFrm
= GetShell()->GetLayout();
998 SwAccessibleContextMap_Impl::iterator aIter
= mpFrmMap
->find( pRootFrm
);
999 if( aIter
!= mpFrmMap
->end() )
1000 xAcc
= (*aIter
).second
;
1002 xAcc
= new SwAccessibleDocument( this );
1006 SwAccessibleDocument
*pAcc
=
1007 static_cast< SwAccessibleDocument
* >( xAcc
.get() );
1008 pAcc
->Dispose( sal_True
);
1011 vos::OGuard
aGuard( maMutex
);
1013 ASSERT( !mpFrmMap
|| mpFrmMap
->empty(),
1014 "Frame map should be empty after disposing the root frame" );
1017 SwAccessibleContextMap_Impl::iterator aIter
= mpFrmMap
->begin();
1018 while( aIter
!= mpFrmMap
->end() )
1020 uno::Reference
< XAccessible
> xTmp
= (*aIter
).second
;
1023 SwAccessibleContext
*pTmp
=
1024 static_cast< SwAccessibleContext
* >( xTmp
.get() );
1030 ASSERT( !mpShapeMap
|| mpShapeMap
->empty(),
1031 "Object map should be empty after disposing the root frame" );
1034 SwAccessibleShapeMap_Impl::iterator aIter
= mpShapeMap
->begin();
1035 while( aIter
!= mpShapeMap
->end() )
1037 uno::Reference
< XAccessible
> xTmp
= (*aIter
).second
;
1040 ::accessibility::AccessibleShape
*pTmp
=
1041 static_cast< ::accessibility::AccessibleShape
* >( xTmp
.get() );
1054 // --> OD 2005-12-13 #i27301#
1055 delete mpSelectedParas
;
1056 mpSelectedParas
= 0;
1064 vos::OGuard
aGuard( maEventMutex
);
1066 ASSERT( !(mpEvents
|| mpEventMap
), "pending events" );
1069 SwAccessibleEventList_Impl::iterator aIter
= mpEvents
->begin();
1070 while( aIter
!= mpEvents
->end() )
1077 SwAccessibleEventMap_Impl::iterator aIter
= mpEventMap
->begin();
1078 while( aIter
!= mpEventMap
->end() )
1089 mpVSh
->GetLayout()->RemoveAccessibleShell();
1092 uno::Reference
< XAccessible
> SwAccessibleMap::_GetDocumentView(
1093 sal_Bool bPagePreview
)
1095 uno::Reference
< XAccessible
> xAcc
;
1096 sal_Bool bSetVisArea
= sal_False
;
1099 vos::OGuard
aGuard( maMutex
);
1103 mpFrmMap
= new SwAccessibleContextMap_Impl
;
1105 mpFrmMap
->mbLocked
= sal_False
;
1110 ASSERT( !mpFrmMap
->mbLocked
, "Map is locked" );
1111 mpFrmMap
->mbLocked
= sal_True
;
1114 const SwRootFrm
*pRootFrm
= GetShell()->GetLayout();
1115 SwAccessibleContextMap_Impl::iterator aIter
= mpFrmMap
->find( pRootFrm
);
1116 if( aIter
!= mpFrmMap
->end() )
1117 xAcc
= (*aIter
).second
;
1120 bSetVisArea
= sal_True
; // Set VisArea when map mutex is not
1126 xAcc
= new SwAccessiblePreview( this );
1128 xAcc
= new SwAccessibleDocument( this );
1130 if( aIter
!= mpFrmMap
->end() )
1132 (*aIter
).second
= xAcc
;
1136 SwAccessibleContextMap_Impl::value_type
aEntry( pRootFrm
, xAcc
);
1137 mpFrmMap
->insert( aEntry
);
1142 mpFrmMap
->mbLocked
= sal_False
;
1148 SwAccessibleDocumentBase
*pAcc
=
1149 static_cast< SwAccessibleDocumentBase
* >( xAcc
.get() );
1156 uno::Reference
< XAccessible
> SwAccessibleMap::GetDocumentView( )
1158 return _GetDocumentView( sal_False
);
1161 // OD 14.01.2003 #103492# - complete re-factoring of method due to new page/print
1162 // preview functionality.
1163 uno::Reference
<XAccessible
> SwAccessibleMap::GetDocumentPreview(
1164 const std::vector
<PrevwPage
*>& _rPrevwPages
,
1165 const Fraction
& _rScale
,
1166 const SwPageFrm
* _pSelectedPageFrm
,
1167 const Size
& _rPrevwWinSize
)
1169 // create & update preview data object
1170 if( mpPreview
== NULL
)
1171 mpPreview
= new SwAccPreviewData();
1172 mpPreview
->Update( _rPrevwPages
, _rScale
, _pSelectedPageFrm
, _rPrevwWinSize
);
1174 uno::Reference
<XAccessible
> xAcc
= _GetDocumentView( sal_True
);
1178 uno::Reference
< XAccessible
> SwAccessibleMap::GetContext( const SwFrm
*pFrm
,
1181 uno::Reference
< XAccessible
> xAcc
;
1182 uno::Reference
< XAccessible
> xOldCursorAcc
;
1183 sal_Bool bOldShapeSelected
= sal_False
;
1186 vos::OGuard
aGuard( maMutex
);
1188 if( !mpFrmMap
&& bCreate
)
1189 mpFrmMap
= new SwAccessibleContextMap_Impl
;
1192 SwAccessibleContextMap_Impl::iterator aIter
= mpFrmMap
->find( pFrm
);
1193 if( aIter
!= mpFrmMap
->end() )
1194 xAcc
= (*aIter
).second
;
1196 if( !xAcc
.is() && bCreate
)
1198 SwAccessibleContext
*pAcc
= 0;
1199 switch( pFrm
->GetType() )
1203 pAcc
= new SwAccessibleParagraph( this,
1204 static_cast< const SwTxtFrm
* >( pFrm
) );
1207 pAcc
= new SwAccessibleHeaderFooter( this,
1208 static_cast< const SwHeaderFrm
*>( pFrm
) );
1211 pAcc
= new SwAccessibleHeaderFooter( this,
1212 static_cast< const SwFooterFrm
*>( pFrm
) );
1216 const SwFtnFrm
*pFtnFrm
=
1217 static_cast < const SwFtnFrm
* >( pFrm
);
1218 sal_Bool bIsEndnote
=
1219 SwAccessibleFootnote::IsEndnote( pFtnFrm
);
1220 pAcc
= new SwAccessibleFootnote( this, bIsEndnote
,
1221 (bIsEndnote
? mnEndnote
++ : mnFootnote
++),
1227 const SwFlyFrm
*pFlyFrm
=
1228 static_cast < const SwFlyFrm
* >( pFrm
);
1229 switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm
) )
1232 pAcc
= new SwAccessibleGraphic( this, pFlyFrm
);
1235 pAcc
= new SwAccessibleEmbeddedObject( this, pFlyFrm
);
1238 pAcc
= new SwAccessibleTextFrame( this, pFlyFrm
);
1244 pAcc
= new SwAccessibleCell( this,
1245 static_cast< const SwCellFrm
*>( pFrm
) );
1248 pAcc
= new SwAccessibleTable( this,
1249 static_cast< const SwTabFrm
*>( pFrm
) );
1252 DBG_ASSERT( GetShell()->IsPreView(),
1253 "accessible page frames only in PagePreview" );
1254 pAcc
= new SwAccessiblePage( this, pFrm
);
1259 ASSERT( xAcc
.is(), "unknown frame type" );
1262 if( aIter
!= mpFrmMap
->end() )
1264 (*aIter
).second
= xAcc
;
1268 SwAccessibleContextMap_Impl::value_type
aEntry( pFrm
, xAcc
);
1269 mpFrmMap
->insert( aEntry
);
1272 if( pAcc
->HasCursor() &&
1273 !AreInSameTable( mxCursorContext
, pFrm
) )
1275 // If the new context has the focus, and if we know
1276 // another context that had the focus, then the focus
1277 // just moves from the old context to the new one. We
1278 // have to send a focus event and a caret event for
1279 // the old context then. We have to to that know,
1280 // because after we have left this method, anyone might
1281 // call getStates for the new context and will get a
1282 // focused state then. Sending the focus changes event
1283 // after that seems to be strange. However, we cannot
1284 // send a focus event fo the new context now, because
1285 // noone except us knows it. In any case, we remeber
1286 // the new context as the one that has the focus
1289 xOldCursorAcc
= mxCursorContext
;
1290 mxCursorContext
= xAcc
;
1292 bOldShapeSelected
= mbShapeSelected
;
1293 mbShapeSelected
= sal_False
;
1300 // Invalidate focus for old object when map is not locked
1301 if( xOldCursorAcc
.is() )
1302 InvalidateCursorPosition( xOldCursorAcc
);
1303 if( bOldShapeSelected
)
1304 InvalidateShapeSelection();
1309 ::vos::ORef
< SwAccessibleContext
> SwAccessibleMap::GetContextImpl(
1313 uno::Reference
< XAccessible
> xAcc( GetContext( pFrm
, bCreate
) );
1315 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
1316 static_cast< SwAccessibleContext
* >( xAcc
.get() ) );
1321 uno::Reference
< XAccessible
> SwAccessibleMap::GetContext(
1322 const SdrObject
*pObj
,
1323 SwAccessibleContext
*pParentImpl
,
1326 uno::Reference
< XAccessible
> xAcc
;
1327 uno::Reference
< XAccessible
> xOldCursorAcc
;
1330 vos::OGuard
aGuard( maMutex
);
1332 if( !mpShapeMap
&& bCreate
)
1333 mpShapeMap
= new SwAccessibleShapeMap_Impl( this );
1336 SwAccessibleShapeMap_Impl::iterator aIter
=
1337 mpShapeMap
->find( pObj
);
1338 if( aIter
!= mpShapeMap
->end() )
1339 xAcc
= (*aIter
).second
;
1341 if( !xAcc
.is() && bCreate
)
1343 ::accessibility::AccessibleShape
*pAcc
= 0;
1344 uno::Reference
< drawing::XShape
> xShape(
1345 const_cast< SdrObject
* >( pObj
)->getUnoShape(),
1349 ::accessibility::ShapeTypeHandler
& rShapeTypeHandler
=
1350 ::accessibility::ShapeTypeHandler::Instance();
1351 uno::Reference
< XAccessible
> xParent( pParentImpl
);
1352 ::accessibility::AccessibleShapeInfo
aShapeInfo(
1353 xShape
, xParent
, this );
1355 pAcc
= rShapeTypeHandler
.CreateAccessibleObject(
1356 aShapeInfo
, mpShapeMap
->GetInfo() );
1360 ASSERT( xAcc
.is(), "unknown shape type" );
1364 if( aIter
!= mpShapeMap
->end() )
1366 (*aIter
).second
= xAcc
;
1370 SwAccessibleShapeMap_Impl::value_type
aEntry( pObj
,
1372 mpShapeMap
->insert( aEntry
);
1380 // Invalidate focus for old object when map is not locked
1381 if( xOldCursorAcc
.is() )
1382 InvalidateCursorPosition( xOldCursorAcc
);
1387 ::vos::ORef
< ::accessibility::AccessibleShape
> SwAccessibleMap::GetContextImpl(
1388 const SdrObject
*pObj
,
1389 SwAccessibleContext
*pParentImpl
,
1392 uno::Reference
< XAccessible
> xAcc( GetContext( pObj
, pParentImpl
, bCreate
) );
1394 ::vos::ORef
< ::accessibility::AccessibleShape
> xAccImpl(
1395 static_cast< ::accessibility::AccessibleShape
* >( xAcc
.get() ) );
1401 void SwAccessibleMap::RemoveContext( const SwFrm
*pFrm
)
1403 vos::OGuard
aGuard( maMutex
);
1407 SwAccessibleContextMap_Impl::iterator aIter
=
1408 mpFrmMap
->find( pFrm
);
1409 if( aIter
!= mpFrmMap
->end() )
1411 mpFrmMap
->erase( aIter
);
1413 // Remove reference to old caret object. Though mxCursorContext
1414 // is a weak reference and cleared automatically, clearing it
1415 // directly makes sure to not keep a defunctional object.
1416 uno::Reference
< XAccessible
> xOldAcc( mxCursorContext
);
1419 SwAccessibleContext
*pOldAccImpl
=
1420 static_cast< SwAccessibleContext
*>( xOldAcc
.get() );
1421 ASSERT( pOldAccImpl
->GetFrm(), "old caret context is disposed" );
1422 if( pOldAccImpl
->GetFrm() == pFrm
)
1424 xOldAcc
.clear(); // get an empty ref
1425 mxCursorContext
= xOldAcc
;
1429 if( mpFrmMap
->empty() )
1438 void SwAccessibleMap::RemoveContext( const SdrObject
*pObj
)
1440 vos::OGuard
aGuard( maMutex
);
1444 SwAccessibleShapeMap_Impl::iterator aIter
=
1445 mpShapeMap
->find( pObj
);
1446 if( aIter
!= mpShapeMap
->end() )
1448 mpShapeMap
->erase( aIter
);
1450 // The shape selection flag is not cleared, but one might do
1451 // so but has to make sure that the removed context is the one
1452 // that is selected.
1454 if( mpShapeMap
->empty() )
1464 void SwAccessibleMap::Dispose( const SwFrm
*pFrm
, const SdrObject
*pObj
,
1465 sal_Bool bRecursive
)
1467 SwFrmOrObj
aFrmOrObj( pFrm
, pObj
);
1469 // Indeed, the following assert checks the frame's accessible flag,
1470 // because that's the one that is evaluated in the layout. The frame
1471 // might not be accessible anyway. That's the case for cell frames that
1472 // contain further cells.
1473 ASSERT( !aFrmOrObj
.GetSwFrm() || aFrmOrObj
.GetSwFrm()->IsAccessibleFrm(),
1474 "non accessible frame should be disposed" );
1476 ::vos::ORef
< SwAccessibleContext
> xAccImpl
;
1477 ::vos::ORef
< SwAccessibleContext
> xParentAccImpl
;
1478 ::vos::ORef
< ::accessibility::AccessibleShape
> xShapeAccImpl
;
1479 if( aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1481 // get accessible context for frame
1483 vos::OGuard
aGuard( maMutex
);
1485 // First of all look for an accessible context for a frame
1486 if( aFrmOrObj
.GetSwFrm() && mpFrmMap
)
1488 SwAccessibleContextMap_Impl::iterator aIter
=
1489 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1490 if( aIter
!= mpFrmMap
->end() )
1492 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
1494 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1497 if( !xAccImpl
.isValid() && mpFrmMap
)
1499 // If there is none, look if the parent is accessible.
1500 const SwFrm
*pParent
=
1501 SwAccessibleFrame::GetParent( aFrmOrObj
,
1502 GetShell()->IsPreView());
1506 SwAccessibleContextMap_Impl::iterator aIter
=
1507 mpFrmMap
->find( pParent
);
1508 if( aIter
!= mpFrmMap
->end() )
1510 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
1512 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1516 if( !xParentAccImpl
.isValid() && !aFrmOrObj
.GetSwFrm() &&
1519 SwAccessibleShapeMap_Impl::iterator aIter
=
1520 mpShapeMap
->find( aFrmOrObj
.GetSdrObject() );
1521 if( aIter
!= mpShapeMap
->end() )
1523 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
1525 static_cast< ::accessibility::AccessibleShape
*>( xAcc
.get() );
1528 if( pObj
&& GetShell()->ActionPend() &&
1529 (xParentAccImpl
.isValid() || xShapeAccImpl
.isValid()) )
1531 // Keep a reference to the XShape to avoid that it
1532 // is deleted with a SwFrmFmt::Modify.
1533 uno::Reference
< drawing::XShape
> xShape(
1534 const_cast< SdrObject
* >( pObj
)->getUnoShape(),
1539 mpShapes
= new SwShapeList_Impl
;
1540 mpShapes
->push_back( xShape
);
1545 // remove events stored for the frame
1547 vos::OGuard
aGuard( maEventMutex
);
1550 SwAccessibleEventMap_Impl::iterator aIter
=
1551 mpEventMap
->find( aFrmOrObj
);
1552 if( aIter
!= mpEventMap
->end() )
1554 SwAccessibleEvent_Impl
aEvent(
1555 SwAccessibleEvent_Impl::DISPOSE
, aFrmOrObj
);
1556 AppendEvent( aEvent
);
1561 // If the frame is accessible and there is a context for it, dispose
1562 // the frame. If the frame is no context for it but disposing should
1563 // take place recursive, the frame's children have to be disposed
1564 // anyway, so we have to create the context then.
1565 if( xAccImpl
.isValid() )
1567 xAccImpl
->Dispose( bRecursive
);
1569 else if( xParentAccImpl
.isValid() )
1571 // If the frame is a cell frame, the table must be notified.
1572 // If we are in an action, a table model change event will
1573 // be broadcasted at the end of the action to give the table
1574 // a chance to generate a single table change event.
1576 xParentAccImpl
->DisposeChild( aFrmOrObj
, bRecursive
);
1578 else if( xShapeAccImpl
.isValid() )
1580 RemoveContext( aFrmOrObj
.GetSdrObject() );
1581 xShapeAccImpl
->dispose();
1584 if( mpPreview
&& pFrm
&& pFrm
->IsPageFrm() )
1585 mpPreview
->DisposePage( static_cast< const SwPageFrm
*>( pFrm
) );
1589 void SwAccessibleMap::InvalidatePosOrSize( const SwFrm
*pFrm
,
1590 const SdrObject
*pObj
,
1591 const SwRect
& rOldBox
)
1593 SwFrmOrObj
aFrmOrObj( pFrm
, pObj
);
1594 if( aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1596 ::vos::ORef
< SwAccessibleContext
> xAccImpl
;
1597 ::vos::ORef
< SwAccessibleContext
> xParentAccImpl
;
1599 vos::OGuard
aGuard( maMutex
);
1603 if( aFrmOrObj
.GetSwFrm() )
1605 SwAccessibleContextMap_Impl::iterator aIter
=
1606 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1607 if( aIter
!= mpFrmMap
->end() )
1609 // If there is an accesible object already it is
1610 // notified directly.
1611 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
1613 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1616 if( !xAccImpl
.isValid() )
1618 // Otherwise we look if the parent is accessible.
1619 // If not, there is nothing to do.
1620 const SwFrm
*pParent
=
1621 SwAccessibleFrame::GetParent( aFrmOrObj
,
1622 GetShell()->IsPreView());
1626 SwAccessibleContextMap_Impl::iterator aIter
=
1627 mpFrmMap
->find( pParent
);
1628 if( aIter
!= mpFrmMap
->end() )
1630 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
1632 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1639 if( xAccImpl
.isValid() )
1641 if( GetShell()->ActionPend() )
1643 SwAccessibleEvent_Impl
aEvent(
1644 SwAccessibleEvent_Impl::POS_CHANGED
, xAccImpl
.getBodyPtr(),
1645 aFrmOrObj
, rOldBox
);
1646 AppendEvent( aEvent
);
1651 xAccImpl
->InvalidatePosOrSize( rOldBox
);
1654 else if( xParentAccImpl
.isValid() )
1656 if( GetShell()->ActionPend() )
1658 SwAccessibleEvent_Impl
aEvent(
1659 SwAccessibleEvent_Impl::CHILD_POS_CHANGED
,
1660 xParentAccImpl
.getBodyPtr(), aFrmOrObj
, rOldBox
);
1661 AppendEvent( aEvent
);
1666 xParentAccImpl
->InvalidateChildPosOrSize( aFrmOrObj
,
1673 void SwAccessibleMap::InvalidateContent( const SwFrm
*pFrm
)
1675 SwFrmOrObj
aFrmOrObj( pFrm
);
1676 if( aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1678 uno::Reference
< XAccessible
> xAcc
;
1680 vos::OGuard
aGuard( maMutex
);
1684 SwAccessibleContextMap_Impl::iterator aIter
=
1685 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1686 if( aIter
!= mpFrmMap
->end() )
1687 xAcc
= (*aIter
).second
;
1693 SwAccessibleContext
*pAccImpl
=
1694 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1695 if( GetShell()->ActionPend() )
1697 SwAccessibleEvent_Impl
aEvent(
1698 SwAccessibleEvent_Impl::INVALID_CONTENT
, pAccImpl
,
1700 AppendEvent( aEvent
);
1705 pAccImpl
->InvalidateContent();
1711 // --> OD 2009-01-06 #i88069#
1712 void SwAccessibleMap::InvalidateAttr( const SwTxtFrm
& rTxtFrm
)
1714 SwFrmOrObj
aFrmOrObj( &rTxtFrm
);
1715 if( aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1717 uno::Reference
< XAccessible
> xAcc
;
1719 vos::OGuard
aGuard( maMutex
);
1723 SwAccessibleContextMap_Impl::iterator aIter
=
1724 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1725 if( aIter
!= mpFrmMap
->end() )
1726 xAcc
= (*aIter
).second
;
1732 SwAccessibleContext
*pAccImpl
=
1733 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1734 if( GetShell()->ActionPend() )
1736 SwAccessibleEvent_Impl
aEvent( SwAccessibleEvent_Impl::INVALID_ATTR
,
1737 pAccImpl
, aFrmOrObj
);
1738 aEvent
.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED
);
1739 AppendEvent( aEvent
);
1744 pAccImpl
->InvalidateAttr();
1751 void SwAccessibleMap::InvalidateCursorPosition( const SwFrm
*pFrm
)
1753 SwFrmOrObj
aFrmOrObj( pFrm
);
1754 sal_Bool bShapeSelected
= sal_False
;
1755 const ViewShell
*pVSh
= GetShell();
1756 if( pVSh
->ISA( SwCrsrShell
) )
1758 const SwCrsrShell
*pCSh
= static_cast< const SwCrsrShell
* >( pVSh
);
1759 if( pCSh
->IsTableMode() )
1761 while( aFrmOrObj
.GetSwFrm() && !aFrmOrObj
.GetSwFrm()->IsCellFrm() )
1762 aFrmOrObj
= aFrmOrObj
.GetSwFrm()->GetUpper();
1764 else if( pVSh
->ISA( SwFEShell
) )
1766 sal_uInt16 nObjCount
;
1767 const SwFEShell
*pFESh
= static_cast< const SwFEShell
* >( pVSh
);
1768 const SwFrm
*pFlyFrm
= pFESh
->GetCurrFlyFrm();
1771 ASSERT( !pFrm
|| pFrm
->FindFlyFrm() == pFlyFrm
,
1772 "cursor is not contained in fly frame" );
1773 aFrmOrObj
= pFlyFrm
;
1775 else if( (nObjCount
= pFESh
->IsObjSelected()) > 0 )
1777 bShapeSelected
= sal_True
;
1778 aFrmOrObj
= static_cast<const SwFrm
*>( 0 );
1783 ASSERT( bShapeSelected
|| aFrmOrObj
.IsAccessible(GetShell()->IsPreView()),
1784 "frame is not accessible" );
1786 uno::Reference
< XAccessible
> xOldAcc
;
1787 uno::Reference
< XAccessible
> xAcc
;
1788 sal_Bool bOldShapeSelected
= sal_False
;
1791 vos::OGuard
aGuard( maMutex
);
1793 xOldAcc
= mxCursorContext
;
1794 mxCursorContext
= xAcc
; // clear reference
1796 bOldShapeSelected
= mbShapeSelected
;
1797 mbShapeSelected
= bShapeSelected
;
1799 if( aFrmOrObj
.GetSwFrm() && mpFrmMap
)
1801 SwAccessibleContextMap_Impl::iterator aIter
=
1802 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1803 if( aIter
!= mpFrmMap
->end() )
1804 xAcc
= (*aIter
).second
;
1806 // For cells, some extra thoughts are necessary,
1807 // because invalidating the cursor for one cell
1808 // invalidates the cursor for all cells of the same
1809 // table. For this reason, we don't want to
1810 // invalidate the cursor for the old cursor object
1811 // and the new one if they are within the same table,
1812 // because this would result in doing the work twice.
1813 // Moreover, we have to make sure to invalidate the
1814 // cursor even if the current cell has no accessible object.
1815 // If the old cursor objects exists and is in the same
1816 // table, its the best choice, because using it avoids
1817 // an unnessarary cursor invalidation cycle when creating
1818 // a new object for the current cell.
1819 if( aFrmOrObj
.GetSwFrm()->IsCellFrm() )
1822 AreInSameTable( xOldAcc
, aFrmOrObj
.GetSwFrm() ) )
1825 xOldAcc
= xAcc
; // avoid extra invalidation
1827 xAcc
= xOldAcc
; // make sure ate least one
1830 xAcc
= GetContext( aFrmOrObj
.GetSwFrm(), sal_True
);
1835 if( xOldAcc
.is() && xOldAcc
!= xAcc
)
1836 InvalidateCursorPosition( xOldAcc
);
1837 if( bOldShapeSelected
|| bShapeSelected
)
1838 InvalidateShapeSelection();
1840 InvalidateCursorPosition( xAcc
);
1843 void SwAccessibleMap::InvalidateFocus()
1845 uno::Reference
< XAccessible
> xAcc
;
1846 sal_Bool bShapeSelected
;
1848 vos::OGuard
aGuard( maMutex
);
1850 xAcc
= mxCursorContext
;
1851 bShapeSelected
= mbShapeSelected
;
1856 SwAccessibleContext
*pAccImpl
=
1857 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1858 pAccImpl
->InvalidateFocus();
1860 else if( bShapeSelected
)
1862 DoInvalidateShapeFocus();
1866 void SwAccessibleMap::SetCursorContext(
1867 const ::vos::ORef
< SwAccessibleContext
>& rCursorContext
)
1869 vos::OGuard
aGuard( maMutex
);
1870 uno::Reference
< XAccessible
> xAcc( rCursorContext
.getBodyPtr() );
1871 mxCursorContext
= xAcc
;
1874 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
1875 void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates
,
1876 const SwFrm
* _pFrm
)
1878 // Start with the frame or the first upper that is accessible
1879 SwFrmOrObj
aFrmOrObj( _pFrm
);
1880 while( aFrmOrObj
.GetSwFrm() &&
1881 !aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1882 aFrmOrObj
= aFrmOrObj
.GetSwFrm()->GetUpper();
1883 if( !aFrmOrObj
.GetSwFrm() )
1884 aFrmOrObj
= GetShell()->GetLayout();
1886 uno::Reference
< XAccessible
> xAcc( GetContext( aFrmOrObj
.GetSwFrm(), sal_True
) );
1887 SwAccessibleContext
*pAccImpl
=
1888 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1889 if( GetShell()->ActionPend() )
1891 SwAccessibleEvent_Impl
aEvent(
1892 SwAccessibleEvent_Impl::CARET_OR_STATES
, pAccImpl
,
1893 pAccImpl
->GetFrm(), _nStates
);
1894 AppendEvent( aEvent
);
1899 pAccImpl
->InvalidateStates( _nStates
);
1904 void SwAccessibleMap::_InvalidateRelationSet( const SwFrm
* pFrm
,
1907 // first, see if this frame is accessible, and if so, get the respective
1908 SwFrmOrObj
aFrmOrObj( pFrm
);
1909 if( aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1911 uno::Reference
< XAccessible
> xAcc
;
1913 vos::OGuard
aGuard( maMutex
);
1917 SwAccessibleContextMap_Impl::iterator aIter
=
1918 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1919 if( aIter
!= mpFrmMap
->end() )
1921 xAcc
= (*aIter
).second
;
1926 // deliver event directly, or queue event
1929 SwAccessibleContext
*pAccImpl
=
1930 static_cast< SwAccessibleContext
*>( xAcc
.get() );
1931 if( GetShell()->ActionPend() )
1933 SwAccessibleEvent_Impl
aEvent(
1934 SwAccessibleEvent_Impl::CARET_OR_STATES
, pAccImpl
, pFrm
,
1935 bFrom
? ACC_STATE_RELATION_FROM
: ACC_STATE_RELATION_TO
);
1936 AppendEvent( aEvent
);
1941 pAccImpl
->InvalidateRelation( bFrom
1942 ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
1943 : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED
);
1949 void SwAccessibleMap::InvalidateRelationSet( const SwFrm
* pMaster
,
1950 const SwFrm
* pFollow
)
1952 _InvalidateRelationSet( pMaster
, sal_False
);
1953 _InvalidateRelationSet( pFollow
, sal_True
);
1956 /** invalidation CONTENT_FLOW_FROM/_TO relation of a paragraph
1958 OD 2005-12-01 #i27138#
1962 void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm
& _rTxtFrm
,
1965 _InvalidateRelationSet( &_rTxtFrm
, _bFrom
);
1968 /** invalidation of text selection of a paragraph
1970 OD 2005-12-12 #i27301#
1974 void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm
& _rTxtFrm
)
1976 // first, see if this frame is accessible, and if so, get the respective
1977 SwFrmOrObj
aFrmOrObj( &_rTxtFrm
);
1978 if( aFrmOrObj
.IsAccessible( GetShell()->IsPreView() ) )
1980 uno::Reference
< XAccessible
> xAcc
;
1982 vos::OGuard
aGuard( maMutex
);
1986 SwAccessibleContextMap_Impl::iterator aIter
=
1987 mpFrmMap
->find( aFrmOrObj
.GetSwFrm() );
1988 if( aIter
!= mpFrmMap
->end() )
1990 xAcc
= (*aIter
).second
;
1995 // deliver event directly, or queue event
1998 SwAccessibleContext
*pAccImpl
=
1999 static_cast< SwAccessibleContext
*>( xAcc
.get() );
2000 if( GetShell()->ActionPend() )
2002 SwAccessibleEvent_Impl
aEvent(
2003 SwAccessibleEvent_Impl::CARET_OR_STATES
,
2004 pAccImpl
, &_rTxtFrm
,
2005 ACC_STATE_TEXT_SELECTION_CHANGED
);
2006 AppendEvent( aEvent
);
2011 pAccImpl
->InvalidateTextSelection();
2017 // OD 15.01.2003 #103492# - complete re-factoring of method due to new page/print
2018 // preview functionality.
2019 void SwAccessibleMap::UpdatePreview( const std::vector
<PrevwPage
*>& _rPrevwPages
,
2020 const Fraction
& _rScale
,
2021 const SwPageFrm
* _pSelectedPageFrm
,
2022 const Size
& _rPrevwWinSize
)
2024 DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
2025 DBG_ASSERT( mpPreview
!= NULL
, "no preview data?" );
2027 // OD 15.01.2003 #103492# - adjustments for changed method signature
2028 mpPreview
->Update( _rPrevwPages
, _rScale
, _pSelectedPageFrm
, _rPrevwWinSize
);
2030 // propagate change of VisArea through the document's
2031 // accessibility tree; this will also send appropriate scroll
2033 SwAccessibleContext
* pDoc
=
2034 GetContextImpl( GetShell()->GetLayout() ).getBodyPtr();
2035 static_cast<SwAccessibleDocumentBase
*>( pDoc
)->SetVisArea();
2037 uno::Reference
< XAccessible
> xOldAcc
;
2038 uno::Reference
< XAccessible
> xAcc
;
2040 vos::OGuard
aGuard( maMutex
);
2042 xOldAcc
= mxCursorContext
;
2044 const SwPageFrm
*pSelPage
= mpPreview
->GetSelPage();
2045 if( pSelPage
&& mpFrmMap
)
2047 SwAccessibleContextMap_Impl::iterator aIter
=
2048 mpFrmMap
->find( pSelPage
);
2049 if( aIter
!= mpFrmMap
->end() )
2050 xAcc
= (*aIter
).second
;
2054 if( xOldAcc
.is() && xOldAcc
!= xAcc
)
2055 InvalidateCursorPosition( xOldAcc
);
2057 InvalidateCursorPosition( xAcc
);
2060 void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage
)
2062 DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
2063 DBG_ASSERT( mpPreview
!= NULL
, "no preview data?" );
2065 // OD 16.01.2003 #103492# - changed metthod call due to method signature change.
2066 mpPreview
->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage
) );
2068 uno::Reference
< XAccessible
> xOldAcc
;
2069 uno::Reference
< XAccessible
> xAcc
;
2071 vos::OGuard
aGuard( maMutex
);
2073 xOldAcc
= mxCursorContext
;
2075 const SwPageFrm
*pSelPage
= mpPreview
->GetSelPage();
2076 if( pSelPage
&& mpFrmMap
)
2078 SwAccessibleContextMap_Impl::iterator aIter
=
2079 mpFrmMap
->find( pSelPage
);
2080 if( aIter
!= mpFrmMap
->end() )
2081 xAcc
= (*aIter
).second
;
2085 if( xOldAcc
.is() && xOldAcc
!= xAcc
)
2086 InvalidateCursorPosition( xOldAcc
);
2088 InvalidateCursorPosition( xAcc
);
2092 sal_Bool
SwAccessibleMap::IsPageSelected( const SwPageFrm
*pPageFrm
) const
2094 return mpPreview
&& mpPreview
->GetSelPage() == pPageFrm
;
2098 void SwAccessibleMap::FireEvents()
2101 vos::OGuard
aGuard( maEventMutex
);
2104 mpEvents
->SetFiring();
2105 SwAccessibleEventList_Impl::iterator aIter
= mpEvents
->begin();
2106 while( aIter
!= mpEvents
->end() )
2108 FireEvent( *aIter
);
2120 vos::OGuard
aGuard( maMutex
);
2130 sal_Bool
SwAccessibleMap::IsValid() const
2135 Rectangle
SwAccessibleMap::GetVisibleArea() const
2137 MapMode
aSrc( MAP_TWIP
);
2138 MapMode
aDest( MAP_100TH_MM
);
2139 return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc
, aDest
);
2142 // Convert a MM100 value realtive to the document root into a pixel value
2143 // realtive to the screen!
2144 Point
SwAccessibleMap::LogicToPixel( const Point
& rPoint
) const
2146 MapMode
aSrc( MAP_100TH_MM
);
2147 MapMode
aDest( MAP_TWIP
);
2149 Point aPoint
= rPoint
;
2151 aPoint
= OutputDevice::LogicToLogic( aPoint
, aSrc
, aDest
);
2152 Window
*pWin
= GetShell()->GetWin();
2155 // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
2157 GetMapMode( aPoint
, aMapMode
);
2158 aPoint
= pWin
->LogicToPixel( aPoint
, aMapMode
);
2159 aPoint
= pWin
->OutputToAbsoluteScreenPixel( aPoint
);
2165 Size
SwAccessibleMap::LogicToPixel( const Size
& rSize
) const
2167 MapMode
aSrc( MAP_100TH_MM
);
2168 MapMode
aDest( MAP_TWIP
);
2169 Size
aSize( OutputDevice::LogicToLogic( rSize
, aSrc
, aDest
) );
2170 if( GetShell()->GetWin() )
2172 // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
2174 GetMapMode( Point(0,0), aMapMode
);
2175 aSize
= GetShell()->GetWin()->LogicToPixel( aSize
, aMapMode
);
2181 Point
SwAccessibleMap::PixelToLogic( const Point
& rPoint
) const
2184 Window
*pWin
= GetShell()->GetWin();
2187 aPoint
= pWin
->ScreenToOutputPixel( rPoint
);
2188 // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
2190 GetMapMode( aPoint
, aMapMode
);
2191 aPoint
= pWin
->PixelToLogic( aPoint
, aMapMode
);
2192 MapMode
aSrc( MAP_TWIP
);
2193 MapMode
aDest( MAP_100TH_MM
);
2194 aPoint
= OutputDevice::LogicToLogic( aPoint
, aSrc
, aDest
);
2200 Size
SwAccessibleMap::PixelToLogic( const Size
& rSize
) const
2203 if( GetShell()->GetWin() )
2205 // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
2207 GetMapMode( Point(0,0), aMapMode
);
2208 aSize
= GetShell()->GetWin()->PixelToLogic( rSize
, aMapMode
);
2209 MapMode
aSrc( MAP_TWIP
);
2210 MapMode
aDest( MAP_100TH_MM
);
2211 aSize
= OutputDevice::LogicToLogic( aSize
, aSrc
, aDest
);
2217 sal_Bool
SwAccessibleMap::ReplaceChild (
2218 ::accessibility::AccessibleShape
* pCurrentChild
,
2219 const uno::Reference
< drawing::XShape
>& _rxShape
,
2220 const long /*_nIndex*/,
2221 const ::accessibility::AccessibleShapeTreeInfo
& /*_rShapeTreeInfo*/
2222 ) throw (uno::RuntimeException
)
2224 const SdrObject
*pObj
= 0;
2226 vos::OGuard
aGuard( maMutex
);
2229 SwAccessibleShapeMap_Impl::const_iterator aIter
= mpShapeMap
->begin();
2230 SwAccessibleShapeMap_Impl::const_iterator aEndIter
= mpShapeMap
->end();
2231 while( aIter
!= aEndIter
&& !pObj
)
2233 uno::Reference
< XAccessible
> xAcc( (*aIter
).second
);
2234 ::accessibility::AccessibleShape
*pAccShape
=
2235 static_cast < ::accessibility::AccessibleShape
* >( xAcc
.get() );
2236 if( pAccShape
== pCurrentChild
)
2238 pObj
= (*aIter
).first
;
2247 uno::Reference
< drawing::XShape
> xShape( _rxShape
); //keep reference to shape, because
2248 // we might be the only one that
2250 // Also get keep parent.
2251 uno::Reference
< XAccessible
> xParent( pCurrentChild
->getAccessibleParent() );
2252 pCurrentChild
= 0; // well be realease by dispose
2256 vos::OGuard
aGuard( maMutex
);
2259 mpShapeMap
= new SwAccessibleShapeMap_Impl( this );
2261 // create the new child
2262 ::accessibility::ShapeTypeHandler
& rShapeTypeHandler
=
2263 ::accessibility::ShapeTypeHandler::Instance();
2264 ::accessibility::AccessibleShapeInfo
aShapeInfo(
2265 xShape
, xParent
, this );
2266 ::accessibility::AccessibleShape
* pReplacement
=
2267 rShapeTypeHandler
.CreateAccessibleObject (
2268 aShapeInfo
, mpShapeMap
->GetInfo() );
2270 uno::Reference
< XAccessible
> xAcc( pReplacement
);
2273 pReplacement
->Init();
2275 SwAccessibleShapeMap_Impl::iterator aIter
=
2276 mpShapeMap
->find( pObj
);
2277 if( aIter
!= mpShapeMap
->end() )
2279 (*aIter
).second
= xAcc
;
2283 SwAccessibleShapeMap_Impl::value_type
aEntry( pObj
, xAcc
);
2284 mpShapeMap
->insert( aEntry
);
2290 InvalidatePosOrSize( 0, pObj
, aEmptyRect
);
2295 Point
SwAccessibleMap::PixelToCore( const Point
& rPoint
) const
2298 if( GetShell()->GetWin() )
2300 // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
2302 GetMapMode( rPoint
, aMapMode
);
2303 aPoint
= GetShell()->GetWin()->PixelToLogic( rPoint
, aMapMode
);
2308 static inline long lcl_CorrectCoarseValue(long aCoarseValue
, long aFineValue
,
2309 long aRefValue
, bool bToLower
)
2311 long aResult
= aCoarseValue
;
2315 if (aFineValue
< aRefValue
)
2320 if (aFineValue
> aRefValue
)
2327 static inline void lcl_CorrectRectangle(Rectangle
& rRect
,
2328 const Rectangle
& rSource
,
2329 const Rectangle
& rInGrid
)
2331 rRect
.nLeft
= lcl_CorrectCoarseValue(rRect
.nLeft
, rSource
.nLeft
,
2332 rInGrid
.nLeft
, false);
2333 rRect
.nTop
= lcl_CorrectCoarseValue(rRect
.nTop
, rSource
.nTop
,
2334 rInGrid
.nTop
, false);
2335 rRect
.nRight
= lcl_CorrectCoarseValue(rRect
.nRight
, rSource
.nRight
,
2336 rInGrid
.nRight
, true);
2337 rRect
.nBottom
= lcl_CorrectCoarseValue(rRect
.nBottom
, rSource
.nBottom
,
2338 rInGrid
.nBottom
, true);
2341 Rectangle
SwAccessibleMap::CoreToPixel( const Rectangle
& rRect
) const
2344 if( GetShell()->GetWin() )
2346 // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
2348 GetMapMode( rRect
.TopLeft(), aMapMode
);
2349 aRect
= GetShell()->GetWin()->LogicToPixel( rRect
, aMapMode
);
2351 Rectangle aTmpRect
= GetShell()->GetWin()->PixelToLogic( aRect
, aMapMode
);
2352 lcl_CorrectRectangle(aRect
, rRect
, aTmpRect
);
2358 /** get mapping mode for LogicToPixel and PixelToLogic conversions
2360 OD 15.01.2003 #103492#
2361 Replacement method <PreviewAdjust(..)> by new method <GetMapMode>.
2362 Method returns mapping mode of current output device and adjusts it,
2363 if the shell is in page/print preview.
2364 Necessary, because <PreviewAdjust(..)> changes mapping mode at current
2365 output device for mapping logic document positions to page preview window
2366 positions and vice versa and doesn't take care to recover its changes.
2370 void SwAccessibleMap::GetMapMode( const Point
& _rPoint
,
2371 MapMode
& _orMapMode
) const
2373 MapMode aMapMode
= GetShell()->GetWin()->GetMapMode();
2374 if( GetShell()->IsPreView() )
2376 DBG_ASSERT( mpPreview
!= NULL
, "need preview data" );
2378 mpPreview
->AdjustMapMode( aMapMode
, _rPoint
);
2380 _orMapMode
= aMapMode
;
2383 /** get size of a dedicated preview page
2385 OD 15.01.2003 #103492#
2389 Size
SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum
) const
2391 DBG_ASSERT( mpVSh
->IsPreView(), "no page preview accessible." );
2392 DBG_ASSERT( mpVSh
->IsPreView() && ( mpPreview
!= NULL
),
2393 "missing accessible preview data at page preview" );
2394 if ( mpVSh
->IsPreView() && ( mpPreview
!= NULL
) )
2396 return mpVSh
->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum
);
2400 return Size( 0, 0 );
2404 /** method to build up a new data structure of the accessible pararaphs,
2405 which have a selection
2407 OD 2005-12-13 #i27301#
2408 Important note: method has to used inside a mutual exclusive section
2412 SwAccessibleSelectedParas_Impl
* SwAccessibleMap::_BuildSelectedParas()
2414 // no accessible contexts, no selection
2420 // get cursor as an instance of its base class <SwPaM>
2423 SwCrsrShell
* pCrsrShell
= dynamic_cast<SwCrsrShell
*>(GetShell());
2426 SwFEShell
* pFEShell
= dynamic_cast<SwFEShell
*>(pCrsrShell
);
2428 ( !pFEShell
->IsFrmSelected() &&
2429 pFEShell
->IsObjSelected() == 0 ) )
2431 // get cursor without updating an existing table cursor.
2432 pCrsr
= pCrsrShell
->GetCrsr( FALSE
);
2436 // no cursor, no selection
2442 SwAccessibleSelectedParas_Impl
* pRetSelectedParas( 0L );
2444 // loop on all cursors
2445 SwPaM
* pRingStart
= pCrsr
;
2448 // for a selection the cursor has to have a mark.
2449 // for savety reasons assure that point and mark are in text nodes
2450 if ( pCrsr
->HasMark() &&
2451 pCrsr
->GetPoint()->nNode
.GetNode().IsTxtNode() &&
2452 pCrsr
->GetMark()->nNode
.GetNode().IsTxtNode() )
2454 SwPosition
* pStartPos
= pCrsr
->Start();
2455 SwPosition
* pEndPos
= pCrsr
->End();
2456 // loop on all text nodes inside the selection
2457 SwNodeIndex
aIdx( pStartPos
->nNode
);
2458 for ( ; aIdx
.GetIndex() <= pEndPos
->nNode
.GetIndex(); ++aIdx
)
2460 SwTxtNode
* pTxtNode( aIdx
.GetNode().GetTxtNode() );
2463 // loop on all text frames registered at the text node.
2464 SwClientIter
aIter( *pTxtNode
);
2465 for( SwFrm
* pFrm
= (SwFrm
*)aIter
.First( TYPE(SwFrm
) );
2467 pFrm
= (SwFrm
*)aIter
.Next() )
2469 ASSERT( dynamic_cast<SwTxtFrm
*>(pFrm
),
2470 "<SwAccessibleMap::_BuildSelectedParas()> - unexpected frame type" );
2471 SwTxtFrm
* pTxtFrm( dynamic_cast<SwTxtFrm
*>(pFrm
) );
2474 uno::WeakReference
< XAccessible
> xWeakAcc
;
2475 SwAccessibleContextMap_Impl::iterator aMapIter
=
2476 mpFrmMap
->find( pTxtFrm
);
2477 if( aMapIter
!= mpFrmMap
->end() )
2479 xWeakAcc
= (*aMapIter
).second
;
2480 SwAccessibleParaSelection
aDataEntry(
2481 pTxtNode
== &(pStartPos
->nNode
.GetNode())
2482 ? pStartPos
->nContent
.GetIndex()
2484 pTxtNode
== &(pEndPos
->nNode
.GetNode())
2485 ? pEndPos
->nContent
.GetIndex()
2487 SwAccessibleSelectedParas_Impl::value_type
2488 aEntry( xWeakAcc
, aDataEntry
);
2489 if ( !pRetSelectedParas
)
2492 new SwAccessibleSelectedParas_Impl
;
2494 pRetSelectedParas
->insert( aEntry
);
2502 // prepare next turn: get next cursor in ring
2503 pCrsr
= static_cast<SwPaM
*>( pCrsr
->GetNext() );
2504 } while ( pCrsr
!= pRingStart
);
2506 return pRetSelectedParas
;
2509 /** invalidation of text selection of all paragraphs
2511 OD 2005-12-13 #i27301#
2515 void SwAccessibleMap::InvalidateTextSelectionOfAllParas()
2517 vos::OGuard
aGuard( maMutex
);
2519 // keep previously known selected paragraphs
2520 SwAccessibleSelectedParas_Impl
* pPrevSelectedParas( mpSelectedParas
);
2522 // determine currently selected paragraphs
2523 mpSelectedParas
= _BuildSelectedParas();
2525 // compare currently selected paragraphs with the previously selected
2526 // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
2527 // first, search for new and changed selections.
2528 // on the run remove selections from previously known ones, if they are
2529 // also in the current ones.
2530 if ( mpSelectedParas
)
2532 SwAccessibleSelectedParas_Impl::iterator aIter
= mpSelectedParas
->begin();
2533 for ( ; aIter
!= mpSelectedParas
->end(); ++aIter
)
2535 bool bSubmitEvent( false );
2536 if ( !pPrevSelectedParas
)
2539 bSubmitEvent
= true;
2543 SwAccessibleSelectedParas_Impl::iterator aPrevSelected
=
2544 pPrevSelectedParas
->find( (*aIter
).first
);
2545 if ( aPrevSelected
!= pPrevSelectedParas
->end() )
2547 // check, if selection has changed
2548 if ( (*aIter
).second
.nStartOfSelection
!=
2549 (*aPrevSelected
).second
.nStartOfSelection
||
2550 (*aIter
).second
.nEndOfSelection
!=
2551 (*aPrevSelected
).second
.nEndOfSelection
)
2553 // changed selection
2554 bSubmitEvent
= true;
2556 pPrevSelectedParas
->erase( aPrevSelected
);
2561 bSubmitEvent
= true;
2567 uno::Reference
< XAccessible
> xAcc( (*aIter
).first
);
2570 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
2571 static_cast<SwAccessibleContext
*>( xAcc
.get() ) );
2572 if ( xAccImpl
.isValid() && xAccImpl
->GetFrm() )
2574 const SwTxtFrm
* pTxtFrm(
2575 dynamic_cast<const SwTxtFrm
*>(xAccImpl
->GetFrm()) );
2577 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
2580 InvalidateParaTextSelection( *pTxtFrm
);
2588 // second, handle previous selections - after the first step the data
2589 // structure of the previously known only contains the 'old' selections
2590 if ( pPrevSelectedParas
)
2592 SwAccessibleSelectedParas_Impl::iterator aIter
= pPrevSelectedParas
->begin();
2593 for ( ; aIter
!= pPrevSelectedParas
->end(); ++aIter
)
2595 uno::Reference
< XAccessible
> xAcc( (*aIter
).first
);
2598 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
2599 static_cast<SwAccessibleContext
*>( xAcc
.get() ) );
2600 if ( xAccImpl
.isValid() && xAccImpl
->GetFrm() )
2602 const SwTxtFrm
* pTxtFrm(
2603 dynamic_cast<const SwTxtFrm
*>(xAccImpl
->GetFrm()) );
2605 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
2608 InvalidateParaTextSelection( *pTxtFrm
);
2614 delete pPrevSelectedParas
;
2622 SwAccPreviewData::SwAccPreviewData() :
2627 SwAccPreviewData::~SwAccPreviewData()
2631 // OD 13.01.2003 #103492# - complete re-factoring of method due to new page/print
2632 // preview functionality.
2633 void SwAccPreviewData::Update( const std::vector
<PrevwPage
*>& _rPrevwPages
,
2634 const Fraction
& _rScale
,
2635 const SwPageFrm
* _pSelectedPageFrm
,
2636 const Size
& _rPrevwWinSize
)
2638 // store preview scaling, maximal preview page size and selected page
2640 mpSelPage
= _pSelectedPageFrm
;
2642 // prepare loop on preview pages
2643 maPreviewRects
.clear();
2644 maLogicRects
.clear();
2648 // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and
2650 for ( std::vector
<PrevwPage
*>::const_iterator aPageIter
= _rPrevwPages
.begin();
2651 aPageIter
!= _rPrevwPages
.end();
2654 aPage
= (*aPageIter
)->pPage
;
2656 // add preview page rectangle to <maPreviewRects>
2657 Rectangle
aPrevwPgRect( (*aPageIter
)->aPrevwWinPos
, (*aPageIter
)->aPageSize
);
2658 maPreviewRects
.push_back( aPrevwPgRect
);
2660 // add logic page rectangle to <maLogicRects>
2661 SwRect
aLogicPgSwRect( aPage
.GetBox() );
2662 Rectangle
aLogicPgRect( aLogicPgSwRect
.SVRect() );
2663 maLogicRects
.push_back( aLogicPgRect
);
2664 // union visible area with visible part of logic page rectangle
2665 if ( (*aPageIter
)->bVisible
)
2667 if ( !(*aPageIter
)->pPage
->IsEmptyPage() )
2669 AdjustLogicPgRectToVisibleArea( aLogicPgSwRect
,
2670 SwRect( aPrevwPgRect
),
2673 if ( maVisArea
.IsEmpty() )
2674 maVisArea
= aLogicPgSwRect
;
2676 maVisArea
.Union( aLogicPgSwRect
);
2681 // OD 16.01.2003 #103492# - complete re-factoring of method due to new page/print
2682 // preview functionality.
2683 void SwAccPreviewData::InvalidateSelection( const SwPageFrm
* _pSelectedPageFrm
)
2685 mpSelPage
= _pSelectedPageFrm
;
2686 ASSERT( mpSelPage
, "selected page not found" );
2689 struct ContainsPredicate
2691 const Point
& mrPoint
;
2692 ContainsPredicate( const Point
& rPoint
) : mrPoint(rPoint
) {}
2693 bool operator() ( const Rectangle
& rRect
) const
2695 return rRect
.IsInside( mrPoint
) ? true : false;
2699 const SwRect
& SwAccPreviewData::GetVisArea() const
2704 void SwAccPreviewData::AdjustMapMode( MapMode
& rMapMode
,
2705 const Point
& rPoint
) const
2708 rMapMode
.SetScaleX( maScale
);
2709 rMapMode
.SetScaleY( maScale
);
2711 // find proper rectangle
2712 Rectangles::const_iterator aBegin
= maLogicRects
.begin();
2713 Rectangles::const_iterator aEnd
= maLogicRects
.end();
2714 Rectangles::const_iterator aFound
= ::std::find_if( aBegin
, aEnd
,
2715 ContainsPredicate( rPoint
) );
2717 if( aFound
!= aEnd
)
2719 // found! set new origin
2720 Point aPoint
= (maPreviewRects
.begin() + (aFound
- aBegin
))->TopLeft();
2721 aPoint
-= (maLogicRects
.begin() + (aFound
-aBegin
))->TopLeft();
2722 rMapMode
.SetOrigin( aPoint
);
2724 // else: don't adjust MapMode
2727 void SwAccPreviewData::DisposePage(const SwPageFrm
*pPageFrm
)
2729 if( mpSelPage
== pPageFrm
)
2733 /** adjust logic page retangle to its visible part
2735 OD 17.01.2003 #103492#
2739 void SwAccPreviewData::AdjustLogicPgRectToVisibleArea(
2740 SwRect
& _iorLogicPgSwRect
,
2741 const SwRect
& _rPrevwPgSwRect
,
2742 const Size
& _rPrevwWinSize
)
2744 // determine preview window rectangle
2745 const SwRect
aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize
);
2746 // calculate visible preview page rectangle
2747 SwRect
aVisPrevwPgSwRect( _rPrevwPgSwRect
);
2748 aVisPrevwPgSwRect
.Intersection( aPrevwWinSwRect
);
2749 // adjust logic page rectangle
2752 nTmpDiff
= aVisPrevwPgSwRect
.Left() - _rPrevwPgSwRect
.Left();
2754 _iorLogicPgSwRect
.Left( _iorLogicPgSwRect
.Left() + nTmpDiff
);
2756 nTmpDiff
= aVisPrevwPgSwRect
.Top() - _rPrevwPgSwRect
.Top();
2758 _iorLogicPgSwRect
.Top( _iorLogicPgSwRect
.Top() + nTmpDiff
);
2760 nTmpDiff
= _rPrevwPgSwRect
.Right() - aVisPrevwPgSwRect
.Right();
2762 _iorLogicPgSwRect
.Right( _iorLogicPgSwRect
.Right() - nTmpDiff
);
2764 nTmpDiff
= _rPrevwPgSwRect
.Bottom() - aVisPrevwPgSwRect
.Bottom();
2766 _iorLogicPgSwRect
.Bottom( _iorLogicPgSwRect
.Bottom() - nTmpDiff
);