[Libreoffice-commits] core.git: Branch 'private/jmux/mailmerge-fixes' - 586 commits - accessibility/Library_acc.mk accessibility/source android/Bootstrap android/experimental avmedia/Module_avmedia.mk avmedia/source basctl/source basebmp/Module_basebmp.mk basegfx/source basegfx/test basic/inc basic/source bean/inc bean/Library_officebean.mk bean/native binaryurp/source bin/gbuild-to-ide bridges/source canvas/source chart2/qa chart2/source comphelper/source compilerplugins/clang config_host.mk.in configmgr/source configure.ac connectivity/CppunitTest_connectivity_ado.mk connectivity/Library_ado.mk connectivity/Library_dbtools.mk connectivity/source cppuhelper/source cppu/source cui/AllLangResTarget_cui.mk cui/source cui/uiconfig cui/UIConfig_cui.mk dbaccess/AllLangResTarget_dbu.mk dbaccess/CppunitTest_dbaccess_embeddeddb_performancetest.mk dbaccess/CppunitTest_dbaccess_hsqldb_test.mk dbaccess/inc dbaccess/source dbaccess/uiconfig dbaccess/UIConfig_dbaccess.mk desktop/inc desktop/Library_sofficeapp .mk desktop/source download.lst drawinglayer/source editeng/source embeddedobj/source embedserv/Library_emser.mk extensions/CppunitTest_extensions_test_update.mk extensions/Library_oleautobridge.mk extensions/Library_so_activex.mk extensions/Library_so_activex_x64.mk extensions/Library_updchk.mk extensions/source extensions/uiconfig extensions/UIConfig_sabpilot.mk extensions/UIConfig_spropctrlr.mk external/clucene external/coinmp external/collada2gltf external/cppunit external/firebird external/glew external/icu external/lcms2 external/libgltf external/libmwaw external/libwpd external/more_fonts external/nss external/openssl external/poppler external/python3 extras/AllLangPackage_autotextshare.mk extras/CustomTarget_autocorr.mk extras/CustomTarget_autotextshare.mk extras/CustomTarget_autotextuser.mk extras/Module_extras.mk extras/Package_autocorr.mk extras/Package_autotextuser.mk extras/source filter/Configuration_filter.mk filter/CppunitTest_filter_priority.mk filter/CppunitTest_fi lter_xslt.mk filter/Library_svgfilter.mk filter/Module_filter.mk filter/qa filter/source forms/source formula/source fpicker/Library_fps_office.mk fpicker/source framework/inc framework/Library_fwe.mk framework/Library_fwk.mk framework/source helpcontent2 hwpfilter/source i18npool/source include/basebmp include/com include/comphelper include/connectivity include/dbaccess include/editeng include/formula include/LibreOfficeKit include/oox include/osl include/rtl include/sal include/sax include/sfx2 include/svl include/svtools include/svx include/test include/toolkit include/tools include/touch include/ucbhelper include/vbahelper include/vcl include/xmloff ios/CustomTarget_TiledLibreOffice_app.mk ios/experimental ios/lo.xcconfig.in jvmaccess/source jvmfwk/plugins l10ntools/source Library_merged.mk libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk libreofficekit/Executable_gtktiledviewer.mk libreofficekit/Module_libreofficekit.mk libreofficekit/qa libreofficekit/source lotuswo rdpro/source Makefile.in offapi/com offapi/UnoApi_offapi.mk oovbaapi/ooo oox/inc oox/Library_oox.mk oox/source package/source postprocess/Rdb_services.mk pyuno/source README.cross registry/source reportdesign/inc reportdesign/source reportdesign/uiconfig reportdesign/UIConfig_dbreport.mk Repository.mk rsc/inc rsc/source sal/CppunitTest_sal_osl_process.mk sal/Module_sal.mk sal/osl sal/qa sal/rtl sal/util sax/source sc/inc scp2/inc scp2/source sc/qa scripting/source sc/source sc/uiconfig sc/UIConfig_scalc.mk sd/CppunitTest_sd_export_tests.mk sdext/Library_pdfimport.mk sdext/source sd/inc sd/Module_sd.mk sd/qa sd/source setup_native/Library_getuid.mk setup_native/source sfx2/AllLangResTarget_sfx2.mk sfx2/inc sfx2/Library_sfx.mk sfx2/source sfx2/uiconfig sfx2/UIConfig_sfx.mk shell/source solenv/bin solenv/gbuild solenv/gcc-wrappers sot/Library_sot.mk sot/source starmath/source starmath/uiconfig stoc/source store/Library_store.mk store/source store/workben svgio/inc svgio/source svl/sour ce svtools/Library_svt.mk svtools/source svx/inc svx/source svx/uiconfig svx/UIConfig_svx.mk sw/AllLangResTarget_sw.mk sw/inc sw/Library_swui.mk sw/qa sw/source sw/uiconfig sw/UIConfig_swriter.mk test/source toolkit/Library_tk.mk toolkit/source tools/source ucbhelper/source ucb/source unoidl/source unotools/source vbahelper/source vcl/generic vcl/headless vcl/inc vcl/Library_vcl.mk vcl/osx vcl/quartz vcl/source vcl/unx vcl/win winaccessibility/Library_uacccom.mk writerfilter/CppunitTest_writerfilter_misc.mk writerfilter/CustomTarget_source.mk writerfilter/inc writerfilter/qa writerfilter/source xmloff/inc xmloff/Library_xo.mk xmloff/qa xmloff/source

Jan-Marek Glogowski glogow at fbihome.de
Sat Jul 12 14:35:20 PDT 2014


Rebased ref, commits from common ancestor:
commit d1983090d08626a42a8c70232f8efa26cc3f2daa
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 6747b2f965006e0e411da997552bad1910b52c05
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 fb8d788d9a886e0954aca553b1d22aa1b91e999a
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 3a4b2a5571a621a5010bda3cab628809109dfd7c
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 30772d82283105a3d410a366060b3fcc0b966f22
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 74afb9265d71e87941378dac3912db7e81c1e906
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 3fd41ef60fdb063eaf66a3e0fd9b0db2f5e78bad
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 5e01084fef606ce88d0bb87f1f72c4ff60a5a03d
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 1 15:25:10 2014 +0200

    Append fixup
    
    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 d6e412a8855164a5b9bfe2ae60224d253276aef8
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 40ff23436a0980093e9688fa584aba4c2e6cb283
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 d28c51a631450f70b16f174c987eee4676e84d44
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 27 14:58:24 2014 +0200

    Some minor MM code cleanups
    
    Just makes the code in SwFEShell::Paste and
    SwDBManager::MergeDocuments 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 682dd4512e7bb7e927d6c8964d83e8d2dae605a2
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 d57bfe208423ee9ff120fb46ec1293d43aac105e
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 beb339916736f9b8421db69f4130c281879c8ff3
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 20bb3ad51f81c5581dbf40b5fbfd28a8b04d73c6
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 0b3b545dd50281b0451a99d57d079aa5bd499322
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 87f970073de32bff053fb01fd9c32dfa1452d388
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 1bae012c997a3cf5b99a6772746107c0a6800458
Author: Takeshi Abe <tabe at fixedpoint.jp>
Date:   Sat Jul 12 23:10:34 2014 +0900

    Avoid possible memory leaks in case of exceptions
    
    Change-Id: Id0304366c4e6191db85527935f5bc5cdb0aeb8d8

diff --git a/sot/source/sdstor/stgdir.cxx b/sot/source/sdstor/stgdir.cxx
index f4903a5..d7dce35 100644
--- a/sot/source/sdstor/stgdir.cxx
+++ b/sot/source/sdstor/stgdir.cxx
@@ -26,7 +26,7 @@
 #include "stgstrms.hxx"
 #include "stgdir.hxx"
 #include "stgio.hxx"
-
+#include <boost/scoped_array.hpp>
 
 //////////////////////////// class StgDirEntry
 
@@ -350,13 +350,12 @@ bool StgDirEntry::SetSize( sal_Int32 nNewSize )
                 // if so, we probably need to copy the old data
                 if( nOldSize )
                 {
-                    void* pBuf = new sal_uInt8[ nOldSize ];
+                    boost::scoped_array<sal_uInt8> pBuf(new sal_uInt8[ nOldSize ]);
                     pOld->Pos2Page( 0L );
                     pStgStrm->Pos2Page( 0L );
-                    if( pOld->Read( pBuf, nOldSize )
-                     && pStgStrm->Write( pBuf, nOldSize ) )
+                    if( pOld->Read( pBuf.get(), nOldSize )

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list