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

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

Generated by: LCOV version 1.10