LCOV - code coverage report
Current view: top level - svx/source/accessibility - AccessibleTextHelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 305 577 52.9 %
Date: 2012-08-25 Functions: 52 77 67.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 270 961 28.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : //------------------------------------------------------------------------
      31                 :            : //
      32                 :            : // Global header
      33                 :            : //
      34                 :            : //------------------------------------------------------------------------
      35                 :            : 
      36                 :            : #include <limits.h>
      37                 :            : #include <memory>
      38                 :            : #include <algorithm>
      39                 :            : #include <deque>
      40                 :            : #include <osl/mutex.hxx>
      41                 :            : #include <com/sun/star/uno/Any.hxx>
      42                 :            : #include <com/sun/star/uno/Reference.hxx>
      43                 :            : #include <cppuhelper/weakref.hxx>
      44                 :            : #include <com/sun/star/awt/Point.hpp>
      45                 :            : #include <com/sun/star/awt/Rectangle.hpp>
      46                 :            : #include <com/sun/star/lang/DisposedException.hpp>
      47                 :            : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      48                 :            : #include <com/sun/star/accessibility/XAccessible.hpp>
      49                 :            : #include <com/sun/star/accessibility/XAccessibleContext.hpp>
      50                 :            : #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
      51                 :            : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      52                 :            : #include <comphelper/accessibleeventnotifier.hxx>
      53                 :            : #include <unotools/accessiblestatesethelper.hxx>
      54                 :            : #include <vcl/unohelp.hxx>
      55                 :            : #include <vcl/svapp.hxx>
      56                 :            : 
      57                 :            : //------------------------------------------------------------------------
      58                 :            : //
      59                 :            : // Project-local header
      60                 :            : //
      61                 :            : //------------------------------------------------------------------------
      62                 :            : #include "AccessibleTextEventQueue.hxx"
      63                 :            : #include <svx/AccessibleTextHelper.hxx>
      64                 :            : #include <svx/unoshape.hxx>
      65                 :            : #include "editeng/unolingu.hxx"
      66                 :            : #include <editeng/unotext.hxx>
      67                 :            : 
      68                 :            : #include "editeng/unoedhlp.hxx"
      69                 :            : #include "editeng/unopracc.hxx"
      70                 :            : #include "editeng/AccessibleParaManager.hxx"
      71                 :            : #include "editeng/AccessibleEditableTextPara.hxx"
      72                 :            : #include <svx/svdmodel.hxx>
      73                 :            : #include <svx/svdpntv.hxx>
      74                 :            : #include <editeng/editdata.hxx>
      75                 :            : #include <editeng/editeng.hxx>
      76                 :            : #include <editeng/editview.hxx>
      77                 :            : 
      78                 :            : using namespace ::com::sun::star;
      79                 :            : using namespace ::com::sun::star::accessibility;
      80                 :            : 
      81                 :            : namespace accessibility
      82                 :            : {
      83                 :            : 
      84                 :            : //------------------------------------------------------------------------
      85                 :            : //
      86                 :            : // AccessibleTextHelper_Impl declaration
      87                 :            : //
      88                 :            : //------------------------------------------------------------------------
      89                 :            : 
      90                 :            :     DBG_NAME( AccessibleTextHelper_Impl )
      91                 :            : 
      92                 :            :     template < typename first_type, typename second_type >
      93                 :          0 :         ::std::pair< first_type, second_type > makeSortedPair( first_type   first,
      94                 :            :                                                                                  second_type    second  )
      95                 :            :     {
      96         [ #  # ]:          0 :         if( first > second )
      97                 :          0 :             return ::std::make_pair( second, first );
      98                 :            :         else
      99                 :          0 :             return ::std::make_pair( first, second );
     100                 :            :     }
     101                 :            : 
     102                 :            :     class AccessibleTextHelper_Impl : public SfxListener
     103                 :            :     {
     104                 :            : 
     105                 :            :     public:
     106                 :            :         typedef ::std::vector< sal_Int16 > VectorOfStates;
     107                 :            : 
     108                 :            :         // receive pointer to our frontend class and view window
     109                 :            :         AccessibleTextHelper_Impl();
     110                 :            :         ~AccessibleTextHelper_Impl();
     111                 :            : 
     112                 :            :         // XAccessibleContext child handling methods
     113                 :            :         sal_Int32 SAL_CALL getAccessibleChildCount() SAL_THROW((uno::RuntimeException));
     114                 :            :         uno::Reference< XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException));
     115                 :            : 
     116                 :            :         // XAccessibleEventBroadcaster child related methods
     117                 :            :         void SAL_CALL addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException));
     118                 :            :         void SAL_CALL removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException));
     119                 :            : 
     120                 :            :         // XAccessibleComponent child related methods
     121                 :            :         uno::Reference< XAccessible > SAL_CALL getAccessibleAtPoint( const awt::Point& aPoint ) SAL_THROW((uno::RuntimeException));
     122                 :            : 
     123                 :            :         SvxEditSourceAdapter& GetEditSource() const SAL_THROW((uno::RuntimeException));
     124                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     125                 :            :         void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException));
     126                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
     127                 :            : 
     128                 :         56 :         void SetEventSource( const uno::Reference< XAccessible >& rInterface )
     129                 :            :         {
     130                 :            :             DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     131                 :         56 :             mxFrontEnd = rInterface;
     132                 :         56 :         }
     133                 :          0 :         uno::Reference< XAccessible > GetEventSource() const
     134                 :            :         {
     135                 :            :             DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     136                 :          0 :             return mxFrontEnd;
     137                 :            :         }
     138                 :            : 
     139                 :            :         void SetOffset( const Point& );
     140                 :          6 :         Point GetOffset() const
     141                 :            :         {
     142                 :            :             DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     143         [ +  - ]:          6 :             ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
     144         [ +  - ]:          6 :             return aPoint;
     145                 :            :         }
     146                 :            : 
     147                 :            :         void SetStartIndex( sal_Int32 nOffset );
     148                 :         64 :         sal_Int32 GetStartIndex() const
     149                 :            :         {
     150                 :            :             DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     151                 :            :             // Strictly correct only with locked solar mutex, // but
     152                 :            :             // here we rely on the fact that sal_Int32 access is
     153                 :            :             // atomic
     154                 :         64 :             return mnStartIndex;
     155                 :            :         }
     156                 :            : 
     157                 :            :         void SetAdditionalChildStates( const VectorOfStates& rChildStates );
     158                 :            : 
     159                 :            :         sal_Bool IsSelected() const;
     160                 :            : 
     161                 :            :         void Dispose();
     162                 :            : 
     163                 :            :         // do NOT hold object mutex when calling this! Danger of deadlock
     164                 :            :         void FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue = uno::Any(), const uno::Any& rOldValue = uno::Any() ) const;
     165                 :            :         void FireEvent( const AccessibleEventObject& rEvent ) const;
     166                 :            : 
     167                 :            :         void SetFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException));
     168                 :            :         sal_Bool HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException));
     169                 :            :         void SetChildFocus( sal_Int32 nChild, sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException));
     170                 :            :         void SetShapeFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException));
     171                 :            :         void ChangeChildFocus( sal_Int32 nNewChild ) SAL_THROW((::com::sun::star::uno::RuntimeException));
     172                 :            : 
     173                 :            : #ifdef DBG_UTIL
     174                 :            :         void CheckInvariants() const;
     175                 :            : #endif
     176                 :            : 
     177                 :            :         // checks all children for visibility, throws away invisible ones
     178                 :            :         void UpdateVisibleChildren( bool bBroadcastEvents=true );
     179                 :            : 
     180                 :            :         // check all children for changes in position and size
     181                 :            :         void UpdateBoundRect();
     182                 :            : 
     183                 :            :         // calls SetSelection on the forwarder and updates maLastSelection
     184                 :            :         // cache.
     185                 :            :         void UpdateSelection();
     186                 :            : 
     187                 :            :     private:
     188                 :            : 
     189                 :            :         // Process event queue
     190                 :            :         void ProcessQueue();
     191                 :            : 
     192                 :            :         // syntactic sugar for FireEvent
     193         [ +  - ]:          2 :         void GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const { FireEvent( nEventId, rNewValue ); }
     194         [ +  - ]:          1 :         void LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const { FireEvent( nEventId, uno::Any(), rOldValue ); }
     195                 :            : 
     196                 :            :         // shutdown usage of current edit source on myself and the children.
     197                 :            :         void ShutdownEditSource() SAL_THROW((uno::RuntimeException));
     198                 :            : 
     199                 :            :         void ParagraphsMoved( sal_Int32 nFirst, sal_Int32 nMiddle, sal_Int32 nLast );
     200                 :            : 
     201                 :            :         virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
     202                 :            : 
     203                 :        117 :         int getNotifierClientId() const { return mnNotifierClientId; }
     204                 :            : 
     205                 :            :         // lock solar mutex before
     206                 :            :         SvxTextForwarder& GetTextForwarder() const SAL_THROW((uno::RuntimeException));
     207                 :            :         // lock solar mutex before
     208                 :            :         SvxViewForwarder& GetViewForwarder() const SAL_THROW((uno::RuntimeException));
     209                 :            :         // lock solar mutex before
     210                 :            :         SvxEditViewForwarder& GetEditViewForwarder( sal_Bool bCreate = sal_False ) const SAL_THROW((uno::RuntimeException));
     211                 :            : 
     212                 :            :         // are we in edit mode?
     213                 :            :         sal_Bool IsActive() const SAL_THROW((uno::RuntimeException));
     214                 :            : 
     215                 :            :         // our frontend class (the one implementing the actual
     216                 :            :         // interface). That's not necessarily the one containing the impl
     217                 :            :         // pointer!
     218                 :            :         uno::Reference< XAccessible > mxFrontEnd;
     219                 :            : 
     220                 :            :         // a wrapper for the text forwarders (guarded by solar mutex)
     221                 :            :         mutable SvxEditSourceAdapter maEditSource;
     222                 :            : 
     223                 :            :         // store last selection (to correctly report selection changes, guarded by solar mutex)
     224                 :            :         ESelection maLastSelection;
     225                 :            : 
     226                 :            :         // cache range of visible children (guarded by solar mutex)
     227                 :            :         sal_Int32 mnFirstVisibleChild;
     228                 :            :         sal_Int32 mnLastVisibleChild;
     229                 :            : 
     230                 :            :         // offset to add to all our children (unguarded, relying on
     231                 :            :         // the fact that sal_Int32 access is atomic)
     232                 :            :         sal_Int32 mnStartIndex;
     233                 :            : 
     234                 :            :         // the object handling our children (guarded by solar mutex)
     235                 :            :         ::accessibility::AccessibleParaManager maParaManager;
     236                 :            : 
     237                 :            :         // number of not-yet-closed event frames (BEGIN/END sequences) (guarded by solar mutex)
     238                 :            :         sal_Int32 maEventOpenFrames;
     239                 :            : 
     240                 :            :         // Queued events from Notify() (guarded by solar mutex)
     241                 :            :         AccessibleTextEventQueue maEventQueue;
     242                 :            : 
     243                 :            :         // spin lock to prevent notify in notify (guarded by solar mutex)
     244                 :            :         sal_Bool mbInNotify;
     245                 :            : 
     246                 :            :         // whether the object or it's children has the focus set (guarded by solar mutex)
     247                 :            :         sal_Bool mbGroupHasFocus;
     248                 :            : 
     249                 :            :         // whether we (this object) has the focus set (guarded by solar mutex)
     250                 :            :         sal_Bool mbThisHasFocus;
     251                 :            : 
     252                 :            :         mutable ::osl::Mutex maMutex;
     253                 :            : 
     254                 :            :         /// our current offset to the containing shape/cell (guarded by maMutex)
     255                 :            :         Point maOffset;
     256                 :            : 
     257                 :            :         /// client Id from AccessibleEventNotifier
     258                 :            :         int mnNotifierClientId;
     259                 :            :     };
     260                 :            : 
     261                 :            :     //------------------------------------------------------------------------
     262                 :            :     //
     263                 :            :     // AccessibleTextHelper_Impl implementation
     264                 :            :     //
     265                 :            :     //------------------------------------------------------------------------
     266                 :            : 
     267                 :         56 :     AccessibleTextHelper_Impl::AccessibleTextHelper_Impl() :
     268                 :            :         mxFrontEnd( NULL ),
     269                 :            :         maLastSelection( EE_PARA_NOT_FOUND,EE_PARA_NOT_FOUND,EE_PARA_NOT_FOUND,EE_PARA_NOT_FOUND ),
     270                 :            :         mnFirstVisibleChild( -1 ),
     271                 :            :         mnLastVisibleChild( -2 ),
     272                 :            :         mnStartIndex( 0 ),
     273                 :            :         maEventOpenFrames( 0 ),
     274                 :            :         mbInNotify( sal_False ),
     275                 :            :         mbGroupHasFocus( sal_False ),
     276                 :            :         mbThisHasFocus( sal_False ),
     277                 :            :         maOffset(0,0),
     278                 :            :         // well, that's strictly exception safe, though not really
     279                 :            :         // robust. We rely on the fact that this member is constructed
     280                 :            :         // last, and that the constructor body is empty, thus no
     281                 :            :         // chance for exceptions once the Id is fetched. Nevertheless,
     282                 :            :         // normally should employ RAII here...
     283 [ +  - ][ +  - ]:         56 :         mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient())
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     284                 :            :     {
     285                 :            :         DBG_CTOR( AccessibleTextHelper_Impl, NULL );
     286                 :            : 
     287                 :            : #ifdef DBG_UTIL
     288                 :            :         OSL_TRACE( "AccessibleTextHelper_Impl received ID: %d", mnNotifierClientId );
     289                 :            : #endif
     290                 :         56 :     }
     291                 :            : 
     292 [ +  - ][ +  - ]:         45 :     AccessibleTextHelper_Impl::~AccessibleTextHelper_Impl()
         [ +  - ][ +  - ]
     293                 :            :     {
     294                 :            :         DBG_DTOR( AccessibleTextHelper_Impl, NULL );
     295                 :            : 
     296         [ +  - ]:         45 :         SolarMutexGuard aGuard;
     297                 :            : 
     298                 :            :         try
     299                 :            :         {
     300                 :            :             // call Dispose here, too, since we've some resources not
     301                 :            :             // automatically freed otherwise
     302         [ +  - ]:         45 :             Dispose();
     303                 :            :         }
     304   [ +  -  #  # ]:         45 :         catch( const uno::Exception& ) {}
     305 [ -  + ][ #  # ]:         90 :     }
     306                 :            : 
     307                 :        216 :     SvxTextForwarder& AccessibleTextHelper_Impl::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
     308                 :            :     {
     309                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     310                 :            : 
     311         [ -  + ]:        216 :         if( !maEditSource.IsValid() )
     312 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd);
     313                 :            : 
     314                 :        216 :         SvxTextForwarder* pTextForwarder = maEditSource.GetTextForwarder();
     315                 :            : 
     316         [ -  + ]:        216 :         if( !pTextForwarder )
     317 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, model might be dead")), mxFrontEnd);
     318                 :            : 
     319         [ +  - ]:        216 :         if( pTextForwarder->IsValid() )
     320                 :        216 :             return *pTextForwarder;
     321                 :            :         else
     322 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, model might be dead")), mxFrontEnd);
     323                 :            :     }
     324                 :            : 
     325                 :         82 :     SvxViewForwarder& AccessibleTextHelper_Impl::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
     326                 :            :     {
     327                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     328                 :            : 
     329         [ -  + ]:         82 :         if( !maEditSource.IsValid() )
     330 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd);
     331                 :            : 
     332                 :         82 :         SvxViewForwarder* pViewForwarder = maEditSource.GetViewForwarder();
     333                 :            : 
     334         [ -  + ]:         82 :         if( !pViewForwarder )
     335 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, model might be dead")), mxFrontEnd);
     336                 :            : 
     337         [ +  - ]:         82 :         if( pViewForwarder->IsValid() )
     338                 :         82 :             return *pViewForwarder;
     339                 :            :         else
     340 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, model might be dead")), mxFrontEnd);
     341                 :            :     }
     342                 :            : 
     343                 :         19 :     SvxEditViewForwarder& AccessibleTextHelper_Impl::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException))
     344                 :            :     {
     345                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     346                 :            : 
     347         [ -  + ]:         19 :         if( !maEditSource.IsValid() )
     348 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd);
     349                 :            : 
     350                 :         19 :         SvxEditViewForwarder* pViewForwarder = maEditSource.GetEditViewForwarder( bCreate );
     351                 :            : 
     352         [ +  + ]:         19 :         if( !pViewForwarder )
     353                 :            :         {
     354         [ -  + ]:         15 :             if( bCreate )
     355 [ #  # ][ #  # ]:          0 :                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch edit view forwarder, model might be dead")), mxFrontEnd);
     356                 :            :             else
     357 [ +  - ][ +  - ]:         15 :                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit view forwarder, object not in edit mode")), mxFrontEnd);
     358                 :            :         }
     359                 :            : 
     360         [ +  - ]:          4 :         if( pViewForwarder->IsValid() )
     361                 :          4 :             return *pViewForwarder;
     362                 :            :         else
     363                 :            :         {
     364         [ #  # ]:          0 :             if( bCreate )
     365 [ #  # ][ #  # ]:          0 :                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, model might be dead")), mxFrontEnd);
     366                 :            :             else
     367 [ #  # ][ #  # ]:          0 :                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")), mxFrontEnd);
     368                 :            :         }
     369                 :            :     }
     370                 :            : 
     371                 :        138 :     SvxEditSourceAdapter& AccessibleTextHelper_Impl::GetEditSource() const SAL_THROW((uno::RuntimeException))
     372                 :            :     {
     373                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     374                 :            : 
     375         [ +  - ]:        138 :         if( maEditSource.IsValid() )
     376                 :        138 :             return maEditSource;
     377                 :            :         else
     378 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::GetEditSource: no edit source")), mxFrontEnd );
     379                 :            :     }
     380                 :            : 
     381                 :          0 :     sal_Bool AccessibleTextHelper_Impl::IsSelected() const
     382                 :            :     {
     383                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     384                 :            : 
     385                 :          0 :         sal_Bool bRet = sal_False;
     386                 :            : 
     387                 :            :         try
     388                 :            :         {
     389                 :          0 :             ESelection aSelection;
     390 [ #  # ][ #  # ]:          0 :             bRet = GetEditViewForwarder().GetSelection( aSelection );
     391                 :            :         }
     392                 :          0 :         catch( const uno::Exception& ) {}
     393                 :            : 
     394         [ #  # ]:          0 :         return bRet;
     395                 :            :     }
     396                 :            : 
     397                 :            :     // functor for sending child events (no stand-alone function, they are maybe not inlined)
     398                 :            :     class AccessibleTextHelper_OffsetChildIndex : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
     399                 :            :     {
     400                 :            :     public:
     401                 :          0 :         AccessibleTextHelper_OffsetChildIndex( sal_Int32 nDifference ) : mnDifference(nDifference) {}
     402                 :          0 :         void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
     403                 :            :         {
     404                 :          0 :             rPara.SetIndexInParent( rPara.GetIndexInParent() + mnDifference );
     405                 :          0 :         }
     406                 :            : 
     407                 :            :     private:
     408                 :            :         const sal_Int32 mnDifference;
     409                 :            :     };
     410                 :            : 
     411                 :          0 :     void AccessibleTextHelper_Impl::SetStartIndex( sal_Int32 nOffset )
     412                 :            :     {
     413                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     414                 :            : 
     415                 :          0 :         sal_Int32 nOldOffset( mnStartIndex );
     416                 :            : 
     417                 :          0 :         mnStartIndex = nOffset;
     418                 :            : 
     419         [ #  # ]:          0 :         if( nOldOffset != nOffset )
     420                 :            :         {
     421                 :            :             // update children
     422                 :          0 :             AccessibleTextHelper_OffsetChildIndex aFunctor( nOffset - nOldOffset );
     423                 :            : 
     424                 :            :             ::std::for_each( maParaManager.begin(), maParaManager.end(),
     425 [ #  # ][ #  # ]:          0 :                              AccessibleParaManager::WeakChildAdapter< AccessibleTextHelper_OffsetChildIndex > (aFunctor) );
                 [ #  # ]
     426                 :            :         }
     427                 :          0 :     }
     428                 :            : 
     429                 :         15 :     void AccessibleTextHelper_Impl::SetAdditionalChildStates( const VectorOfStates& rChildStates )
     430                 :            :     {
     431                 :         15 :         maParaManager.SetAdditionalChildStates( rChildStates );
     432                 :         15 :     }
     433                 :            : 
     434                 :          0 :     void AccessibleTextHelper_Impl::SetChildFocus( sal_Int32 nChild, sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
     435                 :            :     {
     436                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     437                 :            : 
     438         [ #  # ]:          0 :         if( bHaveFocus )
     439                 :            :         {
     440         [ #  # ]:          0 :             if( mbThisHasFocus )
     441                 :          0 :                 SetShapeFocus( sal_False );
     442                 :            : 
     443                 :          0 :             maParaManager.SetFocus( nChild );
     444                 :            : 
     445                 :            :             // we just received the focus, also send caret event then
     446                 :          0 :             UpdateSelection();
     447                 :            : 
     448                 :            :             OSL_TRACE("AccessibleTextHelper_Impl::SetChildFocus(): Paragraph %d received focus", nChild );
     449                 :            :         }
     450                 :            :         else
     451                 :            :         {
     452                 :          0 :             maParaManager.SetFocus( -1 );
     453                 :            : 
     454                 :            :             OSL_TRACE("AccessibleTextHelper_Impl::SetChildFocus(): Paragraph %d lost focus", nChild );
     455                 :            : 
     456         [ #  # ]:          0 :             if( mbGroupHasFocus )
     457                 :          0 :                 SetShapeFocus( sal_True );
     458                 :            :         }
     459                 :          0 :     }
     460                 :            : 
     461                 :          0 :     void AccessibleTextHelper_Impl::ChangeChildFocus( sal_Int32 nNewChild ) SAL_THROW((::com::sun::star::uno::RuntimeException))
     462                 :            :     {
     463                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     464                 :            : 
     465         [ #  # ]:          0 :         if( mbThisHasFocus )
     466                 :          0 :             SetShapeFocus( sal_False );
     467                 :            : 
     468                 :          0 :         mbGroupHasFocus = sal_True;
     469                 :          0 :         maParaManager.SetFocus( nNewChild );
     470                 :            : 
     471                 :            :         OSL_TRACE("AccessibleTextHelper_Impl::ChangeChildFocus(): Paragraph %d received focus", nNewChild );
     472                 :          0 :     }
     473                 :            : 
     474                 :          2 :     void AccessibleTextHelper_Impl::SetShapeFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
     475                 :            :     {
     476                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     477                 :            : 
     478                 :          2 :         sal_Bool bOldFocus( mbThisHasFocus );
     479                 :            : 
     480                 :          2 :         mbThisHasFocus = bHaveFocus;
     481                 :            : 
     482         [ +  - ]:          2 :         if( bOldFocus != bHaveFocus )
     483                 :            :         {
     484         [ +  - ]:          2 :             if( bHaveFocus )
     485                 :            :             {
     486         [ +  - ]:          2 :                 GotPropertyEvent( uno::makeAny(AccessibleStateType::FOCUSED), AccessibleEventId::STATE_CHANGED );
     487                 :            :                 OSL_TRACE("AccessibleTextHelper_Impl::SetShapeFocus(): Parent object received focus" );
     488                 :            :             }
     489                 :            :             else
     490                 :            :             {
     491         [ #  # ]:          0 :                 LostPropertyEvent( uno::makeAny(AccessibleStateType::FOCUSED), AccessibleEventId::STATE_CHANGED );
     492                 :            :                 OSL_TRACE("AccessibleTextHelper_Impl::SetShapeFocus(): Parent object lost focus" );
     493                 :            :             }
     494                 :            :         }
     495                 :          2 :     }
     496                 :            : 
     497                 :          2 :     void AccessibleTextHelper_Impl::SetFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
     498                 :            :     {
     499                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     500                 :            : 
     501                 :          2 :         sal_Bool bOldFocus( mbGroupHasFocus );
     502                 :            : 
     503                 :          2 :         mbGroupHasFocus = bHaveFocus;
     504                 :            : 
     505         [ -  + ]:          2 :         if( IsActive() )
     506                 :            :         {
     507                 :            :             try
     508                 :            :             {
     509                 :            :                 // find the one with the cursor and get/set focus accordingly
     510                 :          0 :                 ESelection aSelection;
     511 [ #  # ][ #  # ]:          0 :                 if( GetEditViewForwarder().GetSelection( aSelection ) )
                 [ #  # ]
     512         [ #  # ]:          0 :                     SetChildFocus( aSelection.nEndPara, bHaveFocus );
     513                 :            :             }
     514                 :          0 :             catch( const uno::Exception& ) {}
     515                 :            :         }
     516         [ +  - ]:          2 :         else if( bOldFocus != bHaveFocus )
     517                 :            :         {
     518                 :          2 :             SetShapeFocus( bHaveFocus );
     519                 :            :         }
     520                 :            : 
     521                 :            :         OSL_TRACE("AccessibleTextHelper_Impl::SetFocus: focus changed, Object %d, state: %s", this, bHaveFocus ? "focused" : "not focused");
     522         [ #  # ]:          2 :     }
     523                 :            : 
     524                 :         12 :     sal_Bool AccessibleTextHelper_Impl::HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException))
     525                 :            :     {
     526                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     527                 :            : 
     528                 :            :         // No locking of solar mutex here, since we rely on the fact
     529                 :            :         // that sal_Bool access is atomic
     530                 :         12 :         return mbThisHasFocus;
     531                 :            :     }
     532                 :            : 
     533                 :         78 :     sal_Bool AccessibleTextHelper_Impl::IsActive() const SAL_THROW((uno::RuntimeException))
     534                 :            :     {
     535                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     536                 :            : 
     537                 :            :         try
     538                 :            :         {
     539         [ +  - ]:         78 :             SvxEditSource& rEditSource = GetEditSource();
     540         [ +  - ]:         78 :             SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
     541                 :            : 
     542         [ +  + ]:         78 :             if( !pViewForwarder )
     543                 :         74 :                 return sal_False;
     544                 :            : 
     545 [ +  - ][ +  - ]:          4 :             if( pViewForwarder->IsValid() )
     546                 :          4 :                 return sal_True;
     547                 :            :             else
     548         [ #  # ]:         78 :                 return sal_False;
     549                 :            :         }
     550                 :          0 :         catch( const uno::RuntimeException& )
     551                 :            :         {
     552                 :          0 :             return sal_False;
     553                 :            :         }
     554                 :            :     }
     555                 :            : 
     556                 :         15 :     void AccessibleTextHelper_Impl::UpdateSelection()
     557                 :            :     {
     558                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     559                 :            : 
     560                 :            :         try
     561                 :            :         {
     562                 :         15 :             ESelection aSelection;
     563 [ #  # ][ #  # ]:         15 :             if( GetEditViewForwarder().GetSelection( aSelection ) )
                 [ -  + ]
     564                 :            :             {
     565 [ #  # ][ #  # ]:          0 :                 if( !maLastSelection.IsEqual( aSelection ) &&
                 [ #  # ]
     566         [ #  # ]:          0 :                     aSelection.nEndPara < maParaManager.GetNum() )
     567                 :            :                 {
     568                 :            :                     // #103998# Not that important, changed from assertion to trace
     569                 :          0 :                     if( mbThisHasFocus )
     570                 :            :                     {
     571                 :            :                         OSL_TRACE("AccessibleTextHelper_Impl::UpdateSelection(): Parent has focus!");
     572                 :            :                     }
     573                 :            : 
     574 [ #  # ][ #  # ]:          0 :                     sal_uInt16 nMaxValidParaIndex( static_cast< sal_uInt16 >( GetTextForwarder().GetParagraphCount() ) - 1 );
     575                 :            : 
     576                 :            :                     // notify all affected paragraphs (TODO: may be suboptimal,
     577                 :            :                     // since some paragraphs might stay selected)
     578         [ #  # ]:          0 :                     if( maLastSelection.nStartPara != EE_PARA_NOT_FOUND )
     579                 :            :                     {
     580                 :            :                         // Did the caret move from one paragraph to another?
     581                 :            :                         // #100530# no caret events if not focused.
     582 [ #  # ][ #  # ]:          0 :                         if( mbGroupHasFocus &&
     583                 :            :                             maLastSelection.nEndPara != aSelection.nEndPara )
     584                 :            :                         {
     585 [ #  # ][ #  # ]:          0 :                             if( maLastSelection.nEndPara < maParaManager.GetNum() )
     586                 :            :                             {
     587         [ #  # ]:          0 :                                 maParaManager.FireEvent( ::std::min( maLastSelection.nEndPara, nMaxValidParaIndex ),
     588         [ #  # ]:          0 :                                                          ::std::min( maLastSelection.nEndPara, nMaxValidParaIndex )+1,
     589                 :            :                                                          AccessibleEventId::CARET_CHANGED,
     590                 :            :                                                          uno::makeAny(static_cast<sal_Int32>(-1)),
     591 [ #  # ][ #  # ]:          0 :                                                          uno::makeAny(static_cast<sal_Int32>(maLastSelection.nEndPos)) );
                 [ #  # ]
     592                 :            :                             }
     593                 :            : 
     594         [ #  # ]:          0 :                             ChangeChildFocus( aSelection.nEndPara );
     595                 :            : 
     596                 :            :                             OSL_TRACE("AccessibleTextHelper_Impl::UpdateSelection(): focus changed, Object: %d, Paragraph: %d, Last paragraph: %d",
     597                 :            :                                        this, aSelection.nEndPara, maLastSelection.nEndPara);
     598                 :            :                         }
     599                 :            :                     }
     600                 :            : 
     601                 :            :                     // #100530# no caret events if not focused.
     602         [ #  # ]:          0 :                     if( mbGroupHasFocus )
     603                 :            :                     {
     604                 :          0 :                         uno::Any aOldCursor;
     605                 :            : 
     606                 :            :                         // #i13705# The old cursor can only contain valid
     607                 :            :                         // values if it's the same paragraph!
     608 [ #  # ][ #  # ]:          0 :                         if( maLastSelection.nStartPara != EE_PARA_NOT_FOUND &&
     609                 :            :                             maLastSelection.nEndPara == aSelection.nEndPara )
     610                 :            :                         {
     611         [ #  # ]:          0 :                             aOldCursor <<= static_cast<sal_Int32>(maLastSelection.nEndPos);
     612                 :            :                         }
     613                 :            :                         else
     614                 :            :                         {
     615         [ #  # ]:          0 :                             aOldCursor <<= static_cast<sal_Int32>(-1);
     616                 :            :                         }
     617                 :            : 
     618                 :            :                         maParaManager.FireEvent( aSelection.nEndPara,
     619                 :            :                                                  aSelection.nEndPara+1,
     620                 :            :                                                  AccessibleEventId::CARET_CHANGED,
     621                 :            :                                                  uno::makeAny(static_cast<sal_Int32>(aSelection.nEndPos)),
     622 [ #  # ][ #  # ]:          0 :                                                  aOldCursor );
     623                 :            :                     }
     624                 :            : 
     625                 :            :                     OSL_TRACE("AccessibleTextHelper_Impl::UpdateSelection(): caret changed, Object: %d, New pos: %d, Old pos: %d, New para: %d, Old para: %d",
     626                 :            :                                this, aSelection.nEndPos, maLastSelection.nEndPos, aSelection.nEndPara, maLastSelection.nEndPara);
     627                 :            : 
     628                 :            :                     // #108947# Sort new range before calling FireEvent
     629                 :            :                     ::std::pair< xub_StrLen, xub_StrLen > sortedSelection(
     630         [ #  # ]:          0 :                         makeSortedPair(::std::min( aSelection.nStartPara, nMaxValidParaIndex ),
     631 [ #  # ][ #  # ]:          0 :                                        ::std::min( aSelection.nEndPara, nMaxValidParaIndex ) ) );
     632                 :            : 
     633                 :            :                     // #108947# Sort last range before calling FireEvent
     634                 :            :                     ::std::pair< xub_StrLen, xub_StrLen > sortedLastSelection(
     635         [ #  # ]:          0 :                         makeSortedPair(::std::min( maLastSelection.nStartPara, nMaxValidParaIndex ),
     636 [ #  # ][ #  # ]:          0 :                                        ::std::min( maLastSelection.nEndPara, nMaxValidParaIndex ) ) );
     637                 :            : 
     638                 :            :                     // event TEXT_SELECTION_CHANGED has to be submitted. (#i27299#)
     639                 :            :                     const sal_Int16 nTextSelChgEventId =
     640                 :          0 :                                     AccessibleEventId::TEXT_SELECTION_CHANGED;
     641                 :            :                     // #107037# notify selection change
     642         [ #  # ]:          0 :                     if( maLastSelection.nStartPara == EE_PARA_NOT_FOUND )
     643                 :            :                     {
     644                 :            :                         // last selection is undefined
     645                 :            :                         // use method <ESelection::HasRange()> (#i27299#)
     646         [ #  # ]:          0 :                         if ( aSelection.HasRange() )
     647                 :            :                         {
     648                 :            :                             // selection was undefined, now is on
     649                 :            :                             maParaManager.FireEvent( sortedSelection.first,
     650                 :            :                                                      sortedSelection.second+1,
     651         [ #  # ]:          0 :                                                      nTextSelChgEventId );
     652                 :            :                         }
     653                 :            :                     }
     654                 :            :                     else
     655                 :            :                     {
     656                 :            :                         // last selection is valid
     657                 :            :                         // use method <ESelection::HasRange()> (#i27299#)
     658   [ #  #  #  # ]:          0 :                         if ( maLastSelection.HasRange() &&
                 [ #  # ]
     659                 :          0 :                              !aSelection.HasRange() )
     660                 :            :                         {
     661                 :            :                             // selection was on, now is empty
     662                 :            :                             maParaManager.FireEvent( sortedLastSelection.first,
     663                 :            :                                                      sortedLastSelection.second+1,
     664         [ #  # ]:          0 :                                                      nTextSelChgEventId );
     665                 :            :                         }
     666                 :            :                         // use method <ESelection::HasRange()> (#i27299#)
     667   [ #  #  #  # ]:          0 :                         else if( !maLastSelection.HasRange() &&
                 [ #  # ]
     668                 :          0 :                                  aSelection.HasRange() )
     669                 :            :                         {
     670                 :            :                             // selection was empty, now is on
     671                 :            :                             maParaManager.FireEvent( sortedSelection.first,
     672                 :            :                                                      sortedSelection.second+1,
     673         [ #  # ]:          0 :                                                      nTextSelChgEventId );
     674                 :            :                         }
     675                 :            :                         // no event TEXT_SELECTION_CHANGED event, if new and
     676                 :            :                         // last selection are empty. (#i27299#)
     677   [ #  #  #  # ]:          0 :                         else if ( maLastSelection.HasRange() &&
                 [ #  # ]
     678                 :          0 :                                   aSelection.HasRange() )
     679                 :            :                         {
     680                 :            :                             // use sorted last and new selection
     681                 :          0 :                             ESelection aTmpLastSel( maLastSelection );
     682                 :          0 :                             aTmpLastSel.Adjust();
     683                 :          0 :                             ESelection aTmpSel( aSelection );
     684                 :          0 :                             aTmpSel.Adjust();
     685                 :            :                             // first submit event for new and changed selection
     686                 :          0 :                             sal_uInt32 nPara = aTmpSel.nStartPara;
     687         [ #  # ]:          0 :                             for ( ; nPara <= aTmpSel.nEndPara; ++nPara )
     688                 :            :                             {
     689 [ #  # ][ #  # ]:          0 :                                 if ( nPara < aTmpLastSel.nStartPara ||
     690                 :            :                                      nPara > aTmpLastSel.nEndPara )
     691                 :            :                                 {
     692                 :            :                                     // new selection on paragraph <nPara>
     693                 :            :                                     maParaManager.FireEvent( nPara,
     694         [ #  # ]:          0 :                                                              nTextSelChgEventId );
     695                 :            :                                 }
     696                 :            :                                 else
     697                 :            :                                 {
     698                 :            :                                     // check for changed selection on paragraph <nPara>
     699                 :            :                                     const xub_StrLen nParaStartPos =
     700                 :            :                                             nPara == aTmpSel.nStartPara
     701         [ #  # ]:          0 :                                             ? aTmpSel.nStartPos : 0;
     702                 :            :                                     const xub_StrLen nParaEndPos =
     703                 :            :                                             nPara == aTmpSel.nEndPara
     704         [ #  # ]:          0 :                                             ? aTmpSel.nEndPos : STRING_LEN;
     705                 :            :                                     const xub_StrLen nLastParaStartPos =
     706                 :            :                                             nPara == aTmpLastSel.nStartPara
     707         [ #  # ]:          0 :                                             ? aTmpLastSel.nStartPos : 0;
     708                 :            :                                     const xub_StrLen nLastParaEndPos =
     709                 :            :                                             nPara == aTmpLastSel.nEndPara
     710         [ #  # ]:          0 :                                             ? aTmpLastSel.nEndPos : STRING_LEN;
     711 [ #  # ][ #  # ]:          0 :                                     if ( nParaStartPos != nLastParaStartPos ||
     712                 :            :                                          nParaEndPos != nLastParaEndPos )
     713                 :            :                                     {
     714                 :            :                                         maParaManager.FireEvent(
     715         [ #  # ]:          0 :                                                     nPara, nTextSelChgEventId );
     716                 :            :                                     }
     717                 :            :                                 }
     718                 :            :                             }
     719                 :            :                             // second submit event for 'old' selections
     720                 :          0 :                             nPara = aTmpLastSel.nStartPara;
     721         [ #  # ]:          0 :                             for ( ; nPara <= aTmpLastSel.nEndPara; ++nPara )
     722                 :            :                             {
     723 [ #  # ][ #  # ]:          0 :                                 if ( nPara < aTmpSel.nStartPara ||
     724                 :            :                                      nPara > aTmpSel.nEndPara )
     725                 :            :                                 {
     726                 :            :                                     maParaManager.FireEvent( nPara,
     727 [ #  # ][ -  + ]:         15 :                                                              nTextSelChgEventId );
     728                 :            :                                 }
     729                 :            :                             }
     730                 :            :                         }
     731                 :            :                     }
     732                 :            : 
     733                 :          0 :                     maLastSelection = aSelection;
     734                 :            :                 }
     735                 :            :             }
     736                 :            :         }
     737                 :            :         // no selection? no update actions
     738                 :         15 :         catch( const uno::RuntimeException& ) {}
     739                 :         15 :     }
     740                 :            : 
     741                 :         60 :     void AccessibleTextHelper_Impl::ShutdownEditSource() SAL_THROW((uno::RuntimeException))
     742                 :            :     {
     743                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     744                 :            : 
     745                 :            :         // This should only be called with solar mutex locked, i.e. from the main office thread
     746                 :            : 
     747                 :            :         // This here is somewhat clumsy: As soon as our children have
     748                 :            :         // a NULL EditSource (maParaManager.SetEditSource()), they
     749                 :            :         // enter the disposed state and cannot be reanimated. Thus, it
     750                 :            :         // is unavoidable and a hard requirement to let go and create
     751                 :            :         // from scratch each and every child.
     752                 :            : 
     753                 :            :         // invalidate children
     754                 :         60 :         maParaManager.Dispose();
     755                 :         60 :         maParaManager.SetNum(0);
     756                 :            : 
     757                 :            :         // lost all children
     758         [ +  + ]:         60 :         if( mxFrontEnd.is() )
     759         [ +  - ]:          4 :             FireEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN);
     760                 :            : 
     761                 :            :         // quit listen on stale edit source
     762         [ +  + ]:         60 :         if( maEditSource.IsValid() )
     763                 :          4 :             EndListening( maEditSource.GetBroadcaster() );
     764                 :            : 
     765                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     766 [ +  - ][ +  - ]:         60 :         maEditSource.SetEditSource( ::std::auto_ptr< SvxEditSource >(NULL) );
     767                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
     768                 :         60 :     }
     769                 :            : 
     770                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     771                 :         60 :     void AccessibleTextHelper_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
     772                 :            :     {
     773                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     774                 :            : 
     775                 :            :         // This should only be called with solar mutex locked, i.e. from the main office thread
     776                 :            : 
     777                 :            :         // shutdown old edit source
     778                 :         60 :         ShutdownEditSource();
     779                 :            : 
     780                 :            :         // set new edit source
     781         [ +  - ]:         60 :         maEditSource.SetEditSource( pEditSource );
     782                 :            : 
     783                 :            :         // init child vector to the current child count
     784         [ +  + ]:         60 :         if( maEditSource.IsValid() )
     785                 :            :         {
     786                 :         56 :             maParaManager.SetNum( GetTextForwarder().GetParagraphCount() );
     787                 :            : 
     788                 :            :             // listen on new edit source
     789                 :         56 :             StartListening( maEditSource.GetBroadcaster() );
     790                 :            : 
     791                 :         56 :             UpdateVisibleChildren();
     792                 :            :         }
     793                 :         60 :     }
     794                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     795                 :            : 
     796                 :          0 :     void AccessibleTextHelper_Impl::SetOffset( const Point& rPoint )
     797                 :            :     {
     798                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     799                 :            : 
     800                 :            :         // guard against non-atomic access to maOffset data structure
     801                 :            :         {
     802         [ #  # ]:          0 :             ::osl::MutexGuard aGuard( maMutex );
     803         [ #  # ]:          0 :             maOffset = rPoint;
     804                 :            :         }
     805                 :            : 
     806                 :          0 :         maParaManager.SetEEOffset( rPoint );
     807                 :            : 
     808                 :            :         // in all cases, check visibility afterwards.
     809                 :          0 :         UpdateVisibleChildren();
     810                 :          0 :         UpdateBoundRect();
     811                 :          0 :     }
     812                 :            : 
     813                 :         76 :     void AccessibleTextHelper_Impl::UpdateVisibleChildren( bool bBroadcastEvents )
     814                 :            :     {
     815                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     816                 :            : 
     817                 :            :         try
     818                 :            :         {
     819         [ +  - ]:         76 :             SvxTextForwarder& rCacheTF = GetTextForwarder();
     820         [ +  - ]:         76 :             SvxViewForwarder& rCacheVF = GetViewForwarder();
     821                 :            : 
     822         [ +  - ]:         76 :             Rectangle aViewArea = rCacheVF.GetVisArea();
     823                 :            : 
     824 [ +  - ][ +  + ]:         76 :             if( IsActive() )
     825                 :            :             {
     826                 :            :                 // maybe the edit view scrolls, adapt aViewArea
     827 [ +  - ][ +  - ]:          4 :                 Rectangle aEditViewArea = GetEditViewForwarder().GetVisArea();
     828         [ +  - ]:          4 :                 aViewArea += aEditViewArea.TopLeft();
     829                 :            : 
     830                 :            :                 // now determine intersection
     831         [ +  - ]:          4 :                 aViewArea.Intersection( aEditViewArea );
     832                 :            :             }
     833                 :            : 
     834 [ +  - ][ +  - ]:         76 :             Rectangle aTmpBB, aParaBB;
     835                 :         76 :             sal_Bool bFirstChild = sal_True;
     836                 :            :             sal_Int32 nCurrPara;
     837         [ +  - ]:         76 :             sal_Int32 nParas=rCacheTF.GetParagraphCount();
     838                 :            : 
     839                 :         76 :             mnFirstVisibleChild = -1;
     840                 :         76 :             mnLastVisibleChild = -2;
     841                 :            : 
     842         [ +  + ]:        152 :             for( nCurrPara=0; nCurrPara<nParas; ++nCurrPara )
     843                 :            :             {
     844                 :            :                 DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX,
     845                 :            :                            "AccessibleTextHelper_Impl::UpdateVisibleChildren: index value overflow");
     846                 :            : 
     847         [ +  - ]:         76 :                 aTmpBB = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( nCurrPara ) );
     848                 :            : 
     849                 :            :                 // convert to screen coordinates
     850 [ +  - ][ +  - ]:         76 :                 aParaBB = ::accessibility::AccessibleEditableTextPara::LogicToPixel( aTmpBB, rCacheTF.GetMapMode(), rCacheVF );
                 [ +  - ]
     851                 :            : 
     852 [ +  - ][ +  + ]:         76 :                 if( aParaBB.IsOver( aViewArea ) )
     853                 :            :                 {
     854                 :            :                     // at least partially visible
     855         [ +  - ]:         63 :                     if( bFirstChild )
     856                 :            :                     {
     857                 :         63 :                         bFirstChild = sal_False;
     858                 :         63 :                         mnFirstVisibleChild = nCurrPara;
     859                 :            :                     }
     860                 :            : 
     861                 :         63 :                     mnLastVisibleChild = nCurrPara;
     862                 :            : 
     863                 :            :                     // child not yet created?
     864         [ +  - ]:         63 :                     ::accessibility::AccessibleParaManager::WeakChild aChild( maParaManager.GetChild(nCurrPara) );
     865         [ +  + ]:        116 :                     if( aChild.second.Width == 0 &&
           [ +  -  -  + ]
         [ #  # ][ -  + ]
     866                 :            :                         aChild.second.Height == 0 &&
     867                 :         53 :                         mxFrontEnd.is() &&
     868                 :            :                         bBroadcastEvents )
     869                 :            :                     {
     870                 :            :                         GotPropertyEvent( uno::makeAny( maParaManager.CreateChild( nCurrPara - mnFirstVisibleChild,
     871         [ #  # ]:          0 :                                                                                    mxFrontEnd, GetEditSource(), nCurrPara ).first ),
     872 [ #  # ][ #  # ]:          0 :                                           AccessibleEventId::CHILD );
         [ #  # ][ #  # ]
     873         [ +  - ]:         63 :                     }
     874                 :            :                 }
     875                 :            :                 else
     876                 :            :                 {
     877                 :            :                     // not or no longer visible
     878 [ +  - ][ +  + ]:         13 :                     if( maParaManager.IsReferencable( nCurrPara ) )
     879                 :            :                     {
     880         [ +  - ]:          1 :                         if( bBroadcastEvents )
     881 [ +  - ][ +  - ]:          2 :                             LostPropertyEvent( uno::makeAny( maParaManager.GetChild( nCurrPara ).first.get().getRef() ),
         [ +  - ][ +  - ]
     882 [ +  - ][ +  - ]:          1 :                                                AccessibleEventId::CHILD );
     883                 :            : 
     884                 :            :                         // clear reference
     885         [ +  - ]:          1 :                         maParaManager.Release( nCurrPara );
     886                 :            :                     }
     887                 :            :                 }
     888                 :            :             }
     889                 :            :         }
     890         [ #  # ]:          0 :         catch( const uno::Exception& )
     891                 :            :         {
     892                 :            :             OSL_FAIL("AccessibleTextHelper_Impl::UpdateVisibleChildren error while determining visible children");
     893                 :            : 
     894                 :            :             // something failed - currently no children
     895                 :          0 :             mnFirstVisibleChild = -1;
     896                 :          0 :             mnLastVisibleChild = -2;
     897         [ #  # ]:          0 :             maParaManager.SetNum(0);
     898                 :            : 
     899                 :            :             // lost all children
     900         [ #  # ]:          0 :             if( bBroadcastEvents )
     901         [ #  # ]:          0 :                 FireEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN);
     902                 :            :         }
     903                 :         76 :     }
     904                 :            : 
     905                 :            :     // functor for checking changes in paragraph bounding boxes (no stand-alone function, maybe not inlined)
     906                 :            :     class AccessibleTextHelper_UpdateChildBounds : public ::std::unary_function< const ::accessibility::AccessibleParaManager::WeakChild&,
     907                 :            :         ::accessibility::AccessibleParaManager::WeakChild >
     908                 :            :     {
     909                 :            :     public:
     910                 :         20 :         AccessibleTextHelper_UpdateChildBounds( AccessibleTextHelper_Impl& rImpl ) : mrImpl(rImpl) {}
     911                 :         20 :         ::accessibility::AccessibleParaManager::WeakChild operator()( const ::accessibility::AccessibleParaManager::WeakChild& rChild )
     912                 :            :         {
     913                 :            :             // retrieve hard reference from weak one
     914         [ +  - ]:         20 :             ::accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( rChild.first.get() );
     915                 :            : 
     916         [ +  + ]:         20 :             if( aHardRef.is() )
     917                 :            :             {
     918         [ +  - ]:         10 :                 awt::Rectangle          aNewRect = aHardRef->getBounds();
     919                 :         10 :                 const awt::Rectangle&   aOldRect = rChild.second;
     920                 :            : 
     921 [ +  - ][ +  - ]:         10 :                 if( aNewRect.X != aOldRect.X ||
         [ +  + ][ -  + ]
     922                 :            :                     aNewRect.Y != aOldRect.Y ||
     923                 :            :                     aNewRect.Width != aOldRect.Width ||
     924                 :            :                     aNewRect.Height != aOldRect.Height )
     925                 :            :                 {
     926                 :            :                     // visible data changed
     927         [ +  - ]:          4 :                     aHardRef->FireEvent( AccessibleEventId::BOUNDRECT_CHANGED );
     928                 :            : 
     929                 :            :                     // update internal bounds
     930         [ +  - ]:         10 :                     return ::accessibility::AccessibleParaManager::WeakChild( rChild.first, aNewRect );
     931                 :            :                 }
     932                 :            :             }
     933                 :            : 
     934                 :            :             // identity transform
     935 [ +  - ][ +  - ]:         20 :             return rChild;
     936                 :            :         }
     937                 :            : 
     938                 :            :     private:
     939                 :            :         AccessibleTextHelper_Impl&  mrImpl;
     940                 :            :     };
     941                 :            : 
     942                 :         20 :     void AccessibleTextHelper_Impl::UpdateBoundRect()
     943                 :            :     {
     944                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     945                 :            : 
     946                 :            :         // send BOUNDRECT_CHANGED to affected children
     947                 :         20 :         AccessibleTextHelper_UpdateChildBounds aFunctor( *this );
     948 [ +  - ][ +  - ]:         20 :         ::std::transform( maParaManager.begin(), maParaManager.end(), maParaManager.begin(), aFunctor );
         [ +  - ][ +  - ]
     949                 :         20 :     }
     950                 :            : 
     951                 :            : #ifdef DBG_UTIL
     952                 :            :     void AccessibleTextHelper_Impl::CheckInvariants() const
     953                 :            :     {
     954                 :            :         if( mnFirstVisibleChild >= 0 &&
     955                 :            :             mnFirstVisibleChild > mnLastVisibleChild )
     956                 :            :         {
     957                 :            :             OSL_FAIL( "AccessibleTextHelper: range invalid" );
     958                 :            :         }
     959                 :            :     }
     960                 :            : #endif
     961                 :            : 
     962                 :            :     // functor for sending child events (no stand-alone function, they are maybe not inlined)
     963                 :            :     class AccessibleTextHelper_LostChildEvent : public ::std::unary_function< const ::accessibility::AccessibleParaManager::WeakChild&, void >
     964                 :            :     {
     965                 :            :     public:
     966                 :          0 :         AccessibleTextHelper_LostChildEvent( AccessibleTextHelper_Impl& rImpl ) : mrImpl(rImpl) {}
     967                 :          0 :         void operator()( const ::accessibility::AccessibleParaManager::WeakChild& rPara )
     968                 :            :         {
     969                 :            :             // retrieve hard reference from weak one
     970         [ #  # ]:          0 :             ::accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( rPara.first.get() );
     971                 :            : 
     972         [ #  # ]:          0 :             if( aHardRef.is() )
     973 [ #  # ][ #  # ]:          0 :                 mrImpl.FireEvent(AccessibleEventId::CHILD, uno::Any(), uno::makeAny( aHardRef.getRef() ) );
                 [ #  # ]
     974                 :          0 :         }
     975                 :            : 
     976                 :            :     private:
     977                 :            :         AccessibleTextHelper_Impl&  mrImpl;
     978                 :            :     };
     979                 :            : 
     980                 :          0 :     void AccessibleTextHelper_Impl::ParagraphsMoved( sal_Int32 nFirst, sal_Int32 nMiddle, sal_Int32 nLast )
     981                 :            :     {
     982                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
     983                 :            : 
     984                 :          0 :         const sal_Int32 nParas = GetTextForwarder().GetParagraphCount();
     985                 :            : 
     986                 :            :         /* rotate paragraphs
     987                 :            :          * =================
     988                 :            :          *
     989                 :            :          * Three cases:
     990                 :            :          *
     991                 :            :          * 1.
     992                 :            :          *   ... nParagraph ... nParam1 ... nParam2 ...
     993                 :            :          *       |______________[xxxxxxxxxxx]
     994                 :            :          *              becomes
     995                 :            :          *       [xxxxxxxxxxx]|______________
     996                 :            :          *
     997                 :            :          * tail is 0
     998                 :            :          *
     999                 :            :          * 2.
    1000                 :            :          *   ... nParam1 ... nParagraph ... nParam2 ...
    1001                 :            :          *       [xxxxxxxxxxx|xxxxxxxxxxxxxx]____________
    1002                 :            :          *              becomes
    1003                 :            :          *       ____________[xxxxxxxxxxx|xxxxxxxxxxxxxx]
    1004                 :            :          *
    1005                 :            :          * tail is nParagraph - nParam1
    1006                 :            :          *
    1007                 :            :          * 3.
    1008                 :            :          *   ... nParam1 ... nParam2 ... nParagraph ...
    1009                 :            :          *       [xxxxxxxxxxx]___________|____________
    1010                 :            :          *              becomes
    1011                 :            :          *       ___________|____________[xxxxxxxxxxx]
    1012                 :            :          *
    1013                 :            :          * tail is nParam2 - nParam1
    1014                 :            :          */
    1015                 :            : 
    1016                 :            :         // sort nParagraph, nParam1 and nParam2 in ascending order, calc range
    1017         [ #  # ]:          0 :         if( nMiddle < nFirst )
    1018                 :            :         {
    1019                 :          0 :             ::std::swap(nFirst, nMiddle);
    1020                 :            :         }
    1021         [ #  # ]:          0 :         else if( nMiddle < nLast )
    1022                 :            :         {
    1023                 :          0 :             nLast = nLast + nMiddle - nFirst;
    1024                 :            :         }
    1025                 :            :         else
    1026                 :            :         {
    1027                 :          0 :             ::std::swap(nMiddle, nLast);
    1028                 :          0 :             nLast = nLast + nMiddle - nFirst;
    1029                 :            :         }
    1030                 :            : 
    1031 [ #  # ][ #  # ]:          0 :         if( nFirst < nParas && nMiddle < nParas && nLast < nParas )
                 [ #  # ]
    1032                 :            :         {
    1033                 :            :             // since we have no "paragraph index
    1034                 :            :             // changed" event on UAA, remove
    1035                 :            :             // [first,last] and insert again later (in
    1036                 :            :             // UpdateVisibleChildren)
    1037                 :            : 
    1038                 :            :             // maParaManager.Rotate( nFirst, nMiddle, nLast );
    1039                 :            : 
    1040                 :            :             // send CHILD_EVENT to affected children
    1041 [ #  # ][ #  # ]:          0 :             ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin();
    1042                 :          0 :             ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin;
    1043                 :            : 
    1044         [ #  # ]:          0 :             ::std::advance( begin, nFirst );
    1045         [ #  # ]:          0 :             ::std::advance( end, nLast+1 );
    1046                 :            : 
    1047                 :            :             // TODO: maybe optimize here in the following way.  If the
    1048                 :            :             // number of removed children exceeds a certain threshold,
    1049                 :            :             // use INVALIDATE_CHILDREN
    1050                 :          0 :             AccessibleTextHelper_LostChildEvent aFunctor( *this );
    1051                 :            : 
    1052         [ #  # ]:          0 :             ::std::for_each( begin, end, aFunctor );
    1053                 :            : 
    1054         [ #  # ]:          0 :             maParaManager.Release(nFirst, nLast+1);
    1055                 :            :             // should be no need for UpdateBoundRect, since all affected children are cleared.
    1056                 :            :         }
    1057                 :          0 :     }
    1058                 :            : 
    1059                 :            :     // functor for sending child events (no stand-alone function, they are maybe not inlined)
    1060                 :            :     class AccessibleTextHelper_ChildrenTextChanged : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
    1061                 :            :     {
    1062                 :            :     public:
    1063                 :          0 :         void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
    1064                 :            :         {
    1065                 :          0 :             rPara.TextChanged();
    1066                 :          0 :         }
    1067                 :            :     };
    1068                 :            : 
    1069                 :            :     /** functor processing queue events
    1070                 :            : 
    1071                 :            :         Reacts on TEXT_HINT_PARAINSERTED/REMOVED events and stores
    1072                 :            :         their content
    1073                 :            :      */
    1074                 :            :     class AccessibleTextHelper_QueueFunctor : public ::std::unary_function< const SfxHint*, void >
    1075                 :            :     {
    1076                 :            :     public:
    1077                 :          9 :         AccessibleTextHelper_QueueFunctor() :
    1078                 :            :             mnParasChanged( 0 ),
    1079                 :            :             mnParaIndex(-1),
    1080                 :          9 :             mnHintId(-1)
    1081                 :          9 :         {}
    1082                 :          9 :         void operator()( const SfxHint* pEvent )
    1083                 :            :         {
    1084 [ +  - ][ +  - ]:          9 :             if( pEvent &&
    1085                 :            :                 mnParasChanged != -1 )
    1086                 :            :             {
    1087                 :            :                 // determine hint type
    1088 [ +  - ][ +  + ]:          9 :                 const TextHint* pTextHint = PTR_CAST( TextHint, pEvent );
    1089 [ +  - ][ -  + ]:          9 :                 const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, pEvent );
    1090                 :            : 
    1091 [ +  - ][ +  +  :         19 :                 if( !pEditSourceHint && pTextHint &&
             +  -  -  + ]
                 [ -  + ]
    1092                 :          5 :                     (pTextHint->GetId() == TEXT_HINT_PARAINSERTED ||
    1093                 :          5 :                      pTextHint->GetId() == TEXT_HINT_PARAREMOVED ) )
    1094                 :            :                 {
    1095         [ #  # ]:          0 :                     if( pTextHint->GetValue() == EE_PARA_ALL )
    1096                 :            :                     {
    1097                 :          0 :                         mnParasChanged = -1;
    1098                 :            :                     }
    1099                 :            :                     else
    1100                 :            :                     {
    1101                 :          0 :                         mnHintId = pTextHint->GetId();
    1102                 :          0 :                         mnParaIndex = pTextHint->GetValue();
    1103                 :          0 :                         ++mnParasChanged;
    1104                 :            :                     }
    1105                 :            :                 }
    1106                 :            :             }
    1107                 :          9 :         }
    1108                 :            : 
    1109                 :            :         /** Query number of paragraphs changed during queue processing.
    1110                 :            : 
    1111                 :            :             @return number of changed paragraphs, -1 for
    1112                 :            :             "every paragraph changed"
    1113                 :            :         */
    1114                 :          0 :         int GetNumberOfParasChanged() { return mnParasChanged; }
    1115                 :            :         /** Query index of last added/removed paragraph
    1116                 :            : 
    1117                 :            :             @return index of lastly added paragraphs, -1 for none
    1118                 :            :             added so far.
    1119                 :            :         */
    1120                 :          0 :         int GetParaIndex() { return mnParaIndex; }
    1121                 :            :         /** Query hint id of last interesting event
    1122                 :            : 
    1123                 :            :             @return hint id of last interesting event (REMOVED/INSERTED).
    1124                 :            :         */
    1125                 :          0 :         int GetHintId() { return mnHintId; }
    1126                 :            : 
    1127                 :            :     private:
    1128                 :            :         /** number of paragraphs changed during queue processing. -1 for
    1129                 :            :             "every paragraph changed"
    1130                 :            :         */
    1131                 :            :         int mnParasChanged;
    1132                 :            :         /// index of paragraph added/removed last
    1133                 :            :         int mnParaIndex;
    1134                 :            :         /// TextHint ID (removed/inserted) of last interesting event
    1135                 :            :         int mnHintId;
    1136                 :            :     };
    1137                 :            : 
    1138                 :          9 :     void AccessibleTextHelper_Impl::ProcessQueue()
    1139                 :            :     {
    1140                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1141                 :            : 
    1142                 :            :         // inspect queue for paragraph insert/remove events. If there
    1143                 :            :         // is exactly _one_ of those in the queue, and the number of
    1144                 :            :         // paragraphs has changed by exactly one, use that event to
    1145                 :            :         // determine a priori which paragraph was added/removed. This
    1146                 :            :         // is necessary, since I must sync right here with the
    1147                 :            :         // EditEngine state (number of paragraphs etc.), since I'm
    1148                 :            :         // potentially sending listener events right away.
    1149                 :          9 :         AccessibleTextHelper_QueueFunctor aFunctor;
    1150         [ +  - ]:          9 :         maEventQueue.ForEach( aFunctor );
    1151                 :            : 
    1152 [ +  - ][ +  - ]:          9 :         const sal_Int32 nNewParas( GetTextForwarder().GetParagraphCount() );
    1153         [ +  - ]:          9 :         const sal_Int32 nCurrParas( maParaManager.GetNum() );
    1154                 :            : 
    1155                 :            :         // whether every paragraph already is updated (no need to
    1156                 :            :         // repeat that later on, e.g. for PARA_MOVED events)
    1157                 :          9 :         bool            bEverythingUpdated( false );
    1158                 :            : 
    1159   [ -  +  #  # ]:          9 :         if( labs( nNewParas - nCurrParas ) == 1 &&
                 [ -  + ]
    1160                 :          0 :             aFunctor.GetNumberOfParasChanged() == 1 )
    1161                 :            :         {
    1162                 :            :             // #103483# Exactly one paragraph added/removed. This is
    1163                 :            :             // the normal case, optimize event handling here.
    1164                 :            : 
    1165         [ #  # ]:          0 :             if( aFunctor.GetHintId() == TEXT_HINT_PARAINSERTED )
    1166                 :            :             {
    1167                 :            :                 // update num of paras
    1168         [ #  # ]:          0 :                 maParaManager.SetNum( nNewParas );
    1169                 :            : 
    1170                 :            :                 // release everything from the insertion position until the end
    1171         [ #  # ]:          0 :                 maParaManager.Release(aFunctor.GetParaIndex(), nCurrParas);
    1172                 :            : 
    1173                 :            :                 // TODO: Clarify whether this behaviour _really_ saves
    1174                 :            :                 // anybody anything!
    1175                 :            :                 // update children, _don't_ broadcast
    1176         [ #  # ]:          0 :                 UpdateVisibleChildren( false );
    1177         [ #  # ]:          0 :                 UpdateBoundRect();
    1178                 :            : 
    1179                 :            :                 // send insert event
    1180                 :            :                 // #109864# Enforce creation of this paragraph
    1181                 :            :                 try
    1182                 :            :                 {
    1183                 :          0 :                     GotPropertyEvent( uno::makeAny( getAccessibleChild( aFunctor.GetParaIndex() -
    1184                 :          0 :                                                                         mnFirstVisibleChild + GetStartIndex() ) ),
    1185 [ #  # ][ #  # ]:          0 :                                       AccessibleEventId::CHILD );
         [ #  # ][ #  # ]
    1186                 :            :                 }
    1187         [ #  # ]:          0 :                 catch( const uno::Exception& )
    1188                 :            :                 {
    1189                 :            :                     OSL_FAIL("AccessibleTextHelper_Impl::ProcessQueue: could not create new paragraph");
    1190                 :            :                 }
    1191                 :            :             }
    1192         [ #  # ]:          0 :             else if( aFunctor.GetHintId() == TEXT_HINT_PARAREMOVED )
    1193                 :            :             {
    1194 [ #  # ][ #  # ]:          0 :                 ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin();
    1195         [ #  # ]:          0 :                 ::std::advance( begin, aFunctor.GetParaIndex() );
    1196                 :          0 :                 ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin;
    1197         [ #  # ]:          0 :                 ::std::advance( end, 1 );
    1198                 :            : 
    1199                 :            :                 // #i61812# remember para to be removed for later notification
    1200                 :            :                 // AFTER the new state is applied (that after the para got removed)
    1201                 :          0 :                 ::uno::Reference< XAccessible > xPara;
    1202         [ #  # ]:          0 :                 ::accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( begin->first.get() );
    1203         [ #  # ]:          0 :                 if( aHardRef.is() )
    1204 [ #  # ][ #  # ]:          0 :                     xPara = ::uno::Reference< XAccessible >( aHardRef.getRef(), ::uno::UNO_QUERY );
    1205                 :            : 
    1206                 :            :                 // release everything from the remove position until the end
    1207         [ #  # ]:          0 :                 maParaManager.Release(aFunctor.GetParaIndex(), nCurrParas);
    1208                 :            : 
    1209                 :            :                 // update num of paras
    1210         [ #  # ]:          0 :                 maParaManager.SetNum( nNewParas );
    1211                 :            : 
    1212                 :            :                 // TODO: Clarify whether this behaviour _really_ saves
    1213                 :            :                 // anybody anything!
    1214                 :            :                 // update children, _don't_ broadcast
    1215         [ #  # ]:          0 :                 UpdateVisibleChildren( false );
    1216         [ #  # ]:          0 :                 UpdateBoundRect();
    1217                 :            : 
    1218                 :            :                 // #i61812# notification for removed para
    1219         [ #  # ]:          0 :                 if (xPara.is())
    1220 [ #  # ][ #  # ]:          0 :                     FireEvent(AccessibleEventId::CHILD, uno::Any(), uno::makeAny( xPara) );
                 [ #  # ]
    1221                 :            :             }
    1222                 :            : #ifdef DBG_UTIL
    1223                 :            :             else
    1224                 :            :                 OSL_FAIL("AccessibleTextHelper_Impl::ProcessQueue() invalid hint id");
    1225                 :            : #endif
    1226                 :            :         }
    1227         [ -  + ]:          9 :         else if( nNewParas != nCurrParas )
    1228                 :            :         {
    1229                 :            :             // release all paras
    1230         [ #  # ]:          0 :             maParaManager.Release(0, nCurrParas);
    1231                 :            : 
    1232                 :            :             // update num of paras
    1233         [ #  # ]:          0 :             maParaManager.SetNum( nNewParas );
    1234                 :            : 
    1235                 :            :             // #109864# create from scratch, don't broadcast
    1236         [ #  # ]:          0 :             UpdateVisibleChildren( false );
    1237         [ #  # ]:          0 :             UpdateBoundRect();
    1238                 :            : 
    1239                 :            :             // number of paragraphs somehow changed - but we have no
    1240                 :            :             // chance determining how. Thus, throw away everything and
    1241                 :            :             // create from scratch.
    1242                 :            :             // (child events should be broadcast after the changes are done...)
    1243         [ #  # ]:          0 :             FireEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN);
    1244                 :            : 
    1245                 :            :             // no need for further updates later on
    1246                 :          0 :             bEverythingUpdated = true;
    1247                 :            :         }
    1248                 :            : 
    1249 [ +  - ][ +  + ]:         18 :         while( !maEventQueue.IsEmpty() )
    1250                 :            :         {
    1251                 :            :             SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1252         [ +  - ]:          9 :             ::std::auto_ptr< SfxHint > pHint( maEventQueue.PopFront() );
           [ +  -  #  # ]
    1253                 :            :             SAL_WNODEPRECATED_DECLARATIONS_POP
    1254         [ +  - ]:          9 :             if( pHint.get() )
    1255                 :            :             {
    1256                 :          9 :                 const SfxHint& rHint = *(pHint.get());
    1257                 :            : 
    1258                 :            :                 // determine hint type
    1259 [ +  - ][ +  - ]:          9 :                 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
         [ +  + ][ +  - ]
    1260 [ +  - ][ +  - ]:          9 :                 const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
         [ +  - ][ +  + ]
    1261 [ +  - ][ +  - ]:          9 :                 const TextHint* pTextHint = PTR_CAST( TextHint, &rHint );
         [ +  - ][ +  + ]
    1262 [ +  - ][ +  - ]:          9 :                 const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
         [ +  - ][ -  + ]
    1263 [ +  - ][ +  - ]:          9 :                 const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, &rHint );
         [ +  - ][ -  + ]
    1264                 :            : 
    1265                 :            :                 try
    1266                 :            :                 {
    1267 [ +  - ][ +  - ]:          9 :                     const sal_Int32 nParas = GetTextForwarder().GetParagraphCount();
    1268                 :            : 
    1269         [ -  + ]:          9 :                     if( pEditSourceHint )
    1270                 :            :                     {
    1271      [ #  #  # ]:          0 :                         switch( pEditSourceHint->GetId() )
    1272                 :            :                         {
    1273                 :            :                             case EDITSOURCE_HINT_PARASMOVED:
    1274                 :            :                             {
    1275                 :            :                                 DBG_ASSERT( pEditSourceHint->GetStartValue() < GetTextForwarder().GetParagraphCount() &&
    1276                 :            :                                             pEditSourceHint->GetEndValue() < GetTextForwarder().GetParagraphCount(),
    1277                 :            :                                             "AccessibleTextHelper_Impl::NotifyHdl: Invalid notification");
    1278                 :            : 
    1279         [ #  # ]:          0 :                                 if( !bEverythingUpdated )
    1280                 :            :                                 {
    1281         [ #  # ]:          0 :                                     ParagraphsMoved(pEditSourceHint->GetStartValue(),
    1282         [ #  # ]:          0 :                                                     pEditSourceHint->GetValue(),
    1283 [ #  # ][ #  # ]:          0 :                                                     pEditSourceHint->GetEndValue());
    1284                 :            : 
    1285                 :            :                                     // in all cases, check visibility afterwards.
    1286         [ #  # ]:          0 :                                     UpdateVisibleChildren();
    1287                 :            :                                 }
    1288                 :          0 :                                 break;
    1289                 :            :                             }
    1290                 :            : 
    1291                 :            :                             case EDITSOURCE_HINT_SELECTIONCHANGED:
    1292                 :            :                                 // notify listeners
    1293                 :            :                                 try
    1294                 :            :                                 {
    1295         [ #  # ]:          0 :                                     UpdateSelection();
    1296                 :            :                                 }
    1297                 :            :                                 // maybe we're not in edit mode (this is not an error)
    1298         [ #  # ]:          0 :                                 catch( const uno::Exception& ) {}
    1299                 :          0 :                                 break;
    1300                 :            :                         }
    1301                 :            :                     }
    1302         [ +  + ]:          9 :                     else if( pTextHint )
    1303                 :            :                     {
    1304   [ -  -  -  +  :          5 :                         switch( pTextHint->GetId() )
                   -  - ]
    1305                 :            :                         {
    1306                 :            :                             case TEXT_HINT_MODIFIED:
    1307                 :            :                             {
    1308                 :            :                                 // notify listeners
    1309                 :          0 :                                 sal_Int32 nPara( pTextHint->GetValue() );
    1310                 :            : 
    1311                 :            :                                 // #108900# Delegate change event to children
    1312                 :            :                                 AccessibleTextHelper_ChildrenTextChanged aNotifyChildrenFunctor;
    1313                 :            : 
    1314         [ #  # ]:          0 :                                 if( nPara == static_cast<sal_Int32>(EE_PARA_ALL) )
    1315                 :            :                                 {
    1316                 :            :                                     // #108900# Call every child
    1317                 :            :                                     ::std::for_each( maParaManager.begin(), maParaManager.end(),
    1318 [ #  # ][ #  # ]:          0 :                                                      AccessibleParaManager::WeakChildAdapter< AccessibleTextHelper_ChildrenTextChanged > (aNotifyChildrenFunctor) );
                 [ #  # ]
    1319                 :            :                                 }
    1320                 :            :                                 else
    1321         [ #  # ]:          0 :                                     if( nPara < nParas )
    1322                 :            :                                     {
    1323                 :            :                                         // #108900# Call child at index nPara
    1324         [ #  # ]:          0 :                                         ::std::for_each( maParaManager.begin()+nPara, maParaManager.begin()+nPara+1,
    1325 [ #  # ][ #  # ]:          0 :                                                          AccessibleParaManager::WeakChildAdapter< AccessibleTextHelper_ChildrenTextChanged > (aNotifyChildrenFunctor) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1326                 :            :                                     }
    1327                 :            :                                 break;
    1328                 :            :                             }
    1329                 :            : 
    1330                 :            :                             case TEXT_HINT_PARAINSERTED:
    1331                 :            :                                 // already happened above
    1332                 :          0 :                                 break;
    1333                 :            : 
    1334                 :            :                             case TEXT_HINT_PARAREMOVED:
    1335                 :            :                                 // already happened above
    1336                 :          0 :                                 break;
    1337                 :            : 
    1338                 :            :                             case TEXT_HINT_TEXTHEIGHTCHANGED:
    1339                 :            :                                 // visibility changed, done below
    1340                 :          5 :                                 break;
    1341                 :            : 
    1342                 :            :                             case TEXT_HINT_VIEWSCROLLED:
    1343                 :            :                                 // visibility changed, done below
    1344                 :          0 :                                 break;
    1345                 :            :                         }
    1346                 :            : 
    1347                 :            :                         // in all cases, check visibility afterwards.
    1348         [ +  - ]:          5 :                         UpdateVisibleChildren();
    1349         [ +  - ]:          5 :                         UpdateBoundRect();
    1350                 :            :                     }
    1351         [ -  + ]:          4 :                     else if( pViewHint )
    1352                 :            :                     {
    1353 [ #  # ][ #  # ]:          0 :                         switch( pViewHint->GetHintType() )
    1354                 :            :                         {
    1355                 :            :                             case SvxViewHint::SVX_HINT_VIEWCHANGED:
    1356                 :            :                                 // just check visibility
    1357         [ #  # ]:          0 :                                 UpdateVisibleChildren();
    1358         [ #  # ]:          0 :                                 UpdateBoundRect();
    1359                 :          0 :                                 break;
    1360                 :            :                         }
    1361                 :            :                     }
    1362         [ +  - ]:          4 :                     else if( pSdrHint )
    1363                 :            :                     {
    1364         [ +  - ]:          4 :                         switch( pSdrHint->GetKind() )
              [ -  -  + ]
    1365                 :            :                         {
    1366                 :            :                             case HINT_BEGEDIT:
    1367                 :            :                             {
    1368                 :            :                                 // change children state
    1369         [ #  # ]:          0 :                                 maParaManager.SetActive();
    1370                 :            : 
    1371                 :            :                                 // per definition, edit mode text has the focus
    1372         [ #  # ]:          0 :                                 SetFocus( sal_True );
    1373                 :          0 :                                 break;
    1374                 :            :                             }
    1375                 :            : 
    1376                 :            :                             case HINT_ENDEDIT:
    1377                 :            :                             {
    1378                 :            :                                 // focused child now looses focus
    1379                 :          0 :                                 ESelection aSelection;
    1380 [ #  # ][ #  # ]:          0 :                                 if( GetEditViewForwarder().GetSelection( aSelection ) )
                 [ #  # ]
    1381         [ #  # ]:          0 :                                     SetChildFocus( aSelection.nEndPara, sal_False );
    1382                 :            : 
    1383                 :            :                                 // change children state
    1384         [ #  # ]:          0 :                                 maParaManager.SetActive( sal_False );
    1385                 :            : 
    1386                 :            :                                 maLastSelection = ESelection( EE_PARA_NOT_FOUND, EE_PARA_NOT_FOUND,
    1387                 :          0 :                                                               EE_PARA_NOT_FOUND, EE_PARA_NOT_FOUND);
    1388                 :            :                                 break;
    1389                 :            :                             }
    1390                 :            :                             default:
    1391                 :          4 :                                 break;
    1392                 :            :                         }
    1393                 :            :                     }
    1394                 :            :                     // it's VITAL to keep the SfxSimpleHint last! It's the base of some classes above!
    1395         [ #  # ]:          0 :                     else if( pSimpleHint )
    1396                 :            :                     {
    1397         [ #  # ]:          0 :                         switch( pSimpleHint->GetId() )
    1398                 :            :                         {
    1399                 :            :                             case SFX_HINT_DYING:
    1400                 :            :                                 // edit source is dying under us, become defunc then
    1401                 :            :                                 try
    1402                 :            :                                 {
    1403                 :            :                                     // make edit source inaccessible
    1404                 :            :                                     // Note: cannot destroy it here, since we're called from there!
    1405         [ #  # ]:          0 :                                     ShutdownEditSource();
    1406                 :            :                                 }
    1407   [ #  #  #  # ]:          0 :                                 catch( const uno::Exception& ) {}
    1408                 :            : 
    1409                 :          0 :                                 break;
    1410                 :            :                         }
    1411                 :            :                     }
    1412                 :            :                 }
    1413         [ #  # ]:          0 :                 catch( const uno::Exception& )
    1414                 :            :                 {
    1415                 :            : #ifdef DBG_UTIL
    1416                 :            :                     OSL_TRACE("AccessibleTextHelper_Impl::ProcessQueue: Unhandled exception.");
    1417                 :            : #endif
    1418                 :            :                 }
    1419                 :            :             }
    1420         [ +  - ]:          9 :         }
    1421                 :          9 :     }
    1422                 :            : 
    1423                 :         19 :     void AccessibleTextHelper_Impl::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
    1424                 :            :     {
    1425                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1426                 :            : 
    1427                 :            :         // precondition: solar mutex locked
    1428                 :            :         DBG_TESTSOLARMUTEX();
    1429                 :            : 
    1430                 :            :         // precondition: not in a recursion
    1431         [ -  + ]:         19 :         if( mbInNotify )
    1432         [ #  # ]:         19 :             return;
    1433                 :            : 
    1434                 :         19 :         mbInNotify = sal_True;
    1435                 :            : 
    1436                 :            :         // determine hint type
    1437 [ +  - ][ +  + ]:         19 :         const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
    1438 [ +  - ][ +  + ]:         19 :         const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
    1439 [ +  - ][ +  + ]:         19 :         const TextHint* pTextHint = PTR_CAST( TextHint, &rHint );
    1440 [ +  - ][ -  + ]:         19 :         const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
    1441 [ +  - ][ -  + ]:         19 :         const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, &rHint );
    1442                 :            : 
    1443                 :            :         try
    1444                 :            :         {
    1445                 :            :             // Process notification event
    1446         [ -  + ]:         19 :             if( pEditSourceHint )
    1447                 :            :             {
    1448         [ #  # ]:          0 :                 maEventQueue.Append( *pEditSourceHint );
    1449                 :            :                 // EditEngine should emit TEXT_SELECTION_CHANGED events (#i27299#)
    1450         [ #  # ]:          0 :                 if( maEventOpenFrames == 0 )
    1451         [ #  # ]:          0 :                     ProcessQueue();
    1452                 :            :             }
    1453         [ +  + ]:         19 :             else if( pTextHint )
    1454                 :            :             {
    1455      [ +  +  + ]:         15 :                 switch( pTextHint->GetId() )
    1456                 :            :                 {
    1457                 :            :                     case TEXT_HINT_BLOCKNOTIFICATION_END:
    1458                 :            :                     case TEXT_HINT_INPUT_END:
    1459                 :          5 :                         --maEventOpenFrames;
    1460                 :            : 
    1461         [ +  - ]:          5 :                         if( maEventOpenFrames == 0 )
    1462                 :            :                         {
    1463                 :            :                             // #103483#
    1464                 :            :                             /* All information should have arrived
    1465                 :            :                              * now, process queue. As stated in the
    1466                 :            :                              * above bug, we can often avoid throwing
    1467                 :            :                              * away all paragraphs by looking forward
    1468                 :            :                              * in the event queue (searching for
    1469                 :            :                              * PARAINSERT/REMOVE events). Furthermore,
    1470                 :            :                              * processing the event queue only at the
    1471                 :            :                              * end of an interaction cycle, ensures
    1472                 :            :                              * that the EditEngine state and the
    1473                 :            :                              * AccessibleText state are the same
    1474                 :            :                              * (well, mostly. If there are _multiple_
    1475                 :            :                              * interaction cycles in the EE queues, it
    1476                 :            :                              * can still happen that EE state is
    1477                 :            :                              * different. That's so to say broken by
    1478                 :            :                              * design with that delayed EE event
    1479                 :            :                              * concept).
    1480                 :            :                              */
    1481         [ +  - ]:          5 :                             ProcessQueue();
    1482                 :            :                         }
    1483                 :          5 :                         break;
    1484                 :            : 
    1485                 :            :                     case TEXT_HINT_BLOCKNOTIFICATION_START:
    1486                 :            :                     case TEXT_HINT_INPUT_START:
    1487                 :          5 :                         ++maEventOpenFrames;
    1488                 :            :                         // no FALLTHROUGH reason: event will not be processed,
    1489                 :            :                         // thus appending the event isn't necessary. (#i27299#)
    1490                 :          5 :                         break;
    1491                 :            :                     default:
    1492         [ +  - ]:          5 :                         maEventQueue.Append( *pTextHint );
    1493                 :            :                         // EditEngine should emit TEXT_SELECTION_CHANGED events (#i27299#)
    1494         [ -  + ]:          5 :                         if( maEventOpenFrames == 0 )
    1495         [ #  # ]:          0 :                             ProcessQueue();
    1496                 :         15 :                         break;
    1497                 :            :                 }
    1498                 :            :             }
    1499         [ -  + ]:          4 :             else if( pViewHint )
    1500                 :            :             {
    1501         [ #  # ]:          0 :                 maEventQueue.Append( *pViewHint );
    1502                 :            : 
    1503                 :            :                 // process visibility right away, if not within an
    1504                 :            :                 // open EE notification frame. Otherwise, event
    1505                 :            :                 // processing would be delayed until next EE
    1506                 :            :                 // notification sequence.
    1507         [ #  # ]:          0 :                 if( maEventOpenFrames == 0 )
    1508         [ #  # ]:          0 :                     ProcessQueue();
    1509                 :            :             }
    1510         [ +  - ]:          4 :             else if( pSdrHint )
    1511                 :            :             {
    1512         [ +  - ]:          4 :                 maEventQueue.Append( *pSdrHint );
    1513                 :            : 
    1514                 :            :                 // process drawing layer events right away, if not
    1515                 :            :                 // within an open EE notification frame. Otherwise,
    1516                 :            :                 // event processing would be delayed until next EE
    1517                 :            :                 // notification sequence.
    1518         [ +  - ]:          4 :                 if( maEventOpenFrames == 0 )
    1519         [ +  - ]:          4 :                     ProcessQueue();
    1520                 :            :             }
    1521                 :            :             // it's VITAL to keep the SfxSimpleHint last! It's the base of some classes above!
    1522         [ #  # ]:          0 :             else if( pSimpleHint )
    1523                 :            :             {
    1524                 :            :                 // handle this event _at once_, because after that, objects are invalid
    1525         [ #  # ]:          0 :                 switch( pSimpleHint->GetId() )
    1526                 :            :                 {
    1527                 :            :                     case SFX_HINT_DYING:
    1528                 :            :                         // edit source is dying under us, become defunc then
    1529         [ #  # ]:          0 :                         maEventQueue.Clear();
    1530                 :            :                         try
    1531                 :            :                         {
    1532                 :            :                             // make edit source inaccessible
    1533                 :            :                             // Note: cannot destroy it here, since we're called from there!
    1534         [ #  # ]:          0 :                             ShutdownEditSource();
    1535                 :            :                         }
    1536   [ #  #  #  # ]:          0 :                         catch( const uno::Exception& ) {}
    1537                 :            : 
    1538                 :          0 :                         break;
    1539                 :            :                 }
    1540                 :            :             }
    1541                 :            :         }
    1542                 :          0 :         catch( const uno::Exception& )
    1543                 :            :         {
    1544                 :            : #ifdef DBG_UTIL
    1545                 :            :             OSL_TRACE("AccessibleTextHelper_Impl::Notify: Unhandled exception.");
    1546                 :            : #endif
    1547                 :          0 :             mbInNotify = sal_False;
    1548                 :            :         }
    1549                 :            : 
    1550                 :         19 :         mbInNotify = sal_False;
    1551                 :            :     }
    1552                 :            : 
    1553                 :         57 :     void AccessibleTextHelper_Impl::Dispose()
    1554                 :            :     {
    1555                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1556                 :            : 
    1557         [ +  + ]:         57 :         if( getNotifierClientId() != -1 )
    1558                 :            :         {
    1559                 :            :             try
    1560                 :            :             {
    1561                 :            :                 // #106234# Unregister from EventNotifier
    1562         [ +  - ]:         45 :                 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
    1563                 :            : #ifdef DBG_UTIL
    1564                 :            :                 OSL_TRACE( "AccessibleTextHelper_Impl disposed ID: %d", mnNotifierClientId );
    1565                 :            : #endif
    1566                 :            :             }
    1567         [ #  # ]:          0 :             catch( const uno::Exception& ) {}
    1568                 :            : 
    1569                 :         45 :             mnNotifierClientId = -1;
    1570                 :            :         }
    1571                 :            : 
    1572                 :            :         try
    1573                 :            :         {
    1574                 :            :             // dispose children
    1575         [ +  - ]:         57 :             maParaManager.Dispose();
    1576                 :            :         }
    1577                 :          0 :         catch( const uno::Exception& ) {}
    1578                 :            : 
    1579                 :            :         // quit listen on stale edit source
    1580         [ +  + ]:         57 :         if( maEditSource.IsValid() )
    1581                 :         41 :             EndListening( maEditSource.GetBroadcaster() );
    1582                 :            : 
    1583                 :            :         // clear references
    1584                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1585 [ +  - ][ +  - ]:         57 :         maEditSource.SetEditSource( ::std::auto_ptr< SvxEditSource >(NULL) );
    1586                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    1587                 :         57 :         mxFrontEnd = NULL;
    1588         [ #  # ]:         57 :     }
    1589                 :            : 
    1590                 :          7 :     void AccessibleTextHelper_Impl::FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const
    1591                 :            :     {
    1592                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1593                 :            : 
    1594                 :            :         // -- object locked --
    1595         [ +  - ]:          7 :         ::osl::ClearableMutexGuard aGuard( maMutex );
    1596                 :            : 
    1597         [ +  - ]:          7 :         AccessibleEventObject aEvent;
    1598                 :            : 
    1599                 :            :         DBG_ASSERT(mxFrontEnd.is(), "AccessibleTextHelper::FireEvent: no event source set" );
    1600                 :            : 
    1601         [ +  - ]:          7 :         if( mxFrontEnd.is() )
    1602 [ +  - ][ +  - ]:          7 :             aEvent = AccessibleEventObject(mxFrontEnd->getAccessibleContext(), nEventId, rNewValue, rOldValue);
         [ +  - ][ +  - ]
                 [ +  - ]
    1603                 :            :         else
    1604 [ #  # ][ #  # ]:          0 :             aEvent = AccessibleEventObject(uno::Reference< uno::XInterface >(), nEventId, rNewValue, rOldValue);
                 [ #  # ]
    1605                 :            : 
    1606                 :            :         // no locking necessary, FireEvent internally copies listeners
    1607                 :            :         // if someone removes/adds in between Further locking,
    1608                 :            :         // actually, might lead to deadlocks, since we're calling out
    1609                 :            :         // of this object
    1610         [ +  - ]:          7 :         aGuard.clear();
    1611                 :            :         // -- until here --
    1612                 :            : 
    1613 [ +  - ][ +  - ]:          7 :         FireEvent(aEvent);
                 [ +  - ]
    1614                 :          7 :     }
    1615                 :            : 
    1616                 :          7 :     void AccessibleTextHelper_Impl::FireEvent( const AccessibleEventObject& rEvent ) const
    1617                 :            :     {
    1618                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1619                 :            : 
    1620                 :            :         // #102261# Call global queue for focus events
    1621         [ -  + ]:          7 :         if( rEvent.EventId == AccessibleStateType::FOCUSED )
    1622                 :          0 :             vcl::unohelper::NotifyAccessibleStateEventGlobally( rEvent );
    1623                 :            : 
    1624                 :            :         // #106234# Delegate to EventNotifier
    1625                 :          7 :         ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
    1626                 :          7 :                                                          rEvent );
    1627                 :          7 :     }
    1628                 :            : 
    1629                 :            :     // XAccessibleContext
    1630                 :        198 :     sal_Int32 SAL_CALL AccessibleTextHelper_Impl::getAccessibleChildCount() SAL_THROW((uno::RuntimeException))
    1631                 :            :     {
    1632                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1633                 :            : 
    1634                 :        198 :         return mnLastVisibleChild - mnFirstVisibleChild + 1;
    1635                 :            :     }
    1636                 :            : 
    1637                 :         60 :     uno::Reference< XAccessible > SAL_CALL AccessibleTextHelper_Impl::getAccessibleChild( sal_Int32 i ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
    1638                 :            :     {
    1639                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1640                 :            : 
    1641                 :         60 :         i -= GetStartIndex();
    1642                 :            : 
    1643   [ +  -  -  + ]:        120 :         if( 0 > i || i >= getAccessibleChildCount() ||
         [ -  + ][ +  - ]
    1644                 :         60 :             GetTextForwarder().GetParagraphCount() <= i )
    1645                 :            :         {
    1646 [ #  # ][ #  # ]:          0 :             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), mxFrontEnd);
    1647                 :            :         }
    1648                 :            : 
    1649                 :            :         DBG_ASSERT(mxFrontEnd.is(), "AccessibleTextHelper_Impl::UpdateVisibleChildren: no frontend set");
    1650                 :            : 
    1651         [ +  - ]:         60 :         if( mxFrontEnd.is() )
    1652                 :         60 :             return maParaManager.CreateChild( i, mxFrontEnd, GetEditSource(), mnFirstVisibleChild + i ).first;
    1653                 :            :         else
    1654                 :         60 :             return NULL;
    1655                 :            :     }
    1656                 :            : 
    1657                 :          2 :     void SAL_CALL AccessibleTextHelper_Impl::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
    1658                 :            :     {
    1659                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1660                 :            : 
    1661         [ +  - ]:          2 :         if( getNotifierClientId() != -1 )
    1662                 :          2 :             ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
    1663                 :          2 :     }
    1664                 :            : 
    1665                 :          2 :     void SAL_CALL AccessibleTextHelper_Impl::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
    1666                 :            :     {
    1667                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1668                 :            : 
    1669         [ +  - ]:          2 :         if( getNotifierClientId() != -1 )
    1670                 :          2 :             ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
    1671                 :          2 :     }
    1672                 :            : 
    1673                 :          6 :     uno::Reference< XAccessible > SAL_CALL AccessibleTextHelper_Impl::getAccessibleAtPoint( const awt::Point& _aPoint ) SAL_THROW((uno::RuntimeException))
    1674                 :            :     {
    1675                 :            :         DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
    1676                 :            : 
    1677                 :            :         // make given position relative
    1678         [ -  + ]:          6 :         if( !mxFrontEnd.is() )
    1679 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::getAccessibleAt: frontend invalid")), mxFrontEnd );
    1680                 :            : 
    1681 [ +  - ][ +  - ]:          6 :         uno::Reference< XAccessibleContext > xFrontEndContext = mxFrontEnd->getAccessibleContext();
    1682                 :            : 
    1683         [ -  + ]:          6 :         if( !xFrontEndContext.is() )
    1684 [ #  # ][ #  # ]:          0 :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::getAccessibleAt: frontend invalid")), mxFrontEnd );
    1685                 :            : 
    1686         [ +  - ]:          6 :         uno::Reference< XAccessibleComponent > xFrontEndComponent( xFrontEndContext, uno::UNO_QUERY );
    1687                 :            : 
    1688         [ -  + ]:          6 :         if( !xFrontEndComponent.is() )
    1689                 :            :             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::getAccessibleAt: frontend is no XAccessibleComponent")),
    1690 [ #  # ][ #  # ]:          0 :                                         mxFrontEnd );
    1691                 :            : 
    1692                 :            :         // #103862# No longer need to make given position relative
    1693                 :          6 :         Point aPoint( _aPoint.X, _aPoint.Y );
    1694                 :            : 
    1695                 :            :         // respect EditEngine offset to surrounding shape/cell
    1696         [ +  - ]:          6 :         aPoint -= GetOffset();
    1697                 :            : 
    1698                 :            :         // convert to EditEngine coordinate system
    1699         [ +  - ]:          6 :         SvxTextForwarder& rCacheTF = GetTextForwarder();
    1700 [ +  - ][ +  - ]:          6 :         Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
         [ +  - ][ +  - ]
    1701                 :            : 
    1702                 :            :         // iterate over all visible children (including those not yet created)
    1703                 :            :         sal_Int32 nChild;
    1704         [ +  + ]:         12 :         for( nChild=mnFirstVisibleChild; nChild <= mnLastVisibleChild; ++nChild )
    1705                 :            :         {
    1706                 :            :             DBG_ASSERT(nChild >= 0 && nChild <= USHRT_MAX,
    1707                 :            :                        "AccessibleTextHelper_Impl::getAccessibleAt: index value overflow");
    1708                 :            : 
    1709         [ +  - ]:          6 :             Rectangle aParaBounds( rCacheTF.GetParaBounds( static_cast< sal_uInt16 > (nChild) ) );
    1710                 :            : 
    1711 [ +  - ][ +  + ]:          6 :             if( aParaBounds.IsInside( aLogPoint ) )
    1712         [ +  - ]:          4 :                 return getAccessibleChild( nChild - mnFirstVisibleChild + GetStartIndex() );
    1713                 :            :         }
    1714                 :            : 
    1715                 :            :         // found none
    1716         [ +  - ]:          6 :         return NULL;
    1717                 :            :     }
    1718                 :            : 
    1719                 :            :     //------------------------------------------------------------------------
    1720                 :            :     //
    1721                 :            :     // AccessibleTextHelper implementation (simply forwards to impl)
    1722                 :            :     //
    1723                 :            :     //------------------------------------------------------------------------
    1724                 :            : 
    1725                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1726                 :         56 :     AccessibleTextHelper::AccessibleTextHelper( ::std::auto_ptr< SvxEditSource > pEditSource ) :
    1727         [ +  - ]:         56 :         mpImpl( new AccessibleTextHelper_Impl() )
    1728                 :            :     {
    1729         [ +  - ]:         56 :         SolarMutexGuard aGuard;
    1730                 :            : 
    1731 [ +  - ][ +  - ]:         56 :         SetEditSource( pEditSource );
                 [ +  - ]
    1732                 :         56 :     }
    1733                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1734                 :            : 
    1735                 :         45 :     AccessibleTextHelper::~AccessibleTextHelper()
    1736                 :            :     {
    1737         [ -  + ]:         90 :     }
    1738                 :            : 
    1739                 :          0 :     const SvxEditSource& AccessibleTextHelper::GetEditSource() const SAL_THROW((uno::RuntimeException))
    1740                 :            :     {
    1741                 :            : #ifdef DBG_UTIL
    1742                 :            :         mpImpl->CheckInvariants();
    1743                 :            : 
    1744                 :            :         const SvxEditSource& aEditSource = mpImpl->GetEditSource();
    1745                 :            : 
    1746                 :            :         mpImpl->CheckInvariants();
    1747                 :            : 
    1748                 :            :         return aEditSource;
    1749                 :            : #else
    1750                 :          0 :         return mpImpl->GetEditSource();
    1751                 :            : #endif
    1752                 :            :     }
    1753                 :            : 
    1754                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1755                 :         60 :     void AccessibleTextHelper::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
    1756                 :            :     {
    1757                 :            : #ifdef DBG_UTIL
    1758                 :            :         // precondition: solar mutex locked
    1759                 :            :         DBG_TESTSOLARMUTEX();
    1760                 :            : 
    1761                 :            :         mpImpl->CheckInvariants();
    1762                 :            : #endif
    1763                 :            : 
    1764         [ +  - ]:         60 :         mpImpl->SetEditSource( pEditSource );
    1765                 :            : 
    1766                 :            : #ifdef DBG_UTIL
    1767                 :            :         mpImpl->CheckInvariants();
    1768                 :            : #endif
    1769                 :         60 :     }
    1770                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1771                 :            : 
    1772                 :         56 :     void AccessibleTextHelper::SetEventSource( const uno::Reference< XAccessible >& rInterface )
    1773                 :            :     {
    1774                 :            : #ifdef DBG_UTIL
    1775                 :            :         mpImpl->CheckInvariants();
    1776                 :            : #endif
    1777                 :            : 
    1778                 :         56 :         mpImpl->SetEventSource( rInterface );
    1779                 :            : 
    1780                 :            : #ifdef DBG_UTIL
    1781                 :            :         mpImpl->CheckInvariants();
    1782                 :            : #endif
    1783                 :         56 :     }
    1784                 :            : 
    1785                 :          0 :     uno::Reference< XAccessible > AccessibleTextHelper::GetEventSource() const
    1786                 :            :     {
    1787                 :            : #ifdef DBG_UTIL
    1788                 :            :         mpImpl->CheckInvariants();
    1789                 :            : 
    1790                 :            :         uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
    1791                 :            : 
    1792                 :            :         mpImpl->CheckInvariants();
    1793                 :            : 
    1794                 :            :         return xRet;
    1795                 :            : #else
    1796                 :          0 :         return mpImpl->GetEventSource();
    1797                 :            : #endif
    1798                 :            :     }
    1799                 :            : 
    1800                 :          2 :     void AccessibleTextHelper::SetFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
    1801                 :            :     {
    1802                 :            : #ifdef DBG_UTIL
    1803                 :            :         // precondition: solar mutex locked
    1804                 :            :         DBG_TESTSOLARMUTEX();
    1805                 :            : 
    1806                 :            :         mpImpl->CheckInvariants();
    1807                 :            : #endif
    1808                 :            : 
    1809                 :          2 :         mpImpl->SetFocus( bHaveFocus );
    1810                 :            : 
    1811                 :            : #ifdef DBG_UTIL
    1812                 :            :         mpImpl->CheckInvariants();
    1813                 :            : #endif
    1814                 :          2 :     }
    1815                 :            : 
    1816                 :         12 :     sal_Bool AccessibleTextHelper::HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException))
    1817                 :            :     {
    1818                 :            : #ifdef DBG_UTIL
    1819                 :            :         mpImpl->CheckInvariants();
    1820                 :            : 
    1821                 :            :         sal_Bool bRet( mpImpl->HaveFocus() );
    1822                 :            : 
    1823                 :            :         mpImpl->CheckInvariants();
    1824                 :            : 
    1825                 :            :         return bRet;
    1826                 :            : #else
    1827                 :         12 :         return mpImpl->HaveFocus();
    1828                 :            : #endif
    1829                 :            :     }
    1830                 :            : 
    1831                 :          0 :     void AccessibleTextHelper::FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const
    1832                 :            :     {
    1833                 :            : #ifdef DBG_UTIL
    1834                 :            :         mpImpl->CheckInvariants();
    1835                 :            : #endif
    1836                 :            : 
    1837                 :          0 :         mpImpl->FireEvent( nEventId, rNewValue, rOldValue );
    1838                 :            : 
    1839                 :            : #ifdef DBG_UTIL
    1840                 :            :         mpImpl->CheckInvariants();
    1841                 :            : #endif
    1842                 :          0 :     }
    1843                 :            : 
    1844                 :          0 :     void AccessibleTextHelper::FireEvent( const AccessibleEventObject& rEvent ) const
    1845                 :            :     {
    1846                 :            : #ifdef DBG_UTIL
    1847                 :            :         mpImpl->CheckInvariants();
    1848                 :            : #endif
    1849                 :            : 
    1850                 :          0 :         mpImpl->FireEvent( rEvent );
    1851                 :            : 
    1852                 :            : #ifdef DBG_UTIL
    1853                 :            :         mpImpl->CheckInvariants();
    1854                 :            : #endif
    1855                 :          0 :     }
    1856                 :            : 
    1857                 :          0 :     void AccessibleTextHelper::SetOffset( const Point& rPoint )
    1858                 :            :     {
    1859                 :            : #ifdef DBG_UTIL
    1860                 :            :         // precondition: solar mutex locked
    1861                 :            :         DBG_TESTSOLARMUTEX();
    1862                 :            : 
    1863                 :            :         mpImpl->CheckInvariants();
    1864                 :            : #endif
    1865                 :            : 
    1866                 :          0 :         mpImpl->SetOffset( rPoint );
    1867                 :            : 
    1868                 :            : #ifdef DBG_UTIL
    1869                 :            :         mpImpl->CheckInvariants();
    1870                 :            : #endif
    1871                 :          0 :     }
    1872                 :            : 
    1873                 :          0 :     Point AccessibleTextHelper::GetOffset() const
    1874                 :            :     {
    1875                 :            : #ifdef DBG_UTIL
    1876                 :            :         mpImpl->CheckInvariants();
    1877                 :            : 
    1878                 :            :         Point aPoint( mpImpl->GetOffset() );
    1879                 :            : 
    1880                 :            :         mpImpl->CheckInvariants();
    1881                 :            : 
    1882                 :            :         return aPoint;
    1883                 :            : #else
    1884                 :          0 :         return mpImpl->GetOffset();
    1885                 :            : #endif
    1886                 :            :     }
    1887                 :            : 
    1888                 :          0 :     void AccessibleTextHelper::SetStartIndex( sal_Int32 nOffset )
    1889                 :            :     {
    1890                 :            : #ifdef DBG_UTIL
    1891                 :            :         // precondition: solar mutex locked
    1892                 :            :         DBG_TESTSOLARMUTEX();
    1893                 :            : 
    1894                 :            :         mpImpl->CheckInvariants();
    1895                 :            : #endif
    1896                 :            : 
    1897                 :          0 :         mpImpl->SetStartIndex( nOffset );
    1898                 :            : 
    1899                 :            : #ifdef DBG_UTIL
    1900                 :            :         mpImpl->CheckInvariants();
    1901                 :            : #endif
    1902                 :          0 :     }
    1903                 :            : 
    1904                 :          0 :     sal_Int32 AccessibleTextHelper::GetStartIndex() const
    1905                 :            :     {
    1906                 :            : #ifdef DBG_UTIL
    1907                 :            :         mpImpl->CheckInvariants();
    1908                 :            : 
    1909                 :            :         sal_Int32 nOffset = mpImpl->GetStartIndex();
    1910                 :            : 
    1911                 :            :         mpImpl->CheckInvariants();
    1912                 :            : 
    1913                 :            :         return nOffset;
    1914                 :            : #else
    1915                 :          0 :         return mpImpl->GetStartIndex();
    1916                 :            : #endif
    1917                 :            :     }
    1918                 :            : 
    1919                 :         15 :     void AccessibleTextHelper::SetAdditionalChildStates( const VectorOfStates& rChildStates )
    1920                 :            :     {
    1921                 :         15 :         mpImpl->SetAdditionalChildStates( rChildStates );
    1922                 :         15 :     }
    1923                 :            : 
    1924                 :         15 :     void AccessibleTextHelper::UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException))
    1925                 :            :     {
    1926                 :            : #ifdef DBG_UTIL
    1927                 :            :         // precondition: solar mutex locked
    1928                 :            :         DBG_TESTSOLARMUTEX();
    1929                 :            : 
    1930                 :            :         mpImpl->CheckInvariants();
    1931                 :            : #endif
    1932                 :            : 
    1933                 :         15 :         mpImpl->UpdateVisibleChildren();
    1934                 :         15 :         mpImpl->UpdateBoundRect();
    1935                 :            : 
    1936                 :         15 :         mpImpl->UpdateSelection();
    1937                 :            : 
    1938                 :            : #ifdef DBG_UTIL
    1939                 :            :         mpImpl->CheckInvariants();
    1940                 :            : #endif
    1941                 :         15 :     }
    1942                 :            : 
    1943                 :         12 :     void AccessibleTextHelper::Dispose()
    1944                 :            :     {
    1945                 :            :         // As Dispose calls ShutdownEditSource, which in turn
    1946                 :            :         // deregisters as listener on the edit source, have to lock
    1947                 :            :         // here
    1948         [ +  - ]:         12 :         SolarMutexGuard aGuard;
    1949                 :            : 
    1950                 :            : #ifdef DBG_UTIL
    1951                 :            :         mpImpl->CheckInvariants();
    1952                 :            : #endif
    1953                 :            : 
    1954 [ +  - ][ +  - ]:         12 :         mpImpl->Dispose();
    1955                 :            : 
    1956                 :            : #ifdef DBG_UTIL
    1957                 :            :         mpImpl->CheckInvariants();
    1958                 :            : #endif
    1959                 :         12 :     }
    1960                 :            : 
    1961                 :          0 :     sal_Bool AccessibleTextHelper::IsSelected() const
    1962                 :            :     {
    1963         [ #  # ]:          0 :         SolarMutexGuard aGuard;
    1964                 :            : 
    1965                 :            : #ifdef DBG_UTIL
    1966                 :            :         mpImpl->CheckInvariants();
    1967                 :            : 
    1968                 :            :         sal_Bool aRet = mpImpl->IsSelected();
    1969                 :            : 
    1970                 :            :         mpImpl->CheckInvariants();
    1971                 :            : 
    1972                 :            :         return aRet;
    1973                 :            : #else
    1974 [ #  # ][ #  # ]:          0 :         return mpImpl->IsSelected();
    1975                 :            : #endif
    1976                 :            :     }
    1977                 :            : 
    1978                 :            :     // XAccessibleContext
    1979                 :        138 :     sal_Int32 AccessibleTextHelper::GetChildCount() SAL_THROW((uno::RuntimeException))
    1980                 :            :     {
    1981         [ +  - ]:        138 :         SolarMutexGuard aGuard;
    1982                 :            : 
    1983                 :            : #ifdef DBG_UTIL
    1984                 :            :         mpImpl->CheckInvariants();
    1985                 :            : 
    1986                 :            :         sal_Int32 nRet = mpImpl->getAccessibleChildCount();
    1987                 :            : 
    1988                 :            :         mpImpl->CheckInvariants();
    1989                 :            : 
    1990                 :            :         return nRet;
    1991                 :            : #else
    1992         [ +  - ]:        138 :         return mpImpl->getAccessibleChildCount();
    1993                 :            : #endif
    1994                 :            :     }
    1995                 :            : 
    1996                 :         56 :     uno::Reference< XAccessible > AccessibleTextHelper::GetChild( sal_Int32 i ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
    1997                 :            :     {
    1998         [ +  - ]:         56 :         SolarMutexGuard aGuard;
    1999                 :            : 
    2000                 :            : #ifdef DBG_UTIL
    2001                 :            :         mpImpl->CheckInvariants();
    2002                 :            : 
    2003                 :            :         uno::Reference< XAccessible > xRet = mpImpl->getAccessibleChild( i );
    2004                 :            : 
    2005                 :            :         mpImpl->CheckInvariants();
    2006                 :            : 
    2007                 :            :         return xRet;
    2008                 :            : #else
    2009 [ +  - ][ +  - ]:         56 :         return mpImpl->getAccessibleChild( i );
    2010                 :            : #endif
    2011                 :            :     }
    2012                 :            : 
    2013                 :          2 :     void AccessibleTextHelper::AddEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
    2014                 :            :     {
    2015                 :            : #ifdef DBG_UTIL
    2016                 :            :         mpImpl->CheckInvariants();
    2017                 :            : 
    2018                 :            :         mpImpl->addEventListener( xListener );
    2019                 :            : 
    2020                 :            :         mpImpl->CheckInvariants();
    2021                 :            : #else
    2022                 :          2 :         mpImpl->addEventListener( xListener );
    2023                 :            : #endif
    2024                 :          2 :     }
    2025                 :            : 
    2026                 :          2 :     void AccessibleTextHelper::RemoveEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
    2027                 :            :     {
    2028                 :            : #ifdef DBG_UTIL
    2029                 :            :         mpImpl->CheckInvariants();
    2030                 :            : 
    2031                 :            :         mpImpl->removeEventListener( xListener );
    2032                 :            : 
    2033                 :            :         mpImpl->CheckInvariants();
    2034                 :            : #else
    2035                 :          2 :         mpImpl->removeEventListener( xListener );
    2036                 :            : #endif
    2037                 :          2 :     }
    2038                 :            : 
    2039                 :            :     // XAccessibleComponent
    2040                 :          6 :     uno::Reference< XAccessible > AccessibleTextHelper::GetAt( const awt::Point& aPoint ) SAL_THROW((uno::RuntimeException))
    2041                 :            :     {
    2042         [ +  - ]:          6 :         SolarMutexGuard aGuard;
    2043                 :            : 
    2044                 :            : #ifdef DBG_UTIL
    2045                 :            :         mpImpl->CheckInvariants();
    2046                 :            : 
    2047                 :            :         uno::Reference< XAccessible > xChild = mpImpl->getAccessibleAtPoint( aPoint );
    2048                 :            : 
    2049                 :            :         mpImpl->CheckInvariants();
    2050                 :            : 
    2051                 :            :         return xChild;
    2052                 :            : #else
    2053 [ +  - ][ +  - ]:          6 :         return mpImpl->getAccessibleAtPoint( aPoint );
    2054                 :            : #endif
    2055                 :            :     }
    2056                 :            : 
    2057                 :            : } // end of namespace accessibility
    2058                 :            : 
    2059                 :            : //------------------------------------------------------------------------
    2060                 :            : 
    2061                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10