summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorJuergen Funk <juergen.funk_ml@cib.de>2015-12-03 16:04:15 +0100
committerKatarina Behrens <Katarina.Behrens@cib.de>2015-12-21 10:34:59 +0000
commitd8ff907197037045fd0cb173e341f515968b65b1 (patch)
tree8a425e24a43dbb4507be1113d75608a541322dbf /sw/source
parent3725144bfa547fcb76d54e3e2c0977ac09c436f0 (diff)
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@cib.de> Tested-by: Katarina Behrens <Katarina.Behrens@cib.de>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/uibase/dbui/dbmgr.cxx995
1 files changed, 576 insertions, 419 deletions
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 0c0a7c7aaf2d..3074fde75728 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;
}