--- sw/source/ui/dbui/dbmgr.cxx +++ sw/source/ui/dbui/dbmgr.cxx @@ -3147,27 +3147,28 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig, pImpl->pMergeData = new SwDSParam( rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection()); + SwDSParam* pMergeData = pImpl->pMergeData; try{ //set to start position - if(pImpl->pMergeData->aSelection.getLength()) + if(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; + pMergeData->aSelection.getConstArray()[ pMergeData->nSelectionIndex++ ] >>= nPos; + pMergeData->bEndOfDB = !pMergeData->xResultSet->absolute( nPos ); + pMergeData->CheckEndOfDB(); + if(pMergeData->nSelectionIndex >= pMergeData->aSelection.getLength()) + pMergeData->bEndOfDB = TRUE; } else { - pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first(); - pImpl->pMergeData->CheckEndOfDB(); + pMergeData->bEndOfDB = !pMergeData->xResultSet->first(); + pMergeData->CheckEndOfDB(); } } catch(Exception&) { - pImpl->pMergeData->bEndOfDB = TRUE; - pImpl->pMergeData->CheckEndOfDB(); + pMergeData->bEndOfDB = TRUE; + pMergeData->CheckEndOfDB(); DBG_ERROR("exception in MergeNew()"); } @@ -3246,56 +3247,50 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig, long nStartRow, nEndRow; ULONG nDocNo = 1; sal_Int32 nDocCount = 0; - if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) ) + if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pMergeData->xResultSet ) ) aMonitorDlg.SetTotalCount( nDocCount ); - do + // create a new docshell from the temporary document + SfxBoolItem aHidden( SID_HIDDEN, TRUE ); + SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii(URL_PREFIX_PRIV_SOFFICE )); + SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); + SfxStringItem aURL( SID_FILE_NAME, sSourceDocURL ); + const SfxPoolItem* pReturnValue = + rSourceView.GetViewFrame()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, + &aURL, &aFilterName, &aHidden, &aReferer, &aTarget, 0L); + + if(pReturnValue) { - nStartRow = pImpl->pMergeData->xResultSet->getRow(); - if (!IsMergeSilent()) + SfxViewFrameItem* pVItem = (SfxViewFrameItem*)pReturnValue; + SwView* pWorkView = (SwView*) pVItem->GetFrame()->GetViewShell(); + SwWrtShell& rWorkShell = pWorkView->GetWrtShell(); + pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird. + + // prepare workind document + SwDoc* pWorkDoc = rWorkShell.GetDoc(); + SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr(); + pWorkDoc->SetNewDBMgr( this ); + pWorkDoc->EmbedAllLinks(); + if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds()) + rWorkShell.Undo(); + do { - aMonitorDlg.SetCurrentPosition( nDocNo ); - aMonitorDlg.Invalidate(); - aMonitorDlg.Update(); - // the print monitor needs some time to act - for( USHORT i = 0; i < 25; i++) - Application::Reschedule(); - } + nStartRow = pMergeData->xResultSet->getRow(); + if (!IsMergeSilent()) + { + aMonitorDlg.SetCurrentPosition( nDocNo ); + aMonitorDlg.Update(); + } - // create a new docshell from the temporary document - SfxBoolItem aHidden( SID_HIDDEN, TRUE ); - SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii(URL_PREFIX_PRIV_SOFFICE )); - SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); - SfxStringItem aURL( SID_FILE_NAME, sSourceDocURL ); - const SfxPoolItem* pReturnValue = - rSourceView.GetViewFrame()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, - &aURL, &aFilterName, &aHidden, &aReferer, &aTarget, 0L); - if(pReturnValue) - { - SfxViewFrameItem* pVItem = (SfxViewFrameItem*)pReturnValue; - SwView* pWorkView = (SwView*) pVItem->GetFrame()->GetViewShell(); - SwWrtShell& rWorkShell = pWorkView->GetWrtShell(); - pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird. - - // merge the data - SwDoc* pWorkDoc = rWorkShell.GetDoc(); - SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr(); - pWorkDoc->SetNewDBMgr( this ); - pWorkDoc->EmbedAllLinks(); - if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds()) - rWorkShell.Undo(); // create a layout rWorkShell.CalcLayout(); SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, rWorkShell.GetView().GetViewFrame()->GetObjectShell())); rWorkShell.ViewShell::UpdateFlds(); SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, rWorkShell.GetView().GetViewFrame()->GetObjectShell())); - - // strip invisible content and convert fields to text + // Ensure numbering is correct on target document rWorkShell.RemoveInvisibleContent(); - rWorkShell.ConvertFieldsToText(); rWorkShell.SetNumberingRestart(); - // insert the document into the target document rWorkShell.SttEndDoc(FALSE); rWorkShell.SttEndDoc(TRUE); @@ -3346,6 +3341,7 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig, } } pTargetShell->Paste( rWorkShell.GetDoc(), sal_True ); + pTargetShell->ConvertFieldsToText(); //convert fields in page styles (header/footer - has to be done after the first document has been pasted if(1 == nDocNo) { @@ -3362,21 +3358,28 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig, rMMConfig.AddMergedDocument( aMergeInfo ); ++nRet; - // the print monitor needs some time to act - for( USHORT i = 0; i < 25; i++) - Application::Reschedule(); - - //restore the ole DBMgr - pWorkDoc->SetNewDBMgr( pWorkDBMgr ); - //now the temporary document should be closed - SfxObjectShellRef xDocSh(pWorkView->GetDocShell()); - xDocSh->DoClose(); - } - nEndRow = pImpl->pMergeData->xResultSet->getRow(); - ++nDocNo; - } while( !bCancel && + // Undo everything on current workshell allows to loop for a + // merge action within the same document. It saves _loads_ + // of times : 7 times faster than the previous way. + // see i40827 for more information + const SwNodes *pUndoNds = pWorkDoc->GetUndoNds(); + if (pUndoNds) + { + for( USHORT j = 0; j < pUndoNds->Count(); j++) + rWorkShell.Undo(); + } + nEndRow = pMergeData->xResultSet->getRow(); + ++nDocNo; + } while( !bCancel && (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord())); + //restore the ole DBMgr + pWorkDoc->SetNewDBMgr( pWorkDBMgr ); + + //now the temporary document should be closed + SfxObjectShellRef xDocSh(pWorkView->GetDocShell()); + xDocSh->DoClose(); + } //deselect all, go out of the frame and go to the beginning of the document Point aPt(LONG_MIN, LONG_MIN); pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME); @@ -3428,4 +3431,3 @@ void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource ) } } } -