Fixed for i#103021
[ooovba.git] / applied_patches / 0129-sw-mailmerge-faster.diff
blobde81d54e5e3929ed5e72a573c6f44953a619fa11
1 diff --git sw/source/ui/dbui/dbmgr.cxx sw/source/ui/dbui/dbmgr.cxx
2 index e17ff7b..d22779b 100644
3 --- sw/source/ui/dbui/dbmgr.cxx
4 +++ sw/source/ui/dbui/dbmgr.cxx
5 @@ -3147,27 +3147,28 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
6 pImpl->pMergeData = new SwDSParam(
7 rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection());
9 + SwDSParam* pMergeData = pImpl->pMergeData;
10 try{
11 //set to start position
12 - if(pImpl->pMergeData->aSelection.getLength())
13 + if(pMergeData->aSelection.getLength())
15 sal_Int32 nPos = 0;
16 - pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
17 - pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
18 - pImpl->pMergeData->CheckEndOfDB();
19 - if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
20 - pImpl->pMergeData->bEndOfDB = TRUE;
21 + pMergeData->aSelection.getConstArray()[ pMergeData->nSelectionIndex++ ] >>= nPos;
22 + pMergeData->bEndOfDB = !pMergeData->xResultSet->absolute( nPos );
23 + pMergeData->CheckEndOfDB();
24 + if(pMergeData->nSelectionIndex >= pMergeData->aSelection.getLength())
25 + pMergeData->bEndOfDB = TRUE;
27 else
29 - pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
30 - pImpl->pMergeData->CheckEndOfDB();
31 + pMergeData->bEndOfDB = !pMergeData->xResultSet->first();
32 + pMergeData->CheckEndOfDB();
35 catch(Exception&)
37 - pImpl->pMergeData->bEndOfDB = TRUE;
38 - pImpl->pMergeData->CheckEndOfDB();
39 + pMergeData->bEndOfDB = TRUE;
40 + pMergeData->CheckEndOfDB();
41 DBG_ERROR("exception in MergeNew()");
44 @@ -3246,56 +3247,50 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
45 long nStartRow, nEndRow;
46 ULONG nDocNo = 1;
47 sal_Int32 nDocCount = 0;
48 - if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) )
49 + if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pMergeData->xResultSet ) )
50 aMonitorDlg.SetTotalCount( nDocCount );
52 - do
53 + // create a new docshell from the temporary document
54 + SfxBoolItem aHidden( SID_HIDDEN, TRUE );
55 + SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii(URL_PREFIX_PRIV_SOFFICE ));
56 + SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
57 + SfxStringItem aURL( SID_FILE_NAME, sSourceDocURL );
58 + const SfxPoolItem* pReturnValue =
59 + rSourceView.GetViewFrame()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON,
60 + &aURL, &aFilterName, &aHidden, &aReferer, &aTarget, 0L);
62 + if(pReturnValue)
64 - nStartRow = pImpl->pMergeData->xResultSet->getRow();
65 - if (!IsMergeSilent())
66 + SfxViewFrameItem* pVItem = (SfxViewFrameItem*)pReturnValue;
67 + SwView* pWorkView = (SwView*) pVItem->GetFrame()->GetViewShell();
68 + SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
69 + pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird.
71 + // prepare workind document
72 + SwDoc* pWorkDoc = rWorkShell.GetDoc();
73 + SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
74 + pWorkDoc->SetNewDBMgr( this );
75 + pWorkDoc->EmbedAllLinks();
76 + if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds())
77 + rWorkShell.Undo();
78 + do
80 - aMonitorDlg.SetCurrentPosition( nDocNo );
81 - aMonitorDlg.Invalidate();
82 - aMonitorDlg.Update();
83 - // the print monitor needs some time to act
84 - for( USHORT i = 0; i < 25; i++)
85 - Application::Reschedule();
86 - }
87 + nStartRow = pMergeData->xResultSet->getRow();
88 + if (!IsMergeSilent())
89 + {
90 + aMonitorDlg.SetCurrentPosition( nDocNo );
91 + aMonitorDlg.Update();
92 + }
94 - // create a new docshell from the temporary document
95 - SfxBoolItem aHidden( SID_HIDDEN, TRUE );
96 - SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii(URL_PREFIX_PRIV_SOFFICE ));
97 - SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
98 - SfxStringItem aURL( SID_FILE_NAME, sSourceDocURL );
99 - const SfxPoolItem* pReturnValue =
100 - rSourceView.GetViewFrame()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON,
101 - &aURL, &aFilterName, &aHidden, &aReferer, &aTarget, 0L);
102 - if(pReturnValue)
104 - SfxViewFrameItem* pVItem = (SfxViewFrameItem*)pReturnValue;
105 - SwView* pWorkView = (SwView*) pVItem->GetFrame()->GetViewShell();
106 - SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
107 - pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird.
109 - // merge the data
110 - SwDoc* pWorkDoc = rWorkShell.GetDoc();
111 - SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
112 - pWorkDoc->SetNewDBMgr( this );
113 - pWorkDoc->EmbedAllLinks();
114 - if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds())
115 - rWorkShell.Undo();
116 // create a layout
117 rWorkShell.CalcLayout();
118 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
119 rWorkShell.ViewShell::UpdateFlds();
120 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
122 - // strip invisible content and convert fields to text
123 + // Ensure numbering is correct on target document
124 rWorkShell.RemoveInvisibleContent();
125 - rWorkShell.ConvertFieldsToText();
126 rWorkShell.SetNumberingRestart();
129 // insert the document into the target document
130 rWorkShell.SttEndDoc(FALSE);
131 rWorkShell.SttEndDoc(TRUE);
132 @@ -3346,6 +3341,7 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
135 pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );
136 + pTargetShell->ConvertFieldsToText();
137 //convert fields in page styles (header/footer - has to be done after the first document has been pasted
138 if(1 == nDocNo)
140 @@ -3362,21 +3358,28 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
141 rMMConfig.AddMergedDocument( aMergeInfo );
142 ++nRet;
144 - // the print monitor needs some time to act
145 - for( USHORT i = 0; i < 25; i++)
146 - Application::Reschedule();
148 - //restore the ole DBMgr
149 - pWorkDoc->SetNewDBMgr( pWorkDBMgr );
150 - //now the temporary document should be closed
151 - SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
152 - xDocSh->DoClose();
154 - nEndRow = pImpl->pMergeData->xResultSet->getRow();
155 - ++nDocNo;
156 - } while( !bCancel &&
157 + // Undo everything on current workshell allows to loop for a
158 + // merge action within the same document. It saves _loads_
159 + // of times : 7 times faster than the previous way.
160 + // see i40827 for more information
161 + const SwNodes *pUndoNds = pWorkDoc->GetUndoNds();
162 + if (pUndoNds)
164 + for( USHORT j = 0; j < pUndoNds->Count(); j++)
165 + rWorkShell.Undo();
167 + nEndRow = pMergeData->xResultSet->getRow();
168 + ++nDocNo;
169 + } while( !bCancel &&
170 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
172 + //restore the ole DBMgr
173 + pWorkDoc->SetNewDBMgr( pWorkDBMgr );
175 + //now the temporary document should be closed
176 + SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
177 + xDocSh->DoClose();
179 //deselect all, go out of the frame and go to the beginning of the document
180 Point aPt(LONG_MIN, LONG_MIN);
181 pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME);
182 @@ -3428,4 +3431,3 @@ void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource )