LCOV - code coverage report
Current view: top level - sw/source/core/unocore - unoobj2.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 599 743 80.6 %
Date: 2015-06-13 12:38:46 Functions: 80 109 73.4 %
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 <calbck.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        1179 : GetSupportedServiceNamesImpl(
     123             :         size_t const nServices, char const*const pServices[])
     124             : {
     125        1179 :     uno::Sequence< OUString > ret(nServices);
     126       10242 :     for (size_t i = 0; i < nServices; ++i)
     127             :     {
     128        9063 :         ret[i] = OUString::createFromAscii(pServices[i]);
     129             :     }
     130        1179 :     return ret;
     131             : }
     132             : 
     133             : } // namespace sw
     134             : 
     135             : namespace sw {
     136             : 
     137           1 : void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget)
     138             : {
     139           1 :     rTarget = rSource;
     140             : 
     141           1 :     if (rSource.GetNext() != &rSource)
     142             :     {
     143           0 :         SwPaM *pPam = const_cast<SwPaM*>(rSource.GetNext());
     144           0 :         do
     145             :         {
     146             :             // create new PaM
     147           0 :             SwPaM *const pNew = new SwPaM(*pPam, nullptr);
     148             :             // insert into ring
     149           0 :             pNew->MoveTo(&rTarget);
     150           0 :             pPam = pPam->GetNext();
     151             :         }
     152             :         while (pPam != &rSource);
     153             :     }
     154           1 : }
     155             : 
     156             : } // namespace sw
     157             : 
     158             : struct FrameClientSortListLess
     159             : {
     160           0 :     bool operator() (FrameClientSortListEntry const& r1,
     161             :                      FrameClientSortListEntry 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             : namespace
     169             : {
     170        2905 :     void lcl_CollectFrameAtNodeWithLayout(SwDoc* pDoc, const SwContentFrm* pCFrm,
     171             :             FrameClientSortList_t& rFrames,
     172             :             const sal_uInt16 nAnchorType)
     173             :     {
     174        2905 :         auto pObjs = pCFrm->GetDrawObjs();
     175        2905 :         if(!pObjs)
     176        5597 :             return;
     177         213 :         const auto aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
     178         783 :         for(const auto pAnchoredObj : *pObjs)
     179             :         {
     180         570 :             SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
     181             :             // Filter out textboxes, which are not interesting at an UNO level.
     182         570 :             if(aTextBoxes.find(&rFormat) != aTextBoxes.end())
     183          11 :                 continue;
     184         559 :             if(rFormat.GetAnchor().GetAnchorId() == nAnchorType)
     185             :             {
     186             :                 const auto nIdx =
     187         110 :                     rFormat.GetAnchor().GetContentAnchor()->nContent.GetIndex();
     188         110 :                 const auto nOrder = rFormat.GetAnchor().GetOrder();
     189         110 :                 FrameClientSortListEntry entry(nIdx, nOrder, new sw::FrameClient(&rFormat));
     190         110 :                 rFrames.push_back(entry);
     191             :             }
     192         213 :         }
     193             :     }
     194             : }
     195             : 
     196             : 
     197        2939 : void CollectFrameAtNode( const SwNodeIndex& rIdx,
     198             :                          FrameClientSortList_t& rFrames,
     199             :                          const bool bAtCharAnchoredObjs )
     200             : {
     201             :     // _bAtCharAnchoredObjs:
     202             :     // <true>: at-character anchored objects are collected
     203             :     // <false>: at-paragraph anchored objects are collected
     204             : 
     205             :     // search all borders, images, and OLEs that are connected to the paragraph
     206        2939 :     SwDoc* pDoc = rIdx.GetNode().GetDoc();
     207             : 
     208             :     const auto nChkType = static_cast< sal_uInt16 >((bAtCharAnchoredObjs)
     209        2939 :             ? FLY_AT_CHAR : FLY_AT_PARA);
     210             :     const SwContentFrm* pCFrm;
     211             :     const SwContentNode* pCNd;
     212        8807 :     if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() &&
     213        5868 :         0 != (pCNd = rIdx.GetNode().GetContentNode()) &&
     214        2929 :         0 != (pCFrm = pCNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout())) )
     215             :     {
     216        2905 :         lcl_CollectFrameAtNodeWithLayout(pDoc, pCFrm, rFrames, nChkType);
     217             :     }
     218             :     else
     219             :     {
     220          34 :         const SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats();
     221          34 :         const size_t nSize = rFormats.size();
     222          58 :         for ( size_t i = 0; i < nSize; i++)
     223             :         {
     224          24 :             const SwFrameFormat* pFormat = rFormats[ i ];
     225          24 :             const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
     226             :             const SwPosition* pAnchorPos;
     227          48 :             if( rAnchor.GetAnchorId() == nChkType &&
     228          24 :                 0 != (pAnchorPos = rAnchor.GetContentAnchor()) &&
     229           0 :                     pAnchorPos->nNode == rIdx )
     230             :             {
     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 :                 FrameClientSortListEntry entry(nIndex, nOrder, new sw::FrameClient(const_cast<SwFrameFormat*>(pFormat)));
     238           0 :                 rFrames.push_back(entry);
     239             :             }
     240             :         }
     241          34 :         ::std::sort(rFrames.begin(), rFrames.end(), FrameClientSortListLess());
     242             :     }
     243        2939 : }
     244             : 
     245      203312 : UnoActionContext::UnoActionContext(SwDoc *const pDoc)
     246      203312 :     : m_pDoc(pDoc)
     247             : {
     248      203312 :     SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     249      203312 :     if (pRootFrm)
     250             :     {
     251       20970 :         pRootFrm->StartAllAction();
     252             :     }
     253      203312 : }
     254             : 
     255      203312 : UnoActionContext::~UnoActionContext()
     256             : {
     257             :     // Doc may already have been removed here
     258      203312 :     if (m_pDoc)
     259             :     {
     260      203312 :         SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     261      203312 :         if (pRootFrm)
     262             :         {
     263       20970 :             pRootFrm->EndAllAction();
     264             :         }
     265             :     }
     266      203312 : }
     267             : 
     268         245 : UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc)
     269         245 :     : m_pDoc(pDoc)
     270             : {
     271         245 :     SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     272         245 :     if (pRootFrm)
     273             :     {
     274         174 :         pRootFrm->UnoRemoveAllActions();
     275             :     }
     276         245 : }
     277             : 
     278         245 : UnoActionRemoveContext::~UnoActionRemoveContext()
     279             : {
     280         245 :     SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     281         245 :     if (pRootFrm)
     282             :     {
     283         174 :         pRootFrm->UnoRestoreAllActions();
     284             :     }
     285         245 : }
     286             : 
     287      170378 : void ClientModify(SwClient* pClient, const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     288             : {
     289      170378 :     switch( pOld ? pOld->Which() : 0 )
     290             :     {
     291             :     case RES_REMOVE_UNO_OBJECT:
     292             :     case RES_OBJECTDYING:
     293      111854 :         if( static_cast<void*>(pClient->GetRegisteredIn()) == static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject )
     294      111201 :             pClient->GetRegisteredIn()->Remove(pClient);
     295      111854 :         break;
     296             : 
     297             :     case RES_FMT_CHG:
     298             :         // Is the move to the new one finished and will the old one be deleted?
     299        3222 :         if( static_cast<const SwFormatChg*>(pNew)->pChangedFormat == pClient->GetRegisteredIn() &&
     300         810 :             static_cast<const SwFormatChg*>(pOld)->pChangedFormat->IsFormatInDTOR() )
     301         804 :             static_cast<SwModify*>(pClient->GetRegisteredIn())->Remove(pClient);
     302        2412 :         break;
     303             :     }
     304      170378 : }
     305             : 
     306      110498 : void SwUnoCursorHelper::SetCrsrAttr(SwPaM & rPam,
     307             :         const SfxItemSet& rSet,
     308             :         const SetAttrMode nAttrMode, const bool bTableMode)
     309             : {
     310      110498 :     const SetAttrMode nFlags = nAttrMode | SetAttrMode::APICALL;
     311      110498 :     SwDoc* pDoc = rPam.GetDoc();
     312             :     //StartEndAction
     313      110498 :     UnoActionContext aAction(pDoc);
     314      110498 :     if (rPam.GetNext() != &rPam)    // Ring of Cursors
     315             :     {
     316          73 :         pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSATTR, NULL);
     317             : 
     318        1533 :         for(SwPaM& rCurrent : rPam.GetRingContainer())
     319             :         {
     320        2920 :             if (rCurrent.HasMark() &&
     321           0 :                 ( (bTableMode) ||
     322           0 :                   (*rCurrent.GetPoint() != *rCurrent.GetMark()) ))
     323             :             {
     324        1460 :                 pDoc->getIDocumentContentOperations().InsertItemSet(rCurrent, rSet, nFlags);
     325             :             }
     326             :         }
     327             : 
     328          73 :         pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSATTR, NULL);
     329             :     }
     330             :     else
     331             :     {
     332      110425 :         pDoc->getIDocumentContentOperations().InsertItemSet( rPam, rSet, nFlags );
     333             :     }
     334             : 
     335      110498 :     if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SfxItemState::DEFAULT )
     336             :     {
     337         870 :         SwTextNode * pTmpNode = rPam.GetNode().GetTextNode();
     338         870 :         if ( pTmpNode )
     339             :         {
     340         870 :             rPam.GetDoc()->GetNodes().UpdateOutlineNode( *pTmpNode );
     341             :         }
     342      110498 :     }
     343      110498 : }
     344             : 
     345             : // #i63870#
     346             : // split third parameter <bCurrentAttrOnly> into new parameters <bOnlyTextAttr>
     347             : // and <bGetFromChrFormat> to get better control about resulting <SfxItemSet>
     348      138761 : void SwUnoCursorHelper::GetCrsrAttr(SwPaM & rPam,
     349             :         SfxItemSet & rSet, const bool bOnlyTextAttr, const bool bGetFromChrFormat)
     350             : {
     351             :     static const sal_uLong nMaxLookup = 1000;
     352      138761 :     SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
     353      138761 :     SfxItemSet *pSet = &rSet;
     354      281740 :     for(SwPaM& rCurrent : rPam.GetRingContainer())
     355             :     {
     356      142979 :         SwPosition const & rStart( *rCurrent.Start() );
     357      142979 :         SwPosition const & rEnd( *rCurrent.End() );
     358      142979 :         const sal_uLong nSttNd = rStart.nNode.GetIndex();
     359      142979 :         const sal_uLong nEndNd = rEnd  .nNode.GetIndex();
     360             : 
     361      142979 :         if (nEndNd - nSttNd >= nMaxLookup)
     362             :         {
     363           0 :             rSet.ClearItem();
     364           0 :             rSet.InvalidateAllItems();
     365      138761 :             return;// uno::Any();
     366             :         }
     367             : 
     368             :         // the first node inserts the values into the get set
     369             :         // all other nodes merge their values into the get set
     370      292048 :         for (sal_uLong n = nSttNd; n <= nEndNd; ++n)
     371             :         {
     372      149069 :             SwNode *const pNd = rPam.GetDoc()->GetNodes()[ n ];
     373      149069 :             switch (pNd->GetNodeType())
     374             :             {
     375             :                 case ND_TEXTNODE:
     376             :                 {
     377             :                     const sal_Int32 nStart = (n == nSttNd)
     378      146479 :                         ? rStart.nContent.GetIndex() : 0;
     379             :                     const sal_Int32 nEnd   = (n == nEndNd)
     380      142695 :                         ? rEnd.nContent.GetIndex()
     381      289174 :                         : pNd->GetTextNode()->GetText().getLength();
     382      146479 :                     pNd->GetTextNode()->GetAttr(*pSet, nStart, nEnd, bOnlyTextAttr, bGetFromChrFormat);
     383             :                 }
     384      146479 :                 break;
     385             : 
     386             :                 case ND_GRFNODE:
     387             :                 case ND_OLENODE:
     388           0 :                     static_cast<SwContentNode*>(pNd)->GetAttr( *pSet );
     389           0 :                 break;
     390             : 
     391             :                 default:
     392        2590 :                     continue; // skip this node
     393             :             }
     394             : 
     395      146479 :             if (pSet != &rSet)
     396             :             {
     397        8002 :                 rSet.MergeValues( aSet );
     398             :             }
     399             :             else
     400             :             {
     401      138477 :                 pSet = &aSet;
     402             :             }
     403             : 
     404      146479 :             if (aSet.Count())
     405             :             {
     406        5720 :                 aSet.ClearItem();
     407             :             }
     408             :         }
     409      138761 :     }
     410             : }
     411             : 
     412             : struct SwXParagraphEnumerationImpl SAL_FINAL : public SwXParagraphEnumeration
     413             : {
     414             :     uno::Reference< text::XText > const m_xParentText;
     415             :     const CursorType m_eCursorType;
     416             :     /// Start node of the cell _or_ table the enumeration belongs to.
     417             :     /// Used to restrict the movement of the UNO cursor to the cell and its
     418             :     /// embedded tables.
     419             :     SwStartNode const*const m_pOwnStartNode;
     420             :     SwTable const*const m_pOwnTable;
     421             :     const sal_uLong m_nEndIndex;
     422             :     sal_Int32 m_nFirstParaStart;
     423             :     sal_Int32 m_nLastParaEnd;
     424             :     bool m_bFirstParagraph;
     425             :     uno::Reference< text::XTextContent > m_xNextPara;
     426             :     sw::UnoCursorPointer m_pCrsr;
     427             : 
     428        9103 :     SwXParagraphEnumerationImpl(
     429             :             uno::Reference< text::XText > const& xParent,
     430             :             ::std::shared_ptr<SwUnoCrsr> pCursor,
     431             :             const CursorType eType,
     432             :             SwStartNode const*const pStartNode, SwTable const*const pTable)
     433             :         : m_xParentText( xParent )
     434             :         , m_eCursorType( eType )
     435             :         // remember table and start node for later travelling
     436             :         // (used in export of tables in tables)
     437             :         , m_pOwnStartNode( pStartNode )
     438             :         // for import of tables in tables we have to remember the actual
     439             :         // table and start node of the current position in the enumeration.
     440             :         , m_pOwnTable( pTable )
     441        9103 :         , m_nEndIndex( pCursor->End()->nNode.GetIndex() )
     442             :         , m_nFirstParaStart( -1 )
     443             :         , m_nLastParaEnd( -1 )
     444             :         , m_bFirstParagraph( true )
     445       18206 :         , m_pCrsr(pCursor)
     446             :     {
     447             :         OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?");
     448             :         OSL_ENSURE(   !((CURSOR_SELECTION_IN_TABLE == eType) ||
     449             :                         (CURSOR_TBLTEXT == eType))
     450             :                    || (m_pOwnTable && m_pOwnStartNode),
     451             :             "SwXParagraphEnumeration: table type but no start node or table?");
     452             : 
     453       16203 :         if ((CURSOR_SELECTION == m_eCursorType) ||
     454        7100 :             (CURSOR_SELECTION_IN_TABLE == m_eCursorType))
     455             :         {
     456        2942 :             SwUnoCrsr & rCursor = *GetCursor();
     457        2942 :             rCursor.Normalize();
     458        2942 :             m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex();
     459        2942 :             m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex();
     460        2942 :             rCursor.DeleteMark();
     461             :         }
     462        9103 :     }
     463             : 
     464       18206 :     virtual ~SwXParagraphEnumerationImpl()
     465       18206 :         { m_pCrsr.reset(nullptr); }
     466        9581 :     virtual void SAL_CALL release() throw () SAL_OVERRIDE
     467             :     {
     468        9581 :         SolarMutexGuard g;
     469        9581 :         OWeakObject::release();
     470        9581 :     }
     471             : 
     472             :     // XServiceInfo
     473           0 :     virtual OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
     474           0 :         { return OUString("SwXParagraphEnumeration"); }
     475           0 :     virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
     476           0 :         { return cppu::supportsService(this, rServiceName); };
     477           0 :     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
     478           0 :         { return {"com.sun.star.text.ParagraphEnumeration"}; };
     479             : 
     480             :     // XEnumeration
     481             :     virtual sal_Bool SAL_CALL hasMoreElements() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     482             :     virtual ::com::sun::star::uno::Any SAL_CALL nextElement() throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     483             : 
     484       23099 :     SwUnoCrsr* GetCursor()
     485       23099 :         { return &(*m_pCrsr); }
     486             :     uno::Reference< text::XTextContent > NextElement_Impl()
     487             :         throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
     488             : };
     489             : 
     490        9103 : SwXParagraphEnumeration* SwXParagraphEnumeration::Create(
     491             :     uno::Reference< text::XText > const& xParent,
     492             :     ::std::shared_ptr<SwUnoCrsr> pCursor,
     493             :     const CursorType eType,
     494             :     SwStartNode const*const pStartNode,
     495             :     SwTable const*const pTable)
     496             : {
     497        9103 :     return new SwXParagraphEnumerationImpl(xParent, pCursor, eType, pStartNode, pTable);
     498             : }
     499             : 
     500             : sal_Bool SAL_CALL
     501        8865 : SwXParagraphEnumerationImpl::hasMoreElements() throw (uno::RuntimeException, std::exception)
     502             : {
     503        8865 :     SolarMutexGuard aGuard;
     504        8865 :     return m_bFirstParagraph || m_xNextPara.is();
     505             : }
     506             : 
     507             : //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx
     508             : static SwTableNode *
     509       24255 : lcl_FindTopLevelTable(
     510             :         SwTableNode *const pTableNode, SwTable const*const pOwnTable)
     511             : {
     512             :     // find top-most table in current context (section) level
     513             : 
     514       24255 :     SwTableNode * pLast = pTableNode;
     515       49382 :     for (SwTableNode* pTmp = pLast;
     516       24691 :          pTmp != NULL  &&  &pTmp->GetTable() != pOwnTable;  /* we must not go up higher than the own table! */
     517         436 :          pTmp = pTmp->StartOfSectionNode()->FindTableNode() )
     518             :     {
     519         436 :         pLast = pTmp;
     520             :     }
     521       24255 :     return pLast;
     522             : }
     523             : 
     524             : static bool
     525       28204 : lcl_CursorIsInSection(
     526             :         SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode)
     527             : {
     528             :     // returns true if the cursor is in the section (or in a sub section!)
     529             :     // represented by pOwnStartNode
     530             : 
     531       28204 :     bool bRes = true;
     532       28204 :     if (pUnoCrsr && pOwnStartNode)
     533             :     {
     534       12830 :         const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode();
     535       25660 :         bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() &&
     536       25660 :                pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex();
     537             :     }
     538       28204 :     return bRes;
     539             : }
     540             : 
     541             : uno::Reference< text::XTextContent >
     542       20157 : SwXParagraphEnumerationImpl::NextElement_Impl() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
     543             : {
     544       20157 :     SwUnoCrsr *const pUnoCrsr = GetCursor();
     545       20157 :     if (!pUnoCrsr)
     546             :     {
     547           0 :         throw uno::RuntimeException();
     548             :     }
     549             : 
     550             :     // check for exceeding selections
     551       31217 :     if (!m_bFirstParagraph &&
     552       20117 :         ((CURSOR_SELECTION == m_eCursorType) ||
     553        9057 :          (CURSOR_SELECTION_IN_TABLE == m_eCursorType)))
     554             :     {
     555        2942 :         SwPosition* pStart = pUnoCrsr->Start();
     556        2942 :         auto aNewCrsr(pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, false));
     557             :         // one may also go into tables here
     558        5884 :         if ((CURSOR_TBLTEXT != m_eCursorType) &&
     559        2942 :             (CURSOR_SELECTION_IN_TABLE != m_eCursorType))
     560             :         {
     561        2003 :             aNewCrsr->SetRemainInSection( false );
     562             :         }
     563             : 
     564             :         // os 2005-01-14: This part is only necessary to detect movements out
     565             :         // of a selection; if there is no selection we don't have to care
     566        2942 :         SwTableNode *const pTableNode = aNewCrsr->GetNode().FindTableNode();
     567        5884 :         if (((CURSOR_TBLTEXT != m_eCursorType) &&
     568        4945 :             (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTableNode)
     569             :         {
     570           0 :             aNewCrsr->GetPoint()->nNode = pTableNode->EndOfSectionIndex();
     571           0 :             aNewCrsr->Move(fnMoveForward, fnGoNode);
     572             :         }
     573             :         else
     574             :         {
     575        2942 :             aNewCrsr->MovePara(fnParaNext, fnParaStart);
     576             :         }
     577        2942 :         if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex())
     578             :         {
     579         215 :             return 0;
     580        2727 :         }
     581             :     }
     582             : 
     583       19942 :     bool bInTable = false;
     584       19942 :     if (!m_bFirstParagraph)
     585             :     {
     586       10845 :         pUnoCrsr->SetRemainInSection( false );
     587             :         // what to do if already in a table?
     588       10845 :         SwTableNode * pTableNode = pUnoCrsr->GetNode().FindTableNode();
     589       10845 :         pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
     590       10845 :         if (pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
     591             :         {
     592             :             // this is a foreign table: go to end
     593         109 :             pUnoCrsr->GetPoint()->nNode = pTableNode->EndOfSectionIndex();
     594         109 :             if (!pUnoCrsr->Move(fnMoveForward, fnGoNode))
     595             :             {
     596           1 :                 return 0;
     597             :             }
     598         108 :             bInTable = true;
     599             :         }
     600             :     }
     601             : 
     602       19941 :     uno::Reference< text::XTextContent >  xRef;
     603             :     // the cursor must remain in the current section or a subsection
     604             :     // before AND after the movement...
     605       33351 :     if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) &&
     606       21580 :         (m_bFirstParagraph || bInTable ||
     607       18999 :         (pUnoCrsr->MovePara(fnParaNext, fnParaStart) &&
     608        8263 :             lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ))))
     609             :     {
     610       13410 :         SwPosition* pStart = pUnoCrsr->Start();
     611             :         const sal_Int32 nFirstContent =
     612       13410 :             (m_bFirstParagraph) ? m_nFirstParaStart : -1;
     613             :         const sal_Int32 nLastContent =
     614       13410 :             (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1;
     615             : 
     616             :         // position in a table, or in a simple paragraph?
     617       13410 :         SwTableNode * pTableNode = pUnoCrsr->GetNode().FindTableNode();
     618       13410 :         pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
     619       13410 :         if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */
     620       13410 :             pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
     621             :         {
     622             :             // this is a foreign table
     623             :             SwFrameFormat* pTableFormat =
     624         320 :                 static_cast<SwFrameFormat*>(pTableNode->GetTable().GetFrameFormat());
     625         320 :             xRef = SwXTextTable::CreateXTextTable(pTableFormat);
     626             :         }
     627             :         else
     628             :         {
     629       13090 :             text::XText *const pText = m_xParentText.get();
     630       39270 :             xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(),
     631       13090 :                 pStart->nNode.GetNode().GetTextNode(),
     632       26180 :                 static_cast<SwXText*>(pText), nFirstContent, nLastContent);
     633             :         }
     634             :     }
     635             : 
     636       19941 :     return xRef;
     637             : }
     638             : 
     639       11062 : uno::Any SAL_CALL SwXParagraphEnumerationImpl::nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     640             : {
     641       11062 :     SolarMutexGuard aGuard;
     642       11062 :     if (m_bFirstParagraph)
     643             :     {
     644        9097 :         m_xNextPara = NextElement_Impl();
     645        9097 :         m_bFirstParagraph = false;
     646             :     }
     647       22124 :     const uno::Reference< text::XTextContent > xRef = m_xNextPara;
     648       11062 :     if (!xRef.is())
     649             :     {
     650           2 :         throw container::NoSuchElementException();
     651             :     }
     652       11060 :     m_xNextPara = NextElement_Impl();
     653             : 
     654       11060 :     uno::Any aRet;
     655       11060 :     aRet <<= xRef;
     656       22122 :     return aRet;
     657             : }
     658             : 
     659             : class SwXTextRange::Impl
     660             :     : public SwClient
     661             : {
     662             : public:
     663             :     const SfxItemPropertySet &  m_rPropSet;
     664             :     const enum RangePosition    m_eRangePosition;
     665             :     SwDoc &                     m_rDoc;
     666             :     uno::Reference<text::XText> m_xParentText;
     667             :     SwDepend            m_ObjectDepend; // register at format of table or frame
     668             :     ::sw::mark::IMark * m_pMark;
     669             : 
     670      105737 :     Impl(   SwDoc & rDoc, const enum RangePosition eRange,
     671             :             SwFrameFormat *const pTableFormat = 0,
     672             :             const uno::Reference< text::XText > & xParent = 0)
     673             :         : SwClient()
     674      105737 :         , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
     675             :         , m_eRangePosition(eRange)
     676             :         , m_rDoc(rDoc)
     677             :         , m_xParentText(xParent)
     678             :         , m_ObjectDepend(this, pTableFormat)
     679      211474 :         , m_pMark(0)
     680             :     {
     681      105737 :     }
     682             : 
     683      211474 :     virtual ~Impl()
     684      211474 :     {
     685             :         // Impl owns the bookmark; delete it here: SolarMutex is locked
     686      105737 :         Invalidate();
     687      211474 :     }
     688             : 
     689      211679 :     void Invalidate()
     690             :     {
     691      211679 :         if (m_pMark)
     692             :         {
     693      101200 :             m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
     694      101200 :             m_pMark = 0;
     695             :         }
     696      211679 :     }
     697             : 
     698       65432 :     const ::sw::mark::IMark * GetBookmark() const { return m_pMark; }
     699             : 
     700             : protected:
     701             :     // SwClient
     702             :     virtual void    Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
     703             : };
     704             : 
     705      106366 : void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     706             : {
     707      106366 :     const bool bAlreadyRegistered = 0 != GetRegisteredIn();
     708      106366 :     ClientModify(this, pOld, pNew);
     709      106366 :     if (m_ObjectDepend.GetRegisteredIn())
     710             :     {
     711        1231 :         ClientModify(&m_ObjectDepend, pOld, pNew);
     712             :         // if the depend was removed then the range must be removed too
     713        1231 :         if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn())
     714             :         {
     715           0 :             GetRegisteredIn()->Remove(this);
     716             :         }
     717             :         // or if the range has been removed but the depend is still
     718             :         // connected then the depend must be removed
     719        1838 :         else if (bAlreadyRegistered && !GetRegisteredIn() &&
     720         607 :                     m_ObjectDepend.GetRegisteredIn())
     721             :         {
     722             :             m_ObjectDepend.GetRegisteredIn()
     723         607 :                 ->Remove(& m_ObjectDepend);
     724             :         }
     725             :     }
     726      106366 :     if (!GetRegisteredIn())
     727             :     {
     728      105742 :         m_pMark = 0;
     729             :     }
     730      106366 : }
     731             : 
     732      105130 : SwXTextRange::SwXTextRange(SwPaM& rPam,
     733             :         const uno::Reference< text::XText > & xParent,
     734             :         const enum RangePosition eRange)
     735      105130 :     : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) )
     736             : {
     737      105130 :     SetPositions(rPam);
     738      105130 : }
     739             : 
     740         607 : SwXTextRange::SwXTextRange(SwFrameFormat& rTableFormat)
     741             :     : m_pImpl(
     742         607 :         new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) )
     743             : {
     744         607 :     SwTable *const pTable = SwTable::FindTable( &rTableFormat );
     745         607 :     SwTableNode *const pTableNode = pTable->GetTableNode();
     746         607 :     SwPosition aPosition( *pTableNode );
     747        1214 :     SwPaM aPam( aPosition );
     748             : 
     749        1214 :     SetPositions( aPam );
     750         607 : }
     751             : 
     752      211474 : SwXTextRange::~SwXTextRange()
     753             : {
     754      211474 : }
     755             : 
     756           0 : const SwDoc * SwXTextRange::GetDoc() const
     757             : {
     758           0 :     return & m_pImpl->m_rDoc;
     759             : }
     760             : 
     761       52827 : SwDoc * SwXTextRange::GetDoc()
     762             : {
     763       52827 :     return & m_pImpl->m_rDoc;
     764             : }
     765             : 
     766         200 : void SwXTextRange::Invalidate()
     767             : {
     768         200 :     m_pImpl->Invalidate();
     769         200 : }
     770             : 
     771      105742 : void SwXTextRange::SetPositions(const SwPaM& rPam)
     772             : {
     773      105742 :     m_pImpl->Invalidate();
     774      105742 :     IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess();
     775      105742 :     m_pImpl->m_pMark = pMA->makeMark(rPam, OUString(),
     776      105742 :                 IDocumentMarkAccess::MarkType::UNO_BOOKMARK);
     777      105742 :     m_pImpl->m_pMark->Add(m_pImpl.get());
     778      105742 : }
     779             : 
     780           5 : void SwXTextRange::DeleteAndInsert(
     781             :         const OUString& rText, const bool bForceExpandHints)
     782             : throw (uno::RuntimeException)
     783             : {
     784           5 :     if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
     785             :     {
     786             :         // setString on table not allowed
     787           0 :         throw uno::RuntimeException();
     788             :     }
     789             : 
     790           5 :     const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
     791          10 :     SwCursor aCursor(aPos, 0, false);
     792           5 :     if (GetPositions(aCursor))
     793             :     {
     794           5 :         UnoActionContext aAction(& m_pImpl->m_rDoc);
     795           5 :         m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
     796           5 :         if (aCursor.HasMark())
     797             :         {
     798           2 :             m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor);
     799             :         }
     800             : 
     801           5 :         if (!rText.isEmpty())
     802             :         {
     803             :             SwUnoCursorHelper::DocInsertStringSplitCR(
     804           3 :                     m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints);
     805             : 
     806           3 :             SwUnoCursorHelper::SelectPam(aCursor, true);
     807           3 :             aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, false, false);
     808             :         }
     809           5 :         SetPositions(aCursor);
     810           5 :         m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
     811           5 :     }
     812           5 : }
     813             : 
     814             : namespace
     815             : {
     816             :     class theSwXTextRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangeUnoTunnelId > {};
     817             : }
     818             : 
     819      414849 : const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
     820             : {
     821      414849 :     return theSwXTextRangeUnoTunnelId::get().getSeq();
     822             : }
     823             : 
     824             : // XUnoTunnel
     825             : sal_Int64 SAL_CALL
     826      233944 : SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId)
     827             : throw (uno::RuntimeException, std::exception)
     828             : {
     829      233944 :     return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this);
     830             : }
     831             : 
     832             : OUString SAL_CALL
     833           0 : SwXTextRange::getImplementationName() throw (uno::RuntimeException, std::exception)
     834             : {
     835           0 :     return OUString("SwXTextRange");
     836             : }
     837             : 
     838             : static char const*const g_ServicesTextRange[] =
     839             : {
     840             :     "com.sun.star.text.TextRange",
     841             :     "com.sun.star.style.CharacterProperties",
     842             :     "com.sun.star.style.CharacterPropertiesAsian",
     843             :     "com.sun.star.style.CharacterPropertiesComplex",
     844             :     "com.sun.star.style.ParagraphProperties",
     845             :     "com.sun.star.style.ParagraphPropertiesAsian",
     846             :     "com.sun.star.style.ParagraphPropertiesComplex",
     847             : };
     848             : 
     849             : static const size_t g_nServicesTextRange(
     850             :     sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0]));
     851             : 
     852           0 : sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName)
     853             : throw (uno::RuntimeException, std::exception)
     854             : {
     855           0 :     return cppu::supportsService(this, rServiceName);
     856             : }
     857             : 
     858             : uno::Sequence< OUString > SAL_CALL
     859           0 : SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
     860             : {
     861             :     return ::sw::GetSupportedServiceNamesImpl(
     862           0 :             g_nServicesTextRange, g_ServicesTextRange);
     863             : }
     864             : 
     865             : uno::Reference< text::XText > SAL_CALL
     866        6182 : SwXTextRange::getText() throw (uno::RuntimeException, std::exception)
     867             : {
     868        6182 :     SolarMutexGuard aGuard;
     869             : 
     870        6182 :     if (!m_pImpl->m_xParentText.is())
     871             :     {
     872           0 :         if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
     873           0 :             m_pImpl->m_ObjectDepend.GetRegisteredIn())
     874             :         {
     875             :             SwFrameFormat const*const pTableFormat = static_cast<SwFrameFormat const*>(
     876           0 :                     m_pImpl->m_ObjectDepend.GetRegisteredIn());
     877           0 :             SwTable const*const pTable = SwTable::FindTable( pTableFormat );
     878           0 :             SwTableNode const*const pTableNode = pTable->GetTableNode();
     879           0 :             const SwPosition aPosition( *pTableNode );
     880           0 :             m_pImpl->m_xParentText =
     881           0 :                 ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition);
     882             :         }
     883             :     }
     884             :     OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text");
     885        6182 :     return m_pImpl->m_xParentText;
     886             : }
     887             : 
     888             : uno::Reference< text::XTextRange > SAL_CALL
     889         862 : SwXTextRange::getStart() throw (uno::RuntimeException, std::exception)
     890             : {
     891         862 :     SolarMutexGuard aGuard;
     892             : 
     893         862 :     uno::Reference< text::XTextRange >  xRet;
     894         862 :     ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
     895         862 :     if (!m_pImpl->m_xParentText.is())
     896             :     {
     897           0 :         getText();
     898             :     }
     899         862 :     if(pBkmk)
     900             :     {
     901         862 :         SwPaM aPam(pBkmk->GetMarkStart());
     902         862 :         xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
     903             :     }
     904           0 :     else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
     905             :     {
     906             :         // start and end are this, if it's a table
     907           0 :         xRet = this;
     908             :     }
     909             :     else
     910             :     {
     911           0 :         throw uno::RuntimeException();
     912             :     }
     913         862 :     return xRet;
     914             : }
     915             : 
     916             : uno::Reference< text::XTextRange > SAL_CALL
     917        2580 : SwXTextRange::getEnd() throw (uno::RuntimeException, std::exception)
     918             : {
     919        2580 :     SolarMutexGuard aGuard;
     920             : 
     921        2580 :     uno::Reference< text::XTextRange >  xRet;
     922        2580 :     ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
     923        2580 :     if (!m_pImpl->m_xParentText.is())
     924             :     {
     925           0 :         getText();
     926             :     }
     927        2580 :     if(pBkmk)
     928             :     {
     929        2580 :         SwPaM aPam(pBkmk->GetMarkEnd());
     930        2580 :         xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
     931             :     }
     932           0 :     else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
     933             :     {
     934             :         // start and end are this, if it's a table
     935           0 :         xRet = this;
     936             :     }
     937             :     else
     938             :     {
     939           0 :         throw uno::RuntimeException();
     940             :     }
     941        2580 :     return xRet;
     942             : }
     943             : 
     944        4846 : OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException, std::exception)
     945             : {
     946        4846 :     SolarMutexGuard aGuard;
     947             : 
     948        4846 :     OUString sRet;
     949             :     // for tables there is no bookmark, thus also no text
     950             :     // one could export the table as ASCII here maybe?
     951        9692 :     SwPaM aPaM(GetDoc()->GetNodes());
     952        4846 :     if (GetPositions(aPaM) && aPaM.HasMark())
     953             :     {
     954        4844 :         SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
     955             :     }
     956        9692 :     return sRet;
     957             : }
     958             : 
     959           5 : void SAL_CALL SwXTextRange::setString(const OUString& rString)
     960             : throw (uno::RuntimeException, std::exception)
     961             : {
     962           5 :     SolarMutexGuard aGuard;
     963             : 
     964           5 :     DeleteAndInsert(rString, false);
     965           5 : }
     966             : 
     967       59529 : bool SwXTextRange::GetPositions(SwPaM& rToFill) const
     968             : {
     969       59529 :     ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
     970       59529 :     if(pBkmk)
     971             :     {
     972       59521 :         *rToFill.GetPoint() = pBkmk->GetMarkPos();
     973       59521 :         if(pBkmk->IsExpanded())
     974             :         {
     975        7004 :             rToFill.SetMark();
     976        7004 :             *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
     977             :         }
     978             :         else
     979             :         {
     980       52517 :             rToFill.DeleteMark();
     981             :         }
     982       59521 :         return true;
     983             :     }
     984           8 :     return false;
     985             : }
     986             : 
     987             : namespace sw {
     988             : 
     989       63691 : bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
     990             :         const uno::Reference< text::XTextRange > & xTextRange)
     991             : {
     992       63691 :     bool bRet = false;
     993             : 
     994       63691 :     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
     995       63691 :     SwXTextRange* pRange = 0;
     996       63691 :     OTextCursorHelper* pCursor = 0;
     997       63691 :     SwXTextPortion* pPortion = 0;
     998       63691 :     SwXText* pText = 0;
     999       63691 :     SwXParagraph* pPara = 0;
    1000       63691 :     if(xRangeTunnel.is())
    1001             :     {
    1002       63690 :         pRange  = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
    1003             :         pCursor =
    1004       63690 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
    1005             :         pPortion=
    1006       63690 :             ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel);
    1007       63690 :         pText   = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel);
    1008       63690 :         pPara   = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel);
    1009             :     }
    1010             : 
    1011             :     // if it's a text then create a temporary cursor there and re-use
    1012             :     // the pCursor variable
    1013             :     // #i108489#: Reference in outside scope to keep cursor alive
    1014      127382 :     uno::Reference< text::XTextCursor > xTextCursor;
    1015       63691 :     if (pText)
    1016             :     {
    1017         453 :         xTextCursor.set( pText->CreateCursor() );
    1018         453 :         xTextCursor->gotoEnd(sal_True);
    1019             :         const uno::Reference<lang::XUnoTunnel> xCrsrTunnel(
    1020         453 :                 xTextCursor, uno::UNO_QUERY);
    1021             :         pCursor =
    1022         453 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCrsrTunnel);
    1023             :     }
    1024       63691 :     if(pRange && pRange->GetDoc() == rToFill.GetDoc())
    1025             :     {
    1026       35649 :         bRet = pRange->GetPositions(rToFill);
    1027             :     }
    1028             :     else
    1029             :     {
    1030       28042 :         if (pPara)
    1031             :         {
    1032           2 :             bRet = pPara->SelectPaM(rToFill);
    1033             :         }
    1034             :         else
    1035             :         {
    1036       28039 :             SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc()
    1037       56079 :                 : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0);
    1038       28039 :             const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM()
    1039       56079 :                 : ((pPortion) ? pPortion->GetCursor() : 0);
    1040       28040 :             if (pUnoCrsr && pDoc == rToFill.GetDoc())
    1041             :             {
    1042             :                 OSL_ENSURE(!pUnoCrsr->IsMultiSelection(),
    1043             :                         "what to do about rings?");
    1044       28039 :                 bRet = true;
    1045       28039 :                 *rToFill.GetPoint() = *pUnoCrsr->GetPoint();
    1046       28039 :                 if (pUnoCrsr->HasMark())
    1047             :                 {
    1048       10814 :                     rToFill.SetMark();
    1049       10814 :                     *rToFill.GetMark() = *pUnoCrsr->GetMark();
    1050             :                 }
    1051             :                 else
    1052       17225 :                     rToFill.DeleteMark();
    1053             :             }
    1054             :         }
    1055             :     }
    1056      127382 :     return bRet;
    1057             : }
    1058             : 
    1059             : static bool
    1060         997 : lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode,
    1061             :     SwFrameFormat const*const pFrameFormat, SwFrameFormat*& rpFormat)
    1062             : {
    1063         997 :     bool bRet = false;
    1064         997 :     const SfxItemSet& rSet = pFrameFormat->GetAttrSet();
    1065             :     const SfxPoolItem* pItem;
    1066         997 :     if (SfxItemState::SET == rSet.GetItemState(
    1067             :             static_cast<sal_uInt16>(bHeader ? RES_HEADER : RES_FOOTER),
    1068         997 :             true, &pItem))
    1069             :     {
    1070         983 :         SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem));
    1071             :         SwFrameFormat *const pHeadFootFormat = (bHeader) ?
    1072             :             static_cast<SwFormatHeader*>(pItemNonConst)->GetHeaderFormat() :
    1073         983 :             static_cast<SwFormatFooter*>(pItemNonConst)->GetFooterFormat();
    1074         983 :         if (pHeadFootFormat)
    1075             :         {
    1076         499 :             const SwFormatContent& rFlyContent = pHeadFootFormat->GetContent();
    1077         499 :             const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
    1078             :             SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType(
    1079         499 :                 (bHeader) ? SwHeaderStartNode : SwFooterStartNode);
    1080         499 :             if (pCurSttNode && (pCurSttNode == pSttNode))
    1081             :             {
    1082         175 :                 rpFormat = pHeadFootFormat;
    1083         175 :                 bRet = true;
    1084             :             }
    1085             :         }
    1086             :     }
    1087         997 :     return bRet;
    1088             : }
    1089             : 
    1090             : } // namespace sw
    1091             : 
    1092             : uno::Reference< text::XTextRange >
    1093        6359 : SwXTextRange::CreateXTextRange(
    1094             :     SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
    1095             : {
    1096             :     const uno::Reference<text::XText> xParentText(
    1097        6359 :             ::sw::CreateParentXText(rDoc, rPos));
    1098       12718 :     const auto pNewCrsr(rDoc.CreateUnoCrsr(rPos, false));
    1099        6359 :     if(pMark)
    1100             :     {
    1101        5378 :         pNewCrsr->SetMark();
    1102        5378 :         *pNewCrsr->GetMark() = *pMark;
    1103             :     }
    1104        6359 :     const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
    1105             :     const uno::Reference< text::XTextRange > xRet(
    1106        6359 :         new SwXTextRange(*pNewCrsr, xParentText,
    1107        6359 :             isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) );
    1108       12718 :     return xRet;
    1109             : }
    1110             : 
    1111             : namespace sw {
    1112             : 
    1113             : uno::Reference< text::XText >
    1114        6497 : CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
    1115             : {
    1116        6497 :     uno::Reference< text::XText > xParentText;
    1117        6497 :     SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode();
    1118       13004 :     while(pSttNode && pSttNode->IsSectionNode())
    1119             :     {
    1120          10 :         pSttNode = pSttNode->StartOfSectionNode();
    1121             :     }
    1122        6497 :     SwStartNodeType eType = pSttNode ? pSttNode->GetStartNodeType() : SwNormalStartNode;
    1123        6497 :     switch(eType)
    1124             :     {
    1125             :         case SwTableBoxStartNode:
    1126             :         {
    1127         857 :             SwTableNode const*const pTableNode = pSttNode->FindTableNode();
    1128             :             SwFrameFormat *const pTableFormat =
    1129         857 :                 static_cast<SwFrameFormat*>(pTableNode->GetTable().GetFrameFormat());
    1130         857 :             SwTableBox *const  pBox = pSttNode->GetTableBox();
    1131             : 
    1132         857 :             xParentText = (pBox)
    1133             :                 ? SwXCell::CreateXCell( pTableFormat, pBox )
    1134         857 :                 : new SwXCell( pTableFormat, *pSttNode );
    1135             :         }
    1136         857 :         break;
    1137             :         case SwFlyStartNode:
    1138             :         {
    1139         101 :             SwFrameFormat *const pFormat = pSttNode->GetFlyFormat();
    1140         101 :             if (0 != pFormat)
    1141             :             {
    1142             :                 xParentText.set(SwXTextFrame::CreateXTextFrame(rDoc, pFormat),
    1143         101 :                         uno::UNO_QUERY);
    1144             :             }
    1145             :         }
    1146         101 :         break;
    1147             :         case SwHeaderStartNode:
    1148             :         case SwFooterStartNode:
    1149             :         {
    1150         175 :             const bool bHeader = (SwHeaderStartNode == eType);
    1151         175 :             const size_t nPDescCount = rDoc.GetPageDescCnt();
    1152         751 :             for(size_t i = 0; i < nPDescCount; i++)
    1153             :             {
    1154         576 :                 const SwPageDesc& rDesc = rDoc.GetPageDesc( i );
    1155         576 :                 const SwFrameFormat* pFrameFormatMaster = &rDesc.GetMaster();
    1156         576 :                 const SwFrameFormat* pFrameFormatLeft = &rDesc.GetLeft();
    1157             : 
    1158         576 :                 SwFrameFormat* pHeadFootFormat = 0;
    1159         576 :                 if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatMaster,
    1160         576 :                             pHeadFootFormat))
    1161             :                 {
    1162             :                     lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatLeft,
    1163         421 :                             pHeadFootFormat);
    1164             :                 }
    1165             : 
    1166         576 :                 if (pHeadFootFormat)
    1167             :                 {
    1168         350 :                     xParentText = SwXHeadFootText::CreateXHeadFootText(
    1169         175 :                             *pHeadFootFormat, bHeader);
    1170             :                 }
    1171             :             }
    1172             :         }
    1173         175 :         break;
    1174             :         case SwFootnoteStartNode:
    1175             :         {
    1176           6 :             const size_t nFootnoteCnt = rDoc.GetFootnoteIdxs().size();
    1177           6 :             uno::Reference< text::XFootnote >  xRef;
    1178           9 :             for (size_t n = 0; n < nFootnoteCnt; ++n )
    1179             :             {
    1180           9 :                 const SwTextFootnote* pTextFootnote = rDoc.GetFootnoteIdxs()[ n ];
    1181           9 :                 const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
    1182           9 :                 pTextFootnote = rFootnote.GetTextFootnote();
    1183             : #if OSL_DEBUG_LEVEL > 1
    1184             :                 const SwStartNode* pTmpSttNode =
    1185             :                         pTextFootnote->GetStartNode()->GetNode().
    1186             :                                 FindSttNodeByType(SwFootnoteStartNode);
    1187             :                 (void)pTmpSttNode;
    1188             : #endif
    1189             : 
    1190          18 :                 if (pSttNode == pTextFootnote->GetStartNode()->GetNode().
    1191           9 :                                     FindSttNodeByType(SwFootnoteStartNode))
    1192             :                 {
    1193             :                     xParentText.set(SwXFootnote::CreateXFootnote(rDoc,
    1194           6 :                             &const_cast<SwFormatFootnote&>(rFootnote)), uno::UNO_QUERY);
    1195           6 :                     break;
    1196             :                 }
    1197           6 :             }
    1198             :         }
    1199           6 :         break;
    1200             :         default:
    1201             :         {
    1202             :             // then it is the body text
    1203             :             const uno::Reference<frame::XModel> xModel =
    1204        5358 :                 rDoc.GetDocShell()->GetBaseModel();
    1205             :             const uno::Reference< text::XTextDocument > xDoc(
    1206       10716 :                 xModel, uno::UNO_QUERY);
    1207       10716 :             xParentText = xDoc->getText();
    1208             :         }
    1209             :     }
    1210             :     OSL_ENSURE(xParentText.is(), "no parent text?");
    1211        6497 :     return xParentText;
    1212             : }
    1213             : 
    1214             : } // namespace sw
    1215             : 
    1216             : uno::Reference< container::XEnumeration > SAL_CALL
    1217           0 : SwXTextRange::createContentEnumeration(const OUString& rServiceName)
    1218             : throw (uno::RuntimeException, std::exception)
    1219             : {
    1220           0 :     SolarMutexGuard g;
    1221             : 
    1222           0 :     if ( rServiceName != "com.sun.star.text.TextContent" )
    1223             :     {
    1224           0 :         throw uno::RuntimeException();
    1225             :     }
    1226             : 
    1227           0 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1228             :     {
    1229           0 :         throw uno::RuntimeException();
    1230             :     }
    1231           0 :     const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
    1232           0 :     const auto pNewCrsr(m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
    1233           0 :     if (!GetPositions(*pNewCrsr))
    1234             :     {
    1235           0 :         throw uno::RuntimeException();
    1236             :     }
    1237             : 
    1238           0 :     return SwXParaFrameEnumeration::Create(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
    1239             : }
    1240             : 
    1241             : uno::Reference< container::XEnumeration > SAL_CALL
    1242           1 : SwXTextRange::createEnumeration() throw (uno::RuntimeException, std::exception)
    1243             : {
    1244           1 :     SolarMutexGuard g;
    1245             : 
    1246           1 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1247             :     {
    1248           0 :         throw uno::RuntimeException();
    1249             :     }
    1250           2 :     const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
    1251           2 :     auto pNewCrsr(m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
    1252           1 :     if (!GetPositions(*pNewCrsr))
    1253             :     {
    1254           0 :         throw uno::RuntimeException();
    1255             :     }
    1256           1 :     if (!m_pImpl->m_xParentText.is())
    1257             :     {
    1258           0 :         getText();
    1259             :     }
    1260             : 
    1261           1 :     const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition)
    1262           1 :             ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
    1263           2 :     return SwXParagraphEnumeration::Create(m_pImpl->m_xParentText, pNewCrsr, eSetType);
    1264             : }
    1265             : 
    1266           0 : uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException, std::exception)
    1267             : {
    1268           0 :     return cppu::UnoType<text::XTextRange>::get();
    1269             : }
    1270             : 
    1271           0 : sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException, std::exception)
    1272             : {
    1273           0 :     return sal_True;
    1274             : }
    1275             : 
    1276             : uno::Sequence< OUString > SAL_CALL
    1277           0 : SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException, std::exception)
    1278             : {
    1279           0 :     uno::Sequence< OUString > aRet(1);
    1280           0 :     OUString* pArray = aRet.getArray();
    1281           0 :     pArray[0] = "com.sun.star.text.TextContent";
    1282           0 :     return aRet;
    1283             : }
    1284             : 
    1285             : uno::Reference< beans::XPropertySetInfo > SAL_CALL
    1286         277 : SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
    1287             : {
    1288         277 :     SolarMutexGuard aGuard;
    1289             : 
    1290             :     static uno::Reference< beans::XPropertySetInfo > xRef =
    1291         277 :         m_pImpl->m_rPropSet.getPropertySetInfo();
    1292         277 :     return xRef;
    1293             : }
    1294             : 
    1295             : void SAL_CALL
    1296         434 : SwXTextRange::setPropertyValue(
    1297             :         const OUString& rPropertyName, const uno::Any& rValue)
    1298             : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
    1299             :         lang::IllegalArgumentException, lang::WrappedTargetException,
    1300             :         uno::RuntimeException, std::exception)
    1301             : {
    1302         434 :     SolarMutexGuard aGuard;
    1303             : 
    1304         434 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1305             :     {
    1306           0 :         throw uno::RuntimeException();
    1307             :     }
    1308         868 :     SwPaM aPaM(GetDoc()->GetNodes());
    1309         434 :     GetPositions(aPaM);
    1310         434 :     SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet,
    1311         868 :             rPropertyName, rValue);
    1312         434 : }
    1313             : 
    1314             : uno::Any SAL_CALL
    1315         433 : SwXTextRange::getPropertyValue(const OUString& rPropertyName)
    1316             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1317             :         uno::RuntimeException, std::exception)
    1318             : {
    1319         433 :     SolarMutexGuard aGuard;
    1320             : 
    1321         433 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1322             :     {
    1323           0 :         throw uno::RuntimeException();
    1324             :     }
    1325         864 :     SwPaM aPaM(GetDoc()->GetNodes());
    1326         433 :     GetPositions(aPaM);
    1327         433 :     return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet,
    1328         866 :             rPropertyName);
    1329             : }
    1330             : 
    1331             : void SAL_CALL
    1332           0 : SwXTextRange::addPropertyChangeListener(
    1333             :         const OUString& /*rPropertyName*/,
    1334             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    1335             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1336             :     uno::RuntimeException, std::exception)
    1337             : {
    1338             :     OSL_FAIL("SwXTextRange::addPropertyChangeListener(): not implemented");
    1339           0 : }
    1340             : 
    1341             : void SAL_CALL
    1342           0 : SwXTextRange::removePropertyChangeListener(
    1343             :         const OUString& /*rPropertyName*/,
    1344             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    1345             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1346             :     uno::RuntimeException, std::exception)
    1347             : {
    1348             :     OSL_FAIL("SwXTextRange::removePropertyChangeListener(): not implemented");
    1349           0 : }
    1350             : 
    1351             : void SAL_CALL
    1352           0 : SwXTextRange::addVetoableChangeListener(
    1353             :         const OUString& /*rPropertyName*/,
    1354             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    1355             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1356             :     uno::RuntimeException, std::exception)
    1357             : {
    1358             :     OSL_FAIL("SwXTextRange::addVetoableChangeListener(): not implemented");
    1359           0 : }
    1360             : 
    1361             : void SAL_CALL
    1362           0 : SwXTextRange::removeVetoableChangeListener(
    1363             :         const OUString& /*rPropertyName*/,
    1364             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    1365             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1366             :         uno::RuntimeException, std::exception)
    1367             : {
    1368             :     OSL_FAIL("SwXTextRange::removeVetoableChangeListener(): not implemented");
    1369           0 : }
    1370             : 
    1371             : beans::PropertyState SAL_CALL
    1372           0 : SwXTextRange::getPropertyState(const OUString& rPropertyName)
    1373             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    1374             : {
    1375           0 :     SolarMutexGuard aGuard;
    1376             : 
    1377           0 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1378             :     {
    1379           0 :         throw uno::RuntimeException();
    1380             :     }
    1381           0 :     SwPaM aPaM(GetDoc()->GetNodes());
    1382           0 :     GetPositions(aPaM);
    1383           0 :     return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet,
    1384           0 :             rPropertyName);
    1385             : }
    1386             : 
    1387             : uno::Sequence< beans::PropertyState > SAL_CALL
    1388         263 : SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName)
    1389             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    1390             : {
    1391         263 :     SolarMutexGuard g;
    1392             : 
    1393         263 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1394             :     {
    1395           0 :         throw uno::RuntimeException();
    1396             :     }
    1397         526 :     SwPaM aPaM(GetDoc()->GetNodes());
    1398         263 :     GetPositions(aPaM);
    1399         263 :     return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet,
    1400         526 :             rPropertyName);
    1401             : }
    1402             : 
    1403           0 : void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName)
    1404             : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
    1405             : {
    1406           0 :     SolarMutexGuard aGuard;
    1407             : 
    1408           0 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1409             :     {
    1410           0 :         throw uno::RuntimeException();
    1411             :     }
    1412           0 :     SwPaM aPaM(GetDoc()->GetNodes());
    1413           0 :     GetPositions(aPaM);
    1414           0 :     SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet,
    1415           0 :             rPropertyName);
    1416           0 : }
    1417             : 
    1418             : uno::Any SAL_CALL
    1419           0 : SwXTextRange::getPropertyDefault(const OUString& rPropertyName)
    1420             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1421             :         uno::RuntimeException, std::exception)
    1422             : {
    1423           0 :     SolarMutexGuard aGuard;
    1424             : 
    1425           0 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1426             :     {
    1427           0 :         throw uno::RuntimeException();
    1428             :     }
    1429           0 :     SwPaM aPaM(GetDoc()->GetNodes());
    1430           0 :     GetPositions(aPaM);
    1431           0 :     return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet,
    1432           0 :             rPropertyName);
    1433             : }
    1434             : 
    1435             : void SAL_CALL
    1436        1330 : SwXTextRange::makeRedline(
    1437             :     const OUString& rRedlineType,
    1438             :     const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
    1439             : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    1440             : {
    1441        1330 :     SolarMutexGuard aGuard;
    1442             : 
    1443        1330 :     if (!GetDoc() || !m_pImpl->GetBookmark())
    1444             :     {
    1445           0 :         throw uno::RuntimeException();
    1446             :     }
    1447        2658 :     SwPaM aPaM(GetDoc()->GetNodes());
    1448        1330 :     SwXTextRange::GetPositions(aPaM);
    1449        2660 :     SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
    1450        1328 : }
    1451             : 
    1452           2 : struct SwXTextRangesImpl SAL_FINAL : public SwXTextRanges
    1453             : {
    1454             : 
    1455             :     // XUnoTunnel
    1456             :     virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1457             : 
    1458             :     // XServiceInfo
    1459           0 :     virtual OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1460           0 :         { return OUString("SwXTextRanges"); };
    1461           0 :     virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1462           0 :         { return cppu::supportsService(this, rServiceName); };
    1463           0 :     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1464           0 :         { return { "com.sun.star.text.TextRanges" }; };
    1465             : 
    1466             :     // XElementAccess
    1467           0 :     virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1468           0 :         { return cppu::UnoType<text::XTextRange>::get(); };
    1469           0 :     virtual sal_Bool SAL_CALL hasElements() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1470           0 :         { return getCount() > 0; };
    1471             :     // XIndexAccess
    1472             :     virtual sal_Int32 SAL_CALL getCount() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1473             :     virtual ::com::sun::star::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1474             : 
    1475           1 :     SwXTextRangesImpl(SwPaM *const pPaM)
    1476           1 :     {
    1477           1 :         if (pPaM)
    1478             :         {
    1479           1 :             m_pUnoCursor.reset(pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint()));
    1480           1 :             ::sw::DeepCopyPaM(*pPaM, *GetCursor());
    1481             :         }
    1482           1 :         MakeRanges();
    1483           1 :     }
    1484          11 :     virtual void SAL_CALL release() throw () SAL_OVERRIDE
    1485             :     {
    1486          11 :         SolarMutexGuard g;
    1487          11 :         OWeakObject::release();
    1488          11 :     }
    1489           3 :     virtual SwUnoCrsr* GetCursor() SAL_OVERRIDE
    1490           3 :         { return &(*m_pUnoCursor); };
    1491             :     void MakeRanges();
    1492             :     ::std::vector< uno::Reference< text::XTextRange > > m_Ranges;
    1493             :     sw::UnoCursorPointer m_pUnoCursor;
    1494             : };
    1495             : 
    1496           1 : void SwXTextRangesImpl::MakeRanges()
    1497             : {
    1498           1 :     if (GetCursor())
    1499             :     {
    1500           2 :         for(SwPaM& rTmpCursor : GetCursor()->GetRingContainer())
    1501             :         {
    1502             :             const uno::Reference< text::XTextRange > xRange(
    1503             :                     SwXTextRange::CreateXTextRange(
    1504           1 :                         *rTmpCursor.GetDoc(),
    1505           2 :                         *rTmpCursor.GetPoint(), rTmpCursor.GetMark()));
    1506           1 :             if (xRange.is())
    1507             :             {
    1508           1 :                 m_Ranges.push_back(xRange);
    1509             :             }
    1510           1 :         }
    1511             :     }
    1512           1 : }
    1513             : 
    1514           1 : SwXTextRanges* SwXTextRanges::Create(SwPaM *const pPaM)
    1515           1 :     { return new SwXTextRangesImpl(pPaM); }
    1516             : 
    1517             : namespace
    1518             : {
    1519             :     class theSwXTextRangesUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangesUnoTunnelId > {};
    1520             : }
    1521             : 
    1522           8 : const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
    1523           8 :     { return theSwXTextRangesUnoTunnelId::get().getSeq(); }
    1524             : 
    1525             : sal_Int64 SAL_CALL
    1526           0 : SwXTextRangesImpl::getSomething(const uno::Sequence< sal_Int8 >& rId)
    1527             :     throw (uno::RuntimeException, std::exception)
    1528             : {
    1529           0 :     return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this);
    1530             : }
    1531             : 
    1532             : /*
    1533             :  *  Text positions
    1534             :  * Up to the first access to a text position, only a SwCursor is stored.
    1535             :  * Afterwards, an array with uno::Reference<XTextPosition> will be created.
    1536             :  */
    1537             : 
    1538           2 : sal_Int32 SAL_CALL SwXTextRangesImpl::getCount()
    1539             :     throw (uno::RuntimeException, std::exception)
    1540             : {
    1541           2 :     SolarMutexGuard aGuard;
    1542           2 :     return static_cast<sal_Int32>(m_Ranges.size());
    1543             : }
    1544             : 
    1545           1 : uno::Any SAL_CALL SwXTextRangesImpl::getByIndex(sal_Int32 nIndex) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
    1546             : {
    1547           1 :     SolarMutexGuard aGuard;
    1548           1 :     if ((nIndex < 0) || (static_cast<size_t>(nIndex) >= m_Ranges.size()))
    1549           0 :         throw lang::IndexOutOfBoundsException();
    1550           1 :     uno::Any ret;
    1551           1 :     ret <<= (m_Ranges.at(nIndex));
    1552           1 :     return ret;
    1553             : }
    1554             : 
    1555           9 : void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString)
    1556             : {
    1557             :     // Start/EndAction
    1558           9 :     SwDoc *const pDoc = rCursor.GetDoc();
    1559           9 :     UnoActionContext aAction(pDoc);
    1560           9 :     pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
    1561           9 :     if (rCursor.HasMark())
    1562             :     {
    1563           8 :         pDoc->getIDocumentContentOperations().DeleteAndJoin(rCursor);
    1564             :     }
    1565           9 :     if (!rString.isEmpty())
    1566             :     {
    1567             :         const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
    1568           8 :                     *pDoc, rCursor, rString, false ) );
    1569             :         OSL_ENSURE( bSuccess, "DocInsertStringSplitCR" );
    1570             :         (void) bSuccess;
    1571           8 :         SwUnoCursorHelper::SelectPam(rCursor, true);
    1572           8 :         rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, false, false);
    1573             :     }
    1574           9 :     pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
    1575           9 : }
    1576             : 
    1577        2302 : struct SwXParaFrameEnumerationImpl SAL_FINAL : public SwXParaFrameEnumeration
    1578             : {
    1579             :     // XServiceInfo
    1580           0 :     virtual OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1581           0 :         { return OUString("SwXParaFrameEnumeration"); };
    1582           0 :     virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1583           0 :         { return cppu::supportsService(this, rServiceName); };
    1584           0 :     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1585           0 :         { return {"com.sun.star.util.ContentEnumeration"}; };
    1586             : 
    1587             :     // XEnumeration
    1588             :     virtual sal_Bool SAL_CALL hasMoreElements() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1589             :     virtual ::com::sun::star::uno::Any SAL_CALL nextElement() throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1590             : 
    1591             :     SwXParaFrameEnumerationImpl(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat = nullptr);
    1592        2368 :     virtual void SAL_CALL release() throw () SAL_OVERRIDE
    1593             :     {
    1594        2368 :         SolarMutexGuard g;
    1595        2368 :         OWeakObject::release();
    1596        2368 :     }
    1597        1742 :     SwUnoCrsr* GetCursor()
    1598        1742 :         { return &(*m_pUnoCursor); }
    1599        1420 :     void PurgeFrameClients()
    1600             :     {
    1601        1420 :         if(!m_pUnoCursor)
    1602             :         {
    1603           0 :             m_vFrames.clear();
    1604           0 :             m_xNextObject = nullptr;
    1605             :         }
    1606             :         else
    1607             :         {
    1608             :             // removing orphaned SwDepends
    1609             :             const auto iter = std::remove_if(m_vFrames.begin(), m_vFrames.end(),
    1610        2218 :                     [] (std::shared_ptr<sw::FrameClient>& rEntry) -> bool { return !rEntry->GetRegisteredIn(); });
    1611        1420 :             m_vFrames.erase(iter, m_vFrames.end());
    1612             :         }
    1613        1420 :     }
    1614             :     void FillFrame();
    1615             :     bool CreateNextObject();
    1616             :     uno::Reference< text::XTextContent > m_xNextObject;
    1617             :     FrameClientList_t m_vFrames;
    1618             :     ::sw::UnoCursorPointer m_pUnoCursor;
    1619             : };
    1620             : 
    1621             : 
    1622             : 
    1623        1151 : SwXParaFrameEnumeration* SwXParaFrameEnumeration::Create(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat)
    1624        1151 :     { return new SwXParaFrameEnumerationImpl(rPaM, eParaFrameMode, pFormat); }
    1625             : 
    1626        1151 : SwXParaFrameEnumerationImpl::SwXParaFrameEnumerationImpl(
    1627             :         const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode,
    1628             :         SwFrameFormat* const pFormat)
    1629        1151 :     : m_pUnoCursor(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), false))
    1630             : {
    1631        1151 :     if (rPaM.HasMark())
    1632             :     {
    1633         161 :         GetCursor()->SetMark();
    1634         161 :         *GetCursor()->GetMark() = *rPaM.GetMark();
    1635             :     }
    1636        1151 :     if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode)
    1637             :     {
    1638         990 :         FrameClientSortList_t vFrames;
    1639         990 :         ::CollectFrameAtNode(rPaM.GetPoint()->nNode, vFrames, false);
    1640             :         ::std::transform(vFrames.begin(), vFrames.end(),
    1641             :             ::std::back_inserter(m_vFrames),
    1642        1067 :             [] (const FrameClientSortListEntry& rEntry) { return rEntry.pFrameClient; });
    1643             :     }
    1644         161 :     else if (pFormat)
    1645             :     {
    1646          25 :         m_vFrames.push_back(std::shared_ptr<sw::FrameClient>(new sw::FrameClient(pFormat)));
    1647             :     }
    1648         136 :     else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) ||
    1649             :              (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode))
    1650             :     {
    1651         136 :         if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)
    1652             :         {
    1653             :             //get all frames that are bound at paragraph or at character
    1654           0 :             for(const auto& pFlyFrm : rPaM.GetDoc()->GetAllFlyFormats(GetCursor(), false, true))
    1655             :             {
    1656           0 :                 const auto pFrameFormat = const_cast<SwFrameFormat*>(&pFlyFrm->GetFormat());
    1657           0 :                 m_vFrames.push_back(std::shared_ptr<sw::FrameClient>(new sw::FrameClient(pFrameFormat)));
    1658           0 :             }
    1659             :         }
    1660         136 :         FillFrame();
    1661             :     }
    1662        1151 : }
    1663             : 
    1664             : // Search for a FLYCNT text attribute at the cursor point and fill the frame
    1665             : // into the array
    1666         136 : void SwXParaFrameEnumerationImpl::FillFrame()
    1667             : {
    1668         136 :     if(!m_pUnoCursor->GetNode().IsTextNode())
    1669           0 :         return;
    1670             :     // search for objects at the cursor - anchored at/as char
    1671         136 :     const auto pTextAttr = m_pUnoCursor->GetNode().GetTextNode()->GetTextAttrForCharAt(
    1672         272 :             m_pUnoCursor->GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT);
    1673         136 :     if(!pTextAttr)
    1674           0 :         return;
    1675         136 :     const SwFormatFlyCnt& rFlyCnt = pTextAttr->GetFlyCnt();
    1676         136 :     SwFrameFormat* const pFrameFormat = rFlyCnt.GetFrameFormat();
    1677         136 :     m_vFrames.push_back(std::shared_ptr<sw::FrameClient>(new sw::FrameClient(pFrameFormat)));
    1678             : }
    1679             : 
    1680        1274 : bool SwXParaFrameEnumerationImpl::CreateNextObject()
    1681             : {
    1682        1274 :     if (!m_vFrames.size())
    1683        1036 :         return false;
    1684             : 
    1685             :     SwFrameFormat* const pFormat = static_cast<SwFrameFormat*>(
    1686         238 :             m_vFrames.front()->GetRegisteredIn());
    1687         238 :     m_vFrames.pop_front();
    1688             :     // the format should be valid here, otherwise the client
    1689             :     // would have been removed by PurgeFrameClients
    1690             :     // check for a shape first
    1691         238 :     SwDrawContact* const pContact = SwIterator<SwDrawContact,SwFormat>( *pFormat ).First();
    1692         238 :     if (pContact)
    1693             :     {
    1694          19 :         SdrObject* const pSdr = pContact->GetMaster();
    1695          19 :         if (pSdr)
    1696          19 :             m_xNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY);
    1697             :     }
    1698             :     else
    1699             :     {
    1700         219 :         const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
    1701             :         OSL_ENSURE(pIdx, "where is the index?");
    1702             :         SwNode const*const pNd =
    1703         219 :             m_pUnoCursor->GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
    1704             : 
    1705         219 :         if (!pNd->IsNoTextNode())
    1706             :         {
    1707             :             m_xNextObject.set(SwXTextFrame::CreateXTextFrame(
    1708          89 :                         *pFormat->GetDoc(), pFormat));
    1709             :         }
    1710         130 :         else if (pNd->IsGrfNode())
    1711             :         {
    1712             :             m_xNextObject.set(SwXTextGraphicObject::CreateXTextGraphicObject(
    1713           6 :                         *pFormat->GetDoc(), pFormat));
    1714             :         }
    1715             :         else
    1716             :         {
    1717             :             assert(pNd->IsOLENode());
    1718             :             m_xNextObject.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
    1719         124 :                         *pFormat->GetDoc(), pFormat));
    1720             :         }
    1721             :     }
    1722         238 :     return m_xNextObject.is();
    1723             : }
    1724             : 
    1725             : sal_Bool SAL_CALL
    1726        1182 : SwXParaFrameEnumerationImpl::hasMoreElements() throw (uno::RuntimeException, std::exception)
    1727             : {
    1728        1182 :     SolarMutexGuard aGuard;
    1729        1182 :     if (!GetCursor())
    1730           0 :         throw uno::RuntimeException();
    1731        1182 :     PurgeFrameClients();
    1732        1182 :     return m_xNextObject.is() || CreateNextObject();
    1733             : }
    1734             : 
    1735         238 : uno::Any SAL_CALL SwXParaFrameEnumerationImpl::nextElement()
    1736             : throw (container::NoSuchElementException,
    1737             :         lang::WrappedTargetException, uno::RuntimeException, std::exception)
    1738             : {
    1739         238 :     SolarMutexGuard aGuard;
    1740         238 :     if (!GetCursor())
    1741           0 :         throw uno::RuntimeException();
    1742         238 :     PurgeFrameClients();
    1743         238 :     if (!m_xNextObject.is() && m_vFrames.size())
    1744         115 :         CreateNextObject();
    1745         238 :     if (!m_xNextObject.is())
    1746           0 :         throw container::NoSuchElementException();
    1747         238 :     uno::Any aRet;
    1748         238 :     aRet <<= m_xNextObject;
    1749         238 :     m_xNextObject = nullptr;
    1750         238 :     return aRet;
    1751         177 : }
    1752             : 
    1753             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11