[Libreoffice-commits] core.git: Branch 'private/jmux/mailmerge-fixes' - 34 commits - android/Bootstrap chart2/source desktop/source include/vcl sc/qa sc/source sw/inc sw/qa sw/source vcl/source

Jan-Marek Glogowski glogow at fbihome.de
Sun Jul 13 11:54:54 PDT 2014


Rebased ref, commits from common ancestor:
commit 828203bcbc7830554db277063d647643f0ae33f6
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Jul 2 11:17:17 2014 +0200

    Fixes multiple-page-anchored-draws.odt
    
    Change-Id: I5ad726da647df8621bc0a16caa78a28b7d2d01c1

diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index bc8e403..d4f40c2 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -1221,6 +1221,9 @@ else
             }
         }
 
+        if ( pTargetShell )
+            pTargetShell->CalcLayout();
+
         // finally copy page bound frames
         const SwFrmFmts *pSpzFrmFmts = rSource.GetSpzFrmFmts();
         for ( sal_uInt16 i = 0; i < pSpzFrmFmts->size(); ++i )
commit 0f065b97f32fecb78fe27fa3c546fc93c2127638
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 15:45:47 2014 +0200

    Fix single node CopyRange
    
    Change-Id: Iadf21d3928303c2ab8df0d93dabd969ed1ff7e09

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index d0e31aa..b276d4d 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -469,7 +469,8 @@ private:
     void CopyFlyInFlyImpl(  const SwNodeRange& rRg,
                             const sal_Int32 nEndContentIndex,
                             const SwNodeIndex& rStartIdx,
-                            const bool bCopyFlyAtFly = false ) const;
+                            const bool bCopyFlyAtFly = false,
+                            const bool bMergedFirstNode = false ) const;
     sal_Int8 SetFlyFrmAnchor( SwFrmFmt& rFlyFmt, SfxItemSet& rSet, bool bNewFrms );
 
     typedef SwFmt* (SwDoc:: *FNCopyFmt)( const OUString&, SwFmt*, bool, bool );
@@ -902,7 +903,8 @@ public:
                             const SwPaM* pCopiedPaM = NULL,
                             bool bMakeNewFrms = true,
                             bool bDelRedlines = true,
-                            bool bCopyFlyAtFly = false ) const;
+                            bool bCopyFlyAtFly = false,
+                            bool bSkipFirstNode = 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
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index 5443c9f..771e9d7 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -673,7 +673,7 @@ SwDoc::CopyRange( SwPaM& rPam, SwPosition& rPos, const bool bCopyAll ) const
     bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
 
     // Catch if there's no copy to do
-    if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) )
+    if( !rPam.HasMark() || ( *pStt > *pEnd && !bColumnSel ) )
         return false;
 
     // Prevent copying in Flys that are anchored in the area
@@ -923,7 +923,7 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
     SwPosition* pEnd = rPam.End();
 
     // Catch when there's no copy to do.
-    if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) ||
+    if( !rPam.HasMark() || ( *pStt > *pEnd && !bColumnSel ) ||
         //JP 29.6.2001: 88963 - dont copy if inspos is in region of start to end
         //JP 15.11.2001: don't test inclusive the end, ever exclusive
         ( pDoc == this && *pStt <= rPos && rPos < *pEnd ))
@@ -1011,6 +1011,8 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
         pNumRuleToPropagate = 0;
     }
 
+    bool bHandledStartNode = false;
+
     // This do/while block is only there so that we can break out of it!
     do {
         if( pSttTxtNd )
@@ -1018,6 +1020,8 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
             // Don't copy the beginning completely?
             if( !bCopyCollFmt || bColumnSel || pStt->nContent.GetIndex() )
             {
+                bHandledStartNode = true;
+
                 SwIndex aDestIdx( rPos.nContent );
                 bool bCopyOk = false;
                 if( !pDestTxtNd )
@@ -1093,18 +1097,11 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
                         pEnd->nContent -= nCpyLen;
                 }
 
-                if( bOneNode )
+                if( bCopyCollFmt && bOneNode )
                 {
-                    if( bCopyCollFmt )
-                    {
-                        pSttTxtNd->CopyCollFmt( *pDestTxtNd );
-                        POP_NUMRULE_STATE
-                    }
-
-                    break;
+                    pSttTxtNd->CopyCollFmt( *pDestTxtNd );
+                    POP_NUMRULE_STATE
                 }
-
-                aRg.aStart++;
             }
         }
         else if( pDestTxtNd )
@@ -1161,7 +1158,7 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
         }
 
         pDestTxtNd = aInsPos.GetNode().GetTxtNode();
-        if( pEndTxtNd )
+        if( pEndTxtNd && (!bOneNode || !bHandledStartNode) )
         {
             SwIndex aDestIdx( rPos.nContent );
             if( !pDestTxtNd )
@@ -1205,7 +1202,7 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
         if( bCopyAll || aRg.aStart != aRg.aEnd )
         {
             SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
-            if( pSttTxtNd && bCopyCollFmt && pDestTxtNd->HasSwAttrSet() )
+            if( !bOneNode && pSttTxtNd && bCopyCollFmt && pDestTxtNd->HasSwAttrSet() )
             {
                 aBrkSet.Put( *pDestTxtNd->GetpSwAttrSet() );
                 if( SFX_ITEM_SET == aBrkSet.GetItemState( RES_BREAK, false ) )
@@ -1217,13 +1214,15 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
             if( aInsPos == pEnd->nNode )
             {
                 SwNodeIndex aSaveIdx( aInsPos, -1 );
-                CopyWithFlyInFly( aRg, 0,aInsPos, &rPam, bMakeNewFrms, false );
+                CopyWithFlyInFly( aRg, 0, aInsPos, &rPam, bMakeNewFrms,
+                                  false, false, bHandledStartNode );
                 ++aSaveIdx;
                 pEnd->nNode = aSaveIdx;
                 pEnd->nContent.Assign( aSaveIdx.GetNode().GetTxtNode(), 0 );
             }
             else
-                CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &rPam, bMakeNewFrms, false );
+                CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &rPam,
+                                  bMakeNewFrms, false, false, bHandledStartNode );
 
             bCopyBookmarks = false;
 
@@ -1312,7 +1311,8 @@ void SwDoc::CopyWithFlyInFly(
     const SwPaM* pCopiedPaM,
     const bool bMakeNewFrms,
     const bool bDelRedlines,
-    const bool bCopyFlyAtFly ) const
+    const bool bCopyFlyAtFly,
+    const bool bMergedFirstNode ) const
 {
     SwDoc* pDest = rInsPos.GetNode().GetDoc();
 
@@ -1320,13 +1320,17 @@ void SwDoc::CopyWithFlyInFly(
 
     SwNodeIndex aSavePos( rInsPos, -1 );
     bool bEndIsEqualEndPos = rInsPos == rRg.aEnd;
-    GetNodes()._CopyNodes( rRg, rInsPos, bMakeNewFrms, true );
-    ++aSavePos;
-    if( bEndIsEqualEndPos )
+    SwNodeRange aRg( rRg );
+    if ( bMergedFirstNode )
+        aRg.aStart++;
+    if ( aRg.aStart <= aRg.aEnd )
+        GetNodes()._CopyNodes( aRg, rInsPos, bMakeNewFrms, true );
+    if ( !bMergedFirstNode )
+        ++aSavePos;
+    if ( bEndIsEqualEndPos )
         ((SwNodeIndex&)rRg.aEnd) = aSavePos;
 
     aRedlRest.Restore();
-
 #if OSL_DEBUG_LEVEL > 0
     {
         //JP 17.06.99: Bug 66973 - check count only if the selection is in
@@ -1340,9 +1344,9 @@ void SwDoc::CopyWithFlyInFly(
             !aTmpI.GetNode().IsEndNode() )
         {
             // If the range starts with a SwStartNode, it isn't copied
-            sal_uInt16 offset = (rRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
+            sal_uInt16 offset = (aRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
             OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
-                    rRg.aEnd.GetIndex() - rRg.aStart.GetIndex() - 1 + offset,
+                    aRg.aEnd.GetIndex() - aRg.aStart.GetIndex() - 1 + offset,
                     "An insufficient number of nodes were copied!" );
         }
     }
@@ -1350,7 +1354,7 @@ void SwDoc::CopyWithFlyInFly(
 
     {
         ::sw::UndoGuard const undoGuard(pDest->GetIDocumentUndoRedo());
-        CopyFlyInFlyImpl( rRg, nEndContentIndex, aSavePos, bCopyFlyAtFly );
+        CopyFlyInFlyImpl( rRg, nEndContentIndex, aSavePos, bCopyFlyAtFly, bMergedFirstNode );
     }
 
     SwNodeRange aCpyRange( aSavePos, rInsPos );
@@ -1392,7 +1396,8 @@ void SwDoc::CopyFlyInFlyImpl(
     const SwNodeRange& rRg,
     const sal_Int32 nEndContentIndex,
     const SwNodeIndex& rStartIdx,
-    const bool bCopyFlyAtFly ) const
+    const bool bCopyFlyAtFly,
+    const bool bMergedFirstNode ) const
 {
     // First collect all Flys, sort them according to their ordering number,
     // and then only copy them. This maintains the ordering numbers (which are only
@@ -1512,6 +1517,9 @@ void SwDoc::CopyFlyInFlyImpl(
 
                 ++aIdx;
             }
+            if ( bMergedFirstNode )
+                nAnchorTxtNdNumInRange--;
+
             if ( !bAnchorTxtNdFound )
             {
                 // This case can *not* happen, but to be robust take the first
commit 278ccd5bae49881ef008f46993d0fe5add588ecf
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 21:42:30 2014 +0200

    Normalize SwDBManager::Merge{MailFiles,Documents}
    
    There is still a difference, if run mail merge throught one or
    the other function (MM wizard or UNO).
    
    Change-Id: Ia372bd3edea4c8dfb58e045fc8fed2efcb2a4fde

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 61bfd68..0601873 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -942,21 +942,23 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
 
                 //copy the styles from the source to the target document
                 pTargetView->GetDocShell()->_LoadStyles( *pSourceDocSh, true );
+
                 //determine the page style and number used at the start of the source document
                 pSourceShell->SttEndDoc(true);
                 nStartingPageNo = pSourceShell->GetVirtPageNum();
                 sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc(
                                             pSourceShell->GetCurPageDesc()).GetName();
-                // copy compatibility options
-                lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell);
-                // #72821# copy dynamic defaults
-                lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() );
+
                 // #i72517#
                 const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc );
                 const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
                 bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
                                                 rMaster.GetFooter().IsActive();
 
+                // copy compatibility options
+                lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell);
+                // #72821# copy dynamic defaults
+                lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() );
             }
 
             PrintMonitor aPrtMonDlg(&pSourceShell->GetView().GetEditWin(), PrintMonitor::MONITOR_TYPE_PRINT);
@@ -1046,18 +1048,25 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                             lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
 #endif
 
-                        {
                             //create a view frame for the document
-                            SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 );
+                            SwView* pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() );
                             //request the layout calculation
-                            SwWrtShell& rWorkShell =
-                                    static_cast< SwView* >(pWorkFrame->GetViewShell())->GetWrtShell();
-                            rWorkShell.CalcLayout();
-                            SwDoc* pWorkDoc = ((SwDocShell*)(&xWorkDocSh))->GetDoc();
+                            SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
+                            pWorkView->AttrChangedNotify( &rWorkShell );// in order for SelectShell to be called
+
+                            SwDoc* pWorkDoc = rWorkShell.GetDoc();
                             SwDBManager* pOldDBManager = pWorkDoc->GetDBManager();
                             pWorkDoc->SetDBManager( this );
+                            pWorkDoc->EmbedAllLinks();
+
+                            // #i69485# lock fields to prevent access to the result set while calculating layout
+                            rWorkShell.LockExpFlds();
+                            rWorkShell.CalcLayout();
+                            rWorkShell.UnlockExpFlds();
+
                             SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh));
-                            pWorkDoc->UpdateFlds(NULL, false);
+//                            pWorkDoc->UpdateFlds(NULL, false);
+                            rWorkShell.SwViewShell::UpdateFlds();
                             SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh));
 
                             pWorkDoc->RemoveInvisibleContent();
@@ -1226,7 +1235,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                                 }
                             }
                             pWorkDoc->SetDBManager( pOldDBManager );
-                        }
+
                         xWorkDocSh->DoClose();
                     }
                 }
@@ -2728,7 +2737,8 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
 
     SwWrtShell& rSourceShell = rSourceView.GetWrtShell();
     bool bSynchronizedDoc = rSourceShell.IsLabelDoc() && rSourceShell.GetSectionFmtCount() > 1;
-    //save the settings of the first
+
+    //determine the page style and number used at the start of the source document
     rSourceShell.SttEndDoc(true);
     sal_uInt16 nStartingPageNo = rSourceShell.GetVirtPageNum();
     OUString sModifiedStartingPageDesc;
@@ -2752,11 +2762,13 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
 
         SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
         rMMConfig.SetTargetView(pTargetView);
+
         //initiate SelectShell() to create sub shells
         pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
         SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr();
         SwDoc* pTargetDoc = pTargetShell->GetDoc();
 
+        //copy the styles from the source to the target document
         pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), true );
 
         // #i63806#
@@ -2807,6 +2819,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 SwDBManager* pWorkDBManager = pWorkDoc->GetDBManager();
                 pWorkDoc->SetDBManager( this );
                 pWorkDoc->EmbedAllLinks();
+
                 SwUndoId nLastUndoId(UNDO_EMPTY);
                 if (rWorkShell.GetLastUndoInfo(0, & nLastUndoId))
                 {
@@ -2815,14 +2828,16 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                         rWorkShell.Undo();
                     }
                 }
+
                 // #i69485# lock fields to prevent access to the result set while calculating layout
                 rWorkShell.LockExpFlds();
                 // create a layout
                 rWorkShell.CalcLayout();
                 rWorkShell.UnlockExpFlds();
-                SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
+
+            SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
             rWorkShell.SwViewShell::UpdateFlds();
-                SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
+            SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
 
             // strip invisible content and convert fields to text
             rWorkShell.RemoveInvisibleContent();
@@ -2843,7 +2858,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 //create a new pagestyle
                 //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
                 OUString sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
-                pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName );
+                pTargetDoc->MakePageDesc( sNewPageDescName );
                 pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
                 const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
 
@@ -2857,9 +2872,6 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             else
                 pTargetPageDesc = pTargetShell->FindPageDescByName( sModifiedStartingPageDesc );
 
-            if(nDocNo == 1)
-                pTargetShell->SetPageStyle( sModifiedStartingPageDesc );
-
             sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
             OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
 
commit 3bc1fda9e0b2ad1983b7c8852444a460c9332e00
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 21:37:11 2014 +0200

    MM: Use SwDoc::Append for SwFeShell::Paste
    
    Same as the SwDBManager::MergeDocuments change.
    
    Change-Id: I44684bce187bb949dafc35a49b0aea9b46465cda

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 4bc0d0e..61bfd68 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -921,6 +921,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             OUString sStartingPageDesc;
             sal_uInt16 nStartingPageNo = 0;
             bool bPageStylesWithHeaderFooter = false;
+            SwDoc* pTargetDoc;
+
             if(bAsSingleFile || rMergeDescriptor.bCreateSingleFile)
             {
                 // create a target docshell to put the merged document into
@@ -936,6 +938,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                 //initiate SelectShell() to create sub shells
                 pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
                 pTargetShell = pTargetView->GetWrtShellPtr();
+                pTargetDoc = pTargetShell->GetDoc();
+
                 //copy the styles from the source to the target document
                 pTargetView->GetDocShell()->_LoadStyles( *pSourceDocSh, true );
                 //determine the page style and number used at the start of the source document
@@ -1079,62 +1083,37 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                                 }
 
                                 // insert the document into the target document
-                                rWorkShell.SttEndDoc(false);
-                                rWorkShell.SttEndDoc(true);
-                                rWorkShell.SelAll();
-                                pTargetShell->SwCrsrShell::SttEndDoc( false );
-                                //#i72517# the headers and footers are still those from the source - update in case of fields inside header/footer
-                                if( !nDocNo && bPageStylesWithHeaderFooter )
-                                    pTargetShell->GetView().GetDocShell()->_LoadStyles( *rWorkShell.GetView().GetDocShell(), true );
+
                                 //#i72517# put the styles to the target document
                                 //if the source uses headers or footers each new copy need to copy a new page styles
+                                SwPageDesc* pTargetPageDesc;
                                 if(bPageStylesWithHeaderFooter)
                                 {
                                     //create a new pagestyle
                                     //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
-
-                                    SwDoc* pTargetDoc = pTargetShell->GetDoc();
-                                    SwPageDesc* pSourcePageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
                                     OUString sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
                                     pTargetDoc->MakePageDesc( sNewPageDescName );
-                                    SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
-                                    if(pSourcePageDesc && pTargetPageDesc)
+                                    pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
+                                    const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
+
+                                    if(pWorkPageDesc && pTargetPageDesc)
                                     {
-                                        pTargetDoc->CopyPageDesc( *pSourcePageDesc, *pTargetPageDesc, false );
+                                        pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, false );
                                         sModifiedStartingPageDesc = sNewPageDescName;
-                                        lcl_CopyFollowPageDesc( *pTargetShell, *pSourcePageDesc, *pTargetPageDesc, nDocNo );
+                                        lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
                                     }
                                 }
-
-                                if(nDocNo > 1)
-                                    pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
                                 else
-                                    pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
-                                OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
-                                //#i51359# add a second paragraph in case there's only one
-                                {
-                                    SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
-                                    SwPosition aTestPos( aIdx );
-                                    SwCursor aTestCrsr(aTestPos,0,false);
-                                    if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
-                                    {
-                                        //append a paragraph
-                                        pWorkDoc->AppendTxtNode( aTestPos );
-                                    }
-                                }
+                                    pTargetPageDesc = pTargetShell->FindPageDescByName( sModifiedStartingPageDesc );
 
 #ifdef DBG_UTIL
                                 if ( nDocNo <= MAX_DOC_DUMP )
                                     lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
 #endif
-                                pTargetShell->Paste( rWorkShell.GetDoc(), true );
+                                pTargetDoc->Append( *(rWorkShell.GetDoc()), nStartingPageNo, pTargetPageDesc, nDocNo == 1 );
 
                                 //convert fields in page styles (header/footer - has to be done after the first document has been pasted
-                                if(1 == nDocNo)
-                                {
-                                    pTargetShell->CalcLayout();
-                                    pTargetShell->ConvertFieldsToText();
-                                }
+                                pTargetShell->CalcLayout();
 #ifdef DBG_UTIL
                                 if ( nDocNo <= MAX_DOC_DUMP )
                                     lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
commit 8823985fc368b5650fbe8a808ab83349a7447f66
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 21:31:35 2014 +0200

    Add debug documents to SwDBManager::MergeMailFiles
    
    Just like the debug documents in SwDBManager::MergeDocuments.
    
    Change-Id: I275575853c80d4e19d6df5ba9d8dc689353d7c85

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 71b51af..4bc0d0e 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -808,6 +808,33 @@ static void lcl_RemoveSectionLinks( SwWrtShell& rWorkShell )
     rWorkShell.SetLabelDoc( false );
 }
 
+#ifdef DBG_UTIL
+
+#define MAX_DOC_DUMP 3
+
+static void lcl_SaveDoc( SfxObjectShell *xTargetDocShell,
+                         const char *name, int no = 0 )
+{
+    boost::scoped_ptr< utl::TempFile > aTempFile;
+    OUString sExt( ".odt" );
+    OUString basename = OUString::createFromAscii( name );
+    if (no > 0 )
+        basename += OUString::number(no) + "-";
+    aTempFile.reset( new utl::TempFile( basename, true, &sExt ) );
+    OSL_ENSURE( aTempFile.get(), "Temporary file not available" );
+    INetURLObject aTempFileURL( aTempFile->GetURL() );
+    SfxMedium* pDstMed = new SfxMedium(
+        aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
+        STREAM_STD_READWRITE );
+    xTargetDocShell->DoSaveAs( *pDstMed );
+    xTargetDocShell->DoSaveCompleted( pDstMed );
+    if( xTargetDocShell->GetError() )
+        SAL_WARN( "sw.mailmerge", "Error saving: " << aTempFile->GetURL() );
+    else
+        SAL_INFO( "sw.mailmerge", "Saved doc as: " << aTempFile->GetURL() );
+}
+#endif
+
 bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
         const SwMergeDescriptor& rMergeDescriptor)
 {
@@ -899,6 +926,9 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                 // create a target docshell to put the merged document into
                 xTargetDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD );
                 xTargetDocShell->DoInitNew( 0 );
+#ifdef DBG_UTIL
+                lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
+#endif
                 SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );
 
                 pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
@@ -1007,6 +1037,10 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                         // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here
                         // copy the source document
                         SfxObjectShellLock xWorkDocSh = pSourceDocSh->GetDoc()->CreateCopy( true );
+#ifdef DBG_UTIL
+                        if ( nDocNo <= MAX_DOC_DUMP )
+                            lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
+#endif
 
                         {
                             //create a view frame for the document
@@ -1088,6 +1122,11 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                                         pWorkDoc->AppendTxtNode( aTestPos );
                                     }
                                 }
+
+#ifdef DBG_UTIL
+                                if ( nDocNo <= MAX_DOC_DUMP )
+                                    lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
+#endif
                                 pTargetShell->Paste( rWorkShell.GetDoc(), true );
 
                                 //convert fields in page styles (header/footer - has to be done after the first document has been pasted
@@ -1096,6 +1135,10 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                                     pTargetShell->CalcLayout();
                                     pTargetShell->ConvertFieldsToText();
                                 }
+#ifdef DBG_UTIL
+                                if ( nDocNo <= MAX_DOC_DUMP )
+                                    lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
+#endif
                             }
                             else
                             {
@@ -2648,33 +2691,6 @@ uno::Reference<XResultSet> SwDBManager::createCursor(const OUString& _sDataSourc
     return xResultSet;
 }
 
-#ifdef DBG_UTIL
-
-#define MAX_DOC_DUMP 3
-
-static void lcl_SaveDoc( SfxObjectShell *xTargetDocShell,
-                         const char *name, int no = 0 )
-{
-    boost::scoped_ptr< utl::TempFile > aTempFile;
-    OUString sExt( ".odt" );
-    OUString basename = OUString::createFromAscii( name );
-    if (no > 0 )
-        basename += OUString::number(no) + "-";
-    aTempFile.reset( new utl::TempFile( basename, true, &sExt ) );
-    OSL_ENSURE( aTempFile.get(), "Temporary file not available" );
-    INetURLObject aTempFileURL( aTempFile->GetURL() );
-    SfxMedium* pDstMed = new SfxMedium(
-        aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
-        STREAM_STD_READWRITE );
-    xTargetDocShell->DoSaveAs( *pDstMed );
-    xTargetDocShell->DoSaveCompleted( pDstMed );
-    if( xTargetDocShell->GetError() )
-        SAL_WARN( "sw.mailmerge", "Error saving: " << aTempFile->GetURL() );
-    else
-        SAL_INFO( "sw.mailmerge", "Saved doc as: " << aTempFile->GetURL() );
-}
-#endif
-
 // merge all data into one resulting document and return the number of merged documents
 sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                             SwView& rSourceView )
commit 1d76ca72ef9effe7b42335690c5a1a1b53518556
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 15:48:01 2014 +0200

    Add debug messages for sw.{createcopy,docappend}
    
    This adds a lot of SAL_INFO messages to SwDoc::CreateCopy and
    SwDoc::Append.
    
    Change-Id: Ie924e20698bec84482fcc5496175a9e29245729e

diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index df1d322..bc8e403 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -986,6 +986,11 @@ void SwDoc::ReplaceCompatabilityOptions(const SwDoc& rSource)
     m_pDocumentSettingManager->ReplaceCompatibilityOptions(rSource.GetDocumentSettingManager());
 }
 
+#define CNTNT_DOC( doc ) \
+    ((doc)->GetNodes().GetEndOfContent().GetIndex() - (doc)->GetNodes().GetEndOfExtras().GetIndex() - 2)
+#define CNTNT_IDX( idx ) \
+    ((idx).GetNode().GetIndex() - GetNodes().GetEndOfExtras().GetIndex() - 1)
+
 SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 {
     SwDoc* pRet = new SwDoc;
@@ -1009,7 +1014,14 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 
     pRet->ReplaceStyles(*this);
 
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.createcopy", "CC-Nd-Src: " << CNTNT_DOC( this ) );
+    SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
+#endif
     pRet->Append(*this, 0, NULL, bCallInitNew);
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
+#endif
 
     // remove the temporary shell if it is there as it was done before
     pRet->SetTmpDocShell( (SfxObjectShell*) NULL );
@@ -1040,9 +1052,35 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
     else
         aCpyPam = SwPaM( aSourceIdx, aSourceEndIdx );
 
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType()
+                              << std::dec << " " << aSourceIdx.GetNode().GetIndex() );
+    aSourceIdx++;
+    SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType()
+                                            << std::dec << " " << aSourceIdx.GetNode().GetIndex() );
+    if ( aSourceIdx.GetNode().GetNodeType() != ND_ENDNODE ) {
+        aSourceIdx++;
+        SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType() << std::dec );
+        aSourceIdx--;
+    }
+    aSourceIdx--;
+    SAL_INFO( "sw.docappend", ".." );
+    SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceEndIdx.GetNode().GetNodeType()
+                              << std::dec << " " << aSourceEndIdx.GetNode().GetIndex() );
+    aSourceEndIdx++;
+    SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceEndIdx.GetNode().GetNodeType()
+                              << std::dec << " " << aSourceEndIdx.GetNode().GetIndex() );
+    aSourceEndIdx--;
+    SAL_INFO( "sw.docappend", "Src-Nd: " << CNTNT_DOC( &rSource ) );
+    SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
+#endif
+
     SwWrtShell* pTargetShell = GetDocShell()->GetWrtShell();
     sal_uInt16 nPhysPageNumber = 0;
     if ( pTargetShell ) {
+#ifdef DBG_UTIL
+        SAL_INFO( "sw.docappend", "Has target write shell" );
+#endif
         pTargetShell->StartAllAction();
 
         // Otherwise we have to handle SwDummySectionNodes as first node
@@ -1059,7 +1097,13 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
         // We always start on an odd physical page number
         if (1 == nPhysPageNumber % 2)
             nPhysPageNumber++;
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "PPNo " << nPhysPageNumber );
+#endif
     }
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
+#endif
 
     // -1, otherwise aFixupIdx would move to new EOC
     SwNodeIndex aFixupIdx( GetNodes().GetEndOfContent(), -1 );
@@ -1068,6 +1112,13 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
     SwNodeIndex aTargetIdx( GetNodes().GetEndOfContent() );
     SwPaM aInsertPam( aTargetIdx );
 
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "Pam-Nd: " << aCpyPam.GetNode( true ).GetIndex() - aCpyPam.GetNode( false ).GetIndex() + 1
+                              << " (0x" << std::hex << (int) aCpyPam.GetNode( false ).GetNodeType() << std::dec
+                              << " " << aCpyPam.GetNode( false ).GetIndex()
+                              << " - 0x" << std::hex << (int) aCpyPam.GetNode( true ).GetNodeType() << std::dec
+                              << " " << aCpyPam.GetNode( true ).GetIndex() << ")" );
+#endif
 
     GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
     LockExpFlds();
@@ -1083,9 +1134,14 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
             SwNodeIndex aIndexBefore(rInsPos.nNode);
 
             aIndexBefore--;
-
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "CopyRange In: " << CNTNT_DOC( this ) );
+#endif
             rSource.CopyRange( aCpyPam, rInsPos, true );
             // Note: aCpyPam is invalid now
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "CopyRange Out: " << CNTNT_DOC( this ) );
+#endif
 
             ++aIndexBefore;
             SwPaM aPaM(SwPosition(aIndexBefore),
@@ -1114,10 +1170,23 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
             if ( nStartPageNumber || pTargetPageDesc ) {
                 // Changes the index of aFixupIdx
                 SwTxtNode *aTxtNd = dynamic_cast<  SwTxtNode* >( GetNodes().GoNext(&aFixupIdx) );
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "Idx " << CNTNT_IDX( aDelIdx ) );
+    SAL_INFO( "sw.docappend", "Idx " << CNTNT_IDX( aFixupIdx ) );
+#endif
                 if ( aTxtNd ) {
                     SfxPoolItem *pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "Which: " << pNewItem->Which() << " " << RES_PAGEDESC );
+#endif
                     SwFmtPageDesc *aDesc = dynamic_cast< SwFmtPageDesc* >( pNewItem );
                     if ( aDesc ) {
+#ifdef DBG_UTIL
+if ( aDesc->GetPageDesc() )
+        SAL_INFO( "sw.docappend", "PD Update " << aDesc->GetPageDesc()->GetName() );
+else
+        SAL_INFO( "sw.docappend", "PD New" );
+#endif
                         if ( nStartPageNumber )
                             aDesc->SetNumOffset( nStartPageNumber );
                         if ( pTargetPageDesc )
@@ -1126,6 +1195,10 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
                     }
                     delete pNewItem;
                 }
+
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "Idx " << CNTNT_IDX( aDelIdx ) );
+#endif
                 iDelNodes++;
             }
 
@@ -1139,6 +1212,11 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
                 if ( pTargetShell )
                     pTargetShell->SttEndDoc( false );
                 aDelIdx -= (iDelNodes - 1);
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "iDelNodes: " << iDelNodes
+                              << "  Idx: " << aDelIdx.GetNode().GetIndex()
+                              << "  EOE: " << GetNodes().GetEndOfExtras().GetIndex() );
+#endif
                 GetNodes().Delete( aDelIdx, iDelNodes );
             }
         }
@@ -1151,6 +1229,10 @@ void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
             SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
             if (FLY_AT_PAGE != aAnchor.GetAnchorId())
                 continue;
+#ifdef DBG_UTIL
+    SAL_INFO( "sw.docappend", "PaAn: " << aAnchor.GetPageNum()
+                              << " => " << aAnchor.GetPageNum() + nPhysPageNumber );
+#endif
             if ( nPhysPageNumber )
                 aAnchor.SetPageNum( aAnchor.GetPageNum() + nPhysPageNumber );
             CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
commit 7fec04665f9be3cbf73ebc0de6bde482ff441612
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 13:02:58 2014 +0200

    Refactor NumRule handling in CopyImpl
    
    The bug fix for i#86492 added a lot of duplicated code. This moves
    the code into their own functions and uses macros to make the
    resulting code even more readable.
    
    Change-Id: Ifa0ece26f3152f1f8d8c65173b459e8c14c5b43a

diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index 1f49b0d..5443c9f 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -849,6 +849,69 @@ static bool lcl_ContainsOnlyParagraphsInList( const SwPaM& rPam )
     return bRet;
 }
 
+#define NUMRULE_STATE \
+     int aNumRuleState = SFX_ITEM_UNKNOWN; \
+     SwNumRuleItem aNumRuleItem; \
+     int aListIdState = SFX_ITEM_UNKNOWN; \
+     SfxStringItem aListIdItem( RES_PARATR_LIST_ID, OUString() ); \
+
+#define PUSH_NUMRULE_STATE \
+     lcl_PushNumruleState( aNumRuleState, aNumRuleItem, aListIdState, aListIdItem, pDestTxtNd );
+
+#define POP_NUMRULE_STATE \
+     lcl_PopNumruleState( aNumRuleState, aNumRuleItem, aListIdState, aListIdItem, pDestTxtNd, rPam );
+
+static void lcl_PushNumruleState( int &aNumRuleState, SwNumRuleItem &aNumRuleItem,
+                                  int &aListIdState, SfxStringItem &aListIdItem,
+                                  const SwTxtNode *pDestTxtNd )
+{
+    // Safe numrule item at destination.
+    // #i86492# - Safe also <ListId> item of destination.
+    const SfxItemSet * pAttrSet = pDestTxtNd->GetpSwAttrSet();
+    if (pAttrSet != NULL)
+    {
+        const SfxPoolItem * pItem = NULL;
+        aNumRuleState = pAttrSet->GetItemState(RES_PARATR_NUMRULE, false, &pItem);
+        if (SFX_ITEM_SET == aNumRuleState)
+            aNumRuleItem = *((SwNumRuleItem *) pItem);
+
+        aListIdState =
+            pAttrSet->GetItemState(RES_PARATR_LIST_ID, false, &pItem);
+        if (SFX_ITEM_SET == aListIdState)
+        {
+            aListIdItem.SetValue( static_cast<const SfxStringItem*>(pItem)->GetValue() );
+        }
+    }
+}
+
+static void lcl_PopNumruleState( int aNumRuleState, const SwNumRuleItem &aNumRuleItem,
+                                 int aListIdState, const SfxStringItem &aListIdItem,
+                                 SwTxtNode *pDestTxtNd, const SwPaM& rPam )
+{
+    /* If only a part of one paragraph is copied
+       restore the numrule at the destination. */
+    // #i86492# - restore also <ListId> item
+    if ( !lcl_MarksWholeNode(rPam) )
+    {
+        if (SFX_ITEM_SET == aNumRuleState)
+        {
+            pDestTxtNd->SetAttr(aNumRuleItem);
+        }
+        else
+        {
+            pDestTxtNd->ResetAttr(RES_PARATR_NUMRULE);
+        }
+        if (SFX_ITEM_SET == aListIdState)
+        {
+            pDestTxtNd->SetAttr(aListIdItem);
+        }
+        else
+        {
+            pDestTxtNd->ResetAttr(RES_PARATR_LIST_ID);
+        }
+    }
+}
+
 bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
         const bool bMakeNewFrms, const bool bCopyAll,
         SwPaM *const pCpyRange ) const
@@ -1012,28 +1075,10 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
                     }
                 }
 
-                // Safe numrule item at destination.
-                // #i86492# - Safe also <ListId> item of destination.
-                int aNumRuleState = SFX_ITEM_UNKNOWN;
-                SwNumRuleItem aNumRuleItem;
-                int aListIdState = SFX_ITEM_UNKNOWN;
-                SfxStringItem aListIdItem( RES_PARATR_LIST_ID, OUString() );
+                NUMRULE_STATE
+                if( bCopyCollFmt && bOneNode )
                 {
-                    const SfxItemSet * pAttrSet = pDestTxtNd->GetpSwAttrSet();
-                    if (pAttrSet != NULL)
-                    {
-                        const SfxPoolItem * pItem = NULL;
-                        aNumRuleState = pAttrSet->GetItemState(RES_PARATR_NUMRULE, false, &pItem);
-                        if (SFX_ITEM_SET == aNumRuleState)
-                            aNumRuleItem = *((SwNumRuleItem *) pItem);
-
-                        aListIdState =
-                            pAttrSet->GetItemState(RES_PARATR_LIST_ID, false, &pItem);
-                        if (SFX_ITEM_SET == aListIdState)
-                        {
-                            aListIdItem.SetValue( static_cast<const SfxStringItem*>(pItem)->GetValue() );
-                        }
-                    }
+                    PUSH_NUMRULE_STATE
                 }
 
                 if( !bCopyOk )
@@ -1053,29 +1098,7 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
                     if( bCopyCollFmt )
                     {
                         pSttTxtNd->CopyCollFmt( *pDestTxtNd );
-
-                        /* If only a part of one paragraph is copied
-                           restore the numrule at the destination. */
-                        // #i86492# - restore also <ListId> item
-                        if ( !lcl_MarksWholeNode(rPam) )
-                        {
-                            if (SFX_ITEM_SET == aNumRuleState)
-                            {
-                                pDestTxtNd->SetAttr(aNumRuleItem);
-                            }
-                            else
-                            {
-                                pDestTxtNd->ResetAttr(RES_PARATR_NUMRULE);
-                            }
-                            if (SFX_ITEM_SET == aListIdState)
-                            {
-                                pDestTxtNd->SetAttr(aListIdItem);
-                            }
-                            else
-                            {
-                                pDestTxtNd->ResetAttr(RES_PARATR_LIST_ID);
-                            }
-                        }
+                        POP_NUMRULE_STATE
                     }
 
                     break;
@@ -1157,31 +1180,14 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
                 bStartIsTxtNode = true;
             }
 
-            // Save numrule at destination
-            // #i86492# - Safe also <ListId> item of destination.
-            int aNumRuleState = SFX_ITEM_UNKNOWN;
-            SwNumRuleItem aNumRuleItem;
-            int aListIdState = SFX_ITEM_UNKNOWN;
-            SfxStringItem aListIdItem( RES_PARATR_LIST_ID, OUString() );
-            {
-                const SfxItemSet* pAttrSet = pDestTxtNd->GetpSwAttrSet();
-                if (pAttrSet != NULL)
-                {
-                    const SfxPoolItem * pItem = NULL;
-
-                    aNumRuleState =
-                        pAttrSet->GetItemState(RES_PARATR_NUMRULE, false, &pItem);
-                    if (SFX_ITEM_SET == aNumRuleState)
-                        aNumRuleItem = *((SwNumRuleItem *) pItem);
+            const bool bEmptyDestNd = pDestTxtNd->GetTxt().isEmpty();
 
-                    aListIdState =
-                        pAttrSet->GetItemState(RES_PARATR_LIST_ID, false, &pItem);
-                    if (SFX_ITEM_SET == aListIdState)
-                        aListIdItem.SetValue( static_cast<const SfxStringItem*>(pItem)->GetValue() );
-                }
+            NUMRULE_STATE
+            if( bCopyCollFmt && ( bOneNode || bEmptyDestNd ))
+            {
+                PUSH_NUMRULE_STATE
             }
 
-            const bool bEmptyDestNd = pDestTxtNd->GetTxt().isEmpty();
             pEndTxtNd->CopyText( pDestTxtNd, aDestIdx, SwIndex( pEndTxtNd ),
                             pEnd->nContent.GetIndex() );
 
@@ -1189,31 +1195,9 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
             if( bCopyCollFmt && ( bOneNode || bEmptyDestNd ))
             {
                 pEndTxtNd->CopyCollFmt( *pDestTxtNd );
-
                 if ( bOneNode )
                 {
-                    /* If only a part of one paragraph is copied
-                       restore the numrule at the destination. */
-                    // #i86492# - restore also <ListId> item
-                    if ( !lcl_MarksWholeNode(rPam) )
-                    {
-                        if (SFX_ITEM_SET == aNumRuleState)
-                        {
-                            pDestTxtNd->SetAttr(aNumRuleItem);
-                        }
-                        else
-                        {
-                            pDestTxtNd->ResetAttr(RES_PARATR_NUMRULE);
-                        }
-                        if (SFX_ITEM_SET == aListIdState)
-                        {
-                            pDestTxtNd->SetAttr(aListIdItem);
-                        }
-                        else
-                        {
-                            pDestTxtNd->ResetAttr(RES_PARATR_LIST_ID);
-                        }
-                    }
+                    POP_NUMRULE_STATE
                 }
             }
         }
commit 1f37f167a223fa09035a6c122df583d1765e0f4f
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 15:25:10 2014 +0200

    Fixup SwDoc::Append
    
    Change-Id: I84ee5290ded20803d1496daa52325c3651a9bc97

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index ec80dd3..d0e31aa 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1885,8 +1885,8 @@ public:
     ::sw::UndoManager const& GetUndoManager() const;
 
     SfxObjectShell* CreateCopy(bool bCallInitNew) const;
-    void Append( const SwDoc& rSource, int nStartPageNumber,
-                 SwPageDesc* pTargetPageDesc, int nPhysPageNumber );
+    void Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
+                 SwPageDesc* pTargetPageDesc, bool bDeletePrevious = false );
 
     /**
      * Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by default)
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 54fa8bc..df1d322 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -92,6 +92,7 @@
 #include <DocumentDrawModelManager.hxx>
 #include <unochart.hxx>
 #include <fldbas.hxx>
+#include <wrtsh.hxx>
 
 #include <cmdid.h>
 
@@ -1008,13 +1009,7 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 
     pRet->ReplaceStyles(*this);
 
-    pRet->Append(*this, 0, NULL, 0);
-
-    if ( bCallInitNew ) {
-        // delete leading page / initial content from target document
-        SwNodeIndex aDeleteIdx( pRet->GetNodes().GetEndOfExtras(), 2 );
-        pRet->GetNodes().Delete( aDeleteIdx, 1 );
-    }
+    pRet->Append(*this, 0, NULL, bCallInitNew);
 
     // remove the temporary shell if it is there as it was done before
     pRet->SetTmpDocShell( (SfxObjectShell*) NULL );
@@ -1025,20 +1020,54 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 }
 
 // appends all pages of source SwDoc - based on SwFEShell::Paste( SwDoc* )
-void SwDoc::Append( const SwDoc& rSource, int nStartPageNumber,
-                    SwPageDesc* pTargetPageDesc, int nPhysPageNumber )
+void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
+                    SwPageDesc* pTargetPageDesc, bool bDeletePrevious )
 {
-    // GetEndOfExtras + 1 = StartOfContent
+    // GetEndOfExtras + 1 = StartOfContent == no content node!
+    // this prevents CopyRange to merge any starting text nodes of the first
+    // source paragraph!
+    // additionally it ensures, that we have at least two nodes in the SwPaM.
     SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
-    SwPaM aCpyPam( aSourceIdx ); //DocStart
+    SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), -1 );
+    SwPaM aCpyPam( aSourceIdx );
+
+    if ( aSourceEndIdx.GetNode().IsTxtNode() ) {
+        aCpyPam.SetMark();
+        // moves to the last content node before EOC; for single paragraph
+        // documents this would result in [n, n], which is considered empty
+        aCpyPam.Move( fnMoveForward, fnGoDoc );
+    }
+    else
+        aCpyPam = SwPaM( aSourceIdx, aSourceEndIdx );
+
+    SwWrtShell* pTargetShell = GetDocShell()->GetWrtShell();
+    sal_uInt16 nPhysPageNumber = 0;
+    if ( pTargetShell ) {
+        pTargetShell->StartAllAction();
+
+        // Otherwise we have to handle SwDummySectionNodes as first node
+        if ( pTargetPageDesc ) {
+            OUString name = pTargetPageDesc->GetName();
+            pTargetShell->InsertPageBreak( &name, nStartPageNumber );
+        }
+
+        // -1 for the page break + -1, becauce it's an offset
+        nPhysPageNumber = pTargetShell->GetPhyPageNum() - 2;
+        if (bDeletePrevious)
+            nPhysPageNumber--;
 
-    // Append at the end of document / content
+        // We always start on an odd physical page number
+        if (1 == nPhysPageNumber % 2)
+            nPhysPageNumber++;
+    }
+
+    // -1, otherwise aFixupIdx would move to new EOC
+    SwNodeIndex aFixupIdx( GetNodes().GetEndOfContent(), -1 );
+
+    // append at the end of document / content
     SwNodeIndex aTargetIdx( GetNodes().GetEndOfContent() );
-    SwPaM aInsertPam( aTargetIdx ); //replaces PCURCRSR from SwFEShell::Paste()
-    aTargetIdx--;
+    SwPaM aInsertPam( aTargetIdx );
 
-    aCpyPam.SetMark();
-    aCpyPam.Move( fnMoveForward, fnGoDoc );
 
     GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
     LockExpFlds();
@@ -1077,24 +1106,44 @@ void SwDoc::Append( const SwDoc& rSource, int nStartPageNumber,
             }
         }
 
-        // update the PageDesc pool item
-        if ( nStartPageNumber || pTargetPageDesc ) {
-            SwTxtNode *aTxtNd = dynamic_cast<  SwTxtNode* >( GetNodes().GoNext(&aTargetIdx) );
-            if ( aTxtNd ) {
-                SfxPoolItem *pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
-                SwFmtPageDesc *aDesc = dynamic_cast< SwFmtPageDesc* >( pNewItem );
-                if ( aDesc ) {
-                    if ( nStartPageNumber )
-                        aDesc->SetNumOffset( nStartPageNumber );
-                    if ( pTargetPageDesc )
-                        aDesc->RegisterToPageDesc( *pTargetPageDesc );
-                    aTxtNd->SetAttr( *aDesc );
+        {
+            sal_uInt16 iDelNodes = 0;
+            SwNodeIndex aDelIdx( aFixupIdx );
+
+            // update the PageDesc format item
+            if ( nStartPageNumber || pTargetPageDesc ) {
+                // Changes the index of aFixupIdx
+                SwTxtNode *aTxtNd = dynamic_cast<  SwTxtNode* >( GetNodes().GoNext(&aFixupIdx) );
+                if ( aTxtNd ) {
+                    SfxPoolItem *pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
+                    SwFmtPageDesc *aDesc = dynamic_cast< SwFmtPageDesc* >( pNewItem );
+                    if ( aDesc ) {
+                        if ( nStartPageNumber )
+                            aDesc->SetNumOffset( nStartPageNumber );
+                        if ( pTargetPageDesc )
+                            aDesc->RegisterToPageDesc( *pTargetPageDesc );
+                        aTxtNd->SetAttr( *aDesc );
+                    }
+                    delete pNewItem;
                 }
-                delete pNewItem;
+                iDelNodes++;
+            }
+
+            if ( bDeletePrevious )
+                iDelNodes++;
+
+            if ( iDelNodes ) {
+                // delete leading empty page(s), e.g. from InsertPageBreak or
+                // new SwDoc. this has to be done before copying the page bound
+                // frames, otherwise the drawing layer gets confused.
+                if ( pTargetShell )
+                    pTargetShell->SttEndDoc( false );
+                aDelIdx -= (iDelNodes - 1);
+                GetNodes().Delete( aDelIdx, iDelNodes );
             }
         }
 
-        // additionally copy page bound frames
+        // finally copy page bound frames
         const SwFrmFmts *pSpzFrmFmts = rSource.GetSpzFrmFmts();
         for ( sal_uInt16 i = 0; i < pSpzFrmFmts->size(); ++i )
         {
@@ -1102,7 +1151,7 @@ void SwDoc::Append( const SwDoc& rSource, int nStartPageNumber,
             SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
             if (FLY_AT_PAGE != aAnchor.GetAnchorId())
                 continue;
-            if ( nStartPageNumber )
+            if ( nPhysPageNumber )
                 aAnchor.SetPageNum( aAnchor.GetPageNum() + nPhysPageNumber );
             CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
         }
@@ -1112,6 +1161,9 @@ void SwDoc::Append( const SwDoc& rSource, int nStartPageNumber,
 
     UnlockExpFlds();
     UpdateFlds(NULL, false);
+
+    if ( pTargetShell )
+        pTargetShell->EndAllAction();
 }
 
 sal_uInt16 SwTxtFmtColls::GetPos(const SwTxtFmtColl* p) const
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index 5575934..1f49b0d 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -1355,8 +1355,10 @@ void SwDoc::CopyWithFlyInFly(
             !rRg.aStart.GetNode().IsSectionNode() &&
             !aTmpI.GetNode().IsEndNode() )
         {
+            // If the range starts with a SwStartNode, it isn't copied
+            sal_uInt16 offset = (rRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
             OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
-                    rRg.aEnd.GetIndex() - rRg.aStart.GetIndex(),
+                    rRg.aEnd.GetIndex() - rRg.aStart.GetIndex() - 1 + offset,
                     "An insufficient number of nodes were copied!" );
         }
     }
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index e8e63db..71b51af 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -2769,7 +2769,6 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
         const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
         bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
                                         rMaster.GetFooter().IsActive();
-        SwNodes *pTargetNodes = &pTargetShell->GetDoc()->GetNodes();
 
         // copy compatibility options
         lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell);
@@ -2840,10 +2839,6 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             }
 
             // insert the document into the target document
-            rWorkShell.SttEndDoc(false);
-            rWorkShell.SttEndDoc(true);
-            rWorkShell.SelAll();
-            pTargetShell->SttEndDoc(false);
 
             //#i63806# put the styles to the target document
             //if the source uses headers or footers each new copy need to copy a new page styles
@@ -2868,7 +2863,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 pTargetPageDesc = pTargetShell->FindPageDescByName( sModifiedStartingPageDesc );
 
             if(nDocNo == 1)
-                pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
+                pTargetShell->SetPageStyle( sModifiedStartingPageDesc );
 
             sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
             OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
@@ -2877,18 +2872,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             if ( nDocNo <= MAX_DOC_DUMP )
                 lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
 #endif
-
-            if (nDocNo == 1 ) {
-                pTargetDoc->Append( *(rWorkShell.GetDoc()), 0, pTargetPageDesc, 0 );
-
-                // delete the leading empty page from the initial SwDoc
-                pTargetShell->SttEndDoc( false );
-                SwNodeIndex aDeleteIdx( pTargetNodes->GetEndOfExtras(), 2 );
-                pTargetNodes->Delete( aDeleteIdx, 1 );
-            }
-            else
-                pTargetDoc->Append( *(rWorkShell.GetDoc()), nStartingPageNo,
-                                    pTargetPageDesc, pTargetShell->GetPhyPageNum() );
+            pTargetDoc->Append( *(rWorkShell.GetDoc()), nStartingPageNo, pTargetPageDesc, nDocNo == 1 );
 
             // #i72820# calculate layout to be able to find the correct page index
             pTargetShell->CalcLayout();
commit 522edcaff04c775336e877b77d7d6b02008d0d51
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sat Jun 28 01:41:17 2014 +0200

    MM: introduce SwDoc::Append helper function
    
    This drops all the specialized, workaround code from MM, introduced
    to use the SwFEShell::Paste function.
    
    There is still a little common codepath, therefore this adds
    comments to always update both functions.
    
    Change-Id: I704b3ef3257dd977dac95e16e25049ff8ade97ed

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index ac31da1..ec80dd3 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1883,7 +1883,10 @@ public:
     ::sw::MetaFieldManager & GetMetaFieldManager();
     ::sw::UndoManager      & GetUndoManager();
     ::sw::UndoManager const& GetUndoManager() const;
+
     SfxObjectShell* CreateCopy(bool bCallInitNew) const;
+    void Append( const SwDoc& rSource, int nStartPageNumber,
+                 SwPageDesc* pTargetPageDesc, int nPhysPageNumber );
 
     /**
      * Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by default)
diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 2660c5a..749e735 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -219,7 +219,7 @@ public:
 
     /// Copy and Paste methods for internal clipboard.
     bool Copy( SwDoc* pClpDoc, const OUString* pNewClpTxt = 0 );
-    bool Paste( SwDoc* pClpDoc, bool bIncludingPageFrames = false, bool bIncludeFullDocument = false);
+    bool Paste( SwDoc* pClpDoc, bool bIncludingPageFrames = false );
 
     /// Paste some pages into another doc - used in mailmerge.
     bool PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 6c19998..54fa8bc 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -995,7 +995,8 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
     SfxObjectShell* pRetShell = new SwDocShell( pRet, SFX_CREATE_MODE_STANDARD );
     if( bCallInitNew )
     {
-        // it could happen that DoInitNew creates model, that increases the refcount of the object
+        // it could happen that DoInitNew creates model,
+        // that increases the refcount of the object
         pRetShell->DoInitNew();
     }
 
@@ -1007,30 +1008,54 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 
     pRet->ReplaceStyles(*this);
 
-    // Based on the simplified codepath from SwFEShell::Paste()
+    pRet->Append(*this, 0, NULL, 0);
 
+    if ( bCallInitNew ) {
+        // delete leading page / initial content from target document
+        SwNodeIndex aDeleteIdx( pRet->GetNodes().GetEndOfExtras(), 2 );
+        pRet->GetNodes().Delete( aDeleteIdx, 1 );
+    }
+
+    // remove the temporary shell if it is there as it was done before
+    pRet->SetTmpDocShell( (SfxObjectShell*) NULL );
+
+    pRet->release();
+
+    return pRetShell;
+}
+
+// appends all pages of source SwDoc - based on SwFEShell::Paste( SwDoc* )
+void SwDoc::Append( const SwDoc& rSource, int nStartPageNumber,
+                    SwPageDesc* pTargetPageDesc, int nPhysPageNumber )
+{
     // GetEndOfExtras + 1 = StartOfContent
-    SwNodeIndex aSourceIdx( GetNodes().GetEndOfExtras(), 1 );
-    SwPaM aCpyPam( aSourceIdx ); // DocStart
+    SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
+    SwPaM aCpyPam( aSourceIdx ); //DocStart
 
-    SwNodeIndex aTargetIdx( pRet->GetNodes().GetEndOfContent() );
-    SwPaM aInsertPam( aTargetIdx );
+    // Append at the end of document / content
+    SwNodeIndex aTargetIdx( GetNodes().GetEndOfContent() );
+    SwPaM aInsertPam( aTargetIdx ); //replaces PCURCRSR from SwFEShell::Paste()
+    aTargetIdx--;
 
     aCpyPam.SetMark();
     aCpyPam.Move( fnMoveForward, fnGoDoc );
 
-    pRet->LockExpFlds();
+    GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
+    LockExpFlds();
 
     {
+        // **
+        // ** refer to SwFEShell::Paste, if you change the following code **
+        // **
+
         SwPosition& rInsPos = *aInsertPam.GetPoint();
-        SwPosition aInsertPosition( rInsPos );
 
         {
             SwNodeIndex aIndexBefore(rInsPos.nNode);
 
             aIndexBefore--;
 
-            CopyRange( aCpyPam, rInsPos, true );
+            rSource.CopyRange( aCpyPam, rInsPos, true );
             // Note: aCpyPam is invalid now
 
             ++aIndexBefore;
@@ -1039,37 +1064,54 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 
             aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
 
-            // No need to update the rsid, as pRet is an empty doc
+            // Update the rsid of each pasted text node
+            SwNodes &rDestNodes = GetNodes();
+            sal_uLong const nEndIdx = aPaM.End()->nNode.GetIndex();
+
+            for (sal_uLong nIdx = aPaM.Start()->nNode.GetIndex();
+                    nIdx <= nEndIdx; ++nIdx)
+            {
+                SwTxtNode *const pTxtNode = rDestNodes[nIdx]->GetTxtNode();
+                if ( pTxtNode )
+                    UpdateParRsid( pTxtNode );
+            }
+        }
+
+        // update the PageDesc pool item
+        if ( nStartPageNumber || pTargetPageDesc ) {
+            SwTxtNode *aTxtNd = dynamic_cast<  SwTxtNode* >( GetNodes().GoNext(&aTargetIdx) );
+            if ( aTxtNd ) {
+                SfxPoolItem *pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
+                SwFmtPageDesc *aDesc = dynamic_cast< SwFmtPageDesc* >( pNewItem );
+                if ( aDesc ) {
+                    if ( nStartPageNumber )
+                        aDesc->SetNumOffset( nStartPageNumber );
+                    if ( pTargetPageDesc )
+                        aDesc->RegisterToPageDesc( *pTargetPageDesc );
+                    aTxtNd->SetAttr( *aDesc );
+                }
+                delete pNewItem;
+            }
         }
 
         // additionally copy page bound frames
-        for ( sal_uInt16 i = 0; i < GetSpzFrmFmts()->size(); ++i )
+        const SwFrmFmts *pSpzFrmFmts = rSource.GetSpzFrmFmts();
+        for ( sal_uInt16 i = 0; i < pSpzFrmFmts->size(); ++i )
         {
-            const SwFrmFmt& rCpyFmt = *(*GetSpzFrmFmts())[i];
+            const SwFrmFmt& rCpyFmt = *(*pSpzFrmFmts)[i];
             SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
             if (FLY_AT_PAGE != aAnchor.GetAnchorId())
                 continue;
-            pRet->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
+            if ( nStartPageNumber )
+                aAnchor.SetPageNum( aAnchor.GetPageNum() + nPhysPageNumber );
+            CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
         }
     }
 
-    pRet->UnlockExpFlds();
-    pRet->UpdateFlds( NULL, false );
+    GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
 
-    // End of SwFEShell::Paste() codepath
-
-    if ( bCallInitNew ) {
-        // delete leading page / initial content from target document
-        SwNodeIndex aDeleteIdx( pRet->GetNodes().GetEndOfExtras(), 2 );
-        pRet->GetNodes().Delete( aDeleteIdx, 1 );
-    }
-
-    // remove the temporary shell if it is there as it was done before
-    pRet->SetTmpDocShell( (SfxObjectShell*)NULL );
-
-    pRet->release();
-
-    return pRetShell;
+    UnlockExpFlds();
+    UpdateFlds(NULL, false);
 }
 
 sal_uInt16 SwTxtFmtColls::GetPos(const SwTxtFmtColl* p) const
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index dc4fce0..31509d0 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -668,13 +668,13 @@ namespace {
     typedef std::pair< PaMPtr, PositionPtr > Insertion;
 }
 
-bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames, bool bIncludeFullDocument )
+bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames )
 {
     SET_CURR_SHELL( this );
     OSL_ENSURE( pClpDoc, "no clipboard document"  );
     const sal_uInt16 nStartPageNumber = GetPhyPageNum();
     // then till end of the nodes array
-    SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), (bIncludeFullDocument) ? 1 : 2 );
+    SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
     SwPaM aCpyPam( aIdx ); //DocStart
 
     // If there are table formulas in the area, then display the table first
@@ -1022,6 +1022,10 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames, bool bIncludeF
                 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
             }
 
+            // **
+            // ** Update SwDoc::Append, if you change the following code **
+            // **
+
             // find out if the clipboard document starts with a table
             bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
             SwPosition aInsertPosition( rInsPos );
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 529c3929..e8e63db 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -2760,6 +2760,10 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
         //initiate SelectShell() to create sub shells
         pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
         SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr();
+        SwDoc* pTargetDoc = pTargetShell->GetDoc();
+
+        pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), true );
+
         // #i63806#
         const SwPageDesc* pSourcePageDesc = rSourceShell.FindPageDescByName( sStartingPageDesc );
         const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
@@ -2848,8 +2852,6 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             {
                 //create a new pagestyle
                 //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
-
-                SwDoc* pTargetDoc = pTargetShell->GetDoc();
                 OUString sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
                 pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName );
                 pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
@@ -2862,65 +2864,31 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                     lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
                 }
             }
-            if(nDocNo == 1 || bPageStylesWithHeaderFooter)
-                pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), true );
-            if(nDocNo > 1)
-                pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
             else
+                pTargetPageDesc = pTargetShell->FindPageDescByName( sModifiedStartingPageDesc );
+
+            if(nDocNo == 1)
                 pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
 
             sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
             OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
-            bool para_added = false;
-
-            //#i51359# add a second paragraph in case there's only one
-            {
-                SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
-                SwPosition aTestPos( aIdx );
-                SwCursor aTestCrsr( aTestPos, 0, false );
-                if ( !aTestCrsr.MovePara(fnParaNext, fnParaStart) )
-                {
-                    //append a paragraph
-                    pWorkDoc->AppendTxtNode( aTestPos );
-                    para_added = true;
-                }
-            }
 
 #ifdef DBG_UTIL
             if ( nDocNo <= MAX_DOC_DUMP )
                 lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
 #endif
 
-            SwNodeIndex fixupIdx( pTargetNodes->GetEndOfContent(), -1 );
-            pTargetShell->Paste( rWorkShell.GetDoc(), true, true );
-
-            if (bPageStylesWithHeaderFooter) {
-                // set the real page desc and update the number offset for the pasted document
-                fixupIdx += 2;
-                SwTxtNode *aTxtNd = fixupIdx.GetNode().GetTxtNode();
-                if ( aTxtNd ) {
-                    SfxPoolItem *pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
-                    SwFmtPageDesc *aDesc = dynamic_cast< SwFmtPageDesc* >( pNewItem );
-                    if ( aDesc ) {
-                        aDesc->SetNumOffset( nStartingPageNo );
-                        aDesc->RegisterToPageDesc( *pTargetPageDesc );
-                        aTxtNd->SetAttr( *aDesc );
-                    }
-                    delete pNewItem;
-                }
+            if (nDocNo == 1 ) {
+                pTargetDoc->Append( *(rWorkShell.GetDoc()), 0, pTargetPageDesc, 0 );
 
-                // delete the leading empty page from InsertPageBreak
-                fixupIdx -= 2;
-                pTargetNodes->Delete( fixupIdx, 2 );
-            }
-
-            if ( para_added ) {
-                // Move cursor to the start or Delete will assert because
-                // of the cursors SwIndex ref on the deleting node.
-                pTargetShell->SttEndDoc( true );
-                SwNodeIndex aTargetIdx( pTargetNodes->GetEndOfContent(), -1 );
-                pTargetNodes->Delete( aTargetIdx, 1 );
+                // delete the leading empty page from the initial SwDoc
+                pTargetShell->SttEndDoc( false );
+                SwNodeIndex aDeleteIdx( pTargetNodes->GetEndOfExtras(), 2 );
+                pTargetNodes->Delete( aDeleteIdx, 1 );
             }
+            else
+                pTargetDoc->Append( *(rWorkShell.GetDoc()), nStartingPageNo,
+                                    pTargetPageDesc, pTargetShell->GetPhyPageNum() );
 
             // #i72820# calculate layout to be able to find the correct page index
             pTargetShell->CalcLayout();
commit 9a71519961df9011a633569aea3985cdf4f7f13c
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Mon Jun 23 09:27:27 2014 +0200

    MM: always copy the internal document
    
    There is really no need to create the first document via UNO
    createClone(), which is also slower then the internal copy.
    
    Actually createClone also calls createCopy, but without
    initializing the document.
    
    Change-Id: I23437b0f3ad663942a02be575b39883f9a3b8587

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index d73bb63..529c3929 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1005,17 +1005,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                             Application::Reschedule();
 
                         // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here
-                        SfxObjectShellLock xWorkDocSh;
                         // copy the source document
-                        if( 1 == nDocNo && (bAsSingleFile || rMergeDescriptor.bCreateSingleFile) )
-                        {
-                            uno::Reference< util::XCloneable > xClone( pSourceDocSh->GetModel(), uno::UNO_QUERY);
-                            uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY);
-                            SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId()));
-                            xWorkDocSh = pWorkModel->GetDocShell();
-                        }
-                        else
-                            xWorkDocSh = pSourceDocSh->GetDoc()->CreateCopy( true );
+                        SfxObjectShellLock xWorkDocSh = pSourceDocSh->GetDoc()->CreateCopy( true );
 
                         {
                             //create a view frame for the document
@@ -2802,18 +2793,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
 
             // copy the source document
             // the copy will be closed later, but it is more safe to use SfxObjectShellLock here
-            SfxObjectShellLock xWorkDocSh;
-            if(nDocNo == 1 )
-            {
-                uno::Reference< util::XCloneable > xClone( rSourceView.GetDocShell()->GetModel(), uno::UNO_QUERY);
-                uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY);
-                SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId()));
-                xWorkDocSh = pWorkModel->GetDocShell();
-            }
-            else
-            {
-                xWorkDocSh = rSourceView.GetDocShell()->GetDoc()->CreateCopy(true);
-            }
+            SfxObjectShellLock xWorkDocSh = rSourceView.GetDocShell()->GetDoc()->CreateCopy(true);
 #ifdef DBG_UTIL
             if ( nDocNo <= MAX_DOC_DUMP )
                 lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
commit b27ada0a596fea359295bde869619b41b1d5968a
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 27 14:58:24 2014 +0200

    Some minor MM related refactoring
    
    Refactors some code of SwFEShell::Paste and
    SwDBManager::MergeDocuments to make it more readable.
    
    Change-Id: Ifd78d6a44fa78eaf1f4fca63f4bbd3ee43ca129d

diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 4b12c78..dc4fce0 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -680,7 +680,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames, bool bIncludeF
     // If there are table formulas in the area, then display the table first
     // so that the table formula can calculate a new value first
     // (individual boxes in the area are retrieved via the layout)
-     SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
+    SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
 
     SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode().GetTableNode();
     if( !pSrcNd )                               // TabellenNode ?
@@ -1071,19 +1071,12 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames, bool bIncludeF
 
                 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->size(); ++i )
                 {
-                    bool bInsWithFmt = true;
                     const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
-                    if( bInsWithFmt  )
-                    {
-                        SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
-                        if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
-                        {
-                            aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
-                        }
-                        else
-                            continue;
-                        GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
-                    }
+                    SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
+                    if ( FLY_AT_PAGE != aAnchor.GetAnchorId() )
+                        continue;
+                    aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
+                    GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
                 }
             }
         }
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index ef8d4df..d73bb63 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -2883,17 +2883,12 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 }
             }
             if(nDocNo == 1 || bPageStylesWithHeaderFooter)
-            {
                 pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), true );
-            }
             if(nDocNo > 1)
-            {
                 pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
-            }
             else
-            {
                 pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
-            }
+
             sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
             OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
             bool para_added = false;
@@ -2901,9 +2896,9 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             //#i51359# add a second paragraph in case there's only one
             {
                 SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
-              SwPosition aTestPos( aIdx );
-              SwCursor aTestCrsr(aTestPos,0,false);
-                if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
+                SwPosition aTestPos( aIdx );
+                SwCursor aTestCrsr( aTestPos, 0, false );
+                if ( !aTestCrsr.MovePara(fnParaNext, fnParaStart) )
                 {
                     //append a paragraph
                     pWorkDoc->AppendTxtNode( aTestPos );
@@ -2955,7 +2950,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
 #endif
 
-            //add the document info to the config item
+            // add the document info to the config item
             SwDocMergeInfo aMergeInfo;
             aMergeInfo.nStartPageInTarget = nPageCountBefore;
             aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt();
@@ -2967,17 +2962,17 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             for( sal_uInt16 i = 0; i < 25; i++)
                 Application::Reschedule();
 
-            //restore the ole DBManager
+            // restore the old DBManager
             pWorkDoc->SetDBManager( pWorkDBManager );
-            //now the temporary document should be closed
-            SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
-            xDocSh->DoClose();
+            // close the temporary document
+            xWorkDocSh->DoClose();
+
             nEndRow = pImpl->pMergeData->xResultSet->getRow();
             ++nDocNo;
         } while( !bCancel &&
                 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
 
-        //deselect all, go out of the frame and go to the beginning of the document
+        // deselect all, go out of the frame and go to the beginning of the document
         Point aPt(LONG_MIN, LONG_MIN);
         pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME);
         if (pTargetShell->IsSelFrmMode())
commit 335903ae841585a0798b5aa57004719802be3320
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 27 11:46:00 2014 +0200

    MM: fix lost or broken paragraph anchored objects
    
    With the extended SwFEShell::Paste version, we can finally paste
    full documents without losing the paragraph anchored Flys of the
    first paragraph.
    
    Actually one should be able to drop the InsertPageBreak and the
    single paragraph delete, but my attempt resulted in problems with
    page anchored Flys and somehow reintroduced the problem seen in
    fdo#80395 with draw objects.
    
    Change-Id: I370fa89f432ba4dd95c1f02605f33f04dfbaad85

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 646a0a6..ef8d4df 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -125,6 +125,8 @@
 #include <unomid.h>
 #include <section.hxx>
 #include <rootfrm.hxx>
+#include <fmtpdsc.hxx>
+#include <ndtxt.hxx>
 
 #include <boost/scoped_ptr.hpp>
 
@@ -2772,6 +2774,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
         const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
         bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
                                         rMaster.GetFooter().IsActive();
+        SwNodes *pTargetNodes = &pTargetShell->GetDoc()->GetNodes();
 
         // copy compatibility options
         lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell);
@@ -2860,6 +2863,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
 
             //#i63806# put the styles to the target document
             //if the source uses headers or footers each new copy need to copy a new page styles
+            SwPageDesc* pTargetPageDesc = NULL;
             if(bPageStylesWithHeaderFooter)
             {
                 //create a new pagestyle
@@ -2868,7 +2872,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 SwDoc* pTargetDoc = pTargetShell->GetDoc();
                 OUString sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
                 pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName );
-                SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
+                pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
                 const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
 
                 if(pWorkPageDesc && pTargetPageDesc)
@@ -2911,7 +2915,29 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             if ( nDocNo <= MAX_DOC_DUMP )
                 lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
 #endif
-            pTargetShell->Paste( rWorkShell.GetDoc(), true );
+
+            SwNodeIndex fixupIdx( pTargetNodes->GetEndOfContent(), -1 );
+            pTargetShell->Paste( rWorkShell.GetDoc(), true, true );
+
+            if (bPageStylesWithHeaderFooter) {
+                // set the real page desc and update the number offset for the pasted document
+                fixupIdx += 2;
+                SwTxtNode *aTxtNd = fixupIdx.GetNode().GetTxtNode();
+                if ( aTxtNd ) {
+                    SfxPoolItem *pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
+                    SwFmtPageDesc *aDesc = dynamic_cast< SwFmtPageDesc* >( pNewItem );
+                    if ( aDesc ) {
+                        aDesc->SetNumOffset( nStartingPageNo );
+                        aDesc->RegisterToPageDesc( *pTargetPageDesc );
+                        aTxtNd->SetAttr( *aDesc );
+                    }
+                    delete pNewItem;
+                }
+
+                // delete the leading empty page from InsertPageBreak
+                fixupIdx -= 2;
+                pTargetNodes->Delete( fixupIdx, 2 );
+            }
 
             if ( para_added ) {
                 // Move cursor to the start or Delete will assert because
@@ -2921,12 +2947,9 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 pTargetNodes->Delete( aTargetIdx, 1 );
             }
 
-            //convert fields in page styles (header/footer - has to be done after the first document has been pasted
-            if(1 == nDocNo)
-            {
-                pTargetShell->CalcLayout();
-                pTargetShell->ConvertFieldsToText();
-            }
+            // #i72820# calculate layout to be able to find the correct page index
+            pTargetShell->CalcLayout();
+
 #ifdef DBG_UTIL
             if ( nDocNo <= MAX_DOC_DUMP )
                 lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
@@ -2935,8 +2958,6 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             //add the document info to the config item
             SwDocMergeInfo aMergeInfo;
             aMergeInfo.nStartPageInTarget = nPageCountBefore;
-            //#i72820# calculate layout to be able to find the correct page index
-            pTargetShell->CalcLayout();
             aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt();
             aMergeInfo.nDBRow = nStartRow;
             rMMConfig.AddMergedDocument( aMergeInfo );
commit 024c295e76cd83c7e9ad5adb83515d79da4e3a46
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 27 11:28:02 2014 +0200

    MM: fix workaround for single paragraph docs
    
    There is already a workaround for pasting a document with a single
    paragraph by appending a dummy empty paragraph to the working copy.
    
    This patch removes the dummy paragraph from the target document.
    
    Change-Id: I288d35264bf6f1a5f92c50d6a309e3bdd4ab5836

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 0ed706f..646a0a6 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -2892,6 +2892,8 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
             }
             sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
             OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
+            bool para_added = false;
+
             //#i51359# add a second paragraph in case there's only one
             {
                 SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
@@ -2901,6 +2903,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 {
                     //append a paragraph
                     pWorkDoc->AppendTxtNode( aTestPos );
+                    para_added = true;
                 }
             }
 
@@ -2909,6 +2912,15 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
 #endif
             pTargetShell->Paste( rWorkShell.GetDoc(), true );
+
+            if ( para_added ) {
+                // Move cursor to the start or Delete will assert because
+                // of the cursors SwIndex ref on the deleting node.
+                pTargetShell->SttEndDoc( true );
+                SwNodeIndex aTargetIdx( pTargetNodes->GetEndOfContent(), -1 );
+                pTargetNodes->Delete( aTargetIdx, 1 );
+            }
+
             //convert fields in page styles (header/footer - has to be done after the first document has been pasted
             if(1 == nDocNo)
             {
commit f3ee42e20721f8b2166122eb0cd378ee41feb229
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 27 11:21:47 2014 +0200

    Optionally paste the full document
    
    In the mail merge case we want to paste the full document including
    the SwTxtNode containing the SwFmtPageDesc node, which is always
    the first node of a document.
    
    For normal paste we want to merge the first paragraph into the
    paragraph at the cursor position. This currently loses all Flys
    anchored at the first paragraph.
    
    Change-Id: I2b1ce279743f559e700b47276012ad56d74a059c

diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 9c2e89d..2660c5a 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -219,7 +219,7 @@ public:
 
     /// Copy and Paste methods for internal clipboard.
     bool Copy( SwDoc* pClpDoc, const OUString* pNewClpTxt = 0 );
-    bool Paste( SwDoc* pClpDoc, bool bIncludingPageFrames = false);
+    bool Paste( SwDoc* pClpDoc, bool bIncludingPageFrames = false, bool bIncludeFullDocument = false);
 
     /// Paste some pages into another doc - used in mailmerge.
     bool PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage);
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index be8058f..4b12c78 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -668,13 +668,13 @@ namespace {
     typedef std::pair< PaMPtr, PositionPtr > Insertion;
 }
 
-bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames )
+bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames, bool bIncludeFullDocument )
 {
     SET_CURR_SHELL( this );
     OSL_ENSURE( pClpDoc, "no clipboard document"  );
     const sal_uInt16 nStartPageNumber = GetPhyPageNum();
     // then till end of the nodes array
-    SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
+    SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), (bIncludeFullDocument) ? 1 : 2 );
     SwPaM aCpyPam( aIdx ); //DocStart
 
     // If there are table formulas in the area, then display the table first
commit a03044dc1ce01b80dd4cf8e683cc8bb54379cf4b
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Mon Jun 23 09:16:18 2014 +0200

    Replace the whole content for copied documents
    
    If the document is initialized in CreateCopy, it already contains
    the initial empty paragraph. So we have to delete the content from
    initial document, as we're going to replace the whole content with
    the pasted document.
    
    Change-Id: I33faed4de77919fb926d408e19af9c1ec3b0f7d3

diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 10fbe1e..6c19998 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -1010,10 +1010,10 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
     // Based on the simplified codepath from SwFEShell::Paste()
 
     // GetEndOfExtras + 1 = StartOfContent
-    SwNodeIndex aSourceIdx( GetNodes().GetEndOfExtras(), 2 );
+    SwNodeIndex aSourceIdx( GetNodes().GetEndOfExtras(), 1 );
     SwPaM aCpyPam( aSourceIdx ); // DocStart
 
-    SwNodeIndex aTargetIdx( pRet->GetNodes(), 2 );
+    SwNodeIndex aTargetIdx( pRet->GetNodes().GetEndOfContent() );
     SwPaM aInsertPam( aTargetIdx );
 
     aCpyPam.SetMark();
@@ -1058,6 +1058,12 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 
     // End of SwFEShell::Paste() codepath
 
+    if ( bCallInitNew ) {
+        // delete leading page / initial content from target document
+        SwNodeIndex aDeleteIdx( pRet->GetNodes().GetEndOfExtras(), 2 );
+        pRet->GetNodes().Delete( aDeleteIdx, 1 );
+    }
+
     // remove the temporary shell if it is there as it was done before
     pRet->SetTmpDocShell( (SfxObjectShell*)NULL );
 
commit 5cf0ec6549ca63acc765f8069935f2c63a2ab036
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jun 26 20:23:39 2014 +0200

    Merge SwDoc::Paste into SwDoc::CreateCopy
    
    Change-Id: I95686eb116e17b4da6662b4fbadcf08a0b92a6f4

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 2f84c0d..ac31da1 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -531,7 +531,6 @@ private:
     OUString msDocAccTitle;
 
     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);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 60a4df3..10fbe1e 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -1007,37 +1007,22 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
 
     pRet->ReplaceStyles(*this);
 
-    // copy content
-    pRet->Paste( *this );
+    // Based on the simplified codepath from SwFEShell::Paste()
 
-    // remove the temporary shell if it is there as it was done before
-    pRet->SetTmpDocShell( (SfxObjectShell*)NULL );
-
-    pRet->release();
-
-    return pRetShell;
-}
+    // GetEndOfExtras + 1 = StartOfContent
+    SwNodeIndex aSourceIdx( GetNodes().GetEndOfExtras(), 2 );
+    SwPaM aCpyPam( aSourceIdx ); // DocStart
 
-// copy document content - code from SwFEShell::Paste( SwDoc* )
-void SwDoc::Paste( const SwDoc& rSource )
-{
-    // this has to be empty const sal_uInt16 nStartPageNumber = GetPhyPageNum();
-    // until the end of the NodesArray
-    SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 2 );
-    SwPaM aCpyPam( aSourceIdx ); //DocStart
-    SwNodeIndex aTargetIdx( GetNodes().GetEndOfExtras(), 2 );
-    SwPaM aInsertPam( aTargetIdx ); //replaces PCURCRSR from SwFEShell::Paste()
+    SwNodeIndex aTargetIdx( pRet->GetNodes(), 2 );
+    SwPaM aInsertPam( aTargetIdx );
 
     aCpyPam.SetMark();
     aCpyPam.Move( fnMoveForward, fnGoDoc );
 
-    this->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
-    this->LockExpFlds();
+    pRet->LockExpFlds();
 
     {
         SwPosition& rInsPos = *aInsertPam.GetPoint();
-        //find out if the clipboard document starts with a table
-        bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
         SwPosition aInsertPosition( rInsPos );
 
         {
@@ -1045,7 +1030,7 @@ void SwDoc::Paste( const SwDoc& rSource )
 
             aIndexBefore--;
 
-            rSource.CopyRange( aCpyPam, rInsPos, true );
+            CopyRange( aCpyPam, rInsPos, true );
             // Note: aCpyPam is invalid now
 
             ++aIndexBefore;
@@ -1054,38 +1039,31 @@ void SwDoc::Paste( const SwDoc& rSource )
 
             aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
 
-            // No need to update the rsid, as this is an empty doc
+            // No need to update the rsid, as pRet is an empty doc
         }
 
-        //TODO: Is this necessary here? SaveTblBoxCntnt( &rInsPos );
-        if(/*bIncludingPageFrames && */bStartWithTable)
+        // additionally copy page bound frames
+        for ( sal_uInt16 i = 0; i < GetSpzFrmFmts()->size(); ++i )
         {
-            //remove the paragraph in front of the table
-            SwPaM aPara(aInsertPosition);
-            this->DelFullPara(aPara);
-        }
-        //additionally copy page bound frames
-        if( /*bIncludingPageFrames && */rSource.GetSpzFrmFmts()->size() )
-        {
-            for ( sal_uInt16 i = 0; i < rSource.GetSpzFrmFmts()->size(); ++i )
-            {
-                const SwFrmFmt& rCpyFmt = *(*rSource.GetSpzFrmFmts())[i];
-                    SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
-                    if (FLY_AT_PAGE == aAnchor.GetAnchorId())
-                    {
-                        aAnchor.SetPageNum( aAnchor.GetPageNum() /*+ nStartPageNumber - */);
-                    }
-                    else
-                        continue;
-                    this->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
-            }
+            const SwFrmFmt& rCpyFmt = *(*GetSpzFrmFmts())[i];
+            SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
+            if (FLY_AT_PAGE != aAnchor.GetAnchorId())
+                continue;
+            pRet->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
         }
     }
 
-    this->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
+    pRet->UnlockExpFlds();
+    pRet->UpdateFlds( NULL, false );
+
+    // End of SwFEShell::Paste() codepath
 
-    UnlockExpFlds();
-    UpdateFlds(NULL, false);
+    // remove the temporary shell if it is there as it was done before
+    pRet->SetTmpDocShell( (SfxObjectShell*)NULL );
+
+    pRet->release();
+
+    return pRetShell;
 }
 
 sal_uInt16 SwTxtFmtColls::GetPos(const SwTxtFmtColl* p) const
commit 6ada85d88acb3d8344391bac07b46a00b43293b6
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 13 14:44:37 2014 +0200

    Revert "fdo#66145: do not check IsFirstShared() in SwPageDesc::GetLeftFmt()"
    
    This reverts commit 4df438c9a9d5e698c47c1e85903eb81880a5e6fa.
    
    Change-Id: I8f8d32c07f8706fad6c62fba2a9a373feed6cbed

diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx
index e7641f2..42c7cc4 100644
--- a/sw/source/core/layout/pagedesc.cxx
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -305,14 +305,14 @@ bool SwPageDesc::IsFollowNextPageOfNode( const SwNode& rNd ) const
 SwFrmFmt *SwPageDesc::GetLeftFmt(bool const bFirst)
 {
     return (nsUseOnPage::PD_LEFT & eUse)
-            ? ((bFirst) ? &m_FirstLeft : &aLeft)
+            ? ((bFirst && !IsFirstShared()) ? &m_FirstLeft : &aLeft)
             : 0;
 }
 
 SwFrmFmt *SwPageDesc::GetRightFmt(bool const bFirst)
 {
     return (nsUseOnPage::PD_RIGHT & eUse)
-            ? ((bFirst) ? &m_FirstMaster : &aMaster)
+            ? ((bFirst && !IsFirstShared()) ? &m_FirstMaster : &aMaster)
             : 0;
 }
 
commit d0a7a60cfa1a34ec7218656489b7463cd9eb1aad
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Sun Jul 13 18:02:29 2014 +0200

    fdo#80905 SwXTextFieldMasters::hasByName(): sync with SwXFieldMaster
    
    Normally a mail merge field has a name like
    "css.text.fieldmaster.DataBase.<datasource name>.<table name>.<column
    name>", however this isn't enforced: just
    "css.text.fieldmaster.DataBase.TEST" is also accepted (even if its
    semantics are ~undefined).
    
    If SwXFieldMaster::setPropertyValue() allows setting such a field master
    name, then SwXTextFieldMasters::hasByName() should not ignore such field
    masters that have no dot in their name ("TEST") or use "Database", not
    "DataBase", otherwise (sane) client code in writerfilter ends up with
    hasByName() returning false, but setPropertyValue() throwing an
    exception, because the field master does have such a name.
    
    This fixes DOCX/RTF import of multiple mail merge fields with the same
    field command.
    
    Change-Id: I498eabace25f8e466b3504ba13fa3060d4ba22da

diff --git a/sw/qa/extras/rtfimport/data/fdo80905.rtf b/sw/qa/extras/rtfimport/data/fdo80905.rtf
new file mode 100644

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list