LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/unocore - unotext.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 936 1266 73.9 %
Date: 2013-07-09 Functions: 85 101 84.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <stdlib.h>
      21             : 
      22             : #include <memory>
      23             : #include <iostream>
      24             : 
      25             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      26             : #include <com/sun/star/text/ControlCharacter.hpp>
      27             : #include <com/sun/star/text/TableColumnSeparator.hpp>
      28             : 
      29             : #include <osl/mutex.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : #include <comphelper/sequence.hxx>
      32             : #include <comphelper/servicehelper.hxx>
      33             : 
      34             : #include <cmdid.h>
      35             : #include <unotextbodyhf.hxx>
      36             : #include <unotext.hxx>
      37             : #include <unotextrange.hxx>
      38             : #include <unotextcursor.hxx>
      39             : #include <unosection.hxx>
      40             : #include <unobookmark.hxx>
      41             : #include <unorefmark.hxx>
      42             : #include <unoport.hxx>
      43             : #include <unotbl.hxx>
      44             : #include <unoidx.hxx>
      45             : #include <unocoll.hxx>
      46             : #include <unoframe.hxx>
      47             : #include <unofield.hxx>
      48             : #include <unometa.hxx>
      49             : #include <unodraw.hxx>
      50             : #include <unoredline.hxx>
      51             : #include <unomap.hxx>
      52             : #include <unoprnms.hxx>
      53             : #include <unoparagraph.hxx>
      54             : #include <unocrsrhelper.hxx>
      55             : #include <docsh.hxx>
      56             : #include <docary.hxx>
      57             : #include <doc.hxx>
      58             : #include <IDocumentUndoRedo.hxx>
      59             : #include <redline.hxx>
      60             : #include <swundo.hxx>
      61             : #include <section.hxx>
      62             : #include <IMark.hxx>
      63             : #include <fmtanchr.hxx>
      64             : #include <fmtcntnt.hxx>
      65             : #include <crsskip.hxx>
      66             : #include <ndtxt.hxx>
      67             : 
      68             : 
      69             : using namespace ::com::sun::star;
      70             : 
      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        2328 :     Impl(   SwXText & rThis,
      88             :             SwDoc *const pDoc, const enum CursorType eType)
      89             :         : m_rThis(rThis)
      90        2328 :         , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT))
      91             :         , m_eType(eType)
      92             :         , m_pDoc(pDoc)
      93        4656 :         , m_bIsValid(0 != pDoc)
      94             :     {
      95        2328 :     }
      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        2328 : SwXText::SwXText(SwDoc *const pDoc, const enum CursorType eType)
     126        2328 :     : m_pImpl( new SwXText::Impl(*this, pDoc, eType) )
     127             : {
     128        2328 : }
     129             : 
     130        2326 : SwXText::~SwXText()
     131             : {
     132        2326 : }
     133             : 
     134        7160 : const SwDoc * SwXText::GetDoc() const
     135             : {
     136        7160 :     return m_pImpl->m_pDoc;
     137             : }
     138       49446 :       SwDoc * SwXText::GetDoc()
     139             : {
     140       49446 :     return m_pImpl->m_pDoc;
     141             : }
     142             : 
     143       11198 : bool SwXText::IsValid() const
     144             : {
     145       11198 :     return m_pImpl->m_bIsValid;
     146             : }
     147             : 
     148          91 : void SwXText::Invalidate()
     149             : {
     150          91 :     m_pImpl->m_bIsValid = false;
     151          91 : }
     152             : 
     153         204 : void SwXText::SetDoc(SwDoc *const pDoc)
     154             : {
     155             :     OSL_ENSURE(!m_pImpl->m_pDoc || !pDoc,
     156             :         "SwXText::SetDoc: already have a doc?");
     157         204 :     m_pImpl->m_pDoc = pDoc;
     158         204 :     m_pImpl->m_bIsValid = (0 != pDoc);
     159         204 : }
     160             : 
     161             : void
     162           0 : SwXText::PrepareForAttach(uno::Reference< text::XTextRange > &, const SwPaM &)
     163             : {
     164           0 : }
     165             : 
     166        3463 : 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        3463 :     return false;
     171             : }
     172             : 
     173        7160 : const SwStartNode *SwXText::GetStartNode() const
     174             : {
     175        7160 :     return GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
     176             : }
     177             : 
     178             : uno::Reference< text::XTextCursor >
     179        2826 : SwXText::CreateCursor() throw (uno::RuntimeException)
     180             : {
     181        2826 :     uno::Reference< text::XTextCursor >  xRet;
     182        2826 :     if(IsValid())
     183             :     {
     184        2826 :         SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
     185        2826 :         SwPosition aPos(rNode);
     186             :         xRet = static_cast<text::XWordCursor*>(
     187        2826 :                 new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos));
     188        2826 :         xRet->gotoStart(sal_False);
     189             :     }
     190        2826 :     return xRet;
     191             : }
     192             : 
     193             : uno::Any SAL_CALL
     194        4110 : SwXText::queryInterface(const uno::Type& rType) throw (uno::RuntimeException)
     195             : {
     196        4110 :     uno::Any aRet;
     197        4110 :     if (rType == text::XText::static_type())
     198             :     {
     199         643 :         aRet <<= uno::Reference< text::XText >(this);
     200             :     }
     201        3467 :     else if (rType == text::XSimpleText::static_type())
     202             :     {
     203           3 :         aRet <<= uno::Reference< text::XSimpleText >(this);
     204             :     }
     205        3464 :     else if (rType == text::XTextRange::static_type())
     206             :     {
     207          77 :         aRet <<= uno::Reference< text::XTextRange>(this);
     208             :     }
     209        3387 :     else if (rType == text::XTextRangeCompare::static_type())
     210             :     {
     211           6 :         aRet <<= uno::Reference< text::XTextRangeCompare >(this);
     212             :     }
     213        3381 :     else if (rType == lang::XTypeProvider::static_type())
     214             :     {
     215           3 :         aRet <<= uno::Reference< lang::XTypeProvider >(this);
     216             :     }
     217        3378 :     else if (rType == text::XRelativeTextContentInsert::static_type())
     218             :     {
     219           5 :         aRet <<= uno::Reference< text::XRelativeTextContentInsert >(this);
     220             :     }
     221        3373 :     else if (rType == text::XRelativeTextContentRemove::static_type())
     222             :     {
     223           0 :         aRet <<= uno::Reference< text::XRelativeTextContentRemove >(this);
     224             :     }
     225        3373 :     else if (rType == beans::XPropertySet::static_type())
     226             :     {
     227          45 :         aRet <<= uno::Reference< beans::XPropertySet >(this);
     228             :     }
     229        3328 :     else if (rType == lang::XUnoTunnel::static_type())
     230             :     {
     231         409 :         aRet <<= uno::Reference< lang::XUnoTunnel >(this);
     232             :     }
     233        2919 :     else if (rType == text::XTextAppendAndConvert::static_type())
     234             :     {
     235         647 :         aRet <<= uno::Reference< text::XTextAppendAndConvert >(this);
     236             :     }
     237        2272 :     else if (rType == text::XTextAppend::static_type())
     238             :     {
     239         464 :         aRet <<= uno::Reference< text::XTextAppend >(this);
     240             :     }
     241        1808 :     else if (rType == text::XTextPortionAppend::static_type())
     242             :     {
     243           0 :         aRet <<= uno::Reference< text::XTextPortionAppend >(this);
     244             :     }
     245        1808 :     else if (rType == text::XParagraphAppend::static_type())
     246             :     {
     247           0 :         aRet <<= uno::Reference< text::XParagraphAppend >(this);
     248             :     }
     249        1808 :     else if (rType == text::XTextConvert::static_type() )
     250             :     {
     251           0 :         aRet <<= uno::Reference< text::XTextConvert >(this);
     252             :     }
     253        1808 :     else if (rType == text::XTextContentAppend::static_type())
     254             :     {
     255           0 :         aRet <<= uno::Reference< text::XTextContentAppend >(this);
     256             :     }
     257        1808 :     else if(rType == text::XTextCopy::static_type())
     258             :     {
     259           8 :         aRet <<= uno::Reference< text::XTextCopy >( this );
     260             :     }
     261        4110 :     return aRet;
     262             : }
     263             : 
     264             : uno::Sequence< uno::Type > SAL_CALL
     265           3 : SwXText::getTypes() throw (uno::RuntimeException)
     266             : {
     267           3 :     uno::Sequence< uno::Type > aRet(12);
     268           3 :     uno::Type* pTypes = aRet.getArray();
     269           3 :     pTypes[0] = text::XText::static_type();
     270           3 :     pTypes[1] = text::XTextRangeCompare::static_type();
     271           3 :     pTypes[2] = text::XRelativeTextContentInsert::static_type();
     272           3 :     pTypes[3] = text::XRelativeTextContentRemove::static_type();
     273           3 :     pTypes[4] = lang::XUnoTunnel::static_type();
     274           3 :     pTypes[5] = beans::XPropertySet::static_type();
     275           3 :     pTypes[6] = text::XTextPortionAppend::static_type();
     276           3 :     pTypes[7] = text::XParagraphAppend::static_type();
     277           3 :     pTypes[8] = text::XTextContentAppend::static_type();
     278           3 :     pTypes[9] = text::XTextConvert::static_type();
     279           3 :     pTypes[10] = text::XTextAppend::static_type();
     280           3 :     pTypes[11] = text::XTextAppendAndConvert::static_type();
     281             : 
     282           3 :     return aRet;
     283             : }
     284             : 
     285             : // belongs the range in the text ? insert it then.
     286             : void SAL_CALL
     287        3111 : SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange,
     288             :     const OUString& rString, sal_Bool bAbsorb)
     289             : throw (uno::RuntimeException)
     290             : {
     291        3111 :     SolarMutexGuard aGuard;
     292             : 
     293        3111 :     if (!xTextRange.is())
     294             :     {
     295           1 :         throw uno::RuntimeException();
     296             :     }
     297        3110 :     if (!GetDoc())
     298             :     {
     299           0 :         throw uno::RuntimeException();
     300             :     }
     301             :     const uno::Reference<lang::XUnoTunnel> xRangeTunnel(xTextRange,
     302        6220 :             uno::UNO_QUERY);
     303             :     SwXTextRange *const pRange =
     304        3110 :         ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
     305             :     OTextCursorHelper *const pCursor =
     306        3110 :         ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
     307        3110 :     if ((!pRange  || pRange ->GetDoc() != GetDoc()) &&
     308        3110 :         (!pCursor || pCursor->GetDoc() != GetDoc()))
     309             :     {
     310           0 :         throw uno::RuntimeException();
     311             :     }
     312             : 
     313        3110 :     const SwStartNode *const pOwnStartNode = GetStartNode();
     314        6220 :     SwPaM aPam(GetDoc()->GetNodes());
     315        3110 :     const SwPaM * pPam(0);
     316        3110 :     if (pCursor)
     317             :     {
     318        3110 :         pPam = pCursor->GetPaM();
     319             :     }
     320             :     else // pRange
     321             :     {
     322           0 :         if (pRange->GetPositions(aPam))
     323             :         {
     324           0 :             pPam = &aPam;
     325             :         }
     326             :     }
     327        3110 :     if (!pPam)
     328             :     {
     329           0 :         throw uno::RuntimeException();
     330             :     }
     331             : 
     332        3110 :     const SwStartNode* pTmp(pPam->GetNode()->StartOfSectionNode());
     333        6399 :     while (pTmp && pTmp->IsSectionNode())
     334             :     {
     335         179 :         pTmp = pTmp->StartOfSectionNode();
     336             :     }
     337        3110 :     if (!pOwnStartNode || (pOwnStartNode != pTmp))
     338             :     {
     339           0 :         throw uno::RuntimeException();
     340             :     }
     341             : 
     342        3110 :     bool bForceExpandHints( false );
     343        3110 :     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        3109 :     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          93 :         if (pCursor)
     361             :         {
     362             :             SwXTextCursor * const pTextCursor(
     363          93 :                 dynamic_cast<SwXTextCursor*>(pCursor) );
     364          93 :             if (pTextCursor)
     365             :             {
     366          93 :                 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        3016 :         UnoActionContext aContext(GetDoc());
     383        6032 :         SwPaM aInsertPam(*pPam->Start());
     384        6032 :         ::sw::GroupUndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
     385             :         SwUnoCursorHelper::DocInsertStringSplitCR(
     386        6032 :             *GetDoc(), aInsertPam, rString, bForceExpandHints );
     387        3111 :     }
     388        3109 : }
     389             : 
     390             : void SAL_CALL
     391         875 : SwXText::insertControlCharacter(
     392             :         const uno::Reference< text::XTextRange > & xTextRange,
     393             :         sal_Int16 nControlCharacter, sal_Bool bAbsorb)
     394             : throw (lang::IllegalArgumentException, uno::RuntimeException)
     395             : {
     396         875 :     SolarMutexGuard aGuard;
     397             : 
     398         875 :     if (!xTextRange.is())
     399             :     {
     400           1 :         throw lang::IllegalArgumentException();
     401             :     }
     402         874 :     if (!GetDoc())
     403             :     {
     404           0 :         throw uno::RuntimeException();
     405             :     }
     406             : 
     407        1748 :     SwUnoInternalPaM aPam(*GetDoc());
     408         874 :     if (!::sw::XTextRangeToSwPaM(aPam, xTextRange))
     409             :     {
     410           0 :         throw uno::RuntimeException();
     411             :     }
     412         874 :     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         873 :         : IDocumentContentOperations::INS_EMPTYEXPAND;
     420             : 
     421        1746 :     SwPaM aTmp(*aPam.Start());
     422         873 :     if (bAbsorb && aPam.HasMark())
     423             :     {
     424           0 :         m_pImpl->m_pDoc->DeleteAndJoin(aPam);
     425             :     }
     426             : 
     427         873 :     sal_Unicode cIns = 0;
     428         873 :     switch (nControlCharacter)
     429             :     {
     430             :         case text::ControlCharacter::PARAGRAPH_BREAK :
     431             :             // a table cell now becomes an ordinary text cell!
     432         226 :             m_pImpl->m_pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
     433         226 :             m_pImpl->m_pDoc->SplitNode( *aTmp.GetPoint(), sal_False );
     434         226 :             break;
     435             :         case text::ControlCharacter::APPEND_PARAGRAPH:
     436             :         {
     437         571 :             m_pImpl->m_pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
     438         571 :             m_pImpl->m_pDoc->AppendTxtNode( *aTmp.GetPoint() );
     439             : 
     440             :             const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
     441         571 :                     xTextRange, uno::UNO_QUERY);
     442             :             SwXTextRange *const pRange =
     443         571 :                 ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
     444             :             OTextCursorHelper *const pCursor =
     445             :                 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(
     446         571 :                             xRangeTunnel);
     447         571 :             if (pRange)
     448             :             {
     449           0 :                 pRange->SetPositions(aTmp);
     450             :             }
     451         571 :             else if (pCursor)
     452             :             {
     453         571 :                 SwPaM *const pCrsr = pCursor->GetPaM();
     454         571 :                 *pCrsr->GetPoint() = *aTmp.GetPoint();
     455         571 :                 pCrsr->DeleteMark();
     456         571 :             }
     457             :         }
     458         571 :         break;
     459          74 :         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         873 :     if (cIns)
     465             :     {
     466          76 :         m_pImpl->m_pDoc->InsertString( aTmp, OUString(cIns), nInsertFlags );
     467             :     }
     468             : 
     469         873 :     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         875 :     }
     501         873 : }
     502             : 
     503             : void SAL_CALL
     504        2642 : 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)
     509             : {
     510        2642 :     SolarMutexGuard aGuard;
     511             : 
     512        2642 :     if (!xRange.is())
     513             :     {
     514           1 :         lang::IllegalArgumentException aIllegal;
     515           1 :         aIllegal.Message = "first parameter invalid;";
     516           1 :         throw aIllegal;
     517             :     }
     518        2641 :     if (!xContent.is())
     519             :     {
     520           8 :         lang::IllegalArgumentException aIllegal;
     521           8 :         aIllegal.Message += "second parameter invalid";
     522           8 :         throw aIllegal;
     523             :     }
     524        2633 :     if(!GetDoc())
     525             :     {
     526           0 :         uno::RuntimeException aRuntime;
     527           0 :         aRuntime.Message = cInvalidObject;
     528           0 :         throw aRuntime;
     529             :     }
     530             : 
     531        5266 :     SwUnoInternalPaM aPam(*GetDoc());
     532        2633 :     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        2633 :     const SwStartNode* pOwnStartNode = GetStartNode();
     541        2633 :     SwStartNodeType eSearchNodeType = SwNormalStartNode;
     542        2633 :     switch (m_pImpl->m_eType)
     543             :     {
     544           3 :         case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
     545           2 :         case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
     546           3 :         case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
     547          12 :         case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
     548           5 :         case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
     549             :         //case CURSOR_INVALID:
     550             :         //case CURSOR_BODY:
     551             :         default:
     552        2608 :             break;
     553             :     }
     554             : 
     555             :     const SwStartNode* pTmp =
     556        2633 :         aPam.GetNode()->FindSttNodeByType(eSearchNodeType);
     557             : 
     558             :     // ignore SectionNodes
     559        5286 :     while (pTmp && pTmp->IsSectionNode())
     560             :     {
     561          20 :         pTmp = pTmp->StartOfSectionNode();
     562             :     }
     563             :     // if the document starts with a section
     564        5266 :     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        2633 :     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        2633 :     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        2632 :             uno::UNO_QUERY);
     582        2632 :     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        2632 :         ::sw::UnoTunnelGetImplementation<SwXDocumentIndexMark>(xContentTunnel);
     590             :     SwXTextSection *const pSection =
     591        2632 :         ::sw::UnoTunnelGetImplementation<SwXTextSection>(xContentTunnel);
     592             :     SwXBookmark *const pBookmark =
     593        2632 :         ::sw::UnoTunnelGetImplementation<SwXBookmark>(xContentTunnel);
     594             :     SwXReferenceMark *const pReferenceMark =
     595        2632 :         ::sw::UnoTunnelGetImplementation<SwXReferenceMark>(xContentTunnel);
     596             :     SwXMeta *const pMeta =
     597        2632 :         ::sw::UnoTunnelGetImplementation<SwXMeta>(xContentTunnel);
     598             :     SwXTextField* pTextField =
     599        2632 :         ::sw::UnoTunnelGetImplementation<SwXTextField>(xContentTunnel);
     600        2632 :     if (pTextField && pTextField->GetServiceId() != SW_SERVICE_FIELDTYPE_ANNOTATION)
     601          56 :         pTextField = 0;
     602             : 
     603         625 :     const bool bAttribute = pBookmark || pDocumentIndexMark
     604        3249 :         || pSection || pReferenceMark || pMeta || pTextField;
     605             : 
     606        2632 :     if (bAbsorb && !bAttribute)
     607             :     {
     608          21 :         xRange->setString(aEmptyStr);
     609             :     }
     610             :     uno::Reference< text::XTextRange > xTempRange =
     611        5264 :         (bAttribute && bAbsorb) ? xRange : xRange->getStart();
     612        2632 :     if (bForceExpandHints)
     613             :     {
     614             :         // if necessary, replace xTempRange with a new SwXTextCursor
     615          20 :         PrepareForAttach(xTempRange, aPam);
     616             :     }
     617        7906 :     xContent->attach(xTempRange);
     618        2590 : }
     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)
     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)
     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)
     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)
     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)
     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          30 : SwXText::getText() throw (uno::RuntimeException)
     863             : {
     864          30 :     SolarMutexGuard aGuard;
     865             : 
     866          30 :     const uno::Reference< text::XText > xRet(this);
     867          30 :     return xRet;
     868             : }
     869             : 
     870             : uno::Reference< text::XTextRange > SAL_CALL
     871          65 : SwXText::getStart() throw (uno::RuntimeException)
     872             : {
     873          65 :     SolarMutexGuard aGuard;
     874             : 
     875         130 :     const uno::Reference< text::XTextCursor > xRef = CreateCursor();
     876          65 :     if(!xRef.is())
     877             :     {
     878           0 :         uno::RuntimeException aRuntime;
     879           0 :         aRuntime.Message = cInvalidObject;
     880           0 :         throw aRuntime;
     881             :     }
     882          65 :     xRef->gotoStart(sal_False);
     883          65 :     const uno::Reference< text::XTextRange > xRet(xRef, uno::UNO_QUERY);
     884         130 :     return xRet;
     885             : }
     886             : 
     887             : uno::Reference< text::XTextRange > SAL_CALL
     888        1939 : SwXText::getEnd() throw (uno::RuntimeException)
     889             : {
     890        1939 :     SolarMutexGuard aGuard;
     891             : 
     892        3878 :     const uno::Reference< text::XTextCursor > xRef = CreateCursor();
     893        1939 :     if(!xRef.is())
     894             :     {
     895           0 :         uno::RuntimeException aRuntime;
     896           0 :         aRuntime.Message = cInvalidObject;
     897           0 :         throw aRuntime;
     898             :     }
     899        1939 :     xRef->gotoEnd(sal_False);
     900        1939 :     const uno::Reference< text::XTextRange >  xRet(xRef, uno::UNO_QUERY);
     901        3878 :     return xRet;
     902             : }
     903             : 
     904         310 : OUString SAL_CALL SwXText::getString() throw (uno::RuntimeException)
     905             : {
     906         310 :     SolarMutexGuard aGuard;
     907             : 
     908         620 :     const uno::Reference< text::XTextCursor > xRet = CreateCursor();
     909         310 :     if(!xRet.is())
     910             :     {
     911           0 :         uno::RuntimeException aRuntime;
     912           0 :         aRuntime.Message = cInvalidObject;
     913           0 :         throw aRuntime;
     914             :     }
     915         310 :     xRet->gotoEnd(sal_True);
     916         620 :     return xRet->getString();
     917             : }
     918             : 
     919             : void SAL_CALL
     920         195 : SwXText::setString(const OUString& rString) throw (uno::RuntimeException)
     921             : {
     922         195 :     SolarMutexGuard aGuard;
     923             : 
     924         195 :     if (!GetDoc())
     925             :     {
     926           0 :         uno::RuntimeException aRuntime;
     927           0 :         aRuntime.Message = cInvalidObject;
     928           0 :         throw aRuntime;
     929             :     }
     930             : 
     931         195 :     const SwStartNode* pStartNode = GetStartNode();
     932         195 :     if (!pStartNode)
     933             :     {
     934           0 :         throw uno::RuntimeException();
     935             :     }
     936             : 
     937         195 :     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         195 :     if (CURSOR_META != m_pImpl->m_eType)
     941             :     {
     942         168 :         SwPosition aStartPos(*pStartNode);
     943         168 :         const SwEndNode* pEnd = pStartNode->EndOfSectionNode();
     944         336 :         SwNodeIndex aEndIdx(*pEnd);
     945         168 :         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         168 :         bool bInsertNodes = false;
     950         336 :         SwNodeIndex aStartIdx(*pStartNode);
     951         176 :         do
     952             :         {
     953         176 :             ++aStartIdx;
     954         176 :             SwNode& rCurrentNode = aStartIdx.GetNode();
     955         352 :             if(rCurrentNode.GetNodeType() == ND_SECTIONNODE
     956         176 :                 ||rCurrentNode.GetNodeType() == ND_TABLENODE)
     957             :             {
     958           0 :                 bInsertNodes = true;
     959           0 :                 break;
     960             :             }
     961             :         }
     962         176 :         while(aStartIdx < aEndIdx);
     963         168 :         if(bInsertNodes)
     964             :         {
     965           0 :             GetDoc()->AppendTxtNode( aStartPos );
     966           0 :             SwPosition aEndPos(aEndIdx.GetNode());
     967           0 :             SwPaM aPam(aEndPos);
     968           0 :             GetDoc()->AppendTxtNode( *aPam.Start() );
     969         168 :         }
     970             :     }
     971             : 
     972         390 :     const uno::Reference< text::XTextCursor > xRet = CreateCursor();
     973         195 :     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         195 :     xRet->gotoEnd(sal_True);
     981         195 :     xRet->setString(rString);
     982         390 :     GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
     983         195 : }
     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)
    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)
    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          47 : SwXText::getPropertySetInfo() throw(uno::RuntimeException)
    1112             : {
    1113          47 :     SolarMutexGuard g;
    1114             : 
    1115             :     static uno::Reference< beans::XPropertySetInfo > xInfo =
    1116          47 :         m_pImpl->m_rPropSet.getPropertySetInfo();
    1117          47 :     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)
    1126             : {
    1127           0 :     throw lang::IllegalArgumentException();
    1128             : }
    1129             : 
    1130             : uno::Any SAL_CALL
    1131          70 : SwXText::getPropertyValue(
    1132             :     const OUString& rPropertyName)
    1133             : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
    1134             :         uno::RuntimeException)
    1135             : {
    1136          70 :     SolarMutexGuard aGuard;
    1137             : 
    1138          70 :     if(!IsValid())
    1139             :     {
    1140           0 :         throw  uno::RuntimeException();
    1141             :     }
    1142             : 
    1143             :     SfxItemPropertySimpleEntry const*const pEntry =
    1144          70 :         m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
    1145          70 :     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          70 :     uno::Any aRet;
    1154          70 :     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          35 :             const SwRedlineTbl& rRedTbl = GetDoc()->GetRedlineTbl();
    1162          35 :             const sal_uInt16 nRedTblCount = rRedTbl.size();
    1163          35 :             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 :                     SwRedline 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          35 :         break;
    1182             :     }
    1183          70 :     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)
    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)
    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)
    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)
    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       11656 : const uno::Sequence< sal_Int8 > & SwXText::getUnoTunnelId()
    1232             : {
    1233       11656 :     return theSwXTextUnoTunnelId::get().getSeq();
    1234             : }
    1235             : 
    1236             : sal_Int64 SAL_CALL
    1237        1347 : SwXText::getSomething(const uno::Sequence< sal_Int8 >& rId)
    1238             : throw (uno::RuntimeException)
    1239             : {
    1240        1347 :     return ::sw::UnoTunnelImpl<SwXText>(rId, this);
    1241             : }
    1242             : 
    1243             : uno::Reference< text::XTextRange > SAL_CALL
    1244        1602 : SwXText::finishParagraph(
    1245             :         const uno::Sequence< beans::PropertyValue > & rProperties)
    1246             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1247             : {
    1248        1602 :     SolarMutexGuard g;
    1249             : 
    1250        1602 :     return m_pImpl->finishOrAppendParagraph(true, rProperties, uno::Reference< text::XTextRange >());
    1251             : }
    1252             : 
    1253             : uno::Reference< text::XTextRange > SAL_CALL
    1254           4 : SwXText::finishParagraphInsert(
    1255             :         const uno::Sequence< beans::PropertyValue > & rProperties,
    1256             :         const uno::Reference< text::XTextRange >& xInsertPosition)
    1257             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1258             : {
    1259           4 :     SolarMutexGuard g;
    1260             : 
    1261           4 :     return m_pImpl->finishOrAppendParagraph(true, rProperties, xInsertPosition);
    1262             : }
    1263             : 
    1264             : uno::Reference< text::XTextRange >
    1265        1606 : 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        1606 :     if (!m_bIsValid)
    1272             :     {
    1273           0 :         throw  uno::RuntimeException();
    1274             :     }
    1275             : 
    1276        1606 :     const SwStartNode* pStartNode = m_rThis.GetStartNode();
    1277        1606 :     if(!pStartNode)
    1278             :     {
    1279           0 :         throw  uno::RuntimeException();
    1280             :     }
    1281             : 
    1282        1606 :     uno::Reference< text::XTextRange > xRet;
    1283        1606 :     bool bIllegalException = false;
    1284        1606 :     bool bRuntimeException = false;
    1285        3212 :     OUString sMessage;
    1286        1606 :     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        3212 :             SwNodeIndex( *pStartNode->EndOfSectionNode(), -1 ) );
    1292        3212 :     SwPaM aPam(aInsertPosition);
    1293             :     // If we got a position reference, then the insert point is not the end of
    1294             :     // the document.
    1295        1606 :     if (xInsertPosition.is())
    1296             :     {
    1297           4 :         SwUnoInternalPaM aStartPam(*m_rThis.GetDoc());
    1298           4 :         ::sw::XTextRangeToSwPaM(aStartPam, xInsertPosition);
    1299           4 :         aPam = aStartPam;
    1300           4 :         aPam.SetMark();
    1301             :     }
    1302        1606 :     m_pDoc->AppendTxtNode( *aPam.GetPoint() );
    1303             :     // remove attributes from the previous paragraph
    1304        1606 :     m_pDoc->ResetAttrs(aPam);
    1305             :     // in case of finishParagraph the PaM needs to be moved to the
    1306             :     // previous paragraph
    1307        1606 :     if (bFinish)
    1308             :     {
    1309        1606 :         aPam.Move( fnMoveBackward, fnGoNode );
    1310             :     }
    1311             : #if 1 // This section should be removed in favour of the one below when it works.
    1312        1606 :     if (rProperties.getLength())
    1313             :     {
    1314             :         // now set the properties
    1315             :         SfxItemPropertySet const*const pParaPropSet =
    1316        1591 :             aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
    1317             :         const SfxItemPropertyMap &rParagraphMap =
    1318        1591 :             pParaPropSet->getPropertyMap();
    1319             : 
    1320        1591 :         const beans::PropertyValue* pValues = rProperties.getConstArray();
    1321             : 
    1322        6767 :         for (sal_Int32 nProp = 0; nProp < rProperties.getLength(); ++nProp)
    1323             :         {
    1324        5177 :             if (!rParagraphMap.getByName(pValues[nProp].Name))
    1325             :             {
    1326           0 :                 bIllegalException = true;
    1327           0 :                 break;
    1328             :             }
    1329             :             try
    1330             :             {
    1331             :                 SwUnoCursorHelper::SetPropertyValue(aPam, *pParaPropSet,
    1332        5177 :                     pValues[nProp].Name, pValues[nProp].Value);
    1333             :             }
    1334           2 :             catch (const lang::IllegalArgumentException& rIllegal)
    1335             :             {
    1336           1 :                 sMessage = rIllegal.Message;
    1337           1 :                 bIllegalException = true;
    1338           1 :                 break;
    1339             :             }
    1340           0 :             catch (const uno::RuntimeException& rRuntime)
    1341             :             {
    1342           0 :                 sMessage = rRuntime.Message;
    1343           0 :                 bRuntimeException = true;
    1344           0 :                 break;
    1345             :             }
    1346             :         }
    1347             :     }
    1348             : #else
    1349             :     try
    1350             :     {
    1351             :         SfxItemPropertySet const*const pParaPropSet =
    1352             :             aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
    1353             :         if (!bIllegalException)
    1354             :             SwUnoCursorHelper::SetPropertyValues(aPam, *pParaPropSet, rProperties);
    1355             :     }
    1356             :     catch (const lang::IllegalArgumentException& rIllegal)
    1357             :     {
    1358             :         sMessage = rIllegal.Message;
    1359             :         bIllegalException = true;
    1360             :     }
    1361             :     catch (const uno::RuntimeException& rRuntime)
    1362             :     {
    1363             :         sMessage = rRuntime.Message;
    1364             :         bRuntimeException = true;
    1365             :     }
    1366             : #endif
    1367             : 
    1368        1606 :     m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
    1369        1606 :     if (bIllegalException || bRuntimeException)
    1370             :     {
    1371           1 :         m_pDoc->GetIDocumentUndoRedo().Undo();
    1372           0 :         if (bIllegalException)
    1373             :         {
    1374           0 :             lang::IllegalArgumentException aEx;
    1375           0 :             aEx.Message = sMessage;
    1376           0 :             throw aEx;
    1377             :         }
    1378             :         else // if(bRuntimeException)
    1379             :         {
    1380           0 :             uno::RuntimeException aEx;
    1381           0 :             aEx.Message = sMessage;
    1382           0 :             throw aEx;
    1383             :         }
    1384             :     }
    1385        1605 :     SwTxtNode *const pTxtNode( aPam.Start()->nNode.GetNode().GetTxtNode() );
    1386             :     OSL_ENSURE(pTxtNode, "no SwTxtNode?");
    1387        1605 :     if (pTxtNode)
    1388             :     {
    1389             :         xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, *pTxtNode, &m_rThis),
    1390        1605 :                 uno::UNO_QUERY);
    1391             :     }
    1392             : 
    1393        3210 :     return xRet;
    1394             : }
    1395             : 
    1396             : uno::Reference< text::XTextRange > SAL_CALL
    1397        1054 : SwXText::insertTextPortion(
    1398             :         const OUString& rText,
    1399             :         const uno::Sequence< beans::PropertyValue > &
    1400             :             rCharacterAndParagraphProperties,
    1401             :         const uno::Reference<text::XTextRange>& xInsertPosition)
    1402             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1403             : {
    1404        1054 :     SolarMutexGuard aGuard;
    1405             : 
    1406        1054 :     if(!IsValid())
    1407             :     {
    1408           0 :         throw  uno::RuntimeException();
    1409             :     }
    1410        1054 :     uno::Reference< text::XTextRange > xRet;
    1411        2108 :     const uno::Reference< text::XTextCursor > xTextCursor = CreateCursor();
    1412        1054 :     xTextCursor->gotoRange(xInsertPosition, sal_False);
    1413             : 
    1414             :     const uno::Reference< lang::XUnoTunnel > xRangeTunnel(
    1415        2108 :             xTextCursor, uno::UNO_QUERY_THROW );
    1416             :     SwXTextCursor *const pTextCursor =
    1417        1054 :         ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xRangeTunnel);
    1418             : 
    1419        1054 :     bool bIllegalException = false;
    1420        1054 :     bool bRuntimeException = false;
    1421        2108 :     OUString sMessage;
    1422        1054 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
    1423             : 
    1424             : //        SwPaM aPam(*pStartNode->EndOfSectionNode());
    1425             :     //aPam.Move( fnMoveBackward, fnGoNode );
    1426        1054 :     SwUnoCrsr *const pCursor = pTextCursor->GetCursor();
    1427        1054 :     m_pImpl->m_pDoc->DontExpandFmt( *pCursor->Start() );
    1428             : 
    1429        1054 :     if (!rText.isEmpty())
    1430             :     {
    1431        1054 :         const xub_StrLen nContentPos = pCursor->GetPoint()->nContent.GetIndex();
    1432             :         SwUnoCursorHelper::DocInsertStringSplitCR(
    1433        1054 :             *m_pImpl->m_pDoc, *pCursor, rText, false);
    1434        1054 :         SwUnoCursorHelper::SelectPam(*pCursor, true);
    1435        1054 :         pCursor->GetPoint()->nContent = nContentPos;
    1436             :     }
    1437             : 
    1438             :     try
    1439             :     {
    1440             :       SfxItemPropertySet const*const pCursorPropSet =
    1441        1054 :           aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR);
    1442             :       SwUnoCursorHelper::SetPropertyValues(*pCursor, *pCursorPropSet,
    1443             :                                            rCharacterAndParagraphProperties,
    1444        1054 :                                            nsSetAttrMode::SETATTR_NOFORMATATTR);
    1445             :     }
    1446           0 :     catch (const lang::IllegalArgumentException& rIllegal)
    1447             :     {
    1448           0 :         sMessage = rIllegal.Message;
    1449           0 :         bIllegalException = true;
    1450             :     }
    1451           0 :     catch (const uno::RuntimeException& rRuntime)
    1452             :     {
    1453           0 :         sMessage = rRuntime.Message;
    1454           0 :         bRuntimeException = true;
    1455             :     }
    1456        1054 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
    1457        1054 :     if (bIllegalException || bRuntimeException)
    1458             :     {
    1459           0 :         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
    1460           0 :         if (bIllegalException)
    1461             :         {
    1462           0 :             lang::IllegalArgumentException aEx;
    1463           0 :             aEx.Message = sMessage;
    1464           0 :             throw aEx;
    1465             :         }
    1466             :         else //if(bRuntimeException)
    1467             :         {
    1468           0 :             uno::RuntimeException aEx;
    1469           0 :             aEx.Message = sMessage;
    1470           0 :             throw aEx;
    1471             :         }
    1472             :     }
    1473        1054 :     xRet = new SwXTextRange(*pCursor, this);
    1474        2108 :     return xRet;
    1475             : }
    1476             : 
    1477             : /*-------------------------------------------------------------------------
    1478             :     Append text portions at the end of the last paragraph of the text
    1479             :     interface. Support of import filters.
    1480             :   -----------------------------------------------------------------------*/
    1481             : uno::Reference< text::XTextRange > SAL_CALL
    1482        1050 : SwXText::appendTextPortion(
    1483             :         const OUString& rText,
    1484             :         const uno::Sequence< beans::PropertyValue > &
    1485             :             rCharacterAndParagraphProperties)
    1486             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1487             : {
    1488             :     // Right now this doesn't need a guard, as it's just calling the insert
    1489             :     // version, that has it already.
    1490        1050 :     uno::Reference<text::XTextRange> xInsertPosition = getEnd();
    1491        1050 :     return insertTextPortion(rText, rCharacterAndParagraphProperties, xInsertPosition);
    1492             : }
    1493             : 
    1494             : /*-------------------------------------------------------------------------
    1495             :     enable inserting/appending text contents like graphic objects, shapes and so on
    1496             :     to support import filters
    1497             :   -----------------------------------------------------------------------*/
    1498             : uno::Reference< text::XTextRange > SAL_CALL
    1499         289 : SwXText::insertTextContentWithProperties(
    1500             :     const uno::Reference< text::XTextContent >& xTextContent,
    1501             :     const uno::Sequence< beans::PropertyValue >&
    1502             :         rCharacterAndParagraphProperties,
    1503             :     const uno::Reference< text::XTextRange >& xInsertPosition)
    1504             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1505             : {
    1506         289 :     SolarMutexGuard aGuard;
    1507             : 
    1508         289 :     if (!IsValid())
    1509             :     {
    1510           0 :         throw  uno::RuntimeException();
    1511             :     }
    1512             : 
    1513         289 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
    1514             : 
    1515             :     // now attach the text content here
    1516         289 :     insertTextContent( xInsertPosition, xTextContent, false );
    1517             :     // now apply the properties to the anchor
    1518         247 :     if (rCharacterAndParagraphProperties.getLength())
    1519             :     {
    1520             :         try
    1521             :         {
    1522           4 :             const sal_Int32 nLen(rCharacterAndParagraphProperties.getLength());
    1523             :             const uno::Reference< beans::XPropertySet > xAnchor(
    1524           4 :                 xTextContent->getAnchor(), uno::UNO_QUERY);
    1525           4 :             if (xAnchor.is())
    1526             :             {
    1527          24 :                 for (sal_Int32 nElement = 0; nElement < nLen; ++nElement)
    1528             :                 {
    1529          20 :                     xAnchor->setPropertyValue(
    1530          20 :                         rCharacterAndParagraphProperties[nElement].Name,
    1531          40 :                         rCharacterAndParagraphProperties[nElement].Value);
    1532             :                 }
    1533           4 :             }
    1534             :         }
    1535           0 :         catch (const uno::Exception&)
    1536             :         {
    1537           0 :             throw uno::RuntimeException();
    1538             :         }
    1539             :     }
    1540         247 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
    1541         289 :     return xInsertPosition;
    1542             : }
    1543             : 
    1544             : uno::Reference< text::XTextRange > SAL_CALL
    1545         288 : SwXText::appendTextContent(
    1546             :     const uno::Reference< text::XTextContent >& xTextContent,
    1547             :     const uno::Sequence< beans::PropertyValue >&
    1548             :         rCharacterAndParagraphProperties)
    1549             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1550             : {
    1551             :     // Right now this doesn't need a guard, as it's just calling the insert
    1552             :     // version, that has it already.
    1553         288 :     uno::Reference<text::XTextRange> xInsertPosition = getEnd();
    1554         288 :     return insertTextContentWithProperties(xTextContent, rCharacterAndParagraphProperties, xInsertPosition);
    1555             : }
    1556             : 
    1557             : // move previously appended paragraphs into a text frames
    1558             : // to support import filters
    1559             : uno::Reference< text::XTextContent > SAL_CALL
    1560          19 : SwXText::convertToTextFrame(
    1561             :     const uno::Reference< text::XTextRange >& xStart,
    1562             :     const uno::Reference< text::XTextRange >& xEnd,
    1563             :     const uno::Sequence< beans::PropertyValue >& rFrameProperties)
    1564             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    1565             : {
    1566          19 :     SolarMutexGuard aGuard;
    1567             : 
    1568          19 :     if(!IsValid())
    1569             :     {
    1570           0 :         throw  uno::RuntimeException();
    1571             :     }
    1572          19 :     uno::Reference< text::XTextContent > xRet;
    1573          38 :     SwUnoInternalPaM aStartPam(*GetDoc());
    1574             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1575          38 :     std::auto_ptr< SwUnoInternalPaM > pEndPam(new SwUnoInternalPaM(*GetDoc()));
    1576             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1577          37 :     if (!::sw::XTextRangeToSwPaM(aStartPam, xStart) ||
    1578          18 :         !::sw::XTextRangeToSwPaM(*pEndPam, xEnd))
    1579             :     {
    1580           1 :         throw lang::IllegalArgumentException();
    1581             :     }
    1582             : 
    1583             :     const uno::Reference<lang::XUnoTunnel> xStartRangeTunnel(xStart,
    1584          36 :             uno::UNO_QUERY);
    1585             :     SwXTextRange *const pStartRange =
    1586          18 :         ::sw::UnoTunnelGetImplementation<SwXTextRange>(xStartRangeTunnel);
    1587             :     const uno::Reference<lang::XUnoTunnel> xEndRangeTunnel(xEnd,
    1588          36 :             uno::UNO_QUERY);
    1589             :     SwXTextRange *const pEndRange   =
    1590          18 :         ::sw::UnoTunnelGetImplementation<SwXTextRange>(xEndRangeTunnel);
    1591             :     // bookmarks have to be removed before the referenced text node
    1592             :     // is deleted in DelFullPara
    1593          18 :     if (pStartRange)
    1594             :     {
    1595          18 :         pStartRange->Invalidate();
    1596             :     }
    1597          18 :     if (pEndRange)
    1598             :     {
    1599          16 :         pEndRange->Invalidate();
    1600             :     }
    1601             : 
    1602          18 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
    1603          18 :     bool bIllegalException = false;
    1604          18 :     bool bRuntimeException = false;
    1605          36 :     OUString sMessage;
    1606          18 :     SwStartNode* pStartStartNode = aStartPam.GetNode()->StartOfSectionNode();
    1607          36 :     while (pStartStartNode && pStartStartNode->IsSectionNode())
    1608             :     {
    1609           0 :         pStartStartNode = pStartStartNode->StartOfSectionNode();
    1610             :     }
    1611          18 :     SwStartNode* pEndStartNode = pEndPam->GetNode()->StartOfSectionNode();
    1612          36 :     while (pEndStartNode && pEndStartNode->IsSectionNode())
    1613             :     {
    1614           0 :         pEndStartNode = pEndStartNode->StartOfSectionNode();
    1615             :     }
    1616          18 :     bool bParaAfterInserted = false;
    1617          18 :     bool bParaBeforeInserted = false;
    1618          18 :     if (pStartStartNode != pEndStartNode || pStartStartNode != GetStartNode())
    1619             :     {
    1620             :         // todo: if the start/end is in a table then insert a paragraph
    1621             :         // before/after, move the start/end nodes, then convert and
    1622             :         // remove the additional paragraphs in the end
    1623           4 :         if (pStartStartNode->GetStartNodeType() == SwTableBoxStartNode)
    1624             :         {
    1625           4 :             SwTableNode * pStartTableNode(pStartStartNode->FindTableNode());
    1626             :             // Is it the same table start node than the end?
    1627           4 :             SwTableNode *const pEndStartTableNode(pEndStartNode->FindTableNode());
    1628          14 :             while (pEndStartTableNode && pStartTableNode &&
    1629           5 :                    pEndStartTableNode->GetIndex() < pStartTableNode->GetIndex())
    1630             :             {
    1631           1 :                 SwStartNode* pStartStartTableNode = pStartTableNode->StartOfSectionNode();
    1632           1 :                 pStartTableNode = pStartStartTableNode->FindTableNode();
    1633             :             }
    1634           4 :             const SwNodeIndex aTblIdx(  *pStartTableNode, -1 );
    1635           8 :             SwPosition aBefore(aTblIdx);
    1636           4 :             bParaBeforeInserted = GetDoc()->AppendTxtNode( aBefore );
    1637           4 :             aStartPam.DeleteMark();
    1638           4 :             *aStartPam.GetPoint() = aBefore;
    1639           8 :             pStartStartNode = aStartPam.GetNode()->StartOfSectionNode();
    1640             :         }
    1641           4 :         if (pEndStartNode->GetStartNodeType() == SwTableBoxStartNode)
    1642             :         {
    1643           4 :             SwTableNode *const pEndTableNode = pEndStartNode->FindTableNode();
    1644           4 :             SwEndNode *const pTableEnd = pEndTableNode->EndOfSectionNode();
    1645           4 :             SwPosition aTableEnd(*pTableEnd);
    1646           4 :             bParaAfterInserted = GetDoc()->AppendTxtNode( aTableEnd );
    1647           4 :             pEndPam->DeleteMark();
    1648           4 :             *pEndPam->GetPoint() = aTableEnd;
    1649           4 :             pEndStartNode = pEndPam->GetNode()->StartOfSectionNode();
    1650             :         }
    1651             :         // now we should have the positions in the same hierarchy
    1652           8 :         if ((pStartStartNode != pEndStartNode) ||
    1653           4 :             (pStartStartNode != GetStartNode()))
    1654             :         {
    1655             :             // if not - remove the additional paragraphs and throw
    1656           0 :             if (bParaBeforeInserted)
    1657             :             {
    1658           0 :                 SwCursor aDelete(*aStartPam.GetPoint(), 0, false);
    1659           0 :                 *aStartPam.GetPoint() = // park it because node is deleted
    1660           0 :                     SwPosition(GetDoc()->GetNodes().GetEndOfContent());
    1661           0 :                 aDelete.MovePara(fnParaCurr, fnParaStart);
    1662           0 :                 aDelete.SetMark();
    1663           0 :                 aDelete.MovePara(fnParaCurr, fnParaEnd);
    1664           0 :                 GetDoc()->DelFullPara(aDelete);
    1665             :             }
    1666           0 :             if (bParaAfterInserted)
    1667             :             {
    1668           0 :                 SwCursor aDelete(*pEndPam->GetPoint(), 0, false);
    1669           0 :                 *pEndPam->GetPoint() = // park it because node is deleted
    1670           0 :                     SwPosition(GetDoc()->GetNodes().GetEndOfContent());
    1671           0 :                 aDelete.MovePara(fnParaCurr, fnParaStart);
    1672           0 :                 aDelete.SetMark();
    1673           0 :                 aDelete.MovePara(fnParaCurr, fnParaEnd);
    1674           0 :                 GetDoc()->DelFullPara(aDelete);
    1675             :             }
    1676           0 :             throw lang::IllegalArgumentException();
    1677             :         }
    1678             :     }
    1679             : 
    1680             :     // make a selection from aStartPam to a EndPam
    1681             :     // If there is no content in the frame the shape is in
    1682             :     // it gets deleted in the DelFullPara call below,
    1683             :     // In this case insert a tmp text node ( we delete it later )
    1684          36 :     if ( aStartPam.Start()->nNode == pEndPam->Start()->nNode
    1685          18 :     && aStartPam.End()->nNode == pEndPam->End()->nNode )
    1686             :     {
    1687          12 :         SwPosition aEnd(*aStartPam.End());
    1688          12 :         bParaAfterInserted = GetDoc()->AppendTxtNode( aEnd );
    1689          12 :         pEndPam->DeleteMark();
    1690          12 :         *pEndPam->GetPoint() = aEnd;
    1691             :     }
    1692          18 :     aStartPam.SetMark();
    1693          18 :     *aStartPam.End() = *pEndPam->End();
    1694          18 :     pEndPam.reset(0);
    1695             : 
    1696             :     // see if there are frames already anchored to this node
    1697          36 :     std::vector<SwFrmFmt*> aAnchoredFrames;
    1698          33 :     for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrmFmts()->size(); ++i)
    1699             :     {
    1700          15 :         SwFrmFmt* pFrmFmt = (*m_pImpl->m_pDoc->GetSpzFrmFmts())[i];
    1701          15 :         const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
    1702          22 :         if (FLY_AT_PARA == rAnchor.GetAnchorId() &&
    1703           7 :                 aStartPam.GetNode()->GetIndex() == rAnchor.GetCntntAnchor()->nNode.GetIndex())
    1704           2 :             aAnchoredFrames.push_back(pFrmFmt);
    1705             :     }
    1706             : 
    1707          18 :     SwXTextFrame *const pNewFrame = new SwXTextFrame(m_pImpl->m_pDoc);
    1708          36 :     const uno::Reference< text::XTextFrame > xNewFrame = pNewFrame;
    1709          18 :     pNewFrame->SetSelection( aStartPam );
    1710             :     try
    1711             :     {
    1712          18 :         const beans::PropertyValue* pValues = rFrameProperties.getConstArray();
    1713         401 :         for (sal_Int32 nProp = 0; nProp < rFrameProperties.getLength(); ++nProp)
    1714             :         {
    1715             :             pNewFrame->SwXFrame::setPropertyValue(
    1716         383 :                     pValues[nProp].Name, pValues[nProp].Value);
    1717             :         }
    1718             : 
    1719             :         {   // has to be in a block to remove the SwIndexes before
    1720             :             // DelFullPara is called
    1721             :             const uno::Reference< text::XTextRange> xInsertTextRange =
    1722          18 :                 new SwXTextRange(aStartPam, this);
    1723          18 :             aStartPam.DeleteMark(); // mark position node may be deleted!
    1724          18 :             pNewFrame->attach( xInsertTextRange );
    1725          18 :             pNewFrame->setName(m_pImpl->m_pDoc->GetUniqueFrameName());
    1726             :         }
    1727             : 
    1728          18 :         SwTxtNode *const pTxtNode(aStartPam.GetNode()->GetTxtNode());
    1729             :         OSL_ASSERT(pTxtNode);
    1730          18 :         if (!pTxtNode || !pTxtNode->Len()) // don't remove if it contains text!
    1731             :         {
    1732             :             {   // has to be in a block to remove the SwIndexes before
    1733             :                 // DelFullPara is called
    1734          18 :                 SwPaM aMovePam( *aStartPam.GetNode() );
    1735          18 :                 if (aMovePam.Move( fnMoveForward, fnGoCntnt ))
    1736             :                 {
    1737             :                     // move the anchor to the next paragraph
    1738          17 :                     SwFmtAnchor aNewAnchor(pNewFrame->GetFrmFmt()->GetAnchor());
    1739          17 :                     aNewAnchor.SetAnchor( aMovePam.Start() );
    1740          17 :                     m_pImpl->m_pDoc->SetAttr(
    1741          34 :                         aNewAnchor, *pNewFrame->GetFrmFmt() );
    1742             : 
    1743             :                     // also move frames anchored to us
    1744          19 :                     for (std::vector<SwFrmFmt*>::iterator i = aAnchoredFrames.begin(); i != aAnchoredFrames.end(); ++i)
    1745             :                     {
    1746             :                         // copy the anchor to the next paragraph
    1747           2 :                         SwFmtAnchor aAnchor((*i)->GetAnchor());
    1748           2 :                         aAnchor.SetAnchor(aMovePam.Start());
    1749           2 :                         m_pImpl->m_pDoc->SetAttr(aAnchor, *(*i));
    1750          19 :                     }
    1751          18 :                 }
    1752             :             }
    1753          18 :             m_pImpl->m_pDoc->DelFullPara(aStartPam);
    1754             :         }
    1755             :     }
    1756           0 :     catch (const lang::IllegalArgumentException& rIllegal)
    1757             :     {
    1758           0 :         sMessage = rIllegal.Message;
    1759           0 :         bIllegalException = true;
    1760             :     }
    1761           0 :     catch (const uno::RuntimeException& rRuntime)
    1762             :     {
    1763           0 :         sMessage = rRuntime.Message;
    1764           0 :         bRuntimeException = true;
    1765             :     }
    1766          18 :     xRet = pNewFrame;
    1767          18 :     if (bParaBeforeInserted || bParaAfterInserted)
    1768             :     {
    1769             :         const uno::Reference<text::XTextCursor> xFrameTextCursor =
    1770          16 :             pNewFrame->createTextCursor();
    1771             :         const uno::Reference<XUnoTunnel> xTunnel(xFrameTextCursor,
    1772          32 :                 uno::UNO_QUERY);
    1773             :         SwXTextCursor *const pFrameCursor =
    1774          16 :             ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xTunnel);
    1775          16 :         if (bParaBeforeInserted)
    1776             :         {
    1777             :             // todo: remove paragraph before frame
    1778           4 :             m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
    1779             :         }
    1780          16 :         if (bParaAfterInserted)
    1781             :         {
    1782          16 :             xFrameTextCursor->gotoEnd(sal_False);
    1783          16 :             if (!bParaBeforeInserted)
    1784          12 :                 m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
    1785             :             else
    1786             :             {
    1787             :                 // In case the frame has a table only, the cursor points to the end of the first cell of the table.
    1788           4 :                 SwPaM aPaM(*pFrameCursor->GetPaM()->GetNode()->FindSttNodeByType(SwFlyStartNode)->EndOfSectionNode());
    1789             :                 // Now we have the end of the frame -- the node before that will be the paragraph we want to remove.
    1790           4 :                 aPaM.GetPoint()->nNode--;
    1791           4 :                 m_pImpl->m_pDoc->DelFullPara(aPaM);
    1792             :             }
    1793          16 :         }
    1794             :     }
    1795             : 
    1796          18 :     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
    1797          18 :     if (bIllegalException || bRuntimeException)
    1798             :     {
    1799           0 :         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
    1800           0 :         if (bIllegalException)
    1801             :         {
    1802           0 :             lang::IllegalArgumentException aEx;
    1803           0 :             aEx.Message = sMessage;
    1804           0 :             throw aEx;
    1805             :         }
    1806             :         else //if(bRuntimeException)
    1807             :         {
    1808           0 :             uno::RuntimeException aEx;
    1809           0 :             aEx.Message = sMessage;
    1810           0 :             throw aEx;
    1811             :         }
    1812             :     }
    1813          37 :     return xRet;
    1814             : }
    1815             : 
    1816             : /*-------------------------------------------------------------------------
    1817             :     Move previously imported paragraphs into a new text table.
    1818             :   -----------------------------------------------------------------------*/
    1819           6 : struct VerticallyMergedCell
    1820             : {
    1821             :     std::vector<uno::Reference< beans::XPropertySet > > aCells;
    1822             :     sal_Int32                                           nLeftPosition;
    1823             :     bool                                                bOpen;
    1824             : 
    1825           2 :     VerticallyMergedCell(uno::Reference< beans::XPropertySet > const& rxCell,
    1826             :             const sal_Int32 nLeft)
    1827             :         : nLeftPosition( nLeft )
    1828           2 :         , bOpen( true )
    1829             :     {
    1830           2 :         aCells.push_back( rxCell );
    1831           2 :     }
    1832             : };
    1833             : 
    1834             : #define COL_POS_FUZZY 2
    1835             : 
    1836           0 : static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 )
    1837             : {
    1838           0 :     return abs( nPos1 - nPos2 ) < COL_POS_FUZZY;
    1839             : }
    1840             : 
    1841             : SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1842         699 : void SwXText::Impl::ConvertCell(
    1843             :     const bool bFirstCell,
    1844             :     const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
    1845             :     ::std::vector<SwNodeRange> & rRowNodes,
    1846             :     ::std::auto_ptr< SwPaM > & rpFirstPaM,
    1847             :     SwPaM & rLastPaM,
    1848             :     bool & rbExcept)
    1849             : {
    1850         699 :     if (rCell.getLength() != 2)
    1851             :     {
    1852             :         throw lang::IllegalArgumentException(
    1853             :                 "rCell needs to contain 2 elements",
    1854           1 :                 uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
    1855             :     }
    1856         698 :     const uno::Reference<text::XTextRange> xStartRange = rCell[0];
    1857        1396 :     const uno::Reference<text::XTextRange> xEndRange = rCell[1];
    1858        1396 :     SwUnoInternalPaM aStartCellPam(*m_pDoc);
    1859        1396 :     SwUnoInternalPaM aEndCellPam(*m_pDoc);
    1860             : 
    1861             :     // !!! TODO - PaMs in tables and sections do not work here -
    1862             :     //     the same applies to PaMs in frames !!!
    1863             : 
    1864        1396 :     if (!::sw::XTextRangeToSwPaM(aStartCellPam, xStartRange) ||
    1865         698 :         !::sw::XTextRangeToSwPaM(aEndCellPam, xEndRange))
    1866             :     {
    1867             :         throw lang::IllegalArgumentException(
    1868             :                 "Start or End range cannot be resolved to a SwPaM",
    1869           0 :                 uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
    1870             :     }
    1871             : 
    1872         698 :     SwNodeRange aTmpRange(aStartCellPam.Start()->nNode,
    1873        2094 :                           aEndCellPam.End()->nNode);
    1874             :     SwNodeRange * pCorrectedRange =
    1875         698 :         m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange);
    1876             : 
    1877         698 :     if (pCorrectedRange != NULL)
    1878             :     {
    1879           8 :         SwPaM aNewStartPaM(pCorrectedRange->aStart, 0);
    1880           8 :         aStartCellPam = aNewStartPaM;
    1881             : 
    1882           8 :         xub_StrLen nEndLen = 0;
    1883           8 :         SwTxtNode * pTxtNode = pCorrectedRange->aEnd.GetNode().GetTxtNode();
    1884           8 :         if (pTxtNode != NULL)
    1885           8 :             nEndLen = pTxtNode->Len();
    1886             : 
    1887          16 :         SwPaM aNewEndPaM(pCorrectedRange->aEnd, nEndLen);
    1888          16 :         aEndCellPam = aNewEndPaM;
    1889             :     }
    1890             : 
    1891             :     /** check the nodes between start and end
    1892             :         it is allowed to have pairs of StartNode/EndNodes
    1893             :      */
    1894         698 :     if (aStartCellPam.Start()->nNode < aEndCellPam.End()->nNode)
    1895             :     {
    1896             :         // increment on each StartNode and decrement on each EndNode
    1897             :         // we must reach zero at the end and must not go below zero
    1898          17 :         long nOpenNodeBlock = 0;
    1899          17 :         SwNodeIndex aCellIndex = aStartCellPam.Start()->nNode;
    1900          94 :         while (aCellIndex < aEndCellPam.End()->nNode.GetIndex())
    1901             :         {
    1902          60 :             if (aCellIndex.GetNode().IsStartNode())
    1903             :             {
    1904          18 :                 ++nOpenNodeBlock;
    1905             :             }
    1906          42 :             else if (aCellIndex.GetNode().IsEndNode())
    1907             :             {
    1908          18 :                 --nOpenNodeBlock;
    1909             :             }
    1910          60 :             if (nOpenNodeBlock < 0)
    1911             :             {
    1912           0 :                 rbExcept = true;
    1913           0 :                 break;
    1914             :             }
    1915          60 :             ++aCellIndex;
    1916             :         }
    1917          17 :         if (nOpenNodeBlock != 0)
    1918             :         {
    1919           0 :             rbExcept = true;
    1920         698 :             return;
    1921          17 :         }
    1922             :     }
    1923             : 
    1924             :     /** The vector<vector> NodeRanges has to contain consecutive nodes.
    1925             :         In rTableRanges the ranges don't need to be full paragraphs but
    1926             :         they have to follow each other. To process the ranges they
    1927             :         have to be aligned on paragraph borders by inserting paragraph
    1928             :         breaks. Non-consecutive ranges must initiate an exception.
    1929             :      */
    1930         698 :     if (bFirstCell)
    1931             :     {
    1932             :         // align the beginning - if necessary
    1933          86 :         if (aStartCellPam.Start()->nContent.GetIndex())
    1934             :         {
    1935           0 :             m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
    1936             :         }
    1937             :     }
    1938             :     else
    1939             :     {
    1940             :         // check the predecessor
    1941         612 :         const sal_uLong nLastNodeIndex = rLastPaM.End()->nNode.GetIndex();
    1942             :         const sal_uLong nStartCellNodeIndex =
    1943         612 :             aStartCellPam.Start()->nNode.GetIndex();
    1944         612 :         const sal_uLong nLastNodeEndIndex = rLastPaM.End()->nNode.GetIndex();
    1945         612 :         if (nLastNodeIndex == nStartCellNodeIndex)
    1946             :         {
    1947             :             // same node as predecessor then equal nContent?
    1948           0 :             if (rLastPaM.End()->nContent != aStartCellPam.Start()->nContent)
    1949             :             {
    1950           0 :                 rbExcept = true;
    1951             :             }
    1952             :             else
    1953             :             {
    1954           0 :                 m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
    1955             :             }
    1956             :         }
    1957         612 :         else if (nStartCellNodeIndex == (nLastNodeEndIndex + 1))
    1958             :         {
    1959             :             // next paragraph - now the content index of the new should be 0
    1960             :             // and of the old one should be equal to the text length
    1961             :             // but if it isn't we don't care - the cell is being inserted on
    1962             :             // the node border anyway
    1963             :         }
    1964             :         else
    1965             :         {
    1966           0 :             rbExcept = true;
    1967             :         }
    1968             :     }
    1969             :     // now check if there's a need to insert another paragraph break
    1970        1396 :     if (aEndCellPam.End()->nContent.GetIndex() <
    1971         698 :             aEndCellPam.End()->nNode.GetNode().GetTxtNode()->Len())
    1972             :     {
    1973           0 :         m_pDoc->SplitNode(*aEndCellPam.End(), sal_False);
    1974             :         // take care that the new start/endcell is moved to the right position
    1975             :         // aStartCellPam has to point to the start of the new (previous) node
    1976             :         // aEndCellPam has to point to the end of the new (previous) node
    1977           0 :         aStartCellPam.DeleteMark();
    1978           0 :         aStartCellPam.Move(fnMoveBackward, fnGoNode);
    1979           0 :         aStartCellPam.GetPoint()->nContent = 0;
    1980           0 :         aEndCellPam.DeleteMark();
    1981           0 :         aEndCellPam.Move(fnMoveBackward, fnGoNode);
    1982           0 :         aEndCellPam.GetPoint()->nContent =
    1983           0 :             aEndCellPam.GetNode()->GetTxtNode()->Len();
    1984             :     }
    1985             : 
    1986         698 :     *rLastPaM.GetPoint() = *aEndCellPam.Start();
    1987         698 :     if (aStartCellPam.HasMark())
    1988             :     {
    1989           0 :         rLastPaM.SetMark();
    1990           0 :         *rLastPaM.GetMark() = *aEndCellPam.End();
    1991             :     }
    1992             :     else
    1993             :     {
    1994         698 :         rLastPaM.DeleteMark();
    1995             :     }
    1996             : 
    1997         698 :     SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
    1998        2094 :             aEndCellPam.End()->nNode);
    1999         698 :     rRowNodes.push_back(aCellRange);
    2000         698 :     if (bFirstCell)
    2001             :     {
    2002          86 :         rpFirstPaM.reset(new SwPaM(*aStartCellPam.Start()));
    2003         698 :     }
    2004             : }
    2005             : SAL_WNODEPRECATED_DECLARATIONS_POP
    2006             : 
    2007             : typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;
    2008             : 
    2009             : static void
    2010         188 : lcl_ApplyRowProperties(
    2011             :     uno::Sequence<beans::PropertyValue> const& rRowProperties,
    2012             :     uno::Any const& rRow,
    2013             :     TableColumnSeparators & rRowSeparators)
    2014             : {
    2015         188 :     uno::Reference< beans::XPropertySet > xRow;
    2016         188 :     rRow >>= xRow;
    2017         188 :     const beans::PropertyValue* pProperties = rRowProperties.getConstArray();
    2018         596 :     for (sal_Int32 nProperty = 0; nProperty < rRowProperties.getLength();
    2019             :          ++nProperty)
    2020             :     {
    2021         408 :         if ( pProperties[ nProperty ].Name == "TableColumnSeparators" )
    2022             :         {
    2023             :             // add the separators to access the cell's positions
    2024             :             // for vertical merging later
    2025         182 :             TableColumnSeparators aSeparators;
    2026         182 :             pProperties[ nProperty ].Value >>= aSeparators;
    2027         182 :             rRowSeparators = aSeparators;
    2028             :         }
    2029         408 :         xRow->setPropertyValue(
    2030         408 :             pProperties[ nProperty ].Name, pProperties[ nProperty ].Value);
    2031         188 :     }
    2032         188 : }
    2033             : 
    2034             : #if OSL_DEBUG_LEVEL > 0
    2035             : //-->debug cell properties of all rows
    2036             : static void
    2037             : lcl_DebugCellProperties(
    2038             :     const uno::Sequence< uno::Sequence< uno::Sequence<
    2039             :         beans::PropertyValue > > >& rCellProperties)
    2040             : {
    2041             :     OUString sNames;
    2042             :     for (sal_Int32  nDebugRow = 0; nDebugRow < rCellProperties.getLength();
    2043             :          ++nDebugRow)
    2044             :     {
    2045             :         const uno::Sequence< beans::PropertyValues > aDebugCurrentRow =
    2046             :             rCellProperties[nDebugRow];
    2047             :         sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
    2048             :         (void) nDebugCells;
    2049             :         for (sal_Int32  nDebugCell = 0; nDebugCell < nDebugCells;
    2050             :              ++nDebugCell)
    2051             :         {
    2052             :             const uno::Sequence< beans::PropertyValue >&
    2053             :                 rDebugCellProperties = aDebugCurrentRow[nDebugCell];
    2054             :             const sal_Int32 nDebugCellProperties =
    2055             :                 rDebugCellProperties.getLength();
    2056             :             for (sal_Int32  nDebugProperty = 0;
    2057             :                  nDebugProperty < nDebugCellProperties; ++nDebugProperty)
    2058             :             {
    2059             :                 const OUString sName =
    2060             :                     rDebugCellProperties[nDebugProperty].Name;
    2061             :                 sNames += sName;
    2062             :                 sNames += OUString('-');
    2063             :             }
    2064             :             sNames += OUString('+');
    2065             :         }
    2066             :         sNames += OUString('|');
    2067             :     }
    2068             :     (void)sNames;
    2069             : }
    2070             : //--<
    2071             : #endif
    2072             : 
    2073             : static void
    2074         698 : lcl_ApplyCellProperties(
    2075             :     const sal_Int32 nCell,
    2076             :     TableColumnSeparators const& rRowSeparators,
    2077             :     const uno::Sequence< beans::PropertyValue >& rCellProperties,
    2078             :     uno::Reference< uno::XInterface > xCell,
    2079             :     ::std::vector<VerticallyMergedCell> & rMergedCells)
    2080             : {
    2081         698 :     const sal_Int32 nCellProperties = rCellProperties.getLength();
    2082         698 :     const uno::Reference< beans::XPropertySet > xCellPS(xCell, uno::UNO_QUERY);
    2083        6920 :     for (sal_Int32 nProperty = 0; nProperty < nCellProperties; ++nProperty)
    2084             :     {
    2085        6222 :         const OUString & rName  = rCellProperties[nProperty].Name;
    2086        6222 :         const uno::Any & rValue = rCellProperties[nProperty].Value;
    2087        6222 :         if ( rName == "VerticalMerge" )
    2088             :         {
    2089             :             // determine left border position
    2090             :             // add the cell to a queue of merged cells
    2091           2 :             sal_Bool bMerge = sal_False;
    2092           2 :             rValue >>= bMerge;
    2093           2 :             sal_Int32 nLeftPos = -1;
    2094           2 :             if (!nCell)
    2095             :             {
    2096           2 :                 nLeftPos = 0;
    2097             :             }
    2098           0 :             else if (rRowSeparators.getLength() >= nCell)
    2099             :             {
    2100             :                 const text::TableColumnSeparator* pSeparators =
    2101           0 :                     rRowSeparators.getConstArray();
    2102           0 :                 nLeftPos = pSeparators[nCell - 1].Position;
    2103             :             }
    2104           2 :             if (bMerge)
    2105             :             {
    2106             :                 // 'close' all the cell with the same left position
    2107             :                 // if separate vertical merges in the same column exist
    2108           2 :                 if (rMergedCells.size())
    2109             :                 {
    2110             :                     std::vector<VerticallyMergedCell>::iterator aMergedIter =
    2111           0 :                         rMergedCells.begin();
    2112           0 :                     while (aMergedIter != rMergedCells.end())
    2113             :                     {
    2114           0 :                         if (lcl_SimilarPosition(aMergedIter->nLeftPosition,
    2115           0 :                                     nLeftPos))
    2116             :                         {
    2117           0 :                             aMergedIter->bOpen = false;
    2118             :                         }
    2119           0 :                         ++aMergedIter;
    2120             :                     }
    2121             :                 }
    2122             :                 // add the new group of merged cells
    2123           2 :                 rMergedCells.push_back(VerticallyMergedCell(xCellPS, nLeftPos));
    2124             :             }
    2125             :             else
    2126             :             {
    2127             :                 // find the cell that
    2128             :                 OSL_ENSURE(rMergedCells.size(),
    2129             :                         "the first merged cell is missing");
    2130           0 :                 if (rMergedCells.size())
    2131             :                 {
    2132             :                     std::vector<VerticallyMergedCell>::iterator aMergedIter =
    2133           0 :                         rMergedCells.begin();
    2134             : #if OSL_DEBUG_LEVEL > 0
    2135             :                     bool bDbgFound = false;
    2136             : #endif
    2137           0 :                     while (aMergedIter != rMergedCells.end())
    2138             :                     {
    2139           0 :                         if (aMergedIter->bOpen &&
    2140           0 :                             lcl_SimilarPosition(aMergedIter->nLeftPosition,
    2141           0 :                                 nLeftPos))
    2142             :                         {
    2143           0 :                             aMergedIter->aCells.push_back( xCellPS );
    2144             : #if OSL_DEBUG_LEVEL > 0
    2145             :                             bDbgFound = true;
    2146             : #endif
    2147             :                         }
    2148           0 :                         ++aMergedIter;
    2149             :                     }
    2150             : #if OSL_DEBUG_LEVEL > 0
    2151             :                     OSL_ENSURE( bDbgFound,
    2152             :                             "couldn't find first vertically merged cell" );
    2153             : #endif
    2154             :                 }
    2155             :             }
    2156             :         }
    2157             :         else
    2158             :         {
    2159             :             try
    2160             :             {
    2161        6220 :                 xCellPS->setPropertyValue(rName, rValue);
    2162             :             }
    2163         583 :             catch (const uno::Exception&)
    2164             :             {
    2165             :                 // Apply the paragraph and char properties to the cell's content
    2166             :                 const uno::Reference< text::XText > xCellText(xCell,
    2167         583 :                         uno::UNO_QUERY);
    2168             :                 const uno::Reference< text::XTextCursor > xCellCurs =
    2169        1166 :                     xCellText->createTextCursor();
    2170         583 :                 xCellCurs->gotoStart( sal_False );
    2171         583 :                 xCellCurs->gotoEnd( sal_True );
    2172             :                 const uno::Reference< beans::XPropertyState >
    2173        1166 :                     xCellTextPropState(xCellCurs, uno::UNO_QUERY);
    2174         583 :                 const beans::PropertyState state = xCellTextPropState->getPropertyState(rName);
    2175         583 :                 if (state == beans::PropertyState_DEFAULT_VALUE)
    2176             :                 {
    2177             :                     const uno::Reference< beans::XPropertySet >
    2178         583 :                         xCellTextProps(xCellCurs, uno::UNO_QUERY);
    2179         583 :                     xCellTextProps->setPropertyValue(rName, rValue);
    2180         583 :                 }
    2181             :             }
    2182             :         }
    2183         698 :     }
    2184         698 : }
    2185             : 
    2186             : static void
    2187          86 : lcl_MergeCells(::std::vector<VerticallyMergedCell> & rMergedCells)
    2188             : {
    2189          86 :     if (rMergedCells.size())
    2190             :     {
    2191             :         std::vector<VerticallyMergedCell>::iterator aMergedIter =
    2192           2 :             rMergedCells.begin();
    2193           6 :         while (aMergedIter != rMergedCells.end())
    2194             :         {
    2195             :             sal_Int32 nCellCount =
    2196           2 :                 static_cast<sal_Int32>(aMergedIter->aCells.size());
    2197             :             std::vector<uno::Reference< beans::XPropertySet > >::iterator
    2198           2 :                 aCellIter = aMergedIter->aCells.begin();
    2199           2 :             bool bFirstCell = true;
    2200             :             // the first of the cells gets the number of cells set as RowSpan
    2201             :             // the others get the inverted number of remaining merged cells
    2202             :             // (3,-2,-1)
    2203           6 :             while (aCellIter != aMergedIter->aCells.end())
    2204             :             {
    2205           2 :                 (*aCellIter)->setPropertyValue(
    2206           2 :                     OUString::createFromAscii(SW_PROP_NAME_STR(UNO_NAME_ROW_SPAN)),
    2207           4 :                     uno::makeAny(nCellCount));
    2208           2 :                 if (bFirstCell)
    2209             :                 {
    2210           2 :                     nCellCount *= -1;
    2211           2 :                     bFirstCell = false;
    2212             :                 }
    2213           2 :                 ++nCellCount;
    2214           2 :                 ++aCellIter;
    2215             :             }
    2216           2 :             ++aMergedIter;
    2217             :         }
    2218             :     }
    2219          86 : }
    2220             : 
    2221             : uno::Reference< text::XTextTable > SAL_CALL
    2222          87 : SwXText::convertToTable(
    2223             :     const uno::Sequence< uno::Sequence< uno::Sequence<
    2224             :         uno::Reference< text::XTextRange > > > >& rTableRanges,
    2225             :     const uno::Sequence< uno::Sequence< uno::Sequence<
    2226             :         beans::PropertyValue > > >& rCellProperties,
    2227             :     const uno::Sequence< uno::Sequence< beans::PropertyValue > >&
    2228             :         rRowProperties,
    2229             :     const uno::Sequence< beans::PropertyValue >& rTableProperties)
    2230             : throw (lang::IllegalArgumentException, uno::RuntimeException)
    2231             : {
    2232          87 :     SolarMutexGuard aGuard;
    2233             : 
    2234          87 :     if(!IsValid())
    2235             :     {
    2236           0 :         throw  uno::RuntimeException();
    2237             :     }
    2238             : 
    2239             :     //at first collect the text ranges as SwPaMs
    2240             :     const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >*
    2241          87 :         pTableRanges = rTableRanges.getConstArray();
    2242             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2243         174 :     std::auto_ptr < SwPaM > pFirstPaM;
    2244             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2245         174 :     std::vector< std::vector<SwNodeRange> > aTableNodes;
    2246          87 :     bool bExcept = false;
    2247         174 :     SwPaM aLastPaM(m_pImpl->m_pDoc->GetNodes());
    2248         275 :     for (sal_Int32 nRow = 0; !bExcept && (nRow < rTableRanges.getLength());
    2249             :             ++nRow)
    2250             :     {
    2251         189 :         std::vector<SwNodeRange> aRowNodes;
    2252             :         const uno::Sequence< uno::Reference< text::XTextRange > >* pRow =
    2253         189 :             pTableRanges[nRow].getConstArray();
    2254         189 :         const sal_Int32 nCells(pTableRanges[nRow].getLength());
    2255             : 
    2256         887 :         for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
    2257             :         {
    2258         699 :             m_pImpl->ConvertCell((nCell == 0) && (nRow == 0), pRow[nCell],
    2259        1398 :                 aRowNodes, pFirstPaM, aLastPaM, bExcept);
    2260             :         }
    2261         188 :         aTableNodes.push_back(aRowNodes);
    2262         189 :     }
    2263             : 
    2264          86 :     if(bExcept)
    2265             :     {
    2266           0 :         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
    2267           0 :         throw lang::IllegalArgumentException();
    2268             :     }
    2269             : 
    2270             :     std::vector< TableColumnSeparators >
    2271         172 :         aRowSeparators(rRowProperties.getLength());
    2272         172 :     std::vector<VerticallyMergedCell> aMergedCells;
    2273             : 
    2274          86 :     SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes );
    2275             : 
    2276          86 :     if (!pTable)
    2277           0 :         return uno::Reference< text::XTextTable >();
    2278             : 
    2279          86 :     SwXTextTable *const pTextTable = new SwXTextTable( *pTable->GetFrmFmt() );
    2280         172 :     const uno::Reference< text::XTextTable > xRet = pTextTable;
    2281         172 :     const uno::Reference< beans::XPropertySet > xPrSet = pTextTable;
    2282             :     // set properties to the table
    2283             :     // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException
    2284             :     try
    2285             :     {
    2286             :         //apply table properties
    2287             :         const beans::PropertyValue* pTableProperties =
    2288          86 :             rTableProperties.getConstArray();
    2289        1089 :         for (sal_Int32 nProperty = 0; nProperty < rTableProperties.getLength();
    2290             :              ++nProperty)
    2291             :         {
    2292             :             try
    2293             :             {
    2294        2006 :                 xPrSet->setPropertyValue( pTableProperties[nProperty].Name,
    2295        2006 :                         pTableProperties[nProperty].Value );
    2296             :             }
    2297         314 :             catch (const uno::Exception& e)
    2298             :             {
    2299             :                 SAL_WARN( "sw.uno", "Exception when setting property: "
    2300             :                     + pTableProperties[nProperty].Name + ". Message: " + e.Message );
    2301             :             }
    2302             :         }
    2303             : 
    2304             :         //apply row properties
    2305          86 :         const uno::Reference< table::XTableRows >  xRows = xRet->getRows();
    2306             : 
    2307             :         const beans::PropertyValues* pRowProperties =
    2308          86 :             rRowProperties.getConstArray();
    2309         274 :         for (sal_Int32 nRow = 0; nRow < xRows->getCount(); ++nRow)
    2310             :         {
    2311         188 :             if( nRow >= rRowProperties.getLength())
    2312             :             {
    2313           0 :                 break;
    2314             :             }
    2315         188 :             lcl_ApplyRowProperties(pRowProperties[nRow],
    2316         376 :                 xRows->getByIndex(nRow), aRowSeparators[nRow]);
    2317             :         }
    2318             : 
    2319             : #if OSL_DEBUG_LEVEL > 0
    2320             :         lcl_DebugCellProperties(rCellProperties);
    2321             : #endif
    2322             : 
    2323             :         //apply cell properties
    2324         274 :         for (sal_Int32 nRow = 0; nRow < rCellProperties.getLength(); ++nRow)
    2325             :         {
    2326             :             const uno::Sequence< beans::PropertyValues > aCurrentRow =
    2327         188 :                 rCellProperties[nRow];
    2328         188 :             sal_Int32 nCells = aCurrentRow.getLength();
    2329         886 :             for (sal_Int32  nCell = 0; nCell < nCells; ++nCell)
    2330             :             {
    2331             :                 lcl_ApplyCellProperties(nCell,
    2332         698 :                     aRowSeparators[nRow], aCurrentRow[nCell],
    2333         698 :                     pTextTable->getCellByPosition(nCell, nRow),
    2334        1396 :                     aMergedCells);
    2335             :             }
    2336         188 :         }
    2337             :         // now that the cell properties are set the vertical merge values
    2338             :         // have to be applied
    2339          86 :         lcl_MergeCells(aMergedCells);
    2340             :     }
    2341           0 :     catch (const lang::WrappedTargetException&)
    2342             :     {
    2343             :     }
    2344           0 :     catch (const lang::IndexOutOfBoundsException&)
    2345             :     {
    2346             :     }
    2347             : 
    2348         173 :     return xRet;
    2349             : }
    2350             : 
    2351             : 
    2352             : void SAL_CALL
    2353           4 : SwXText::copyText(
    2354             :     const uno::Reference< text::XTextCopy >& xSource )
    2355             : throw (uno::RuntimeException)
    2356             : {
    2357           4 :     SolarMutexGuard aGuard;
    2358             : 
    2359           8 :     uno::Reference< text::XText > const xText(xSource, uno::UNO_QUERY_THROW);
    2360             :     uno::Reference< text::XTextCursor > const xCursor =
    2361           8 :         xText->createTextCursor();
    2362           4 :     xCursor->gotoEnd( sal_True );
    2363             : 
    2364             :     uno::Reference< lang::XUnoTunnel > const xCursorTunnel(xCursor,
    2365           8 :         uno::UNO_QUERY_THROW);
    2366             : 
    2367             :     OTextCursorHelper *const pCursor =
    2368           4 :         ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCursorTunnel);
    2369           4 :     if (!pCursor)
    2370             :     {
    2371           0 :         throw uno::RuntimeException();
    2372             :     }
    2373             : 
    2374           8 :     SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
    2375           8 :     SwPosition rPos( rNdIndex );
    2376           8 :     m_pImpl->m_pDoc->CopyRange( *pCursor->GetPaM(), rPos, false );
    2377           4 : }
    2378             : 
    2379             : 
    2380             : /******************************************************************
    2381             :  * SwXBodyText
    2382             :  ******************************************************************/
    2383         576 : SwXBodyText::SwXBodyText(SwDoc *const pDoc)
    2384         576 :     : SwXText(pDoc, CURSOR_BODY)
    2385             : {
    2386         576 : }
    2387             : 
    2388        1148 : SwXBodyText::~SwXBodyText()
    2389             : {
    2390        1148 : }
    2391             : 
    2392             : OUString SAL_CALL
    2393           0 : SwXBodyText::getImplementationName() throw (uno::RuntimeException)
    2394             : {
    2395           0 :     return OUString("SwXBodyText");
    2396             : }
    2397             : 
    2398             : static char const*const g_ServicesBodyText[] =
    2399             : {
    2400             :     "com.sun.star.text.Text",
    2401             : };
    2402             : 
    2403             : static const size_t g_nServicesBodyText(
    2404             :     sizeof(g_ServicesBodyText)/sizeof(g_ServicesBodyText[0]));
    2405             : 
    2406           1 : sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName)
    2407             : throw (uno::RuntimeException)
    2408             : {
    2409             :     return ::sw::SupportsServiceImpl(
    2410           1 :             g_nServicesBodyText, g_ServicesBodyText, rServiceName);
    2411             : }
    2412             : 
    2413             : uno::Sequence< OUString > SAL_CALL
    2414           0 : SwXBodyText::getSupportedServiceNames() throw (uno::RuntimeException)
    2415             : {
    2416             :     return ::sw::GetSupportedServiceNamesImpl(
    2417           0 :             g_nServicesBodyText, g_ServicesBodyText);
    2418             : }
    2419             : 
    2420             : uno::Any SAL_CALL
    2421         984 : SwXBodyText::queryAggregation(const uno::Type& rType)
    2422             : throw (uno::RuntimeException)
    2423             : {
    2424         984 :     uno::Any aRet;
    2425         984 :     if (rType == container::XEnumerationAccess::static_type())
    2426             :     {
    2427         674 :         aRet <<= uno::Reference< container::XEnumerationAccess >(this);
    2428             :     }
    2429         310 :     else if (rType == container::XElementAccess::static_type())
    2430             :     {
    2431           4 :         aRet <<= uno::Reference< container::XElementAccess >(this);
    2432             :     }
    2433         306 :     else if (rType == lang::XServiceInfo::static_type())
    2434             :     {
    2435           2 :         aRet <<= uno::Reference< lang::XServiceInfo >(this);
    2436             :     }
    2437             :     else
    2438             :     {
    2439         304 :         aRet = SwXText::queryInterface( rType );
    2440             :     }
    2441         984 :     if(aRet.getValueType() == ::getCppuVoidType())
    2442             :     {
    2443         304 :         aRet = OWeakAggObject::queryAggregation( rType );
    2444             :     }
    2445         984 :     return aRet;
    2446             : }
    2447             : 
    2448             : uno::Sequence< uno::Type > SAL_CALL
    2449           3 : SwXBodyText::getTypes() throw (uno::RuntimeException)
    2450             : {
    2451           3 :     const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes();
    2452           6 :     const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
    2453           6 :     return ::comphelper::concatSequences(aTypes, aTextTypes);
    2454             : }
    2455             : 
    2456             : namespace
    2457             : {
    2458             :     class theSwXBodyTextImplementationId : public rtl::Static< UnoTunnelIdInit, theSwXBodyTextImplementationId> {};
    2459             : }
    2460             : 
    2461             : uno::Sequence< sal_Int8 > SAL_CALL
    2462           3 : SwXBodyText::getImplementationId() throw (uno::RuntimeException)
    2463             : {
    2464           3 :     return theSwXBodyTextImplementationId::get().getSeq();
    2465             : }
    2466             : 
    2467             : uno::Any SAL_CALL
    2468        2171 : SwXBodyText::queryInterface(const uno::Type& rType)
    2469             : throw (uno::RuntimeException)
    2470             : {
    2471        2171 :     const uno::Any ret = SwXText::queryInterface(rType);
    2472        2171 :     return (ret.getValueType() == ::getCppuVoidType())
    2473             :         ?   SwXBodyText_Base::queryInterface(rType)
    2474        2171 :         :   ret;
    2475             : }
    2476             : 
    2477        4284 : SwXTextCursor * SwXBodyText::CreateTextCursor(const bool bIgnoreTables)
    2478             : {
    2479        4284 :     if(!IsValid())
    2480             :     {
    2481           0 :         return 0;
    2482             :     }
    2483             : 
    2484             :     // the cursor has to skip tables contained in this text
    2485        4284 :     SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent());
    2486        4284 :     aPam.Move( fnMoveBackward, fnGoDoc );
    2487        4284 :     if (!bIgnoreTables)
    2488             :     {
    2489        4276 :         SwTableNode * pTblNode = aPam.GetNode()->FindTableNode();
    2490        4276 :         SwCntntNode * pCont = 0;
    2491        8648 :         while (pTblNode)
    2492             :         {
    2493          96 :             aPam.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
    2494          96 :             pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
    2495          96 :             pTblNode = pCont->FindTableNode();
    2496             :         }
    2497        4276 :         if (pCont)
    2498             :         {
    2499          95 :             aPam.GetPoint()->nContent.Assign(pCont, 0);
    2500             :         }
    2501             :     }
    2502        4284 :     return new SwXTextCursor(*GetDoc(), this, CURSOR_BODY, *aPam.GetPoint());
    2503             : }
    2504             : 
    2505             : uno::Reference< text::XTextCursor > SAL_CALL
    2506        4276 : SwXBodyText::createTextCursor() throw (uno::RuntimeException)
    2507             : {
    2508        4276 :     SolarMutexGuard aGuard;
    2509             : 
    2510             :     const uno::Reference< text::XTextCursor > xRef(
    2511        4276 :             static_cast<text::XWordCursor*>(CreateTextCursor(false)) );
    2512        4276 :     if (!xRef.is())
    2513             :     {
    2514           0 :         uno::RuntimeException aRuntime;
    2515           0 :         aRuntime.Message = cInvalidObject;
    2516           0 :         throw aRuntime;
    2517             :     }
    2518        4276 :     return xRef;
    2519             : }
    2520             : 
    2521             : uno::Reference< text::XTextCursor > SAL_CALL
    2522        1684 : SwXBodyText::createTextCursorByRange(
    2523             :     const uno::Reference< text::XTextRange > & xTextPosition)
    2524             : throw (uno::RuntimeException)
    2525             : {
    2526        1684 :     SolarMutexGuard aGuard;
    2527             : 
    2528        1684 :     if(!IsValid())
    2529             :     {
    2530           0 :         uno::RuntimeException aRuntime;
    2531           0 :         aRuntime.Message = cInvalidObject;
    2532           0 :         throw aRuntime;
    2533             :     }
    2534             : 
    2535        1684 :     uno::Reference< text::XTextCursor >  aRef;
    2536        3368 :     SwUnoInternalPaM aPam(*GetDoc());
    2537        1684 :     if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
    2538             :     {
    2539        1681 :         if ( !aPam.GetNode()->GetTxtNode() )
    2540           0 :             throw uno::RuntimeException("Invalid text range", uno::Reference< uno::XInterface >() );
    2541             : 
    2542        1681 :         SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
    2543             : 
    2544        1681 :         SwStartNode* p1 = aPam.GetNode()->StartOfSectionNode();
    2545             :         //document starts with a section?
    2546        3397 :         while(p1->IsSectionNode())
    2547             :         {
    2548          35 :             p1 = p1->StartOfSectionNode();
    2549             :         }
    2550        1681 :         SwStartNode *const p2 = rNode.StartOfSectionNode();
    2551             : 
    2552        1681 :         if(p1 == p2)
    2553             :         {
    2554             :             aRef = static_cast<text::XWordCursor*>(
    2555        1679 :                     new SwXTextCursor(*GetDoc(), this, CURSOR_BODY,
    2556        1679 :                         *aPam.GetPoint(), aPam.GetMark()));
    2557             :         }
    2558             :     }
    2559        1684 :     if(!aRef.is())
    2560             :     {
    2561             :         throw uno::RuntimeException( "End of content node doesn't have the proper start node",
    2562           5 :                uno::Reference< uno::XInterface >( *this ) );
    2563             :     }
    2564        3363 :     return aRef;
    2565             : }
    2566             : 
    2567             : uno::Reference< container::XEnumeration > SAL_CALL
    2568         734 : SwXBodyText::createEnumeration()
    2569             : throw (uno::RuntimeException)
    2570             : {
    2571         734 :     SolarMutexGuard aGuard;
    2572             : 
    2573         734 :     if (!IsValid())
    2574             :     {
    2575           0 :         uno::RuntimeException aRuntime;
    2576           0 :         aRuntime.Message = cInvalidObject;
    2577           0 :         throw aRuntime;
    2578             :     }
    2579             : 
    2580         734 :     SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
    2581        1468 :     SwPosition aPos(rNode);
    2582             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2583             :     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
    2584        1468 :         GetDoc()->CreateUnoCrsr(aPos, false));
    2585             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2586         734 :     pUnoCursor->Move(fnMoveBackward, fnGoDoc);
    2587             :     const uno::Reference< container::XEnumeration > xRet
    2588         734 :         = new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_BODY);
    2589        1468 :     return xRet;
    2590             : }
    2591             : 
    2592             : uno::Type SAL_CALL
    2593           1 : SwXBodyText::getElementType() throw (uno::RuntimeException)
    2594             : {
    2595           1 :     return text::XTextRange::static_type();
    2596             : }
    2597             : 
    2598             : sal_Bool SAL_CALL
    2599           1 : SwXBodyText::hasElements() throw (uno::RuntimeException)
    2600             : {
    2601           1 :     SolarMutexGuard aGuard;
    2602             : 
    2603           1 :     if (!IsValid())
    2604             :     {
    2605           0 :         uno::RuntimeException aRuntime;
    2606           0 :         aRuntime.Message = cInvalidObject;
    2607           0 :         throw aRuntime;
    2608             :     }
    2609             : 
    2610           1 :     return sal_True;
    2611             : }
    2612             : 
    2613             : /******************************************************************
    2614             :  *  SwXHeadFootText
    2615             :  ******************************************************************/
    2616         262 : class SwXHeadFootText::Impl
    2617             :     : public SwClient
    2618             : {
    2619             : 
    2620             : public:
    2621             : 
    2622             :     bool                        m_bIsHeader;
    2623             : 
    2624         131 :     Impl(   SwXHeadFootText & /*rThis*/,
    2625             :             SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
    2626             :         : SwClient(& rHeadFootFmt)
    2627         131 :         , m_bIsHeader(bIsHeader)
    2628             :     {
    2629         131 :     }
    2630             : 
    2631         543 :     SwFrmFmt * GetHeadFootFmt() const {
    2632             :         return static_cast<SwFrmFmt*>(
    2633         543 :                 const_cast<SwModify*>(GetRegisteredIn()));
    2634             :     }
    2635             : 
    2636         395 :     SwFrmFmt & GetHeadFootFmtOrThrow() {
    2637         395 :         SwFrmFmt *const pFmt( GetHeadFootFmt() );
    2638         395 :         if (!pFmt) {
    2639             :             throw uno::RuntimeException(OUString(
    2640           0 :                     "SwXHeadFootText: disposed or invalid"), 0);
    2641             :         }
    2642         395 :         return *pFmt;
    2643             :     }
    2644             : protected:
    2645             :     // SwClient
    2646             :     virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew);
    2647             : 
    2648             : };
    2649             : 
    2650           5 : void SwXHeadFootText::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
    2651             : {
    2652           5 :     ClientModify(this, pOld, pNew);
    2653           5 : }
    2654             : 
    2655         508 : bool SwXHeadFootText::IsXHeadFootText(SwClient *const pClient)
    2656             : {
    2657         508 :     return 0 != dynamic_cast<SwXHeadFootText::Impl*>(pClient);
    2658             : }
    2659             : 
    2660             : uno::Reference< text::XText >
    2661         143 : SwXHeadFootText::CreateXHeadFootText(
    2662             :         SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
    2663             : {
    2664             :     // re-use existing SwXHeadFootText
    2665             :     // #i105557#: do not iterate over the registered clients: race condition
    2666         143 :     uno::Reference< text::XText > xText(rHeadFootFmt.GetXObject(),
    2667         143 :             uno::UNO_QUERY);
    2668         143 :     if (!xText.is())
    2669             :     {
    2670             :         SwXHeadFootText *const pXHFT(
    2671         131 :                 new SwXHeadFootText(rHeadFootFmt, bIsHeader));
    2672         131 :         xText.set(pXHFT);
    2673         131 :         rHeadFootFmt.SetXObject(xText);
    2674             :     }
    2675         143 :     return xText;
    2676             : }
    2677             : 
    2678         131 : SwXHeadFootText::SwXHeadFootText(SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
    2679             :     : SwXText(rHeadFootFmt.GetDoc(),
    2680             :             (bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER)
    2681         131 :     , m_pImpl( new SwXHeadFootText::Impl(*this, rHeadFootFmt, bIsHeader) )
    2682             : {
    2683         131 : }
    2684             : 
    2685         262 : SwXHeadFootText::~SwXHeadFootText()
    2686             : {
    2687         262 : }
    2688             : 
    2689             : OUString SAL_CALL
    2690           0 : SwXHeadFootText::getImplementationName() throw (uno::RuntimeException)
    2691             : {
    2692           0 :     return OUString("SwXHeadFootText");
    2693             : }
    2694             : 
    2695             : static char const*const g_ServicesHeadFootText[] =
    2696             : {
    2697             :     "com.sun.star.text.Text",
    2698             : };
    2699             : 
    2700           1 : sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName)
    2701             : throw (uno::RuntimeException)
    2702             : {
    2703             :     return ::sw::SupportsServiceImpl(
    2704             :             SAL_N_ELEMENTS(g_ServicesHeadFootText),
    2705           1 :             g_ServicesHeadFootText, rServiceName);
    2706             : }
    2707             : 
    2708             : uno::Sequence< OUString > SAL_CALL
    2709           0 : SwXHeadFootText::getSupportedServiceNames() throw (uno::RuntimeException)
    2710             : {
    2711             :     return ::sw::GetSupportedServiceNamesImpl(
    2712             :             SAL_N_ELEMENTS(g_ServicesHeadFootText),
    2713           0 :             g_ServicesHeadFootText);
    2714             : }
    2715             : 
    2716         148 : const SwStartNode *SwXHeadFootText::GetStartNode() const
    2717             : {
    2718         148 :     const SwStartNode *pSttNd = 0;
    2719         148 :     SwFrmFmt *const pHeadFootFmt = m_pImpl->GetHeadFootFmt();
    2720         148 :     if(pHeadFootFmt)
    2721             :     {
    2722         148 :         const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
    2723         148 :         if( rFlyCntnt.GetCntntIdx() )
    2724             :         {
    2725         148 :             pSttNd = rFlyCntnt.GetCntntIdx()->GetNode().GetStartNode();
    2726             :         }
    2727             :     }
    2728         148 :     return pSttNd;
    2729             : }
    2730             : 
    2731             : uno::Reference< text::XTextCursor >
    2732         131 : SwXHeadFootText::CreateCursor() throw (uno::RuntimeException)
    2733             : {
    2734         131 :     return createTextCursor();
    2735             : }
    2736             : 
    2737             : uno::Sequence< uno::Type > SAL_CALL
    2738           0 : SwXHeadFootText::getTypes() throw (uno::RuntimeException)
    2739             : {
    2740           0 :     const uno::Sequence< uno::Type > aTypes = SwXHeadFootText_Base::getTypes();
    2741           0 :     const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
    2742           0 :     return ::comphelper::concatSequences(aTypes, aTextTypes);
    2743             : }
    2744             : 
    2745             : namespace
    2746             : {
    2747             :     class theSwXHeadFootTextImplementationId : public rtl::Static< UnoTunnelIdInit, theSwXHeadFootTextImplementationId > {};
    2748             : }
    2749             : 
    2750             : uno::Sequence< sal_Int8 > SAL_CALL
    2751           0 : SwXHeadFootText::getImplementationId() throw (uno::RuntimeException)
    2752             : {
    2753           0 :     return theSwXHeadFootTextImplementationId::get().getSeq();
    2754             : }
    2755             : 
    2756             : uno::Any SAL_CALL
    2757         770 : SwXHeadFootText::queryInterface(const uno::Type& rType)
    2758             : throw (uno::RuntimeException)
    2759             : {
    2760         770 :     const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType);
    2761         770 :     return (ret.getValueType() == ::getCppuVoidType())
    2762             :         ?   SwXText::queryInterface(rType)
    2763         770 :         :   ret;
    2764             : }
    2765             : 
    2766             : uno::Reference< text::XTextCursor > SAL_CALL
    2767         316 : SwXHeadFootText::createTextCursor() throw (uno::RuntimeException)
    2768             : {
    2769         316 :     SolarMutexGuard aGuard;
    2770             : 
    2771         316 :     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
    2772             : 
    2773         316 :     uno::Reference< text::XTextCursor > xRet;
    2774         316 :     const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
    2775         316 :     const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
    2776         632 :     SwPosition aPos(rNode);
    2777         316 :     SwXTextCursor *const pXCursor = new SwXTextCursor(*GetDoc(), this,
    2778         316 :             (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER, aPos);
    2779         316 :     SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor();
    2780         316 :     pUnoCrsr->Move(fnMoveForward, fnGoNode);
    2781             : 
    2782             :     // save current start node to be able to check if there is content
    2783             :     // after the table - otherwise the cursor would be in the body text!
    2784             :     SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType(
    2785         316 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2786             :     // is there a table here?
    2787         316 :     SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
    2788         316 :     SwCntntNode* pCont = 0;
    2789         633 :     while (pTblNode)
    2790             :     {
    2791           1 :         pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
    2792           1 :         pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
    2793           1 :         pTblNode = pCont->FindTableNode();
    2794             :     }
    2795         316 :     if (pCont)
    2796             :     {
    2797           1 :         pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
    2798             :     }
    2799             :     SwStartNode const*const pNewStartNode =
    2800             :         pUnoCrsr->GetNode()->FindSttNodeByType(
    2801         316 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2802         316 :     if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
    2803             :     {
    2804           0 :         uno::RuntimeException aExcept;
    2805           0 :         aExcept.Message = S2U("no text available");
    2806           0 :         throw aExcept;
    2807             :     }
    2808         316 :     xRet = static_cast<text::XWordCursor*>(pXCursor);
    2809         632 :     return xRet;
    2810             : }
    2811             : 
    2812             : uno::Reference< text::XTextCursor > SAL_CALL
    2813          48 : SwXHeadFootText::createTextCursorByRange(
    2814             :     const uno::Reference< text::XTextRange > & xTextPosition)
    2815             : throw (uno::RuntimeException)
    2816             : {
    2817          48 :     SolarMutexGuard aGuard;
    2818             : 
    2819          48 :     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
    2820             : 
    2821          96 :     SwUnoInternalPaM aPam(*GetDoc());
    2822          48 :     if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
    2823             :     {
    2824           0 :         uno::RuntimeException aRuntime;
    2825           0 :         aRuntime.Message = cInvalidObject;
    2826           0 :         throw aRuntime;
    2827             :     }
    2828             : 
    2829          48 :     uno::Reference< text::XTextCursor >  xRet;
    2830          48 :     SwNode& rNode = rHeadFootFmt.GetCntnt().GetCntntIdx()->GetNode();
    2831          96 :     SwPosition aPos(rNode);
    2832          96 :     SwPaM aHFPam(aPos);
    2833          48 :     aHFPam.Move(fnMoveForward, fnGoNode);
    2834             :     SwStartNode *const pOwnStartNode = aHFPam.GetNode()->FindSttNodeByType(
    2835          48 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2836             :     SwStartNode *const p1 = aPam.GetNode()->FindSttNodeByType(
    2837          48 :             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
    2838          48 :     if (p1 == pOwnStartNode)
    2839             :     {
    2840             :         xRet = static_cast<text::XWordCursor*>(
    2841          48 :                 new SwXTextCursor(*GetDoc(), this,
    2842          48 :                     (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER,
    2843          96 :                     *aPam.GetPoint(), aPam.GetMark()));
    2844             :     }
    2845          96 :     return xRet;
    2846             : }
    2847             : 
    2848             : uno::Reference< container::XEnumeration > SAL_CALL
    2849          31 : SwXHeadFootText::createEnumeration()
    2850             : throw (uno::RuntimeException)
    2851             : {
    2852          31 :     SolarMutexGuard aGuard;
    2853             : 
    2854          31 :     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
    2855             : 
    2856          31 :     uno::Reference< container::XEnumeration >  aRef;
    2857          31 :     const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
    2858          31 :     const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
    2859          62 :     SwPosition aPos(rNode);
    2860             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2861             :     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
    2862          62 :         GetDoc()->CreateUnoCrsr(aPos, false));
    2863             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2864          31 :     pUnoCursor->Move(fnMoveForward, fnGoNode);
    2865         124 :     aRef = new SwXParagraphEnumeration(this, pUnoCursor,
    2866          93 :                 (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER);
    2867             : 
    2868          62 :     return aRef;
    2869             : }
    2870             : 
    2871             : uno::Type SAL_CALL
    2872           1 : SwXHeadFootText::getElementType() throw (uno::RuntimeException)
    2873             : {
    2874           1 :     return text::XTextRange::static_type();
    2875             : }
    2876             : 
    2877           1 : sal_Bool SAL_CALL SwXHeadFootText::hasElements() throw (uno::RuntimeException)
    2878             : {
    2879           1 :     return sal_True;
    2880          99 : }
    2881             : 
    2882             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10