LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/unocore - unotext.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 729 1256 58.0 %
Date: 2012-12-27 Functions: 66 101 65.3 %
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             : 
      21             : #include <stdlib.h>
      22             : 
      23             : #include <memory>
      24             : #include <iostream>
      25             : 
      26             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      27             : #include <com/sun/star/text/ControlCharacter.hpp>
      28             : #include <com/sun/star/text/TableColumnSeparator.hpp>
      29             : 
      30             : #include <osl/mutex.hxx>
      31             : #include <vcl/svapp.hxx>
      32             : #include <comphelper/sequence.hxx>
      33             : #include <comphelper/servicehelper.hxx>
      34             : 
      35             : #include <cmdid.h>
      36             : #include <unotextbodyhf.hxx>
      37             : #include <unotext.hxx>
      38             : #include <unotextrange.hxx>
      39             : #include <unotextcursor.hxx>
      40             : #include <unosection.hxx>
      41             : #include <unobookmark.hxx>
      42             : #include <unorefmark.hxx>
      43             : #include <unoport.hxx>
      44             : #include <unotbl.hxx>
      45             : #include <unoidx.hxx>
      46             : #include <unoframe.hxx>
      47             : #include <unofield.hxx>
      48             : #include <unometa.hxx>
      49             : #include <unodraw.hxx>
      50             : #include <unoredline.hxx>
      51             : #include <unomap.hxx>
      52             : #include <unoprnms.hxx>
      53             : #include <unoparagraph.hxx>
      54             : #include <unocrsrhelper.hxx>
      55             : #include <docsh.hxx>
      56             : #include <docary.hxx>
      57             : #include <doc.hxx>
      58             : #include <IDocumentUndoRedo.hxx>
      59             : #include <redline.hxx>
      60             : #include <swundo.hxx>
      61             : #include <section.hxx>
      62             : #include <IMark.hxx>
      63             : #include <fmtanchr.hxx>
      64             : #include <fmtcntnt.hxx>
      65             : #include <crsskip.hxx>
      66             : #include <ndtxt.hxx>
      67             : 
      68             : 
      69             : using namespace ::com::sun::star;
      70             : using ::rtl::OUString;
      71             : 
      72             : 
      73             : const sal_Char cInvalidObject[] = "this object is invalid";
      74             : 
      75             : /******************************************************************
      76             :  * SwXText
      77             :  ******************************************************************/
      78             : class SwXText::Impl
      79             : {
      80             : 
      81             : public:
      82             :     SwXText &                   m_rThis;
      83             :     SfxItemPropertySet const&   m_rPropSet;
      84             :     const enum CursorType       m_eType;
      85             :     SwDoc *                     m_pDoc;
      86             :     bool                        m_bIsValid;
      87             : 
      88         860 :     Impl(   SwXText & rThis,
      89             :             SwDoc *const pDoc, const enum CursorType eType)
      90             :         : m_rThis(rThis)
      91         860 :         , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT))
      92             :         , m_eType(eType)
      93             :         , m_pDoc(pDoc)
      94        1720 :         , m_bIsValid(0 != pDoc)
      95             :     {
      96         860 :     }
      97             : 
      98             :     uno::Reference< text::XTextRange >
      99             :         finishOrAppendParagraph(
     100             :             const bool bFinish,
     101             :             const uno::Sequence< beans::PropertyValue >&
     102             :                 rCharacterAndParagraphProperties,
     103             :             const uno::Reference< text::XTextRange >& xInsertPosition)
     104             :         throw (lang::IllegalArgumentException, uno::RuntimeException);
     105             : 
     106             :     sal_Int16 ComparePositions(
     107             :             const uno::Reference<text::XTextRange>& xPos1,
     108             :             const uno::Reference<text::XTextRange>& xPos2)
     109             :         throw (lang::IllegalArgumentException, uno::RuntimeException);
     110             : 
     111             :     bool CheckForOwnMember(const SwPaM & rPaM)
     112             :         throw (lang::IllegalArgumentException, uno::RuntimeException);
     113             : 
     114             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     115             :     void ConvertCell(
     116             :             const bool bFirstCell,
     117             :             const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
     118             :             ::std::vector<SwNodeRange> & rRowNodes,
     119             :             ::std::auto_ptr< SwPaM > & rpFirstPaM,
     120             :             SwPaM & rLastPaM,
     121             :             bool & rbExcept);
     122             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     123             : 
     124             : };
     125             : 
     126         860 : SwXText::SwXText(SwDoc *const pDoc, const enum CursorType eType)
     127         860 :     : m_pImpl( new SwXText::Impl(*this, pDoc, eType) )
     128             : {
     129         860 : }
     130             : 
     131         690 : SwXText::~SwXText()
     132             : {
     133         690 : }
     134             : 
     135         978 : const SwDoc * SwXText::GetDoc() const
     136             : {
     137         978 :     return m_pImpl->m_pDoc;
     138             : }
     139        8886 :       SwDoc * SwXText::GetDoc()
     140             : {
     141        8886 :     return m_pImpl->m_pDoc;
     142             : }
     143             : 
     144        4064 : bool SwXText::IsValid() const
     145             : {
     146        4064 :     return m_pImpl->m_bIsValid;
     147             : }
     148             : 
     149           0 : void SwXText::Invalidate()
     150             : {
     151           0 :     m_pImpl->m_bIsValid = false;
     152           0 : }
     153             : 
     154          32 : void SwXText::SetDoc(SwDoc *const pDoc)
     155             : {
     156             :     OSL_ENSURE(!m_pImpl->m_pDoc || !pDoc,
     157             :         "SwXText::SetDoc: already have a doc?");
     158          32 :     m_pImpl->m_pDoc = pDoc;
     159          32 :     m_pImpl->m_bIsValid = (0 != pDoc);
     160          32 : }
     161             : 
     162             : void
     163           0 : SwXText::PrepareForAttach(uno::Reference< text::XTextRange > &, const SwPaM &)
     164             : {
     165           0 : }
     166             : 
     167         467 : bool SwXText::CheckForOwnMemberMeta(const SwPaM &, const bool)
     168             :     throw (lang::IllegalArgumentException, uno::RuntimeException)
     169             : {
     170             :     OSL_ENSURE(CURSOR_META != m_pImpl->m_eType, "should not be called!");
     171         467 :     return false;
     172             : }
     173             : 
     174         978 : const SwStartNode *SwXText::GetStartNode() const
     175             : {
     176         978 :     return GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
     177             : }
     178             : 
     179             : uno::Reference< text::XTextCursor >
     180        1629 : SwXText::CreateCursor() throw (uno::RuntimeException)
     181             : {
     182        1629 :     uno::Reference< text::XTextCursor >  xRet;
     183        1629 :     if(IsValid())
     184             :     {
     185        1629 :         SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
     186        1629 :         SwPosition aPos(rNode);
     187             :         xRet = static_cast<text::XWordCursor*>(
     188        1629 :                 new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos));
     189        1629 :         xRet->gotoStart(sal_False);
     190             :     }
     191        1629 :     return xRet;
     192             : }
     193             : 
     194             : uno::Any SAL_CALL
     195        1491 : SwXText::queryInterface(const uno::Type& rType) throw (uno::RuntimeException)
     196             : {
     197        1491 :     uno::Any aRet;
     198        1491 :     if (rType == text::XText::static_type())
     199             :     {
     200          24 :         aRet <<= uno::Reference< text::XText >(this);
     201             :     }
     202        1467 :     else if (rType == text::XSimpleText::static_type())
     203             :     {
     204           0 :         aRet <<= uno::Reference< text::XSimpleText >(this);
     205             :     }
     206        1467 :     else if (rType == text::XTextRange::static_type())
     207             :     {
     208          16 :         aRet <<= uno::Reference< text::XTextRange>(this);
     209             :     }
     210        1451 :     else if (rType == text::XTextRangeCompare::static_type())
     211             :     {
     212           0 :         aRet <<= uno::Reference< text::XTextRangeCompare >(this);
     213             :     }
     214        1451 :     else if (rType == lang::XTypeProvider::static_type())
     215             :     {
     216           0 :         aRet <<= uno::Reference< lang::XTypeProvider >(this);
     217             :     }
     218        1451 :     else if (rType == text::XRelativeTextContentInsert::static_type())
     219             :     {
     220           0 :         aRet <<= uno::Reference< text::XRelativeTextContentInsert >(this);
     221             :     }
     222        1451 :     else if (rType == text::XRelativeTextContentRemove::static_type())
     223             :     {
     224           0 :         aRet <<= uno::Reference< text::XRelativeTextContentRemove >(this);
     225             :     }
     226        1451 :     else if (rType == beans::XPropertySet::static_type())
     227             :     {
     228          26 :         aRet <<= uno::Reference< beans::XPropertySet >(this);
     229             :     }
     230        1425 :     else if (rType == lang::XUnoTunnel::static_type())
     231             :     {
     232         197 :         aRet <<= uno::Reference< lang::XUnoTunnel >(this);
     233             :     }
     234        1228 :     else if (rType == text::XTextAppendAndConvert::static_type())
     235             :     {
     236         443 :         aRet <<= uno::Reference< text::XTextAppendAndConvert >(this);
     237             :     }
     238         785 :     else if (rType == text::XTextAppend::static_type())
     239             :     {
     240         255 :         aRet <<= uno::Reference< text::XTextAppend >(this);
     241             :     }
     242         530 :     else if (rType == text::XTextPortionAppend::static_type())
     243             :     {
     244           0 :         aRet <<= uno::Reference< text::XTextPortionAppend >(this);
     245             :     }
     246         530 :     else if (rType == text::XParagraphAppend::static_type())
     247             :     {
     248           0 :         aRet <<= uno::Reference< text::XParagraphAppend >(this);
     249             :     }
     250         530 :     else if (rType == text::XTextConvert::static_type() )
     251             :     {
     252           0 :         aRet <<= uno::Reference< text::XTextConvert >(this);
     253             :     }
     254         530 :     else if (rType == text::XTextContentAppend::static_type())
     255             :     {
     256           0 :         aRet <<= uno::Reference< text::XTextContentAppend >(this);
     257             :     }
     258         530 :     else if(rType == text::XTextCopy::static_type())
     259             :     {
     260           8 :         aRet <<= uno::Reference< text::XTextCopy >( this );
     261             :     }
     262        1491 :     return aRet;
     263             : }
     264             : 
     265             : uno::Sequence< uno::Type > SAL_CALL
     266           0 : SwXText::getTypes() throw (uno::RuntimeException)
     267             : {
     268           0 :     uno::Sequence< uno::Type > aRet(12);
     269           0 :     uno::Type* pTypes = aRet.getArray();
     270           0 :     pTypes[0] = text::XText::static_type();
     271           0 :     pTypes[1] = text::XTextRangeCompare::static_type();
     272           0 :     pTypes[2] = text::XRelativeTextContentInsert::static_type();
     273           0 :     pTypes[3] = text::XRelativeTextContentRemove::static_type();
     274           0 :     pTypes[4] = lang::XUnoTunnel::static_type();
     275           0 :     pTypes[5] = beans::XPropertySet::static_type();
     276           0 :     pTypes[6] = text::XTextPortionAppend::static_type();
     277           0 :     pTypes[7] = text::XParagraphAppend::static_type();
     278           0 :     pTypes[8] = text::XTextContentAppend::static_type();
     279           0 :     pTypes[9] = text::XTextConvert::static_type();
     280           0 :     pTypes[10] = text::XTextAppend::static_type();
     281           0 :     pTypes[11] = text::XTextAppendAndConvert::static_type();
     282             : 
     283           0 :     return aRet;
     284             : }
     285             : 
     286             : // belongs the range in the text ? insert it then.
     287             : void SAL_CALL
     288          80 : SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange,
     289             :     const OUString& rString, sal_Bool bAbsorb)
     290             : throw (uno::RuntimeException)
     291             : {
     292          80 :     SolarMutexGuard aGuard;
     293             : 
     294          80 :     if (!xTextRange.is())
     295             :     {
     296           0 :         throw uno::RuntimeException();
     297             :     }
     298          80 :     if (!GetDoc())
     299             :     {
     300           0 :         throw uno::RuntimeException();
     301             :     }
     302             :     const uno::Reference<lang::XUnoTunnel> xRangeTunnel(xTextRange,
     303          80 :             uno::UNO_QUERY);
     304             :     SwXTextRange *const pRange =
     305          80 :         ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
     306             :     OTextCursorHelper *const pCursor =
     307          80 :         ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
     308         160 :     if ((!pRange  || pRange ->GetDoc() != GetDoc()) &&
     309          80 :         (!pCursor || pCursor->GetDoc() != GetDoc()))
     310             :     {
     311           0 :         throw uno::RuntimeException();
     312             :     }
     313             : 
     314          80 :     const SwStartNode *const pOwnStartNode = GetStartNode();
     315          80 :     SwPaM aPam(GetDoc()->GetNodes());
     316          80 :     const SwPaM * pPam(0);
     317          80 :     if (pCursor)
     318             :     {
     319          80 :         pPam = pCursor->GetPaM();
     320             :     }
     321             :     else // pRange
     322             :     {
     323           0 :         if (pRange->GetPositions(aPam))
     324             :         {
     325           0 :             pPam = &aPam;
     326             :         }
     327             :     }
     328          80 :     if (!pPam)
     329             :     {
     330           0 :         throw uno::RuntimeException();
     331             :     }
     332             : 
     333          80 :     const SwStartNode* pTmp(pPam->GetNode()->StartOfSectionNode());
     334         163 :     while (pTmp && pTmp->IsSectionNode())
     335             :     {
     336           3 :         pTmp = pTmp->StartOfSectionNode();
     337             :     }
     338          80 :     if (!pOwnStartNode || (pOwnStartNode != pTmp))
     339             :     {
     340           0 :         throw uno::RuntimeException();
     341             :     }
     342             : 
     343          80 :     bool bForceExpandHints( false );
     344          80 :     if (CURSOR_META == m_pImpl->m_eType)
     345             :     {
     346             :         try
     347             :         {
     348           0 :             bForceExpandHints = CheckForOwnMemberMeta(*pPam, bAbsorb);
     349             :         }
     350           0 :         catch (const lang::IllegalArgumentException& iae)
     351             :         {
     352             :             // stupid method not allowed to throw iae
     353           0 :             throw uno::RuntimeException(iae.Message, 0);
     354             :         }
     355             :     }
     356          80 :     if (bAbsorb)
     357             :     {
     358             :         //!! scan for CR characters and inserting the paragraph breaks
     359             :         //!! has to be done in the called function.
     360             :         //!! Implemented in SwXTextRange::DeleteAndInsert
     361           3 :         if (pCursor)
     362             :         {
     363             :             SwXTextCursor * const pTextCursor(
     364           3 :                 dynamic_cast<SwXTextCursor*>(pCursor) );
     365           3 :             if (pTextCursor)
     366             :             {
     367           3 :                 pTextCursor->DeleteAndInsert(rString, bForceExpandHints);
     368             :             }
     369             :             else
     370             :             {
     371           0 :                 xTextRange->setString(rString);
     372             :             }
     373             :         }
     374             :         else
     375             :         {
     376           0 :             pRange->DeleteAndInsert(rString, bForceExpandHints);
     377             :         }
     378             :     }
     379             :     else
     380             :     {
     381             :         // create a PaM positioned before the parameter PaM,
     382             :         // so the text is inserted before
     383          77 :         UnoActionContext aContext(GetDoc());
     384          77 :         SwPaM aInsertPam(*pPam->Start());
     385          77 :         ::sw::GroupUndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
     386             :         SwUnoCursorHelper::DocInsertStringSplitCR(
     387          77 :             *GetDoc(), aInsertPam, rString, bForceExpandHints );
     388          80 :     }
     389          80 : }
     390             : 
     391             : void SAL_CALL
     392         209 : SwXText::insertControlCharacter(
     393             :         const uno::Reference< text::XTextRange > & xTextRange,
     394             :         sal_Int16 nControlCharacter, sal_Bool bAbsorb)
     395             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     396             : {
     397         209 :     SolarMutexGuard aGuard;
     398             : 
     399         209 :     if (!xTextRange.is())
     400             :     {
     401           0 :         throw lang::IllegalArgumentException();
     402             :     }
     403         209 :     if (!GetDoc())
     404             :     {
     405           0 :         throw uno::RuntimeException();
     406             :     }
     407             : 
     408         209 :     SwUnoInternalPaM aPam(*GetDoc());
     409         209 :     if (!::sw::XTextRangeToSwPaM(aPam, xTextRange))
     410             :     {
     411           0 :         throw uno::RuntimeException();
     412             :     }
     413         209 :     const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
     414             : 
     415             :     const enum IDocumentContentOperations::InsertFlags nInsertFlags =
     416             :         (bForceExpandHints)
     417             :         ? static_cast<IDocumentContentOperations::InsertFlags>(
     418             :                 IDocumentContentOperations::INS_FORCEHINTEXPAND |
     419             :                 IDocumentContentOperations::INS_EMPTYEXPAND)
     420         209 :         : IDocumentContentOperations::INS_EMPTYEXPAND;
     421             : 
     422         209 :     SwPaM aTmp(*aPam.Start());
     423         209 :     if (bAbsorb && aPam.HasMark())
     424             :     {
     425           0 :         m_pImpl->m_pDoc->DeleteAndJoin(aPam);
     426             :     }
     427             : 
     428         209 :     sal_Unicode cIns = 0;
     429         209 :     switch (nControlCharacter)
     430             :     {
     431             :         case text::ControlCharacter::PARAGRAPH_BREAK :
     432             :             // a table cell now becomes an ordinary text cell!
     433           0 :             m_pImpl->m_pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
     434           0 :             m_pImpl->m_pDoc->SplitNode( *aTmp.GetPoint(), sal_False );
     435           0 :             break;
     436             :         case text::ControlCharacter::APPEND_PARAGRAPH:
     437             :         {
     438         209 :             m_pImpl->m_pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
     439         209 :             m_pImpl->m_pDoc->AppendTxtNode( *aTmp.GetPoint() );
     440             : 
     441             :             const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
     442         209 :                     xTextRange, uno::UNO_QUERY);
     443             :             SwXTextRange *const pRange =
     444         209 :                 ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
     445             :             OTextCursorHelper *const pCursor =
     446             :                 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(
     447         209 :                             xRangeTunnel);
     448         209 :             if (pRange)
     449             :             {
     450           0 :                 pRange->SetPositions(aTmp);
     451             :             }
     452         209 :             else if (pCursor)
     453             :             {
     454         209 :                 SwPaM *const pCrsr = pCursor->GetPaM();
     455         209 :                 *pCrsr->GetPoint() = *aTmp.GetPoint();
     456         209 :                 pCrsr->DeleteMark();
     457         209 :             }
     458             :         }
     459         209 :         break;
     460           0 :         case text::ControlCharacter::LINE_BREAK:  cIns = 10;              break;
     461           0 :         case text::ControlCharacter::SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
     462           0 :         case text::ControlCharacter::HARD_HYPHEN: cIns = CHAR_HARDHYPHEN; break;
     463           0 :         case text::ControlCharacter::HARD_SPACE:  cIns = CHAR_HARDBLANK;  break;
     464             :     }
     465         209 :     if (cIns)
     466             :     {
     467           0 :         m_pImpl->m_pDoc->InsertString( aTmp, rtl::OUString(cIns), nInsertFlags );
     468             :     }
     469             : 
     470         209 :     if (bAbsorb)
     471             :     {
     472             :         const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
     473           0 :                 xTextRange, uno::UNO_QUERY);
     474             :         SwXTextRange *const pRange =
     475           0 :             ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
     476             :         OTextCursorHelper *const pCursor =
     477           0 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
     478             : 
     479           0 :         SwCursor aCrsr(*aTmp.GetPoint(),0,false);
     480           0 :         SwUnoCursorHelper::SelectPam(aCrsr, true);
     481           0 :         aCrsr.Left(1, CRSR_SKIP_CHARS, sal_False, sal_False);
     482             :         //hier muss der uebergebene PaM umgesetzt werden:
     483           0 :         if (pRange)
     484             :         {
     485           0 :             pRange->SetPositions(aCrsr);
     486             :         }
     487             :         else
     488             :         {
     489           0 :             SwPaM *const pUnoCrsr = pCursor->GetPaM();
     490           0 :             *pUnoCrsr->GetPoint() = *aCrsr.GetPoint();
     491           0 :             if (aCrsr.HasMark())
     492             :             {
     493           0 :                 pUnoCrsr->SetMark();
     494           0 :                 *pUnoCrsr->GetMark() = *aCrsr.GetMark();
     495             :             }
     496             :             else
     497             :             {
     498           0 :                 pUnoCrsr->DeleteMark();
     499             :             }
     500           0 :         }
     501         209 :     }
     502         209 : }
     503             : 
     504             : void SAL_CALL
     505         258 : SwXText::insertTextContent(
     506             :         const uno::Reference< text::XTextRange > & xRange,
     507             :         const uno::Reference< text::XTextContent > & xContent,
     508             :         sal_Bool bAbsorb)
     509             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     510             : {
     511         258 :     SolarMutexGuard aGuard;
     512             : 
     513         258 :     if (!xRange.is())
     514             :     {
     515           0 :         lang::IllegalArgumentException aIllegal;
     516           0 :         aIllegal.Message = C2U("first parameter invalid;");
     517           0 :         throw aIllegal;
     518             :     }
     519         258 :     if (!xContent.is())
     520             :     {
     521           0 :         lang::IllegalArgumentException aIllegal;
     522           0 :         aIllegal.Message += C2U("second parameter invalid");
     523           0 :         throw aIllegal;
     524             :     }
     525         258 :     if(!GetDoc())
     526             :     {
     527           0 :         uno::RuntimeException aRuntime;
     528           0 :         aRuntime.Message = C2U(cInvalidObject);
     529           0 :         throw aRuntime;
     530             :     }
     531             : 
     532         258 :     SwUnoInternalPaM aPam(*GetDoc());
     533         258 :     if (!::sw::XTextRangeToSwPaM(aPam, xRange))
     534             :     {
     535           0 :         lang::IllegalArgumentException aIllegal;
     536           0 :         aIllegal.Message = C2U("first parameter invalid");
     537           0 :         throw aIllegal;
     538             :     }
     539             :     // first test if the range is at the right position, then call
     540             :     // xContent->attach
     541         258 :     const SwStartNode* pOwnStartNode = GetStartNode();
     542         258 :     SwStartNodeType eSearchNodeType = SwNormalStartNode;
     543         258 :     switch (m_pImpl->m_eType)
     544             :     {
     545           0 :         case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
     546           0 :         case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
     547           0 :         case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
     548           6 :         case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
     549           5 :         case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
     550             :         //case CURSOR_INVALID:
     551             :         //case CURSOR_BODY:
     552             :         default:
     553         247 :             break;
     554             :     }
     555             : 
     556             :     const SwStartNode* pTmp =
     557         258 :         aPam.GetNode()->FindSttNodeByType(eSearchNodeType);
     558             : 
     559             :     // ignore SectionNodes
     560         516 :     while (pTmp && pTmp->IsSectionNode())
     561             :     {
     562           0 :         pTmp = pTmp->StartOfSectionNode();
     563             :     }
     564             :     // if the document starts with a section
     565         516 :     while (pOwnStartNode->IsSectionNode())
     566             :     {
     567           0 :         pOwnStartNode = pOwnStartNode->StartOfSectionNode();
     568             :     }
     569             :     // this checks if (this) and xRange are in the same text::XText interface
     570         258 :     if (pOwnStartNode != pTmp)
     571             :     {
     572           0 :         uno::RuntimeException aRunException;
     573           0 :         aRunException.Message = C2U("text interface and cursor not related");
     574           0 :         throw aRunException;
     575             :     }
     576             : 
     577         258 :     const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
     578             : 
     579             :     // special treatment for Contents that do not replace the range, but
     580             :     // instead are "overlaid"
     581             :     const uno::Reference<lang::XUnoTunnel> xContentTunnel(xContent,
     582         258 :             uno::UNO_QUERY);
     583         258 :     if (!xContentTunnel.is())
     584             :     {
     585           0 :         lang::IllegalArgumentException aArgException;
     586             :         aArgException.Message =
     587           0 :             C2U("text content does not support lang::XUnoTunnel");
     588           0 :         throw aArgException;
     589             :     }
     590             :     SwXDocumentIndexMark *const pDocumentIndexMark =
     591         258 :         ::sw::UnoTunnelGetImplementation<SwXDocumentIndexMark>(xContentTunnel);
     592             :     SwXTextSection *const pSection =
     593         258 :         ::sw::UnoTunnelGetImplementation<SwXTextSection>(xContentTunnel);
     594             :     SwXBookmark *const pBookmark =
     595         258 :         ::sw::UnoTunnelGetImplementation<SwXBookmark>(xContentTunnel);
     596             :     SwXReferenceMark *const pReferenceMark =
     597         258 :         ::sw::UnoTunnelGetImplementation<SwXReferenceMark>(xContentTunnel);
     598             :     SwXMeta *const pMeta =
     599         258 :         ::sw::UnoTunnelGetImplementation<SwXMeta>(xContentTunnel);
     600             :     SwXTextField* pTextField =
     601         258 :         ::sw::UnoTunnelGetImplementation<SwXTextField>(xContentTunnel);
     602         258 :     if (pTextField && pTextField->GetServiceId() != SW_SERVICE_FIELDTYPE_ANNOTATION)
     603           7 :         pTextField = 0;
     604             : 
     605             :     const bool bAttribute = pBookmark || pDocumentIndexMark
     606         258 :         || pSection || pReferenceMark || pMeta || pTextField;
     607             : 
     608         258 :     if (bAbsorb && !bAttribute)
     609             :     {
     610           0 :         xRange->setString(aEmptyStr);
     611             :     }
     612             :     uno::Reference< text::XTextRange > xTempRange =
     613         258 :         (bAttribute && bAbsorb) ? xRange : xRange->getStart();
     614         258 :     if (bForceExpandHints)
     615             :     {
     616             :         // if necessary, replace xTempRange with a new SwXTextCursor
     617           0 :         PrepareForAttach(xTempRange, aPam);
     618             :     }
     619         290 :     xContent->attach(xTempRange);
     620         226 : }
     621             : 
     622             : void SAL_CALL
     623           0 : SwXText::insertTextContentBefore(
     624             :     const uno::Reference< text::XTextContent>& xNewContent,
     625             :     const uno::Reference< text::XTextContent>& xSuccessor)
     626             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     627             : {
     628           0 :     SolarMutexGuard aGuard;
     629             : 
     630           0 :     if(!GetDoc())
     631             :     {
     632           0 :         uno::RuntimeException aRuntime;
     633           0 :         aRuntime.Message = C2U(cInvalidObject);
     634           0 :         throw aRuntime;
     635             :     }
     636             : 
     637             :     const uno::Reference<lang::XUnoTunnel> xParaTunnel(xNewContent,
     638           0 :             uno::UNO_QUERY);
     639             :     SwXParagraph *const pPara =
     640           0 :             ::sw::UnoTunnelGetImplementation<SwXParagraph>(xParaTunnel);
     641           0 :     if (!pPara || !pPara->IsDescriptor() || !xSuccessor.is())
     642             :     {
     643           0 :         throw lang::IllegalArgumentException();
     644             :     }
     645             : 
     646           0 :     sal_Bool bRet = sal_False;
     647             :     const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
     648           0 :             uno::UNO_QUERY);
     649             :     SwXTextSection *const pXSection =
     650           0 :             ::sw::UnoTunnelGetImplementation<SwXTextSection>(xSuccTunnel);
     651             :     SwXTextTable *const pXTable =
     652           0 :             ::sw::UnoTunnelGetImplementation<SwXTextTable>(xSuccTunnel);
     653           0 :     SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
     654           0 :     SwTxtNode * pTxtNode = 0;
     655           0 :     if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
     656             :     {
     657           0 :         SwTable *const pTable = SwTable::FindTable( pTableFmt );
     658           0 :         SwTableNode *const pTblNode = pTable->GetTableNode();
     659             : 
     660           0 :         const SwNodeIndex aTblIdx( *pTblNode, -1 );
     661           0 :         SwPosition aBefore(aTblIdx);
     662           0 :         bRet = GetDoc()->AppendTxtNode( aBefore );
     663           0 :         pTxtNode = aBefore.nNode.GetNode().GetTxtNode();
     664             :     }
     665           0 :     else if (pXSection && pXSection->GetFmt() &&
     666           0 :             pXSection->GetFmt()->GetDoc() == GetDoc())
     667             :     {
     668           0 :         SwSectionFmt *const pSectFmt = pXSection->GetFmt();
     669           0 :         SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
     670             : 
     671           0 :         const SwNodeIndex aSectIdx( *pSectNode, -1 );
     672           0 :         SwPosition aBefore(aSectIdx);
     673           0 :         bRet = GetDoc()->AppendTxtNode( aBefore );
     674           0 :         pTxtNode = aBefore.nNode.GetNode().GetTxtNode();
     675             :     }
     676           0 :     if (!bRet || !pTxtNode)
     677             :     {
     678           0 :         throw lang::IllegalArgumentException();
     679             :     }
     680           0 :     pPara->attachToText(*this, *pTxtNode);
     681           0 : }
     682             : 
     683             : void SAL_CALL
     684           0 : SwXText::insertTextContentAfter(
     685             :     const uno::Reference< text::XTextContent>& xNewContent,
     686             :     const uno::Reference< text::XTextContent>& xPredecessor)
     687             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     688             : {
     689           0 :     SolarMutexGuard aGuard;
     690             : 
     691           0 :     if(!GetDoc())
     692             :     {
     693           0 :         throw uno::RuntimeException();
     694             :     }
     695             : 
     696             :     const uno::Reference<lang::XUnoTunnel> xParaTunnel(xNewContent,
     697           0 :             uno::UNO_QUERY);
     698             :     SwXParagraph *const pPara =
     699           0 :             ::sw::UnoTunnelGetImplementation<SwXParagraph>(xParaTunnel);
     700           0 :     if(!pPara || !pPara->IsDescriptor() || !xPredecessor.is())
     701             :     {
     702           0 :         throw lang::IllegalArgumentException();
     703             :     }
     704             : 
     705             :     const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
     706           0 :             uno::UNO_QUERY);
     707             :     SwXTextSection *const pXSection =
     708           0 :             ::sw::UnoTunnelGetImplementation<SwXTextSection>(xPredTunnel);
     709             :     SwXTextTable *const pXTable =
     710           0 :             ::sw::UnoTunnelGetImplementation<SwXTextTable>(xPredTunnel);
     711           0 :     SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
     712           0 :     sal_Bool bRet = sal_False;
     713           0 :     SwTxtNode * pTxtNode = 0;
     714           0 :     if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
     715             :     {
     716           0 :         SwTable *const pTable = SwTable::FindTable( pTableFmt );
     717           0 :         SwTableNode *const pTblNode = pTable->GetTableNode();
     718             : 
     719           0 :         SwEndNode *const pTableEnd = pTblNode->EndOfSectionNode();
     720           0 :         SwPosition aTableEnd(*pTableEnd);
     721           0 :         bRet = GetDoc()->AppendTxtNode( aTableEnd );
     722           0 :         pTxtNode = aTableEnd.nNode.GetNode().GetTxtNode();
     723             :     }
     724           0 :     else if (pXSection && pXSection->GetFmt() &&
     725           0 :             pXSection->GetFmt()->GetDoc() == GetDoc())
     726             :     {
     727           0 :         SwSectionFmt *const pSectFmt = pXSection->GetFmt();
     728           0 :         SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
     729           0 :         SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
     730           0 :         SwPosition aEnd(*pEnd);
     731           0 :         bRet = GetDoc()->AppendTxtNode( aEnd );
     732           0 :         pTxtNode = aEnd.nNode.GetNode().GetTxtNode();
     733             :     }
     734           0 :     if (!bRet || !pTxtNode)
     735             :     {
     736           0 :         throw lang::IllegalArgumentException();
     737             :     }
     738           0 :     pPara->attachToText(*this, *pTxtNode);
     739           0 : }
     740             : 
     741             : void SAL_CALL
     742           0 : SwXText::removeTextContentBefore(
     743             :     const uno::Reference< text::XTextContent>& xSuccessor)
     744             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     745             : {
     746           0 :     SolarMutexGuard aGuard;
     747             : 
     748           0 :     if(!GetDoc())
     749             :     {
     750           0 :         uno::RuntimeException aRuntime;
     751           0 :         aRuntime.Message = C2U(cInvalidObject);
     752           0 :         throw aRuntime;
     753             :     }
     754             : 
     755           0 :     sal_Bool bRet = sal_False;
     756             :     const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
     757           0 :             uno::UNO_QUERY);
     758             :     SwXTextSection *const pXSection =
     759           0 :             ::sw::UnoTunnelGetImplementation<SwXTextSection>(xSuccTunnel);
     760             :     SwXTextTable *const pXTable =
     761           0 :             ::sw::UnoTunnelGetImplementation<SwXTextTable>(xSuccTunnel);
     762           0 :     SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
     763           0 :     if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
     764             :     {
     765           0 :         SwTable *const pTable = SwTable::FindTable( pTableFmt );
     766           0 :         SwTableNode *const pTblNode = pTable->GetTableNode();
     767             : 
     768           0 :         const SwNodeIndex aTblIdx( *pTblNode, -1 );
     769           0 :         if(aTblIdx.GetNode().IsTxtNode())
     770             :         {
     771           0 :             SwPaM aBefore(aTblIdx);
     772           0 :             bRet = GetDoc()->DelFullPara( aBefore );
     773           0 :         }
     774             :     }
     775           0 :     else if (pXSection && pXSection->GetFmt() &&
     776           0 :             pXSection->GetFmt()->GetDoc() == GetDoc())
     777             :     {
     778           0 :         SwSectionFmt *const pSectFmt = pXSection->GetFmt();
     779           0 :         SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
     780             : 
     781           0 :         const SwNodeIndex aSectIdx(  *pSectNode, -1 );
     782           0 :         if(aSectIdx.GetNode().IsTxtNode())
     783             :         {
     784           0 :             SwPaM aBefore(aSectIdx);
     785           0 :             bRet = GetDoc()->DelFullPara( aBefore );
     786           0 :         }
     787             :     }
     788           0 :     if(!bRet)
     789             :     {
     790           0 :         throw lang::IllegalArgumentException();
     791           0 :     }
     792           0 : }
     793             : 
     794             : void SAL_CALL
     795           0 : SwXText::removeTextContentAfter(
     796             :         const uno::Reference< text::XTextContent>& xPredecessor)
     797             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     798             : {
     799           0 :     SolarMutexGuard aGuard;
     800             : 
     801           0 :     if(!GetDoc())
     802             :     {
     803           0 :         uno::RuntimeException aRuntime;
     804           0 :         aRuntime.Message = C2U(cInvalidObject);
     805           0 :         throw aRuntime;
     806             :     }
     807             : 
     808           0 :     sal_Bool bRet = sal_False;
     809             :     const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
     810           0 :             uno::UNO_QUERY);
     811             :     SwXTextSection *const pXSection =
     812           0 :             ::sw::UnoTunnelGetImplementation<SwXTextSection>(xPredTunnel);
     813             :     SwXTextTable *const pXTable =
     814           0 :             ::sw::UnoTunnelGetImplementation<SwXTextTable>(xPredTunnel);
     815           0 :     SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
     816           0 :     if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
     817             :     {
     818           0 :         SwTable *const pTable = SwTable::FindTable( pTableFmt );
     819           0 :         SwTableNode *const pTblNode = pTable->GetTableNode();
     820           0 :         SwEndNode *const pTableEnd = pTblNode->EndOfSectionNode();
     821             : 
     822           0 :         const SwNodeIndex aTblIdx( *pTableEnd, 1 );
     823           0 :         if(aTblIdx.GetNode().IsTxtNode())
     824             :         {
     825           0 :             SwPaM aPaM(aTblIdx);
     826           0 :             bRet = GetDoc()->DelFullPara( aPaM );
     827           0 :         }
     828             :     }
     829           0 :     else if (pXSection && pXSection->GetFmt() &&
     830           0 :             pXSection->GetFmt()->GetDoc() == GetDoc())
     831             :     {
     832           0 :         SwSectionFmt *const pSectFmt = pXSection->GetFmt();
     833           0 :         SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
     834           0 :         SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
     835           0 :         const SwNodeIndex aSectIdx(  *pEnd, 1 );
     836           0 :         if(aSectIdx.GetNode().IsTxtNode())
     837             :         {
     838           0 :             SwPaM aAfter(aSectIdx);
     839           0 :             bRet = GetDoc()->DelFullPara( aAfter );
     840           0 :         }
     841             :     }
     842           0 :     if(!bRet)
     843             :     {
     844           0 :         throw lang::IllegalArgumentException();
     845           0 :     }
     846           0 : }
     847             : 
     848             : void SAL_CALL
     849           0 : SwXText::removeTextContent(
     850             :         const uno::Reference< text::XTextContent > & xContent)
     851             : throw (container::NoSuchElementException, uno::RuntimeException)
     852             : {
     853             :     // forward: need no solar mutex here
     854           0 :     if(!xContent.is())
     855             :     {
     856           0 :         uno::RuntimeException aRuntime;
     857           0 :         aRuntime.Message = C2U("first parameter invalid");
     858           0 :         throw aRuntime;
     859             :     }
     860           0 :     xContent->dispose();
     861           0 : }
     862             : 
     863             : uno::Reference< text::XText > SAL_CALL
     864           2 : SwXText::getText() throw (uno::RuntimeException)
     865             : {
     866           2 :     SolarMutexGuard aGuard;
     867             : 
     868           2 :     const uno::Reference< text::XText > xRet(this);
     869           2 :     return xRet;
     870             : }
     871             : 
     872             : uno::Reference< text::XTextRange > SAL_CALL
     873           7 : SwXText::getStart() throw (uno::RuntimeException)
     874             : {
     875           7 :     SolarMutexGuard aGuard;
     876             : 
     877           7 :     const uno::Reference< text::XTextCursor > xRef = CreateCursor();
     878           7 :     if(!xRef.is())
     879             :     {
     880           0 :         uno::RuntimeException aRuntime;
     881           0 :         aRuntime.Message = C2U(cInvalidObject);
     882           0 :         throw aRuntime;
     883             :     }
     884           7 :     xRef->gotoStart(sal_False);
     885           7 :     const uno::Reference< text::XTextRange > xRet(xRef, uno::UNO_QUERY);
     886           7 :     return xRet;
     887             : }
     888             : 
     889             : uno::Reference< text::XTextRange > SAL_CALL
     890        1110 : SwXText::getEnd() throw (uno::RuntimeException)
     891             : {
     892        1110 :     SolarMutexGuard aGuard;
     893             : 
     894        1110 :     const uno::Reference< text::XTextCursor > xRef = CreateCursor();
     895        1110 :     if(!xRef.is())
     896             :     {
     897           0 :         uno::RuntimeException aRuntime;
     898           0 :         aRuntime.Message = C2U(cInvalidObject);
     899           0 :         throw aRuntime;
     900             :     }
     901        1110 :     xRef->gotoEnd(sal_False);
     902        1110 :     const uno::Reference< text::XTextRange >  xRet(xRef, uno::UNO_QUERY);
     903        1110 :     return xRet;
     904             : }
     905             : 
     906           7 : OUString SAL_CALL SwXText::getString() throw (uno::RuntimeException)
     907             : {
     908           7 :     SolarMutexGuard aGuard;
     909             : 
     910           7 :     const uno::Reference< text::XTextCursor > xRet = CreateCursor();
     911           7 :     if(!xRet.is())
     912             :     {
     913           0 :         uno::RuntimeException aRuntime;
     914           0 :         aRuntime.Message = C2U(cInvalidObject);
     915           0 :         throw aRuntime;
     916             :     }
     917           7 :     xRet->gotoEnd(sal_True);
     918           7 :     return xRet->getString();
     919             : }
     920             : 
     921             : void SAL_CALL
     922          17 : SwXText::setString(const OUString& rString) throw (uno::RuntimeException)
     923             : {
     924          17 :     SolarMutexGuard aGuard;
     925             : 
     926          17 :     if (!GetDoc())
     927             :     {
     928           0 :         uno::RuntimeException aRuntime;
     929           0 :         aRuntime.Message = C2U(cInvalidObject);
     930           0 :         throw aRuntime;
     931             :     }
     932             : 
     933          17 :     const SwStartNode* pStartNode = GetStartNode();
     934          17 :     if (!pStartNode)
     935             :     {
     936           0 :         throw uno::RuntimeException();
     937             :     }
     938             : 
     939          17 :     GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_START, NULL);
     940             :     //insert an empty paragraph at the start and at the end to ensure that
     941             :     //all tables and sections can be removed by the selecting text::XTextCursor
     942          17 :     if (CURSOR_META != m_pImpl->m_eType)
     943             :     {
     944          17 :         SwPosition aStartPos(*pStartNode);
     945          17 :         const SwEndNode* pEnd = pStartNode->EndOfSectionNode();
     946          17 :         SwNodeIndex aEndIdx(*pEnd);
     947          17 :         aEndIdx--;
     948             :         //the inserting of nodes should only be done if really necessary
     949             :         //to prevent #97924# (removes paragraph attributes when setting the text
     950             :         //e.g. of a table cell
     951          17 :         bool bInsertNodes = false;
     952          17 :         SwNodeIndex aStartIdx(*pStartNode);
     953          17 :         do
     954             :         {
     955          17 :             ++aStartIdx;
     956          17 :             SwNode& rCurrentNode = aStartIdx.GetNode();
     957          34 :             if(rCurrentNode.GetNodeType() == ND_SECTIONNODE
     958          17 :                 ||rCurrentNode.GetNodeType() == ND_TABLENODE)
     959             :             {
     960           0 :                 bInsertNodes = true;
     961           0 :                 break;
     962             :             }
     963             :         }
     964          17 :         while(aStartIdx < aEndIdx);
     965          17 :         if(bInsertNodes)
     966             :         {
     967           0 :             GetDoc()->AppendTxtNode( aStartPos );
     968           0 :             SwPosition aEndPos(aEndIdx.GetNode());
     969           0 :             SwPaM aPam(aEndPos);
     970           0 :             GetDoc()->AppendTxtNode( *aPam.Start() );
     971          17 :         }
     972             :     }
     973             : 
     974          17 :     const uno::Reference< text::XTextCursor > xRet = CreateCursor();
     975          17 :     if(!xRet.is())
     976             :     {
     977           0 :         GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
     978           0 :         uno::RuntimeException aRuntime;
     979           0 :         aRuntime.Message = C2U(cInvalidObject);
     980           0 :         throw aRuntime;
     981             :     }
     982          17 :     xRet->gotoEnd(sal_True);
     983          17 :     xRet->setString(rString);
     984          17 :     GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
     985          17 : }
     986             : 
     987             : //FIXME why is CheckForOwnMember duplicated in some insert methods?
     988             : //  Description: Checks if pRange/pCursor are member of the same text interface.
     989             : //              Only one of the pointers has to be set!
     990           0 : bool SwXText::Impl::CheckForOwnMember(
     991             :     const SwPaM & rPaM)
     992             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     993             : {
     994           0 :     const uno::Reference<text::XTextCursor> xOwnCursor(m_rThis.CreateCursor());
     995             : 
     996           0 :     const uno::Reference<lang::XUnoTunnel> xTunnel(xOwnCursor, uno::UNO_QUERY);
     997             :     OTextCursorHelper *const pOwnCursor =
     998           0 :             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xTunnel);
     999             :     OSL_ENSURE(pOwnCursor, "OTextCursorHelper::getUnoTunnelId() ??? ");
    1000             :     const SwStartNode* pOwnStartNode =
    1001           0 :         pOwnCursor->GetPaM()->GetNode()->StartOfSectionNode();
    1002           0 :     SwStartNodeType eSearchNodeType = SwNormalStartNode;
    1003           0 :     switch (m_eType)
    1004             :     {
    1005           0 :         case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
    1006           0 :         case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
    1007           0 :         case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
    1008           0 :         case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
    1009           0 :         case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
    1010             :         //case CURSOR_INVALID:
    1011             :         //case CURSOR_BODY:
    1012             :         default:
    1013             :             ;
    1014             :     }
    1015             : 
    1016           0 :     SwNode const*const pSrcNode(rPaM.GetNode());
    1017           0 :     if (!pSrcNode) { return false; }
    1018           0 :     const SwStartNode* pTmp = pSrcNode->FindSttNodeByType(eSearchNodeType);
    1019             : 
    1020             :     //SectionNodes ueberspringen
    1021           0 :     while(pTmp && pTmp->IsSectionNode())
    1022             :     {
    1023           0 :         pTmp = pTmp->StartOfSectionNode();
    1024             :     }
    1025             : 
    1026             :     //if the document starts with a section
    1027           0 :     while(pOwnStartNode->IsSectionNode())
    1028             :     {
    1029           0 :         pOwnStartNode = pOwnStartNode->StartOfSectionNode();
    1030             :     }
    1031             : 
    1032             :     //this checks if (this) and xRange are in the same text::XText interface
    1033           0 :     return (pOwnStartNode == pTmp);
    1034             : }
    1035             : 
    1036             : sal_Int16
    1037           0 : SwXText::Impl::ComparePositions(
    1038             :     const uno::Reference<text::XTextRange>& xPos1,
    1039             :     const uno::Reference<text::XTextRange>& xPos2)
    1040             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1041             : {
    1042           0 :     SwUnoInternalPaM aPam1(*m_pDoc);
    1043           0 :     SwUnoInternalPaM aPam2(*m_pDoc);
    1044             : 
    1045           0 :     if (!::sw::XTextRangeToSwPaM(aPam1, xPos1) ||
    1046           0 :         !::sw::XTextRangeToSwPaM(aPam2, xPos2))
    1047             :     {
    1048           0 :         throw lang::IllegalArgumentException();
    1049             :     }
    1050           0 :     if (!CheckForOwnMember(aPam1) || !CheckForOwnMember(aPam2))
    1051             :     {
    1052           0 :         throw lang::IllegalArgumentException();
    1053             :     }
    1054             : 
    1055           0 :     sal_Int16 nCompare = 0;
    1056           0 :     SwPosition const*const pStart1 = aPam1.Start();
    1057           0 :     SwPosition const*const pStart2 = aPam2.Start();
    1058           0 :     if (*pStart1 < *pStart2)
    1059             :     {
    1060           0 :         nCompare = 1;
    1061             :     }
    1062           0 :     else if (*pStart1 > *pStart2)
    1063             :     {
    1064           0 :         nCompare = -1;
    1065             :     }
    1066             :     else
    1067             :     {
    1068             :         OSL_ENSURE(*pStart1 == *pStart2,
    1069             :                 "SwPositions should be equal here");
    1070           0 :         nCompare = 0;
    1071             :     }
    1072             : 
    1073           0 :     return nCompare;
    1074             : }
    1075             : 
    1076             : sal_Int16 SAL_CALL
    1077           0 : SwXText::compareRegionStarts(
    1078             :     const uno::Reference<text::XTextRange>& xRange1,
    1079             :     const uno::Reference<text::XTextRange>& xRange2)
    1080             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1081             : {
    1082           0 :     SolarMutexGuard aGuard;
    1083             : 
    1084           0 :     if (!xRange1.is() || !xRange2.is())
    1085             :     {
    1086           0 :         throw lang::IllegalArgumentException();
    1087             :     }
    1088           0 :     const uno::Reference<text::XTextRange> xStart1 = xRange1->getStart();
    1089           0 :     const uno::Reference<text::XTextRange> xStart2 = xRange2->getStart();
    1090             : 
    1091           0 :     return m_pImpl->ComparePositions(xStart1, xStart2);
    1092             : }
    1093             : 
    1094             : sal_Int16 SAL_CALL
    1095           0 : SwXText::compareRegionEnds(
    1096             :     const uno::Reference<text::XTextRange>& xRange1,
    1097             :     const uno::Reference<text::XTextRange>& xRange2)
    1098             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1099             : {
    1100           0 :     SolarMutexGuard aGuard;
    1101             : 
    1102           0 :     if (!xRange1.is() || !xRange2.is())
    1103             :     {
    1104           0 :         throw lang::IllegalArgumentException();
    1105             :     }
    1106           0 :     uno::Reference<text::XTextRange> xEnd1 = xRange1->getEnd();
    1107           0 :     uno::Reference<text::XTextRange> xEnd2 = xRange2->getEnd();
    1108             : 
    1109           0 :     return m_pImpl->ComparePositions(xEnd1, xEnd2);
    1110             : }
    1111             : 
    1112             : uno::Reference< beans::XPropertySetInfo > SAL_CALL
    1113          26 : SwXText::getPropertySetInfo() throw(uno::RuntimeException)
    1114             : {
    1115          26 :     SolarMutexGuard g;
    1116             : 
    1117             :     static uno::Reference< beans::XPropertySetInfo > xInfo =
    1118          26 :         m_pImpl->m_rPropSet.getPropertySetInfo();
    1119          26 :     return xInfo;
    1120             : }
    1121             : 
    1122             : void SAL_CALL
    1123           0 : SwXText::setPropertyValue(const ::rtl::OUString& /*aPropertyName*/,
    1124             :         const uno::Any& /*aValue*/)
    1125             : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
    1126             :     lang::IllegalArgumentException, lang::WrappedTargetException,
    1127             :     uno::RuntimeException)
    1128             : {
    1129           0 :     throw lang::IllegalArgumentException();
    1130             : }
    1131             : 
    1132             : uno::Any SAL_CALL
    1133          28 : SwXText::getPropertyValue(
    1134             :     const ::rtl::OUString& rPropertyName)
    1135             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1136             :         uno::RuntimeException)
    1137             : {
    1138          28 :     SolarMutexGuard aGuard;
    1139             : 
    1140          28 :     if(!IsValid())
    1141             :     {
    1142           0 :         throw  uno::RuntimeException();
    1143             :     }
    1144             : 
    1145             :     SfxItemPropertySimpleEntry const*const pEntry =
    1146          28 :         m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
    1147          28 :     if (!pEntry)
    1148             :     {
    1149           0 :         beans::UnknownPropertyException aExcept;
    1150           0 :         aExcept.Message = C2U("Unknown property: ");
    1151           0 :         aExcept.Message += rPropertyName;
    1152           0 :         throw aExcept;
    1153             :     }
    1154             : 
    1155          28 :     uno::Any aRet;
    1156          28 :     switch (pEntry->nWID)
    1157             :     {
    1158             : //          no code necessary - the redline is always located at the end node
    1159             : //            case FN_UNO_REDLINE_NODE_START:
    1160             : //            break;
    1161             :         case FN_UNO_REDLINE_NODE_END:
    1162             :         {
    1163          14 :             const SwRedlineTbl& rRedTbl = GetDoc()->GetRedlineTbl();
    1164          14 :             const sal_uInt16 nRedTblCount = rRedTbl.size();
    1165          14 :             if (nRedTblCount > 0)
    1166             :             {
    1167           0 :                 SwStartNode const*const pStartNode = GetStartNode();
    1168           0 :                 const sal_uLong nOwnIndex = pStartNode->EndOfSectionIndex();
    1169           0 :                 for (sal_uInt16 nRed = 0; nRed < nRedTblCount; nRed++)
    1170             :                 {
    1171           0 :                     SwRedline const*const pRedline = rRedTbl[nRed];
    1172           0 :                     SwPosition const*const pRedStart = pRedline->Start();
    1173           0 :                     const SwNodeIndex nRedNode = pRedStart->nNode;
    1174           0 :                     if (nOwnIndex == nRedNode.GetIndex())
    1175             :                     {
    1176             :                         aRet <<= SwXRedlinePortion::CreateRedlineProperties(
    1177           0 :                                 *pRedline, sal_True);
    1178             :                         break;
    1179             :                     }
    1180           0 :                 }
    1181             :             }
    1182             :         }
    1183          14 :         break;
    1184             :     }
    1185          28 :     return aRet;
    1186             : }
    1187             : 
    1188             : void SAL_CALL
    1189           0 : SwXText::addPropertyChangeListener(
    1190             :         const ::rtl::OUString& /*rPropertyName*/,
    1191             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    1192             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1193             :     uno::RuntimeException)
    1194             : {
    1195             :     OSL_FAIL("SwXText::addPropertyChangeListener(): not implemented");
    1196           0 : }
    1197             : 
    1198             : void SAL_CALL
    1199           0 : SwXText::removePropertyChangeListener(
    1200             :         const ::rtl::OUString& /*rPropertyName*/,
    1201             :         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
    1202             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1203             :     uno::RuntimeException)
    1204             : {
    1205             :     OSL_FAIL("SwXText::removePropertyChangeListener(): not implemented");
    1206           0 : }
    1207             : 
    1208             : void SAL_CALL
    1209           0 : SwXText::addVetoableChangeListener(
    1210             :         const ::rtl::OUString& /*rPropertyName*/,
    1211             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    1212             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1213             :     uno::RuntimeException)
    1214             : {
    1215             :     OSL_FAIL("SwXText::addVetoableChangeListener(): not implemented");
    1216           0 : }
    1217             : 
    1218             : void SAL_CALL
    1219           0 : SwXText::removeVetoableChangeListener(
    1220             :         const ::rtl::OUString& /*rPropertyName*/,
    1221             :         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
    1222             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1223             :         uno::RuntimeException)
    1224             : {
    1225             :     OSL_FAIL("SwXText::removeVetoableChangeListener(): not implemented");
    1226           0 : }
    1227             : 
    1228             : namespace
    1229             : {
    1230             :     class theSwXTextUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextUnoTunnelId > {};
    1231             : }
    1232             : 
    1233        2365 : const uno::Sequence< sal_Int8 > & SwXText::getUnoTunnelId()
    1234             : {
    1235        2365 :     return theSwXTextUnoTunnelId::get().getSeq();
    1236             : }
    1237             : 
    1238             : sal_Int64 SAL_CALL
    1239         381 : SwXText::getSomething(const uno::Sequence< sal_Int8 >& rId)
    1240             : throw (uno::RuntimeException)
    1241             : {
    1242         381 :     return ::sw::UnoTunnelImpl<SwXText>(rId, this);
    1243             : }
    1244             : 
    1245             : uno::Reference< text::XTextRange > SAL_CALL
    1246         731 : SwXText::finishParagraph(
    1247             :         const uno::Sequence< beans::PropertyValue > & rProperties)
    1248             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1249             : {
    1250         731 :     SolarMutexGuard g;
    1251             : 
    1252         731 :     return m_pImpl->finishOrAppendParagraph(true, rProperties, uno::Reference< text::XTextRange >());
    1253             : }
    1254             : 
    1255             : uno::Reference< text::XTextRange > SAL_CALL
    1256           0 : SwXText::finishParagraphInsert(
    1257             :         const uno::Sequence< beans::PropertyValue > & rProperties,
    1258             :         const uno::Reference< text::XTextRange >& xInsertPosition)
    1259             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1260             : {
    1261           0 :     SolarMutexGuard g;
    1262             : 
    1263           0 :     return m_pImpl->finishOrAppendParagraph(true, rProperties, xInsertPosition);
    1264             : }
    1265             : 
    1266             : uno::Reference< text::XTextRange >
    1267         731 : SwXText::Impl::finishOrAppendParagraph(
    1268             :         const bool bFinish,
    1269             :         const uno::Sequence< beans::PropertyValue > & rProperties,
    1270             :         const uno::Reference< text::XTextRange >& xInsertPosition)
    1271             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1272             : {
    1273         731 :     if (!m_bIsValid)
    1274             :     {
    1275           0 :         throw  uno::RuntimeException();
    1276             :     }
    1277             : 
    1278         731 :     const SwStartNode* pStartNode = m_rThis.GetStartNode();
    1279         731 :     if(!pStartNode)
    1280             :     {
    1281           0 :         throw  uno::RuntimeException();
    1282             :     }
    1283             : 
    1284         731 :     uno::Reference< text::XTextRange > xRet;
    1285         731 :     bool bIllegalException = false;
    1286         731 :     bool bRuntimeException = false;
    1287         731 :     ::rtl::OUString sMessage;
    1288         731 :     m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_START , NULL);
    1289             :     // find end node, go backward - don't skip tables because the new
    1290             :     // paragraph has to be the last node
    1291             :     //aPam.Move( fnMoveBackward, fnGoNode );
    1292             :     SwPosition aInsertPosition(
    1293         731 :             SwNodeIndex( *pStartNode->EndOfSectionNode(), -1 ) );
    1294         731 :     SwPaM aPam(aInsertPosition);
    1295             :     // If we got a position reference, then the insert point is not the end of
    1296             :     // the document.
    1297         731 :     if (xInsertPosition.is())
    1298             :     {
    1299           0 :         SwUnoInternalPaM aStartPam(*m_rThis.GetDoc());
    1300           0 :         ::sw::XTextRangeToSwPaM(aStartPam, xInsertPosition);
    1301           0 :         aPam = aStartPam;
    1302           0 :         aPam.SetMark();
    1303             :     }
    1304         731 :     m_pDoc->AppendTxtNode( *aPam.GetPoint() );
    1305             :     // remove attributes from the previous paragraph
    1306         731 :     m_pDoc->ResetAttrs(aPam);
    1307             :     // in case of finishParagraph the PaM needs to be moved to the
    1308             :     // previous paragraph
    1309         731 :     if (bFinish)
    1310             :     {
    1311         731 :         aPam.Move( fnMoveBackward, fnGoNode );
    1312             :     }
    1313         731 :     if (rProperties.getLength())
    1314             :     {
    1315             :         // now set the properties
    1316             :         SfxItemPropertySet const*const pParaPropSet =
    1317         728 :             aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
    1318             :         const SfxItemPropertyMap &rParagraphMap =
    1319         728 :             pParaPropSet->getPropertyMap();
    1320             : 
    1321         728 :         const beans::PropertyValue* pValues = rProperties.getConstArray();
    1322             : 
    1323        2606 :         for (sal_Int32 nProp = 0; nProp < rProperties.getLength(); ++nProp)
    1324             :         {
    1325        1878 :             if (!rParagraphMap.getByName(pValues[nProp].Name))
    1326             :             {
    1327           0 :                 bIllegalException = true;
    1328           0 :                 break;
    1329             :             }
    1330             :             try
    1331             :             {
    1332             :                 SwUnoCursorHelper::SetPropertyValue(aPam, *pParaPropSet,
    1333        1878 :                     pValues[nProp].Name, pValues[nProp].Value);
    1334             :             }
    1335           0 :             catch (const lang::IllegalArgumentException& rIllegal)
    1336             :             {
    1337           0 :                 sMessage = rIllegal.Message;
    1338           0 :                 bIllegalException = true;
    1339             :                 break;
    1340             :             }
    1341           0 :             catch (const uno::RuntimeException& rRuntime)
    1342             :             {
    1343           0 :                 sMessage = rRuntime.Message;
    1344           0 :                 bRuntimeException = true;
    1345             :                 break;
    1346             :             }
    1347             :         }
    1348             :     }
    1349         731 :     m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
    1350         731 :     if (bIllegalException || bRuntimeException)
    1351             :     {
    1352           0 :         m_pDoc->GetIDocumentUndoRedo().Undo();
    1353           0 :         if (bIllegalException)
    1354             :         {
    1355           0 :             lang::IllegalArgumentException aEx;
    1356           0 :             aEx.Message = sMessage;
    1357           0 :             throw aEx;
    1358             :         }
    1359             :         else // if(bRuntimeException)
    1360             :         {
    1361           0 :             uno::RuntimeException aEx;
    1362           0 :             aEx.Message = sMessage;
    1363           0 :             throw aEx;
    1364             :         }
    1365             :     }
    1366         731 :     SwTxtNode *const pTxtNode( aPam.Start()->nNode.GetNode().GetTxtNode() );
    1367             :     OSL_ENSURE(pTxtNode, "no SwTxtNode?");
    1368         731 :     if (pTxtNode)
    1369             :     {
    1370             :         xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, *pTxtNode, &m_rThis),
    1371         731 :                 uno::UNO_QUERY);
    1372             :     }
    1373             : 
    1374         731 :     return xRet;
    1375             : }
    1376             : 
    1377             : uno::Reference< text::XTextRange > SAL_CALL
    1378         585 : SwXText::insertTextPortion(
    1379             :         const ::rtl::OUString& rText,
    1380             :         const uno::Sequence< beans::PropertyValue > &
    1381             :             rCharacterAndParagraphProperties,
    1382             :         const uno::Reference<text::XTextRange>& xInsertPosition)
    1383             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1384             : {
    1385         585 :     SolarMutexGuard aGuard;
    1386             : 
    1387         585 :     if(!IsValid())
    1388             :     {
    1389           0 :         throw  uno::RuntimeException();
    1390             :     }
    1391         585 :     uno::Reference< text::XTextRange > xRet;
    1392         585 :     const uno::Reference< text::XTextCursor > xTextCursor = CreateCursor();
    1393         585 :     xTextCursor->gotoRange(xInsertPosition, sal_False);
    1394             : 
    1395             :     const uno::Reference< lang::XUnoTunnel > xRangeTunnel(
    1396         585 :             xTextCursor, uno::UNO_QUERY_THROW );
    1397             :     SwXTextCursor *const pTextCursor =
    1398         585 :         ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xRangeTunnel);
    1399             : 
    1400         585 :     bool bIllegalException = false;
    1401         585 :     bool bRuntimeException = false;
    1402         585 :     ::rtl::OUString sMessage;
    1403         585 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
    1404             : 
    1405             : //        SwPaM aPam(*pStartNode->EndOfSectionNode());
    1406             :     //aPam.Move( fnMoveBackward, fnGoNode );
    1407         585 :     SwUnoCrsr *const pCursor = pTextCursor->GetCursor();
    1408         585 :     m_pImpl->m_pDoc->DontExpandFmt( *pCursor->Start() );
    1409             : 
    1410         585 :     if (!rText.isEmpty())
    1411             :     {
    1412         585 :         const xub_StrLen nContentPos = pCursor->GetPoint()->nContent.GetIndex();
    1413             :         SwUnoCursorHelper::DocInsertStringSplitCR(
    1414         585 :             *m_pImpl->m_pDoc, *pCursor, rText, false);
    1415         585 :         SwUnoCursorHelper::SelectPam(*pCursor, true);
    1416         585 :         pCursor->GetPoint()->nContent = nContentPos;
    1417             :     }
    1418             : 
    1419         585 :     if (rCharacterAndParagraphProperties.getLength())
    1420             :     {
    1421             :         const SfxItemPropertyMap &rCursorMap =
    1422             :             aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)
    1423         257 :                 ->getPropertyMap();
    1424             :         beans::PropertyValue const*const pValues =
    1425         257 :             rCharacterAndParagraphProperties.getConstArray();
    1426             :         SfxItemPropertySet const*const pCursorPropSet =
    1427         257 :             aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR);
    1428         257 :         const sal_Int32 nLen(rCharacterAndParagraphProperties.getLength());
    1429        2673 :         for (sal_Int32 nProp = 0; nProp < nLen; ++nProp)
    1430             :         {
    1431        2416 :             if (!rCursorMap.getByName( pValues[nProp].Name ))
    1432             :             {
    1433           0 :                 bIllegalException = true;
    1434           0 :                 break;
    1435             :             }
    1436             :             try
    1437             :             {
    1438             :                 SwUnoCursorHelper::SetPropertyValue(
    1439             :                     *pCursor, *pCursorPropSet,
    1440        4832 :                     pValues[nProp].Name, pValues[nProp].Value,
    1441        4832 :                     nsSetAttrMode::SETATTR_NOFORMATATTR);
    1442             :             }
    1443           0 :             catch (const lang::IllegalArgumentException& rIllegal)
    1444             :             {
    1445           0 :                 sMessage = rIllegal.Message;
    1446           0 :                 bIllegalException = true;
    1447             :                 break;
    1448             :             }
    1449           0 :             catch (const uno::RuntimeException& rRuntime)
    1450             :             {
    1451           0 :                 sMessage = rRuntime.Message;
    1452           0 :                 bRuntimeException = true;
    1453             :                 break;
    1454             :             }
    1455             :         }
    1456             :     }
    1457         585 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
    1458         585 :     if (bIllegalException || bRuntimeException)
    1459             :     {
    1460           0 :         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
    1461           0 :         if (bIllegalException)
    1462             :         {
    1463           0 :             lang::IllegalArgumentException aEx;
    1464           0 :             aEx.Message = sMessage;
    1465           0 :             throw aEx;
    1466             :         }
    1467             :         else //if(bRuntimeException)
    1468             :         {
    1469           0 :             uno::RuntimeException aEx;
    1470           0 :             aEx.Message = sMessage;
    1471           0 :             throw aEx;
    1472             :         }
    1473             :     }
    1474         585 :     xRet = new SwXTextRange(*pCursor, this);
    1475         585 :     return xRet;
    1476             : }
    1477             : 
    1478             : /*-------------------------------------------------------------------------
    1479             :     Append text portions at the end of the last paragraph of the text
    1480             :     interface. Support of import filters.
    1481             :   -----------------------------------------------------------------------*/
    1482             : uno::Reference< text::XTextRange > SAL_CALL
    1483         585 : SwXText::appendTextPortion(
    1484             :         const ::rtl::OUString& rText,
    1485             :         const uno::Sequence< beans::PropertyValue > &
    1486             :             rCharacterAndParagraphProperties)
    1487             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1488             : {
    1489             :     // Right now this doesn't need a guard, as it's just calling the insert
    1490             :     // version, that has it already.
    1491         585 :     uno::Reference<text::XTextRange> xInsertPosition = getEnd();
    1492         585 :     return insertTextPortion(rText, rCharacterAndParagraphProperties, xInsertPosition);
    1493             : }
    1494             : 
    1495             : /*-------------------------------------------------------------------------
    1496             :     enable inserting/appending text contents like graphic objects, shapes and so on
    1497             :     to support import filters
    1498             :   -----------------------------------------------------------------------*/
    1499             : uno::Reference< text::XTextRange > SAL_CALL
    1500         217 : SwXText::insertTextContentWithProperties(
    1501             :     const uno::Reference< text::XTextContent >& xTextContent,
    1502             :     const uno::Sequence< beans::PropertyValue >&
    1503             :         rCharacterAndParagraphProperties,
    1504             :     const uno::Reference< text::XTextRange >& xInsertPosition)
    1505             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1506             : {
    1507         217 :     SolarMutexGuard aGuard;
    1508             : 
    1509         217 :     if (!IsValid())
    1510             :     {
    1511           0 :         throw  uno::RuntimeException();
    1512             :     }
    1513             : 
    1514         217 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
    1515             : 
    1516             :     // now attach the text content here
    1517         217 :     insertTextContent( xInsertPosition, xTextContent, false );
    1518             :     // now apply the properties to the anchor
    1519         185 :     if (rCharacterAndParagraphProperties.getLength())
    1520             :     {
    1521             :         try
    1522             :         {
    1523           3 :             const sal_Int32 nLen(rCharacterAndParagraphProperties.getLength());
    1524             :             const uno::Reference< beans::XPropertySet > xAnchor(
    1525           3 :                 xTextContent->getAnchor(), uno::UNO_QUERY);
    1526           3 :             if (xAnchor.is())
    1527             :             {
    1528          17 :                 for (sal_Int32 nElement = 0; nElement < nLen; ++nElement)
    1529             :                 {
    1530          14 :                     xAnchor->setPropertyValue(
    1531          14 :                         rCharacterAndParagraphProperties[nElement].Name,
    1532          28 :                         rCharacterAndParagraphProperties[nElement].Value);
    1533             :                 }
    1534           3 :             }
    1535             :         }
    1536           0 :         catch (const uno::Exception&)
    1537             :         {
    1538           0 :             throw uno::RuntimeException();
    1539             :         }
    1540             :     }
    1541         185 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
    1542         217 :     return xInsertPosition;
    1543             : }
    1544             : 
    1545             : uno::Reference< text::XTextRange > SAL_CALL
    1546         217 : SwXText::appendTextContent(
    1547             :     const uno::Reference< text::XTextContent >& xTextContent,
    1548             :     const uno::Sequence< beans::PropertyValue >&
    1549             :         rCharacterAndParagraphProperties)
    1550             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1551             : {
    1552             :     // Right now this doesn't need a guard, as it's just calling the insert
    1553             :     // version, that has it already.
    1554         217 :     uno::Reference<text::XTextRange> xInsertPosition = getEnd();
    1555         217 :     return insertTextContentWithProperties(xTextContent, rCharacterAndParagraphProperties, xInsertPosition);
    1556             : }
    1557             : 
    1558             : // move previously appended paragraphs into a text frames
    1559             : // to support import filters
    1560             : uno::Reference< text::XTextContent > SAL_CALL
    1561          15 : SwXText::convertToTextFrame(
    1562             :     const uno::Reference< text::XTextRange >& xStart,
    1563             :     const uno::Reference< text::XTextRange >& xEnd,
    1564             :     const uno::Sequence< beans::PropertyValue >& rFrameProperties)
    1565             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1566             : {
    1567          15 :     SolarMutexGuard aGuard;
    1568             : 
    1569          15 :     if(!IsValid())
    1570             :     {
    1571           0 :         throw  uno::RuntimeException();
    1572             :     }
    1573          15 :     uno::Reference< text::XTextContent > xRet;
    1574          15 :     SwUnoInternalPaM aStartPam(*GetDoc());
    1575             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1576          15 :     std::auto_ptr< SwUnoInternalPaM > pEndPam(new SwUnoInternalPaM(*GetDoc()));
    1577             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1578          29 :     if (!::sw::XTextRangeToSwPaM(aStartPam, xStart) ||
    1579          14 :         !::sw::XTextRangeToSwPaM(*pEndPam, xEnd))
    1580             :     {
    1581           1 :         throw lang::IllegalArgumentException();
    1582             :     }
    1583             : 
    1584             :     const uno::Reference<lang::XUnoTunnel> xStartRangeTunnel(xStart,
    1585          14 :             uno::UNO_QUERY);
    1586             :     SwXTextRange *const pStartRange =
    1587          14 :         ::sw::UnoTunnelGetImplementation<SwXTextRange>(xStartRangeTunnel);
    1588             :     const uno::Reference<lang::XUnoTunnel> xEndRangeTunnel(xEnd,
    1589          14 :             uno::UNO_QUERY);
    1590             :     SwXTextRange *const pEndRange   =
    1591          14 :         ::sw::UnoTunnelGetImplementation<SwXTextRange>(xEndRangeTunnel);
    1592             :     // bookmarks have to be removed before the referenced text node
    1593             :     // is deleted in DelFullPara
    1594          14 :     if (pStartRange)
    1595             :     {
    1596          14 :         pStartRange->Invalidate();
    1597             :     }
    1598          14 :     if (pEndRange)
    1599             :     {
    1600          12 :         pEndRange->Invalidate();
    1601             :     }
    1602             : 
    1603          14 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
    1604          14 :     bool bIllegalException = false;
    1605          14 :     bool bRuntimeException = false;
    1606          14 :     ::rtl::OUString sMessage;
    1607          14 :     SwStartNode* pStartStartNode = aStartPam.GetNode()->StartOfSectionNode();
    1608          28 :     while (pStartStartNode && pStartStartNode->IsSectionNode())
    1609             :     {
    1610           0 :         pStartStartNode = pStartStartNode->StartOfSectionNode();
    1611             :     }
    1612          14 :     SwStartNode* pEndStartNode = pEndPam->GetNode()->StartOfSectionNode();
    1613          28 :     while (pEndStartNode && pEndStartNode->IsSectionNode())
    1614             :     {
    1615           0 :         pEndStartNode = pEndStartNode->StartOfSectionNode();
    1616             :     }
    1617          14 :     bool bParaAfterInserted = false;
    1618          14 :     bool bParaBeforeInserted = false;
    1619          14 :     if (pStartStartNode != pEndStartNode || pStartStartNode != GetStartNode())
    1620             :     {
    1621             :         // todo: if the start/end is in a table then insert a paragraph
    1622             :         // before/after, move the start/end nodes, then convert and
    1623             :         // remove the addtional paragraphs in the end
    1624           1 :         if (pStartStartNode->GetStartNodeType() == SwTableBoxStartNode)
    1625             :         {
    1626           1 :             SwTableNode *const pStartTableNode(pStartStartNode->FindTableNode());
    1627           1 :             const SwNodeIndex aTblIdx(  *pStartTableNode, -1 );
    1628           1 :             SwPosition aBefore(aTblIdx);
    1629           1 :             bParaBeforeInserted = GetDoc()->AppendTxtNode( aBefore );
    1630           1 :             aStartPam.DeleteMark();
    1631           1 :             *aStartPam.GetPoint() = aBefore;
    1632           1 :             pStartStartNode = aStartPam.GetNode()->StartOfSectionNode();
    1633             :         }
    1634           1 :         if (pEndStartNode->GetStartNodeType() == SwTableBoxStartNode)
    1635             :         {
    1636           1 :             SwTableNode *const pEndTableNode = pEndStartNode->FindTableNode();
    1637           1 :             SwEndNode *const pTableEnd = pEndTableNode->EndOfSectionNode();
    1638           1 :             SwPosition aTableEnd(*pTableEnd);
    1639           1 :             bParaAfterInserted = GetDoc()->AppendTxtNode( aTableEnd );
    1640           1 :             pEndPam->DeleteMark();
    1641           1 :             *pEndPam->GetPoint() = aTableEnd;
    1642           1 :             pEndStartNode = pEndPam->GetNode()->StartOfSectionNode();
    1643             :         }
    1644             :         // now we should have the positions in the same hierarchy
    1645           2 :         if ((pStartStartNode != pEndStartNode) ||
    1646           1 :             (pStartStartNode != GetStartNode()))
    1647             :         {
    1648             :             // if not - remove the additional paragraphs and throw
    1649           0 :             if (bParaBeforeInserted)
    1650             :             {
    1651           0 :                 SwCursor aDelete(*aStartPam.GetPoint(), 0, false);
    1652           0 :                 aDelete.MovePara(fnParaCurr, fnParaStart);
    1653           0 :                 aDelete.SetMark();
    1654           0 :                 aDelete.MovePara(fnParaCurr, fnParaEnd);
    1655           0 :                 GetDoc()->DelFullPara(aDelete);
    1656             :             }
    1657           0 :             if (bParaAfterInserted)
    1658             :             {
    1659           0 :                 SwCursor aDelete(*pEndPam->GetPoint(), 0, false);
    1660           0 :                 aDelete.MovePara(fnParaCurr, fnParaStart);
    1661           0 :                 aDelete.SetMark();
    1662           0 :                 aDelete.MovePara(fnParaCurr, fnParaEnd);
    1663           0 :                 GetDoc()->DelFullPara(aDelete);
    1664             :             }
    1665           0 :             throw lang::IllegalArgumentException();
    1666             :         }
    1667             :     }
    1668             : 
    1669             :     // make a selection from aStartPam to a EndPam
    1670             :     // If there is no content in the frame the shape is in
    1671             :     // it gets deleted in the DelFullPara call below,
    1672             :     // In this case insert a tmp text node ( we delete it later )
    1673          25 :     if ( aStartPam.Start()->nNode == pEndPam->Start()->nNode
    1674          11 :     && aStartPam.End()->nNode == pEndPam->End()->nNode )
    1675             :     {
    1676          11 :         SwPosition aEnd(*aStartPam.End());
    1677          11 :         bParaAfterInserted = GetDoc()->AppendTxtNode( aEnd );
    1678          11 :         pEndPam->DeleteMark();
    1679          11 :         *pEndPam->GetPoint() = aEnd;
    1680             :     }
    1681          14 :     aStartPam.SetMark();
    1682          14 :     *aStartPam.End() = *pEndPam->End();
    1683          14 :     pEndPam.reset(0);
    1684             : 
    1685             :     // see if there are frames already anchored to this node
    1686          14 :     std::vector<SwFrmFmt*> aAnchoredFrames;
    1687          30 :     for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrmFmts()->size(); ++i)
    1688             :     {
    1689          16 :         SwFrmFmt* pFrmFmt = (*m_pImpl->m_pDoc->GetSpzFrmFmts())[i];
    1690          16 :         const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
    1691          29 :         if (FLY_AT_PARA == rAnchor.GetAnchorId() &&
    1692          13 :                 aStartPam.GetNode()->GetIndex() == rAnchor.GetCntntAnchor()->nNode.GetIndex())
    1693           6 :             aAnchoredFrames.push_back(pFrmFmt);
    1694             :     }
    1695             : 
    1696          14 :     SwXTextFrame *const pNewFrame = new SwXTextFrame(m_pImpl->m_pDoc);
    1697          14 :     const uno::Reference< text::XTextFrame > xNewFrame = pNewFrame;
    1698          14 :     pNewFrame->SetSelection( aStartPam );
    1699             :     try
    1700             :     {
    1701          14 :         const beans::PropertyValue* pValues = rFrameProperties.getConstArray();
    1702         322 :         for (sal_Int32 nProp = 0; nProp < rFrameProperties.getLength(); ++nProp)
    1703             :         {
    1704             :             pNewFrame->SwXFrame::setPropertyValue(
    1705         308 :                     pValues[nProp].Name, pValues[nProp].Value);
    1706             :         }
    1707             : 
    1708             :         {   // has to be in a block to remove the SwIndexes before
    1709             :             // DelFullPara is called
    1710             :             const uno::Reference< text::XTextRange> xInsertTextRange =
    1711          14 :                 new SwXTextRange(aStartPam, this);
    1712          14 :             aStartPam.DeleteMark(); // mark position node may be deleted!
    1713          14 :             pNewFrame->attach( xInsertTextRange );
    1714          14 :             pNewFrame->setName(m_pImpl->m_pDoc->GetUniqueFrameName());
    1715             :         }
    1716             : 
    1717          14 :         SwTxtNode *const pTxtNode(aStartPam.GetNode()->GetTxtNode());
    1718             :         OSL_ASSERT(pTxtNode);
    1719          14 :         if (!pTxtNode || !pTxtNode->Len()) // don't remove if it contains text!
    1720             :         {
    1721             :             {   // has to be in a block to remove the SwIndexes before
    1722             :                 // DelFullPara is called
    1723          14 :                 SwPaM aMovePam( *aStartPam.GetNode() );
    1724          14 :                 if (aMovePam.Move( fnMoveForward, fnGoCntnt ))
    1725             :                 {
    1726             :                     // move the anchor to the next paragraph
    1727          14 :                     SwFmtAnchor aNewAnchor(pNewFrame->GetFrmFmt()->GetAnchor());
    1728          14 :                     aNewAnchor.SetAnchor( aMovePam.Start() );
    1729          14 :                     m_pImpl->m_pDoc->SetAttr(
    1730          28 :                         aNewAnchor, *pNewFrame->GetFrmFmt() );
    1731             : 
    1732             :                     // also move frames anchored to us
    1733          20 :                     for (std::vector<SwFrmFmt*>::iterator i = aAnchoredFrames.begin(); i != aAnchoredFrames.end(); ++i)
    1734             :                     {
    1735             :                         // copy the anchor to the next paragraph
    1736           6 :                         SwFmtAnchor aAnchor((*i)->GetAnchor());
    1737           6 :                         aAnchor.SetAnchor(aMovePam.Start());
    1738           6 :                         m_pImpl->m_pDoc->SetAttr(aAnchor, *(*i));
    1739          20 :                     }
    1740          14 :                 }
    1741             :             }
    1742          14 :             m_pImpl->m_pDoc->DelFullPara(aStartPam);
    1743             :         }
    1744             :     }
    1745           0 :     catch (const lang::IllegalArgumentException& rIllegal)
    1746             :     {
    1747           0 :         sMessage = rIllegal.Message;
    1748           0 :         bIllegalException = true;
    1749             :     }
    1750           0 :     catch (const uno::RuntimeException& rRuntime)
    1751             :     {
    1752           0 :         sMessage = rRuntime.Message;
    1753           0 :         bRuntimeException = true;
    1754             :     }
    1755          14 :     xRet = pNewFrame;
    1756          14 :     if (bParaBeforeInserted || bParaAfterInserted)
    1757             :     {
    1758             :         const uno::Reference<text::XTextCursor> xFrameTextCursor =
    1759          12 :             pNewFrame->createTextCursor();
    1760             :         const uno::Reference<XUnoTunnel> xTunnel(xFrameTextCursor,
    1761          12 :                 uno::UNO_QUERY);
    1762             :         SwXTextCursor *const pFrameCursor =
    1763          12 :             ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xTunnel);
    1764          12 :         if (bParaBeforeInserted)
    1765             :         {
    1766             :             // todo: remove paragraph before frame
    1767           1 :             m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
    1768             :         }
    1769          12 :         if (bParaAfterInserted)
    1770             :         {
    1771          12 :             xFrameTextCursor->gotoEnd(sal_False);
    1772          12 :             if (!bParaBeforeInserted)
    1773          11 :                 m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
    1774             :             else
    1775             :             {
    1776             :                 // In case the frame has a table only, the cursor points to the end of the first cell of the table.
    1777           1 :                 SwPaM aPaM(*pFrameCursor->GetPaM()->GetNode()->FindSttNodeByType(SwFlyStartNode)->EndOfSectionNode());
    1778             :                 // Now we have the end of the frame -- the node before that will be the paragraph we want to remove.
    1779           1 :                 aPaM.GetPoint()->nNode--;
    1780           1 :                 m_pImpl->m_pDoc->DelFullPara(aPaM);
    1781             :             }
    1782          12 :         }
    1783             :     }
    1784             : 
    1785          14 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
    1786          14 :     if (bIllegalException || bRuntimeException)
    1787             :     {
    1788           0 :         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
    1789           0 :         if (bIllegalException)
    1790             :         {
    1791           0 :             lang::IllegalArgumentException aEx;
    1792           0 :             aEx.Message = sMessage;
    1793           0 :             throw aEx;
    1794             :         }
    1795             :         else //if(bRuntimeException)
    1796             :         {
    1797           0 :             uno::RuntimeException aEx;
    1798           0 :             aEx.Message = sMessage;
    1799           0 :             throw aEx;
    1800             :         }
    1801             :     }
    1802          14 :     return xRet;
    1803             : }
    1804             : 
    1805             : /*-------------------------------------------------------------------------
    1806             :     Move previously imported paragraphs into a new text table.
    1807             :   -----------------------------------------------------------------------*/
    1808           3 : struct VerticallyMergedCell
    1809             : {
    1810             :     std::vector<uno::Reference< beans::XPropertySet > > aCells;
    1811             :     sal_Int32                                           nLeftPosition;
    1812             :     bool                                                bOpen;
    1813             : 
    1814           1 :     VerticallyMergedCell(uno::Reference< beans::XPropertySet > const& rxCell,
    1815             :             const sal_Int32 nLeft)
    1816             :         : nLeftPosition( nLeft )
    1817           1 :         , bOpen( true )
    1818             :     {
    1819           1 :         aCells.push_back( rxCell );
    1820           1 :     }
    1821             : };
    1822             : 
    1823             : #define COL_POS_FUZZY 2
    1824             : 
    1825           0 : static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 )
    1826             : {
    1827           0 :     return abs( nPos1 - nPos2 ) < COL_POS_FUZZY;
    1828             : }
    1829             : 
    1830             : SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1831         264 : void SwXText::Impl::ConvertCell(
    1832             :     const bool bFirstCell,
    1833             :     const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
    1834             :     ::std::vector<SwNodeRange> & rRowNodes,
    1835             :     ::std::auto_ptr< SwPaM > & rpFirstPaM,
    1836             :     SwPaM & rLastPaM,
    1837             :     bool & rbExcept)
    1838             : {
    1839         264 :     if (rCell.getLength() != 2)
    1840             :     {
    1841             :         throw lang::IllegalArgumentException(
    1842             :                 rtl::OUString::createFromAscii( "rCell needs to contain 2 elements" ),
    1843           0 :                 uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
    1844             :     }
    1845         264 :     const uno::Reference<text::XTextRange> xStartRange = rCell[0];
    1846         264 :     const uno::Reference<text::XTextRange> xEndRange = rCell[1];
    1847         264 :     SwUnoInternalPaM aStartCellPam(*m_pDoc);
    1848         264 :     SwUnoInternalPaM aEndCellPam(*m_pDoc);
    1849             : 
    1850             :     // !!! TODO - PaMs in tables and sections do not work here -
    1851             :     //     the same applies to PaMs in frames !!!
    1852             : 
    1853         528 :     if (!::sw::XTextRangeToSwPaM(aStartCellPam, xStartRange) ||
    1854         264 :         !::sw::XTextRangeToSwPaM(aEndCellPam, xEndRange))
    1855             :     {
    1856             :         throw lang::IllegalArgumentException(
    1857             :                 rtl::OUString::createFromAscii( "Start or End range cannot be resolved to a SwPaM" ),
    1858           0 :                 uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
    1859             :     }
    1860             : 
    1861         264 :     SwNodeRange aTmpRange(aStartCellPam.Start()->nNode,
    1862         528 :                           aEndCellPam.End()->nNode);
    1863             :     SwNodeRange * pCorrectedRange =
    1864         264 :         m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange);
    1865             : 
    1866         264 :     if (pCorrectedRange != NULL)
    1867             :     {
    1868           5 :         SwPaM aNewStartPaM(pCorrectedRange->aStart, 0);
    1869           5 :         aStartCellPam = aNewStartPaM;
    1870             : 
    1871           5 :         xub_StrLen nEndLen = 0;
    1872           5 :         SwTxtNode * pTxtNode = pCorrectedRange->aEnd.GetNode().GetTxtNode();
    1873           5 :         if (pTxtNode != NULL)
    1874           5 :             nEndLen = pTxtNode->Len();
    1875             : 
    1876           5 :         SwPaM aNewEndPaM(pCorrectedRange->aEnd, nEndLen);
    1877           5 :         aEndCellPam = aNewEndPaM;
    1878             :     }
    1879             : 
    1880             :     /** check the nodes between start and end
    1881             :         it is allowed to have pairs of StartNode/EndNodes
    1882             :      */
    1883         264 :     if (aStartCellPam.Start()->nNode < aEndCellPam.End()->nNode)
    1884             :     {
    1885             :         // increment on each StartNode and decrement on each EndNode
    1886             :         // we must reach zero at the end and must not go below zero
    1887           8 :         long nOpenNodeBlock = 0;
    1888           8 :         SwNodeIndex aCellIndex = aStartCellPam.Start()->nNode;
    1889          45 :         while (aCellIndex < aEndCellPam.End()->nNode.GetIndex())
    1890             :         {
    1891          29 :             if (aCellIndex.GetNode().IsStartNode())
    1892             :             {
    1893          10 :                 ++nOpenNodeBlock;
    1894             :             }
    1895          19 :             else if (aCellIndex.GetNode().IsEndNode())
    1896             :             {
    1897          10 :                 --nOpenNodeBlock;
    1898             :             }
    1899          29 :             if (nOpenNodeBlock < 0)
    1900             :             {
    1901           0 :                 rbExcept = true;
    1902           0 :                 break;
    1903             :             }
    1904          29 :             ++aCellIndex;
    1905             :         }
    1906           8 :         if (nOpenNodeBlock != 0)
    1907             :         {
    1908           0 :             rbExcept = true;
    1909         264 :             return;
    1910           8 :         }
    1911             :     }
    1912             : 
    1913             :     /** The vector<vector> NodeRanges has to contain consecutive nodes.
    1914             :         In rTableRanges the ranges don't need to be full paragraphs but
    1915             :         they have to follow each other. To process the ranges they
    1916             :         have to be aligned on paragraph borders by inserting paragraph
    1917             :         breaks. Non-consecutive ranges must initiate an exception.
    1918             :      */
    1919         264 :     if (bFirstCell)
    1920             :     {
    1921             :         // align the beginning - if necessary
    1922          46 :         if (aStartCellPam.Start()->nContent.GetIndex())
    1923             :         {
    1924           0 :             m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
    1925             :         }
    1926             :     }
    1927             :     else
    1928             :     {
    1929             :         // check the predecessor
    1930         218 :         const sal_uLong nLastNodeIndex = rLastPaM.End()->nNode.GetIndex();
    1931             :         const sal_uLong nStartCellNodeIndex =
    1932         218 :             aStartCellPam.Start()->nNode.GetIndex();
    1933         218 :         const sal_uLong nLastNodeEndIndex = rLastPaM.End()->nNode.GetIndex();
    1934         218 :         if (nLastNodeIndex == nStartCellNodeIndex)
    1935             :         {
    1936             :             // same node as predecessor then equal nContent?
    1937           0 :             if (rLastPaM.End()->nContent != aStartCellPam.Start()->nContent)
    1938             :             {
    1939           0 :                 rbExcept = true;
    1940             :             }
    1941             :             else
    1942             :             {
    1943           0 :                 m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
    1944             :             }
    1945             :         }
    1946         218 :         else if (nStartCellNodeIndex == (nLastNodeEndIndex + 1))
    1947             :         {
    1948             :             // next paragraph - now the content index of the new should be 0
    1949             :             // and of the old one should be equal to the text length
    1950             :             // but if it isn't we don't care - the cell is being inserted on
    1951             :             // the node border anyway
    1952             :         }
    1953             :         else
    1954             :         {
    1955           0 :             rbExcept = true;
    1956             :         }
    1957             :     }
    1958             :     // now check if there's a need to insert another paragraph break
    1959         528 :     if (aEndCellPam.End()->nContent.GetIndex() <
    1960         264 :             aEndCellPam.End()->nNode.GetNode().GetTxtNode()->Len())
    1961             :     {
    1962           0 :         m_pDoc->SplitNode(*aEndCellPam.End(), sal_False);
    1963             :         // take care that the new start/endcell is moved to the right position
    1964             :         // aStartCellPam has to point to the start of the new (previous) node
    1965             :         // aEndCellPam has to point to the end of the new (previous) node
    1966           0 :         aStartCellPam.DeleteMark();
    1967           0 :         aStartCellPam.Move(fnMoveBackward, fnGoNode);
    1968           0 :         aStartCellPam.GetPoint()->nContent = 0;
    1969           0 :         aEndCellPam.DeleteMark();
    1970           0 :         aEndCellPam.Move(fnMoveBackward, fnGoNode);
    1971           0 :         aEndCellPam.GetPoint()->nContent =
    1972           0 :             aEndCellPam.GetNode()->GetTxtNode()->Len();
    1973             :     }
    1974             : 
    1975         264 :     *rLastPaM.GetPoint() = *aEndCellPam.Start();
    1976         264 :     if (aStartCellPam.HasMark())
    1977             :     {
    1978           0 :         rLastPaM.SetMark();
    1979           0 :         *rLastPaM.GetMark() = *aEndCellPam.End();
    1980             :     }
    1981             :     else
    1982             :     {
    1983         264 :         rLastPaM.DeleteMark();
    1984             :     }
    1985             : 
    1986         264 :     SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
    1987         528 :             aEndCellPam.End()->nNode);
    1988         264 :     rRowNodes.push_back(aCellRange);
    1989         264 :     if (bFirstCell)
    1990             :     {
    1991          46 :         rpFirstPaM.reset(new SwPaM(*aStartCellPam.Start()));
    1992         264 :     }
    1993             : }
    1994             : SAL_WNODEPRECATED_DECLARATIONS_POP
    1995             : 
    1996             : typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;
    1997             : 
    1998             : static void
    1999          68 : lcl_ApplyRowProperties(
    2000             :     uno::Sequence<beans::PropertyValue> const& rRowProperties,
    2001             :     uno::Any const& rRow,
    2002             :     TableColumnSeparators & rRowSeparators)
    2003             : {
    2004          68 :     uno::Reference< beans::XPropertySet > xRow;
    2005          68 :     rRow >>= xRow;
    2006          68 :     const beans::PropertyValue* pProperties = rRowProperties.getConstArray();
    2007         222 :     for (sal_Int32 nProperty = 0; nProperty < rRowProperties.getLength();
    2008             :          ++nProperty)
    2009             :     {
    2010         154 :         if ( pProperties[ nProperty ].Name == "TableColumnSeparators" )
    2011             :         {
    2012             :             // add the separators to access the cell's positions
    2013             :             // for vertical merging later
    2014          68 :             TableColumnSeparators aSeparators;
    2015          68 :             pProperties[ nProperty ].Value >>= aSeparators;
    2016          68 :             rRowSeparators = aSeparators;
    2017             :         }
    2018         154 :         xRow->setPropertyValue(
    2019         154 :             pProperties[ nProperty ].Name, pProperties[ nProperty ].Value);
    2020          68 :     }
    2021          68 : }
    2022             : 
    2023             : #if OSL_DEBUG_LEVEL > 0
    2024             : //-->debug cell properties of all rows
    2025             : static void
    2026             : lcl_DebugCellProperties(
    2027             :     const uno::Sequence< uno::Sequence< uno::Sequence<
    2028             :         beans::PropertyValue > > >& rCellProperties)
    2029             : {
    2030             :     ::rtl::OUString sNames;
    2031             :     for (sal_Int32  nDebugRow = 0; nDebugRow < rCellProperties.getLength();
    2032             :          ++nDebugRow)
    2033             :     {
    2034             :         const uno::Sequence< beans::PropertyValues > aDebugCurrentRow =
    2035             :             rCellProperties[nDebugRow];
    2036             :         sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
    2037             :         (void) nDebugCells;
    2038             :         for (sal_Int32  nDebugCell = 0; nDebugCell < nDebugCells;
    2039             :              ++nDebugCell)
    2040             :         {
    2041             :             const uno::Sequence< beans::PropertyValue >&
    2042             :                 rDebugCellProperties = aDebugCurrentRow[nDebugCell];
    2043             :             const sal_Int32 nDebugCellProperties =
    2044             :                 rDebugCellProperties.getLength();
    2045             :             for (sal_Int32  nDebugProperty = 0;
    2046             :                  nDebugProperty < nDebugCellProperties; ++nDebugProperty)
    2047             :             {
    2048             :                 const ::rtl::OUString sName =
    2049             :                     rDebugCellProperties[nDebugProperty].Name;
    2050             :                 sNames += sName;
    2051             :                 sNames += ::rtl::OUString('-');
    2052             :             }
    2053             :             sNames += ::rtl::OUString('+');
    2054             :         }
    2055             :         sNames += ::rtl::OUString('|');
    2056             :     }
    2057             :     (void)sNames;
    2058             : }
    2059             : //--<
    2060             : #endif
    2061             : 
    2062             : static void
    2063         264 : lcl_ApplyCellProperties(
    2064             :     const sal_Int32 nCell,
    2065             :     TableColumnSeparators const& rRowSeparators,
    2066             :     const uno::Sequence< beans::PropertyValue >& rCellProperties,
    2067             :     uno::Reference< uno::XInterface > xCell,
    2068             :     ::std::vector<VerticallyMergedCell> & rMergedCells)
    2069             : {
    2070         264 :     const sal_Int32 nCellProperties = rCellProperties.getLength();
    2071         264 :     const uno::Reference< beans::XPropertySet > xCellPS(xCell, uno::UNO_QUERY);
    2072        2248 :     for (sal_Int32 nProperty = 0; nProperty < nCellProperties; ++nProperty)
    2073             :     {
    2074        1984 :         const OUString & rName  = rCellProperties[nProperty].Name;
    2075        1984 :         const uno::Any & rValue = rCellProperties[nProperty].Value;
    2076        1984 :         if ( rName == "VerticalMerge" )
    2077             :         {
    2078             :             // determine left border position
    2079             :             // add the cell to a queue of merged cells
    2080           1 :             sal_Bool bMerge = sal_False;
    2081           1 :             rValue >>= bMerge;
    2082           1 :             sal_Int32 nLeftPos = -1;
    2083           1 :             if (!nCell)
    2084             :             {
    2085           1 :                 nLeftPos = 0;
    2086             :             }
    2087           0 :             else if (rRowSeparators.getLength() >= nCell)
    2088             :             {
    2089             :                 const text::TableColumnSeparator* pSeparators =
    2090           0 :                     rRowSeparators.getConstArray();
    2091           0 :                 nLeftPos = pSeparators[nCell - 1].Position;
    2092             :             }
    2093           1 :             if (bMerge)
    2094             :             {
    2095             :                 // 'close' all the cell with the same left position
    2096             :                 // if separate vertical merges in the same column exist
    2097           1 :                 if (rMergedCells.size())
    2098             :                 {
    2099             :                     std::vector<VerticallyMergedCell>::iterator aMergedIter =
    2100           0 :                         rMergedCells.begin();
    2101           0 :                     while (aMergedIter != rMergedCells.end())
    2102             :                     {
    2103           0 :                         if (lcl_SimilarPosition(aMergedIter->nLeftPosition,
    2104           0 :                                     nLeftPos))
    2105             :                         {
    2106           0 :                             aMergedIter->bOpen = false;
    2107             :                         }
    2108           0 :                         ++aMergedIter;
    2109             :                     }
    2110             :                 }
    2111             :                 // add the new group of merged cells
    2112           1 :                 rMergedCells.push_back(VerticallyMergedCell(xCellPS, nLeftPos));
    2113             :             }
    2114             :             else
    2115             :             {
    2116             :                 // find the cell that
    2117             :                 OSL_ENSURE(rMergedCells.size(),
    2118             :                         "the first merged cell is missing");
    2119           0 :                 if (rMergedCells.size())
    2120             :                 {
    2121             :                     std::vector<VerticallyMergedCell>::iterator aMergedIter =
    2122           0 :                         rMergedCells.begin();
    2123             : #if OSL_DEBUG_LEVEL > 0
    2124             :                     bool bDbgFound = false;
    2125             : #endif
    2126           0 :                     while (aMergedIter != rMergedCells.end())
    2127             :                     {
    2128           0 :                         if (aMergedIter->bOpen &&
    2129           0 :                             lcl_SimilarPosition(aMergedIter->nLeftPosition,
    2130           0 :                                 nLeftPos))
    2131             :                         {
    2132           0 :                             aMergedIter->aCells.push_back( xCellPS );
    2133             : #if OSL_DEBUG_LEVEL > 0
    2134             :                             bDbgFound = true;
    2135             : #endif
    2136             :                         }
    2137           0 :                         ++aMergedIter;
    2138             :                     }
    2139             : #if OSL_DEBUG_LEVEL > 0
    2140             :                     OSL_ENSURE( bDbgFound,
    2141             :                             "couldn't find first vertically merged cell" );
    2142             : #endif
    2143             :                 }
    2144             :             }
    2145             :         }
    2146             :         else
    2147             :         {
    2148             :             try
    2149             :             {
    2150        1983 :                 xCellPS->setPropertyValue(rName, rValue);
    2151             :             }
    2152           0 :             catch (const uno::Exception&)
    2153             :             {
    2154             :                 // Apply the paragraph and char properties to the cell's content
    2155             :                 const uno::Reference< text::XText > xCellText(xCell,
    2156           0 :                         uno::UNO_QUERY);
    2157             :                 const uno::Reference< text::XTextCursor > xCellCurs =
    2158           0 :                     xCellText->createTextCursor();
    2159           0 :                 xCellCurs->gotoStart( sal_False );
    2160           0 :                 xCellCurs->gotoEnd( sal_True );
    2161             :                 const uno::Reference< beans::XPropertySet > xCellTextProps(
    2162           0 :                         xCellCurs, uno::UNO_QUERY);
    2163           0 :                 xCellTextProps->setPropertyValue(rName, rValue);
    2164             :             }
    2165             :         }
    2166         264 :     }
    2167         264 : }
    2168             : 
    2169             : static void
    2170          46 : lcl_MergeCells(::std::vector<VerticallyMergedCell> & rMergedCells)
    2171             : {
    2172          46 :     if (rMergedCells.size())
    2173             :     {
    2174             :         std::vector<VerticallyMergedCell>::iterator aMergedIter =
    2175           1 :             rMergedCells.begin();
    2176           3 :         while (aMergedIter != rMergedCells.end())
    2177             :         {
    2178             :             sal_Int32 nCellCount =
    2179           1 :                 static_cast<sal_Int32>(aMergedIter->aCells.size());
    2180             :             std::vector<uno::Reference< beans::XPropertySet > >::iterator
    2181           1 :                 aCellIter = aMergedIter->aCells.begin();
    2182           1 :             bool bFirstCell = true;
    2183             :             // the first of the cells gets the number of cells set as RowSpan
    2184             :             // the others get the inverted number of remaining merged cells
    2185             :             // (3,-2,-1)
    2186           3 :             while (aCellIter != aMergedIter->aCells.end())
    2187             :             {
    2188           1 :                 (*aCellIter)->setPropertyValue(
    2189           1 :                     rtl::OUString::createFromAscii(SW_PROP_NAME_STR(UNO_NAME_ROW_SPAN)),
    2190           2 :                     uno::makeAny(nCellCount));
    2191           1 :                 if (bFirstCell)
    2192             :                 {
    2193           1 :                     nCellCount *= -1;
    2194           1 :                     bFirstCell = false;
    2195             :                 }
    2196           1 :                 ++nCellCount;
    2197           1 :                 ++aCellIter;
    2198             :             }
    2199           1 :             ++aMergedIter;
    2200             :         }
    2201             :     }
    2202          46 : }
    2203             : 
    2204             : uno::Reference< text::XTextTable > SAL_CALL
    2205          46 : SwXText::convertToTable(
    2206             :     const uno::Sequence< uno::Sequence< uno::Sequence<
    2207             :         uno::Reference< text::XTextRange > > > >& rTableRanges,
    2208             :     const uno::Sequence< uno::Sequence< uno::Sequence<
    2209             :         beans::PropertyValue > > >& rCellProperties,
    2210             :     const uno::Sequence< uno::Sequence< beans::PropertyValue > >&
    2211             :         rRowProperties,
    2212             :     const uno::Sequence< beans::PropertyValue >& rTableProperties)
    2213             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    2214             : {
    2215          46 :     SolarMutexGuard aGuard;
    2216             : 
    2217          46 :     if(!IsValid())
    2218             :     {
    2219           0 :         throw  uno::RuntimeException();
    2220             :     }
    2221             : 
    2222             :     //at first collect the text ranges as SwPaMs
    2223             :     const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >*
    2224          46 :         pTableRanges = rTableRanges.getConstArray();
    2225             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2226          46 :     std::auto_ptr < SwPaM > pFirstPaM;
    2227             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2228          46 :     std::vector< std::vector<SwNodeRange> > aTableNodes;
    2229          46 :     bool bExcept = false;
    2230          46 :     SwPaM aLastPaM(m_pImpl->m_pDoc->GetNodes());
    2231         114 :     for (sal_Int32 nRow = 0; !bExcept && (nRow < rTableRanges.getLength());
    2232             :             ++nRow)
    2233             :     {
    2234          68 :         std::vector<SwNodeRange> aRowNodes;
    2235             :         const uno::Sequence< uno::Reference< text::XTextRange > >* pRow =
    2236          68 :             pTableRanges[nRow].getConstArray();
    2237          68 :         const sal_Int32 nCells(pTableRanges[nRow].getLength());
    2238             : 
    2239         332 :         for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
    2240             :         {
    2241         264 :             m_pImpl->ConvertCell((nCell == 0) && (nRow == 0), pRow[nCell],
    2242         528 :                 aRowNodes, pFirstPaM, aLastPaM, bExcept);
    2243             :         }
    2244          68 :         aTableNodes.push_back(aRowNodes);
    2245          68 :     }
    2246             : 
    2247          46 :     if(bExcept)
    2248             :     {
    2249           0 :         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
    2250           0 :         throw lang::IllegalArgumentException();
    2251             :     }
    2252             : 
    2253             :     std::vector< TableColumnSeparators >
    2254          46 :         aRowSeparators(rRowProperties.getLength());
    2255          46 :     std::vector<VerticallyMergedCell> aMergedCells;
    2256             : 
    2257          46 :     SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes );
    2258             : 
    2259          46 :     if (!pTable)
    2260           0 :         return uno::Reference< text::XTextTable >();
    2261             : 
    2262          46 :     SwXTextTable *const pTextTable = new SwXTextTable( *pTable->GetFrmFmt() );
    2263          46 :     const uno::Reference< text::XTextTable > xRet = pTextTable;
    2264          46 :     const uno::Reference< beans::XPropertySet > xPrSet = pTextTable;
    2265             :     // set properties to the table
    2266             :     // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException
    2267             :     try
    2268             :     {
    2269             :         //apply table properties
    2270             :         const beans::PropertyValue* pTableProperties =
    2271          46 :             rTableProperties.getConstArray();
    2272         514 :         for (sal_Int32 nProperty = 0; nProperty < rTableProperties.getLength();
    2273             :              ++nProperty)
    2274             :         {
    2275             :             try
    2276             :             {
    2277         936 :                 xPrSet->setPropertyValue( pTableProperties[nProperty].Name,
    2278         936 :                         pTableProperties[nProperty].Value );
    2279             :             }
    2280         100 :             catch (const uno::Exception& e)
    2281             :             {
    2282             : #if DEBUG
    2283             :                 std::clog << "Exception when setting property: ";
    2284             :                 std::clog << rtl::OUStringToOString(
    2285             :                     pTableProperties[nProperty].Name, RTL_TEXTENCODING_UTF8)
    2286             :                     .getStr();
    2287             :                 std::clog << ". Message: ";
    2288             :                 std::clog << rtl::OUStringToOString( e.Message,
    2289             :                     RTL_TEXTENCODING_UTF8 ).getStr();
    2290             :                 std::clog << std::endl;
    2291             : #else
    2292             :                 (void)e;
    2293             : #endif
    2294             :             }
    2295             :         }
    2296             : 
    2297             :         //apply row properties
    2298          46 :         const uno::Reference< table::XTableRows >  xRows = xRet->getRows();
    2299             : 
    2300             :         const beans::PropertyValues* pRowProperties =
    2301          46 :             rRowProperties.getConstArray();
    2302         114 :         for (sal_Int32 nRow = 0; nRow < xRows->getCount(); ++nRow)
    2303             :         {
    2304          68 :             if( nRow >= rRowProperties.getLength())
    2305             :             {
    2306           0 :                 break;
    2307             :             }
    2308          68 :             lcl_ApplyRowProperties(pRowProperties[nRow],
    2309         136 :                 xRows->getByIndex(nRow), aRowSeparators[nRow]);
    2310             :         }
    2311             : 
    2312             : #if OSL_DEBUG_LEVEL > 0
    2313             :         lcl_DebugCellProperties(rCellProperties);
    2314             : #endif
    2315             : 
    2316             :         //apply cell properties
    2317         114 :         for (sal_Int32 nRow = 0; nRow < rCellProperties.getLength(); ++nRow)
    2318             :         {
    2319             :             const uno::Sequence< beans::PropertyValues > aCurrentRow =
    2320          68 :                 rCellProperties[nRow];
    2321          68 :             sal_Int32 nCells = aCurrentRow.getLength();
    2322         332 :             for (sal_Int32  nCell = 0; nCell < nCells; ++nCell)
    2323             :             {
    2324             :                 lcl_ApplyCellProperties(nCell,
    2325         264 :                     aRowSeparators[nRow], aCurrentRow[nCell],
    2326         264 :                     pTextTable->getCellByPosition(nCell, nRow),
    2327         528 :                     aMergedCells);
    2328             :             }
    2329          68 :         }
    2330             :         // now that the cell properties are set the vertical merge values
    2331             :         // have to be applied
    2332          46 :         lcl_MergeCells(aMergedCells);
    2333             :     }
    2334           0 :     catch (const lang::WrappedTargetException&)
    2335             :     {
    2336             :     }
    2337           0 :     catch (const lang::IndexOutOfBoundsException&)
    2338             :     {
    2339             :     }
    2340             : 
    2341          46 :     return xRet;
    2342             : }
    2343             : 
    2344             : 
    2345             : void SAL_CALL
    2346           4 : SwXText::copyText(
    2347             :     const uno::Reference< text::XTextCopy >& xSource )
    2348             : throw (uno::RuntimeException)
    2349             : {
    2350           4 :     SolarMutexGuard aGuard;
    2351             : 
    2352           4 :     uno::Reference< text::XText > const xText(xSource, uno::UNO_QUERY_THROW);
    2353             :     uno::Reference< text::XTextCursor > const xCursor =
    2354           4 :         xText->createTextCursor();
    2355           4 :     xCursor->gotoEnd( sal_True );
    2356             : 
    2357             :     uno::Reference< lang::XUnoTunnel > const xCursorTunnel(xCursor,
    2358           4 :         uno::UNO_QUERY_THROW);
    2359             : 
    2360             :     OTextCursorHelper *const pCursor =
    2361           4 :         ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCursorTunnel);
    2362           4 :     if (!pCursor)
    2363             :     {
    2364           0 :         throw uno::RuntimeException();
    2365             :     }
    2366             : 
    2367           4 :     SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
    2368           4 :     SwPosition rPos( rNdIndex );
    2369           4 :     m_pImpl->m_pDoc->CopyRange( *pCursor->GetPaM(), rPos, false );
    2370           4 : }
    2371             : 
    2372             : 
    2373             : /******************************************************************
    2374             :  * SwXBodyText
    2375             :  ******************************************************************/
    2376         234 : SwXBodyText::SwXBodyText(SwDoc *const pDoc)
    2377         234 :     : SwXText(pDoc, CURSOR_BODY)
    2378             : {
    2379         234 : }
    2380             : 
    2381         128 : SwXBodyText::~SwXBodyText()
    2382             : {
    2383         128 : }
    2384             : 
    2385             : OUString SAL_CALL
    2386           0 : SwXBodyText::getImplementationName() throw (uno::RuntimeException)
    2387             : {
    2388           0 :     return C2U("SwXBodyText");
    2389             : }
    2390             : 
    2391             : static char const*const g_ServicesBodyText[] =
    2392             : {
    2393             :     "com.sun.star.text.Text",
    2394             : };
    2395             : 
    2396             : static const size_t g_nServicesBodyText(
    2397             :     sizeof(g_ServicesBodyText)/sizeof(g_ServicesBodyText[0]));
    2398             : 
    2399           0 : sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName)
    2400             : throw (uno::RuntimeException)
    2401             : {
    2402             :     return ::sw::SupportsServiceImpl(
    2403           0 :             g_nServicesBodyText, g_ServicesBodyText, rServiceName);
    2404             : }
    2405             : 
    2406             : uno::Sequence< OUString > SAL_CALL
    2407           0 : SwXBodyText::getSupportedServiceNames() throw (uno::RuntimeException)
    2408             : {
    2409             :     return ::sw::GetSupportedServiceNamesImpl(
    2410           0 :             g_nServicesBodyText, g_ServicesBodyText);
    2411             : }
    2412             : 
    2413             : uno::Any SAL_CALL
    2414         400 : SwXBodyText::queryAggregation(const uno::Type& rType)
    2415             : throw (uno::RuntimeException)
    2416             : {
    2417         400 :     uno::Any aRet;
    2418         400 :     if (rType == container::XEnumerationAccess::static_type())
    2419             :     {
    2420         400 :         aRet <<= uno::Reference< container::XEnumerationAccess >(this);
    2421             :     }
    2422           0 :     else if (rType == container::XElementAccess::static_type())
    2423             :     {
    2424           0 :         aRet <<= uno::Reference< container::XElementAccess >(this);
    2425             :     }
    2426           0 :     else if (rType == lang::XServiceInfo::static_type())
    2427             :     {
    2428           0 :         aRet <<= uno::Reference< lang::XServiceInfo >(this);
    2429             :     }
    2430             :     else
    2431             :     {
    2432           0 :         aRet = SwXText::queryInterface( rType );
    2433             :     }
    2434         400 :     if(aRet.getValueType() == ::getCppuVoidType())
    2435             :     {
    2436           0 :         aRet = OWeakAggObject::queryAggregation( rType );
    2437             :     }
    2438         400 :     return aRet;
    2439             : }
    2440             : 
    2441             : uno::Sequence< uno::Type > SAL_CALL
    2442           0 : SwXBodyText::getTypes() throw (uno::RuntimeException)
    2443             : {
    2444           0 :     const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes();
    2445           0 :     const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
    2446           0 :     return ::comphelper::concatSequences(aTypes, aTextTypes);
    2447             : }
    2448             : 
    2449             : namespace
    2450             : {
    2451             :     class theSwXBodyTextImplementationId : public rtl::Static< UnoTunnelIdInit, theSwXBodyTextImplementationId> {};
    2452             : }
    2453             : 
    2454             : uno::Sequence< sal_Int8 > SAL_CALL
    2455           0 : SwXBodyText::getImplementationId() throw (uno::RuntimeException)
    2456             : {
    2457           0 :     return theSwXBodyTextImplementationId::get().getSeq();
    2458             : }
    2459             : 
    2460             : uno::Any SAL_CALL
    2461        1105 : SwXBodyText::queryInterface(const uno::Type& rType)
    2462             : throw (uno::RuntimeException)
    2463             : {
    2464        1105 :     const uno::Any ret = SwXText::queryInterface(rType);
    2465        1105 :     return (ret.getValueType() == ::getCppuVoidType())
    2466             :         ?   SwXBodyText_Base::queryInterface(rType)
    2467        1105 :         :   ret;
    2468             : }
    2469             : 
    2470         971 : SwXTextCursor * SwXBodyText::CreateTextCursor(const bool bIgnoreTables)
    2471             : {
    2472         971 :     if(!IsValid())
    2473             :     {
    2474           0 :         return 0;
    2475             :     }
    2476             : 
    2477             :     // the cursor has to skip tables contained in this text
    2478         971 :     SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent());
    2479         971 :     aPam.Move( fnMoveBackward, fnGoDoc );
    2480         971 :     if (!bIgnoreTables)
    2481             :     {
    2482         971 :         SwTableNode * pTblNode = aPam.GetNode()->FindTableNode();
    2483         971 :         SwCntntNode * pCont = 0;
    2484        1968 :         while (pTblNode)
    2485             :         {
    2486          26 :             aPam.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
    2487          26 :             pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
    2488          26 :             pTblNode = pCont->FindTableNode();
    2489             :         }
    2490         971 :         if (pCont)
    2491             :         {
    2492          25 :             aPam.GetPoint()->nContent.Assign(pCont, 0);
    2493             :         }
    2494             :     }
    2495         971 :     return new SwXTextCursor(*GetDoc(), this, CURSOR_BODY, *aPam.GetPoint());
    2496             : }
    2497             : 
    2498             : uno::Reference< text::XTextCursor > SAL_CALL
    2499         971 : SwXBodyText::createTextCursor() throw (uno::RuntimeException)
    2500             : {
    2501         971 :     SolarMutexGuard aGuard;
    2502             : 
    2503             :     const uno::Reference< text::XTextCursor > xRef(
    2504         971 :             static_cast<text::XWordCursor*>(CreateTextCursor(false)) );
    2505         971 :     if (!xRef.is())
    2506             :     {
    2507           0 :         uno::RuntimeException aRuntime;
    2508           0 :         aRuntime.Message = C2U(cInvalidObject);
    2509           0 :         throw aRuntime;
    2510             :     }
    2511         971 :     return xRef;
    2512             : }
    2513             : 
    2514             : uno::Reference< text::XTextCursor > SAL_CALL
    2515         173 : SwXBodyText::createTextCursorByRange(
    2516             :     const uno::Reference< text::XTextRange > & xTextPosition)
    2517             : throw (uno::RuntimeException)
    2518             : {
    2519         173 :     SolarMutexGuard aGuard;
    2520             : 
    2521         173 :     if(!IsValid())
    2522             :     {
    2523           0 :         uno::RuntimeException aRuntime;
    2524           0 :         aRuntime.Message = C2U(cInvalidObject);
    2525           0 :         throw aRuntime;
    2526             :     }
    2527             : 
    2528         173 :     uno::Reference< text::XTextCursor >  aRef;
    2529         173 :     SwUnoInternalPaM aPam(*GetDoc());
    2530         173 :     if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
    2531             :     {
    2532         171 :         if ( !aPam.GetNode()->GetTxtNode() )
    2533           0 :             throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Invalid text range") ), uno::Reference< uno::XInterface >() );
    2534             : 
    2535         171 :         SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
    2536             : 
    2537         171 :         SwStartNode* p1 = aPam.GetNode()->StartOfSectionNode();
    2538             :         //document starts with a section?
    2539         343 :         while(p1->IsSectionNode())
    2540             :         {
    2541           1 :             p1 = p1->StartOfSectionNode();
    2542             :         }
    2543         171 :         SwStartNode *const p2 = rNode.StartOfSectionNode();
    2544             : 
    2545         171 :         if(p1 == p2)
    2546             :         {
    2547             :             aRef = static_cast<text::XWordCursor*>(
    2548         171 :                     new SwXTextCursor(*GetDoc(), this, CURSOR_BODY,
    2549         171 :                         *aPam.GetPoint(), aPam.GetMark()));
    2550             :         }
    2551             :     }
    2552         173 :     if(!aRef.is())
    2553             :     {
    2554             :         throw uno::RuntimeException( rtl::OUString::createFromAscii( "End of content node doesn't have the proper start node" ),
    2555           2 :                uno::Reference< uno::XInterface >( *this ) );
    2556             :     }
    2557         173 :     return aRef;
    2558             : }
    2559             : 
    2560             : uno::Reference< container::XEnumeration > SAL_CALL
    2561         400 : SwXBodyText::createEnumeration()
    2562             : throw (uno::RuntimeException)
    2563             : {
    2564         400 :     SolarMutexGuard aGuard;
    2565             : 
    2566         400 :     if (!IsValid())
    2567             :     {
    2568           0 :         uno::RuntimeException aRuntime;
    2569           0 :         aRuntime.Message = C2U(cInvalidObject);
    2570           0 :         throw aRuntime;
    2571             :     }
    2572             : 
    2573         400 :     SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
    2574         400 :     SwPosition aPos(rNode);
    2575             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2576             :     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
    2577         400 :         GetDoc()->CreateUnoCrsr(aPos, false));
    2578             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2579         400 :     pUnoCursor->Move(fnMoveBackward, fnGoDoc);
    2580             :     const uno::Reference< container::XEnumeration > xRet
    2581         400 :         = new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_BODY);
    2582         400 :     return xRet;
    2583             : }
    2584             : 
    2585             : uno::Type SAL_CALL
    2586           0 : SwXBodyText::getElementType() throw (uno::RuntimeException)
    2587             : {
    2588           0 :     return text::XTextRange::static_type();
    2589             : }
    2590             : 
    2591             : sal_Bool SAL_CALL
    2592           0 : SwXBodyText::hasElements() throw (uno::RuntimeException)
    2593             : {
    2594           0 :     SolarMutexGuard aGuard;
    2595             : 
    2596           0 :     if (!IsValid())
    2597             :     {
    2598           0 :         uno::RuntimeException aRuntime;
    2599           0 :         aRuntime.Message = C2U(cInvalidObject);
    2600           0 :         throw aRuntime;
    2601             :     }
    2602             : 
    2603           0 :     return sal_True;
    2604             : }
    2605             : 
    2606             : /******************************************************************
    2607             :  *  SwXHeadFootText
    2608             :  ******************************************************************/
    2609         162 : class SwXHeadFootText::Impl
    2610             :     : public SwClient
    2611             : {
    2612             : 
    2613             : public:
    2614             : 
    2615             :     bool                        m_bIsHeader;
    2616             : 
    2617          81 :     Impl(   SwXHeadFootText & /*rThis*/,
    2618             :             SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
    2619             :         : SwClient(& rHeadFootFmt)
    2620          81 :         , m_bIsHeader(bIsHeader)
    2621             :     {
    2622          81 :     }
    2623             : 
    2624         308 :     SwFrmFmt * GetHeadFootFmt() const {
    2625             :         return static_cast<SwFrmFmt*>(
    2626         308 :                 const_cast<SwModify*>(GetRegisteredIn()));
    2627             :     }
    2628             : 
    2629         220 :     SwFrmFmt & GetHeadFootFmtOrThrow() {
    2630         220 :         SwFrmFmt *const pFmt( GetHeadFootFmt() );
    2631         220 :         if (!pFmt) {
    2632             :             throw uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
    2633           0 :                     "SwXHeadFootText: disposed or invalid")), 0);
    2634             :         }
    2635         220 :         return *pFmt;
    2636             :     }
    2637             : protected:
    2638             :     // SwClient
    2639             :     virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew);
    2640             : 
    2641             : };
    2642             : 
    2643           0 : void SwXHeadFootText::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
    2644             : {
    2645           0 :     ClientModify(this, pOld, pNew);
    2646           0 : }
    2647             : 
    2648         338 : bool SwXHeadFootText::IsXHeadFootText(SwClient *const pClient)
    2649             : {
    2650         338 :     return 0 != dynamic_cast<SwXHeadFootText::Impl*>(pClient);
    2651             : }
    2652             : 
    2653             : uno::Reference< text::XText >
    2654          93 : SwXHeadFootText::CreateXHeadFootText(
    2655             :         SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
    2656             : {
    2657             :     // re-use existing SwXHeadFootText
    2658             :     // #i105557#: do not iterate over the registered clients: race condition
    2659          93 :     uno::Reference< text::XText > xText(rHeadFootFmt.GetXObject(),
    2660          93 :             uno::UNO_QUERY);
    2661          93 :     if (!xText.is())
    2662             :     {
    2663             :         SwXHeadFootText *const pXHFT(
    2664          81 :                 new SwXHeadFootText(rHeadFootFmt, bIsHeader));
    2665          81 :         xText.set(pXHFT);
    2666          81 :         rHeadFootFmt.SetXObject(xText);
    2667             :     }
    2668          93 :     return xText;
    2669             : }
    2670             : 
    2671          81 : SwXHeadFootText::SwXHeadFootText(SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
    2672             :     : SwXText(rHeadFootFmt.GetDoc(),
    2673             :             (bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER)
    2674          81 :     , m_pImpl( new SwXHeadFootText::Impl(*this, rHeadFootFmt, bIsHeader) )
    2675             : {
    2676          81 : }
    2677             : 
    2678         162 : SwXHeadFootText::~SwXHeadFootText()
    2679             : {
    2680         162 : }
    2681             : 
    2682             : OUString SAL_CALL
    2683           0 : SwXHeadFootText::getImplementationName() throw (uno::RuntimeException)
    2684             : {
    2685           0 :     return C2U("SwXHeadFootText");
    2686             : }
    2687             : 
    2688             : static char const*const g_ServicesHeadFootText[] =
    2689             : {
    2690             :     "com.sun.star.text.Text",
    2691             : };
    2692             : 
    2693           0 : sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName)
    2694             : throw (uno::RuntimeException)
    2695             : {
    2696             :     return ::sw::SupportsServiceImpl(
    2697             :             SAL_N_ELEMENTS(g_ServicesHeadFootText),
    2698           0 :             g_ServicesHeadFootText, rServiceName);
    2699             : }
    2700             : 
    2701             : uno::Sequence< OUString > SAL_CALL
    2702           0 : SwXHeadFootText::getSupportedServiceNames() throw (uno::RuntimeException)
    2703             : {
    2704             :     return ::sw::GetSupportedServiceNamesImpl(
    2705             :             SAL_N_ELEMENTS(g_ServicesHeadFootText),
    2706           0 :             g_ServicesHeadFootText);
    2707             : }
    2708             : 
    2709          88 : const SwStartNode *SwXHeadFootText::GetStartNode() const
    2710             : {
    2711          88 :     const SwStartNode *pSttNd = 0;
    2712          88 :     SwFrmFmt *const pHeadFootFmt = m_pImpl->GetHeadFootFmt();
    2713          88 :     if(pHeadFootFmt)
    2714             :     {
    2715          88 :         const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
    2716          88 :         if( rFlyCntnt.GetCntntIdx() )
    2717             :         {
    2718          88 :             pSttNd = rFlyCntnt.GetCntntIdx()->GetNode().GetStartNode();
    2719             :         }
    2720             :     }
    2721          88 :     return pSttNd;
    2722             : }
    2723             : 
    2724             : uno::Reference< text::XTextCursor >
    2725          66 : SwXHeadFootText::CreateCursor() throw (uno::RuntimeException)
    2726             : {
    2727          66 :     return createTextCursor();
    2728             : }
    2729             : 
    2730             : uno::Sequence< uno::Type > SAL_CALL
    2731           0 : SwXHeadFootText::getTypes() throw (uno::RuntimeException)
    2732             : {
    2733           0 :     const uno::Sequence< uno::Type > aTypes = SwXHeadFootText_Base::getTypes();
    2734           0 :     const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
    2735           0 :     return ::comphelper::concatSequences(aTypes, aTextTypes);
    2736             : }
    2737             : 
    2738             : namespace
    2739             : {
    2740             :     class theSwXHeadFootTextImplementationId : public rtl::Static< UnoTunnelIdInit, theSwXHeadFootTextImplementationId > {};
    2741             : }
    2742             : 
    2743             : uno::Sequence< sal_Int8 > SAL_CALL
    2744           0 : SwXHeadFootText::getImplementationId() throw (uno::RuntimeException)
    2745             : {
    2746           0 :     return theSwXHeadFootTextImplementationId::get().getSeq();
    2747             : }
    2748             : 
    2749             : uno::Any SAL_CALL
    2750         589 : SwXHeadFootText::queryInterface(const uno::Type& rType)
    2751             : throw (uno::RuntimeException)
    2752             : {
    2753         589 :     const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType);
    2754         589 :     return (ret.getValueType() == ::getCppuVoidType())
    2755             :         ?   SwXText::queryInterface(rType)
    2756         589 :         :   ret;
    2757             : }
    2758             : 
    2759             : uno::Reference< text::XTextCursor > SAL_CALL
    2760         161 : SwXHeadFootText::createTextCursor() throw (uno::RuntimeException)
    2761             : {
    2762         161 :     SolarMutexGuard aGuard;
    2763             : 
    2764         161 :     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
    2765             : 
    2766         161 :     uno::Reference< text::XTextCursor > xRet;
    2767         161 :     const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
    2768         161 :     const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
    2769         161 :     SwPosition aPos(rNode);
    2770         161 :     SwXTextCursor *const pXCursor = new SwXTextCursor(*GetDoc(), this,
    2771         161 :             (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER, aPos);
    2772         161 :     SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor();
    2773         161 :     pUnoCrsr->Move(fnMoveForward, fnGoNode);
    2774             : 
    2775             :     // save current start node to be able to check if there is content
    2776             :     // after the table - otherwise the cursor would be in the body text!
    2777             :     SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType(
    2778         161 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2779             :     // is there a table here?
    2780         161 :     SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
    2781         161 :     SwCntntNode* pCont = 0;
    2782         323 :     while (pTblNode)
    2783             :     {
    2784           1 :         pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
    2785           1 :         pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
    2786           1 :         pTblNode = pCont->FindTableNode();
    2787             :     }
    2788         161 :     if (pCont)
    2789             :     {
    2790           1 :         pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
    2791             :     }
    2792             :     SwStartNode const*const pNewStartNode =
    2793             :         pUnoCrsr->GetNode()->FindSttNodeByType(
    2794         161 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2795         161 :     if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
    2796             :     {
    2797           0 :         uno::RuntimeException aExcept;
    2798           0 :         aExcept.Message = S2U("no text available");
    2799           0 :         throw aExcept;
    2800             :     }
    2801         161 :     xRet = static_cast<text::XWordCursor*>(pXCursor);
    2802         161 :     return xRet;
    2803             : }
    2804             : 
    2805             : uno::Reference< text::XTextCursor > SAL_CALL
    2806          35 : SwXHeadFootText::createTextCursorByRange(
    2807             :     const uno::Reference< text::XTextRange > & xTextPosition)
    2808             : throw (uno::RuntimeException)
    2809             : {
    2810          35 :     SolarMutexGuard aGuard;
    2811             : 
    2812          35 :     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
    2813             : 
    2814          35 :     SwUnoInternalPaM aPam(*GetDoc());
    2815          35 :     if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
    2816             :     {
    2817           0 :         uno::RuntimeException aRuntime;
    2818           0 :         aRuntime.Message = C2U(cInvalidObject);
    2819           0 :         throw aRuntime;
    2820             :     }
    2821             : 
    2822          35 :     uno::Reference< text::XTextCursor >  xRet;
    2823          35 :     SwNode& rNode = rHeadFootFmt.GetCntnt().GetCntntIdx()->GetNode();
    2824          35 :     SwPosition aPos(rNode);
    2825          35 :     SwPaM aHFPam(aPos);
    2826          35 :     aHFPam.Move(fnMoveForward, fnGoNode);
    2827             :     SwStartNode *const pOwnStartNode = aHFPam.GetNode()->FindSttNodeByType(
    2828          35 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2829             :     SwStartNode *const p1 = aPam.GetNode()->FindSttNodeByType(
    2830          35 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2831          35 :     if (p1 == pOwnStartNode)
    2832             :     {
    2833             :         xRet = static_cast<text::XWordCursor*>(
    2834          35 :                 new SwXTextCursor(*GetDoc(), this,
    2835          35 :                     (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER,
    2836          70 :                     *aPam.GetPoint(), aPam.GetMark()));
    2837             :     }
    2838          35 :     return xRet;
    2839             : }
    2840             : 
    2841             : uno::Reference< container::XEnumeration > SAL_CALL
    2842          24 : SwXHeadFootText::createEnumeration()
    2843             : throw (uno::RuntimeException)
    2844             : {
    2845          24 :     SolarMutexGuard aGuard;
    2846             : 
    2847          24 :     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
    2848             : 
    2849          24 :     uno::Reference< container::XEnumeration >  aRef;
    2850          24 :     const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
    2851          24 :     const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
    2852          24 :     SwPosition aPos(rNode);
    2853             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2854             :     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
    2855          24 :         GetDoc()->CreateUnoCrsr(aPos, false));
    2856             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2857          24 :     pUnoCursor->Move(fnMoveForward, fnGoNode);
    2858             :     aRef = new SwXParagraphEnumeration(this, pUnoCursor,
    2859          24 :                 (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER);
    2860             : 
    2861          24 :     return aRef;
    2862             : }
    2863             : 
    2864             : uno::Type SAL_CALL
    2865           0 : SwXHeadFootText::getElementType() throw (uno::RuntimeException)
    2866             : {
    2867           0 :     return text::XTextRange::static_type();
    2868             : }
    2869             : 
    2870           0 : sal_Bool SAL_CALL SwXHeadFootText::hasElements() throw (uno::RuntimeException)
    2871             : {
    2872           0 :     return sal_True;
    2873          30 : }
    2874             : 
    2875             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10