diff --git a/sw/inc/IDocumentFieldsAccess.hxx b/sw/inc/IDocumentFieldsAccess.hxx index f73e51c81d8e..83d65b5ca109 100644 --- a/sw/inc/IDocumentFieldsAccess.hxx +++ b/sw/inc/IDocumentFieldsAccess.hxx @@ -130,6 +130,8 @@ namespace com { namespace sun { namespace star { namespace uno { class Any; } } virtual void InsDelFieldInFieldLst(bool bIns, const SwTextField& rField) = 0; + virtual sal_Int32 GetRecordsPerDocument() const = 0; + protected: virtual ~IDocumentFieldsAccess() {}; }; diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx index c4062314ac00..49fef17220eb 100644 --- a/sw/source/core/doc/DocumentFieldsManager.cxx +++ b/sw/source/core/doc/DocumentFieldsManager.cxx @@ -911,7 +911,6 @@ void DocumentFieldsManager::UpdateExpFields( SwTextField* pUpdateField, bool bUp SwSection* pSect = const_cast((*it)->GetSection()); if( pSect ) { - SwSbxValue aValue = aCalc.Calculate( pSect->GetCondition() ); if(!aValue.IsVoidValue()) @@ -1184,6 +1183,38 @@ void DocumentFieldsManager::UpdateUsrFields() } } +sal_Int32 DocumentFieldsManager::GetRecordsPerDocument() const +{ + sal_Int32 nRecords = 1; + + mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL ); + if( mpUpdateFields->GetSortLst()->empty() ) + return nRecords; + + for( SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); + it != mpUpdateFields->GetSortLst()->end(); ++it ) + { + const SwTextField *pTextField = (*it)->GetTextField(); + if( !pTextField ) + continue; + + const SwFormatField &pFormatField = pTextField->GetFormatField(); + const SwField* pField = pFormatField.GetField(); + + switch( pField->GetTyp()->Which() ) + { + case RES_DBNEXTSETFLD: + case RES_DBNUMSETFLD: + nRecords++; + break; + default: + break; + } + } + + return nRecords; +} + void DocumentFieldsManager::UpdatePageFields( SfxPoolItem* pMsgHint ) { for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i ) diff --git a/sw/source/core/inc/DocumentFieldsManager.hxx b/sw/source/core/inc/DocumentFieldsManager.hxx index 260cb8be77b5..fb1ad7c8af8c 100644 --- a/sw/source/core/inc/DocumentFieldsManager.hxx +++ b/sw/source/core/inc/DocumentFieldsManager.hxx @@ -60,6 +60,7 @@ public: virtual bool IsNewFieldLst() const override; virtual void SetNewFieldLst( bool bFlag) override; virtual void InsDelFieldInFieldLst(bool bIns, const SwTextField& rField) override; + virtual sal_Int32 GetRecordsPerDocument() const override; //Non Interface methods diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx index 238f62d2e536..ff90ea629dba 100644 --- a/sw/source/uibase/dbui/dbmgr.cxx +++ b/sw/source/uibase/dbui/dbmgr.cxx @@ -178,10 +178,14 @@ static SfxObjectShell* lcl_CreateWorkingDocument( SwDBManager** const pDBManager, SwView** const pView, SwWrtShell** const pWrtShell, SwDoc** const pDoc ); -static bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference& xResultSet ) +static bool lcl_getCountFromResultSet( sal_Int32& rCount, const SwDSParam* pParam ) { - uno::Reference xPrSet(xResultSet, uno::UNO_QUERY); - if(xPrSet.is()) + rCount = pParam->aSelection.getLength(); + if ( rCount > 0 ) + return true; + + uno::Reference xPrSet(pParam->xResultSet, uno::UNO_QUERY); + if ( xPrSet.is() ) { try { @@ -190,8 +194,8 @@ static bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference>= bFinal; if(!bFinal) { - xResultSet->last(); - xResultSet->first(); + pParam->xResultSet->last(); + pParam->xResultSet->first(); } uno::Any aCount = xPrSet->getPropertyValue("RowCount"); if( aCount >>= rCount ) @@ -1264,16 +1268,33 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell, } sal_Int32 nDocNo = 1; - sal_Int32 nDocCount = 0; + // For single file mode, the number of pages in the target document so far, which is used // by AppendDoc() to adjust position of page-bound objects. Getting this information directly // from the target doc would require repeated layouts of the doc, which is expensive, but // it can be manually computed from the source documents (for which we do layouts, so the page // count is known, and there is a blank page between each of them in the target document). int targetDocPageCount = 0; - if( !bIsMergeSilent && !bMT_PRINTER && - lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) ) - static_cast( pProgressDlg.get() )->SetTotalCount( nDocCount ); + + if( !bIsMergeSilent && !bMT_PRINTER ) + { + sal_Int32 nRecordCount = 1; + lcl_getCountFromResultSet( nRecordCount, pImpl->pMergeData ); + + // syncronized docs don't auto-advance the record set, but there is a + // "security" check, which will always advance the record set, if there + // is no "next record" field in a synchronized doc => nRecordPerDoc > 0 + sal_Int32 nRecordPerDoc = pSourceShell->GetDoc() + ->getIDocumentFieldsAccess().GetRecordsPerDocument(); + if ( bSynchronizedDoc && (nRecordPerDoc > 1) ) + --nRecordPerDoc; + assert( nRecordPerDoc > 0 ); + + sal_Int32 nMaxDocs = nRecordCount / nRecordPerDoc; + if ( 0 != nRecordCount % nRecordPerDoc ) + nMaxDocs += 1; + static_cast( pProgressDlg.get() )->SetTotalCount( nMaxDocs ); + } long nStartRow, nEndRow; bool bFreezedLayouts = false;