LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/access - accmap.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 400 1149 34.8 %
Date: 2013-07-09 Functions: 48 114 42.1 %
Legend: Lines: hit not hit

          Line data    Source code
       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>
      21             : #include <rtl/strbuf.hxx>
      22             : #include <cppuhelper/weakref.hxx>
      23             : #include <vcl/window.hxx>
      24             : #include <svx/svdmodel.hxx>
      25             : #include <svx/unomod.hxx>
      26             : #include <algorithm>
      27             : #include <map>
      28             : #include <list>
      29             : #include <accmap.hxx>
      30             : #include <acccontext.hxx>
      31             : #include <accdoc.hxx>
      32             : #include <accpreview.hxx>
      33             : #include <accpage.hxx>
      34             : #include <accpara.hxx>
      35             : #include <accheaderfooter.hxx>
      36             : #include <accfootnote.hxx>
      37             : #include <acctextframe.hxx>
      38             : #include <accgraphic.hxx>
      39             : #include <accembedded.hxx>
      40             : #include <acccell.hxx>
      41             : #include <acctable.hxx>
      42             : #include <fesh.hxx>
      43             : #include <rootfrm.hxx>
      44             : #include <txtfrm.hxx>
      45             : #include <hffrm.hxx>
      46             : #include <ftnfrm.hxx>
      47             : #include <cellfrm.hxx>
      48             : #include <tabfrm.hxx>
      49             : #include <pagefrm.hxx>
      50             : #include <flyfrm.hxx>
      51             : #include <ndtyp.hxx>
      52             : #include <IDocumentDrawModelAccess.hxx>
      53             : #include <svx/ShapeTypeHandler.hxx>
      54             : #include <vcl/svapp.hxx>
      55             : #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
      56             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      57             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      58             : #include <cppuhelper/implbase1.hxx>
      59             : #include <pagepreviewlayout.hxx>
      60             : #include <pam.hxx>
      61             : #include <ndtxt.hxx>
      62             : #include <dflyobj.hxx>
      63             : #include <prevwpage.hxx>
      64             : #include <switerator.hxx>
      65             : #include <boost/bind.hpp>
      66             : 
      67             : using namespace ::com::sun::star;
      68             : using namespace ::com::sun::star::accessibility;
      69             : using namespace ::sw::access;
      70             : 
      71             : struct SwFrmFunc
      72             : {
      73        1572 :     bool operator()( const SwFrm * p1,
      74             :                          const SwFrm * p2) const
      75             :     {
      76        1572 :         return p1 < p2;
      77             :     }
      78             : };
      79             : 
      80             : typedef ::std::map < const SwFrm *, uno::WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl;
      81             : 
      82          12 : class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl
      83             : {
      84             : public:
      85             : 
      86             : #if OSL_DEBUG_LEVEL > 0
      87             :     bool mbLocked;
      88             : #endif
      89             : 
      90          12 :     SwAccessibleContextMap_Impl()
      91             : #if OSL_DEBUG_LEVEL > 0
      92             :         : mbLocked( false )
      93             : #endif
      94          12 :     {}
      95             : 
      96             : };
      97             : 
      98             : class SwDrawModellListener_Impl : public SfxListener,
      99             :     public ::cppu::WeakImplHelper1< document::XEventBroadcaster >
     100             : {
     101             :     mutable ::osl::Mutex maListenerMutex;
     102             :     ::cppu::OInterfaceContainerHelper maEventListeners;
     103             :     SdrModel *mpDrawModel;
     104             : protected:
     105             :     virtual ~SwDrawModellListener_Impl();
     106             : public:
     107             : 
     108             :     SwDrawModellListener_Impl( SdrModel *pDrawModel );
     109             : 
     110             : 
     111             :     virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
     112             :     virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
     113             : 
     114             :     virtual void        Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
     115             :     void Dispose();
     116             : };
     117             : 
     118           0 : SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) :
     119             :     maEventListeners( maListenerMutex ),
     120           0 :     mpDrawModel( pDrawModel )
     121             : {
     122           0 :     StartListening( *mpDrawModel );
     123           0 : }
     124             : 
     125           0 : SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
     126             : {
     127           0 :     EndListening( *mpDrawModel );
     128           0 : }
     129             : 
     130           0 : void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
     131             : {
     132           0 :     maEventListeners.addInterface( xListener );
     133           0 : }
     134             : 
     135           0 : void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
     136             : {
     137           0 :     maEventListeners.removeInterface( xListener );
     138           0 : }
     139             : 
     140           0 : void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/,
     141             :         const SfxHint& rHint )
     142             : {
     143             :     // do not broadcast notifications for writer fly frames, because there
     144             :     // are no shapes that need to know about them.
     145           0 :     const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
     146           0 :     if ( !pSdrHint ||
     147           0 :          ( pSdrHint->GetObject() &&
     148           0 :            ( pSdrHint->GetObject()->ISA(SwFlyDrawObj) ||
     149           0 :              pSdrHint->GetObject()->ISA(SwVirtFlyDrawObj) ||
     150           0 :              IS_TYPE(SdrObject,pSdrHint->GetObject()) ) ) )
     151             :     {
     152           0 :         return;
     153             :     }
     154             : 
     155             :     OSL_ENSURE( mpDrawModel, "draw model listener is disposed" );
     156           0 :     if( !mpDrawModel )
     157           0 :         return;
     158             : 
     159           0 :     document::EventObject aEvent;
     160           0 :     if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
     161           0 :         return;
     162             : 
     163           0 :     ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
     164           0 :     while( aIter.hasMoreElements() )
     165             :     {
     166             :         uno::Reference < document::XEventListener > xListener( aIter.next(),
     167           0 :                                                 uno::UNO_QUERY );
     168             :         try
     169             :         {
     170           0 :             xListener->notifyEvent( aEvent );
     171             :         }
     172           0 :         catch( uno::RuntimeException const & r )
     173             :         {
     174             :             SAL_WARN( "sw.core", "Runtime exception caught while notifying shape.: " << r.Message );
     175             :         }
     176           0 :     }
     177             : }
     178             : 
     179           0 : void SwDrawModellListener_Impl::Dispose()
     180             : {
     181           0 :     mpDrawModel = 0;
     182           0 : }
     183             : 
     184             : struct SwShapeFunc
     185             : {
     186           0 :     bool operator()( const SdrObject * p1,
     187             :                          const SdrObject * p2) const
     188             :     {
     189           0 :         return p1 < p2;
     190             :     }
     191             : };
     192             : typedef ::std::map < const SdrObject *, uno::WeakReference < XAccessible >, SwShapeFunc > _SwAccessibleShapeMap_Impl;
     193             : typedef ::std::pair < const SdrObject *, ::rtl::Reference < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl;
     194             : 
     195             : class SwAccessibleShapeMap_Impl: public _SwAccessibleShapeMap_Impl
     196             : 
     197             : {
     198             :     ::accessibility::AccessibleShapeTreeInfo maInfo;
     199             : 
     200             : public:
     201             : 
     202             : #if OSL_DEBUG_LEVEL > 0
     203             :     bool mbLocked;
     204             : #endif
     205           0 :     SwAccessibleShapeMap_Impl( SwAccessibleMap *pMap )
     206             : #if OSL_DEBUG_LEVEL > 0
     207             :         : mbLocked( false )
     208             : #endif
     209           0 :     {
     210           0 :         maInfo.SetSdrView( pMap->GetShell()->GetDrawView() );
     211           0 :         maInfo.SetWindow( pMap->GetShell()->GetWin() );
     212           0 :         maInfo.SetViewForwarder( pMap );
     213             :         uno::Reference < document::XEventBroadcaster > xModelBroadcaster =
     214             :             new SwDrawModellListener_Impl(
     215           0 :                     pMap->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() );
     216           0 :         maInfo.SetControllerBroadcaster( xModelBroadcaster );
     217           0 :     }
     218             : 
     219             :     ~SwAccessibleShapeMap_Impl();
     220             : 
     221           0 :     const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; }
     222             : 
     223             :     SwAccessibleObjShape_Impl *Copy( size_t& rSize,
     224             :         const SwFEShell *pFESh = 0,
     225             :         SwAccessibleObjShape_Impl  **pSelShape = 0 ) const;
     226             : };
     227             : 
     228           0 : SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl()
     229             : {
     230           0 :     uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetControllerBroadcaster() );
     231           0 :     if( xBrd.is() )
     232           0 :         static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose();
     233           0 : }
     234             : 
     235             : SwAccessibleObjShape_Impl
     236           0 :     *SwAccessibleShapeMap_Impl::Copy(
     237             :             size_t& rSize, const SwFEShell *pFESh,
     238             :             SwAccessibleObjShape_Impl **pSelStart ) const
     239             : {
     240           0 :     SwAccessibleObjShape_Impl *pShapes = 0;
     241           0 :     SwAccessibleObjShape_Impl *pSelShape = 0;
     242             : 
     243           0 :     sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
     244           0 :     rSize = size();
     245             : 
     246           0 :     if( rSize > 0 )
     247             :     {
     248             :         pShapes =
     249           0 :             new SwAccessibleObjShape_Impl[rSize];
     250             : 
     251           0 :         const_iterator aIter = begin();
     252           0 :         const_iterator aEndIter = end();
     253             : 
     254           0 :         SwAccessibleObjShape_Impl *pShape = pShapes;
     255           0 :         pSelShape = &(pShapes[rSize]);
     256           0 :         while( aIter != aEndIter )
     257             :         {
     258           0 :             const SdrObject *pObj = (*aIter).first;
     259           0 :             uno::Reference < XAccessible > xAcc( (*aIter).second );
     260           0 :             if( nSelShapes && pFESh->IsObjSelected( *pObj ) )
     261             :             {
     262             :                 // selected objects are inserted from the back
     263           0 :                 --pSelShape;
     264           0 :                 pSelShape->first = pObj;
     265           0 :                 pSelShape->second =
     266             :                     static_cast < ::accessibility::AccessibleShape* >(
     267           0 :                                                     xAcc.get() );
     268           0 :                 --nSelShapes;
     269             :             }
     270             :             else
     271             :             {
     272           0 :                 pShape->first = pObj;
     273           0 :                 pShape->second =
     274             :                     static_cast < ::accessibility::AccessibleShape* >(
     275           0 :                                                     xAcc.get() );
     276           0 :                 ++pShape;
     277             :             }
     278           0 :             ++aIter;
     279           0 :         }
     280             :         OSL_ENSURE( pSelShape == pShape, "copying shapes went wrong!" );
     281             :     }
     282             : 
     283           0 :     if( pSelStart )
     284           0 :         *pSelStart = pSelShape;
     285             : 
     286           0 :     return pShapes;
     287             : }
     288             : 
     289         111 : struct SwAccessibleEvent_Impl
     290             : {
     291             : public:
     292             :     enum EventType { CARET_OR_STATES,
     293             :                      INVALID_CONTENT,
     294             :                      POS_CHANGED,
     295             :                      CHILD_POS_CHANGED,
     296             :                      SHAPE_SELECTION,
     297             :                      DISPOSE,
     298             :                      INVALID_ATTR };
     299             : 
     300             : private:
     301             :     SwRect      maOldBox;                       // the old bounds for CHILD_POS_CHANGED
     302             :                                                 // and POS_CHANGED
     303             :     uno::WeakReference < XAccessible > mxAcc;   // The object that fires the event
     304             :     SwAccessibleChild   maFrmOrObj;             // the child for CHILD_POS_CHANGED and
     305             :                                                 // the same as xAcc for any other
     306             :                                                 // event type
     307             :     EventType   meType;                         // The event type
     308             :     tAccessibleStates mnStates;                 // check states or update caret pos
     309             : 
     310             :     SwAccessibleEvent_Impl& operator==( const SwAccessibleEvent_Impl& );
     311             : 
     312             : public:
     313           0 :     SwAccessibleEvent_Impl( EventType eT,
     314             :                             SwAccessibleContext *pA,
     315             :                             const SwAccessibleChild& rFrmOrObj )
     316             :         : mxAcc( pA ),
     317             :           maFrmOrObj( rFrmOrObj ),
     318             :           meType( eT ),
     319           0 :           mnStates( 0 )
     320           0 :     {}
     321             : 
     322           0 :     SwAccessibleEvent_Impl( EventType eT,
     323             :                             const SwAccessibleChild& rFrmOrObj )
     324             :         : maFrmOrObj( rFrmOrObj ),
     325             :           meType( eT ),
     326           0 :           mnStates( 0 )
     327             :     {
     328             :         OSL_ENSURE( SwAccessibleEvent_Impl::DISPOSE == meType,
     329             :                 "wrong event constructor, DISPOSE only" );
     330           0 :     }
     331             : 
     332           0 :     SwAccessibleEvent_Impl( EventType eT )
     333             :         : meType( eT ),
     334           0 :           mnStates( 0 )
     335             :     {
     336             :         OSL_ENSURE( SwAccessibleEvent_Impl::SHAPE_SELECTION == meType,
     337             :                 "wrong event constructor, SHAPE_SELECTION only" );
     338           0 :     }
     339             : 
     340          37 :     SwAccessibleEvent_Impl( EventType eT,
     341             :                             SwAccessibleContext *pA,
     342             :                             const SwAccessibleChild& rFrmOrObj,
     343             :                             const SwRect& rR )
     344             :         : maOldBox( rR ),
     345             :           mxAcc( pA ),
     346             :           maFrmOrObj( rFrmOrObj ),
     347             :           meType( eT ),
     348          37 :           mnStates( 0 )
     349             :     {
     350             :         OSL_ENSURE( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType ||
     351             :                 SwAccessibleEvent_Impl::POS_CHANGED == meType,
     352             :                 "wrong event constructor, (CHILD_)POS_CHANGED only" );
     353          37 :     }
     354             : 
     355           0 :     SwAccessibleEvent_Impl( EventType eT,
     356             :                             SwAccessibleContext *pA,
     357             :                             const SwAccessibleChild& rFrmOrObj,
     358             :                             const tAccessibleStates _nStates )
     359             :         : mxAcc( pA ),
     360             :           maFrmOrObj( rFrmOrObj ),
     361             :           meType( eT ),
     362           0 :           mnStates( _nStates )
     363             :     {
     364             :         OSL_ENSURE( SwAccessibleEvent_Impl::CARET_OR_STATES == meType,
     365             :                 "wrong event constructor, CARET_OR_STATES only" );
     366           0 :     }
     367             : 
     368             :     // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
     369           0 :     inline void SetType( EventType eT )
     370             :     {
     371           0 :         meType = eT;
     372           0 :     }
     373         185 :     inline EventType GetType() const
     374             :     {
     375         185 :         return meType;
     376             :     }
     377             : 
     378          37 :     inline ::rtl::Reference < SwAccessibleContext > GetContext() const
     379             :     {
     380          37 :         uno::Reference < XAccessible > xTmp( mxAcc );
     381             :         ::rtl::Reference < SwAccessibleContext > xAccImpl(
     382          37 :                             static_cast<SwAccessibleContext*>( xTmp.get() ) );
     383             : 
     384          37 :         return xAccImpl;
     385             :     }
     386             : 
     387          37 :     inline const SwRect& GetOldBox() const
     388             :     {
     389          37 :         return maOldBox;
     390             :     }
     391             :     // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
     392           0 :     inline void SetOldBox( const SwRect& rOldBox )
     393             :     {
     394           0 :         maOldBox = rOldBox;
     395           0 :     }
     396             : 
     397          83 :     inline const SwAccessibleChild& GetFrmOrObj() const
     398             :     {
     399          83 :         return maFrmOrObj;
     400             :     }
     401             : 
     402             :     // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
     403           0 :     inline void SetStates( tAccessibleStates _nStates )
     404             :     {
     405           0 :         mnStates |= _nStates;
     406           0 :     }
     407             : 
     408          37 :     inline bool IsUpdateCursorPos() const
     409             :     {
     410          37 :         return (mnStates & ACC_STATE_CARET) != 0;
     411             :     }
     412          37 :     inline bool IsInvalidateStates() const
     413             :     {
     414          37 :         return (mnStates & ACC_STATE_MASK) != 0;
     415             :     }
     416          37 :     inline bool IsInvalidateRelation() const
     417             :     {
     418          37 :         return (mnStates & ACC_STATE_RELATION_MASK) != 0;
     419             :     }
     420          37 :     inline bool IsInvalidateTextSelection() const
     421             :     {
     422          37 :         return ( mnStates & ACC_STATE_TEXT_SELECTION_CHANGED ) != 0;
     423             :     }
     424             : 
     425          37 :     inline bool IsInvalidateTextAttrs() const
     426             :     {
     427          37 :         return ( mnStates & ACC_STATE_TEXT_ATTRIBUTE_CHANGED ) != 0;
     428             :     }
     429             : 
     430           0 :     inline tAccessibleStates GetStates() const
     431             :     {
     432           0 :         return mnStates & ACC_STATE_MASK;
     433             :     }
     434             : 
     435           0 :     inline tAccessibleStates GetAllStates() const
     436             :     {
     437           0 :         return mnStates;
     438             :     }
     439             : 
     440             : };
     441             : 
     442             : typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl;
     443             : 
     444          15 : class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl
     445             : {
     446             :     bool mbFiring;
     447             : 
     448             : public:
     449             : 
     450          15 :     SwAccessibleEventList_Impl()
     451          15 :         : mbFiring( false )
     452          15 :     {}
     453             : 
     454          15 :     inline void SetFiring()
     455             :     {
     456          15 :         mbFiring = true;
     457          15 :     }
     458          37 :     inline bool IsFiring() const
     459             :     {
     460          37 :         return mbFiring;
     461             :     }
     462             : };
     463             : 
     464             : // The shape list is filled if an accessible shape is destroyed. It
     465             : // simply keeps a reference to the accessible shape's XShape. These
     466             : // references are destroyed within the EndAction when firing events.
     467             : // There are two reason for this. First of all, a new accessible shape
     468             : // for the XShape might be created soon. It's then cheaper if the XShape
     469             : // still exists. The other reason are situations where an accessible shape
     470             : // is destroyed within an SwFrmFmt::Modify. In this case, destroying
     471             : // the XShape at the same time (indirectly by destroying the accessible
     472             : // shape) leads to an assert, because a client of the Modify is destroyed
     473             : // within a Modify call.
     474             : 
     475             : typedef ::std::list < uno::Reference < drawing::XShape > > _SwShapeList_Impl;
     476             : 
     477           0 : class SwShapeList_Impl: public _SwShapeList_Impl
     478             : {
     479             : public:
     480             : 
     481           0 :     SwShapeList_Impl() {}
     482             : };
     483             : 
     484             : struct SwAccessibleChildFunc
     485             : {
     486         104 :     bool operator()( const SwAccessibleChild& r1,
     487             :                          const SwAccessibleChild& r2 ) const
     488             :     {
     489         104 :         const void *p1 = r1.GetSwFrm()
     490             :                          ? static_cast < const void * >( r1.GetSwFrm())
     491           0 :                          : ( r1.GetDrawObject()
     492             :                              ? static_cast < const void * >( r1.GetDrawObject() )
     493         104 :                              : static_cast < const void * >( r1.GetWindow() ) );
     494         104 :         const void *p2 = r2.GetSwFrm()
     495             :                          ? static_cast < const void * >( r2.GetSwFrm())
     496           0 :                          : ( r2.GetDrawObject()
     497             :                              ? static_cast < const void * >( r2.GetDrawObject() )
     498         104 :                              : static_cast < const void * >( r2.GetWindow() ) );
     499         104 :         return p1 < p2;
     500             :     }
     501             : };
     502             : typedef ::std::map < SwAccessibleChild, SwAccessibleEventList_Impl::iterator,
     503             :                      SwAccessibleChildFunc > _SwAccessibleEventMap_Impl;
     504             : 
     505          30 : class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl
     506             : {
     507             : };
     508             : 
     509             : struct SwAccessibleParaSelection
     510             : {
     511             :     xub_StrLen nStartOfSelection;
     512             :     xub_StrLen nEndOfSelection;
     513             : 
     514           0 :     SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection,
     515             :                                const xub_StrLen _nEndOfSelection )
     516             :         : nStartOfSelection( _nStartOfSelection ),
     517           0 :           nEndOfSelection( _nEndOfSelection )
     518           0 :     {}
     519             : };
     520             : 
     521             : struct SwXAccWeakRefComp
     522             : {
     523           0 :     bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1,
     524             :                          const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const
     525             :     {
     526           0 :         return _rXAccWeakRef1.get() < _rXAccWeakRef2.get();
     527             :     }
     528             : };
     529             : 
     530             : typedef ::std::map< uno::WeakReference < XAccessible >,
     531             :                     SwAccessibleParaSelection,
     532             :                     SwXAccWeakRefComp > _SwAccessibleSelectedParas_Impl;
     533             : 
     534           0 : class SwAccessibleSelectedParas_Impl: public _SwAccessibleSelectedParas_Impl
     535             : {};
     536             : 
     537             : // helper class that stores preview data
     538             : class SwAccPreviewData
     539             : {
     540             :     typedef std::vector<Rectangle> Rectangles;
     541             :     Rectangles maPreviewRects;
     542             :     Rectangles maLogicRects;
     543             : 
     544             :     SwRect maVisArea;
     545             :     Fraction maScale;
     546             : 
     547             :     const SwPageFrm *mpSelPage;
     548             : 
     549             :     /** adjust logic page retangle to its visible part
     550             : 
     551             :         @param _iorLogicPgSwRect
     552             :         input/output parameter - reference to the logic page rectangle, which
     553             :         has to be adjusted.
     554             : 
     555             :         @param _rPrevwPgSwRect
     556             :         input parameter - constant reference to the corresponding preview page
     557             :         rectangle; needed to determine the visible part of the logic page rectangle.
     558             : 
     559             :         @param _rPrevwWinSize
     560             :         input paramter - constant reference to the preview window size in TWIP;
     561             :         needed to determine the visible part of the logic page rectangle
     562             :     */
     563             :     void AdjustLogicPgRectToVisibleArea( SwRect&         _iorLogicPgSwRect,
     564             :                                          const SwRect&   _rPrevwPgSwRect,
     565             :                                          const Size&     _rPrevwWinSize );
     566             : 
     567             : public:
     568             :     SwAccPreviewData();
     569             :     ~SwAccPreviewData();
     570             : 
     571             :     void Update( const SwAccessibleMap& rAccMap,
     572             :                  const std::vector<PrevwPage*>& _rPrevwPages,
     573             :                  const Fraction&  _rScale,
     574             :                  const SwPageFrm* _pSelectedPageFrm,
     575             :                  const Size&      _rPrevwWinSize );
     576             : 
     577             :     void InvalidateSelection( const SwPageFrm* _pSelectedPageFrm );
     578             : 
     579             :     const SwRect& GetVisArea() const;
     580             : 
     581             :     MapMode GetMapModeForPreview( ) const;
     582             : 
     583             :     /** Adjust the MapMode so that the preview page appears at the
     584             :      * proper position. rPoint identifies the page for which the
     585             :      * MapMode should be adjusted. If bFromPreview is true, rPoint is
     586             :      * a preview coordinate; else it's a document coordinate. */
     587             :     void AdjustMapMode( MapMode& rMapMode,
     588             :                         const Point& rPoint ) const;
     589             : 
     590           0 :     inline const SwPageFrm *GetSelPage() const { return mpSelPage; }
     591             : 
     592             :     void DisposePage(const SwPageFrm *pPageFrm );
     593             : };
     594             : 
     595           0 : SwAccPreviewData::SwAccPreviewData() :
     596           0 :     mpSelPage( 0 )
     597             : {
     598           0 : }
     599             : 
     600           0 : SwAccPreviewData::~SwAccPreviewData()
     601             : {
     602           0 : }
     603             : 
     604           0 : void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap,
     605             :                                const std::vector<PrevwPage*>& _rPrevwPages,
     606             :                                const Fraction&  _rScale,
     607             :                                const SwPageFrm* _pSelectedPageFrm,
     608             :                                const Size&      _rPrevwWinSize )
     609             : {
     610             :     // store preview scaling, maximal preview page size and selected page
     611           0 :     maScale = _rScale;
     612           0 :     mpSelPage = _pSelectedPageFrm;
     613             : 
     614             :     // prepare loop on preview pages
     615           0 :     maPreviewRects.clear();
     616           0 :     maLogicRects.clear();
     617           0 :     SwAccessibleChild aPage;
     618           0 :     maVisArea.Clear();
     619             : 
     620             :     // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and
     621             :     // <maVisArea>
     622           0 :     for ( std::vector<PrevwPage*>::const_iterator aPageIter = _rPrevwPages.begin();
     623           0 :           aPageIter != _rPrevwPages.end();
     624             :           ++aPageIter )
     625             :     {
     626           0 :         aPage = (*aPageIter)->pPage;
     627             : 
     628             :         // add preview page rectangle to <maPreviewRects>
     629           0 :         Rectangle aPrevwPgRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize );
     630           0 :         maPreviewRects.push_back( aPrevwPgRect );
     631             : 
     632             :         // add logic page rectangle to <maLogicRects>
     633           0 :         SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) );
     634           0 :         Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() );
     635           0 :         maLogicRects.push_back( aLogicPgRect );
     636             :         // union visible area with visible part of logic page rectangle
     637           0 :         if ( (*aPageIter)->bVisible )
     638             :         {
     639           0 :             if ( !(*aPageIter)->pPage->IsEmptyPage() )
     640             :             {
     641             :                 AdjustLogicPgRectToVisibleArea( aLogicPgSwRect,
     642             :                                                 SwRect( aPrevwPgRect ),
     643           0 :                                                 _rPrevwWinSize );
     644             :             }
     645           0 :             if ( maVisArea.IsEmpty() )
     646           0 :                 maVisArea = aLogicPgSwRect;
     647             :             else
     648           0 :                 maVisArea.Union( aLogicPgSwRect );
     649             :         }
     650             :     }
     651           0 : }
     652             : 
     653           0 : void SwAccPreviewData::InvalidateSelection( const SwPageFrm* _pSelectedPageFrm )
     654             : {
     655           0 :     mpSelPage = _pSelectedPageFrm;
     656             :     OSL_ENSURE( mpSelPage, "selected page not found" );
     657           0 : }
     658             : 
     659             : struct ContainsPredicate
     660             : {
     661             :     const Point& mrPoint;
     662           0 :     ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {}
     663           0 :     bool operator() ( const Rectangle& rRect ) const
     664             :     {
     665           0 :         return rRect.IsInside( mrPoint ) ? true : false;
     666             :     }
     667             : };
     668             : 
     669           0 : const SwRect& SwAccPreviewData::GetVisArea() const
     670             : {
     671           0 :     return maVisArea;
     672             : }
     673             : 
     674           0 : void SwAccPreviewData::AdjustMapMode( MapMode& rMapMode,
     675             :                                       const Point& rPoint ) const
     676             : {
     677             :     // adjust scale
     678           0 :     rMapMode.SetScaleX( maScale );
     679           0 :     rMapMode.SetScaleY( maScale );
     680             : 
     681             :     // find proper rectangle
     682           0 :     Rectangles::const_iterator aBegin = maLogicRects.begin();
     683           0 :     Rectangles::const_iterator aEnd = maLogicRects.end();
     684             :     Rectangles::const_iterator aFound = ::std::find_if( aBegin, aEnd,
     685           0 :                                                  ContainsPredicate( rPoint ) );
     686             : 
     687           0 :     if( aFound != aEnd )
     688             :     {
     689             :         // found! set new origin
     690           0 :         Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft();
     691           0 :         aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft();
     692           0 :         rMapMode.SetOrigin( aPoint );
     693             :     }
     694             :     // else: don't adjust MapMode
     695           0 : }
     696             : 
     697           0 : void SwAccPreviewData::DisposePage(const SwPageFrm *pPageFrm )
     698             : {
     699           0 :     if( mpSelPage == pPageFrm )
     700           0 :         mpSelPage = 0;
     701           0 : }
     702             : 
     703             : // adjust logic page retangle to its visible part
     704           0 : void SwAccPreviewData::AdjustLogicPgRectToVisibleArea(
     705             :                             SwRect&         _iorLogicPgSwRect,
     706             :                             const SwRect&   _rPrevwPgSwRect,
     707             :                             const Size&     _rPrevwWinSize )
     708             : {
     709             :     // determine preview window rectangle
     710           0 :     const SwRect aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize );
     711             :     // calculate visible preview page rectangle
     712           0 :     SwRect aVisPrevwPgSwRect( _rPrevwPgSwRect );
     713           0 :     aVisPrevwPgSwRect.Intersection( aPrevwWinSwRect );
     714             :     // adjust logic page rectangle
     715             :     SwTwips nTmpDiff;
     716             :     // left
     717           0 :     nTmpDiff = aVisPrevwPgSwRect.Left() - _rPrevwPgSwRect.Left();
     718           0 :     if ( nTmpDiff > 0 )
     719           0 :         _iorLogicPgSwRect.Left( _iorLogicPgSwRect.Left() + nTmpDiff );
     720             :     // top
     721           0 :     nTmpDiff = aVisPrevwPgSwRect.Top() - _rPrevwPgSwRect.Top();
     722           0 :     if ( nTmpDiff > 0 )
     723           0 :         _iorLogicPgSwRect.Top( _iorLogicPgSwRect.Top() + nTmpDiff );
     724             :     // right
     725           0 :     nTmpDiff = _rPrevwPgSwRect.Right() - aVisPrevwPgSwRect.Right();
     726           0 :     if ( nTmpDiff > 0 )
     727           0 :         _iorLogicPgSwRect.Right( _iorLogicPgSwRect.Right() - nTmpDiff );
     728             :     // bottom
     729           0 :     nTmpDiff = _rPrevwPgSwRect.Bottom() - aVisPrevwPgSwRect.Bottom();
     730           0 :     if ( nTmpDiff > 0 )
     731           0 :         _iorLogicPgSwRect.Bottom( _iorLogicPgSwRect.Bottom() - nTmpDiff );
     732           0 : }
     733             : 
     734          15 : static bool AreInSameTable( const uno::Reference< XAccessible >& rAcc,
     735             :                                   const SwFrm *pFrm )
     736             : {
     737          15 :     bool bRet = false;
     738             : 
     739          15 :     if( pFrm && pFrm->IsCellFrm() && rAcc.is() )
     740             :     {
     741             :         // Is it in the same table? We check that
     742             :         // by comparing the last table frame in the
     743             :         // follow chain, because that's cheaper than
     744             :         // searching the first one.
     745             :         SwAccessibleContext *pAccImpl =
     746           1 :             static_cast< SwAccessibleContext *>( rAcc.get() );
     747           1 :         if( pAccImpl->GetFrm()->IsCellFrm() )
     748             :         {
     749           1 :             const SwTabFrm *pTabFrm1 = pAccImpl->GetFrm()->FindTabFrm();
     750           2 :             while( pTabFrm1->GetFollow() )
     751           0 :                    pTabFrm1 = pTabFrm1->GetFollow();
     752             : 
     753           1 :             const SwTabFrm *pTabFrm2 = pFrm->FindTabFrm();
     754           2 :             while( pTabFrm2->GetFollow() )
     755           0 :                    pTabFrm2 = pTabFrm2->GetFollow();
     756             : 
     757           1 :             bRet = (pTabFrm1 == pTabFrm2);
     758             :         }
     759             :     }
     760             : 
     761          15 :     return bRet;
     762             : }
     763             : 
     764          37 : void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent )
     765             : {
     766          37 :     ::rtl::Reference < SwAccessibleContext > xAccImpl( rEvent.GetContext() );
     767          37 :     if( SwAccessibleEvent_Impl::SHAPE_SELECTION == rEvent.GetType() )
     768             :     {
     769           0 :         DoInvalidateShapeSelection();
     770             :     }
     771          37 :     else if( xAccImpl.is() && xAccImpl->GetFrm() )
     772             :     {
     773          74 :         if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE &&
     774          37 :              rEvent.IsInvalidateTextAttrs() )
     775             :         {
     776           0 :             xAccImpl->InvalidateAttr();
     777             :         }
     778          37 :         switch( rEvent.GetType() )
     779             :         {
     780             :         case SwAccessibleEvent_Impl::INVALID_CONTENT:
     781           0 :             xAccImpl->InvalidateContent();
     782           0 :             break;
     783             :         case SwAccessibleEvent_Impl::POS_CHANGED:
     784          28 :             xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() );
     785          28 :             break;
     786             :         case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
     787          18 :             xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrmOrObj(),
     788          18 :                                        rEvent.GetOldBox() );
     789           9 :             break;
     790             :         case SwAccessibleEvent_Impl::DISPOSE:
     791             :             OSL_ENSURE( xAccImpl.is(),
     792             :                     "dispose event has been stored" );
     793           0 :             break;
     794             :         case SwAccessibleEvent_Impl::INVALID_ATTR:
     795             :             // nothing to do here - handled above
     796           0 :             break;
     797             :         default:
     798           0 :             break;
     799             :         }
     800          37 :         if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
     801             :         {
     802          37 :             if( rEvent.IsUpdateCursorPos() )
     803           0 :                 xAccImpl->InvalidateCursorPos();
     804          37 :             if( rEvent.IsInvalidateStates() )
     805           0 :                 xAccImpl->InvalidateStates( rEvent.GetStates() );
     806          37 :             if( rEvent.IsInvalidateRelation() )
     807             :             {
     808             :                 // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and
     809             :                 // CONTENT_FLOWS_TO_RELATION_CHANGED are possible
     810           0 :                 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_FROM )
     811             :                 {
     812             :                     xAccImpl->InvalidateRelation(
     813           0 :                         AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED );
     814             :                 }
     815           0 :                 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_TO )
     816             :                 {
     817             :                     xAccImpl->InvalidateRelation(
     818           0 :                         AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
     819             :                 }
     820             :             }
     821             : 
     822          37 :             if ( rEvent.IsInvalidateTextSelection() )
     823             :             {
     824           0 :                 xAccImpl->InvalidateTextSelection();
     825             :             }
     826             :         }
     827          37 :     }
     828          37 : }
     829             : 
     830          37 : void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent )
     831             : {
     832          37 :     osl::MutexGuard aGuard( maEventMutex );
     833             : 
     834          37 :     if( !mpEvents )
     835          15 :         mpEvents = new SwAccessibleEventList_Impl;
     836          37 :     if( !mpEventMap )
     837          15 :         mpEventMap = new SwAccessibleEventMap_Impl;
     838             : 
     839          37 :     if( mpEvents->IsFiring() )
     840             :     {
     841             :         // While events are fired new ones are generated. They have to be fired
     842             :         // now. This does not work for DISPOSE events!
     843             :         OSL_ENSURE( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
     844             :                 "dispose event while firing events" );
     845           0 :         FireEvent( rEvent );
     846             :     }
     847             :     else
     848             :     {
     849             : 
     850             :         SwAccessibleEventMap_Impl::iterator aIter =
     851          37 :                                         mpEventMap->find( rEvent.GetFrmOrObj() );
     852          37 :         if( aIter != mpEventMap->end() )
     853             :         {
     854           0 :             SwAccessibleEvent_Impl aEvent( *(*aIter).second );
     855             :             OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
     856             :                     "dispose events should not be stored" );
     857           0 :             bool bAppendEvent = true;
     858           0 :             switch( rEvent.GetType() )
     859             :             {
     860             :             case SwAccessibleEvent_Impl::CARET_OR_STATES:
     861             :                 // A CARET_OR_STATES event is added to any other
     862             :                 // event only. It is broadcasted after any other event, so the
     863             :                 // event should be put to the back.
     864             :                 OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
     865             :                         "invalid event combination" );
     866           0 :                 aEvent.SetStates( rEvent.GetAllStates() );
     867           0 :                 break;
     868             :             case SwAccessibleEvent_Impl::INVALID_CONTENT:
     869             :                 // An INVALID_CONTENT event overwrites a CARET_OR_STATES
     870             :                 // event (but keeps its flags) and it is contained in a
     871             :                 // POS_CHANGED event.
     872             :                 // Therefore, the event's type has to be adapted and the event
     873             :                 // has to be put at the end.
     874             :                 //
     875             :                 // fdo#56031 An INVALID_CONTENT event overwrites a INVALID_ATTR
     876             :                 // event and overwrites its flags
     877             :                 OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
     878             :                         "invalid event combination" );
     879           0 :                 if( aEvent.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES )
     880           0 :                     aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT );
     881           0 :                 else if ( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR )
     882             :                 {
     883           0 :                     aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT );
     884           0 :                     aEvent.SetStates( rEvent.GetAllStates() );
     885             :                 }
     886             : 
     887           0 :                 break;
     888             :             case SwAccessibleEvent_Impl::POS_CHANGED:
     889             :                 // A pos changed event overwrites CARET_STATES (keeping its
     890             :                 // flags) as well as INVALID_CONTENT. The old box position
     891             :                 // has to be stored however if the old event is not a
     892             :                 // POS_CHANGED itself.
     893             :                 OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
     894             :                         "invalid event combination" );
     895           0 :                 if( aEvent.GetType() != SwAccessibleEvent_Impl::POS_CHANGED )
     896           0 :                     aEvent.SetOldBox( rEvent.GetOldBox() );
     897           0 :                 aEvent.SetType( SwAccessibleEvent_Impl::POS_CHANGED );
     898           0 :                 break;
     899             :             case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
     900             :                 // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED
     901             :                 // events. The only action that needs to be done again is
     902             :                 // to put the old event to the back. The new one cannot be used,
     903             :                 // because we are interested in the old frame bounds.
     904             :                 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
     905             :                         "invalid event combination" );
     906           0 :                 break;
     907             :             case SwAccessibleEvent_Impl::SHAPE_SELECTION:
     908             :                 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION,
     909             :                         "invalid event combination" );
     910           0 :                 break;
     911             :             case SwAccessibleEvent_Impl::DISPOSE:
     912             :                 // DISPOSE events overwrite all others. They are not stored
     913             :                 // but executed immediately to avoid broadcasting of
     914             :                 // defunctional objects. So what needs to be done here is to
     915             :                 // remove all events for the frame in question.
     916           0 :                 bAppendEvent = false;
     917           0 :                 break;
     918             :             case SwAccessibleEvent_Impl::INVALID_ATTR:
     919             :                 OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR,
     920             :                         "invalid event combination" );
     921           0 :                 break;
     922             :             }
     923           0 :             if( bAppendEvent )
     924             :             {
     925           0 :                 mpEvents->erase( (*aIter).second );
     926           0 :                 (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent );
     927             :             }
     928             :             else
     929             :             {
     930           0 :                 mpEvents->erase( (*aIter).second );
     931           0 :                 mpEventMap->erase( aIter );
     932           0 :             }
     933             :         }
     934          37 :         else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
     935             :         {
     936          37 :             SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrmOrObj(),
     937          74 :                     mpEvents->insert( mpEvents->end(), rEvent ) );
     938          37 :             mpEventMap->insert( aEntry );
     939             :         }
     940          37 :     }
     941          37 : }
     942             : 
     943          68 : void SwAccessibleMap::InvalidateCursorPosition(
     944             :         const uno::Reference< XAccessible >& rAcc )
     945             : {
     946             :     SwAccessibleContext *pAccImpl =
     947          68 :         static_cast< SwAccessibleContext *>( rAcc.get() );
     948             :     OSL_ENSURE( pAccImpl, "no caret context" );
     949             :     OSL_ENSURE( pAccImpl->GetFrm(), "caret context is disposed" );
     950          68 :     if( GetShell()->ActionPend() )
     951             :     {
     952             :         SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
     953             :                                        pAccImpl,
     954             :                                        SwAccessibleChild(pAccImpl->GetFrm()),
     955           0 :                                        ACC_STATE_CARET );
     956           0 :         AppendEvent( aEvent );
     957             :     }
     958             :     else
     959             :     {
     960          68 :         FireEvents();
     961             :         // While firing events the current frame might have
     962             :         // been disposed because it moved out of the vis area.
     963             :         // Setting the cursor for such frames is useless and even
     964             :         // causes asserts.
     965          68 :         if( pAccImpl->GetFrm() )
     966          68 :             pAccImpl->InvalidateCursorPos();
     967             :     }
     968          68 : }
     969             : 
     970           0 : void SwAccessibleMap::InvalidateShapeSelection()
     971             : {
     972           0 :     if( GetShell()->ActionPend() )
     973             :     {
     974             :         SwAccessibleEvent_Impl aEvent(
     975           0 :             SwAccessibleEvent_Impl::SHAPE_SELECTION );
     976           0 :         AppendEvent( aEvent );
     977             :     }
     978             :     else
     979             :     {
     980           0 :         FireEvents();
     981           0 :         DoInvalidateShapeSelection();
     982             :     }
     983           0 : }
     984             : 
     985           0 : void SwAccessibleMap::DoInvalidateShapeSelection()
     986             : {
     987           0 :     SwAccessibleObjShape_Impl *pShapes = 0;
     988           0 :     SwAccessibleObjShape_Impl *pSelShape = 0;
     989           0 :     size_t nShapes = 0;
     990             : 
     991           0 :     const ViewShell *pVSh = GetShell();
     992           0 :     const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
     993           0 :                             static_cast< const SwFEShell * >( pVSh ) : 0;
     994           0 :     sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
     995             : 
     996             :     {
     997           0 :         osl::MutexGuard aGuard( maMutex );
     998           0 :         if( mpShapeMap )
     999           0 :             pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
    1000             :     }
    1001             : 
    1002           0 :     if( pShapes )
    1003             :     {
    1004           0 :         ::std::list< const SwFrm * > aParents;
    1005           0 :         Window *pWin = GetShell()->GetWin();
    1006           0 :         bool bFocused = pWin && pWin->HasFocus();
    1007           0 :         SwAccessibleObjShape_Impl *pShape = pShapes;
    1008           0 :         while( nShapes )
    1009             :         {
    1010           0 :             if( pShape->second.is() )
    1011             :             {
    1012             :                 sal_Bool bChanged;
    1013           0 :                 if( pShape >= pSelShape )
    1014             :                 {
    1015             :                     bChanged =
    1016           0 :                         pShape->second->SetState( AccessibleStateType::SELECTED );
    1017           0 :                     if( bFocused && 1 == nSelShapes )
    1018           0 :                         pShape->second->SetState( AccessibleStateType::FOCUSED );
    1019             :                     else
    1020           0 :                         pShape->second->ResetState( AccessibleStateType::FOCUSED );
    1021             :                 }
    1022             :                 else
    1023             :                 {
    1024             :                     bChanged =
    1025           0 :                         pShape->second->ResetState( AccessibleStateType::SELECTED );
    1026           0 :                     pShape->second->ResetState( AccessibleStateType::FOCUSED );
    1027             :                 }
    1028           0 :                 if( bChanged )
    1029             :                 {
    1030             :                     const SwFrm* pParent = SwAccessibleFrame::GetParent(
    1031             :                                                     SwAccessibleChild( pShape->first ),
    1032           0 :                                                     GetShell()->IsPreView() );
    1033           0 :                     aParents.push_back( pParent );
    1034             :                 }
    1035             :             }
    1036             : 
    1037           0 :             --nShapes;
    1038           0 :             ++pShape;
    1039             :         }
    1040           0 :         if( aParents.size() > 0 )
    1041             :         {
    1042           0 :             ::std::list< const SwFrm * >::const_iterator aIter = aParents.begin();
    1043           0 :             ::std::list< const SwFrm * >::const_iterator aEndIter = aParents.end();
    1044           0 :             while( aIter != aEndIter )
    1045             :             {
    1046           0 :                 ::rtl::Reference< SwAccessibleContext > xParentAccImpl;
    1047             :                 {
    1048           0 :                     osl::MutexGuard aGuard( maMutex );
    1049           0 :                     if(  mpFrmMap )
    1050             :                     {
    1051             :                         SwAccessibleContextMap_Impl::const_iterator aMapIter =
    1052           0 :                             mpFrmMap->find( *aIter );
    1053           0 :                         if( aMapIter != mpFrmMap->end() )
    1054             :                         {
    1055           0 :                             uno::Reference < XAccessible > xAcc( (*aMapIter).second );
    1056           0 :                             xParentAccImpl =
    1057           0 :                                 static_cast< SwAccessibleContext *>( xAcc.get() );
    1058             :                         }
    1059           0 :                     }
    1060             :                 }
    1061           0 :                 if( xParentAccImpl.is() )
    1062             :                 {
    1063           0 :                     AccessibleEventObject aEvent;
    1064           0 :                     aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
    1065           0 :                     xParentAccImpl->FireAccessibleEvent( aEvent );
    1066             :                 }
    1067             : 
    1068           0 :                 ++aIter;
    1069           0 :             }
    1070             :         }
    1071             : 
    1072           0 :         delete[] pShapes;
    1073             :     }
    1074           0 : }
    1075             : 
    1076           0 : void SwAccessibleMap::DoInvalidateShapeFocus()
    1077             : {
    1078           0 :     const ViewShell *pVSh = GetShell();
    1079           0 :     const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
    1080           0 :                             static_cast< const SwFEShell * >( pVSh ) : 0;
    1081           0 :     sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
    1082             : 
    1083           0 :     if( nSelShapes != 1 )
    1084           0 :         return;
    1085             : 
    1086           0 :     SwAccessibleObjShape_Impl *pShapes = 0;
    1087           0 :     SwAccessibleObjShape_Impl *pSelShape = 0;
    1088           0 :     size_t nShapes = 0;
    1089             : 
    1090             :     {
    1091           0 :         osl::MutexGuard aGuard( maMutex );
    1092           0 :         if( mpShapeMap )
    1093           0 :             pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
    1094             :     }
    1095             : 
    1096           0 :     if( pShapes )
    1097             :     {
    1098           0 :         Window *pWin = GetShell()->GetWin();
    1099           0 :         bool bFocused = pWin && pWin->HasFocus();
    1100           0 :         SwAccessibleObjShape_Impl  *pShape = pShapes;
    1101           0 :         while( nShapes )
    1102             :         {
    1103           0 :             if( pShape->second.is() )
    1104             :             {
    1105           0 :                 if( bFocused && pShape >= pSelShape )
    1106           0 :                     pShape->second->SetState( AccessibleStateType::FOCUSED );
    1107             :                 else
    1108           0 :                     pShape->second->ResetState( AccessibleStateType::FOCUSED );
    1109             :             }
    1110             : 
    1111           0 :             --nShapes;
    1112           0 :             ++pShape;
    1113             :         }
    1114             : 
    1115           0 :         delete[] pShapes;
    1116             :     }
    1117             : }
    1118             : 
    1119          12 : SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) :
    1120             :     mpFrmMap( 0  ),
    1121             :     mpShapeMap( 0  ),
    1122             :     mpShapes( 0  ),
    1123             :     mpEvents( 0  ),
    1124             :     mpEventMap( 0  ),
    1125             :     mpSelectedParas( 0 ),
    1126             :     mpVSh( pSh ),
    1127             :         mpPreview( 0 ),
    1128             :     mnPara( 1 ),
    1129             :     mnFootnote( 1 ),
    1130             :     mnEndnote( 1 ),
    1131          12 :     mbShapeSelected( false )
    1132             : {
    1133          12 :     pSh->GetLayout()->AddAccessibleShell();
    1134          12 : }
    1135             : 
    1136          36 : SwAccessibleMap::~SwAccessibleMap()
    1137             : {
    1138          12 :     uno::Reference < XAccessible > xAcc;
    1139             :     {
    1140          12 :         osl::MutexGuard aGuard( maMutex );
    1141          12 :         if( mpFrmMap )
    1142             :         {
    1143          12 :             const SwRootFrm *pRootFrm = GetShell()->GetLayout();
    1144          12 :             SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
    1145          12 :             if( aIter != mpFrmMap->end() )
    1146          12 :                 xAcc = (*aIter).second;
    1147          12 :             if( !xAcc.is() )
    1148           0 :                 xAcc = new SwAccessibleDocument( this );
    1149          12 :         }
    1150             :     }
    1151             : 
    1152             :     SwAccessibleDocument *pAcc =
    1153          12 :         static_cast< SwAccessibleDocument * >( xAcc.get() );
    1154          12 :     pAcc->Dispose( sal_True );
    1155             : 
    1156             :     {
    1157          12 :         osl::MutexGuard aGuard( maMutex );
    1158             : #if OSL_DEBUG_LEVEL > 0
    1159             :         OSL_ENSURE( !mpFrmMap || mpFrmMap->empty(),
    1160             :                 "Frame map should be empty after disposing the root frame" );
    1161             :         if( mpFrmMap )
    1162             :         {
    1163             :             SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
    1164             :             while( aIter != mpFrmMap->end() )
    1165             :             {
    1166             :                 uno::Reference < XAccessible > xTmp = (*aIter).second;
    1167             :                 if( xTmp.is() )
    1168             :                 {
    1169             :                     SwAccessibleContext *pTmp =
    1170             :                         static_cast< SwAccessibleContext * >( xTmp.get() );
    1171             :                     (void) pTmp;
    1172             :                 }
    1173             :                 ++aIter;
    1174             :             }
    1175             :         }
    1176             :         OSL_ENSURE( !mpShapeMap || mpShapeMap->empty(),
    1177             :                 "Object map should be empty after disposing the root frame" );
    1178             :         if( mpShapeMap )
    1179             :         {
    1180             :             SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin();
    1181             :             while( aIter != mpShapeMap->end() )
    1182             :             {
    1183             :                 uno::Reference < XAccessible > xTmp = (*aIter).second;
    1184             :                 if( xTmp.is() )
    1185             :                 {
    1186             :                     ::accessibility::AccessibleShape *pTmp =
    1187             :                         static_cast< ::accessibility::AccessibleShape* >( xTmp.get() );
    1188             :                     (void) pTmp;
    1189             :                 }
    1190             :                 ++aIter;
    1191             :             }
    1192             :         }
    1193             : #endif
    1194          12 :         delete mpFrmMap;
    1195          12 :         mpFrmMap = 0;
    1196          12 :         delete mpShapeMap;
    1197          12 :         mpShapeMap = 0;
    1198          12 :         delete mpShapes;
    1199          12 :         mpShapes = 0;
    1200          12 :         delete mpSelectedParas;
    1201          12 :         mpSelectedParas = 0;
    1202             :     }
    1203             : 
    1204          12 :     delete mpPreview;
    1205          12 :     mpPreview = NULL;
    1206             : 
    1207             :     {
    1208          12 :         osl::MutexGuard aGuard( maEventMutex );
    1209             : #if OSL_DEBUG_LEVEL > 0
    1210             :         OSL_ENSURE( !(mpEvents || mpEventMap), "pending events" );
    1211             :         if( mpEvents )
    1212             :         {
    1213             :             SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
    1214             :             while( aIter != mpEvents->end() )
    1215             :             {
    1216             :                 ++aIter;
    1217             :             }
    1218             :         }
    1219             :         if( mpEventMap )
    1220             :         {
    1221             :             SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin();
    1222             :             while( aIter != mpEventMap->end() )
    1223             :             {
    1224             :                 ++aIter;
    1225             :             }
    1226             :         }
    1227             : #endif
    1228          12 :         delete mpEventMap;
    1229          12 :         mpEventMap = 0;
    1230          12 :         delete mpEvents;
    1231          12 :         mpEvents = 0;
    1232             :     }
    1233          12 :     mpVSh->GetLayout()->RemoveAccessibleShell();
    1234          24 : }
    1235             : 
    1236          31 : uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView(
    1237             :     bool bPagePreview )
    1238             : {
    1239          31 :     uno::Reference < XAccessible > xAcc;
    1240          31 :     bool bSetVisArea = false;
    1241             : 
    1242             :     {
    1243          31 :         osl::MutexGuard aGuard( maMutex );
    1244             : 
    1245          31 :         if( !mpFrmMap )
    1246             :         {
    1247          12 :             mpFrmMap = new SwAccessibleContextMap_Impl;
    1248             : #if OSL_DEBUG_LEVEL > 0
    1249             :             mpFrmMap->mbLocked = false;
    1250             : #endif
    1251             :         }
    1252             : 
    1253             : #if OSL_DEBUG_LEVEL > 0
    1254             :         OSL_ENSURE( !mpFrmMap->mbLocked, "Map is locked" );
    1255             :         mpFrmMap->mbLocked = true;
    1256             : #endif
    1257             : 
    1258          31 :         const SwRootFrm *pRootFrm = GetShell()->GetLayout();
    1259          31 :         SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
    1260          31 :         if( aIter != mpFrmMap->end() )
    1261          19 :             xAcc = (*aIter).second;
    1262          31 :         if( xAcc.is() )
    1263             :         {
    1264          19 :             bSetVisArea = true; // Set VisArea when map mutex is not locked
    1265             :         }
    1266             :         else
    1267             :         {
    1268          12 :             if( bPagePreview )
    1269           0 :                 xAcc = new SwAccessiblePreview( this );
    1270             :             else
    1271          12 :                 xAcc = new SwAccessibleDocument( this );
    1272             : 
    1273          12 :             if( aIter != mpFrmMap->end() )
    1274             :             {
    1275           0 :                 (*aIter).second = xAcc;
    1276             :             }
    1277             :             else
    1278             :             {
    1279          12 :                 SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc );
    1280          12 :                 mpFrmMap->insert( aEntry );
    1281             :             }
    1282          31 :         }
    1283             : 
    1284             : #if OSL_DEBUG_LEVEL > 0
    1285             :         mpFrmMap->mbLocked = false;
    1286             : #endif
    1287             :     }
    1288             : 
    1289          31 :     if( bSetVisArea )
    1290             :     {
    1291             :         SwAccessibleDocumentBase *pAcc =
    1292          19 :             static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
    1293          19 :         pAcc->SetVisArea();
    1294             :     }
    1295             : 
    1296          31 :     return xAcc;
    1297             : }
    1298             : 
    1299          31 : uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
    1300             : {
    1301          31 :     return _GetDocumentView( false );
    1302             : }
    1303             : 
    1304           0 : uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
    1305             :                                     const std::vector<PrevwPage*>& _rPrevwPages,
    1306             :                                     const Fraction&  _rScale,
    1307             :                                     const SwPageFrm* _pSelectedPageFrm,
    1308             :                                     const Size&      _rPrevwWinSize )
    1309             : {
    1310             :     // create & update preview data object
    1311           0 :     if( mpPreview == NULL )
    1312           0 :         mpPreview = new SwAccPreviewData();
    1313           0 :     mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
    1314             : 
    1315           0 :     uno::Reference<XAccessible> xAcc = _GetDocumentView( true );
    1316           0 :     return xAcc;
    1317             : }
    1318             : 
    1319         329 : uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
    1320             :                                                      sal_Bool bCreate )
    1321             : {
    1322         329 :     uno::Reference < XAccessible > xAcc;
    1323         658 :     uno::Reference < XAccessible > xOldCursorAcc;
    1324         329 :     bool bOldShapeSelected = false;
    1325             : 
    1326             :     {
    1327         329 :         osl::MutexGuard aGuard( maMutex );
    1328             : 
    1329         329 :         if( !mpFrmMap && bCreate )
    1330           0 :             mpFrmMap = new SwAccessibleContextMap_Impl;
    1331         329 :         if( mpFrmMap )
    1332             :         {
    1333         329 :             SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm );
    1334         329 :             if( aIter != mpFrmMap->end() )
    1335         211 :                 xAcc = (*aIter).second;
    1336             : 
    1337         329 :             if( !xAcc.is() && bCreate )
    1338             :             {
    1339          28 :                 SwAccessibleContext *pAcc = 0;
    1340          28 :                 switch( pFrm->GetType() )
    1341             :                 {
    1342             :                 case FRM_TXT:
    1343          17 :                     mnPara++;
    1344          34 :                     pAcc = new SwAccessibleParagraph( *this,
    1345          34 :                                     static_cast< const SwTxtFrm& >( *pFrm ) );
    1346          17 :                     break;
    1347             :                 case FRM_HEADER:
    1348             :                     pAcc = new SwAccessibleHeaderFooter( this,
    1349           0 :                                     static_cast< const SwHeaderFrm *>( pFrm ) );
    1350           0 :                     break;
    1351             :                 case FRM_FOOTER:
    1352             :                     pAcc = new SwAccessibleHeaderFooter( this,
    1353           0 :                                     static_cast< const SwFooterFrm *>( pFrm ) );
    1354           0 :                     break;
    1355             :                 case FRM_FTN:
    1356             :                     {
    1357             :                         const SwFtnFrm *pFtnFrm =
    1358           1 :                             static_cast < const SwFtnFrm * >( pFrm );
    1359             :                         sal_Bool bIsEndnote =
    1360           1 :                             SwAccessibleFootnote::IsEndnote( pFtnFrm );
    1361             :                         pAcc = new SwAccessibleFootnote( this, bIsEndnote,
    1362             :                                     (bIsEndnote ? mnEndnote++ : mnFootnote++),
    1363           1 :                                     pFtnFrm );
    1364             :                     }
    1365           1 :                     break;
    1366             :                 case FRM_FLY:
    1367             :                     {
    1368             :                         const SwFlyFrm *pFlyFrm =
    1369           1 :                             static_cast < const SwFlyFrm * >( pFrm );
    1370           1 :                         switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) )
    1371             :                         {
    1372             :                         case ND_GRFNODE:
    1373           1 :                             pAcc = new SwAccessibleGraphic( this, pFlyFrm );
    1374           1 :                             break;
    1375             :                         case ND_OLENODE:
    1376           0 :                             pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm );
    1377           0 :                             break;
    1378             :                         default:
    1379           0 :                             pAcc = new SwAccessibleTextFrame( this, pFlyFrm );
    1380           0 :                             break;
    1381             :                         }
    1382             :                     }
    1383           1 :                     break;
    1384             :                 case FRM_CELL:
    1385             :                     pAcc = new SwAccessibleCell( this,
    1386           7 :                                     static_cast< const SwCellFrm *>( pFrm ) );
    1387           7 :                     break;
    1388             :                 case FRM_TAB:
    1389             :                     pAcc = new SwAccessibleTable( this,
    1390           2 :                                     static_cast< const SwTabFrm *>( pFrm ) );
    1391           2 :                     break;
    1392             :                 case FRM_PAGE:
    1393             :                     OSL_ENSURE( GetShell()->IsPreView(),
    1394             :                                 "accessible page frames only in PagePreview" );
    1395           0 :                     pAcc = new SwAccessiblePage( this, pFrm );
    1396           0 :                     break;
    1397             :                 }
    1398          28 :                 xAcc = pAcc;
    1399             : 
    1400             :                 OSL_ENSURE( xAcc.is(), "unknown frame type" );
    1401          28 :                 if( xAcc.is() )
    1402             :                 {
    1403          28 :                     if( aIter != mpFrmMap->end() )
    1404             :                     {
    1405           0 :                         (*aIter).second = xAcc;
    1406             :                     }
    1407             :                     else
    1408             :                     {
    1409          28 :                         SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc );
    1410          28 :                         mpFrmMap->insert( aEntry );
    1411             :                     }
    1412             : 
    1413          98 :                     if( pAcc->HasCursor() &&
    1414          70 :                         !AreInSameTable( mxCursorContext, pFrm ) )
    1415             :                     {
    1416             :                         // If the new context has the focus, and if we know
    1417             :                         // another context that had the focus, then the focus
    1418             :                         // just moves from the old context to the new one. We
    1419             :                         // then have to send a focus event and a caret event for
    1420             :                         // the old context. We have to to that now,
    1421             :                         // because after we have left this method, anyone might
    1422             :                         // call getStates for the new context and will get a
    1423             :                         // focused state then. Sending the focus changes event
    1424             :                         // after that seems to be strange. However, we cannot
    1425             :                         // send a focus event for the new context now, because
    1426             :                         // noone except us knows it. In any case, we remember
    1427             :                         // the new context as the one that has the focus
    1428             :                         // currently.
    1429             : 
    1430          14 :                         xOldCursorAcc = mxCursorContext;
    1431          14 :                         mxCursorContext = xAcc;
    1432             : 
    1433          14 :                         bOldShapeSelected = mbShapeSelected;
    1434          14 :                         mbShapeSelected = false;
    1435             :                     }
    1436             :                 }
    1437             :             }
    1438         329 :         }
    1439             :     }
    1440             : 
    1441             :     // Invalidate focus for old object when map is not locked
    1442         329 :     if( xOldCursorAcc.is() )
    1443           0 :         InvalidateCursorPosition( xOldCursorAcc );
    1444         329 :     if( bOldShapeSelected )
    1445           0 :         InvalidateShapeSelection();
    1446             : 
    1447         658 :     return xAcc;
    1448             : }
    1449             : 
    1450         283 : ::rtl::Reference < SwAccessibleContext > SwAccessibleMap::GetContextImpl(
    1451             :             const SwFrm *pFrm,
    1452             :             sal_Bool bCreate )
    1453             : {
    1454         283 :     uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) );
    1455             : 
    1456             :     ::rtl::Reference < SwAccessibleContext > xAccImpl(
    1457         283 :          static_cast< SwAccessibleContext * >( xAcc.get() ) );
    1458             : 
    1459         283 :     return xAccImpl;
    1460             : }
    1461             : 
    1462           0 : uno::Reference< XAccessible> SwAccessibleMap::GetContext(
    1463             :         const SdrObject *pObj,
    1464             :         SwAccessibleContext *pParentImpl,
    1465             :         sal_Bool bCreate )
    1466             : {
    1467           0 :     uno::Reference < XAccessible > xAcc;
    1468           0 :     uno::Reference < XAccessible > xOldCursorAcc;
    1469             : 
    1470             :     {
    1471           0 :         osl::MutexGuard aGuard( maMutex );
    1472             : 
    1473           0 :         if( !mpShapeMap && bCreate )
    1474           0 :             mpShapeMap = new SwAccessibleShapeMap_Impl( this );
    1475           0 :         if( mpShapeMap )
    1476             :         {
    1477             :             SwAccessibleShapeMap_Impl::iterator aIter =
    1478           0 :                    mpShapeMap->find( pObj );
    1479           0 :             if( aIter != mpShapeMap->end() )
    1480           0 :                 xAcc = (*aIter).second;
    1481             : 
    1482           0 :             if( !xAcc.is() && bCreate )
    1483             :             {
    1484           0 :                 ::accessibility::AccessibleShape *pAcc = 0;
    1485             :                 uno::Reference < drawing::XShape > xShape(
    1486           0 :                     const_cast< SdrObject * >( pObj )->getUnoShape(),
    1487           0 :                     uno::UNO_QUERY );
    1488           0 :                 if( xShape.is() )
    1489             :                 {
    1490             :                     ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
    1491           0 :                                 ::accessibility::ShapeTypeHandler::Instance();
    1492           0 :                     uno::Reference < XAccessible > xParent( pParentImpl );
    1493             :                     ::accessibility::AccessibleShapeInfo aShapeInfo(
    1494           0 :                             xShape, xParent, this );
    1495             : 
    1496             :                     pAcc = rShapeTypeHandler.CreateAccessibleObject(
    1497           0 :                                 aShapeInfo, mpShapeMap->GetInfo() );
    1498             :                 }
    1499           0 :                 xAcc = pAcc;
    1500             : 
    1501             :                 OSL_ENSURE( xAcc.is(), "unknown shape type" );
    1502           0 :                 if( xAcc.is() )
    1503             :                 {
    1504           0 :                     pAcc->Init();
    1505           0 :                     if( aIter != mpShapeMap->end() )
    1506             :                     {
    1507           0 :                         (*aIter).second = xAcc;
    1508             :                     }
    1509             :                     else
    1510             :                     {
    1511             :                         SwAccessibleShapeMap_Impl::value_type aEntry( pObj,
    1512           0 :                                                                       xAcc );
    1513           0 :                         mpShapeMap->insert( aEntry );
    1514             :                     }
    1515             :                     // TODO: focus!!!
    1516           0 :                 }
    1517             :             }
    1518           0 :         }
    1519             :     }
    1520             : 
    1521             :     // Invalidate focus for old object when map is not locked
    1522           0 :     if( xOldCursorAcc.is() )
    1523           0 :         InvalidateCursorPosition( xOldCursorAcc );
    1524             : 
    1525           0 :     return xAcc;
    1526             : }
    1527             : 
    1528           0 : ::rtl::Reference < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl(
    1529             :             const SdrObject *pObj,
    1530             :             SwAccessibleContext *pParentImpl,
    1531             :             sal_Bool bCreate )
    1532             : {
    1533           0 :     uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
    1534             : 
    1535             :     ::rtl::Reference < ::accessibility::AccessibleShape > xAccImpl(
    1536           0 :          static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
    1537             : 
    1538           0 :     return xAccImpl;
    1539             : }
    1540             : 
    1541          40 : void SwAccessibleMap::RemoveContext( const SwFrm *pFrm )
    1542             : {
    1543          40 :     osl::MutexGuard aGuard( maMutex );
    1544             : 
    1545          40 :     if( mpFrmMap )
    1546             :     {
    1547             :         SwAccessibleContextMap_Impl::iterator aIter =
    1548          40 :             mpFrmMap->find( pFrm );
    1549          40 :         if( aIter != mpFrmMap->end() )
    1550             :         {
    1551          40 :             mpFrmMap->erase( aIter );
    1552             : 
    1553             :             // Remove reference to old caret object. Though mxCursorContext
    1554             :             // is a weak reference and cleared automatically, clearing it
    1555             :             // directly makes sure to not keep a non-functional object.
    1556          40 :             uno::Reference < XAccessible > xOldAcc( mxCursorContext );
    1557          40 :             if( xOldAcc.is() )
    1558             :             {
    1559             :                 SwAccessibleContext *pOldAccImpl =
    1560          10 :                     static_cast< SwAccessibleContext *>( xOldAcc.get() );
    1561             :                 OSL_ENSURE( pOldAccImpl->GetFrm(), "old caret context is disposed" );
    1562          10 :                 if( pOldAccImpl->GetFrm() == pFrm )
    1563             :                 {
    1564           9 :                     xOldAcc.clear();    // get an empty ref
    1565           9 :                     mxCursorContext = xOldAcc;
    1566             :                 }
    1567             :             }
    1568             : 
    1569          40 :             if( mpFrmMap->empty() )
    1570             :             {
    1571          12 :                 delete mpFrmMap;
    1572          12 :                 mpFrmMap = 0;
    1573          40 :             }
    1574             :         }
    1575          40 :     }
    1576          40 : }
    1577             : 
    1578           0 : void SwAccessibleMap::RemoveContext( const SdrObject *pObj )
    1579             : {
    1580           0 :     osl::MutexGuard aGuard( maMutex );
    1581             : 
    1582           0 :     if( mpShapeMap )
    1583             :     {
    1584             :         SwAccessibleShapeMap_Impl::iterator aIter =
    1585           0 :             mpShapeMap->find( pObj );
    1586           0 :         if( aIter != mpShapeMap->end() )
    1587             :         {
    1588           0 :             mpShapeMap->erase( aIter );
    1589             : 
    1590             :             // The shape selection flag is not cleared, but one might do
    1591             :             // so but has to make sure that the removed context is the one
    1592             :             // that is selected.
    1593             : 
    1594           0 :             if( mpShapeMap->empty() )
    1595             :             {
    1596           0 :                 delete mpShapeMap;
    1597           0 :                 mpShapeMap = 0;
    1598             :             }
    1599             :         }
    1600           0 :     }
    1601           0 : }
    1602             : 
    1603           0 : void SwAccessibleMap::Dispose( const SwFrm *pFrm,
    1604             :                                const SdrObject *pObj,
    1605             :                                Window* pWindow,
    1606             :                                sal_Bool bRecursive )
    1607             : {
    1608           0 :     SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
    1609             : 
    1610             :     // Indeed, the following assert checks the frame's accessible flag,
    1611             :     // because that's the one that is evaluated in the layout. The frame
    1612             :     // might not be accessible anyway. That's the case for cell frames that
    1613             :     // contain further cells.
    1614             :     OSL_ENSURE( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(),
    1615             :             "non accessible frame should be disposed" );
    1616             : 
    1617           0 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    1618             :     {
    1619           0 :         ::rtl::Reference< SwAccessibleContext > xAccImpl;
    1620           0 :         ::rtl::Reference< SwAccessibleContext > xParentAccImpl;
    1621           0 :         ::rtl::Reference< ::accessibility::AccessibleShape > xShapeAccImpl;
    1622             :         // get accessible context for frame
    1623             :         {
    1624           0 :             osl::MutexGuard aGuard( maMutex );
    1625             : 
    1626             :             // First of all look for an accessible context for a frame
    1627           0 :             if( aFrmOrObj.GetSwFrm() && mpFrmMap )
    1628             :             {
    1629             :                 SwAccessibleContextMap_Impl::iterator aIter =
    1630           0 :                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    1631           0 :                 if( aIter != mpFrmMap->end() )
    1632             :                 {
    1633           0 :                     uno::Reference < XAccessible > xAcc( (*aIter).second );
    1634           0 :                     xAccImpl =
    1635           0 :                         static_cast< SwAccessibleContext *>( xAcc.get() );
    1636             :                 }
    1637             :             }
    1638           0 :             if( !xAccImpl.is() && mpFrmMap )
    1639             :             {
    1640             :                 // If there is none, look if the parent is accessible.
    1641             :                 const SwFrm *pParent =
    1642             :                         SwAccessibleFrame::GetParent( aFrmOrObj,
    1643           0 :                                                       GetShell()->IsPreView());
    1644             : 
    1645           0 :                 if( pParent )
    1646             :                 {
    1647             :                     SwAccessibleContextMap_Impl::iterator aIter =
    1648           0 :                         mpFrmMap->find( pParent );
    1649           0 :                     if( aIter != mpFrmMap->end() )
    1650             :                     {
    1651           0 :                         uno::Reference < XAccessible > xAcc( (*aIter).second );
    1652           0 :                         xParentAccImpl =
    1653           0 :                             static_cast< SwAccessibleContext *>( xAcc.get() );
    1654             :                     }
    1655             :                 }
    1656             :             }
    1657           0 :             if( !xParentAccImpl.is() && !aFrmOrObj.GetSwFrm() &&
    1658             :                 mpShapeMap )
    1659             :             {
    1660             :                 SwAccessibleShapeMap_Impl::iterator aIter =
    1661           0 :                     mpShapeMap->find( aFrmOrObj.GetDrawObject() );
    1662           0 :                 if( aIter != mpShapeMap->end() )
    1663             :                 {
    1664           0 :                     uno::Reference < XAccessible > xAcc( (*aIter).second );
    1665           0 :                     xShapeAccImpl =
    1666           0 :                         static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
    1667             :                 }
    1668             :             }
    1669           0 :             if( pObj && GetShell()->ActionPend() &&
    1670           0 :                 (xParentAccImpl.is() || xShapeAccImpl.is()) )
    1671             :             {
    1672             :                 // Keep a reference to the XShape to avoid that it
    1673             :                 // is deleted with a SwFrmFmt::Modify.
    1674             :                 uno::Reference < drawing::XShape > xShape(
    1675           0 :                     const_cast< SdrObject * >( pObj )->getUnoShape(),
    1676           0 :                     uno::UNO_QUERY );
    1677           0 :                 if( xShape.is() )
    1678             :                 {
    1679           0 :                     if( !mpShapes )
    1680           0 :                         mpShapes = new SwShapeList_Impl;
    1681           0 :                     mpShapes->push_back( xShape );
    1682           0 :                 }
    1683           0 :             }
    1684             :         }
    1685             : 
    1686             :         // remove events stored for the frame
    1687             :         {
    1688           0 :             osl::MutexGuard aGuard( maEventMutex );
    1689           0 :             if( mpEvents )
    1690             :             {
    1691             :                 SwAccessibleEventMap_Impl::iterator aIter =
    1692           0 :                     mpEventMap->find( aFrmOrObj );
    1693           0 :                 if( aIter != mpEventMap->end() )
    1694             :                 {
    1695             :                     SwAccessibleEvent_Impl aEvent(
    1696           0 :                             SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj );
    1697           0 :                     AppendEvent( aEvent );
    1698             :                 }
    1699           0 :             }
    1700             :         }
    1701             : 
    1702             :         // If the frame is accessible and there is a context for it, dispose
    1703             :         // the frame. If the frame is no context for it but disposing should
    1704             :         // take place recursive, the frame's children have to be disposed
    1705             :         // anyway, so we have to create the context then.
    1706           0 :         if( xAccImpl.is() )
    1707             :         {
    1708           0 :             xAccImpl->Dispose( bRecursive );
    1709             :         }
    1710           0 :         else if( xParentAccImpl.is() )
    1711             :         {
    1712             :             // If the frame is a cell frame, the table must be notified.
    1713             :             // If we are in an action, a table model change event will
    1714             :             // be broadcasted at the end of the action to give the table
    1715             :             // a chance to generate a single table change event.
    1716             : 
    1717           0 :             xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive );
    1718             :         }
    1719           0 :         else if( xShapeAccImpl.is() )
    1720             :         {
    1721           0 :             RemoveContext( aFrmOrObj.GetDrawObject() );
    1722           0 :             xShapeAccImpl->dispose();
    1723             :         }
    1724             : 
    1725           0 :         if( mpPreview && pFrm && pFrm->IsPageFrm() )
    1726           0 :             mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) );
    1727             :     }
    1728           0 : }
    1729             : 
    1730          59 : void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm,
    1731             :                                            const SdrObject *pObj,
    1732             :                                            Window* pWindow,
    1733             :                                            const SwRect& rOldBox )
    1734             : {
    1735          59 :     SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
    1736          59 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    1737             :     {
    1738          37 :         ::rtl::Reference< SwAccessibleContext > xAccImpl;
    1739          74 :         ::rtl::Reference< SwAccessibleContext > xParentAccImpl;
    1740             :         {
    1741          37 :             osl::MutexGuard aGuard( maMutex );
    1742             : 
    1743          37 :             if( mpFrmMap )
    1744             :             {
    1745          37 :                 if( aFrmOrObj.GetSwFrm() )
    1746             :                 {
    1747             :                     SwAccessibleContextMap_Impl::iterator aIter =
    1748          37 :                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    1749          37 :                     if( aIter != mpFrmMap->end() )
    1750             :                     {
    1751             :                         // If there is an accesible object already it is
    1752             :                         // notified directly.
    1753          28 :                         uno::Reference < XAccessible > xAcc( (*aIter).second );
    1754          28 :                         xAccImpl =
    1755          56 :                             static_cast< SwAccessibleContext *>( xAcc.get() );
    1756             :                     }
    1757             :                 }
    1758          37 :                 if( !xAccImpl.is() )
    1759             :                 {
    1760             :                     // Otherwise we look if the parent is accessible.
    1761             :                     // If not, there is nothing to do.
    1762             :                     const SwFrm *pParent =
    1763             :                         SwAccessibleFrame::GetParent( aFrmOrObj,
    1764           9 :                                                       GetShell()->IsPreView());
    1765             : 
    1766           9 :                     if( pParent )
    1767             :                     {
    1768             :                         SwAccessibleContextMap_Impl::iterator aIter =
    1769           9 :                             mpFrmMap->find( pParent );
    1770           9 :                         if( aIter != mpFrmMap->end() )
    1771             :                         {
    1772           9 :                             uno::Reference < XAccessible > xAcc( (*aIter).second );
    1773           9 :                             xParentAccImpl =
    1774          18 :                                 static_cast< SwAccessibleContext *>( xAcc.get() );
    1775             :                         }
    1776             :                     }
    1777             :                 }
    1778          37 :             }
    1779             :         }
    1780             : 
    1781          37 :         if( xAccImpl.is() )
    1782             :         {
    1783          28 :             if( GetShell()->ActionPend() )
    1784             :             {
    1785             :                 SwAccessibleEvent_Impl aEvent(
    1786             :                     SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.get(),
    1787          28 :                     aFrmOrObj, rOldBox );
    1788          28 :                 AppendEvent( aEvent );
    1789             :             }
    1790             :             else
    1791             :             {
    1792           0 :                 FireEvents();
    1793           0 :                 xAccImpl->InvalidatePosOrSize( rOldBox );
    1794             :             }
    1795             :         }
    1796           9 :         else if( xParentAccImpl.is() )
    1797             :         {
    1798           9 :             if( GetShell()->ActionPend() )
    1799             :             {
    1800             :                 SwAccessibleEvent_Impl aEvent(
    1801             :                     SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
    1802           9 :                     xParentAccImpl.get(), aFrmOrObj, rOldBox );
    1803           9 :                 AppendEvent( aEvent );
    1804             :             }
    1805             :             else
    1806             :             {
    1807           0 :                 FireEvents();
    1808           0 :                 xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj,
    1809           0 :                                                           rOldBox );
    1810             :             }
    1811          37 :         }
    1812             :     }
    1813          59 : }
    1814             : 
    1815           0 : void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm )
    1816             : {
    1817           0 :     SwAccessibleChild aFrmOrObj( pFrm );
    1818           0 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    1819             :     {
    1820           0 :         uno::Reference < XAccessible > xAcc;
    1821             :         {
    1822           0 :             osl::MutexGuard aGuard( maMutex );
    1823             : 
    1824           0 :             if( mpFrmMap )
    1825             :             {
    1826             :                 SwAccessibleContextMap_Impl::iterator aIter =
    1827           0 :                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    1828           0 :                 if( aIter != mpFrmMap->end() )
    1829           0 :                     xAcc = (*aIter).second;
    1830           0 :             }
    1831             :         }
    1832             : 
    1833           0 :         if( xAcc.is() )
    1834             :         {
    1835             :             SwAccessibleContext *pAccImpl =
    1836           0 :                 static_cast< SwAccessibleContext *>( xAcc.get() );
    1837           0 :             if( GetShell()->ActionPend() )
    1838             :             {
    1839             :                 SwAccessibleEvent_Impl aEvent(
    1840             :                     SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl,
    1841           0 :                     aFrmOrObj );
    1842           0 :                 AppendEvent( aEvent );
    1843             :             }
    1844             :             else
    1845             :             {
    1846           0 :                 FireEvents();
    1847           0 :                 pAccImpl->InvalidateContent();
    1848             :             }
    1849           0 :         }
    1850             :     }
    1851           0 : }
    1852             : 
    1853           0 : void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm )
    1854             : {
    1855           0 :     SwAccessibleChild aFrmOrObj( &rTxtFrm );
    1856           0 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    1857             :     {
    1858           0 :         uno::Reference < XAccessible > xAcc;
    1859             :         {
    1860           0 :             osl::MutexGuard aGuard( maMutex );
    1861             : 
    1862           0 :             if( mpFrmMap )
    1863             :             {
    1864             :                 SwAccessibleContextMap_Impl::iterator aIter =
    1865           0 :                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    1866           0 :                 if( aIter != mpFrmMap->end() )
    1867           0 :                     xAcc = (*aIter).second;
    1868           0 :             }
    1869             :         }
    1870             : 
    1871           0 :         if( xAcc.is() )
    1872             :         {
    1873             :             SwAccessibleContext *pAccImpl =
    1874           0 :                 static_cast< SwAccessibleContext *>( xAcc.get() );
    1875           0 :             if( GetShell()->ActionPend() )
    1876             :             {
    1877             :                 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR,
    1878           0 :                                                pAccImpl, aFrmOrObj );
    1879           0 :                 aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED );
    1880           0 :                 AppendEvent( aEvent );
    1881             :             }
    1882             :             else
    1883             :             {
    1884           0 :                 FireEvents();
    1885           0 :                 pAccImpl->InvalidateAttr();
    1886             :             }
    1887           0 :         }
    1888             :     }
    1889           0 : }
    1890             : 
    1891          76 : void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm )
    1892             : {
    1893          76 :     SwAccessibleChild aFrmOrObj( pFrm );
    1894          76 :     bool bShapeSelected = false;
    1895          76 :     const ViewShell *pVSh = GetShell();
    1896          76 :     if( pVSh->ISA( SwCrsrShell ) )
    1897             :     {
    1898          76 :         const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh );
    1899          76 :         if( pCSh->IsTableMode() )
    1900             :         {
    1901          24 :             while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() )
    1902           8 :                 aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
    1903             :         }
    1904          68 :         else if( pVSh->ISA( SwFEShell ) )
    1905             :         {
    1906          68 :             const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
    1907          68 :             const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
    1908          68 :             if( pFlyFrm )
    1909             :             {
    1910             :                 OSL_ENSURE( !pFrm || pFrm->FindFlyFrm() == pFlyFrm,
    1911             :                         "cursor is not contained in fly frame" );
    1912           0 :                 aFrmOrObj = pFlyFrm;
    1913             :             }
    1914          68 :             else if( pFESh->IsObjSelected() > 0 )
    1915             :             {
    1916           0 :                 bShapeSelected = true;
    1917           0 :                 aFrmOrObj = static_cast<const SwFrm *>( 0 );
    1918             :             }
    1919             :         }
    1920             :     }
    1921             : 
    1922             :     OSL_ENSURE( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()),
    1923             :             "frame is not accessible" );
    1924             : 
    1925          76 :     uno::Reference < XAccessible > xOldAcc;
    1926         152 :     uno::Reference < XAccessible > xAcc;
    1927          76 :     bool bOldShapeSelected = false;
    1928             : 
    1929             :     {
    1930          76 :         osl::MutexGuard aGuard( maMutex );
    1931             : 
    1932          76 :         xOldAcc = mxCursorContext;
    1933          76 :         mxCursorContext = xAcc; // clear reference
    1934             : 
    1935          76 :         bOldShapeSelected = mbShapeSelected;
    1936          76 :         mbShapeSelected = bShapeSelected;
    1937             : 
    1938          76 :         if( aFrmOrObj.GetSwFrm() && mpFrmMap )
    1939             :         {
    1940             :             SwAccessibleContextMap_Impl::iterator aIter =
    1941          76 :                 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    1942          76 :             if( aIter != mpFrmMap->end() )
    1943          60 :                 xAcc = (*aIter).second;
    1944             : 
    1945             :             // For cells, some extra thoughts are necessary,
    1946             :             // because invalidating the cursor for one cell
    1947             :             // invalidates the cursor for all cells of the same
    1948             :             // table. For this reason, we don't want to
    1949             :             // invalidate the cursor for the old cursor object
    1950             :             // and the new one if they are within the same table,
    1951             :             // because this would result in doing the work twice.
    1952             :             // Moreover, we have to make sure to invalidate the
    1953             :             // cursor even if the current cell has no accessible object.
    1954             :             // If the old cursor objects exists and is in the same
    1955             :             // table, its the best choice, because using it avoids
    1956             :             // an unnessarary cursor invalidation cycle when creating
    1957             :             // a new object for the current cell.
    1958          76 :             if( aFrmOrObj.GetSwFrm()->IsCellFrm() )
    1959             :             {
    1960           9 :                 if( xOldAcc.is() &&
    1961           1 :                     AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) )
    1962             :                 {
    1963           1 :                     if( xAcc.is() )
    1964           1 :                         xOldAcc = xAcc; // avoid extra invalidation
    1965             :                     else
    1966           0 :                         xAcc = xOldAcc; // make sure ate least one
    1967             :                 }
    1968           8 :                 if( !xAcc.is() )
    1969           5 :                     xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True );
    1970             :             }
    1971          76 :         }
    1972             :     }
    1973             : 
    1974          76 :     if( xOldAcc.is() && xOldAcc != xAcc )
    1975           3 :         InvalidateCursorPosition( xOldAcc );
    1976          76 :     if( bOldShapeSelected || bShapeSelected )
    1977           0 :         InvalidateShapeSelection();
    1978          76 :     if( xAcc.is() )
    1979         141 :         InvalidateCursorPosition( xAcc );
    1980          76 : }
    1981             : 
    1982          12 : void SwAccessibleMap::InvalidateFocus()
    1983             : {
    1984          12 :     uno::Reference < XAccessible > xAcc;
    1985             :     bool bShapeSelected;
    1986             :     {
    1987          12 :         osl::MutexGuard aGuard( maMutex );
    1988             : 
    1989          12 :         xAcc = mxCursorContext;
    1990          12 :         bShapeSelected = mbShapeSelected;
    1991             :     }
    1992             : 
    1993          12 :     if( xAcc.is() )
    1994             :     {
    1995             :         SwAccessibleContext *pAccImpl =
    1996           9 :             static_cast< SwAccessibleContext *>( xAcc.get() );
    1997           9 :         pAccImpl->InvalidateFocus();
    1998             :     }
    1999           3 :     else if( bShapeSelected  )
    2000             :     {
    2001           0 :         DoInvalidateShapeFocus();
    2002          12 :     }
    2003          12 : }
    2004             : 
    2005          79 : void SwAccessibleMap::SetCursorContext(
    2006             :         const ::rtl::Reference < SwAccessibleContext >& rCursorContext )
    2007             : {
    2008          79 :     osl::MutexGuard aGuard( maMutex );
    2009         158 :     uno::Reference < XAccessible > xAcc( rCursorContext.get() );
    2010         158 :     mxCursorContext = xAcc;
    2011          79 : }
    2012             : 
    2013           0 : void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates,
    2014             :                                         const SwFrm* _pFrm )
    2015             : {
    2016             :     // Start with the frame or the first upper that is accessible
    2017           0 :     SwAccessibleChild aFrmOrObj( _pFrm );
    2018           0 :     while( aFrmOrObj.GetSwFrm() &&
    2019           0 :             !aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    2020           0 :         aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
    2021           0 :     if( !aFrmOrObj.GetSwFrm() )
    2022           0 :         aFrmOrObj = GetShell()->GetLayout();
    2023             : 
    2024           0 :     uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) );
    2025             :     SwAccessibleContext *pAccImpl =
    2026           0 :         static_cast< SwAccessibleContext *>( xAcc.get() );
    2027           0 :     if( GetShell()->ActionPend() )
    2028             :     {
    2029             :         SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
    2030             :                                        pAccImpl,
    2031             :                                        SwAccessibleChild(pAccImpl->GetFrm()),
    2032           0 :                                        _nStates );
    2033           0 :         AppendEvent( aEvent );
    2034             :     }
    2035             :     else
    2036             :     {
    2037           0 :         FireEvents();
    2038           0 :         pAccImpl->InvalidateStates( _nStates );
    2039           0 :     }
    2040           0 : }
    2041             : 
    2042           0 : void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm,
    2043             :                                               bool bFrom )
    2044             : {
    2045             :     // first, see if this frame is accessible, and if so, get the respective
    2046           0 :     SwAccessibleChild aFrmOrObj( pFrm );
    2047           0 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    2048             :     {
    2049           0 :         uno::Reference < XAccessible > xAcc;
    2050             :         {
    2051           0 :             osl::MutexGuard aGuard( maMutex );
    2052             : 
    2053           0 :             if( mpFrmMap )
    2054             :             {
    2055             :                 SwAccessibleContextMap_Impl::iterator aIter =
    2056           0 :                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    2057           0 :                 if( aIter != mpFrmMap->end() )
    2058             :                 {
    2059           0 :                     xAcc = (*aIter).second;
    2060             :                 }
    2061           0 :             }
    2062             :         }
    2063             : 
    2064             :         // deliver event directly, or queue event
    2065           0 :         if( xAcc.is() )
    2066             :         {
    2067             :             SwAccessibleContext *pAccImpl =
    2068           0 :                             static_cast< SwAccessibleContext *>( xAcc.get() );
    2069           0 :             if( GetShell()->ActionPend() )
    2070             :             {
    2071             :                 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
    2072             :                                                pAccImpl, SwAccessibleChild(pFrm),
    2073             :                                                ( bFrom
    2074             :                                                  ? ACC_STATE_RELATION_FROM
    2075           0 :                                                  : ACC_STATE_RELATION_TO ) );
    2076           0 :                 AppendEvent( aEvent );
    2077             :             }
    2078             :             else
    2079             :             {
    2080           0 :                 FireEvents();
    2081             :                 pAccImpl->InvalidateRelation( bFrom
    2082             :                         ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
    2083           0 :                         : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
    2084             :             }
    2085           0 :         }
    2086             :     }
    2087           0 : }
    2088             : 
    2089           0 : void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster,
    2090             :                                              const SwFrm* pFollow )
    2091             : {
    2092           0 :     _InvalidateRelationSet( pMaster, false );
    2093           0 :     _InvalidateRelationSet( pFollow, true );
    2094           0 : }
    2095             : 
    2096             : // invalidation of CONTENT_FLOW_FROM/_TO relation of a paragraph
    2097           0 : void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm,
    2098             :                                                   const bool _bFrom )
    2099             : {
    2100           0 :     _InvalidateRelationSet( &_rTxtFrm, _bFrom );
    2101           0 : }
    2102             : 
    2103             : // invalidation of text selection of a paragraph
    2104           0 : void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm )
    2105             : {
    2106             :     // first, see if this frame is accessible, and if so, get the respective
    2107           0 :     SwAccessibleChild aFrmOrObj( &_rTxtFrm );
    2108           0 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    2109             :     {
    2110           0 :         uno::Reference < XAccessible > xAcc;
    2111             :         {
    2112           0 :             osl::MutexGuard aGuard( maMutex );
    2113             : 
    2114           0 :             if( mpFrmMap )
    2115             :             {
    2116             :                 SwAccessibleContextMap_Impl::iterator aIter =
    2117           0 :                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    2118           0 :                 if( aIter != mpFrmMap->end() )
    2119             :                 {
    2120           0 :                     xAcc = (*aIter).second;
    2121             :                 }
    2122           0 :             }
    2123             :         }
    2124             : 
    2125             :         // deliver event directly, or queue event
    2126           0 :         if( xAcc.is() )
    2127             :         {
    2128             :             SwAccessibleContext *pAccImpl =
    2129           0 :                             static_cast< SwAccessibleContext *>( xAcc.get() );
    2130           0 :             if( GetShell()->ActionPend() )
    2131             :             {
    2132             :                 SwAccessibleEvent_Impl aEvent(
    2133             :                     SwAccessibleEvent_Impl::CARET_OR_STATES,
    2134             :                     pAccImpl,
    2135             :                     SwAccessibleChild( &_rTxtFrm ),
    2136           0 :                     ACC_STATE_TEXT_SELECTION_CHANGED );
    2137           0 :                 AppendEvent( aEvent );
    2138             :             }
    2139             :             else
    2140             :             {
    2141           0 :                 FireEvents();
    2142           0 :                 pAccImpl->InvalidateTextSelection();
    2143             :             }
    2144           0 :         }
    2145             :     }
    2146           0 : }
    2147             : 
    2148           0 : sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm,
    2149             :                                           Window& rChild ) const
    2150             : {
    2151           0 :     sal_Int32 nIndex( -1 );
    2152             : 
    2153           0 :     SwAccessibleChild aFrmOrObj( &rParentFrm );
    2154           0 :     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
    2155             :     {
    2156           0 :         uno::Reference < XAccessible > xAcc;
    2157             :         {
    2158           0 :             osl::MutexGuard aGuard( maMutex );
    2159             : 
    2160           0 :             if( mpFrmMap )
    2161             :             {
    2162             :                 SwAccessibleContextMap_Impl::iterator aIter =
    2163           0 :                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
    2164           0 :                 if( aIter != mpFrmMap->end() )
    2165             :                 {
    2166           0 :                     xAcc = (*aIter).second;
    2167             :                 }
    2168           0 :             }
    2169             :         }
    2170             : 
    2171           0 :         if( xAcc.is() )
    2172             :         {
    2173             :             SwAccessibleContext *pAccImpl =
    2174           0 :                             static_cast< SwAccessibleContext *>( xAcc.get() );
    2175             : 
    2176             :             nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
    2177           0 :                                               SwAccessibleChild( &rChild ) );
    2178           0 :         }
    2179             :     }
    2180             : 
    2181           0 :     return nIndex;
    2182             : }
    2183             : 
    2184           0 : void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages,
    2185             :                                      const Fraction&  _rScale,
    2186             :                                      const SwPageFrm* _pSelectedPageFrm,
    2187             :                                      const Size&      _rPrevwWinSize )
    2188             : {
    2189             :     OSL_ENSURE( GetShell()->IsPreView(), "no preview?" );
    2190             :     OSL_ENSURE( mpPreview != NULL, "no preview data?" );
    2191             : 
    2192           0 :     mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
    2193             : 
    2194             :     // propagate change of VisArea through the document's
    2195             :     // accessibility tree; this will also send appropriate scroll
    2196             :     // events
    2197             :     SwAccessibleContext* pDoc =
    2198           0 :         GetContextImpl( GetShell()->GetLayout() ).get();
    2199           0 :     static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
    2200             : 
    2201           0 :     uno::Reference < XAccessible > xOldAcc;
    2202           0 :     uno::Reference < XAccessible > xAcc;
    2203             :     {
    2204           0 :         osl::MutexGuard aGuard( maMutex );
    2205             : 
    2206           0 :         xOldAcc = mxCursorContext;
    2207             : 
    2208           0 :         const SwPageFrm *pSelPage = mpPreview->GetSelPage();
    2209           0 :         if( pSelPage && mpFrmMap )
    2210             :         {
    2211             :             SwAccessibleContextMap_Impl::iterator aIter =
    2212           0 :                 mpFrmMap->find( pSelPage );
    2213           0 :             if( aIter != mpFrmMap->end() )
    2214           0 :                 xAcc = (*aIter).second;
    2215           0 :         }
    2216             :     }
    2217             : 
    2218           0 :     if( xOldAcc.is() && xOldAcc != xAcc )
    2219           0 :         InvalidateCursorPosition( xOldAcc );
    2220           0 :     if( xAcc.is() )
    2221           0 :         InvalidateCursorPosition( xAcc );
    2222           0 : }
    2223             : 
    2224           0 : void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage )
    2225             : {
    2226             :     OSL_ENSURE( GetShell()->IsPreView(), "no preview?" );
    2227             :     OSL_ENSURE( mpPreview != NULL, "no preview data?" );
    2228             : 
    2229           0 :     mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
    2230             : 
    2231           0 :     uno::Reference < XAccessible > xOldAcc;
    2232           0 :     uno::Reference < XAccessible > xAcc;
    2233             :     {
    2234           0 :         osl::MutexGuard aGuard( maMutex );
    2235             : 
    2236           0 :         xOldAcc = mxCursorContext;
    2237             : 
    2238           0 :         const SwPageFrm *pSelPage = mpPreview->GetSelPage();
    2239           0 :         if( pSelPage && mpFrmMap )
    2240             :         {
    2241             :             SwAccessibleContextMap_Impl::iterator aIter =
    2242           0 :                 mpFrmMap->find( pSelPage );
    2243           0 :             if( aIter != mpFrmMap->end() )
    2244           0 :                 xAcc = (*aIter).second;
    2245           0 :         }
    2246             :     }
    2247             : 
    2248           0 :     if( xOldAcc.is() && xOldAcc != xAcc )
    2249           0 :         InvalidateCursorPosition( xOldAcc );
    2250           0 :     if( xAcc.is() )
    2251           0 :         InvalidateCursorPosition( xAcc );
    2252           0 : }
    2253             : 
    2254             : 
    2255           0 : bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const
    2256             : {
    2257           0 :     return mpPreview && mpPreview->GetSelPage() == pPageFrm;
    2258             : }
    2259             : 
    2260             : 
    2261         144 : void SwAccessibleMap::FireEvents()
    2262             : {
    2263             :     {
    2264         144 :         osl::MutexGuard aGuard( maEventMutex );
    2265         144 :         if( mpEvents )
    2266             :         {
    2267          15 :             mpEvents->SetFiring();
    2268             :             ::std::for_each(mpEvents->begin(), mpEvents->end(),
    2269          15 :                             boost::bind(&SwAccessibleMap::FireEvent, this, _1));
    2270             : 
    2271          15 :             delete mpEventMap;
    2272          15 :             mpEventMap = 0;
    2273             : 
    2274          15 :             delete mpEvents;
    2275          15 :             mpEvents = 0;
    2276         144 :         }
    2277             :     }
    2278             :     {
    2279         144 :         osl::MutexGuard aGuard( maMutex );
    2280         144 :         if( mpShapes )
    2281             :         {
    2282           0 :             delete mpShapes;
    2283           0 :             mpShapes = 0;
    2284         144 :         }
    2285             :     }
    2286             : 
    2287         144 : }
    2288             : 
    2289           0 : sal_Bool SwAccessibleMap::IsValid() const
    2290             : {
    2291           0 :     return sal_True;
    2292             : }
    2293             : 
    2294           0 : Rectangle SwAccessibleMap::GetVisibleArea() const
    2295             : {
    2296           0 :     MapMode aSrc( MAP_TWIP );
    2297           0 :     MapMode aDest( MAP_100TH_MM );
    2298           0 :     return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest );
    2299             : }
    2300             : 
    2301             : // Convert a MM100 value relative to the document root into a pixel value
    2302             : // relative to the screen!
    2303           0 : Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
    2304             : {
    2305           0 :     MapMode aSrc( MAP_100TH_MM );
    2306           0 :     MapMode aDest( MAP_TWIP );
    2307             : 
    2308           0 :     Point aPoint = rPoint;
    2309             : 
    2310           0 :     aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
    2311           0 :     Window *pWin = GetShell()->GetWin();
    2312           0 :     if( pWin )
    2313             :     {
    2314           0 :         MapMode aMapMode;
    2315           0 :         GetMapMode( aPoint, aMapMode );
    2316           0 :         aPoint = pWin->LogicToPixel( aPoint, aMapMode );
    2317           0 :         aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
    2318             :     }
    2319             : 
    2320           0 :     return aPoint;
    2321             : }
    2322             : 
    2323           0 : Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const
    2324             : {
    2325           0 :     MapMode aSrc( MAP_100TH_MM );
    2326           0 :     MapMode aDest( MAP_TWIP );
    2327           0 :     Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) );
    2328           0 :     if( GetShell()->GetWin() )
    2329             :     {
    2330           0 :         MapMode aMapMode;
    2331           0 :         GetMapMode( Point(0,0), aMapMode );
    2332           0 :         aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode );
    2333             :     }
    2334             : 
    2335           0 :     return aSize;
    2336             : }
    2337             : 
    2338           0 : Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const
    2339             : {
    2340           0 :     Point aPoint;
    2341           0 :     Window *pWin = GetShell()->GetWin();
    2342           0 :     if( pWin )
    2343             :     {
    2344           0 :         aPoint = pWin->ScreenToOutputPixel( rPoint );
    2345           0 :         MapMode aMapMode;
    2346           0 :         GetMapMode( aPoint, aMapMode );
    2347           0 :         aPoint = pWin->PixelToLogic( aPoint, aMapMode );
    2348           0 :         MapMode aSrc( MAP_TWIP );
    2349           0 :         MapMode aDest( MAP_100TH_MM );
    2350           0 :         aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
    2351             :     }
    2352             : 
    2353           0 :     return aPoint;
    2354             : }
    2355             : 
    2356           0 : Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const
    2357             : {
    2358           0 :     Size aSize;
    2359           0 :     if( GetShell()->GetWin() )
    2360             :     {
    2361           0 :         MapMode aMapMode;
    2362           0 :         GetMapMode( Point(0,0), aMapMode );
    2363           0 :         aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode );
    2364           0 :         MapMode aSrc( MAP_TWIP );
    2365           0 :         MapMode aDest( MAP_100TH_MM );
    2366           0 :         aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest );
    2367             :     }
    2368             : 
    2369           0 :     return aSize;
    2370             : }
    2371             : 
    2372           0 : sal_Bool SwAccessibleMap::ReplaceChild (
    2373             :         ::accessibility::AccessibleShape* pCurrentChild,
    2374             :         const uno::Reference< drawing::XShape >& _rxShape,
    2375             :         const long /*_nIndex*/,
    2376             :         const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
    2377             :     )   throw (uno::RuntimeException)
    2378             : {
    2379           0 :     const SdrObject *pObj = 0;
    2380             :     {
    2381           0 :         osl::MutexGuard aGuard( maMutex );
    2382           0 :         if( mpShapeMap )
    2383             :         {
    2384           0 :             SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
    2385           0 :             SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
    2386           0 :             while( aIter != aEndIter && !pObj )
    2387             :             {
    2388           0 :                 uno::Reference < XAccessible > xAcc( (*aIter).second );
    2389             :                 ::accessibility::AccessibleShape *pAccShape =
    2390           0 :                     static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
    2391           0 :                 if( pAccShape == pCurrentChild )
    2392             :                 {
    2393           0 :                     pObj = (*aIter).first;
    2394             :                 }
    2395           0 :                 ++aIter;
    2396           0 :             }
    2397           0 :         }
    2398             :     }
    2399           0 :     if( !pObj )
    2400           0 :         return sal_False;
    2401             : 
    2402           0 :     uno::Reference < drawing::XShape > xShape( _rxShape );  // keep reference to shape, because
    2403             :                                                             // we might be the only one that
    2404             :                                                             // holds it.
    2405             :     // Also get keep parent.
    2406           0 :     uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
    2407           0 :     pCurrentChild = 0;  // will be released by dispose
    2408           0 :     Dispose( 0, pObj, 0 );
    2409             : 
    2410             :     {
    2411           0 :         osl::MutexGuard aGuard( maMutex );
    2412             : 
    2413           0 :         if( !mpShapeMap )
    2414           0 :             mpShapeMap = new SwAccessibleShapeMap_Impl( this );
    2415             : 
    2416             :         // create the new child
    2417             :         ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
    2418           0 :                         ::accessibility::ShapeTypeHandler::Instance();
    2419             :         ::accessibility::AccessibleShapeInfo aShapeInfo(
    2420           0 :                                             xShape, xParent, this );
    2421             :         ::accessibility::AccessibleShape* pReplacement =
    2422             :             rShapeTypeHandler.CreateAccessibleObject (
    2423           0 :                 aShapeInfo, mpShapeMap->GetInfo() );
    2424             : 
    2425           0 :         uno::Reference < XAccessible > xAcc( pReplacement );
    2426           0 :         if( xAcc.is() )
    2427             :         {
    2428           0 :             pReplacement->Init();
    2429             : 
    2430             :             SwAccessibleShapeMap_Impl::iterator aIter =
    2431           0 :                 mpShapeMap->find( pObj );
    2432           0 :             if( aIter != mpShapeMap->end() )
    2433             :             {
    2434           0 :                 (*aIter).second = xAcc;
    2435             :             }
    2436             :             else
    2437             :             {
    2438           0 :                 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc );
    2439           0 :                 mpShapeMap->insert( aEntry );
    2440             :             }
    2441           0 :         }
    2442             :     }
    2443             : 
    2444           0 :     SwRect aEmptyRect;
    2445           0 :     InvalidatePosOrSize( 0, pObj, 0, aEmptyRect );
    2446             : 
    2447           0 :     return sal_True;
    2448             : }
    2449             : 
    2450           0 : Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
    2451             : {
    2452           0 :     Point aPoint;
    2453           0 :     if( GetShell()->GetWin() )
    2454             :     {
    2455           0 :         MapMode aMapMode;
    2456           0 :         GetMapMode( rPoint, aMapMode );
    2457           0 :         aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode );
    2458             :     }
    2459           0 :     return aPoint;
    2460             : }
    2461             : 
    2462       12572 : static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue,
    2463             :                                           long aRefValue, bool bToLower)
    2464             : {
    2465       12572 :     long aResult = aCoarseValue;
    2466             : 
    2467       12572 :     if (bToLower)
    2468             :     {
    2469        6286 :         if (aFineValue < aRefValue)
    2470        2622 :             aResult -= 1;
    2471             :     }
    2472             :     else
    2473             :     {
    2474        6286 :         if (aFineValue > aRefValue)
    2475         188 :             aResult += 1;
    2476             :     }
    2477             : 
    2478       12572 :     return aResult;
    2479             : }
    2480             : 
    2481        3143 : static inline void lcl_CorrectRectangle(Rectangle & rRect,
    2482             :                                         const Rectangle & rSource,
    2483             :                                         const Rectangle & rInGrid)
    2484             : {
    2485        6286 :     rRect.Left() = lcl_CorrectCoarseValue(rRect.Left(), rSource.Left(),
    2486        6286 :                                           rInGrid.Left(), false);
    2487        6286 :     rRect.Top() = lcl_CorrectCoarseValue(rRect.Top(), rSource.Top(),
    2488        6286 :                                          rInGrid.Top(), false);
    2489        6286 :     rRect.Right() = lcl_CorrectCoarseValue(rRect.Right(), rSource.Right(),
    2490        6286 :                                            rInGrid.Right(), true);
    2491        6286 :     rRect.Bottom() = lcl_CorrectCoarseValue(rRect.Bottom(), rSource.Bottom(),
    2492        6286 :                                             rInGrid.Bottom(), true);
    2493        3143 : }
    2494             : 
    2495        3143 : Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const
    2496             : {
    2497        3143 :     Rectangle aRect;
    2498        3143 :     if( GetShell()->GetWin() )
    2499             :     {
    2500        3143 :         MapMode aMapMode;
    2501        3143 :         GetMapMode( rRect.TopLeft(), aMapMode );
    2502        3143 :         aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode );
    2503             : 
    2504        3143 :         Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode );
    2505        3143 :         lcl_CorrectRectangle(aRect, rRect, aTmpRect);
    2506             :     }
    2507             : 
    2508        3143 :     return aRect;
    2509             : }
    2510             : 
    2511             : /** get mapping mode for LogicToPixel and PixelToLogic conversions
    2512             : 
    2513             :     Method returns mapping mode of current output device and adjusts it,
    2514             :     if the shell is in page/print preview.
    2515             :     Necessary, because <PreviewAdjust(..)> changes mapping mode at current
    2516             :     output device for mapping logic document positions to page preview window
    2517             :     positions and vice versa and doesn't take care to recover its changes.
    2518             : */
    2519        3143 : void SwAccessibleMap::GetMapMode( const Point& _rPoint,
    2520             :                                   MapMode&     _orMapMode ) const
    2521             : {
    2522        3143 :     MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
    2523        3143 :     if( GetShell()->IsPreView() )
    2524             :     {
    2525             :         OSL_ENSURE( mpPreview != NULL, "need preview data" );
    2526             : 
    2527           0 :         mpPreview->AdjustMapMode( aMapMode, _rPoint );
    2528             :     }
    2529        3143 :     _orMapMode = aMapMode;
    2530        3143 : }
    2531             : 
    2532           0 : Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const
    2533             : {
    2534             :     OSL_ENSURE( mpVSh->IsPreView(), "no page preview accessible." );
    2535             :     OSL_ENSURE( mpVSh->IsPreView() && ( mpPreview != NULL ),
    2536             :                 "missing accessible preview data at page preview" );
    2537           0 :     if ( mpVSh->IsPreView() && ( mpPreview != NULL ) )
    2538             :     {
    2539           0 :         return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum );
    2540             :     }
    2541             :     else
    2542             :     {
    2543           0 :         return Size( 0, 0 );
    2544             :     }
    2545             : }
    2546             : 
    2547             : /** method to build up a new data structure of the accessible pararaphs,
    2548             :     which have a selection
    2549             :     Important note: method has to be used inside a mutual exclusive section
    2550             : */
    2551          76 : SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas()
    2552             : {
    2553             :     // no accessible contexts, no selection
    2554          76 :     if ( !mpFrmMap )
    2555             :     {
    2556           0 :         return 0L;
    2557             :     }
    2558             : 
    2559             :     // get cursor as an instance of its base class <SwPaM>
    2560          76 :     SwPaM* pCrsr( 0L );
    2561             :     {
    2562          76 :         SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell());
    2563          76 :         if ( pCrsrShell )
    2564             :         {
    2565          76 :             SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell);
    2566         228 :             if ( !pFEShell ||
    2567         152 :                  ( !pFEShell->IsFrmSelected() &&
    2568          76 :                    pFEShell->IsObjSelected() == 0 ) )
    2569             :             {
    2570             :                 // get cursor without updating an existing table cursor.
    2571          76 :                 pCrsr = pCrsrShell->GetCrsr( sal_False );
    2572             :             }
    2573             :         }
    2574             :     }
    2575             :     // no cursor, no selection
    2576          76 :     if ( !pCrsr )
    2577             :     {
    2578           0 :         return 0L;
    2579             :     }
    2580             : 
    2581          76 :     SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L );
    2582             : 
    2583             :     // loop on all cursors
    2584          76 :     SwPaM* pRingStart = pCrsr;
    2585          91 :     do {
    2586             : 
    2587             :         // for a selection the cursor has to have a mark.
    2588             :         // for safety reasons assure that point and mark are in text nodes
    2589         205 :         if ( pCrsr->HasMark() &&
    2590         114 :              pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() &&
    2591          23 :              pCrsr->GetMark()->nNode.GetNode().IsTxtNode() )
    2592             :         {
    2593          23 :             SwPosition* pStartPos = pCrsr->Start();
    2594          23 :             SwPosition* pEndPos = pCrsr->End();
    2595             :             // loop on all text nodes inside the selection
    2596          23 :             SwNodeIndex aIdx( pStartPos->nNode );
    2597          46 :             for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx )
    2598             :             {
    2599          23 :                 SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() );
    2600          23 :                 if ( pTxtNode )
    2601             :                 {
    2602             :                     // loop on all text frames registered at the text node.
    2603          23 :                     SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode );
    2604          46 :                     for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() )
    2605             :                         {
    2606          23 :                             uno::WeakReference < XAccessible > xWeakAcc;
    2607             :                             SwAccessibleContextMap_Impl::iterator aMapIter =
    2608          23 :                                                     mpFrmMap->find( pTxtFrm );
    2609          23 :                             if( aMapIter != mpFrmMap->end() )
    2610             :                             {
    2611           0 :                                 xWeakAcc = (*aMapIter).second;
    2612             :                                 SwAccessibleParaSelection aDataEntry(
    2613           0 :                                     pTxtNode == &(pStartPos->nNode.GetNode())
    2614           0 :                                                 ? pStartPos->nContent.GetIndex()
    2615             :                                                 : 0,
    2616           0 :                                     pTxtNode == &(pEndPos->nNode.GetNode())
    2617           0 :                                                 ? pEndPos->nContent.GetIndex()
    2618           0 :                                                 : STRING_LEN );
    2619             :                                 SwAccessibleSelectedParas_Impl::value_type
    2620           0 :                                                 aEntry( xWeakAcc, aDataEntry );
    2621           0 :                                 if ( !pRetSelectedParas )
    2622             :                                 {
    2623             :                                     pRetSelectedParas =
    2624           0 :                                             new SwAccessibleSelectedParas_Impl;
    2625             :                                 }
    2626           0 :                                 pRetSelectedParas->insert( aEntry );
    2627             :                             }
    2628          46 :                         }
    2629             :                     }
    2630          23 :                 }
    2631             :             }
    2632             : 
    2633             :         // prepare next turn: get next cursor in ring
    2634          91 :         pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
    2635             :     } while ( pCrsr != pRingStart );
    2636             : 
    2637          76 :     return pRetSelectedParas;
    2638             : }
    2639             : 
    2640          76 : void SwAccessibleMap::InvalidateTextSelectionOfAllParas()
    2641             : {
    2642          76 :     osl::MutexGuard aGuard( maMutex );
    2643             : 
    2644             :     // keep previously known selected paragraphs
    2645          76 :     SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas );
    2646             : 
    2647             :     // determine currently selected paragraphs
    2648          76 :     mpSelectedParas = _BuildSelectedParas();
    2649             : 
    2650             :     // compare currently selected paragraphs with the previously selected
    2651             :     // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
    2652             :     // first, search for new and changed selections.
    2653             :     // on the run remove selections from previously known ones, if they are
    2654             :     // also in the current ones.
    2655          76 :     if ( mpSelectedParas )
    2656             :     {
    2657           0 :         SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin();
    2658           0 :         for ( ; aIter != mpSelectedParas->end(); ++aIter )
    2659             :         {
    2660           0 :             bool bSubmitEvent( false );
    2661           0 :             if ( !pPrevSelectedParas )
    2662             :             {
    2663             :                 // new selection
    2664           0 :                 bSubmitEvent = true;
    2665             :             }
    2666             :             else
    2667             :             {
    2668             :                 SwAccessibleSelectedParas_Impl::iterator aPrevSelected =
    2669           0 :                                         pPrevSelectedParas->find( (*aIter).first );
    2670           0 :                 if ( aPrevSelected != pPrevSelectedParas->end() )
    2671             :                 {
    2672             :                     // check, if selection has changed
    2673           0 :                     if ( (*aIter).second.nStartOfSelection !=
    2674           0 :                                     (*aPrevSelected).second.nStartOfSelection ||
    2675           0 :                          (*aIter).second.nEndOfSelection !=
    2676           0 :                                     (*aPrevSelected).second.nEndOfSelection )
    2677             :                     {
    2678             :                         // changed selection
    2679           0 :                         bSubmitEvent = true;
    2680             :                     }
    2681           0 :                     pPrevSelectedParas->erase( aPrevSelected );
    2682             :                 }
    2683             :                 else
    2684             :                 {
    2685             :                     // new selection
    2686           0 :                     bSubmitEvent = true;
    2687             :                 }
    2688             :             }
    2689             : 
    2690           0 :             if ( bSubmitEvent )
    2691             :             {
    2692           0 :                 uno::Reference < XAccessible > xAcc( (*aIter).first );
    2693           0 :                 if ( xAcc.is() )
    2694             :                 {
    2695             :                     ::rtl::Reference < SwAccessibleContext > xAccImpl(
    2696           0 :                                 static_cast<SwAccessibleContext*>( xAcc.get() ) );
    2697           0 :                     if ( xAccImpl.is() && xAccImpl->GetFrm() )
    2698             :                     {
    2699             :                         const SwTxtFrm* pTxtFrm(
    2700           0 :                             dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
    2701             :                         OSL_ENSURE( pTxtFrm,
    2702             :                                 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
    2703           0 :                         if ( pTxtFrm )
    2704             :                         {
    2705           0 :                             InvalidateParaTextSelection( *pTxtFrm );
    2706             :                         }
    2707           0 :                     }
    2708           0 :                 }
    2709             :             }
    2710             :         }
    2711             :     }
    2712             : 
    2713             :     // second, handle previous selections - after the first step the data
    2714             :     // structure of the previously known only contains the 'old' selections
    2715          76 :     if ( pPrevSelectedParas )
    2716             :     {
    2717           0 :         SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
    2718           0 :         for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
    2719             :         {
    2720           0 :             uno::Reference < XAccessible > xAcc( (*aIter).first );
    2721           0 :             if ( xAcc.is() )
    2722             :             {
    2723             :                 ::rtl::Reference < SwAccessibleContext > xAccImpl(
    2724           0 :                             static_cast<SwAccessibleContext*>( xAcc.get() ) );
    2725           0 :                 if ( xAccImpl.is() && xAccImpl->GetFrm() )
    2726             :                 {
    2727             :                     const SwTxtFrm* pTxtFrm(
    2728           0 :                             dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
    2729             :                     OSL_ENSURE( pTxtFrm,
    2730             :                             "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
    2731           0 :                     if ( pTxtFrm )
    2732             :                     {
    2733           0 :                         InvalidateParaTextSelection( *pTxtFrm );
    2734             :                     }
    2735           0 :                 }
    2736             :             }
    2737           0 :         }
    2738             : 
    2739           0 :         delete pPrevSelectedParas;
    2740          76 :     }
    2741          76 : }
    2742             : 
    2743         135 : const SwRect& SwAccessibleMap::GetVisArea() const
    2744             : {
    2745             :     OSL_ENSURE( !GetShell()->IsPreView() || (mpPreview != NULL),
    2746             :                 "preview without preview data?" );
    2747             : 
    2748         135 :     return GetShell()->IsPreView()
    2749           0 :            ? mpPreview->GetVisArea()
    2750         135 :            : GetShell()->VisArea();
    2751          99 : }
    2752             : 
    2753             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10