[Libreoffice-commits] core.git: Branch 'feature/refactor-god-objects' - sw/inc sw/Library_sw.mk sw/qa sw/source

Valentin Kettner vakevk+libreoffice at gmail.com
Thu Jul 10 10:10:42 PDT 2014


Rebased ref, commits from common ancestor:
commit 50d3555abd9549cc18285b0730e222f5ec974535
Author: Valentin Kettner <vakevk+libreoffice at gmail.com>
Date:   Mon Jul 7 14:32:02 2014 +0200

    Refactored IDocumentContentOperations out of SwDoc.
    
    Into the new class DocumentContentOperationsManager.
    
    Made SwNodes in sw/inc/ndarr.hxx friend class to
    DocumentContentOperationsManager so it can call DelNodes at end of
    DocumentContentOperationsManager::DeleteSection .
    
    Added DeleteAutoCorrExceptWord to SwDoc, its needed in the Manager.
    
    Added a non const version of SwDoc::GetDfltGrfFmtColl() to SwDoc
    because its needed in the Manager.
    
    Made SwDoc a friend class to DocumentContentOperationsManager so it
    can call SwDoc::checkRedlining and SwDocL::_MakeFlySection.
    
    Moved SwDoc::CopyImpl_ , SwDoc::CopyWithFlyInFly and
    SwDoc::CopyFlyInFlyImpl into the Manager.
    
    Moved "struct ParaRstFmt" and "lcl_RstTxtAttr" from docfmt.cxx
    in DocumentContentOperationsManager.hxx .
    
    Change-Id: Icaab57f4a8c158a85e549ecb4aacc752bc95bbc9

diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 0f5d0a4..06e38a9 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -193,6 +193,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
     sw/source/core/doc/DocumentListItemsManager \
     sw/source/core/doc/DocumentListsManager \
     sw/source/core/doc/DocumentOutlineNodesManager \
+    sw/source/core/doc/DocumentContentOperationsManager \
     sw/source/core/doc/extinput \
     sw/source/core/doc/fmtcol \
     sw/source/core/doc/ftnidx \
diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index 5768460..5227528 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -21,6 +21,8 @@
 #define INCLUDED_SW_INC_IDOCUMENTCONTENTOPERATIONS_HXX
 
 #include <sal/types.h>
+#include <rtl/ustring.hxx>
+using rtl::OUString;
 
 class SwPaM;
 struct SwPosition;
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index ab74b4e..6489035 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -24,7 +24,6 @@
 #include <IDocumentMarkAccess.hxx>
 #include <IDocumentRedlineAccess.hxx>
 #include <IDocumentFieldsAccess.hxx>
-#include <IDocumentContentOperations.hxx>
 #include <IDocumentStylePoolAccess.hxx>
 #include <IDocumentLineNumberAccess.hxx>
 #include <IDocumentStatistics.hxx>
@@ -193,6 +192,7 @@ class IDocumentLinksAdministration;
 class IDocumentListItems;
 class IDocumentListsAccess;
 class IDocumentOutlineNodes;
+class IDocumentContentOperations;
 class _SetGetExpFlds;
 
 namespace sw { namespace mark {
@@ -211,6 +211,7 @@ namespace sw {
     class DocumentListItemsManager;
     class DocumentListsManager;
     class DocumentOutlineNodesManager;
+    class DocumentContentOperationsManager;
 }
 
 namespace com { namespace sun { namespace star {
@@ -250,7 +251,6 @@ class SW_DLLPUBLIC SwDoc :
     public IInterface,
     public IDocumentRedlineAccess,
     public IDocumentFieldsAccess,
-    public IDocumentContentOperations,
     public IDocumentStylePoolAccess,
     public IDocumentLineNumberAccess,
     public IDocumentStatistics,
@@ -258,6 +258,7 @@ class SW_DLLPUBLIC SwDoc :
     public IDocumentLayoutAccess,
     public IDocumentExternalData
 {
+    friend class ::sw::DocumentContentOperationsManager;
 
     friend void _InitCore();
     friend void _FinitCore();
@@ -292,6 +293,7 @@ class SW_DLLPUBLIC SwDoc :
     const ::boost::scoped_ptr< ::sw::DocumentListItemsManager > m_pDocumentListItemsManager;
     const ::boost::scoped_ptr< ::sw::DocumentListsManager > m_pDocumentListsManager;
     const ::boost::scoped_ptr< ::sw::DocumentOutlineNodesManager > m_pDocumentOutlineNodesManager;
+    const ::boost::scoped_ptr< ::sw::DocumentContentOperationsManager > m_pDocumentContentOperationsManager;
 
     // Pointer
     SwFrmFmt        *mpDfltFrmFmt;       //< Default formats.
@@ -427,26 +429,10 @@ private:
     // private methods
     void checkRedlining(RedlineMode_t& _rReadlineMode);
 
-    /** Only for internal use and therefore private.
-     Copy a range within the same or to another document.
-     Position may not lie within range! */
-    bool CopyImpl( SwPaM&, SwPosition&, const bool MakeNewFrms /*= true */,
-            const bool bCopyAll, SwPaM *const pCpyRng /*= 0*/ ) const;
-
     SwFlyFrmFmt* _MakeFlySection( const SwPosition& rAnchPos,
                                 const SwCntntNode& rNode, RndStdIds eRequestId,
                                 const SfxItemSet* pFlyAttrSet,
                                 SwFrmFmt* = 0 );
-
-    SwFlyFrmFmt* _InsNoTxtNode( const SwPosition&rPos, SwNoTxtNode*,
-                                const SfxItemSet* pFlyAttrSet,
-                                const SfxItemSet* pGrfAttrSet,
-                                SwFrmFmt* = 0 );
-
-    void CopyFlyInFlyImpl(  const SwNodeRange& rRg,
-                            const sal_Int32 nEndContentIndex,
-                            const SwNodeIndex& rStartIdx,
-                            const bool bCopyFlyAtFly = false ) const;
     sal_Int8 SetFlyFrmAnchor( SwFrmFmt& rFlyFmt, SfxItemSet& rSet, bool bNewFrms );
 
     typedef SwFmt* (SwDoc:: *FNCopyFmt)( const OUString&, SwFmt*, bool, bool );
@@ -507,11 +493,6 @@ private:
 
     void InitTOXTypes();
     void Paste( const SwDoc& );
-    bool DeleteAndJoinImpl(SwPaM&, const bool);
-    bool DeleteAndJoinWithRedlineImpl(SwPaM&, const bool unused = false);
-    bool DeleteRangeImpl(SwPaM&, const bool unused = false);
-    bool DeleteRangeImplImpl(SwPaM &);
-    bool ReplaceRangeImpl(SwPaM&, OUString const&, const bool);
 
 public:
     enum DocumentType {
@@ -645,52 +626,13 @@ public:
     bool containsUpdatableFields();
 
     // IDocumentContentOperations
-    virtual bool CopyRange(SwPaM&, SwPosition&, const bool bCopyAll) const SAL_OVERRIDE;
-    virtual void DeleteSection(SwNode* pNode) SAL_OVERRIDE;
-    virtual bool DeleteRange(SwPaM&) SAL_OVERRIDE;
-    virtual bool DelFullPara(SwPaM&) SAL_OVERRIDE;
-    // Add optional parameter <bForceJoinNext>, default value <false>
-    // Needed for hiding of deletion redlines
-    virtual bool DeleteAndJoin( SwPaM&,
-                                const bool bForceJoinNext = false ) SAL_OVERRIDE;
-    virtual bool MoveRange(SwPaM&, SwPosition&, SwMoveFlags) SAL_OVERRIDE;
-    virtual bool MoveNodeRange(SwNodeRange&, SwNodeIndex&, SwMoveFlags) SAL_OVERRIDE;
-    virtual bool MoveAndJoin(SwPaM&, SwPosition&, SwMoveFlags) SAL_OVERRIDE;
-    virtual bool Overwrite(const SwPaM &rRg, const OUString& rStr) SAL_OVERRIDE;
-    virtual bool InsertString(const SwPaM &rRg, const OUString&,
-              const enum InsertFlags nInsertMode = INS_EMPTYEXPAND ) SAL_OVERRIDE;
+    IDocumentContentOperations const & getIDocumentContentOperations() const;
+    IDocumentContentOperations & getIDocumentContentOperations();
+    ::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const;
+    ::sw::DocumentContentOperationsManager & GetDocumentContentOperationsManager();
+
     virtual bool UpdateParRsid( SwTxtNode *pTxtNode, sal_uInt32 nVal = 0 );
     virtual bool UpdateRsid( const SwPaM &rRg, sal_Int32 nLen );
-    virtual SwFlyFrmFmt* Insert(const SwPaM &rRg, const OUString& rGrfName, const OUString& rFltName, const Graphic* pGraphic,
-                        const SfxItemSet* pFlyAttrSet, const SfxItemSet* pGrfAttrSet, SwFrmFmt*) SAL_OVERRIDE;
-    virtual SwFlyFrmFmt* Insert(const SwPaM& rRg, const GraphicObject& rGrfObj, const SfxItemSet* pFlyAttrSet,
-                        const SfxItemSet* pGrfAttrSet, SwFrmFmt*) SAL_OVERRIDE;
-    virtual SwDrawFrmFmt* InsertDrawObj(
-        const SwPaM &rRg,
-        SdrObject& rDrawObj,
-        const SfxItemSet& rFlyAttrSet ) SAL_OVERRIDE;
-    virtual SwFlyFrmFmt* Insert(const SwPaM &rRg, const svt::EmbeddedObjectRef& xObj, const SfxItemSet* pFlyAttrSet,
-                        const SfxItemSet* pGrfAttrSet, SwFrmFmt*) SAL_OVERRIDE;
-
-    // Add a para for the char attribute exp...
-    virtual bool InsertPoolItem(
-        const SwPaM &rRg,
-        const SfxPoolItem&,
-        const SetAttrMode nFlags,
-        const bool bExpandCharToPara=false) SAL_OVERRIDE;
-
-    virtual bool InsertItemSet (const SwPaM &rRg, const SfxItemSet&,
-                                const SetAttrMode nFlags) SAL_OVERRIDE;
-    virtual void ReRead(SwPaM&, const OUString& rGrfName, const OUString& rFltName, const Graphic* pGraphic, const GraphicObject* pGrfObj) SAL_OVERRIDE;
-    virtual void TransliterateText(const SwPaM& rPaM, utl::TransliterationWrapper&) SAL_OVERRIDE;
-    virtual SwFlyFrmFmt* InsertOLE(const SwPaM &rRg, const OUString& rObjName, sal_Int64 nAspect, const SfxItemSet* pFlyAttrSet,
-                           const SfxItemSet* pGrfAttrSet, SwFrmFmt*) SAL_OVERRIDE;
-    virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart) SAL_OVERRIDE;
-    virtual bool AppendTxtNode(SwPosition& rPos) SAL_OVERRIDE;
-        virtual void SetModified(SwPaM &rPaM);
-    virtual bool ReplaceRange(SwPaM& rPam, const OUString& rNewStr,
-                              const bool bRegExReplace) SAL_OVERRIDE;
-    virtual void RemoveLeadingWhiteSpace(const SwPosition & rPos ) SAL_OVERRIDE;
 
     // IDocumentStylePoolAccess
     virtual SwTxtFmtColl* GetTxtCollFromPool( sal_uInt16 nId, bool bRegardLanguage = true ) SAL_OVERRIDE;
@@ -845,14 +787,6 @@ public:
                                 const SwSelBoxes* pSelBoxes = 0,
                                 SwFrmFmt *pParent = 0 );
 
-    void CopyWithFlyInFly( const SwNodeRange& rRg,
-                            const sal_Int32 nEndContentIndex,
-                            const SwNodeIndex& rInsPos,
-                            const SwPaM* pCopiedPaM = NULL,
-                            bool bMakeNewFrms = true,
-                            bool bDelRedlines = true,
-                            bool bCopyFlyAtFly = false ) const;
-
     //UUUU Helper that checks for unique items for DrawingLayer items of type NameOrIndex
     // and evtl. corrects that items to ensure unique names for that type. This call may
     // modify/correct entries inside of the given SfxItemSet, and it will apply a name to
@@ -1043,6 +977,7 @@ public:
     void ChkCondColls();
 
     const SwGrfFmtColl* GetDfltGrfFmtColl() const   { return mpDfltGrfFmtColl; }
+    SwGrfFmtColl* GetDfltGrfFmtColl()  { return mpDfltGrfFmtColl; }
     const SwGrfFmtColls *GetGrfFmtColls() const     { return mpGrfFmtCollTbl; }
     SwGrfFmtColl *MakeGrfFmtColl(const OUString &rFmtName,
                                     SwGrfFmtColl *pDerivedFrom);
@@ -1592,6 +1527,7 @@ public:
     // Save current values for automatic registration of exceptions in Autocorrection.
     void SetAutoCorrExceptWord( SwAutoCorrExceptWord* pNew );
     SwAutoCorrExceptWord* GetAutoCorrExceptWord()       { return mpACEWord; }
+    void DeleteAutoCorrExceptWord();
 
     const SwFmtINetFmt* FindINetAttr( const OUString& rName ) const;
 
diff --git a/sw/inc/ndarr.hxx b/sw/inc/ndarr.hxx
index d8c71d6..a004af3 100644
--- a/sw/inc/ndarr.hxx
+++ b/sw/inc/ndarr.hxx
@@ -64,6 +64,8 @@ class SwUndoTblToTxt;
 class SwUndoTxtToTbl;
 struct SwPosition;
 
+namespace sw { class DocumentContentOperationsManager; }
+
 // class SwNodes
 
 typedef SwNode * SwNodePtr;
@@ -88,6 +90,7 @@ class SW_DLLPUBLIC SwNodes
     friend class SwDoc;
     friend class SwNode;
     friend class SwNodeIndex;
+    friend class ::sw::DocumentContentOperationsManager;
 
     SwNodeIndex* pRoot;                 ///< List of all indices on nodes.
 
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index c15ca72..75cbf77 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -187,7 +187,7 @@ void SwDocTest::testDocStat()
     SwPaM aPaM(aIdx);
 
     OUString sText("Hello World");
-    m_pDoc->InsertString(aPaM, sText);
+    m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sText);
 
     CPPUNIT_ASSERT_MESSAGE("Should still be non-updated 0 count", m_pDoc->GetDocStat().nChar == 0);
 
@@ -230,15 +230,15 @@ void SwDocTest::testModelToViewHelper()
         SwFmtFtn aFtn;
         aFtn.SetNumStr(OUString("foo"));
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString("AAAAA BBBBB "));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("AAAAA BBBBB "));
         SwTxtNode* pTxtNode = aPaM.GetNode().GetTxtNode();
         sal_Int32 nPos = aPaM.GetPoint()->nContent.GetIndex();
         pTxtNode->InsertItem(aFtn, nPos, nPos);
-        m_pDoc->InsertString(aPaM, OUString(" CCCCC "));
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(" CCCCC "));
         nPos = aPaM.GetPoint()->nContent.GetIndex();
         pTxtNode->InsertItem(aFtn, nPos, nPos);
-        m_pDoc->InsertString(aPaM, OUString(" DDDDD"));
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(" DDDDD"));
         CPPUNIT_ASSERT(pTxtNode->GetTxt().getLength() == (4*5) + 5 + 2);
 
         //set start of selection to first B
@@ -248,7 +248,7 @@ void SwDocTest::testModelToViewHelper()
         aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 14);
         //set character attribute hidden on range
         SvxCharHiddenItem aHidden(true, RES_CHRATR_HIDDEN);
-        m_pDoc->InsertPoolItem(aPaM, aHidden, 0 );
+        m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aHidden, 0 );
         aPaM.DeleteMark();
 
         //turn on red-lining and show changes
@@ -261,7 +261,7 @@ void SwDocTest::testModelToViewHelper()
         aPaM.SetMark();
         //set end of selection to second last B
         aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 9);
-        m_pDoc->DeleteAndJoin(aPaM);    //redline-aware deletion api
+        m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPaM);    //redline-aware deletion api
         aPaM.DeleteMark();
 
         {
@@ -400,8 +400,8 @@ void SwDocTest::testModelToViewHelper()
                 aModelToViewHelper.getFieldPositions().size());
         }
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString("AAAAA"));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("AAAAA"));
         IDocumentMarkAccess* pMarksAccess = m_pDoc->getIDocumentMarkAccess();
         sw::mark::IFieldmark *pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(
                 pMarksAccess->makeNoTextFieldBookmark(aPaM, "test", ODF_FORMDROPDOWN));
@@ -410,7 +410,7 @@ void SwDocTest::testModelToViewHelper()
         vListEntries[0] = "BBBBB";
         (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] = uno::makeAny(vListEntries);
         (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] = uno::makeAny(sal_Int32(0));
-        m_pDoc->InsertString(aPaM, OUString("CCCCC"));
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("CCCCC"));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11),
                 pTxtNode->GetTxt().getLength());
@@ -473,13 +473,13 @@ void SwDocTest::testSwScanner()
     {
         const sal_Unicode IDEOGRAPHICFULLSTOP_D[] = { 0x3002, 'D' };
 
-        m_pDoc->InsertString(aPaM, OUString(IDEOGRAPHICFULLSTOP_D,
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(IDEOGRAPHICFULLSTOP_D,
             SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D)));
 
         SvxLanguageItem aCJKLangItem( LANGUAGE_CHINESE_SIMPLIFIED, RES_CHRATR_CJK_LANGUAGE );
         SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE );
-        m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 );
-        m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 );
+        m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aCJKLangItem, 0 );
+        m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aWestLangItem, 0 );
 
         SwDocStat aDocStat;
         pTxtNode = aPaM.GetNode().GetTxtNode();
@@ -508,14 +508,14 @@ void SwDocTest::testSwScanner()
             0x0020, 0x0064, 0x006F, 0x0065, 0x0073, 0x0020, 0x0074, 0x0068,
             0x0069, 0x0073, 0x0020, 0x0064, 0x006F, 0x003F, 0x0020, 0x0020
         };
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString(test,
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(test,
             SAL_N_ELEMENTS(test)));
 
         SvxLanguageItem aCJKLangItem( LANGUAGE_JAPANESE, RES_CHRATR_CJK_LANGUAGE );
         SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE );
-        m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 );
-        m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 );
+        m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aCJKLangItem, 0 );
+        m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aWestLangItem, 0 );
 
         SwDocStat aDocStat;
         pTxtNode = aPaM.GetNode().GetTxtNode();
@@ -537,8 +537,8 @@ void SwDocTest::testSwScanner()
             0x0065, 0x0065, 0x2019
         };
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString(aShouldBeThree, SAL_N_ELEMENTS(aShouldBeThree)));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(aShouldBeThree, SAL_N_ELEMENTS(aShouldBeThree)));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeThree));
         CPPUNIT_ASSERT_MESSAGE("Should be 3", aDocStat.nWord == 3);
@@ -554,8 +554,8 @@ void SwDocTest::testSwScanner()
             0x006C, 0x0065, 0x0072, 0x3000, 0x00BB
         };
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString(aShouldBeFive, SAL_N_ELEMENTS(aShouldBeFive)));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(aShouldBeFive, SAL_N_ELEMENTS(aShouldBeFive)));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         aDocStat.Reset();
         pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeFive));
@@ -566,8 +566,8 @@ void SwDocTest::testSwScanner()
     {
         SwDocStat aDocStat;
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString("Apple"));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Apple"));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         sal_Int32 nPos = aPaM.GetPoint()->nContent.GetIndex();
         SwFmtFtn aFtn;
@@ -591,16 +591,16 @@ void SwDocTest::testSwScanner()
         CPPUNIT_ASSERT(aDocStat.nWord == 1);
         CPPUNIT_ASSERT_MESSAGE("refmark anchor should not be counted", aDocStat.nChar == 11);
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString("Apple"));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Apple"));
 
         DateTime aDate(DateTime::SYSTEM);
         SwPostItField aPostIt(
             (SwPostItFieldType*)m_pDoc->GetSysFldType(RES_POSTITFLD), OUString("An Author"),
             OUString("Some Text"), OUString("Initials"), OUString("Name"), aDate );
-        m_pDoc->InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0);
+        m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0);
 
-        m_pDoc->InsertString(aPaM, OUString("Apple"));
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Apple"));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         aDocStat.Reset();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
@@ -616,8 +616,8 @@ void SwDocTest::testSwScanner()
         SwDocStat aDocStat;
 
         const char aString[] = "Lorem ipsum";
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString(aString));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(aString));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(2));
@@ -630,7 +630,7 @@ void SwDocTest::testSwScanner()
         //delete everything except the first word
         aPaM.SetMark(); //set start of selection to current pos
         aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 5);   //set end of selection to fifth char of current node
-        m_pDoc->DeleteAndJoin(aPaM);    //redline-aware deletion api
+        m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPaM);    //redline-aware deletion api
         //"real underlying text should be the same"
         CPPUNIT_ASSERT_EQUAL(pTxtNode->GetTxt(), OUString(aString));
 
@@ -679,8 +679,8 @@ void SwDocTest::testSwScanner()
 
         OUString sTemplate("ThisXis a test.");
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', ' '));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', ' '));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
@@ -688,8 +688,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 15);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" = ")));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" = ")));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 5 &&
@@ -697,8 +697,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 17);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" _ ")));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" _ ")));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 5 &&
@@ -706,8 +706,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 17);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" -- ")));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" -- ")));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 5 &&
@@ -715,8 +715,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 18);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', '_'));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', '_'));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
@@ -724,8 +724,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 15);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', '-'));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', '-'));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
@@ -733,8 +733,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 15);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2012));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2012));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
@@ -742,8 +742,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 15);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2015));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2015));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
@@ -753,8 +753,8 @@ void SwDocTest::testSwScanner()
 
         //But default configuration should, msword-alike treak emdash
         //and endash as word separators for word-counting
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2013));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2013));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
@@ -762,8 +762,8 @@ void SwDocTest::testSwScanner()
                        aDocStat.nChar == 15);
         aDocStat.Reset();
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2014));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2014));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
@@ -773,8 +773,8 @@ void SwDocTest::testSwScanner()
 
         const sal_Unicode aChunk[] = {' ', 0x2013, ' '};
         OUString sChunk(aChunk, SAL_N_ELEMENTS(aChunk));
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, sTemplate.replaceAll(OUString('X'), sChunk));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), sChunk));
         pTxtNode = aPaM.GetNode().GetTxtNode();
         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
@@ -792,14 +792,14 @@ void SwDocTest::testGraphicAnchorDeletion()
     SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
     SwPaM aPaM(aIdx);
 
-    m_pDoc->InsertString(aPaM, OUString("Paragraph 1"));
-    m_pDoc->AppendTxtNode(*aPaM.GetPoint());
+    m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 1"));
+    m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
 
-    m_pDoc->InsertString(aPaM, OUString("graphic anchor>><<graphic anchor"));
+    m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("graphic anchor>><<graphic anchor"));
     SwNodeIndex nPara2 = aPaM.GetPoint()->nNode;
-    m_pDoc->AppendTxtNode(*aPaM.GetPoint());
+    m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
 
-    m_pDoc->InsertString(aPaM, OUString("Paragraph 3"));
+    m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 3"));
 
     aPaM.GetPoint()->nNode = nPara2;
     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>>"));
@@ -809,7 +809,7 @@ void SwDocTest::testGraphicAnchorDeletion()
     SwFmtAnchor aAnchor(FLY_AS_CHAR);
     aAnchor.SetAnchor(aPaM.GetPoint());
     aFlySet.Put(aAnchor);
-    SwFlyFrmFmt *pFrame = m_pDoc->Insert(aPaM, OUString(), OUString(), NULL, &aFlySet, NULL, NULL);
+    SwFlyFrmFmt *pFrame = m_pDoc->getIDocumentContentOperations().Insert(aPaM, OUString(), OUString(), NULL, &aFlySet, NULL, NULL);
     CPPUNIT_ASSERT_MESSAGE("Expected frame", pFrame != NULL);
 
     CPPUNIT_ASSERT_MESSAGE("Should be 1 graphic", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 1);
@@ -821,7 +821,7 @@ void SwDocTest::testGraphicAnchorDeletion()
     aPaM.SetMark();
     aPaM.GetPoint()->nNode = nPara2;
     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>"));
-    m_pDoc->DeleteRange(aPaM);
+    m_pDoc->getIDocumentContentOperations().DeleteRange(aPaM);
 
 #ifdef DEBUG_AS_HTML
     {
@@ -908,7 +908,7 @@ void SwDocTest::randomTest()
             switch (getRand (i < 50 ? 3 : 6)) {
             // insert ops first
             case 0: {
-                if (!m_pDoc->InsertString(aCrs, getRandString())) {
+                if (!m_pDoc->getIDocumentContentOperations().InsertString(aCrs, getRandString())) {
 //                    fprintf (stderr, "failed to insert string !\n");
                 }
                 break;
@@ -925,17 +925,17 @@ void SwDocTest::randomTest()
             case 3: // deletion
                 switch (getRand(6)) {
                 case 0:
-                    m_pDoc->DelFullPara(aCrs);
+                    m_pDoc->getIDocumentContentOperations().DelFullPara(aCrs);
                     break;
                 case 1:
-                    m_pDoc->DeleteRange(aCrs);
+                    m_pDoc->getIDocumentContentOperations().DeleteRange(aCrs);
                     break;
                 case 2:
-                    m_pDoc->DeleteAndJoin(aCrs, !!getRand(1));
+                    m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aCrs, !!getRand(1));
                     break;
                 case 3:
                 default:
-                    m_pDoc->Overwrite(aCrs, getRandString());
+                    m_pDoc->getIDocumentContentOperations().Overwrite(aCrs, getRandString());
                     break;
                 }
                 break;
@@ -949,7 +949,7 @@ void SwDocTest::randomTest()
                          IDocumentContentOperations::DOC_MOVEREDLINES |
                          IDocumentContentOperations::DOC_NO_DELFRMS);
                 SwPosition aTo(getRandomPosition(m_pDoc, i/10));
-                m_pDoc->MoveRange(aCrs, aTo, nFlags);
+                m_pDoc->getIDocumentContentOperations().MoveRange(aCrs, aTo, nFlags);
                 break;
             }
 
@@ -983,7 +983,7 @@ translitTest(SwDoc & rDoc, SwPaM & rPaM, sal_uInt32 const nType)
 {
     utl::TransliterationWrapper aTrans(
             ::comphelper::getProcessComponentContext(), nType);
-    rDoc.TransliterateText(rPaM, aTrans);
+    rDoc.getIDocumentContentOperations().TransliterateText(rPaM, aTrans);
     return rPaM.GetTxt();
 }
 
@@ -992,7 +992,7 @@ void SwDocTest::testTransliterate()
     // just some simple test to see if it's totally broken
     SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
     SwPaM aPaM(aIdx);
-    m_pDoc->InsertString(aPaM, OUString("foobar"));
+    m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("foobar"));
     aPaM.SetMark();
     aPaM.GetPoint()->nContent = 0;
     CPPUNIT_ASSERT_EQUAL(OUString("foobar"), aPaM.GetTxt());
@@ -1024,19 +1024,19 @@ void SwDocTest::testMarkMove()
     {
         SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
         SwPaM aPaM(aIdx);
-        m_pDoc->InsertString(aPaM, OUString("Paragraph 1"));
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 1"));
         aPaM.SetMark();
         aPaM.GetMark()->nContent -= aPaM.GetMark()->nContent.GetIndex();
         pMarksAccess->makeMark(aPaM, OUString("Para1"), IDocumentMarkAccess::BOOKMARK);
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString("Paragraph 2"));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 2"));
         aPaM.SetMark();
         aPaM.GetMark()->nContent -= aPaM.GetMark()->nContent.GetIndex();
         pMarksAccess->makeMark(aPaM, OUString("Para2"), IDocumentMarkAccess::BOOKMARK);
 
-        m_pDoc->AppendTxtNode(*aPaM.GetPoint());
-        m_pDoc->InsertString(aPaM, OUString("Paragraph 3"));
+        m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
+        m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 3"));
         aPaM.SetMark();
         aPaM.GetMark()->nContent -= aPaM.GetMark()->nContent.GetIndex();
         pMarksAccess->makeMark(aPaM, OUString("Para3"), IDocumentMarkAccess::BOOKMARK);
@@ -1083,7 +1083,7 @@ void SwDocTest::testMarkMove()
         SwPaM aPaM(aIdx, aIdx, -1);
         aPaM.GetPoint()->nContent += 5;
         aPaM.GetMark()->nContent += 6;
-        m_pDoc->DeleteAndJoin(aPaM);
+        m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPaM);
     }
     pBM1 = pMarksAccess->findMark("Para1")->get();
     pBM2 = pMarksAccess->findMark("Para2")->get();
@@ -1119,7 +1119,7 @@ void SwDocTest::testMarkMove()
         SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
         SwPosition aPos(aIdx);
         aPos.nContent += 8;
-        m_pDoc->SplitNode(aPos, false);
+        m_pDoc->getIDocumentContentOperations().SplitNode(aPos, false);
     }
     pBM1 = pMarksAccess->findMark("Para1")->get();
     pBM2 = pMarksAccess->findMark("Para2")->get();
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index b279e7c..32726bd 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -98,11 +98,11 @@ void SwUiWriterTest::testReplaceForward()
     SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
     SwPaM aPaM(aIdx);
 
-    pDoc->InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
+    pDoc->getIDocumentContentOperations().InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
 
     SwTxtNode* pTxtNode = aPaM.GetNode().GetTxtNode();
     lcl_selectCharacters(aPaM, 5, 9);
-    pDoc->ReplaceRange(aPaM, OUString("toto"), false);
+    pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, OUString("toto"), false);
 
     CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTxtNode->GetTxt());
 
@@ -148,11 +148,11 @@ void SwUiWriterTest::testReplaceBackward()
     SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
     SwPaM aPaM(aIdx);
 
-    pDoc->InsertString(aPaM, OUString("toto titi tutu"));
+    pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("toto titi tutu"));
     SwTxtNode* pTxtNode = aPaM.GetNode().GetTxtNode();
     lcl_selectCharacters(aPaM, 9, 5);
 
-    pDoc->ReplaceRange(aPaM, OUString("toto"), false);
+    pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, OUString("toto"), false);
 
     CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTxtNode->GetTxt());
 
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 6452bdf..0f533d1 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -72,7 +72,7 @@ namespace
         if( ( ch_start != aStartMark ) && ( aEndMark != CH_TXT_ATR_FORMELEMENT ) )
         {
             SwPaM aStartPaM(rStart);
-            io_pDoc->InsertString(aStartPaM, OUString(aStartMark));
+            io_pDoc->getIDocumentContentOperations().InsertString(aStartPaM, OUString(aStartMark));
             rStart.nContent--;
             pField->SetMarkStartPos( rStart );
         }
@@ -85,7 +85,7 @@ namespace
         if ( aEndMark && ( ch_end != aEndMark ) )
         {
             SwPaM aEndPaM(rEnd);
-            io_pDoc->InsertString(aEndPaM, OUString(aEndMark));
+            io_pDoc->getIDocumentContentOperations().InsertString(aEndPaM, OUString(aEndMark));
             rEnd.nContent++;
         }
 
@@ -108,7 +108,7 @@ namespace
         {
             SwPaM aStart(rStart, rStart);
             aStart.End()->nContent++;
-            io_pDoc->DeleteRange(aStart);
+            io_pDoc->getIDocumentContentOperations().DeleteRange(aStart);
         }
 
         const SwPosition& rEnd = pField->GetMarkEnd();
@@ -121,7 +121,7 @@ namespace
         {
             SwPaM aEnd(rEnd, rEnd);
             aEnd.Start()->nContent--;
-            io_pDoc->DeleteRange(aEnd);
+            io_pDoc->getIDocumentContentOperations().DeleteRange(aEnd);
         }
 
         io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index 8ff7f73..6fcef4a 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -1850,7 +1850,7 @@ bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
 
             for( sal_uInt16 n = 0; n < aFPos.nParaCnt + aFPos.nColumnCnt; ++n )
             {
-                GetDoc()->AppendTxtNode( aPos );
+                GetDoc()->getIDocumentContentOperations().AppendTxtNode( aPos );
                 if( !n && pNextFmt )
                 {
                     *m_pCurCrsr->GetPoint() = aPos;
@@ -1859,7 +1859,7 @@ bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
                 if( n < aFPos.nColumnCnt )
                 {
                     *m_pCurCrsr->GetPoint() = aPos;
-                    GetDoc()->InsertPoolItem( *m_pCurCrsr,
+                    GetDoc()->getIDocumentContentOperations().InsertPoolItem( *m_pCurCrsr,
                             SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
                 }
             }
@@ -1885,7 +1885,7 @@ bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
                     if( SVX_ADJUST_LEFT != rAdj.GetAdjust() )
                         aSet.Put( SvxAdjustItem( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ) );
 
-                    GetDoc()->InsertItemSet( *m_pCurCrsr, aSet, 0 );
+                    GetDoc()->getIDocumentContentOperations().InsertItemSet( *m_pCurCrsr, aSet, 0 );
                 }
                 else {
                     OSL_ENSURE( !this, "No CntntNode" );
@@ -1901,7 +1901,7 @@ bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
                     if (aFPos.nSpaceCnt)
                         comphelper::string::padToLength(sInsert, sInsert.getLength() + aFPos.nSpaceCnt, ' ');
                     if (!sInsert.isEmpty())
-                        GetDoc()->InsertString( *m_pCurCrsr, sInsert.makeStringAndClear());
+                        GetDoc()->getIDocumentContentOperations().InsertString( *m_pCurCrsr, sInsert.makeStringAndClear());
                 }
                 // no break - still need to set orientation
             case FILL_MARGIN:
@@ -1919,7 +1919,7 @@ bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
                     default:
                         break;
                     }
-                    GetDoc()->InsertPoolItem( *m_pCurCrsr, aAdj, 0 );
+                    GetDoc()->getIDocumentContentOperations().InsertPoolItem( *m_pCurCrsr, aAdj, 0 );
                 }
                 break;
             }
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index bc581a7..21aa531 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -1152,7 +1152,7 @@ int SwFindParaAttr::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion,
 
         boost::scoped_ptr<OUString> pRepl( (bRegExp) ?
                 ReplaceBackReferences( *pSearchOpt, pCrsr ) : 0 );
-        rCursor.GetDoc()->ReplaceRange( *pCrsr,
+        rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange( *pCrsr,
             (pRepl.get()) ? *pRepl : pSearchOpt->replaceString,
             bRegExp );
         rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() );
@@ -1177,7 +1177,7 @@ int SwFindParaAttr::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion,
         // they are not in ReplaceSet
         if( !pSet->Count() )
         {
-            pCrsr->GetDoc()->InsertItemSet( *pCrsr, *pReplSet, 0 );
+            pCrsr->GetDoc()->getIDocumentContentOperations().InsertItemSet( *pCrsr, *pReplSet, 0 );
         }
         else
         {
@@ -1198,7 +1198,7 @@ int SwFindParaAttr::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion,
                 pItem = aIter.NextItem();
             }
             aSet.Put( *pReplSet );
-            pCrsr->GetDoc()->InsertItemSet( *pCrsr, aSet, 0 );
+            pCrsr->GetDoc()->getIDocumentContentOperations().InsertItemSet( *pCrsr, aSet, 0 );
         }
 
         return FIND_NO_RING;
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index b8e2b47..e6af731 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -582,7 +582,7 @@ int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove,
 
         boost::scoped_ptr<OUString> pRepl( (bRegExp)
                 ? ReplaceBackReferences( rSearchOpt, pCrsr ) : 0 );
-        rCursor.GetDoc()->ReplaceRange( *pCrsr,
+        rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange( *pCrsr,
             (pRepl.get()) ? *pRepl : rSearchOpt.replaceString,
             bRegExp );
         rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() );
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
new file mode 100644
index 0000000..2b9c226
--- /dev/null
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -0,0 +1,4443 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <DocumentContentOperationsManager.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <UndoManager.hxx>
+#include <docary.hxx>
+#include <textboxhelper.hxx>
+#include <dcontact.hxx>
+#include <grfatr.hxx>
+#include <numrule.hxx>
+#include <charfmt.hxx>
+#include <ndgrf.hxx>
+#include <ndnotxt.hxx>
+#include <ndole.hxx>
+#include <fmtcol.hxx>
+#include <breakit.hxx>
+#include <frmfmt.hxx>
+#include <fmtanchr.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtcnct.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <redline.hxx>
+#include <unocrsr.hxx>
+#include <mvsave.hxx>
+#include <ndtxt.hxx>
+#include <poolfmt.hxx>
+#include <paratr.hxx>
+#include <txatbase.hxx>
+#include <UndoRedline.hxx>
+#include <undobj.hxx>
+#include <UndoDelete.hxx>
+#include <UndoSplitMove.hxx>
+#include <UndoOverwrite.hxx>
+#include <UndoInsert.hxx>
+#include <UndoAttribute.hxx>
+#include <rolbck.hxx>
+#include <acorrect.hxx>
+#include <ftnidx.hxx>
+#include <txtftn.hxx>
+#include <hints.hxx>
+#include <crsrsh.hxx>
+#include <fmtflcnt.hxx>
+#include <unotools/charclass.hxx>
+#include <sfx2/Metadatable.hxx>
+#include <svl/stritem.hxx>
+#include <svl/itemiter.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdouno.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <com/sun/star/i18n/Boundary.hpp>
+
+using namespace ::com::sun::star::i18n;
+
+extern void sw_GetJoinFlags( SwPaM& rPam, bool& rJoinTxt, bool& rJoinPrev );
+extern void sw_JoinText( SwPaM& rPam, bool bJoinPrev );
+//local functions originally from sw/source/core/docnode/ndcopy.cxx
+namespace
+{
+    // Copy method from SwDoc
+    // Prevent copying in Flys that are anchored in the area
+    static bool lcl_ChkFlyFly( SwDoc* pDoc, sal_uLong nSttNd, sal_uLong nEndNd,
+                        sal_uLong nInsNd )
+    {
+        const SwFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
+
+        for( sal_uInt16 n = 0; n < rFrmFmtTbl.size(); ++n )
+        {
+            SwFrmFmt const*const  pFmt = rFrmFmtTbl[n];
+            SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
+            SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
+            if (pAPos &&
+                ((FLY_AS_CHAR == pAnchor->GetAnchorId()) ||
+                 (FLY_AT_CHAR == pAnchor->GetAnchorId()) ||
+                 (FLY_AT_FLY  == pAnchor->GetAnchorId()) ||
+                 (FLY_AT_PARA == pAnchor->GetAnchorId())) &&
+                nSttNd <= pAPos->nNode.GetIndex() &&
+                pAPos->nNode.GetIndex() < nEndNd )
+            {
+                const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
+                SwStartNode* pSNd;
+                if( !rCntnt.GetCntntIdx() ||
+                    0 == ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ))
+                    continue;
+
+                if( pSNd->GetIndex() < nInsNd &&
+                    nInsNd < pSNd->EndOfSectionIndex() )
+                    // Do not copy !
+                    return true;
+
+                if( lcl_ChkFlyFly( pDoc, pSNd->GetIndex(),
+                            pSNd->EndOfSectionIndex(), nInsNd ) )
+                    // Do not copy !
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    /*
+        The lcl_CopyBookmarks function has to copy bookmarks from the source to the destination nodes
+        array. It is called after a call of the _CopyNodes(..) function. But this function does not copy
+        every node (at least at the moment: 2/08/2006 ), section start and end nodes will not be copied if the corresponding end/start node is outside the copied pam.
+        The lcl_NonCopyCount function counts the number of these nodes, given the copied pam and a node
+        index inside the pam.
+        rPam is the original source pam, rLastIdx is the last calculated position, rDelCount the number
+        of "non-copy" nodes between rPam.Start() and rLastIdx.
+        nNewIdx is the new position of interest.
+    */
+
+    static void lcl_NonCopyCount( const SwPaM& rPam, SwNodeIndex& rLastIdx, const sal_uLong nNewIdx, sal_uLong& rDelCount )
+    {
+        sal_uLong nStart = rPam.Start()->nNode.GetIndex();
+        sal_uLong nEnd = rPam.End()->nNode.GetIndex();
+        if( rLastIdx.GetIndex() < nNewIdx ) // Moving forward?
+        {
+            do // count "non-copy" nodes
+            {
+                SwNode& rNode = rLastIdx.GetNode();
+                if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
+                    || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
+                    ++rDelCount;
+                ++rLastIdx;
+            }
+            while( rLastIdx.GetIndex() < nNewIdx );
+        }
+        else if( rDelCount ) // optimization: if there are no "non-copy" nodes until now,
+                             // no move backward needed
+        {
+            while( rLastIdx.GetIndex() > nNewIdx )
+            {
+                SwNode& rNode = rLastIdx.GetNode();
+                if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
+                    || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
+                    --rDelCount;
+                rLastIdx--;
+            }
+        }
+    }
+
+    static void lcl_SetCpyPos( const SwPosition& rOrigPos,
+                        const SwPosition& rOrigStt,
+                        const SwPosition& rCpyStt,
+                        SwPosition& rChgPos,
+                        sal_uLong nDelCount )
+    {
+        sal_uLong nNdOff = rOrigPos.nNode.GetIndex();
+        nNdOff -= rOrigStt.nNode.GetIndex();
+        nNdOff -= nDelCount;
+        sal_Int32 nCntntPos = rOrigPos.nContent.GetIndex();
+
+        // Always adjust <nNode> at to be changed <SwPosition> instance <rChgPos>
+        rChgPos.nNode = nNdOff + rCpyStt.nNode.GetIndex();
+        if( !nNdOff )
+        {
+            // dann nur den Content anpassen
+            if( nCntntPos > rOrigStt.nContent.GetIndex() )
+                nCntntPos -= rOrigStt.nContent.GetIndex();
+            else
+                nCntntPos = 0;
+            nCntntPos += rCpyStt.nContent.GetIndex();
+        }
+        rChgPos.nContent.Assign( rChgPos.nNode.GetNode().GetCntntNode(), nCntntPos );
+    }
+
+    // TODO: use SaveBookmark (from _DelBookmarks)
+    static void lcl_CopyBookmarks(
+        const SwPaM& rPam,
+        SwPaM& rCpyPam )
+    {
+        const SwDoc* pSrcDoc = rPam.GetDoc();
+        SwDoc* pDestDoc =  rCpyPam.GetDoc();
+        const IDocumentMarkAccess* const pSrcMarkAccess = pSrcDoc->getIDocumentMarkAccess();
+        ::sw::UndoGuard const undoGuard(pDestDoc->GetIDocumentUndoRedo());
+
+        const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
+        SwPosition* pCpyStt = rCpyPam.Start();
+
+        typedef ::std::vector< const ::sw::mark::IMark* > mark_vector_t;
+        mark_vector_t vMarksToCopy;
+        for ( IDocumentMarkAccess::const_iterator_t ppMark = pSrcMarkAccess->getAllMarksBegin();
+              ppMark != pSrcMarkAccess->getAllMarksEnd();
+              ++ppMark )
+        {
+            const ::sw::mark::IMark* const pMark = ppMark->get();
+
+            const SwPosition& rMarkStart = pMark->GetMarkStart();
+            const SwPosition& rMarkEnd = pMark->GetMarkEnd();
+            // only include marks that are in the range and not touching both start and end
+            // - not for annotation marks.
+            const bool bIsNotOnBoundary =
+                pMark->IsExpanded()
+                ? (rMarkStart != rStt || rMarkEnd != rEnd)  // rMarkStart != rMarkEnd
+                : (rMarkStart != rStt && rMarkEnd != rEnd); // rMarkStart == rMarkEnd
+            if ( rMarkStart >= rStt && rMarkEnd <= rEnd
+                 && ( bIsNotOnBoundary
+                      || IDocumentMarkAccess::GetType( *pMark ) == IDocumentMarkAccess::ANNOTATIONMARK ) )
+            {
+                vMarksToCopy.push_back(pMark);
+            }
+        }
+        // We have to count the "non-copied" nodes..
+        SwNodeIndex aCorrIdx(rStt.nNode);
+        sal_uLong nDelCount = 0;
+        for(mark_vector_t::const_iterator ppMark = vMarksToCopy.begin();
+            ppMark != vMarksToCopy.end();
+            ++ppMark)
+        {
+            const ::sw::mark::IMark* const pMark = *ppMark;
+            SwPaM aTmpPam(*pCpyStt);
+            lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetMarkPos().nNode.GetIndex(), nDelCount);
+            lcl_SetCpyPos( pMark->GetMarkPos(), rStt, *pCpyStt, *aTmpPam.GetPoint(), nDelCount);
+            if(pMark->IsExpanded())
+            {
+                aTmpPam.SetMark();
+                lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetOtherMarkPos().nNode.GetIndex(), nDelCount);
+                lcl_SetCpyPos(pMark->GetOtherMarkPos(), rStt, *pCpyStt, *aTmpPam.GetMark(), nDelCount);
+            }
+
+            ::sw::mark::IMark* const pNewMark = pDestDoc->getIDocumentMarkAccess()->makeMark(
+                aTmpPam,
+                pMark->GetName(),
+                IDocumentMarkAccess::GetType(*pMark));
+            // Explicitly try to get exactly the same name as in the source
+            // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name
+            pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName());
+
+            // copying additional attributes for bookmarks or fieldmarks
+            ::sw::mark::IBookmark* const pNewBookmark =
+                dynamic_cast< ::sw::mark::IBookmark* const >(pNewMark);
+            const ::sw::mark::IBookmark* const pOldBookmark =
+                dynamic_cast< const ::sw::mark::IBookmark* >(pMark);
+            if (pNewBookmark && pOldBookmark)
+            {
+                pNewBookmark->SetKeyCode(pOldBookmark->GetKeyCode());
+                pNewBookmark->SetShortName(pOldBookmark->GetShortName());
+            }
+            ::sw::mark::IFieldmark* const pNewFieldmark =
+                dynamic_cast< ::sw::mark::IFieldmark* const >(pNewMark);
+            const ::sw::mark::IFieldmark* const pOldFieldmark =
+                dynamic_cast< const ::sw::mark::IFieldmark* >(pMark);
+            if (pNewFieldmark && pOldFieldmark)
+            {
+                pNewFieldmark->SetFieldname(pOldFieldmark->GetFieldname());
+                pNewFieldmark->SetFieldHelptext(pOldFieldmark->GetFieldHelptext());
+                ::sw::mark::IFieldmark::parameter_map_t* pNewParams = pNewFieldmark->GetParameters();
+                const ::sw::mark::IFieldmark::parameter_map_t* pOldParams = pOldFieldmark->GetParameters();
+                ::sw::mark::IFieldmark::parameter_map_t::const_iterator pIt = pOldParams->begin();
+                for (; pIt != pOldParams->end(); ++pIt )
+                {
+                    pNewParams->insert( *pIt );
+                }
+            }
+
+            ::sfx2::Metadatable const*const pMetadatable(
+                    dynamic_cast< ::sfx2::Metadatable const* >(pMark));
+            ::sfx2::Metadatable      *const pNewMetadatable(
+                    dynamic_cast< ::sfx2::Metadatable      * >(pNewMark));
+            if (pMetadatable && pNewMetadatable)
+            {
+                pNewMetadatable->RegisterAsCopyOf(*pMetadatable);
+            }
+        }
+    }
+
+    static void lcl_DeleteRedlines( const SwPaM& rPam, SwPaM& rCpyPam )
+    {
+        const SwDoc* pSrcDoc = rPam.GetDoc();
+        const SwRedlineTbl& rTbl = pSrcDoc->GetRedlineTbl();
+        if( !rTbl.empty() )
+        {
+            SwDoc* pDestDoc = rCpyPam.GetDoc();
+            SwPosition* pCpyStt = rCpyPam.Start(), *pCpyEnd = rCpyPam.End();
+            SwPaM* pDelPam = 0;
+            const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
+            // We have to count the "non-copied" nodes
+            sal_uLong nDelCount = 0;
+            SwNodeIndex aCorrIdx( pStt->nNode );
+
+            sal_uInt16 n = 0;
+            pSrcDoc->GetRedline( *pStt, &n );
+            for( ; n < rTbl.size(); ++n )
+            {
+                const SwRangeRedline* pRedl = rTbl[ n ];
+                if( nsRedlineType_t::REDLINE_DELETE == pRedl->GetType() && pRedl->IsVisible() )
+                {
+                    const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
+
+                    SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
+                    switch( eCmpPos )
+                    {
+                    case POS_COLLIDE_END:
+                    case POS_BEFORE:
+                        // Pos1 is before Pos2
+                        break;
+
+                    case POS_COLLIDE_START:
+                    case POS_BEHIND:
+                        // Pos1 is after Pos2
+                        n = rTbl.size();
+                        break;
+
+                    default:
+                        {
+                            pDelPam = new SwPaM( *pCpyStt, pDelPam );
+                            if( *pStt < *pRStt )
+                            {
+                                lcl_NonCopyCount( rPam, aCorrIdx, pRStt->nNode.GetIndex(), nDelCount );
+                                lcl_SetCpyPos( *pRStt, *pStt, *pCpyStt,
+                                                *pDelPam->GetPoint(), nDelCount );
+                            }
+                            pDelPam->SetMark();
+
+                            if( *pEnd < *pREnd )
+                                *pDelPam->GetPoint() = *pCpyEnd;
+                            else
+                            {
+                                lcl_NonCopyCount( rPam, aCorrIdx, pREnd->nNode.GetIndex(), nDelCount );
+                                lcl_SetCpyPos( *pREnd, *pStt, *pCpyStt,
+                                                *pDelPam->GetPoint(), nDelCount );
+                            }
+                        }
+                    }
+                }
+            }
+
+            if( pDelPam )
+            {
+                RedlineMode_t eOld = pDestDoc->GetRedlineMode();
+                pDestDoc->SetRedlineMode_intern( (RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
+
+                ::sw::UndoGuard const undoGuard(pDestDoc->GetIDocumentUndoRedo());
+
+                do {
+                    pDestDoc->getIDocumentContentOperations().DeleteAndJoin( *(SwPaM*)pDelPam->GetNext() );
+                    if( pDelPam->GetNext() == pDelPam )
+                        break;
+                    delete pDelPam->GetNext();
+                } while( true );
+                delete pDelPam;
+
+                pDestDoc->SetRedlineMode_intern( eOld );
+            }
+        }
+    }
+
+    static void lcl_DeleteRedlines( const SwNodeRange& rRg, SwNodeRange& rCpyRg )
+    {
+        SwDoc* pSrcDoc = rRg.aStart.GetNode().GetDoc();
+        if( !pSrcDoc->GetRedlineTbl().empty() )
+        {
+            SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
+            SwPaM aCpyTmp( rCpyRg.aStart, rCpyRg.aEnd );
+            lcl_DeleteRedlines( aRgTmp, aCpyTmp );
+        }
+    }
+
+    static void lcl_ChainFmts( SwFlyFrmFmt *pSrc, SwFlyFrmFmt *pDest )
+    {
+        SwFmtChain aSrc( pSrc->GetChain() );
+        if ( !aSrc.GetNext() )
+        {
+            aSrc.SetNext( pDest );
+            pSrc->SetFmtAttr( aSrc );
+        }
+        SwFmtChain aDest( pDest->GetChain() );
+        if ( !aDest.GetPrev() )
+        {
+            aDest.SetPrev( pSrc );
+            pDest->SetFmtAttr( aDest );
+        }
+    }
+
+    // #i86492#
+    static bool lcl_ContainsOnlyParagraphsInList( const SwPaM& rPam )
+    {
+        bool bRet = false;
+
+        const SwTxtNode* pTxtNd = rPam.Start()->nNode.GetNode().GetTxtNode();
+        const SwTxtNode* pEndTxtNd = rPam.End()->nNode.GetNode().GetTxtNode();
+        if ( pTxtNd && pTxtNd->IsInList() &&
+             pEndTxtNd && pEndTxtNd->IsInList() )
+        {
+            bRet = true;
+            SwNodeIndex aIdx(rPam.Start()->nNode);
+
+            do
+            {
+                ++aIdx;
+                pTxtNd = aIdx.GetNode().GetTxtNode();
+
+                if ( !pTxtNd || !pTxtNd->IsInList() )
+                {
+                    bRet = false;
+                    break;
+                }
+            } while ( pTxtNd && pTxtNd != pEndTxtNd );
+        }
+
+        return bRet;
+    }
+
+    static bool lcl_MarksWholeNode(const SwPaM & rPam)
+    {
+        bool bResult = false;
+        const SwPosition* pStt = rPam.Start();
+        const SwPosition* pEnd = rPam.End();
+
+        if (NULL != pStt && NULL != pEnd)
+        {
+            const SwTxtNode* pSttNd = pStt->nNode.GetNode().GetTxtNode();
+            const SwTxtNode* pEndNd = pEnd->nNode.GetNode().GetTxtNode();
+
+            if (NULL != pSttNd && NULL != pEndNd &&
+                pStt->nContent.GetIndex() == 0 &&
+                pEnd->nContent.GetIndex() == pEndNd->Len())
+            {
+                bResult = true;
+            }
+        }
+
+        return bResult;
+    }
+}
+
+//local functions originally from sw/source/core/doc/docedt.cxx
+namespace
+{
+    static void
+    lcl_CalcBreaks( ::std::vector<sal_Int32> & rBreaks, SwPaM const & rPam )
+    {
+        SwTxtNode const * const pTxtNode(
+                rPam.End()->nNode.GetNode().GetTxtNode() );
+        if (!pTxtNode)
+            return; // left-overlap only possible at end of selection...
+
+        const sal_Int32 nStart(rPam.Start()->nContent.GetIndex());
+        const sal_Int32 nEnd  (rPam.End  ()->nContent.GetIndex());
+        if (nEnd == pTxtNode->Len())
+            return; // paragraph selected until the end
+
+        for (sal_Int32 i = nStart; i < nEnd; ++i)
+        {
+            const sal_Unicode c(pTxtNode->GetTxt()[i]);
+            if ((CH_TXTATR_INWORD == c) || (CH_TXTATR_BREAKWORD == c))
+            {
+                SwTxtAttr const * const pAttr( pTxtNode->GetTxtAttrForCharAt(i) );
+                if (pAttr && pAttr->End() && (*pAttr->End() > nEnd))
+                {
+                    OSL_ENSURE(pAttr->HasDummyChar(), "GetTxtAttrForCharAt broken?");
+                    rBreaks.push_back(i);
+                }
+            }
+        }
+    }
+
+    static bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, SwPaM & rPam,
+            bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&, bool), const bool bForceJoinNext = false)
+    {
+        ::std::vector<sal_Int32> Breaks;
+
+        lcl_CalcBreaks(Breaks, rPam);
+
+        if (!Breaks.size())
+        {
+            return (rDocumentContentOperations.*pFunc)(rPam, bForceJoinNext);
+        }
+
+        // Deletion must be split into several parts if the text node
+        // contains a text attribute with end and with dummy character
+        // and the selection does not contain the text attribute completely,
+        // but overlaps its start (left), where the dummy character is.
+
+        SwPosition const & rSelectionEnd( *rPam.End() );
+
+        bool bRet( true );
+        // iterate from end to start, to avoid invalidating the offsets!
+        ::std::vector<sal_Int32>::reverse_iterator iter( Breaks.rbegin() );
+        SwPaM aPam( rSelectionEnd, rSelectionEnd ); // end node!
+        SwPosition & rEnd( *aPam.End() );
+        SwPosition & rStart( *aPam.Start() );
+
+        while (iter != Breaks.rend())
+        {
+            rStart.nContent = *iter + 1;
+            if (rEnd.nContent > rStart.nContent) // check if part is empty
+            {
+                bRet &= (rDocumentContentOperations.*pFunc)(aPam, bForceJoinNext);
+            }
+            rEnd.nContent = *iter;
+            ++iter;
+        }
+
+        rStart = *rPam.Start(); // set to original start
+        if (rEnd.nContent > rStart.nContent) // check if part is empty
+        {
+            bRet &= (rDocumentContentOperations.*pFunc)(aPam, bForceJoinNext);
+        }
+
+        return bRet;
+    }
+
+    static bool lcl_StrLenOverflow( const SwPaM& rPam )
+    {
+        // If we try to merge two paragraphs we have to test if afterwards
+        // the string doesn't exceed the allowed string length
+        if( rPam.GetPoint()->nNode != rPam.GetMark()->nNode )
+        {
+            const SwPosition* pStt = rPam.Start(), *pEnd = rPam.End();
+            const SwTxtNode* pEndNd = pEnd->nNode.GetNode().GetTxtNode();
+            if( (0 != pEndNd) && pStt->nNode.GetNode().IsTxtNode() )
+            {
+                const sal_uInt64 nSum = pStt->nContent.GetIndex() +
+                    pEndNd->GetTxt().getLength() - pEnd->nContent.GetIndex();
+                return nSum > static_cast<sal_uInt64>(SAL_MAX_INT32);
+            }
+        }
+        return false;
+    }
+
+    struct _SaveRedline
+    {
+        SwRangeRedline* pRedl;
+        sal_uInt32 nStt, nEnd;
+        sal_Int32 nSttCnt;
+        sal_Int32 nEndCnt;
+
+        _SaveRedline( SwRangeRedline* pR, const SwNodeIndex& rSttIdx )
+            : pRedl(pR)
+            , nEnd(0)
+            , nEndCnt(0)
+        {
+            const SwPosition* pStt = pR->Start(),
+                * pEnd = pR->GetMark() == pStt ? pR->GetPoint() : pR->GetMark();
+            sal_uInt32 nSttIdx = rSttIdx.GetIndex();
+            nStt = pStt->nNode.GetIndex() - nSttIdx;
+            nSttCnt = pStt->nContent.GetIndex();
+            if( pR->HasMark() )
+            {
+                nEnd = pEnd->nNode.GetIndex() - nSttIdx;
+                nEndCnt = pEnd->nContent.GetIndex();
+            }
+
+            pRedl->GetPoint()->nNode = 0;
+            pRedl->GetPoint()->nContent.Assign( 0, 0 );
+            pRedl->GetMark()->nNode = 0;
+            pRedl->GetMark()->nContent.Assign( 0, 0 );
+        }
+
+        _SaveRedline( SwRangeRedline* pR, const SwPosition& rPos )
+            : pRedl(pR)
+            , nEnd(0)
+            , nEndCnt(0)
+        {
+            const SwPosition* pStt = pR->Start(),
+                * pEnd = pR->GetMark() == pStt ? pR->GetPoint() : pR->GetMark();
+            sal_uInt32 nSttIdx = rPos.nNode.GetIndex();
+            nStt = pStt->nNode.GetIndex() - nSttIdx;
+            nSttCnt = pStt->nContent.GetIndex();
+            if( nStt == 0 )
+                nSttCnt = nSttCnt - rPos.nContent.GetIndex();
+            if( pR->HasMark() )
+            {
+                nEnd = pEnd->nNode.GetIndex() - nSttIdx;
+                nEndCnt = pEnd->nContent.GetIndex();
+                if( nEnd == 0 )
+                    nEndCnt = nEndCnt - rPos.nContent.GetIndex();
+            }
+
+            pRedl->GetPoint()->nNode = 0;
+            pRedl->GetPoint()->nContent.Assign( 0, 0 );
+            pRedl->GetMark()->nNode = 0;
+            pRedl->GetMark()->nContent.Assign( 0, 0 );
+        }
+
+        void SetPos( sal_uInt32 nInsPos )
+        {
+            pRedl->GetPoint()->nNode = nInsPos + nStt;
+            pRedl->GetPoint()->nContent.Assign( pRedl->GetCntntNode(), nSttCnt );
+            if( pRedl->HasMark() )
+            {
+                pRedl->GetMark()->nNode = nInsPos + nEnd;
+                pRedl->GetMark()->nContent.Assign( pRedl->GetCntntNode(false), nEndCnt );
+            }
+        }
+
+        void SetPos( const SwPosition& aPos )
+        {
+            pRedl->GetPoint()->nNode = aPos.nNode.GetIndex() + nStt;
+            pRedl->GetPoint()->nContent.Assign( pRedl->GetCntntNode(), nSttCnt + ( nStt == 0 ? aPos.nContent.GetIndex() : 0 ) );
+            if( pRedl->HasMark() )
+            {
+                pRedl->GetMark()->nNode = aPos.nNode.GetIndex() + nEnd;
+                pRedl->GetMark()->nContent.Assign( pRedl->GetCntntNode(false), nEndCnt  + ( nEnd == 0 ? aPos.nContent.GetIndex() : 0 ) );
+            }
+        }
+    };
+
+    typedef boost::ptr_vector< _SaveRedline > _SaveRedlines;
+
+    static void lcl_SaveRedlines( const SwPaM& aPam, _SaveRedlines& rArr )
+    {
+        SwDoc* pDoc = aPam.GetNode().GetDoc();
+
+        const SwPosition* pStart = aPam.Start();
+        const SwPosition* pEnd = aPam.End();
+
+        // get first relevant redline
+        sal_uInt16 nCurrentRedline;
+        pDoc->GetRedline( *pStart, &nCurrentRedline );
+        if( nCurrentRedline > 0)
+            nCurrentRedline--;
+
+        // redline mode REDLINE_IGNORE|REDLINE_ON; save old mode
+        RedlineMode_t eOld = pDoc->GetRedlineMode();
+        pDoc->SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
+
+        // iterate over relevant redlines and decide for each whether it should
+        // be saved, or split + saved
+        SwRedlineTbl& rRedlineTable = const_cast<SwRedlineTbl&>( pDoc->GetRedlineTbl() );
+        for( ; nCurrentRedline < rRedlineTable.size(); nCurrentRedline++ )
+        {
+            SwRangeRedline* pCurrent = rRedlineTable[ nCurrentRedline ];
+            SwComparePosition eCompare =
+                ComparePosition( *pCurrent->Start(), *pCurrent->End(),
+                                 *pStart, *pEnd);
+
+            // we must save this redline if it overlaps aPam
+            // (we may have to split it, too)
+            if( eCompare == POS_OVERLAP_BEHIND  ||
+                eCompare == POS_OVERLAP_BEFORE  ||
+                eCompare == POS_OUTSIDE ||
+                eCompare == POS_INSIDE ||
+                eCompare == POS_EQUAL )
+            {
+                rRedlineTable.Remove( nCurrentRedline-- );
+
+                // split beginning, if necessary
+                if( eCompare == POS_OVERLAP_BEFORE  ||
+                    eCompare == POS_OUTSIDE )
+                {
+                    SwRangeRedline* pNewRedline = new SwRangeRedline( *pCurrent );
+                    *pNewRedline->End() = *pStart;
+                    *pCurrent->Start() = *pStart;
+                    pDoc->AppendRedline( pNewRedline, true );
+                }
+
+                // split end, if necessary
+                if( eCompare == POS_OVERLAP_BEHIND  ||
+                    eCompare == POS_OUTSIDE )
+                {
+                    SwRangeRedline* pNewRedline = new SwRangeRedline( *pCurrent );
+                    *pNewRedline->Start() = *pEnd;
+                    *pCurrent->End() = *pEnd;
+                    pDoc->AppendRedline( pNewRedline, true );
+                }
+
+                // save the current redline
+                _SaveRedline* pSave = new _SaveRedline( pCurrent, *pStart );
+                rArr.push_back( pSave );
+            }
+        }
+
+        // restore old redline mode
+        pDoc->SetRedlineMode_intern( eOld );
+    }
+
+    static void lcl_RestoreRedlines( SwDoc* pDoc, const SwPosition& rPos, _SaveRedlines& rArr )
+    {
+        RedlineMode_t eOld = pDoc->GetRedlineMode();
+        pDoc->SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
+
+        for( size_t n = 0; n < rArr.size(); ++n )
+        {
+            rArr[ n ].SetPos( rPos );
+            pDoc->AppendRedline( rArr[ n ].pRedl, true );
+        }
+
+        pDoc->SetRedlineMode_intern( eOld );
+    }
+
+    static void lcl_SaveRedlines( const SwNodeRange& rRg, _SaveRedlines& rArr )
+    {
+        SwDoc* pDoc = rRg.aStart.GetNode().GetDoc();
+        sal_uInt16 nRedlPos;
+        SwPosition aSrchPos( rRg.aStart ); aSrchPos.nNode--;
+        aSrchPos.nContent.Assign( aSrchPos.nNode.GetNode().GetCntntNode(), 0 );
+        if( pDoc->GetRedline( aSrchPos, &nRedlPos ) && nRedlPos )
+            --nRedlPos;
+        else if( nRedlPos >= pDoc->GetRedlineTbl().size() )
+            return ;
+
+        RedlineMode_t eOld = pDoc->GetRedlineMode();
+        pDoc->SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
+        SwRedlineTbl& rRedlTbl = (SwRedlineTbl&)pDoc->GetRedlineTbl();
+
+        do {
+            SwRangeRedline* pTmp = rRedlTbl[ nRedlPos ];
+
+            const SwPosition* pRStt = pTmp->Start(),
+                            * pREnd = pTmp->GetMark() == pRStt
+                                ? pTmp->GetPoint() : pTmp->GetMark();
+
+            if( pRStt->nNode < rRg.aStart )
+            {
+                if( pREnd->nNode > rRg.aStart && pREnd->nNode < rRg.aEnd )
+                {
+                    // Create a copy and set the end of the original to the end of the MoveArea.
+                    // The copy is moved too.
+                    SwRangeRedline* pNewRedl = new SwRangeRedline( *pTmp );
+                    SwPosition* pTmpPos = pNewRedl->Start();
+                    pTmpPos->nNode = rRg.aStart;
+                    pTmpPos->nContent.Assign(
+                                pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
+
+                    _SaveRedline* pSave = new _SaveRedline( pNewRedl, rRg.aStart );
+                    rArr.push_back( pSave );
+
+                    pTmpPos = pTmp->End();
+                    pTmpPos->nNode = rRg.aEnd;
+                    pTmpPos->nContent.Assign(
+                                pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
+                }
+                else if( pREnd->nNode == rRg.aStart )
+                {
+                    SwPosition* pTmpPos = pTmp->End();
+                    pTmpPos->nNode = rRg.aEnd;
+                    pTmpPos->nContent.Assign(
+                                pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
+                }
+            }
+            else if( pRStt->nNode < rRg.aEnd )
+            {
+                rRedlTbl.Remove( nRedlPos-- );
+                if( pREnd->nNode < rRg.aEnd ||
+                    ( pREnd->nNode == rRg.aEnd && !pREnd->nContent.GetIndex()) )
+                {
+                    // move everything
+                    _SaveRedline* pSave = new _SaveRedline( pTmp, rRg.aStart );
+                    rArr.push_back( pSave );
+                }
+                else
+                {
+                    // split
+                    SwRangeRedline* pNewRedl = new SwRangeRedline( *pTmp );
+                    SwPosition* pTmpPos = pNewRedl->End();
+                    pTmpPos->nNode = rRg.aEnd;
+                    pTmpPos->nContent.Assign(
+                                pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
+
+                    _SaveRedline* pSave = new _SaveRedline( pNewRedl, rRg.aStart );
+                    rArr.push_back( pSave );
+
+                    pTmpPos = pTmp->Start();
+                    pTmpPos->nNode = rRg.aEnd;
+                    pTmpPos->nContent.Assign(
+                                pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
+                    pDoc->AppendRedline( pTmp, true );
+                }
+            }
+            else
+                break;
+
+        } while( ++nRedlPos < pDoc->GetRedlineTbl().size() );
+        pDoc->SetRedlineMode_intern( eOld );
+    }
+
+    static void lcl_RestoreRedlines( SwDoc* pDoc, sal_uInt32 nInsPos, _SaveRedlines& rArr )
+    {
+        RedlineMode_t eOld = pDoc->GetRedlineMode();
+        pDoc->SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
+
+        for( size_t n = 0; n < rArr.size(); ++n )
+        {
+            rArr[ n ].SetPos( nInsPos );
+            pDoc->AppendRedline( rArr[ n ].pRedl, true );
+        }
+
+        pDoc->SetRedlineMode_intern( eOld );
+    }
+
+    static bool lcl_SaveFtn( const SwNodeIndex& rSttNd, const SwNodeIndex& rEndNd,
+                     const SwNodeIndex& rInsPos,
+                     SwFtnIdxs& rFtnArr, SwFtnIdxs& rSaveArr,
+                     const SwIndex* pSttCnt = 0, const SwIndex* pEndCnt = 0 )
+    {
+        bool bUpdateFtn = false;
+        const SwNodes& rNds = rInsPos.GetNodes();
+        const bool bDelFtn = rInsPos.GetIndex() < rNds.GetEndOfAutotext().GetIndex() &&
+                    rSttNd.GetIndex() >= rNds.GetEndOfAutotext().GetIndex();
+        const bool bSaveFtn = !bDelFtn &&
+                        rInsPos.GetIndex() >= rNds.GetEndOfExtras().GetIndex();
+        if( !rFtnArr.empty() )
+        {
+
+            sal_uInt16 nPos;
+            rFtnArr.SeekEntry( rSttNd, &nPos );
+            SwTxtFtn* pSrch;
+            const SwNode* pFtnNd;
+
+            // Delete/save all that come after it
+            while( nPos < rFtnArr.size() && ( pFtnNd =
+                &( pSrch = rFtnArr[ nPos ] )->GetTxtNode())->GetIndex()
+                        <= rEndNd.GetIndex() )
+            {
+                const sal_Int32 nFtnSttIdx = pSrch->GetStart();
+                if( ( pEndCnt && pSttCnt )
+                    ? (( &rSttNd.GetNode() == pFtnNd &&
+                         pSttCnt->GetIndex() > nFtnSttIdx) ||
+                       ( &rEndNd.GetNode() == pFtnNd &&
+                        nFtnSttIdx >= pEndCnt->GetIndex() ))
+                    : ( &rEndNd.GetNode() == pFtnNd ))
+                {
+                    ++nPos;     // continue searching
+                }
+                else
+                {
+                    // delete it
+                    if( bDelFtn )
+                    {
+                        SwTxtNode& rTxtNd = (SwTxtNode&)pSrch->GetTxtNode();
+                        SwIndex aIdx( &rTxtNd, nFtnSttIdx );
+                        rTxtNd.EraseText( aIdx, 1 );
+                    }
+                    else
+                    {
+                        pSrch->DelFrms(0);
+                        rFtnArr.erase( rFtnArr.begin() + nPos );
+                        if( bSaveFtn )
+                            rSaveArr.insert( pSrch );
+                    }
+                    bUpdateFtn = true;
+                }
+            }
+
+            while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )->
+                    GetTxtNode())->GetIndex() >= rSttNd.GetIndex() )
+            {
+                const sal_Int32 nFtnSttIdx = pSrch->GetStart();
+                if( !pEndCnt || !pSttCnt ||
+                    !( (( &rSttNd.GetNode() == pFtnNd &&
+                        pSttCnt->GetIndex() > nFtnSttIdx ) ||
+                       ( &rEndNd.GetNode() == pFtnNd &&
+                        nFtnSttIdx >= pEndCnt->GetIndex() )) ))
+                {
+                    if( bDelFtn )
+                    {
+                        // delete it
+                        SwTxtNode& rTxtNd = (SwTxtNode&)pSrch->GetTxtNode();
+                        SwIndex aIdx( &rTxtNd, nFtnSttIdx );
+                        rTxtNd.EraseText( aIdx, 1 );
+                    }
+                    else
+                    {
+                        pSrch->DelFrms(0);
+                        rFtnArr.erase( rFtnArr.begin() + nPos );
+                        if( bSaveFtn )
+                            rSaveArr.insert( pSrch );
+                    }
+                    bUpdateFtn = true;
+                }
+            }
+        }
+        // When moving from redline section into document content section, e.g.
+        // after loading a document with (delete-)redlines, the footnote array
+        // has to be adjusted... (#i70572)
+        if( bSaveFtn )
+        {
+            SwNodeIndex aIdx( rSttNd );
+            while( aIdx < rEndNd ) // Check the moved section
+            {
+                SwNode* pNode = &aIdx.GetNode();
+                if( pNode->IsTxtNode() ) // Looking for text nodes...
+                {
+                    SwpHints *pHints =
+                        static_cast<SwTxtNode*>(pNode)->GetpSwpHints();
+                    if( pHints && pHints->HasFtn() ) //...with footnotes
+                    {
+                        bUpdateFtn = true; // Heureka
+                        sal_uInt16 nCount = pHints->Count();
+                        for( sal_uInt16 i = 0; i < nCount; ++i )
+                        {
+                            SwTxtAttr *pAttr = pHints->GetTextHint( i );
+                            if ( pAttr->Which() == RES_TXTATR_FTN )
+                            {
+                                rSaveArr.insert( static_cast<SwTxtFtn*>(pAttr) );
+                            }
+                        }
+                    }
+                }
+                ++aIdx;
+            }
+        }
+        return bUpdateFtn;
+    }
+
+    static bool lcl_MayOverwrite( const SwTxtNode *pNode, const sal_Int32 nPos )
+    {
+        sal_Unicode const cChr = pNode->GetTxt()[nPos];
+        switch (cChr)
+        {
+            case CH_TXTATR_BREAKWORD:
+            case CH_TXTATR_INWORD:
+                return !pNode->GetTxtAttrForCharAt(nPos);// how could there be none?
+            case CH_TXT_ATR_FIELDSTART:
+            case CH_TXT_ATR_FIELDEND:
+            case CH_TXT_ATR_FORMELEMENT:
+                return false;
+            default:
+                return true;
+        }
+    }
+
+    static void lcl_SkipAttr( const SwTxtNode *pNode, SwIndex &rIdx, sal_Int32 &rStart )
+    {
+        if( !lcl_MayOverwrite( pNode, rStart ) )
+        {
+            // skip all special attributes
+            do {
+                ++rIdx;
+                rStart = rIdx.GetIndex();
+            } while (rStart < pNode->GetTxt().getLength()
+                   && !lcl_MayOverwrite(pNode, rStart) );
+        }
+    }
+
+    static bool lcl_GetTokenToParaBreak( OUString& rStr, OUString& rRet, bool bRegExpRplc )
+    {
+        if( bRegExpRplc )
+        {
+            sal_Int32 nPos = 0;
+            const OUString sPara("\\n");
+            for (;;)
+            {
+                nPos = rStr.indexOf( sPara, nPos );
+                if (nPos<0)
+                {
+                    break;
+                }
+                // Has this been escaped?
+                if( nPos && '\\' == rStr[nPos-1])
+                {
+                    ++nPos;
+                    if( nPos >= rStr.getLength() )
+                    {
+                        break;
+                    }
+                }
+                else
+                {
+                    rRet = rStr.copy( 0, nPos );
+                    rStr = rStr.copy( nPos + sPara.getLength() );
+                    return true;
+                }
+            }
+        }
+        rRet = rStr;
+        rStr = OUString();
+        return false;
+    }
+}
+
+namespace //local functions originally from docfmt.cxx
+{
+    #define DELETECHARSETS if ( bDelete ) { delete pCharSet; delete pOtherSet; }
+
+    /// Insert Hints according to content types;
+    // Is used in SwDoc::Insert(..., SwFmtHint &rHt)
+
+    static bool lcl_InsAttr(
+        SwDoc *const pDoc,
+        const SwPaM &rRg,
+        const SfxItemSet& rChgSet,
+        const SetAttrMode nFlags,
+        SwUndoAttr *const pUndo,
+        const bool bExpandCharToPara=false)
+    {
+        // Divide the Sets (for selections in Nodes)
+        const SfxItemSet* pCharSet = 0;
+        const SfxItemSet* pOtherSet = 0;
+        bool bDelete = false;
+        bool bCharAttr = false;
+        bool bOtherAttr = false;
+
+        // Check, if we can work with rChgSet or if we have to create additional SfxItemSets
+        if ( 1 == rChgSet.Count() )
+        {
+            SfxItemIter aIter( rChgSet );
+            const SfxPoolItem* pItem = aIter.FirstItem();
+            if (!IsInvalidItem(pItem))
+            {
+                const sal_uInt16 nWhich = pItem->Which();
+
+                if ( isCHRATR(nWhich) ||
+                     (RES_TXTATR_CHARFMT == nWhich) ||
+                     (RES_TXTATR_INETFMT == nWhich) ||
+                     (RES_TXTATR_AUTOFMT == nWhich) ||
+                     (RES_TXTATR_UNKNOWN_CONTAINER == nWhich) )
+                {
+                    pCharSet  = &rChgSet;
+                    bCharAttr = true;
+                }
+
+                if (    isPARATR(nWhich)
+                     || isPARATR_LIST(nWhich)
+                     || isFRMATR(nWhich)
+                     || isGRFATR(nWhich)
+                     || isUNKNOWNATR(nWhich) )
+                {
+                    pOtherSet = &rChgSet;
+                    bOtherAttr = true;
+                }
+            }
+        }
+
+        // Build new itemset if either
+        // - rChgSet.Count() > 1 or
+        // - The attribute in rChgSet does not belong to one of the above categories
+        if ( !bCharAttr && !bOtherAttr )
+        {
+            SfxItemSet* pTmpCharItemSet = new SfxItemSet( pDoc->GetAttrPool(),
+                                       RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+                                       RES_TXTATR_AUTOFMT, RES_TXTATR_AUTOFMT,
+                                       RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
+                                       RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+                   RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
+                                       0 );
+
+            SfxItemSet* pTmpOtherItemSet = new SfxItemSet( pDoc->GetAttrPool(),
+                                        RES_PARATR_BEGIN, RES_PARATR_END-1,
+                                        RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
+                                        RES_FRMATR_BEGIN, RES_FRMATR_END-1,
+                                        RES_GRFATR_BEGIN, RES_GRFATR_END-1,
+                                        RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
+                                        0 );
+
+            pTmpCharItemSet->Put( rChgSet );
+            pTmpOtherItemSet->Put( rChgSet );
+
+            pCharSet = pTmpCharItemSet;
+            pOtherSet = pTmpOtherItemSet;
+
+            bDelete = true;
+        }
+
+        SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
+        bool bRet = false;
+        const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
+        SwCntntNode* pNode = pStt->nNode.GetNode().GetCntntNode();
+
+        if( pNode && pNode->IsTxtNode() )
+        {
+            // #i27615#
+            if (rRg.IsInFrontOfLabel())
+            {
+                SwTxtNode * pTxtNd = pNode->GetTxtNode();
+                SwNumRule * pNumRule = pTxtNd->GetNumRule();
+
+                if ( !pNumRule )
+                {
+                    OSL_FAIL( "<InsAttr(..)> - PaM in front of label, but text node has no numbering rule set. This is a serious defect, please inform OD." );
+                    DELETECHARSETS
+                    return false;
+                }
+
+                int nLevel = pTxtNd->GetActualListLevel();
+
+                if (nLevel < 0)
+                    nLevel = 0;
+
+                if (nLevel >= MAXLEVEL)
+                    nLevel = MAXLEVEL - 1;
+
+                SwNumFmt aNumFmt = pNumRule->Get(static_cast<sal_uInt16>(nLevel));
+                SwCharFmt * pCharFmt =
+                    pDoc->FindCharFmtByName(aNumFmt.GetCharFmtName());
+
+                if (pCharFmt)
+                {
+                    if (pHistory)
+                        pHistory->Add(pCharFmt->GetAttrSet(), *pCharFmt);
+
+                    if ( pCharSet )
+                        pCharFmt->SetFmtAttr(*pCharSet);
+                }
+
+                DELETECHARSETS
+                return true;
+            }
+
+            const SwIndex& rSt = pStt->nContent;
+
+            // Attributes without an end do not have a range
+            if ( !bCharAttr && !bOtherAttr )
+            {
+                SfxItemSet aTxtSet( pDoc->GetAttrPool(),
+                            RES_TXTATR_NOEND_BEGIN, RES_TXTATR_NOEND_END-1 );
+                aTxtSet.Put( rChgSet );
+                if( aTxtSet.Count() )
+                {
+                    SwRegHistory history( pNode, *pNode, pHistory );
+                    bRet = history.InsertItems(
+                        aTxtSet, rSt.GetIndex(), rSt.GetIndex(), nFlags ) || bRet;
+
+                    if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline()
+                                    && !pDoc->GetRedlineTbl().empty())))
+                    {
+                        SwPaM aPam( pStt->nNode, pStt->nContent.GetIndex()-1,
+                                    pStt->nNode, pStt->nContent.GetIndex() );
+
+                        if( pUndo )
+                            pUndo->SaveRedlineData( aPam, true );
+
+                        if( pDoc->IsRedlineOn() )
+                            pDoc->AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
+                        else
+                            pDoc->SplitRedline( aPam );
+                    }
+                }
+            }
+
+            // TextAttributes with an end never expand their range
+            if ( !bCharAttr && !bOtherAttr )
+            {
+                // CharFmt and URL attributes are treated separately!
+                // TEST_TEMP ToDo: AutoFmt!
+                SfxItemSet aTxtSet( pDoc->GetAttrPool(),
+                                    RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK,
+                                    RES_TXTATR_META, RES_TXTATR_METAFIELD,
+                                    RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
+                                    RES_TXTATR_INPUTFIELD, RES_TXTATR_INPUTFIELD,
+                                    0 );
+
+                aTxtSet.Put( rChgSet );
+                if( aTxtSet.Count() )
+                {
+                    const sal_Int32 nInsCnt = rSt.GetIndex();
+                    const sal_Int32 nEnd = pStt->nNode == pEnd->nNode
+                                    ? pEnd->nContent.GetIndex()
+                                    : pNode->Len();
+                    SwRegHistory history( pNode, *pNode, pHistory );
+                    bRet = history.InsertItems( aTxtSet, nInsCnt, nEnd, nFlags )
+                           || bRet;
+
+                    if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline()
+                                    && !pDoc->GetRedlineTbl().empty())))
+                    {
+                        // Was text content inserted? (RefMark/TOXMarks without an end)
+                        bool bTxtIns = nInsCnt != rSt.GetIndex();
+                        // Was content inserted or set over the selection?
+                        SwPaM aPam( pStt->nNode, bTxtIns ? nInsCnt + 1 : nEnd,
+                                    pStt->nNode, nInsCnt );
+                        if( pUndo )
+                            pUndo->SaveRedlineData( aPam, bTxtIns );
+
+                        if( pDoc->IsRedlineOn() )
+                            pDoc->AppendRedline(
+                                new SwRangeRedline(
+                                    bTxtIns ? nsRedlineType_t::REDLINE_INSERT : nsRedlineType_t::REDLINE_FORMAT, aPam ),
+                                    true);
+                        else if( bTxtIns )
+                            pDoc->SplitRedline( aPam );
+                    }
+                }
+            }
+        }
+
+        // We always have to set the auto flag for PageDescs that are set at the Node!
+        if( pOtherSet && pOtherSet->Count() )
+        {
+            SwTableNode* pTblNd;
+            const SwFmtPageDesc* pDesc;
+            if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PAGEDESC,
+                            false, (const SfxPoolItem**)&pDesc ))
+            {
+                if( pNode )
+                {
+                    // Set auto flag. Only in the template it's without auto!
+                    SwFmtPageDesc aNew( *pDesc );
+
+                    // Tables now also know line breaks
+                    if( 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
+                        0 != ( pTblNd = pNode->FindTableNode() ) )
+                    {
+                        SwTableNode* pCurTblNd = pTblNd;
+                        while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
+                            pTblNd = pCurTblNd;
+
+                        // set the table format
+                        SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
+                        SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
+                        pFmt->SetFmtAttr( aNew );
+                        bRet = true;
+                    }
+                    else
+                    {
+                        SwRegHistory aRegH( pNode, *pNode, pHistory );
+                        bRet = pNode->SetAttr( aNew ) || bRet;
+                    }
+                }
+
+                // bOtherAttr = true means that pOtherSet == rChgSet. In this case
+                // we know, that there is only one attribute in pOtherSet. We cannot
+                // perform the following operations, instead we return:
+                if ( bOtherAttr )
+                    return bRet;
+
+                const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_PAGEDESC );
+                if( !pOtherSet->Count() )
+                {
+                    DELETECHARSETS
+                    return bRet;
+                }
+            }
+
+            // Tables now also know line breaks
+            const SvxFmtBreakItem* pBreak;
+            if( pNode && 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
+                0 != (pTblNd = pNode->FindTableNode() ) &&
+                SFX_ITEM_SET == pOtherSet->GetItemState( RES_BREAK,
+                            false, (const SfxPoolItem**)&pBreak ) )
+            {
+                SwTableNode* pCurTblNd = pTblNd;
+                while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
+                    pTblNd = pCurTblNd;
+
+                 // set the table format
+                SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
+                SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
+                pFmt->SetFmtAttr( *pBreak );
+                bRet = true;
+
+                // bOtherAttr = true means that pOtherSet == rChgSet. In this case
+                // we know, that there is only one attribute in pOtherSet. We cannot
+                // perform the following operations, instead we return:
+                if ( bOtherAttr )
+                    return bRet;
+
+                const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_BREAK );
+                if( !pOtherSet->Count() )
+                {
+                    DELETECHARSETS
+                    return bRet;
+                }
+            }
+
+            {
+                // If we have a PoolNumRule, create it if needed
+                const SwNumRuleItem* pRule;
+                sal_uInt16 nPoolId=0;
+                if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PARATR_NUMRULE,
+                                    false, (const SfxPoolItem**)&pRule ) &&
+                    !pDoc->FindNumRulePtr( pRule->GetValue() ) &&
+                    USHRT_MAX != (nPoolId = SwStyleNameMapper::GetPoolIdFromUIName ( pRule->GetValue(),
+                                    nsSwGetPoolIdFromName::GET_POOLID_NUMRULE )) )
+                    pDoc->GetNumRuleFromPool( nPoolId );
+            }
+        }
+
+        if( !rRg.HasMark() )        // no range
+        {
+            if( !pNode )
+            {
+                DELETECHARSETS
+                return bRet;
+            }
+
+            if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
+            {
+                SwTxtNode* pTxtNd = static_cast<SwTxtNode*>(pNode);
+                const SwIndex& rSt = pStt->nContent;
+                sal_Int32 nMkPos, nPtPos = rSt.GetIndex();
+                const OUString& rStr = pTxtNd->GetTxt();
+
+                // Special case: if the Crsr is located within a URL attribute, we take over it's area
+                SwTxtAttr const*const pURLAttr(
+                    pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
+                if (pURLAttr && !pURLAttr->GetINetFmt().GetValue().isEmpty())
+                {
+                    nMkPos = pURLAttr->GetStart();
+                    nPtPos = *pURLAttr->End();
+                }
+                else
+                {
+                    Boundary aBndry;
+                    if( g_pBreakIt->GetBreakIter().is() )
+                        aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
+                                    pTxtNd->GetTxt(), nPtPos,
+                                    g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
+                                    WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
+                                    sal_True );
+
+                    if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
+                    {
+                        nMkPos = aBndry.startPos;
+                        nPtPos = aBndry.endPos;
+                    }
+                    else
+                        nPtPos = nMkPos = rSt.GetIndex();
+                }
+
+                // Remove the overriding attributes from the SwpHintsArray,
+                // if the selection spans across the whole paragraph.
+                // These attributes are inserted as FormatAttributes and
+                // never override the TextAttributes!
+                if( !(nFlags & nsSetAttrMode::SETATTR_DONTREPLACE ) &&
+                    pTxtNd->HasHints() && !nMkPos && nPtPos == rStr.getLength())
+                {
+                    SwIndex aSt( pTxtNd );
+                    if( pHistory )
+                    {
+                        // Save all attributes for the Undo.
+                        SwRegHistory aRHst( *pTxtNd, pHistory );
+                        pTxtNd->GetpSwpHints()->Register( &aRHst );
+                        pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet );
+                        if( pTxtNd->GetpSwpHints() )
+                            pTxtNd->GetpSwpHints()->DeRegister();
+                    }
+                    else
+                        pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet );
+                }
+
+                // the SwRegHistory inserts the attribute into the TxtNode!
+                SwRegHistory history( pNode, *pNode, pHistory );
+                bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags )
+                    || bRet;
+
+                if( pDoc->IsRedlineOn() )
+                {
+                    SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos );
+
+                    if( pUndo )
+                        pUndo->SaveRedlineData( aPam, false );
+                    pDoc->AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_FORMAT, aPam ), true);
+                }
+            }
+            if( pOtherSet && pOtherSet->Count() )
+            {
+                SwRegHistory aRegH( pNode, *pNode, pHistory );
+                bRet = pNode->SetAttr( *pOtherSet ) || bRet;
+            }
+
+            DELETECHARSETS
+            return bRet;
+        }
+
+        if( pDoc->IsRedlineOn() && pCharSet && pCharSet->Count() )
+        {
+            if( pUndo )
+                pUndo->SaveRedlineData( rRg, false );
+            pDoc->AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_FORMAT, rRg ), true);
+        }
+
+        /* now if range */
+        sal_uLong nNodes = 0;
+
+        SwNodeIndex aSt( pDoc->GetNodes() );
+        SwNodeIndex aEnd( pDoc->GetNodes() );
+        SwIndex aCntEnd( pEnd->nContent );
+
+        if( pNode )
+        {
+            const sal_Int32 nLen = pNode->Len();
+            if( pStt->nNode != pEnd->nNode )
+                aCntEnd.Assign( pNode, nLen );
+
+            if( pStt->nContent.GetIndex() != 0 || aCntEnd.GetIndex() != nLen )
+            {
+                // the SwRegHistory inserts the attribute into the TxtNode!
+                if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
+                {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list