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

Generated by: LCOV version 1.10