LCOV - code coverage report
Current view: top level - sw/source/core/unocore - unoobj.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1190 1426 83.5 %
Date: 2014-11-03 Functions: 103 119 86.6 %
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 <com/sun/star/table/TableSortField.hpp>
      21             : #include <comphelper/string.hxx>
      22             : #include <cppuhelper/supportsservice.hxx>
      23             : #include <osl/endian.h>
      24             : #include <rtl/ustrbuf.hxx>
      25             : #include <unotools/collatorwrapper.hxx>
      26             : #include <swtypes.hxx>
      27             : #include <hintids.hxx>
      28             : #include <cmdid.h>
      29             : #include <hints.hxx>
      30             : #include <IMark.hxx>
      31             : #include <frmfmt.hxx>
      32             : #include <doc.hxx>
      33             : #include <IDocumentUndoRedo.hxx>
      34             : #include <istyleaccess.hxx>
      35             : #include <ndtxt.hxx>
      36             : #include <ndnotxt.hxx>
      37             : #include <unocrsr.hxx>
      38             : #include <unocrsrhelper.hxx>
      39             : #include <swundo.hxx>
      40             : #include <rootfrm.hxx>
      41             : #include <flyfrm.hxx>
      42             : #include <ftnidx.hxx>
      43             : #include <sfx2/linkmgr.hxx>
      44             : #include <docary.hxx>
      45             : #include <paratr.hxx>
      46             : #include <pam.hxx>
      47             : #include <shellio.hxx>
      48             : #include <swerror.h>
      49             : #include <swtblfmt.hxx>
      50             : #include <fmtruby.hxx>
      51             : #include <docsh.hxx>
      52             : #include <docstyle.hxx>
      53             : #include <charfmt.hxx>
      54             : #include <txtfld.hxx>
      55             : #include <fmtfld.hxx>
      56             : #include <fmtpdsc.hxx>
      57             : #include <pagedesc.hxx>
      58             : #include <edimp.hxx>
      59             : #include <fchrfmt.hxx>
      60             : #include <fmtautofmt.hxx>
      61             : #include <cntfrm.hxx>
      62             : #include <pagefrm.hxx>
      63             : #include <doctxm.hxx>
      64             : #include <sfx2/docfilt.hxx>
      65             : #include <sfx2/docfile.hxx>
      66             : #include <sfx2/fcontnr.hxx>
      67             : #include <fmtrfmrk.hxx>
      68             : #include <txtrfmrk.hxx>
      69             : #include <unotextrange.hxx>
      70             : #include <unotextcursor.hxx>
      71             : #include <unomap.hxx>
      72             : #include <unosett.hxx>
      73             : #include <unoprnms.hxx>
      74             : #include <unodraw.hxx>
      75             : #include <unocoll.hxx>
      76             : #include <unostyle.hxx>
      77             : #include <unometa.hxx>
      78             : #include <fmtanchr.hxx>
      79             : #include <editeng/flstitem.hxx>
      80             : #include <svtools/ctrltool.hxx>
      81             : #include <flypos.hxx>
      82             : #include <txtftn.hxx>
      83             : #include <com/sun/star/text/WrapTextMode.hpp>
      84             : #include <com/sun/star/text/TextContentAnchorType.hpp>
      85             : #include <com/sun/star/text/TextMarkupType.hpp>
      86             : #include <com/sun/star/style/PageStyleLayout.hpp>
      87             : #include <com/sun/star/text/XTextDocument.hpp>
      88             : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
      89             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      90             : #include <unoframe.hxx>
      91             : #include <fmthdft.hxx>
      92             : #include <osl/mutex.hxx>
      93             : #include <vcl/svapp.hxx>
      94             : #include <unotools/syslocale.hxx>
      95             : #include <fmtflcnt.hxx>
      96             : #include <editeng/brushitem.hxx>
      97             : #include <editeng/unolingu.hxx>
      98             : #include <fmtclds.hxx>
      99             : #include <dcontact.hxx>
     100             : #include <SwStyleNameMapper.hxx>
     101             : #include <crsskip.hxx>
     102             : #include <sortopt.hxx>
     103             : #include <com/sun/star/beans/PropertyAttribute.hpp>
     104             : #include <memory>
     105             : #include <unoparaframeenum.hxx>
     106             : #include <unoparagraph.hxx>
     107             : #include <comphelper/servicehelper.hxx>
     108             : 
     109             : using namespace ::com::sun::star;
     110             : 
     111             : // Helper classes
     112      106716 : SwUnoInternalPaM::SwUnoInternalPaM(SwDoc& rDoc) :
     113      106716 :     SwPaM(rDoc.GetNodes())
     114             : {
     115      106716 : }
     116             : 
     117      218174 : SwUnoInternalPaM::~SwUnoInternalPaM()
     118             : {
     119      213432 :     while( GetNext() != this)
     120             :     {
     121           0 :         delete GetNext();
     122             :     }
     123      111458 : }
     124             : 
     125         116 : SwUnoInternalPaM&   SwUnoInternalPaM::operator=(const SwPaM& rPaM)
     126             : {
     127         116 :     const SwPaM* pTmp = &rPaM;
     128         116 :     *GetPoint() = *rPaM.GetPoint();
     129         116 :     if(rPaM.HasMark())
     130             :     {
     131           0 :         SetMark();
     132           0 :         *GetMark() = *rPaM.GetMark();
     133             :     }
     134             :     else
     135         116 :         DeleteMark();
     136         232 :     while(&rPaM != (pTmp = (const SwPaM*)pTmp->GetNext()))
     137             :     {
     138           0 :         if(pTmp->HasMark())
     139           0 :             new SwPaM(*pTmp->GetMark(), *pTmp->GetPoint(), this);
     140             :         else
     141           0 :             new SwPaM(*pTmp->GetPoint(), this);
     142             :     }
     143         116 :     return *this;
     144             : }
     145             : 
     146      593828 : void SwUnoCursorHelper::SelectPam(SwPaM & rPam, const bool bExpand)
     147             : {
     148      593828 :     if (bExpand)
     149             :     {
     150      194422 :         if (!rPam.HasMark())
     151             :         {
     152      189018 :             rPam.SetMark();
     153             :         }
     154             :     }
     155      399406 :     else if (rPam.HasMark())
     156             :     {
     157       12320 :         rPam.DeleteMark();
     158             :     }
     159      593828 : }
     160             : 
     161       15412 : void SwUnoCursorHelper::GetTextFromPam(SwPaM & rPam, OUString & rBuffer)
     162             : {
     163       15412 :     if (!rPam.HasMark())
     164             :     {
     165       15424 :         return;
     166             :     }
     167       15400 :     SvMemoryStream aStream;
     168             : #ifdef OSL_BIGENDIAN
     169             :     aStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
     170             : #else
     171       15400 :     aStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     172             : #endif
     173       30800 :     WriterRef xWrt;
     174             :     // TODO/MBA: looks like a BaseURL doesn't make sense here
     175       15400 :     SwReaderWriter::GetWriter( FILTER_TEXT_DLG, OUString(), xWrt );
     176       15400 :     if( xWrt.Is() )
     177             :     {
     178       15400 :         SwWriter aWriter( aStream, rPam );
     179       15400 :         xWrt->bASCII_NoLastLineEnd = true;
     180       15400 :         xWrt->bExportPargraphNumbering = false;
     181       30800 :         SwAsciiOptions aOpt = xWrt->GetAsciiOptions();
     182       15400 :         aOpt.SetCharSet( RTL_TEXTENCODING_UNICODE );
     183       15400 :         xWrt->SetAsciiOptions( aOpt );
     184       15400 :         xWrt->bUCS2_WithStartChar = false;
     185             :         // #i68522#
     186       15400 :         const bool bOldShowProgress = xWrt->bShowProgress;
     187       15400 :         xWrt->bShowProgress = false;
     188             : 
     189             :         long lLen;
     190       46200 :         if( !IsError( aWriter.Write( xWrt ) ) &&
     191       15400 :             0x7ffffff > (( lLen  = aStream.GetSize() )
     192       15400 :                                     / sizeof( sal_Unicode )) + 1 )
     193             :         {
     194       15400 :             aStream.WriteUInt16( '\0' );
     195             : 
     196       15400 :             aStream.Seek( 0 );
     197       15400 :             aStream.ResetError();
     198             : 
     199       15400 :             long lUniLen = (lLen / sizeof( sal_Unicode ));
     200       15400 :             rtl_uString *pStr = rtl_uString_alloc(lUniLen);
     201       15400 :             aStream.Read(pStr->buffer, lUniLen * sizeof(sal_Unicode));
     202       15400 :             rBuffer = OUString(pStr, SAL_NO_ACQUIRE);
     203             :         }
     204       30800 :         xWrt->bShowProgress = bOldShowProgress;
     205       15400 :     }
     206             : }
     207             : 
     208             : static void
     209       10546 : lcl_setCharStyle(SwDoc *const pDoc, const uno::Any & rValue, SfxItemSet & rSet)
     210             : throw (lang::IllegalArgumentException)
     211             : {
     212       10546 :     SwDocShell *const pDocSh = pDoc->GetDocShell();
     213       10546 :     if(pDocSh)
     214             :     {
     215       10546 :         OUString uStyle;
     216       10546 :         if (!(rValue >>= uStyle))
     217             :         {
     218           0 :             throw lang::IllegalArgumentException();
     219             :         }
     220       21092 :         OUString sStyle;
     221             :         SwStyleNameMapper::FillUIName(uStyle, sStyle,
     222       10546 :                 nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true);
     223             :         SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
     224       10546 :             pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR));
     225       10546 :         if (!pStyle)
     226             :         {
     227           0 :             throw lang::IllegalArgumentException();
     228             :         }
     229       21092 :         const SwFmtCharFmt aFmt(pStyle->GetCharFmt());
     230       21092 :         rSet.Put(aFmt);
     231             :     }
     232       10546 : };
     233             : 
     234             : static void
     235       11764 : lcl_setAutoStyle(IStyleAccess & rStyleAccess, const uno::Any & rValue,
     236             :         SfxItemSet & rSet, const bool bPara)
     237             : throw (lang::IllegalArgumentException)
     238             : {
     239       11764 :     OUString uStyle;
     240       11764 :     if (!(rValue >>= uStyle))
     241             :     {
     242           0 :          throw lang::IllegalArgumentException();
     243             :     }
     244             :     StylePool::SfxItemSet_Pointer_t pStyle = bPara ?
     245        5080 :         rStyleAccess.getByName(uStyle, IStyleAccess::AUTO_STYLE_PARA ):
     246       28608 :         rStyleAccess.getByName(uStyle, IStyleAccess::AUTO_STYLE_CHAR );
     247       11764 :     if(pStyle.get())
     248             :     {
     249             :         SwFmtAutoFmt aFmt( (bPara)
     250        5080 :             ? sal::static_int_cast< sal_uInt16 >(RES_AUTO_STYLE)
     251       16844 :             : sal::static_int_cast< sal_uInt16 >(RES_TXTATR_AUTOFMT) );
     252       11764 :         aFmt.SetStyleHandle( pStyle );
     253       11764 :         rSet.Put(aFmt);
     254             :     }
     255             :     else
     256             :     {
     257           0 :          throw lang::IllegalArgumentException();
     258       11764 :     }
     259       11764 : };
     260             : 
     261             : void
     262       53916 : SwUnoCursorHelper::SetTxtFmtColl(const uno::Any & rAny, SwPaM & rPaM)
     263             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     264             : {
     265       53916 :     SwDoc *const pDoc = rPaM.GetDoc();
     266       53916 :     SwDocShell *const pDocSh = pDoc->GetDocShell();
     267       53916 :     if(!pDocSh)
     268       53898 :         return;
     269       53916 :     OUString uStyle;
     270       53916 :     rAny >>= uStyle;
     271      107832 :     OUString sStyle;
     272             :     SwStyleNameMapper::FillUIName(uStyle, sStyle,
     273       53916 :             nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
     274             :     SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
     275       53916 :             pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_PARA));
     276       53916 :     if (!pStyle)
     277             :     {
     278          18 :         throw lang::IllegalArgumentException();
     279             :     }
     280             : 
     281       53898 :     SwTxtFmtColl *const pLocal = pStyle->GetCollection();
     282      107796 :     UnoActionContext aAction(pDoc);
     283       53898 :     pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
     284       53898 :     SwPaM *pTmpCrsr = &rPaM;
     285       53898 :     do {
     286       53898 :         pDoc->SetTxtFmtColl(*pTmpCrsr, pLocal);
     287       53898 :         pTmpCrsr = static_cast<SwPaM*>(pTmpCrsr->GetNext());
     288             :     } while ( pTmpCrsr != &rPaM );
     289      107814 :     pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
     290             : }
     291             : 
     292             : bool
     293        3996 : SwUnoCursorHelper::SetPageDesc(
     294             :         const uno::Any& rValue, SwDoc & rDoc, SfxItemSet & rSet)
     295             : {
     296        3996 :     OUString uDescName;
     297        3996 :     if (!(rValue >>= uDescName))
     298             :     {
     299           0 :         return false;
     300             :     }
     301        7992 :     ::std::unique_ptr<SwFmtPageDesc> pNewDesc;
     302             :     const SfxPoolItem* pItem;
     303        3996 :     if(SfxItemState::SET == rSet.GetItemState( RES_PAGEDESC, true, &pItem ) )
     304             :     {
     305             :         pNewDesc.reset(new SwFmtPageDesc(
     306         208 :                     *static_cast<const SwFmtPageDesc*>(pItem)));
     307             :     }
     308        3996 :     if (!pNewDesc.get())
     309             :     {
     310        3788 :         pNewDesc.reset(new SwFmtPageDesc());
     311             :     }
     312        7992 :     OUString sDescName;
     313             :     SwStyleNameMapper::FillUIName(uDescName, sDescName,
     314        3996 :             nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, true);
     315       12084 :     if (!pNewDesc->GetPageDesc() ||
     316        4284 :         (pNewDesc->GetPageDesc()->GetName() != sDescName))
     317             :     {
     318        3996 :         bool bPut = false;
     319        3996 :         if (!sDescName.isEmpty())
     320             :         {
     321        3992 :             SwPageDesc *const pPageDesc = SwPageDesc::GetByName(rDoc, sDescName);
     322        3992 :             if (!pPageDesc)
     323             :             {
     324           0 :                 throw lang::IllegalArgumentException();
     325             :             }
     326        3992 :             pNewDesc.get()->RegisterToPageDesc( *pPageDesc );
     327        3992 :             bPut = true;
     328             :         }
     329        3996 :         if(!bPut)
     330             :         {
     331           4 :             rSet.ClearItem(RES_BREAK);
     332           4 :             rSet.Put(SwFmtPageDesc());
     333             :         }
     334             :         else
     335             :         {
     336        3992 :             rSet.Put(*pNewDesc);
     337             :         }
     338             :     }
     339        7992 :     return true;
     340             : }
     341             : 
     342             : static void
     343          12 : lcl_SetNodeNumStart(SwPaM & rCrsr, uno::Any const& rValue)
     344             : {
     345          12 :     sal_Int16 nTmp = 1;
     346          12 :     rValue >>= nTmp;
     347          12 :     sal_uInt16 nStt = (nTmp < 0 ? USHRT_MAX : (sal_uInt16)nTmp);
     348          12 :     SwDoc* pDoc = rCrsr.GetDoc();
     349          12 :     UnoActionContext aAction(pDoc);
     350             : 
     351          12 :     if( rCrsr.GetNext() != &rCrsr )         // MultiSelection?
     352             :     {
     353           0 :         pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
     354           0 :         SwPamRanges aRangeArr( rCrsr );
     355           0 :         SwPaM aPam( *rCrsr.GetPoint() );
     356           0 :         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
     357             :         {
     358           0 :           pDoc->SetNumRuleStart(*aRangeArr.SetPam( n, aPam ).GetPoint());
     359           0 :           pDoc->SetNodeNumStart(*aRangeArr.SetPam( n, aPam ).GetPoint(),
     360           0 :                     nStt );
     361             :         }
     362           0 :         pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
     363             :     }
     364             :     else
     365             :     {
     366          12 :         pDoc->SetNumRuleStart( *rCrsr.GetPoint());
     367          12 :         pDoc->SetNodeNumStart( *rCrsr.GetPoint(), nStt );
     368          12 :     }
     369          12 : }
     370             : 
     371             : static bool
     372           4 : lcl_setCharFmtSequence(SwPaM & rPam, uno::Any const& rValue)
     373             : {
     374           4 :     uno::Sequence<OUString> aCharStyles;
     375           4 :     if (!(rValue >>= aCharStyles))
     376             :     {
     377           0 :         return false;
     378             :     }
     379             : 
     380           8 :     for (sal_Int32 nStyle = 0; nStyle < aCharStyles.getLength(); nStyle++)
     381             :     {
     382           4 :         uno::Any aStyle;
     383           4 :         rPam.GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_START, NULL);
     384           4 :         aStyle <<= aCharStyles.getConstArray()[nStyle];
     385             :         // create a local set and apply each format directly
     386           4 :         SfxItemSet aSet(rPam.GetDoc()->GetAttrPool(),
     387           8 :                 RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT);
     388           4 :         lcl_setCharStyle(rPam.GetDoc(), aStyle, aSet);
     389             :         // the first style should replace the current attributes,
     390             :         // all other have to be added
     391             :         SwUnoCursorHelper::SetCrsrAttr(rPam, aSet, (nStyle)
     392             :                 ? nsSetAttrMode::SETATTR_DONTREPLACE
     393           4 :                 : nsSetAttrMode::SETATTR_DEFAULT);
     394           4 :         rPam.GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_START, NULL);
     395           4 :     }
     396           4 :     return true;
     397             : }
     398             : 
     399             : static void
     400          12 : lcl_setDropcapCharStyle(SwPaM & rPam, SfxItemSet & rItemSet,
     401             :         uno::Any const& rValue)
     402             : {
     403          12 :     OUString uStyle;
     404          12 :     if (!(rValue >>= uStyle))
     405             :     {
     406           0 :         throw lang::IllegalArgumentException();
     407             :     }
     408          24 :     OUString sStyle;
     409             :     SwStyleNameMapper::FillUIName(uStyle, sStyle,
     410          12 :             nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true);
     411          12 :     SwDoc *const pDoc = rPam.GetDoc();
     412             :     //default character style must not be set as default format
     413             :     SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
     414          12 :             pDoc->GetDocShell()
     415          12 :             ->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR));
     416          24 :     if (!pStyle ||
     417          12 :         (static_cast<SwDocStyleSheet*>(pStyle)->GetCharFmt() ==
     418          12 :              pDoc->GetDfltCharFmt()))
     419             :     {
     420           0 :         throw lang::IllegalArgumentException();
     421             :     }
     422          24 :     ::std::unique_ptr<SwFmtDrop> pDrop;
     423          12 :     SfxPoolItem const* pItem(0);
     424          12 :     if (SfxItemState::SET ==
     425          12 :             rItemSet.GetItemState(RES_PARATR_DROP, true, &pItem))
     426             :     {
     427          12 :         pDrop.reset(new SwFmtDrop(*static_cast<const SwFmtDrop*>(pItem)));
     428             :     }
     429          12 :     if (!pDrop.get())
     430             :     {
     431           0 :         pDrop.reset(new SwFmtDrop);
     432             :     }
     433          24 :     const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*pStyle));
     434          12 :     pDrop->SetCharFmt(xStyle->GetCharFmt());
     435          24 :     rItemSet.Put(*pDrop);
     436          12 : }
     437             : 
     438             : static void
     439           8 : lcl_setRubyCharstyle(SfxItemSet & rItemSet, uno::Any const& rValue)
     440             : {
     441           8 :     OUString sTmp;
     442           8 :     if (!(rValue >>= sTmp))
     443             :     {
     444           0 :         throw lang::IllegalArgumentException();
     445             :     }
     446             : 
     447          16 :     ::std::unique_ptr<SwFmtRuby> pRuby;
     448             :     const SfxPoolItem* pItem;
     449           8 :     if (SfxItemState::SET ==
     450           8 :             rItemSet.GetItemState(RES_TXTATR_CJK_RUBY, true, &pItem))
     451             :     {
     452           8 :         pRuby.reset(new SwFmtRuby(*static_cast<const SwFmtRuby*>(pItem)));
     453             :     }
     454           8 :     if (!pRuby.get())
     455             :     {
     456           0 :         pRuby.reset(new SwFmtRuby(OUString()));
     457             :     }
     458          16 :     OUString sStyle;
     459             :     SwStyleNameMapper::FillUIName(sTmp, sStyle,
     460           8 :             nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true );
     461           8 :     pRuby->SetCharFmtName(sStyle);
     462           8 :     pRuby->SetCharFmtId(0);
     463           8 :     if (!sStyle.isEmpty())
     464             :     {
     465             :         const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
     466           8 :                 sStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
     467           8 :         pRuby->SetCharFmtId(nId);
     468             :     }
     469          16 :     rItemSet.Put(*pRuby);
     470           8 : }
     471             : 
     472             : bool
     473      515416 : SwUnoCursorHelper::SetCursorPropertyValue(
     474             :         SfxItemPropertySimpleEntry const& rEntry, const uno::Any& rValue,
     475             :         SwPaM & rPam, SfxItemSet & rItemSet)
     476             : throw (lang::IllegalArgumentException, uno::RuntimeException, uno::DeploymentException)
     477             : {
     478      543306 :     if (!(rEntry.nFlags & beans::PropertyAttribute::MAYBEVOID) &&
     479       27890 :         (rValue.getValueType() == ::getCppuVoidType()))
     480             :     {
     481           0 :         return false;
     482             :     }
     483      515416 :     bool bRet = true;
     484      515416 :     switch (rEntry.nWID)
     485             :     {
     486             :         case RES_TXTATR_CHARFMT:
     487       10542 :             lcl_setCharStyle(rPam.GetDoc(), rValue, rItemSet);
     488       10542 :         break;
     489             :         case RES_TXTATR_AUTOFMT:
     490        6684 :             lcl_setAutoStyle(rPam.GetDoc()->GetIStyleAccess(),
     491        6684 :                     rValue, rItemSet, false);
     492        6684 :         break;
     493             :         case FN_UNO_CHARFMT_SEQUENCE:
     494           4 :             lcl_setCharFmtSequence(rPam, rValue);
     495           4 :         break;
     496             :         case FN_UNO_PARA_STYLE :
     497       53916 :             SwUnoCursorHelper::SetTxtFmtColl(rValue, rPam);
     498       53898 :         break;
     499             :         case RES_AUTO_STYLE:
     500        5080 :             lcl_setAutoStyle(rPam.GetDoc()->GetIStyleAccess(),
     501        5080 :                     rValue, rItemSet, true);
     502        5080 :         break;
     503             :         case FN_UNO_PAGE_STYLE:
     504             :             //FIXME nothing here?
     505           0 :         break;
     506             :         case FN_UNO_NUM_START_VALUE:
     507          12 :             lcl_SetNodeNumStart( rPam, rValue );
     508          12 :         break;
     509             :         case FN_UNO_NUM_LEVEL:
     510             :         // #i91601#
     511             :         case FN_UNO_LIST_ID:
     512             :         case FN_UNO_IS_NUMBER:
     513             :         {
     514             :             // multi selection is not considered
     515        3346 :             SwTxtNode *const pTxtNd = rPam.GetNode().GetTxtNode();
     516        3346 :             if (!pTxtNd)
     517             :             {
     518           0 :                 throw lang::IllegalArgumentException();
     519             :             }
     520        3346 :             if (FN_UNO_NUM_LEVEL == rEntry.nWID)
     521             :             {
     522        3144 :                 sal_Int16 nLevel = 0;
     523        3144 :                 if (rValue >>= nLevel)
     524             :                 {
     525        3144 :                     if (nLevel < 0 || MAXLEVEL <= nLevel)
     526             :                     {
     527             :                         throw lang::IllegalArgumentException(
     528           0 :                             "invalid NumberingLevel", 0, 0);
     529             :                     }
     530        3144 :                     pTxtNd->SetAttrListLevel(nLevel);
     531             :                 }
     532             :             }
     533             :             // #i91601#
     534         202 :             else if (FN_UNO_LIST_ID == rEntry.nWID)
     535             :             {
     536         196 :                 OUString sListId;
     537         196 :                 if (rValue >>= sListId)
     538             :                 {
     539         196 :                     pTxtNd->SetListId( sListId );
     540         196 :                 }
     541             :             }
     542           6 :             else if (FN_UNO_IS_NUMBER == rEntry.nWID)
     543             :             {
     544           6 :                 bool bIsNumber(false);
     545           6 :                 if (rValue >>= bIsNumber)
     546             :                 {
     547           6 :                     if (!bIsNumber)
     548             :                     {
     549           6 :                         pTxtNd->SetCountedInList( false );
     550             :                     }
     551             :                 }
     552             :             }
     553             :             //PROPERTY_MAYBEVOID!
     554             :         }
     555        3346 :         break;
     556             :         case FN_NUMBER_NEWSTART:
     557             :         {
     558           2 :             bool bVal = false;
     559           2 :             if (!(rValue >>= bVal))
     560             :             {
     561           0 :                 throw lang::IllegalArgumentException();
     562             :             }
     563           2 :             rPam.GetDoc()->SetNumRuleStart(*rPam.GetPoint(), bVal);
     564             :         }
     565           2 :         break;
     566             :         case FN_UNO_NUM_RULES:
     567        2610 :             SwUnoCursorHelper::setNumberingProperty(rValue, rPam);
     568        2610 :         break;
     569             :         case RES_PARATR_DROP:
     570             :         {
     571          12 :             if (MID_DROPCAP_CHAR_STYLE_NAME == rEntry.nMemberId)
     572             :             {
     573          12 :                 lcl_setDropcapCharStyle(rPam, rItemSet, rValue);
     574             :             }
     575             :             else
     576             :             {
     577           0 :                 bRet = false;
     578             :             }
     579             :         }
     580          12 :         break;
     581             :         case RES_TXTATR_CJK_RUBY:
     582             :         {
     583         176 :             if (MID_RUBY_CHARSTYLE == rEntry.nMemberId)
     584             :             {
     585           8 :                 lcl_setRubyCharstyle(rItemSet, rValue);
     586             :             }
     587             :             else
     588             :             {
     589         168 :                 bRet = false;
     590             :             }
     591             :         }
     592         176 :         break;
     593             :         case RES_PAGEDESC:
     594             :         {
     595        4206 :             if (MID_PAGEDESC_PAGEDESCNAME == rEntry.nMemberId)
     596             :             {
     597             :                 SwUnoCursorHelper::SetPageDesc(
     598        3996 :                         rValue, *rPam.GetDoc(), rItemSet);
     599             :             }
     600             :             else
     601             :             {
     602         210 :                 bRet = false;
     603             :             }
     604             :         }
     605        4206 :         break;
     606             :         default:
     607      428826 :             bRet = false;
     608             :     }
     609      515398 :     return bRet;
     610             : }
     611             : 
     612             : SwFmtColl *
     613         180 : SwUnoCursorHelper::GetCurTxtFmtColl(SwPaM & rPaM, const bool bConditional)
     614             : {
     615             :     static const sal_uLong nMaxLookup = 1000;
     616         180 :     SwFmtColl *pFmt = 0;
     617         180 :     bool bError = false;
     618         180 :     SwPaM *pTmpCrsr = &rPaM;
     619         180 :     do
     620             :     {
     621         180 :         const sal_uLong nSttNd = pTmpCrsr->Start()->nNode.GetIndex();
     622         180 :         const sal_uLong nEndNd = pTmpCrsr->End()->nNode.GetIndex();
     623             : 
     624         180 :         if( nEndNd - nSttNd >= nMaxLookup )
     625             :         {
     626           0 :             pFmt = 0;
     627           0 :             break;
     628             :         }
     629             : 
     630         180 :         const SwNodes& rNds = rPaM.GetDoc()->GetNodes();
     631         360 :         for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
     632             :         {
     633         180 :             SwTxtNode const*const pNd = rNds[ n ]->GetTxtNode();
     634         180 :             if( pNd )
     635             :             {
     636             :                 SwFmtColl *const pNdFmt = (bConditional)
     637         172 :                     ? pNd->GetFmtColl() : &pNd->GetAnyFmtColl();
     638         172 :                 if( !pFmt )
     639             :                 {
     640         172 :                     pFmt = pNdFmt;
     641             :                 }
     642           0 :                 else if( pFmt != pNdFmt )
     643             :                 {
     644           0 :                     bError = true;
     645           0 :                     break;
     646             :                 }
     647             :             }
     648             :         }
     649             : 
     650         180 :         pTmpCrsr = static_cast<SwPaM*>(pTmpCrsr->GetNext());
     651             :     } while ( pTmpCrsr != &rPaM );
     652         180 :     return (bError) ? 0 : pFmt;
     653             : }
     654             : 
     655             : class SwXTextCursor::Impl
     656             :     : public SwClient
     657             : {
     658             : 
     659             : public:
     660             :     const SfxItemPropertySet &  m_rPropSet;
     661             :     const enum CursorType       m_eType;
     662             :     const uno::Reference< text::XText > m_xParentText;
     663             :     bool                        m_bIsDisposed;
     664             : 
     665      325554 :     Impl(   SwDoc & rDoc,
     666             :             const enum CursorType eType,
     667             :             uno::Reference<text::XText> xParent,
     668             :             SwPosition const& rPoint, SwPosition const*const pMark)
     669      325554 :         : SwClient(rDoc.CreateUnoCrsr(rPoint, false))
     670      325554 :         , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
     671             :         , m_eType(eType)
     672             :         , m_xParentText(xParent)
     673      651108 :         , m_bIsDisposed(false)
     674             :     {
     675      325554 :         if (pMark)
     676             :         {
     677       26958 :             GetCursor()->SetMark();
     678       26958 :             *GetCursor()->GetMark() = *pMark;
     679             :         }
     680      325554 :     }
     681             : 
     682      976662 :     virtual ~Impl() {
     683             :         // Impl owns the cursor; delete it here: SolarMutex is locked
     684      325554 :         delete GetRegisteredIn();
     685      651108 :     }
     686             : 
     687     1536444 :     SwUnoCrsr * GetCursor() {
     688             :         return (m_bIsDisposed) ? 0 :
     689     1536444 :             static_cast<SwUnoCrsr*>(const_cast<SwModify*>(GetRegisteredIn()));
     690             :     }
     691             : 
     692      781488 :     SwUnoCrsr & GetCursorOrThrow() {
     693      781488 :         SwUnoCrsr *const pUnoCursor( GetCursor() );
     694      781488 :         if (!pUnoCursor) {
     695           0 :             throw uno::RuntimeException("SwXTextCursor: disposed or invalid", 0);
     696             :         }
     697      781488 :         return *pUnoCursor;
     698             :     }
     699             : 
     700      327290 :     void Invalidate() {
     701      327290 :         m_bIsDisposed = true;
     702      327290 :     }
     703             : protected:
     704             :     // SwClient
     705             :     virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
     706             : 
     707             : };
     708             : 
     709      327290 : void SwXTextCursor::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     710             : {
     711      327290 :     ClientModify(this, pOld, pNew);
     712             : 
     713      654580 :     if (!GetRegisteredIn() ||
     714             :         // if the cursor leaves its designated section, it becomes invalid
     715        1736 :         ((pOld != NULL) && (pOld->Which() == RES_UNOCURSOR_LEAVES_SECTION)))
     716             :     {
     717      327290 :         Invalidate();
     718             :     }
     719      327290 : }
     720             : 
     721           0 : SwUnoCrsr const* SwXTextCursor::GetCursor() const
     722             : {
     723           0 :     return m_pImpl->GetCursor();
     724             : }
     725             : 
     726      131724 : SwUnoCrsr * SwXTextCursor::GetCursor()
     727             : {
     728      131724 :     return m_pImpl->GetCursor();
     729             : }
     730             : 
     731           0 : SwPaM const* SwXTextCursor::GetPaM() const
     732             : {
     733           0 :     return m_pImpl->GetCursor();
     734             : }
     735             : 
     736      166736 : SwPaM * SwXTextCursor::GetPaM()
     737             : {
     738      166736 :     return m_pImpl->GetCursor();
     739             : }
     740             : 
     741           0 : SwDoc const* SwXTextCursor::GetDoc() const
     742             : {
     743           0 :     return m_pImpl->GetCursor() ? m_pImpl->GetCursor()->GetDoc() : 0;
     744             : }
     745             : 
     746      192364 : SwDoc * SwXTextCursor::GetDoc()
     747             : {
     748      192364 :     return m_pImpl->GetCursor() ? m_pImpl->GetCursor()->GetDoc() : 0;
     749             : }
     750             : 
     751      325548 : SwXTextCursor::SwXTextCursor(
     752             :         SwDoc & rDoc,
     753             :         uno::Reference< text::XText > const& xParent,
     754             :         const enum CursorType eType,
     755             :         const SwPosition& rPos,
     756             :         SwPosition const*const pMark)
     757      325548 :     : m_pImpl( new Impl(rDoc, eType, xParent, rPos, pMark) )
     758             : {
     759      325548 : }
     760             : 
     761           6 : SwXTextCursor::SwXTextCursor(uno::Reference< text::XText > const& xParent,
     762             :         SwPaM const& rSourceCursor, const enum CursorType eType)
     763             :     : m_pImpl( new Impl(*rSourceCursor.GetDoc(), eType,
     764             :                 xParent, *rSourceCursor.GetPoint(),
     765           6 :                 rSourceCursor.HasMark() ? rSourceCursor.GetMark() : 0) )
     766             : {
     767           6 : }
     768             : 
     769      651108 : SwXTextCursor::~SwXTextCursor()
     770             : {
     771      651108 : }
     772             : 
     773       13594 : void SwXTextCursor::DeleteAndInsert(const OUString& rText,
     774             :         const bool bForceExpandHints)
     775             : {
     776       13594 :     SwUnoCrsr *const pUnoCrsr = m_pImpl->GetCursor();
     777       13594 :     if(pUnoCrsr)
     778             :     {
     779             :         // Start/EndAction
     780       13594 :         SwDoc* pDoc = pUnoCrsr->GetDoc();
     781       13594 :         UnoActionContext aAction(pDoc);
     782       13594 :         const sal_Int32 nTxtLen = rText.getLength();
     783       13594 :         pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
     784       13594 :         SwCursor * pCurrent = pUnoCrsr;
     785       13594 :         do
     786             :         {
     787       13594 :             if (pCurrent->HasMark())
     788             :             {
     789        8202 :                 pDoc->getIDocumentContentOperations().DeleteAndJoin(*pCurrent);
     790             :             }
     791       13594 :             if(nTxtLen)
     792             :             {
     793             :                 const bool bSuccess(
     794             :                     SwUnoCursorHelper::DocInsertStringSplitCR(
     795        5572 :                         *pDoc, *pCurrent, rText, bForceExpandHints ) );
     796             :                 OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." );
     797             :                 (void) bSuccess;
     798             : 
     799        5572 :                 SwUnoCursorHelper::SelectPam(*pUnoCrsr, true);
     800        5572 :                 pCurrent->Left(rText.getLength(),
     801        5572 :                         CRSR_SKIP_CHARS, false, false);
     802             :             }
     803       13594 :             pCurrent = static_cast<SwCursor *>(pCurrent->GetNext());
     804       13594 :         } while (pCurrent != pUnoCrsr);
     805       13594 :         pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
     806             :     }
     807       13594 : }
     808             : 
     809             : enum ForceIntoMetaMode { META_CHECK_BOTH, META_INIT_START, META_INIT_END };
     810             : 
     811             : static bool
     812         438 : lcl_ForceIntoMeta(SwPaM & rCursor,
     813             :         uno::Reference<text::XText> const & xParentText,
     814             :         const enum ForceIntoMetaMode eMode)
     815             : {
     816         438 :     bool bRet( true ); // means not forced in META_CHECK_BOTH
     817         438 :     SwXMeta const * const pXMeta( dynamic_cast<SwXMeta*>(xParentText.get()) );
     818             :     OSL_ENSURE(pXMeta, "no parent?");
     819         438 :     if (!pXMeta)
     820           0 :         throw uno::RuntimeException();
     821             :     SwTxtNode * pTxtNode;
     822             :     sal_Int32 nStart;
     823             :     sal_Int32 nEnd;
     824         438 :     const bool bSuccess( pXMeta->SetContentRange(pTxtNode, nStart, nEnd) );
     825             :     OSL_ENSURE(bSuccess, "no pam?");
     826         438 :     if (!bSuccess)
     827           0 :         throw uno::RuntimeException();
     828             :     // force the cursor back into the meta if it has moved outside
     829         438 :     SwPosition start(*pTxtNode, nStart);
     830         876 :     SwPosition end(*pTxtNode, nEnd);
     831         438 :     switch (eMode)
     832             :     {
     833             :         case META_INIT_START:
     834         150 :             *rCursor.GetPoint() = start;
     835         150 :             break;
     836             :         case META_INIT_END:
     837         228 :             *rCursor.GetPoint() = end;
     838         228 :             break;
     839             :         case META_CHECK_BOTH:
     840          60 :             if (*rCursor.Start() < start)
     841             :             {
     842          12 :                 *rCursor.Start() = start;
     843          12 :                 bRet = false;
     844             :             }
     845          60 :             if (*rCursor.End() > end)
     846             :             {
     847          10 :                 *rCursor.End() = end;
     848          10 :                 bRet = false;
     849             :             }
     850          60 :             break;
     851             :     }
     852         876 :     return bRet;
     853             : }
     854             : 
     855         374 : bool SwXTextCursor::IsAtEndOfMeta() const
     856             : {
     857         374 :     if (CURSOR_META == m_pImpl->m_eType)
     858             :     {
     859         106 :         SwUnoCrsr const * const pCursor( m_pImpl->GetCursor() );
     860             :         SwXMeta const*const pXMeta(
     861         106 :                 dynamic_cast<SwXMeta*>(m_pImpl->m_xParentText.get()) );
     862             :         OSL_ENSURE(pXMeta, "no meta?");
     863         106 :         if (pCursor && pXMeta)
     864             :         {
     865             :             SwTxtNode * pTxtNode;
     866             :             sal_Int32 nStart;
     867             :             sal_Int32 nEnd;
     868             :             const bool bSuccess(
     869         106 :                     pXMeta->SetContentRange(pTxtNode, nStart, nEnd) );
     870             :             OSL_ENSURE(bSuccess, "no pam?");
     871         106 :             if (bSuccess)
     872             :             {
     873         106 :                 const SwPosition end(*pTxtNode, nEnd);
     874         212 :                 if (   (*pCursor->GetPoint() == end)
     875         106 :                     || (*pCursor->GetMark()  == end))
     876             :                 {
     877          60 :                     return true;
     878          46 :                 }
     879             :             }
     880             :         }
     881             :     }
     882         314 :     return false;
     883             : }
     884             : 
     885           0 : OUString SwXTextCursor::getImplementationName() throw (uno::RuntimeException, std::exception)
     886             : {
     887           0 :     return OUString("SwXTextCursor");
     888             : }
     889             : 
     890             : static char const*const g_ServicesTextCursor[] =
     891             : {
     892             :     "com.sun.star.text.TextCursor",
     893             :     "com.sun.star.style.CharacterProperties",
     894             :     "com.sun.star.style.CharacterPropertiesAsian",
     895             :     "com.sun.star.style.CharacterPropertiesComplex",
     896             :     "com.sun.star.style.ParagraphProperties",
     897             :     "com.sun.star.style.ParagraphPropertiesAsian",
     898             :     "com.sun.star.style.ParagraphPropertiesComplex",
     899             :     "com.sun.star.text.TextSortable",
     900             : };
     901             : 
     902             : static const size_t g_nServicesTextCursor(
     903             :     sizeof(g_ServicesTextCursor)/sizeof(g_ServicesTextCursor[0]));
     904             : 
     905           8 : sal_Bool SAL_CALL SwXTextCursor::supportsService(const OUString& rServiceName)
     906             : throw (uno::RuntimeException, std::exception)
     907             : {
     908           8 :     return cppu::supportsService(this, rServiceName);
     909             : }
     910             : 
     911             : uno::Sequence< OUString > SAL_CALL
     912           8 : SwXTextCursor::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
     913             : {
     914             :     return ::sw::GetSupportedServiceNamesImpl(
     915           8 :             g_nServicesTextCursor, g_ServicesTextCursor);
     916             : }
     917             : 
     918             : namespace
     919             : {
     920             :     class theSwXTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextCursorUnoTunnelId > {};
     921             : }
     922             : 
     923      656902 : const uno::Sequence< sal_Int8 > & SwXTextCursor::getUnoTunnelId()
     924             : {
     925      656902 :     return theSwXTextCursorUnoTunnelId::get().getSeq();
     926             : }
     927             : 
     928             : sal_Int64 SAL_CALL
     929      569604 : SwXTextCursor::getSomething(const uno::Sequence< sal_Int8 >& rId)
     930             : throw (uno::RuntimeException, std::exception)
     931             : {
     932      569604 :     const sal_Int64 nRet( ::sw::UnoTunnelImpl<SwXTextCursor>(rId, this) );
     933      569604 :     return (nRet) ? nRet : OTextCursorHelper::getSomething(rId);
     934             : }
     935             : 
     936           2 : void SAL_CALL SwXTextCursor::collapseToStart() throw (uno::RuntimeException, std::exception)
     937             : {
     938           2 :     SolarMutexGuard aGuard;
     939             : 
     940           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
     941             : 
     942           2 :     if (rUnoCursor.HasMark())
     943             :     {
     944           2 :         if (*rUnoCursor.GetPoint() > *rUnoCursor.GetMark())
     945             :         {
     946           2 :             rUnoCursor.Exchange();
     947             :         }
     948           2 :         rUnoCursor.DeleteMark();
     949           2 :     }
     950           2 : }
     951             : 
     952           4 : void SAL_CALL SwXTextCursor::collapseToEnd() throw (uno::RuntimeException, std::exception)
     953             : {
     954           4 :     SolarMutexGuard aGuard;
     955             : 
     956           4 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
     957             : 
     958           4 :     if (rUnoCursor.HasMark())
     959             :     {
     960           2 :         if (*rUnoCursor.GetPoint() < *rUnoCursor.GetMark())
     961             :         {
     962           0 :             rUnoCursor.Exchange();
     963             :         }
     964           2 :         rUnoCursor.DeleteMark();
     965           4 :     }
     966           4 : }
     967             : 
     968        4152 : sal_Bool SAL_CALL SwXTextCursor::isCollapsed() throw (uno::RuntimeException, std::exception)
     969             : {
     970        4152 :     SolarMutexGuard aGuard;
     971             : 
     972        4152 :     bool bRet = true;
     973        4152 :     SwUnoCrsr *const pUnoCrsr = m_pImpl->GetCursor();
     974        4152 :     if(pUnoCrsr && pUnoCrsr->GetMark())
     975             :     {
     976        4152 :         bRet = (*pUnoCrsr->GetPoint() == *pUnoCrsr->GetMark());
     977             :     }
     978        4152 :     return bRet;
     979             : }
     980             : 
     981             : sal_Bool SAL_CALL
     982       59786 : SwXTextCursor::goLeft(sal_Int16 nCount, sal_Bool Expand)
     983             : throw (uno::RuntimeException, std::exception)
     984             : {
     985       59786 :     SolarMutexGuard aGuard;
     986             : 
     987       59786 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
     988             : 
     989       59786 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
     990       59786 :     bool bRet = rUnoCursor.Left( nCount, CRSR_SKIP_CHARS, false, false);
     991       59786 :     if (CURSOR_META == m_pImpl->m_eType)
     992             :     {
     993           8 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
     994           8 :                     META_CHECK_BOTH)
     995           8 :             && bRet;
     996             :     }
     997       59786 :     return bRet;
     998             : }
     999             : 
    1000             : sal_Bool SAL_CALL
    1001        7904 : SwXTextCursor::goRight(sal_Int16 nCount, sal_Bool Expand)
    1002             : throw (uno::RuntimeException, std::exception)
    1003             : {
    1004        7904 :     SolarMutexGuard aGuard;
    1005             : 
    1006        7904 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1007             : 
    1008        7904 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1009        7904 :     bool bRet = rUnoCursor.Right(nCount, CRSR_SKIP_CHARS, false, false);
    1010        7904 :     if (CURSOR_META == m_pImpl->m_eType)
    1011             :     {
    1012           8 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1013           8 :                     META_CHECK_BOTH)
    1014           8 :             && bRet;
    1015             :     }
    1016        7904 :     return bRet;
    1017             : }
    1018             : 
    1019             : void SAL_CALL
    1020      219098 : SwXTextCursor::gotoStart(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1021             : {
    1022      219098 :     SolarMutexGuard aGuard;
    1023             : 
    1024      219098 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1025             : 
    1026      219098 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1027      219098 :     if (CURSOR_BODY == m_pImpl->m_eType)
    1028             :     {
    1029      187246 :         rUnoCursor.Move( fnMoveBackward, fnGoDoc );
    1030             :         //check, that the cursor is not in a table
    1031      187246 :         SwTableNode * pTblNode = rUnoCursor.GetNode().FindTableNode();
    1032      187246 :         SwCntntNode * pCNode = 0;
    1033      374684 :         while (pTblNode)
    1034             :         {
    1035         192 :             rUnoCursor.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
    1036         192 :             pCNode = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
    1037         192 :             pTblNode = (pCNode) ? pCNode->FindTableNode() : 0;
    1038             :         }
    1039      187246 :         if (pCNode)
    1040             :         {
    1041         192 :             rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0);
    1042             :         }
    1043             :         SwStartNode const*const pTmp =
    1044      187246 :             rUnoCursor.GetNode().StartOfSectionNode();
    1045      187246 :         if (pTmp->IsSectionNode())
    1046             :         {
    1047             :             SwSectionNode const*const pSectionStartNode =
    1048         536 :                 static_cast<SwSectionNode const*>(pTmp);
    1049         536 :             if (pSectionStartNode->GetSection().IsHiddenFlag())
    1050             :             {
    1051           0 :                 pCNode = GetDoc()->GetNodes().GoNextSection(
    1052           0 :                         &rUnoCursor.GetPoint()->nNode, true, false);
    1053           0 :                 if (pCNode)
    1054             :                 {
    1055           0 :                     rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0);
    1056             :                 }
    1057             :             }
    1058             :         }
    1059             :     }
    1060       63704 :     else if (   (CURSOR_FRAME   == m_pImpl->m_eType)
    1061       31070 :             ||  (CURSOR_TBLTEXT == m_pImpl->m_eType)
    1062         314 :             ||  (CURSOR_HEADER  == m_pImpl->m_eType)
    1063         298 :             ||  (CURSOR_FOOTER  == m_pImpl->m_eType)
    1064         272 :             ||  (CURSOR_FOOTNOTE== m_pImpl->m_eType)
    1065       32002 :             ||  (CURSOR_REDLINE == m_pImpl->m_eType))
    1066             :     {
    1067       31702 :         rUnoCursor.MoveSection(fnSectionCurr, fnSectionStart);
    1068             :     }
    1069         150 :     else if (CURSOR_META == m_pImpl->m_eType)
    1070             :     {
    1071         150 :         lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_START);
    1072      219098 :     }
    1073      219098 : }
    1074             : 
    1075             : void SAL_CALL
    1076      202086 : SwXTextCursor::gotoEnd(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1077             : {
    1078      202086 :     SolarMutexGuard aGuard;
    1079             : 
    1080      202086 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1081             : 
    1082      202086 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1083      202086 :     if (CURSOR_BODY == m_pImpl->m_eType)
    1084             :     {
    1085      151780 :         rUnoCursor.Move( fnMoveForward, fnGoDoc );
    1086             :     }
    1087      100612 :     else if (   (CURSOR_FRAME   == m_pImpl->m_eType)
    1088       41704 :             ||  (CURSOR_TBLTEXT == m_pImpl->m_eType)
    1089       10334 :             ||  (CURSOR_HEADER  == m_pImpl->m_eType)
    1090        5860 :             ||  (CURSOR_FOOTER  == m_pImpl->m_eType)
    1091         522 :             ||  (CURSOR_FOOTNOTE== m_pImpl->m_eType)
    1092       50534 :             ||  (CURSOR_REDLINE == m_pImpl->m_eType))
    1093             :     {
    1094       50078 :         rUnoCursor.MoveSection( fnSectionCurr, fnSectionEnd);
    1095             :     }
    1096         228 :     else if (CURSOR_META == m_pImpl->m_eType)
    1097             :     {
    1098         228 :         lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_END);
    1099      202086 :     }
    1100      202086 : }
    1101             : 
    1102             : void SAL_CALL
    1103      119732 : SwXTextCursor::gotoRange(
    1104             :     const uno::Reference< text::XTextRange > & xRange, sal_Bool bExpand)
    1105             : throw (uno::RuntimeException, std::exception)
    1106             : {
    1107      119732 :     SolarMutexGuard aGuard;
    1108             : 
    1109      119732 :     if (!xRange.is())
    1110             :     {
    1111           2 :         throw uno::RuntimeException();
    1112             :     }
    1113             : 
    1114      119730 :     SwUnoCrsr & rOwnCursor( m_pImpl->GetCursorOrThrow() );
    1115             : 
    1116      239460 :     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xRange, uno::UNO_QUERY);
    1117      119730 :     SwXTextRange* pRange = 0;
    1118      119730 :     OTextCursorHelper* pCursor = 0;
    1119      119730 :     if(xRangeTunnel.is())
    1120             :     {
    1121      119730 :         pRange  = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
    1122             :         pCursor =
    1123      119730 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
    1124             :     }
    1125             : 
    1126      119730 :     if (!pRange && !pCursor)
    1127             :     {
    1128           0 :         throw uno::RuntimeException();
    1129             :     }
    1130             : 
    1131      239460 :     SwPaM aPam(GetDoc()->GetNodes());
    1132      119730 :     const SwPaM * pPam(0);
    1133      119730 :     if (pCursor)
    1134             :     {
    1135       92632 :         pPam = pCursor->GetPaM();
    1136             :     }
    1137       27098 :     else if (pRange)
    1138             :     {
    1139       27098 :         if (pRange->GetPositions(aPam))
    1140             :         {
    1141       27098 :             pPam = & aPam;
    1142             :         }
    1143             :     }
    1144             : 
    1145      119730 :     if (!pPam)
    1146             :     {
    1147           0 :         throw uno::RuntimeException();
    1148             :     }
    1149             : 
    1150             :     {
    1151      119730 :         SwStartNodeType eSearchNodeType = SwNormalStartNode;
    1152      119730 :         switch (m_pImpl->m_eType)
    1153             :         {
    1154        3734 :         case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
    1155        1818 :         case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
    1156         934 :         case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
    1157        1148 :         case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
    1158        1532 :         case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
    1159             :             //case CURSOR_INVALID:
    1160             :             //case CURSOR_BODY:
    1161             :         default:
    1162             :             ;
    1163             :         }
    1164             : 
    1165      119730 :         const SwStartNode* pOwnStartNode = rOwnCursor.GetNode().FindSttNodeByType(eSearchNodeType);
    1166      244948 :         while ( pOwnStartNode != NULL
    1167      125218 :                 && pOwnStartNode->IsSectionNode())
    1168             :         {
    1169        5488 :             pOwnStartNode = pOwnStartNode->StartOfSectionNode();
    1170             :         }
    1171             : 
    1172             :         const SwStartNode* pTmp =
    1173      119730 :             pPam->GetNode().FindSttNodeByType(eSearchNodeType);
    1174      250064 :         while ( pTmp != NULL
    1175      130334 :                 && pTmp->IsSectionNode() )
    1176             :         {
    1177       10604 :             pTmp = pTmp->StartOfSectionNode();
    1178             :         }
    1179             : 
    1180      119730 :         if ( eSearchNodeType == SwTableBoxStartNode )
    1181             :         {
    1182        1818 :             if (!pOwnStartNode || !pTmp)
    1183             :             {
    1184           0 :                 throw uno::RuntimeException();
    1185             :             }
    1186             : 
    1187        1818 :             if ( pOwnStartNode->FindTableNode() != pTmp->FindTableNode() )
    1188             :             {
    1189           0 :                 throw uno::RuntimeException();
    1190             :             }
    1191             :         }
    1192             :         else
    1193             :         {
    1194      117912 :             if ( pOwnStartNode != pTmp )
    1195             :             {
    1196           2 :                 throw uno::RuntimeException();
    1197             :             }
    1198             :         }
    1199             :     }
    1200             : 
    1201      119728 :     if (CURSOR_META == m_pImpl->m_eType)
    1202             :     {
    1203          10 :         SwPaM CopyPam(*pPam->GetMark(), *pPam->GetPoint());
    1204             :         const bool bNotForced( lcl_ForceIntoMeta(
    1205          10 :                     CopyPam, m_pImpl->m_xParentText, META_CHECK_BOTH) );
    1206          10 :         if (!bNotForced)
    1207             :         {
    1208             :             throw uno::RuntimeException(
    1209             :                 "gotoRange: parameter range not contained in nesting"
    1210             :                     " text content for which this cursor was created",
    1211           2 :                 static_cast<text::XWordCursor*>(this));
    1212          10 :         }
    1213             :     }
    1214             : 
    1215             :     // selection has to be expanded here
    1216      119726 :     if(bExpand)
    1217             :     {
    1218             :         // cursor should include its previous range plus the given range
    1219       24250 :         const SwPosition aOwnLeft(*rOwnCursor.Start());
    1220       48500 :         const SwPosition aOwnRight(*rOwnCursor.End());
    1221       24250 :         SwPosition const& rParamLeft  = *pPam->Start();
    1222       24250 :         SwPosition const& rParamRight = *pPam->End();
    1223             : 
    1224             :         // now there are four SwPositions,
    1225             :         // two of them are going to be used, but which ones?
    1226       46422 :         *rOwnCursor.GetPoint() = (aOwnRight > rParamRight)
    1227       46422 :             ? aOwnRight : *rOwnCursor.GetPoint() = rParamRight;
    1228       24250 :         rOwnCursor.SetMark();
    1229       37658 :         *rOwnCursor.GetMark() = (aOwnLeft < rParamLeft)
    1230       61908 :             ? aOwnLeft : *rOwnCursor.GetMark() = rParamLeft;
    1231             :     }
    1232             :     else
    1233             :     {
    1234             :         // cursor should be the given range
    1235       95476 :         *rOwnCursor.GetPoint() = *pPam->GetPoint();
    1236       95476 :         if (pPam->HasMark())
    1237             :         {
    1238        3176 :             rOwnCursor.SetMark();
    1239        3176 :             *rOwnCursor.GetMark() = *pPam->GetMark();
    1240             :         }
    1241             :         else
    1242             :         {
    1243       92300 :             rOwnCursor.DeleteMark();
    1244             :         }
    1245      119732 :     }
    1246      119726 : }
    1247             : 
    1248           2 : sal_Bool SAL_CALL SwXTextCursor::isStartOfWord() throw (uno::RuntimeException, std::exception)
    1249             : {
    1250           2 :     SolarMutexGuard aGuard;
    1251             : 
    1252           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1253             : 
    1254             :     const bool bRet =
    1255           2 :         rUnoCursor.IsStartWordWT( i18n::WordType::DICTIONARY_WORD );
    1256           2 :     return bRet;
    1257             : }
    1258             : 
    1259           2 : sal_Bool SAL_CALL SwXTextCursor::isEndOfWord() throw (uno::RuntimeException, std::exception)
    1260             : {
    1261           2 :     SolarMutexGuard aGuard;
    1262             : 
    1263           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1264             : 
    1265             :     const bool bRet =
    1266           2 :         rUnoCursor.IsEndWordWT( i18n::WordType::DICTIONARY_WORD );
    1267           2 :     return bRet;
    1268             : }
    1269             : 
    1270             : sal_Bool SAL_CALL
    1271           8 : SwXTextCursor::gotoNextWord(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1272             : {
    1273           8 :     SolarMutexGuard aGuard;
    1274             : 
    1275           8 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1276             : 
    1277             :     // problems arise when a paragraph starts with something other than a word
    1278           8 :     bool bRet = false;
    1279             :     // remember old position to check if cursor has moved
    1280             :     // since the called functions are sometimes a bit unreliable
    1281             :     // in specific cases...
    1282           8 :     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
    1283           8 :     SwNode      *const pOldNode   = &pPoint->nNode.GetNode();
    1284           8 :     sal_Int32 const nOldIndex  = pPoint->nContent.GetIndex();
    1285             : 
    1286           8 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1287             :     // end of paragraph
    1288          16 :     if (rUnoCursor.GetCntntNode() &&
    1289           8 :             (pPoint->nContent == rUnoCursor.GetCntntNode()->Len()))
    1290             :     {
    1291           0 :         rUnoCursor.Right(1, CRSR_SKIP_CHARS, false, false);
    1292             :     }
    1293             :     else
    1294             :     {
    1295             :         const bool bTmp =
    1296           8 :             rUnoCursor.GoNextWordWT( i18n::WordType::DICTIONARY_WORD );
    1297             :         // if there is no next word within the current paragraph
    1298             :         // try to go to the start of the next paragraph
    1299           8 :         if (!bTmp)
    1300             :         {
    1301           0 :             rUnoCursor.MovePara(fnParaNext, fnParaStart);
    1302             :         }
    1303             :     }
    1304             : 
    1305             :     // return true if cursor has moved
    1306          16 :     bRet =  (&pPoint->nNode.GetNode() != pOldNode)  ||
    1307          16 :             (pPoint->nContent.GetIndex() != nOldIndex);
    1308           8 :     if (bRet && (CURSOR_META == m_pImpl->m_eType))
    1309             :     {
    1310           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1311           4 :                     META_CHECK_BOTH);
    1312             :     }
    1313             : 
    1314           8 :     return bRet;
    1315             : }
    1316             : 
    1317             : sal_Bool SAL_CALL
    1318          10 : SwXTextCursor::gotoPreviousWord(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1319             : {
    1320          10 :     SolarMutexGuard aGuard;
    1321             : 
    1322          10 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1323             : 
    1324             :     // white spaces create problems on the paragraph start
    1325          10 :     bool bRet = false;
    1326          10 :     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
    1327          10 :     SwNode      *const pOldNode   = &pPoint->nNode.GetNode();
    1328          10 :     sal_Int32 const nOldIndex  = pPoint->nContent.GetIndex();
    1329             : 
    1330          10 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1331             :     // start of paragraph?
    1332          10 :     if (pPoint->nContent == 0)
    1333             :     {
    1334           0 :         rUnoCursor.Left(1, CRSR_SKIP_CHARS, false, false);
    1335             :     }
    1336             :     else
    1337             :     {
    1338          10 :         rUnoCursor.GoPrevWordWT( i18n::WordType::DICTIONARY_WORD );
    1339          10 :         if (pPoint->nContent == 0)
    1340             :         {
    1341           4 :             rUnoCursor.Left(1, CRSR_SKIP_CHARS, false, false);
    1342             :         }
    1343             :     }
    1344             : 
    1345             :     // return true if cursor has moved
    1346          18 :     bRet =  (&pPoint->nNode.GetNode() != pOldNode)  ||
    1347          18 :             (pPoint->nContent.GetIndex() != nOldIndex);
    1348          10 :     if (bRet && (CURSOR_META == m_pImpl->m_eType))
    1349             :     {
    1350           6 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1351           6 :                     META_CHECK_BOTH);
    1352             :     }
    1353             : 
    1354          10 :     return bRet;
    1355             : }
    1356             : 
    1357             : sal_Bool SAL_CALL
    1358          24 : SwXTextCursor::gotoEndOfWord(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1359             : {
    1360          24 :     SolarMutexGuard aGuard;
    1361             : 
    1362          24 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1363             : 
    1364          24 :     bool bRet = false;
    1365          24 :     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
    1366          24 :     SwNode      &      rOldNode   = pPoint->nNode.GetNode();
    1367          24 :     sal_Int32 const nOldIndex  = pPoint->nContent.GetIndex();
    1368             : 
    1369          24 :     const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD;
    1370          24 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1371          24 :     if (!rUnoCursor.IsEndWordWT( nWordType ))
    1372             :     {
    1373          24 :         rUnoCursor.GoEndWordWT( nWordType );
    1374             :     }
    1375             : 
    1376             :     // restore old cursor if we are not at the end of a word by now
    1377             :     // otherwise use current one
    1378          24 :     bRet = rUnoCursor.IsEndWordWT( nWordType );
    1379          24 :     if (!bRet)
    1380             :     {
    1381           0 :         pPoint->nNode       = rOldNode;
    1382           0 :         pPoint->nContent    = nOldIndex;
    1383             :     }
    1384          24 :     else if (CURSOR_META == m_pImpl->m_eType)
    1385             :     {
    1386           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1387           4 :                     META_CHECK_BOTH);
    1388             :     }
    1389             : 
    1390          24 :     return bRet;
    1391             : }
    1392             : 
    1393             : sal_Bool SAL_CALL
    1394          12 : SwXTextCursor::gotoStartOfWord(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1395             : {
    1396          12 :     SolarMutexGuard aGuard;
    1397             : 
    1398          12 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1399             : 
    1400          12 :     bool bRet = false;
    1401          12 :     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
    1402          12 :     SwNode      &      rOldNode   = pPoint->nNode.GetNode();
    1403          12 :     sal_Int32 const nOldIndex  = pPoint->nContent.GetIndex();
    1404             : 
    1405          12 :     const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD;
    1406          12 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1407          12 :     if (!rUnoCursor.IsStartWordWT( nWordType ))
    1408             :     {
    1409          10 :         rUnoCursor.GoStartWordWT( nWordType );
    1410             :     }
    1411             : 
    1412             :     // restore old cursor if we are not at the start of a word by now
    1413             :     // otherwise use current one
    1414          12 :     bRet = rUnoCursor.IsStartWordWT( nWordType );
    1415          12 :     if (!bRet)
    1416             :     {
    1417           0 :         pPoint->nNode       = rOldNode;
    1418           0 :         pPoint->nContent    = nOldIndex;
    1419             :     }
    1420          12 :     else if (CURSOR_META == m_pImpl->m_eType)
    1421             :     {
    1422           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1423           4 :                     META_CHECK_BOTH);
    1424             :     }
    1425             : 
    1426          12 :     return bRet;
    1427             : }
    1428             : 
    1429             : sal_Bool SAL_CALL
    1430           2 : SwXTextCursor::isStartOfSentence() throw (uno::RuntimeException, std::exception)
    1431             : {
    1432           2 :     SolarMutexGuard aGuard;
    1433             : 
    1434           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1435             : 
    1436             :     // start of paragraph?
    1437           2 :     bool bRet = rUnoCursor.GetPoint()->nContent == 0;
    1438             :     // with mark ->no sentence start
    1439             :     // (check if cursor is no selection, i.e. it does not have
    1440             :     // a mark or else point and mark are identical)
    1441           2 :     if (!bRet && (!rUnoCursor.HasMark() ||
    1442           0 :                     *rUnoCursor.GetPoint() == *rUnoCursor.GetMark()))
    1443             :     {
    1444           0 :         SwCursor aCrsr(*rUnoCursor.GetPoint(),0,false);
    1445           0 :         SwPosition aOrigPos = *aCrsr.GetPoint();
    1446           0 :         aCrsr.GoSentence(SwCursor::START_SENT );
    1447           0 :         bRet = aOrigPos == *aCrsr.GetPoint();
    1448             :     }
    1449           2 :     return bRet;
    1450             : }
    1451             : 
    1452             : sal_Bool SAL_CALL
    1453          12 : SwXTextCursor::isEndOfSentence() throw (uno::RuntimeException, std::exception)
    1454             : {
    1455          12 :     SolarMutexGuard aGuard;
    1456             : 
    1457          12 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1458             : 
    1459             :     // end of paragraph?
    1460          24 :     bool bRet = rUnoCursor.GetCntntNode() &&
    1461          24 :         (rUnoCursor.GetPoint()->nContent == rUnoCursor.GetCntntNode()->Len());
    1462             :     // with mark->no sentence end
    1463             :     // (check if cursor is no selection, i.e. it does not have
    1464             :     // a mark or else point and mark are identical)
    1465          14 :     if (!bRet && (!rUnoCursor.HasMark() ||
    1466           2 :                     *rUnoCursor.GetPoint() == *rUnoCursor.GetMark()))
    1467             :     {
    1468           6 :         SwCursor aCrsr(*rUnoCursor.GetPoint(), 0, false);
    1469          12 :         SwPosition aOrigPos = *aCrsr.GetPoint();
    1470           6 :         aCrsr.GoSentence(SwCursor::END_SENT);
    1471          12 :         bRet = aOrigPos == *aCrsr.GetPoint();
    1472             :     }
    1473          12 :     return bRet;
    1474             : }
    1475             : 
    1476             : sal_Bool SAL_CALL
    1477          10 : SwXTextCursor::gotoNextSentence(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1478             : {
    1479          10 :     SolarMutexGuard aGuard;
    1480             : 
    1481          10 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1482             : 
    1483          10 :     const bool bWasEOS = isEndOfSentence();
    1484          10 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1485          10 :     bool bRet = rUnoCursor.GoSentence(SwCursor::NEXT_SENT);
    1486          10 :     if (!bRet)
    1487             :     {
    1488           0 :         bRet = rUnoCursor.MovePara(fnParaNext, fnParaStart);
    1489             :     }
    1490             : 
    1491             :     // if at the end of the sentence (i.e. at the space after the '.')
    1492             :     // advance to next word in order for GoSentence to work properly
    1493             :     // next time and have isStartOfSentence return true after this call
    1494          10 :     if (!rUnoCursor.IsStartWord())
    1495             :     {
    1496           6 :         const bool bNextWord = rUnoCursor.GoNextWord();
    1497           6 :         if (bWasEOS && !bNextWord)
    1498             :         {
    1499           4 :             bRet = false;
    1500             :         }
    1501             :     }
    1502          10 :     if (CURSOR_META == m_pImpl->m_eType)
    1503             :     {
    1504           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1505           4 :                     META_CHECK_BOTH)
    1506           4 :             && bRet;
    1507             :     }
    1508          10 :     return bRet;
    1509             : }
    1510             : 
    1511             : sal_Bool SAL_CALL
    1512          10 : SwXTextCursor::gotoPreviousSentence(sal_Bool Expand)
    1513             : throw (uno::RuntimeException, std::exception)
    1514             : {
    1515          10 :     SolarMutexGuard aGuard;
    1516             : 
    1517          10 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1518             : 
    1519          10 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1520          10 :     bool bRet = rUnoCursor.GoSentence(SwCursor::PREV_SENT);
    1521          10 :     if (!bRet)
    1522             :     {
    1523           2 :         bRet = rUnoCursor.MovePara(fnParaPrev, fnParaStart);
    1524           2 :         if (bRet)
    1525             :         {
    1526           2 :             rUnoCursor.MovePara(fnParaCurr, fnParaEnd);
    1527             :             // at the end of a paragraph move to the sentence end again
    1528           2 :             rUnoCursor.GoSentence(SwCursor::PREV_SENT);
    1529             :         }
    1530             :     }
    1531          10 :     if (CURSOR_META == m_pImpl->m_eType)
    1532             :     {
    1533           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1534           4 :                     META_CHECK_BOTH)
    1535           4 :             && bRet;
    1536             :     }
    1537          10 :     return bRet;
    1538             : }
    1539             : 
    1540             : sal_Bool SAL_CALL
    1541           8 : SwXTextCursor::gotoStartOfSentence(sal_Bool Expand)
    1542             : throw (uno::RuntimeException, std::exception)
    1543             : {
    1544           8 :     SolarMutexGuard aGuard;
    1545             : 
    1546           8 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1547             : 
    1548           8 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1549             :     // if we're at the para start then we wont move
    1550             :     // but bRet is also true if GoSentence failed but
    1551             :     // the start of the sentence is reached
    1552           8 :     bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor)
    1553           8 :         || rUnoCursor.GoSentence(SwCursor::START_SENT)
    1554           8 :         || SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
    1555           8 :     if (CURSOR_META == m_pImpl->m_eType)
    1556             :     {
    1557           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1558           4 :                     META_CHECK_BOTH)
    1559           4 :             && bRet;
    1560             :     }
    1561           8 :     return bRet;
    1562             : }
    1563             : 
    1564             : sal_Bool SAL_CALL
    1565           8 : SwXTextCursor::gotoEndOfSentence(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1566             : {
    1567           8 :     SolarMutexGuard aGuard;
    1568             : 
    1569           8 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1570             : 
    1571           8 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1572             :     // bRet is true if GoSentence() succeeded or if the
    1573             :     // MovePara() succeeded while the end of the para is
    1574             :     // not reached already
    1575           8 :     bool bAlreadyParaEnd = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
    1576           8 :     bool bRet = !bAlreadyParaEnd
    1577          16 :             &&  (rUnoCursor.GoSentence(SwCursor::END_SENT)
    1578           8 :                  || rUnoCursor.MovePara(fnParaCurr, fnParaEnd));
    1579           8 :     if (CURSOR_META == m_pImpl->m_eType)
    1580             :     {
    1581           4 :         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
    1582           4 :                     META_CHECK_BOTH)
    1583           4 :             && bRet;
    1584             :     }
    1585           8 :     return bRet;
    1586             : }
    1587             : 
    1588             : sal_Bool SAL_CALL
    1589           2 : SwXTextCursor::isStartOfParagraph() throw (uno::RuntimeException, std::exception)
    1590             : {
    1591           2 :     SolarMutexGuard aGuard;
    1592             : 
    1593           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1594             : 
    1595           2 :     const bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
    1596           2 :     return bRet;
    1597             : }
    1598             : 
    1599             : sal_Bool SAL_CALL
    1600           6 : SwXTextCursor::isEndOfParagraph() throw (uno::RuntimeException, std::exception)
    1601             : {
    1602           6 :     SolarMutexGuard aGuard;
    1603             : 
    1604           6 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1605             : 
    1606           6 :     const bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
    1607           6 :     return bRet;
    1608             : }
    1609             : 
    1610             : sal_Bool SAL_CALL
    1611         786 : SwXTextCursor::gotoStartOfParagraph(sal_Bool Expand)
    1612             : throw (uno::RuntimeException, std::exception)
    1613             : {
    1614         786 :     SolarMutexGuard aGuard;
    1615             : 
    1616         786 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1617             : 
    1618         786 :     if (CURSOR_META == m_pImpl->m_eType)
    1619             :     {
    1620           2 :         return sal_False;
    1621             :     }
    1622         784 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1623         784 :     bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
    1624         784 :     if (!bRet)
    1625             :     {
    1626         422 :         bRet = rUnoCursor.MovePara(fnParaCurr, fnParaStart);
    1627             :     }
    1628             : 
    1629             :     // since MovePara(fnParaCurr, fnParaStart) only returns false
    1630             :     // if we were already at the start of the paragraph this function
    1631             :     // should always complete successfully.
    1632             :     OSL_ENSURE( bRet, "gotoStartOfParagraph failed" );
    1633         784 :     return bRet;
    1634             : }
    1635             : 
    1636             : sal_Bool SAL_CALL
    1637         546 : SwXTextCursor::gotoEndOfParagraph(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1638             : {
    1639         546 :     SolarMutexGuard aGuard;
    1640             : 
    1641         546 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1642             : 
    1643         546 :     if (CURSOR_META == m_pImpl->m_eType)
    1644             :     {
    1645           2 :         return sal_False;
    1646             :     }
    1647         544 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1648         544 :     bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
    1649         544 :     if (!bRet)
    1650             :     {
    1651         174 :         bRet = rUnoCursor.MovePara(fnParaCurr, fnParaEnd);
    1652             :     }
    1653             : 
    1654             :     // since MovePara(fnParaCurr, fnParaEnd) only returns false
    1655             :     // if we were already at the end of the paragraph this function
    1656             :     // should always complete successfully.
    1657             :     OSL_ENSURE( bRet, "gotoEndOfParagraph failed" );
    1658         544 :     return bRet;
    1659             : }
    1660             : 
    1661             : sal_Bool SAL_CALL
    1662        1386 : SwXTextCursor::gotoNextParagraph(sal_Bool Expand) throw (uno::RuntimeException, std::exception)
    1663             : {
    1664        1386 :     SolarMutexGuard aGuard;
    1665             : 
    1666        1386 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1667             : 
    1668        1386 :     if (CURSOR_META == m_pImpl->m_eType)
    1669             :     {
    1670           2 :         return sal_False;
    1671             :     }
    1672        1384 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1673        1384 :     const bool bRet = rUnoCursor.MovePara(fnParaNext, fnParaStart);
    1674        1384 :     return bRet;
    1675             : }
    1676             : 
    1677             : sal_Bool SAL_CALL
    1678          16 : SwXTextCursor::gotoPreviousParagraph(sal_Bool Expand)
    1679             : throw (uno::RuntimeException, std::exception)
    1680             : {
    1681          16 :     SolarMutexGuard aGuard;
    1682             : 
    1683          16 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1684             : 
    1685          16 :     if (CURSOR_META == m_pImpl->m_eType)
    1686             :     {
    1687           2 :         return sal_False;
    1688             :     }
    1689          14 :     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
    1690          14 :     const bool bRet = rUnoCursor.MovePara(fnParaPrev, fnParaStart);
    1691          14 :     return bRet;
    1692             : }
    1693             : 
    1694             : uno::Reference< text::XText > SAL_CALL
    1695       55570 : SwXTextCursor::getText() throw (uno::RuntimeException, std::exception)
    1696             : {
    1697       55570 :     SolarMutexGuard g;
    1698             : 
    1699       55570 :     return m_pImpl->m_xParentText;
    1700             : }
    1701             : 
    1702             : uno::Reference< text::XTextRange > SAL_CALL
    1703       51670 : SwXTextCursor::getStart() throw (uno::RuntimeException, std::exception)
    1704             : {
    1705       51670 :     SolarMutexGuard aGuard;
    1706             : 
    1707       51670 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1708             : 
    1709       51670 :     uno::Reference< text::XTextRange > xRet;
    1710      103340 :     SwPaM aPam(*rUnoCursor.Start());
    1711      103340 :     const uno::Reference< text::XText >  xParent = getText();
    1712       51670 :     if (CURSOR_META == m_pImpl->m_eType)
    1713             :     {
    1714             :         // return cursor to prevent modifying SwXTextRange for META
    1715             :         SwXTextCursor * const pXCursor(
    1716          52 :             new SwXTextCursor(*rUnoCursor.GetDoc(), xParent, CURSOR_META,
    1717          52 :                 *rUnoCursor.GetPoint()) );
    1718          52 :         pXCursor->gotoStart(sal_False);
    1719          52 :         xRet = static_cast<text::XWordCursor*>(pXCursor);
    1720             :     }
    1721             :     else
    1722             :     {
    1723       51618 :         xRet = new SwXTextRange(aPam, xParent);
    1724             :     }
    1725      103340 :     return xRet;
    1726             : }
    1727             : 
    1728             : uno::Reference< text::XTextRange > SAL_CALL
    1729          22 : SwXTextCursor::getEnd() throw (uno::RuntimeException, std::exception)
    1730             : {
    1731          22 :     SolarMutexGuard aGuard;
    1732             : 
    1733          22 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1734             : 
    1735          22 :     uno::Reference< text::XTextRange >  xRet;
    1736          44 :     SwPaM aPam(*rUnoCursor.End());
    1737          44 :     const uno::Reference< text::XText >  xParent = getText();
    1738          22 :     if (CURSOR_META == m_pImpl->m_eType)
    1739             :     {
    1740             :         // return cursor to prevent modifying SwXTextRange for META
    1741             :         SwXTextCursor * const pXCursor(
    1742           0 :             new SwXTextCursor(*rUnoCursor.GetDoc(), xParent, CURSOR_META,
    1743           0 :                 *rUnoCursor.GetPoint()) );
    1744           0 :         pXCursor->gotoEnd(sal_False);
    1745           0 :         xRet = static_cast<text::XWordCursor*>(pXCursor);
    1746             :     }
    1747             :     else
    1748             :     {
    1749          22 :         xRet = new SwXTextRange(aPam, xParent);
    1750             :     }
    1751          44 :     return xRet;
    1752             : }
    1753             : 
    1754        5498 : OUString SAL_CALL SwXTextCursor::getString() throw (uno::RuntimeException, std::exception)
    1755             : {
    1756        5498 :     SolarMutexGuard aGuard;
    1757             : 
    1758        5498 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1759             : 
    1760        5498 :     OUString aTxt;
    1761        5498 :     SwUnoCursorHelper::GetTextFromPam(rUnoCursor, aTxt);
    1762        5498 :     return aTxt;
    1763             : }
    1764             : 
    1765             : void SAL_CALL
    1766       13234 : SwXTextCursor::setString(const OUString& aString) throw (uno::RuntimeException, std::exception)
    1767             : {
    1768       13234 :     SolarMutexGuard aGuard;
    1769             : 
    1770       13234 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    1771             :     (void) rUnoCursor; // just to check if valid
    1772             : 
    1773       13234 :     const bool bForceExpandHints( (CURSOR_META != m_pImpl->m_eType)
    1774             :         ? false
    1775          62 :         : dynamic_cast<SwXMeta*>(m_pImpl->m_xParentText.get())
    1776       13296 :                 ->CheckForOwnMemberMeta(*GetPaM(), true) );
    1777       13234 :     DeleteAndInsert(aString, bForceExpandHints);
    1778       13234 : }
    1779             : 
    1780       17092 : uno::Any SwUnoCursorHelper::GetPropertyValue(
    1781             :     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    1782             :     const OUString& rPropertyName)
    1783             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1784             :         uno::RuntimeException)
    1785             : {
    1786       17092 :     uno::Any aAny;
    1787             :     SfxItemPropertySimpleEntry const*const pEntry =
    1788       17092 :         rPropSet.getPropertyMap().getByName(rPropertyName);
    1789             : 
    1790       17092 :     if (!pEntry)
    1791             :     {
    1792             :         throw beans::UnknownPropertyException(
    1793           0 :             "Unknown property: " + rPropertyName,
    1794           0 :             static_cast<cppu::OWeakObject *>(0));
    1795             :     }
    1796             : 
    1797             :     beans::PropertyState eTemp;
    1798             :     const bool bDone = SwUnoCursorHelper::getCrsrPropertyValue(
    1799       17092 :             *pEntry, rPaM, &aAny, eTemp );
    1800             : 
    1801       17092 :     if (!bDone)
    1802             :     {
    1803        2934 :         SfxItemSet aSet(rPaM.GetDoc()->GetAttrPool(),
    1804             :             RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
    1805             :             RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
    1806             :             RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
    1807        2934 :             0L);
    1808        2934 :         SwUnoCursorHelper::GetCrsrAttr(rPaM, aSet);
    1809             : 
    1810        2938 :         rPropSet.getPropertyValue(*pEntry, aSet, aAny);
    1811             :     }
    1812             : 
    1813       17088 :     return aAny;
    1814             : }
    1815             : 
    1816       48804 : void SwUnoCursorHelper::SetPropertyValue(
    1817             :     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    1818             :     const OUString& rPropertyName,
    1819             :     const uno::Any& rValue,
    1820             :     const SetAttrMode nAttrMode, const bool bTableMode)
    1821             : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
    1822             :         lang::IllegalArgumentException, lang::WrappedTargetException,
    1823             :         uno::RuntimeException)
    1824             : {
    1825       48804 :     uno::Sequence< beans::PropertyValue > aValues(1);
    1826       48804 :     aValues[0].Name = rPropertyName;
    1827       48804 :     aValues[0].Value = rValue;
    1828       48804 :     SetPropertyValues(rPaM, rPropSet, aValues, nAttrMode, bTableMode);
    1829       48804 : }
    1830             : 
    1831             : // FN_UNO_PARA_STYLE is known to set attributes for nodes, inside
    1832             : // SwUnoCursorHelper::SetTxtFmtColl, instead of extending item set.
    1833             : // We need to get them from nodes in next call to GetCrsrAttr.
    1834             : // The rest could cause similar problems in theory, so we just list them here.
    1835      515084 : inline bool propertyCausesSideEffectsInNodes(sal_uInt16 nWID)
    1836             : {
    1837      461168 :     return nWID == FN_UNO_PARA_STYLE ||
    1838      461164 :            nWID == FN_UNO_CHARFMT_SEQUENCE ||
    1839      976236 :            nWID == FN_UNO_NUM_START_VALUE ||
    1840      515084 :            nWID == FN_UNO_NUM_RULES;
    1841             : }
    1842             : 
    1843      188614 : void SwUnoCursorHelper::SetPropertyValues(
    1844             :     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    1845             :     const uno::Sequence< beans::PropertyValue > &rPropertyValues,
    1846             :     const SetAttrMode nAttrMode, const bool bTableMode)
    1847             : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
    1848             :         lang::IllegalArgumentException, lang::WrappedTargetException,
    1849             :         uno::RuntimeException)
    1850             : {
    1851      188614 :     if (!rPropertyValues.getLength())
    1852      217000 :         return;
    1853             : 
    1854      160210 :     SwDoc *const pDoc = rPaM.GetDoc();
    1855      320420 :     OUString aUnknownExMsg, aPropertyVetoExMsg;
    1856             : 
    1857             :     // Build set of attributes we want to fetch
    1858      320420 :     std::vector<sal_uInt16> aWhichPairs;
    1859      320420 :     std::vector<SfxItemPropertySimpleEntry const*> aEntries;
    1860      160210 :     aEntries.reserve(rPropertyValues.getLength());
    1861     1350716 :     for (sal_Int32 i = 0; i < rPropertyValues.getLength(); ++i)
    1862             :     {
    1863      515148 :         const OUString &rPropertyName = rPropertyValues[i].Name;
    1864             : 
    1865             :         SfxItemPropertySimpleEntry const* pEntry =
    1866      515148 :             rPropSet.getPropertyMap().getByName(rPropertyName);
    1867             : 
    1868             :         // Queue up any exceptions until the end ...
    1869      515148 :         if (!pEntry)
    1870             :         {
    1871           0 :             aUnknownExMsg += "Unknown property: '" + rPropertyName + "' ";
    1872           0 :             break;
    1873             :         }
    1874      515148 :         else if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
    1875             :         {
    1876           0 :             aPropertyVetoExMsg += "Property is read-only: '" + rPropertyName + "' ";
    1877           0 :             break;
    1878             :         } else {
    1879             : // FIXME: we should have some nice way of merging ranges surely ?
    1880      515148 :             aWhichPairs.push_back(pEntry->nWID);
    1881      515148 :             aWhichPairs.push_back(pEntry->nWID);
    1882             :         }
    1883      515148 :         aEntries.push_back(pEntry);
    1884             :     }
    1885             : 
    1886      160210 :     if (!aWhichPairs.empty())
    1887             :     {
    1888      160210 :         aWhichPairs.push_back(0); // terminate
    1889      160210 :         SfxItemSet aItemSet(pDoc->GetAttrPool(), &aWhichPairs[0]);
    1890             : 
    1891             :         // Fetch, overwrite, and re-set the attributes from the core
    1892             : 
    1893      160210 :         bool bPreviousPropertyCausesSideEffectsInNodes = false;
    1894      675276 :         for (size_t i = 0; i < aEntries.size(); ++i)
    1895             :         {
    1896      515084 :             SfxItemPropertySimpleEntry const*const pEntry = aEntries[i];
    1897             :             bool bPropertyCausesSideEffectsInNodes =
    1898      515084 :                 propertyCausesSideEffectsInNodes(pEntry->nWID);
    1899             : 
    1900             :             // we need to get up-to-date item set from nodes
    1901      515084 :             if (i == 0 || bPreviousPropertyCausesSideEffectsInNodes)
    1902      196138 :                 SwUnoCursorHelper::GetCrsrAttr(rPaM, aItemSet);
    1903             : 
    1904      515084 :             const uno::Any &rValue = rPropertyValues[i].Value;
    1905             :             // this can set some attributes in nodes' mpAttrSet
    1906      515084 :             if (!SwUnoCursorHelper::SetCursorPropertyValue(*pEntry, rValue, rPaM, aItemSet))
    1907      428876 :                 rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
    1908             : 
    1909      515066 :             if (i + 1 == aEntries.size() || bPropertyCausesSideEffectsInNodes)
    1910      196120 :                 SwUnoCursorHelper::SetCrsrAttr(rPaM, aItemSet, nAttrMode, bTableMode);
    1911             : 
    1912      515066 :             bPreviousPropertyCausesSideEffectsInNodes = bPropertyCausesSideEffectsInNodes;
    1913      160210 :         }
    1914             :     }
    1915             : 
    1916      160192 :     if (!aUnknownExMsg.isEmpty())
    1917           0 :         throw beans::UnknownPropertyException(aUnknownExMsg, static_cast<cppu::OWeakObject *>(0));
    1918      160192 :     if (!aPropertyVetoExMsg.isEmpty())
    1919      160210 :         throw beans::PropertyVetoException(aPropertyVetoExMsg, static_cast<cppu::OWeakObject *>(0));
    1920             : }
    1921             : 
    1922             : uno::Sequence< beans::PropertyState >
    1923       35720 : SwUnoCursorHelper::GetPropertyStates(
    1924             :             SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    1925             :             const uno::Sequence< OUString >& rPropertyNames,
    1926             :             const SwGetPropertyStatesCaller eCaller)
    1927             : throw (beans::UnknownPropertyException, uno::RuntimeException)
    1928             : {
    1929       35720 :     const OUString* pNames = rPropertyNames.getConstArray();
    1930       35720 :     uno::Sequence< beans::PropertyState > aRet(rPropertyNames.getLength());
    1931       35720 :     beans::PropertyState* pStates = aRet.getArray();
    1932       35720 :     const SfxItemPropertyMap &rMap = rPropSet.getPropertyMap();
    1933       71440 :     ::std::unique_ptr<SfxItemSet> pSet;
    1934       71440 :     ::std::unique_ptr<SfxItemSet> pSetParent;
    1935             : 
    1936      372328 :     for (sal_Int32 i = 0, nEnd = rPropertyNames.getLength(); i < nEnd; i++)
    1937             :     {
    1938             :         SfxItemPropertySimpleEntry const*const pEntry =
    1939      339892 :                 rMap.getByName( pNames[i] );
    1940      339892 :         if(!pEntry)
    1941             :         {
    1942        6584 :             if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
    1943        3288 :                 pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
    1944             :             {
    1945          12 :                 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
    1946          12 :                 continue;
    1947             :             }
    1948        3284 :             else if (SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT ==
    1949             :                         eCaller)
    1950             :             {
    1951             :                 //this values marks the element as unknown property
    1952           0 :                 pStates[i] = beans::PropertyState_MAKE_FIXED_SIZE;
    1953           0 :                 continue;
    1954             :             }
    1955             :             else
    1956             :             {
    1957             :                 throw beans::UnknownPropertyException(
    1958        6568 :                     "Unknown property: " + pNames[i],
    1959        9852 :                     static_cast<cppu::OWeakObject *>(0));
    1960             :             }
    1961             :         }
    1962      336596 :         if (((SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION == eCaller)  ||
    1963      297864 :              (SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT == eCaller)) &&
    1964      595728 :             pEntry->nWID < FN_UNO_RANGE_BEGIN &&
    1965      297864 :             pEntry->nWID > FN_UNO_RANGE_END  &&
    1966           0 :             pEntry->nWID < RES_CHRATR_BEGIN &&
    1967           0 :             pEntry->nWID > RES_TXTATR_END )
    1968             :         {
    1969           0 :             pStates[i] = beans::PropertyState_DEFAULT_VALUE;
    1970             :         }
    1971             :         else
    1972             :         {
    1973      336642 :             if ( pEntry->nWID >= FN_UNO_RANGE_BEGIN &&
    1974          46 :                  pEntry->nWID <= FN_UNO_RANGE_END )
    1975             :             {
    1976             :                 (void)SwUnoCursorHelper::getCrsrPropertyValue(
    1977          46 :                     *pEntry, rPaM, 0, pStates[i] );
    1978             :             }
    1979             :             else
    1980             :             {
    1981      336550 :                 if (!pSet.get())
    1982             :                 {
    1983       32422 :                     switch ( eCaller )
    1984             :                     {
    1985             :                         case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT:
    1986             :                         case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION:
    1987             :                             pSet.reset(
    1988        4092 :                                 new SfxItemSet( rPaM.GetDoc()->GetAttrPool(),
    1989        4092 :                                     RES_CHRATR_BEGIN,   RES_TXTATR_END ));
    1990        4092 :                         break;
    1991             :                         case SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY:
    1992             :                             pSet.reset(
    1993       28190 :                                 new SfxItemSet( rPaM.GetDoc()->GetAttrPool(),
    1994       28190 :                                     pEntry->nWID, pEntry->nWID ));
    1995       28190 :                         break;
    1996             :                         default:
    1997             :                             pSet.reset( new SfxItemSet(
    1998         140 :                                 rPaM.GetDoc()->GetAttrPool(),
    1999             :                                 RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
    2000             :                                 RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
    2001             :                                 RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
    2002         140 :                                 0L ));
    2003             :                     }
    2004             :                     // #i63870#
    2005       32422 :                     SwUnoCursorHelper::GetCrsrAttr( rPaM, *pSet );
    2006             :                 }
    2007             : 
    2008      336550 :                 pStates[i] = ( pSet->Count() )
    2009       39016 :                     ? rPropSet.getPropertyState( *pEntry, *pSet )
    2010      375566 :                     : beans::PropertyState_DEFAULT_VALUE;
    2011             : 
    2012             :                 //try again to find out if a value has been inherited
    2013      336550 :                 if( beans::PropertyState_DIRECT_VALUE == pStates[i] )
    2014             :                 {
    2015       13582 :                     if (!pSetParent.get())
    2016             :                     {
    2017       12830 :                         pSetParent.reset( pSet->Clone( false ) );
    2018             :                         // #i63870#
    2019             :                         SwUnoCursorHelper::GetCrsrAttr(
    2020       12830 :                                 rPaM, *pSetParent, true, false );
    2021             :                     }
    2022             : 
    2023       13582 :                     pStates[i] = ( (pSetParent)->Count() )
    2024        3308 :                         ? rPropSet.getPropertyState( *pEntry, *pSetParent )
    2025       16890 :                         : beans::PropertyState_DEFAULT_VALUE;
    2026             :                 }
    2027             :             }
    2028             :         }
    2029             :     }
    2030       64872 :     return aRet;
    2031             : }
    2032             : 
    2033       31480 : beans::PropertyState SwUnoCursorHelper::GetPropertyState(
    2034             :     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    2035             :     const OUString& rPropertyName)
    2036             : throw (beans::UnknownPropertyException, uno::RuntimeException)
    2037             : {
    2038       31480 :     uno::Sequence< OUString > aStrings ( 1 );
    2039       31480 :     aStrings[0] = rPropertyName;
    2040             :     uno::Sequence< beans::PropertyState > aSeq =
    2041             :         GetPropertyStates(rPaM, rPropSet, aStrings,
    2042       59676 :                 SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY );
    2043       59676 :     return aSeq[0];
    2044             : }
    2045             : 
    2046             : static void
    2047           2 : lcl_SelectParaAndReset( SwPaM &rPaM, SwDoc & rDoc,
    2048             :                         std::set<sal_uInt16> const &rWhichIds )
    2049             : {
    2050             :     // if we are reseting paragraph attributes, we need to select the full paragraph first
    2051           2 :     SwPosition aStart = *rPaM.Start();
    2052           4 :     SwPosition aEnd = *rPaM.End();
    2053           4 :     ::std::unique_ptr< SwUnoCrsr > pTemp ( rDoc.CreateUnoCrsr(aStart, false) );
    2054           2 :     if(!SwUnoCursorHelper::IsStartOfPara(*pTemp))
    2055             :     {
    2056           2 :         pTemp->MovePara(fnParaCurr, fnParaStart);
    2057             :     }
    2058           2 :     pTemp->SetMark();
    2059           2 :     *pTemp->GetPoint() = aEnd;
    2060           2 :     SwUnoCursorHelper::SelectPam(*pTemp, true);
    2061           2 :     if(!SwUnoCursorHelper::IsEndOfPara(*pTemp))
    2062             :     {
    2063           0 :         pTemp->MovePara(fnParaCurr, fnParaEnd);
    2064             :     }
    2065           4 :     rDoc.ResetAttrs(*pTemp, true, rWhichIds);
    2066           2 : }
    2067             : 
    2068           4 : void SwUnoCursorHelper::SetPropertyToDefault(
    2069             :     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    2070             :     const OUString& rPropertyName)
    2071             : throw (beans::UnknownPropertyException, uno::RuntimeException)
    2072             : {
    2073           4 :     SwDoc & rDoc = *rPaM.GetDoc();
    2074             :     SfxItemPropertySimpleEntry const*const pEntry =
    2075           4 :         rPropSet.getPropertyMap().getByName(rPropertyName);
    2076           4 :     if (!pEntry)
    2077             :     {
    2078             :         throw beans::UnknownPropertyException(
    2079           0 :             "Unknown property: " + rPropertyName,
    2080           0 :             static_cast<cppu::OWeakObject *>(0));
    2081             :     }
    2082             : 
    2083           4 :     if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
    2084             :     {
    2085             :         throw uno::RuntimeException(
    2086             :                 "setPropertyToDefault: property is read-only: "
    2087           0 :                 + rPropertyName, 0);
    2088             :     }
    2089             : 
    2090           4 :     if (pEntry->nWID < RES_FRMATR_END)
    2091             :     {
    2092           0 :         std::set<sal_uInt16> aWhichIds;
    2093           0 :         aWhichIds.insert( pEntry->nWID );
    2094           0 :         if (pEntry->nWID < RES_PARATR_BEGIN)
    2095             :         {
    2096           0 :             rDoc.ResetAttrs(rPaM, true, aWhichIds);
    2097             :         }
    2098             :         else
    2099             :         {
    2100           0 :             lcl_SelectParaAndReset ( rPaM, rDoc, aWhichIds );
    2101           0 :         }
    2102             :     }
    2103             :     else
    2104             :     {
    2105           4 :         SwUnoCursorHelper::resetCrsrPropertyValue(*pEntry, rPaM);
    2106             :     }
    2107           4 : }
    2108             : 
    2109           4 : uno::Any SwUnoCursorHelper::GetPropertyDefault(
    2110             :     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
    2111             :     const OUString& rPropertyName)
    2112             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2113             :         uno::RuntimeException)
    2114             : {
    2115             :     SfxItemPropertySimpleEntry const*const pEntry =
    2116           4 :         rPropSet.getPropertyMap().getByName(rPropertyName);
    2117           4 :     if (!pEntry)
    2118             :     {
    2119             :         throw beans::UnknownPropertyException(
    2120           0 :             "Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject *>(0));
    2121             :     }
    2122             : 
    2123           4 :     uno::Any aRet;
    2124           4 :     if (pEntry->nWID < RES_FRMATR_END)
    2125             :     {
    2126           0 :         SwDoc & rDoc = *rPaM.GetDoc();
    2127             :         const SfxPoolItem& rDefItem =
    2128           0 :             rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID);
    2129           0 :         rDefItem.QueryValue(aRet, pEntry->nMemberId);
    2130             :     }
    2131           4 :     return aRet;
    2132             : }
    2133             : 
    2134             : uno::Reference< beans::XPropertySetInfo > SAL_CALL
    2135       37776 : SwXTextCursor::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
    2136             : {
    2137       37776 :     SolarMutexGuard g;
    2138             : 
    2139       37776 :     static uno::Reference< beans::XPropertySetInfo >  xRef;
    2140       37776 :     if(!xRef.is())
    2141             :     {
    2142             :         static SfxItemPropertyMapEntry const aCrsrExtMap_Impl[] =
    2143             :         {
    2144          52 :             { OUString(UNO_NAME_IS_SKIP_HIDDEN_TEXT), FN_SKIP_HIDDEN_TEXT, ::getBooleanCppuType(), PROPERTY_NONE,     0},
    2145          52 :             { OUString(UNO_NAME_IS_SKIP_PROTECTED_TEXT), FN_SKIP_PROTECTED_TEXT, ::getBooleanCppuType(), PROPERTY_NONE,     0},
    2146             :             { OUString(), 0, css::uno::Type(), 0, 0 }
    2147         208 :         };
    2148             :         const uno::Reference< beans::XPropertySetInfo >  xInfo =
    2149          52 :             m_pImpl->m_rPropSet.getPropertySetInfo();
    2150             :         // extend PropertySetInfo!
    2151         104 :         const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
    2152         104 :         xRef = new SfxExtItemPropertySetInfo(
    2153             :             aCrsrExtMap_Impl,
    2154         156 :             aPropSeq );
    2155             :     }
    2156       37776 :     return xRef;
    2157             : }
    2158             : 
    2159             : void SAL_CALL
    2160       47640 : SwXTextCursor::setPropertyValue(
    2161             :         const OUString& rPropertyName, const uno::Any& rValue)
    2162             : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
    2163             :         lang::IllegalArgumentException, lang::WrappedTargetException,
    2164             :         uno::RuntimeException, std::exception)
    2165             : {
    2166       47640 :     SolarMutexGuard aGuard;
    2167             : 
    2168       47640 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2169             : 
    2170       47640 :     if (rPropertyName == UNO_NAME_IS_SKIP_HIDDEN_TEXT)
    2171             :     {
    2172           0 :         bool bSet(false);
    2173           0 :         if (!(rValue >>= bSet))
    2174             :         {
    2175           0 :             throw lang::IllegalArgumentException();
    2176             :         }
    2177           0 :         rUnoCursor.SetSkipOverHiddenSections(bSet);
    2178             :     }
    2179       47640 :     else if (rPropertyName == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
    2180             :     {
    2181           0 :         bool bSet(false);
    2182           0 :         if (!(rValue >>= bSet))
    2183             :         {
    2184           0 :             throw lang::IllegalArgumentException();
    2185             :         }
    2186           0 :         rUnoCursor.SetSkipOverProtectSections(bSet);
    2187             :     }
    2188             :     else
    2189             :     {
    2190             :         SwUnoCursorHelper::SetPropertyValue(rUnoCursor,
    2191       47640 :                 m_pImpl->m_rPropSet, rPropertyName, rValue);
    2192       47640 :     }
    2193       47640 : }
    2194             : 
    2195             : uno::Any SAL_CALL
    2196       15596 : SwXTextCursor::getPropertyValue(const OUString& rPropertyName)
    2197             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2198             :         uno::RuntimeException, std::exception)
    2199             : {
    2200       15596 :     SolarMutexGuard aGuard;
    2201             : 
    2202       15596 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2203             : 
    2204       15596 :     uno::Any aAny;
    2205       15596 :     if (rPropertyName == UNO_NAME_IS_SKIP_HIDDEN_TEXT)
    2206             :     {
    2207           0 :         const bool bSet = rUnoCursor.IsSkipOverHiddenSections();
    2208           0 :         aAny <<= bSet;
    2209             :     }
    2210       15596 :     else if (rPropertyName == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
    2211             :     {
    2212           0 :         const bool bSet = rUnoCursor.IsSkipOverProtectSections();
    2213           0 :         aAny <<= bSet;
    2214             :     }
    2215             :     else
    2216             :     {
    2217       31192 :         aAny = SwUnoCursorHelper::GetPropertyValue(rUnoCursor,
    2218       31192 :                 m_pImpl->m_rPropSet, rPropertyName);
    2219             :     }
    2220       15596 :     return aAny;
    2221             : }
    2222             : 
    2223             : void SAL_CALL
    2224           0 : SwXTextCursor::addPropertyChangeListener(
    2225             :         const OUString& /*rPropertyName*/,
    2226             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    2227             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2228             :     uno::RuntimeException, std::exception)
    2229             : {
    2230             :     OSL_FAIL("SwXTextCursor::addPropertyChangeListener(): not implemented");
    2231           0 : }
    2232             : 
    2233             : void SAL_CALL
    2234           0 : SwXTextCursor::removePropertyChangeListener(
    2235             :         const OUString& /*rPropertyName*/,
    2236             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    2237             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2238             :     uno::RuntimeException, std::exception)
    2239             : {
    2240             :     OSL_FAIL("SwXTextCursor::removePropertyChangeListener(): not implemented");
    2241           0 : }
    2242             : 
    2243             : void SAL_CALL
    2244           0 : SwXTextCursor::addVetoableChangeListener(
    2245             :         const OUString& /*rPropertyName*/,
    2246             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    2247             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2248             :     uno::RuntimeException, std::exception)
    2249             : {
    2250             :     OSL_FAIL("SwXTextCursor::addVetoableChangeListener(): not implemented");
    2251           0 : }
    2252             : 
    2253             : void SAL_CALL
    2254           0 : SwXTextCursor::removeVetoableChangeListener(
    2255             :         const OUString& /*rPropertyName*/,
    2256             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    2257             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2258             :         uno::RuntimeException, std::exception)
    2259             : {
    2260             :     OSL_FAIL("SwXTextCursor::removeVetoableChangeListener(): not implemented");
    2261           0 : }
    2262             : 
    2263             : beans::PropertyState SAL_CALL
    2264       31476 : SwXTextCursor::getPropertyState(const OUString& rPropertyName)
    2265             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    2266             : {
    2267       31476 :     SolarMutexGuard aGuard;
    2268             : 
    2269       31476 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2270             : 
    2271             :     const beans::PropertyState eRet = SwUnoCursorHelper::GetPropertyState(
    2272       31476 :             rUnoCursor, m_pImpl->m_rPropSet, rPropertyName);
    2273       28192 :     return eRet;
    2274             : }
    2275             : 
    2276             : uno::Sequence< beans::PropertyState > SAL_CALL
    2277           8 : SwXTextCursor::getPropertyStates(
    2278             :         const uno::Sequence< OUString >& rPropertyNames)
    2279             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    2280             : {
    2281           8 :     SolarMutexGuard aGuard;
    2282             : 
    2283           8 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2284             : 
    2285             :     return SwUnoCursorHelper::GetPropertyStates(
    2286           8 :             rUnoCursor, m_pImpl->m_rPropSet, rPropertyNames);
    2287             : }
    2288             : 
    2289             : void SAL_CALL
    2290           2 : SwXTextCursor::setPropertyToDefault(const OUString& rPropertyName)
    2291             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    2292             : {
    2293             :     // forward: need no solar mutex here
    2294           2 :     uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
    2295           2 :     setPropertiesToDefault ( aSequence );
    2296           2 : }
    2297             : 
    2298             : uno::Any SAL_CALL
    2299           2 : SwXTextCursor::getPropertyDefault(const OUString& rPropertyName)
    2300             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2301             :         uno::RuntimeException, std::exception)
    2302             : {
    2303             :     // forward: need no solar mutex here
    2304           2 :     const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
    2305           2 :     return getPropertyDefaults ( aSequence ).getConstArray()[0];
    2306             : }
    2307             : 
    2308          24 : void SAL_CALL SwXTextCursor::setPropertyValues(
    2309             :     const uno::Sequence< OUString >& aPropertyNames,
    2310             :     const uno::Sequence< uno::Any >& aValues )
    2311             :     throw (
    2312             :         css::beans::PropertyVetoException, css::lang::IllegalArgumentException,
    2313             :         css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
    2314             : {
    2315          24 :     if( aValues.getLength() != aPropertyNames.getLength() )
    2316             :     {
    2317             :         OSL_FAIL( "mis-matched property value sequences" );
    2318           0 :         throw lang::IllegalArgumentException();
    2319             :     }
    2320             : 
    2321          24 :     SolarMutexGuard aGuard;
    2322             : 
    2323          24 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2324             : 
    2325             :     // a little lame to have to copy into this.
    2326          48 :     uno::Sequence< beans::PropertyValue > aPropertyValues( aValues.getLength() );
    2327          72 :     for ( sal_Int32 i = 0; i < aPropertyNames.getLength(); i++ )
    2328             :     {
    2329          96 :         if ( aPropertyNames[ i ] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
    2330          48 :              aPropertyNames[ i ] == UNO_NAME_IS_SKIP_PROTECTED_TEXT )
    2331             :         {
    2332             :             // the behaviour of these is hard to model in a group
    2333             :             OSL_FAIL("invalid property name for batch setting");
    2334           0 :             throw lang::IllegalArgumentException();
    2335             :         }
    2336          48 :         aPropertyValues[ i ].Name = aPropertyNames[ i ];
    2337          48 :         aPropertyValues[ i ].Value = aValues[ i ];
    2338             :     }
    2339          48 :     SwUnoCursorHelper::SetPropertyValues( rUnoCursor, m_pImpl->m_rPropSet, aPropertyValues );
    2340          24 : }
    2341             : 
    2342             : uno::Sequence< uno::Any > SAL_CALL
    2343           0 : SwXTextCursor::getPropertyValues( const uno::Sequence< OUString >& aPropertyNames )
    2344             :     throw (css::uno::RuntimeException, std::exception)
    2345             : {
    2346             :     // a banal implementation for now
    2347           0 :     uno::Sequence< uno::Any > aValues( aPropertyNames.getLength() );
    2348           0 :     for (sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
    2349           0 :         aValues[i] = getPropertyValue( aPropertyNames[ i ] );
    2350           0 :     return aValues;
    2351             : }
    2352             : 
    2353           0 : void SAL_CALL SwXTextCursor::addPropertiesChangeListener(
    2354             :         const uno::Sequence< OUString >& /* aPropertyNames */,
    2355             :         const uno::Reference< css::beans::XPropertiesChangeListener >& /* xListener */ )
    2356             :     throw (css::uno::RuntimeException, std::exception)
    2357             : {
    2358             :     OSL_FAIL("SwXTextCursor::addPropertiesChangeListener(): not implemented");
    2359           0 : }
    2360           0 : void SAL_CALL SwXTextCursor::removePropertiesChangeListener(
    2361             :         const uno::Reference< css::beans::XPropertiesChangeListener >& /* xListener */ )
    2362             :     throw (css::uno::RuntimeException, std::exception)
    2363             : {
    2364             :     OSL_FAIL("SwXTextCursor::removePropertiesChangeListener(): not implemented");
    2365           0 : }
    2366             : 
    2367           0 : void SAL_CALL SwXTextCursor::firePropertiesChangeEvent(
    2368             :         const uno::Sequence< OUString >& /* aPropertyNames */,
    2369             :         const uno::Reference< css::beans::XPropertiesChangeListener >& /* xListener */ )
    2370             :     throw (css::uno::RuntimeException, std::exception)
    2371             : {
    2372             :     OSL_FAIL("SwXTextCursor::firePropertiesChangeEvent(): not implemented");
    2373           0 : }
    2374             : 
    2375             : // para specific attribute ranges
    2376             : static sal_uInt16 g_ParaResetableSetRange[] = {
    2377             :     RES_FRMATR_BEGIN, RES_FRMATR_END-1,
    2378             :     RES_PARATR_BEGIN, RES_PARATR_END-1,
    2379             :     RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
    2380             :     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
    2381             :     0
    2382             : };
    2383             : 
    2384             : // selection specific attribute ranges
    2385             : static sal_uInt16 g_ResetableSetRange[] = {
    2386             :     RES_CHRATR_BEGIN, RES_CHRATR_END-1,
    2387             :     RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
    2388             :     RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
    2389             :     RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
    2390             :     RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
    2391             :     0
    2392             : };
    2393             : 
    2394             : static void
    2395           4 : lcl_EnumerateIds(sal_uInt16 const* pIdRange, std::set<sal_uInt16> &rWhichIds)
    2396             : {
    2397          26 :     while (*pIdRange)
    2398             :     {
    2399          18 :         const sal_uInt16 nStart = *pIdRange++;
    2400          18 :         const sal_uInt16 nEnd   = *pIdRange++;
    2401         234 :         for (sal_uInt16 nId = nStart + 1;  nId <= nEnd;  ++nId)
    2402             :         {
    2403         216 :             rWhichIds.insert( rWhichIds.end(), nId );
    2404             :         }
    2405             :     }
    2406           4 : }
    2407             : 
    2408             : void SAL_CALL
    2409           2 : SwXTextCursor::setAllPropertiesToDefault()
    2410             : throw (uno::RuntimeException, std::exception)
    2411             : {
    2412           2 :     SolarMutexGuard aGuard;
    2413             : 
    2414           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2415             : 
    2416           4 :     std::set<sal_uInt16> aParaWhichIds;
    2417           4 :     std::set<sal_uInt16> aWhichIds;
    2418           2 :     lcl_EnumerateIds(g_ParaResetableSetRange, aParaWhichIds);
    2419           2 :     lcl_EnumerateIds(g_ResetableSetRange, aWhichIds);
    2420           2 :     if (!aParaWhichIds.empty())
    2421             :     {
    2422           2 :         lcl_SelectParaAndReset(rUnoCursor, *rUnoCursor.GetDoc(),
    2423           2 :             aParaWhichIds);
    2424             :     }
    2425           2 :     if (!aWhichIds.empty())
    2426             :     {
    2427           2 :         rUnoCursor.GetDoc()->ResetAttrs(rUnoCursor, true, aWhichIds);
    2428           2 :     }
    2429           2 : }
    2430             : 
    2431             : void SAL_CALL
    2432           4 : SwXTextCursor::setPropertiesToDefault(
    2433             :         const uno::Sequence< OUString >& rPropertyNames)
    2434             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    2435             : {
    2436           4 :     SolarMutexGuard aGuard;
    2437             : 
    2438           4 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2439             : 
    2440           4 :     const sal_Int32 nCount = rPropertyNames.getLength();
    2441           4 :     if ( nCount )
    2442             :     {
    2443           4 :         SwDoc & rDoc = *rUnoCursor.GetDoc();
    2444           4 :         const OUString * pNames = rPropertyNames.getConstArray();
    2445           4 :         std::set<sal_uInt16> aWhichIds;
    2446           8 :         std::set<sal_uInt16> aParaWhichIds;
    2447           8 :         for (sal_Int32 i = 0; i < nCount; i++)
    2448             :         {
    2449             :             SfxItemPropertySimpleEntry const*const  pEntry =
    2450           4 :                 m_pImpl->m_rPropSet.getPropertyMap().getByName( pNames[i] );
    2451           4 :             if (!pEntry)
    2452             :             {
    2453           2 :                 if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
    2454           0 :                     pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
    2455             :                 {
    2456           2 :                     continue;
    2457             :                 }
    2458             :                 throw beans::UnknownPropertyException(
    2459           0 :                     "Unknown property: " + pNames[i],
    2460           0 :                     static_cast<cppu::OWeakObject *>(this));
    2461             :             }
    2462           2 :             if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
    2463             :             {
    2464             :                 throw uno::RuntimeException(
    2465           0 :                     "setPropertiesToDefault: property is read-only: " + pNames[i],
    2466           0 :                     static_cast<cppu::OWeakObject *>(this));
    2467             :             }
    2468             : 
    2469           2 :             if (pEntry->nWID < RES_FRMATR_END)
    2470             :             {
    2471           0 :                 if (pEntry->nWID < RES_PARATR_BEGIN)
    2472             :                 {
    2473           0 :                     aWhichIds.insert( pEntry->nWID );
    2474             :                 }
    2475             :                 else
    2476             :                 {
    2477           0 :                     aParaWhichIds.insert( pEntry->nWID );
    2478             :                 }
    2479             :             }
    2480           2 :             else if (pEntry->nWID == FN_UNO_NUM_START_VALUE)
    2481             :             {
    2482           2 :                 SwUnoCursorHelper::resetCrsrPropertyValue(*pEntry, rUnoCursor);
    2483             :             }
    2484             :         }
    2485             : 
    2486           4 :         if (!aParaWhichIds.empty())
    2487             :         {
    2488           0 :             lcl_SelectParaAndReset(rUnoCursor, rDoc, aParaWhichIds);
    2489             :         }
    2490           4 :         if (!aWhichIds.empty())
    2491             :         {
    2492           0 :             rDoc.ResetAttrs(rUnoCursor, true, aWhichIds);
    2493           4 :         }
    2494           4 :     }
    2495           4 : }
    2496             : 
    2497             : uno::Sequence< uno::Any > SAL_CALL
    2498           4 : SwXTextCursor::getPropertyDefaults(
    2499             :         const uno::Sequence< OUString >& rPropertyNames)
    2500             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    2501             :         uno::RuntimeException, std::exception)
    2502             : {
    2503           4 :     SolarMutexGuard aGuard;
    2504             : 
    2505           4 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2506             : 
    2507           4 :     const sal_Int32 nCount = rPropertyNames.getLength();
    2508           4 :     uno::Sequence< uno::Any > aRet(nCount);
    2509           4 :     if ( nCount )
    2510             :     {
    2511           4 :         SwDoc & rDoc = *rUnoCursor.GetDoc();
    2512           4 :         const OUString *pNames = rPropertyNames.getConstArray();
    2513           4 :         uno::Any *pAny = aRet.getArray();
    2514         312 :         for (sal_Int32 i = 0; i < nCount; i++)
    2515             :         {
    2516             :             SfxItemPropertySimpleEntry const*const pEntry =
    2517         308 :                 m_pImpl->m_rPropSet.getPropertyMap().getByName( pNames[i] );
    2518         308 :             if (!pEntry)
    2519             :             {
    2520           8 :                 if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
    2521           2 :                     pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
    2522             :                 {
    2523           6 :                     continue;
    2524             :                 }
    2525             :                 throw beans::UnknownPropertyException(
    2526           0 :                     "Unknown property: " + pNames[i],
    2527           0 :                     static_cast<cppu::OWeakObject *>(0));
    2528             :             }
    2529         302 :             if (pEntry->nWID < RES_FRMATR_END)
    2530             :             {
    2531             :                 const SfxPoolItem& rDefItem =
    2532         282 :                     rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID);
    2533         282 :                 rDefItem.QueryValue(pAny[i], pEntry->nMemberId);
    2534             :             }
    2535             :         }
    2536             :     }
    2537           4 :     return aRet;
    2538             : }
    2539             : 
    2540           0 : void SAL_CALL SwXTextCursor::invalidateMarkings(::sal_Int32 nType)
    2541             : throw (uno::RuntimeException, std::exception)
    2542             : {
    2543           0 :     SolarMutexGuard aGuard;
    2544             : 
    2545           0 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2546             : 
    2547           0 :     SwNode& node = rUnoCursor.GetNode();
    2548             : 
    2549           0 :     SwTxtNode* txtNode = node.GetTxtNode();
    2550             : 
    2551           0 :     if (txtNode == 0) return;
    2552             : 
    2553           0 :     if ( text::TextMarkupType::SPELLCHECK == nType )
    2554             :     {
    2555           0 :         txtNode->SetWrongDirty(true);
    2556           0 :         txtNode->SetWrong(0, true);
    2557             :     }
    2558           0 :     else if( text::TextMarkupType::PROOFREADING == nType )
    2559             :     {
    2560           0 :         txtNode->SetGrammarCheckDirty(true);
    2561           0 :         txtNode->SetGrammarCheck(0,true);
    2562             :     }
    2563           0 :     else if ( text::TextMarkupType::SMARTTAG == nType )
    2564             :     {
    2565           0 :         txtNode->SetSmartTagDirty(true);
    2566           0 :         txtNode->SetSmartTags (0, true);
    2567             :     }
    2568           0 :     else return;
    2569             : 
    2570           0 :     SwFmtColl* fmtColl=txtNode->GetFmtColl();
    2571             : 
    2572           0 :     if (fmtColl == 0) return;
    2573             : 
    2574           0 :     SwFmtChg aNew( fmtColl );
    2575           0 :     txtNode->NotifyClients( 0, &aNew );
    2576             : }
    2577             : 
    2578             : void SAL_CALL
    2579         234 : SwXTextCursor::makeRedline(
    2580             :     const OUString& rRedlineType,
    2581             :     const uno::Sequence< beans::PropertyValue >& rRedlineProperties)
    2582             : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    2583             : {
    2584         234 :     SolarMutexGuard aGuard;
    2585             : 
    2586         234 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2587             : 
    2588         234 :     SwUnoCursorHelper::makeRedline(rUnoCursor, rRedlineType, rRedlineProperties);
    2589         234 : }
    2590             : 
    2591           0 : void SAL_CALL SwXTextCursor::insertDocumentFromURL(const OUString& rURL,
    2592             :     const uno::Sequence< beans::PropertyValue >& rOptions)
    2593             : throw (lang::IllegalArgumentException, io::IOException,
    2594             :         uno::RuntimeException, std::exception)
    2595             : {
    2596           0 :     SolarMutexGuard aGuard;
    2597             : 
    2598           0 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2599             : 
    2600           0 :     SwUnoCursorHelper::InsertFile(&rUnoCursor, rURL, rOptions);
    2601           0 : }
    2602             : 
    2603             : uno::Sequence< beans::PropertyValue >
    2604           4 : SwUnoCursorHelper::CreateSortDescriptor(const bool bFromTable)
    2605             : {
    2606           4 :     uno::Sequence< beans::PropertyValue > aRet(5);
    2607           4 :     beans::PropertyValue* pArray = aRet.getArray();
    2608             : 
    2609           8 :     uno::Any aVal;
    2610           4 :     aVal.setValue( &bFromTable, ::getCppuBooleanType());
    2611           8 :     pArray[0] = beans::PropertyValue("IsSortInTable", -1, aVal,
    2612           4 :                     beans::PropertyState_DIRECT_VALUE);
    2613             : 
    2614           4 :     aVal <<= sal_Unicode(' ');
    2615           8 :     pArray[1] = beans::PropertyValue("Delimiter", -1, aVal,
    2616           4 :                     beans::PropertyState_DIRECT_VALUE);
    2617             : 
    2618           4 :     aVal <<= false;
    2619           8 :     pArray[2] = beans::PropertyValue("IsSortColumns", -1, aVal,
    2620           4 :                     beans::PropertyState_DIRECT_VALUE);
    2621             : 
    2622           4 :     aVal <<= (sal_Int32) 3;
    2623           8 :     pArray[3] = beans::PropertyValue("MaxSortFieldsCount", -1, aVal,
    2624           4 :                     beans::PropertyState_DIRECT_VALUE);
    2625             : 
    2626           8 :     uno::Sequence< table::TableSortField > aFields(3);
    2627           4 :     table::TableSortField* pFields = aFields.getArray();
    2628             : 
    2629           8 :     lang::Locale aLang( SvtSysLocale().GetLanguageTag().getLocale());
    2630             :     // get collator algorithm to be used for the locale
    2631             :     uno::Sequence< OUString > aSeq(
    2632           8 :             GetAppCollator().listCollatorAlgorithms( aLang ) );
    2633           4 :     const sal_Int32 nLen = aSeq.getLength();
    2634             :     OSL_ENSURE( nLen > 0, "list of collator algorithms is empty!");
    2635           8 :     OUString aCollAlg;
    2636           4 :     if (nLen > 0)
    2637             :     {
    2638           4 :         aCollAlg = aSeq.getConstArray()[0];
    2639             :     }
    2640             : 
    2641             : #if OSL_DEBUG_LEVEL > 1
    2642             :     const OUString *pTxt = aSeq.getConstArray();
    2643             :     (void)pTxt;
    2644             : #endif
    2645             : 
    2646           4 :     pFields[0].Field = 1;
    2647           4 :     pFields[0].IsAscending = sal_True;
    2648           4 :     pFields[0].IsCaseSensitive = sal_False;
    2649           4 :     pFields[0].FieldType = table::TableSortFieldType_ALPHANUMERIC;
    2650           4 :     pFields[0].CollatorLocale = aLang;
    2651           4 :     pFields[0].CollatorAlgorithm = aCollAlg;
    2652             : 
    2653           4 :     pFields[1].Field = 1;
    2654           4 :     pFields[1].IsAscending = sal_True;
    2655           4 :     pFields[1].IsCaseSensitive = sal_False;
    2656           4 :     pFields[1].FieldType = table::TableSortFieldType_ALPHANUMERIC;
    2657           4 :     pFields[1].CollatorLocale = aLang;
    2658           4 :     pFields[1].CollatorAlgorithm = aCollAlg;
    2659             : 
    2660           4 :     pFields[2].Field = 1;
    2661           4 :     pFields[2].IsAscending = sal_True;
    2662           4 :     pFields[2].IsCaseSensitive = sal_False;
    2663           4 :     pFields[2].FieldType = table::TableSortFieldType_ALPHANUMERIC;
    2664           4 :     pFields[2].CollatorLocale = aLang;
    2665           4 :     pFields[2].CollatorAlgorithm = aCollAlg;
    2666             : 
    2667           4 :     aVal <<= aFields;
    2668           8 :     pArray[4] = beans::PropertyValue("SortFields", -1, aVal,
    2669           4 :                     beans::PropertyState_DIRECT_VALUE);
    2670             : 
    2671           8 :     return aRet;
    2672             : }
    2673             : 
    2674             : uno::Sequence< beans::PropertyValue > SAL_CALL
    2675           2 : SwXTextCursor::createSortDescriptor() throw (uno::RuntimeException, std::exception)
    2676             : {
    2677           2 :     SolarMutexGuard aGuard;
    2678             : 
    2679           2 :     return SwUnoCursorHelper::CreateSortDescriptor(false);
    2680             : }
    2681             : 
    2682          16 : bool SwUnoCursorHelper::ConvertSortProperties(
    2683             :     const uno::Sequence< beans::PropertyValue >& rDescriptor,
    2684             :     SwSortOptions& rSortOpt)
    2685             : {
    2686          16 :     bool bRet = true;
    2687          16 :     const beans::PropertyValue* pProperties = rDescriptor.getConstArray();
    2688             : 
    2689          16 :     rSortOpt.bTable = false;
    2690          16 :     rSortOpt.cDeli = ' ';
    2691          16 :     rSortOpt.eDirection = SRT_COLUMNS;  //!! UI text may be contrary though !!
    2692             : 
    2693          16 :     SwSortKey* pKey1 = new SwSortKey;
    2694          16 :     pKey1->nColumnId = USHRT_MAX;
    2695          16 :     pKey1->bIsNumeric = true;
    2696          16 :     pKey1->eSortOrder = SRT_ASCENDING;
    2697             : 
    2698          16 :     SwSortKey* pKey2 = new SwSortKey;
    2699          16 :     pKey2->nColumnId = USHRT_MAX;
    2700          16 :     pKey2->bIsNumeric = true;
    2701          16 :     pKey2->eSortOrder = SRT_ASCENDING;
    2702             : 
    2703          16 :     SwSortKey* pKey3 = new SwSortKey;
    2704          16 :     pKey3->nColumnId = USHRT_MAX;
    2705          16 :     pKey3->bIsNumeric = true;
    2706          16 :     pKey3->eSortOrder = SRT_ASCENDING;
    2707          16 :     SwSortKey* aKeys[3] = {pKey1, pKey2, pKey3};
    2708             : 
    2709          16 :     bool bOldSortdescriptor(false);
    2710          16 :     bool bNewSortdescriptor(false);
    2711             : 
    2712          96 :     for (sal_Int32 n = 0; n < rDescriptor.getLength(); ++n)
    2713             :     {
    2714          80 :         uno::Any aValue( pProperties[n].Value );
    2715          80 :         const OUString& rPropName = pProperties[n].Name;
    2716             : 
    2717             :         // old and new sortdescriptor
    2718          80 :         if ( rPropName == "IsSortInTable" )
    2719             :         {
    2720          16 :             if (aValue.getValueType() == ::getBooleanCppuType())
    2721             :             {
    2722          16 :                 rSortOpt.bTable = *(sal_Bool*)aValue.getValue();
    2723             :             }
    2724             :             else
    2725             :             {
    2726           0 :                 bRet = false;
    2727             :             }
    2728             :         }
    2729          64 :         else if ( rPropName == "Delimiter" )
    2730             :         {
    2731             :             sal_Unicode uChar;
    2732          16 :             if (aValue >>= uChar)
    2733             :             {
    2734          16 :                 rSortOpt.cDeli = uChar;
    2735             :             }
    2736             :             else
    2737             :             {
    2738           0 :                 bRet = false;
    2739             :             }
    2740             :         }
    2741             :         // old sortdescriptor
    2742          48 :         else if ( rPropName == "SortColumns" )
    2743             :         {
    2744           0 :             bOldSortdescriptor = true;
    2745           0 :             bool bTemp(false);
    2746           0 :             if (aValue >>= bTemp)
    2747             :             {
    2748           0 :                 rSortOpt.eDirection = bTemp ? SRT_COLUMNS : SRT_ROWS;
    2749             :             }
    2750             :             else
    2751             :             {
    2752           0 :                 bRet = false;
    2753             :             }
    2754             :         }
    2755          48 :         else if ( rPropName == "IsCaseSensitive" )
    2756             :         {
    2757           0 :             bOldSortdescriptor = true;
    2758           0 :             bool bTemp(false);
    2759           0 :             if (aValue >>= bTemp)
    2760             :             {
    2761           0 :                 rSortOpt.bIgnoreCase = !bTemp;
    2762             :             }
    2763             :             else
    2764             :             {
    2765           0 :                 bRet = false;
    2766             :             }
    2767             :         }
    2768          48 :         else if ( rPropName == "CollatorLocale" )
    2769             :         {
    2770           0 :             bOldSortdescriptor = true;
    2771           0 :             lang::Locale aLocale;
    2772           0 :             if (aValue >>= aLocale)
    2773             :             {
    2774           0 :                 rSortOpt.nLanguage = LanguageTag::convertToLanguageType( aLocale);
    2775             :             }
    2776             :             else
    2777             :             {
    2778           0 :                 bRet = false;
    2779           0 :             }
    2780             :         }
    2781          96 :         else if (rPropName.startsWith("CollatorAlgorithm") &&
    2782          48 :             rPropName.getLength() == 18 &&
    2783           0 :             (rPropName[17] >= '0' && rPropName[17] <= '9'))
    2784             :         {
    2785           0 :             bOldSortdescriptor = true;
    2786           0 :             sal_uInt16 nIndex = rPropName[17];
    2787           0 :             nIndex -= '0';
    2788           0 :             OUString aTxt;
    2789           0 :             if ((aValue >>= aTxt) && nIndex < 3)
    2790             :             {
    2791           0 :                 aKeys[nIndex]->sSortType = aTxt;
    2792             :             }
    2793             :             else
    2794             :             {
    2795           0 :                 bRet = false;
    2796           0 :             }
    2797             :         }
    2798          96 :         else if (rPropName.startsWith("SortRowOrColumnNo") &&
    2799          48 :             rPropName.getLength() == 18 &&
    2800           0 :             (rPropName[17] >= '0' && rPropName[17] <= '9'))
    2801             :         {
    2802           0 :             bOldSortdescriptor = true;
    2803           0 :             sal_uInt16 nIndex = rPropName[17];
    2804           0 :             nIndex -= '0';
    2805           0 :             sal_Int16 nCol = -1;
    2806           0 :             if (aValue.getValueType() == ::cppu::UnoType<sal_Int16>::get()
    2807           0 :                 && nIndex < 3)
    2808             :             {
    2809           0 :                 aValue >>= nCol;
    2810             :             }
    2811           0 :             if (nCol >= 0)
    2812             :             {
    2813           0 :                 aKeys[nIndex]->nColumnId = nCol;
    2814             :             }
    2815             :             else
    2816             :             {
    2817           0 :                 bRet = false;
    2818             :             }
    2819             :         }
    2820          96 :         else if (rPropName.startsWith("IsSortNumeric") &&
    2821          48 :             rPropName.getLength() == 14 &&
    2822           0 :             (rPropName[13] >= '0' && rPropName[13] <= '9'))
    2823             :         {
    2824           0 :             bOldSortdescriptor = true;
    2825           0 :             sal_uInt16 nIndex = rPropName[13];
    2826           0 :             nIndex = nIndex - '0';
    2827           0 :             if (aValue.getValueType() == ::getBooleanCppuType() && nIndex < 3)
    2828             :             {
    2829           0 :                 bool bTemp = *(sal_Bool*)aValue.getValue();
    2830           0 :                 aKeys[nIndex]->bIsNumeric = bTemp;
    2831             :             }
    2832             :             else
    2833             :             {
    2834           0 :                 bRet = false;
    2835             :             }
    2836             :         }
    2837          96 :         else if (rPropName.startsWith("IsSortAscending") &&
    2838          48 :             rPropName.getLength() == 16 &&
    2839           0 :             (rPropName[15] >= '0' && rPropName[15] <= '9'))
    2840             :         {
    2841           0 :             bOldSortdescriptor = true;
    2842           0 :             sal_uInt16 nIndex = rPropName[15];
    2843           0 :             nIndex -= '0';
    2844           0 :             if (aValue.getValueType() == ::getBooleanCppuType() && nIndex < 3)
    2845             :             {
    2846           0 :                 bool bTemp = *(sal_Bool*)aValue.getValue();
    2847           0 :                 aKeys[nIndex]->eSortOrder = (bTemp)
    2848           0 :                     ? SRT_ASCENDING : SRT_DESCENDING;
    2849             :             }
    2850             :             else
    2851             :             {
    2852           0 :                 bRet = false;
    2853             :             }
    2854             :         }
    2855             :         // new sortdescriptor
    2856          48 :         else if ( rPropName == "IsSortColumns" )
    2857             :         {
    2858          16 :             bNewSortdescriptor = true;
    2859          16 :             if (aValue.getValueType() == ::getBooleanCppuType())
    2860             :             {
    2861          16 :                 bool bTemp = *(sal_Bool*)aValue.getValue();
    2862          16 :                 rSortOpt.eDirection = bTemp ? SRT_COLUMNS : SRT_ROWS;
    2863             :             }
    2864             :             else
    2865             :             {
    2866           0 :                 bRet = false;
    2867             :             }
    2868             :         }
    2869          32 :         else if ( rPropName == "SortFields" )
    2870             :         {
    2871          16 :             bNewSortdescriptor = true;
    2872          16 :             uno::Sequence < table::TableSortField > aFields;
    2873          16 :             if (aValue >>= aFields)
    2874             :             {
    2875          16 :                 sal_Int32 nCount(aFields.getLength());
    2876          16 :                 if (nCount <= 3)
    2877             :                 {
    2878          16 :                     table::TableSortField* pFields = aFields.getArray();
    2879          64 :                     for (sal_Int32 i = 0; i < nCount; ++i)
    2880             :                     {
    2881          48 :                         rSortOpt.bIgnoreCase = !pFields[i].IsCaseSensitive;
    2882             :                         rSortOpt.nLanguage =
    2883          48 :                             LanguageTag::convertToLanguageType( pFields[i].CollatorLocale );
    2884          48 :                         aKeys[i]->sSortType = pFields[i].CollatorAlgorithm;
    2885          48 :                         aKeys[i]->nColumnId =
    2886          48 :                             static_cast<sal_uInt16>(pFields[i].Field);
    2887          48 :                         aKeys[i]->bIsNumeric = (pFields[i].FieldType ==
    2888          48 :                                 table::TableSortFieldType_NUMERIC);
    2889          48 :                         aKeys[i]->eSortOrder = (pFields[i].IsAscending)
    2890          48 :                             ? SRT_ASCENDING : SRT_DESCENDING;
    2891             :                     }
    2892             :                 }
    2893             :                 else
    2894             :                 {
    2895           0 :                     bRet = false;
    2896             :                 }
    2897             :             }
    2898             :             else
    2899             :             {
    2900           0 :                 bRet = false;
    2901          16 :             }
    2902             :         }
    2903          80 :     }
    2904             : 
    2905          16 :     if (bNewSortdescriptor && bOldSortdescriptor)
    2906             :     {
    2907             :         OSL_FAIL("someone tried to set the old deprecated and "
    2908             :             "the new sortdescriptor");
    2909           0 :         bRet = false;
    2910             :     }
    2911             : 
    2912          16 :     if (pKey1->nColumnId != USHRT_MAX)
    2913             :     {
    2914          16 :         rSortOpt.aKeys.push_back(pKey1);
    2915             :     }
    2916          16 :     if (pKey2->nColumnId != USHRT_MAX)
    2917             :     {
    2918          16 :         rSortOpt.aKeys.push_back(pKey2);
    2919             :     }
    2920          16 :     if (pKey3->nColumnId != USHRT_MAX)
    2921             :     {
    2922          16 :         rSortOpt.aKeys.push_back(pKey3);
    2923             :     }
    2924             : 
    2925          16 :     return bRet && !rSortOpt.aKeys.empty();
    2926             : }
    2927             : 
    2928             : void SAL_CALL
    2929           8 : SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
    2930             :     throw (uno::RuntimeException, std::exception)
    2931             : {
    2932           8 :     SolarMutexGuard aGuard;
    2933             : 
    2934           8 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2935             : 
    2936           8 :     if (rUnoCursor.HasMark())
    2937             :     {
    2938           8 :         SwSortOptions aSortOpt;
    2939           8 :         if (!SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
    2940             :         {
    2941           0 :             throw uno::RuntimeException();
    2942             :         }
    2943          16 :         UnoActionContext aContext( rUnoCursor.GetDoc() );
    2944             : 
    2945           8 :         SwPosition & rStart = *rUnoCursor.Start();
    2946           8 :         SwPosition & rEnd   = *rUnoCursor.End();
    2947             : 
    2948          16 :         SwNodeIndex aPrevIdx( rStart.nNode, -1 );
    2949           8 :         const sal_uLong nOffset = rEnd.nNode.GetIndex() - rStart.nNode.GetIndex();
    2950           8 :         const sal_Int32 nCntStt  = rStart.nContent.GetIndex();
    2951             : 
    2952           8 :         rUnoCursor.GetDoc()->SortText(rUnoCursor, aSortOpt);
    2953             : 
    2954             :         // update selection
    2955           8 :         rUnoCursor.DeleteMark();
    2956           8 :         rUnoCursor.GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
    2957           8 :         SwCntntNode *const pCNd = rUnoCursor.GetCntntNode();
    2958           8 :         sal_Int32 nLen = pCNd->Len();
    2959           8 :         if (nLen > nCntStt)
    2960             :         {
    2961           6 :             nLen = nCntStt;
    2962             :         }
    2963           8 :         rUnoCursor.GetPoint()->nContent.Assign(pCNd, nLen );
    2964           8 :         rUnoCursor.SetMark();
    2965             : 
    2966           8 :         rUnoCursor.GetPoint()->nNode += nOffset;
    2967           8 :         SwCntntNode *const pCNd2 = rUnoCursor.GetCntntNode();
    2968          16 :         rUnoCursor.GetPoint()->nContent.Assign( pCNd2, pCNd2->Len() );
    2969           8 :     }
    2970           8 : }
    2971             : 
    2972             : uno::Reference< container::XEnumeration > SAL_CALL
    2973           2 : SwXTextCursor::createContentEnumeration(const OUString& rServiceName)
    2974             : throw (uno::RuntimeException, std::exception)
    2975             : {
    2976           2 :     SolarMutexGuard g;
    2977             : 
    2978           2 :     if (rServiceName != "com.sun.star.text.TextContent")
    2979             :     {
    2980           0 :         throw uno::RuntimeException();
    2981             :     }
    2982             : 
    2983           2 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2984             : 
    2985             :     uno::Reference< container::XEnumeration > xRet =
    2986           2 :         new SwXParaFrameEnumeration(rUnoCursor, PARAFRAME_PORTION_TEXTRANGE);
    2987           2 :     return xRet;
    2988             : }
    2989             : 
    2990             : uno::Reference< container::XEnumeration > SAL_CALL
    2991        4606 : SwXTextCursor::createEnumeration() throw (uno::RuntimeException, std::exception)
    2992             : {
    2993        4606 :     SolarMutexGuard g;
    2994             : 
    2995        4606 :     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
    2996             : 
    2997             :     const uno::Reference<lang::XUnoTunnel> xTunnel(
    2998        9212 :             m_pImpl->m_xParentText, uno::UNO_QUERY);
    2999        4606 :     SwXText* pParentText = 0;
    3000        4606 :     if (xTunnel.is())
    3001             :     {
    3002        4606 :         pParentText = ::sw::UnoTunnelGetImplementation<SwXText>(xTunnel);
    3003             :     }
    3004             :     OSL_ENSURE(pParentText, "parent is not a SwXText");
    3005        4606 :     if (!pParentText)
    3006             :     {
    3007           0 :         throw uno::RuntimeException();
    3008             :     }
    3009             : 
    3010             :     ::std::unique_ptr<SwUnoCrsr> pNewCrsr(
    3011        9212 :         rUnoCursor.GetDoc()->CreateUnoCrsr(*rUnoCursor.GetPoint()) );
    3012        4606 :     if (rUnoCursor.HasMark())
    3013             :     {
    3014         416 :         pNewCrsr->SetMark();
    3015         416 :         *pNewCrsr->GetMark() = *rUnoCursor.GetMark();
    3016             :     }
    3017        4606 :     const CursorType eSetType = (CURSOR_TBLTEXT == m_pImpl->m_eType)
    3018        4606 :             ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
    3019        4606 :     SwTableNode const*const pStartNode( (CURSOR_TBLTEXT == m_pImpl->m_eType)
    3020         974 :             ? rUnoCursor.GetPoint()->nNode.GetNode().FindTableNode()
    3021        5580 :             : 0);
    3022             :     SwTable const*const pTable(
    3023        4606 :             (pStartNode) ? & pStartNode->GetTable() : 0 );
    3024             :     const uno::Reference< container::XEnumeration > xRet =
    3025             :         new SwXParagraphEnumeration(
    3026        4606 :             pParentText, std::move(pNewCrsr), eSetType, pStartNode, pTable);
    3027             : 
    3028        9212 :     return xRet;
    3029             : }
    3030             : 
    3031             : uno::Type SAL_CALL
    3032           0 : SwXTextCursor::getElementType() throw (uno::RuntimeException, std::exception)
    3033             : {
    3034           0 :     return cppu::UnoType<text::XTextRange>::get();
    3035             : }
    3036             : 
    3037           0 : sal_Bool SAL_CALL SwXTextCursor::hasElements() throw (uno::RuntimeException, std::exception)
    3038             : {
    3039           0 :     return sal_True;
    3040             : }
    3041             : 
    3042             : uno::Sequence< OUString > SAL_CALL
    3043           2 : SwXTextCursor::getAvailableServiceNames() throw (uno::RuntimeException, std::exception)
    3044             : {
    3045           2 :     uno::Sequence< OUString > aRet(1);
    3046           2 :     OUString* pArray = aRet.getArray();
    3047           2 :     pArray[0] = "com.sun.star.text.TextContent";
    3048           2 :     return aRet;
    3049             : }
    3050             : 
    3051     1860084 : IMPLEMENT_FORWARD_REFCOUNT( SwXTextCursor,SwXTextCursor_Base )
    3052             : 
    3053             : uno::Any SAL_CALL
    3054      519004 : SwXTextCursor::queryInterface(const uno::Type& rType)
    3055             : throw (uno::RuntimeException, std::exception)
    3056             : {
    3057      519004 :     return (rType == cppu::UnoType<lang::XUnoTunnel>::get())
    3058             :         ? OTextCursorHelper::queryInterface(rType)
    3059      519004 :         : SwXTextCursor_Base::queryInterface(rType);
    3060         270 : }
    3061             : 
    3062             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10