LCOV - code coverage report
Current view: top level - sw/source/core/unocore - unoobj2.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 643 772 83.3 %
Date: 2014-04-11 Functions: 91 112 81.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <rtl/ustrbuf.hxx>
      21             : #include <swtypes.hxx>
      22             : #include <hintids.hxx>
      23             : #include <cmdid.h>
      24             : #include <hints.hxx>
      25             : #include <IMark.hxx>
      26             : #include <bookmrk.hxx>
      27             : #include <frmfmt.hxx>
      28             : #include <doc.hxx>
      29             : #include <IDocumentUndoRedo.hxx>
      30             : #include <ndtxt.hxx>
      31             : #include <ndnotxt.hxx>
      32             : #include <unocrsr.hxx>
      33             : #include <swundo.hxx>
      34             : #include <rootfrm.hxx>
      35             : #include <flyfrm.hxx>
      36             : #include <ftnidx.hxx>
      37             : #include <sfx2/linkmgr.hxx>
      38             : #include <docary.hxx>
      39             : #include <paratr.hxx>
      40             : #include <pam.hxx>
      41             : #include <shellio.hxx>
      42             : #include <swerror.h>
      43             : #include <swtblfmt.hxx>
      44             : #include <docsh.hxx>
      45             : #include <docstyle.hxx>
      46             : #include <charfmt.hxx>
      47             : #include <txtfld.hxx>
      48             : #include <fmtfld.hxx>
      49             : #include <fmtpdsc.hxx>
      50             : #include <pagedesc.hxx>
      51             : #include <poolfmt.hrc>
      52             : #include <poolfmt.hxx>
      53             : #include <edimp.hxx>
      54             : #include <fchrfmt.hxx>
      55             : #include <cntfrm.hxx>
      56             : #include <pagefrm.hxx>
      57             : #include <doctxm.hxx>
      58             : #include <sfx2/docfilt.hxx>
      59             : #include <sfx2/docfile.hxx>
      60             : #include <sfx2/fcontnr.hxx>
      61             : #include <fmtrfmrk.hxx>
      62             : #include <txtrfmrk.hxx>
      63             : #include <unoparaframeenum.hxx>
      64             : #include <unofootnote.hxx>
      65             : #include <unotextbodyhf.hxx>
      66             : #include <unotextrange.hxx>
      67             : #include <unoparagraph.hxx>
      68             : #include <unomap.hxx>
      69             : #include <unoport.hxx>
      70             : #include <unocrsrhelper.hxx>
      71             : #include <unosett.hxx>
      72             : #include <unoprnms.hxx>
      73             : #include <unotbl.hxx>
      74             : #include <unodraw.hxx>
      75             : #include <unocoll.hxx>
      76             : #include <unostyle.hxx>
      77             : #include <fmtanchr.hxx>
      78             : #include <editeng/flstitem.hxx>
      79             : #include <editeng/unolingu.hxx>
      80             : #include <svtools/ctrltool.hxx>
      81             : #include <flypos.hxx>
      82             : #include <txtftn.hxx>
      83             : #include <fmtftn.hxx>
      84             : #include <fmtcntnt.hxx>
      85             : #include <com/sun/star/text/WrapTextMode.hpp>
      86             : #include <com/sun/star/text/TextContentAnchorType.hpp>
      87             : #include <com/sun/star/style/PageStyleLayout.hpp>
      88             : #include <com/sun/star/text/XTextDocument.hpp>
      89             : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
      90             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      91             : #include <unoframe.hxx>
      92             : #include <fmthdft.hxx>
      93             : #include <osl/mutex.hxx>
      94             : #include <vcl/svapp.hxx>
      95             : #include <fmtflcnt.hxx>
      96             : #include <editeng/brushitem.hxx>
      97             : #include <fmtclds.hxx>
      98             : #include <dcontact.hxx>
      99             : #include <dflyobj.hxx>
     100             : #include <crsskip.hxx>
     101             : #include <vector>
     102             : #include <sortedobjs.hxx>
     103             : #include <sortopt.hxx>
     104             : #include <algorithm>
     105             : #include <iterator>
     106             : #include <boost/bind.hpp>
     107             : #include <switerator.hxx>
     108             : #include <comphelper/servicehelper.hxx>
     109             : #include <cppuhelper/supportsservice.hxx>
     110             : 
     111             : using namespace ::com::sun::star;
     112             : 
     113             : namespace sw {
     114             : 
     115             : uno::Sequence< OUString >
     116         346 : GetSupportedServiceNamesImpl(
     117             :         size_t const nServices, char const*const pServices[])
     118             : {
     119         346 :     uno::Sequence< OUString > ret(nServices);
     120        2735 :     for (size_t i = 0; i < nServices; ++i)
     121             :     {
     122        2389 :         ret[i] = OUString::createFromAscii(pServices[i]);
     123             :     }
     124         346 :     return ret;
     125             : }
     126             : 
     127             : } // namespace sw
     128             : 
     129             : namespace sw {
     130             : 
     131           4 : void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget)
     132             : {
     133           4 :     rTarget = rSource;
     134             : 
     135           4 :     if (rSource.GetNext() != &rSource)
     136             :     {
     137           2 :         SwPaM *pPam = static_cast<SwPaM *>(rSource.GetNext());
     138          35 :         do
     139             :         {
     140             :             // create new PaM
     141          35 :             SwPaM *const pNew = new SwPaM(*pPam);
     142             :             // insert into ring
     143          35 :             pNew->MoveTo(&rTarget);
     144          35 :             pPam = static_cast<SwPaM *>(pPam->GetNext());
     145             :         }
     146             :         while (pPam != &rSource);
     147             :     }
     148           4 : }
     149             : 
     150             : } // namespace sw
     151             : 
     152             : struct FrameDependSortListLess
     153             : {
     154           0 :     bool operator() (FrameDependSortListEntry const& r1,
     155             :                      FrameDependSortListEntry const& r2) const
     156             :     {
     157           0 :         return  (r1.nIndex <  r2.nIndex)
     158           0 :             || ((r1.nIndex == r2.nIndex) && (r1.nOrder < r2.nOrder));
     159             :     }
     160             : };
     161             : 
     162             : // OD 2004-05-07 #i28701# - adjust 4th parameter
     163         757 : void CollectFrameAtNode( SwClient& rClnt, const SwNodeIndex& rIdx,
     164             :                          FrameDependSortList_t & rFrames,
     165             :                          const bool _bAtCharAnchoredObjs )
     166             : {
     167             :     // _bAtCharAnchoredObjs:
     168             :     // <sal_True>: at-character anchored objects are collected
     169             :     // <sal_False>: at-paragraph anchored objects are collected
     170             : 
     171             :     // search all borders, images, and OLEs that are connected to the paragraph
     172         757 :     SwDoc* pDoc = rIdx.GetNode().GetDoc();
     173             : 
     174             :     sal_uInt16 nChkType = static_cast< sal_uInt16 >((_bAtCharAnchoredObjs)
     175         757 :             ? FLY_AT_CHAR : FLY_AT_PARA);
     176             :     const SwCntntFrm* pCFrm;
     177             :     const SwCntntNode* pCNd;
     178        2269 :     if( pDoc->GetCurrentViewShell() &&
     179        1512 :         0 != (pCNd = rIdx.GetNode().GetCntntNode()) &&
     180         755 :         0 != (pCFrm = pCNd->getLayoutFrm( pDoc->GetCurrentLayout())) )
     181             :     {
     182         755 :         const SwSortedObjs *pObjs = pCFrm->GetDrawObjs();
     183         755 :         if( pObjs )
     184         566 :             for( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
     185             :             {
     186         403 :                 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
     187         403 :                 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
     188         403 :                 if ( rFmt.GetAnchor().GetAnchorId() == nChkType )
     189             :                 {
     190             :                     // create SwDepend and insert into array
     191          31 :                     SwDepend* pNewDepend = new SwDepend( &rClnt, &rFmt );
     192             :                     const sal_Int32 idx =
     193          31 :                         rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex();
     194          31 :                     sal_uInt32 nOrder = rFmt.GetAnchor().GetOrder();
     195             : 
     196             :                     // OD 2004-05-07 #i28701# - sorting no longer needed,
     197             :                     // because list <SwSortedObjs> is already sorted.
     198          31 :                     FrameDependSortListEntry entry(idx, nOrder, pNewDepend);
     199          31 :                     rFrames.push_back(entry);
     200             :                 }
     201             :             }
     202             :     }
     203             :     else
     204             :     {
     205           2 :         const SwFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
     206           2 :         sal_uInt16 nSize = rFmts.size();
     207           2 :         for ( sal_uInt16 i = 0; i < nSize; i++)
     208             :         {
     209           0 :             const SwFrmFmt* pFmt = rFmts[ i ];
     210           0 :             const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
     211             :             const SwPosition* pAnchorPos;
     212           0 :             if( rAnchor.GetAnchorId() == nChkType &&
     213           0 :                 0 != (pAnchorPos = rAnchor.GetCntntAnchor()) &&
     214           0 :                     pAnchorPos->nNode == rIdx )
     215             :             {
     216             :                 //jetzt einen SwDepend anlegen und in das Array einfuegen
     217           0 :                 SwDepend* pNewDepend = new SwDepend( &rClnt, (SwFrmFmt*)pFmt);
     218             : 
     219             :                 // OD 2004-05-07 #i28701# - determine insert position for
     220             :                 // sorted <rFrameArr>
     221           0 :                 const sal_Int32 nIndex = pAnchorPos->nContent.GetIndex();
     222           0 :                 sal_uInt32 nOrder = rAnchor.GetOrder();
     223             : 
     224           0 :                 FrameDependSortListEntry entry(nIndex, nOrder, pNewDepend);
     225           0 :                 rFrames.push_back(entry);
     226             :             }
     227             :         }
     228           2 :         ::std::sort(rFrames.begin(), rFrames.end(), FrameDependSortListLess());
     229             :     }
     230         757 : }
     231             : 
     232             : /****************************************************************************
     233             :     ActionContext
     234             : ****************************************************************************/
     235      125159 : UnoActionContext::UnoActionContext(SwDoc *const pDoc)
     236      125159 :     : m_pDoc(pDoc)
     237             : {
     238      125159 :     SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout();
     239      125159 :     if (pRootFrm)
     240             :     {
     241       19731 :         pRootFrm->StartAllAction();
     242             :     }
     243      125159 : }
     244             : 
     245      125159 : UnoActionContext::~UnoActionContext()
     246             : {
     247             :     // Doc may already have been removed here
     248      125159 :     if (m_pDoc)
     249             :     {
     250      125159 :         SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout();
     251      125159 :         if (pRootFrm)
     252             :         {
     253       19731 :             pRootFrm->EndAllAction();
     254             :         }
     255             :     }
     256      125159 : }
     257             : 
     258             : /****************************************************************************
     259             :     ActionRemoveContext
     260             : ****************************************************************************/
     261         194 : UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc)
     262         194 :     : m_pDoc(pDoc)
     263             : {
     264         194 :     SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout();
     265         194 :     if (pRootFrm)
     266             :     {
     267         173 :         pRootFrm->UnoRemoveAllActions();
     268             :     }
     269         194 : }
     270             : 
     271         194 : UnoActionRemoveContext::~UnoActionRemoveContext()
     272             : {
     273         194 :     SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout();
     274         194 :     if (pRootFrm)
     275             :     {
     276         173 :         pRootFrm->UnoRestoreAllActions();
     277             :     }
     278         194 : }
     279             : 
     280      238208 : void ClientModify(SwClient* pClient, const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     281             : {
     282      238208 :     switch( pOld ? pOld->Which() : 0 )
     283             :     {
     284             :     case RES_REMOVE_UNO_OBJECT:
     285             :     case RES_OBJECTDYING:
     286      206943 :         if( (void*)pClient->GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
     287      206554 :             ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient);
     288      206943 :         break;
     289             : 
     290             :     case RES_FMT_CHG:
     291             :         // Is the move to the new one finished and will the old one be deleted?
     292        1364 :         if( ((SwFmtChg*)pNew)->pChangedFmt == pClient->GetRegisteredIn() &&
     293         653 :             ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() )
     294         633 :             ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient);
     295         711 :         break;
     296             :     }
     297      238208 : }
     298             : 
     299       77587 : void SwUnoCursorHelper::SetCrsrAttr(SwPaM & rPam,
     300             :         const SfxItemSet& rSet,
     301             :         const SetAttrMode nAttrMode, const bool bTableMode)
     302             : {
     303       77587 :     const SetAttrMode nFlags = nAttrMode | nsSetAttrMode::SETATTR_APICALL;
     304       77587 :     SwDoc* pDoc = rPam.GetDoc();
     305             :     //StartEndAction
     306       77587 :     UnoActionContext aAction(pDoc);
     307       77587 :     if (rPam.GetNext() != &rPam)    // Ring of Cursors
     308             :     {
     309          73 :         pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSATTR, NULL);
     310             : 
     311          73 :         SwPaM *pCurrent = &rPam;
     312        1460 :         do
     313             :         {
     314        2920 :             if (pCurrent->HasMark() &&
     315           0 :                 ( (bTableMode) ||
     316           0 :                   (*pCurrent->GetPoint() != *pCurrent->GetMark()) ))
     317             :             {
     318        1460 :                 pDoc->InsertItemSet(*pCurrent, rSet, nFlags);
     319             :             }
     320        1460 :             pCurrent= static_cast<SwPaM *>(pCurrent->GetNext());
     321             :         } while (pCurrent != &rPam);
     322             : 
     323          73 :         pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSATTR, NULL);
     324             :     }
     325             :     else
     326             :     {
     327       77514 :         pDoc->InsertItemSet( rPam, rSet, nFlags );
     328             :     }
     329             : 
     330       77587 :     if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SFX_ITEM_AVAILABLE )
     331             :     {
     332          45 :         SwTxtNode * pTmpNode = rPam.GetNode()->GetTxtNode();
     333          45 :         if ( pTmpNode )
     334             :         {
     335          45 :             rPam.GetDoc()->GetNodes().UpdateOutlineNode( *pTmpNode );
     336             :         }
     337       77587 :     }
     338       77587 : }
     339             : 
     340             : // #i63870#
     341             : // split third parameter <bCurrentAttrOnly> into new parameters <bOnlyTxtAttr>
     342             : // and <bGetFromChrFmt> to get better control about resulting <SfxItemSet>
     343       92979 : void SwUnoCursorHelper::GetCrsrAttr(SwPaM & rPam,
     344             :         SfxItemSet & rSet, const bool bOnlyTxtAttr, const bool bGetFromChrFmt)
     345             : {
     346             :     static const sal_uInt16 nMaxLookup = 1000;
     347       92979 :     SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
     348       92979 :     SfxItemSet *pSet = &rSet;
     349       92979 :     SwPaM *pCurrent = & rPam;
     350       97197 :     do
     351             :     {
     352       97197 :         SwPosition const & rStart( *pCurrent->Start() );
     353       97197 :         SwPosition const & rEnd( *pCurrent->End() );
     354       97197 :         const sal_uLong nSttNd = rStart.nNode.GetIndex();
     355       97197 :         const sal_uLong nEndNd = rEnd  .nNode.GetIndex();
     356             : 
     357       97197 :         if (nEndNd - nSttNd >= nMaxLookup)
     358             :         {
     359           0 :             rSet.ClearItem();
     360           0 :             rSet.InvalidateAllItems();
     361       92979 :             return;// uno::Any();
     362             :         }
     363             : 
     364             :         // the first node inserts the values into the get set
     365             :         // all other nodes merge their values into the get set
     366      194711 :         for (sal_uLong n = nSttNd; n <= nEndNd; ++n)
     367             :         {
     368       97514 :             SwNode *const pNd = rPam.GetDoc()->GetNodes()[ n ];
     369       97514 :             switch (pNd->GetNodeType())
     370             :             {
     371             :                 case ND_TEXTNODE:
     372             :                 {
     373             :                     const sal_Int32 nStart = (n == nSttNd)
     374       97230 :                         ? rStart.nContent.GetIndex() : 0;
     375             :                     const sal_Int32 nEnd   = (n == nEndNd)
     376       96913 :                         ? rEnd.nContent.GetIndex()
     377      194143 :                         : static_cast<SwTxtNode*>(pNd)->GetTxt().getLength();
     378             :                     static_cast<SwTxtNode*>(pNd)->GetAttr(
     379       97230 :                         *pSet, nStart, nEnd, bOnlyTxtAttr, bGetFromChrFmt);
     380             :                 }
     381       97230 :                 break;
     382             : 
     383             :                 case ND_GRFNODE:
     384             :                 case ND_OLENODE:
     385           0 :                     static_cast<SwCntntNode*>(pNd)->GetAttr( *pSet );
     386           0 :                 break;
     387             : 
     388             :                 default:
     389         284 :                     continue; // skip this node
     390             :             }
     391             : 
     392       97230 :             if (pSet != &rSet)
     393             :             {
     394        4535 :                 rSet.MergeValues( aSet );
     395             :             }
     396             :             else
     397             :             {
     398       92695 :                 pSet = &aSet;
     399             :             }
     400             : 
     401       97230 :             if (aSet.Count())
     402             :             {
     403        3654 :                 aSet.ClearItem();
     404             :             }
     405             :         }
     406       97197 :         pCurrent= static_cast<SwPaM *>(pCurrent->GetNext());
     407       92979 :     } while ( pCurrent != &rPam );
     408             : }
     409             : 
     410             : /******************************************************************
     411             :  * SwXParagraphEnumeration
     412             :  ******************************************************************/
     413             : class SwXParagraphEnumeration::Impl
     414             :     : public SwClient
     415             : {
     416             : public:
     417             :     uno::Reference< text::XText > const     m_xParentText;
     418             :     const CursorType        m_eCursorType;
     419             :     /// Start node of the cell _or_ table the enumeration belongs to.
     420             :     /// Used to restrict the movement of the UNO cursor to the cell and its
     421             :     /// embedded tables.
     422             :     SwStartNode const*const m_pOwnStartNode;
     423             :     SwTable const*const     m_pOwnTable;
     424             :     const sal_uLong             m_nEndIndex;
     425             :     sal_Int32               m_nFirstParaStart;
     426             :     sal_Int32               m_nLastParaEnd;
     427             :     bool                    m_bFirstParagraph;
     428             :     uno::Reference< text::XTextContent >    m_xNextPara;
     429             : 
     430             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     431        5759 :     Impl(   uno::Reference< text::XText > const& xParent,
     432             :             ::std::auto_ptr<SwUnoCrsr> pCursor,
     433             :             const CursorType eType,
     434             :             SwStartNode const*const pStartNode, SwTable const*const pTable)
     435        5759 :         : SwClient( pCursor.release() )
     436             :         , m_xParentText( xParent )
     437             :         , m_eCursorType( eType )
     438             :         // remember table and start node for later travelling
     439             :         // (used in export of tables in tables)
     440             :         , m_pOwnStartNode( pStartNode )
     441             :         // for import of tables in tables we have to remember the actual
     442             :         // table and start node of the current position in the enumeration.
     443             :         , m_pOwnTable( pTable )
     444        5759 :         , m_nEndIndex( GetCursor()->End()->nNode.GetIndex() )
     445             :         , m_nFirstParaStart( -1 )
     446             :         , m_nLastParaEnd( -1 )
     447       11518 :         , m_bFirstParagraph( true )
     448             :     {
     449             :         OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?");
     450             :         OSL_ENSURE(GetRegisteredIn(),  "SwXParagraphEnumeration: no cursor?");
     451             :         OSL_ENSURE(   !((CURSOR_SELECTION_IN_TABLE == eType) ||
     452             :                         (CURSOR_TBLTEXT == eType))
     453             :                    || (m_pOwnTable && m_pOwnStartNode),
     454             :             "SwXParagraphEnumeration: table type but no start node or table?");
     455             : 
     456       10457 :         if ((CURSOR_SELECTION == m_eCursorType) ||
     457        4698 :             (CURSOR_SELECTION_IN_TABLE == m_eCursorType))
     458             :         {
     459        1401 :             SwUnoCrsr & rCursor = *GetCursor();
     460        1401 :             rCursor.Normalize();
     461        1401 :             m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex();
     462        1401 :             m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex();
     463        1401 :             rCursor.DeleteMark();
     464             :         }
     465        5759 :     }
     466             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     467             : 
     468       17277 :     virtual ~Impl() {
     469             :         // Impl owns the cursor; delete it here: SolarMutex is locked
     470        5759 :         delete GetRegisteredIn();
     471       11518 :     }
     472             : 
     473       19296 :     SwUnoCrsr * GetCursor() {
     474             :         return static_cast<SwUnoCrsr*>(
     475       19296 :                 const_cast<SwModify*>(GetRegisteredIn()));
     476             :     }
     477             : 
     478             :     uno::Reference< text::XTextContent > NextElement_Impl()
     479             :         throw (container::NoSuchElementException, lang::WrappedTargetException,
     480             :                 uno::RuntimeException);
     481             : protected:
     482             :     // SwClient
     483             :     virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
     484             : };
     485             : 
     486        5759 : void SwXParagraphEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     487             : {
     488        5759 :     ClientModify(this, pOld, pNew);
     489        5759 : }
     490             : 
     491             : SAL_WNODEPRECATED_DECLARATIONS_PUSH
     492        5759 : SwXParagraphEnumeration::SwXParagraphEnumeration(
     493             :         uno::Reference< text::XText > const& xParent,
     494             :         ::std::auto_ptr<SwUnoCrsr> pCursor,
     495             :         const CursorType eType,
     496             :         SwStartNode const*const pStartNode, SwTable const*const pTable)
     497             :     : m_pImpl( new SwXParagraphEnumeration::Impl(xParent, pCursor, eType,
     498        5759 :                     pStartNode, pTable) )
     499             : {
     500        5759 : }
     501             : SAL_WNODEPRECATED_DECLARATIONS_POP
     502             : 
     503       11518 : SwXParagraphEnumeration::~SwXParagraphEnumeration()
     504             : {
     505       11518 : }
     506             : 
     507             : OUString SAL_CALL
     508           0 : SwXParagraphEnumeration::getImplementationName() throw (uno::RuntimeException, std::exception)
     509             : {
     510           0 :     return OUString("SwXParagraphEnumeration");
     511             : }
     512             : 
     513             : static char const*const g_ServicesParagraphEnum[] =
     514             : {
     515             :     "com.sun.star.text.ParagraphEnumeration",
     516             : };
     517             : 
     518             : static const size_t g_nServicesParagraphEnum(
     519             :     sizeof(g_ServicesParagraphEnum)/sizeof(g_ServicesParagraphEnum[0]));
     520             : 
     521             : sal_Bool SAL_CALL
     522           0 : SwXParagraphEnumeration::supportsService(const OUString& rServiceName)
     523             : throw (uno::RuntimeException, std::exception)
     524             : {
     525           0 :     return cppu::supportsService(this, rServiceName);
     526             : }
     527             : 
     528             : uno::Sequence< OUString > SAL_CALL
     529           0 : SwXParagraphEnumeration::getSupportedServiceNames()
     530             : throw (uno::RuntimeException, std::exception)
     531             : {
     532             :     return ::sw::GetSupportedServiceNamesImpl(
     533           0 :             g_nServicesParagraphEnum, g_ServicesParagraphEnum);
     534             : }
     535             : 
     536             : sal_Bool SAL_CALL
     537        6143 : SwXParagraphEnumeration::hasMoreElements() throw (uno::RuntimeException, std::exception)
     538             : {
     539        6143 :     SolarMutexGuard aGuard;
     540             : 
     541        6143 :     return (m_pImpl->m_bFirstParagraph) ? sal_True : m_pImpl->m_xNextPara.is();
     542             : }
     543             : 
     544             : //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx
     545             : static SwTableNode *
     546       14032 : lcl_FindTopLevelTable(
     547             :         SwTableNode *const pTblNode, SwTable const*const pOwnTable)
     548             : {
     549             :     // find top-most table in current context (section) level
     550             : 
     551       14032 :     SwTableNode * pLast = pTblNode;
     552       28834 :     for (SwTableNode* pTmp = pLast;
     553       14417 :          pTmp != NULL  &&  &pTmp->GetTable() != pOwnTable;  /* we must not go up higher than the own table! */
     554         385 :          pTmp = pTmp->StartOfSectionNode()->FindTableNode() )
     555             :     {
     556         385 :         pLast = pTmp;
     557             :     }
     558       14032 :     return pLast;
     559             : }
     560             : 
     561             : static bool
     562       16822 : lcl_CursorIsInSection(
     563             :         SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode)
     564             : {
     565             :     // returns true if the cursor is in the section (or in a sub section!)
     566             :     // represented by pOwnStartNode
     567             : 
     568       16822 :     bool bRes = true;
     569       16822 :     if (pUnoCrsr && pOwnStartNode)
     570             :     {
     571        8963 :         const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode();
     572       17926 :         bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() &&
     573       17926 :                pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex();
     574             :     }
     575       16822 :     return bRes;
     576             : }
     577             : 
     578             : uno::Reference< text::XTextContent >
     579       12136 : SwXParagraphEnumeration::Impl::NextElement_Impl()
     580             : throw (container::NoSuchElementException, lang::WrappedTargetException,
     581             :         uno::RuntimeException)
     582             : {
     583       12136 :     SwUnoCrsr *const pUnoCrsr = GetCursor();
     584       12136 :     if (!pUnoCrsr)
     585             :     {
     586           0 :         throw uno::RuntimeException();
     587             :     }
     588             : 
     589             :     // check for exceeding selections
     590       18520 :     if (!m_bFirstParagraph &&
     591       11707 :         ((CURSOR_SELECTION == m_eCursorType) ||
     592        5323 :          (CURSOR_SELECTION_IN_TABLE == m_eCursorType)))
     593             :     {
     594        1401 :         SwPosition* pStart = pUnoCrsr->Start();
     595             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     596             :         const ::std::auto_ptr<SwUnoCrsr> aNewCrsr(
     597        1401 :             pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, false) );
     598             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     599             :         // one may also go into tables here
     600        2802 :         if ((CURSOR_TBLTEXT != m_eCursorType) &&
     601        1401 :             (CURSOR_SELECTION_IN_TABLE != m_eCursorType))
     602             :         {
     603        1061 :             aNewCrsr->SetRemainInSection( sal_False );
     604             :         }
     605             : 
     606             :         // os 2005-01-14: This part is only necessary to detect movements out
     607             :         // of a selection; if there is no selection we don't have to care
     608        1401 :         SwTableNode *const pTblNode = aNewCrsr->GetNode()->FindTableNode();
     609        2802 :         if (((CURSOR_TBLTEXT != m_eCursorType) &&
     610        2462 :             (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTblNode)
     611             :         {
     612           0 :             aNewCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
     613           0 :             aNewCrsr->Move(fnMoveForward, fnGoNode);
     614             :         }
     615             :         else
     616             :         {
     617        1401 :             aNewCrsr->MovePara(fnParaNext, fnParaStart);
     618             :         }
     619        1401 :         if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex())
     620             :         {
     621          37 :             return 0;
     622        1364 :         }
     623             :     }
     624             : 
     625       12099 :     bool bInTable = false;
     626       12099 :     if (!m_bFirstParagraph)
     627             :     {
     628        6347 :         pUnoCrsr->SetRemainInSection( sal_False );
     629             :         // what to do if already in a table?
     630        6347 :         SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode();
     631        6347 :         pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable );
     632        6347 :         if (pTblNode && (&pTblNode->GetTable() != m_pOwnTable))
     633             :         {
     634             :             // this is a foreign table: go to end
     635         170 :             pUnoCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
     636         170 :             if (!pUnoCrsr->Move(fnMoveForward, fnGoNode))
     637             :             {
     638           1 :                 return 0;
     639             :             }
     640         169 :             bInTable = true;
     641             :         }
     642             :     }
     643             : 
     644       12098 :     uno::Reference< text::XTextContent >  xRef;
     645             :     // the cursor must remain in the current section or a subsection
     646             :     // before AND after the movement...
     647       19783 :     if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) &&
     648       12523 :         (m_bFirstParagraph || bInTable ||
     649       10901 :         (pUnoCrsr->MovePara(fnParaNext, fnParaStart) &&
     650        4724 :             lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ))))
     651             :     {
     652        7685 :         SwPosition* pStart = pUnoCrsr->Start();
     653             :         const sal_Int32 nFirstContent =
     654        7685 :             (m_bFirstParagraph) ? m_nFirstParaStart : -1;
     655             :         const sal_Int32 nLastContent =
     656        7685 :             (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1;
     657             : 
     658             :         // position in a table, or in a simple paragraph?
     659        7685 :         SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode();
     660        7685 :         pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable );
     661        7685 :         if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */
     662        7685 :             pTblNode && (&pTblNode->GetTable() != m_pOwnTable))
     663             :         {
     664             :             // this is a foreign table
     665             :             SwFrmFmt* pTableFmt =
     666         201 :                 static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt());
     667             :             text::XTextTable *const pTable =
     668         201 :                 SwXTextTables::GetObject( *pTableFmt );
     669             :             xRef = static_cast<text::XTextContent*>(
     670         201 :                     static_cast<SwXTextTable*>(pTable));
     671             :         }
     672             :         else
     673             :         {
     674        7484 :             text::XText *const pText = m_xParentText.get();
     675       22452 :             xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(),
     676        7484 :                 *pStart->nNode.GetNode().GetTxtNode(),
     677       14968 :                 static_cast<SwXText*>(pText), nFirstContent, nLastContent);
     678             :         }
     679             :     }
     680             : 
     681       12098 :     return xRef;
     682             : }
     683             : 
     684        6386 : uno::Any SAL_CALL SwXParagraphEnumeration::nextElement()
     685             : throw (container::NoSuchElementException, lang::WrappedTargetException,
     686             :         uno::RuntimeException, std::exception)
     687             : {
     688        6386 :     SolarMutexGuard aGuard;
     689             : 
     690        6386 :     if (m_pImpl->m_bFirstParagraph)
     691             :     {
     692        5752 :         m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl();
     693        5752 :         m_pImpl->m_bFirstParagraph = false;
     694             :     }
     695       12772 :     const uno::Reference< text::XTextContent > xRef = m_pImpl->m_xNextPara;
     696        6386 :     if (!xRef.is())
     697             :     {
     698           2 :         throw container::NoSuchElementException();
     699             :     }
     700        6384 :     m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl();
     701             : 
     702        6384 :     uno::Any aRet;
     703        6384 :     aRet <<= xRef;
     704       12770 :     return aRet;
     705             : }
     706             : 
     707             : /******************************************************************
     708             :  * SwXTextRange
     709             :  ******************************************************************/
     710             : class SwXTextRange::Impl
     711             :     : public SwClient
     712             : {
     713             : public:
     714             :     const SfxItemPropertySet &  m_rPropSet;
     715             :     const enum RangePosition    m_eRangePosition;
     716             :     SwDoc &                     m_rDoc;
     717             :     uno::Reference<text::XText> m_xParentText;
     718             :     SwDepend            m_ObjectDepend; // register at format of table or frame
     719             :     ::sw::mark::IMark * m_pMark;
     720             : 
     721       79818 :     Impl(   SwDoc & rDoc, const enum RangePosition eRange,
     722             :             SwFrmFmt *const pTblFmt = 0,
     723             :             const uno::Reference< text::XText > & xParent = 0)
     724             :         : SwClient()
     725       79818 :         , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
     726             :         , m_eRangePosition(eRange)
     727             :         , m_rDoc(rDoc)
     728             :         , m_xParentText(xParent)
     729             :         , m_ObjectDepend(this, pTblFmt)
     730      159636 :         , m_pMark(0)
     731             :     {
     732       79818 :     }
     733             : 
     734      159632 :     virtual ~Impl()
     735      159632 :     {
     736             :         // Impl owns the bookmark; delete it here: SolarMutex is locked
     737       79816 :         Invalidate();
     738      159632 :     }
     739             : 
     740      159767 :     void Invalidate()
     741             :     {
     742      159767 :         if (m_pMark)
     743             :         {
     744       78830 :             m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
     745       78830 :             m_pMark = 0;
     746             :         }
     747      159767 :     }
     748             : 
     749       58401 :     const ::sw::mark::IMark * GetBookmark() const { return m_pMark; }
     750             : 
     751             : protected:
     752             :     // SwClient
     753             :     virtual void    Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
     754             : };
     755             : 
     756       80143 : void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     757             : {
     758       80143 :     const bool bAlreadyRegistered = 0 != GetRegisteredIn();
     759       80143 :     ClientModify(this, pOld, pNew);
     760       80143 :     if (m_ObjectDepend.GetRegisteredIn())
     761             :     {
     762         695 :         ClientModify(&m_ObjectDepend, pOld, pNew);
     763             :         // if the depend was removed then the range must be removed too
     764         695 :         if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn())
     765             :         {
     766           0 :             const_cast<SwModify*>(GetRegisteredIn())->Remove(this);
     767             :         }
     768             :         // or if the range has been removed but the depend is still
     769             :         // connected then the depend must be removed
     770        1082 :         else if (bAlreadyRegistered && !GetRegisteredIn() &&
     771         387 :                     m_ObjectDepend.GetRegisteredIn())
     772             :         {
     773         387 :             const_cast<SwModify*>(m_ObjectDepend.GetRegisteredIn())
     774         774 :                 ->Remove(& m_ObjectDepend);
     775             :         }
     776             :     }
     777       80143 :     if (!GetRegisteredIn())
     778             :     {
     779       79835 :         m_pMark = 0;
     780             :     }
     781       80143 : }
     782             : 
     783       79431 : SwXTextRange::SwXTextRange(SwPaM& rPam,
     784             :         const uno::Reference< text::XText > & xParent,
     785             :         const enum RangePosition eRange)
     786       79431 :     : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) )
     787             : {
     788       79431 :     SetPositions(rPam);
     789       79431 : }
     790             : 
     791         387 : SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt)
     792             :     : m_pImpl(
     793         387 :         new SwXTextRange::Impl(*rTblFmt.GetDoc(), RANGE_IS_TABLE, &rTblFmt) )
     794             : {
     795         387 :     SwTable *const pTable = SwTable::FindTable( &rTblFmt );
     796         387 :     SwTableNode *const pTblNode = pTable->GetTableNode();
     797         387 :     SwPosition aPosition( *pTblNode );
     798         774 :     SwPaM aPam( aPosition );
     799             : 
     800         774 :     SetPositions( aPam );
     801         387 : }
     802             : 
     803      159632 : SwXTextRange::~SwXTextRange()
     804             : {
     805      159632 : }
     806             : 
     807           0 : const SwDoc * SwXTextRange::GetDoc() const
     808             : {
     809           0 :     return & m_pImpl->m_rDoc;
     810             : }
     811             : 
     812       36819 : SwDoc * SwXTextRange::GetDoc()
     813             : {
     814       36819 :     return & m_pImpl->m_rDoc;
     815             : }
     816             : 
     817         116 : void SwXTextRange::Invalidate()
     818             : {
     819         116 :     m_pImpl->Invalidate();
     820         116 : }
     821             : 
     822       79835 : void SwXTextRange::SetPositions(const SwPaM& rPam)
     823             : {
     824       79835 :     m_pImpl->Invalidate();
     825       79835 :     IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess();
     826       79835 :     m_pImpl->m_pMark = pMA->makeMark(rPam, OUString(),
     827       79835 :                 IDocumentMarkAccess::UNO_BOOKMARK);
     828       79835 :     m_pImpl->m_pMark->Add(m_pImpl.get());
     829       79835 : }
     830             : 
     831          17 : void SwXTextRange::DeleteAndInsert(
     832             :         const OUString& rText, const bool bForceExpandHints)
     833             : throw (uno::RuntimeException)
     834             : {
     835          17 :     if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
     836             :     {
     837             :         // setString on table not allowed
     838           0 :         throw uno::RuntimeException();
     839             :     }
     840             : 
     841          17 :     const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
     842          34 :     SwCursor aCursor(aPos, 0, false);
     843          17 :     if (GetPositions(aCursor))
     844             :     {
     845          17 :         UnoActionContext aAction(& m_pImpl->m_rDoc);
     846          17 :         m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
     847          17 :         if (aCursor.HasMark())
     848             :         {
     849           9 :             m_pImpl->m_rDoc.DeleteAndJoin(aCursor);
     850             :         }
     851             : 
     852          17 :         if (!rText.isEmpty())
     853             :         {
     854             :             SwUnoCursorHelper::DocInsertStringSplitCR(
     855          11 :                     m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints);
     856             : 
     857          11 :             SwUnoCursorHelper::SelectPam(aCursor, true);
     858          11 :             aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False);
     859             :         }
     860          17 :         SetPositions(aCursor);
     861          17 :         m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
     862          17 :     }
     863          17 : }
     864             : 
     865             : namespace
     866             : {
     867             :     class theSwXTextRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangeUnoTunnelId > {};
     868             : }
     869             : 
     870      287530 : const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
     871             : {
     872      287530 :     return theSwXTextRangeUnoTunnelId::get().getSeq();
     873             : }
     874             : 
     875             : // XUnoTunnel
     876             : sal_Int64 SAL_CALL
     877      170457 : SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId)
     878             : throw (uno::RuntimeException, std::exception)
     879             : {
     880      170457 :     return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this);
     881             : }
     882             : 
     883             : OUString SAL_CALL
     884           3 : SwXTextRange::getImplementationName() throw (uno::RuntimeException, std::exception)
     885             : {
     886           3 :     return OUString("SwXTextRange");
     887             : }
     888             : 
     889             : static char const*const g_ServicesTextRange[] =
     890             : {
     891             :     "com.sun.star.text.TextRange",
     892             :     "com.sun.star.style.CharacterProperties",
     893             :     "com.sun.star.style.CharacterPropertiesAsian",
     894             :     "com.sun.star.style.CharacterPropertiesComplex",
     895             :     "com.sun.star.style.ParagraphProperties",
     896             :     "com.sun.star.style.ParagraphPropertiesAsian",
     897             :     "com.sun.star.style.ParagraphPropertiesComplex",
     898             : };
     899             : 
     900             : static const size_t g_nServicesTextRange(
     901             :     sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0]));
     902             : 
     903           5 : sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName)
     904             : throw (uno::RuntimeException, std::exception)
     905             : {
     906           5 :     return cppu::supportsService(this, rServiceName);
     907             : }
     908             : 
     909             : uno::Sequence< OUString > SAL_CALL
     910           5 : SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
     911             : {
     912             :     return ::sw::GetSupportedServiceNamesImpl(
     913           5 :             g_nServicesTextRange, g_ServicesTextRange);
     914             : }
     915             : 
     916             : uno::Reference< text::XText > SAL_CALL
     917        3872 : SwXTextRange::getText() throw (uno::RuntimeException, std::exception)
     918             : {
     919        3872 :     SolarMutexGuard aGuard;
     920             : 
     921        3872 :     if (!m_pImpl->m_xParentText.is())
     922             :     {
     923           0 :         if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
     924           0 :             m_pImpl->m_ObjectDepend.GetRegisteredIn())
     925             :         {
     926             :             SwFrmFmt const*const pTblFmt = static_cast<SwFrmFmt const*>(
     927           0 :                     m_pImpl->m_ObjectDepend.GetRegisteredIn());
     928           0 :             SwTable const*const pTable = SwTable::FindTable( pTblFmt );
     929           0 :             SwTableNode const*const pTblNode = pTable->GetTableNode();
     930           0 :             const SwPosition aPosition( *pTblNode );
     931           0 :             m_pImpl->m_xParentText =
     932           0 :                 ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition);
     933             :         }
     934             :     }
     935             :     OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text");
     936        3872 :     return m_pImpl->m_xParentText;
     937             : }
     938             : 
     939             : uno::Reference< text::XTextRange > SAL_CALL
     940          13 : SwXTextRange::getStart() throw (uno::RuntimeException, std::exception)
     941             : {
     942          13 :     SolarMutexGuard aGuard;
     943             : 
     944          13 :     uno::Reference< text::XTextRange >  xRet;
     945          13 :     ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
     946          13 :     if (!m_pImpl->m_xParentText.is())
     947             :     {
     948           0 :         getText();
     949             :     }
     950          13 :     if(pBkmk)
     951             :     {
     952          13 :         SwPaM aPam(pBkmk->GetMarkStart());
     953          13 :         xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
     954             :     }
     955           0 :     else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
     956             :     {
     957             :         // start and end are this, if it's a table
     958           0 :         xRet = this;
     959             :     }
     960             :     else
     961             :     {
     962           0 :         throw uno::RuntimeException();
     963             :     }
     964          13 :     return xRet;
     965             : }
     966             : 
     967             : uno::Reference< text::XTextRange > SAL_CALL
     968        7630 : SwXTextRange::getEnd() throw (uno::RuntimeException, std::exception)
     969             : {
     970        7630 :     SolarMutexGuard aGuard;
     971             : 
     972        7630 :     uno::Reference< text::XTextRange >  xRet;
     973        7630 :     ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
     974        7630 :     if (!m_pImpl->m_xParentText.is())
     975             :     {
     976           0 :         getText();
     977             :     }
     978        7630 :     if(pBkmk)
     979             :     {
     980        7630 :         SwPaM aPam(pBkmk->GetMarkEnd());
     981        7630 :         xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
     982             :     }
     983           0 :     else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
     984             :     {
     985             :         // start and end are this, if it's a table
     986           0 :         xRet = this;
     987             :     }
     988             :     else
     989             :     {
     990           0 :         throw uno::RuntimeException();
     991             :     }
     992        7630 :     return xRet;
     993             : }
     994             : 
     995        4842 : OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException, std::exception)
     996             : {
     997        4842 :     SolarMutexGuard aGuard;
     998             : 
     999        4842 :     OUString sRet;
    1000             :     // for tables there is no bookmark, thus also no text
    1001             :     // one could export the table as ASCII here maybe?
    1002        9684 :     SwPaM aPaM(GetDoc()->GetNodes());
    1003        4842 :     if (GetPositions(aPaM) && aPaM.HasMark())
    1004             :     {
    1005        4841 :         SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
    1006             :     }
    1007        9684 :     return sRet;
    1008             : }
    1009             : 
    1010          17 : void SAL_CALL SwXTextRange::setString(const OUString& rString)
    1011             : throw (uno::RuntimeException, std::exception)
    1012             : {
    1013          17 :     SolarMutexGuard aGuard;
    1014             : 
    1015          17 :     DeleteAndInsert(rString, false);
    1016          17 : }
    1017             : 
    1018       49079 : bool SwXTextRange::GetPositions(SwPaM& rToFill) const
    1019             : {
    1020       49079 :     ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
    1021       49079 :     if(pBkmk)
    1022             :     {
    1023       49079 :         *rToFill.GetPoint() = pBkmk->GetMarkPos();
    1024       49079 :         if(pBkmk->IsExpanded())
    1025             :         {
    1026        6144 :             rToFill.SetMark();
    1027        6144 :             *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
    1028             :         }
    1029             :         else
    1030             :         {
    1031       42935 :             rToFill.DeleteMark();
    1032             :         }
    1033       49079 :         return true;
    1034             :     }
    1035           0 :     return false;
    1036             : }
    1037             : 
    1038             : namespace sw {
    1039             : 
    1040       45903 : bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
    1041             :         const uno::Reference< text::XTextRange > & xTextRange)
    1042             : {
    1043       45903 :     bool bRet = false;
    1044             : 
    1045       45903 :     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
    1046       45903 :     SwXTextRange* pRange = 0;
    1047       45903 :     OTextCursorHelper* pCursor = 0;
    1048       45903 :     SwXTextPortion* pPortion = 0;
    1049       45903 :     SwXText* pText = 0;
    1050       45903 :     SwXParagraph* pPara = 0;
    1051       45903 :     if(xRangeTunnel.is())
    1052             :     {
    1053       45901 :         pRange  = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
    1054             :         pCursor =
    1055       45901 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
    1056             :         pPortion=
    1057       45901 :             ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel);
    1058       45901 :         pText   = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel);
    1059       45901 :         pPara   = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel);
    1060             :     }
    1061             : 
    1062             :     // if it's a text then create a temporary cursor there and re-use
    1063             :     // the pCursor variable
    1064             :     // #i108489#: Reference in outside scope to keep cursor alive
    1065       91806 :     uno::Reference< text::XTextCursor > xTextCursor;
    1066       45903 :     if (pText)
    1067             :     {
    1068           1 :         xTextCursor.set( pText->CreateCursor() );
    1069           1 :         xTextCursor->gotoEnd(sal_True);
    1070             :         const uno::Reference<lang::XUnoTunnel> xCrsrTunnel(
    1071           1 :                 xTextCursor, uno::UNO_QUERY);
    1072             :         pCursor =
    1073           1 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCrsrTunnel);
    1074             :     }
    1075       45903 :     if(pRange && pRange->GetDoc() == rToFill.GetDoc())
    1076             :     {
    1077       24844 :         bRet = pRange->GetPositions(rToFill);
    1078             :     }
    1079             :     else
    1080             :     {
    1081       21059 :         if (pPara)
    1082             :         {
    1083           0 :             bRet = pPara->SelectPaM(rToFill);
    1084             :         }
    1085             :         else
    1086             :         {
    1087       21057 :             SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc()
    1088       42116 :                 : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0);
    1089       21057 :             const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM()
    1090       42116 :                 : ((pPortion) ? pPortion->GetCursor() : 0);
    1091       21059 :             if (pUnoCrsr && pDoc == rToFill.GetDoc())
    1092             :             {
    1093             :                 OSL_ENSURE((SwPaM*)pUnoCrsr->GetNext() == pUnoCrsr,
    1094             :                         "what to do about rings?");
    1095       21056 :                 bRet = true;
    1096       21056 :                 *rToFill.GetPoint() = *pUnoCrsr->GetPoint();
    1097       21056 :                 if (pUnoCrsr->HasMark())
    1098             :                 {
    1099       10098 :                     rToFill.SetMark();
    1100       10098 :                     *rToFill.GetMark() = *pUnoCrsr->GetMark();
    1101             :                 }
    1102             :                 else
    1103       10958 :                     rToFill.DeleteMark();
    1104             :             }
    1105             :         }
    1106             :     }
    1107       91806 :     return bRet;
    1108             : }
    1109             : 
    1110             : static bool
    1111          94 : lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode,
    1112             :     SwFrmFmt const*const pFrmFmt, SwFrmFmt*& rpFormat)
    1113             : {
    1114          94 :     bool bRet = false;
    1115          94 :     const SfxItemSet& rSet = pFrmFmt->GetAttrSet();
    1116             :     const SfxPoolItem* pItem;
    1117          94 :     if (SFX_ITEM_SET == rSet.GetItemState(
    1118             :             static_cast<sal_uInt16>(bHeader ? RES_HEADER : RES_FOOTER),
    1119          94 :             true, &pItem))
    1120             :     {
    1121          94 :         SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem));
    1122             :         SwFrmFmt *const pHeadFootFmt = (bHeader) ?
    1123             :             static_cast<SwFmtHeader*>(pItemNonConst)->GetHeaderFmt() :
    1124          94 :             static_cast<SwFmtFooter*>(pItemNonConst)->GetFooterFmt();
    1125          94 :         if (pHeadFootFmt)
    1126             :         {
    1127          94 :             const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
    1128          94 :             const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
    1129             :             SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType(
    1130          94 :                 (bHeader) ? SwHeaderStartNode : SwFooterStartNode);
    1131          94 :             if (pCurSttNode && (pCurSttNode == pSttNode))
    1132             :             {
    1133          60 :                 rpFormat = pHeadFootFmt;
    1134          60 :                 bRet = true;
    1135             :             }
    1136             :         }
    1137             :     }
    1138          94 :     return bRet;
    1139             : }
    1140             : 
    1141             : } // namespace sw
    1142             : 
    1143             : uno::Reference< text::XTextRange >
    1144        5482 : SwXTextRange::CreateXTextRange(
    1145             :     SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
    1146             : {
    1147             :     const uno::Reference<text::XText> xParentText(
    1148        5482 :             ::sw::CreateParentXText(rDoc, rPos));
    1149             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1150             :     const ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
    1151       10964 :             rDoc.CreateUnoCrsr(rPos, false));
    1152             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1153        5482 :     if(pMark)
    1154             :     {
    1155        5082 :         pNewCrsr->SetMark();
    1156        5082 :         *pNewCrsr->GetMark() = *pMark;
    1157             :     }
    1158        5482 :     const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
    1159             :     const uno::Reference< text::XTextRange > xRet(
    1160        5482 :         new SwXTextRange(*pNewCrsr, xParentText,
    1161        5482 :             isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) );
    1162       10964 :     return xRet;
    1163             : }
    1164             : 
    1165             : namespace sw {
    1166             : 
    1167             : uno::Reference< text::XText >
    1168        5587 : CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
    1169             : {
    1170        5587 :     uno::Reference< text::XText > xParentText;
    1171        5587 :     SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode();
    1172       11243 :     while(pSttNode && pSttNode->IsSectionNode())
    1173             :     {
    1174          69 :         pSttNode = pSttNode->StartOfSectionNode();
    1175             :     }
    1176        5587 :     SwStartNodeType eType = pSttNode ? pSttNode->GetStartNodeType() : SwNormalStartNode;
    1177        5587 :     switch(eType)
    1178             :     {
    1179             :         case SwTableBoxStartNode:
    1180             :         {
    1181         305 :             SwTableNode const*const pTblNode = pSttNode->FindTableNode();
    1182             :             SwFrmFmt *const pTableFmt =
    1183         305 :                 static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt());
    1184         305 :             SwTableBox *const  pBox = pSttNode->GetTblBox();
    1185             : 
    1186         305 :             xParentText = (pBox)
    1187             :                 ? SwXCell::CreateXCell( pTableFmt, pBox )
    1188         305 :                 : new SwXCell( pTableFmt, *pSttNode );
    1189             :         }
    1190         305 :         break;
    1191             :         case SwFlyStartNode:
    1192             :         {
    1193           0 :             SwFrmFmt *const pFmt = pSttNode->GetFlyFmt();
    1194           0 :             if (0 != pFmt)
    1195             :             {
    1196           0 :                 SwXTextFrame* pFrame = SwIterator<SwXTextFrame,SwFmt>::FirstElement( *pFmt );
    1197           0 :                 xParentText = pFrame ? pFrame : new SwXTextFrame( *pFmt );
    1198             :             }
    1199             :         }
    1200           0 :         break;
    1201             :         case SwHeaderStartNode:
    1202             :         case SwFooterStartNode:
    1203             :         {
    1204          60 :             const bool bHeader = (SwHeaderStartNode == eType);
    1205          60 :             const sal_uInt16 nPDescCount = rDoc.GetPageDescCnt();
    1206         136 :             for(sal_uInt16 i = 0; i < nPDescCount; i++)
    1207             :             {
    1208          76 :                 const SwPageDesc& rDesc = rDoc.GetPageDesc( i );
    1209          76 :                 const SwFrmFmt* pFrmFmtMaster = &rDesc.GetMaster();
    1210          76 :                 const SwFrmFmt* pFrmFmtLeft = &rDesc.GetLeft();
    1211             : 
    1212          76 :                 SwFrmFmt* pHeadFootFmt = 0;
    1213          76 :                 if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtMaster,
    1214          76 :                             pHeadFootFmt))
    1215             :                 {
    1216             :                     lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtLeft,
    1217          18 :                             pHeadFootFmt);
    1218             :                 }
    1219             : 
    1220          76 :                 if (pHeadFootFmt)
    1221             :                 {
    1222         120 :                     xParentText = SwXHeadFootText::CreateXHeadFootText(
    1223          60 :                             *pHeadFootFmt, bHeader);
    1224             :                 }
    1225             :             }
    1226             :         }
    1227          60 :         break;
    1228             :         case SwFootnoteStartNode:
    1229             :         {
    1230           0 :             const sal_uInt16 nFtnCnt = rDoc.GetFtnIdxs().size();
    1231           0 :             uno::Reference< text::XFootnote >  xRef;
    1232           0 :             for (sal_uInt16 n = 0; n < nFtnCnt; ++n )
    1233             :             {
    1234           0 :                 const SwTxtFtn* pTxtFtn = rDoc.GetFtnIdxs()[ n ];
    1235           0 :                 const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
    1236           0 :                 pTxtFtn = rFtn.GetTxtFtn();
    1237             : #if OSL_DEBUG_LEVEL > 1
    1238             :                 const SwStartNode* pTmpSttNode =
    1239             :                         pTxtFtn->GetStartNode()->GetNode().
    1240             :                                 FindSttNodeByType(SwFootnoteStartNode);
    1241             :                 (void)pTmpSttNode;
    1242             : #endif
    1243             : 
    1244           0 :                 if (pSttNode == pTxtFtn->GetStartNode()->GetNode().
    1245           0 :                                     FindSttNodeByType(SwFootnoteStartNode))
    1246             :                 {
    1247           0 :                     xParentText = SwXFootnote::CreateXFootnote(rDoc, rFtn);
    1248           0 :                     break;
    1249             :                 }
    1250           0 :             }
    1251             :         }
    1252           0 :         break;
    1253             :         default:
    1254             :         {
    1255             :             // then it is the body text
    1256             :             const uno::Reference<frame::XModel> xModel =
    1257        5222 :                 rDoc.GetDocShell()->GetBaseModel();
    1258             :             const uno::Reference< text::XTextDocument > xDoc(
    1259       10444 :                 xModel, uno::UNO_QUERY);
    1260       10444 :             xParentText = xDoc->getText();
    1261             :         }
    1262             :     }
    1263             :     OSL_ENSURE(xParentText.is(), "no parent text?");
    1264        5587 :     return xParentText;
    1265             : }
    1266             : 
    1267             : } // namespace sw
    1268             : 
    1269             : uno::Reference< container::XEnumeration > SAL_CALL
    1270           1 : SwXTextRange::createContentEnumeration(const OUString& rServiceName)
    1271             : throw (uno::RuntimeException, std::exception)
    1272             : {
    1273           1 :     SolarMutexGuard g;
    1274             : 
    1275           1 :     if ( rServiceName != "com.sun.star.text.TextContent" )
    1276             :     {
    1277           0 :         throw uno::RuntimeException();
    1278             :     }
    1279             : 
    1280           1 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1281             :     {
    1282           0 :         throw uno::RuntimeException();
    1283             :     }
    1284           2 :     const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
    1285             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1286             :     const ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
    1287           2 :             m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
    1288             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1289           1 :     if (!GetPositions(*pNewCrsr))
    1290             :     {
    1291           0 :         throw uno::RuntimeException();
    1292             :     }
    1293             : 
    1294             :     const uno::Reference< container::XEnumeration > xRet =
    1295           1 :         new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
    1296           2 :     return xRet;
    1297             : }
    1298             : 
    1299             : uno::Reference< container::XEnumeration > SAL_CALL
    1300           0 : SwXTextRange::createEnumeration() throw (uno::RuntimeException, std::exception)
    1301             : {
    1302           0 :     SolarMutexGuard g;
    1303             : 
    1304           0 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1305             :     {
    1306           0 :         throw uno::RuntimeException();
    1307             :     }
    1308           0 :     const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
    1309             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1310             :     ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
    1311           0 :             m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
    1312             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1313           0 :     if (!GetPositions(*pNewCrsr))
    1314             :     {
    1315           0 :         throw uno::RuntimeException();
    1316             :     }
    1317           0 :     if (!m_pImpl->m_xParentText.is())
    1318             :     {
    1319           0 :         getText();
    1320             :     }
    1321             : 
    1322           0 :     const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition)
    1323           0 :             ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
    1324             :     const uno::Reference< container::XEnumeration > xRet =
    1325           0 :         new SwXParagraphEnumeration(m_pImpl->m_xParentText, pNewCrsr, eSetType);
    1326           0 :     return xRet;
    1327             : }
    1328             : 
    1329           0 : uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException, std::exception)
    1330             : {
    1331           0 :     return cppu::UnoType<text::XTextRange>::get();
    1332             : }
    1333             : 
    1334           0 : sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException, std::exception)
    1335             : {
    1336           0 :     return sal_True;
    1337             : }
    1338             : 
    1339             : uno::Sequence< OUString > SAL_CALL
    1340           1 : SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException, std::exception)
    1341             : {
    1342           1 :     uno::Sequence< OUString > aRet(1);
    1343           1 :     OUString* pArray = aRet.getArray();
    1344           1 :     pArray[0] = "com.sun.star.text.TextContent";
    1345           1 :     return aRet;
    1346             : }
    1347             : 
    1348             : uno::Reference< beans::XPropertySetInfo > SAL_CALL
    1349         206 : SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
    1350             : {
    1351         206 :     SolarMutexGuard aGuard;
    1352             : 
    1353             :     static uno::Reference< beans::XPropertySetInfo > xRef =
    1354         206 :         m_pImpl->m_rPropSet.getPropertySetInfo();
    1355         206 :     return xRef;
    1356             : }
    1357             : 
    1358             : void SAL_CALL
    1359         441 : SwXTextRange::setPropertyValue(
    1360             :         const OUString& rPropertyName, const uno::Any& rValue)
    1361             : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
    1362             :         lang::IllegalArgumentException, lang::WrappedTargetException,
    1363             :         uno::RuntimeException, std::exception)
    1364             : {
    1365         441 :     SolarMutexGuard aGuard;
    1366             : 
    1367         441 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1368             :     {
    1369           0 :         throw uno::RuntimeException();
    1370             :     }
    1371         882 :     SwPaM aPaM(GetDoc()->GetNodes());
    1372         441 :     GetPositions(aPaM);
    1373         441 :     SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet,
    1374         882 :             rPropertyName, rValue);
    1375         441 : }
    1376             : 
    1377             : uno::Any SAL_CALL
    1378         556 : SwXTextRange::getPropertyValue(const OUString& rPropertyName)
    1379             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1380             :         uno::RuntimeException, std::exception)
    1381             : {
    1382         556 :     SolarMutexGuard aGuard;
    1383             : 
    1384         556 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1385             :     {
    1386           0 :         throw uno::RuntimeException();
    1387             :     }
    1388        1110 :     SwPaM aPaM(GetDoc()->GetNodes());
    1389         556 :     GetPositions(aPaM);
    1390         556 :     return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet,
    1391        1112 :             rPropertyName);
    1392             : }
    1393             : 
    1394             : void SAL_CALL
    1395           0 : SwXTextRange::addPropertyChangeListener(
    1396             :         const OUString& /*rPropertyName*/,
    1397             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    1398             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1399             :     uno::RuntimeException, std::exception)
    1400             : {
    1401             :     OSL_FAIL("SwXTextRange::addPropertyChangeListener(): not implemented");
    1402           0 : }
    1403             : 
    1404             : void SAL_CALL
    1405           0 : SwXTextRange::removePropertyChangeListener(
    1406             :         const OUString& /*rPropertyName*/,
    1407             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    1408             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1409             :     uno::RuntimeException, std::exception)
    1410             : {
    1411             :     OSL_FAIL("SwXTextRange::removePropertyChangeListener(): not implemented");
    1412           0 : }
    1413             : 
    1414             : void SAL_CALL
    1415           0 : SwXTextRange::addVetoableChangeListener(
    1416             :         const OUString& /*rPropertyName*/,
    1417             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    1418             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1419             :     uno::RuntimeException, std::exception)
    1420             : {
    1421             :     OSL_FAIL("SwXTextRange::addVetoableChangeListener(): not implemented");
    1422           0 : }
    1423             : 
    1424             : void SAL_CALL
    1425           0 : SwXTextRange::removeVetoableChangeListener(
    1426             :         const OUString& /*rPropertyName*/,
    1427             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    1428             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1429             :         uno::RuntimeException, std::exception)
    1430             : {
    1431             :     OSL_FAIL("SwXTextRange::removeVetoableChangeListener(): not implemented");
    1432           0 : }
    1433             : 
    1434             : beans::PropertyState SAL_CALL
    1435           1 : SwXTextRange::getPropertyState(const OUString& rPropertyName)
    1436             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    1437             : {
    1438           1 :     SolarMutexGuard aGuard;
    1439             : 
    1440           1 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1441             :     {
    1442           0 :         throw uno::RuntimeException();
    1443             :     }
    1444           2 :     SwPaM aPaM(GetDoc()->GetNodes());
    1445           1 :     GetPositions(aPaM);
    1446           1 :     return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet,
    1447           2 :             rPropertyName);
    1448             : }
    1449             : 
    1450             : uno::Sequence< beans::PropertyState > SAL_CALL
    1451          27 : SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName)
    1452             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    1453             : {
    1454          27 :     SolarMutexGuard g;
    1455             : 
    1456          27 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1457             :     {
    1458           0 :         throw uno::RuntimeException();
    1459             :     }
    1460          54 :     SwPaM aPaM(GetDoc()->GetNodes());
    1461          27 :     GetPositions(aPaM);
    1462          27 :     return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet,
    1463          54 :             rPropertyName);
    1464             : }
    1465             : 
    1466           1 : void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName)
    1467             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    1468             : {
    1469           1 :     SolarMutexGuard aGuard;
    1470             : 
    1471           1 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1472             :     {
    1473           0 :         throw uno::RuntimeException();
    1474             :     }
    1475           2 :     SwPaM aPaM(GetDoc()->GetNodes());
    1476           1 :     GetPositions(aPaM);
    1477           1 :     SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet,
    1478           2 :             rPropertyName);
    1479           1 : }
    1480             : 
    1481             : uno::Any SAL_CALL
    1482           1 : SwXTextRange::getPropertyDefault(const OUString& rPropertyName)
    1483             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1484             :         uno::RuntimeException, std::exception)
    1485             : {
    1486           1 :     SolarMutexGuard aGuard;
    1487             : 
    1488           1 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1489             :     {
    1490           0 :         throw uno::RuntimeException();
    1491             :     }
    1492           2 :     SwPaM aPaM(GetDoc()->GetNodes());
    1493           1 :     GetPositions(aPaM);
    1494           1 :     return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet,
    1495           2 :             rPropertyName);
    1496             : }
    1497             : 
    1498             : void SAL_CALL
    1499         651 : SwXTextRange::makeRedline(
    1500             :     const OUString& rRedlineType,
    1501             :     const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
    1502             : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    1503             : {
    1504         651 :     SolarMutexGuard aGuard;
    1505             : 
    1506         651 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1507             :     {
    1508           0 :         throw uno::RuntimeException();
    1509             :     }
    1510        1210 :     SwPaM aPaM(GetDoc()->GetNodes());
    1511         651 :     SwXTextRange::GetPositions(aPaM);
    1512        1302 :     SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
    1513         559 : }
    1514             : 
    1515             : /******************************************************************
    1516             :  * SwXTextRanges
    1517             :  ******************************************************************/
    1518             : class SwXTextRanges::Impl
    1519             :     : public SwClient
    1520             : {
    1521             : public:
    1522             :     ::std::vector< uno::Reference< text::XTextRange > > m_Ranges;
    1523             : 
    1524           4 :     Impl(SwPaM *const pPaM)
    1525             :         : SwClient( (pPaM)
    1526           4 :             ? pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint())
    1527           8 :             : 0 )
    1528             :     {
    1529           4 :         if (pPaM)
    1530             :         {
    1531           4 :             ::sw::DeepCopyPaM(*pPaM, *GetCursor());
    1532             :         }
    1533           4 :         MakeRanges();
    1534           4 :     }
    1535             : 
    1536          12 :     virtual ~Impl() {
    1537             :         // Impl owns the cursor; delete it here: SolarMutex is locked
    1538           4 :         delete GetRegisteredIn();
    1539           8 :     }
    1540             : 
    1541           8 :     SwUnoCrsr * GetCursor() {
    1542             :         return static_cast<SwUnoCrsr*>(
    1543           8 :                 const_cast<SwModify*>(GetRegisteredIn()));
    1544             :     }
    1545             : 
    1546             :     void MakeRanges();
    1547             : 
    1548             : protected:
    1549             :     // SwClient
    1550             :     virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
    1551             : };
    1552             : 
    1553           4 : void SwXTextRanges::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
    1554             : {
    1555           4 :     ClientModify(this, pOld, pNew);
    1556           4 : }
    1557             : 
    1558           4 : void SwXTextRanges::Impl::MakeRanges()
    1559             : {
    1560           4 :     SwUnoCrsr *const pCursor = GetCursor();
    1561           4 :     if (pCursor)
    1562             :     {
    1563           4 :         SwPaM *pTmpCursor = pCursor;
    1564          39 :         do {
    1565             :             const uno::Reference< text::XTextRange > xRange(
    1566             :                     SwXTextRange::CreateXTextRange(
    1567          39 :                         *pTmpCursor->GetDoc(),
    1568          78 :                         *pTmpCursor->GetPoint(), pTmpCursor->GetMark()));
    1569          39 :             if (xRange.is())
    1570             :             {
    1571          39 :                 m_Ranges.push_back(xRange);
    1572             :             }
    1573          39 :             pTmpCursor = static_cast<SwPaM*>(pTmpCursor->GetNext());
    1574             :         }
    1575          39 :         while (pTmpCursor != pCursor);
    1576             :     }
    1577           4 : }
    1578             : 
    1579           0 : const SwUnoCrsr* SwXTextRanges::GetCursor() const
    1580             : {
    1581           0 :     return m_pImpl->GetCursor();
    1582             : }
    1583             : 
    1584           4 : SwXTextRanges::SwXTextRanges(SwPaM *const pPaM)
    1585           4 :     : m_pImpl( new SwXTextRanges::Impl(pPaM) )
    1586             : {
    1587           4 : }
    1588             : 
    1589           8 : SwXTextRanges::~SwXTextRanges()
    1590             : {
    1591           8 : }
    1592             : 
    1593             : namespace
    1594             : {
    1595             :     class theSwXTextRangesUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangesUnoTunnelId > {};
    1596             : }
    1597             : 
    1598           9 : const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
    1599             : {
    1600           9 :     return theSwXTextRangesUnoTunnelId::get().getSeq();
    1601             : }
    1602             : 
    1603             : sal_Int64 SAL_CALL
    1604           0 : SwXTextRanges::getSomething(const uno::Sequence< sal_Int8 >& rId)
    1605             : throw (uno::RuntimeException, std::exception)
    1606             : {
    1607           0 :     return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this);
    1608             : }
    1609             : 
    1610             : /****************************************************************************
    1611             :  *  Text positions
    1612             :  * Up to the first access to a text position, only a SwCursor is stored.
    1613             :  * Afterwards, an array with uno::Reference<XTextPosition> will be created.
    1614             : ****************************************************************************/
    1615             : OUString SAL_CALL
    1616           0 : SwXTextRanges::getImplementationName() throw (uno::RuntimeException, std::exception)
    1617             : {
    1618           0 :     return OUString("SwXTextRanges");
    1619             : }
    1620             : 
    1621             : static char const*const g_ServicesTextRanges[] =
    1622             : {
    1623             :     "com.sun.star.text.TextRanges",
    1624             : };
    1625             : 
    1626             : static const size_t g_nServicesTextRanges(
    1627             :     sizeof(g_ServicesTextRanges)/sizeof(g_ServicesTextRanges[0]));
    1628             : 
    1629           0 : sal_Bool SAL_CALL SwXTextRanges::supportsService(const OUString& rServiceName)
    1630             : throw (uno::RuntimeException, std::exception)
    1631             : {
    1632           0 :     return cppu::supportsService(this, rServiceName);
    1633             : }
    1634             : 
    1635             : uno::Sequence< OUString > SAL_CALL
    1636           0 : SwXTextRanges::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
    1637             : {
    1638             :     return ::sw::GetSupportedServiceNamesImpl(
    1639           0 :             g_nServicesTextRanges, g_ServicesTextRanges);
    1640             : }
    1641             : 
    1642           4 : sal_Int32 SAL_CALL SwXTextRanges::getCount() throw (uno::RuntimeException, std::exception)
    1643             : {
    1644           4 :     SolarMutexGuard aGuard;
    1645             : 
    1646           4 :     return static_cast<sal_Int32>(m_pImpl->m_Ranges.size());
    1647             : }
    1648             : 
    1649           5 : uno::Any SAL_CALL SwXTextRanges::getByIndex(sal_Int32 nIndex)
    1650             : throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException,
    1651             :         uno::RuntimeException, std::exception)
    1652             : {
    1653           5 :     SolarMutexGuard aGuard;
    1654             : 
    1655          10 :     if ((nIndex < 0) ||
    1656           5 :         (static_cast<size_t>(nIndex) >= m_pImpl->m_Ranges.size()))
    1657             :     {
    1658           1 :         throw lang::IndexOutOfBoundsException();
    1659             :     }
    1660           4 :     uno::Any ret;
    1661           4 :     ret <<= (m_pImpl->m_Ranges.at(nIndex));
    1662           5 :     return ret;
    1663             : }
    1664             : 
    1665             : uno::Type SAL_CALL
    1666           1 : SwXTextRanges::getElementType() throw (uno::RuntimeException, std::exception)
    1667             : {
    1668           1 :     return cppu::UnoType<text::XTextRange>::get();
    1669             : }
    1670             : 
    1671           1 : sal_Bool SAL_CALL SwXTextRanges::hasElements() throw (uno::RuntimeException, std::exception)
    1672             : {
    1673             :     // no mutex necessary: getCount() does locking
    1674           1 :     return getCount() > 0;
    1675             : }
    1676             : 
    1677           8 : void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString)
    1678             : {
    1679             :     // Start/EndAction
    1680           8 :     SwDoc *const pDoc = rCursor.GetDoc();
    1681           8 :     UnoActionContext aAction(pDoc);
    1682           8 :     pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
    1683           8 :     if (rCursor.HasMark())
    1684             :     {
    1685           7 :         pDoc->DeleteAndJoin(rCursor);
    1686             :     }
    1687           8 :     if (!rString.isEmpty())
    1688             :     {
    1689           8 :         OUString aText(rString);
    1690             :         const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
    1691           8 :                     *pDoc, rCursor, aText, false ) );
    1692             :         OSL_ENSURE( bSuccess, "DocInsertStringSplitCR" );
    1693             :         (void) bSuccess;
    1694           8 :         SwUnoCursorHelper::SelectPam(rCursor, true);
    1695           8 :         rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False);
    1696             :     }
    1697           8 :     pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
    1698           8 : }
    1699             : 
    1700             : /******************************************************************
    1701             :  * SwXParaFrameEnumeration
    1702             :  ******************************************************************/
    1703             : class SwXParaFrameEnumeration::Impl
    1704             :     : public SwClient
    1705             : {
    1706             : public:
    1707             :     // created by hasMoreElements
    1708             :     uno::Reference< text::XTextContent > m_xNextObject;
    1709             :     FrameDependList_t m_Frames;
    1710             : 
    1711         307 :     Impl(SwPaM const & rPaM)
    1712         307 :         : SwClient(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), false))
    1713             :     {
    1714         307 :         if (rPaM.HasMark())
    1715             :         {
    1716         159 :             GetCursor()->SetMark();
    1717         159 :             *GetCursor()->GetMark() = *rPaM.GetMark();
    1718             :         }
    1719         307 :     }
    1720             : 
    1721         921 :     virtual ~Impl() {
    1722             :         // Impl owns the cursor; delete it here: SolarMutex is locked
    1723         307 :         delete GetRegisteredIn();
    1724         614 :     }
    1725             : 
    1726        1219 :     SwUnoCrsr * GetCursor() {
    1727             :         return static_cast<SwUnoCrsr*>(
    1728        1219 :                 const_cast<SwModify*>(GetRegisteredIn()));
    1729             :     }
    1730             : 
    1731             : protected:
    1732             :     // SwClient
    1733             :     virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
    1734             : };
    1735             : 
    1736             : struct InvalidFrameDepend {
    1737           0 :     bool operator() (::boost::shared_ptr<SwDepend> const & rEntry)
    1738           0 :     { return !rEntry->GetRegisteredIn(); }
    1739             : };
    1740             : 
    1741         307 : void SwXParaFrameEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
    1742             : {
    1743         307 :     ClientModify(this, pOld, pNew);
    1744         307 :     if(!GetRegisteredIn())
    1745             :     {
    1746         307 :         m_Frames.clear();
    1747         307 :         m_xNextObject = 0;
    1748             :     }
    1749             :     else
    1750             :     {
    1751             :         // check if any frame went away...
    1752             :         FrameDependList_t::iterator const iter =
    1753             :             ::std::remove_if(m_Frames.begin(), m_Frames.end(),
    1754           0 :                     InvalidFrameDepend());
    1755           0 :         m_Frames.erase(iter, m_Frames.end());
    1756             :     }
    1757         307 : }
    1758             : 
    1759             : static sal_Bool
    1760         355 : lcl_CreateNextObject(SwUnoCrsr& i_rUnoCrsr,
    1761             :         uno::Reference<text::XTextContent> & o_rNextObject,
    1762             :         FrameDependList_t & i_rFrames)
    1763             : {
    1764         355 :     if (!i_rFrames.size())
    1765         191 :         return sal_False;
    1766             : 
    1767             :     SwFrmFmt *const pFormat = static_cast<SwFrmFmt*>(const_cast<SwModify*>(
    1768         164 :                 i_rFrames.front()->GetRegisteredIn()));
    1769         164 :     i_rFrames.pop_front();
    1770             :     // the format should be valid here, otherwise the client
    1771             :     // would have been removed in ::Modify
    1772             :     // check for a shape first
    1773         164 :     SwDrawContact* const pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFormat );
    1774         164 :     if (pContact)
    1775             :     {
    1776           1 :         SdrObject * const pSdr = pContact->GetMaster();
    1777           1 :         if (pSdr)
    1778             :         {
    1779           1 :             o_rNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY);
    1780             :         }
    1781             :     }
    1782             :     else
    1783             :     {
    1784         163 :         const SwNodeIndex* pIdx = pFormat->GetCntnt().GetCntntIdx();
    1785             :         OSL_ENSURE(pIdx, "where is the index?");
    1786             :         SwNode const*const pNd =
    1787         163 :             i_rUnoCrsr.GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
    1788             : 
    1789         163 :         const FlyCntType eType = (!pNd->IsNoTxtNode()) ? FLYCNTTYPE_FRM
    1790         163 :             : ( (pNd->IsGrfNode()) ? FLYCNTTYPE_GRF : FLYCNTTYPE_OLE );
    1791             : 
    1792             :         const uno::Reference< container::XNamed >  xFrame =
    1793         163 :             SwXFrames::GetObject(*pFormat, eType);
    1794         163 :         o_rNextObject.set(xFrame, uno::UNO_QUERY);
    1795             :     }
    1796             : 
    1797         164 :     return o_rNextObject.is();
    1798             : }
    1799             : 
    1800             : /* ---------------------------------------------------------------------------
    1801             :     Description: Search for a FLYCNT text attribute at the cursor point
    1802             :                 and fill the frame into the array
    1803             :  ---------------------------------------------------------------------------*/
    1804             : static void
    1805         135 : lcl_FillFrame(SwClient & rEnum, SwUnoCrsr& rUnoCrsr,
    1806             :         FrameDependList_t & rFrames)
    1807             : {
    1808             :     // search for objects at the cursor - anchored at/as char
    1809         135 :     SwTxtAttr const*const pTxtAttr = (rUnoCrsr.GetNode()->IsTxtNode())
    1810             :         ? rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
    1811         135 :             rUnoCrsr.GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT)
    1812         270 :         : 0;
    1813         135 :     if (pTxtAttr)
    1814             :     {
    1815         133 :         const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
    1816         133 :         SwFrmFmt * const  pFrmFmt = rFlyCnt.GetFrmFmt();
    1817         133 :         SwDepend * const pNewDepend = new SwDepend(&rEnum, pFrmFmt);
    1818         133 :         rFrames.push_back( ::boost::shared_ptr<SwDepend>(pNewDepend) );
    1819             :     }
    1820         135 : }
    1821             : 
    1822         307 : SwXParaFrameEnumeration::SwXParaFrameEnumeration(
    1823             :         const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode,
    1824             :         SwFrmFmt *const pFmt)
    1825         307 :     : m_pImpl( new SwXParaFrameEnumeration::Impl(rPaM) )
    1826             : {
    1827         307 :     if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode)
    1828             :     {
    1829         147 :         FrameDependSortList_t frames;
    1830         294 :         ::CollectFrameAtNode(*m_pImpl.get(), rPaM.GetPoint()->nNode,
    1831         294 :                 frames, false);
    1832             :         ::std::transform(frames.begin(), frames.end(),
    1833         147 :             ::std::back_inserter(m_pImpl->m_Frames),
    1834         294 :             ::boost::bind(&FrameDependSortListEntry::pFrameDepend, _1));
    1835             :     }
    1836         160 :     else if (pFmt)
    1837             :     {
    1838             :         // create SwDepend for frame and insert into array
    1839          25 :         SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFmt);
    1840          25 :         m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend));
    1841             :     }
    1842         135 :     else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) ||
    1843             :              (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode))
    1844             :     {
    1845         135 :         if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)
    1846             :         {
    1847             :             //get all frames that are bound at paragraph or at character
    1848           2 :             SwPosFlyFrms aFlyFrms(rPaM.GetDoc()->GetAllFlyFmts(m_pImpl->GetCursor(), false, true));
    1849             : 
    1850           2 :             for(SwPosFlyFrms::const_iterator aIter(aFlyFrms.begin()); aIter != aFlyFrms.end(); ++aIter)
    1851             :             {
    1852           0 :                 SwFrmFmt *const pFrmFmt = const_cast<SwFrmFmt*>(&((*aIter)->GetFmt()));
    1853             : 
    1854             :                 // create SwDepend for frame and insert into array
    1855           0 :                 SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFrmFmt);
    1856           0 :                 m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend));
    1857           2 :             }
    1858             :         }
    1859             : 
    1860         135 :         lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), m_pImpl->m_Frames);
    1861             :     }
    1862         307 : }
    1863             : 
    1864         614 : SwXParaFrameEnumeration::~SwXParaFrameEnumeration()
    1865             : {
    1866         614 : }
    1867             : 
    1868             : sal_Bool SAL_CALL
    1869         245 : SwXParaFrameEnumeration::hasMoreElements() throw (uno::RuntimeException, std::exception)
    1870             : {
    1871         245 :     SolarMutexGuard aGuard;
    1872             : 
    1873         245 :     if (!m_pImpl->GetCursor())
    1874           0 :         throw uno::RuntimeException();
    1875             : 
    1876         245 :     return (m_pImpl->m_xNextObject.is())
    1877             :         ? sal_True
    1878         241 :         : lcl_CreateNextObject(*m_pImpl->GetCursor(),
    1879         486 :             m_pImpl->m_xNextObject, m_pImpl->m_Frames);
    1880             : }
    1881             : 
    1882         164 : uno::Any SAL_CALL SwXParaFrameEnumeration::nextElement()
    1883             : throw (container::NoSuchElementException,
    1884             :         lang::WrappedTargetException, uno::RuntimeException, std::exception)
    1885             : {
    1886         164 :     SolarMutexGuard aGuard;
    1887             : 
    1888         164 :     if (!m_pImpl->GetCursor())
    1889             :     {
    1890           0 :         throw uno::RuntimeException();
    1891             :     }
    1892             : 
    1893         164 :     if (!m_pImpl->m_xNextObject.is() && m_pImpl->m_Frames.size())
    1894             :     {
    1895         114 :         lcl_CreateNextObject(*m_pImpl->GetCursor(),
    1896         228 :                 m_pImpl->m_xNextObject, m_pImpl->m_Frames);
    1897             :     }
    1898         164 :     if (!m_pImpl->m_xNextObject.is())
    1899             :     {
    1900           0 :         throw container::NoSuchElementException();
    1901             :     }
    1902         164 :     uno::Any aRet;
    1903         164 :     aRet <<= m_pImpl->m_xNextObject;
    1904         164 :     m_pImpl->m_xNextObject = 0;
    1905         164 :     return aRet;
    1906             : }
    1907             : 
    1908             : OUString SAL_CALL
    1909           0 : SwXParaFrameEnumeration::getImplementationName() throw (uno::RuntimeException, std::exception)
    1910             : {
    1911           0 :     return OUString("SwXParaFrameEnumeration");
    1912             : }
    1913             : 
    1914             : static char const*const g_ServicesParaFrameEnum[] =
    1915             : {
    1916             :     "com.sun.star.util.ContentEnumeration",
    1917             : };
    1918             : 
    1919             : static const size_t g_nServicesParaFrameEnum(
    1920             :     sizeof(g_ServicesParaFrameEnum)/sizeof(g_ServicesParaFrameEnum[0]));
    1921             : 
    1922             : sal_Bool SAL_CALL
    1923           0 : SwXParaFrameEnumeration::supportsService(const OUString& rServiceName)
    1924             : throw (uno::RuntimeException, std::exception)
    1925             : {
    1926           0 :     return cppu::supportsService(this, rServiceName);
    1927             : }
    1928             : 
    1929             : uno::Sequence< OUString > SAL_CALL
    1930           0 : SwXParaFrameEnumeration::getSupportedServiceNames()
    1931             : throw (uno::RuntimeException, std::exception)
    1932             : {
    1933             :     return ::sw::GetSupportedServiceNamesImpl(
    1934           0 :             g_nServicesParaFrameEnum, g_ServicesParaFrameEnum);
    1935         111 : }
    1936             : 
    1937             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10