[Libreoffice-commits] core.git: include/vcl sw/CppunitTest_sw_globalfilter.mk sw/CppunitTest_sw_odfexport.mk sw/CppunitTest_sw_odfimport.mk sw/CppunitTest_sw_ooxmlfieldexport.mk sw/CppunitTest_sw_ooxmlimport.mk sw/CppunitTest_sw_ooxmlw14export.mk sw/CppunitTest_sw_rtfexport.mk sw/CppunitTest_sw_rtfimport.mk sw/CppunitTest_sw_ww8import.mk sw/inc sw/ooxmlexport_setup.mk sw/qa sw/source

Juergen Funk juergen.funk_ml at cib.de
Mon Dec 21 02:35:38 PST 2015


 include/vcl/print.hxx                 |    2 
 sw/CppunitTest_sw_globalfilter.mk     |    1 
 sw/CppunitTest_sw_odfexport.mk        |    1 
 sw/CppunitTest_sw_odfimport.mk        |    1 
 sw/CppunitTest_sw_ooxmlfieldexport.mk |    1 
 sw/CppunitTest_sw_ooxmlimport.mk      |    1 
 sw/CppunitTest_sw_ooxmlw14export.mk   |    1 
 sw/CppunitTest_sw_rtfexport.mk        |    1 
 sw/CppunitTest_sw_rtfimport.mk        |    1 
 sw/CppunitTest_sw_ww8import.mk        |    1 
 sw/inc/dbmgr.hxx                      |   99 +++
 sw/ooxmlexport_setup.mk               |    1 
 sw/qa/extras/inc/swmodeltestbase.hxx  |    2 
 sw/source/uibase/dbui/dbmgr.cxx       |  995 +++++++++++++++++++---------------
 14 files changed, 685 insertions(+), 423 deletions(-)

New commits:
commit d8ff907197037045fd0cb173e341f515968b65b1
Author: Juergen Funk <juergen.funk_ml at cib.de>
Date:   Thu Dec 3 16:04:15 2015 +0100

    tdf93236 N-UP printing in combination with mailmerge broken file-print 1/4
    
    Refactory the methode "MergeMailFiles"
    
    Change-Id: I65441ade522c06335b0da23cb2fed9afc5bcb72e
    Reviewed-on: https://gerrit.libreoffice.org/20714
    Reviewed-by: Katarina Behrens <Katarina.Behrens at cib.de>
    Tested-by: Katarina Behrens <Katarina.Behrens at cib.de>

diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx
index b8f32ff..bb30f8e 100644
--- a/include/vcl/print.hxx
+++ b/include/vcl/print.hxx
@@ -574,7 +574,7 @@ public:
     VCL_PLUGIN_PUBLIC void              createProgressDialog();
     VCL_PLUGIN_PUBLIC bool              isProgressCanceled() const;
     SAL_DLLPRIVATE    void              setMultipage( const MultiPageSetup& );
-    SAL_DLLPRIVATE    const MultiPageSetup&
+    VCL_PLUGIN_PUBLIC const MultiPageSetup&
                                         getMultipage() const;
     VCL_PLUGIN_PUBLIC void              setLastPage( bool i_bLastPage );
     SAL_DLLPRIVATE    void              setReversePrint( bool i_bReverse );
diff --git a/sw/CppunitTest_sw_globalfilter.mk b/sw/CppunitTest_sw_globalfilter.mk
index 6650266..a74cb66 100644
--- a/sw/CppunitTest_sw_globalfilter.mk
+++ b/sw/CppunitTest_sw_globalfilter.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_globalfilter,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_odfexport.mk b/sw/CppunitTest_sw_odfexport.mk
index c6434ac..aa5a40a 100644
--- a/sw/CppunitTest_sw_odfexport.mk
+++ b/sw/CppunitTest_sw_odfexport.mk
@@ -38,6 +38,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_odfexport,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_odfimport.mk b/sw/CppunitTest_sw_odfimport.mk
index eaa3542..c5937d3 100644
--- a/sw/CppunitTest_sw_odfimport.mk
+++ b/sw/CppunitTest_sw_odfimport.mk
@@ -40,6 +40,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_odfimport,\
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/source/uibase/inc \
 	-I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_ooxmlfieldexport.mk b/sw/CppunitTest_sw_ooxmlfieldexport.mk
index ae67c20..086e53e 100644
--- a/sw/CppunitTest_sw_ooxmlfieldexport.mk
+++ b/sw/CppunitTest_sw_ooxmlfieldexport.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_ooxmlfieldexport,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
 	-I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_ooxmlimport.mk b/sw/CppunitTest_sw_ooxmlimport.mk
index 4074255..1a275bf 100644
--- a/sw/CppunitTest_sw_ooxmlimport.mk
+++ b/sw/CppunitTest_sw_ooxmlimport.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_ooxmlimport,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_ooxmlw14export.mk b/sw/CppunitTest_sw_ooxmlw14export.mk
index 5958019..d6bcd07 100644
--- a/sw/CppunitTest_sw_ooxmlw14export.mk
+++ b/sw/CppunitTest_sw_ooxmlw14export.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_ooxmlw14export,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
 	-I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_rtfexport.mk b/sw/CppunitTest_sw_rtfexport.mk
index b47c906..0228ee0 100644
--- a/sw/CppunitTest_sw_rtfexport.mk
+++ b/sw/CppunitTest_sw_rtfexport.mk
@@ -37,6 +37,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_rtfexport,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
 	-I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_rtfimport.mk b/sw/CppunitTest_sw_rtfimport.mk
index 3eafcea..9cfa5b4 100644
--- a/sw/CppunitTest_sw_rtfimport.mk
+++ b/sw/CppunitTest_sw_rtfimport.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_rtfimport,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/CppunitTest_sw_ww8import.mk b/sw/CppunitTest_sw_ww8import.mk
index ed28ae9..80cde28 100644
--- a/sw/CppunitTest_sw_ww8import.mk
+++ b/sw/CppunitTest_sw_ww8import.mk
@@ -36,6 +36,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_ww8import,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index f5b752f..580b0f1 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -30,6 +30,11 @@
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
 #include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <unotools/tempfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <dbui.hxx>
 
 #include <memory>
 #include <vector>
@@ -40,6 +45,7 @@ namespace com{namespace sun{namespace star{
         class XStatement;
         class XDataSource;
         class XResultSet;
+        class xRowSet;
     }
     namespace beans{
 
@@ -82,6 +88,8 @@ class SwMailMergeConfigItem;
 class SwCalc;
 class INetURLObject;
 class SwDocShell;
+class SwDoc;
+class SfxFilter;
 
 enum DBManagerOptions
 {
@@ -223,7 +231,80 @@ friend class SwConnectionDisposedListener_Impl;
     /// merge to file _and_ merge to e-Mail
     SAL_DLLPRIVATE bool          MergeMailFiles(SwWrtShell* pSh,
                                         const SwMergeDescriptor& rMergeDescriptor, vcl::Window* pParent );
-    SAL_DLLPRIVATE bool          ToNextRecord(SwDSParam* pParam);
+    SAL_DLLPRIVATE bool          ToNextRecord(SwDSParam* pParam, bool bReset);
+
+    static css::uno::Reference< css::sdbc::XRowSet>
+        GetRowSet(css::uno::Reference< css::sdbc::XConnection>,
+        const OUString& rTableOrQuery, SwDBSelect   eTableOrQuery);
+
+    SAL_DLLPRIVATE static css::uno::Reference< css::beans::XPropertySet>
+        GetRowSupplier(css::uno::Reference< css::sdbc::XConnection> xConnection,
+        const OUString& rTableOrQuery,  SwDBSelect   eTableOrQuery)
+    {
+        css::uno::Reference<css::sdbc::XRowSet> xRowSet = GetRowSet(xConnection, rTableOrQuery, eTableOrQuery);
+
+        return css::uno::Reference<css::beans::XPropertySet>( xRowSet, css::uno::UNO_QUERY );
+    }
+
+    SAL_DLLPRIVATE void CreateDumpDocs(sal_Int32 &nMaxDumpDocs);
+
+    SAL_DLLPRIVATE void SetSourceProp(SwDocShell* pSourceDocSh);
+
+    SAL_DLLPRIVATE void GetPathAddress(OUString &sPath, OUString &sAddress,
+                                      css::uno::Reference< css::beans::XPropertySet > xColumnProp);
+
+    SAL_DLLPRIVATE bool CreateNewTemp(OUString &sPath, const OUString &sAddress,
+                                      std::unique_ptr< utl::TempFile > &aTempFile,
+                                      const SwMergeDescriptor& rMergeDescriptor,  const SfxFilter* pStoreToFilter);
+
+    SAL_DLLPRIVATE void UpdateProgressDlg(bool bMergeShell,  VclPtr<CancelableDialog> pProgressDlg, bool createTempFile,
+                                          std::unique_ptr< INetURLObject > &aTempFileURL,
+                                          SwDocShell *pSourceDocSh, sal_Int32 nDocNo);
+
+    SAL_DLLPRIVATE bool CreateTargetDocShell(sal_Int32 nMaxDumpDocs, bool bMergeShell, vcl::Window *pSourceWindow,
+                                             SwWrtShell *pSourceShell, SwDocShell *pSourceDocSh,
+                                             SfxObjectShellRef &xTargetDocShell, SwDoc *&pTargetDoc,
+                                             SwWrtShell *&pTargetShell, SwView  *&pTargetView,
+                                             sal_uInt16 &nStartingPageNo, OUString &sStartingPageDesc);
+
+    SAL_DLLPRIVATE void LockUnlockDisp(bool bLock, SwDocShell *pSourceDocSh);
+
+    SAL_DLLPRIVATE void CreateProgessDlg(vcl::Window *&pSourceWindow, VclPtr<CancelableDialog> &pProgressDlg,
+                                         bool bMergeShell, SwWrtShell *pSourceShell, vcl::Window *pParent);
+
+    SAL_DLLPRIVATE void CreateWorkDoc(SfxObjectShellLock &xWorkDocSh, SwView *&pWorkView, SwDoc *&pWorkDoc, SwDBManager *&pOldDBManager,
+                                      SwDocShell *pSourceDocSh, sal_Int32 nMaxDumpDocs,  sal_Int32 nDocNo);
+
+    SAL_DLLPRIVATE void UpdateExpFields(SwWrtShell& rWorkShell, SfxObjectShellLock xWorkDocSh);
+
+    SAL_DLLPRIVATE void CreateStoreToFilter(const SfxFilter *&pStoreToFilter, const OUString *&pStoreToFilterOptions,
+                                            SwDocShell *pSourceDocSh, bool bEMail, const SwMergeDescriptor &rMergeDescriptor);
+
+    SAL_DLLPRIVATE void MergeSingleFiles(SwDoc *pWorkDoc, SwWrtShell &rWorkShell, SwWrtShell *pTargetShell, SwDoc *pTargetDoc,
+                                         SfxObjectShellLock &xWorkDocSh, SfxObjectShellRef xTargetDocShell,
+                                         bool bPageStylesWithHeaderFooter, bool bSynchronizedDoc,
+                                         OUString &sModifiedStartingPageDesc, OUString &sStartingPageDesc, sal_Int32 nDocNo,
+                                         long nStartRow, sal_uInt16 nStartingPageNo, int &targetDocPageCount, const bool bMergeShell,
+                                         const SwMergeDescriptor& rMergeDescriptor, sal_Int32 nMaxDumpDocs);
+
+    SAL_DLLPRIVATE void ResetWorkDoc(SwDoc *pWorkDoc, SfxObjectShellLock &xWorkDocSh, SwDBManager *pOldDBManager);
+
+    SAL_DLLPRIVATE void FreezeLayouts(SwWrtShell *pTargetShell, bool freeze);
+
+    SAL_DLLPRIVATE void FinishMailMergeFile(SfxObjectShellLock &xWorkDocSh, SwView *pWorkView, SwDoc *pTargetDoc,
+                                             SwWrtShell *pTargetShell, bool bCreateSingleFile, bool bPrinter,
+                                             SwDoc *pWorkDoc, SwDBManager *pOldDBManager);
+
+    SAL_DLLPRIVATE bool SavePrintDoc(SfxObjectShellRef xTargetDocShell, SwView *pTargetView,
+                                     const SwMergeDescriptor &rMergeDescriptor,
+                                     std::unique_ptr< utl::TempFile > &aTempFile,
+                                     const SfxFilter *&pStoreToFilter, const OUString *&pStoreToFilterOptions,
+                                     const bool bMergeShell, bool bCreateSingleFile, const bool bPrinter);
+
+    SAL_DLLPRIVATE void SetPrinterOptions(const SwMergeDescriptor &rMergeDescriptor,
+                                          css::uno::Sequence< css::beans::PropertyValue > &aOptions);
+
+    SAL_DLLPRIVATE void RemoveTmpFiles(::std::vector< OUString> &aFilesToRemove);
 
     SwDBManager(SwDBManager const&) = delete;
     SwDBManager& operator=(SwDBManager const&) = delete;
@@ -278,6 +359,13 @@ public:
                             SvNumberFormatter* pNFormatr,
                             long nLanguage );
 
+    sal_Int32   GetRowCount(const OUString& rDBName, const OUString& rTableName);
+
+    static sal_Int32 GetRowCount(css::uno::Reference< css::sdbc::XConnection> xConnection,
+                                 const OUString& rTableName);
+
+    sal_Int32 GetRowCount() const;
+
     sal_uLong GetColumnFormat( const OUString& rDBName,
                             const OUString& rTableName,
                             const OUString& rColNm,
@@ -342,9 +430,14 @@ public:
                 css::uno::Reference< css::sdbc::XDataSource>& rxSource);
 
     static css::uno::Reference< css::sdbcx::XColumnsSupplier>
-            GetColumnSupplier(css::uno::Reference< css::sdbc::XConnection>,
+            GetColumnSupplier(css::uno::Reference< css::sdbc::XConnection> xConnection,
                                     const OUString& rTableOrQuery,
-                                    SwDBSelect eTableOrQuery = SwDBSelect::UNKNOWN);
+                                    SwDBSelect eTableOrQuery = SwDBSelect::UNKNOWN)
+    {
+        css::uno::Reference<css::sdbc::XRowSet> xRowSet = GetRowSet(xConnection, rTableOrQuery, eTableOrQuery);
+
+        return css::uno::Reference<css::sdbcx::XColumnsSupplier>( xRowSet, css::uno::UNO_QUERY );
+    }
 
     static css::uno::Sequence<OUString> GetExistingDatabaseNames();
 
diff --git a/sw/ooxmlexport_setup.mk b/sw/ooxmlexport_setup.mk
index c4a0981..9c89c28 100644
--- a/sw/ooxmlexport_setup.mk
+++ b/sw/ooxmlexport_setup.mk
@@ -93,6 +93,7 @@ $(eval $(call gb_CppunitTest_set_include,sw_ooxmlexport$(1),\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
 	-I$(SRCDIR)/sw/qa/extras/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
     $$(INCLUDE) \
 ))
 
diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx
index 273bdfc..ce02b3e 100644
--- a/sw/qa/extras/inc/swmodeltestbase.hxx
+++ b/sw/qa/extras/inc/swmodeltestbase.hxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/sdb/CommandType.hpp>
 #include <com/sun/star/sdb/DatabaseContext.hpp>
 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
 
 #include <test/bootstrapfixture.hxx>
 #include <test/xmltesttools.hxx>
@@ -39,6 +40,7 @@
 #include <unotools/tempfile.hxx>
 #include <unotools/localfilehelper.hxx>
 #include <unotools/mediadescriptor.hxx>
+#include <sfx2/objsh.hxx>
 #include <dbmgr.hxx>
 #include <unoprnms.hxx>
 
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 0c0a7c7..3074fde 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -49,7 +49,6 @@
 #include <dbconfig.hxx>
 #include <pagedesc.hxx>
 #include <vcl/lstbox.hxx>
-#include <unotools/tempfile.hxx>
 #include <unotools/pathoptions.hxx>
 #include <svl/urihelper.hxx>
 #include <svl/zforlist.hxx>
@@ -73,7 +72,6 @@
 #include <flddat.hxx>
 #include <modcfg.hxx>
 #include <shellio.hxx>
-#include <dbui.hxx>
 #include <dbmgr.hxx>
 #include <doc.hxx>
 #include <IDocumentSettingAccess.hxx>
@@ -89,9 +87,7 @@
 #include <sfx2/request.hxx>
 #include <hintids.hxx>
 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
-#include <com/sun/star/sdbc/XRowSet.hpp>
 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
-#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
 #include <com/sun/star/sdb/XColumn.hpp>
 #include <com/sun/star/sdbc/DataType.hpp>
@@ -450,29 +446,7 @@ bool SwDBManager::MergeNew( const SwMergeDescriptor& rMergeDesc, vcl::Window* pP
         pImpl->pMergeData->xConnection = xConnection;
     // add an XEventListener
 
-    try{
-        //set to start position
-        if(pImpl->pMergeData->aSelection.getLength())
-        {
-            sal_Int32 nPos = 0;
-            pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
-            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
-            pImpl->pMergeData->CheckEndOfDB();
-            if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
-                pImpl->pMergeData->bEndOfDB = true;
-        }
-        else
-        {
-            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
-            pImpl->pMergeData->CheckEndOfDB();
-        }
-    }
-    catch (const uno::Exception& e)
-    {
-        pImpl->pMergeData->bEndOfDB = true;
-        pImpl->pMergeData->CheckEndOfDB();
-        SAL_WARN("sw.mailmerge", "exception in MergeNew(): " << e.Message);
-    }
+    ToNextRecord(pImpl->pMergeData, true);
 
     uno::Reference<sdbc::XDataSource> xSource = SwDBManager::getDataSourceAsParent(xConnection,aData.sDataSource);
 
@@ -740,18 +714,8 @@ void SwDBManager::GetColumnNames(ListBox* pListBox,
         OUString sDBName(rDBName);
         xConnection = RegisterConnection( sDBName );
     }
-    uno::Reference< sdbcx::XColumnsSupplier> xColsSupp = SwDBManager::GetColumnSupplier(xConnection, rTableName);
-    if(xColsSupp.is())
-    {
-        uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
-        const uno::Sequence<OUString> aColNames = xCols->getElementNames();
-        const OUString* pColNames = aColNames.getConstArray();
-        for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
-        {
-            pListBox->InsertEntry(pColNames[nCol]);
-        }
-        ::comphelper::disposeComponent( xColsSupp );
-    }
+
+    GetColumnNames(pListBox, xConnection, rTableName, bAppend);
 }
 
 void SwDBManager::GetColumnNames(ListBox* pListBox,
@@ -774,6 +738,56 @@ void SwDBManager::GetColumnNames(ListBox* pListBox,
     }
 }
 
+
+sal_Int32 SwDBManager::GetRowCount(const OUString& rDBName, const OUString& rTableName)
+{
+    SwDBData aData;
+    aData.sDataSource = rDBName;
+    aData.sCommand = rTableName;
+    aData.nCommandType = -1;
+    SwDSParam* pParam = FindDSData(aData, false);
+    uno::Reference<sdbc::XConnection> xConnection;
+    if(pParam && pParam->xConnection.is())
+        xConnection = pParam->xConnection;
+    else
+    {
+        OUString sDBName(rDBName);
+        xConnection = RegisterConnection( sDBName );
+    }
+
+    return GetRowCount(xConnection, rTableName);
+}
+
+
+sal_Int32 SwDBManager::GetRowCount(uno::Reference<sdbc::XConnection> xConnection,
+                             const OUString& rTableName)
+{
+    uno::Reference<beans::XPropertySet> xRow = GetRowSupplier(xConnection, rTableName, SwDBSelect::UNKNOWN);
+    sal_Int32 nCnt = 0;
+
+    if(xRow.is())
+        xRow->getPropertyValue( "RowCount" ) >>= nCnt;
+
+    return nCnt;
+}
+
+
+
+sal_Int32 SwDBManager::GetRowCount() const
+{
+    sal_Int32 nCnt = pImpl->pMergeData->aSelection.getLength();
+
+    if(nCnt == 0)
+    {
+        uno::Reference<beans::XPropertySet> xProp(pImpl->pMergeData->xResultSet, uno::UNO_QUERY);
+        if(xProp.is())
+            xProp->getPropertyValue("RowCount") >>= nCnt;
+    }
+
+    return nCnt;
+}
+
+
 SwDBManager::SwDBManager(SwDoc* pDoc)
     : bCancel(false)
     , bInitDBFields(false)
@@ -913,16 +927,9 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
     OUString sBodyMimeType;
     rtl_TextEncoding eEncoding = ::osl_getThreadTextEncoding();
 
-    static const char *sMaxDumpDocs = nullptr;
     static sal_Int32 nMaxDumpDocs = 0;
-    if (!sMaxDumpDocs)
-    {
-        sMaxDumpDocs = getenv("SW_DEBUG_MAILMERGE_DOCS");
-        if (!sMaxDumpDocs)
-            sMaxDumpDocs = "";
-        else
-            nMaxDumpDocs = rtl_ustr_toInt32(reinterpret_cast<const sal_Unicode*>( sMaxDumpDocs ), 10);
-    }
+
+    CreateDumpDocs(nMaxDumpDocs);
 
     if(bEMail)
     {
@@ -957,40 +964,17 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
         SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher();
         SwDocShell* pSourceDocSh = pSourceShell->GetView().GetDocShell();
 
-        uno::Reference<document::XDocumentProperties> xSourceDocProps;
-        {
-            uno::Reference<document::XDocumentPropertiesSupplier>
-                xDPS(pSourceDocSh->GetModel(), uno::UNO_QUERY);
-            xSourceDocProps.set(xDPS->getDocumentProperties());
-            OSL_ENSURE(xSourceDocProps.is(), "DocumentProperties is null");
-        }
+        SetSourceProp(pSourceDocSh);
 
         if( !bMergeShell && pSourceDocSh->IsModified() )
             pSfxDispatcher->Execute( pSourceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SfxCallMode::SYNCHRON|SfxCallMode::RECORD);
         if( bMergeShell || !pSourceDocSh->IsModified() )
         {
-            const SfxFilter* pStoreToFilter = SwIoSystem::GetFileFilter(
-                pSourceDocSh->GetMedium()->GetURLObject().GetMainURL(INetURLObject::NO_DECODE));
-            SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
+            const SfxFilter* pStoreToFilter = nullptr;
             const OUString* pStoreToFilterOptions = nullptr;
 
-            // if a save_to filter is set then use it - otherwise use the default
-            if( bEMail && !rMergeDescriptor.bSendAsAttachment )
-            {
-                OUString sExtension = rMergeDescriptor.bSendAsHTML ? OUString("html") : OUString("txt");
-                pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
-            }
-            else if( !rMergeDescriptor.sSaveToFilter.isEmpty())
-            {
-                const SfxFilter* pFilter =
-                        pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter );
-                if(pFilter)
-                {
-                    pStoreToFilter = pFilter;
-                    if(!rMergeDescriptor.sSaveToFilterOptions.isEmpty())
-                        pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions;
-                }
-            }
+            CreateStoreToFilter(pStoreToFilter, pStoreToFilterOptions, pSourceDocSh, bEMail, rMergeDescriptor);
+
             bCancel = false;
 
             // in case of creating a single resulting file this has to be created here
@@ -1001,7 +985,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
 
             SwView* pTargetView = nullptr;
             std::unique_ptr< utl::TempFile > aTempFile;
-            bool createTempFile = ( rMergeDescriptor.nMergeType == DBMGR_MERGE_EMAIL || rMergeDescriptor.nMergeType == DBMGR_MERGE_FILE );
+            bool createTempFile = ( bEMail || rMergeDescriptor.nMergeType == DBMGR_MERGE_FILE );
             OUString sModifiedStartingPageDesc;
             OUString sStartingPageDesc;
             sal_uInt16 nStartingPageNo = 0;
@@ -1010,78 +994,21 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             vcl::Window *pSourceWindow = nullptr;
             VclPtr<CancelableDialog> pProgressDlg;
 
-            if (!IsMergeSilent()) {
-                pSourceWindow = &pSourceShell->GetView().GetEditWin();
-                if( ! pParent )
-                    pParent = pSourceWindow;
-                if( bMergeShell )
-                    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(pSourceShell->GetView().GetDocShell()->GetTitle(22));
-                }
-                pProgressDlg->SetCancelHdl( LINK(this, SwDBManager, PrtCancelHdl) );
-                pProgressDlg->Show();
-
-                for( sal_uInt16 i = 0; i < 25; i++)
-                    Application::Reschedule();
-            }
+            CreateProgessDlg(pSourceWindow, pProgressDlg, bMergeShell, pSourceShell, pParent);
 
             if(bCreateSingleFile)
             {
-                // create a target docshell to put the merged document into
-                xTargetDocShell = new SwDocShell( SfxObjectCreateMode::STANDARD );
-                xTargetDocShell->DoInitNew();
-                if (nMaxDumpDocs)
-                    lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
-                SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );
-                if (bMergeShell && 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 );
+                bPageStylesWithHeaderFooter = CreateTargetDocShell(nMaxDumpDocs, bMergeShell, pSourceWindow, pSourceShell,
+                                                                   pSourceDocSh, xTargetDocShell, pTargetDoc, pTargetShell,
+                                                                   pTargetView, nStartingPageNo, sStartingPageDesc);
 
-                //determine the page style and number used at the start of the source document
-                pSourceShell->SttEndDoc(true);
-                nStartingPageNo = pSourceShell->GetVirtPageNum();
-                sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc(
-                                            pSourceShell->GetCurPageDesc()).GetName();
-
-                // #i72517#
-                const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc );
-                const SwFrameFormat& rMaster = pSourcePageDesc->GetMaster();
-                bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
-                                                rMaster.GetFooter().IsActive();
-
-                // copy compatibility options
-                pTargetShell->GetDoc()->ReplaceCompatibilityOptions( *pSourceShell->GetDoc());
-                // #72821# copy dynamic defaults
-                pTargetShell->GetDoc()->ReplaceDefaults( *pSourceShell->GetDoc());
-
-                pTargetShell->GetDoc()->ReplaceDocumentProperties( *pSourceShell->GetDoc());
+                sModifiedStartingPageDesc = sStartingPageDesc;
             }
-
             // 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);
-            }
+            LockUnlockDisp(true, pSourceDocSh);
 
             sal_Int32 nDocNo = 1;
             sal_Int32 nDocCount = 0;
@@ -1115,168 +1042,38 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
 
                     OUString sAddress;
                     if( !bEMail && bColumnName )
-                    {
-                        SwDBFormatData aDBFormat;
-                        aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
-                        aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
-                        sAddress = GetDBField( xColumnProp, aDBFormat);
-                        if (sAddress.isEmpty())
-                            sAddress = "_";
-                        sPath += sAddress;
-                    }
+                        GetPathAddress(sPath, sAddress, xColumnProp);
 
                     // create a new temporary file name - only done once in case of bCreateSingleFile
                     if( createTempFile && ( 1 == nDocNo || !bCreateSingleFile ))
-                    {
-                        INetURLObject aEntry(sPath);
-                        OUString sLeading;
-                        //#i97667# if the name is from a database field then it will be used _as is_
-                        if( !sAddress.isEmpty() )
-                            sLeading = sAddress;
-                        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( rMergeDescriptor.bSubjectIsFilename )
-                            aTempFile->EnableKillingFile();
-                        if( !aTempFile->IsValid() )
-                        {
-                            ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
-                            bNoError = false;
-                            bCancel = true;
-                        }
-                    }
+                        bNoError = CreateNewTemp(sPath, sAddress, aTempFile, rMergeDescriptor, pStoreToFilter);
 
                     if( !bCancel )
                     {
                         std::unique_ptr< INetURLObject > aTempFileURL;
                         if( createTempFile )
                             aTempFileURL.reset( new INetURLObject(aTempFile->GetURL()));
-                        if (!IsMergeSilent()) {
-                            if( bMergeShell )
-                                static_cast<CreateMonitor*>( pProgressDlg.get() )->SetCurrentPosition( nDocNo );
-                            else {
-                                PrintMonitor *pPrintMonDlg = static_cast<PrintMonitor*>( pProgressDlg.get() );
-                                pPrintMonDlg->m_pPrinter->SetText( createTempFile ? aTempFileURL->GetBase() : OUString( pSourceDocSh->GetTitle( 22 )));
-                                OUString sStat(SW_RES(STR_STATSTR_LETTER));   // Brief
-                                sStat += " ";
-                                sStat += OUString::number( nDocNo );
-                                pPrintMonDlg->m_pPrintInfo->SetText( sStat );
-                            }
-                            pProgressDlg->Update();
-                        }
 
-                        // Computation time for the GUI
-                        for( sal_uInt16 i = 0; i < 25; i++ )
-                            Application::Reschedule();
+                        UpdateProgressDlg(bMergeShell, pProgressDlg, createTempFile, aTempFileURL, pSourceDocSh, nDocNo);
+
 
                         // 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.
                         if( 1 == nDocNo || bCreateSingleFile )
-                        {
-                            assert( !xWorkDocSh.Is());
-                            // copy the source document
-                            xWorkDocSh = pSourceDocSh->GetDoc()->CreateCopy( true );
-
-                            //create a view frame for the document
-                            pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() );
-                            //request the layout calculation
-                            SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
-                            pWorkView->AttrChangedNotify( &rWorkShell );// in order for SelectShell to be called
-
-                            pWorkDoc = rWorkShell.GetDoc();
-                            pWorkDoc->ReplaceDocumentProperties( *pSourceDocSh->GetDoc());
-                            if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
-                                lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
-                            pOldDBManager = pWorkDoc->GetDBManager();
-                            pWorkDoc->SetDBManager( this );
-                            pWorkDoc->getIDocumentLinksAdministration().EmbedAllLinks();
-
-                            // #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.
-                            rWorkShell.LockExpFields();
-                            rWorkShell.CalcLayout();
-                        }
+                            CreateWorkDoc(xWorkDocSh, pWorkView, pWorkDoc, pOldDBManager, pSourceDocSh, nMaxDumpDocs, nDocNo);
 
-                        SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
-                        SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh));
-                        // 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 ( rWorkShell.IsExpFieldsLocked() )
-                            rWorkShell.UnlockExpFields();
-                        rWorkShell.SwViewShell::UpdateFields();
-                        rWorkShell.LockExpFields();
-                        SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh));
-
-                        // launch MailMergeEvent if required
-                        const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
-                        if(pEvtSrc)
-                        {
-                            uno::Reference< uno::XInterface > xRef( const_cast<text::XMailMergeBroadcaster *>(static_cast<text::XMailMergeBroadcaster const *>(pEvtSrc)) );
-                            text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() );
-                            pEvtSrc->LaunchMailMergeEvent( aEvt );
-                        }
+                        SwWrtShell &rWorkShell = pWorkView->GetWrtShell();
+
+                        UpdateExpFields(rWorkShell, xWorkDocSh);
 
                         if(bCreateSingleFile)
                         {
-                            pWorkDoc->RemoveInvisibleContent();
+                            MergeSingleFiles(pWorkDoc, rWorkShell, pTargetShell, pTargetDoc, xWorkDocSh, xTargetDocShell,
+                                             bPageStylesWithHeaderFooter, bSynchronizedDoc, sModifiedStartingPageDesc,
+                                             sStartingPageDesc, nDocNo, nStartRow, nStartingPageNo, targetDocPageCount,
+                                             bMergeShell, rMergeDescriptor, nMaxDumpDocs);
 
-                            OSL_ENSURE( pTargetShell, "no target shell available!" );
-                            // copy created file into the target document
-                            rWorkShell.ConvertFieldsToText();
-                            rWorkShell.SetNumberingRestart();
-                            if( bSynchronizedDoc )
-                            {
-                                lcl_RemoveSectionLinks( rWorkShell );
-                            }
-
-                            // insert the document into the target document
-
-                            //#i72517# put the styles to the target document
-                            //if the source uses headers or footers each new copy need to copy a new page styles
-                            SwPageDesc* pTargetPageDesc(nullptr);
-                            if(bPageStylesWithHeaderFooter)
-                            {
-                                //create a new pagestyle
-                                //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
-                                OUString sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
-                                pTargetPageDesc = pTargetDoc->MakePageDesc( sNewPageDescName );
-                                const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
-
-                                if(pWorkPageDesc && pTargetPageDesc)
-                                {
-                                    pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, false );
-                                    sModifiedStartingPageDesc = sNewPageDescName;
-                                    lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
-                                }
-                            }
-                            else
-                                pTargetPageDesc = pTargetShell->FindPageDescByName( sModifiedStartingPageDesc );
-
-                            if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
-                                lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
-                            if( targetDocPageCount % 2 == 1 )
-                                ++targetDocPageCount; // Docs always start on odd pages (so offset must be even).
-                            SwNodeIndex appendedDocStart = pTargetDoc->AppendDoc(*rWorkShell.GetDoc(),
-                                nStartingPageNo, pTargetPageDesc, nDocNo == 1, targetDocPageCount);
-                            targetDocPageCount += rWorkShell.GetPageCnt();
-                            if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
-                                lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
-                            if (bMergeShell)
-                            {
-                                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( rMergeDescriptor.nMergeType == DBMGR_MERGE_PRINTER )
                         {
@@ -1293,19 +1090,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                                 aOptions[ 1 ].Name = "MonitorVisible";
                                 aOptions[ 1 ].Value <<= sal_False;
                                 // move print options
-                                const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
-                                for( sal_Int32 nOption = 0, nIndex = 1 ; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
-                                {
-                                    if( pPrintOptions[nOption].Name == "CopyCount" || pPrintOptions[nOption].Name == "FileName"
-                                        || pPrintOptions[nOption].Name == "Collate" || pPrintOptions[nOption].Name == "Pages"
-                                        || pPrintOptions[nOption].Name == "Wait" || pPrintOptions[nOption].Name == "PrinterName" )
-                                    {
-                                        // add an option
-                                        aOptions.realloc( nIndex + 1 );
-                                        aOptions[ nIndex ].Name = pPrintOptions[nOption].Name;
-                                        aOptions[ nIndex++ ].Value = pPrintOptions[nOption].Value ;
-                                    }
-                                }
+                                SetPrinterOptions(rMergeDescriptor, aOptions);
                                 pWorkView->StartPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync );
                                 SfxPrinter* pDocPrt = pWorkView->GetPrinter();
                                 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : SfxViewShell::GetJobSetup();
@@ -1427,9 +1212,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                         }
                         if( bCreateSingleFile )
                         {
-                            pWorkDoc->SetDBManager( pOldDBManager );
-                            xWorkDocSh->DoClose();
-                            xWorkDocSh = nullptr;
+                            ResetWorkDoc(pWorkDoc, xWorkDocSh, pOldDBManager);
                         }
                     }
                 }
@@ -1440,149 +1223,506 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                 // sub-document, to get the correct PageDesc.
                 if(!bFreezedLayouts && bCreateSingleFile)
                 {
-                    for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
-                        aLayout->FreezeLayout(true);
+                    FreezeLayouts(pTargetShell, true);
                     bFreezedLayouts = true;
                 }
             } while( !bCancel &&
                 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
 
-            if ( xWorkDocSh.Is() && pWorkView->GetWrtShell().IsExpFieldsLocked() )
-            {
-                // Unlock document fields after merge complete
-                pWorkView->GetWrtShell().UnlockExpFields();
-            }
+            FinishMailMergeFile(xWorkDocSh, pWorkView, pTargetDoc, pTargetShell, bCreateSingleFile, rMergeDescriptor.nMergeType == DBMGR_MERGE_PRINTER,
+                                 pWorkDoc, pOldDBManager);
 
-            if( !bCreateSingleFile )
-            {
-                if( rMergeDescriptor.nMergeType == DBMGR_MERGE_PRINTER )
-                {
-                    Printer::FinishPrintJob( pWorkView->GetPrinterController());
+            pProgressDlg.disposeAndClear();
+
+            // save the single output document
+            bNoError = SavePrintDoc(xTargetDocShell, pTargetView, rMergeDescriptor, aTempFile,
+                                        pStoreToFilter, pStoreToFilterOptions,
+                                        bMergeShell, bCreateSingleFile, rMergeDescriptor.nMergeType == DBMGR_MERGE_PRINTER);
+
+
+            //remove the temporary files
+            RemoveTmpFiles(aFilesToRemove);
+
+            // unlock all dispatchers
+            LockUnlockDisp(false, pSourceDocSh);
+
+            SW_MOD()->SetView(&pSourceShell->GetView());
+        }
+    }
+
+    if(bEMail)
+    {
+        xMailDispatcher->stop();
+        xMailDispatcher->shutdown();
+    }
+
+    return bNoError;
+}
+
+void SwDBManager::CreateDumpDocs(sal_Int32 &nMaxDumpDocs)
+{
+    static const char *sMaxDumpDocs = nullptr;
+
+    if (!sMaxDumpDocs)
+    {
+        sMaxDumpDocs = getenv("SW_DEBUG_MAILMERGE_DOCS");
+        if (!sMaxDumpDocs)
+            sMaxDumpDocs = "";
+        else
+            nMaxDumpDocs = rtl_ustr_toInt32(reinterpret_cast<const sal_Unicode*>( sMaxDumpDocs ), 10);
+    }
+}
+
+void SwDBManager::SetSourceProp(SwDocShell* pSourceDocSh)
+{
+    uno::Reference<document::XDocumentProperties> xSourceDocProps;
+    {
+        uno::Reference<document::XDocumentPropertiesSupplier>
+            xDPS(pSourceDocSh->GetModel(), uno::UNO_QUERY);
+        xSourceDocProps.set(xDPS->getDocumentProperties());
+        OSL_ENSURE(xSourceDocProps.is(), "DocumentProperties is null");
+    }
+}
+
+void SwDBManager::GetPathAddress(OUString &sPath, OUString &sAddress, uno::Reference< beans::XPropertySet > xColumnProp)
+{
+    SwDBFormatData aDBFormat;
+    aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
+    aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
+    sAddress = GetDBField( xColumnProp, aDBFormat);
+    if (sAddress.isEmpty())
+        sAddress = "_";
+    sPath += sAddress;
+}
+
+bool SwDBManager::CreateNewTemp(OUString &sPath, const OUString &sAddress,
+                                std::unique_ptr< utl::TempFile > &aTempFile,
+                                const SwMergeDescriptor& rMergeDescriptor,  const SfxFilter* pStoreToFilter)
+{
+    INetURLObject aEntry(sPath);
+    OUString sLeading;
+    bool bErr = true;
+
+    //#i97667# if the name is from a database field then it will be used _as is_
+    if( !sAddress.isEmpty() )
+        sLeading = sAddress;
+    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( rMergeDescriptor.bSubjectIsFilename )
+        aTempFile->EnableKillingFile();
+
+    if( !aTempFile->IsValid() )
+    {
+        ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
+        bErr    = false;
+        bCancel = true;
+    }
+
+    return bErr;
+}
+
+void SwDBManager::UpdateProgressDlg(bool bMergeShell, VclPtr<CancelableDialog> pProgressDlg, bool createTempFile,
+                                    std::unique_ptr< INetURLObject > &aTempFileURL,
+                                    SwDocShell *pSourceDocSh, sal_Int32 nDocNo)
+{
+    if (!IsMergeSilent())
+    {
+        if( bMergeShell )
+            static_cast<CreateMonitor*>( pProgressDlg.get() )->SetCurrentPosition( nDocNo );
+        else
+        {
+            PrintMonitor *pPrintMonDlg = static_cast<PrintMonitor*>( pProgressDlg.get() );
+            pPrintMonDlg->m_pPrinter->SetText( createTempFile ? aTempFileURL->GetBase() : OUString( pSourceDocSh->GetTitle( 22 )));
+            OUString sStat(SW_RES(STR_STATSTR_LETTER));   // Brief
+            sStat += " ";
+            sStat += OUString::number( nDocNo );
+            pPrintMonDlg->m_pPrintInfo->SetText( sStat );
+        }
+
+        pProgressDlg->Update();
+
+        // Computation time for the GUI
+        for( sal_uInt16 i = 0; i < 25; i++ )
+            Application::Reschedule();
+    }
+}
+
+bool SwDBManager::CreateTargetDocShell(sal_Int32 nMaxDumpDocs, bool bMergeShell, vcl::Window *pSourceWindow,
+                                       SwWrtShell *pSourceShell, SwDocShell *pSourceDocSh,
+                                       SfxObjectShellRef &xTargetDocShell, SwDoc *&pTargetDoc,
+                                       SwWrtShell *&pTargetShell, SwView  *&pTargetView,
+                                       sal_uInt16 &nStartingPageNo, OUString &sStartingPageDesc)
+{
+    // create a target docshell to put the merged document into
+    xTargetDocShell = new SwDocShell( SfxObjectCreateMode::STANDARD );
+    xTargetDocShell->DoInitNew( );
+    if (nMaxDumpDocs)
+        lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
+    SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );
+    if (bMergeShell && 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 );
+
+    //determine the page style and number used at the start of the source document
+    pSourceShell->SttEndDoc(true);
+    nStartingPageNo = pSourceShell->GetVirtPageNum();
+    sStartingPageDesc = pSourceShell->GetPageDesc(
+        pSourceShell->GetCurPageDesc()).GetName();
+
+    // #i72517#
+    const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc );
+    const SwFrameFormat& rMaster = pSourcePageDesc->GetMaster();
+    bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
+                                       rMaster.GetFooter().IsActive();
+
+    // copy compatibility options
+    pTargetShell->GetDoc()->ReplaceCompatibilityOptions( *pSourceShell->GetDoc());
+    // #72821# copy dynamic defaults
+    pTargetShell->GetDoc()->ReplaceDefaults( *pSourceShell->GetDoc());
+
+    pTargetShell->GetDoc()->ReplaceDocumentProperties( *pSourceShell->GetDoc());
+
+    return bPageStylesWithHeaderFooter;
+}
+
+void SwDBManager::LockUnlockDisp(bool bLock, SwDocShell *pSourceDocSh)
+{
+    SfxViewFrame *pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
+    while (pViewFrame)
+    {
+        pViewFrame->GetDispatcher()->Lock(bLock);
+        pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pSourceDocSh);
+    }
+}
+
+void SwDBManager::CreateProgessDlg(vcl::Window *&pSourceWindow, VclPtr<CancelableDialog> &pProgressDlg, bool bMergeShell,
+                                   SwWrtShell *pSourceShell, vcl::Window *pParent)
+{
+    if (!IsMergeSilent())
+    {
+        pSourceWindow = &pSourceShell->GetView().GetEditWin();
+        if( ! pParent )
+            pParent = pSourceWindow;
+        if( bMergeShell )
+            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(pSourceShell->GetView().GetDocShell()->GetTitle(22));
+        }
+        pProgressDlg->SetCancelHdl( LINK(this, SwDBManager, PrtCancelHdl) );
+        pProgressDlg->Show();
+
+        for( sal_uInt16 i = 0; i < 25; i++)
+            Application::Reschedule();
+    }
+}
+
+void SwDBManager::CreateWorkDoc(SfxObjectShellLock &xWorkDocSh, SwView *&pWorkView, SwDoc *&pWorkDoc, SwDBManager *&pOldDBManager,
+                                SwDocShell *pSourceDocSh, sal_Int32 nMaxDumpDocs,  sal_Int32 nDocNo)
+{
+    assert( !xWorkDocSh.Is());
+    // copy the source document
+    xWorkDocSh = pSourceDocSh->GetDoc()->CreateCopy( true );
+
+    //create a view frame for the document
+    pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() );
+    //request the layout calculation
+    SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
+    pWorkView->AttrChangedNotify( &rWorkShell );// in order for SelectShell to be called
+
+    pWorkDoc = rWorkShell.GetDoc();
+    pWorkDoc->ReplaceDocumentProperties( *pSourceDocSh->GetDoc());
+    if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
+        lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
+    pOldDBManager = pWorkDoc->GetDBManager();
+    pWorkDoc->SetDBManager( this );
+    pWorkDoc->getIDocumentLinksAdministration().EmbedAllLinks();
+
+    // #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.
+    rWorkShell.LockExpFields();
+    rWorkShell.CalcLayout();
+}
+
+void SwDBManager::UpdateExpFields(SwWrtShell& rWorkShell, SfxObjectShellLock xWorkDocSh)
+{
+    SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh));
+    // 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 ( rWorkShell.IsExpFieldsLocked() )
+        rWorkShell.UnlockExpFields();
+    rWorkShell.SwViewShell::UpdateFields();
+    rWorkShell.LockExpFields();
+    SfxGetpApp()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh));
+
+    // launch MailMergeEvent if required
+    const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
+    if(pEvtSrc)
+    {
+        uno::Reference< uno::XInterface > xRef( const_cast<text::XMailMergeBroadcaster *>(static_cast<text::XMailMergeBroadcaster const *>(pEvtSrc)) );
+        text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() );
+        pEvtSrc->LaunchMailMergeEvent( aEvt );
+    }
+}
+
+void SwDBManager::CreateStoreToFilter(const SfxFilter *&pStoreToFilter, const OUString *&pStoreToFilterOptions,
+                                      SwDocShell *pSourceDocSh, bool bEMail, const SwMergeDescriptor &rMergeDescriptor)
+{
+    pStoreToFilter = SwIoSystem::GetFileFilter(
+        pSourceDocSh->GetMedium()->GetURLObject().GetMainURL(INetURLObject::NO_DECODE));
+    SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
+
+    // if a save_to filter is set then use it - otherwise use the default
+    if( bEMail && !rMergeDescriptor.bSendAsAttachment )
+    {
+        OUString sExtension = rMergeDescriptor.bSendAsHTML ? OUString("html") : OUString("txt");
+        pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
+    }
+    else if( !rMergeDescriptor.sSaveToFilter.isEmpty())
+    {
+        const SfxFilter* pFilter =
+            pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter );
+        if(pFilter)
+        {
+            pStoreToFilter = pFilter;
+            if(!rMergeDescriptor.sSaveToFilterOptions.isEmpty())
+                pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions;
+        }
+    }
+}
+
+void SwDBManager::MergeSingleFiles(SwDoc *pWorkDoc, SwWrtShell &rWorkShell, SwWrtShell *pTargetShell, SwDoc *pTargetDoc,
+                                   SfxObjectShellLock &xWorkDocSh, SfxObjectShellRef xTargetDocShell,
+                                   bool bPageStylesWithHeaderFooter, bool bSynchronizedDoc,
+                                   OUString &sModifiedStartingPageDesc, OUString &sStartingPageDesc, sal_Int32 nDocNo,
+                                   long nStartRow, sal_uInt16 nStartingPageNo, int &targetDocPageCount, const bool bMergeShell,
+                                   const SwMergeDescriptor& rMergeDescriptor, sal_Int32 nMaxDumpDocs)
+{
+    pWorkDoc->RemoveInvisibleContent();
+
+    OSL_ENSURE( pTargetShell, "no target shell available!" );
+    // copy created file into the target document
+    rWorkShell.ConvertFieldsToText();
+    rWorkShell.SetNumberingRestart();
+    if( bSynchronizedDoc )
+    {
+        lcl_RemoveSectionLinks( rWorkShell );
+    }
+
+    // insert the document into the target document
+
+    //#i72517# put the styles to the target document
+    //if the source uses headers or footers each new copy need to copy a new page styles
+    SwPageDesc* pTargetPageDesc(nullptr);
+    if(bPageStylesWithHeaderFooter)
+    {
+        //create a new pagestyle
+        //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
+        OUString sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
+        pTargetPageDesc = pTargetDoc->MakePageDesc( sNewPageDescName );
+        const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
+
+        if(pWorkPageDesc && pTargetPageDesc)
+        {
+            pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, false );
+            sModifiedStartingPageDesc = sNewPageDescName;
+            lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
+        }
+    }
+    else
+        pTargetPageDesc = pTargetShell->FindPageDescByName( sModifiedStartingPageDesc );
+
+    if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
+        lcl_SaveDoc( xWorkDocSh, "WorkDoc", nDocNo );
+    if( targetDocPageCount % 2 == 1 )
+        ++targetDocPageCount; // Docs always start on odd pages (so offset must be even).
+    SwNodeIndex appendedDocStart = pTargetDoc->AppendDoc(*rWorkShell.GetDoc(),
+                                                         nStartingPageNo, pTargetPageDesc, nDocNo == 1, targetDocPageCount);
+    targetDocPageCount += rWorkShell.GetPageCnt();
+    if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )
+        lcl_SaveDoc( xTargetDocShell, "MergeDoc" );
+    if (bMergeShell)
+    {
+        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 );
+    }
+}
+
+void SwDBManager::ResetWorkDoc(SwDoc *pWorkDoc, SfxObjectShellLock &xWorkDocSh, SwDBManager *pOldDBManager)
+{
+    pWorkDoc->SetDBManager( pOldDBManager );
+    xWorkDocSh->DoClose();
+    xWorkDocSh = nullptr;
+}
+
+void SwDBManager::FreezeLayouts(SwWrtShell *pTargetShell, bool freeze)
+{
+    for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
+    {
+        aLayout->FreezeLayout(freeze);
+        if(!freeze)
+            aLayout->AllCheckPageDescs();
+    }
+}
+
+void SwDBManager::FinishMailMergeFile(SfxObjectShellLock &xWorkDocSh, SwView *pWorkView, SwDoc *pTargetDoc,
+                                       SwWrtShell *pTargetShell, bool bCreateSingleFile, bool bPrinter,
+                                       SwDoc *pWorkDoc, SwDBManager *pOldDBManager)
+{
+    if ( xWorkDocSh.Is() && pWorkView->GetWrtShell().IsExpFieldsLocked() )
+    {
+        // Unlock document fields after merge complete
+        pWorkView->GetWrtShell().UnlockExpFields();
+    }
+
+    if(!bCreateSingleFile)
+    {
+        if(bPrinter)
+        {
+            Printer::FinishPrintJob( pWorkView->GetPrinterController() );
 #if ENABLE_CUPS && !defined(MACOSX)
-                    psp::PrinterInfoManager::get().flushBatchPrint();
+            psp::PrinterInfoManager::get().flushBatchPrint();
 #endif
-                }
-                pWorkDoc->SetDBManager( pOldDBManager );
-                xWorkDocSh->DoClose();
-            }
+        }
 
-            if (bCreateSingleFile)
-            {
-                // sw::DocumentLayoutManager::CopyLayoutFormat() did not generate
-                // unique fly names, do it here once.
-                pTargetDoc->SetInMailMerge(false);
-                pTargetDoc->SetAllUniqueFlyNames();
-            }
+        ResetWorkDoc(pWorkDoc, xWorkDocSh, pOldDBManager);
+    }
 
-            for( sal_uInt16 i = 0; i < 25; i++)
-                Application::Reschedule();
+    if( bCreateSingleFile )
+    {
+        // 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.
-            if(bCreateSingleFile)
-            {
-                pTargetShell->CalcLayout();
-                for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
-                {
-                    aLayout->FreezeLayout(false);
-                    aLayout->AllCheckPageDescs();
-                }
-            }
+    for( sal_uInt16 i = 0; i < 25; i++)
+        Application::Reschedule();
 
-            pProgressDlg.disposeAndClear();
+    if( bCreateSingleFile )
+    {
+        // Unfreeze target document layouts and correct all PageDescs.
+        pTargetShell->CalcLayout();
+        FreezeLayouts(pTargetShell, false);
+    }
+}
 
-            // save the single output document
-            if (bMergeShell)
-            {
-                rMergeDescriptor.pMailMergeConfigItem->SetTargetView( pTargetView );
-            }
-            else if(bCreateSingleFile)
+bool SwDBManager::SavePrintDoc(SfxObjectShellRef xTargetDocShell, SwView *pTargetView, const SwMergeDescriptor &rMergeDescriptor,
+                               std::unique_ptr< utl::TempFile > &aTempFile,
+                               const SfxFilter *&pStoreToFilter, const OUString *&pStoreToFilterOptions,
+                               const bool bMergeShell, bool bCreateSingleFile, const bool bPrinter)
+{
+    bool bNoError = true;
+
+    if (bMergeShell)
+    {
+        rMergeDescriptor.pMailMergeConfigItem->SetTargetView( pTargetView );
+    }
+    else if(bCreateSingleFile)
+    {
+        if(!bCancel)
+        {
+            if( !bPrinter )
             {
-                if( rMergeDescriptor.nMergeType != DBMGR_MERGE_PRINTER )
+                assert( aTempFile.get());
+                INetURLObject aTempFileURL( rMergeDescriptor.bSubjectIsFilename ? sSubject : aTempFile->GetURL());
+                SfxMedium* pDstMed = new SfxMedium(
+                    aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
+                    STREAM_STD_READWRITE );
+                pDstMed->SetFilter( pStoreToFilter );
+                if(pDstMed->GetItemSet())
                 {
-                    if( !bCancel )
-                    {
-                        assert( aTempFile.get());
-                        INetURLObject aTempFileURL( rMergeDescriptor.bSubjectIsFilename ? sSubject : aTempFile->GetURL());
-                        SfxMedium* pDstMed = new SfxMedium(
-                            aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
-                            STREAM_STD_READWRITE );
-                        pDstMed->SetFilter( pStoreToFilter );
-                        if(pDstMed->GetItemSet())
-                        {
-                            if(pStoreToFilterOptions )
-                                pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
-                            if(rMergeDescriptor.aSaveToFilterData.getLength())
-                                pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, uno::makeAny(rMergeDescriptor.aSaveToFilterData)));
-                        }
-
-                        xTargetDocShell->DoSaveAs(*pDstMed);
-                        xTargetDocShell->DoSaveCompleted(pDstMed);
-                        if( xTargetDocShell->GetError() )
-                        {
-                            // error message ??
-                            ErrorHandler::HandleError( xTargetDocShell->GetError() );
-                            bNoError = false;
-                        }
-                    }
+                    if(pStoreToFilterOptions )
+                        pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
+                    if(rMergeDescriptor.aSaveToFilterData.getLength())
+                        pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, uno::makeAny(rMergeDescriptor.aSaveToFilterData)));
                 }
-                else if( pTargetView ) // must be available!
-                {
-                    //print the target document
-                    // printing should be done synchronously otherwise the document
-                    // might already become invalid during the process
-                    uno::Sequence< beans::PropertyValue > aOptions( rMergeDescriptor.aPrintOptions );
-
-                    aOptions.realloc( 1 );
-                    aOptions[ 0 ].Name = "Wait";
-                    aOptions[ 0 ].Value <<= sal_True ;
-                    // move print options
-                    const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
-                    for( sal_Int32 nOption = 0, nIndex = 1 ; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
-                    {
-                        if( pPrintOptions[nOption].Name == "CopyCount" || pPrintOptions[nOption].Name == "FileName"
-                            || pPrintOptions[nOption].Name == "Collate" || pPrintOptions[nOption].Name == "Pages"
-                            || pPrintOptions[nOption].Name == "Wait" || pPrintOptions[nOption].Name == "PrinterName" )
-                        {
-                            // add an option
-                            aOptions.realloc( nIndex + 1 );
-                            aOptions[ nIndex ].Name = pPrintOptions[nOption].Name;
-                            aOptions[ nIndex++ ].Value = pPrintOptions[nOption].Value ;
-                        }
-                    }
 
-                        pTargetView->ExecPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync );
+                xTargetDocShell->DoSaveAs(*pDstMed);
+                xTargetDocShell->DoSaveCompleted(pDstMed);
+                if( xTargetDocShell->GetError() )
+                {
+                    // error message ??
+                    ErrorHandler::HandleError( xTargetDocShell->GetError() );
+                    bNoError = false;
                 }
-
-                // Leave docshell available for caller (e.g. MM wizard)
-                if (!bMergeShell)
-                    xTargetDocShell->DoClose();
             }
+            else if( pTargetView ) // must be available!
+            {
+                //print the target document
+                // printing should be done synchronously otherwise the document
+                // might already become invalid during the process
+                uno::Sequence< beans::PropertyValue > aOptions( rMergeDescriptor.aPrintOptions );
 
-            //remove the temporary files
-            ::std::vector<OUString>::iterator aFileIter;
-            for(aFileIter = aFilesToRemove.begin();
-                        aFileIter != aFilesToRemove.end(); ++aFileIter)
-                SWUnoHelper::UCB_DeleteFile( *aFileIter );
+                aOptions.realloc( 1 );
+                aOptions[ 0 ].Name = "Wait";
+                aOptions[ 0 ].Value <<= sal_True ;
 
-            // unlock all dispatchers
-            pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
-            while (pViewFrame)
-            {
-                pViewFrame->GetDispatcher()->Lock(false);
-                pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pSourceDocSh);
-            }
+                SetPrinterOptions(rMergeDescriptor, aOptions);
 
-            SW_MOD()->SetView(&pSourceShell->GetView());
+                pTargetView->ExecPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync );
+            }
         }
+
+        // Leave docshell available for caller (e.g. MM wizard)
+        if (!bMergeShell)
+            xTargetDocShell->DoClose();
     }
 
-    if(bEMail)
+    return bNoError;
+}
+
+void SwDBManager::SetPrinterOptions(const SwMergeDescriptor &rMergeDescriptor, uno::Sequence< beans::PropertyValue > &aOptions)
+{
+    // move print options
+    const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
+    for( sal_Int32 nOption = 0, nIndex = aOptions.getLength() ; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
     {
-        xMailDispatcher->stop();
-        xMailDispatcher->shutdown();
+        if( pPrintOptions[nOption].Name == "CopyCount" || pPrintOptions[nOption].Name == "FileName"
+            || pPrintOptions[nOption].Name == "Collate" || pPrintOptions[nOption].Name == "Pages"
+            || pPrintOptions[nOption].Name == "Wait" || pPrintOptions[nOption].Name == "PrinterName" )
+        {
+            // add an option
+            aOptions.realloc( nIndex + 1 );
+            aOptions[ nIndex ].Name = pPrintOptions[nOption].Name;
+            aOptions[ nIndex++ ].Value = pPrintOptions[nOption].Value ;
+        }
     }
+}
 
-    return bNoError;
+void SwDBManager::RemoveTmpFiles(::std::vector< OUString> &aFilesToRemove)
+{
+    ::std::vector<OUString>::iterator aFileIter;
+    for(aFileIter = aFilesToRemove.begin();
+        aFileIter != aFilesToRemove.end(); ++aFileIter)
+        SWUnoHelper::UCB_DeleteFile( *aFileIter );
 }
 
 void SwDBManager::MergeCancel()
@@ -1827,11 +1967,11 @@ uno::Reference< sdbc::XConnection> SwDBManager::GetConnection(const OUString& rD
     return xConnection;
 }
 
-uno::Reference< sdbcx::XColumnsSupplier> SwDBManager::GetColumnSupplier(uno::Reference<sdbc::XConnection> xConnection,
+uno::Reference<sdbc::XRowSet> SwDBManager::GetRowSet(uno::Reference<sdbc::XConnection> xConnection,
                                     const OUString& rTableOrQuery,
                                     SwDBSelect   eTableOrQuery)
 {
-    uno::Reference< sdbcx::XColumnsSupplier> xRet;
+    uno::Reference<sdbc::XRowSet> xRet;
     try
     {
         if(eTableOrQuery == SwDBSelect::UNKNOWN)
@@ -1865,7 +2005,7 @@ uno::Reference< sdbcx::XColumnsSupplier> SwDBManager::GetColumnSupplier(uno::Ref
         xRowProperties->setPropertyValue("FetchSize", uno::makeAny((sal_Int32)10));
         xRowProperties->setPropertyValue("ActiveConnection", uno::makeAny(xConnection));
         xRowSet->execute();
-        xRet.set( xRowSet, uno::UNO_QUERY );
+        xRet = xRowSet;
     }
     catch (const uno::Exception& e)
     {
@@ -2052,7 +2192,7 @@ bool    SwDBManager::GetMergeColumnCnt(const OUString& rColumnName, sal_uInt16 n
 bool SwDBManager::ToNextMergeRecord()
 {
     OSL_ENSURE(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
-    return ToNextRecord(pImpl->pMergeData);
+    return ToNextRecord(pImpl->pMergeData, false);
 }
 
 bool SwDBManager::FillCalcWithMergeData( SvNumberFormatter *pDocFormatter,
@@ -2142,12 +2282,21 @@ bool SwDBManager::ToNextRecord(
         aData.nCommandType = -1;
         pFound = FindDSData(aData, false);
     }
-    return ToNextRecord(pFound);
+    return ToNextRecord(pFound, false);
 }
 
-bool SwDBManager::ToNextRecord(SwDSParam* pParam)
+
+bool SwDBManager::ToNextRecord(SwDSParam* pParam, bool bReset)
 {
     bool bRet = true;
+
+    if( bReset )
+    {
+        pParam->nSelectionIndex = 0;
+        pParam->bEndOfDB        =
+        pParam->bAfterSelection = false;
+    }
+
     if(!pParam || !pParam->xResultSet.is() || pParam->bEndOfDB ||
             (pParam->aSelection.getLength() && pParam->aSelection.getLength() <= pParam->nSelectionIndex))
     {
@@ -2167,6 +2316,11 @@ bool SwDBManager::ToNextRecord(SwDSParam* pParam)
             if(pParam->nSelectionIndex >= pParam->aSelection.getLength())
                 pParam->bEndOfDB = true;
         }
+        else if (bReset)
+        {
+            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
+            pImpl->pMergeData->CheckEndOfDB();
+        }
         else
         {
             sal_Int32 nBefore = pParam->xResultSet->getRow();
@@ -2182,8 +2336,11 @@ bool SwDBManager::ToNextRecord(SwDSParam* pParam)
             ++pParam->nSelectionIndex;
         }
     }
-    catch(const uno::Exception&)
+    catch(const uno::Exception &e)
     {
+        pParam->bEndOfDB = true;
+        pParam->CheckEndOfDB();
+        SAL_WARN("sw.mailmerge", "exception in ToNextRecord(): " << e.Message);
     }
     return bRet;
 }


More information about the Libreoffice-commits mailing list