Rebased ref, commits from common ancestor:
commit 6afa4d32617619eb572e9e2bbdeb17160f1d4be3
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Feb 10 19:24:50 2016 +0100

    MM: fix debug document dumping
    
    Previously the debug documents were dumped to the temporary mail
    merge directory, which is removed at the end of MM. So this dumps
    the document to an extra directory.
    
    Also fixes the broken reinterpret_cast "env" => "int" conversation
    to get the real number of documents, which work with multi-digit
    numbers.
    
    Change-Id: I456b506e9a70cffdfc93cb3eadd39c454a536343

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 517051f..2fccde8 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -848,12 +848,27 @@ static void lcl_RemoveSectionLinks( SwWrtShell& 
rWorkShell )
 static void lcl_SaveDebugDoc( SfxObjectShell *xTargetDocShell,
                               const char *name, int no = 0 )
 {
+    static OUString sTempDirURL;
+    if( sTempDirURL.isEmpty() )
+    {
+        SvtPathOptions aPathOpt;
+        utl::TempFile aTempDir( &aPathOpt.GetTempPath(), true );
+        if( aTempDir.IsValid() )
+        {
+            INetURLObject aTempDirURL( aTempDir.GetURL() );
+            sTempDirURL = aTempDirURL.GetMainURL( INetURLObject::NO_DECODE );
+            SAL_INFO( "sw.mailmerge", "Dump directory: " << sTempDirURL );
+        }
+    }
+    if( sTempDirURL.isEmpty() )
+        return;
+
     const OUString sExt( ".odt" );
     OUString basename = OUString::createFromAscii( name );
     if (no > 0)
         basename += OUString::number(no) + "-";
     // aTempFile is not deleted, but that seems to be intentional
-    utl::TempFile aTempFile(basename, true, &sExt);
+    utl::TempFile aTempFile( basename, true, &sExt, &sTempDirURL );
     INetURLObject aTempFileURL( aTempFile.GetURL() );
     SfxMedium* pDstMed = new SfxMedium(
         aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
@@ -1103,7 +1118,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
         if (!sMaxDumpDocs)
             sMaxDumpDocs = "";
         else
-            nMaxDumpDocs = rtl_ustr_toInt32(reinterpret_cast<const 
sal_Unicode*>( sMaxDumpDocs ), 10);
+            nMaxDumpDocs = OUString(sMaxDumpDocs, strlen(sMaxDumpDocs), 
osl_getThreadTextEncoding()).toInt32();
     }
 
     ::rtl::Reference< MailDispatcher >  xMailDispatcher;
commit b2ef9752602f654137490a77966cd3c2742d9e43
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Feb 1 22:00:37 2016 +0100

    MM: remove lock from saved documents
    
    Actually we have to call DoSaveCompleted to get rid of the locking.
    Instead this adds a parameter to skip the recent file registration
    used in non bCreateSingleFile modes.
    
    Change-Id: I57151f08ad8d737007da84c4566685cc37612dfb

diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 9f2f71a..ccc7213 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -327,7 +327,7 @@ public:
     bool                        DoSaveObjectAs( SfxMedium &rNewStor, bool 
bCommit );
 
     // TODO/LATER: currently only overridden in Calc, should be made 
non-virtual
-    virtual bool                DoSaveCompleted( SfxMedium* pNewStor=nullptr );
+    virtual bool                DoSaveCompleted( SfxMedium* pNewStor=nullptr, 
bool bRegisterRecent=true );
 
     bool                        LoadOwnFormat( SfxMedium& pMedium );
     virtual bool                SaveAsOwnFormat( SfxMedium& pMedium );
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 22f3af5..10d0540 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -2449,9 +2449,9 @@ bool ScDocShell::SaveCompleted( const uno::Reference < 
embed::XStorage >& xStor
     return SfxObjectShell::SaveCompleted( xStor );
 }
 
-bool ScDocShell::DoSaveCompleted( SfxMedium * pNewStor )
+bool ScDocShell::DoSaveCompleted( SfxMedium * pNewStor, bool bRegisterRecent )
 {
-    bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor );
+    bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor, bRegisterRecent );
 
     //  SC_HINT_DOC_SAVED for change ReadOnly -> Read/Write
     Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) );
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 69421be..079b542 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -203,7 +203,7 @@ public:
     virtual void    LoadStyles( SfxObjectShell &rSource ) override;
 
     virtual bool    SaveCompleted( const css::uno::Reference< 
css::embed::XStorage >& ) override;      // SfxInPlaceObject
-    virtual bool    DoSaveCompleted( SfxMedium * pNewStor) override;     // 
SfxObjectShell
+    virtual bool    DoSaveCompleted( SfxMedium * pNewStor, bool 
bRegisterRecent ) override;     // SfxObjectShell
     virtual bool    QuerySlotExecutable( sal_uInt16 nSlotId ) override;
 
     virtual void    Draw( OutputDevice *, const JobSetup & rSetup,
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index b6de496..62edc74 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -1942,7 +1942,7 @@ bool SfxObjectShell::DoSaveAs( SfxMedium& rMedium )
 }
 
 
-bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed )
+bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed, bool bRegisterRecent 
)
 {
     bool bOk = true;
     bool bMedChanged = pNewMed && pNewMed!=pMedium;
@@ -2092,7 +2092,8 @@ bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed )
     pMedium->ClearBackup_Impl();
     pMedium->LockOrigFileOnDemand( true, false );
 
-    AddToRecentlyUsedList();
+    if (bRegisterRecent)
+        AddToRecentlyUsedList();
 
     return bOk;
 }
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index cd2d4f9..517051f 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -858,7 +858,10 @@ static void lcl_SaveDebugDoc( SfxObjectShell 
*xTargetDocShell,
     SfxMedium* pDstMed = new SfxMedium(
         aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
         STREAM_STD_READWRITE );
-    if( !xTargetDocShell->DoSaveAs( *pDstMed ) )
+    bool bAnyError = !xTargetDocShell->DoSaveAs( *pDstMed );
+    // xObjectShell->DoSaveCompleted crashes the mail merge unit tests, so 
skip it
+    bAnyError |= (0 != xTargetDocShell->GetError());
+    if( bAnyError )
         SAL_WARN( "sw.mailmerge", "Error saving: " << aTempFile.GetURL() );
     else
         SAL_INFO( "sw.mailmerge", "Saved doc as: " << aTempFile.GetURL() );
@@ -898,12 +901,10 @@ static bool lcl_SaveDoc(
         rWorkShell.ConvertFieldsToText();
 
     bool bAnyError = !xObjectShell->DoSaveAs(*pDstMed);
-
     // Actually this should be a bool... so in case of email and individual
     // files, where this is set, we skip the the recently used handling
-    if( !decodedURL )
-        xObjectShell->DoSaveCompleted( pDstMed );
-    bAnyError = bAnyError || xObjectShell->GetError();
+    bAnyError |= !xObjectShell->DoSaveCompleted( pDstMed, !decodedURL );
+    bAnyError |= (0 != xObjectShell->GetError());
     if( bAnyError )
     {
         // error message ??
commit d119bd16dacea5df027e985cc9e696ad852b9c14
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Jan 27 14:41:35 2016 +0100

    MM: remove multiple unneeded indention levels
    
    Change-Id: Ia363904d3c3fbabdb7aa0dd9aa0715d7d6982f85

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 8792029..cd2d4f9 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1110,487 +1110,484 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* 
pSourceShell,
     rtl_TextEncoding                    sMailEncoding = 
::osl_getThreadTextEncoding();
 
     uno::Reference< beans::XPropertySet > xColumnProp;
+
+    // Check for (mandatory) email or (optional) filename column
+    SwDBFormatData aColumnDBFormat;
+    bool bColumnName = !rMergeDescriptor.sDBcolumn.isEmpty();
+    if( ! bColumnName )
     {
-        // Check for (mandatory) email or (optional) filename column
-        SwDBFormatData aColumnDBFormat;
-        bool bColumnName = !rMergeDescriptor.sDBcolumn.isEmpty();
-        if( ! bColumnName )
-        {
-            if( bMT_EMAIL )
-                return false;
-        }
-        else
-        {
-            uno::Reference< sdbcx::XColumnsSupplier > xColsSupp( 
pImpl->pMergeData->xResultSet, uno::UNO_QUERY );
-            uno::Reference<container::XNameAccess> xCols = 
xColsSupp->getColumns();
-            if( !xCols->hasByName( rMergeDescriptor.sDBcolumn ) )
-                return false;
-            uno::Any aCol = xCols->getByName( rMergeDescriptor.sDBcolumn );
-            aCol >>= xColumnProp;
+        if( bMT_EMAIL )
+            return false;
+    }
+    else
+    {
+        uno::Reference< sdbcx::XColumnsSupplier > xColsSupp( 
pImpl->pMergeData->xResultSet, uno::UNO_QUERY );
+        uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
+        if( !xCols->hasByName( rMergeDescriptor.sDBcolumn ) )
+            return false;
+        uno::Any aCol = xCols->getByName( rMergeDescriptor.sDBcolumn );
+        aCol >>= xColumnProp;
 
-            aColumnDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
-            aColumnDBFormat.aNullDate  = pImpl->pMergeData->aNullDate;
+        aColumnDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
+        aColumnDBFormat.aNullDate  = pImpl->pMergeData->aNullDate;
 
-            if( bMT_EMAIL )
+        if( bMT_EMAIL )
+        {
+            xMailDispatcher.set( new 
MailDispatcher(rMergeDescriptor.xSmtpServer));
+            if(!rMergeDescriptor.bSendAsAttachment && 
rMergeDescriptor.bSendAsHTML)
             {
-                xMailDispatcher.set( new 
MailDispatcher(rMergeDescriptor.xSmtpServer));
-                if(!rMergeDescriptor.bSendAsAttachment && 
rMergeDescriptor.bSendAsHTML)
-                {
-                    sMailBodyMimeType = "text/html; charset=";
-                    sMailBodyMimeType += OUString::createFromAscii(
-                                        
rtl_getBestMimeCharsetFromTextEncoding( sMailEncoding ));
-                    SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
-                    sMailEncoding = rHtmlOptions.GetTextEncoding();
-                }
-                else
-                    sMailBodyMimeType = "text/plain; charset=UTF-8; 
format=flowed";
+                sMailBodyMimeType = "text/html; charset=";
+                sMailBodyMimeType += OUString::createFromAscii(
+                                    rtl_getBestMimeCharsetFromTextEncoding( 
sMailEncoding ));
+                SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
+                sMailEncoding = rHtmlOptions.GetTextEncoding();
             }
+            else
+                sMailBodyMimeType = "text/plain; charset=UTF-8; format=flowed";
         }
+    }
+
+    SwDocShell  *pSourceDocSh = pSourceShell->GetView().GetDocShell();
 
-        SwDocShell  *pSourceDocSh = pSourceShell->GetView().GetDocShell();
+    // setup the output format
+    std::shared_ptr<const SfxFilter> pStoreToFilter = 
SwIoSystem::GetFileFilter(
+        
pSourceDocSh->GetMedium()->GetURLObject().GetMainURL(INetURLObject::NO_DECODE));
+    SfxFilterContainer* pFilterContainer = 
SwDocShell::Factory().GetFilterContainer();
+    const OUString* pStoreToFilterOptions = nullptr;
 
+    // if a save_to filter is set then use it - otherwise use the default
+    if( bMT_EMAIL && !rMergeDescriptor.bSendAsAttachment )
+    {
+        OUString sExtension = rMergeDescriptor.bSendAsHTML ? OUString("html") 
: OUString("txt");
+        pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, 
SfxFilterFlags::EXPORT);
+    }
+    else if( !rMergeDescriptor.sSaveToFilter.isEmpty())
+    {
+        std::shared_ptr<const SfxFilter> pFilter =
+                pFilterContainer->GetFilter4FilterName( 
rMergeDescriptor.sSaveToFilter );
+        if(pFilter)
         {
-            // setup the output format
-            std::shared_ptr<const SfxFilter> pStoreToFilter = 
SwIoSystem::GetFileFilter(
-                
pSourceDocSh->GetMedium()->GetURLObject().GetMainURL(INetURLObject::NO_DECODE));
-            SfxFilterContainer* pFilterContainer = 
SwDocShell::Factory().GetFilterContainer();
-            const OUString* pStoreToFilterOptions = nullptr;
+            pStoreToFilter = pFilter;
+            if(!rMergeDescriptor.sSaveToFilterOptions.isEmpty())
+                pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions;
+        }
+    }
+    const bool bIsPDFexport = pStoreToFilter && 
pStoreToFilter->GetFilterName() == "writer_pdf_Export";
 
-            // if a save_to filter is set then use it - otherwise use the 
default
-            if( bMT_EMAIL && !rMergeDescriptor.bSendAsAttachment )
-            {
-                OUString sExtension = rMergeDescriptor.bSendAsHTML ? 
OUString("html") : OUString("txt");
-                pStoreToFilter = 
pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
-            }
-            else if( !rMergeDescriptor.sSaveToFilter.isEmpty())
-            {
-                std::shared_ptr<const SfxFilter> pFilter =
-                        pFilterContainer->GetFilter4FilterName( 
rMergeDescriptor.sSaveToFilter );
-                if(pFilter)
-                {
-                    pStoreToFilter = pFilter;
-                    if(!rMergeDescriptor.sSaveToFilterOptions.isEmpty())
-                        pStoreToFilterOptions = 
&rMergeDescriptor.sSaveToFilterOptions;
-                }
-            }
-            const bool bIsPDFexport = pStoreToFilter && 
pStoreToFilter->GetFilterName() == "writer_pdf_Export";
+    m_aMergeStatus = MergeStatus::OK;
 
-            m_aMergeStatus = MergeStatus::OK;
+    // in case of creating a single resulting file this has to be created here
+    SwView*           pTargetView     = rMergeDescriptor.pMailMergeConfigItem ?
+                                        
rMergeDescriptor.pMailMergeConfigItem->GetTargetView() : nullptr;
+    SwWrtShell*       pTargetShell    = nullptr;
+    SwDoc*            pTargetDoc      = nullptr;
+    SfxObjectShellRef xTargetDocShell = nullptr;
 
-            // in case of creating a single resulting file this has to be 
created here
-            SwView*           pTargetView     = 
rMergeDescriptor.pMailMergeConfigItem ?
-                                                
rMergeDescriptor.pMailMergeConfigItem->GetTargetView() : nullptr;
-            SwWrtShell*       pTargetShell    = nullptr;
-            SwDoc*            pTargetDoc      = nullptr;
-            SfxObjectShellRef xTargetDocShell = nullptr;
+    std::unique_ptr< utl::TempFile > aTempFile;
+    sal_uInt16 nStartingPageNo = 0;
 
-            std::unique_ptr< utl::TempFile > aTempFile;
-            sal_uInt16 nStartingPageNo = 0;
+    vcl::Window *pSourceWindow = nullptr;
+    VclPtr<CancelableDialog> pProgressDlg;
 
-            vcl::Window *pSourceWindow = nullptr;
-            VclPtr<CancelableDialog> pProgressDlg;
+    if( !bIsMergeSilent )
+    {
+        // construct the process dialog
+        pSourceWindow = &pSourceShell->GetView().GetEditWin();
+        if( !pParent )
+            pParent = pSourceWindow;
+        if( !bMT_PRINTER )
+            pProgressDlg = VclPtr<CreateMonitor>::Create(
+                pParent, pParent != pSourceWindow );
+        else {
+            pProgressDlg = VclPtr<PrintMonitor>::Create(
+                pParent, pParent != pSourceWindow,
+                PrintMonitor::MONITOR_TYPE_PRINT );
+            static_cast<PrintMonitor*>( pProgressDlg.get() )->SetText(
+                pSourceDocSh->GetTitle(22) );
+        }
+        pProgressDlg->SetCancelHdl( LINK(this, SwDBManager, PrtCancelHdl) );
+        pProgressDlg->Show();
 
-            if( !bIsMergeSilent )
-            {
-                // construct the process dialog
-                pSourceWindow = &pSourceShell->GetView().GetEditWin();
-                if( !pParent )
-                    pParent = pSourceWindow;
-                if( !bMT_PRINTER )
-                    pProgressDlg = VclPtr<CreateMonitor>::Create(
-                        pParent, pParent != pSourceWindow );
-                else {
-                    pProgressDlg = VclPtr<PrintMonitor>::Create(
-                        pParent, pParent != pSourceWindow,
-                        PrintMonitor::MONITOR_TYPE_PRINT );
-                    static_cast<PrintMonitor*>( pProgressDlg.get() )->SetText(
-                        pSourceDocSh->GetTitle(22) );
-                }
-                pProgressDlg->SetCancelHdl( LINK(this, SwDBManager, 
PrtCancelHdl) );
-                pProgressDlg->Show();
+        RESCHEDULE_GUI;
+    }
 
-                RESCHEDULE_GUI;
-            }
+    if( bCreateSingleFile && !pTargetView )
+    {
+        // create a target docshell to put the merged document into
+        xTargetDocShell = lcl_CreateWorkingDocument( WorkingDocType::TARGET,
+            *pSourceShell, bMT_SHELL ? pSourceWindow : nullptr,
+            nullptr, &pTargetView, &pTargetShell, &pTargetDoc );
+        if (nMaxDumpDocs)
+            lcl_SaveDebugDoc( xTargetDocShell, "MergeDoc" );
+    }
+    else if( pTargetView )
+    {
+        pTargetShell = pTargetView->GetWrtShellPtr();
+        pTargetDoc = pTargetShell->GetDoc();
+        xTargetDocShell = pTargetView->GetDocShell();
+    }
 
-            if( bCreateSingleFile && !pTargetView )
+    if( bCreateSingleFile )
+    {
+        // determine the page style and number used at the start of the source 
document
+        pSourceShell->SttEndDoc(true);
+        nStartingPageNo = pSourceShell->GetVirtPageNum();
+    }
+
+    // Progress, to prohibit KeyInputs
+    SfxProgress aProgress(pSourceDocSh, ::aEmptyOUStr, 1);
+
+    // lock all dispatchers
+    SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
+    while (pViewFrame)
+    {
+        pViewFrame->GetDispatcher()->Lock(true);
+        pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pSourceDocSh);
+    }
+
+    sal_Int32 nDocNo = 1;
+    sal_Int32 nDocCount = 0;
+    // For single file mode, the number of pages in the target document so 
far, which is used
+    // by AppendDoc() to adjust position of page-bound objects. Getting this 
information directly
+    // from the target doc would require repeated layouts of the doc, which is 
expensive, but
+    // it can be manually computed from the source documents (for which we do 
layouts, so the page
+    // count is known, and there is a blank page between each of them in the 
target document).
+    int targetDocPageCount = 0;
+    if( !bIsMergeSilent && !bMT_PRINTER &&
+            lcl_getCountFromResultSet( nDocCount, 
pImpl->pMergeData->xResultSet ) )
+        static_cast<CreateMonitor*>( pProgressDlg.get() )->SetTotalCount( 
nDocCount );
+
+    long nStartRow, nEndRow;
+    bool bFreezedLayouts = false;
+    // to collect temporary email files
+    ::std::vector< OUString> aFilesToRemove;
+
+    // The SfxObjectShell will be closed explicitly later but
+    // it is more safe to use SfxObjectShellLock here
+    SfxObjectShellLock xWorkDocSh;
+    SwView*            pWorkView             = nullptr;
+    SwDoc*             pWorkDoc              = nullptr;
+    SwDBManager*       pWorkDocOrigDBManager = nullptr;
+    SwWrtShell*        pWorkShell            = nullptr;
+    bool               bWorkDocInitialized   = false;
+
+    do
+    {
+        nStartRow = pImpl->pMergeData ? 
pImpl->pMergeData->xResultSet->getRow() : 0;
+
+        OUString sPath = rMergeDescriptor.sPath;
+        OUString sColumnData;
+
+        // Read the indicated data column, which should contain a valid mail
+        // address or an optional file name
+        if( bMT_EMAIL || bColumnName )
+        {
+            sColumnData = GetDBField( xColumnProp, aColumnDBFormat );
+            if( !bMT_EMAIL )
             {
-                xTargetDocShell = lcl_CreateWorkingDocument( 
WorkingDocType::TARGET,
-                    *pSourceShell, bMT_SHELL ? pSourceWindow : nullptr,
-                    nullptr, &pTargetView, &pTargetShell, &pTargetDoc );
-                if (nMaxDumpDocs)
-                    lcl_SaveDebugDoc( xTargetDocShell, "MergeDoc" );
+                if (sColumnData.isEmpty())
+                    sColumnData = "_";
+                sPath += sColumnData;
             }
-            else if( pTargetView )
+        }
+
+        // create a new temporary file name - only done once in case of 
bCreateSingleFile
+        if( bNeedsTempFiles && ( !bWorkDocInitialized || !bCreateSingleFile ))
+        {
+            INetURLObject aEntry(sPath);
+            OUString sLeading;
+            //#i97667# if the name is from a database field then it will be 
used _as is_
+            if( !sColumnData.isEmpty() )
+                sLeading = sColumnData;
+            else
+                sLeading = aEntry.GetBase();
+            aEntry.removeSegment();
+            sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE );
+            OUString 
sExt(comphelper::string::stripStart(pStoreToFilter->GetDefaultExtension(), 
'*'));
+            aTempFile.reset( new utl::TempFile(sLeading, true, &sExt, &sPath) 
);
+            if( !aTempFile->IsValid() )
             {
-                pTargetShell = pTargetView->GetWrtShellPtr();
-                pTargetDoc = pTargetShell->GetDoc();
-                xTargetDocShell = pTargetView->GetDocShell();
+                ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
+                m_aMergeStatus = MergeStatus::ERROR;
             }
+        }
 
-            if( bCreateSingleFile )
-            {
-                //determine the page style and number used at the start of the 
source document
-                pSourceShell->SttEndDoc(true);
-                nStartingPageNo = pSourceShell->GetVirtPageNum();
+        if( IsMergeOk() )
+        {
+            std::unique_ptr< INetURLObject > aTempFileURL;
+            if( bNeedsTempFiles )
+                aTempFileURL.reset( new INetURLObject(aTempFile->GetURL()));
+            if( !bIsMergeSilent ) {
+                if( !bMT_PRINTER )
+                    static_cast<CreateMonitor*>( pProgressDlg.get() 
)->SetCurrentPosition( nDocNo );
+                else {
+                    PrintMonitor *pPrintMonDlg = static_cast<PrintMonitor*>( 
pProgressDlg.get() );
+                    pPrintMonDlg->m_pPrinter->SetText( bNeedsTempFiles
+                        ? aTempFileURL->GetBase() : pSourceDocSh->GetTitle( 22 
) );
+                    OUString sStat( SW_RES(STR_STATSTR_LETTER) );
+                    sStat += " " + OUString::number( nDocNo );
+                    pPrintMonDlg->m_pPrintInfo->SetText( sStat );
+                }
+                pProgressDlg->Update();
             }
 
-            // Progress, to prohibit KeyInputs
-            SfxProgress aProgress(pSourceDocSh, ::aEmptyOUStr, 1);
+            RESCHEDULE_GUI;
 
-            // lock all dispatchers
-            SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
-            while (pViewFrame)
+            // Create a copy of the source document and work with that one 
instead of the source.
+            // If we're not in the single file mode (which requires modifying 
the document for the merging),
+            // it is enough to do this just once. Currently PDF also has to be 
treated special.
+            if( !bWorkDocInitialized || bCreateSingleFile || bIsPDFexport )
             {
-                pViewFrame->GetDispatcher()->Lock(true);
-                pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pSourceDocSh);
+                assert( !xWorkDocSh.Is());
+                pWorkDocOrigDBManager = this;
+                xWorkDocSh = lcl_CreateWorkingDocument( WorkingDocType::COPY,
+                    *pSourceShell, nullptr, &pWorkDocOrigDBManager,
+                    &pWorkView, &pWorkShell, &pWorkDoc );
+                if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
+                    lcl_SaveDebugDoc( xWorkDocSh, "WorkDoc", nDocNo );
+
+                // #i69458# lock fields to prevent access to the result set 
while calculating layout
+                // tdf#92324: and do not unlock: keep document locked during 
printing to avoid
+                // ExpFields update during printing, generation of preview, 
etc.
+                pWorkShell->LockExpFields();
+                pWorkShell->CalcLayout();
             }
 
-            sal_Int32 nDocNo = 1;
-            sal_Int32 nDocCount = 0;
-            // For single file mode, the number of pages in the target 
document so far, which is used
-            // by AppendDoc() to adjust position of page-bound objects. 
Getting this information directly
-            // from the target doc would require repeated layouts of the doc, 
which is expensive, but
-            // it can be manually computed from the source documents (for 
which we do layouts, so the page
-            // count is known, and there is a blank page between each of them 
in the target document).
-            int targetDocPageCount = 0;
-            if( !bIsMergeSilent && !bMT_PRINTER &&
-                    lcl_getCountFromResultSet( nDocCount, 
pImpl->pMergeData->xResultSet ) )
-                static_cast<CreateMonitor*>( pProgressDlg.get() 
)->SetTotalCount( nDocCount );
-
-            long nStartRow, nEndRow;
-            bool bFreezedLayouts = false;
-            // to collect temporary email files
-            ::std::vector< OUString> aFilesToRemove;
-
-            // The SfxObjectShell will be closed explicitly later but
-            // it is more safe to use SfxObjectShellLock here
-            SfxObjectShellLock xWorkDocSh;
-            SwView*            pWorkView             = nullptr;
-            SwDoc*             pWorkDoc              = nullptr;
-            SwDBManager*       pWorkDocOrigDBManager = nullptr;
-            SwWrtShell*        pWorkShell            = nullptr;
-            bool               bWorkDocInitialized   = false;
-
-            do
-            {
-                nStartRow = pImpl->pMergeData ? 
pImpl->pMergeData->xResultSet->getRow() : 0;
-                {
-                    OUString sPath = rMergeDescriptor.sPath;
-                    OUString sColumnData;
+            EMIT_SW_EVENT(FIELD_MERGE, xWorkDocSh);
 
-                    // Read the indicated data column, which should contain a 
valid mail
-                    // address or an optional file name
-                    if( bMT_EMAIL || bColumnName )
-                    {
-                        sColumnData = GetDBField( xColumnProp, aColumnDBFormat 
);
-                        if( !bMT_EMAIL )
-                        {
-                            if (sColumnData.isEmpty())
-                                sColumnData = "_";
-                            sPath += sColumnData;
-                        }
-                    }
+            // tdf#92324: Allow ExpFields update only by explicit instruction 
to avoid
+            // database cursor movement on any other fields update, for 
example during
+            // print preview and other operations
+            if ( pWorkShell->IsExpFieldsLocked() )
+                pWorkShell->UnlockExpFields();
+            pWorkShell->SwViewShell::UpdateFields();
+            pWorkShell->LockExpFields();
 
-                    // create a new temporary file name - only done once in 
case of bCreateSingleFile
-                    if( bNeedsTempFiles && ( !bWorkDocInitialized || 
!bCreateSingleFile ))
-                    {
-                        INetURLObject aEntry(sPath);
-                        OUString sLeading;
-                        //#i97667# if the name is from a database field then 
it will be used _as is_
-                        if( !sColumnData.isEmpty() )
-                            sLeading = sColumnData;
-                        else
-                            sLeading = aEntry.GetBase();
-                        aEntry.removeSegment();
-                        sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE );
-                        OUString 
sExt(comphelper::string::stripStart(pStoreToFilter->GetDefaultExtension(), 
'*'));
-                        aTempFile.reset(
-                            new utl::TempFile(sLeading, true, &sExt, &sPath));
-                        if( !aTempFile->IsValid() )
-                        {
-                            ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED 
);
-                            m_aMergeStatus = MergeStatus::ERROR;
-                        }
-                    }
+            EMIT_SW_EVENT(FIELD_MERGE_FINISHED, xWorkDocSh);
 
-                    if( IsMergeOk() )
-                    {
-                        std::unique_ptr< INetURLObject > aTempFileURL;
-                        if( bNeedsTempFiles )
-                            aTempFileURL.reset( new 
INetURLObject(aTempFile->GetURL()));
-                        if( !bIsMergeSilent ) {
-                            if( !bMT_PRINTER )
-                                static_cast<CreateMonitor*>( 
pProgressDlg.get() )->SetCurrentPosition( nDocNo );
-                            else {
-                                PrintMonitor *pPrintMonDlg = 
static_cast<PrintMonitor*>( pProgressDlg.get() );
-                                pPrintMonDlg->m_pPrinter->SetText( 
bNeedsTempFiles ? aTempFileURL->GetBase() : OUString( pSourceDocSh->GetTitle( 
22 )));
-                                OUString sStat(SW_RES(STR_STATSTR_LETTER));
-                                sStat += " ";
-                                sStat += OUString::number( nDocNo );
-                                pPrintMonDlg->m_pPrintInfo->SetText( sStat );
-                            }
-                            pProgressDlg->Update();
-                        }
+            // also emit MailMergeEvent on XInterface if possible
+            const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
+            if(pEvtSrc)
+            {
+                uno::Reference< uno::XInterface > xRef(
+                    
static_cast<text::XMailMergeBroadcaster*>(const_cast<SwXMailMerge*>(pEvtSrc)) );
+                text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() );
+                pEvtSrc->LaunchMailMergeEvent( aEvt );
+            }
 
-                        RESCHEDULE_GUI;
+            // working copy is merged - prepare final steps depending on merge 
options
 
-                        // Create a copy of the source document and work with 
that one instead of the source.
-                        // If we're not in the single file mode (which 
requires modifying the document for the merging),
-                        // it is enough to do this just once. Currently PDF 
also has to be treated special.
-                        if( !bWorkDocInitialized || bCreateSingleFile || 
bIsPDFexport )
-                        {
-                            assert( !xWorkDocSh.Is());
-                            pWorkDocOrigDBManager = this;
-                            xWorkDocSh = lcl_CreateWorkingDocument( 
WorkingDocType::COPY,
-                                *pSourceShell, nullptr, &pWorkDocOrigDBManager,
-                                &pWorkView, &pWorkShell, &pWorkDoc );
-                            if ( (nMaxDumpDocs < 0) || (nDocNo <= 
nMaxDumpDocs) )
-                                lcl_SaveDebugDoc( xWorkDocSh, "WorkDoc", 
nDocNo );
-
-                            // #i69458# lock fields to prevent access to the 
result set while calculating layout
-                            // tdf#92324: and do not unlock: keep document 
locked during printing to avoid
-                            // ExpFields update during printing, generation of 
preview, etc.
-                            pWorkShell->LockExpFields();
-                            pWorkShell->CalcLayout();
-                        }
+            if( bCreateSingleFile )
+            {
+                assert( pTargetShell && "no target shell available!" );
 
-                        EMIT_SW_EVENT(FIELD_MERGE, xWorkDocSh);
+                // prepare working copy and target to append
 
-                        // tdf#92324: Allow ExpFields update only by explicit 
instruction to avoid
-                        // database cursor movement on any other fields 
update, for example during
-                        // print preview and other operations
-                        if ( pWorkShell->IsExpFieldsLocked() )
-                            pWorkShell->UnlockExpFields();
-                        pWorkShell->SwViewShell::UpdateFields();
-                        pWorkShell->LockExpFields();
+                pWorkDoc->RemoveInvisibleContent();
+                pWorkShell->ConvertFieldsToText();
+                pWorkShell->SetNumberingRestart();
+                if( bSynchronizedDoc )
+                {
+                    lcl_RemoveSectionLinks( *pWorkShell );
+                }
 
-                        EMIT_SW_EVENT(FIELD_MERGE_FINISHED, xWorkDocSh);
+                if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
+                    lcl_SaveDebugDoc( xWorkDocSh, "WorkDoc", nDocNo );
 
-                        // also emit MailMergeEvent on XInterface if possible
-                        const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
-                        if(pEvtSrc)
-                        {
-                            uno::Reference< uno::XInterface > xRef(
-                                
static_cast<text::XMailMergeBroadcaster*>(const_cast<SwXMailMerge*>(pEvtSrc)) );
-                            text::MailMergeEvent aEvt( xRef, 
xWorkDocSh->GetModel() );
-                            pEvtSrc->LaunchMailMergeEvent( aEvt );
-                        }
-
-                        // working copy is merged - prepare final steps 
depending on merge options
+                // append the working document to the target document
+                if( targetDocPageCount % 2 == 1 )
+                    ++targetDocPageCount; // Docs always start on odd pages 
(so offset must be even).
+                SwNodeIndex appendedDocStart = pTargetDoc->AppendDoc( 
*pWorkDoc,
+                    nStartingPageNo, !bWorkDocInitialized, targetDocPageCount, 
nDocNo);
+                targetDocPageCount += pWorkShell->GetPageCnt();
 
-                        if (bCreateSingleFile)
-                        {
-                            assert( pTargetShell && "no target shell 
available!" );
-
-                            // prepare working copy and target to append
-
-                            pWorkDoc->RemoveInvisibleContent();
-                            pWorkShell->ConvertFieldsToText();
-                            pWorkShell->SetNumberingRestart();
-                            if( bSynchronizedDoc )
-                            {
-                                lcl_RemoveSectionLinks( *pWorkShell );
-                            }
-
-                            if ( (nMaxDumpDocs < 0) || (nDocNo <= 
nMaxDumpDocs) )
-                                lcl_SaveDebugDoc( xWorkDocSh, "WorkDoc", 
nDocNo );
-
-                            // append the working document to the target 
document
-                            if( targetDocPageCount % 2 == 1 )
-                                ++targetDocPageCount; // Docs always start on 
odd pages (so offset must be even).
-                            SwNodeIndex appendedDocStart = 
pTargetDoc->AppendDoc( *pWorkDoc,
-                                nStartingPageNo, !bWorkDocInitialized, 
targetDocPageCount, nDocNo);
-                            targetDocPageCount += pWorkShell->GetPageCnt();
-
-                            if ( (nMaxDumpDocs < 0) || (nDocNo <= 
nMaxDumpDocs) )
-                                lcl_SaveDebugDoc( xTargetDocShell, "MergeDoc" 
);
-
-                            if (bMT_SHELL)
-                            {
-                                SwDocMergeInfo aMergeInfo;
-                                // Name of the mark is actually irrelevant, 
UNO bookmarks have internals names.
-                                aMergeInfo.startPageInTarget = 
pTargetDoc->getIDocumentMarkAccess()->makeMark( appendedDocStart, "",
-                                    
IDocumentMarkAccess::MarkType::UNO_BOOKMARK );
-                                aMergeInfo.nDBRow = nStartRow;
-                                
rMergeDescriptor.pMailMergeConfigItem->AddMergedDocument( aMergeInfo );
-                            }
-                        }
-                        else if( bMT_PRINTER )
-                        {
-                            if( !bWorkDocInitialized ) // set up printing only 
once at the beginning
-                            {
-                                uno::Sequence< beans::PropertyValue > 
aOptions( rMergeDescriptor.aPrintOptions );
-                                lcl_PreparePrinterOptions( 
rMergeDescriptor.aPrintOptions, false, aOptions );
-
-                                pWorkView->StartPrint( aOptions, 
bIsMergeSilent, rMergeDescriptor.bPrintAsync );
-                                // some GetPrinter functions have a true 
default, so keep the false
-                                SfxPrinter* pDocPrt = pWorkView->GetPrinter( 
false );
-                                JobSetup aJobSetup = pDocPrt ? 
pDocPrt->GetJobSetup() : pWorkView->GetJobSetup();
-                                if( !Printer::PreparePrintJob( 
pWorkView->GetPrinterController(), aJobSetup ) )
-                                    MergeCancel();
-                            }
-                            if( IsMergeOk() && !Printer::ExecutePrintJob( 
pWorkView->GetPrinterController()) )
-                            {
-                                m_aMergeStatus = MergeStatus::ERROR;
-                            }
-                        }
-                        else
-                        {
-                            assert( bNeedsTempFiles );
-                            assert( pWorkShell->IsExpFieldsLocked() );
-
-                            // fields are locked, so it's fine to
-                            // restore the old / empty DB manager for save
-                            pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
-
-                            // save merged document
-                            OUString sFileURL;
-                            if( !lcl_SaveDoc( aTempFileURL.get(), 
pStoreToFilter, pStoreToFilterOptions,
-                                              
&rMergeDescriptor.aSaveToFilterData, bIsPDFexport,
-                                              xWorkDocSh, *pWorkShell, 
&sFileURL ) )
-                            {
-                                m_aMergeStatus = MergeStatus::ERROR;
-                            }
-
-                            // back to the MM DB manager
-                            pWorkDoc->SetDBManager( this );
-
-                            if( bMT_EMAIL && !IsMergeError() )
-                            {
-                                // schedule file for later removal
-                                aFilesToRemove.push_back( sFileURL );
-
-                                if( !SwMailMergeHelper::CheckMailAddress( 
sColumnData ) )
-                                {
-                                    OSL_FAIL("invalid e-Mail address in 
database column");
-                                }
-                                else
-                                {
-                                    uno::Reference< mail::XMailMessage > 
xMessage = lcl_CreateMailFromDoc(
-                                        rMergeDescriptor, sFileURL, 
sColumnData, sMailBodyMimeType,
-                                        sMailEncoding, 
pStoreToFilter->GetMimeType() );
-                                    if( xMessage.is() )
-                                    {
-                                        xMailDispatcher->enqueueMailMessage( 
xMessage );
-                                        if( !xMailDispatcher->isStarted() )
-                                            xMailDispatcher->start();
-                                    }
-                                }
-                            }
-                        }
-                        if( bCreateSingleFile || bIsPDFexport )
-                        {
-                            pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
-                            xWorkDocSh->DoClose();
-                            xWorkDocSh = nullptr;
-                        }
-                    }
-                }
-                bWorkDocInitialized = true;
-                nDocNo++;
-                nEndRow = pImpl->pMergeData ? 
pImpl->pMergeData->xResultSet->getRow() : 0;
+                if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
+                    lcl_SaveDebugDoc( xTargetDocShell, "MergeDoc" );
 
-                // Freeze the layouts of the target document after the first 
inserted
-                // sub-document, to get the correct PageDesc.
-                if(!bFreezedLayouts && bCreateSingleFile)
+                if (bMT_SHELL)
                 {
-                    for ( auto aLayout : 
pTargetShell->GetDoc()->GetAllLayouts() )
-                        aLayout->FreezeLayout(true);
-                    bFreezedLayouts = true;
+                    SwDocMergeInfo aMergeInfo;
+                    // Name of the mark is actually irrelevant, UNO bookmarks 
have internals names.
+                    aMergeInfo.startPageInTarget = 
pTargetDoc->getIDocumentMarkAccess()->makeMark(
+                        appendedDocStart, "", 
IDocumentMarkAccess::MarkType::UNO_BOOKMARK );
+                    aMergeInfo.nDBRow = nStartRow;
+                    rMergeDescriptor.pMailMergeConfigItem->AddMergedDocument( 
aMergeInfo );
                 }
-            } while( IsMergeOk() &&
-                ((bSynchronizedDoc && (nStartRow != nEndRow)) ? 
IsValidMergeRecord() : ToNextMergeRecord()));
-
-            if ( xWorkDocSh.Is() && 
pWorkView->GetWrtShell().IsExpFieldsLocked() )
-            {
-                // Unlock document fields after merge complete
-                pWorkView->GetWrtShell().UnlockExpFields();
             }
-
-            if( !bCreateSingleFile )
+            else if( bMT_PRINTER )
             {
-                if( bMT_PRINTER )
-                    Printer::FinishPrintJob( 
pWorkView->GetPrinterController());
-                if( !bIsPDFexport )
+                if( !bWorkDocInitialized ) // set up printing only once at the 
beginning
+                {
+                    uno::Sequence< beans::PropertyValue > aOptions( 
rMergeDescriptor.aPrintOptions );
+                    lcl_PreparePrinterOptions( rMergeDescriptor.aPrintOptions, 
false, aOptions );
+
+                    pWorkView->StartPrint( aOptions, bIsMergeSilent, 
rMergeDescriptor.bPrintAsync );
+                    // some GetPrinter functions have a true default, so keep 
the false
+                    SfxPrinter* pDocPrt = pWorkView->GetPrinter( false );
+                    JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : 
pWorkView->GetJobSetup();
+                    if( !Printer::PreparePrintJob( 
pWorkView->GetPrinterController(), aJobSetup ) )
+                        MergeCancel();
+                }
+                if( IsMergeOk() && !Printer::ExecutePrintJob( 
pWorkView->GetPrinterController()) )
                 {
-                    pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
-                    xWorkDocSh->DoClose();
+                    m_aMergeStatus = MergeStatus::ERROR;
                 }
             }
-            else if( IsMergeOk() ) // && bCreateSingleFile
+            else
             {
-                RESCHEDULE_GUI;
-
-                // sw::DocumentLayoutManager::CopyLayoutFormat() did not 
generate
-                // unique fly names, do it here once.
-                pTargetDoc->SetInMailMerge(false);
-                pTargetDoc->SetAllUniqueFlyNames();
-
-                // Unfreeze target document layouts and correct all PageDescs.
-                pTargetShell->CalcLayout();
-                for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
+                assert( bNeedsTempFiles );
+                assert( pWorkShell->IsExpFieldsLocked() );
+
+                // fields are locked, so it's fine to
+                // restore the old / empty DB manager for save
+                pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
+
+                // save merged document
+                OUString sFileURL;
+                if( !lcl_SaveDoc( aTempFileURL.get(), pStoreToFilter, 
pStoreToFilterOptions,
+                                  &rMergeDescriptor.aSaveToFilterData, 
bIsPDFexport,
+                                  xWorkDocSh, *pWorkShell, &sFileURL ) )
                 {
-                    aLayout->FreezeLayout(false);
-                    aLayout->AllCheckPageDescs();
+                    m_aMergeStatus = MergeStatus::ERROR;
                 }
 
-                RESCHEDULE_GUI;
+                // back to the MM DB manager
+                pWorkDoc->SetDBManager( this );
 
-                if( IsMergeOk() && bMT_FILE )
+                if( bMT_EMAIL && !IsMergeError() )
                 {
-                    // save merged document
-                    assert( aTempFile.get() );
-                    INetURLObject aTempFileURL;
-                    if( rMergeDescriptor.sPath.isEmpty() )
-                        aTempFileURL.SetURL( aTempFile->GetURL() );
-                    else
+                    // schedule file for later removal
+                    aFilesToRemove.push_back( sFileURL );
+
+                    if( !SwMailMergeHelper::CheckMailAddress( sColumnData ) )
                     {
-                        aTempFileURL.SetURL( rMergeDescriptor.sPath );
-                        // remove the unneeded temporary file
-                        aTempFile->EnableKillingFile();
+                        OSL_FAIL("invalid e-Mail address in database column");
                     }
-                    if( !lcl_SaveDoc( &aTempFileURL, pStoreToFilter,
-                            pStoreToFilterOptions, 
&rMergeDescriptor.aSaveToFilterData,
-                            bIsPDFexport, xTargetDocShell, *pTargetShell ) )
+                    else
                     {
-                        m_aMergeStatus = MergeStatus::ERROR;
+                        uno::Reference< mail::XMailMessage > xMessage = 
lcl_CreateMailFromDoc(
+                            rMergeDescriptor, sFileURL, sColumnData, 
sMailBodyMimeType,
+                            sMailEncoding, pStoreToFilter->GetMimeType() );
+                        if( xMessage.is() )
+                        {
+                            xMailDispatcher->enqueueMailMessage( xMessage );
+                            if( !xMailDispatcher->isStarted() )
+                                xMailDispatcher->start();
+                        }
                     }
                 }
-                else if( IsMergeOk() && bMT_PRINTER )
-                {
-                    // print the target document
-                    uno::Sequence< beans::PropertyValue > aOptions( 
rMergeDescriptor.aPrintOptions );
-                    lcl_PreparePrinterOptions( rMergeDescriptor.aPrintOptions, 
true, aOptions );
-                    pTargetView->ExecPrint( aOptions, bIsMergeSilent, 
rMergeDescriptor.bPrintAsync );
-                }
-
-                if( IsMergeOk() && bMT_SHELL )
-                    // leave docshell available for caller (e.g. MM wizard)
-                    rMergeDescriptor.pMailMergeConfigItem->SetTargetView( 
pTargetView );
-                else
-                    xTargetDocShell->DoClose();
             }
+            if( bCreateSingleFile || bIsPDFexport )
+            {
+                pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
+                xWorkDocSh->DoClose();
+                xWorkDocSh = nullptr;
+            }
+        }
 
-            pProgressDlg.disposeAndClear();
+        bWorkDocInitialized = true;
+        nDocNo++;
+        nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() 
: 0;
 
-            // remove the temporary files
-            ::std::vector<OUString>::iterator aFileIter;
-            for(aFileIter = aFilesToRemove.begin();
-                        aFileIter != aFilesToRemove.end(); ++aFileIter)
-                SWUnoHelper::UCB_DeleteFile( *aFileIter );
+        // Freeze the layouts of the target document after the first inserted
+        // sub-document, to get the correct PageDesc.
+        if(!bFreezedLayouts && bCreateSingleFile)
+        {
+            for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
+                aLayout->FreezeLayout(true);
+            bFreezedLayouts = true;
+        }
+    } while( IsMergeOk() &&
+        ((bSynchronizedDoc && (nStartRow != nEndRow)) ? IsValidMergeRecord() : 
ToNextMergeRecord()));
+
+    if ( xWorkDocSh.Is() && pWorkView->GetWrtShell().IsExpFieldsLocked() )
+    {
+        // Unlock document fields after merge complete
+        pWorkView->GetWrtShell().UnlockExpFields();
+    }
+
+    if( !bCreateSingleFile )
+    {
+        if( bMT_PRINTER )
+            Printer::FinishPrintJob( pWorkView->GetPrinterController());
+        if( !bIsPDFexport )
+        {
+            pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
+            xWorkDocSh->DoClose();
+        }
+    }
+    else if( IsMergeOk() ) // && bCreateSingleFile
+    {
+        RESCHEDULE_GUI;
+
+        // sw::DocumentLayoutManager::CopyLayoutFormat() did not generate
+        // unique fly names, do it here once.
+        pTargetDoc->SetInMailMerge(false);
+        pTargetDoc->SetAllUniqueFlyNames();
 
-            // unlock all dispatchers
-            pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
-            while (pViewFrame)
+        // Unfreeze target document layouts and correct all PageDescs.
+        pTargetShell->CalcLayout();
+        for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
+        {
+            aLayout->FreezeLayout(false);
+            aLayout->AllCheckPageDescs();
+        }
+
+        RESCHEDULE_GUI;
+
+        if( IsMergeOk() && bMT_FILE )
+        {
+            // save merged document
+            assert( aTempFile.get() );
+            INetURLObject aTempFileURL;
+            if( rMergeDescriptor.sPath.isEmpty() )
+                aTempFileURL.SetURL( aTempFile->GetURL() );
+            else
             {
-                pViewFrame->GetDispatcher()->Lock(false);
-                pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pSourceDocSh);
+                aTempFileURL.SetURL( rMergeDescriptor.sPath );
+                // remove the unneeded temporary file
+                aTempFile->EnableKillingFile();
+            }
+            if( !lcl_SaveDoc( &aTempFileURL, pStoreToFilter,
+                    pStoreToFilterOptions, &rMergeDescriptor.aSaveToFilterData,
+                    bIsPDFexport, xTargetDocShell, *pTargetShell ) )
+            {
+                m_aMergeStatus = MergeStatus::ERROR;
             }
-
-            SW_MOD()->SetView(&pSourceShell->GetView());
         }
+        else if( IsMergeOk() && bMT_PRINTER )
+        {
+            // print the target document
+            uno::Sequence< beans::PropertyValue > aOptions( 
rMergeDescriptor.aPrintOptions );
+            lcl_PreparePrinterOptions( rMergeDescriptor.aPrintOptions, true, 
aOptions );
+            pTargetView->ExecPrint( aOptions, bIsMergeSilent, 
rMergeDescriptor.bPrintAsync );
+        }
+
+        if( IsMergeOk() && bMT_SHELL )
+            // leave docshell available for caller (e.g. MM wizard)
+            rMergeDescriptor.pMailMergeConfigItem->SetTargetView( pTargetView 
);
+        else
+            xTargetDocShell->DoClose();
+    }
+
+    RESCHEDULE_GUI;
+
+    pProgressDlg.disposeAndClear();
+
+    // remove the temporary files
+    for( const OUString &sFileURL : aFilesToRemove )
+        SWUnoHelper::UCB_DeleteFile( sFileURL );
+
+    // unlock all dispatchers
+    pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
+    while (pViewFrame)
+    {
+        pViewFrame->GetDispatcher()->Lock(false);
+        pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pSourceDocSh);
     }
 
+    SW_MOD()->SetView(&pSourceShell->GetView());
+
     if( xMailDispatcher.is() )
     {
         xMailDispatcher->stop();
@@ -2843,23 +2840,19 @@ void SwDBManager::ExecuteFormLetter( SwWrtShell& rSh,
         SfxObjectShellRef xDocShell = 
rSh.GetView().GetViewFrame()->GetObjectShell();
 
         EMIT_SW_EVENT(MAIL_MERGE, xDocShell);
-        {
-            {
-                {
-                    // prepare mail merge descriptor
-                    SwMergeDescriptor aMergeDesc( 
pImpl->pMergeDialog->GetMergeType(), rSh, aDescriptor );
-                    aMergeDesc.sSaveToFilter = 
pImpl->pMergeDialog->GetSaveFilter();
-                    aMergeDesc.bCreateSingleFile = 
pImpl->pMergeDialog->IsSaveSingleDoc();
-                    aMergeDesc.sPath = pImpl->pMergeDialog->GetTargetURL();
-                    if( !aMergeDesc.bCreateSingleFile && 
pImpl->pMergeDialog->IsGenerateFromDataBase() )
-                    {
-                        aMergeDesc.sDBcolumn = 
pImpl->pMergeDialog->GetColumnName();
-                    }
 
-                    Merge( aMergeDesc );
-                }
-            }
+        // prepare mail merge descriptor
+        SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), 
rSh, aDescriptor );
+        aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter();
+        aMergeDesc.bCreateSingleFile = pImpl->pMergeDialog->IsSaveSingleDoc();
+        aMergeDesc.sPath = pImpl->pMergeDialog->GetTargetURL();
+        if( !aMergeDesc.bCreateSingleFile && 
pImpl->pMergeDialog->IsGenerateFromDataBase() )
+        {
+            aMergeDesc.sDBcolumn = pImpl->pMergeDialog->GetColumnName();
         }
+
+        Merge( aMergeDesc );
+
         EMIT_SW_EVENT(MAIL_MERGE_END, xDocShell);
 
         // reset the cursor inside
commit 1cd0d8a8ff69a0f077e1ada4a1a65625c4f64f49
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Jan 27 13:59:42 2016 +0100

    MM: rename MergeNew => Merge
    
    Since all old code from the original Merge function is gone, just
    do the rename.
    
    Change-Id: I7cc1b4b58cc73bea83a723b2478a8b4bf59a382f

diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index 7f7a394..583e902 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -289,7 +289,7 @@ public:
     inline void     SetMergeSilent( bool bVal )     { bMergeSilent = bVal; }
 
     /// Merging of data records into fields.
-    bool            MergeNew( const SwMergeDescriptor& rMergeDesc, 
vcl::Window* pParent = nullptr );
+    bool            Merge( const SwMergeDescriptor& rMergeDesc, vcl::Window* 
pParent = nullptr );
     void            MergeCancel();
 
     inline bool     IsMergeOk()     { return MergeStatus::OK     == 
m_aMergeStatus; };
diff --git a/sw/source/ui/dbui/mailmergewizard.cxx 
b/sw/source/ui/dbui/mailmergewizard.cxx
index d361063..8c60483 100644
--- a/sw/source/ui/dbui/mailmergewizard.cxx
+++ b/sw/source/ui/dbui/mailmergewizard.cxx
@@ -251,7 +251,7 @@ void SwMailMergeWizard::CreateTargetDocument()
     aMergeDesc.pMailMergeConfigItem = &m_rConfigItem;
     aMergeDesc.bCreateSingleFile = true;
 
-    GetSwView()->GetWrtShell().GetDBManager()->MergeNew( aMergeDesc, this );
+    GetSwView()->GetWrtShell().GetDBManager()->Merge( aMergeDesc, this );
     m_rConfigItem.SetMergeDone();
     if( m_rConfigItem.GetTargetView() )
         m_rConfigItem.GetTargetView()->GetViewFrame()->GetFrame().Appear();
diff --git a/sw/source/uibase/app/apphdl.cxx b/sw/source/uibase/app/apphdl.cxx
index e721abc..237db65 100644
--- a/sw/source/uibase/app/apphdl.cxx
+++ b/sw/source/uibase/app/apphdl.cxx
@@ -635,7 +635,7 @@ SwMailMergeConfigItem* PerformMailMerge(SwView* pView)
     SwMergeDescriptor aMergeDesc(DBMGR_MERGE_SHELL, rSh, aDescriptor);
     aMergeDesc.pMailMergeConfigItem = pConfigItem;
     aMergeDesc.bCreateSingleFile = true;
-    rSh.GetDBManager()->MergeNew(aMergeDesc);
+    rSh.GetDBManager()->Merge(aMergeDesc);
 
     pConfigItem->SetMergeDone();
 
@@ -773,7 +773,7 @@ void SwModule::ExecOther(SfxRequest& rReq)
 
             SwWrtShell& rSh = pView->GetWrtShell();
             SwMergeDescriptor aMergeDesc(DBMGR_MERGE, rSh, aDescriptor);
-            rSh.GetDBManager()->MergeNew(aMergeDesc);
+            rSh.GetDBManager()->Merge(aMergeDesc);
 
             // update enabled / disabled status of the buttons in the toolbar
             SfxBindings& rBindings = 
rSh.GetView().GetViewFrame()->GetBindings();
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 4ffe665..8792029 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -419,7 +419,7 @@ static bool lcl_GetColumnCnt(SwDSParam* pParam, const 
OUString& rColumnName,
 };
 
 // import data
-bool SwDBManager::MergeNew( const SwMergeDescriptor& rMergeDesc, vcl::Window* 
pParent )
+bool SwDBManager::Merge( const SwMergeDescriptor& rMergeDesc, vcl::Window* 
pParent )
 {
     assert( !bInMerge && !pImpl->pMergeData && "merge already activated!" );
 
@@ -2856,7 +2856,7 @@ void SwDBManager::ExecuteFormLetter( SwWrtShell& rSh,
                         aMergeDesc.sDBcolumn = 
pImpl->pMergeDialog->GetColumnName();
                     }
 
-                    MergeNew( aMergeDesc );
+                    Merge( aMergeDesc );
                 }
             }
         }
diff --git a/sw/source/uibase/shells/textsh2.cxx 
b/sw/source/uibase/shells/textsh2.cxx
index 6d2ccb2..33f2b87 100644
--- a/sw/source/uibase/shells/textsh2.cxx
+++ b/sw/source/uibase/shells/textsh2.cxx
@@ -178,7 +178,7 @@ void SwTextShell::ExecDB(SfxRequest &rReq)
                 aDescriptor[daCommandType]  <<= nCommandTypeArg;
 
                 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), 
aDescriptor );
-                pDBManager->MergeNew(aMergeDesc);
+                pDBManager->Merge(aMergeDesc);
 
                 if ( bDisposeResultSet )
                     ::comphelper::disposeComponent(xCursor);
diff --git a/sw/source/uibase/uno/unodispatch.cxx 
b/sw/source/uibase/uno/unodispatch.cxx
index 534aea5..ee9ac7c 100644
--- a/sw/source/uibase/uno/unodispatch.cxx
+++ b/sw/source/uibase/uno/unodispatch.cxx
@@ -219,7 +219,7 @@ void SwXDispatch::dispatch(const util::URL& aURL,
     {
         svx::ODataAccessDescriptor aDescriptor(aArgs);
         SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
-        pDBManager->MergeNew(aMergeDesc);
+        pDBManager->Merge(aMergeDesc);
     }
     else if(aURL.Complete.equalsAscii(cURLInsertColumns))
     {
diff --git a/sw/source/uibase/uno/unomailmerge.cxx 
b/sw/source/uibase/uno/unomailmerge.cxx
index d5b9d97..d29be10 100644
--- a/sw/source/uibase/uno/unomailmerge.cxx
+++ b/sw/source/uibase/uno/unomailmerge.cxx
@@ -547,7 +547,7 @@ uno::Any SAL_CALL SwXMailMerge::execute(
             throw IllegalArgumentException("Property type mismatch or property 
not set: " + rName, static_cast < cppu::OWeakObject * > ( this ), 0 );
     }
 
-    // need to translate the selection: the API here requires a sequence of 
bookmarks, but the MergeNew
+    // need to translate the selection: the API here requires a sequence of 
bookmarks, but the Merge
     // method we will call below requires a sequence of indices.
     if ( aCurSelection.getLength() )
     {
@@ -800,7 +800,7 @@ uno::Any SAL_CALL SwXMailMerge::execute(
     pMgr->SetMailMergeEvtSrc( this );   // launch events for listeners
 
     SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, 
SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xCurDocSh));
-    bool bSucc = pMgr->MergeNew( aMergeDesc );
+    bool bSucc = pMgr->Merge( aMergeDesc );
     SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, 
SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), xCurDocSh));
 
     pMgr->SetMailMergeEvtSrc( pOldSrc );
commit cb4a6fd3152224fcfc960d4b5dead89b050882dd
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Jan 27 13:04:04 2016 +0100

    MM: don't try to save the source MM document
    
    Just create in internal copy, if the source document is modified.
    
    Change-Id: I4587b3df5ff0b42c98f1b69fe18b4f11f5c9b8e4

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 36b6d3c..4ffe665 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -167,6 +167,13 @@ const sal_Char cActiveConnection[] = "ActiveConnection";
 enum class SwDBNextRecord { NEXT, FIRST };
 static bool lcl_ToNextRecord( SwDSParam* pParam, const SwDBNextRecord action = 
SwDBNextRecord::NEXT );
 
+enum class WorkingDocType { SOURCE, TARGET, COPY };
+static SfxObjectShell* lcl_CreateWorkingDocument(
+    const WorkingDocType aType, const SwWrtShell &rSourceWrtShell,
+    const vcl::Window *pSourceWindow,
+    SwDBManager** const pDBManager,
+    SwView** const pView, SwWrtShell** const pWrtShell, SwDoc** const pDoc );
+
 static bool lcl_getCountFromResultSet( sal_Int32& rCount, const 
uno::Reference<sdbc::XResultSet>& xResultSet )
 {
     uno::Reference<beans::XPropertySet> xPrSet(xResultSet, uno::UNO_QUERY);
@@ -416,6 +423,35 @@ bool SwDBManager::MergeNew( const SwMergeDescriptor& 
rMergeDesc, vcl::Window* pP
 {
     assert( !bInMerge && !pImpl->pMergeData && "merge already activated!" );
 
+    SfxObjectShellLock  xWorkObjSh;
+    SwWrtShell         *pWorkShell            = nullptr;
+    SwDoc              *pWorkDoc              = nullptr;
+    SwDBManager        *pWorkDocOrigDBManager = nullptr;
+
+    switch( rMergeDesc.nMergeType )
+    {
+        case DBMGR_MERGE_PRINTER:
+        case DBMGR_MERGE_EMAIL:
+        case DBMGR_MERGE_FILE:
+        case DBMGR_MERGE_SHELL:
+        {
+            SwDocShell *pSourceDocSh = rMergeDesc.rSh.GetView().GetDocShell();
+            if( pSourceDocSh->IsModified() )
+            {
+                pWorkDocOrigDBManager = this;
+                xWorkObjSh = lcl_CreateWorkingDocument(
+                    WorkingDocType::SOURCE, rMergeDesc.rSh, nullptr,
+                    &pWorkDocOrigDBManager, nullptr, &pWorkShell, &pWorkDoc );
+            }
+            // fall through
+        }
+
+        default:
+            if( !xWorkObjSh.Is() )
+                pWorkShell = &rMergeDesc.rSh;
+            break;
+    }
+
     SwDBData aData;
     aData.nCommandType = sdb::CommandType::TABLE;
     uno::Reference<sdbc::XResultSet>  xResSet;
@@ -477,7 +513,7 @@ bool SwDBManager::MergeNew( const SwMergeDescriptor& 
rMergeDesc, vcl::Window* pP
 
     lcl_InitNumberFormatter(*pImpl->pMergeData, xSource);
 
-    rMergeDesc.rSh.ChgDBData(aData);
+    pWorkShell->ChgDBData(aData);
     bInMerge = true;
 
     if (IsInitDBFields())
@@ -485,13 +521,13 @@ bool SwDBManager::MergeNew( const SwMergeDescriptor& 
rMergeDesc, vcl::Window* pP
         // with database fields without DB-Name, use DB-Name from Doc
         std::vector<OUString> aDBNames;
         aDBNames.push_back(OUString());
-        SwDBData aInsertData = rMergeDesc.rSh.GetDBData();
+        SwDBData aInsertData = pWorkShell->GetDBData();
         OUString sDBName = aInsertData.sDataSource;
         sDBName += OUString(DB_DELIM);
         sDBName += aInsertData.sCommand;
         sDBName += OUString(DB_DELIM);
         sDBName += OUString::number(aInsertData.nCommandType);
-        rMergeDesc.rSh.ChangeDBFields( aDBNames, sDBName);
+        pWorkShell->ChangeDBFields( aDBNames, sDBName);
         SetInitDBFields(false);
     }
 
@@ -499,10 +535,10 @@ bool SwDBManager::MergeNew( const SwMergeDescriptor& 
rMergeDesc, vcl::Window* pP
     switch(rMergeDesc.nMergeType)
     {
         case DBMGR_MERGE:
-            rMergeDesc.rSh.StartAllAction();
-            rMergeDesc.rSh.SwViewShell::UpdateFields( true );
-            rMergeDesc.rSh.SetModified();
-            rMergeDesc.rSh.EndAllAction();
+            pWorkShell->StartAllAction();
+            pWorkShell->SwViewShell::UpdateFields( true );
+            pWorkShell->SetModified();
+            pWorkShell->EndAllAction();
             break;
 
         case DBMGR_MERGE_PRINTER:
@@ -510,18 +546,24 @@ bool SwDBManager::MergeNew( const SwMergeDescriptor& 
rMergeDesc, vcl::Window* pP
         case DBMGR_MERGE_FILE:
         case DBMGR_MERGE_SHELL:
             // save files and send them as e-Mail if required
-            bRet = MergeMailFiles(&rMergeDesc.rSh, rMergeDesc, pParent);
+            bRet = MergeMailFiles(pWorkShell, rMergeDesc, pParent);
             break;
 
         default:
             // insert selected entries
             // (was: InsertRecord)
-            ImportFromConnection(&rMergeDesc.rSh);
+            ImportFromConnection(pWorkShell);
             break;
     }
 
     DELETEZ( pImpl->pMergeData );
 
+    if( xWorkObjSh.Is() )
+    {
+        pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
+        xWorkObjSh->DoClose();
+    }
+
     bInMerge = false;
 
     return bRet;
@@ -904,8 +946,6 @@ static void lcl_PreparePrinterOptions(
     }
 }
 
-enum class WorkingDocType { SOURCE, TARGET, COPY };
-
 static SfxObjectShell* lcl_CreateWorkingDocument(
     // input
     const WorkingDocType aType, const SwWrtShell &rSourceWrtShell,
@@ -1107,21 +1147,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* 
pSourceShell,
             }
         }
 
-        SwDocShell* pSourceDocSh = pSourceShell->GetView().GetDocShell();
-
-        uno::Reference<document::XDocumentProperties> xSourceDocProps;
-        {
-            uno::Reference<document::XDocumentPropertiesSupplier>
-                xDPS(pSourceDocSh->GetModel(), uno::UNO_QUERY);
-            xSourceDocProps.set(xDPS->getDocumentProperties());
-            assert( xSourceDocProps.is() && "DocumentProperties is null" );
-        }
+        SwDocShell  *pSourceDocSh = pSourceShell->GetView().GetDocShell();
 
-        // Try saving the source document
-        SfxDispatcher* pSfxDispatcher = 
pSourceShell->GetView().GetViewFrame()->GetDispatcher();
-        if( !bMT_SHELL && pSourceDocSh->IsModified() )
-            pSfxDispatcher->Execute( pSourceDocSh->HasName() ? SID_SAVEDOC : 
SID_SAVEASDOC, SfxCallMode::SYNCHRON|SfxCallMode::RECORD);
-        if( bMT_SHELL || !pSourceDocSh->IsModified() )
         {
             // setup the output format
             std::shared_ptr<const SfxFilter> pStoreToFilter = 
SwIoSystem::GetFileFilter(
@@ -2819,15 +2846,8 @@ void SwDBManager::ExecuteFormLetter( SwWrtShell& rSh,
         {
             {
                 {
-                    SwWrtShell  *pWorkShell;
-                    SwDoc       *pWorkDoc;
-                    SwDBManager *pWorkDocOrigDBManager = this;
-                    SfxObjectShellLock xWorkDocSh = lcl_CreateWorkingDocument(
-                        WorkingDocType::SOURCE, rSh, nullptr,
-                        &pWorkDocOrigDBManager, nullptr, &pWorkShell, 
&pWorkDoc );
-
                     // prepare mail merge descriptor
-                    SwMergeDescriptor aMergeDesc( 
pImpl->pMergeDialog->GetMergeType(), *pWorkShell, aDescriptor );
+                    SwMergeDescriptor aMergeDesc( 
pImpl->pMergeDialog->GetMergeType(), rSh, aDescriptor );
                     aMergeDesc.sSaveToFilter = 
pImpl->pMergeDialog->GetSaveFilter();
                     aMergeDesc.bCreateSingleFile = 
pImpl->pMergeDialog->IsSaveSingleDoc();
                     aMergeDesc.sPath = pImpl->pMergeDialog->GetTargetURL();
@@ -2837,9 +2857,6 @@ void SwDBManager::ExecuteFormLetter( SwWrtShell& rSh,
                     }
 
                     MergeNew( aMergeDesc );
-
-                    pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
-                    xWorkDocSh->DoClose();
                 }
             }
         }
commit 8bba8961f646842ffd783cf11c67c91ac209b62e
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Jan 27 11:51:29 2016 +0100

    MM: just show the print progress dialog for print
    
    Change-Id: I75a33c14f4a2b5ab404ce937e5d23392f6021a1b

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index f41ed21..36b6d3c 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1167,9 +1167,9 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             {
                 // construct the process dialog
                 pSourceWindow = &pSourceShell->GetView().GetEditWin();
-                if( ! pParent )
+                if( !pParent )
                     pParent = pSourceWindow;
-                if( bMT_SHELL )
+                if( !bMT_PRINTER )
                     pProgressDlg = VclPtr<CreateMonitor>::Create(
                         pParent, pParent != pSourceWindow );
                 else {
@@ -1226,7 +1226,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             // it can be manually computed from the source documents (for 
which we do layouts, so the page
             // count is known, and there is a blank page between each of them 
in the target document).
             int targetDocPageCount = 0;
-            if( !bIsMergeSilent && bMT_SHELL &&
+            if( !bIsMergeSilent && !bMT_PRINTER &&
                     lcl_getCountFromResultSet( nDocCount, 
pImpl->pMergeData->xResultSet ) )
                 static_cast<CreateMonitor*>( pProgressDlg.get() 
)->SetTotalCount( nDocCount );
 
@@ -1292,7 +1292,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                         if( bNeedsTempFiles )
                             aTempFileURL.reset( new 
INetURLObject(aTempFile->GetURL()));
                         if( !bIsMergeSilent ) {
-                            if( bMT_SHELL )
+                            if( !bMT_PRINTER )
                                 static_cast<CreateMonitor*>( 
pProgressDlg.get() )->SetCurrentPosition( nDocNo );
                             else {
                                 PrintMonitor *pPrintMonDlg = 
static_cast<PrintMonitor*>( pProgressDlg.get() );
commit c02280ebe93b63925469b2df8eee68cde355feea
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Jan 27 11:48:28 2016 +0100

    MM: fix silent mode on merge start
    
    We currently don't handle the change of silent mode during a running
    mail merge job correctly, so don't allow it.
    
    Change-Id: I2cb8cc1c737e93e8b2a90a6e73fb3e49008fe91d

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 3ae101a..f41ed21 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1038,6 +1038,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
     //check if the doc is synchronized and contains at least one linked section
     const bool bSynchronizedDoc = pSourceShell->IsLabelDoc() && 
pSourceShell->GetSectionFormatCount() > 1;
     const bool bNeedsTempFiles = ( bMT_EMAIL || bMT_FILE );
+    const bool bIsMergeSilent = IsMergeSilent();
 
     bool bCheckSingleFile_ = rMergeDescriptor.bCreateSingleFile;
     if( bMT_EMAIL )
@@ -1162,7 +1163,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             vcl::Window *pSourceWindow = nullptr;
             VclPtr<CancelableDialog> pProgressDlg;
 
-            if( !IsMergeSilent() )
+            if( !bIsMergeSilent )
             {
                 // construct the process dialog
                 pSourceWindow = &pSourceShell->GetView().GetEditWin();
@@ -1225,7 +1226,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             // it can be manually computed from the source documents (for 
which we do layouts, so the page
             // count is known, and there is a blank page between each of them 
in the target document).
             int targetDocPageCount = 0;
-            if( !IsMergeSilent() && bMT_SHELL &&
+            if( !bIsMergeSilent && bMT_SHELL &&
                     lcl_getCountFromResultSet( nDocCount, 
pImpl->pMergeData->xResultSet ) )
                 static_cast<CreateMonitor*>( pProgressDlg.get() 
)->SetTotalCount( nDocCount );
 
@@ -1290,7 +1291,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                         std::unique_ptr< INetURLObject > aTempFileURL;
                         if( bNeedsTempFiles )
                             aTempFileURL.reset( new 
INetURLObject(aTempFile->GetURL()));
-                        if (!IsMergeSilent()) {
+                        if( !bIsMergeSilent ) {
                             if( bMT_SHELL )
                                 static_cast<CreateMonitor*>( 
pProgressDlg.get() )->SetCurrentPosition( nDocNo );
                             else {
@@ -1394,7 +1395,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                                 uno::Sequence< beans::PropertyValue > 
aOptions( rMergeDescriptor.aPrintOptions );
                                 lcl_PreparePrinterOptions( 
rMergeDescriptor.aPrintOptions, false, aOptions );
 
-                                pWorkView->StartPrint( aOptions, 
IsMergeSilent(), rMergeDescriptor.bPrintAsync );
+                                pWorkView->StartPrint( aOptions, 
bIsMergeSilent, rMergeDescriptor.bPrintAsync );
                                 // some GetPrinter functions have a true 
default, so keep the false
                                 SfxPrinter* pDocPrt = pWorkView->GetPrinter( 
false );
                                 JobSetup aJobSetup = pDocPrt ? 
pDocPrt->GetJobSetup() : pWorkView->GetJobSetup();
@@ -1533,7 +1534,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                     // print the target document
                     uno::Sequence< beans::PropertyValue > aOptions( 
rMergeDescriptor.aPrintOptions );
                     lcl_PreparePrinterOptions( rMergeDescriptor.aPrintOptions, 
true, aOptions );
-                    pTargetView->ExecPrint( aOptions, IsMergeSilent(), 
rMergeDescriptor.bPrintAsync );
+                    pTargetView->ExecPrint( aOptions, bIsMergeSilent, 
rMergeDescriptor.bPrintAsync );
                 }
 
                 if( IsMergeOk() && bMT_SHELL )
commit 05dcf08cbd536f6c7fb716535772987d859d3cfb
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Jan 27 11:42:45 2016 +0100

    MM: move mail creation into a local function
    
    And also use C++11 range-based for loop loops.
    
    Change-Id: I7bafc419a21cdd6bb7aaed7d67b640409d308f79

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index fe866e5..3ae101a 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -966,6 +966,60 @@ static SfxObjectShell* lcl_CreateWorkingDocument(
     return xWorkObjectShell;
 }
 
+uno::Reference< mail::XMailMessage > lcl_CreateMailFromDoc(
+    const SwMergeDescriptor &rMergeDescriptor,
+    const OUString &sFileURL, const OUString &sMailRecipient,
+    const OUString &sMailBodyMimeType, const rtl_TextEncoding &sMailEncoding,
+    const OUString &sAttachmentMimeType )
+{
+    SwMailMessage* pMessage = new SwMailMessage;
+    uno::Reference< mail::XMailMessage > xMessage = pMessage;
+    if( rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo() )
+        
pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo());
+    pMessage->addRecipient( sMailRecipient );
+    pMessage->SetSenderAddress( 
rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() );
+
+    OUString sBody;
+    if( rMergeDescriptor.bSendAsAttachment )
+    {
+        sBody = rMergeDescriptor.sMailBody;
+        mail::MailAttachment aAttach;
+        aAttach.Data = new SwMailTransferable( sFileURL,
+            rMergeDescriptor.sAttachmentName, sAttachmentMimeType );
+        aAttach.ReadableName = rMergeDescriptor.sAttachmentName;
+        pMessage->addAttachment( aAttach );
+    }
+    else
+    {
+        //read in the temporary file and use it as mail body
+        SfxMedium aMedium( sFileURL, StreamMode::READ );
+        SvStream* pInStream = aMedium.GetInStream();
+        assert( pInStream && "no output file created?" );
+        if( pInStream )
+            return xMessage;
+
+        pInStream->SetStreamCharSet( sMailEncoding );
+        OString sLine;
+        while ( pInStream->ReadLine( sLine ) )
+        {
+            sBody += OStringToOUString( sLine, sMailEncoding );
+            sBody += "\n";
+        }
+    }
+    pMessage->setSubject( rMergeDescriptor.sSubject );
+    uno::Reference< datatransfer::XTransferable> xBody =
+                new SwMailTransferable( sBody, sMailBodyMimeType );
+    pMessage->setBody( xBody );
+
+    for( const OUString& sCcRecipient : rMergeDescriptor.aCopiesTo )
+        pMessage->addCcRecipient( sCcRecipient );
+    for( const OUString& sBccRecipient : rMergeDescriptor.aBlindCopiesTo )
+        pMessage->addBccRecipient( sBccRecipient );
+
+    xMessage = pMessage;
+    return xMessage;
+}
+
 /**
  * Please have a look at the README in the same directory, before you make
  * larger changes in this function!
@@ -1375,75 +1429,24 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* 
pSourceShell,
 
                             if( bMT_EMAIL && !IsMergeError() )
                             {
+                                // schedule file for later removal
+                                aFilesToRemove.push_back( sFileURL );
+
                                 if( !SwMailMergeHelper::CheckMailAddress( 
sColumnData ) )
                                 {
                                     OSL_FAIL("invalid e-Mail address in 
database column");
                                 }
                                 else
                                 {
-                                    SwMailMessage* pMessage = new 
SwMailMessage;
-                                    uno::Reference< mail::XMailMessage > 
xMessage = pMessage;
-                                    
if(rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo())
-                                        
pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo());
-                                    pMessage->addRecipient( sColumnData );
-                                    pMessage->SetSenderAddress( 
rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() );
-                                    OUString sBody;
-
-                                    if(rMergeDescriptor.bSendAsAttachment)
-                                    {
-                                        sBody = rMergeDescriptor.sMailBody;
-                                        mail::MailAttachment aAttach;
-                                        aAttach.Data = new SwMailTransferable(
-                                                sFileURL,
-                                                
rMergeDescriptor.sAttachmentName,
-                                                pStoreToFilter->GetMimeType());
-                                        aAttach.ReadableName = 
rMergeDescriptor.sAttachmentName;
-                                        pMessage->addAttachment( aAttach );
-                                    }
-                                    else
-                                    {
-                                        {
-                                            //read in the temporary file and 
use it as mail body
-                                            SfxMedium aMedium( sFileURL, 
StreamMode::READ);
-                                            SvStream* pInStream = 
aMedium.GetInStream();
-                                            assert( pInStream && "no output 
file created?" );
-                                            if(pInStream)
-                                            {
-                                                pInStream->SetStreamCharSet( 
sMailEncoding );
-                                                OString sLine;
-                                                bool bDone = 
pInStream->ReadLine( sLine );
-                                                while ( bDone )
-                                                {
-                                                    sBody += 
OStringToOUString( sLine, sMailEncoding );
-                                                    sBody += "\n";
-                                                    bDone = 
pInStream->ReadLine( sLine );
-                                                }
-                                            }
-                                        }
-                                    }
-                                    pMessage->setSubject( 
rMergeDescriptor.sSubject );
-                                    uno::Reference< 
datatransfer::XTransferable> xBody =
-                                                new SwMailTransferable(
-                                                    sBody, sMailBodyMimeType);
-                                    pMessage->setBody( xBody );
-
-                                    if(rMergeDescriptor.aCopiesTo.getLength())
-                                    {
-                                        const OUString* pCopies = 
rMergeDescriptor.aCopiesTo.getConstArray();
-                                        for( sal_Int32 nToken = 0; nToken < 
rMergeDescriptor.aCopiesTo.getLength(); ++nToken)
-                                            pMessage->addCcRecipient( 
pCopies[nToken] );
-                                    }
-                                    
if(rMergeDescriptor.aBlindCopiesTo.getLength())
+                                    uno::Reference< mail::XMailMessage > 
xMessage = lcl_CreateMailFromDoc(
+                                        rMergeDescriptor, sFileURL, 
sColumnData, sMailBodyMimeType,
+                                        sMailEncoding, 
pStoreToFilter->GetMimeType() );
+                                    if( xMessage.is() )
                                     {
-                                        const OUString* pCopies = 
rMergeDescriptor.aBlindCopiesTo.getConstArray();
-                                        for( sal_Int32 nToken = 0; nToken < 
rMergeDescriptor.aBlindCopiesTo.getLength(); ++nToken)
-                                            pMessage->addBccRecipient( 
pCopies[nToken] );
+                                        xMailDispatcher->enqueueMailMessage( 
xMessage );
+                                        if( !xMailDispatcher->isStarted() )
+                                            xMailDispatcher->start();
                                     }
-                                    xMailDispatcher->enqueueMailMessage( 
xMessage );
-                                    if(!xMailDispatcher->isStarted())
-                                        xMailDispatcher->start();
-                                    //schedule for removal
-                                    aFilesToRemove.push_back(sFileURL);
                                 }
                             }
                         }
commit 4ae74a8139579f9d0dc2c5e9acbd419f20afcea2
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Jan 25 19:36:26 2016 +0100

    MM: don't register files in recently used...
    
    ... in email and !bCreateSingleFile file mode. Also saves a bunch
    of instructions. For my simple document it was ~10% of the save
    time and 75% is the creation of the preview thumbnails...
    
    Change-Id: I14f7092007b1acfed6cbe0f2f4cd6eaecd32b514

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index df1348a..fe866e5 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -856,7 +856,11 @@ static bool lcl_SaveDoc(
         rWorkShell.ConvertFieldsToText();
 
     bool bAnyError = !xObjectShell->DoSaveAs(*pDstMed);
-    xObjectShell->DoSaveCompleted(pDstMed);
+
+    // Actually this should be a bool... so in case of email and individual
+    // files, where this is set, we skip the the recently used handling
+    if( !decodedURL )
+        xObjectShell->DoSaveCompleted( pDstMed );
     bAnyError = bAnyError || xObjectShell->GetError();
     if( bAnyError )
     {
commit e32440f5867670106c0d6d95901e55fbf92c5f66
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Jan 25 18:10:29 2016 +0100

    MM: use working doc DB manager on save
    
    This is related to tdf#97318 but doesn't fix it, as the wizard
    works with a single merged document, which is split later.
    
    When saving the working document in !bCreateSingleFile mode, we
    have to restore the documents DB manager for two reasons:
    
    1. We otherwise would save the whole database content.
    2. We crash with embedded databases of the original DB manager.
    
    Change-Id: I9b209854703ec95c2c63c83019e857f2d26f753d

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 6e217df..df1348a 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1351,6 +1351,12 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* 
pSourceShell,
                         else
                         {
                             assert( bNeedsTempFiles );
+                            assert( pWorkShell->IsExpFieldsLocked() );
+
+                            // fields are locked, so it's fine to
+                            // restore the old / empty DB manager for save
+                            pWorkDoc->SetDBManager( pWorkDocOrigDBManager );
+
                             // save merged document
                             OUString sFileURL;
                             if( !lcl_SaveDoc( aTempFileURL.get(), 
pStoreToFilter, pStoreToFilterOptions,
@@ -1359,6 +1365,10 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* 
pSourceShell,
                             {
                                 m_aMergeStatus = MergeStatus::ERROR;
                             }
+
+                            // back to the MM DB manager
+                            pWorkDoc->SetDBManager( this );
+
                             if( bMT_EMAIL && !IsMergeError() )
                             {
                                 if( !SwMailMergeHelper::CheckMailAddress( 
sColumnData ) )
commit a3b2bc98309c6f3da107f19f48450d01962e5077
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Jan 25 17:48:15 2016 +0100

    MM: correctly handle directory in dialog
    
    For convenience we present file URLs in the systems local file
    notation. But the directory selection dialog expects an URL, so
    we have to convert the local notation from the edit entry to a
    file URL.
    
    Change-Id: Idff6f7d4b135eef087c61560b0603b9a6669dbf7

diff --git a/include/unotools/pathoptions.hxx b/include/unotools/pathoptions.hxx
index 1b311ec..2784f8c 100644
--- a/include/unotools/pathoptions.hxx
+++ b/include/unotools/pathoptions.hxx
@@ -25,9 +25,12 @@
 
 #define SVT_SEARCHPATH_DELIMITER      ';'
 
-// class SvtPathOptions --------------------------------------------------
-
 class SvtPathOptions_Impl;
+
+/*! Handle various defined paths
+
+  All path functions return URLs!
+*/
 class SAL_WARN_UNUSED UNOTOOLS_DLLPUBLIC SvtPathOptions : public 
utl::detail::Options
 {
 private:
diff --git a/sw/source/ui/envelp/mailmrge.cxx b/sw/source/ui/envelp/mailmrge.cxx
index 184053a..f1623bc 100644
--- a/sw/source/ui/envelp/mailmrge.cxx
+++ b/sw/source/ui/envelp/mailmrge.cxx
@@ -491,24 +491,32 @@ bool SwMailMergeDlg::AskUserFilename() const
     return (m_pSaveSingleDocRB->IsChecked() || 
!m_pGenerateFromDataBaseCB->IsChecked());
 }
 
+OUString SwMailMergeDlg::GetURLfromPath() const
+{
+    SfxMedium* pMedium = rSh.GetView().GetDocShell()->GetMedium();
+    INetURLObject aAbs;
+    if( pMedium )
+        aAbs = pMedium->GetURLObject();
+    if( INetProtocol::NotValid == aAbs.GetProtocol() )
+    {
+        SvtPathOptions aPathOpt;
+        aAbs.SetURL( aPathOpt.GetWorkPath() );
+    }
+    return URIHelper::SmartRel2Abs(
+        aAbs, m_pPathED->GetText(), URIHelper::GetMaybeFileHdl());
+}
+
 bool SwMailMergeDlg::ExecQryShell()
 {
     if(pImpl->xSelSupp.is()) {
-        pImpl->xSelSupp->removeSelectionChangeListener(  pImpl->xChgLstnr );
+        pImpl->xSelSupp->removeSelectionChangeListener( pImpl->xChgLstnr );
     }
 
     if (m_pPrinterRB->IsChecked())
         nMergeType = DBMGR_MERGE_PRINTER;
     else {
         nMergeType = DBMGR_MERGE_FILE;
-        SfxMedium* pMedium = rSh.GetView().GetDocShell()->GetMedium();
-        INetURLObject aAbs;
-        if( pMedium )
-            aAbs = pMedium->GetURLObject();
-        pModOpt->SetMailingPath(
-            URIHelper::SmartRel2Abs(
-                aAbs, m_pPathED->GetText(), URIHelper::GetMaybeFileHdl()));
-
+        pModOpt->SetMailingPath( GetURLfromPath() );
         pModOpt->SetIsNameFromColumn(m_pGenerateFromDataBaseCB->IsChecked());
 
         if (!AskUserFilename()) {
@@ -593,15 +601,9 @@ OUString SwMailMergeDlg::GetTargetURL() const
 
 IMPL_LINK_NOARG_TYPED(SwMailMergeDlg, InsertPathHdl, Button*, void)
 {
-    OUString sPath( m_pPathED->GetText() );
-    if( sPath.isEmpty() ) {
-        SvtPathOptions aPathOpt;
-        sPath = aPathOpt.GetWorkPath();
-    }
-
     uno::Reference< XComponentContext > xContext( 
::comphelper::getProcessComponentContext() );
     uno::Reference < XFolderPicker2 > xFP = FolderPicker::create(xContext);
-    xFP->setDisplayDirectory(sPath);
+    xFP->setDisplayDirectory( GetURLfromPath() );
     if( xFP->execute() == RET_OK ) {
         INetURLObject aURL(xFP->getDirectory());
         if(aURL.GetProtocol() == INetProtocol::File)
diff --git a/sw/source/uibase/inc/mailmrge.hxx 
b/sw/source/uibase/inc/mailmrge.hxx
index cc30e6c..59b8cc4 100644
--- a/sw/source/uibase/inc/mailmrge.hxx
+++ b/sw/source/uibase/inc/mailmrge.hxx
@@ -115,6 +115,7 @@ class SwMailMergeDlg : public SvxStandardDialog
     virtual void    Apply() override;
     bool            ExecQryShell();
     bool            AskUserFilename() const;
+    OUString        GetURLfromPath() const;
 
 public:
     SwMailMergeDlg(vcl::Window* pParent, SwWrtShell& rSh,
commit 6f3e26104d670ea080fcebaa9870bb99478a0c51
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Fri Jan 22 21:25:11 2016 +0100

    tdf#96914 MM: don't round trip the source document
    
    To get a unmodified document, the mail merge via File -> Print
    used to write a document and reload it. This is not a problem with
    normal documents, but with embedded databases this results in a
    second database with the same name, which disposes the first
    registered database and the xResultSet from the mail merge dialog.
    
    As a workaround this just creates an internal copy, sets the
    correct database settings and resets the modified status.
    
    We still need a more general solution to handle documents with the
    same embedded DB name in a sane way, probably by making the embedded
    database a private object of the documents database manager.
    
    We also need to keep the IsLabelDoc information, otherwise
    cloning label documents breaks MM due to undetected, existing
    section links. This is currently handled MM internal when creating
    a document clone, but probably a reset function for the rest of the
    document settings should be created and used.
    
    Change-Id: I20ddea30196d65cb89f69977867f012816ec6001

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 11d00389b..7c3cfc9 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1622,7 +1622,7 @@ public:
     ::sw::UndoManager      & GetUndoManager();
     ::sw::UndoManager const& GetUndoManager() const;
 
-    SfxObjectShell* CreateCopy(bool bCallInitNew) const;
+    SfxObjectShell* CreateCopy(bool bCallInitNew, bool bEmpty) const;
     SwNodeIndex AppendDoc(const SwDoc& rSource, sal_uInt16 nStartPageNumber,
                  bool bDeletePrevious = false, int physicalPageOffset = 0,
                  const sal_uLong nDocNo = 1);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 0975ad5..1dcea33 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -868,7 +868,7 @@ void SwDoc::ReplaceCompatibilityOptions(const SwDoc& 
rSource)
     ((idx).GetNode().GetIndex() - GetNodes().GetEndOfExtras().GetIndex() - 1)
 #endif
 
-SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
+SfxObjectShell* SwDoc::CreateCopy( bool bCallInitNew, bool bEmpty ) const
 {
     SwDoc* pRet = new SwDoc;
 
@@ -891,14 +891,17 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) 
const
 
     pRet->ReplaceStyles(*this);
 
+    if( !bEmpty )
+    {
 #ifdef DBG_UTIL
-    SAL_INFO( "sw.createcopy", "CC-Nd-Src: " << CNTNT_DOC( this ) );
-    SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
+        SAL_INFO( "sw.createcopy", "CC-Nd-Src: " << CNTNT_DOC( this ) );
+        SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
 #endif
-    pRet->AppendDoc(*this, 0, bCallInitNew, 0, 0);
+        pRet->AppendDoc(*this, 0, bCallInitNew, 0, 0);
 #ifdef DBG_UTIL
-    SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
+        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( nullptr );
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index ab46a5e..6e217df 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -41,7 +41,6 @@
 #include <com/sun/star/ui/dialogs/XFilePicker2.hpp>
 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
 #include <com/sun/star/uno/XNamingService.hpp>
-#include <com/sun/star/util/XCloseable.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <sfx2/fcontnr.hxx>
 #include <sfx2/filedlghelper.hxx>
@@ -135,6 +134,7 @@
 #include <ndtxt.hxx>
 #include <calc.hxx>
 #include <dbfld.hxx>
+#include <IDocumentState.hxx>
 
 #include <memory>
 #include <comphelper/propertysequence.hxx>
@@ -900,6 +900,68 @@ static void lcl_PreparePrinterOptions(
     }
 }
 
+enum class WorkingDocType { SOURCE, TARGET, COPY };
+
+static SfxObjectShell* lcl_CreateWorkingDocument(
+    // input
+    const WorkingDocType aType, const SwWrtShell &rSourceWrtShell,
+    // optional input
+    const vcl::Window *pSourceWindow,
+    // optional in and output to swap the DB manager
+    SwDBManager** const pDBManager,
+    // optional output
+    SwView** const pView, SwWrtShell** const pWrtShell, SwDoc** const pDoc )
+{
+    const SwDoc *pSourceDoc = rSourceWrtShell.GetDoc();
+    SfxObjectShellRef xWorkObjectShell = pSourceDoc->CreateCopy( true, (aType 
== WorkingDocType::TARGET) );
+    SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( 
*xWorkObjectShell, 0 );
+
+    if( pSourceWindow )
+    {
+        // the created window has to be located at the same position as the 
source window
+        vcl::Window& rTargetWindow = pWorkFrame->GetFrame().GetWindow();
+        rTargetWindow.SetPosPixel( pSourceWindow->GetPosPixel() );
+    }
+
+    SwView* pWorkView = static_cast< SwView* >( pWorkFrame->GetViewShell() );
+    SwWrtShell* pWorkWrtShell = pWorkView->GetWrtShellPtr();
+    pWorkView->AttrChangedNotify( pWorkWrtShell );// in order for SelectShell 
to be called
+    SwDoc* pWorkDoc = pWorkWrtShell->GetDoc();
+    pWorkDoc->ReplaceDocumentProperties( *pSourceDoc );
+
+    if( aType == WorkingDocType::TARGET )
+    {
+        assert( !pDBManager );
+        pWorkDoc->SetInMailMerge( true );
+        pWorkWrtShell->SetLabelDoc( false );
+    }
+    else
+    {
+        // We have to swap the DBmanager of the new doc, so we also need input
+        assert( pDBManager && *pDBManager );
+        SwDBManager *pWorkDBManager = pWorkDoc->GetDBManager();
+        pWorkDoc->SetDBManager( *pDBManager );
+        *pDBManager = pWorkDBManager;
+
+        if( aType == WorkingDocType::SOURCE )
+        {
+            // the GetDBData call constructs the data, if it's missing - kind 
of const...
+            pWorkWrtShell->ChgDBData( 
const_cast<SwDoc*>(pSourceDoc)->GetDBData() );
+            // some DocumentSettings are currently not copied by 
SwDoc::CreateCopy
+            pWorkWrtShell->SetLabelDoc( rSourceWrtShell.IsLabelDoc() );
+            pWorkDoc->getIDocumentState().ResetModified();
+        }
+        else
+            pWorkDoc->getIDocumentLinksAdministration().EmbedAllLinks();
+    }
+
+    if( pView )     *pView     = pWorkView;
+    if( pWrtShell ) *pWrtShell = pWorkWrtShell;
+    if( pDoc )      *pDoc      = pWorkDoc;
+
+    return xWorkObjectShell;
+}
+
 /**
  * Please have a look at the README in the same directory, before you make
  * larger changes in this function!
@@ -986,8 +1048,6 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             }
         }
 
-        // Try saving the source document
-        SfxDispatcher* pSfxDispatcher = 
pSourceShell->GetView().GetViewFrame()->GetDispatcher();
         SwDocShell* pSourceDocSh = pSourceShell->GetView().GetDocShell();
 
         uno::Reference<document::XDocumentProperties> xSourceDocProps;
@@ -998,6 +1058,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             assert( xSourceDocProps.is() && "DocumentProperties is null" );
         }
 
+        // Try saving the source document
+        SfxDispatcher* pSfxDispatcher = 
pSourceShell->GetView().GetViewFrame()->GetDispatcher();
         if( !bMT_SHELL && pSourceDocSh->IsModified() )
             pSfxDispatcher->Execute( pSourceDocSh->HasName() ? SID_SAVEDOC : 
SID_SAVEASDOC, SfxCallMode::SYNCHRON|SfxCallMode::RECORD);
         if( bMT_SHELL || !pSourceDocSh->IsModified() )
@@ -1066,36 +1128,11 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* 
pSourceShell,
 
             if( bCreateSingleFile && !pTargetView )
             {
-                // create a target docshell to put the merged document into
-                xTargetDocShell = new SwDocShell( 
SfxObjectCreateMode::STANDARD );
-                xTargetDocShell->DoInitNew( );
+                xTargetDocShell = lcl_CreateWorkingDocument( 
WorkingDocType::TARGET,
+                    *pSourceShell, bMT_SHELL ? pSourceWindow : nullptr,
+                    nullptr, &pTargetView, &pTargetShell, &pTargetDoc );
                 if (nMaxDumpDocs)
                     lcl_SaveDebugDoc( xTargetDocShell, "MergeDoc" );
-                SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( 
*xTargetDocShell, 0 );
-                if (bMT_SHELL && pSourceWindow)
-                {
-                    //the created window has to be located at the same 
position as the source window
-                    vcl::Window& rTargetWindow = 
pTargetFrame->GetFrame().GetWindow();
-                    rTargetWindow.SetPosPixel(pSourceWindow->GetPosPixel());
-                }
-
-                pTargetView = 
static_cast<SwView*>(pTargetFrame->GetViewShell());
-
-                //initiate SelectShell() to create sub shells
-                pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
-                pTargetShell = pTargetView->GetWrtShellPtr();
-                pTargetDoc = pTargetShell->GetDoc();
-                pTargetDoc->SetInMailMerge(true);
-
-                //copy the styles from the source to the target document
-                pTargetView->GetDocShell()->_LoadStyles( *pSourceDocSh, true );
-
-                // copy compatibility options
-                pTargetDoc->ReplaceCompatibilityOptions( 
*pSourceShell->GetDoc());
-                // #72821# copy dynamic defaults
-                pTargetDoc->ReplaceDefaults( *pSourceShell->GetDoc());
-
-                pTargetDoc->ReplaceDocumentProperties( 
*pSourceShell->GetDoc());
             }
             else if( pTargetView )

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to