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

Generated by: LCOV version 1.10