LCOV - code coverage report
Current view: top level - editeng/source/accessibility - AccessibleStaticTextBase.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 52 383 13.6 %
Date: 2014-11-03 Functions: 16 60 26.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : 
      22             : 
      23             : // Global header
      24             : 
      25             : 
      26             : 
      27             : #include <limits.h>
      28             : #include <utility>
      29             : #include <vector>
      30             : #include <algorithm>
      31             : #include <boost/ref.hpp>
      32             : #include <osl/mutex.hxx>
      33             : #include <vcl/window.hxx>
      34             : #include <vcl/svapp.hxx>
      35             : #include <comphelper/sequenceasvector.hxx>
      36             : #include <com/sun/star/uno/Any.hxx>
      37             : #include <com/sun/star/uno/Reference.hxx>
      38             : #include <com/sun/star/awt/Point.hpp>
      39             : #include <com/sun/star/awt/Rectangle.hpp>
      40             : #include <com/sun/star/accessibility/AccessibleTextType.hpp>
      41             : 
      42             : 
      43             : 
      44             : // Project-local header
      45             : 
      46             : 
      47             : 
      48             : #include <editeng/editdata.hxx>
      49             : #include <editeng/unopracc.hxx>
      50             : #include "editeng/unoedprx.hxx"
      51             : #include <editeng/AccessibleStaticTextBase.hxx>
      52             : #include "editeng/AccessibleEditableTextPara.hxx"
      53             : 
      54             : 
      55             : using namespace ::com::sun::star;
      56             : using namespace ::com::sun::star::accessibility;
      57             : 
      58             : /* TODO:
      59             :    =====
      60             : 
      61             :    - separate adapter functionality from AccessibleStaticText class
      62             : 
      63             :    - refactor common loops into templates, using mem_fun
      64             : 
      65             :  */
      66             : 
      67             : namespace accessibility
      68             : {
      69             :     typedef ::comphelper::SequenceAsVector< beans::PropertyValue > PropertyValueVector;
      70             : 
      71             :     class PropertyValueEqualFunctor : public ::std::binary_function< beans::PropertyValue, beans::PropertyValue, bool >
      72             :     {
      73             :     public:
      74           0 :         PropertyValueEqualFunctor()
      75           0 :         {}
      76           0 :         bool operator() ( const beans::PropertyValue& lhs, const beans::PropertyValue& rhs ) const
      77             :         {
      78           0 :             return ( lhs.Name == rhs.Name && lhs.Value == rhs.Value );
      79             :         }
      80             :     };
      81             :     sal_Unicode cNewLine(0x0a);
      82             : 
      83             : 
      84             :     // Static Helper
      85             : 
      86             : 
      87           0 :     ESelection MakeSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
      88             :                               sal_Int32 nEndPara, sal_Int32 nEndIndex )
      89             :     {
      90             :         DBG_ASSERT(nStartPara >= 0 && nStartPara <= SAL_MAX_INT32 &&
      91             :                    nStartIndex >= 0 && nStartIndex <= USHRT_MAX &&
      92             :                    nEndPara >= 0 && nEndPara <= SAL_MAX_INT32 &&
      93             :                    nEndIndex >= 0 && nEndIndex <= USHRT_MAX ,
      94             :                    "AccessibleStaticTextBase_Impl::MakeSelection: index value overflow");
      95             : 
      96           0 :         return ESelection(nStartPara, nStartIndex, nEndPara, nEndIndex);
      97             :     }
      98             : 
      99             : 
     100             : 
     101             :     // AccessibleStaticTextBase_Impl declaration
     102             : 
     103             : 
     104             : 
     105             : 
     106             :     /** AccessibleStaticTextBase_Impl
     107             : 
     108             :         This class implements the AccessibleStaticTextBase
     109             :         functionality, mainly by forwarding the calls to an aggregated
     110             :         AccessibleEditableTextPara. As this is a therefore non-trivial
     111             :         adapter, factoring out the common functionality from
     112             :         AccessibleEditableTextPara might be a profitable future task.
     113             :      */
     114             :     class AccessibleStaticTextBase_Impl
     115             :     {
     116             :         friend class AccessibleStaticTextBase;
     117             :     public:
     118             : 
     119             :         // receive pointer to our frontend class and view window
     120             :         AccessibleStaticTextBase_Impl();
     121             :         ~AccessibleStaticTextBase_Impl();
     122             : 
     123           0 :         SvxEditSourceAdapter& GetEditSource() const
     124             :         {
     125             : 
     126           0 :             return maEditSource;
     127             :         }
     128             : 
     129             :         void SetEditSource( ::std::unique_ptr< SvxEditSource > && pEditSource );
     130             : 
     131          10 :         void SetEventSource( const uno::Reference< XAccessible >& rInterface )
     132             :         {
     133             : 
     134          10 :             mxThis = rInterface;
     135          10 :         }
     136           0 :         uno::Reference< XAccessible > GetEventSource() const
     137             :         {
     138             : 
     139           0 :             return mxThis;
     140             :         }
     141             : 
     142             :         void SetOffset( const Point& );
     143           0 :         Point GetOffset() const
     144             :         {
     145             : 
     146           0 :             ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
     147           0 :             return aPoint;
     148             :         }
     149             : 
     150             :         void UpdateChildren();
     151             :         void Dispose();
     152             : 
     153             : #ifdef DBG_UTIL
     154             :         void CheckInvariants() const;
     155             : #endif
     156             : 
     157             :         AccessibleEditableTextPara& GetParagraph( sal_Int32 nPara ) const;
     158             :         sal_Int32                   GetParagraphCount() const;
     159             : 
     160           0 :         EPosition                   Index2Internal( sal_Int32 nFlatIndex ) const
     161             :         {
     162             : 
     163           0 :             return ImpCalcInternal( nFlatIndex, false );
     164             :         }
     165             : 
     166           0 :         EPosition                   Range2Internal( sal_Int32 nFlatIndex ) const
     167             :         {
     168             : 
     169           0 :             return ImpCalcInternal( nFlatIndex, true );
     170             :         }
     171             : 
     172             :         sal_Int32                   Internal2Index( EPosition nEEIndex ) const;
     173             : 
     174             :         void                        CorrectTextSegment( TextSegment&    aTextSegment,
     175             :                                                         int             nPara   ) const;
     176             : 
     177             :         bool                    SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
     178             :                                                   sal_Int32 nEndPara, sal_Int32 nEndIndex );
     179             :         bool                    CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
     180             :                                               sal_Int32 nEndPara, sal_Int32 nEndIndex );
     181             : 
     182             :         Rectangle                   GetParagraphBoundingBox() const;
     183             :         bool                    RemoveLineBreakCount( sal_Int32& rIndex );
     184             : 
     185             :     private:
     186             : 
     187             :         EPosition                   ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const;
     188             : 
     189             :         // our frontend class (the one implementing the actual
     190             :         // interface). That's not necessarily the one containing the impl
     191             :         // pointer
     192             :         uno::Reference< XAccessible > mxThis;
     193             : 
     194             :         // implements our functionality, we're just an adapter (guarded by solar mutex)
     195             :         mutable AccessibleEditableTextPara* mpTextParagraph;
     196             : 
     197             :         uno::Reference< XAccessible > mxParagraph;
     198             : 
     199             :         // a wrapper for the text forwarders (guarded by solar mutex)
     200             :         mutable SvxEditSourceAdapter maEditSource;
     201             : 
     202             :         // guard for maOffset
     203             :         mutable ::osl::Mutex maMutex;
     204             : 
     205             :         /// our current offset to the containing shape/cell (guarded by maMutex)
     206             :         Point maOffset;
     207             : 
     208             :     };
     209             : 
     210             : 
     211             : 
     212             :     // AccessibleStaticTextBase_Impl implementation
     213             : 
     214             : 
     215             : 
     216          10 :     AccessibleStaticTextBase_Impl::AccessibleStaticTextBase_Impl() :
     217             :         mxThis( NULL ),
     218          10 :         mpTextParagraph( new AccessibleEditableTextPara(NULL) ),
     219             :         mxParagraph( mpTextParagraph ),
     220             :         maEditSource(),
     221             :         maMutex(),
     222          20 :         maOffset(0,0)
     223             :     {
     224             : 
     225             :         // TODO: this is still somewhat of a hack, all the more since
     226             :         // now the maTextParagraph has an empty parent reference set
     227          10 :     }
     228             : 
     229          10 :     AccessibleStaticTextBase_Impl::~AccessibleStaticTextBase_Impl()
     230             :     {
     231          10 :     }
     232             : 
     233          10 :     void AccessibleStaticTextBase_Impl::SetEditSource( ::std::unique_ptr< SvxEditSource > && pEditSource )
     234             :     {
     235             : 
     236          10 :         maEditSource.SetEditSource( std::move(pEditSource) );
     237          10 :         if( mpTextParagraph )
     238          10 :             mpTextParagraph->SetEditSource( &maEditSource );
     239          10 :     }
     240             : 
     241          20 :     void AccessibleStaticTextBase_Impl::SetOffset( const Point& rPoint )
     242             :     {
     243             : 
     244             :         // guard against non-atomic access to maOffset data structure
     245             :         {
     246          20 :             ::osl::MutexGuard aGuard( maMutex );
     247          20 :             maOffset = rPoint;
     248             :         }
     249             : 
     250          20 :         if( mpTextParagraph )
     251          20 :             mpTextParagraph->SetEEOffset( rPoint );
     252             : 
     253             :         // in all cases, check visibility afterwards.
     254          20 :         UpdateChildren();
     255          20 :     }
     256             : 
     257          20 :     void AccessibleStaticTextBase_Impl::UpdateChildren()
     258             :     {
     259             : 
     260             :         // currently no children
     261          20 :     }
     262             : 
     263          10 :     void AccessibleStaticTextBase_Impl::Dispose()
     264             :     {
     265             : 
     266             :         // we're the owner of the paragraph, so destroy it, too
     267          10 :         if( mpTextParagraph )
     268          10 :             mpTextParagraph->Dispose();
     269             : 
     270             :         // drop references
     271          10 :         mxParagraph = NULL;
     272          10 :         mxThis = NULL;
     273          10 :         mpTextParagraph = NULL;
     274          10 :     }
     275             : 
     276             : #ifdef DBG_UTIL
     277             :     void AccessibleStaticTextBase_Impl::CheckInvariants() const
     278             :     {
     279             :         // TODO
     280             :     }
     281             : #endif
     282             : 
     283           0 :     AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int32 nPara ) const
     284             :     {
     285             : 
     286           0 :         if( !mpTextParagraph )
     287           0 :             throw lang::DisposedException ("object has been already disposed", mxThis );
     288             : 
     289             :         // TODO: Have a different method on AccessibleEditableTextPara
     290             :         // that does not care about state changes
     291           0 :         mpTextParagraph->SetParagraphIndex( nPara );
     292             : 
     293           0 :         return *mpTextParagraph;
     294             :     }
     295             : 
     296           0 :     sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const
     297             :     {
     298             : 
     299           0 :         if( !mpTextParagraph )
     300           0 :             return 0;
     301             :         else
     302           0 :             return mpTextParagraph->GetTextForwarder().GetParagraphCount();
     303             :     }
     304             : 
     305           0 :     sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index( EPosition nEEIndex ) const
     306             :     {
     307             :         // XXX checks for overflow and returns maximum if so
     308           0 :         sal_Int32 aRes(0);
     309           0 :         for(sal_Int32 i=0; i<nEEIndex.nPara; ++i)
     310             :         {
     311           0 :             sal_Int32 nCount = GetParagraph(i).getCharacterCount();
     312           0 :             if (SAL_MAX_INT32 - aRes > nCount)
     313           0 :                 return SAL_MAX_INT32;
     314           0 :             aRes += nCount;
     315             :         }
     316             : 
     317           0 :         if (SAL_MAX_INT32 - aRes > nEEIndex.nIndex)
     318           0 :             return SAL_MAX_INT32;
     319           0 :         return aRes + nEEIndex.nIndex;
     320             :     }
     321             : 
     322           0 :     void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment&    aTextSegment,
     323             :                                                             int             nPara   ) const
     324             :     {
     325             :         // Keep 'invalid' values at the TextSegment
     326           0 :         if( aTextSegment.SegmentStart != -1 &&
     327           0 :             aTextSegment.SegmentEnd != -1 )
     328             :         {
     329             :             // #112814# Correct TextSegment by paragraph offset
     330           0 :             sal_Int32 nOffset(0);
     331             :             int i;
     332           0 :             for(i=0; i<nPara; ++i)
     333           0 :                 nOffset += GetParagraph(i).getCharacterCount();
     334             : 
     335           0 :             aTextSegment.SegmentStart += nOffset;
     336           0 :             aTextSegment.SegmentEnd += nOffset;
     337             :         }
     338           0 :     }
     339             : 
     340           0 :     EPosition AccessibleStaticTextBase_Impl::ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const
     341             :     {
     342             : 
     343           0 :         if( nFlatIndex < 0 )
     344             :             throw lang::IndexOutOfBoundsException("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds",
     345           0 :                                                   mxThis);
     346             :         // gratuitously accepting larger indices here, AccessibleEditableTextPara will throw eventually
     347             : 
     348             :         sal_Int32 nCurrPara, nCurrIndex, nParas, nCurrCount;
     349           0 :         for( nCurrPara=0, nParas=GetParagraphCount(), nCurrCount=0, nCurrIndex=0; nCurrPara<nParas; ++nCurrPara )
     350             :         {
     351           0 :             nCurrCount = GetParagraph( nCurrPara ).getCharacterCount();
     352           0 :             nCurrIndex += nCurrCount;
     353           0 :             if( nCurrIndex >= nFlatIndex )
     354             :             {
     355             :                 // check overflow
     356             :                 DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= SAL_MAX_INT32 &&
     357             :                            nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
     358             :                            "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
     359             : 
     360           0 :                 return EPosition(nCurrPara, nFlatIndex - nCurrIndex + nCurrCount);
     361             :             }
     362             :         }
     363             : 
     364             :         // #102170# Allow one-past the end for ranges
     365           0 :         if( bExclusive && nCurrIndex == nFlatIndex )
     366             :         {
     367             :             // check overflow
     368             :             DBG_ASSERT(nCurrPara > 0 && nCurrPara <= SAL_MAX_INT32 &&
     369             :                        nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
     370             :                        "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
     371             : 
     372           0 :             return EPosition(nCurrPara-1, nFlatIndex - nCurrIndex + nCurrCount);
     373             :         }
     374             : 
     375             :         // not found? Out of bounds
     376             :         throw lang::IndexOutOfBoundsException("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds",
     377           0 :                                               mxThis);
     378             :     }
     379             : 
     380           0 :     bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
     381             :                                                           sal_Int32 nEndPara, sal_Int32 nEndIndex )
     382             :     {
     383             : 
     384           0 :         if( !mpTextParagraph )
     385           0 :             return false;
     386             : 
     387             :         try
     388             :         {
     389           0 :             SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( true );
     390           0 :             return rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
     391             :         }
     392           0 :         catch( const uno::RuntimeException& )
     393             :         {
     394           0 :             return false;
     395             :         }
     396             :     }
     397             : 
     398           0 :     bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
     399             :                                                       sal_Int32 nEndPara, sal_Int32 nEndIndex )
     400             :     {
     401             : 
     402           0 :         if( !mpTextParagraph )
     403           0 :             return false;
     404             : 
     405             :         try
     406             :         {
     407           0 :             SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( true );
     408           0 :             mpTextParagraph->GetTextForwarder();    // MUST be after GetEditViewForwarder(), see method docs
     409             :             bool aRetVal;
     410             : 
     411             :             // save current selection
     412           0 :             ESelection aOldSelection;
     413             : 
     414           0 :             rCacheVF.GetSelection( aOldSelection );
     415           0 :             rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
     416           0 :             aRetVal = rCacheVF.Copy();
     417           0 :             rCacheVF.SetSelection( aOldSelection ); // restore
     418             : 
     419           0 :             return aRetVal;
     420             :         }
     421           0 :         catch( const uno::RuntimeException& )
     422             :         {
     423           0 :             return false;
     424             :         }
     425             :     }
     426             : 
     427           0 :     Rectangle AccessibleStaticTextBase_Impl::GetParagraphBoundingBox() const
     428             :     {
     429           0 :         Rectangle aRect;
     430           0 :         if( mpTextParagraph )
     431             :         {
     432           0 :             awt::Rectangle aAwtRect = mpTextParagraph->getBounds();
     433           0 :             aRect = Rectangle( Point( aAwtRect.X, aAwtRect.Y ), Size( aAwtRect.Width, aAwtRect.Height ) );
     434             :         }
     435             :         else
     436             :         {
     437           0 :             aRect.SetEmpty();
     438             :         }
     439           0 :         return aRect;
     440             :     }
     441             :     //the input argument is the index(including "\n" ) in the string.
     442             :     //the function will calculate the actual index(not including "\n") in the string.
     443             :     //and return true if the index is just at a "\n"
     444           0 :     bool AccessibleStaticTextBase_Impl::RemoveLineBreakCount( sal_Int32& rIndex )
     445             :     {
     446             :         // get the total char number inside the cell.
     447             :         sal_Int32 i, nCount, nParas;
     448           0 :         for( i=0, nCount=0, nParas=GetParagraphCount(); i<nParas; ++i )
     449           0 :             nCount += GetParagraph(i).getCharacterCount();
     450           0 :         nCount = nCount + (nParas-1);
     451           0 :         if( nCount == 0 &&  rIndex == 0) return false;
     452             : 
     453             : 
     454             :         sal_Int32 nCurrPara, nCurrCount;
     455           0 :         sal_Int32 nLineBreakPos = 0, nLineBreakCount = 0;
     456           0 :         sal_Int32 nParaCount = GetParagraphCount();
     457           0 :         for ( nCurrCount = 0, nCurrPara = 0; nCurrPara < nParaCount; nCurrPara++ )
     458             :         {
     459           0 :             nCurrCount += GetParagraph( nCurrPara ).getCharacterCount();
     460           0 :             nLineBreakPos = nCurrCount++;
     461           0 :             if ( rIndex == nLineBreakPos )
     462             :             {
     463           0 :                 rIndex -= (++nLineBreakCount);//(++nLineBreakCount);
     464           0 :                 if ( rIndex < 0)
     465             :                 {
     466           0 :                     rIndex = 0;
     467             :                 }
     468             :                 //if the index is at the last position of the last paragraph
     469             :                 //there is no "\n" , so we should increase rIndex by 1 and return false.
     470           0 :                 if ( (nCurrPara+1) == nParaCount )
     471             :                 {
     472           0 :                     rIndex++;
     473           0 :                     return false;
     474             :                 }
     475             :                 else
     476             :                 {
     477           0 :                     return true;
     478             :                 }
     479             :             }
     480           0 :             else if ( rIndex < nLineBreakPos )
     481             :             {
     482           0 :                 rIndex -= nLineBreakCount;
     483           0 :                 return false;
     484             :             }
     485             :             else
     486             :             {
     487           0 :                 nLineBreakCount++;
     488             :             }
     489             :         }
     490           0 :         return false;
     491             :     }
     492             : 
     493             : 
     494             :     // AccessibleStaticTextBase implementation
     495             : 
     496          10 :     AccessibleStaticTextBase::AccessibleStaticTextBase( ::std::unique_ptr< SvxEditSource > && pEditSource ) :
     497          10 :         mpImpl( new AccessibleStaticTextBase_Impl() )
     498             :     {
     499          10 :         SolarMutexGuard aGuard;
     500             : 
     501          10 :         SetEditSource( std::move(pEditSource) );
     502          10 :     }
     503             : 
     504          10 :     AccessibleStaticTextBase::~AccessibleStaticTextBase()
     505             :     {
     506          10 :     }
     507             : 
     508           0 :     const SvxEditSource& AccessibleStaticTextBase::GetEditSource() const
     509             :     {
     510             : #ifdef DBG_UTIL
     511             :         mpImpl->CheckInvariants();
     512             : 
     513             :         const SvxEditSource& aEditSource = mpImpl->GetEditSource();
     514             : 
     515             :         mpImpl->CheckInvariants();
     516             : 
     517             :         return aEditSource;
     518             : #else
     519           0 :         return mpImpl->GetEditSource();
     520             : #endif
     521             :     }
     522             : 
     523          10 :     void AccessibleStaticTextBase::SetEditSource( ::std::unique_ptr< SvxEditSource > && pEditSource )
     524             :     {
     525             : #ifdef DBG_UTIL
     526             :         // precondition: solar mutex locked
     527             :         DBG_TESTSOLARMUTEX();
     528             : 
     529             :         mpImpl->CheckInvariants();
     530             : 
     531             :         mpImpl->SetEditSource( std::move(pEditSource) );
     532             : 
     533             :         mpImpl->CheckInvariants();
     534             : #else
     535          10 :         mpImpl->SetEditSource( std::move(pEditSource) );
     536             : #endif
     537          10 :     }
     538             : 
     539          10 :     void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface )
     540             :     {
     541             : #ifdef DBG_UTIL
     542             :         mpImpl->CheckInvariants();
     543             : #endif
     544             : 
     545          10 :         mpImpl->SetEventSource( rInterface );
     546             : 
     547             : #ifdef DBG_UTIL
     548             :         mpImpl->CheckInvariants();
     549             : #endif
     550          10 :     }
     551             : 
     552           0 :     uno::Reference< XAccessible > AccessibleStaticTextBase::GetEventSource() const
     553             :     {
     554             : #ifdef DBG_UTIL
     555             :         mpImpl->CheckInvariants();
     556             : 
     557             :         uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
     558             : 
     559             :         mpImpl->CheckInvariants();
     560             : 
     561             :         return xRet;
     562             : #else
     563           0 :         return mpImpl->GetEventSource();
     564             : #endif
     565             :     }
     566             : 
     567          20 :     void AccessibleStaticTextBase::SetOffset( const Point& rPoint )
     568             :     {
     569             : #ifdef DBG_UTIL
     570             :         // precondition: solar mutex locked
     571             :         DBG_TESTSOLARMUTEX();
     572             : 
     573             :         mpImpl->CheckInvariants();
     574             : 
     575             :         mpImpl->SetOffset( rPoint );
     576             : 
     577             :         mpImpl->CheckInvariants();
     578             : #else
     579          20 :         mpImpl->SetOffset( rPoint );
     580             : #endif
     581          20 :     }
     582             : 
     583           0 :     Point AccessibleStaticTextBase::GetOffset() const
     584             :     {
     585             : #ifdef DBG_UTIL
     586             :         mpImpl->CheckInvariants();
     587             : 
     588             :         Point aPoint( mpImpl->GetOffset() );
     589             : 
     590             :         mpImpl->CheckInvariants();
     591             : 
     592             :         return aPoint;
     593             : #else
     594           0 :         return mpImpl->GetOffset();
     595             : #endif
     596             :     }
     597             : 
     598           0 :     void AccessibleStaticTextBase::UpdateChildren()
     599             :     {
     600             : #ifdef DBG_UTIL
     601             :         // precondition: solar mutex locked
     602             :         DBG_TESTSOLARMUTEX();
     603             : 
     604             :         mpImpl->CheckInvariants();
     605             : 
     606             :         mpImpl->UpdateChildren();
     607             : 
     608             :         mpImpl->CheckInvariants();
     609             : #else
     610           0 :         mpImpl->UpdateChildren();
     611             : #endif
     612           0 :     }
     613             : 
     614          10 :     void AccessibleStaticTextBase::Dispose()
     615             :     {
     616             : #ifdef DBG_UTIL
     617             :         mpImpl->CheckInvariants();
     618             : #endif
     619             : 
     620          10 :         mpImpl->Dispose();
     621             : 
     622             : #ifdef DBG_UTIL
     623             :         mpImpl->CheckInvariants();
     624             : #endif
     625          10 :     }
     626             : 
     627             :     // XAccessibleContext
     628          16 :     sal_Int32 SAL_CALL AccessibleStaticTextBase::getAccessibleChildCount() throw (uno::RuntimeException, std::exception)
     629             :     {
     630             :         // no children at all
     631          16 :         return 0;
     632             :     }
     633             : 
     634           0 :     uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleChild( sal_Int32 /*i*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     635             :     {
     636             :         // no children at all
     637           0 :         return uno::Reference< XAccessible >();
     638             :     }
     639             : 
     640           0 :     uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleAtPoint( const awt::Point& /*_aPoint*/ ) throw (uno::RuntimeException, std::exception)
     641             :     {
     642             :         // no children at all
     643           0 :         return uno::Reference< XAccessible >();
     644             :     }
     645             : 
     646             :     // XAccessibleText
     647           0 :     sal_Int32 SAL_CALL AccessibleStaticTextBase::getCaretPosition() throw (uno::RuntimeException, std::exception)
     648             :     {
     649           0 :         SolarMutexGuard aGuard;
     650             : 
     651             :         sal_Int32 i, nPos, nParas;
     652           0 :         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
     653             :         {
     654           0 :             if( (nPos=mpImpl->GetParagraph(i).getCaretPosition()) != -1 )
     655           0 :                 return nPos;
     656             :         }
     657             : 
     658           0 :         return nPos;
     659             :     }
     660             : 
     661           0 :     sal_Bool SAL_CALL AccessibleStaticTextBase::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     662             :     {
     663           0 :         return setSelection(nIndex, nIndex);
     664             :     }
     665             : 
     666           0 :     sal_Unicode SAL_CALL AccessibleStaticTextBase::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     667             :     {
     668           0 :         SolarMutexGuard aGuard;
     669             : 
     670           0 :         EPosition aPos( mpImpl->Index2Internal(nIndex) );
     671             : 
     672           0 :         return mpImpl->GetParagraph( aPos.nPara ).getCharacter( aPos.nIndex );
     673             :     }
     674             : 
     675           0 :     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< OUString >& aRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     676             :     {
     677           0 :         SolarMutexGuard aGuard;
     678             : 
     679             :         //get the actual index without "\n"
     680           0 :         mpImpl->RemoveLineBreakCount( nIndex );
     681             : 
     682           0 :         EPosition aPos( mpImpl->Index2Internal(nIndex) );
     683             : 
     684           0 :         return mpImpl->GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes );
     685             :     }
     686             : 
     687           0 :     awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     688             :     {
     689           0 :         SolarMutexGuard aGuard;
     690             : 
     691             :         // #108900# Allow ranges for nIndex, as one-past-the-end
     692             :         // values are now legal, too.
     693           0 :         EPosition aPos( mpImpl->Range2Internal(nIndex) );
     694             : 
     695             :         // #i70916# Text in spread sheet cells return the wrong extents
     696           0 :         AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
     697           0 :         awt::Rectangle aParaBounds( rPara.getBounds() );
     698           0 :         awt::Rectangle aBounds( rPara.getCharacterBounds( aPos.nIndex ) );
     699           0 :         aBounds.X += aParaBounds.X;
     700           0 :         aBounds.Y += aParaBounds.Y;
     701             : 
     702           0 :         return aBounds;
     703             :     }
     704             : 
     705           0 :     sal_Int32 SAL_CALL AccessibleStaticTextBase::getCharacterCount() throw (uno::RuntimeException, std::exception)
     706             :     {
     707           0 :         SolarMutexGuard aGuard;
     708             : 
     709             :         sal_Int32 i, nCount, nParas;
     710           0 :         for( i=0, nCount=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
     711           0 :             nCount += mpImpl->GetParagraph(i).getCharacterCount();
     712             :         //count on the number of "\n" which equals number of paragraphs decrease 1.
     713           0 :         nCount = nCount + (nParas-1);
     714           0 :         return nCount;
     715             :     }
     716             : 
     717           0 :     sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException, std::exception)
     718             :     {
     719           0 :         SolarMutexGuard aGuard;
     720             : 
     721           0 :         const sal_Int32 nParas( mpImpl->GetParagraphCount() );
     722             :         sal_Int32 nIndex;
     723             :         int i;
     724           0 :         for( i=0; i<nParas; ++i )
     725             :         {
     726             :             // TODO: maybe exploit the fact that paragraphs are
     727             :             // ordered vertically for early exit
     728             : 
     729             :             // #i70916# Text in spread sheet cells return the wrong extents
     730           0 :             AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( i );
     731           0 :             awt::Rectangle aParaBounds( rPara.getBounds() );
     732           0 :             awt::Point aPoint( rPoint );
     733           0 :             aPoint.X -= aParaBounds.X;
     734           0 :             aPoint.Y -= aParaBounds.Y;
     735             : 
     736             :             // #112814# Use correct index offset
     737           0 :             if ( ( nIndex = rPara.getIndexAtPoint( aPoint ) ) != -1 )
     738           0 :                 return mpImpl->Internal2Index(EPosition(i, nIndex));
     739             :         }
     740             : 
     741           0 :         return -1;
     742             :     }
     743             : 
     744           0 :     OUString SAL_CALL AccessibleStaticTextBase::getSelectedText() throw (uno::RuntimeException, std::exception)
     745             :     {
     746           0 :         SolarMutexGuard aGuard;
     747             : 
     748           0 :         sal_Int32 nStart( getSelectionStart() );
     749           0 :         sal_Int32 nEnd( getSelectionEnd() );
     750             : 
     751             :         // #104481# Return the empty string for 'no selection'
     752           0 :         if( nStart < 0 || nEnd < 0 )
     753           0 :             return OUString();
     754             : 
     755           0 :         return getTextRange( nStart, nEnd );
     756             :     }
     757             : 
     758           0 :     sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionStart() throw (uno::RuntimeException, std::exception)
     759             :     {
     760           0 :         SolarMutexGuard aGuard;
     761             : 
     762             :         sal_Int32 i, nPos, nParas;
     763           0 :         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
     764             :         {
     765           0 :             if( (nPos=mpImpl->GetParagraph(i).getSelectionStart()) != -1 )
     766           0 :                 return nPos;
     767             :         }
     768             : 
     769           0 :         return nPos;
     770             :     }
     771             : 
     772           0 :     sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionEnd() throw (uno::RuntimeException, std::exception)
     773             :     {
     774           0 :         SolarMutexGuard aGuard;
     775             : 
     776             :         sal_Int32 i, nPos, nParas;
     777           0 :         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
     778             :         {
     779           0 :             if( (nPos=mpImpl->GetParagraph(i).getSelectionEnd()) != -1 )
     780           0 :                 return nPos;
     781             :         }
     782             : 
     783           0 :         return nPos;
     784             :     }
     785             : 
     786           0 :     sal_Bool SAL_CALL AccessibleStaticTextBase::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     787             :     {
     788           0 :         SolarMutexGuard aGuard;
     789             : 
     790           0 :         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
     791           0 :         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
     792             : 
     793             :         return mpImpl->SetSelection( aStartIndex.nPara, aStartIndex.nIndex,
     794           0 :                                      aEndIndex.nPara, aEndIndex.nIndex );
     795             :     }
     796             : 
     797           0 :     OUString SAL_CALL AccessibleStaticTextBase::getText() throw (uno::RuntimeException, std::exception)
     798             :     {
     799           0 :         SolarMutexGuard aGuard;
     800             : 
     801             :         sal_Int32 i, nParas;
     802           0 :         OUString aRes;
     803           0 :         for( i=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
     804           0 :             aRes += mpImpl->GetParagraph(i).getText();
     805             : 
     806           0 :         return aRes;
     807             :     }
     808             : 
     809           0 :     OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     810             :     {
     811           0 :         SolarMutexGuard aGuard;
     812             : 
     813           0 :         if( nStartIndex > nEndIndex )
     814           0 :             ::std::swap(nStartIndex, nEndIndex);
     815             :         //if startindex equals endindex we will get nothing. So return an empty string directly.
     816           0 :         if ( nStartIndex == nEndIndex )
     817             :         {
     818           0 :             return OUString();
     819             :         }
     820           0 :         bool bStart = mpImpl->RemoveLineBreakCount( nStartIndex );
     821             :         //if the start index is just at a "\n", we need to begin from the next char
     822           0 :         if ( bStart )
     823             :         {
     824           0 :             nStartIndex++;
     825             :         }
     826             :         //we need to find out whether the previous position of the current endindex is at "\n" or not
     827             :         //if yes we need to mark it and add "\n" at the end of the result
     828           0 :         sal_Int32 nTemp = nEndIndex - 1;
     829           0 :         bool bEnd = mpImpl->RemoveLineBreakCount( nTemp );
     830           0 :         bool bTemp = mpImpl->RemoveLineBreakCount( nEndIndex );
     831             :         //if the below condition is true it indicates an empty paragraph with just a "\n"
     832             :         //so we need to set one "\n" flag to avoid duplication.
     833           0 :         if ( bStart && bEnd && ( nStartIndex == nEndIndex) )
     834             :         {
     835           0 :             bEnd = false;
     836             :         }
     837             :         //if the current endindex is at a "\n", we need to increase endindex by 1 to make sure
     838             :         //the char before "\n" is included. Because string returned by this function will not include
     839             :         //the char at the endindex.
     840           0 :         if ( bTemp )
     841             :         {
     842           0 :             nEndIndex++;
     843             :         }
     844           0 :         OUString aRes;
     845           0 :         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
     846           0 :         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
     847             : 
     848             :         // #102170# Special case: start and end paragraph are identical
     849           0 :         if( aStartIndex.nPara == aEndIndex.nPara )
     850             :         {
     851             :             //we don't return the string directly now for that we have to do some further process for "\n"
     852           0 :             aRes = mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex );
     853             :         }
     854             :         else
     855             :         {
     856           0 :             sal_Int32 i( aStartIndex.nPara );
     857           0 :             aRes = mpImpl->GetParagraph(i).getTextRange( aStartIndex.nIndex,
     858           0 :                                                          mpImpl->GetParagraph(i).getCharacterCount()/*-1*/);
     859           0 :             ++i;
     860             : 
     861             :             // paragraphs inbetween are fully included
     862           0 :             for( ; i<aEndIndex.nPara; ++i )
     863             :             {
     864           0 :                 aRes += OUString(cNewLine);
     865           0 :                 aRes += mpImpl->GetParagraph(i).getText();
     866             :             }
     867             : 
     868           0 :             if( i<=aEndIndex.nPara )
     869             :             {
     870             :                 //if the below condition is mathed it means the endindex is at mid of the last paragraph
     871             :                 //we need to add a "\n" before we add the last part of the string.
     872           0 :                 if ( !bEnd && aEndIndex.nIndex )
     873             :                 {
     874           0 :                     aRes += OUString(cNewLine);
     875             :                 }
     876           0 :                 aRes += mpImpl->GetParagraph(i).getTextRange( 0, aEndIndex.nIndex );
     877             :             }
     878             :         }
     879             :         //According the the flag we marked before, we have to add "\n" at the beginning
     880             :         //or at the end of the result string.
     881           0 :         if ( bStart )
     882             :         {
     883           0 :             aRes = OUString(cNewLine) + aRes;
     884             :         }
     885           0 :         if ( bEnd )
     886             :         {
     887           0 :             aRes += OUString(cNewLine);
     888             :         }
     889           0 :         return aRes;
     890             :     }
     891             : 
     892           0 :     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     893             :     {
     894           0 :         SolarMutexGuard aGuard;
     895             : 
     896           0 :         bool bLineBreak = mpImpl->RemoveLineBreakCount( nIndex );
     897           0 :         EPosition aPos( mpImpl->Range2Internal(nIndex) );
     898             : 
     899           0 :         ::com::sun::star::accessibility::TextSegment aResult;
     900             : 
     901           0 :         if( AccessibleTextType::PARAGRAPH == aTextType )
     902             :         {
     903             :             // #106393# Special casing one behind last paragraph is
     904             :             // not necessary, since then, we return the content and
     905             :             // boundary of that last paragraph. Range2Internal is
     906             :             // tolerant against that, and returns the last paragraph
     907             :             // in aPos.nPara.
     908             : 
     909             :             // retrieve full text of the paragraph
     910           0 :             aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
     911             : 
     912             :             // #112814# Adapt the start index with the paragraph offset
     913           0 :             aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
     914           0 :             aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
     915             :         }
     916           0 :         else if ( AccessibleTextType::ATTRIBUTE_RUN == aTextType )
     917             :         {
     918           0 :               SvxAccessibleTextAdapter& rTextForwarder = mpImpl->GetParagraph( aPos.nIndex ).GetTextForwarder();
     919             :               sal_Int32 nStartIndex, nEndIndex;
     920           0 :               if ( rTextForwarder.GetAttributeRun( nStartIndex, nEndIndex, aPos.nPara, aPos.nIndex, true ) )
     921             :               {
     922           0 :                      aResult.SegmentText = getTextRange( nStartIndex, nEndIndex );
     923           0 :                      aResult.SegmentStart = nStartIndex;
     924           0 :                      aResult.SegmentEnd = nEndIndex;
     925             :               }
     926             :         }
     927             :         else
     928             :         {
     929             :             // No special handling required, forward to wrapped class
     930           0 :             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType );
     931             : 
     932             :             // #112814# Adapt the start index with the paragraph offset
     933           0 :             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
     934           0 :             if ( bLineBreak )
     935             :             {
     936           0 :                 aResult.SegmentText = OUString(cNewLine);
     937             :             }
     938             :         }
     939             : 
     940           0 :         return aResult;
     941             :     }
     942             : 
     943           0 :     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     944             :     {
     945           0 :         SolarMutexGuard aGuard;
     946             : 
     947           0 :         sal_Int32 nOldIdx = nIndex;
     948           0 :         bool bLineBreak =  mpImpl->RemoveLineBreakCount( nIndex );
     949           0 :         EPosition aPos( mpImpl->Range2Internal(nIndex) );
     950             : 
     951           0 :         ::com::sun::star::accessibility::TextSegment aResult;
     952             : 
     953           0 :         if( AccessibleTextType::PARAGRAPH == aTextType )
     954             :         {
     955           0 :             if( aPos.nIndex == mpImpl->GetParagraph( aPos.nPara ).getCharacterCount() )
     956             :             {
     957             :                 // #103589# Special casing one behind the last paragraph
     958           0 :                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
     959             : 
     960             :                 // #112814# Adapt the start index with the paragraph offset
     961           0 :                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
     962             :             }
     963           0 :             else if( aPos.nPara > 0 )
     964             :             {
     965           0 :                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara - 1 ).getText();
     966             : 
     967             :                 // #112814# Adapt the start index with the paragraph offset
     968           0 :                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara - 1, 0 ) );
     969             :             }
     970             : 
     971           0 :             aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
     972             :         }
     973             :         else
     974             :         {
     975             :             // No special handling required, forward to wrapped class
     976           0 :             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType );
     977             : 
     978             :             // #112814# Adapt the start index with the paragraph offset
     979           0 :             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
     980           0 :             if ( bLineBreak && (nOldIdx-1) >= 0)
     981             :             {
     982           0 :                 aResult = getTextAtIndex( nOldIdx-1, aTextType );
     983             :             }
     984             :         }
     985             : 
     986           0 :         return aResult;
     987             :     }
     988             : 
     989           0 :     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     990             :     {
     991           0 :         SolarMutexGuard aGuard;
     992             : 
     993           0 :         sal_Int32 nTemp = nIndex+1;
     994           0 :         bool bLineBreak = mpImpl->RemoveLineBreakCount( nTemp );
     995           0 :         mpImpl->RemoveLineBreakCount( nIndex );
     996           0 :         EPosition aPos( mpImpl->Range2Internal(nIndex) );
     997             : 
     998           0 :         ::com::sun::star::accessibility::TextSegment aResult;
     999             : 
    1000           0 :         if( AccessibleTextType::PARAGRAPH == aTextType )
    1001             :         {
    1002             :             // Special casing one behind the last paragraph is not
    1003             :             // necessary, this case is invalid here for
    1004             :             // getTextBehindIndex
    1005           0 :             if( aPos.nPara + 1 < mpImpl->GetParagraphCount() )
    1006             :             {
    1007           0 :                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara + 1 ).getText();
    1008             : 
    1009             :                 // #112814# Adapt the start index with the paragraph offset
    1010           0 :                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara + 1, 0 ) );
    1011           0 :                 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
    1012             :             }
    1013             :         }
    1014             :         else
    1015             :         {
    1016             :             // No special handling required, forward to wrapped class
    1017           0 :             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType );
    1018             : 
    1019             :             // #112814# Adapt the start index with the paragraph offset
    1020           0 :             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
    1021           0 :             if ( bLineBreak )
    1022             :             {
    1023           0 :                 aResult.SegmentText = OUString(cNewLine) + aResult.SegmentText;
    1024             :             }
    1025             :        }
    1026             : 
    1027           0 :         return aResult;
    1028             :     }
    1029             : 
    1030           0 :     sal_Bool SAL_CALL AccessibleStaticTextBase::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    1031             :     {
    1032           0 :         SolarMutexGuard aGuard;
    1033             : 
    1034           0 :         if( nStartIndex > nEndIndex )
    1035           0 :             ::std::swap(nStartIndex, nEndIndex);
    1036             : 
    1037           0 :         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
    1038           0 :         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
    1039             : 
    1040             :         return mpImpl->CopyText( aStartIndex.nPara, aStartIndex.nIndex,
    1041           0 :                                  aEndIndex.nPara, aEndIndex.nIndex );
    1042             :     }
    1043             : 
    1044             :     // XAccessibleTextAttributes
    1045           0 :     uno::Sequence< beans::PropertyValue > AccessibleStaticTextBase::getDefaultAttributes( const uno::Sequence< OUString >& RequestedAttributes ) throw (uno::RuntimeException, std::exception)
    1046             :     {
    1047             :         // get the intersection of the default attributes of all paragraphs
    1048             : 
    1049           0 :         SolarMutexGuard aGuard;
    1050             : 
    1051           0 :         PropertyValueVector aDefAttrVec( mpImpl->GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes ) );
    1052             : 
    1053           0 :         const sal_Int32 nParaCount = mpImpl->GetParagraphCount();
    1054           0 :         for ( sal_Int32 nPara = 1; nPara < nParaCount; ++nPara )
    1055             :         {
    1056           0 :             uno::Sequence< beans::PropertyValue > aSeq = mpImpl->GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes );
    1057           0 :             PropertyValueVector aIntersectionVec;
    1058             : 
    1059           0 :             PropertyValueVector::const_iterator aEnd = aDefAttrVec.end();
    1060           0 :             for ( PropertyValueVector::const_iterator aItr = aDefAttrVec.begin(); aItr != aEnd; ++aItr )
    1061             :             {
    1062           0 :                 const beans::PropertyValue* pItr = aSeq.getConstArray();
    1063           0 :                 const beans::PropertyValue* pEnd  = pItr + aSeq.getLength();
    1064           0 :                 const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( *aItr ) ) );
    1065           0 :                 if ( pFind != pEnd )
    1066             :                 {
    1067           0 :                     aIntersectionVec.push_back( *pFind );
    1068             :                 }
    1069             :             }
    1070             : 
    1071           0 :             aDefAttrVec.swap( aIntersectionVec );
    1072             : 
    1073           0 :             if ( aDefAttrVec.empty() )
    1074             :             {
    1075           0 :                 break;
    1076             :             }
    1077           0 :         }
    1078             : 
    1079           0 :         return aDefAttrVec.getAsConstList();
    1080             :     }
    1081             : 
    1082           0 :     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunAttributes( sal_Int32 nIndex, const uno::Sequence< OUString >& RequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    1083             :     {
    1084             :         // get those default attributes of the paragraph, which are not part
    1085             :         // of the intersection of all paragraphs and add them to the run attributes
    1086             : 
    1087           0 :         SolarMutexGuard aGuard;
    1088             : 
    1089           0 :         EPosition aPos( mpImpl->Index2Internal( nIndex ) );
    1090           0 :         AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
    1091           0 :         uno::Sequence< beans::PropertyValue > aDefAttrSeq = rPara.getDefaultAttributes( RequestedAttributes );
    1092           0 :         uno::Sequence< beans::PropertyValue > aRunAttrSeq = rPara.getRunAttributes( aPos.nIndex, RequestedAttributes );
    1093           0 :         uno::Sequence< beans::PropertyValue > aIntersectionSeq = getDefaultAttributes( RequestedAttributes );
    1094           0 :         PropertyValueVector aDiffVec;
    1095             : 
    1096           0 :         const beans::PropertyValue* pDefAttr = aDefAttrSeq.getConstArray();
    1097           0 :         const sal_Int32 nLength = aDefAttrSeq.getLength();
    1098           0 :         for ( sal_Int32 i = 0; i < nLength; ++i )
    1099             :         {
    1100           0 :             const beans::PropertyValue* pItr = aIntersectionSeq.getConstArray();
    1101           0 :             const beans::PropertyValue* pEnd  = pItr + aIntersectionSeq.getLength();
    1102           0 :             const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( pDefAttr[i] ) ) );
    1103           0 :             if ( pFind == pEnd && pDefAttr[i].Handle != 0)
    1104             :             {
    1105           0 :                 aDiffVec.push_back( pDefAttr[i] );
    1106             :             }
    1107             :         }
    1108             : 
    1109           0 :         return ::comphelper::concatSequences( aRunAttrSeq, aDiffVec.getAsConstList() );
    1110             :     }
    1111             : 
    1112           0 :     Rectangle AccessibleStaticTextBase::GetParagraphBoundingBox() const
    1113             :     {
    1114           0 :         return mpImpl->GetParagraphBoundingBox();
    1115             :     }
    1116             : 
    1117         669 : }  // end of namespace accessibility
    1118             : 
    1119             : 
    1120             : 
    1121             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10