LCOV - code coverage report
Current view: top level - sw/source/core/access - accpara.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 292 1771 16.5 %
Date: 2015-06-13 12:38:46 Functions: 40 117 34.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <txtfrm.hxx>
      21             : #include <flyfrm.hxx>
      22             : #include <ndtxt.hxx>
      23             : #include <pam.hxx>
      24             : #include <unotextrange.hxx>
      25             : #include <unocrsrhelper.hxx>
      26             : #include <crstate.hxx>
      27             : #include <accmap.hxx>
      28             : #include <fesh.hxx>
      29             : #include <viewopt.hxx>
      30             : #include <osl/mutex.hxx>
      31             : #include <vcl/svapp.hxx>
      32             : #include <vcl/window.hxx>
      33             : #include <rtl/ustrbuf.hxx>
      34             : #include <com/sun/star/accessibility/AccessibleRole.hpp>
      35             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      36             : #include <com/sun/star/accessibility/AccessibleTextType.hpp>
      37             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      38             : #include <unotools/accessiblestatesethelper.hxx>
      39             : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      40             : #include <com/sun/star/i18n/WordType.hpp>
      41             : #include <com/sun/star/i18n/XBreakIterator.hpp>
      42             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      43             : #include <breakit.hxx>
      44             : #include <accpara.hxx>
      45             : #include <access.hrc>
      46             : #include <accportions.hxx>
      47             : #include <sfx2/viewsh.hxx>
      48             : #include <sfx2/viewfrm.hxx>
      49             : #include <sfx2/dispatch.hxx>
      50             : #include <unotools/charclass.hxx>
      51             : #include <unocrsr.hxx>
      52             : #include <unoport.hxx>
      53             : #include <doc.hxx>
      54             : #include <IDocumentRedlineAccess.hxx>
      55             : #include <crsskip.hxx>
      56             : #include <txtatr.hxx>
      57             : #include <acchyperlink.hxx>
      58             : #include <acchypertextdata.hxx>
      59             : #include <unotools/accessiblerelationsethelper.hxx>
      60             : #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
      61             : #include <section.hxx>
      62             : #include <doctxm.hxx>
      63             : #include <comphelper/accessibletexthelper.hxx>
      64             : #include <algorithm>
      65             : #include <docufld.hxx>
      66             : #include <txtfld.hxx>
      67             : #include <fmtfld.hxx>
      68             : #include <modcfg.hxx>
      69             : #include <com/sun/star/beans/XPropertySet.hpp>
      70             : #include "swmodule.hxx"
      71             : #include "redline.hxx"
      72             : #include <com/sun/star/awt/FontWeight.hpp>
      73             : #include <com/sun/star/awt/FontStrikeout.hpp>
      74             : #include <com/sun/star/awt/FontSlant.hpp>
      75             : #include <wrong.hxx>
      76             : #include <editeng/brushitem.hxx>
      77             : #include <swatrset.hxx>
      78             : #include <frmatr.hxx>
      79             : #include <unosett.hxx>
      80             : #include <paratr.hxx>
      81             : #include <com/sun/star/container/XIndexReplace.hpp>
      82             : #include <unomap.hxx>
      83             : #include <unoprnms.hxx>
      84             : #include <com/sun/star/text/WritingMode2.hpp>
      85             : #include <viewimp.hxx>
      86             : #include <boost/scoped_ptr.hpp>
      87             : #include <textmarkuphelper.hxx>
      88             : #include <parachangetrackinginfo.hxx>
      89             : #include <com/sun/star/text/TextMarkupType.hpp>
      90             : #include <comphelper/servicehelper.hxx>
      91             : #include <cppuhelper/supportsservice.hxx>
      92             : 
      93             : #include <reffld.hxx>
      94             : #include <expfld.hxx>
      95             : #include <flddat.hxx>
      96             : #include <fldui.hrc>
      97             : #include "../../uibase/inc/fldmgr.hxx"
      98             : #include "fldbas.hxx"      // SwField
      99             : 
     100             : using namespace ::com::sun::star;
     101             : using namespace ::com::sun::star::accessibility;
     102             : using namespace ::com::sun::star::container;
     103             : 
     104             : using beans::PropertyValue;
     105             : using beans::XMultiPropertySet;
     106             : using beans::UnknownPropertyException;
     107             : using beans::PropertyState_DIRECT_VALUE;
     108             : 
     109             : using std::max;
     110             : using std::min;
     111             : using std::sort;
     112             : 
     113             : namespace com { namespace sun { namespace star {
     114             :     namespace text {
     115             :         class XText;
     116             :     }
     117             : } } }
     118             : 
     119             : const sal_Char sServiceName[] = "com.sun.star.text.AccessibleParagraphView";
     120             : const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleParagraphView";
     121             : 
     122         282 : const SwTextNode* SwAccessibleParagraph::GetTextNode() const
     123             : {
     124         282 :     const SwFrm* pFrm = GetFrm();
     125             :     OSL_ENSURE( pFrm->IsTextFrm(), "The text frame has mutated!" );
     126             : 
     127         282 :     const SwTextNode* pNode = static_cast<const SwTextFrm*>(pFrm)->GetTextNode();
     128             :     OSL_ENSURE( pNode != NULL, "A text frame without a text node." );
     129             : 
     130         282 :     return pNode;
     131             : }
     132             : 
     133          34 : OUString SwAccessibleParagraph::GetString()
     134             : {
     135          34 :     return GetPortionData().GetAccessibleString();
     136             : }
     137             : 
     138          13 : OUString SwAccessibleParagraph::GetDescription()
     139             : {
     140          13 :     return OUString(); // provide empty description for paragraphs
     141             : }
     142             : 
     143         123 : sal_Int32 SwAccessibleParagraph::GetCaretPos()
     144             : {
     145         123 :     sal_Int32 nRet = -1;
     146             : 
     147             :     // get the selection's point, and test whether it's in our node
     148             :     // #i27301# - consider adjusted method signature
     149         123 :     SwPaM* pCaret = GetCursor( false );  // caret is first PaM in PaM-ring
     150             : 
     151         123 :     if( pCaret != NULL )
     152             :     {
     153          99 :         const SwTextNode* pNode = GetTextNode();
     154             : 
     155             :         // check whether the point points into 'our' node
     156          99 :         SwPosition* pPoint = pCaret->GetPoint();
     157          99 :         if( pNode->GetIndex() == pPoint->nNode.GetIndex() )
     158             :         {
     159             :             // same node? Then check whether it's also within 'our' part
     160             :             // of the paragraph
     161          79 :             const sal_Int32 nIndex = pPoint->nContent.GetIndex();
     162         211 :             if(!GetPortionData().IsValidCorePosition( nIndex ) ||
     163         132 :                 ( GetPortionData().IsZeroCorePositionData() && nIndex== 0) )
     164             :             {
     165          53 :                 const SwTextFrm *pTextFrm = PTR_CAST( SwTextFrm, GetFrm() );
     166          53 :                 bool bFormat = (pTextFrm && pTextFrm->HasPara());
     167          53 :                 if(bFormat)
     168             :                 {
     169          31 :                     ClearPortionData();
     170          31 :                     UpdatePortionData();
     171             :                 }
     172             :             }
     173          79 :             if( GetPortionData().IsValidCorePosition( nIndex ) )
     174             :             {
     175             :                 // Yes, it's us!
     176             :                 // consider that cursor/caret is in front of the list label
     177          79 :                 if ( pCaret->IsInFrontOfLabel() )
     178             :                 {
     179           0 :                     nRet = 0;
     180             :                 }
     181             :                 else
     182             :                 {
     183          79 :                     nRet = GetPortionData().GetAccessiblePosition( nIndex );
     184             :                 }
     185             : 
     186             :                 OSL_ENSURE( nRet >= 0, "invalid cursor?" );
     187             :                 OSL_ENSURE( nRet <= GetPortionData().GetAccessibleString().
     188             :                                               getLength(), "invalid cursor?" );
     189             :             }
     190             :             // else: in this paragraph, but in different frame
     191             :         }
     192             :         // else: not in this paragraph
     193             :     }
     194             :     // else: no cursor -> no caret
     195             : 
     196         123 :     return nRet;
     197             : }
     198             : 
     199           3 : bool SwAccessibleParagraph::GetSelection(
     200             :     sal_Int32& nStart, sal_Int32& nEnd)
     201             : {
     202           3 :     bool bRet = false;
     203           3 :     nStart = -1;
     204           3 :     nEnd = -1;
     205             : 
     206             :     // get the selection, and test whether it affects our text node
     207           3 :     SwPaM* pCrsr = GetCursor( true ); // #i27301# - consider adjusted method signature
     208           3 :     if( pCrsr != NULL )
     209             :     {
     210             :         // get SwPosition for my node
     211           3 :         const SwTextNode* pNode = GetTextNode();
     212           3 :         sal_uLong nHere = pNode->GetIndex();
     213             : 
     214             :         // iterate over ring
     215           6 :         for(SwPaM& rTmpCrsr : pCrsr->GetRingContainer())
     216             :         {
     217             :             // ignore, if no mark
     218           3 :             if( rTmpCrsr.HasMark() )
     219             :             {
     220             :                 // check whether nHere is 'inside' pCrsr
     221           0 :                 SwPosition* pStart = rTmpCrsr.Start();
     222           0 :                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
     223           0 :                 SwPosition* pEnd = rTmpCrsr.End();
     224           0 :                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
     225           0 :                 if( ( nHere >= nStartIndex ) &&
     226             :                     ( nHere <= nEndIndex )      )
     227             :                 {
     228             :                     // translate start and end positions
     229             : 
     230             :                     // start position
     231           0 :                     sal_Int32 nLocalStart = -1;
     232           0 :                     if( nHere > nStartIndex )
     233             :                     {
     234             :                         // selection starts in previous node:
     235             :                         // then our local selection starts with the paragraph
     236           0 :                         nLocalStart = 0;
     237             :                     }
     238             :                     else
     239             :                     {
     240             :                         OSL_ENSURE( nHere == nStartIndex,
     241             :                                     "miscalculated index" );
     242             : 
     243             :                         // selection starts in this node:
     244             :                         // then check whether it's before or inside our part of
     245             :                         // the paragraph, and if so, get the proper position
     246           0 :                         const sal_Int32 nCoreStart = pStart->nContent.GetIndex();
     247           0 :                         if( nCoreStart <
     248           0 :                             GetPortionData().GetFirstValidCorePosition() )
     249             :                         {
     250           0 :                             nLocalStart = 0;
     251             :                         }
     252           0 :                         else if( nCoreStart <=
     253           0 :                                  GetPortionData().GetLastValidCorePosition() )
     254             :                         {
     255             :                             OSL_ENSURE(
     256             :                                 GetPortionData().IsValidCorePosition(
     257             :                                                                   nCoreStart ),
     258             :                                  "problem determining valid core position" );
     259             : 
     260             :                             nLocalStart =
     261           0 :                                 GetPortionData().GetAccessiblePosition(
     262           0 :                                                                   nCoreStart );
     263             :                         }
     264             :                     }
     265             : 
     266             :                     // end position
     267           0 :                     sal_Int32 nLocalEnd = -1;
     268           0 :                     if( nHere < nEndIndex )
     269             :                     {
     270             :                         // selection ends in following node:
     271             :                         // then our local selection extends to the end
     272           0 :                         nLocalEnd = GetPortionData().GetAccessibleString().
     273           0 :                                                                    getLength();
     274             :                     }
     275             :                     else
     276             :                     {
     277             :                         OSL_ENSURE( nHere == nEndIndex,
     278             :                                     "miscalculated index" );
     279             : 
     280             :                         // selection ends in this node: then select everything
     281             :                         // before our part of the node
     282           0 :                         const sal_Int32 nCoreEnd = pEnd->nContent.GetIndex();
     283           0 :                         if( nCoreEnd >
     284           0 :                                 GetPortionData().GetLastValidCorePosition() )
     285             :                         {
     286             :                             // selection extends beyond out part of this para
     287           0 :                             nLocalEnd = GetPortionData().GetAccessibleString().
     288           0 :                                                                    getLength();
     289             :                         }
     290           0 :                         else if( nCoreEnd >=
     291           0 :                                  GetPortionData().GetFirstValidCorePosition() )
     292             :                         {
     293             :                             // selection is inside our part of this para
     294             :                             OSL_ENSURE(
     295             :                                 GetPortionData().IsValidCorePosition(
     296             :                                                                   nCoreEnd ),
     297             :                                  "problem determining valid core position" );
     298             : 
     299           0 :                             nLocalEnd = GetPortionData().GetAccessiblePosition(
     300           0 :                                                                    nCoreEnd );
     301             :                         }
     302             :                     }
     303             : 
     304           0 :                     if( ( nLocalStart != -1 ) && ( nLocalEnd != -1 ) )
     305             :                     {
     306           0 :                         nStart = nLocalStart;
     307           0 :                         nEnd = nLocalEnd;
     308           0 :                         bRet = true;
     309             :                     }
     310             :                 }
     311             :                 // else: this PaM doesn't point to this paragraph
     312             :             }
     313             :             // else: this PaM is collapsed and doesn't select anything
     314           3 :             if(bRet)
     315           0 :                 break;
     316             :         }
     317             :     // else: nocursor -> no selection
     318             :     }
     319           3 :     return bRet;
     320             : }
     321             : 
     322             : // #i27301# - new parameter <_bForSelection>
     323         149 : SwPaM* SwAccessibleParagraph::GetCursor( const bool _bForSelection )
     324             : {
     325             :     // get the cursor shell; if we don't have any, we don't have a
     326             :     // cursor/selection either
     327         149 :     SwPaM* pCrsr = NULL;
     328         149 :     SwCrsrShell* pCrsrShell = SwAccessibleParagraph::GetCrsrShell();
     329             :     // #i27301# - if cursor is retrieved for selection, the cursors for
     330             :     // a table selection has to be returned.
     331         273 :     if ( pCrsrShell != NULL &&
     332         146 :          ( _bForSelection || !pCrsrShell->IsTableMode() ) )
     333             :     {
     334         124 :         SwFEShell *pFESh = pCrsrShell->ISA( SwFEShell )
     335         124 :                             ? static_cast< SwFEShell * >( pCrsrShell ) : 0;
     336         372 :         if( !pFESh ||
     337         248 :             !(pFESh->IsFrmSelected() || pFESh->IsObjSelected() > 0) )
     338             :         {
     339             :             // get the selection, and test whether it affects our text node
     340         124 :             pCrsr = pCrsrShell->GetCrsr( false /* ??? */ );
     341             :         }
     342             :     }
     343             : 
     344         149 :     return pCrsr;
     345             : }
     346             : 
     347          79 : bool SwAccessibleParagraph::IsHeading() const
     348             : {
     349          79 :     const SwTextNode *pTextNd = GetTextNode();
     350          79 :     return pTextNd->IsOutline();
     351             : }
     352             : 
     353          22 : void SwAccessibleParagraph::GetStates(
     354             :         ::utl::AccessibleStateSetHelper& rStateSet )
     355             : {
     356          22 :     SwAccessibleContext::GetStates( rStateSet );
     357             : 
     358             :     // MULTILINE
     359          22 :     rStateSet.AddState( AccessibleStateType::MULTI_LINE );
     360             : 
     361             :     // MULTISELECTABLE
     362          22 :     SwCrsrShell *pCrsrSh = GetCrsrShell();
     363          22 :     if( pCrsrSh )
     364          22 :         rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
     365             : 
     366             :     // FOCUSABLE
     367          22 :     if( pCrsrSh )
     368          22 :         rStateSet.AddState( AccessibleStateType::FOCUSABLE );
     369             : 
     370             :     // FOCUSED (simulates node index of cursor)
     371          22 :     SwPaM* pCaret = GetCursor( false ); // #i27301# - consider adjusted method signature
     372          22 :     const SwTextNode* pTextNd = GetTextNode();
     373          64 :     if( pCaret != 0 && pTextNd != 0 &&
     374          63 :         pTextNd->GetIndex() == pCaret->GetPoint()->nNode.GetIndex() &&
     375          20 :         nOldCaretPos != -1)
     376             :     {
     377          20 :         vcl::Window *pWin = GetWindow();
     378          20 :         if( pWin && pWin->HasFocus() )
     379          16 :             rStateSet.AddState( AccessibleStateType::FOCUSED );
     380          20 :         ::rtl::Reference < SwAccessibleContext > xThis( this );
     381          20 :         GetMap()->SetCursorContext( xThis );
     382             :     }
     383          22 : }
     384             : 
     385          14 : void SwAccessibleParagraph::_InvalidateContent( bool bVisibleDataFired )
     386             : {
     387          14 :     OUString sOldText( GetString() );
     388             : 
     389          14 :     ClearPortionData();
     390             : 
     391          28 :     const OUString& rText = GetString();
     392             : 
     393          14 :     if( rText != sOldText )
     394             :     {
     395             :         // The text is changed
     396           0 :         AccessibleEventObject aEvent;
     397           0 :         aEvent.EventId = AccessibleEventId::TEXT_CHANGED;
     398             : 
     399             :         // determine exact changes between sOldText and rText
     400             :         comphelper::OCommonAccessibleText::implInitTextChangedEvent(
     401             :             sOldText, rText,
     402           0 :             aEvent.OldValue, aEvent.NewValue );
     403             : 
     404           0 :         FireAccessibleEvent( aEvent );
     405           0 :         uno::Reference< XAccessible > xparent = getAccessibleParent();
     406           0 :         uno::Reference< XAccessibleContext > xAccContext(xparent,uno::UNO_QUERY);
     407           0 :         if (xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
     408             :         {
     409           0 :             SwAccessibleContext* pPara = static_cast< SwAccessibleContext* >(xparent.get());
     410           0 :             if(pPara)
     411             :             {
     412           0 :                 AccessibleEventObject aParaEvent;
     413           0 :                 aParaEvent.EventId = AccessibleEventId::VALUE_CHANGED;
     414           0 :                 pPara->FireAccessibleEvent(aParaEvent);
     415             :             }
     416           0 :         }
     417             :     }
     418          14 :     else if( !bVisibleDataFired )
     419             :     {
     420           0 :         FireVisibleDataEvent();
     421             :     }
     422             : 
     423          14 :     bool bNewIsHeading = IsHeading();
     424             :     //Get the real heading level, Heading1 ~ Heading10
     425          14 :     nHeadingLevel = GetRealHeadingLevel();
     426             :     bool bOldIsHeading;
     427             :     {
     428          14 :         osl::MutexGuard aGuard( m_Mutex );
     429          14 :         bOldIsHeading = bIsHeading;
     430          14 :         if( bIsHeading != bNewIsHeading )
     431           0 :             bIsHeading = bNewIsHeading;
     432             :     }
     433             : 
     434          14 :     if( bNewIsHeading != bOldIsHeading )
     435             :     {
     436             :         // The role has changed
     437           0 :         AccessibleEventObject aEvent;
     438           0 :         aEvent.EventId = AccessibleEventId::ROLE_CHANGED;
     439             : 
     440           0 :         FireAccessibleEvent( aEvent );
     441             :     }
     442             : 
     443          14 :     if( rText != sOldText )
     444             :     {
     445           0 :         OUString sNewDesc( GetDescription() );
     446           0 :         OUString sOldDesc;
     447             :         {
     448           0 :             osl::MutexGuard aGuard( m_Mutex );
     449           0 :             sOldDesc = sDesc;
     450           0 :             if( sDesc != sNewDesc )
     451           0 :                 sDesc = sNewDesc;
     452             :         }
     453             : 
     454           0 :         if( sNewDesc != sOldDesc )
     455             :         {
     456             :             // The text is changed
     457           0 :             AccessibleEventObject aEvent;
     458           0 :             aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
     459           0 :             aEvent.OldValue <<= sOldDesc;
     460           0 :             aEvent.NewValue <<= sNewDesc;
     461             : 
     462           0 :             FireAccessibleEvent( aEvent );
     463           0 :         }
     464          14 :     }
     465          14 : }
     466             : 
     467          58 : void SwAccessibleParagraph::_InvalidateCursorPos()
     468             : {
     469             :     // The text is changed
     470          58 :     sal_Int32 nNew = GetCaretPos();
     471             :     sal_Int32 nOld;
     472             :     {
     473          58 :         osl::MutexGuard aGuard( m_Mutex );
     474          58 :         nOld = nOldCaretPos;
     475          58 :         nOldCaretPos = nNew;
     476             :     }
     477          58 :     if( -1 != nNew )
     478             :     {
     479             :         // remember that object as the one that has the caret. This is
     480             :         // necessary to notify that object if the cursor leaves it.
     481          57 :         ::rtl::Reference < SwAccessibleContext > xThis( this );
     482          57 :         GetMap()->SetCursorContext( xThis );
     483             :     }
     484             : 
     485          58 :     vcl::Window *pWin = GetWindow();
     486          58 :     if( nOld != nNew )
     487             :     {
     488             :         // The cursor's node position is simulated by the focus!
     489           3 :         if( pWin && pWin->HasFocus() && -1 == nOld )
     490           1 :             FireStateChangedEvent( AccessibleStateType::FOCUSED, true );
     491             : 
     492           3 :         AccessibleEventObject aEvent;
     493           3 :         aEvent.EventId = AccessibleEventId::CARET_CHANGED;
     494           3 :         aEvent.OldValue <<= nOld;
     495           3 :         aEvent.NewValue <<= nNew;
     496             : 
     497           3 :         FireAccessibleEvent( aEvent );
     498             : 
     499           3 :         if( pWin && pWin->HasFocus() && -1 == nNew )
     500           0 :             FireStateChangedEvent( AccessibleStateType::FOCUSED, false );
     501             :         //To send TEXT_SELECTION_CHANGED event
     502           3 :         sal_Int32 nStart=0;
     503           3 :         sal_Int32 nEnd  =0;
     504           3 :         bool bCurSelection=GetSelection(nStart,nEnd);
     505           3 :         if(m_bLastHasSelection || bCurSelection )
     506             :         {
     507           0 :             aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
     508           0 :             aEvent.OldValue <<= uno::Any();
     509           0 :             aEvent.NewValue <<= uno::Any();
     510           0 :             FireAccessibleEvent(aEvent);
     511             :         }
     512           3 :         m_bLastHasSelection =bCurSelection;
     513             :     }
     514          58 : }
     515             : 
     516           5 : void SwAccessibleParagraph::_InvalidateFocus()
     517             : {
     518           5 :     vcl::Window *pWin = GetWindow();
     519           5 :     if( pWin )
     520             :     {
     521             :         sal_Int32 nPos;
     522             :         {
     523           5 :             osl::MutexGuard aGuard( m_Mutex );
     524           5 :             nPos = nOldCaretPos;
     525             :         }
     526             :         OSL_ENSURE( nPos != -1, "focus object should be selected" );
     527             : 
     528             :         FireStateChangedEvent( AccessibleStateType::FOCUSED,
     529           5 :                                pWin->HasFocus() && nPos != -1 );
     530             :     }
     531           5 : }
     532             : 
     533          65 : SwAccessibleParagraph::SwAccessibleParagraph(
     534             :         SwAccessibleMap& rInitMap,
     535             :         const SwTextFrm& rTextFrm )
     536          65 :     : SwClient( const_cast<SwTextNode*>(rTextFrm.GetTextNode()) ) // #i108125#
     537             :     , SwAccessibleContext( &rInitMap, AccessibleRole::PARAGRAPH, &rTextFrm )
     538             :     , sDesc()
     539             :     , pPortionData( NULL )
     540             :     , pHyperTextData( NULL )
     541             :     , nOldCaretPos( -1 )
     542             :     , bIsHeading( false )
     543             :     //Get the real heading level, Heading1 ~ Heading10
     544             :     , nHeadingLevel (-1)
     545             :     , aSelectionHelper( *this )
     546          65 :     , mpParaChangeTrackInfo( new SwParaChangeTrackingInfo( rTextFrm ) ) // #i108125#
     547         130 :     , m_bLastHasSelection(false)  //To add TEXT_SELECTION_CHANGED event
     548             : {
     549          65 :     SolarMutexGuard aGuard;
     550             : 
     551          65 :     bIsHeading = IsHeading();
     552             :     //Get the real heading level, Heading1 ~ Heading10
     553          65 :     nHeadingLevel = GetRealHeadingLevel();
     554          65 :     SetName( OUString() ); // set an empty accessibility name for paragraphs
     555             : 
     556             :     // If this object has the focus, then it is remembered by the map itself.
     557          65 :     nOldCaretPos = GetCaretPos();
     558          65 : }
     559             : 
     560         195 : SwAccessibleParagraph::~SwAccessibleParagraph()
     561             : {
     562          65 :     SolarMutexGuard aGuard;
     563             : 
     564          65 :     delete pPortionData;
     565          65 :     delete pHyperTextData;
     566          65 :     delete mpParaChangeTrackInfo; // #i108125#
     567         130 : }
     568             : 
     569          79 : bool SwAccessibleParagraph::HasCursor()
     570             : {
     571          79 :     osl::MutexGuard aGuard( m_Mutex );
     572          79 :     return nOldCaretPos != -1;
     573             : }
     574             : 
     575         110 : void SwAccessibleParagraph::UpdatePortionData()
     576             :     throw( uno::RuntimeException )
     577             : {
     578             :     // obtain the text frame
     579             :     OSL_ENSURE( GetFrm() != NULL, "The text frame has vanished!" );
     580             :     OSL_ENSURE( GetFrm()->IsTextFrm(), "The text frame has mutated!" );
     581         110 :     const SwTextFrm* pFrm = static_cast<const SwTextFrm*>( GetFrm() );
     582             : 
     583             :     // build new portion data
     584         110 :     delete pPortionData;
     585             :     pPortionData = new SwAccessiblePortionData(
     586         110 :         pFrm->GetTextNode(), GetMap()->GetShell()->GetViewOptions() );
     587         110 :     pFrm->VisitPortions( *pPortionData );
     588             : 
     589             :     OSL_ENSURE( pPortionData != NULL, "UpdatePortionData() failed" );
     590         110 : }
     591             : 
     592          45 : void SwAccessibleParagraph::ClearPortionData()
     593             : {
     594          45 :     delete pPortionData;
     595          45 :     pPortionData = NULL;
     596             : 
     597          45 :     delete pHyperTextData;
     598          45 :     pHyperTextData = 0;
     599          45 : }
     600             : 
     601           0 : void SwAccessibleParagraph::ExecuteAtViewShell( sal_uInt16 nSlot )
     602             : {
     603             :     OSL_ENSURE( GetMap() != NULL, "no map?" );
     604           0 :     SwViewShell* pViewShell = GetMap()->GetShell();
     605             : 
     606             :     OSL_ENSURE( pViewShell != NULL, "View shell expected!" );
     607           0 :     SfxViewShell* pSfxShell = pViewShell->GetSfxViewShell();
     608             : 
     609             :     OSL_ENSURE( pSfxShell != NULL, "SfxViewShell shell expected!" );
     610           0 :     if( !pSfxShell )
     611           0 :         return;
     612             : 
     613           0 :     SfxViewFrame *pFrame = pSfxShell->GetViewFrame();
     614             :     OSL_ENSURE( pFrame != NULL, "View frame expected!" );
     615           0 :     if( !pFrame )
     616           0 :         return;
     617             : 
     618           0 :     SfxDispatcher *pDispatcher = pFrame->GetDispatcher();
     619             :     OSL_ENSURE( pDispatcher != NULL, "Dispatcher expected!" );
     620           0 :     if( !pDispatcher )
     621           0 :         return;
     622             : 
     623           0 :     pDispatcher->Execute( nSlot );
     624             : }
     625             : 
     626          79 : SwXTextPortion* SwAccessibleParagraph::CreateUnoPortion(
     627             :     sal_Int32 nStartIndex,
     628             :     sal_Int32 nEndIndex )
     629             : {
     630             :     OSL_ENSURE( (IsValidChar(nStartIndex, GetString().getLength()) &&
     631             :                  (nEndIndex == -1)) ||
     632             :                 IsValidRange(nStartIndex, nEndIndex, GetString().getLength()),
     633             :                 "please check parameters before calling this method" );
     634             : 
     635          79 :     const sal_Int32 nStart = GetPortionData().GetModelPosition( nStartIndex );
     636             :     const sal_Int32 nEnd = (nEndIndex == -1) ? (nStart + 1) :
     637          79 :                         GetPortionData().GetModelPosition( nEndIndex );
     638             : 
     639             :     // create UNO cursor
     640          79 :     SwTextNode* pTextNode = const_cast<SwTextNode*>( GetTextNode() );
     641          79 :     SwIndex aIndex( pTextNode, nStart );
     642         158 :     SwPosition aStartPos( *pTextNode, aIndex );
     643         158 :     auto pUnoCursor(pTextNode->GetDoc()->CreateUnoCrsr( aStartPos ));
     644          79 :     pUnoCursor->SetMark();
     645          79 :     pUnoCursor->GetMark()->nContent = nEnd;
     646             : 
     647             :     // create a (dummy) text portion to be returned
     648         158 :     uno::Reference<text::XText> aEmpty;
     649             :     SwXTextPortion* pPortion =
     650          79 :         new SwXTextPortion ( pUnoCursor.get(), aEmpty, PORTION_TEXT);
     651             : 
     652         158 :     return pPortion;
     653             : }
     654             : 
     655             : // range checking for parameter
     656             : 
     657           0 : bool SwAccessibleParagraph::IsValidChar(
     658             :     sal_Int32 nPos, sal_Int32 nLength)
     659             : {
     660           0 :     return (nPos >= 0) && (nPos < nLength);
     661             : }
     662             : 
     663           0 : bool SwAccessibleParagraph::IsValidPosition(
     664             :     sal_Int32 nPos, sal_Int32 nLength)
     665             : {
     666           0 :     return (nPos >= 0) && (nPos <= nLength);
     667             : }
     668             : 
     669           0 : bool SwAccessibleParagraph::IsValidRange(
     670             :     sal_Int32 nBegin, sal_Int32 nEnd, sal_Int32 nLength)
     671             : {
     672           0 :     return IsValidPosition(nBegin, nLength) && IsValidPosition(nEnd, nLength);
     673             : }
     674             : 
     675           0 : SwTOXSortTabBase* SwAccessibleParagraph::GetTOXSortTabBase()
     676             : {
     677           0 :     const SwTextNode* pTextNd = GetTextNode();
     678           0 :     if( pTextNd )
     679             :     {
     680           0 :         const SwSectionNode * pSectNd = pTextNd->FindSectionNode();
     681           0 :         if( pSectNd )
     682             :         {
     683           0 :             const SwSection * pSect = &pSectNd->GetSection();
     684           0 :             const  SwTOXBaseSection *pTOXBaseSect = static_cast<const SwTOXBaseSection *>(pSect);
     685           0 :             if( pSect->GetType() == TOX_CONTENT_SECTION )
     686             :             {
     687           0 :                 SwTOXSortTabBase* pSortBase = 0;
     688           0 :                 size_t nSize = pTOXBaseSect->GetTOXSortTabBases().size();
     689             : 
     690           0 :                 for(size_t nIndex = 0; nIndex<nSize; nIndex++ )
     691             :                 {
     692           0 :                     pSortBase = pTOXBaseSect->GetTOXSortTabBases()[nIndex];
     693           0 :                     if( pSortBase->pTOXNd == pTextNd )
     694           0 :                         break;
     695             :                 }
     696             : 
     697           0 :                 if (pSortBase)
     698             :                 {
     699           0 :                     return pSortBase;
     700             :                 }
     701             :             }
     702             :         }
     703             :     }
     704           0 :     return NULL;
     705             : }
     706             : 
     707             : //the function is to check whether the position is in a redline range.
     708           0 : const SwRangeRedline* SwAccessibleParagraph::GetRedlineAtIndex( sal_Int32 )
     709             : {
     710           0 :     const SwRangeRedline* pRedline = NULL;
     711           0 :     SwPaM* pCrSr = GetCursor( true );
     712           0 :     if ( pCrSr )
     713             :     {
     714           0 :         SwPosition* pStart = pCrSr->Start();
     715           0 :         const SwTextNode* pNode = GetTextNode();
     716           0 :         if ( pNode )
     717             :         {
     718           0 :             const SwDoc* pDoc = pNode->GetDoc();
     719           0 :             if ( pDoc )
     720             :             {
     721           0 :                 pRedline = pDoc->getIDocumentRedlineAccess().GetRedline( *pStart, NULL );
     722             :             }
     723             :         }
     724             :     }
     725             : 
     726           0 :     return pRedline;
     727             : }
     728             : 
     729             : // text boundaries
     730             : 
     731           0 : bool SwAccessibleParagraph::GetCharBoundary(
     732             :     i18n::Boundary& rBound,
     733             :     const OUString&,
     734             :     sal_Int32 nPos )
     735             : {
     736           0 :     if( GetPortionData().FillBoundaryIFDateField( rBound,  nPos) )
     737           0 :         return true;
     738             : 
     739           0 :     rBound.startPos = nPos;
     740           0 :     rBound.endPos = nPos+1;
     741           0 :     return true;
     742             : }
     743             : 
     744           0 : bool SwAccessibleParagraph::GetWordBoundary(
     745             :     i18n::Boundary& rBound,
     746             :     const OUString& rText,
     747             :     sal_Int32 nPos )
     748             : {
     749           0 :     bool bRet = false;
     750             : 
     751             :     // now ask the Break-Iterator for the word
     752             :     OSL_ENSURE( g_pBreakIt != NULL, "We always need a break." );
     753             :     OSL_ENSURE( g_pBreakIt->GetBreakIter().is(), "No break-iterator." );
     754           0 :     if( g_pBreakIt->GetBreakIter().is() )
     755             :     {
     756             :         // get locale for this position
     757           0 :         const sal_Int32 nModelPos = GetPortionData().GetModelPosition( nPos );
     758             :         lang::Locale aLocale = g_pBreakIt->GetLocale(
     759           0 :                               GetTextNode()->GetLang( nModelPos ) );
     760             : 
     761             :         // which type of word are we interested in?
     762             :         // (DICTIONARY_WORD includes punctuation, ANY_WORD doesn't.)
     763           0 :         const sal_Int16 nWordType = i18n::WordType::ANY_WORD;
     764             : 
     765             :         // get word boundary, as the Break-Iterator sees fit.
     766           0 :         rBound = g_pBreakIt->GetBreakIter()->getWordBoundary(
     767           0 :             rText, nPos, aLocale, nWordType, sal_True );
     768             : 
     769             :         // It's a word if the first character is an alpha-numeric character.
     770           0 :         bRet = GetAppCharClass().isLetterNumeric(
     771           0 :             OUString(rText[rBound.startPos]) );
     772             :     }
     773             :     else
     774             :     {
     775             :         // no break Iterator -> no word
     776           0 :         rBound.startPos = nPos;
     777           0 :         rBound.endPos = nPos;
     778             :     }
     779             : 
     780           0 :     return bRet;
     781             : }
     782             : 
     783           0 : bool SwAccessibleParagraph::GetSentenceBoundary(
     784             :     i18n::Boundary& rBound,
     785             :     const OUString& rText,
     786             :     sal_Int32 nPos )
     787             : {
     788           0 :     const sal_Unicode* pStr = rText.getStr();
     789           0 :     if (pStr)
     790             :     {
     791           0 :         while( pStr[nPos] == sal_Unicode(' ') && nPos < rText.getLength())
     792           0 :             nPos++;
     793             :     }
     794             : 
     795           0 :     GetPortionData().GetSentenceBoundary( rBound, nPos );
     796           0 :     return true;
     797             : }
     798             : 
     799           0 : bool SwAccessibleParagraph::GetLineBoundary(
     800             :     i18n::Boundary& rBound,
     801             :     const OUString& rText,
     802             :     sal_Int32 nPos )
     803             : {
     804           0 :     if( rText.getLength() == nPos )
     805           0 :         GetPortionData().GetLastLineBoundary( rBound );
     806             :     else
     807           0 :         GetPortionData().GetLineBoundary( rBound, nPos );
     808           0 :     return true;
     809             : }
     810             : 
     811           0 : bool SwAccessibleParagraph::GetParagraphBoundary(
     812             :     i18n::Boundary& rBound,
     813             :     const OUString& rText,
     814             :     sal_Int32 )
     815             : {
     816           0 :     rBound.startPos = 0;
     817           0 :     rBound.endPos = rText.getLength();
     818           0 :     return true;
     819             : }
     820             : 
     821           0 : bool SwAccessibleParagraph::GetAttributeBoundary(
     822             :     i18n::Boundary& rBound,
     823             :     const OUString&,
     824             :     sal_Int32 nPos )
     825             : {
     826           0 :     GetPortionData().GetAttributeBoundary( rBound, nPos );
     827           0 :     return true;
     828             : }
     829             : 
     830           0 : bool SwAccessibleParagraph::GetGlyphBoundary(
     831             :     i18n::Boundary& rBound,
     832             :     const OUString& rText,
     833             :     sal_Int32 nPos )
     834             : {
     835           0 :     bool bRet = false;
     836             : 
     837             :     // ask the Break-Iterator for the glyph by moving one cell
     838             :     // forward, and then one cell back
     839             :     OSL_ENSURE( g_pBreakIt != NULL, "We always need a break." );
     840             :     OSL_ENSURE( g_pBreakIt->GetBreakIter().is(), "No break-iterator." );
     841           0 :     if( g_pBreakIt->GetBreakIter().is() )
     842             :     {
     843             :         // get locale for this position
     844           0 :         const sal_Int32 nModelPos = GetPortionData().GetModelPosition( nPos );
     845             :         lang::Locale aLocale = g_pBreakIt->GetLocale(
     846           0 :                               GetTextNode()->GetLang( nModelPos ) );
     847             : 
     848             :         // get word boundary, as the Break-Iterator sees fit.
     849           0 :         const sal_Int16 nIterMode = i18n::CharacterIteratorMode::SKIPCELL;
     850           0 :         sal_Int32 nDone = 0;
     851           0 :         rBound.endPos = g_pBreakIt->GetBreakIter()->nextCharacters(
     852           0 :              rText, nPos, aLocale, nIterMode, 1, nDone );
     853           0 :         rBound.startPos = g_pBreakIt->GetBreakIter()->previousCharacters(
     854           0 :              rText, rBound.endPos, aLocale, nIterMode, 1, nDone );
     855           0 :         bRet = ((rBound.startPos <= nPos) && (nPos <= rBound.endPos));
     856             :         OSL_ENSURE( rBound.startPos <= nPos, "start pos too high" );
     857           0 :         OSL_ENSURE( rBound.endPos >= nPos, "end pos too low" );
     858             :     }
     859             :     else
     860             :     {
     861             :         // no break Iterator -> no glyph
     862           0 :         rBound.startPos = nPos;
     863           0 :         rBound.endPos = nPos;
     864             :     }
     865             : 
     866           0 :     return bRet;
     867             : }
     868             : 
     869           0 : bool SwAccessibleParagraph::GetTextBoundary(
     870             :     i18n::Boundary& rBound,
     871             :     const OUString& rText,
     872             :     sal_Int32 nPos,
     873             :     sal_Int16 nTextType )
     874             :     throw (
     875             :         lang::IndexOutOfBoundsException,
     876             :         lang::IllegalArgumentException,
     877             :         uno::RuntimeException)
     878             : {
     879             :     // error checking
     880           0 :     if( !( AccessibleTextType::LINE == nTextType
     881           0 :                 ? IsValidPosition( nPos, rText.getLength() )
     882           0 :                 : IsValidChar( nPos, rText.getLength() ) ) )
     883           0 :         throw lang::IndexOutOfBoundsException();
     884             : 
     885             :     bool bRet;
     886             : 
     887           0 :     switch( nTextType )
     888             :     {
     889             :         case AccessibleTextType::WORD:
     890           0 :             bRet = GetWordBoundary( rBound, rText, nPos );
     891           0 :             break;
     892             : 
     893             :         case AccessibleTextType::SENTENCE:
     894           0 :             bRet = GetSentenceBoundary( rBound, rText, nPos );
     895           0 :             break;
     896             : 
     897             :         case AccessibleTextType::PARAGRAPH:
     898           0 :             bRet = GetParagraphBoundary( rBound, rText, nPos );
     899           0 :             break;
     900             : 
     901             :         case AccessibleTextType::CHARACTER:
     902           0 :             bRet = GetCharBoundary( rBound, rText, nPos );
     903           0 :             break;
     904             : 
     905             :         case AccessibleTextType::LINE:
     906             :             //Solve the problem of returning wrong LINE and PARAGRAPH
     907           0 :             if((nPos == rText.getLength()) && nPos > 0)
     908           0 :                 bRet = GetLineBoundary( rBound, rText, nPos - 1);
     909             :             else
     910           0 :                 bRet = GetLineBoundary( rBound, rText, nPos );
     911           0 :             break;
     912             : 
     913             :         case AccessibleTextType::ATTRIBUTE_RUN:
     914           0 :             bRet = GetAttributeBoundary( rBound, rText, nPos );
     915           0 :             break;
     916             : 
     917             :         case AccessibleTextType::GLYPH:
     918           0 :             bRet = GetGlyphBoundary( rBound, rText, nPos );
     919           0 :             break;
     920             : 
     921             :         default:
     922           0 :             throw lang::IllegalArgumentException( );
     923             :     }
     924             : 
     925           0 :     return bRet;
     926             : }
     927             : 
     928          13 : OUString SAL_CALL SwAccessibleParagraph::getAccessibleDescription()
     929             :         throw (uno::RuntimeException, std::exception)
     930             : {
     931          13 :     SolarMutexGuard aGuard;
     932             : 
     933          13 :     CHECK_FOR_DEFUNC( XAccessibleContext );
     934             : 
     935          26 :     osl::MutexGuard aGuard2( m_Mutex );
     936          13 :     if( sDesc.isEmpty() )
     937          13 :         sDesc = GetDescription();
     938             : 
     939          26 :     return sDesc;
     940             : }
     941             : 
     942           1 : lang::Locale SAL_CALL SwAccessibleParagraph::getLocale()
     943             :         throw (IllegalAccessibleComponentStateException, uno::RuntimeException, std::exception)
     944             : {
     945           1 :     SolarMutexGuard aGuard;
     946             : 
     947           1 :     const SwTextFrm *pTextFrm = PTR_CAST( SwTextFrm, GetFrm() );
     948           1 :     if( !pTextFrm )
     949             :     {
     950           0 :         THROW_RUNTIME_EXCEPTION( XAccessibleContext, "internal error (no text frame)" );
     951             :     }
     952             : 
     953           1 :     const SwTextNode *pTextNd = pTextFrm->GetTextNode();
     954           1 :     lang::Locale aLoc( g_pBreakIt->GetLocale( pTextNd->GetLang( 0 ) ) );
     955             : 
     956           1 :     return aLoc;
     957             : }
     958             : 
     959             : // #i27138# - paragraphs are in relation CONTENT_FLOWS_FROM and/or CONTENT_FLOWS_TO
     960           3 : uno::Reference<XAccessibleRelationSet> SAL_CALL SwAccessibleParagraph::getAccessibleRelationSet()
     961             :     throw ( uno::RuntimeException, std::exception )
     962             : {
     963           3 :     SolarMutexGuard aGuard;
     964           3 :     CHECK_FOR_DEFUNC( XAccessibleContext );
     965             : 
     966           3 :     utl::AccessibleRelationSetHelper* pHelper = new utl::AccessibleRelationSetHelper();
     967             : 
     968           3 :     const SwTextFrm* pTextFrm = dynamic_cast<const SwTextFrm*>(GetFrm());
     969             :     OSL_ENSURE( pTextFrm,
     970             :             "<SwAccessibleParagraph::getAccessibleRelationSet()> - missing text frame");
     971           3 :     if ( pTextFrm )
     972             :     {
     973           3 :         const SwContentFrm* pPrevCntFrm( pTextFrm->FindPrevCnt( true ) );
     974           3 :         if ( pPrevCntFrm )
     975             :         {
     976           1 :             uno::Sequence< uno::Reference<XInterface> > aSequence(1);
     977           1 :             aSequence[0] = GetMap()->GetContext( pPrevCntFrm );
     978             :             AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
     979           2 :                                         aSequence );
     980           2 :             pHelper->AddRelation( aAccRel );
     981             :         }
     982             : 
     983           3 :         const SwContentFrm* pNextCntFrm( pTextFrm->FindNextCnt( true ) );
     984           3 :         if ( pNextCntFrm )
     985             :         {
     986           2 :             uno::Sequence< uno::Reference<XInterface> > aSequence(1);
     987           2 :             aSequence[0] = GetMap()->GetContext( pNextCntFrm );
     988             :             AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
     989           4 :                                         aSequence );
     990           4 :             pHelper->AddRelation( aAccRel );
     991             :         }
     992             :     }
     993             : 
     994           3 :     return pHelper;
     995             : }
     996             : 
     997           1 : void SAL_CALL SwAccessibleParagraph::grabFocus()
     998             :         throw (uno::RuntimeException, std::exception)
     999             : {
    1000           1 :     SolarMutexGuard aGuard;
    1001             : 
    1002           1 :     CHECK_FOR_DEFUNC( XAccessibleContext );
    1003             : 
    1004             :     // get cursor shell
    1005           1 :     SwCrsrShell *pCrsrSh = GetCrsrShell();
    1006           1 :     SwPaM *pCrsr = GetCursor( false ); // #i27301# - consider new method signature
    1007           1 :     const SwTextFrm *pTextFrm = static_cast<const SwTextFrm*>( GetFrm() );
    1008           1 :     const SwTextNode* pTextNd = pTextFrm->GetTextNode();
    1009             : 
    1010           1 :     if( pCrsrSh != 0 && pTextNd != 0 &&
    1011           1 :         ( pCrsr == 0 ||
    1012           2 :            pCrsr->GetPoint()->nNode.GetIndex() != pTextNd->GetIndex() ||
    1013           1 :           !pTextFrm->IsInside( pCrsr->GetPoint()->nContent.GetIndex()) ) )
    1014             :     {
    1015             :         // create pam for selection
    1016             :         SwIndex aIndex( const_cast< SwTextNode * >( pTextNd ),
    1017           0 :                         pTextFrm->GetOfst() );
    1018           0 :         SwPosition aStartPos( *pTextNd, aIndex );
    1019           0 :         SwPaM aPaM( aStartPos );
    1020             : 
    1021             :         // set PaM at cursor shell
    1022           0 :         Select( aPaM );
    1023             : 
    1024             :     }
    1025             : 
    1026             :     // ->#i13955#
    1027           1 :     vcl::Window * pWindow = GetWindow();
    1028             : 
    1029           1 :     if (pWindow != NULL)
    1030           1 :         pWindow->GrabFocus();
    1031             :     // <-#i13955#
    1032           1 : }
    1033             : 
    1034             : // #i71385#
    1035           2 : static bool lcl_GetBackgroundColor( Color & rColor,
    1036             :                              const SwFrm* pFrm,
    1037             :                              SwCrsrShell* pCrsrSh )
    1038             : {
    1039           2 :     const SvxBrushItem* pBackgrdBrush = 0;
    1040           2 :     const Color* pSectionTOXColor = 0;
    1041           2 :     SwRect aDummyRect;
    1042             : 
    1043             :     //UUUU
    1044           2 :     drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes;
    1045             : 
    1046           4 :     if ( pFrm &&
    1047           2 :          pFrm->GetBackgroundBrush( aFillAttributes, pBackgrdBrush, pSectionTOXColor, aDummyRect, false ) )
    1048             :     {
    1049           0 :         if ( pSectionTOXColor )
    1050             :         {
    1051           0 :             rColor = *pSectionTOXColor;
    1052           0 :             return true;
    1053             :         }
    1054             :         else
    1055             :         {
    1056           0 :             rColor =  pBackgrdBrush->GetColor();
    1057           0 :             return true;
    1058             :         }
    1059             :     }
    1060           2 :     else if ( pCrsrSh )
    1061             :     {
    1062           2 :         rColor = pCrsrSh->Imp()->GetRetoucheColor();
    1063           2 :         return true;
    1064             :     }
    1065             : 
    1066           0 :     return false;
    1067             : }
    1068             : 
    1069           1 : sal_Int32 SAL_CALL SwAccessibleParagraph::getForeground()
    1070             :                                 throw (uno::RuntimeException, std::exception)
    1071             : {
    1072           1 :     Color aBackgroundCol;
    1073             : 
    1074           1 :     if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrm(), GetCrsrShell() ) )
    1075             :     {
    1076           1 :         if ( aBackgroundCol.IsDark() )
    1077             :         {
    1078           0 :             return COL_WHITE;
    1079             :         }
    1080             :         else
    1081             :         {
    1082           1 :             return COL_BLACK;
    1083             :         }
    1084             :     }
    1085             : 
    1086           0 :     return SwAccessibleContext::getForeground();
    1087             : }
    1088             : 
    1089           1 : sal_Int32 SAL_CALL SwAccessibleParagraph::getBackground()
    1090             :                                 throw (uno::RuntimeException, std::exception)
    1091             : {
    1092           1 :     Color aBackgroundCol;
    1093             : 
    1094           1 :     if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrm(), GetCrsrShell() ) )
    1095             :     {
    1096           1 :         return aBackgroundCol.GetColor();
    1097             :     }
    1098             : 
    1099           0 :     return SwAccessibleContext::getBackground();
    1100             : }
    1101             : 
    1102           3 : OUString SAL_CALL SwAccessibleParagraph::getImplementationName()
    1103             :         throw( uno::RuntimeException, std::exception )
    1104             : {
    1105           3 :     return OUString(sImplementationName);
    1106             : }
    1107             : 
    1108           0 : sal_Bool SAL_CALL SwAccessibleParagraph::supportsService(
    1109             :         const OUString& sTestServiceName)
    1110             :     throw (uno::RuntimeException, std::exception)
    1111             : {
    1112           0 :     return cppu::supportsService(this, sTestServiceName);
    1113             : }
    1114             : 
    1115           0 : uno::Sequence< OUString > SAL_CALL SwAccessibleParagraph::getSupportedServiceNames()
    1116             :         throw( uno::RuntimeException, std::exception )
    1117             : {
    1118           0 :     uno::Sequence< OUString > aRet(2);
    1119           0 :     OUString* pArray = aRet.getArray();
    1120           0 :     pArray[0] = sServiceName;
    1121           0 :     pArray[1] = sAccessibleServiceName;
    1122           0 :     return aRet;
    1123             : }
    1124             : 
    1125           0 : uno::Sequence< OUString > getAttributeNames()
    1126             : {
    1127             :     static uno::Sequence< OUString >* pNames = NULL;
    1128             : 
    1129           0 :     if( pNames == NULL )
    1130             :     {
    1131             :         // Add the font name to attribute list
    1132           0 :         uno::Sequence< OUString >* pSeq = new uno::Sequence< OUString >( 13 );
    1133             : 
    1134           0 :         OUString* pStrings = pSeq->getArray();
    1135             : 
    1136             :         // sorted list of strings
    1137           0 :         sal_Int32 i = 0;
    1138             : 
    1139           0 :         pStrings[i++] = UNO_NAME_CHAR_BACK_COLOR;
    1140           0 :         pStrings[i++] = UNO_NAME_CHAR_COLOR;
    1141           0 :         pStrings[i++] = UNO_NAME_CHAR_CONTOURED;
    1142           0 :         pStrings[i++] = UNO_NAME_CHAR_EMPHASIS;
    1143           0 :         pStrings[i++] = UNO_NAME_CHAR_ESCAPEMENT;
    1144           0 :         pStrings[i++] = UNO_NAME_CHAR_FONT_NAME;
    1145           0 :         pStrings[i++] = UNO_NAME_CHAR_HEIGHT;
    1146           0 :         pStrings[i++] = UNO_NAME_CHAR_POSTURE;
    1147           0 :         pStrings[i++] = UNO_NAME_CHAR_SHADOWED;
    1148           0 :         pStrings[i++] = UNO_NAME_CHAR_STRIKEOUT;
    1149           0 :         pStrings[i++] = UNO_NAME_CHAR_UNDERLINE;
    1150           0 :         pStrings[i++] = UNO_NAME_CHAR_UNDERLINE_COLOR;
    1151           0 :         pStrings[i++] = UNO_NAME_CHAR_WEIGHT;
    1152             :         assert(i == pSeq->getLength());
    1153           0 :         pNames = pSeq;
    1154             :     }
    1155           0 :     return *pNames;
    1156             : }
    1157             : 
    1158           0 : uno::Sequence< OUString > getSupplementalAttributeNames()
    1159             : {
    1160             :     static uno::Sequence< OUString >* pNames = NULL;
    1161             : 
    1162           0 :     if( pNames == NULL )
    1163             :     {
    1164           0 :         uno::Sequence< OUString >* pSeq = new uno::Sequence< OUString >( 9 );
    1165             : 
    1166           0 :         OUString* pStrings = pSeq->getArray();
    1167             : 
    1168             :         // sorted list of strings
    1169           0 :         sal_Int32 i = 0;
    1170             : 
    1171           0 :         pStrings[i++] = UNO_NAME_NUMBERING_LEVEL;
    1172           0 :         pStrings[i++] = UNO_NAME_NUMBERING_RULES;
    1173           0 :         pStrings[i++] = UNO_NAME_PARA_ADJUST;
    1174           0 :         pStrings[i++] = UNO_NAME_PARA_BOTTOM_MARGIN;
    1175           0 :         pStrings[i++] = UNO_NAME_PARA_FIRST_LINE_INDENT;
    1176           0 :         pStrings[i++] = UNO_NAME_PARA_LEFT_MARGIN;
    1177           0 :         pStrings[i++] = UNO_NAME_PARA_LINE_SPACING;
    1178           0 :         pStrings[i++] = UNO_NAME_PARA_RIGHT_MARGIN;
    1179           0 :         pStrings[i++] = UNO_NAME_TABSTOPS;
    1180             :         assert(i == pSeq->getLength());
    1181           0 :         pNames = pSeq;
    1182             :     }
    1183           0 :     return *pNames;
    1184             : }
    1185             : 
    1186             : // XInterface
    1187             : 
    1188         652 : uno::Any SwAccessibleParagraph::queryInterface( const uno::Type& rType )
    1189             :     throw (uno::RuntimeException, std::exception)
    1190             : {
    1191         652 :     uno::Any aRet;
    1192         652 :     if ( rType == cppu::UnoType<XAccessibleText>::get())
    1193             :     {
    1194           3 :         uno::Reference<XAccessibleText> aAccText = static_cast<XAccessibleText *>(*this); // resolve ambiguity
    1195           3 :         aRet <<= aAccText;
    1196             :     }
    1197         649 :     else if ( rType == cppu::UnoType<XAccessibleEditableText>::get())
    1198             :     {
    1199           0 :         uno::Reference<XAccessibleEditableText> aAccEditText = this;
    1200           0 :         aRet <<= aAccEditText;
    1201             :     }
    1202         649 :     else if ( rType == cppu::UnoType<XAccessibleSelection>::get())
    1203             :     {
    1204           9 :         uno::Reference<XAccessibleSelection> aAccSel = this;
    1205           9 :         aRet <<= aAccSel;
    1206             :     }
    1207         640 :     else if ( rType == cppu::UnoType<XAccessibleHypertext>::get())
    1208             :     {
    1209           0 :         uno::Reference<XAccessibleHypertext> aAccHyp = this;
    1210           0 :         aRet <<= aAccHyp;
    1211             :     }
    1212             :     // #i63870#
    1213             :     // add interface com::sun:star:accessibility::XAccessibleTextAttributes
    1214         640 :     else if ( rType == cppu::UnoType<XAccessibleTextAttributes>::get())
    1215             :     {
    1216           0 :         uno::Reference<XAccessibleTextAttributes> aAccTextAttr = this;
    1217           0 :         aRet <<= aAccTextAttr;
    1218             :     }
    1219             :     // #i89175#
    1220             :     // add interface com::sun:star:accessibility::XAccessibleTextMarkup
    1221         640 :     else if ( rType == cppu::UnoType<XAccessibleTextMarkup>::get())
    1222             :     {
    1223           0 :         uno::Reference<XAccessibleTextMarkup> aAccTextMarkup = this;
    1224           0 :         aRet <<= aAccTextMarkup;
    1225             :     }
    1226             :     // add interface com::sun:star:accessibility::XAccessibleMultiLineText
    1227         640 :     else if ( rType == cppu::UnoType<XAccessibleMultiLineText>::get())
    1228             :     {
    1229           0 :         uno::Reference<XAccessibleMultiLineText> aAccMultiLineText = this;
    1230           0 :         aRet <<= aAccMultiLineText;
    1231             :     }
    1232         640 :     else if ( rType == cppu::UnoType<XAccessibleTextSelection>::get())
    1233             :     {
    1234           0 :         uno::Reference< com::sun::star::accessibility::XAccessibleTextSelection > aTextExtension = this;
    1235           0 :         aRet <<= aTextExtension;
    1236             :     }
    1237         640 :     else if ( rType == cppu::UnoType<XAccessibleExtendedAttributes>::get())
    1238             :     {
    1239           0 :         uno::Reference<XAccessibleExtendedAttributes> xAttr = this;
    1240           0 :         aRet <<= xAttr;
    1241             :     }
    1242             :     else
    1243             :     {
    1244         640 :         aRet = SwAccessibleContext::queryInterface(rType);
    1245             :     }
    1246             : 
    1247         652 :     return aRet;
    1248             : }
    1249             : 
    1250             : // XTypeProvider
    1251           0 : uno::Sequence< uno::Type > SAL_CALL SwAccessibleParagraph::getTypes() throw(uno::RuntimeException, std::exception)
    1252             : {
    1253           0 :     uno::Sequence< uno::Type > aTypes( SwAccessibleContext::getTypes() );
    1254             : 
    1255           0 :     sal_Int32 nIndex = aTypes.getLength();
    1256             :     // #i63870# - add type accessibility::XAccessibleTextAttributes
    1257             :     // #i89175# - add type accessibility::XAccessibleTextMarkup and
    1258             :     // accessibility::XAccessibleMultiLineText
    1259           0 :     aTypes.realloc( nIndex + 6 );
    1260             : 
    1261           0 :     uno::Type* pTypes = aTypes.getArray();
    1262           0 :     pTypes[nIndex++] = cppu::UnoType<XAccessibleEditableText>::get();
    1263           0 :     pTypes[nIndex++] = cppu::UnoType<XAccessibleTextAttributes>::get();
    1264           0 :     pTypes[nIndex++] = ::cppu::UnoType<XAccessibleSelection>::get();
    1265           0 :     pTypes[nIndex++] = cppu::UnoType<XAccessibleTextMarkup>::get();
    1266           0 :     pTypes[nIndex++] = cppu::UnoType<XAccessibleMultiLineText>::get();
    1267           0 :     pTypes[nIndex] = cppu::UnoType<XAccessibleHypertext>::get();
    1268             : 
    1269           0 :     return aTypes;
    1270             : }
    1271             : 
    1272           0 : uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleParagraph::getImplementationId()
    1273             :         throw(uno::RuntimeException, std::exception)
    1274             : {
    1275           0 :     return css::uno::Sequence<sal_Int8>();
    1276             : }
    1277             : 
    1278             : // XAccesibleText
    1279             : 
    1280           0 : sal_Int32 SwAccessibleParagraph::getCaretPosition()
    1281             :     throw (uno::RuntimeException, std::exception)
    1282             : {
    1283           0 :     SolarMutexGuard aGuard;
    1284             : 
    1285           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    1286             : 
    1287           0 :     sal_Int32 nRet = GetCaretPos();
    1288             :     {
    1289           0 :         osl::MutexGuard aOldCaretPosGuard( m_Mutex );
    1290             :         OSL_ENSURE( nRet == nOldCaretPos, "caret pos out of sync" );
    1291           0 :         nOldCaretPos = nRet;
    1292             :     }
    1293           0 :     if( -1 != nRet )
    1294             :     {
    1295           0 :         ::rtl::Reference < SwAccessibleContext > xThis( this );
    1296           0 :         GetMap()->SetCursorContext( xThis );
    1297             :     }
    1298             : 
    1299           0 :     return nRet;
    1300             : }
    1301             : 
    1302           0 : sal_Bool SAL_CALL SwAccessibleParagraph::setCaretPosition( sal_Int32 nIndex )
    1303             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    1304             : {
    1305           0 :     SolarMutexGuard aGuard;
    1306             : 
    1307           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    1308             : 
    1309             :     // parameter checking
    1310           0 :     sal_Int32 nLength = GetString().getLength();
    1311           0 :     if ( ! IsValidPosition( nIndex, nLength ) )
    1312             :     {
    1313           0 :         throw lang::IndexOutOfBoundsException();
    1314             :     }
    1315             : 
    1316           0 :     bool bRet = false;
    1317             : 
    1318             :     // get cursor shell
    1319           0 :     SwCrsrShell* pCrsrShell = GetCrsrShell();
    1320           0 :     if( pCrsrShell != NULL )
    1321             :     {
    1322             :         // create pam for selection
    1323           0 :         SwTextNode* pNode = const_cast<SwTextNode*>( GetTextNode() );
    1324           0 :         SwIndex aIndex( pNode, GetPortionData().GetModelPosition(nIndex));
    1325           0 :         SwPosition aStartPos( *pNode, aIndex );
    1326           0 :         SwPaM aPaM( aStartPos );
    1327             : 
    1328             :         // set PaM at cursor shell
    1329           0 :         bRet = Select( aPaM );
    1330             :     }
    1331             : 
    1332           0 :     return bRet;
    1333             : }
    1334             : 
    1335           0 : sal_Unicode SwAccessibleParagraph::getCharacter( sal_Int32 nIndex )
    1336             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    1337             : {
    1338           0 :     SolarMutexGuard aGuard;
    1339             : 
    1340           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    1341             : 
    1342           0 :     OUString sText( GetString() );
    1343             : 
    1344             :     // return character (if valid)
    1345           0 :     if( IsValidChar(nIndex, sText.getLength() ) )
    1346             :     {
    1347           0 :         return sText[nIndex];
    1348             :     }
    1349             :     else
    1350           0 :         throw lang::IndexOutOfBoundsException();
    1351             : }
    1352             : 
    1353           0 : com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > SwAccessibleParagraph::GetCurrentTabStop( sal_Int32 nIndex  )
    1354             : {
    1355           0 :     SolarMutexGuard aGuard;
    1356             : 
    1357           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    1358             : 
    1359             :     /*  #i12332# The position after the string needs special treatment.
    1360             :         IsValidChar -> IsValidPosition
    1361             :     */
    1362           0 :     if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
    1363           0 :         throw lang::IndexOutOfBoundsException();
    1364             : 
    1365             :     /*  #i12332#  */
    1366           0 :     bool bBehindText = false;
    1367           0 :     if ( nIndex == GetString().getLength() )
    1368           0 :         bBehindText = true;
    1369             : 
    1370             :     // get model position & prepare GetCharRect() arguments
    1371           0 :     SwCrsrMoveState aMoveState;
    1372           0 :     aMoveState.bRealHeight = true;
    1373           0 :     aMoveState.bRealWidth = true;
    1374           0 :     SwSpecialPos aSpecialPos;
    1375           0 :     SwTextNode* pNode = const_cast<SwTextNode*>( GetTextNode() );
    1376             : 
    1377             :     /*  #i12332# FillSpecialPos does not accept nIndex ==
    1378             :          GetString().getLength(). In that case nPos is set to the
    1379             :          length of the string in the core. This way GetCharRect
    1380             :          returns the rectangle for a cursor at the end of the
    1381             :          paragraph. */
    1382             :     const sal_Int32 nPos = bBehindText
    1383           0 :         ? pNode->GetText().getLength()
    1384           0 :         : GetPortionData().FillSpecialPos(nIndex, aSpecialPos, aMoveState.pSpecialPos );
    1385             : 
    1386             :     // call GetCharRect
    1387           0 :     SwRect aCoreRect;
    1388           0 :     SwIndex aIndex( pNode, nPos );
    1389           0 :     SwPosition aPosition( *pNode, aIndex );
    1390           0 :     GetFrm()->GetCharRect( aCoreRect, aPosition, &aMoveState );
    1391             : 
    1392             :     // already get the caret position
    1393           0 :     com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs;
    1394           0 :     const sal_Int32 nStrLen = GetTextNode()->GetText().getLength();
    1395           0 :     if( nStrLen > 0 )
    1396             :     {
    1397           0 :         SwFrm* pTFrm = const_cast<SwFrm*>(GetFrm());
    1398           0 :         tabs = pTFrm->GetTabStopInfo(aCoreRect.Left());
    1399             :     }
    1400             : 
    1401           0 :     if( tabs.hasElements() )
    1402             :     {
    1403             :         // translate core coordinates into accessibility coordinates
    1404           0 :         vcl::Window *pWin = GetWindow();
    1405           0 :         CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
    1406             : 
    1407           0 :         SwRect aTmpRect(0, 0, tabs[0].Position, 0);
    1408             : 
    1409           0 :         Rectangle aScreenRect( GetMap()->CoreToPixel( aTmpRect.SVRect() ));
    1410           0 :         SwRect aFrmLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
    1411             : 
    1412           0 :         Point aFrmPixPos( GetMap()->CoreToPixel( aFrmLogBounds.SVRect() ).TopLeft() );
    1413           0 :         aScreenRect.Move( -aFrmPixPos.X(), -aFrmPixPos.Y() );
    1414             : 
    1415           0 :         tabs[0].Position = aScreenRect.GetWidth();
    1416             :     }
    1417             : 
    1418           0 :     return tabs;
    1419             : }
    1420             : 
    1421             : struct IndexCompare
    1422             : {
    1423             :     const PropertyValue* pValues;
    1424           0 :     explicit IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {}
    1425           0 :     bool operator() ( const sal_Int32& a, const sal_Int32& b ) const
    1426             :     {
    1427           0 :         return (pValues[a].Name < pValues[b].Name);
    1428             :     }
    1429             : };
    1430             : 
    1431           0 : OUString SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
    1432             : {
    1433           0 :     OUString strTypeName;
    1434           0 :     SwFieldMgr aMgr;
    1435           0 :     SwTextField* pTextField = NULL;
    1436           0 :     SwTextNode* pTextNd = const_cast<SwTextNode*>( GetTextNode() );
    1437           0 :     SwIndex fldIndex( pTextNd, nIndex );
    1438           0 :     sal_Int32 nFieldIndex = GetPortionData().GetFieldIndex(nIndex);
    1439           0 :     if (nFieldIndex >= 0)
    1440             :     {
    1441           0 :         const SwpHints* pSwpHints = GetTextNode()->GetpSwpHints();
    1442           0 :         if (pSwpHints)
    1443             :         {
    1444           0 :             const size_t nSize = pSwpHints->Count();
    1445           0 :             for( size_t i = 0; i < nSize; ++i )
    1446             :             {
    1447           0 :                 const SwTextAttr* pHt = (*pSwpHints)[i];
    1448           0 :                 if ( ( pHt->Which() == RES_TXTATR_FIELD
    1449           0 :                        || pHt->Which() == RES_TXTATR_ANNOTATION
    1450           0 :                        || pHt->Which() == RES_TXTATR_INPUTFIELD )
    1451           0 :                      && (nFieldIndex-- == 0))
    1452             :                 {
    1453             :                     pTextField = const_cast<SwTextField*>(
    1454           0 :                                 static_txtattr_cast<SwTextField const*>(pHt));
    1455           0 :                     break;
    1456             :                 }
    1457           0 :                 else if (pHt->Which() == RES_TXTATR_REFMARK
    1458           0 :                          && (nFieldIndex-- == 0))
    1459           0 :                     strTypeName = "set reference";
    1460             :             }
    1461             :         }
    1462             :     }
    1463           0 :     if (pTextField)
    1464             :     {
    1465           0 :         const SwField* pField = (pTextField->GetFormatField()).GetField();
    1466           0 :         if (pField)
    1467             :         {
    1468           0 :             strTypeName = SwFieldType::GetTypeStr(pField->GetTypeId());
    1469           0 :             const sal_uInt16 nWhich = pField->GetTyp()->Which();
    1470           0 :             OUString sEntry;
    1471           0 :             sal_Int32 subType = 0;
    1472           0 :             switch (nWhich)
    1473             :             {
    1474             :             case RES_DOCSTATFLD:
    1475           0 :                 subType = static_cast<const SwDocStatField*>(pField)->GetSubType();
    1476           0 :                 break;
    1477             :             case RES_GETREFFLD:
    1478             :                 {
    1479           0 :                     switch( pField->GetSubType() )
    1480             :                     {
    1481             :                     case REF_BOOKMARK:
    1482             :                         {
    1483           0 :                             const SwGetRefField* pRefField = dynamic_cast<const SwGetRefField*>(pField);
    1484           0 :                             if ( pRefField && pRefField->IsRefToHeadingCrossRefBookmark() )
    1485           0 :                                 sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Headings"));
    1486           0 :                             else if ( pRefField && pRefField->IsRefToNumItemCrossRefBookmark() )
    1487           0 :                                 sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Numbered Paragraphs"));
    1488             :                             else
    1489           0 :                                 sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Bookmarks"));
    1490             :                         }
    1491           0 :                         break;
    1492             :                     case REF_FOOTNOTE:
    1493           0 :                         sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Footnotes"));
    1494           0 :                         break;
    1495             :                     case REF_ENDNOTE:
    1496           0 :                         sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Endnotes"));
    1497           0 :                         break;
    1498             :                     case REF_SETREFATTR:
    1499           0 :                         sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Insert Reference"));
    1500           0 :                         break;
    1501             :                     case REF_SEQUENCEFLD:
    1502           0 :                         sEntry = static_cast<const SwGetRefField*>(pField)->GetSetRefName();
    1503           0 :                         break;
    1504             :                     }
    1505             :                     //Get format string
    1506           0 :                     strTypeName = sEntry;
    1507             :                     // <pField->GetFormat() >= 0> is always true as <pField->GetFormat()> is unsigned
    1508             : //                    if (pField->GetFormat() >= 0)
    1509             :                     {
    1510           0 :                         sEntry = aMgr.GetFormatStr( pField->GetTypeId(), pField->GetFormat() );
    1511           0 :                         if (sEntry.getLength() > 0)
    1512             :                         {
    1513           0 :                             strTypeName += "-";
    1514           0 :                             strTypeName += sEntry;
    1515             :                         }
    1516             :                     }
    1517             :                 }
    1518           0 :                 break;
    1519             :             case RES_DATETIMEFLD:
    1520           0 :                 subType = static_cast<const SwDateTimeField*>(pField)->GetSubType();
    1521           0 :                 break;
    1522             :             case RES_JUMPEDITFLD:
    1523             :                 {
    1524           0 :                     const sal_uInt16 nFormat= pField->GetFormat();
    1525           0 :                     const sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), false);
    1526           0 :                     if (nFormat < nSize)
    1527             :                     {
    1528           0 :                         sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nFormat);
    1529           0 :                         if (sEntry.getLength() > 0)
    1530             :                         {
    1531           0 :                             strTypeName += "-";
    1532           0 :                             strTypeName += sEntry;
    1533             :                         }
    1534             :                     }
    1535             :                 }
    1536           0 :                 break;
    1537             :             case RES_EXTUSERFLD:
    1538           0 :                 subType = static_cast<const SwExtUserField*>(pField)->GetSubType();
    1539           0 :                 break;
    1540             :             case RES_HIDDENTXTFLD:
    1541             :             case RES_SETEXPFLD:
    1542             :                 {
    1543           0 :                     sEntry = pField->GetTyp()->GetName();
    1544           0 :                     if (sEntry.getLength() > 0)
    1545             :                     {
    1546           0 :                         strTypeName += "-";
    1547           0 :                         strTypeName += sEntry;
    1548             :                     }
    1549             :                 }
    1550           0 :                 break;
    1551             :             case RES_DOCINFOFLD:
    1552           0 :                 subType = pField->GetSubType();
    1553           0 :                 subType &= 0x00ff;
    1554           0 :                 break;
    1555             :             case RES_REFPAGESETFLD:
    1556             :                 {
    1557           0 :                     const SwRefPageSetField* pRPld = static_cast<const SwRefPageSetField*>(pField);
    1558           0 :                     bool bOn = pRPld->IsOn();
    1559           0 :                     strTypeName += "-";
    1560           0 :                     if (bOn)
    1561           0 :                         strTypeName += "on";
    1562             :                     else
    1563           0 :                         strTypeName += "off";
    1564             :                 }
    1565           0 :                 break;
    1566             :             case RES_AUTHORFLD:
    1567             :                 {
    1568           0 :                     strTypeName += "-";
    1569           0 :                     strTypeName += aMgr.GetFormatStr(pField->GetTypeId(), pField->GetFormat() & 0xff);
    1570             :                 }
    1571           0 :                 break;
    1572             :             }
    1573           0 :             if (subType > 0 || (subType == 0 && (nWhich == RES_DOCINFOFLD || nWhich == RES_EXTUSERFLD || nWhich == RES_DOCSTATFLD)))
    1574             :             {
    1575           0 :                 std::vector<OUString> aLst;
    1576           0 :                 aMgr.GetSubTypes(pField->GetTypeId(), aLst);
    1577           0 :                 if (static_cast<size_t>(subType) < aLst.size())
    1578           0 :                     sEntry = aLst[subType];
    1579           0 :                 if (sEntry.getLength() > 0)
    1580             :                 {
    1581           0 :                     if (nWhich == RES_DOCINFOFLD)
    1582             :                     {
    1583           0 :                         strTypeName = sEntry;
    1584           0 :                         sal_uInt32 nSize = aMgr.GetFormatCount(pField->GetTypeId(), false);
    1585           0 :                         const sal_uInt16 nExSub = pField->GetSubType() & 0xff00;
    1586           0 :                         if (nSize > 0 && nExSub > 0)
    1587             :                         {
    1588             :                             //Get extra subtype string
    1589           0 :                             strTypeName += "-";
    1590           0 :                             sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nExSub/0x0100-1);
    1591           0 :                             strTypeName += sEntry;
    1592             :                         }
    1593             :                     }
    1594             :                     else
    1595             :                     {
    1596           0 :                         strTypeName += "-";
    1597           0 :                         strTypeName += sEntry;
    1598             :                     }
    1599           0 :                 }
    1600           0 :             }
    1601             :         }
    1602             :     }
    1603           0 :     return strTypeName;
    1604             : }
    1605             : 
    1606             : // #i63870# - re-implement method on behalf of methods
    1607             : // <_getDefaultAttributesImpl(..)> and <_getRunAttributesImpl(..)>
    1608           0 : uno::Sequence<PropertyValue> SwAccessibleParagraph::getCharacterAttributes(
    1609             :     sal_Int32 nIndex,
    1610             :     const uno::Sequence< OUString >& aRequestedAttributes )
    1611             :     throw (lang::IndexOutOfBoundsException,
    1612             :            uno::RuntimeException,
    1613             :            std::exception)
    1614             : {
    1615             : 
    1616           0 :     SolarMutexGuard aGuard;
    1617           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    1618             : 
    1619           0 :     const OUString& rText = GetString();
    1620             : 
    1621           0 :     if( ! IsValidChar( nIndex, rText.getLength()+1 ) )
    1622           0 :         throw lang::IndexOutOfBoundsException();
    1623             : 
    1624           0 :     bool bSupplementalMode = false;
    1625           0 :     uno::Sequence< OUString > aNames = aRequestedAttributes;
    1626           0 :     if (aNames.getLength() == 0)
    1627             :     {
    1628           0 :         bSupplementalMode = true;
    1629           0 :         aNames = getAttributeNames();
    1630             :     }
    1631             :     // retrieve default character attributes
    1632           0 :     tAccParaPropValMap aDefAttrSeq;
    1633           0 :     _getDefaultAttributesImpl( aNames, aDefAttrSeq, true );
    1634             : 
    1635             :     // retrieved run character attributes
    1636           0 :     tAccParaPropValMap aRunAttrSeq;
    1637           0 :     _getRunAttributesImpl( nIndex, aNames, aRunAttrSeq );
    1638             : 
    1639             :     // merge default and run attributes
    1640           0 :     uno::Sequence< PropertyValue > aValues( aDefAttrSeq.size() );
    1641           0 :     PropertyValue* pValues = aValues.getArray();
    1642           0 :     sal_Int32 i = 0;
    1643           0 :     for ( tAccParaPropValMap::const_iterator aDefIter = aDefAttrSeq.begin();
    1644           0 :           aDefIter != aDefAttrSeq.end();
    1645             :           ++aDefIter )
    1646             :     {
    1647             :         tAccParaPropValMap::const_iterator aRunIter =
    1648           0 :                                         aRunAttrSeq.find( aDefIter->first );
    1649           0 :         if ( aRunIter != aRunAttrSeq.end() )
    1650             :         {
    1651           0 :             pValues[i] = aRunIter->second;
    1652             :         }
    1653             :         else
    1654             :         {
    1655           0 :             pValues[i] = aDefIter->second;
    1656             :         }
    1657           0 :         ++i;
    1658             :     }
    1659           0 :     if( bSupplementalMode )
    1660             :     {
    1661           0 :         uno::Sequence< OUString > aSupplementalNames = aRequestedAttributes;
    1662           0 :         if (aSupplementalNames.getLength() == 0)
    1663           0 :             aSupplementalNames = getSupplementalAttributeNames();
    1664             : 
    1665           0 :         tAccParaPropValMap aSupplementalAttrSeq;
    1666           0 :         _getSupplementalAttributesImpl( nIndex, aSupplementalNames, aSupplementalAttrSeq );
    1667             : 
    1668           0 :         aValues.realloc( aValues.getLength() + aSupplementalAttrSeq.size() );
    1669           0 :         pValues = aValues.getArray();
    1670             : 
    1671           0 :         for ( tAccParaPropValMap::const_iterator aSupplementalIter = aSupplementalAttrSeq.begin();
    1672           0 :             aSupplementalIter != aSupplementalAttrSeq.end();
    1673             :             ++aSupplementalIter )
    1674             :         {
    1675           0 :             pValues[i] = aSupplementalIter->second;
    1676           0 :             ++i;
    1677             :         }
    1678             : 
    1679           0 :         _correctValues( nIndex, aValues );
    1680             : 
    1681           0 :         aValues.realloc( aValues.getLength() + 1 );
    1682             : 
    1683           0 :         pValues = aValues.getArray();
    1684             : 
    1685           0 :         const SwTextNode* pTextNode( GetTextNode() );
    1686           0 :         PropertyValue& rValue = pValues[aValues.getLength() - 1 ];
    1687           0 :         rValue.Name = "NumberingPrefix";
    1688           0 :         OUString sNumBullet = pTextNode->GetNumString();
    1689           0 :         rValue.Value <<= sNumBullet;
    1690           0 :         rValue.Handle = -1;
    1691           0 :         rValue.State = PropertyState_DIRECT_VALUE;
    1692             : 
    1693           0 :         OUString strTypeName = GetFieldTypeNameAtIndex(nIndex);
    1694           0 :         if (!strTypeName.isEmpty())
    1695             :         {
    1696           0 :             aValues.realloc( aValues.getLength() + 1 );
    1697           0 :             pValues = aValues.getArray();
    1698           0 :             PropertyValue& rValueFT = pValues[aValues.getLength() - 1];
    1699           0 :             rValueFT.Name = "FieldType";
    1700           0 :             rValueFT.Value <<= strTypeName.toAsciiLowerCase();
    1701           0 :             rValueFT.Handle = -1;
    1702           0 :             rValueFT.State = PropertyState_DIRECT_VALUE;
    1703             :         }
    1704             : 
    1705             :         //sort property values
    1706             :         // build sorted index array
    1707           0 :         sal_Int32 nLength = aValues.getLength();
    1708           0 :         const PropertyValue* pPairs = aValues.getConstArray();
    1709           0 :         sal_Int32* pIndices = new sal_Int32[nLength];
    1710           0 :         for( i = 0; i < nLength; i++ )
    1711           0 :             pIndices[i] = i;
    1712           0 :         sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
    1713             :         // create sorted sequences according to index array
    1714           0 :         uno::Sequence<PropertyValue> aNewValues( nLength );
    1715           0 :         PropertyValue* pNewValues = aNewValues.getArray();
    1716           0 :         for( i = 0; i < nLength; i++ )
    1717             :         {
    1718           0 :             pNewValues[i] = pPairs[pIndices[i]];
    1719             :         }
    1720           0 :         delete[] pIndices;
    1721           0 :         return aNewValues;
    1722             :     }
    1723             : 
    1724           0 :     return aValues;
    1725             : }
    1726             : 
    1727           0 : static void SetPutRecursive(SfxItemSet &targetSet, const SfxItemSet &sourceSet)
    1728             : {
    1729           0 :     const SfxItemSet *const pParentSet = sourceSet.GetParent();
    1730           0 :     if (pParentSet)
    1731           0 :         SetPutRecursive(targetSet, *pParentSet);
    1732           0 :     targetSet.Put(sourceSet);
    1733           0 : }
    1734             : 
    1735             : // #i63870#
    1736           0 : void SwAccessibleParagraph::_getDefaultAttributesImpl(
    1737             :         const uno::Sequence< OUString >& aRequestedAttributes,
    1738             :         tAccParaPropValMap& rDefAttrSeq,
    1739             :         const bool bOnlyCharAttrs )
    1740             : {
    1741             :     // retrieve default attributes
    1742           0 :     const SwTextNode* pTextNode( GetTextNode() );
    1743           0 :     ::boost::scoped_ptr<SfxItemSet> pSet;
    1744           0 :     if ( !bOnlyCharAttrs )
    1745             :     {
    1746           0 :         pSet.reset( new SfxItemSet( const_cast<SwAttrPool&>(pTextNode->GetDoc()->GetAttrPool()),
    1747             :                                RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
    1748             :                                RES_PARATR_BEGIN, RES_PARATR_END - 1,
    1749             :                                RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
    1750           0 :                                0 ) );
    1751             :     }
    1752             :     else
    1753             :     {
    1754           0 :         pSet.reset( new SfxItemSet( const_cast<SwAttrPool&>(pTextNode->GetDoc()->GetAttrPool()),
    1755             :                                RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
    1756           0 :                                0 ) );
    1757             :     }
    1758             :     // #i82637# - From the perspective of the a11y API the default character
    1759             :     // attributes are the character attributes, which are set at the paragraph style
    1760             :     // of the paragraph. The character attributes set at the automatic paragraph
    1761             :     // style of the paragraph are treated as run attributes.
    1762             :     //    pTextNode->SwContentNode::GetAttr( *pSet );
    1763             :     // get default paragraph attributes, if needed, and merge these into <pSet>
    1764           0 :     if ( !bOnlyCharAttrs )
    1765             :     {
    1766           0 :         SfxItemSet aParaSet( const_cast<SwAttrPool&>(pTextNode->GetDoc()->GetAttrPool()),
    1767             :                              RES_PARATR_BEGIN, RES_PARATR_END - 1,
    1768             :                              RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
    1769           0 :                              0 );
    1770           0 :         pTextNode->SwContentNode::GetAttr( aParaSet );
    1771           0 :         pSet->Put( aParaSet );
    1772             :     }
    1773             :     // get default character attributes and merge these into <pSet>
    1774             :     OSL_ENSURE( pTextNode->GetTextColl(),
    1775             :             "<SwAccessibleParagraph::_getDefaultAttributesImpl(..)> - missing paragraph style. Serious defect, please inform OD!" );
    1776           0 :     if ( pTextNode->GetTextColl() )
    1777             :     {
    1778           0 :         SfxItemSet aCharSet( const_cast<SwAttrPool&>(pTextNode->GetDoc()->GetAttrPool()),
    1779             :                              RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
    1780           0 :                              0 );
    1781           0 :         SetPutRecursive( aCharSet, pTextNode->GetTextColl()->GetAttrSet() );
    1782           0 :         pSet->Put( aCharSet );
    1783             :     }
    1784             : 
    1785             :     // build-up sequence containing the run attributes <rDefAttrSeq>
    1786           0 :     tAccParaPropValMap aDefAttrSeq;
    1787             :     {
    1788             :         const SfxItemPropertyMap& rPropMap =
    1789           0 :                     aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_CURSOR )->getPropertyMap();
    1790           0 :         PropertyEntryVector_t aPropertyEntries = rPropMap.getPropertyEntries();
    1791           0 :         PropertyEntryVector_t::const_iterator aPropIt = aPropertyEntries.begin();
    1792           0 :         while ( aPropIt != aPropertyEntries.end() )
    1793             :         {
    1794           0 :             const SfxPoolItem* pItem = pSet->GetItem( aPropIt->nWID );
    1795           0 :             if ( pItem )
    1796             :             {
    1797           0 :                 uno::Any aVal;
    1798           0 :                 pItem->QueryValue( aVal, aPropIt->nMemberId );
    1799             : 
    1800           0 :                 PropertyValue rPropVal;
    1801           0 :                 rPropVal.Name = aPropIt->sName;
    1802           0 :                 rPropVal.Value = aVal;
    1803           0 :                 rPropVal.Handle = -1;
    1804           0 :                 rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
    1805             : 
    1806           0 :                 aDefAttrSeq[rPropVal.Name] = rPropVal;
    1807             :             }
    1808           0 :             ++aPropIt;
    1809             :         }
    1810             : 
    1811             :         // #i72800#
    1812             :         // add property value entry for the paragraph style
    1813           0 :         if ( !bOnlyCharAttrs && pTextNode->GetTextColl() )
    1814             :         {
    1815           0 :             if ( aDefAttrSeq.find( UNO_NAME_PARA_STYLE_NAME ) == aDefAttrSeq.end() )
    1816             :             {
    1817           0 :                 PropertyValue rPropVal;
    1818           0 :                 rPropVal.Name = UNO_NAME_PARA_STYLE_NAME;
    1819           0 :                 uno::Any aVal( uno::makeAny( pTextNode->GetTextColl()->GetName() ) );
    1820           0 :                 rPropVal.Value = aVal;
    1821           0 :                 rPropVal.Handle = -1;
    1822           0 :                 rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
    1823             : 
    1824           0 :                 aDefAttrSeq[rPropVal.Name] = rPropVal;
    1825             :             }
    1826             :         }
    1827             : 
    1828             :         // #i73371#
    1829             :         // resolve value text::WritingMode2::PAGE of property value entry WritingMode
    1830           0 :         if ( !bOnlyCharAttrs && GetFrm() )
    1831             :         {
    1832           0 :             tAccParaPropValMap::iterator aIter = aDefAttrSeq.find( UNO_NAME_WRITING_MODE );
    1833           0 :             if ( aIter != aDefAttrSeq.end() )
    1834             :             {
    1835           0 :                 PropertyValue rPropVal( aIter->second );
    1836           0 :                 sal_Int16 nVal = rPropVal.Value.get<sal_Int16>();
    1837           0 :                 if ( nVal == text::WritingMode2::PAGE )
    1838             :                 {
    1839           0 :                     const SwFrm* pUpperFrm( GetFrm()->GetUpper() );
    1840           0 :                     while ( pUpperFrm )
    1841             :                     {
    1842           0 :                         if ( pUpperFrm->GetType() &
    1843             :                                ( FRM_PAGE | FRM_FLY | FRM_SECTION | FRM_TAB | FRM_CELL ) )
    1844             :                         {
    1845           0 :                             if ( pUpperFrm->IsVertical() )
    1846             :                             {
    1847           0 :                                 nVal = text::WritingMode2::TB_RL;
    1848             :                             }
    1849           0 :                             else if ( pUpperFrm->IsRightToLeft() )
    1850             :                             {
    1851           0 :                                 nVal = text::WritingMode2::RL_TB;
    1852             :                             }
    1853             :                             else
    1854             :                             {
    1855           0 :                                 nVal = text::WritingMode2::LR_TB;
    1856             :                             }
    1857           0 :                             rPropVal.Value <<= nVal;
    1858           0 :                             aDefAttrSeq[rPropVal.Name] = rPropVal;
    1859           0 :                             break;
    1860             :                         }
    1861             : 
    1862           0 :                         if ( const SwFlyFrm* pFlyFrm = dynamic_cast<const SwFlyFrm*>(pUpperFrm) )
    1863             :                         {
    1864           0 :                             pUpperFrm = pFlyFrm->GetAnchorFrm();
    1865             :                         }
    1866             :                         else
    1867             :                         {
    1868           0 :                             pUpperFrm = pUpperFrm->GetUpper();
    1869             :                         }
    1870             :                     }
    1871           0 :                 }
    1872             :             }
    1873           0 :         }
    1874             :     }
    1875             : 
    1876           0 :     if ( aRequestedAttributes.getLength() == 0 )
    1877             :     {
    1878           0 :         rDefAttrSeq = aDefAttrSeq;
    1879             :     }
    1880             :     else
    1881             :     {
    1882           0 :         const OUString* pReqAttrs = aRequestedAttributes.getConstArray();
    1883           0 :         const sal_Int32 nLength = aRequestedAttributes.getLength();
    1884           0 :         for( sal_Int32 i = 0; i < nLength; ++i )
    1885             :         {
    1886           0 :             tAccParaPropValMap::const_iterator const aIter = aDefAttrSeq.find( pReqAttrs[i] );
    1887           0 :             if ( aIter != aDefAttrSeq.end() )
    1888             :             {
    1889           0 :                 rDefAttrSeq[ aIter->first ] = aIter->second;
    1890             :             }
    1891             :         }
    1892           0 :     }
    1893           0 : }
    1894             : 
    1895           0 : uno::Sequence< PropertyValue > SwAccessibleParagraph::getDefaultAttributes(
    1896             :         const uno::Sequence< OUString >& aRequestedAttributes )
    1897             :         throw ( uno::RuntimeException, std::exception )
    1898             : {
    1899           0 :     SolarMutexGuard aGuard;
    1900           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    1901             : 
    1902           0 :     tAccParaPropValMap aDefAttrSeq;
    1903           0 :     _getDefaultAttributesImpl( aRequestedAttributes, aDefAttrSeq );
    1904             : 
    1905             :     // #i92233#
    1906             :     static const char sMMToPixelRatio[] = "MMToPixelRatio";
    1907           0 :     bool bProvideMMToPixelRatio( false );
    1908             :     {
    1909           0 :         if ( aRequestedAttributes.getLength() == 0 )
    1910             :         {
    1911           0 :             bProvideMMToPixelRatio = true;
    1912             :         }
    1913             :         else
    1914             :         {
    1915             :             const OUString* aRequestedAttrIter =
    1916           0 :                   ::std::find( aRequestedAttributes.begin(), aRequestedAttributes.end(), sMMToPixelRatio );
    1917           0 :             if ( aRequestedAttrIter != aRequestedAttributes.end() )
    1918           0 :                 bProvideMMToPixelRatio = true;
    1919             :         }
    1920             :     }
    1921             : 
    1922           0 :     uno::Sequence< PropertyValue > aValues( aDefAttrSeq.size() +
    1923           0 :                                             ( bProvideMMToPixelRatio ? 1 : 0 ) );
    1924           0 :     PropertyValue* pValues = aValues.getArray();
    1925           0 :     sal_Int32 i = 0;
    1926           0 :     for ( tAccParaPropValMap::const_iterator aIter  = aDefAttrSeq.begin();
    1927           0 :           aIter != aDefAttrSeq.end();
    1928             :           ++aIter )
    1929             :     {
    1930           0 :         pValues[i] = aIter->second;
    1931           0 :         ++i;
    1932             :     }
    1933             : 
    1934             :     // #i92233#
    1935           0 :     if ( bProvideMMToPixelRatio )
    1936             :     {
    1937           0 :         PropertyValue rPropVal;
    1938           0 :         rPropVal.Name = sMMToPixelRatio;
    1939           0 :         const Size a100thMMSize( 1000, 1000 );
    1940           0 :         const Size aPixelSize = GetMap()->LogicToPixel( a100thMMSize );
    1941           0 :         const float fRatio = ((float)a100thMMSize.Width()/100)/aPixelSize.Width();
    1942           0 :         rPropVal.Value = uno::makeAny( fRatio );
    1943           0 :         rPropVal.Handle = -1;
    1944           0 :         rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
    1945           0 :         pValues[ aValues.getLength() - 1 ] = rPropVal;
    1946             :     }
    1947             : 
    1948           0 :     return aValues;
    1949             : }
    1950             : 
    1951           0 : void SwAccessibleParagraph::_getRunAttributesImpl(
    1952             :         const sal_Int32 nIndex,
    1953             :         const uno::Sequence< OUString >& aRequestedAttributes,
    1954             :         tAccParaPropValMap& rRunAttrSeq )
    1955             : {
    1956             :     // create PaM for character at position <nIndex>
    1957           0 :     SwPaM* pPaM( 0 );
    1958             :     {
    1959           0 :         const SwTextNode* pTextNode( GetTextNode() );
    1960           0 :         SwPosition* pStartPos = new SwPosition( *pTextNode );
    1961           0 :         pStartPos->nContent.Assign( const_cast<SwTextNode*>(pTextNode), nIndex );
    1962           0 :         SwPosition* pEndPos = new SwPosition( *pTextNode );
    1963           0 :         pEndPos->nContent.Assign( const_cast<SwTextNode*>(pTextNode), nIndex+1 );
    1964             : 
    1965           0 :         pPaM = new SwPaM( *pStartPos, *pEndPos );
    1966             : 
    1967           0 :         delete pStartPos;
    1968           0 :         delete pEndPos;
    1969             :     }
    1970             : 
    1971             :     // retrieve character attributes for the created PaM <pPaM>
    1972           0 :     SfxItemSet aSet( pPaM->GetDoc()->GetAttrPool(),
    1973             :                      RES_CHRATR_BEGIN, RES_CHRATR_END -1,
    1974           0 :                      0 );
    1975             :     // #i82637#
    1976             :     // From the perspective of the a11y API the character attributes, which
    1977             :     // are set at the automatic paragraph style of the paragraph, are treated
    1978             :     // as run attributes.
    1979             :     //    SwXTextCursor::GetCrsrAttr( *pPaM, aSet, sal_True, sal_True );
    1980             :     // get character attributes from automatic paragraph style and merge these into <aSet>
    1981             :     {
    1982           0 :         const SwTextNode* pTextNode( GetTextNode() );
    1983           0 :         if ( pTextNode->HasSwAttrSet() )
    1984             :         {
    1985           0 :             SfxItemSet aAutomaticParaStyleCharAttrs( pPaM->GetDoc()->GetAttrPool(),
    1986             :                                                      RES_CHRATR_BEGIN, RES_CHRATR_END -1,
    1987           0 :                                                      0 );
    1988           0 :             aAutomaticParaStyleCharAttrs.Put( *(pTextNode->GetpSwAttrSet()), false );
    1989           0 :             aSet.Put( aAutomaticParaStyleCharAttrs );
    1990             :         }
    1991             :     }
    1992             :     // get character attributes at <pPaM> and merge these into <aSet>
    1993             :     {
    1994           0 :         SfxItemSet aCharAttrsAtPaM( pPaM->GetDoc()->GetAttrPool(),
    1995             :                                     RES_CHRATR_BEGIN, RES_CHRATR_END -1,
    1996           0 :                                     0 );
    1997           0 :         SwUnoCursorHelper::GetCrsrAttr(*pPaM, aCharAttrsAtPaM, true, true);
    1998           0 :         aSet.Put( aCharAttrsAtPaM );
    1999             :     }
    2000             : 
    2001             :     // build-up sequence containing the run attributes <rRunAttrSeq>
    2002             :     {
    2003           0 :         tAccParaPropValMap aRunAttrSeq;
    2004             :         {
    2005           0 :             tAccParaPropValMap aDefAttrSeq;
    2006           0 :             uno::Sequence< OUString > aDummy;
    2007           0 :             _getDefaultAttributesImpl( aDummy, aDefAttrSeq, true ); // #i82637#
    2008             : 
    2009             :             const SfxItemPropertyMap& rPropMap =
    2010           0 :                     aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_CURSOR )->getPropertyMap();
    2011           0 :             PropertyEntryVector_t aPropertyEntries = rPropMap.getPropertyEntries();
    2012           0 :             PropertyEntryVector_t::const_iterator aPropIt = aPropertyEntries.begin();
    2013           0 :             while ( aPropIt != aPropertyEntries.end() )
    2014             :             {
    2015           0 :                 const SfxPoolItem* pItem( 0 );
    2016             :                 // #i82637# - Found character attributes, whose value equals the value of
    2017             :                 // the corresponding default character attributes, are excluded.
    2018           0 :                 if ( aSet.GetItemState( aPropIt->nWID, true, &pItem ) == SfxItemState::SET )
    2019             :                 {
    2020           0 :                     uno::Any aVal;
    2021           0 :                     pItem->QueryValue( aVal, aPropIt->nMemberId );
    2022             : 
    2023           0 :                     PropertyValue rPropVal;
    2024           0 :                     rPropVal.Name = aPropIt->sName;
    2025           0 :                     rPropVal.Value = aVal;
    2026           0 :                     rPropVal.Handle = -1;
    2027           0 :                     rPropVal.State = PropertyState_DIRECT_VALUE;
    2028             : 
    2029             :                     tAccParaPropValMap::const_iterator aDefIter =
    2030           0 :                                             aDefAttrSeq.find( rPropVal.Name );
    2031           0 :                     if ( aDefIter == aDefAttrSeq.end() ||
    2032           0 :                          rPropVal.Value != aDefIter->second.Value )
    2033             :                     {
    2034           0 :                         aRunAttrSeq[rPropVal.Name] = rPropVal;
    2035           0 :                     }
    2036             :                 }
    2037             : 
    2038           0 :                 ++aPropIt;
    2039           0 :             }
    2040             :         }
    2041             : 
    2042           0 :         if ( aRequestedAttributes.getLength() == 0 )
    2043             :         {
    2044           0 :             rRunAttrSeq = aRunAttrSeq;
    2045             :         }
    2046             :         else
    2047             :         {
    2048           0 :             const OUString* pReqAttrs = aRequestedAttributes.getConstArray();
    2049           0 :             const sal_Int32 nLength = aRequestedAttributes.getLength();
    2050           0 :             for( sal_Int32 i = 0; i < nLength; ++i )
    2051             :             {
    2052           0 :                 tAccParaPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] );
    2053           0 :                 if ( aIter != aRunAttrSeq.end() )
    2054             :                 {
    2055           0 :                     rRunAttrSeq[ (*aIter).first ] = (*aIter).second;
    2056             :                 }
    2057             :             }
    2058           0 :         }
    2059             :     }
    2060             : 
    2061           0 :     delete pPaM;
    2062           0 : }
    2063             : 
    2064           0 : uno::Sequence< PropertyValue > SwAccessibleParagraph::getRunAttributes(
    2065             :         sal_Int32 nIndex,
    2066             :         const uno::Sequence< OUString >& aRequestedAttributes )
    2067             :         throw ( lang::IndexOutOfBoundsException,
    2068             :                 uno::RuntimeException, std::exception )
    2069             : {
    2070           0 :     SolarMutexGuard aGuard;
    2071           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2072             : 
    2073             :     {
    2074           0 :         const OUString& rText = GetString();
    2075           0 :         if ( !IsValidChar( nIndex, rText.getLength() ) )
    2076             :         {
    2077           0 :             throw lang::IndexOutOfBoundsException();
    2078           0 :         }
    2079             :     }
    2080             : 
    2081           0 :     tAccParaPropValMap aRunAttrSeq;
    2082           0 :     _getRunAttributesImpl( nIndex, aRequestedAttributes, aRunAttrSeq );
    2083             : 
    2084           0 :     uno::Sequence< PropertyValue > aValues( aRunAttrSeq.size() );
    2085           0 :     PropertyValue* pValues = aValues.getArray();
    2086           0 :     sal_Int32 i = 0;
    2087           0 :     for ( tAccParaPropValMap::const_iterator aIter  = aRunAttrSeq.begin();
    2088           0 :           aIter != aRunAttrSeq.end();
    2089             :           ++aIter )
    2090             :     {
    2091           0 :         pValues[i] = aIter->second;
    2092           0 :         ++i;
    2093             :     }
    2094             : 
    2095           0 :     return aValues;
    2096             : }
    2097             : 
    2098           0 : void SwAccessibleParagraph::_getSupplementalAttributesImpl(
    2099             :         const sal_Int32,
    2100             :         const uno::Sequence< OUString >& aRequestedAttributes,
    2101             :         tAccParaPropValMap& rSupplementalAttrSeq )
    2102             : {
    2103           0 :     const SwTextNode* pTextNode( GetTextNode() );
    2104           0 :     ::boost::scoped_ptr<SfxItemSet> pSet;
    2105           0 :     pSet.reset( new SfxItemSet( const_cast<SwAttrPool&>(pTextNode->GetDoc()->GetAttrPool()),
    2106             :         RES_PARATR_ADJUST, RES_PARATR_ADJUST,
    2107             :         RES_PARATR_TABSTOP, RES_PARATR_TABSTOP,
    2108             :         RES_PARATR_LINESPACING, RES_PARATR_LINESPACING,
    2109             :         RES_UL_SPACE, RES_UL_SPACE,
    2110             :         RES_LR_SPACE, RES_LR_SPACE,
    2111             :         RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
    2112             :         RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
    2113           0 :         0 ) );
    2114             : 
    2115           0 :     if ( pTextNode->HasBullet() || pTextNode->HasNumber() )
    2116             :     {
    2117           0 :         pSet->Put( pTextNode->GetAttr(RES_PARATR_LIST_LEVEL, true) );
    2118             :     }
    2119           0 :     pSet->Put( pTextNode->SwContentNode::GetAttr(RES_UL_SPACE) );
    2120           0 :     pSet->Put( pTextNode->SwContentNode::GetAttr(RES_LR_SPACE) );
    2121           0 :     pSet->Put( pTextNode->SwContentNode::GetAttr(RES_PARATR_ADJUST) );
    2122             : 
    2123           0 :     tAccParaPropValMap aSupplementalAttrSeq;
    2124             :     {
    2125             :         const SfxItemPropertyMapEntry* pPropMap(
    2126           0 :                 aSwMapProvider.GetPropertyMapEntries( PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE ) );
    2127           0 :         while ( !pPropMap->aName.isEmpty() )
    2128             :         {
    2129           0 :             const SfxPoolItem* pItem = pSet->GetItem( pPropMap->nWID );
    2130           0 :             if ( pItem )
    2131             :             {
    2132           0 :                 uno::Any aVal;
    2133           0 :                 pItem->QueryValue( aVal, pPropMap->nMemberId );
    2134             : 
    2135           0 :                 PropertyValue rPropVal;
    2136           0 :                 rPropVal.Name = pPropMap->aName;
    2137           0 :                 rPropVal.Value = aVal;
    2138           0 :                 rPropVal.Handle = -1;
    2139           0 :                 rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
    2140             : 
    2141           0 :                 aSupplementalAttrSeq[rPropVal.Name] = rPropVal;
    2142             :             }
    2143             : 
    2144           0 :             ++pPropMap;
    2145             :         }
    2146             :     }
    2147             : 
    2148           0 :     const OUString* pSupplementalAttrs = aRequestedAttributes.getConstArray();
    2149           0 :     const sal_Int32 nSupplementalLength = aRequestedAttributes.getLength();
    2150             : 
    2151           0 :     for( sal_Int32 index = 0; index < nSupplementalLength; ++index )
    2152             :     {
    2153           0 :         tAccParaPropValMap::const_iterator const aIter = aSupplementalAttrSeq.find( pSupplementalAttrs[index] );
    2154           0 :         if ( aIter != aSupplementalAttrSeq.end() )
    2155             :         {
    2156           0 :             rSupplementalAttrSeq[ aIter->first ] = aIter->second;
    2157             :         }
    2158           0 :     }
    2159           0 : }
    2160             : 
    2161           0 : void SwAccessibleParagraph::_correctValues( const sal_Int32 nIndex,
    2162             :                                            uno::Sequence< PropertyValue >& rValues)
    2163             : {
    2164           0 :     PropertyValue ChangeAttr, ChangeAttrColor;
    2165             : 
    2166           0 :     const SwRangeRedline* pRedline = GetRedlineAtIndex( nIndex );
    2167           0 :     if ( pRedline )
    2168             :     {
    2169             : 
    2170           0 :         const SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
    2171           0 :         AuthorCharAttr aChangeAttr;
    2172           0 :         if ( pOpt )
    2173             :         {
    2174           0 :             switch( pRedline->GetType())
    2175             :             {
    2176             :             case nsRedlineType_t::REDLINE_INSERT:
    2177           0 :                 aChangeAttr = pOpt->GetInsertAuthorAttr();
    2178           0 :                 break;
    2179             :             case nsRedlineType_t::REDLINE_DELETE:
    2180           0 :                 aChangeAttr = pOpt->GetDeletedAuthorAttr();
    2181           0 :                 break;
    2182             :             case nsRedlineType_t::REDLINE_FORMAT:
    2183           0 :                 aChangeAttr = pOpt->GetFormatAuthorAttr();
    2184           0 :                 break;
    2185             :             }
    2186             :         }
    2187           0 :         switch( aChangeAttr.nItemId )
    2188             :         {
    2189             :         case SID_ATTR_CHAR_WEIGHT:
    2190           0 :             ChangeAttr.Name = UNO_NAME_CHAR_WEIGHT;
    2191           0 :             ChangeAttr.Value <<= awt::FontWeight::BOLD;
    2192           0 :             break;
    2193             :         case SID_ATTR_CHAR_POSTURE:
    2194           0 :             ChangeAttr.Name = UNO_NAME_CHAR_POSTURE;
    2195           0 :             ChangeAttr.Value <<= awt::FontSlant_ITALIC; //char posture
    2196           0 :             break;
    2197             :         case SID_ATTR_CHAR_STRIKEOUT:
    2198           0 :             ChangeAttr.Name = UNO_NAME_CHAR_STRIKEOUT;
    2199           0 :             ChangeAttr.Value <<= awt::FontStrikeout::SINGLE; //char strikeout
    2200           0 :             break;
    2201             :         case SID_ATTR_CHAR_UNDERLINE:
    2202           0 :             ChangeAttr.Name = UNO_NAME_CHAR_UNDERLINE;
    2203           0 :             ChangeAttr.Value <<= aChangeAttr.nAttr; //underline line
    2204           0 :             break;
    2205             :         }
    2206           0 :         if( aChangeAttr.nColor != COL_NONE_COLOR )
    2207             :         {
    2208           0 :             if( aChangeAttr.nItemId == SID_ATTR_BRUSH )
    2209             :             {
    2210           0 :                 ChangeAttrColor.Name = UNO_NAME_CHAR_BACK_COLOR;
    2211           0 :                 if( aChangeAttr.nColor == COL_TRANSPARENT )//char backcolor
    2212           0 :                     ChangeAttrColor.Value <<= COL_BLUE;
    2213             :                 else
    2214           0 :                     ChangeAttrColor.Value <<= aChangeAttr.nColor;
    2215             :             }
    2216             :             else
    2217             :             {
    2218           0 :                 ChangeAttrColor.Name = UNO_NAME_CHAR_COLOR;
    2219           0 :                 if( aChangeAttr.nColor == COL_TRANSPARENT )//char color
    2220           0 :                     ChangeAttrColor.Value <<= COL_BLUE;
    2221             :                 else
    2222           0 :                     ChangeAttrColor.Value <<= aChangeAttr.nColor;
    2223             :             }
    2224             :         }
    2225             :     }
    2226             : 
    2227           0 :     PropertyValue* pValues = rValues.getArray();
    2228             : 
    2229           0 :     const SwTextNode* pTextNode( GetTextNode() );
    2230             : 
    2231           0 :     sal_Int32 nValues = rValues.getLength();
    2232           0 :     for (sal_Int32 i = 0;  i < nValues;  ++i)
    2233             :     {
    2234           0 :         PropertyValue& rValue = pValues[i];
    2235             : 
    2236           0 :         if (rValue.Name == ChangeAttr.Name )
    2237             :         {
    2238           0 :             rValue.Value = ChangeAttr.Value;
    2239           0 :             continue;
    2240             :         }
    2241             : 
    2242           0 :         if (rValue.Name == ChangeAttrColor.Name )
    2243             :         {
    2244           0 :             rValue.Value = ChangeAttrColor.Value;
    2245           0 :             continue;
    2246             :         }
    2247             : 
    2248             :         //back color
    2249           0 :         if (rValue.Name == UNO_NAME_CHAR_BACK_COLOR)
    2250             :         {
    2251           0 :             uno::Any &anyChar = rValue.Value;
    2252           0 :             sal_uInt32 crBack = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
    2253           0 :             if (COL_AUTO == crBack)
    2254             :             {
    2255           0 :                 uno::Reference<XAccessibleComponent> xComponent(this);
    2256           0 :                 if (xComponent.is())
    2257             :                 {
    2258           0 :                     crBack = (sal_uInt32)xComponent->getBackground();
    2259             :                 }
    2260           0 :                 rValue.Value <<= crBack;
    2261             :             }
    2262           0 :             continue;
    2263             :         }
    2264             : 
    2265             :         //char color
    2266           0 :         if (rValue.Name == UNO_NAME_CHAR_COLOR)
    2267             :         {
    2268           0 :             if( GetPortionData().IsInGrayPortion( nIndex ) )
    2269           0 :                  rValue.Value <<= SwViewOption::GetFieldShadingsColor().GetColor();
    2270           0 :             uno::Any &anyChar = rValue.Value;
    2271           0 :             sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
    2272             : 
    2273           0 :             if( COL_AUTO == crChar )
    2274             :             {
    2275           0 :                 uno::Reference<XAccessibleComponent> xComponent(this);
    2276           0 :                 if (xComponent.is())
    2277             :                 {
    2278           0 :                     Color cr(xComponent->getBackground());
    2279           0 :                     crChar = cr.IsDark() ? COL_WHITE : COL_BLACK;
    2280           0 :                     rValue.Value <<= crChar;
    2281           0 :                 }
    2282             :             }
    2283           0 :             continue;
    2284             :         }
    2285             : 
    2286             :         // UnderLine
    2287           0 :         if (rValue.Name == UNO_NAME_CHAR_UNDERLINE)
    2288             :         {
    2289             :             //misspelled word
    2290           0 :             SwCrsrShell* pCrsrShell = GetCrsrShell();
    2291           0 :             if( pCrsrShell != NULL && pCrsrShell->GetViewOptions() && pCrsrShell->GetViewOptions()->IsOnlineSpell())
    2292             :             {
    2293           0 :                 const SwWrongList* pWrongList = pTextNode->GetWrong();
    2294           0 :                 if( NULL != pWrongList )
    2295             :                 {
    2296           0 :                     sal_Int32 nBegin = nIndex;
    2297           0 :                     sal_Int32 nLen = 1;
    2298           0 :                     if( pWrongList->InWrongWord(nBegin,nLen) && !pTextNode->IsSymbol(nBegin) )
    2299             :                     {
    2300           0 :                         rValue.Value <<= (sal_uInt16)UNDERLINE_WAVE;
    2301             :                     }
    2302             :                 }
    2303             :             }
    2304           0 :             continue;
    2305             :         }
    2306             : 
    2307             :         // UnderLineColor
    2308           0 :         if (rValue.Name == UNO_NAME_CHAR_UNDERLINE_COLOR)
    2309             :         {
    2310             :             //misspelled word
    2311           0 :             SwCrsrShell* pCrsrShell = GetCrsrShell();
    2312           0 :             if( pCrsrShell != NULL && pCrsrShell->GetViewOptions() && pCrsrShell->GetViewOptions()->IsOnlineSpell())
    2313             :             {
    2314           0 :                 const SwWrongList* pWrongList = pTextNode->GetWrong();
    2315           0 :                 if( NULL != pWrongList )
    2316             :                 {
    2317           0 :                     sal_Int32 nBegin = nIndex;
    2318           0 :                     sal_Int32 nLen = 1;
    2319           0 :                     if( pWrongList->InWrongWord(nBegin,nLen) && !pTextNode->IsSymbol(nBegin) )
    2320             :                     {
    2321           0 :                         rValue.Value <<= (sal_Int32)0x00ff0000;
    2322           0 :                         continue;
    2323             :                     }
    2324             :                 }
    2325             :             }
    2326             : 
    2327           0 :             uno::Any &anyChar = rValue.Value;
    2328           0 :             sal_uInt32 crUnderline = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
    2329           0 :             if ( COL_AUTO == crUnderline )
    2330             :             {
    2331           0 :                 uno::Reference<XAccessibleComponent> xComponent(this);
    2332           0 :                 if (xComponent.is())
    2333             :                 {
    2334           0 :                     Color cr(xComponent->getBackground());
    2335           0 :                     crUnderline = cr.IsDark() ? COL_WHITE : COL_BLACK;
    2336           0 :                     rValue.Value <<= crUnderline;
    2337           0 :                 }
    2338             :             }
    2339             : 
    2340           0 :             continue;
    2341             :         }
    2342             : 
    2343             :         //tab stop
    2344           0 :         if (rValue.Name == UNO_NAME_TABSTOPS)
    2345             :         {
    2346           0 :             com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs = GetCurrentTabStop( nIndex );
    2347           0 :             if( !tabs.hasElements() )
    2348             :             {
    2349           0 :                 tabs.realloc(1);
    2350           0 :                 ::com::sun::star::style::TabStop ts;
    2351           0 :                 com::sun::star::awt::Rectangle rc0 = getCharacterBounds(0);
    2352           0 :                 com::sun::star::awt::Rectangle rc1 = getCharacterBounds(nIndex);
    2353           0 :                 if( rc1.X - rc0.X >= 48 )
    2354           0 :                     ts.Position = (rc1.X - rc0.X) - (rc1.X - rc0.X - 48)% 47 + 47;
    2355             :                 else
    2356           0 :                     ts.Position = 48;
    2357           0 :                 ts.DecimalChar = ' ';
    2358           0 :                 ts.FillChar = ' ';
    2359           0 :                 ts.Alignment = ::com::sun::star::style::TabAlign_LEFT;
    2360           0 :                 tabs[0] = ts;
    2361             :             }
    2362           0 :             rValue.Value <<= tabs;
    2363           0 :             continue;
    2364             :         }
    2365             : 
    2366             :         //number bullet
    2367           0 :         if (rValue.Name == UNO_NAME_NUMBERING_RULES)
    2368             :         {
    2369           0 :             if ( pTextNode->HasBullet() || pTextNode->HasNumber() )
    2370             :             {
    2371           0 :                 uno::Any aVal;
    2372           0 :                 SwNumRule* pNumRule = pTextNode->GetNumRule();
    2373           0 :                 if (pNumRule)
    2374             :                 {
    2375           0 :                     uno::Reference< container::XIndexReplace >  xNum = new SwXNumberingRules(*pNumRule);
    2376           0 :                     aVal.setValue(&xNum, cppu::UnoType<container::XIndexReplace>::get());
    2377             :                 }
    2378           0 :                 rValue.Value <<= aVal;
    2379             :             }
    2380           0 :             continue;
    2381             :         }
    2382             : 
    2383             :         //footnote & endnote
    2384           0 :         if (rValue.Name == UNO_NAME_CHAR_ESCAPEMENT)
    2385             :         {
    2386           0 :             if ( GetPortionData().IsIndexInFootnode(nIndex) )
    2387             :             {
    2388           0 :                 rValue.Value <<= (sal_Int32)101;
    2389             :             }
    2390           0 :             continue;
    2391             :         }
    2392           0 :     }
    2393           0 : }
    2394             : 
    2395           0 : awt::Rectangle SwAccessibleParagraph::getCharacterBounds(
    2396             :     sal_Int32 nIndex )
    2397             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2398             : {
    2399           0 :     SolarMutexGuard aGuard;
    2400             : 
    2401           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2402             : 
    2403             :     // #i12332# The position after the string needs special treatment.
    2404             :     // IsValidChar -> IsValidPosition
    2405           0 :     if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
    2406           0 :         throw lang::IndexOutOfBoundsException();
    2407             : 
    2408             :     // #i12332#
    2409           0 :     bool bBehindText = false;
    2410           0 :     if ( nIndex == GetString().getLength() )
    2411           0 :         bBehindText = true;
    2412             : 
    2413             :     // get model position & prepare GetCharRect() arguments
    2414           0 :     SwCrsrMoveState aMoveState;
    2415           0 :     aMoveState.bRealHeight = true;
    2416           0 :     aMoveState.bRealWidth = true;
    2417           0 :     SwSpecialPos aSpecialPos;
    2418           0 :     SwTextNode* pNode = const_cast<SwTextNode*>( GetTextNode() );
    2419             : 
    2420             :     /**  #i12332# FillSpecialPos does not accept nIndex ==
    2421             :          GetString().getLength(). In that case nPos is set to the
    2422             :          length of the string in the core. This way GetCharRect
    2423             :          returns the rectangle for a cursor at the end of the
    2424             :          paragraph. */
    2425             :     const sal_Int32 nPos = bBehindText
    2426           0 :         ? pNode->GetText().getLength()
    2427           0 :         : GetPortionData().FillSpecialPos(nIndex, aSpecialPos, aMoveState.pSpecialPos );
    2428             : 
    2429             :     // call GetCharRect
    2430           0 :     SwRect aCoreRect;
    2431           0 :     SwIndex aIndex( pNode, nPos );
    2432           0 :     SwPosition aPosition( *pNode, aIndex );
    2433           0 :     GetFrm()->GetCharRect( aCoreRect, aPosition, &aMoveState );
    2434             : 
    2435             :     // translate core coordinates into accessibility coordinates
    2436           0 :     vcl::Window *pWin = GetWindow();
    2437           0 :     CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
    2438             : 
    2439           0 :     Rectangle aScreenRect( GetMap()->CoreToPixel( aCoreRect.SVRect() ));
    2440           0 :     SwRect aFrmLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
    2441             : 
    2442           0 :     Point aFrmPixPos( GetMap()->CoreToPixel( aFrmLogBounds.SVRect() ).TopLeft() );
    2443           0 :     aScreenRect.Move( -aFrmPixPos.getX(), -aFrmPixPos.getY() );
    2444             : 
    2445             :     // convert into AWT Rectangle
    2446             :     return awt::Rectangle(
    2447           0 :         aScreenRect.Left(), aScreenRect.Top(),
    2448           0 :         aScreenRect.GetWidth(), aScreenRect.GetHeight() );
    2449             : }
    2450             : 
    2451           0 : sal_Int32 SwAccessibleParagraph::getCharacterCount()
    2452             :     throw (uno::RuntimeException, std::exception)
    2453             : {
    2454           0 :     SolarMutexGuard aGuard;
    2455             : 
    2456           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2457             : 
    2458           0 :     return GetString().getLength();
    2459             : }
    2460             : 
    2461           0 : sal_Int32 SwAccessibleParagraph::getIndexAtPoint( const awt::Point& rPoint )
    2462             :     throw (uno::RuntimeException, std::exception)
    2463             : {
    2464           0 :     SolarMutexGuard aGuard;
    2465             : 
    2466           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2467             : 
    2468             :     // construct SwPosition (where GetCrsrOfst() will put the result into)
    2469           0 :     SwTextNode* pNode = const_cast<SwTextNode*>( GetTextNode() );
    2470           0 :     SwIndex aIndex( pNode, 0);
    2471           0 :     SwPosition aPos( *pNode, aIndex );
    2472             : 
    2473             :     // construct Point (translate into layout coordinates)
    2474           0 :     vcl::Window *pWin = GetWindow();
    2475           0 :     CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
    2476           0 :     Point aPoint( rPoint.X, rPoint.Y );
    2477           0 :     SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
    2478           0 :     Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() );
    2479           0 :     aPoint.setX(aPoint.getX() + aPixPos.getX());
    2480           0 :     aPoint.setY(aPoint.getY() + aPixPos.getY());
    2481           0 :     MapMode aMapMode = pWin->GetMapMode();
    2482           0 :     Point aCorePoint( GetMap()->PixelToCore( aPoint ) );
    2483           0 :     if( !aLogBounds.IsInside( aCorePoint ) )
    2484             :     {
    2485             :         // #i12332# rPoint is may also be in rectangle returned by
    2486             :         // getCharacterBounds(getCharacterCount()
    2487             : 
    2488             :         awt::Rectangle aRectEndPos =
    2489           0 :             getCharacterBounds(getCharacterCount());
    2490             : 
    2491           0 :         if (rPoint.X - aRectEndPos.X >= 0 &&
    2492           0 :             rPoint.X - aRectEndPos.X < aRectEndPos.Width &&
    2493           0 :             rPoint.Y - aRectEndPos.Y >= 0 &&
    2494           0 :             rPoint.Y - aRectEndPos.Y < aRectEndPos.Height)
    2495           0 :             return getCharacterCount();
    2496             : 
    2497           0 :         return -1;
    2498             :     }
    2499             : 
    2500             :     // ask core for position
    2501             :     OSL_ENSURE( GetFrm() != NULL, "The text frame has vanished!" );
    2502             :     OSL_ENSURE( GetFrm()->IsTextFrm(), "The text frame has mutated!" );
    2503           0 :     const SwTextFrm* pFrm = static_cast<const SwTextFrm*>( GetFrm() );
    2504           0 :     SwCrsrMoveState aMoveState;
    2505           0 :     aMoveState.bPosMatchesBounds = true;
    2506           0 :     const bool bSuccess = pFrm->GetCrsrOfst( &aPos, aCorePoint, &aMoveState );
    2507             : 
    2508           0 :     SwIndex aContentIdx = aPos.nContent;
    2509           0 :     const sal_Int32 nIndex = aContentIdx.GetIndex();
    2510           0 :     if ( nIndex > 0 )
    2511             :     {
    2512           0 :         SwRect aResultRect;
    2513           0 :         pFrm->GetCharRect( aResultRect, aPos );
    2514           0 :         bool bVert = pFrm->IsVertical();
    2515           0 :         bool bR2L = pFrm->IsRightToLeft();
    2516             : 
    2517           0 :         if ( (!bVert && aResultRect.Pos().getX() > aCorePoint.getX()) ||
    2518           0 :              ( bVert && aResultRect.Pos().getY() > aCorePoint.getY()) ||
    2519           0 :              ( bR2L  && aResultRect.Right()   < aCorePoint.getX()) )
    2520             :         {
    2521           0 :             SwIndex aIdxPrev( pNode, nIndex - 1);
    2522           0 :             SwPosition aPosPrev( *pNode, aIdxPrev );
    2523           0 :             SwRect aResultRectPrev;
    2524           0 :             pFrm->GetCharRect( aResultRectPrev, aPosPrev );
    2525           0 :             if ( (!bVert && aResultRectPrev.Pos().getX() < aCorePoint.getX() && aResultRect.Pos().getY() == aResultRectPrev.Pos().getY()) ||
    2526           0 :                  ( bVert && aResultRectPrev.Pos().getY() < aCorePoint.getY() && aResultRect.Pos().getX() == aResultRectPrev.Pos().getX()) ||
    2527           0 :                  (  bR2L && aResultRectPrev.Right()   > aCorePoint.getX() && aResultRect.Pos().getY() == aResultRectPrev.Pos().getY()) )
    2528           0 :                 aPos = aPosPrev;
    2529             :         }
    2530             :     }
    2531             : 
    2532             :     return bSuccess ?
    2533           0 :         GetPortionData().GetAccessiblePosition( aPos.nContent.GetIndex() )
    2534           0 :         : -1L;
    2535             : }
    2536             : 
    2537           0 : OUString SwAccessibleParagraph::getSelectedText()
    2538             :     throw (uno::RuntimeException, std::exception)
    2539             : {
    2540           0 :     SolarMutexGuard aGuard;
    2541             : 
    2542           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2543             : 
    2544             :     sal_Int32 nStart, nEnd;
    2545           0 :     bool bSelected = GetSelection( nStart, nEnd );
    2546             :     return bSelected
    2547             :            ? GetString().copy( nStart, nEnd - nStart )
    2548           0 :            : OUString();
    2549             : }
    2550             : 
    2551           0 : sal_Int32 SwAccessibleParagraph::getSelectionStart()
    2552             :     throw (uno::RuntimeException, std::exception)
    2553             : {
    2554           0 :     SolarMutexGuard aGuard;
    2555             : 
    2556           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2557             : 
    2558             :     sal_Int32 nStart, nEnd;
    2559           0 :     GetSelection( nStart, nEnd );
    2560           0 :     return nStart;
    2561             : }
    2562             : 
    2563           0 : sal_Int32 SwAccessibleParagraph::getSelectionEnd()
    2564             :     throw (uno::RuntimeException, std::exception)
    2565             : {
    2566           0 :     SolarMutexGuard aGuard;
    2567             : 
    2568           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2569             : 
    2570             :     sal_Int32 nStart, nEnd;
    2571           0 :     GetSelection( nStart, nEnd );
    2572           0 :     return nEnd;
    2573             : }
    2574             : 
    2575           0 : sal_Bool SwAccessibleParagraph::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
    2576             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2577             : {
    2578           0 :     SolarMutexGuard aGuard;
    2579             : 
    2580           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2581             : 
    2582             :     // parameter checking
    2583           0 :     sal_Int32 nLength = GetString().getLength();
    2584           0 :     if ( ! IsValidRange( nStartIndex, nEndIndex, nLength ) )
    2585             :     {
    2586           0 :         throw lang::IndexOutOfBoundsException();
    2587             :     }
    2588             : 
    2589           0 :     bool bRet = false;
    2590             : 
    2591             :     // get cursor shell
    2592           0 :     SwCrsrShell* pCrsrShell = GetCrsrShell();
    2593           0 :     if( pCrsrShell != NULL )
    2594             :     {
    2595             :         // create pam for selection
    2596           0 :         SwTextNode* pNode = const_cast<SwTextNode*>( GetTextNode() );
    2597           0 :         SwIndex aIndex( pNode, GetPortionData().GetModelPosition(nStartIndex));
    2598           0 :         SwPosition aStartPos( *pNode, aIndex );
    2599           0 :         SwPaM aPaM( aStartPos );
    2600           0 :         aPaM.SetMark();
    2601           0 :         aPaM.GetPoint()->nContent =
    2602           0 :             GetPortionData().GetModelPosition(nEndIndex);
    2603             : 
    2604             :         // set PaM at cursor shell
    2605           0 :         bRet = Select( aPaM );
    2606             :     }
    2607             : 
    2608           0 :     return bRet;
    2609             : }
    2610             : 
    2611           6 : OUString SwAccessibleParagraph::getText()
    2612             :     throw (uno::RuntimeException, std::exception)
    2613             : {
    2614           6 :     SolarMutexGuard aGuard;
    2615             : 
    2616           6 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2617             : 
    2618           6 :     return GetString();
    2619             : }
    2620             : 
    2621           0 : OUString SwAccessibleParagraph::getTextRange(
    2622             :     sal_Int32 nStartIndex, sal_Int32 nEndIndex )
    2623             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2624             : {
    2625           0 :     SolarMutexGuard aGuard;
    2626             : 
    2627           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2628             : 
    2629           0 :     OUString sText( GetString() );
    2630             : 
    2631           0 :     if ( IsValidRange( nStartIndex, nEndIndex, sText.getLength() ) )
    2632             :     {
    2633           0 :         OrderRange( nStartIndex, nEndIndex );
    2634           0 :         return sText.copy(nStartIndex, nEndIndex-nStartIndex );
    2635             :     }
    2636             :     else
    2637           0 :         throw lang::IndexOutOfBoundsException();
    2638             : }
    2639             : 
    2640           0 : /*accessibility::*/TextSegment SwAccessibleParagraph::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    2641             : {
    2642           0 :     SolarMutexGuard aGuard;
    2643             : 
    2644           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2645             : 
    2646           0 :     /*accessibility::*/TextSegment aResult;
    2647           0 :     aResult.SegmentStart = -1;
    2648           0 :     aResult.SegmentEnd = -1;
    2649             : 
    2650           0 :     const OUString rText = GetString();
    2651             :     // implement the silly specification that first position after
    2652             :     // text must return an empty string, rather than throwing an
    2653             :     // IndexOutOfBoundsException, except for LINE, where the last
    2654             :     // line is returned
    2655           0 :     if( nIndex == rText.getLength() && AccessibleTextType::LINE != nTextType )
    2656           0 :         return aResult;
    2657             : 
    2658             :     // with error checking
    2659           0 :     i18n::Boundary aBound;
    2660           0 :     bool bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
    2661             : 
    2662             :     OSL_ENSURE( aBound.startPos >= 0,               "illegal boundary" );
    2663             :     OSL_ENSURE( aBound.startPos <= aBound.endPos,   "illegal boundary" );
    2664             : 
    2665             :     // return word (if present)
    2666           0 :     if ( bWord )
    2667             :     {
    2668           0 :         aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
    2669           0 :         aResult.SegmentStart = aBound.startPos;
    2670           0 :         aResult.SegmentEnd = aBound.endPos;
    2671             :     }
    2672             : 
    2673           0 :     return aResult;
    2674             : }
    2675             : 
    2676           0 : /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    2677             : {
    2678           0 :     SolarMutexGuard aGuard;
    2679             : 
    2680           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2681             : 
    2682           0 :     const OUString rText = GetString();
    2683             : 
    2684           0 :     /*accessibility::*/TextSegment aResult;
    2685           0 :     aResult.SegmentStart = -1;
    2686           0 :     aResult.SegmentEnd = -1;
    2687             :     //If nIndex = 0, then nobefore text so return -1 directly.
    2688           0 :     if( nIndex == 0 )
    2689           0 :             return aResult;
    2690             :     //Tab will be return when call WORDTYPE
    2691             : 
    2692             :     // get starting pos
    2693           0 :     i18n::Boundary aBound;
    2694           0 :     if (nIndex ==  rText.getLength())
    2695           0 :         aBound.startPos = aBound.endPos = nIndex;
    2696             :     else
    2697             :     {
    2698           0 :         bool bTmp = GetTextBoundary( aBound, rText, nIndex, nTextType );
    2699             : 
    2700           0 :         if ( ! bTmp )
    2701           0 :             aBound.startPos = aBound.endPos = nIndex;
    2702             :     }
    2703             : 
    2704             :     // now skip to previous word
    2705           0 :     if (nTextType==2 || nTextType == 3)
    2706             :     {
    2707           0 :         i18n::Boundary preBound = aBound;
    2708           0 :         while(preBound.startPos==aBound.startPos && nIndex > 0)
    2709             :         {
    2710           0 :             nIndex = min( nIndex, preBound.startPos ) - 1;
    2711           0 :             if( nIndex < 0 ) break;
    2712           0 :             GetTextBoundary( preBound, rText, nIndex, nTextType );
    2713             :         }
    2714             :         //if (nIndex>0)
    2715           0 :         if (nIndex>=0)
    2716             :         //Tab will be return when call WORDTYPE
    2717             :         {
    2718           0 :             aResult.SegmentText = rText.copy( preBound.startPos, preBound.endPos - preBound.startPos );
    2719           0 :             aResult.SegmentStart = preBound.startPos;
    2720           0 :             aResult.SegmentEnd = preBound.endPos;
    2721           0 :         }
    2722             :     }
    2723             :     else
    2724             :     {
    2725           0 :         bool bWord = false;
    2726           0 :         while( !bWord )
    2727             :         {
    2728           0 :             nIndex = min( nIndex, aBound.startPos ) - 1;
    2729           0 :             if( nIndex >= 0 )
    2730             :             {
    2731           0 :                 bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
    2732             :             }
    2733             :             else
    2734           0 :                 break;  // exit if beginning of string is reached
    2735             :         }
    2736             : 
    2737           0 :         if (bWord && nIndex<rText.getLength())
    2738             :         {
    2739           0 :             aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
    2740           0 :             aResult.SegmentStart = aBound.startPos;
    2741           0 :             aResult.SegmentEnd = aBound.endPos;
    2742             :         }
    2743             :     }
    2744           0 :     return aResult;
    2745             : }
    2746             : 
    2747           0 : /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    2748             : {
    2749           0 :     SolarMutexGuard aGuard;
    2750             : 
    2751           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2752             : 
    2753           0 :     /*accessibility::*/TextSegment aResult;
    2754           0 :     aResult.SegmentStart = -1;
    2755           0 :     aResult.SegmentEnd = -1;
    2756           0 :     const OUString rText = GetString();
    2757             : 
    2758             :     // implement the silly specification that first position after
    2759             :     // text must return an empty string, rather than throwing an
    2760             :     // IndexOutOfBoundsException
    2761           0 :     if( nIndex == rText.getLength() )
    2762           0 :         return aResult;
    2763             : 
    2764             :     // get first word, then skip to next word
    2765           0 :     i18n::Boundary aBound;
    2766           0 :     GetTextBoundary( aBound, rText, nIndex, nTextType );
    2767           0 :     bool bWord = false;
    2768           0 :     while( !bWord )
    2769             :     {
    2770           0 :         nIndex = max( sal_Int32(nIndex+1), aBound.endPos );
    2771           0 :         if( nIndex < rText.getLength() )
    2772           0 :             bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
    2773             :         else
    2774           0 :             break;  // exit if end of string is reached
    2775             :     }
    2776             : 
    2777           0 :     if ( bWord )
    2778             :     {
    2779           0 :         aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
    2780           0 :         aResult.SegmentStart = aBound.startPos;
    2781           0 :         aResult.SegmentEnd = aBound.endPos;
    2782             :     }
    2783             : 
    2784             : /*
    2785             :         sal_Bool bWord = sal_False;
    2786             :     bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
    2787             : 
    2788             :         if (nTextType==2)
    2789             :         {
    2790             :                 Boundary nexBound=aBound;
    2791             : 
    2792             :         // real current word
    2793             :         if( nIndex <= aBound.endPos && nIndex >= aBound.startPos )
    2794             :         {
    2795             :             while(nexBound.endPos==aBound.endPos&&nIndex<rText.getLength())
    2796             :             {
    2797             :                 // nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) + 1;
    2798             :                 nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) ;
    2799             :                 const sal_Unicode* pStr = rText.getStr();
    2800             :                 if (pStr)
    2801             :                 {
    2802             :                     if( pStr[nIndex] == sal_Unicode(' ') )
    2803             :                         nIndex++;
    2804             :                 }
    2805             :                 if( nIndex < rText.getLength() )
    2806             :                 {
    2807             :                     bWord = GetTextBoundary( nexBound, rText, nIndex, nTextType );
    2808             :                 }
    2809             :             }
    2810             :         }
    2811             : 
    2812             :         if (bWord && nIndex<rText.getLength())
    2813             :         {
    2814             :             aResult.SegmentText = rText.copy( nexBound.startPos, nexBound.endPos - nexBound.startPos );
    2815             :             aResult.SegmentStart = nexBound.startPos;
    2816             :             aResult.SegmentEnd = nexBound.endPos;
    2817             :         }
    2818             : 
    2819             :     }
    2820             :     else
    2821             :     {
    2822             :         bWord = sal_False;
    2823             :         while( !bWord )
    2824             :         {
    2825             :             nIndex = max( (sal_Int32)(nIndex+1), aBound.endPos );
    2826             :             if( nIndex < rText.getLength() )
    2827             :             {
    2828             :                 bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
    2829             :             }
    2830             :             else
    2831             :                 break;  // exit if end of string is reached
    2832             :         }
    2833             :         if (bWord && nIndex<rText.getLength())
    2834             :         {
    2835             :             aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
    2836             :             aResult.SegmentStart = aBound.startPos;
    2837             :             aResult.SegmentEnd = aBound.endPos;
    2838             :         }
    2839             :     }
    2840             : */
    2841           0 :     return aResult;
    2842             : }
    2843             : 
    2844           0 : sal_Bool SwAccessibleParagraph::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
    2845             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2846             : {
    2847           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    2848           0 :     SolarMutexGuard aGuard;
    2849             : 
    2850             :     // select and copy (through dispatch mechanism)
    2851           0 :     setSelection( nStartIndex, nEndIndex );
    2852           0 :     ExecuteAtViewShell( SID_COPY );
    2853           0 :     return sal_True;
    2854             : }
    2855             : 
    2856             : // XAccesibleEditableText
    2857             : 
    2858           0 : sal_Bool SwAccessibleParagraph::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
    2859             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2860             : {
    2861           0 :     CHECK_FOR_DEFUNC( XAccessibleEditableText );
    2862           0 :     SolarMutexGuard aGuard;
    2863             : 
    2864           0 :     if( !IsEditableState() )
    2865           0 :         return sal_False;
    2866             : 
    2867             :     // select and cut (through dispatch mechanism)
    2868           0 :     setSelection( nStartIndex, nEndIndex );
    2869           0 :     ExecuteAtViewShell( SID_CUT );
    2870           0 :     return sal_True;
    2871             : }
    2872             : 
    2873           0 : sal_Bool SwAccessibleParagraph::pasteText( sal_Int32 nIndex )
    2874             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2875             : {
    2876           0 :     CHECK_FOR_DEFUNC( XAccessibleEditableText );
    2877           0 :     SolarMutexGuard aGuard;
    2878             : 
    2879           0 :     if( !IsEditableState() )
    2880           0 :         return sal_False;
    2881             : 
    2882             :     // select and paste (through dispatch mechanism)
    2883           0 :     setSelection( nIndex, nIndex );
    2884           0 :     ExecuteAtViewShell( SID_PASTE );
    2885           0 :     return sal_True;
    2886             : }
    2887             : 
    2888           0 : sal_Bool SwAccessibleParagraph::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
    2889             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2890             : {
    2891           0 :     return replaceText( nStartIndex, nEndIndex, OUString() );
    2892             : }
    2893             : 
    2894           0 : sal_Bool SwAccessibleParagraph::insertText( const OUString& sText, sal_Int32 nIndex )
    2895             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2896             : {
    2897           0 :     return replaceText( nIndex, nIndex, sText );
    2898             : }
    2899             : 
    2900           0 : sal_Bool SwAccessibleParagraph::replaceText(
    2901             :     sal_Int32 nStartIndex, sal_Int32 nEndIndex,
    2902             :     const OUString& sReplacement )
    2903             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2904             : {
    2905           0 :     SolarMutexGuard aGuard;
    2906             : 
    2907           0 :     CHECK_FOR_DEFUNC( XAccessibleEditableText );
    2908             : 
    2909           0 :     const OUString& rText = GetString();
    2910             : 
    2911           0 :     if( IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
    2912             :     {
    2913           0 :         if( !IsEditableState() )
    2914           0 :             return sal_False;
    2915             : 
    2916           0 :         SwTextNode* pNode = const_cast<SwTextNode*>( GetTextNode() );
    2917             : 
    2918             :         // translate positions
    2919             :         sal_Int32 nStart;
    2920             :         sal_Int32 nEnd;
    2921           0 :         bool bSuccess = GetPortionData().GetEditableRange(
    2922           0 :                                         nStartIndex, nEndIndex, nStart, nEnd );
    2923             : 
    2924             :         // edit only if the range is editable
    2925           0 :         if( bSuccess )
    2926             :         {
    2927             :             // create SwPosition for nStartIndex
    2928           0 :             SwIndex aIndex( pNode, nStart );
    2929           0 :             SwPosition aStartPos( *pNode, aIndex );
    2930             : 
    2931             :             // create SwPosition for nEndIndex
    2932           0 :             SwPosition aEndPos( aStartPos );
    2933           0 :             aEndPos.nContent = nEnd;
    2934             : 
    2935             :             // now create XTextRange as helper and set string
    2936             :             const uno::Reference<text::XTextRange> xRange(
    2937             :                 SwXTextRange::CreateXTextRange(
    2938           0 :                     *pNode->GetDoc(), aStartPos, &aEndPos));
    2939           0 :             xRange->setString(sReplacement);
    2940             : 
    2941             :             // delete portion data
    2942           0 :             ClearPortionData();
    2943             :         }
    2944             : 
    2945           0 :         return bSuccess;
    2946             :     }
    2947             :     else
    2948           0 :         throw lang::IndexOutOfBoundsException();
    2949             : }
    2950             : 
    2951           0 : sal_Bool SwAccessibleParagraph::setAttributes(
    2952             :     sal_Int32 nStartIndex,
    2953             :     sal_Int32 nEndIndex,
    2954             :     const uno::Sequence<PropertyValue>& rAttributeSet )
    2955             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    2956             : {
    2957           0 :     SolarMutexGuard aGuard;
    2958           0 :     CHECK_FOR_DEFUNC( XAccessibleEditableText );
    2959             : 
    2960           0 :     const OUString& rText = GetString();
    2961             : 
    2962           0 :     if( ! IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
    2963           0 :         throw lang::IndexOutOfBoundsException();
    2964             : 
    2965           0 :     if( !IsEditableState() )
    2966           0 :         return sal_False;
    2967             : 
    2968             :     // create a (dummy) text portion for the sole purpose of calling
    2969             :     // setPropertyValue on it
    2970             :     uno::Reference<XMultiPropertySet> xPortion = CreateUnoPortion( nStartIndex,
    2971           0 :                                                               nEndIndex );
    2972             : 
    2973             :     // build sorted index array
    2974           0 :     sal_Int32 nLength = rAttributeSet.getLength();
    2975           0 :     const PropertyValue* pPairs = rAttributeSet.getConstArray();
    2976           0 :     sal_Int32* pIndices = new sal_Int32[nLength];
    2977             :     sal_Int32 i;
    2978           0 :     for( i = 0; i < nLength; i++ )
    2979           0 :         pIndices[i] = i;
    2980           0 :     sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
    2981             : 
    2982             :     // create sorted sequences according to index array
    2983           0 :     uno::Sequence< OUString > aNames( nLength );
    2984           0 :     OUString* pNames = aNames.getArray();
    2985           0 :     uno::Sequence< uno::Any > aValues( nLength );
    2986           0 :     uno::Any* pValues = aValues.getArray();
    2987           0 :     for( i = 0; i < nLength; i++ )
    2988             :     {
    2989           0 :         const PropertyValue& rVal = pPairs[pIndices[i]];
    2990           0 :         pNames[i]  = rVal.Name;
    2991           0 :         pValues[i] = rVal.Value;
    2992             :     }
    2993           0 :     delete[] pIndices;
    2994             : 
    2995             :     // now set the values
    2996           0 :     bool bRet = true;
    2997             :     try
    2998             :     {
    2999           0 :         xPortion->setPropertyValues( aNames, aValues );
    3000             :     }
    3001           0 :     catch (const UnknownPropertyException&)
    3002             :     {
    3003             :         // error handling through return code!
    3004           0 :         bRet = false;
    3005             :     }
    3006             : 
    3007           0 :     return bRet;
    3008             : }
    3009             : 
    3010           0 : sal_Bool SwAccessibleParagraph::setText( const OUString& sText )
    3011             :     throw (uno::RuntimeException, std::exception)
    3012             : {
    3013           0 :     return replaceText(0, GetString().getLength(), sText);
    3014             : }
    3015             : 
    3016             : // XAccessibleSelection
    3017             : 
    3018           2 : void SwAccessibleParagraph::selectAccessibleChild(
    3019             :     sal_Int32 nChildIndex )
    3020             :     throw ( lang::IndexOutOfBoundsException,
    3021             :             uno::RuntimeException, std::exception )
    3022             : {
    3023           2 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3024             : 
    3025           2 :     aSelectionHelper.selectAccessibleChild(nChildIndex);
    3026           0 : }
    3027             : 
    3028           2 : sal_Bool SwAccessibleParagraph::isAccessibleChildSelected(
    3029             :     sal_Int32 nChildIndex )
    3030             :     throw ( lang::IndexOutOfBoundsException,
    3031             :             uno::RuntimeException, std::exception )
    3032             : {
    3033           2 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3034             : 
    3035           2 :     return aSelectionHelper.isAccessibleChildSelected(nChildIndex);
    3036             : }
    3037             : 
    3038           2 : void SwAccessibleParagraph::clearAccessibleSelection(  )
    3039             :     throw ( uno::RuntimeException, std::exception )
    3040             : {
    3041           2 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3042           2 : }
    3043             : 
    3044           3 : void SwAccessibleParagraph::selectAllAccessibleChildren(  )
    3045             :     throw ( uno::RuntimeException, std::exception )
    3046             : {
    3047           3 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3048             : 
    3049           3 :     aSelectionHelper.selectAllAccessibleChildren();
    3050           3 : }
    3051             : 
    3052           5 : sal_Int32 SwAccessibleParagraph::getSelectedAccessibleChildCount(  )
    3053             :     throw ( uno::RuntimeException, std::exception )
    3054             : {
    3055           5 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3056             : 
    3057           5 :     return aSelectionHelper.getSelectedAccessibleChildCount();
    3058             : }
    3059             : 
    3060           2 : uno::Reference<XAccessible> SwAccessibleParagraph::getSelectedAccessibleChild(
    3061             :     sal_Int32 nSelectedChildIndex )
    3062             :     throw ( lang::IndexOutOfBoundsException,
    3063             :             uno::RuntimeException, std::exception)
    3064             : {
    3065           2 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3066             : 
    3067           2 :     return aSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
    3068             : }
    3069             : 
    3070             : // index has to be treated as global child index.
    3071           2 : void SwAccessibleParagraph::deselectAccessibleChild(
    3072             :     sal_Int32 nChildIndex )
    3073             :     throw ( lang::IndexOutOfBoundsException,
    3074             :             uno::RuntimeException, std::exception )
    3075             : {
    3076           2 :     CHECK_FOR_DEFUNC( XAccessibleSelection );
    3077             : 
    3078           2 :     aSelectionHelper.deselectAccessibleChild( nChildIndex );
    3079           0 : }
    3080             : 
    3081             : // XAccessibleHypertext
    3082             : 
    3083             : class SwHyperlinkIter_Impl
    3084             : {
    3085             :     const SwpHints *pHints;
    3086             :     sal_Int32 nStt;
    3087             :     sal_Int32 nEnd;
    3088             :     size_t nPos;
    3089             : 
    3090             : public:
    3091             :     explicit SwHyperlinkIter_Impl( const SwTextFrm *pTextFrm );
    3092             :     const SwTextAttr *next();
    3093           0 :     size_t getCurrHintPos() const { return nPos-1; }
    3094             : 
    3095           0 :     sal_Int32 startIdx() const { return nStt; }
    3096           0 :     sal_Int32 endIdx() const { return nEnd; }
    3097             : };
    3098             : 
    3099           0 : SwHyperlinkIter_Impl::SwHyperlinkIter_Impl( const SwTextFrm *pTextFrm ) :
    3100           0 :     pHints( pTextFrm->GetTextNode()->GetpSwpHints() ),
    3101           0 :     nStt( pTextFrm->GetOfst() ),
    3102           0 :     nPos( 0 )
    3103             : {
    3104           0 :     const SwTextFrm *pFollFrm = pTextFrm->GetFollow();
    3105           0 :     nEnd = pFollFrm ? pFollFrm->GetOfst() : pTextFrm->GetTextNode()->Len();
    3106           0 : }
    3107             : 
    3108           0 : const SwTextAttr *SwHyperlinkIter_Impl::next()
    3109             : {
    3110           0 :     const SwTextAttr *pAttr = 0;
    3111           0 :     if( pHints )
    3112             :     {
    3113           0 :         while( !pAttr && nPos < pHints->Count() )
    3114             :         {
    3115           0 :             const SwTextAttr *pHt = (*pHints)[nPos];
    3116           0 :             if( RES_TXTATR_INETFMT == pHt->Which() )
    3117             :             {
    3118           0 :                 const sal_Int32 nHtStt = pHt->GetStart();
    3119           0 :                 const sal_Int32 nHtEnd = *pHt->GetAnyEnd();
    3120           0 :                 if( nHtEnd > nHtStt &&
    3121           0 :                     ( (nHtStt >= nStt && nHtStt < nEnd) ||
    3122           0 :                       (nHtEnd > nStt && nHtEnd <= nEnd) ) )
    3123             :                 {
    3124           0 :                     pAttr = pHt;
    3125             :                 }
    3126             :             }
    3127           0 :             ++nPos;
    3128             :         }
    3129             :     }
    3130             : 
    3131           0 :     return pAttr;
    3132             : };
    3133             : 
    3134           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getHyperLinkCount()
    3135             :     throw (uno::RuntimeException, std::exception)
    3136             : {
    3137           0 :     SolarMutexGuard aGuard;
    3138             : 
    3139           0 :     CHECK_FOR_DEFUNC( XAccessibleHypertext );
    3140             : 
    3141           0 :     sal_Int32 nCount = 0;
    3142             :     // #i77108# - provide hyperlinks also in editable documents.
    3143             : 
    3144           0 :     const SwTextFrm *pTextFrm = static_cast<const SwTextFrm*>( GetFrm() );
    3145           0 :     SwHyperlinkIter_Impl aIter( pTextFrm );
    3146           0 :     while( aIter.next() )
    3147           0 :         nCount++;
    3148             : 
    3149           0 :     return nCount;
    3150             : }
    3151             : 
    3152             : uno::Reference< XAccessibleHyperlink > SAL_CALL
    3153           0 :     SwAccessibleParagraph::getHyperLink( sal_Int32 nLinkIndex )
    3154             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    3155             : {
    3156           0 :     SolarMutexGuard aGuard;
    3157           0 :     CHECK_FOR_DEFUNC( XAccessibleHypertext );
    3158             : 
    3159           0 :     uno::Reference< XAccessibleHyperlink > xRet;
    3160             : 
    3161           0 :     const SwTextFrm *pTextFrm = static_cast<const SwTextFrm*>( GetFrm() );
    3162           0 :     SwHyperlinkIter_Impl aHIter( pTextFrm );
    3163           0 :     sal_Int32 nTIndex = -1;
    3164           0 :     SwTOXSortTabBase* pTBase = GetTOXSortTabBase();
    3165           0 :     SwTextAttr* pHt = const_cast<SwTextAttr*>(aHIter.next());
    3166           0 :     while( (nLinkIndex < getHyperLinkCount()) && nTIndex < nLinkIndex)
    3167             :     {
    3168           0 :         sal_Int32 nHStt = -1;
    3169           0 :         bool bH = false;
    3170             : 
    3171           0 :         if( pHt )
    3172           0 :             nHStt = pHt->GetStart();
    3173           0 :         bool bTOC = false;
    3174             :         // Inside TOC & get the first link
    3175           0 :         if( pTBase && nTIndex == -1 )
    3176             :         {
    3177           0 :             nTIndex++;
    3178           0 :             bTOC = true;
    3179             :         }
    3180           0 :         else if( nHStt >= 0 )
    3181             :         {
    3182             :               // only hyperlink available
    3183           0 :             nTIndex++;
    3184           0 :             bH = true;
    3185             :         }
    3186             : 
    3187           0 :         if( nTIndex == nLinkIndex )
    3188             :         {   // found
    3189           0 :             if( bH )
    3190             :             {   // it's a hyperlink
    3191           0 :                 if( pHt )
    3192             :                 {
    3193           0 :                     if( !pHyperTextData )
    3194           0 :                         pHyperTextData = new SwAccessibleHyperTextData;
    3195             :                     SwAccessibleHyperTextData::iterator aIter =
    3196           0 :                         pHyperTextData ->find( pHt );
    3197           0 :                     if( aIter != pHyperTextData->end() )
    3198             :                     {
    3199           0 :                         xRet = (*aIter).second;
    3200             :                     }
    3201           0 :                     if( !xRet.is() )
    3202             :                     {
    3203             :                         {
    3204           0 :                             const sal_Int32 nTmpHStt= GetPortionData().GetAccessiblePosition(
    3205           0 :                                 max( aHIter.startIdx(), pHt->GetStart() ) );
    3206           0 :                             const sal_Int32 nTmpHEnd= GetPortionData().GetAccessiblePosition(
    3207           0 :                                 min( aHIter.endIdx(), *pHt->GetAnyEnd() ) );
    3208           0 :                             xRet = new SwAccessibleHyperlink( aHIter.getCurrHintPos(),
    3209           0 :                                 this, nTmpHStt, nTmpHEnd );
    3210             :                         }
    3211           0 :                         if( aIter != pHyperTextData->end() )
    3212             :                         {
    3213           0 :                             (*aIter).second = xRet;
    3214             :                         }
    3215             :                         else
    3216             :                         {
    3217           0 :                             SwAccessibleHyperTextData::value_type aEntry( pHt, xRet );
    3218           0 :                             pHyperTextData->insert( aEntry );
    3219             :                         }
    3220             :                     }
    3221             :                 }
    3222             :             }
    3223           0 :             break;
    3224             :         }
    3225             : 
    3226             :         // iterate next
    3227           0 :         if( bH )
    3228             :             // iterate next hyperlink
    3229           0 :             pHt = const_cast<SwTextAttr*>(aHIter.next());
    3230           0 :         else if(bTOC)
    3231           0 :             continue;
    3232             :         else
    3233             :             // no candidate, exit
    3234           0 :             break;
    3235             :     }
    3236           0 :     if( !xRet.is() )
    3237           0 :         throw lang::IndexOutOfBoundsException();
    3238             : 
    3239           0 :     return xRet;
    3240             : }
    3241             : 
    3242           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getHyperLinkIndex( sal_Int32 nCharIndex )
    3243             :     throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
    3244             : {
    3245           0 :     SolarMutexGuard aGuard;
    3246           0 :     CHECK_FOR_DEFUNC( XAccessibleHypertext );
    3247             : 
    3248             :     // parameter checking
    3249           0 :     sal_Int32 nLength = GetString().getLength();
    3250           0 :     if ( ! IsValidPosition( nCharIndex, nLength ) )
    3251             :     {
    3252           0 :         throw lang::IndexOutOfBoundsException();
    3253             :     }
    3254             : 
    3255           0 :     sal_Int32 nRet = -1;
    3256             :     // #i77108#
    3257             :     {
    3258           0 :         const SwTextFrm *pTextFrm = static_cast<const SwTextFrm*>( GetFrm() );
    3259           0 :         SwHyperlinkIter_Impl aHIter( pTextFrm );
    3260             : 
    3261           0 :         const sal_Int32 nIdx = GetPortionData().GetModelPosition( nCharIndex );
    3262           0 :         sal_Int32 nPos = 0;
    3263           0 :         const SwTextAttr *pHt = aHIter.next();
    3264           0 :         while( pHt && !(nIdx >= pHt->GetStart() && nIdx < *pHt->GetAnyEnd()) )
    3265             :         {
    3266           0 :             pHt = aHIter.next();
    3267           0 :             nPos++;
    3268             :         }
    3269             : 
    3270           0 :         if( pHt )
    3271           0 :             nRet = nPos;
    3272             :     }
    3273             : 
    3274           0 :     if (nRet == -1)
    3275           0 :         throw lang::IndexOutOfBoundsException();
    3276             :     else
    3277           0 :         return nRet;
    3278             :     //return nRet;
    3279             : }
    3280             : 
    3281             : // #i71360#, #i108125# - adjustments for change tracking text markup
    3282           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getTextMarkupCount( sal_Int32 nTextMarkupType )
    3283             :                                         throw (lang::IllegalArgumentException,
    3284             :                                                uno::RuntimeException, std::exception)
    3285             : {
    3286           0 :     boost::scoped_ptr<SwTextMarkupHelper> pTextMarkupHelper;
    3287           0 :     switch ( nTextMarkupType )
    3288             :     {
    3289             :         case text::TextMarkupType::TRACK_CHANGE_INSERTION:
    3290             :         case text::TextMarkupType::TRACK_CHANGE_DELETION:
    3291             :         case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
    3292             :         {
    3293             :             pTextMarkupHelper.reset( new SwTextMarkupHelper(
    3294             :                 GetPortionData(),
    3295           0 :                 *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
    3296             :         }
    3297           0 :         break;
    3298             :         default:
    3299             :         {
    3300           0 :             pTextMarkupHelper.reset( new SwTextMarkupHelper( GetPortionData(), *GetTextNode() ) );
    3301             :         }
    3302             :     }
    3303             : 
    3304           0 :     return pTextMarkupHelper->getTextMarkupCount( nTextMarkupType );
    3305             : }
    3306             : 
    3307             : //MSAA Extension Implementation in app  module
    3308           0 : sal_Bool SAL_CALL SwAccessibleParagraph::scrollToPosition( const ::com::sun::star::awt::Point&, sal_Bool )
    3309             :     throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
    3310             : {
    3311           0 :     return sal_False;
    3312             : }
    3313             : 
    3314           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getSelectedPortionCount(  )
    3315             :     throw (::com::sun::star::uno::RuntimeException,
    3316             :            std::exception)
    3317             : {
    3318           0 :     SolarMutexGuard g;
    3319             : 
    3320           0 :     sal_Int32 nSeleted = 0;
    3321           0 :     SwPaM* pCrsr = GetCursor( true );
    3322           0 :     if( pCrsr != NULL )
    3323             :     {
    3324             :         // get SwPosition for my node
    3325           0 :         const SwTextNode* pNode = GetTextNode();
    3326           0 :         sal_uLong nHere = pNode->GetIndex();
    3327             : 
    3328             :         // iterate over ring
    3329           0 :         for(SwPaM& rTmpCrsr : pCrsr->GetRingContainer())
    3330             :         {
    3331             :             // ignore, if no mark
    3332           0 :             if( rTmpCrsr.HasMark() )
    3333             :             {
    3334             :                 // check whether nHere is 'inside' pCrsr
    3335           0 :                 SwPosition* pStart = rTmpCrsr.Start();
    3336           0 :                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
    3337           0 :                 SwPosition* pEnd = rTmpCrsr.End();
    3338           0 :                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
    3339           0 :                 if( ( nHere >= nStartIndex ) &&
    3340             :                     ( nHere <= nEndIndex )      )
    3341             :                 {
    3342           0 :                     nSeleted++;
    3343             :                 }
    3344             :                 // else: this PaM doesn't point to this paragraph
    3345             :             }
    3346             :             // else: this PaM is collapsed and doesn't select anything
    3347             :         }
    3348             :     }
    3349           0 :     return nSeleted;
    3350             : 
    3351             : }
    3352             : 
    3353           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionStart( sal_Int32 nSelectedPortionIndex )
    3354             :     throw (::com::sun::star::lang::IndexOutOfBoundsException,
    3355             :            ::com::sun::star::uno::RuntimeException,
    3356             :            std::exception)
    3357             : {
    3358           0 :     SolarMutexGuard aGuard;
    3359             : 
    3360           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    3361             : 
    3362             :     sal_Int32 nStart, nEnd;
    3363           0 :     /*sal_Bool bSelected = */GetSelectionAtIndex(nSelectedPortionIndex, nStart, nEnd );
    3364           0 :     return nStart;
    3365             : }
    3366             : 
    3367           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionEnd( sal_Int32 nSelectedPortionIndex )
    3368             :     throw (::com::sun::star::lang::IndexOutOfBoundsException,
    3369             :            ::com::sun::star::uno::RuntimeException,
    3370             :            std::exception)
    3371             : {
    3372           0 :     SolarMutexGuard aGuard;
    3373             : 
    3374           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    3375             : 
    3376             :     sal_Int32 nStart, nEnd;
    3377           0 :     /*sal_Bool bSelected = */GetSelectionAtIndex(nSelectedPortionIndex, nStart, nEnd );
    3378           0 :     return nEnd;
    3379             : }
    3380             : 
    3381           0 : sal_Bool SAL_CALL SwAccessibleParagraph::removeSelection( sal_Int32 selectionIndex )
    3382             :     throw (::com::sun::star::lang::IndexOutOfBoundsException,
    3383             :            ::com::sun::star::uno::RuntimeException,
    3384             :            std::exception)
    3385             : {
    3386           0 :     SolarMutexGuard g;
    3387             : 
    3388           0 :     if(selectionIndex < 0) return sal_False;
    3389             : 
    3390           0 :     sal_Int32 nSelected = selectionIndex;
    3391             : 
    3392             :     // get the selection, and test whether it affects our text node
    3393           0 :     SwPaM* pCrsr = GetCursor( true );
    3394             : 
    3395           0 :     if( pCrsr != NULL )
    3396             :     {
    3397           0 :         bool bRet = false;
    3398             : 
    3399             :         // get SwPosition for my node
    3400           0 :         const SwTextNode* pNode = GetTextNode();
    3401           0 :         sal_uLong nHere = pNode->GetIndex();
    3402             : 
    3403             :         // iterate over ring
    3404           0 :         SwPaM* pRingStart = pCrsr;
    3405           0 :         do
    3406             :         {
    3407             :             // ignore, if no mark
    3408           0 :             if( pCrsr->HasMark() )
    3409             :             {
    3410             :                 // check whether nHere is 'inside' pCrsr
    3411           0 :                 SwPosition* pStart = pCrsr->Start();
    3412           0 :                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
    3413           0 :                 SwPosition* pEnd = pCrsr->End();
    3414           0 :                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
    3415           0 :                 if( ( nHere >= nStartIndex ) &&
    3416             :                     ( nHere <= nEndIndex )      )
    3417             :                 {
    3418           0 :                     if( nSelected == 0 )
    3419             :                     {
    3420           0 :                         pCrsr->MoveTo(nullptr);
    3421           0 :                         delete pCrsr;
    3422           0 :                         bRet = true;
    3423             :                     }
    3424             :                     else
    3425             :                     {
    3426           0 :                         nSelected--;
    3427             :                     }
    3428             :                 }
    3429             :             }
    3430             :             // else: this PaM is collapsed and doesn't select anything
    3431           0 :             if(!bRet)
    3432           0 :                 pCrsr = pCrsr->GetNext();
    3433             :         }
    3434           0 :         while( !bRet && (pCrsr != pRingStart) );
    3435             :     }
    3436           0 :     return sal_True;
    3437             : }
    3438             : 
    3439           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::addSelection( sal_Int32, sal_Int32 startOffset, sal_Int32 endOffset)
    3440             :     throw (::com::sun::star::lang::IndexOutOfBoundsException,
    3441             :            ::com::sun::star::uno::RuntimeException,
    3442             :            std::exception)
    3443             : {
    3444           0 :     SolarMutexGuard aGuard;
    3445             : 
    3446           0 :     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
    3447             : 
    3448             :     // parameter checking
    3449           0 :     sal_Int32 nLength = GetString().getLength();
    3450           0 :     if ( ! IsValidRange( startOffset, endOffset, nLength ) )
    3451             :     {
    3452           0 :         throw lang::IndexOutOfBoundsException();
    3453             :     }
    3454             : 
    3455           0 :     sal_Int32 nSelectedCount = getSelectedPortionCount();
    3456           0 :     for ( sal_Int32 i = nSelectedCount ; i >= 0 ; i--)
    3457             :     {
    3458             :         sal_Int32 nStart, nEnd;
    3459           0 :         bool bSelected = GetSelectionAtIndex(i, nStart, nEnd );
    3460           0 :         if(bSelected)
    3461             :         {
    3462           0 :             if(nStart <= nEnd )
    3463             :             {
    3464           0 :                 if (( startOffset>=nStart && startOffset <=nEnd ) ||     //startOffset in a selection
    3465           0 :                        ( endOffset>=nStart && endOffset <=nEnd )     ||  //endOffset in a selection
    3466           0 :                     ( startOffset <= nStart && endOffset >=nEnd)  ||       //start and  end include the old selection
    3467           0 :                     ( startOffset >= nStart && endOffset <=nEnd) )
    3468             :                 {
    3469           0 :                     removeSelection(i);
    3470             :                 }
    3471             : 
    3472             :             }
    3473             :             else
    3474             :             {
    3475           0 :                 if (( startOffset>=nEnd && startOffset <=nStart ) ||     //startOffset in a selection
    3476           0 :                        ( endOffset>=nEnd && endOffset <=nStart )     || //endOffset in a selection
    3477           0 :                     ( startOffset <= nStart && endOffset >=nEnd)  ||       //start and  end include the old selection
    3478           0 :                     ( startOffset >= nStart && endOffset <=nEnd) )
    3479             : 
    3480             :                 {
    3481           0 :                     removeSelection(i);
    3482             :                 }
    3483             :             }
    3484             :         }
    3485             : 
    3486             :     }
    3487             : 
    3488             :     // get cursor shell
    3489           0 :     SwCrsrShell* pCrsrShell = GetCrsrShell();
    3490           0 :     if( pCrsrShell != NULL )
    3491             :     {
    3492             :         // create pam for selection
    3493           0 :         pCrsrShell->StartAction();
    3494           0 :         SwPaM* aPaM = pCrsrShell->CreateCrsr();
    3495           0 :         aPaM->SetMark();
    3496           0 :         aPaM->GetPoint()->nContent = GetPortionData().GetModelPosition(startOffset);
    3497           0 :         aPaM->GetMark()->nContent =  GetPortionData().GetModelPosition(endOffset);
    3498           0 :         pCrsrShell->EndAction();
    3499             :     }
    3500             : 
    3501           0 :     return 0;
    3502             : }
    3503             : 
    3504             : /*accessibility::*/TextSegment SAL_CALL
    3505           0 :         SwAccessibleParagraph::getTextMarkup( sal_Int32 nTextMarkupIndex,
    3506             :                                               sal_Int32 nTextMarkupType )
    3507             :                                         throw (lang::IndexOutOfBoundsException,
    3508             :                                                lang::IllegalArgumentException,
    3509             :                                                uno::RuntimeException, std::exception)
    3510             : {
    3511           0 :     boost::scoped_ptr<SwTextMarkupHelper> pTextMarkupHelper;
    3512           0 :     switch ( nTextMarkupType )
    3513             :     {
    3514             :         case text::TextMarkupType::TRACK_CHANGE_INSERTION:
    3515             :         case text::TextMarkupType::TRACK_CHANGE_DELETION:
    3516             :         case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
    3517             :         {
    3518             :             pTextMarkupHelper.reset( new SwTextMarkupHelper(
    3519             :                 GetPortionData(),
    3520           0 :                 *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
    3521             :         }
    3522           0 :         break;
    3523             :         default:
    3524             :         {
    3525           0 :             pTextMarkupHelper.reset( new SwTextMarkupHelper( GetPortionData(), *GetTextNode() ) );
    3526             :         }
    3527             :     }
    3528             : 
    3529           0 :     return pTextMarkupHelper->getTextMarkup( nTextMarkupIndex, nTextMarkupType );
    3530             : }
    3531             : 
    3532             : uno::Sequence< /*accessibility::*/TextSegment > SAL_CALL
    3533           0 :         SwAccessibleParagraph::getTextMarkupAtIndex( sal_Int32 nCharIndex,
    3534             :                                                      sal_Int32 nTextMarkupType )
    3535             :                                         throw (lang::IndexOutOfBoundsException,
    3536             :                                                lang::IllegalArgumentException,
    3537             :                                                uno::RuntimeException, std::exception)
    3538             : {
    3539             :     // parameter checking
    3540           0 :     const sal_Int32 nLength = GetString().getLength();
    3541           0 :     if ( ! IsValidPosition( nCharIndex, nLength ) )
    3542             :     {
    3543           0 :         throw lang::IndexOutOfBoundsException();
    3544             :     }
    3545             : 
    3546           0 :     boost::scoped_ptr<SwTextMarkupHelper> pTextMarkupHelper;
    3547           0 :     switch ( nTextMarkupType )
    3548             :     {
    3549             :         case text::TextMarkupType::TRACK_CHANGE_INSERTION:
    3550             :         case text::TextMarkupType::TRACK_CHANGE_DELETION:
    3551             :         case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
    3552             :         {
    3553             :             pTextMarkupHelper.reset( new SwTextMarkupHelper(
    3554             :                 GetPortionData(),
    3555           0 :                 *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
    3556             :         }
    3557           0 :         break;
    3558             :         default:
    3559             :         {
    3560           0 :             pTextMarkupHelper.reset( new SwTextMarkupHelper( GetPortionData(), *GetTextNode() ) );
    3561             :         }
    3562             :     }
    3563             : 
    3564           0 :     return pTextMarkupHelper->getTextMarkupAtIndex( nCharIndex, nTextMarkupType );
    3565             : }
    3566             : 
    3567             : // #i89175#
    3568           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getLineNumberAtIndex( sal_Int32 nIndex )
    3569             :                                         throw (lang::IndexOutOfBoundsException,
    3570             :                                                uno::RuntimeException, std::exception)
    3571             : {
    3572             :     // parameter checking
    3573           0 :     const sal_Int32 nLength = GetString().getLength();
    3574           0 :     if ( ! IsValidPosition( nIndex, nLength ) )
    3575             :     {
    3576           0 :         throw lang::IndexOutOfBoundsException();
    3577             :     }
    3578             : 
    3579           0 :     const sal_Int32 nLineNo = GetPortionData().GetLineNo( nIndex );
    3580           0 :     return nLineNo;
    3581             : }
    3582             : 
    3583             : /*accessibility::*/TextSegment SAL_CALL
    3584           0 :         SwAccessibleParagraph::getTextAtLineNumber( sal_Int32 nLineNo )
    3585             :                                         throw (lang::IndexOutOfBoundsException,
    3586             :                                                uno::RuntimeException, std::exception)
    3587             : {
    3588             :     // parameter checking
    3589           0 :     if ( nLineNo < 0 ||
    3590           0 :          nLineNo >= GetPortionData().GetLineCount() )
    3591             :     {
    3592           0 :         throw lang::IndexOutOfBoundsException();
    3593             :     }
    3594             : 
    3595           0 :     i18n::Boundary aLineBound;
    3596           0 :     GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
    3597             : 
    3598           0 :     /*accessibility::*/TextSegment aTextAtLine;
    3599           0 :     const OUString rText = GetString();
    3600           0 :     aTextAtLine.SegmentText = rText.copy( aLineBound.startPos,
    3601           0 :                                           aLineBound.endPos - aLineBound.startPos );
    3602           0 :     aTextAtLine.SegmentStart = aLineBound.startPos;
    3603           0 :     aTextAtLine.SegmentEnd = aLineBound.endPos;
    3604             : 
    3605           0 :     return aTextAtLine;
    3606             : }
    3607             : 
    3608           0 : /*accessibility::*/TextSegment SAL_CALL SwAccessibleParagraph::getTextAtLineWithCaret()
    3609             :                                         throw (uno::RuntimeException, std::exception)
    3610             : {
    3611           0 :     const sal_Int32 nLineNoOfCaret = getNumberOfLineWithCaret();
    3612             : 
    3613           0 :     if ( nLineNoOfCaret >= 0 &&
    3614           0 :          nLineNoOfCaret < GetPortionData().GetLineCount() )
    3615             :     {
    3616           0 :         return getTextAtLineNumber( nLineNoOfCaret );
    3617             :     }
    3618             : 
    3619           0 :     return /*accessibility::*/TextSegment();
    3620             : }
    3621             : 
    3622           0 : sal_Int32 SAL_CALL SwAccessibleParagraph::getNumberOfLineWithCaret()
    3623             :                                         throw (uno::RuntimeException, std::exception)
    3624             : {
    3625           0 :     const sal_Int32 nCaretPos = getCaretPosition();
    3626           0 :     const sal_Int32 nLength = GetString().getLength();
    3627           0 :     if ( !IsValidPosition( nCaretPos, nLength ) )
    3628             :     {
    3629           0 :         return -1;
    3630             :     }
    3631             : 
    3632           0 :     sal_Int32 nLineNo = GetPortionData().GetLineNo( nCaretPos );
    3633             : 
    3634             :     // special handling for cursor positioned at end of text line via End key
    3635           0 :     if ( nCaretPos != 0 )
    3636             :     {
    3637           0 :         i18n::Boundary aLineBound;
    3638           0 :         GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
    3639           0 :         if ( nCaretPos == aLineBound.startPos )
    3640             :         {
    3641           0 :             SwCrsrShell* pCrsrShell = SwAccessibleParagraph::GetCrsrShell();
    3642           0 :             if ( pCrsrShell != 0 )
    3643             :             {
    3644           0 :                 const awt::Rectangle aCharRect = getCharacterBounds( nCaretPos );
    3645             : 
    3646           0 :                 const SwRect& aCursorCoreRect = pCrsrShell->GetCharRect();
    3647             :                 // translate core coordinates into accessibility coordinates
    3648           0 :                 vcl::Window *pWin = GetWindow();
    3649           0 :                 CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
    3650             : 
    3651           0 :                 Rectangle aScreenRect( GetMap()->CoreToPixel( aCursorCoreRect.SVRect() ));
    3652             : 
    3653           0 :                 SwRect aFrmLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
    3654           0 :                 Point aFrmPixPos( GetMap()->CoreToPixel( aFrmLogBounds.SVRect() ).TopLeft() );
    3655           0 :                 aScreenRect.Move( -aFrmPixPos.getX(), -aFrmPixPos.getY() );
    3656             : 
    3657             :                 // convert into AWT Rectangle
    3658           0 :                 const awt::Rectangle aCursorRect( aScreenRect.Left(),
    3659           0 :                                                   aScreenRect.Top(),
    3660           0 :                                                   aScreenRect.GetWidth(),
    3661           0 :                                                   aScreenRect.GetHeight() );
    3662             : 
    3663           0 :                 if ( aCharRect.X != aCursorRect.X ||
    3664           0 :                      aCharRect.Y != aCursorRect.Y )
    3665             :                 {
    3666           0 :                     --nLineNo;
    3667             :                 }
    3668             :             }
    3669             :         }
    3670             :     }
    3671             : 
    3672           0 :     return nLineNo;
    3673             : }
    3674             : 
    3675             : // #i108125#
    3676          72 : void SwAccessibleParagraph::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
    3677             : {
    3678          72 :     mpParaChangeTrackInfo->reset();
    3679             : 
    3680          72 :     CheckRegistration( pOld, pNew );
    3681          72 : }
    3682             : 
    3683           0 : bool SwAccessibleParagraph::GetSelectionAtIndex(
    3684             :     sal_Int32& nIndex, sal_Int32& nStart, sal_Int32& nEnd)
    3685             : {
    3686           0 :         if(nIndex < 0) return false;
    3687             : 
    3688           0 :     bool bRet = false;
    3689           0 :     nStart = -1;
    3690           0 :     nEnd = -1;
    3691           0 :     sal_Int32 nSelected = nIndex;
    3692             : 
    3693             :     // get the selection, and test whether it affects our text node
    3694           0 :     SwPaM* pCrsr = GetCursor( true );
    3695           0 :     if( pCrsr != NULL )
    3696             :     {
    3697             :         // get SwPosition for my node
    3698           0 :         const SwTextNode* pNode = GetTextNode();
    3699           0 :         sal_uLong nHere = pNode->GetIndex();
    3700             : 
    3701             :         // iterate over ring
    3702           0 :         for(SwPaM& rTmpCrsr : pCrsr->GetRingContainer())
    3703             :         {
    3704             :             // ignore, if no mark
    3705           0 :             if( rTmpCrsr.HasMark() )
    3706             :             {
    3707             :                 // check whether nHere is 'inside' pCrsr
    3708           0 :                 SwPosition* pStart = rTmpCrsr.Start();
    3709           0 :                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
    3710           0 :                 SwPosition* pEnd = rTmpCrsr.End();
    3711           0 :                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
    3712           0 :                 if( ( nHere >= nStartIndex ) &&
    3713             :                     ( nHere <= nEndIndex )      )
    3714             :                 {
    3715           0 :                     if( nSelected == 0 )
    3716             :                     {
    3717             :                         // translate start and end positions
    3718             : 
    3719             :                         // start position
    3720           0 :                         sal_Int32 nLocalStart = -1;
    3721           0 :                         if( nHere > nStartIndex )
    3722             :                         {
    3723             :                             // selection starts in previous node:
    3724             :                             // then our local selection starts with the paragraph
    3725           0 :                             nLocalStart = 0;
    3726             :                         }
    3727             :                         else
    3728             :                         {
    3729             :                             assert(nHere == nStartIndex);
    3730             : 
    3731             :                             // selection starts in this node:
    3732             :                             // then check whether it's before or inside our part of
    3733             :                             // the paragraph, and if so, get the proper position
    3734           0 :                             const sal_Int32 nCoreStart = pStart->nContent.GetIndex();
    3735           0 :                             if( nCoreStart <
    3736           0 :                                 GetPortionData().GetFirstValidCorePosition() )
    3737             :                             {
    3738           0 :                                 nLocalStart = 0;
    3739             :                             }
    3740           0 :                             else if( nCoreStart <=
    3741           0 :                                      GetPortionData().GetLastValidCorePosition() )
    3742             :                             {
    3743             :                                 SAL_WARN_IF(
    3744             :                                     GetPortionData().IsValidCorePosition(
    3745             :                                                                   nCoreStart),
    3746             :                                     "sw.core",
    3747             :                                     "problem determining valid core position");
    3748             : 
    3749             :                                 nLocalStart =
    3750           0 :                                     GetPortionData().GetAccessiblePosition(
    3751           0 :                                                                       nCoreStart );
    3752             :                             }
    3753             :                         }
    3754             : 
    3755             :                         // end position
    3756           0 :                         sal_Int32 nLocalEnd = -1;
    3757           0 :                         if( nHere < nEndIndex )
    3758             :                         {
    3759             :                             // selection ends in following node:
    3760             :                             // then our local selection extends to the end
    3761           0 :                             nLocalEnd = GetPortionData().GetAccessibleString().
    3762           0 :                                                                        getLength();
    3763             :                         }
    3764             :                         else
    3765             :                         {
    3766             :                             assert(nHere == nEndIndex);
    3767             : 
    3768             :                             // selection ends in this node: then select everything
    3769             :                             // before our part of the node
    3770           0 :                             const sal_Int32 nCoreEnd = pEnd->nContent.GetIndex();
    3771           0 :                             if( nCoreEnd >
    3772           0 :                                     GetPortionData().GetLastValidCorePosition() )
    3773             :                             {
    3774             :                                 // selection extends beyond out part of this para
    3775           0 :                                 nLocalEnd = GetPortionData().GetAccessibleString().
    3776           0 :                                                                        getLength();
    3777             :                             }
    3778           0 :                             else if( nCoreEnd >=
    3779           0 :                                      GetPortionData().GetFirstValidCorePosition() )
    3780             :                             {
    3781             :                                 // selection is inside our part of this para
    3782             :                                 SAL_WARN_IF(
    3783             :                                     GetPortionData().IsValidCorePosition(
    3784             :                                                                   nCoreEnd),
    3785             :                                     "sw.core",
    3786             :                                     "problem determining valid core position");
    3787             : 
    3788           0 :                                 nLocalEnd = GetPortionData().GetAccessiblePosition(
    3789           0 :                                                                        nCoreEnd );
    3790             :                             }
    3791             :                         }
    3792             : 
    3793           0 :                         if( ( nLocalStart != -1 ) && ( nLocalEnd != -1 ) )
    3794             :                         {
    3795           0 :                             nStart = nLocalStart;
    3796           0 :                             nEnd = nLocalEnd;
    3797           0 :                             bRet = true;
    3798             :                         }
    3799             :                     } // if hit the index
    3800             :                     else
    3801             :                     {
    3802           0 :                         nSelected--;
    3803             :                     }
    3804             :                 }
    3805             :                 // else: this PaM doesn't point to this paragraph
    3806             :             }
    3807             :             // else: this PaM is collapsed and doesn't select anything
    3808           0 :             if(bRet)
    3809           0 :                 break;
    3810             :         }
    3811             :     }
    3812             :     // else: nocursor -> no selection
    3813             : 
    3814           0 :     if( bRet )
    3815             :     {
    3816           0 :         sal_Int32 nCaretPos = GetCaretPos();
    3817           0 :         if( nStart == nCaretPos )
    3818             :         {
    3819           0 :             sal_Int32 tmp = nStart;
    3820           0 :             nStart = nEnd;
    3821           0 :             nEnd = tmp;
    3822             :         }
    3823             :     }
    3824           0 :     return bRet;
    3825             : }
    3826             : 
    3827          21 : sal_Int16 SAL_CALL SwAccessibleParagraph::getAccessibleRole() throw (::com::sun::star::uno::RuntimeException, std::exception)
    3828             : {
    3829          21 :     SolarMutexGuard g;
    3830             : 
    3831             :     //Get the real heading level, Heading1 ~ Heading10
    3832          21 :     if (nHeadingLevel > 0)
    3833             :     {
    3834           0 :         return AccessibleRole::HEADING;
    3835             :     }
    3836             :     else
    3837             :     {
    3838          21 :         return AccessibleRole::PARAGRAPH;
    3839          21 :     }
    3840             : }
    3841             : 
    3842             : //Get the real heading level, Heading1 ~ Heading10
    3843          79 : sal_Int32 SwAccessibleParagraph::GetRealHeadingLevel()
    3844             : {
    3845          79 :     uno::Reference< ::com::sun::star::beans::XPropertySet > xPortion = CreateUnoPortion( 0, 0 );
    3846         158 :     OUString pString = "ParaStyleName";
    3847         158 :     uno::Any styleAny = xPortion->getPropertyValue( pString );
    3848         158 :     OUString sValue;
    3849          79 :     if (styleAny >>= sValue)
    3850             :     {
    3851          79 :         sal_Int32 length = sValue.getLength();
    3852          79 :         if (length == 9 || length == 10)
    3853             :         {
    3854           0 :             OUString headStr = sValue.copy(0, 7);
    3855           0 :             if (headStr == "Heading")
    3856             :             {
    3857           0 :                 OUString intStr = sValue.copy(8);
    3858           0 :                 sal_Int32 headingLevel = intStr.toInt32(10);
    3859           0 :                 return headingLevel;
    3860           0 :             }
    3861             :         }
    3862             :     }
    3863         158 :     return -1;
    3864             : }
    3865             : 
    3866           0 : uno::Any SAL_CALL SwAccessibleParagraph::getExtendedAttributes()
    3867             :         throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
    3868             : {
    3869           0 :     SolarMutexGuard g;
    3870             : 
    3871           0 :     uno::Any Ret;
    3872           0 :     OUString strHeading("heading-level:");
    3873           0 :     if( nHeadingLevel >= 0 )
    3874           0 :         strHeading += OUString::number(nHeadingLevel, 10);
    3875           0 :     strHeading += ";";
    3876             : 
    3877           0 :     strHeading += strHeading.copy(8); // tdf#84102: expose the same attribute with the name "level"
    3878             : 
    3879           0 :     Ret <<= strHeading;
    3880             : 
    3881           0 :     return Ret;
    3882         177 : }
    3883             : 
    3884             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11