LCOV - code coverage report
Current view: top level - sw/source/core/unocore - unotext.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 961 1265 76.0 %
Date: 2014-04-11 Functions: 87 101 86.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10