Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <cstdarg>
30 : :
31 : : #include <stdio.h>
32 : : #include <unotxdoc.hxx>
33 : : #include <com/sun/star/text/NotePrintMode.hpp>
34 : : #include <sfx2/app.hxx>
35 : : #include <com/sun/star/sdb/CommandType.hpp>
36 : : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
37 : : #include <com/sun/star/frame/XComponentLoader.hpp>
38 : : #include <com/sun/star/lang/DisposedException.hpp>
39 : : #include <com/sun/star/lang/XEventListener.hpp>
40 : : #include <com/sun/star/util/XNumberFormatter.hpp>
41 : : #include <com/sun/star/sdb/XCompletedConnection.hpp>
42 : : #include <com/sun/star/sdb/XCompletedExecution.hpp>
43 : : #include <com/sun/star/container/XChild.hpp>
44 : : #include <com/sun/star/text/MailMergeEvent.hpp>
45 : : #include <com/sun/star/frame/XStorable.hpp>
46 : : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
47 : : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
48 : : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
49 : : #include <com/sun/star/uno/XNamingService.hpp>
50 : : #include <com/sun/star/util/XCloseable.hpp>
51 : : #include <com/sun/star/beans/XPropertySet.hpp>
52 : : #include <sfx2/fcontnr.hxx>
53 : : #include <sfx2/filedlghelper.hxx>
54 : : #include <sfx2/viewfrm.hxx>
55 : : #include <dbconfig.hxx>
56 : : #include <swdbtoolsclient.hxx>
57 : : #include <pagedesc.hxx>
58 : : #include <vcl/lstbox.hxx>
59 : : #include <unotools/tempfile.hxx>
60 : : #include <unotools/pathoptions.hxx>
61 : : #include <svl/urihelper.hxx>
62 : : #include <svl/zforlist.hxx>
63 : : #include <svl/zformat.hxx>
64 : : #include <svl/stritem.hxx>
65 : : #include <svl/eitem.hxx>
66 : : #include <vcl/oldprintadaptor.hxx>
67 : : #include <sfx2/docfile.hxx>
68 : : #include <sfx2/progress.hxx>
69 : : #include <sfx2/dispatch.hxx>
70 : : #include <svl/mailenum.hxx>
71 : : #include <cmdid.h>
72 : : #include <swmodule.hxx>
73 : : #include <view.hxx>
74 : : #include <docsh.hxx>
75 : : #include <edtwin.hxx>
76 : : #include <wrtsh.hxx>
77 : : #include <fldbas.hxx>
78 : : #include <initui.hxx>
79 : : #include <swundo.hxx>
80 : : #include <flddat.hxx>
81 : : #include <modcfg.hxx>
82 : : #include <shellio.hxx>
83 : : #include <dbui.hxx>
84 : : #include <dbmgr.hxx>
85 : : #include <doc.hxx>
86 : : #include <swwait.hxx>
87 : : #include <swunohelper.hxx>
88 : : #include <dbui.hrc>
89 : : #include <globals.hrc>
90 : : #include <statstr.hrc>
91 : : #include <mmconfigitem.hxx>
92 : : #include <sfx2/request.hxx>
93 : : #include <hintids.hxx>
94 : : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
95 : : #include <com/sun/star/sdbc/XRowSet.hpp>
96 : : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
97 : : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
98 : : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
99 : : #include <com/sun/star/sdb/XColumn.hpp>
100 : : #include <com/sun/star/sdbc/DataType.hpp>
101 : : #include <com/sun/star/sdbc/ResultSetType.hpp>
102 : : #include <com/sun/star/mail/MailAttachment.hpp>
103 : : #include <comphelper/processfactory.hxx>
104 : : #include <comphelper/property.hxx>
105 : : #include <comphelper/string.hxx>
106 : : #include <comphelper/types.hxx>
107 : : #include <mailmergehelper.hxx>
108 : : #include <maildispatcher.hxx>
109 : : #include <svtools/htmlcfg.hxx>
110 : : #include <i18npool/mslangid.hxx>
111 : : #include <com/sun/star/util/XNumberFormatTypes.hpp>
112 : : #include <editeng/langitem.hxx>
113 : : #include <svl/numuno.hxx>
114 : :
115 : : #include <unomailmerge.hxx>
116 : : #include <sfx2/event.hxx>
117 : : #include <vcl/msgbox.hxx>
118 : : #include <svx/dataaccessdescriptor.hxx>
119 : : #include <osl/mutex.hxx>
120 : : #include <rtl/textenc.h>
121 : : #include <ndindex.hxx>
122 : : #include <pam.hxx>
123 : : #include <swcrsr.hxx>
124 : : #include <swevent.hxx>
125 : : #include <osl/file.hxx>
126 : : #include <swabstdlg.hxx>
127 : : #include <fmthdft.hxx>
128 : : #include <envelp.hrc>
129 : : #include <memory>
130 : : #include <vector>
131 : : #include <unomid.h>
132 : : #include <section.hxx>
133 : :
134 : : using namespace ::osl;
135 : : using namespace ::svx;
136 : : using namespace ::com::sun::star;
137 : : using namespace ::com::sun::star::text;
138 : : using namespace ::com::sun::star::uno;
139 : : using namespace ::com::sun::star::container;
140 : : using namespace ::com::sun::star::frame;
141 : : using namespace ::com::sun::star::lang;
142 : : using namespace ::com::sun::star::sdb;
143 : : using namespace ::com::sun::star::sdbc;
144 : : using namespace ::com::sun::star::sdbcx;
145 : : using namespace ::com::sun::star::beans;
146 : : using namespace ::com::sun::star::util;
147 : : using namespace ::com::sun::star::task;
148 : : using namespace ::com::sun::star::ui::dialogs;
149 : :
150 : : #define DB_SEP_SPACE 0
151 : : #define DB_SEP_TAB 1
152 : : #define DB_SEP_RETURN 2
153 : : #define DB_SEP_NEWLINE 3
154 : :
155 : : const sal_Char cCursor[] = "Cursor";
156 : : const sal_Char cCommand[] = "Command";
157 : : const sal_Char cCommandType[] = "CommandType";
158 : : const sal_Char cDataSourceName[] = "DataSourceName";
159 : : const sal_Char cSelection[] = "Selection";
160 : : const sal_Char cActiveConnection[] = "ActiveConnection";
161 : :
162 : : // -----------------------------------------------------------------------------
163 : : // Use nameless namespace to avoid to rubbish the global namespace
164 : : // -----------------------------------------------------------------------------
165 : : namespace
166 : : {
167 : :
168 : 0 : bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference<XResultSet>& xResultSet )
169 : : {
170 [ # # ]: 0 : uno::Reference<XPropertySet> xPrSet(xResultSet, UNO_QUERY);
171 [ # # ]: 0 : if(xPrSet.is())
172 : : {
173 : : try
174 : : {
175 : 0 : sal_Bool bFinal = sal_False;
176 [ # # ][ # # ]: 0 : Any aFinal = xPrSet->getPropertyValue(C2U("IsRowCountFinal"));
[ # # ]
177 : 0 : aFinal >>= bFinal;
178 [ # # ]: 0 : if(!bFinal)
179 : : {
180 [ # # ][ # # ]: 0 : xResultSet->last();
181 [ # # ][ # # ]: 0 : xResultSet->first();
182 : : }
183 [ # # ][ # # ]: 0 : Any aCount = xPrSet->getPropertyValue(C2U("RowCount"));
[ # # ]
184 [ # # ]: 0 : if( aCount >>= rCount )
185 [ # # ][ # # ]: 0 : return true;
[ # # ]
186 : : }
187 [ # # ]: 0 : catch(const Exception&)
188 : : {
189 : : }
190 : : }
191 : 0 : return false;
192 : : }
193 : : // copy compatibility options
194 : 0 : void lcl_CopyCompatibilityOptions( SwWrtShell& rSourceShell, SwWrtShell& rTargetShell)
195 : : {
196 : 0 : IDocumentSettingAccess* pIDsa = rSourceShell.getIDocumentSettingAccess();
197 : :
198 : 0 : rTargetShell.SetParaSpaceMax( pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX));
199 : 0 : rTargetShell.SetParaSpaceMaxAtPages(pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES));
200 : 0 : rTargetShell.SetTabCompat( pIDsa->get(IDocumentSettingAccess::TAB_COMPAT));
201 : 0 : rTargetShell.SetAddExtLeading( pIDsa->get(IDocumentSettingAccess::ADD_EXT_LEADING));
202 : 0 : rTargetShell.SetUseVirDev( pIDsa->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE));
203 : 0 : rTargetShell.SetAddParaSpacingToTableCells( pIDsa->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS));
204 : 0 : rTargetShell.SetUseFormerLineSpacing( pIDsa->get(IDocumentSettingAccess::OLD_LINE_SPACING));
205 : 0 : rTargetShell.SetUseFormerObjectPositioning( pIDsa->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS));
206 : 0 : rTargetShell.SetConsiderWrapOnObjPos( pIDsa->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION));
207 : 0 : rTargetShell.SetUseFormerTextWrapping( pIDsa->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING));
208 : 0 : }
209 : : }
210 : :
211 : : class SwConnectionDisposedListener_Impl : public cppu::WeakImplHelper1
212 : : < lang::XEventListener >
213 : : {
214 : : SwNewDBMgr& rDBMgr;
215 : :
216 : : virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
217 : : public:
218 : : SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr);
219 : : ~SwConnectionDisposedListener_Impl();
220 : :
221 : : };
222 : :
223 : 1458 : struct SwNewDBMgr_Impl
224 : : {
225 : : SwDSParam* pMergeData;
226 : : AbstractMailMergeDlg* pMergeDialog;
227 : : uno::Reference<lang::XEventListener> xDisposeListener;
228 : :
229 : 1549 : SwNewDBMgr_Impl(SwNewDBMgr& rDBMgr)
230 : : :pMergeData(0)
231 : : ,pMergeDialog(0)
232 [ + - ][ + - ]: 1549 : ,xDisposeListener(new SwConnectionDisposedListener_Impl(rDBMgr))
233 : 1549 : {}
234 : : };
235 : :
236 : 0 : void lcl_InitNumberFormatter(SwDSParam& rParam, uno::Reference<XDataSource> xSource)
237 : : {
238 [ # # ]: 0 : uno::Reference<XMultiServiceFactory> xMgr = ::comphelper::getProcessServiceFactory();
239 [ # # ]: 0 : if( xMgr.is() )
240 : : {
241 [ # # ][ # # ]: 0 : uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.util.NumberFormatter" ));
[ # # ]
242 [ # # ][ # # ]: 0 : rParam.xFormatter = uno::Reference<util::XNumberFormatter>(xInstance, UNO_QUERY) ;
243 : : }
244 [ # # ]: 0 : if(!xSource.is())
245 [ # # ][ # # ]: 0 : xSource = SwNewDBMgr::getDataSourceAsParent(rParam.xConnection, rParam.sDataSource);
246 : :
247 [ # # ]: 0 : uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
248 [ # # ]: 0 : if(xSourceProps.is())
249 : : {
250 [ # # ][ # # ]: 0 : Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier"));
[ # # ]
251 [ # # ]: 0 : if(aFormats.hasValue())
252 : : {
253 : 0 : uno::Reference<XNumberFormatsSupplier> xSuppl;
254 [ # # ]: 0 : aFormats >>= xSuppl;
255 [ # # ]: 0 : if(xSuppl.is())
256 : : {
257 [ # # ][ # # ]: 0 : uno::Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings();
258 [ # # ][ # # ]: 0 : Any aNull = xSettings->getPropertyValue(C2U("NullDate"));
[ # # ]
259 [ # # ]: 0 : aNull >>= rParam.aNullDate;
260 [ # # ]: 0 : if(rParam.xFormatter.is())
261 [ # # ][ # # ]: 0 : rParam.xFormatter->attachNumberFormatsSupplier(xSuppl);
262 : 0 : }
263 : 0 : }
264 : 0 : }
265 : 0 : }
266 : :
267 : 0 : sal_Bool lcl_MoveAbsolute(SwDSParam* pParam, long nAbsPos)
268 : : {
269 : 0 : sal_Bool bRet = sal_False;
270 : : try
271 : : {
272 [ # # ]: 0 : if(pParam->bScrollable)
273 : : {
274 [ # # ][ # # ]: 0 : bRet = pParam->xResultSet->absolute( nAbsPos );
275 : : }
276 : : else
277 : : {
278 : : OSL_FAIL("no absolute positioning available");
279 : : }
280 : : }
281 : 0 : catch(const Exception&)
282 : : {
283 : : }
284 [ # # ]: 0 : return bRet;
285 : : }
286 : :
287 : 0 : sal_Bool lcl_GetColumnCnt(SwDSParam* pParam,
288 : : const String& rColumnName, long nLanguage, rtl::OUString& rResult, double* pNumber)
289 : : {
290 [ # # ]: 0 : uno::Reference< XColumnsSupplier > xColsSupp( pParam->xResultSet, UNO_QUERY );
291 : 0 : uno::Reference<XNameAccess> xCols;
292 : : try
293 : : {
294 [ # # ][ # # ]: 0 : xCols = xColsSupp->getColumns();
[ # # ][ # # ]
295 : : }
296 [ # # ]: 0 : catch(const lang::DisposedException&)
297 : : {
298 : : }
299 [ # # ][ # # ]: 0 : if(!xCols.is() || !xCols->hasByName(rColumnName))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
300 : 0 : return sal_False;
301 [ # # ][ # # ]: 0 : Any aCol = xCols->getByName(rColumnName);
[ # # ]
302 : 0 : uno::Reference< XPropertySet > xColumnProps;
303 [ # # ]: 0 : aCol >>= xColumnProps;
304 : :
305 [ # # ]: 0 : SwDBFormatData aFormatData;
306 [ # # ]: 0 : if(!pParam->xFormatter.is())
307 : : {
308 : : uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(
309 [ # # ]: 0 : pParam->xConnection,pParam->sDataSource);
310 [ # # ]: 0 : lcl_InitNumberFormatter(*pParam, xSource );
311 : : }
312 : 0 : aFormatData.aNullDate = pParam->aNullDate;
313 [ # # ]: 0 : aFormatData.xFormatter = pParam->xFormatter;
314 : :
315 [ # # ]: 0 : MsLangId::convertLanguageToLocale( (LanguageType)nLanguage, aFormatData.aLocale );
316 : :
317 [ # # ][ # # ]: 0 : rResult = SwNewDBMgr::GetDBField( xColumnProps, aFormatData, pNumber);
[ # # ]
318 [ # # ]: 0 : return sal_True;
319 : : };
320 : :
321 : : /*--------------------------------------------------------------------
322 : : Description: import data
323 : : --------------------------------------------------------------------*/
324 : 0 : sal_Bool SwNewDBMgr::MergeNew(const SwMergeDescriptor& rMergeDesc )
325 : : {
326 : 0 : SetMergeType( rMergeDesc.nMergeType );
327 : :
328 : : OSL_ENSURE(!bInMerge && !pImpl->pMergeData, "merge already activated!");
329 : :
330 : 0 : SwDBData aData;
331 : 0 : aData.nCommandType = CommandType::TABLE;
332 : 0 : uno::Reference<XResultSet> xResSet;
333 [ # # ]: 0 : Sequence<Any> aSelection;
334 : 0 : uno::Reference< XConnection> xConnection;
335 : :
336 [ # # ]: 0 : aData.sDataSource = rMergeDesc.rDescriptor.getDataSource();
337 [ # # ]: 0 : rMergeDesc.rDescriptor[daCommand] >>= aData.sCommand;
338 [ # # ]: 0 : rMergeDesc.rDescriptor[daCommandType] >>= aData.nCommandType;
339 : :
340 [ # # ][ # # ]: 0 : if ( rMergeDesc.rDescriptor.has(daCursor) )
341 [ # # ][ # # ]: 0 : rMergeDesc.rDescriptor[daCursor] >>= xResSet;
342 [ # # ][ # # ]: 0 : if ( rMergeDesc.rDescriptor.has(daSelection) )
343 [ # # ][ # # ]: 0 : rMergeDesc.rDescriptor[daSelection] >>= aSelection;
344 [ # # ][ # # ]: 0 : if ( rMergeDesc.rDescriptor.has(daConnection) )
345 [ # # ][ # # ]: 0 : rMergeDesc.rDescriptor[daConnection] >>= xConnection;
346 : :
347 [ # # ][ # # ]: 0 : if(aData.sDataSource.isEmpty() || aData.sCommand.isEmpty() || !xResSet.is())
[ # # ][ # # ]
348 : : {
349 : 0 : return sal_False;
350 : : }
351 : :
352 [ # # ][ # # ]: 0 : pImpl->pMergeData = new SwDSParam(aData, xResSet, aSelection);
353 [ # # ]: 0 : SwDSParam* pTemp = FindDSData(aData, sal_False);
354 [ # # ]: 0 : if(pTemp)
355 [ # # ]: 0 : *pTemp = *pImpl->pMergeData;
356 : : else
357 : : {
358 : : // calls from the calculator may have added a connection with an invalid commandtype
359 : : //"real" data base connections added here have to re-use the already available
360 : : //DSData and set the correct CommandType
361 : 0 : SwDBData aTempData(aData);
362 : 0 : aData.nCommandType = -1;
363 [ # # ]: 0 : pTemp = FindDSData(aData, sal_False);
364 [ # # ]: 0 : if(pTemp)
365 [ # # ]: 0 : *pTemp = *pImpl->pMergeData;
366 : : else
367 : : {
368 [ # # ][ # # ]: 0 : SwDSParam* pInsert = new SwDSParam(*pImpl->pMergeData);
369 [ # # ]: 0 : aDataSourceParams.push_back(pInsert);
370 : : try
371 : : {
372 [ # # ]: 0 : uno::Reference<XComponent> xComponent(pInsert->xConnection, UNO_QUERY);
373 [ # # ]: 0 : if(xComponent.is())
374 [ # # ][ # # ]: 0 : xComponent->addEventListener(pImpl->xDisposeListener);
[ # # ]
375 : : }
376 [ # # ]: 0 : catch(const Exception&)
377 : : {
378 : : }
379 [ # # ]: 0 : }
380 : : }
381 [ # # ]: 0 : if(!pImpl->pMergeData->xConnection.is())
382 [ # # ]: 0 : pImpl->pMergeData->xConnection = xConnection;
383 : : // add an XEventListener
384 : :
385 : : try{
386 : : //set to start position
387 [ # # ]: 0 : if(pImpl->pMergeData->aSelection.getLength())
388 : : {
389 : 0 : sal_Int32 nPos = 0;
390 : 0 : pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
391 [ # # ][ # # ]: 0 : pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
392 : 0 : pImpl->pMergeData->CheckEndOfDB();
393 [ # # ]: 0 : if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
394 : 0 : pImpl->pMergeData->bEndOfDB = sal_True;
395 : : }
396 : : else
397 : : {
398 [ # # ][ # # ]: 0 : pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
399 : 0 : pImpl->pMergeData->CheckEndOfDB();
400 : : }
401 : : }
402 [ # # ]: 0 : catch(const Exception&)
403 : : {
404 : 0 : pImpl->pMergeData->bEndOfDB = sal_True;
405 : 0 : pImpl->pMergeData->CheckEndOfDB();
406 : : OSL_FAIL("exception in MergeNew()");
407 : : }
408 : :
409 [ # # ]: 0 : uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,aData.sDataSource);
410 : :
411 [ # # ]: 0 : lcl_InitNumberFormatter(*pImpl->pMergeData, xSource);
412 : :
413 [ # # ]: 0 : rMergeDesc.rSh.ChgDBData(aData);
414 : 0 : bInMerge = sal_True;
415 : :
416 [ # # ]: 0 : if (IsInitDBFields())
417 : : {
418 : : // with database fields without DB-Name, use DB-Name from Doc
419 [ # # ]: 0 : std::vector<String> aDBNames;
420 [ # # ][ # # ]: 0 : aDBNames.push_back(String());
[ # # ]
421 [ # # ]: 0 : SwDBData aInsertData = rMergeDesc.rSh.GetDBData();
422 [ # # ]: 0 : String sDBName = aInsertData.sDataSource;
423 [ # # ]: 0 : sDBName += DB_DELIM;
424 [ # # ][ # # ]: 0 : sDBName += (String)aInsertData.sCommand;
[ # # ]
425 [ # # ]: 0 : sDBName += DB_DELIM;
426 [ # # ][ # # ]: 0 : sDBName += String::CreateFromInt32(aInsertData.nCommandType);
[ # # ]
427 [ # # ]: 0 : rMergeDesc.rSh.ChangeDBFields( aDBNames, sDBName);
428 [ # # ]: 0 : SetInitDBFields(sal_False);
429 : : }
430 : :
431 : 0 : sal_Bool bRet = sal_True;
432 [ # # # ]: 0 : switch(rMergeDesc.nMergeType)
433 : : {
434 : : case DBMGR_MERGE:
435 [ # # ]: 0 : bRet = Merge(&rMergeDesc.rSh);
436 : 0 : break;
437 : :
438 : : case DBMGR_MERGE_MAILMERGE: // printing merge from 'old' merge dialog or from UNO-component
439 : : case DBMGR_MERGE_MAILING:
440 : : case DBMGR_MERGE_MAILFILES:
441 : : case DBMGR_MERGE_SINGLE_FILE:
442 : : // save files and send them as e-Mail if required
443 : : bRet = MergeMailFiles(&rMergeDesc.rSh,
444 [ # # ]: 0 : rMergeDesc);
445 : 0 : break;
446 : :
447 : : default:
448 : : // insert selected entries
449 : : // (was: InsertRecord)
450 [ # # ]: 0 : ImportFromConnection(&rMergeDesc.rSh);
451 : 0 : break;
452 : : }
453 : :
454 [ # # ]: 0 : EndMerge();
455 [ # # ]: 0 : return bRet;
456 : : }
457 : :
458 : : /*--------------------------------------------------------------------
459 : : Description: import data
460 : : --------------------------------------------------------------------*/
461 : 0 : sal_Bool SwNewDBMgr::Merge(SwWrtShell* pSh)
462 : : {
463 : 0 : pSh->StartAllAction();
464 : :
465 : 0 : pSh->ViewShell::UpdateFlds(sal_True);
466 : 0 : pSh->SetModified();
467 : :
468 : 0 : pSh->EndAllAction();
469 : :
470 : 0 : return sal_True;
471 : : }
472 : :
473 : 0 : void SwNewDBMgr::ImportFromConnection( SwWrtShell* pSh )
474 : : {
475 [ # # ][ # # ]: 0 : if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB)
476 : : {
477 : : {
478 : 0 : pSh->StartAllAction();
479 : 0 : pSh->StartUndo(UNDO_EMPTY);
480 : 0 : sal_Bool bGroupUndo(pSh->DoesGroupUndo());
481 : 0 : pSh->DoGroupUndo(sal_False);
482 : :
483 [ # # ]: 0 : if( pSh->HasSelection() )
484 : 0 : pSh->DelRight();
485 : :
486 : 0 : SwWait *pWait = 0;
487 : :
488 : : {
489 : 0 : sal_uLong i = 0;
490 [ # # ]: 0 : do {
491 : :
492 : 0 : ImportDBEntry(pSh);
493 [ # # ]: 0 : if( 10 == ++i )
494 [ # # ]: 0 : pWait = new SwWait( *pSh->GetView().GetDocShell(), sal_True);
495 : :
496 : 0 : } while(ToNextMergeRecord());
497 : : }
498 : :
499 : 0 : pSh->DoGroupUndo(bGroupUndo);
500 : 0 : pSh->EndUndo(UNDO_EMPTY);
501 : 0 : pSh->EndAllAction();
502 [ # # ]: 0 : delete pWait;
503 : : }
504 : : }
505 : 0 : }
506 : :
507 : 0 : String lcl_FindColumn(const String& sFormatStr,sal_uInt16 &nUsedPos, sal_uInt8 &nSeparator)
508 : : {
509 : 0 : String sReturn;
510 : 0 : sal_uInt16 nLen = sFormatStr.Len();
511 : 0 : nSeparator = 0xff;
512 [ # # ][ # # ]: 0 : while(nUsedPos < nLen && nSeparator == 0xff)
[ # # ]
513 : : {
514 : 0 : sal_Unicode cAkt = sFormatStr.GetChar(nUsedPos);
515 [ # # # # : 0 : switch(cAkt)
# ]
516 : : {
517 : : case ',':
518 : 0 : nSeparator = DB_SEP_SPACE;
519 : 0 : break;
520 : : case ';':
521 : 0 : nSeparator = DB_SEP_RETURN;
522 : 0 : break;
523 : : case ':':
524 : 0 : nSeparator = DB_SEP_TAB;
525 : 0 : break;
526 : : case '#':
527 : 0 : nSeparator = DB_SEP_NEWLINE;
528 : 0 : break;
529 : : default:
530 [ # # ]: 0 : sReturn += cAkt;
531 : : }
532 : 0 : nUsedPos++;
533 : :
534 : : }
535 : 0 : return sReturn;
536 : : }
537 : :
538 : 0 : void SwNewDBMgr::ImportDBEntry(SwWrtShell* pSh)
539 : : {
540 [ # # ][ # # ]: 0 : if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB)
541 : : {
542 [ # # ]: 0 : uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
543 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
544 [ # # ]: 0 : String sFormatStr;
545 : 0 : sal_uInt16 nFmtLen = sFormatStr.Len();
546 [ # # ]: 0 : if( nFmtLen )
547 : : {
548 : 0 : const char cSpace = ' ';
549 : 0 : const char cTab = '\t';
550 : 0 : sal_uInt16 nUsedPos = 0;
551 : : sal_uInt8 nSeparator;
552 [ # # ]: 0 : String sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator);
553 [ # # ]: 0 : while( sColumn.Len() )
554 : : {
555 [ # # ][ # # ]: 0 : if(!xCols->hasByName(sColumn))
[ # # ][ # # ]
556 : 0 : return;
557 [ # # ][ # # ]: 0 : Any aCol = xCols->getByName(sColumn);
[ # # ]
558 : 0 : uno::Reference< XPropertySet > xColumnProp;
559 [ # # ]: 0 : aCol >>= xColumnProp;
560 [ # # ]: 0 : if(xColumnProp.is())
561 : : {
562 [ # # ]: 0 : SwDBFormatData aDBFormat;
563 [ # # ]: 0 : String sInsert = GetDBField( xColumnProp, aDBFormat);
564 [ # # ]: 0 : if( DB_SEP_SPACE == nSeparator )
565 [ # # ]: 0 : sInsert += cSpace;
566 [ # # ]: 0 : else if( DB_SEP_TAB == nSeparator)
567 [ # # ]: 0 : sInsert += cTab;
568 [ # # ]: 0 : pSh->Insert(sInsert);
569 [ # # ]: 0 : if( DB_SEP_RETURN == nSeparator)
570 [ # # ]: 0 : pSh->SplitNode();
571 [ # # ]: 0 : else if(DB_SEP_NEWLINE == nSeparator)
572 [ # # ][ # # ]: 0 : pSh->InsertLineBreak();
[ # # ]
573 : : }
574 : : else
575 : : {
576 : : // column not found -> show error
577 : 0 : rtl::OUStringBuffer sInsert;
578 [ # # ][ # # ]: 0 : sInsert.append('?').append(sColumn).append('?');
[ # # ][ # # ]
579 [ # # ][ # # ]: 0 : pSh->Insert(sInsert.makeStringAndClear());
[ # # ][ # # ]
580 : : }
581 [ # # ][ # # ]: 0 : sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator);
[ # # ]
582 : 0 : }
583 [ # # ][ # # ]: 0 : pSh->SplitNode();
[ # # ]
584 : : }
585 : : else
586 : : {
587 [ # # ]: 0 : String sStr;
588 [ # # ][ # # ]: 0 : Sequence<rtl::OUString> aColNames = xCols->getElementNames();
589 : 0 : const rtl::OUString* pColNames = aColNames.getConstArray();
590 : 0 : long nLength = aColNames.getLength();
591 [ # # ]: 0 : for(long i = 0; i < nLength; i++)
592 : : {
593 [ # # ][ # # ]: 0 : Any aCol = xCols->getByName(pColNames[i]);
594 : 0 : uno::Reference< XPropertySet > xColumnProp;
595 [ # # ]: 0 : aCol >>= xColumnProp;
596 [ # # ]: 0 : SwDBFormatData aDBFormat;
597 [ # # ][ # # ]: 0 : sStr += GetDBField( xColumnProp, aDBFormat);
[ # # ]
598 [ # # ]: 0 : if (i < nLength - 1)
599 [ # # ]: 0 : sStr += '\t';
600 [ # # ]: 0 : }
601 [ # # ]: 0 : pSh->SwEditShell::Insert2(sStr);
602 [ # # ][ # # ]: 0 : pSh->SwFEShell::SplitNode(); // line feed
[ # # ]
603 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
604 : : }
605 : : }
606 : :
607 : : /*--------------------------------------------------------------------
608 : : Description: fill Listbox with tablelist
609 : : --------------------------------------------------------------------*/
610 : 0 : sal_Bool SwNewDBMgr::GetTableNames(ListBox* pListBox, const String& rDBName)
611 : : {
612 : 0 : sal_Bool bRet = sal_False;
613 [ # # ]: 0 : String sOldTableName(pListBox->GetSelectEntry());
614 [ # # ]: 0 : pListBox->Clear();
615 [ # # ][ # # ]: 0 : SwDSParam* pParam = FindDSConnection(rDBName, sal_False);
616 : 0 : uno::Reference< XConnection> xConnection;
617 [ # # ][ # # ]: 0 : if(pParam && pParam->xConnection.is())
[ # # ]
618 [ # # ]: 0 : xConnection = pParam->xConnection;
619 : : else
620 : : {
621 [ # # ]: 0 : rtl::OUString sDBName(rDBName);
622 [ # # ]: 0 : if ( !sDBName.isEmpty() )
623 [ # # ][ # # ]: 0 : xConnection = RegisterConnection( sDBName );
624 : : }
625 [ # # ]: 0 : if(xConnection.is())
626 : : {
627 [ # # ]: 0 : uno::Reference<XTablesSupplier> xTSupplier = uno::Reference<XTablesSupplier>(xConnection, UNO_QUERY);
628 [ # # ]: 0 : if(xTSupplier.is())
629 : : {
630 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xTbls = xTSupplier->getTables();
631 [ # # ][ # # ]: 0 : Sequence<rtl::OUString> aTbls = xTbls->getElementNames();
632 : 0 : const rtl::OUString* pTbls = aTbls.getConstArray();
633 [ # # ]: 0 : for(long i = 0; i < aTbls.getLength(); i++)
634 : : {
635 [ # # ][ # # ]: 0 : sal_uInt16 nEntry = pListBox->InsertEntry(pTbls[i]);
[ # # ]
636 [ # # ]: 0 : pListBox->SetEntryData(nEntry, (void*)0);
637 [ # # ]: 0 : }
638 : : }
639 [ # # ]: 0 : uno::Reference<XQueriesSupplier> xQSupplier = uno::Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
640 [ # # ]: 0 : if(xQSupplier.is())
641 : : {
642 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries();
643 [ # # ][ # # ]: 0 : Sequence<rtl::OUString> aQueries = xQueries->getElementNames();
644 : 0 : const rtl::OUString* pQueries = aQueries.getConstArray();
645 [ # # ]: 0 : for(long i = 0; i < aQueries.getLength(); i++)
646 : : {
647 [ # # ][ # # ]: 0 : sal_uInt16 nEntry = pListBox->InsertEntry(pQueries[i]);
[ # # ]
648 [ # # ]: 0 : pListBox->SetEntryData(nEntry, (void*)1);
649 [ # # ]: 0 : }
650 : : }
651 [ # # ]: 0 : if (sOldTableName.Len())
652 [ # # ]: 0 : pListBox->SelectEntry(sOldTableName);
653 : 0 : bRet = sal_True;
654 : : }
655 [ # # ]: 0 : return bRet;
656 : : }
657 : :
658 : : /*--------------------------------------------------------------------
659 : : Description: fill Listbox with column names of a database
660 : : --------------------------------------------------------------------*/
661 : 0 : sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox,
662 : : const String& rDBName, const String& rTableName, sal_Bool bAppend)
663 : : {
664 [ # # ]: 0 : if (!bAppend)
665 [ # # ]: 0 : pListBox->Clear();
666 : 0 : SwDBData aData;
667 [ # # ]: 0 : aData.sDataSource = rDBName;
668 [ # # ]: 0 : aData.sCommand = rTableName;
669 : 0 : aData.nCommandType = -1;
670 [ # # ]: 0 : SwDSParam* pParam = FindDSData(aData, sal_False);
671 : 0 : uno::Reference< XConnection> xConnection;
672 [ # # ][ # # ]: 0 : if(pParam && pParam->xConnection.is())
[ # # ]
673 [ # # ]: 0 : xConnection = pParam->xConnection;
674 : : else
675 : : {
676 [ # # ]: 0 : rtl::OUString sDBName(rDBName);
677 [ # # ][ # # ]: 0 : xConnection = RegisterConnection( sDBName );
678 : : }
679 [ # # ]: 0 : uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
680 [ # # ]: 0 : if(xColsSupp.is())
681 : : {
682 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
683 [ # # ][ # # ]: 0 : const Sequence<rtl::OUString> aColNames = xCols->getElementNames();
684 : 0 : const rtl::OUString* pColNames = aColNames.getConstArray();
685 [ # # ]: 0 : for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
686 : : {
687 [ # # ][ # # ]: 0 : pListBox->InsertEntry(pColNames[nCol]);
[ # # ]
688 : : }
689 [ # # ][ # # ]: 0 : ::comphelper::disposeComponent( xColsSupp );
690 : : }
691 : 0 : return(sal_True);
692 : : }
693 : :
694 : 0 : sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox,
695 : : uno::Reference< XConnection> xConnection,
696 : : const String& rTableName, sal_Bool bAppend)
697 : : {
698 [ # # ]: 0 : if (!bAppend)
699 [ # # ]: 0 : pListBox->Clear();
700 [ # # ]: 0 : uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
701 [ # # ]: 0 : if(xColsSupp.is())
702 : : {
703 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
704 [ # # ][ # # ]: 0 : const Sequence<rtl::OUString> aColNames = xCols->getElementNames();
705 : 0 : const rtl::OUString* pColNames = aColNames.getConstArray();
706 [ # # ]: 0 : for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
707 : : {
708 [ # # ][ # # ]: 0 : pListBox->InsertEntry(pColNames[nCol]);
[ # # ]
709 : : }
710 [ # # ][ # # ]: 0 : ::comphelper::disposeComponent( xColsSupp );
711 : : }
712 : 0 : return(sal_True);
713 : : }
714 : :
715 : : /*--------------------------------------------------------------------
716 : : Description: CTOR
717 : : --------------------------------------------------------------------*/
718 : 1549 : SwNewDBMgr::SwNewDBMgr() :
719 : : nMergeType(DBMGR_INSERT),
720 : : bInitDBFields(sal_False),
721 : : bInMerge(sal_False),
722 : : bMergeSilent(sal_False),
723 : : bMergeLock(sal_False),
724 [ + - ]: 1549 : pImpl(new SwNewDBMgr_Impl(*this)),
725 [ + - ][ + - ]: 1549 : pMergeEvtSrc(NULL)
[ + - ][ + - ]
726 : : {
727 : 1549 : }
728 : :
729 [ + - ][ + - ]: 1458 : SwNewDBMgr::~SwNewDBMgr()
[ + - ]
730 : : {
731 [ - + ]: 1458 : for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.size(); nPos++)
732 : : {
733 [ # # ]: 0 : SwDSParam* pParam = &aDataSourceParams[nPos];
734 [ # # ]: 0 : if(pParam->xConnection.is())
735 : : {
736 : : try
737 : : {
738 [ # # ]: 0 : uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY);
739 [ # # ]: 0 : if(xComp.is())
740 [ # # ][ # # ]: 0 : xComp->dispose();
[ # # ]
741 : : }
742 [ # # ]: 0 : catch(const RuntimeException&)
743 : : {
744 : : //may be disposed already since multiple entries may have used the same connection
745 : : }
746 : : }
747 : : }
748 [ + - ][ + - ]: 1458 : delete pImpl;
749 : 1458 : }
750 : :
751 : : /*--------------------------------------------------------------------
752 : : Description: save bulk letters as single documents
753 : : --------------------------------------------------------------------*/
754 : 0 : String lcl_FindUniqueName(SwWrtShell* pTargetShell, const String& rStartingPageDesc, sal_uLong nDocNo )
755 : : {
756 : 0 : do
757 : : {
758 [ # # ]: 0 : String sTest = rStartingPageDesc;
759 [ # # ][ # # ]: 0 : sTest += String::CreateFromInt32( nDocNo );
[ # # ]
760 [ # # ][ # # ]: 0 : if( !pTargetShell->FindPageDescByName( sTest ) )
761 [ # # ]: 0 : return sTest;
762 [ # # ][ # # ]: 0 : ++nDocNo;
763 : : }while(true);
764 : : }
765 : :
766 : 0 : void lcl_CopyDynamicDefaults( const SwDoc& rSource, SwDoc& rTarget )
767 : : {
768 : : sal_uInt16 aRangeOfDefaults[] = {
769 : : RES_FRMATR_BEGIN, RES_FRMATR_END-1,
770 : : RES_CHRATR_BEGIN, RES_CHRATR_END-1,
771 : : RES_PARATR_BEGIN, RES_PARATR_END-1,
772 : : RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
773 : : RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
774 : : 0
775 : 0 : };
776 : :
777 [ # # ]: 0 : SfxItemSet aNewDefaults( rTarget.GetAttrPool(), aRangeOfDefaults );
778 : :
779 : : sal_uInt16 nWhich;
780 : 0 : sal_uInt16 nRange = 0;
781 [ # # ]: 0 : while( aRangeOfDefaults[nRange] != 0)
782 : : {
783 [ # # ]: 0 : for( nWhich = aRangeOfDefaults[nRange]; nWhich < aRangeOfDefaults[nRange + 1]; ++nWhich )
784 : : {
785 [ # # ]: 0 : const SfxPoolItem& rSourceAttr = rSource.GetDefault( nWhich );
786 [ # # ][ # # ]: 0 : if( rSourceAttr != rTarget.GetDefault( nWhich ) )
[ # # ]
787 [ # # ]: 0 : aNewDefaults.Put( rSourceAttr );
788 : : }
789 : 0 : nRange += 2;
790 : : }
791 [ # # ]: 0 : if( aNewDefaults.Count() )
792 [ # # ][ # # ]: 0 : rTarget.SetDefault( aNewDefaults );
793 : 0 : }
794 : :
795 : 0 : void lcl_CopyFollowPageDesc(
796 : : SwWrtShell& rTargetShell,
797 : : const SwPageDesc& rSourcePageDesc,
798 : : const SwPageDesc& rTargetPageDesc,
799 : : const sal_uLong nDocNo )
800 : : {
801 : : //now copy the follow page desc, too
802 : 0 : const SwPageDesc* pFollowPageDesc = rSourcePageDesc.GetFollow();
803 [ # # ]: 0 : String sFollowPageDesc = pFollowPageDesc->GetName();
804 [ # # ][ # # ]: 0 : if( sFollowPageDesc != rSourcePageDesc.GetName() )
805 : : {
806 : 0 : SwDoc* pTargetDoc = rTargetShell.GetDoc();
807 [ # # ]: 0 : String sNewFollowPageDesc = lcl_FindUniqueName(&rTargetShell, sFollowPageDesc, nDocNo );
808 [ # # ]: 0 : sal_uInt16 nNewDesc = pTargetDoc->MakePageDesc( sNewFollowPageDesc );
809 [ # # ]: 0 : SwPageDesc& rTargetFollowPageDesc = pTargetDoc->GetPageDesc( nNewDesc );
810 : :
811 [ # # ]: 0 : pTargetDoc->CopyPageDesc( *pFollowPageDesc, rTargetFollowPageDesc, sal_False );
812 [ # # ]: 0 : SwPageDesc aDesc( rTargetPageDesc );
813 : 0 : aDesc.SetFollow( &rTargetFollowPageDesc );
814 [ # # ][ # # ]: 0 : pTargetDoc->ChgPageDesc( rTargetPageDesc.GetName(), aDesc );
[ # # ]
815 [ # # ]: 0 : }
816 : 0 : }
817 : :
818 : 0 : void lcl_RemoveSectionLinks( SwWrtShell& rWorkShell )
819 : : {
820 : : //reset all links of the sections of synchronized labels
821 : 0 : sal_uInt16 nSections = rWorkShell.GetSectionFmtCount();
822 [ # # ]: 0 : for( sal_uInt16 nSection = 0; nSection < nSections; ++nSection )
823 : : {
824 [ # # ][ # # ]: 0 : SwSectionData aSectionData( *rWorkShell.GetSectionFmt( nSection ).GetSection() );
[ # # ]
825 [ # # ]: 0 : if( aSectionData.GetType() == FILE_LINK_SECTION )
826 : : {
827 : 0 : aSectionData.SetType( CONTENT_SECTION );
828 [ # # ][ # # ]: 0 : aSectionData.SetLinkFileName( String() );
[ # # ]
829 [ # # ]: 0 : rWorkShell.UpdateSection( nSection, aSectionData );
830 : : }
831 [ # # ]: 0 : }
832 : 0 : rWorkShell.SetLabelDoc( sal_False );
833 : 0 : }
834 : :
835 : 0 : sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
836 : : const SwMergeDescriptor& rMergeDescriptor)
837 : : {
838 : : //check if the doc is synchronized and contains at least one linked section
839 [ # # ][ # # ]: 0 : sal_Bool bSynchronizedDoc = pSourceShell->IsLabelDoc() && pSourceShell->GetSectionFmtCount() > 1;
[ # # ][ # # ]
840 : 0 : sal_Bool bLoop = sal_True;
841 : 0 : sal_Bool bEMail = rMergeDescriptor.nMergeType == DBMGR_MERGE_MAILING;
842 : 0 : const bool bAsSingleFile = rMergeDescriptor.nMergeType == DBMGR_MERGE_SINGLE_FILE;
843 : :
844 : 0 : ::rtl::Reference< MailDispatcher > xMailDispatcher;
845 : 0 : ::rtl::OUString sBodyMimeType;
846 [ # # ]: 0 : rtl_TextEncoding eEncoding = ::osl_getThreadTextEncoding();
847 : :
848 [ # # ]: 0 : if(bEMail)
849 : : {
850 [ # # ][ # # ]: 0 : xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer));
851 [ # # ][ # # ]: 0 : if(!rMergeDescriptor.bSendAsAttachment && rMergeDescriptor.bSendAsHTML)
852 : : {
853 [ # # ]: 0 : sBodyMimeType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("text/html; charset="));
854 : : sBodyMimeType += ::rtl::OUString::createFromAscii(
855 [ # # ]: 0 : rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
856 [ # # ]: 0 : SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
857 [ # # ]: 0 : eEncoding = rHtmlOptions.GetTextEncoding();
858 : : }
859 : : else
860 : : sBodyMimeType =
861 [ # # ]: 0 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("text/plain; charset=UTF-8; format=flowed"));
862 : : }
863 : :
864 : 0 : uno::Reference< XPropertySet > xColumnProp;
865 : : {
866 : 0 : sal_Bool bColumnName = sEMailAddrFld.Len() > 0;
867 : :
868 [ # # ]: 0 : if (bColumnName)
869 : : {
870 [ # # ]: 0 : uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
871 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
872 [ # # ][ # # ]: 0 : if(!xCols->hasByName(sEMailAddrFld))
[ # # ][ # # ]
873 : 0 : return sal_False;
874 [ # # ][ # # ]: 0 : Any aCol = xCols->getByName(sEMailAddrFld);
[ # # ]
875 [ # # ][ # # ]: 0 : aCol >>= xColumnProp;
[ # # ]
876 : : }
877 : :
878 : 0 : SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher();
879 [ # # ]: 0 : SwDocShell* pSourrceDocSh = pSourceShell->GetView().GetDocShell();
880 [ # # ][ # # ]: 0 : pSfxDispatcher->Execute( pSourrceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD);
881 : : // has document been saved successfully?
882 [ # # ][ # # ]: 0 : if( !pSourrceDocSh->IsModified() )
883 : : {
884 [ # # ]: 0 : SfxMedium* pOrig = pSourceShell->GetView().GetDocShell()->GetMedium();
885 [ # # ][ # # ]: 0 : String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ));
[ # # ]
886 : : const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter(
887 [ # # ]: 0 : sSourceDocumentURL, ::aEmptyStr );
888 : 0 : const SfxFilter* pStoreToFilter = pSfxFlt;
889 [ # # ][ # # ]: 0 : SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
890 : 0 : const String* pStoreToFilterOptions = 0;
891 : : // if a save_to filter is set then use it - otherwise use the default
892 [ # # ][ # # ]: 0 : if( bEMail && !rMergeDescriptor.bSendAsAttachment )
893 : : {
894 [ # # ][ # # ]: 0 : rtl::OUString sExtension = rMergeDescriptor.bSendAsHTML ? rtl::OUString("html") : rtl::OUString("txt");
[ # # ]
895 [ # # ][ # # ]: 0 : pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SFX_FILTER_EXPORT);
[ # # ]
896 : : }
897 [ # # ]: 0 : else if( rMergeDescriptor.sSaveToFilter.Len())
898 : : {
899 : : const SfxFilter* pFilter =
900 [ # # ]: 0 : pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter );
901 [ # # ]: 0 : if(pFilter)
902 : : {
903 : 0 : pStoreToFilter = pFilter;
904 [ # # ]: 0 : if(rMergeDescriptor.sSaveToFilterOptions.Len())
905 : 0 : pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions;
906 : : }
907 : : }
908 : 0 : bCancel = sal_False;
909 : :
910 : : // in case of creating a single resulting file this has to be created here
911 : 0 : SwWrtShell* pTargetShell = 0;
912 : :
913 : : // the shell will be explicitly closed at the end of the method, but it is
914 : : // still more safe to use SfxObjectShellLock here
915 : 0 : SfxObjectShellLock xTargetDocShell;
916 : :
917 : 0 : SwView* pTargetView = 0;
918 : 0 : std::auto_ptr< utl::TempFile > aTempFile;
919 [ # # ]: 0 : String sModifiedStartingPageDesc;
920 [ # # ]: 0 : String sStartingPageDesc;
921 : 0 : sal_uInt16 nStartingPageNo = 0;
922 : 0 : bool bPageStylesWithHeaderFooter = false;
923 [ # # ][ # # ]: 0 : if(bAsSingleFile || rMergeDescriptor.bCreateSingleFile)
924 : : {
925 : : // create a target docshell to put the merged document into
926 [ # # ][ # # ]: 0 : xTargetDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD );
[ # # ]
927 [ # # ]: 0 : xTargetDocShell->DoInitNew( 0 );
928 [ # # ]: 0 : SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );
929 : :
930 [ # # ]: 0 : pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
931 : :
932 : : //initiate SelectShell() to create sub shells
933 [ # # ]: 0 : pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
934 : 0 : pTargetShell = pTargetView->GetWrtShellPtr();
935 : : //copy the styles from the source to the target document
936 [ # # ]: 0 : SwgReaderOption aOpt;
937 : 0 : aOpt.SetTxtFmts( sal_True );
938 : 0 : aOpt.SetFrmFmts( sal_True );
939 : 0 : aOpt.SetPageDescs( sal_True );
940 : 0 : aOpt.SetNumRules( sal_True );
941 : 0 : aOpt.SetMerge( sal_False );
942 : : pTargetView->GetDocShell()->LoadStylesFromFile(
943 [ # # ][ # # ]: 0 : sSourceDocumentURL, aOpt, sal_True );
944 : : //determine the page style and number used at the start of the source document
945 [ # # ]: 0 : pSourceShell->SttEndDoc(sal_True);
946 [ # # ]: 0 : nStartingPageNo = pSourceShell->GetVirtPageNum();
947 : : sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc(
948 [ # # ][ # # ]: 0 : pSourceShell->GetCurPageDesc()).GetName();
[ # # ][ # # ]
949 : : // copy compatibility options
950 [ # # ]: 0 : lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell);
951 : : // #72821# copy dynamic defaults
952 [ # # ]: 0 : lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() );
953 : : // #i72517#
954 [ # # ]: 0 : const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc );
955 : 0 : const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
956 [ # # ]: 0 : bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() ||
957 [ # # ][ # # ]: 0 : rMaster.GetFooter().IsActive();
[ # # ][ # # ]
958 : :
959 : : }
960 : :
961 [ # # ]: 0 : PrintMonitor aPrtMonDlg(&pSourceShell->GetView().GetEditWin(), PrintMonitor::MONITOR_TYPE_PRINT);
962 [ # # ][ # # ]: 0 : aPrtMonDlg.aDocName.SetText(pSourceShell->GetView().GetDocShell()->GetTitle(22));
[ # # ][ # # ]
963 : :
964 [ # # ]: 0 : aPrtMonDlg.aCancel.SetClickHdl(LINK(this, SwNewDBMgr, PrtCancelHdl));
965 [ # # ]: 0 : if (!IsMergeSilent())
966 [ # # ]: 0 : aPrtMonDlg.Show();
967 : :
968 : : // Progress, to prohibit KeyInputs
969 [ # # ]: 0 : SfxProgress aProgress(pSourrceDocSh, ::aEmptyStr, 1);
970 : :
971 : : // lock all dispatchers
972 [ # # ]: 0 : SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
973 [ # # ]: 0 : while (pViewFrm)
974 : : {
975 [ # # ]: 0 : pViewFrm->GetDispatcher()->Lock(sal_True);
976 [ # # ]: 0 : pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
977 : : }
978 : 0 : sal_uLong nDocNo = 1;
979 : :
980 : : long nStartRow, nEndRow;
981 : : // collect temporary files
982 [ # # ]: 0 : ::std::vector< String> aFilesToRemove;
983 [ # # ][ # # ]: 0 : do
[ # # ][ # # ]
[ # # ]
984 : : {
985 [ # # ][ # # ]: 0 : nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
[ # # ]
986 : : {
987 [ # # ]: 0 : String sPath(sSubject);
988 : :
989 [ # # ]: 0 : String sAddress;
990 [ # # ][ # # ]: 0 : if( !bEMail && bColumnName )
991 : : {
992 [ # # ]: 0 : SwDBFormatData aDBFormat;
993 [ # # ]: 0 : aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
994 : 0 : aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
995 [ # # ][ # # ]: 0 : sAddress = GetDBField( xColumnProp, aDBFormat);
[ # # ]
996 [ # # ]: 0 : if (!sAddress.Len())
997 [ # # ]: 0 : sAddress = '_';
998 [ # # ][ # # ]: 0 : sPath += sAddress;
999 : : }
1000 : :
1001 : : // create a new temporary file name - only done once in case of bCreateSingleFile
1002 [ # # ][ # # ]: 0 : if( 1 == nDocNo || (!rMergeDescriptor.bCreateSingleFile && !bAsSingleFile) )
[ # # ]
1003 : : {
1004 [ # # ][ # # ]: 0 : INetURLObject aEntry(sPath);
1005 [ # # ]: 0 : String sLeading;
1006 : : //#i97667# if the name is from a database field then it will be used _as is_
1007 [ # # ]: 0 : if( sAddress.Len() )
1008 [ # # ]: 0 : sLeading = sAddress;
1009 : : else
1010 [ # # ][ # # ]: 0 : sLeading = aEntry.GetBase();
1011 [ # # ]: 0 : aEntry.removeSegment();
1012 [ # # ][ # # ]: 0 : sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE );
1013 [ # # ][ # # ]: 0 : String sExt(comphelper::string::stripStart(pStoreToFilter->GetDefaultExtension(), '*'));
[ # # ][ # # ]
[ # # ]
1014 : : aTempFile = std::auto_ptr< utl::TempFile >(
1015 [ # # ][ # # ]: 0 : new utl::TempFile(sLeading,&sExt,&sPath ));
[ # # ]
1016 [ # # ]: 0 : if( bAsSingleFile )
1017 [ # # ][ # # ]: 0 : aTempFile->EnableKillingFile();
[ # # ]
1018 : : }
1019 : :
1020 [ # # ][ # # ]: 0 : if( !aTempFile->IsValid() )
1021 : : {
1022 [ # # ]: 0 : ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
1023 : 0 : bLoop = sal_False;
1024 : 0 : bCancel = sal_True;
1025 : : }
1026 : : else
1027 : : {
1028 [ # # ][ # # ]: 0 : INetURLObject aTempFileURL(aTempFile->GetURL());
[ # # ][ # # ]
1029 [ # # ][ # # ]: 0 : aPrtMonDlg.aPrinter.SetText( aTempFileURL.GetBase() );
[ # # ][ # # ]
1030 [ # # ]: 0 : String sStat(SW_RES(STR_STATSTR_LETTER)); // Brief
1031 [ # # ]: 0 : sStat += ' ';
1032 [ # # ][ # # ]: 0 : sStat += String::CreateFromInt32( nDocNo );
[ # # ]
1033 [ # # ]: 0 : aPrtMonDlg.aPrintInfo.SetText(sStat);
1034 : :
1035 : : // computation time for Save-Monitor:
1036 [ # # ]: 0 : for (sal_uInt16 i = 0; i < 10; i++)
1037 [ # # ]: 0 : Application::Reschedule();
1038 : :
1039 : : // Create and save new document
1040 : : // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here
1041 [ # # ][ # # ]: 0 : SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
[ # # ]
1042 [ # # ][ # # ]: 0 : SfxMedium* pWorkMed = new SfxMedium( sSourceDocumentURL, STREAM_STD_READ );
1043 [ # # ]: 0 : pWorkMed->SetFilter( pSfxFlt );
1044 : :
1045 [ # # ][ # # ]: 0 : if (xWorkDocSh->DoLoad(pWorkMed))
1046 : : {
1047 : : //create a view frame for the document
1048 [ # # ]: 0 : SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 );
1049 : : //request the layout calculation
1050 : : SwWrtShell& rWorkShell =
1051 [ # # ]: 0 : static_cast< SwView* >(pWorkFrame->GetViewShell())->GetWrtShell();
1052 [ # # ]: 0 : rWorkShell.CalcLayout();
1053 : 0 : SwDoc* pWorkDoc = ((SwDocShell*)(&xWorkDocSh))->GetDoc();
1054 : 0 : SwNewDBMgr* pOldDBMgr = pWorkDoc->GetNewDBMgr();
1055 : 0 : pWorkDoc->SetNewDBMgr( this );
1056 [ # # ][ # # ]: 0 : SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh));
[ # # ][ # # ]
[ # # ]
1057 [ # # ]: 0 : pWorkDoc->UpdateFlds(NULL, false);
1058 [ # # ][ # # ]: 0 : SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh));
[ # # ][ # # ]
[ # # ]
1059 : :
1060 [ # # ]: 0 : pWorkDoc->RemoveInvisibleContent();
1061 : :
1062 : : // launch MailMergeEvent if required
1063 : 0 : const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
1064 [ # # ]: 0 : if(pEvtSrc)
1065 : : {
1066 [ # # ][ # # ]: 0 : uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc );
1067 [ # # ][ # # ]: 0 : text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() );
1068 [ # # ][ # # ]: 0 : pEvtSrc->LaunchMailMergeEvent( aEvt );
1069 : : }
1070 : :
1071 [ # # ][ # # ]: 0 : if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile )
1072 : : {
1073 : : OSL_ENSURE( pTargetShell, "no target shell available!" );
1074 : : // copy created file into the target document
1075 [ # # ]: 0 : rWorkShell.ConvertFieldsToText();
1076 [ # # ]: 0 : rWorkShell.SetNumberingRestart();
1077 [ # # ]: 0 : if( bSynchronizedDoc )
1078 : : {
1079 [ # # ]: 0 : lcl_RemoveSectionLinks( rWorkShell );
1080 : : }
1081 : :
1082 : : // insert the document into the target document
1083 [ # # ]: 0 : rWorkShell.SttEndDoc(sal_False);
1084 [ # # ]: 0 : rWorkShell.SttEndDoc(sal_True);
1085 [ # # ]: 0 : rWorkShell.SelAll();
1086 [ # # ]: 0 : pTargetShell->SwCrsrShell::SttEndDoc( sal_False );
1087 : : //#i72517# the headers and footers are still those from the source - update in case of fields inside header/footer
1088 [ # # ][ # # ]: 0 : if( !nDocNo && bPageStylesWithHeaderFooter )
1089 [ # # ][ # # ]: 0 : pTargetShell->GetView().GetDocShell()->_LoadStyles( *rWorkShell.GetView().GetDocShell(), sal_True );
[ # # ]
1090 : : //#i72517# put the styles to the target document
1091 : : //if the source uses headers or footers each new copy need to copy a new page styles
1092 [ # # ]: 0 : if(bPageStylesWithHeaderFooter)
1093 : : {
1094 : : //create a new pagestyle
1095 : : //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
1096 : :
1097 : 0 : SwDoc* pTargetDoc = pTargetShell->GetDoc();
1098 [ # # ]: 0 : SwPageDesc* pSourcePageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
1099 [ # # ]: 0 : String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
1100 [ # # ]: 0 : pTargetDoc->MakePageDesc( sNewPageDescName );
1101 [ # # ]: 0 : SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
1102 [ # # ][ # # ]: 0 : if(pSourcePageDesc && pTargetPageDesc)
1103 : : {
1104 [ # # ]: 0 : pTargetDoc->CopyPageDesc( *pSourcePageDesc, *pTargetPageDesc, sal_False );
1105 [ # # ]: 0 : sModifiedStartingPageDesc = sNewPageDescName;
1106 [ # # ]: 0 : lcl_CopyFollowPageDesc( *pTargetShell, *pSourcePageDesc, *pTargetPageDesc, nDocNo );
1107 [ # # ]: 0 : }
1108 : : }
1109 : :
1110 [ # # ]: 0 : if(nDocNo > 1)
1111 [ # # ]: 0 : pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
1112 : : else
1113 [ # # ]: 0 : pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
1114 : : OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
1115 : : //#i51359# add a second paragraph in case there's only one
1116 : : {
1117 [ # # ][ # # ]: 0 : SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
1118 [ # # ]: 0 : SwPosition aTestPos( aIdx );
1119 [ # # ]: 0 : SwCursor aTestCrsr(aTestPos,0,false);
1120 [ # # ][ # # ]: 0 : if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
1121 : : {
1122 : : //append a paragraph
1123 [ # # ]: 0 : pWorkDoc->AppendTxtNode( aTestPos );
1124 [ # # ][ # # ]: 0 : }
[ # # ]
1125 : : }
1126 [ # # ]: 0 : pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );
1127 : :
1128 : : //convert fields in page styles (header/footer - has to be done after the first document has been pasted
1129 [ # # ]: 0 : if(1 == nDocNo)
1130 : : {
1131 [ # # ]: 0 : pTargetShell->CalcLayout();
1132 [ # # ]: 0 : pTargetShell->ConvertFieldsToText();
1133 : 0 : }
1134 : : }
1135 : : else
1136 : : {
1137 [ # # ][ # # ]: 0 : String sFileURL = aTempFileURL.GetMainURL( INetURLObject::NO_DECODE );
1138 : : SfxMedium* pDstMed = new SfxMedium(
1139 : : sFileURL,
1140 [ # # ][ # # ]: 0 : STREAM_STD_READWRITE );
1141 [ # # ]: 0 : pDstMed->SetFilter( pStoreToFilter );
1142 [ # # ][ # # ]: 0 : if(pDstMed->GetItemSet())
1143 : : {
1144 [ # # ]: 0 : if(pStoreToFilterOptions )
1145 [ # # ][ # # ]: 0 : pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
[ # # ][ # # ]
1146 [ # # ]: 0 : if(rMergeDescriptor.aSaveToFilterData.getLength())
1147 [ # # ][ # # ]: 0 : pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData)));
[ # # ][ # # ]
[ # # ]
1148 : : }
1149 : :
1150 : : //convert fields to text if we are exporting to PDF
1151 : : //this prevents a second merge while updating the fields in SwXTextDocument::getRendererCount()
1152 [ # # ][ # # ]: 0 : if( pStoreToFilter && pStoreToFilter->GetFilterName().EqualsAscii("writer_pdf_Export"))
[ # # ][ # # ]
1153 [ # # ]: 0 : rWorkShell.ConvertFieldsToText();
1154 [ # # ]: 0 : xWorkDocSh->DoSaveAs(*pDstMed);
1155 [ # # ]: 0 : xWorkDocSh->DoSaveCompleted(pDstMed);
1156 [ # # ][ # # ]: 0 : if( xWorkDocSh->GetError() )
1157 : : {
1158 : : // error message ??
1159 [ # # ][ # # ]: 0 : ErrorHandler::HandleError( xWorkDocSh->GetError() );
1160 : 0 : bCancel = sal_True;
1161 : 0 : bLoop = sal_False;
1162 : : }
1163 [ # # ]: 0 : if( bEMail )
1164 : : {
1165 [ # # ]: 0 : SwDBFormatData aDBFormat;
1166 [ # # ]: 0 : aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
1167 : 0 : aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
1168 [ # # ]: 0 : String sMailAddress = GetDBField( xColumnProp, aDBFormat);
1169 [ # # ][ # # ]: 0 : if(!SwMailMergeHelper::CheckMailAddress( sMailAddress ))
[ # # ]
1170 : : {
1171 : : OSL_FAIL("invalid e-Mail address in database column");
1172 : : }
1173 : : else
1174 : : {
1175 [ # # ]: 0 : SwMailMessage* pMessage = new SwMailMessage;
1176 [ # # ][ # # ]: 0 : uno::Reference< mail::XMailMessage > xMessage = pMessage;
1177 [ # # ][ # # ]: 0 : if(rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo())
1178 [ # # ][ # # ]: 0 : pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo());
1179 [ # # ][ # # ]: 0 : pMessage->addRecipient( sMailAddress );
1180 [ # # ]: 0 : pMessage->SetSenderAddress( rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() );
1181 : 0 : ::rtl::OUString sBody;
1182 [ # # ]: 0 : if(rMergeDescriptor.bSendAsAttachment)
1183 : : {
1184 [ # # ]: 0 : sBody = rMergeDescriptor.sMailBody;
1185 [ # # ]: 0 : mail::MailAttachment aAttach;
1186 : : aAttach.Data = new SwMailTransferable(
1187 : : sFileURL,
1188 : : rMergeDescriptor.sAttachmentName,
1189 [ # # ][ # # ]: 0 : pStoreToFilter->GetMimeType());
[ # # ][ # # ]
[ # # ]
1190 [ # # ]: 0 : aAttach.ReadableName = rMergeDescriptor.sAttachmentName;
1191 [ # # ][ # # ]: 0 : pMessage->addAttachment( aAttach );
1192 : : }
1193 : : else
1194 : : {
1195 : : {
1196 : : //read in the temporary file and use it as mail body
1197 [ # # ]: 0 : SfxMedium aMedium( sFileURL, STREAM_READ);
1198 [ # # ]: 0 : SvStream* pInStream = aMedium.GetInStream();
1199 : : OSL_ENSURE(pInStream, "no output file created?");
1200 [ # # ]: 0 : if(pInStream)
1201 : : {
1202 : 0 : pInStream->SetStreamCharSet( eEncoding );
1203 : 0 : rtl::OString sLine;
1204 [ # # ]: 0 : sal_Bool bDone = pInStream->ReadLine( sLine );
1205 [ # # ]: 0 : while ( bDone )
1206 : : {
1207 [ # # ]: 0 : sBody += rtl::OStringToOUString(sLine, eEncoding);
1208 : 0 : sBody += ::rtl::OUString('\n');
1209 [ # # ]: 0 : bDone = pInStream->ReadLine( sLine );
1210 : 0 : }
1211 [ # # ]: 0 : }
1212 : : }
1213 : : }
1214 [ # # ][ # # ]: 0 : pMessage->setSubject( rMergeDescriptor.sSubject );
1215 : : uno::Reference< datatransfer::XTransferable> xBody =
1216 : : new SwMailTransferable(
1217 : : sBody,
1218 [ # # ][ # # ]: 0 : sBodyMimeType);
[ # # ]
1219 [ # # ]: 0 : pMessage->setBody( xBody );
1220 : :
1221 [ # # ]: 0 : if(rMergeDescriptor.aCopiesTo.getLength())
1222 : : {
1223 : 0 : const ::rtl::OUString* pCopies = rMergeDescriptor.aCopiesTo.getConstArray();
1224 [ # # ]: 0 : for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aCopiesTo.getLength(); ++nToken)
1225 [ # # ]: 0 : pMessage->addCcRecipient( pCopies[nToken] );
1226 : : }
1227 [ # # ]: 0 : if(rMergeDescriptor.aBlindCopiesTo.getLength())
1228 : : {
1229 : 0 : const ::rtl::OUString* pCopies = rMergeDescriptor.aBlindCopiesTo.getConstArray();
1230 [ # # ]: 0 : for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aBlindCopiesTo.getLength(); ++nToken)
1231 [ # # ]: 0 : pMessage->addBccRecipient( pCopies[nToken] );
1232 : : }
1233 [ # # ]: 0 : xMailDispatcher->enqueueMailMessage( xMessage );
1234 [ # # ][ # # ]: 0 : if(!xMailDispatcher->isStarted())
1235 [ # # ]: 0 : xMailDispatcher->start();
1236 : : //schedule for removal
1237 [ # # ]: 0 : aFilesToRemove.push_back(sFileURL);
1238 [ # # ][ # # ]: 0 : }
1239 [ # # ]: 0 : }
1240 : : }
1241 : 0 : pWorkDoc->SetNewDBMgr( pOldDBMgr );
1242 : : }
1243 [ # # ][ # # ]: 0 : xWorkDocSh->DoClose();
[ # # ][ # # ]
1244 [ # # ][ # # ]: 0 : }
1245 : : }
1246 : 0 : nDocNo++;
1247 [ # # ][ # # ]: 0 : nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
[ # # ]
1248 : 0 : } while( !bCancel &&
1249 [ # # ][ # # ]: 0 : (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
[ # # ]
1250 : :
1251 [ # # ]: 0 : aPrtMonDlg.Show( sal_False );
1252 : :
1253 : : // save the single output document
1254 [ # # ][ # # ]: 0 : if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile)
1255 : : {
1256 [ # # ]: 0 : if( rMergeDescriptor.nMergeType != DBMGR_MERGE_MAILMERGE )
1257 : : {
1258 : : OSL_ENSURE( aTempFile.get(), "Temporary file not available" );
1259 [ # # ][ # # ]: 0 : INetURLObject aTempFileURL(bAsSingleFile ? sSubject : aTempFile->GetURL());
[ # # ][ # # ]
[ # # ][ # # ]
1260 : : SfxMedium* pDstMed = new SfxMedium(
1261 : : aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
1262 [ # # ][ # # ]: 0 : STREAM_STD_READWRITE );
[ # # ][ # # ]
[ # # ]
1263 [ # # ]: 0 : pDstMed->SetFilter( pStoreToFilter );
1264 [ # # ][ # # ]: 0 : if(pDstMed->GetItemSet())
1265 : : {
1266 [ # # ]: 0 : if(pStoreToFilterOptions )
1267 [ # # ][ # # ]: 0 : pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
[ # # ][ # # ]
1268 [ # # ]: 0 : if(rMergeDescriptor.aSaveToFilterData.getLength())
1269 [ # # ][ # # ]: 0 : pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData)));
[ # # ][ # # ]
[ # # ]
1270 : : }
1271 : :
1272 [ # # ]: 0 : xTargetDocShell->DoSaveAs(*pDstMed);
1273 [ # # ]: 0 : xTargetDocShell->DoSaveCompleted(pDstMed);
1274 [ # # ][ # # ]: 0 : if( xTargetDocShell->GetError() )
1275 : : {
1276 : : // error message ??
1277 [ # # ][ # # ]: 0 : ErrorHandler::HandleError( xTargetDocShell->GetError() );
1278 : 0 : bLoop = sal_False;
1279 [ # # ]: 0 : }
1280 : : }
1281 [ # # ]: 0 : else if( pTargetView ) // must be available!
1282 : : {
1283 : : //print the target document
1284 : : #if OSL_DEBUG_LEVEL > 1
1285 : : sal_Bool _bVal;
1286 : : sal_Int16 _nVal;
1287 : : rtl::OUString _sVal;
1288 : : const beans::PropertyValue* pDbgPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
1289 : : for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
1290 : : {
1291 : : rtl::OUString aName( pDbgPrintOptions[nOption].Name );
1292 : : uno::Any aVal( pDbgPrintOptions[nOption].Value );
1293 : : aVal >>= _bVal;
1294 : : aVal >>= _nVal;
1295 : : aVal >>= _sVal;
1296 : : }
1297 : : #endif
1298 : : // printing should be done synchronously otherwise the document
1299 : : // might already become invalid during the process
1300 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aOptions( rMergeDescriptor.aPrintOptions );
1301 : 0 : const sal_Int32 nOpts = aOptions.getLength();
1302 [ # # ]: 0 : aOptions.realloc( nOpts + 1 );
1303 [ # # ][ # # ]: 0 : aOptions[ nOpts ].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wait"));
1304 [ # # ][ # # ]: 0 : aOptions[ nOpts ].Value <<= sal_True ;
1305 : : // move print options
1306 : 0 : const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
1307 [ # # ]: 0 : for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
1308 : : {
1309 [ # # ][ # # : 0 : if( pPrintOptions[nOption].Name == "CopyCount" || pPrintOptions[nOption].Name == "FileName"
# # # # #
# ][ # # ]
1310 : 0 : || pPrintOptions[nOption].Name == "Collate" || pPrintOptions[nOption].Name == "Pages"
1311 : 0 : || pPrintOptions[nOption].Name == "Wait" )
1312 : : {
1313 [ # # ]: 0 : aOptions.realloc( nOpts + 1 );
1314 [ # # ]: 0 : aOptions[ nOpts ].Name = pPrintOptions[nOption].Name;
1315 [ # # ]: 0 : aOptions[ nOpts ].Value = pPrintOptions[nOption].Value ;
1316 : : }
1317 : : }
1318 : :
1319 [ # # ][ # # ]: 0 : pTargetView->ExecPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync );
1320 : : }
1321 [ # # ]: 0 : xTargetDocShell->DoClose();
1322 : : }
1323 : :
1324 : : //remove the temporary files
1325 : 0 : ::std::vector<String>::iterator aFileIter;
1326 [ # # # # ]: 0 : for(aFileIter = aFilesToRemove.begin();
[ # # ]
1327 : 0 : aFileIter != aFilesToRemove.end(); ++aFileIter)
1328 [ # # ][ # # ]: 0 : SWUnoHelper::UCB_DeleteFile( *aFileIter );
1329 : :
1330 : : // unlock all dispatchers
1331 [ # # ]: 0 : pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
1332 [ # # ]: 0 : while (pViewFrm)
1333 : : {
1334 [ # # ]: 0 : pViewFrm->GetDispatcher()->Lock(sal_False);
1335 [ # # ]: 0 : pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
1336 : : }
1337 : :
1338 [ # # ][ # # ]: 0 : SW_MOD()->SetView(&pSourceShell->GetView());
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1339 : : }
1340 : :
1341 : 0 : nMergeType = DBMGR_INSERT;
1342 : : }
1343 : :
1344 [ # # ]: 0 : if(bEMail)
1345 : : {
1346 [ # # ]: 0 : xMailDispatcher->stop();
1347 [ # # ]: 0 : xMailDispatcher->shutdown();
1348 : :
1349 : : }
1350 : :
1351 [ # # ]: 0 : return bLoop;
1352 : : }
1353 : :
1354 : 0 : IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
1355 : : {
1356 : 0 : pButton->GetParent()->Hide();
1357 : 0 : bCancel = sal_True;
1358 : 0 : return 0;
1359 : : }
1360 : 0 : IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
1361 : :
1362 : : /*--------------------------------------------------------------------
1363 : : Description: determine the column's Numberformat and transfer
1364 : : to the forwarded Formatter, if applicable.
1365 : : --------------------------------------------------------------------*/
1366 : 0 : sal_uLong SwNewDBMgr::GetColumnFmt( const String& rDBName,
1367 : : const String& rTableName,
1368 : : const String& rColNm,
1369 : : SvNumberFormatter* pNFmtr,
1370 : : long nLanguage )
1371 : : {
1372 : 0 : sal_uLong nRet = 0;
1373 [ # # ]: 0 : if(pNFmtr)
1374 : : {
1375 : 0 : uno::Reference< XDataSource> xSource;
1376 : 0 : uno::Reference< XConnection> xConnection;
1377 : 0 : sal_Bool bUseMergeData = sal_False;
1378 : 0 : uno::Reference< XColumnsSupplier> xColsSupp;
1379 : 0 : bool bDisposeConnection = false;
1380 [ # # ][ # # : 0 : if(pImpl->pMergeData &&
# # # # ]
1381 [ # # ][ # # ]: 0 : pImpl->pMergeData->sDataSource.equals(rDBName) && pImpl->pMergeData->sCommand.equals(rTableName))
[ # # ][ # # ]
[ # # # # ]
1382 : : {
1383 [ # # ]: 0 : xConnection = pImpl->pMergeData->xConnection;
1384 [ # # ][ # # ]: 0 : xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,rDBName);
[ # # ]
1385 : 0 : bUseMergeData = sal_True;
1386 [ # # ][ # # ]: 0 : xColsSupp = xColsSupp.query( pImpl->pMergeData->xResultSet );
1387 : : }
1388 [ # # ]: 0 : if(!xConnection.is())
1389 : : {
1390 : 0 : SwDBData aData;
1391 [ # # ]: 0 : aData.sDataSource = rDBName;
1392 [ # # ]: 0 : aData.sCommand = rTableName;
1393 : 0 : aData.nCommandType = -1;
1394 [ # # ]: 0 : SwDSParam* pParam = FindDSData(aData, sal_False);
1395 [ # # ][ # # ]: 0 : if(pParam && pParam->xConnection.is())
[ # # ]
1396 : : {
1397 [ # # ]: 0 : xConnection = pParam->xConnection;
1398 [ # # ][ # # ]: 0 : xColsSupp = xColsSupp.query( pParam->xResultSet );
1399 : : }
1400 : : else
1401 : : {
1402 [ # # ]: 0 : rtl::OUString sDBName(rDBName);
1403 [ # # ][ # # ]: 0 : xConnection = RegisterConnection( sDBName );
1404 : 0 : bDisposeConnection = true;
1405 : : }
1406 [ # # ]: 0 : if(bUseMergeData)
1407 [ # # ]: 0 : pImpl->pMergeData->xConnection = xConnection;
1408 : : }
1409 : 0 : bool bDispose = !xColsSupp.is();
1410 [ # # ]: 0 : if(bDispose)
1411 : : {
1412 [ # # ][ # # ]: 0 : xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
1413 : : }
1414 [ # # ]: 0 : if(xColsSupp.is())
1415 : : {
1416 : 0 : uno::Reference<XNameAccess> xCols;
1417 : : try
1418 : : {
1419 [ # # ][ # # ]: 0 : xCols = xColsSupp->getColumns();
[ # # ][ # # ]
1420 : : }
1421 [ # # ]: 0 : catch(const Exception&)
1422 : : {
1423 : : OSL_FAIL("Exception in getColumns()");
1424 : : }
1425 [ # # ][ # # ]: 0 : if(!xCols.is() || !xCols->hasByName(rColNm))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
1426 : 0 : return nRet;
1427 [ # # ][ # # ]: 0 : Any aCol = xCols->getByName(rColNm);
[ # # ]
1428 : 0 : uno::Reference< XPropertySet > xColumn;
1429 [ # # ]: 0 : aCol >>= xColumn;
1430 [ # # ]: 0 : nRet = GetColumnFmt(xSource, xConnection, xColumn, pNFmtr, nLanguage);
1431 [ # # ]: 0 : if(bDispose)
1432 : : {
1433 [ # # ]: 0 : ::comphelper::disposeComponent( xColsSupp );
1434 : : }
1435 [ # # ]: 0 : if(bDisposeConnection)
1436 : : {
1437 [ # # ]: 0 : ::comphelper::disposeComponent( xConnection );
1438 [ # # ]: 0 : }
1439 : : }
1440 : : else
1441 [ # # ][ # # ]: 0 : nRet = pNFmtr->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM );
[ # # ][ # # ]
1442 : : }
1443 : 0 : return nRet;
1444 : : }
1445 : :
1446 : 0 : sal_uLong SwNewDBMgr::GetColumnFmt( uno::Reference< XDataSource> xSource,
1447 : : uno::Reference< XConnection> xConnection,
1448 : : uno::Reference< XPropertySet> xColumn,
1449 : : SvNumberFormatter* pNFmtr,
1450 : : long nLanguage )
1451 : : {
1452 : : // set the NumberFormat in the doc if applicable
1453 : 0 : sal_uLong nRet = 0;
1454 : :
1455 [ # # ]: 0 : if(!xSource.is())
1456 : : {
1457 [ # # ]: 0 : uno::Reference<XChild> xChild(xConnection, UNO_QUERY);
1458 [ # # ]: 0 : if ( xChild.is() )
1459 [ # # ][ # # ]: 0 : xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
[ # # ][ # # ]
1460 : : }
1461 [ # # ][ # # ]: 0 : if(xSource.is() && xConnection.is() && xColumn.is() && pNFmtr)
[ # # ][ # # ]
[ # # ]
1462 : : {
1463 [ # # ]: 0 : SvNumberFormatsSupplierObj* pNumFmt = new SvNumberFormatsSupplierObj( pNFmtr );
1464 [ # # ][ # # ]: 0 : uno::Reference< util::XNumberFormatsSupplier > xDocNumFmtsSupplier = pNumFmt;
1465 [ # # ][ # # ]: 0 : uno::Reference< XNumberFormats > xDocNumberFormats = xDocNumFmtsSupplier->getNumberFormats();
1466 [ # # ]: 0 : uno::Reference< XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY);
1467 : :
1468 [ # # ]: 0 : com::sun::star::lang::Locale aLocale( MsLangId::convertLanguageToLocale( (LanguageType)nLanguage ));
1469 : :
1470 : : //get the number formatter of the data source
1471 [ # # ]: 0 : uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
1472 : 0 : uno::Reference< XNumberFormats > xNumberFormats;
1473 [ # # ]: 0 : if(xSourceProps.is())
1474 : : {
1475 [ # # ][ # # ]: 0 : Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier"));
[ # # ]
1476 [ # # ]: 0 : if(aFormats.hasValue())
1477 : : {
1478 : 0 : uno::Reference<XNumberFormatsSupplier> xSuppl;
1479 [ # # ]: 0 : aFormats >>= xSuppl;
1480 [ # # ]: 0 : if(xSuppl.is())
1481 : : {
1482 [ # # ][ # # ]: 0 : xNumberFormats = xSuppl->getNumberFormats();
[ # # ]
1483 : 0 : }
1484 : 0 : }
1485 : : }
1486 : 0 : bool bUseDefault = true;
1487 : : try
1488 : : {
1489 [ # # ][ # # ]: 0 : Any aFormatKey = xColumn->getPropertyValue(C2U("FormatKey"));
[ # # ]
1490 [ # # ]: 0 : if(aFormatKey.hasValue())
1491 : : {
1492 : 0 : sal_Int32 nFmt = 0;
1493 : 0 : aFormatKey >>= nFmt;
1494 [ # # ]: 0 : if(xNumberFormats.is())
1495 : : {
1496 : : try
1497 : : {
1498 [ # # ][ # # ]: 0 : uno::Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFmt );
1499 [ # # ][ # # ]: 0 : Any aFormatString = xNumProps->getPropertyValue(C2U("FormatString"));
[ # # ]
1500 [ # # ][ # # ]: 0 : Any aLocaleVal = xNumProps->getPropertyValue(C2U("Locale"));
[ # # ]
1501 : 0 : rtl::OUString sFormat;
1502 : 0 : aFormatString >>= sFormat;
1503 : 0 : lang::Locale aLoc;
1504 [ # # ]: 0 : aLocaleVal >>= aLoc;
1505 [ # # ][ # # ]: 0 : nFmt = xDocNumberFormats->queryKey( sFormat, aLoc, sal_False );
1506 [ # # ]: 0 : if(NUMBERFORMAT_ENTRY_NOT_FOUND == sal::static_int_cast< sal_uInt32, sal_Int32>(nFmt))
1507 [ # # ][ # # ]: 0 : nFmt = xDocNumberFormats->addNew( sFormat, aLoc );
1508 : 0 : nRet = nFmt;
1509 [ # # ]: 0 : bUseDefault = false;
1510 : : }
1511 [ # # ]: 0 : catch(const Exception&)
1512 : : {
1513 : : OSL_FAIL("illegal number format key");
1514 : : }
1515 : : }
1516 [ # # ]: 0 : }
1517 : : }
1518 [ # # ]: 0 : catch(const Exception&)
1519 : : {
1520 : : OSL_FAIL("no FormatKey property found");
1521 : : }
1522 [ # # ]: 0 : if(bUseDefault)
1523 [ # # ][ # # ]: 0 : nRet = SwNewDBMgr::GetDbtoolsClient().getDefaultNumberFormat(xColumn, xDocNumberFormatTypes, aLocale);
1524 : : }
1525 : 0 : return nRet;
1526 : : }
1527 : :
1528 : 0 : sal_Int32 SwNewDBMgr::GetColumnType( const String& rDBName,
1529 : : const String& rTableName,
1530 : : const String& rColNm )
1531 : : {
1532 : 0 : sal_Int32 nRet = DataType::SQLNULL;
1533 : 0 : SwDBData aData;
1534 [ # # ]: 0 : aData.sDataSource = rDBName;
1535 [ # # ]: 0 : aData.sCommand = rTableName;
1536 : 0 : aData.nCommandType = -1;
1537 [ # # ]: 0 : SwDSParam* pParam = FindDSData(aData, sal_False);
1538 : 0 : uno::Reference< XConnection> xConnection;
1539 : 0 : uno::Reference< XColumnsSupplier > xColsSupp;
1540 : 0 : bool bDispose = false;
1541 [ # # ][ # # ]: 0 : if(pParam && pParam->xConnection.is())
[ # # ]
1542 : : {
1543 [ # # ]: 0 : xConnection = pParam->xConnection;
1544 [ # # ][ # # ]: 0 : xColsSupp = uno::Reference< XColumnsSupplier >( pParam->xResultSet, UNO_QUERY );
1545 : : }
1546 : : else
1547 : : {
1548 [ # # ]: 0 : rtl::OUString sDBName(rDBName);
1549 [ # # ][ # # ]: 0 : xConnection = RegisterConnection( sDBName );
1550 : : }
1551 [ # # ]: 0 : if( !xColsSupp.is() )
1552 : : {
1553 [ # # ][ # # ]: 0 : xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
1554 : 0 : bDispose = true;
1555 : : }
1556 [ # # ]: 0 : if(xColsSupp.is())
1557 : : {
1558 [ # # ][ # # ]: 0 : uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
1559 [ # # ][ # # ]: 0 : if(xCols->hasByName(rColNm))
[ # # ][ # # ]
1560 : : {
1561 [ # # ][ # # ]: 0 : Any aCol = xCols->getByName(rColNm);
[ # # ]
1562 : 0 : uno::Reference<XPropertySet> xCol;
1563 [ # # ]: 0 : aCol >>= xCol;
1564 [ # # ][ # # ]: 0 : Any aType = xCol->getPropertyValue(rtl::OUString("Type"));
1565 : 0 : aType >>= nRet;
1566 : : }
1567 [ # # ]: 0 : if(bDispose)
1568 [ # # ]: 0 : ::comphelper::disposeComponent( xColsSupp );
1569 : : }
1570 : 0 : return nRet;
1571 : : }
1572 : :
1573 : 0 : uno::Reference< sdbc::XConnection> SwNewDBMgr::GetConnection(const String& rDataSource,
1574 : : uno::Reference<XDataSource>& rxSource)
1575 : : {
1576 : 0 : Reference< sdbc::XConnection> xConnection;
1577 [ # # ]: 0 : Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
1578 : : try
1579 : : {
1580 [ # # ][ # # ]: 0 : Reference<XCompletedConnection> xComplConnection(SwNewDBMgr::GetDbtoolsClient().getDataSource(rDataSource, xMgr),UNO_QUERY);
[ # # ][ # # ]
1581 [ # # ]: 0 : if ( xComplConnection.is() )
1582 : : {
1583 [ # # ]: 0 : rxSource.set(xComplConnection,UNO_QUERY);
1584 : : Reference< XInteractionHandler > xHandler(
1585 [ # # ][ # # ]: 0 : xMgr->createInstance( C2U( "com.sun.star.task.InteractionHandler" )), UNO_QUERY);
[ # # ][ # # ]
1586 [ # # ][ # # ]: 0 : xConnection = xComplConnection->connectWithCompletion( xHandler );
[ # # ]
1587 [ # # ]: 0 : }
1588 : : }
1589 [ # # ]: 0 : catch(const Exception&)
1590 : : {
1591 : : }
1592 : :
1593 : 0 : return xConnection;
1594 : : }
1595 : :
1596 : 0 : uno::Reference< sdbcx::XColumnsSupplier> SwNewDBMgr::GetColumnSupplier(uno::Reference<sdbc::XConnection> xConnection,
1597 : : const String& rTableOrQuery,
1598 : : sal_uInt8 eTableOrQuery)
1599 : : {
1600 : 0 : Reference< sdbcx::XColumnsSupplier> xRet;
1601 : : try
1602 : : {
1603 [ # # ]: 0 : if(eTableOrQuery == SW_DB_SELECT_UNKNOWN)
1604 : : {
1605 : : //search for a table with the given command name
1606 [ # # ]: 0 : Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
1607 [ # # ]: 0 : if(xTSupplier.is())
1608 : : {
1609 [ # # ][ # # ]: 0 : Reference<XNameAccess> xTbls = xTSupplier->getTables();
1610 [ # # ][ # # ]: 0 : eTableOrQuery = xTbls->hasByName(rTableOrQuery) ?
[ # # ]
1611 [ # # ]: 0 : SW_DB_SELECT_TABLE : SW_DB_SELECT_QUERY;
1612 : 0 : }
1613 : : }
1614 : : sal_Int32 nCommandType = SW_DB_SELECT_TABLE == eTableOrQuery ?
1615 [ # # ]: 0 : CommandType::TABLE : CommandType::QUERY;
1616 [ # # ]: 0 : Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
1617 : : Reference<XRowSet> xRowSet(
1618 [ # # ][ # # ]: 0 : xMgr->createInstance(C2U("com.sun.star.sdb.RowSet")), UNO_QUERY);
[ # # ][ # # ]
1619 : :
1620 : 0 : ::rtl::OUString sDataSource;
1621 [ # # ]: 0 : Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection, sDataSource);
1622 [ # # ]: 0 : Reference<XPropertySet> xSourceProperties(xSource, UNO_QUERY);
1623 [ # # ]: 0 : if(xSourceProperties.is())
1624 : : {
1625 [ # # ][ # # ]: 0 : xSourceProperties->getPropertyValue(C2U("Name")) >>= sDataSource;
[ # # ]
1626 : : }
1627 : :
1628 [ # # ]: 0 : Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
1629 [ # # ][ # # ]: 0 : xRowProperties->setPropertyValue(C2U("DataSourceName"), makeAny(sDataSource));
[ # # ][ # # ]
1630 [ # # ][ # # ]: 0 : xRowProperties->setPropertyValue(C2U("Command"), makeAny(::rtl::OUString(rTableOrQuery)));
[ # # ][ # # ]
[ # # ]
1631 [ # # ][ # # ]: 0 : xRowProperties->setPropertyValue(C2U("CommandType"), makeAny(nCommandType));
[ # # ][ # # ]
1632 [ # # ][ # # ]: 0 : xRowProperties->setPropertyValue(C2U("FetchSize"), makeAny((sal_Int32)10));
[ # # ][ # # ]
1633 [ # # ][ # # ]: 0 : xRowProperties->setPropertyValue(C2U("ActiveConnection"), makeAny(xConnection));
[ # # ][ # # ]
1634 [ # # ][ # # ]: 0 : xRowSet->execute();
1635 [ # # ][ # # ]: 0 : xRet = Reference<XColumnsSupplier>( xRowSet, UNO_QUERY );
[ # # ]
1636 : : }
1637 [ # # ]: 0 : catch(const uno::Exception&)
1638 : : {
1639 : : OSL_FAIL("Exception in SwDBMgr::GetColumnSupplier");
1640 : : }
1641 : :
1642 : 0 : return xRet;
1643 : : }
1644 : :
1645 : 0 : String SwNewDBMgr::GetDBField(uno::Reference<XPropertySet> xColumnProps,
1646 : : const SwDBFormatData& rDBFormatData,
1647 : : double* pNumber)
1648 : : {
1649 [ # # ]: 0 : uno::Reference< XColumn > xColumn(xColumnProps, UNO_QUERY);
1650 [ # # ]: 0 : String sRet;
1651 : : OSL_ENSURE(xColumn.is(), "SwNewDBMgr::::ImportDBField: illegal arguments");
1652 [ # # ]: 0 : if(!xColumn.is())
1653 : : return sRet;
1654 : :
1655 [ # # ][ # # ]: 0 : Any aType = xColumnProps->getPropertyValue(C2U("Type"));
[ # # ]
1656 : 0 : sal_Int32 eDataType = 0;
1657 : 0 : aType >>= eDataType;
1658 [ # # # ]: 0 : switch(eDataType)
1659 : : {
1660 : : case DataType::CHAR:
1661 : : case DataType::VARCHAR:
1662 : : case DataType::LONGVARCHAR:
1663 : : try
1664 : : {
1665 [ # # ][ # # ]: 0 : sRet = xColumn->getString();
[ # # ][ # # ]
1666 : : }
1667 [ # # ]: 0 : catch(const SQLException&)
1668 : : {
1669 : : }
1670 : 0 : break;
1671 : : case DataType::BIT:
1672 : : case DataType::BOOLEAN:
1673 : : case DataType::TINYINT:
1674 : : case DataType::SMALLINT:
1675 : : case DataType::INTEGER:
1676 : : case DataType::BIGINT:
1677 : : case DataType::FLOAT:
1678 : : case DataType::REAL:
1679 : : case DataType::DOUBLE:
1680 : : case DataType::NUMERIC:
1681 : : case DataType::DECIMAL:
1682 : : case DataType::DATE:
1683 : : case DataType::TIME:
1684 : : case DataType::TIMESTAMP:
1685 : : {
1686 : :
1687 : : try
1688 : : {
1689 [ # # ]: 0 : SwDbtoolsClient& aClient = SwNewDBMgr::GetDbtoolsClient();
1690 : : sRet = aClient.getFormattedValue(
1691 : : xColumnProps,
1692 : : rDBFormatData.xFormatter,
1693 : : rDBFormatData.aLocale,
1694 [ # # ][ # # ]: 0 : rDBFormatData.aNullDate);
[ # # ]
1695 [ # # ]: 0 : if (pNumber)
1696 : : {
1697 [ # # ][ # # ]: 0 : double fVal = xColumn->getDouble();
1698 [ # # ][ # # ]: 0 : if(!xColumn->wasNull())
[ # # ]
1699 : : {
1700 : 0 : *pNumber = fVal;
1701 : : }
1702 : : }
1703 : : }
1704 [ # # ]: 0 : catch(const Exception&)
1705 : : {
1706 : : OSL_FAIL("exception caught");
1707 : : }
1708 : :
1709 : : }
1710 : 0 : break;
1711 : : }
1712 : :
1713 : 0 : return sRet;
1714 : : }
1715 : :
1716 : : // releases the merge data source table or query after merge is completed
1717 : 0 : void SwNewDBMgr::EndMerge()
1718 : : {
1719 : : OSL_ENSURE(bInMerge, "merge is not active");
1720 : 0 : bInMerge = sal_False;
1721 [ # # ]: 0 : delete pImpl->pMergeData;
1722 : 0 : pImpl->pMergeData = 0;
1723 : 0 : }
1724 : :
1725 : : // checks if a desired data source table or query is open
1726 : 0 : sal_Bool SwNewDBMgr::IsDataSourceOpen(const String& rDataSource,
1727 : : const String& rTableOrQuery, sal_Bool bMergeOnly)
1728 : : {
1729 [ # # ]: 0 : if(pImpl->pMergeData)
1730 : : {
1731 : 0 : return !bMergeLock &&
1732 [ # # ][ # # ]: 0 : ((rDataSource == (String)pImpl->pMergeData->sDataSource &&
[ # # ][ # # ]
1733 [ # # ][ # # ]: 0 : rTableOrQuery == (String)pImpl->pMergeData->sCommand)
[ # # ][ # # ]
[ # # ]
1734 : 0 : ||(!rDataSource.Len() && !rTableOrQuery.Len()))
1735 : : &&
1736 [ # # ][ # # ]: 0 : pImpl->pMergeData->xResultSet.is();
[ # # # #
# # ][ # # ]
1737 : : }
1738 [ # # ]: 0 : else if(!bMergeOnly)
1739 : : {
1740 : 0 : SwDBData aData;
1741 [ # # ]: 0 : aData.sDataSource = rDataSource;
1742 [ # # ]: 0 : aData.sCommand = rTableOrQuery;
1743 : 0 : aData.nCommandType = -1;
1744 [ # # ]: 0 : SwDSParam* pFound = FindDSData(aData, sal_False);
1745 [ # # ][ # # ]: 0 : return (pFound && pFound->xResultSet.is());
1746 : : }
1747 : 0 : return sal_False;
1748 : : }
1749 : :
1750 : : // read column data at a specified position
1751 : 0 : sal_Bool SwNewDBMgr::GetColumnCnt(const String& rSourceName, const String& rTableName,
1752 : : const String& rColumnName, sal_uInt32 nAbsRecordId,
1753 : : long nLanguage,
1754 : : rtl::OUString& rResult, double* pNumber)
1755 : : {
1756 : 0 : sal_Bool bRet = sal_False;
1757 : 0 : SwDSParam* pFound = 0;
1758 : : //check if it's the merge data source
1759 [ # # ][ # # ]: 0 : if(pImpl->pMergeData &&
[ # # ][ # # ]
1760 [ # # ][ # # ]: 0 : rSourceName == (String)pImpl->pMergeData->sDataSource &&
[ # # ][ # # ]
1761 [ # # ][ # # ]: 0 : rTableName == (String)pImpl->pMergeData->sCommand)
[ # # ][ # # ]
[ # # ]
1762 : : {
1763 : 0 : pFound = pImpl->pMergeData;
1764 : : }
1765 : : else
1766 : : {
1767 : 0 : SwDBData aData;
1768 [ # # ]: 0 : aData.sDataSource = rSourceName;
1769 [ # # ]: 0 : aData.sCommand = rTableName;
1770 : 0 : aData.nCommandType = -1;
1771 [ # # ][ # # ]: 0 : pFound = FindDSData(aData, sal_False);
1772 : : }
1773 [ # # ]: 0 : if (!pFound)
1774 : 0 : return sal_False;
1775 : : //check validity of supplied record Id
1776 [ # # ]: 0 : if(pFound->aSelection.getLength())
1777 : : {
1778 : : //the destination has to be an element of the selection
1779 : 0 : const Any* pSelection = pFound->aSelection.getConstArray();
1780 : 0 : sal_Bool bFound = sal_False;
1781 [ # # ][ # # ]: 0 : for(sal_Int32 nPos = 0; !bFound && nPos < pFound->aSelection.getLength(); nPos++)
[ # # ]
1782 : : {
1783 : 0 : sal_Int32 nSelection = 0;
1784 : 0 : pSelection[nPos] >>= nSelection;
1785 [ # # ]: 0 : if(nSelection == static_cast<sal_Int32>(nAbsRecordId))
1786 : 0 : bFound = sal_True;
1787 : : }
1788 [ # # ]: 0 : if(!bFound)
1789 : 0 : return sal_False;
1790 : : }
1791 [ # # ][ # # ]: 0 : if(pFound->xResultSet.is() && !pFound->bAfterSelection)
[ # # ]
1792 : : {
1793 : 0 : sal_Int32 nOldRow = 0;
1794 : : try
1795 : : {
1796 [ # # ][ # # ]: 0 : nOldRow = pFound->xResultSet->getRow();
1797 : : }
1798 : 0 : catch(const Exception&)
1799 : : {
1800 : 0 : return sal_False;
1801 : : }
1802 : : //position to the desired index
1803 : 0 : sal_Bool bMove = sal_True;
1804 [ # # ]: 0 : if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) )
1805 : 0 : bMove = lcl_MoveAbsolute(pFound, nAbsRecordId);
1806 [ # # ]: 0 : if(bMove)
1807 : : {
1808 : 0 : bRet = lcl_GetColumnCnt(pFound, rColumnName, nLanguage, rResult, pNumber);
1809 : : }
1810 [ # # ]: 0 : if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) )
1811 : 0 : bMove = lcl_MoveAbsolute(pFound, nOldRow);
1812 : : }
1813 : 0 : return bRet;
1814 : : }
1815 : :
1816 : :
1817 : : // reads the column data at the current position
1818 : 0 : sal_Bool SwNewDBMgr::GetMergeColumnCnt(const String& rColumnName, sal_uInt16 nLanguage,
1819 : : rtl::OUString &rResult, double *pNumber, sal_uInt32 * /*pFormat*/)
1820 : : {
1821 [ # # ][ # # ]: 0 : if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is() || pImpl->pMergeData->bAfterSelection )
[ # # ][ # # ]
1822 : : {
1823 : 0 : rResult = rtl::OUString();
1824 : 0 : return sal_False;
1825 : : }
1826 : :
1827 : 0 : sal_Bool bRet = lcl_GetColumnCnt(pImpl->pMergeData, rColumnName, nLanguage, rResult, pNumber);
1828 : 0 : return bRet;
1829 : : }
1830 : :
1831 : 0 : sal_Bool SwNewDBMgr::ToNextMergeRecord()
1832 : : {
1833 : : OSL_ENSURE(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
1834 : 0 : return ToNextRecord(pImpl->pMergeData);
1835 : : }
1836 : :
1837 : 0 : sal_Bool SwNewDBMgr::ToNextRecord(
1838 : : const String& rDataSource, const String& rCommand, sal_Int32 /*nCommandType*/)
1839 : : {
1840 : 0 : SwDSParam* pFound = 0;
1841 [ # # ][ # # ]: 0 : if(pImpl->pMergeData &&
[ # # ][ # # ]
1842 [ # # ][ # # ]: 0 : rDataSource == (String)pImpl->pMergeData->sDataSource &&
[ # # ][ # # ]
1843 [ # # ][ # # ]: 0 : rCommand == (String)pImpl->pMergeData->sCommand)
[ # # ][ # # ]
[ # # ]
1844 : 0 : pFound = pImpl->pMergeData;
1845 : : else
1846 : : {
1847 : 0 : SwDBData aData;
1848 [ # # ]: 0 : aData.sDataSource = rDataSource;
1849 [ # # ]: 0 : aData.sCommand = rCommand;
1850 : 0 : aData.nCommandType = -1;
1851 [ # # ]: 0 : pFound = FindDSData(aData, sal_False);
1852 : : }
1853 : 0 : return ToNextRecord(pFound);
1854 : : }
1855 : :
1856 : 0 : sal_Bool SwNewDBMgr::ToNextRecord(SwDSParam* pParam)
1857 : : {
1858 : 0 : sal_Bool bRet = sal_True;
1859 [ # # ][ # # ]: 0 : if(!pParam || !pParam->xResultSet.is() || pParam->bEndOfDB ||
[ # # # #
# # ][ # # ]
1860 : 0 : (pParam->aSelection.getLength() && pParam->aSelection.getLength() <= pParam->nSelectionIndex))
1861 : : {
1862 [ # # ]: 0 : if(pParam)
1863 : 0 : pParam->CheckEndOfDB();
1864 : 0 : return sal_False;
1865 : : }
1866 : : try
1867 : : {
1868 [ # # ]: 0 : if(pParam->aSelection.getLength())
1869 : : {
1870 : 0 : sal_Int32 nPos = 0;
1871 : 0 : pParam->aSelection.getConstArray()[ pParam->nSelectionIndex++ ] >>= nPos;
1872 [ # # ][ # # ]: 0 : pParam->bEndOfDB = !pParam->xResultSet->absolute( nPos );
1873 : 0 : pParam->CheckEndOfDB();
1874 : 0 : bRet = !pParam->bEndOfDB;
1875 [ # # ]: 0 : if(pParam->nSelectionIndex >= pParam->aSelection.getLength())
1876 : 0 : pParam->bEndOfDB = sal_True;
1877 : : }
1878 : : else
1879 : : {
1880 [ # # ][ # # ]: 0 : sal_Int32 nBefore = pParam->xResultSet->getRow();
1881 [ # # ][ # # ]: 0 : pParam->bEndOfDB = !pParam->xResultSet->next();
1882 [ # # ][ # # ]: 0 : if( !pParam->bEndOfDB && nBefore == pParam->xResultSet->getRow())
[ # # ][ # # ]
[ # # ]
1883 : : {
1884 : : //next returned true but it didn't move
1885 : 0 : pParam->bEndOfDB = sal_True;
1886 : : }
1887 : :
1888 : 0 : pParam->CheckEndOfDB();
1889 : 0 : bRet = !pParam->bEndOfDB;
1890 : 0 : ++pParam->nSelectionIndex;
1891 : : }
1892 : : }
1893 : 0 : catch(const Exception&)
1894 : : {
1895 : : }
1896 [ # # ]: 0 : return bRet;
1897 : : }
1898 : :
1899 : : /* ------------------------------------------------------------------------
1900 : : synchronized labels contain a next record field at their end
1901 : : to assure that the next page can be created in mail merge
1902 : : the cursor position must be validated
1903 : : ---------------------------------------------------------------------------*/
1904 : 0 : sal_Bool SwNewDBMgr::ExistsNextRecord() const
1905 : : {
1906 [ # # ][ # # ]: 0 : return pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB;
1907 : : }
1908 : :
1909 : 0 : sal_uInt32 SwNewDBMgr::GetSelectedRecordId()
1910 : : {
1911 : 0 : sal_uInt32 nRet = 0;
1912 : : OSL_ENSURE(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
1913 [ # # ][ # # ]: 0 : if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is())
[ # # ]
1914 : 0 : return sal_False;
1915 : : try
1916 : : {
1917 [ # # ][ # # ]: 0 : nRet = pImpl->pMergeData->xResultSet->getRow();
1918 : : }
1919 : 0 : catch(const Exception&)
1920 : : {
1921 : : }
1922 [ # # ]: 0 : return nRet;
1923 : : }
1924 : :
1925 : 0 : sal_Bool SwNewDBMgr::ToRecordId(sal_Int32 nSet)
1926 : : {
1927 : : OSL_ENSURE(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
1928 [ # # ][ # # ]: 0 : if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()|| nSet < 0)
[ # # ][ # # ]
1929 : 0 : return sal_False;
1930 : 0 : sal_Bool bRet = sal_False;
1931 : 0 : sal_Int32 nAbsPos = nSet;
1932 : :
1933 [ # # ]: 0 : if(nAbsPos >= 0)
1934 : : {
1935 : 0 : bRet = lcl_MoveAbsolute(pImpl->pMergeData, nAbsPos);
1936 : 0 : pImpl->pMergeData->bEndOfDB = !bRet;
1937 : 0 : pImpl->pMergeData->CheckEndOfDB();
1938 : : }
1939 : 0 : return bRet;
1940 : : }
1941 : :
1942 : 0 : sal_Bool SwNewDBMgr::OpenDataSource(const String& rDataSource, const String& rTableOrQuery,
1943 : : sal_Int32 nCommandType, bool bCreate)
1944 : : {
1945 : 0 : SwDBData aData;
1946 [ # # ]: 0 : aData.sDataSource = rDataSource;
1947 [ # # ]: 0 : aData.sCommand = rTableOrQuery;
1948 : 0 : aData.nCommandType = nCommandType;
1949 : :
1950 [ # # ]: 0 : SwDSParam* pFound = FindDSData(aData, sal_True);
1951 : 0 : uno::Reference< XDataSource> xSource;
1952 [ # # ]: 0 : if(pFound->xResultSet.is())
1953 : 0 : return sal_True;
1954 [ # # ][ # # ]: 0 : SwDSParam* pParam = FindDSConnection(rDataSource, sal_False);
1955 : 0 : uno::Reference< XConnection> xConnection;
1956 [ # # ][ # # ]: 0 : if(pParam && pParam->xConnection.is())
[ # # ]
1957 [ # # ]: 0 : pFound->xConnection = pParam->xConnection;
1958 [ # # ]: 0 : else if(bCreate)
1959 : : {
1960 [ # # ]: 0 : rtl::OUString sDataSource(rDataSource);
1961 [ # # ][ # # ]: 0 : pFound->xConnection = RegisterConnection( sDataSource );
[ # # ]
1962 : : }
1963 [ # # ]: 0 : if(pFound->xConnection.is())
1964 : : {
1965 : : try
1966 : : {
1967 [ # # ][ # # ]: 0 : uno::Reference< sdbc::XDatabaseMetaData > xMetaData = pFound->xConnection->getMetaData();
1968 : : try
1969 : : {
1970 : : pFound->bScrollable = xMetaData
1971 [ # # ][ # # ]: 0 : ->supportsResultSetType((sal_Int32)ResultSetType::SCROLL_INSENSITIVE);
1972 : : }
1973 [ # # ]: 0 : catch(const Exception&)
1974 : : {
1975 : : // DB driver may not be ODBC 3.0 compliant
1976 : 0 : pFound->bScrollable = sal_True;
1977 : : }
1978 [ # # ][ # # ]: 0 : pFound->xStatement = pFound->xConnection->createStatement();
[ # # ]
1979 [ # # ][ # # ]: 0 : rtl::OUString aQuoteChar = xMetaData->getIdentifierQuoteString();
1980 [ # # ]: 0 : rtl::OUString sStatement(C2U("SELECT * FROM "));
1981 [ # # ]: 0 : sStatement = C2U("SELECT * FROM ");
1982 : 0 : sStatement += aQuoteChar;
1983 [ # # ]: 0 : sStatement += rTableOrQuery;
1984 : 0 : sStatement += aQuoteChar;
1985 [ # # ][ # # ]: 0 : pFound->xResultSet = pFound->xStatement->executeQuery( sStatement );
[ # # ]
1986 : :
1987 : : //after executeQuery the cursor must be positioned
1988 [ # # ][ # # ]: 0 : pFound->bEndOfDB = !pFound->xResultSet->next();
1989 : 0 : pFound->bAfterSelection = sal_False;
1990 : 0 : pFound->CheckEndOfDB();
1991 : 0 : ++pFound->nSelectionIndex;
1992 : : }
1993 [ # # # # ]: 0 : catch (const Exception&)
1994 : : {
1995 [ # # ]: 0 : pFound->xResultSet = 0;
1996 [ # # ]: 0 : pFound->xStatement = 0;
1997 [ # # ]: 0 : pFound->xConnection = 0;
1998 : : }
1999 : : }
2000 : 0 : return pFound->xResultSet.is();
2001 : : }
2002 : :
2003 : 0 : uno::Reference< XConnection> SwNewDBMgr::RegisterConnection(rtl::OUString& rDataSource)
2004 : : {
2005 [ # # ]: 0 : SwDSParam* pFound = SwNewDBMgr::FindDSConnection(rDataSource, sal_True);
2006 : 0 : uno::Reference< XDataSource> xSource;
2007 [ # # ]: 0 : if(!pFound->xConnection.is())
2008 : : {
2009 [ # # ][ # # ]: 0 : pFound->xConnection = SwNewDBMgr::GetConnection(rDataSource, xSource );
[ # # ][ # # ]
2010 : : try
2011 : : {
2012 [ # # ]: 0 : uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
2013 [ # # ]: 0 : if(xComponent.is())
2014 [ # # ][ # # ]: 0 : xComponent->addEventListener(pImpl->xDisposeListener);
[ # # ]
2015 : : }
2016 [ # # ]: 0 : catch(const Exception&)
2017 : : {
2018 : : }
2019 : : }
2020 : 0 : return pFound->xConnection;
2021 : : }
2022 : :
2023 : 0 : sal_uInt32 SwNewDBMgr::GetSelectedRecordId(
2024 : : const String& rDataSource, const String& rTableOrQuery, sal_Int32 nCommandType)
2025 : : {
2026 : 0 : sal_uInt32 nRet = 0xffffffff;
2027 : : //check for merge data source first
2028 [ # # ][ # # ]: 0 : if(pImpl->pMergeData && rDataSource == (String)pImpl->pMergeData->sDataSource &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # # #
# # ]
2029 [ # # ][ # # ]: 0 : rTableOrQuery == (String)pImpl->pMergeData->sCommand &&
[ # # ][ # # ]
[ # # ]
2030 : : (nCommandType == -1 || nCommandType == pImpl->pMergeData->nCommandType) &&
2031 : 0 : pImpl->pMergeData->xResultSet.is())
2032 [ # # ]: 0 : nRet = GetSelectedRecordId();
2033 : : else
2034 : : {
2035 : 0 : SwDBData aData;
2036 [ # # ]: 0 : aData.sDataSource = rDataSource;
2037 [ # # ]: 0 : aData.sCommand = rTableOrQuery;
2038 : 0 : aData.nCommandType = nCommandType;
2039 [ # # ]: 0 : SwDSParam* pFound = FindDSData(aData, sal_False);
2040 [ # # ][ # # ]: 0 : if(pFound && pFound->xResultSet.is())
[ # # ]
2041 : : {
2042 : : try
2043 : : { //if a selection array is set the current row at the result set may not be set yet
2044 [ # # ]: 0 : if(pFound->aSelection.getLength())
2045 : : {
2046 : 0 : sal_Int32 nSelIndex = pFound->nSelectionIndex;
2047 [ # # ]: 0 : if(nSelIndex >= pFound->aSelection.getLength())
2048 : 0 : nSelIndex = pFound->aSelection.getLength() -1;
2049 : 0 : pFound->aSelection.getConstArray()[nSelIndex] >>= nRet;
2050 : :
2051 : : }
2052 : : else
2053 [ # # ][ # # ]: 0 : nRet = pFound->xResultSet->getRow();
2054 : : }
2055 [ # # ]: 0 : catch(const Exception&)
2056 : : {
2057 : : }
2058 : 0 : }
2059 : : }
2060 : 0 : return nRet;
2061 : : }
2062 : :
2063 : :
2064 : : // close all data sources - after fields were updated
2065 : 42 : void SwNewDBMgr::CloseAll(sal_Bool bIncludingMerge)
2066 : : {
2067 : : //the only thing done here is to reset the selection index
2068 : : //all connections stay open
2069 [ - + ]: 42 : for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.size(); nPos++)
2070 : : {
2071 : 0 : SwDSParam* pParam = &aDataSourceParams[nPos];
2072 [ # # ][ # # ]: 0 : if(bIncludingMerge || pParam != pImpl->pMergeData)
2073 : : {
2074 : 0 : pParam->nSelectionIndex = 0;
2075 : 0 : pParam->bAfterSelection = sal_False;
2076 : 0 : pParam->bEndOfDB = sal_False;
2077 : : try
2078 : : {
2079 [ # # ][ # # ]: 0 : if(!bInMerge && pParam->xResultSet.is())
[ # # ]
2080 [ # # ][ # # ]: 0 : pParam->xResultSet->first();
2081 : : }
2082 : 0 : catch(const Exception&)
2083 : : {}
2084 : : }
2085 : : }
2086 [ # # ]: 42 : }
2087 : :
2088 : 0 : SwDSParam* SwNewDBMgr::FindDSData(const SwDBData& rData, sal_Bool bCreate)
2089 : : {
2090 : : //prefer merge data if available
2091 [ # # ]: 0 : if(pImpl->pMergeData && rData.sDataSource == pImpl->pMergeData->sDataSource &&
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2092 : 0 : rData.sCommand == pImpl->pMergeData->sCommand &&
2093 : : (rData.nCommandType == -1 || rData.nCommandType == pImpl->pMergeData->nCommandType ||
2094 : : (bCreate && pImpl->pMergeData->nCommandType == -1)))
2095 : : {
2096 : 0 : return pImpl->pMergeData;
2097 : : }
2098 : :
2099 : 0 : SwDSParam* pFound = 0;
2100 [ # # ]: 0 : for(sal_uInt16 nPos = aDataSourceParams.size(); nPos; nPos--)
2101 : : {
2102 : 0 : SwDSParam* pParam = &aDataSourceParams[nPos - 1];
2103 [ # # ][ # # ]: 0 : if(rData.sDataSource == pParam->sDataSource &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2104 : 0 : rData.sCommand == pParam->sCommand &&
2105 : : (rData.nCommandType == -1 || rData.nCommandType == pParam->nCommandType ||
2106 : : (bCreate && pParam->nCommandType == -1)))
2107 : : {
2108 : : // calls from the calculator may add a connection with an invalid commandtype
2109 : : //later added "real" data base connections have to re-use the already available
2110 : : //DSData and set the correct CommandType
2111 [ # # ][ # # ]: 0 : if(bCreate && pParam->nCommandType == -1)
2112 : 0 : pParam->nCommandType = rData.nCommandType;
2113 : 0 : pFound = pParam;
2114 : 0 : break;
2115 : : }
2116 : : }
2117 [ # # ]: 0 : if(bCreate)
2118 : : {
2119 [ # # ]: 0 : if(!pFound)
2120 : : {
2121 [ # # ]: 0 : pFound = new SwDSParam(rData);
2122 : 0 : aDataSourceParams.push_back(pFound);
2123 : : try
2124 : : {
2125 [ # # ]: 0 : uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
2126 [ # # ]: 0 : if(xComponent.is())
2127 [ # # ][ # # ]: 0 : xComponent->addEventListener(pImpl->xDisposeListener);
[ # # ]
2128 : : }
2129 : 0 : catch(const Exception&)
2130 : : {
2131 : : }
2132 : : }
2133 : : }
2134 : 0 : return pFound;
2135 : : }
2136 : :
2137 : 0 : SwDSParam* SwNewDBMgr::FindDSConnection(const rtl::OUString& rDataSource, sal_Bool bCreate)
2138 : : {
2139 : : //prefer merge data if available
2140 [ # # ][ # # ]: 0 : if(pImpl->pMergeData && rDataSource == pImpl->pMergeData->sDataSource )
[ # # ]
2141 : : {
2142 : 0 : return pImpl->pMergeData;
2143 : : }
2144 : 0 : SwDSParam* pFound = 0;
2145 [ # # ]: 0 : for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.size(); nPos++)
2146 : : {
2147 : 0 : SwDSParam* pParam = &aDataSourceParams[nPos];
2148 [ # # ]: 0 : if(rDataSource == pParam->sDataSource)
2149 : : {
2150 : 0 : pFound = pParam;
2151 : 0 : break;
2152 : : }
2153 : : }
2154 [ # # ][ # # ]: 0 : if(bCreate && !pFound)
2155 : : {
2156 : 0 : SwDBData aData;
2157 : 0 : aData.sDataSource = rDataSource;
2158 [ # # ][ # # ]: 0 : pFound = new SwDSParam(aData);
2159 [ # # ]: 0 : aDataSourceParams.push_back(pFound);
2160 : : try
2161 : : {
2162 [ # # ]: 0 : uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
2163 [ # # ]: 0 : if(xComponent.is())
2164 [ # # ][ # # ]: 0 : xComponent->addEventListener(pImpl->xDisposeListener);
[ # # ]
2165 : : }
2166 [ # # ]: 0 : catch(const Exception&)
2167 : : {
2168 : 0 : }
2169 : : }
2170 : 0 : return pFound;
2171 : : }
2172 : :
2173 : 252 : const SwDBData& SwNewDBMgr::GetAddressDBName()
2174 : : {
2175 : 252 : return SW_MOD()->GetDBConfig()->GetAddressSource();
2176 : : }
2177 : :
2178 : 0 : Sequence<rtl::OUString> SwNewDBMgr::GetExistingDatabaseNames()
2179 : : {
2180 : 0 : uno::Reference<XNameAccess> xDBContext;
2181 [ # # ]: 0 : uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2182 [ # # ]: 0 : if( xMgr.is() )
2183 : : {
2184 [ # # ][ # # ]: 0 : uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
[ # # ]
2185 [ # # ][ # # ]: 0 : xDBContext = uno::Reference<XNameAccess>(xInstance, UNO_QUERY) ;
2186 : : }
2187 [ # # ]: 0 : if(xDBContext.is())
2188 : : {
2189 [ # # ][ # # ]: 0 : return xDBContext->getElementNames();
2190 : : }
2191 [ # # ]: 0 : return Sequence<rtl::OUString>();
2192 : : }
2193 : :
2194 : 0 : String SwNewDBMgr::LoadAndRegisterDataSource()
2195 : : {
2196 [ # # ]: 0 : sfx2::FileDialogHelper aDlgHelper( TemplateDescription::FILEOPEN_SIMPLE, 0 );
2197 [ # # ]: 0 : Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker();
2198 : :
2199 [ # # ][ # # ]: 0 : String sHomePath(SvtPathOptions().GetWorkPath());
[ # # ][ # # ]
2200 [ # # ]: 0 : aDlgHelper.SetDisplayDirectory( sHomePath );
2201 : :
2202 [ # # ]: 0 : Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY);
2203 : :
2204 [ # # ]: 0 : String sFilterAll(SW_RES(STR_FILTER_ALL));
2205 [ # # ]: 0 : String sFilterAllData(SW_RES(STR_FILTER_ALL_DATA));
2206 [ # # ]: 0 : String sFilterSXB(SW_RES(STR_FILTER_SXB));
2207 [ # # ]: 0 : String sFilterSXC(SW_RES(STR_FILTER_SXC));
2208 [ # # ]: 0 : String sFilterDBF(SW_RES(STR_FILTER_DBF));
2209 [ # # ]: 0 : String sFilterXLS(SW_RES(STR_FILTER_XLS));
2210 [ # # ]: 0 : String sFilterTXT(SW_RES(STR_FILTER_TXT));
2211 [ # # ]: 0 : String sFilterCSV(SW_RES(STR_FILTER_CSV));
2212 : : #ifdef WNT
2213 : : String sFilterMDB(SW_RES(STR_FILTER_MDB));
2214 : : String sFilterACCDB(SW_RES(STR_FILTER_ACCDB));
2215 : : #endif
2216 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterAll, C2U("*") );
[ # # ][ # # ]
2217 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterAllData, C2U("*.ods;*.sxc;*.dbf;*.xls;*.txt;*.csv"));
[ # # ][ # # ]
2218 : :
2219 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterSXB, C2U("*.odb") );
[ # # ][ # # ]
2220 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterSXC, C2U("*.ods;*.sxc") );
[ # # ][ # # ]
2221 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterDBF, C2U("*.dbf") );
[ # # ][ # # ]
2222 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterXLS, C2U("*.xls") );
[ # # ][ # # ]
2223 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterTXT, C2U("*.txt") );
[ # # ][ # # ]
2224 [ # # ][ # # ]: 0 : xFltMgr->appendFilter( sFilterCSV, C2U("*.csv") );
[ # # ][ # # ]
2225 : : #ifdef WNT
2226 : : xFltMgr->appendFilter( sFilterMDB, C2U("*.mdb") );
2227 : : xFltMgr->appendFilter( sFilterACCDB, C2U("*.accdb") );
2228 : : #endif
2229 : :
2230 [ # # ][ # # ]: 0 : xFltMgr->setCurrentFilter( sFilterAll ) ;
[ # # ]
2231 [ # # ]: 0 : String sFind;
2232 : 0 : bool bTextConnection = false;
2233 [ # # ][ # # ]: 0 : if( ERRCODE_NONE == aDlgHelper.Execute() )
2234 : : {
2235 [ # # ][ # # ]: 0 : String sURL = xFP->getFiles().getConstArray()[0];
[ # # ][ # # ]
2236 : : //data sources have to be registered depending on their extensions
2237 [ # # ][ # # ]: 0 : INetURLObject aURL( sURL );
2238 [ # # ][ # # ]: 0 : String sExt( aURL.GetExtension() );
2239 : 0 : Any aURLAny;
2240 : 0 : Any aTableFilterAny;
2241 : 0 : Any aSuppressVersionsAny;
2242 : 0 : Any aInfoAny;
2243 [ # # ]: 0 : INetURLObject aTempURL(aURL);
2244 : 0 : bool bStore = true;
2245 [ # # ][ # # ]: 0 : if(sExt.EqualsAscii("odb"))
2246 : : {
2247 : 0 : bStore = false;
2248 : : }
2249 [ # # ][ # # ]: 0 : else if(sExt.EqualsIgnoreCaseAscii("sxc")
[ # # ][ # # ]
[ # # ]
2250 [ # # ]: 0 : || sExt.EqualsIgnoreCaseAscii("ods")
2251 [ # # ]: 0 : || sExt.EqualsIgnoreCaseAscii("xls"))
2252 : : {
2253 [ # # ]: 0 : rtl::OUString sDBURL(C2U("sdbc:calc:"));
2254 [ # # ]: 0 : sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
2255 [ # # ]: 0 : aURLAny <<= sDBURL;
2256 : : }
2257 [ # # ][ # # ]: 0 : else if(sExt.EqualsIgnoreCaseAscii("dbf"))
2258 : : {
2259 [ # # ]: 0 : aTempURL.removeSegment();
2260 [ # # ]: 0 : aTempURL.removeFinalSlash();
2261 [ # # ]: 0 : rtl::OUString sDBURL(C2U("sdbc:dbase:"));
2262 [ # # ]: 0 : sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
2263 [ # # ]: 0 : aURLAny <<= sDBURL;
2264 : : //set the filter to the file name without extension
2265 [ # # ]: 0 : Sequence<rtl::OUString> aFilters(1);
2266 [ # # ]: 0 : rtl::OUString sTmp(aURL.getBase());
2267 [ # # ][ # # ]: 0 : aFilters[0] = aURL.getBase();
2268 [ # # ][ # # ]: 0 : aTableFilterAny <<= aFilters;
2269 : : }
2270 [ # # ][ # # ]: 0 : else if(sExt.EqualsIgnoreCaseAscii("csv") || sExt.EqualsIgnoreCaseAscii("txt"))
[ # # ][ # # ]
[ # # ]
2271 : : {
2272 [ # # ]: 0 : aTempURL.removeSegment();
2273 [ # # ]: 0 : aTempURL.removeFinalSlash();
2274 [ # # ]: 0 : rtl::OUString sDBURL(C2U("sdbc:flat:"));
2275 : : //only the 'path' has to be added
2276 [ # # ]: 0 : sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
2277 [ # # ]: 0 : aURLAny <<= sDBURL;
2278 : :
2279 : 0 : bTextConnection = true;
2280 : : //set the filter to the file name without extension
2281 [ # # ]: 0 : Sequence<rtl::OUString> aFilters(1);
2282 [ # # ]: 0 : rtl::OUString sTmp(aURL.getBase());
2283 [ # # ][ # # ]: 0 : aFilters[0] = aURL.getBase();
2284 [ # # ][ # # ]: 0 : aTableFilterAny <<= aFilters;
2285 : : }
2286 : : #ifdef WNT
2287 : : else if(sExt.EqualsIgnoreCaseAscii("mdb"))
2288 : : {
2289 : : rtl::OUString sDBURL(C2U("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="));
2290 : : sDBURL += aTempURL.PathToFileName();
2291 : : aURLAny <<= sDBURL;
2292 : : aSuppressVersionsAny <<= makeAny(true);
2293 : : }
2294 : : else if(sExt.EqualsIgnoreCaseAscii("accdb"))
2295 : : {
2296 : : rtl::OUString sDBURL(C2U("sdbc:ado:PROVIDER=Microsoft.ACE.OLEDB.12.0;DATA SOURCE="));
2297 : : sDBURL += aTempURL.PathToFileName();
2298 : : aURLAny <<= sDBURL;
2299 : : aSuppressVersionsAny <<= makeAny(true);
2300 : : }
2301 : : #endif
2302 : : try
2303 : : {
2304 [ # # ]: 0 : Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2305 [ # # ][ # # ]: 0 : Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
[ # # ]
2306 [ # # ]: 0 : Reference<XNameAccess> xDBContext(xInstance, UNO_QUERY_THROW);
2307 [ # # ]: 0 : Reference<XSingleServiceFactory> xFact( xDBContext, UNO_QUERY);
2308 : :
2309 : : String sNewName = INetURLObject::decode( aURL.getName(),
2310 : : INET_HEX_ESCAPE,
2311 : : INetURLObject::DECODE_UNAMBIGUOUS,
2312 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_UTF8 );
[ # # ]
2313 [ # # ]: 0 : xub_StrLen nExtLen = static_cast< xub_StrLen >(aURL.GetExtension().getLength());
2314 [ # # ]: 0 : sNewName.Erase( sNewName.Len() - nExtLen - 1, nExtLen + 1 );
2315 : :
2316 : : //find a unique name if sNewName already exists
2317 [ # # ]: 0 : sFind = sNewName;
2318 : 0 : sal_Int32 nIndex = 0;
2319 [ # # ][ # # ]: 0 : while(xDBContext->hasByName(sFind))
[ # # ][ # # ]
2320 : : {
2321 [ # # ]: 0 : sFind = sNewName;
2322 [ # # ][ # # ]: 0 : sFind += String::CreateFromInt32(++nIndex);
[ # # ]
2323 : : }
2324 : :
2325 : 0 : Reference<XInterface> xNewInstance;
2326 [ # # ]: 0 : if(!bStore)
2327 : : {
2328 : : //odb-file
2329 [ # # ][ # # ]: 0 : Any aDataSource = xDBContext->getByName(aTempURL.GetMainURL(INetURLObject::NO_DECODE));
[ # # ]
2330 [ # # ]: 0 : aDataSource >>= xNewInstance;
2331 : : }
2332 : : else
2333 : : {
2334 [ # # ][ # # ]: 0 : xNewInstance = xFact->createInstance();
[ # # ]
2335 [ # # ]: 0 : Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY);
2336 : :
2337 [ # # ]: 0 : if(aURLAny.hasValue())
2338 [ # # ][ # # ]: 0 : xDataProperties->setPropertyValue(C2U("URL"), aURLAny);
[ # # ]
2339 [ # # ]: 0 : if(aTableFilterAny.hasValue())
2340 [ # # ][ # # ]: 0 : xDataProperties->setPropertyValue(C2U("TableFilter"), aTableFilterAny);
[ # # ]
2341 [ # # ]: 0 : if(aSuppressVersionsAny.hasValue())
2342 [ # # ][ # # ]: 0 : xDataProperties->setPropertyValue(C2U("SuppressVersionColumns"), aSuppressVersionsAny);
[ # # ]
2343 [ # # ]: 0 : if(aInfoAny.hasValue())
2344 [ # # ][ # # ]: 0 : xDataProperties->setPropertyValue(C2U("Info"), aInfoAny);
[ # # ]
2345 : :
2346 [ # # ]: 0 : if( bTextConnection )
2347 : : {
2348 : : uno::Reference < ui::dialogs::XExecutableDialog > xSettingsDlg(
2349 [ # # ][ # # ]: 0 : xMgr->createInstance( C2U( "com.sun.star.sdb.TextConnectionSettings" ) ), uno::UNO_QUERY);
[ # # ][ # # ]
2350 [ # # ][ # # ]: 0 : if( xSettingsDlg->execute() )
[ # # ]
2351 : : {
2352 [ # # ][ # # ]: 0 : uno::Any aSettings = xDataProperties->getPropertyValue( C2U( "Settings" ) );
[ # # ]
2353 : 0 : uno::Reference < beans::XPropertySet > xDSSettings;
2354 [ # # ]: 0 : aSettings >>= xDSSettings;
2355 : : ::comphelper::copyProperties(
2356 : : uno::Reference < beans::XPropertySet >( xSettingsDlg, uno::UNO_QUERY ),
2357 [ # # ][ # # ]: 0 : xDSSettings );
2358 [ # # ][ # # ]: 0 : xDSSettings->setPropertyValue( C2U("Extension"), uno::makeAny( ::rtl::OUString( sExt )));
[ # # ][ # # ]
[ # # ]
2359 : 0 : }
2360 : : }
2361 : :
2362 [ # # ]: 0 : Reference<XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW);
2363 [ # # ][ # # ]: 0 : Reference<XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW);
[ # # ]
2364 [ # # ]: 0 : String sOutputExt = rtl::OUString(".odb");
2365 [ # # ]: 0 : String sTmpName;
2366 : : {
2367 [ # # ]: 0 : utl::TempFile aTempFile(sNewName , &sOutputExt, &sHomePath);
2368 : 0 : aTempFile.EnableKillingFile(sal_True);
2369 [ # # ][ # # ]: 0 : sTmpName = aTempFile.GetURL();
[ # # ][ # # ]
2370 : : }
2371 [ # # ][ # # ]: 0 : xStore->storeAsURL(sTmpName, Sequence< PropertyValue >());
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2372 : : }
2373 [ # # ]: 0 : Reference<XNamingService> xNaming(xDBContext, UNO_QUERY);
2374 [ # # ][ # # ]: 0 : xNaming->registerObject( sFind, xNewInstance );
[ # # ][ # # ]
[ # # ]
2375 : :
2376 : : }
2377 [ # # ]: 0 : catch(const Exception&)
2378 : : {
2379 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
2380 : : }
2381 [ # # ][ # # ]: 0 : return sFind;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2382 : :
2383 : : }
2384 : :
2385 : 0 : void SwNewDBMgr::ExecuteFormLetter( SwWrtShell& rSh,
2386 : : const Sequence<PropertyValue>& rProperties,
2387 : : sal_Bool bWithDataSourceBrowser)
2388 : : {
2389 : : //prevent second call
2390 [ # # ]: 0 : if(pImpl->pMergeDialog)
2391 : : return ;
2392 : 0 : rtl::OUString sDataSource, sDataTableOrQuery;
2393 [ # # ]: 0 : Sequence<Any> aSelection;
2394 : :
2395 : 0 : sal_Int16 nCmdType = CommandType::TABLE;
2396 : 0 : uno::Reference< XConnection> xConnection;
2397 : :
2398 [ # # ]: 0 : ODataAccessDescriptor aDescriptor(rProperties);
2399 [ # # ]: 0 : sDataSource = aDescriptor.getDataSource();
2400 [ # # ]: 0 : aDescriptor[daCommand] >>= sDataTableOrQuery;
2401 [ # # ]: 0 : aDescriptor[daCommandType] >>= nCmdType;
2402 : :
2403 [ # # ][ # # ]: 0 : if ( aDescriptor.has(daSelection) )
2404 [ # # ][ # # ]: 0 : aDescriptor[daSelection] >>= aSelection;
2405 [ # # ][ # # ]: 0 : if ( aDescriptor.has(daConnection) )
2406 [ # # ][ # # ]: 0 : aDescriptor[daConnection] >>= xConnection;
2407 : :
2408 [ # # ][ # # ]: 0 : if(sDataSource.isEmpty() || sDataTableOrQuery.isEmpty())
[ # # ]
2409 : : {
2410 : : OSL_FAIL("PropertyValues missing or unset");
2411 : : return;
2412 : : }
2413 : :
2414 : : //always create a connection for the dialog and dispose it after the dialog has been closed
2415 : 0 : SwDSParam* pFound = 0;
2416 [ # # ]: 0 : if(!xConnection.is())
2417 : : {
2418 [ # # ][ # # ]: 0 : xConnection = SwNewDBMgr::RegisterConnection(sDataSource);
2419 [ # # ]: 0 : pFound = FindDSConnection(sDataSource, sal_True);
2420 : : }
2421 [ # # ]: 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
2422 : : OSL_ENSURE(pFact, "Dialogdiet fail!");
2423 : : pImpl->pMergeDialog = pFact->CreateMailMergeDlg( DLG_MAILMERGE,
2424 [ # # ]: 0 : &rSh.GetView().GetViewFrame()->GetWindow(), rSh,
2425 : : sDataSource,
2426 : : sDataTableOrQuery,
2427 : : nCmdType,
2428 : : xConnection,
2429 [ # # ][ # # ]: 0 : bWithDataSourceBrowser ? 0 : &aSelection);
[ # # ][ # # ]
[ # # ][ # # ]
2430 : : OSL_ENSURE(pImpl->pMergeDialog, "Dialogdiet fail!");
2431 [ # # ][ # # ]: 0 : if(pImpl->pMergeDialog->Execute() == RET_OK)
2432 : : {
2433 [ # # ][ # # ]: 0 : aDescriptor[daSelection] <<= pImpl->pMergeDialog->GetSelection();
[ # # ][ # # ]
2434 : :
2435 [ # # ]: 0 : uno::Reference<XResultSet> xResSet = pImpl->pMergeDialog->GetResultSet();
2436 [ # # ]: 0 : if(xResSet.is())
2437 [ # # ][ # # ]: 0 : aDescriptor[daCursor] <<= xResSet;
2438 : :
2439 : : // SfxObjectShellRef is ok, since there should be no control over the document lifetime here
2440 [ # # ]: 0 : SfxObjectShellRef xDocShell = rSh.GetView().GetViewFrame()->GetObjectShell();
2441 [ # # ][ # # ]: 0 : SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xDocShell));
[ # # ][ # # ]
[ # # ]
2442 : : {
2443 : : //copy rSh to aTempFile
2444 : 0 : ::rtl::OUString sTempURL;
2445 : : const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
2446 : : rtl::OUString(FILTER_XML),
2447 [ # # ][ # # ]: 0 : SwDocShell::Factory().GetFilterContainer() );
[ # # ][ # # ]
[ # # ]
2448 : : try
2449 : : {
2450 : :
2451 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aValues(1);
2452 [ # # ]: 0 : beans::PropertyValue* pValues = aValues.getArray();
2453 [ # # ]: 0 : pValues[0].Name = C2U("FilterName");
2454 [ # # ][ # # ]: 0 : pValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName());
2455 [ # # ][ # # ]: 0 : uno::Reference< frame::XStorable > xStore( xDocShell->GetModel(), uno::UNO_QUERY);
2456 [ # # ][ # # ]: 0 : sTempURL = URIHelper::SmartRel2Abs( INetURLObject(), utl::TempFile::CreateTempName() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2457 [ # # ][ # # ]: 0 : xStore->storeToURL( sTempURL, aValues );
[ # # ][ # # ]
2458 : : }
2459 [ # # ]: 0 : catch(const uno::Exception&)
2460 : : {
2461 : : }
2462 [ # # ][ # # ]: 0 : if( xDocShell->GetError() )
2463 : : {
2464 : : // error message ??
2465 [ # # ][ # # ]: 0 : ErrorHandler::HandleError( xDocShell->GetError() );
2466 : : }
2467 : : else
2468 : : {
2469 : : // the shell will be explicitly closed, but it is more safe to use SfxObjectShellLock here
2470 : : // especially for the case that the loading has failed
2471 [ # # ][ # # ]: 0 : SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
[ # # ]
2472 [ # # ][ # # ]: 0 : SfxMedium* pWorkMed = new SfxMedium( sTempURL, STREAM_STD_READ );
[ # # ][ # # ]
2473 [ # # ]: 0 : pWorkMed->SetFilter( pSfxFlt );
2474 [ # # ][ # # ]: 0 : if( xWorkDocSh->DoLoad(pWorkMed) )
2475 : : {
2476 [ # # ]: 0 : SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 );
2477 [ # # ]: 0 : SwView *pView = (SwView*) pFrame->GetViewShell();
2478 [ # # ]: 0 : pView->AttrChangedNotify( &pView->GetWrtShell() );// in order for SelectShell to be called
2479 : : //set the current DBMgr
2480 : 0 : SwDoc* pWorkDoc = pView->GetWrtShell().GetDoc();
2481 : 0 : SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
2482 : 0 : pWorkDoc->SetNewDBMgr( this );
2483 : :
2484 [ # # ][ # # ]: 0 : SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), pView->GetWrtShell(), aDescriptor );
2485 [ # # ][ # # ]: 0 : aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter();
2486 [ # # ]: 0 : aMergeDesc.bCreateSingleFile = !pImpl->pMergeDialog->IsSaveIndividualDocs();
2487 [ # # ][ # # ]: 0 : if( !aMergeDesc.bCreateSingleFile && pImpl->pMergeDialog->IsGenerateFromDataBase() )
[ # # ][ # # ]
2488 : : {
2489 [ # # ][ # # ]: 0 : aMergeDesc.sAddressFromColumn = pImpl->pMergeDialog->GetColumnName();
[ # # ]
2490 [ # # ][ # # ]: 0 : aMergeDesc.sSubject = pImpl->pMergeDialog->GetPath();
[ # # ]
2491 : : }
2492 : :
2493 [ # # ]: 0 : MergeNew(aMergeDesc);
2494 : :
2495 : 0 : pWorkDoc->SetNewDBMgr( pWorkDBMgr );
2496 : : //close the temporary file
2497 [ # # ][ # # ]: 0 : uno::Reference< util::XCloseable > xClose( xWorkDocSh->GetModel(), uno::UNO_QUERY );
[ # # ]
2498 [ # # ]: 0 : if (xClose.is())
2499 : : {
2500 : : try
2501 : : {
2502 : : //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
2503 : : //! I.e. now that object is responsible for closing the model and doc shell.
2504 [ # # ][ # # ]: 0 : xClose->close( sal_True );
2505 : : }
2506 [ # # ]: 0 : catch (const uno::Exception&)
2507 : : {
2508 : : }
2509 [ # # ]: 0 : }
2510 [ # # ]: 0 : }
2511 : : }
2512 : : //remove the temporary file
2513 [ # # ][ # # ]: 0 : SWUnoHelper::UCB_DeleteFile( sTempURL );
[ # # ]
2514 : : }
2515 [ # # ][ # # ]: 0 : SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), rSh.GetView().GetViewFrame()->GetObjectShell()));
[ # # ][ # # ]
[ # # ][ # # ]
2516 : :
2517 : : // reset the cursor inside
2518 [ # # ]: 0 : xResSet = NULL;
2519 [ # # ][ # # ]: 0 : aDescriptor[daCursor] <<= xResSet;
[ # # ]
2520 : : }
2521 [ # # ]: 0 : if(pFound)
2522 : : {
2523 [ # # ]: 0 : for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.size(); nPos++)
2524 : : {
2525 [ # # ]: 0 : SwDSParam* pParam = &aDataSourceParams[nPos];
2526 [ # # ]: 0 : if(pParam == pFound)
2527 : : {
2528 : : try
2529 : : {
2530 [ # # ]: 0 : uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY);
2531 [ # # ]: 0 : if(xComp.is())
2532 [ # # ][ # # ]: 0 : xComp->dispose();
[ # # ]
2533 : : }
2534 [ # # ]: 0 : catch(const RuntimeException&)
2535 : : {
2536 : : //may be disposed already since multiple entries may have used the same connection
2537 : : }
2538 : 0 : break;
2539 : : }
2540 : : //pFound doesn't need to be removed/deleted -
2541 : : //this has been done by the SwConnectionDisposedListener_Impl already
2542 : : }
2543 : : }
2544 [ # # ][ # # ]: 0 : DELETEZ(pImpl->pMergeDialog);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2545 : : }
2546 : :
2547 : 0 : void SwNewDBMgr::InsertText(SwWrtShell& rSh,
2548 : : const Sequence< PropertyValue>& rProperties)
2549 : : {
2550 : 0 : rtl::OUString sDataSource, sDataTableOrQuery;
2551 : 0 : uno::Reference<XResultSet> xResSet;
2552 [ # # ]: 0 : Sequence<Any> aSelection;
2553 : 0 : sal_Int16 nCmdType = CommandType::TABLE;
2554 : 0 : const PropertyValue* pValues = rProperties.getConstArray();
2555 : 0 : uno::Reference< XConnection> xConnection;
2556 [ # # ]: 0 : for(sal_Int32 nPos = 0; nPos < rProperties.getLength(); nPos++)
2557 : : {
2558 [ # # ]: 0 : if ( pValues[nPos].Name == cDataSourceName )
2559 : 0 : pValues[nPos].Value >>= sDataSource;
2560 [ # # ]: 0 : else if ( pValues[nPos].Name == cCommand )
2561 : 0 : pValues[nPos].Value >>= sDataTableOrQuery;
2562 [ # # ]: 0 : else if ( pValues[nPos].Name == cCursor )
2563 [ # # ]: 0 : pValues[nPos].Value >>= xResSet;
2564 [ # # ]: 0 : else if ( pValues[nPos].Name == cSelection )
2565 [ # # ]: 0 : pValues[nPos].Value >>= aSelection;
2566 [ # # ]: 0 : else if ( pValues[nPos].Name == cCommandType )
2567 : 0 : pValues[nPos].Value >>= nCmdType;
2568 [ # # ]: 0 : else if ( pValues[nPos].Name == cActiveConnection )
2569 [ # # ]: 0 : pValues[nPos].Value >>= xConnection;
2570 : : }
2571 [ # # ][ # # ]: 0 : if(sDataSource.isEmpty() || sDataTableOrQuery.isEmpty() || !xResSet.is())
[ # # ][ # # ]
2572 : : {
2573 : : OSL_FAIL("PropertyValues missing or unset");
2574 : 0 : return;
2575 : : }
2576 [ # # ]: 0 : uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2577 : 0 : uno::Reference<XDataSource> xSource;
2578 [ # # ]: 0 : uno::Reference<XChild> xChild(xConnection, UNO_QUERY);
2579 [ # # ]: 0 : if(xChild.is())
2580 [ # # ][ # # ]: 0 : xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
[ # # ][ # # ]
2581 [ # # ]: 0 : if(!xSource.is())
2582 [ # # ][ # # ]: 0 : xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(sDataSource, xMgr);
[ # # ]
2583 [ # # ]: 0 : uno::Reference< XColumnsSupplier > xColSupp( xResSet, UNO_QUERY );
2584 : 0 : SwDBData aDBData;
2585 : 0 : aDBData.sDataSource = sDataSource;
2586 : 0 : aDBData.sCommand = sDataTableOrQuery;
2587 : 0 : aDBData.nCommandType = nCmdType;
2588 : :
2589 [ # # ]: 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
2590 : : OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
2591 : :
2592 : 0 : AbstractSwInsertDBColAutoPilot* pDlg = pFact->CreateSwInsertDBColAutoPilot( rSh.GetView(),
2593 : : xSource,
2594 : : xColSupp,
2595 : : aDBData,
2596 [ # # ]: 0 : DLG_AP_INSERT_DB_SEL );
2597 : : OSL_ENSURE(pDlg, "Dialogdiet fail!");
2598 [ # # ][ # # ]: 0 : if( RET_OK == pDlg->Execute() )
2599 : : {
2600 : 0 : rtl::OUString sDummy;
2601 [ # # ]: 0 : if(!xConnection.is())
2602 [ # # ][ # # ]: 0 : xConnection = xSource->getConnection(sDummy, sDummy);
[ # # ]
2603 : : try
2604 : : {
2605 [ # # ][ # # ]: 0 : pDlg->DataToDoc( aSelection , xSource, xConnection, xResSet);
2606 : : }
2607 [ # # ]: 0 : catch(const Exception&)
2608 : : {
2609 : : OSL_FAIL("exception caught");
2610 : 0 : }
2611 : : }
2612 [ # # ][ # # ]: 0 : delete pDlg;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2613 : :
2614 : : }
2615 : :
2616 : : SwDbtoolsClient* SwNewDBMgr::pDbtoolsClient = NULL;
2617 : :
2618 : 0 : SwDbtoolsClient& SwNewDBMgr::GetDbtoolsClient()
2619 : : {
2620 [ # # ]: 0 : if ( !pDbtoolsClient )
2621 [ # # ]: 0 : pDbtoolsClient = new SwDbtoolsClient;
2622 : 0 : return *pDbtoolsClient;
2623 : : }
2624 : :
2625 : 73 : void SwNewDBMgr::RemoveDbtoolsClient()
2626 : : {
2627 [ - + ]: 73 : delete pDbtoolsClient;
2628 : 73 : pDbtoolsClient = 0;
2629 : 73 : }
2630 : :
2631 : 0 : uno::Reference<XDataSource> SwNewDBMgr::getDataSourceAsParent(const uno::Reference< XConnection>& _xConnection,const ::rtl::OUString& _sDataSourceName)
2632 : : {
2633 : 0 : uno::Reference<XDataSource> xSource;
2634 : : try
2635 : : {
2636 [ # # ]: 0 : uno::Reference<XChild> xChild(_xConnection, UNO_QUERY);
2637 [ # # ]: 0 : if ( xChild.is() )
2638 [ # # ][ # # ]: 0 : xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
[ # # ][ # # ]
2639 [ # # ]: 0 : if ( !xSource.is() )
2640 [ # # ][ # # ]: 0 : xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(_sDataSourceName, ::comphelper::getProcessServiceFactory());
[ # # ][ # # ]
[ # # ]
2641 : : }
2642 [ # # ]: 0 : catch(const Exception&)
2643 : : {
2644 : : OSL_FAIL("exception in getDataSourceAsParent caught");
2645 : : }
2646 : 0 : return xSource;
2647 : : }
2648 : :
2649 : 0 : uno::Reference<XResultSet> SwNewDBMgr::createCursor(const ::rtl::OUString& _sDataSourceName,
2650 : : const ::rtl::OUString& _sCommand,
2651 : : sal_Int32 _nCommandType,
2652 : : const uno::Reference<XConnection>& _xConnection
2653 : : )
2654 : : {
2655 : 0 : uno::Reference<XResultSet> xResultSet;
2656 : : try
2657 : : {
2658 [ # # ]: 0 : uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2659 [ # # ]: 0 : if( xMgr.is() )
2660 : : {
2661 [ # # ]: 0 : uno::Reference<XInterface> xInstance = xMgr->createInstance(
2662 [ # # ][ # # ]: 0 : C2U( "com.sun.star.sdb.RowSet" ));
2663 [ # # ]: 0 : uno::Reference<XPropertySet> xRowSetPropSet(xInstance, UNO_QUERY);
2664 [ # # ]: 0 : if(xRowSetPropSet.is())
2665 : : {
2666 [ # # ][ # # ]: 0 : xRowSetPropSet->setPropertyValue(C2U("DataSourceName"), makeAny(_sDataSourceName));
[ # # ][ # # ]
2667 [ # # ][ # # ]: 0 : xRowSetPropSet->setPropertyValue(C2U("ActiveConnection"), makeAny(_xConnection));
[ # # ][ # # ]
2668 [ # # ][ # # ]: 0 : xRowSetPropSet->setPropertyValue(C2U("Command"), makeAny(_sCommand));
[ # # ][ # # ]
2669 [ # # ][ # # ]: 0 : xRowSetPropSet->setPropertyValue(C2U("CommandType"), makeAny(_nCommandType));
[ # # ][ # # ]
2670 : :
2671 [ # # ]: 0 : uno::Reference< XCompletedExecution > xRowSet(xInstance, UNO_QUERY);
2672 : :
2673 [ # # ]: 0 : if ( xRowSet.is() )
2674 : : {
2675 [ # # ][ # # ]: 0 : uno::Reference< XInteractionHandler > xHandler(xMgr->createInstance(C2U("com.sun.star.task.InteractionHandler")), UNO_QUERY);
[ # # ][ # # ]
2676 [ # # ][ # # ]: 0 : xRowSet->executeWithCompletion(xHandler);
2677 : : }
2678 [ # # ][ # # ]: 0 : xResultSet = uno::Reference<XResultSet>(xRowSet, UNO_QUERY);
2679 : 0 : }
2680 [ # # ]: 0 : }
2681 : : }
2682 [ # # ]: 0 : catch(const Exception&)
2683 : : {
2684 : : OSL_FAIL("Caught exception while creating a new RowSet!");
2685 : : }
2686 : 0 : return xResultSet;
2687 : : }
2688 : :
2689 : :
2690 : : // merge all data into one resulting document and return the number of merged documents
2691 : 0 : sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
2692 : : SwView& rSourceView )
2693 : : {
2694 : : // check the availability of all data in the config item
2695 [ # # ]: 0 : uno::Reference< XResultSet> xResultSet = rMMConfig.GetResultSet();
2696 [ # # ]: 0 : if(!xResultSet.is())
2697 : 0 : return false;
2698 : 0 : bInMerge = sal_True;
2699 : 0 : sal_Int32 nRet = 0;
2700 : : pImpl->pMergeData = new SwDSParam(
2701 [ # # ][ # # ]: 0 : rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection());
[ # # ][ # # ]
[ # # # # ]
2702 : :
2703 : : try{
2704 : : //set to start position
2705 [ # # ]: 0 : if(pImpl->pMergeData->aSelection.getLength())
2706 : : {
2707 : 0 : sal_Int32 nPos = 0;
2708 : 0 : pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
2709 [ # # ][ # # ]: 0 : pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
2710 : 0 : pImpl->pMergeData->CheckEndOfDB();
2711 [ # # ]: 0 : if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
2712 : 0 : pImpl->pMergeData->bEndOfDB = sal_True;
2713 : : }
2714 : : else
2715 : : {
2716 [ # # ][ # # ]: 0 : pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
2717 : 0 : pImpl->pMergeData->CheckEndOfDB();
2718 : : }
2719 : : }
2720 [ # # ]: 0 : catch(const Exception&)
2721 : : {
2722 : 0 : pImpl->pMergeData->bEndOfDB = sal_True;
2723 : 0 : pImpl->pMergeData->CheckEndOfDB();
2724 : : OSL_FAIL("exception in MergeNew()");
2725 : : }
2726 : :
2727 : : //bCancel is set from the PrintMonitor
2728 : 0 : bCancel = sal_False;
2729 : :
2730 [ # # ]: 0 : CreateMonitor aMonitorDlg(&rSourceView.GetEditWin());
2731 [ # # ][ # # ]: 0 : aMonitorDlg.SetCancelHdl(LINK(this, SwNewDBMgr, PrtCancelHdl));
2732 [ # # ]: 0 : if (!IsMergeSilent())
2733 : : {
2734 [ # # ]: 0 : aMonitorDlg.Show();
2735 [ # # ]: 0 : aMonitorDlg.Invalidate();
2736 [ # # ]: 0 : aMonitorDlg.Update();
2737 : : // the print monitor needs some time to act
2738 [ # # ]: 0 : for( sal_uInt16 i = 0; i < 25; i++)
2739 [ # # ]: 0 : Application::Reschedule();
2740 : : }
2741 : :
2742 : 0 : SwWrtShell& rSourceShell = rSourceView.GetWrtShell();
2743 [ # # ][ # # ]: 0 : sal_Bool bSynchronizedDoc = rSourceShell.IsLabelDoc() && rSourceShell.GetSectionFmtCount() > 1;
[ # # ][ # # ]
2744 : : //save the settings of the first
2745 [ # # ]: 0 : rSourceShell.SttEndDoc(sal_True);
2746 [ # # ]: 0 : sal_uInt16 nStartingPageNo = rSourceShell.GetVirtPageNum();
2747 [ # # ]: 0 : String sModifiedStartingPageDesc;
2748 : : String sStartingPageDesc = sModifiedStartingPageDesc = rSourceShell.GetPageDesc(
2749 [ # # ][ # # ]: 0 : rSourceShell.GetCurPageDesc()).GetName();
[ # # ][ # # ]
2750 : :
2751 : : try
2752 : : {
2753 : : // create a target docshell to put the merged document into
2754 [ # # ][ # # ]: 0 : SfxObjectShellRef xTargetDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) );
2755 [ # # ]: 0 : xTargetDocShell->DoInitNew( 0 );
2756 [ # # ]: 0 : SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );
2757 : :
2758 : : //the created window has to be located at the same position as the source window
2759 [ # # ][ # # ]: 0 : Window& rTargetWindow = pTargetFrame->GetFrame().GetWindow();
2760 [ # # ][ # # ]: 0 : Window& rSourceWindow = rSourceView.GetViewFrame()->GetFrame().GetWindow();
2761 [ # # ][ # # ]: 0 : rTargetWindow.SetPosPixel(rSourceWindow.GetPosPixel());
2762 : :
2763 [ # # ]: 0 : SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
2764 [ # # ]: 0 : rMMConfig.SetTargetView(pTargetView);
2765 : : //initiate SelectShell() to create sub shells
2766 [ # # ]: 0 : pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
2767 : 0 : SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr();
2768 : : // #i63806#
2769 [ # # ]: 0 : const SwPageDesc* pSourcePageDesc = rSourceShell.FindPageDescByName( sStartingPageDesc );
2770 : 0 : const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
2771 [ # # ]: 0 : bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() ||
2772 [ # # ][ # # ]: 0 : rMaster.GetFooter().IsActive();
[ # # ]
2773 : :
2774 : :
2775 : : // copy compatibility options
2776 [ # # ]: 0 : lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell);
2777 : : // #72821# copy dynamic defaults
2778 [ # # ]: 0 : lcl_CopyDynamicDefaults( *rSourceShell.GetDoc(), *pTargetShell->GetDoc() );
2779 : :
2780 : :
2781 : : long nStartRow, nEndRow;
2782 : 0 : sal_uLong nDocNo = 1;
2783 : 0 : sal_Int32 nDocCount = 0;
2784 [ # # ][ # # ]: 0 : if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) )
[ # # ][ # # ]
2785 [ # # ]: 0 : aMonitorDlg.SetTotalCount( nDocCount );
2786 : :
2787 [ # # ][ # # ]: 0 : do
[ # # ][ # # ]
[ # # ]
2788 : : {
2789 [ # # ][ # # ]: 0 : nStartRow = pImpl->pMergeData->xResultSet->getRow();
2790 [ # # ]: 0 : if (!IsMergeSilent())
2791 : : {
2792 [ # # ]: 0 : aMonitorDlg.SetCurrentPosition( nDocNo );
2793 [ # # ]: 0 : aMonitorDlg.Invalidate();
2794 [ # # ]: 0 : aMonitorDlg.Update();
2795 : : // the print monitor needs some time to act
2796 [ # # ]: 0 : for( sal_uInt16 i = 0; i < 25; i++)
2797 [ # # ]: 0 : Application::Reschedule();
2798 : : }
2799 : :
2800 : : // copy the source document
2801 : : // the copy will be closed later, but it is more safe to use SfxObjectShellLock here
2802 : 0 : SfxObjectShellLock xWorkDocSh;
2803 [ # # ]: 0 : if(nDocNo == 1 )
2804 : : {
2805 [ # # ][ # # ]: 0 : uno::Reference< util::XCloneable > xClone( rSourceView.GetDocShell()->GetModel(), uno::UNO_QUERY);
[ # # ]
2806 [ # # ][ # # ]: 0 : uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY);
[ # # ]
2807 [ # # ][ # # ]: 0 : SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId()));
[ # # ]
2808 [ # # ]: 0 : xWorkDocSh = pWorkModel->GetDocShell();
2809 : : }
2810 : : else
2811 : : {
2812 [ # # ][ # # ]: 0 : xWorkDocSh = rSourceView.GetDocShell()->GetDoc()->CreateCopy(true);
[ # # ]
2813 : : }
2814 : : //create a ViewFrame
2815 [ # # ][ # # ]: 0 : SwView* pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() );
2816 : 0 : SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
2817 [ # # ]: 0 : pWorkView->AttrChangedNotify( &rWorkShell );// in order for SelectShell to be called
2818 : :
2819 : : // merge the data
2820 : 0 : SwDoc* pWorkDoc = rWorkShell.GetDoc();
2821 : 0 : SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
2822 : 0 : pWorkDoc->SetNewDBMgr( this );
2823 [ # # ]: 0 : pWorkDoc->EmbedAllLinks();
2824 : 0 : SwUndoId nLastUndoId(UNDO_EMPTY);
2825 [ # # ][ # # ]: 0 : if (rWorkShell.GetLastUndoInfo(0, & nLastUndoId))
2826 : : {
2827 [ # # ]: 0 : if (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId)
2828 : : {
2829 [ # # ]: 0 : rWorkShell.Undo();
2830 : : }
2831 : : }
2832 : : // #i69485# lock fields to prevent access to the result set while calculating layout
2833 [ # # ]: 0 : rWorkShell.LockExpFlds();
2834 : : // create a layout
2835 [ # # ]: 0 : rWorkShell.CalcLayout();
2836 [ # # ]: 0 : rWorkShell.UnlockExpFlds();
2837 [ # # ][ # # ]: 0 : SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
[ # # ][ # # ]
[ # # ][ # # ]
2838 [ # # ]: 0 : rWorkShell.ViewShell::UpdateFlds();
2839 [ # # ][ # # ]: 0 : SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
[ # # ][ # # ]
[ # # ][ # # ]
2840 : :
2841 : : // strip invisible content and convert fields to text
2842 [ # # ]: 0 : rWorkShell.RemoveInvisibleContent();
2843 [ # # ]: 0 : rWorkShell.ConvertFieldsToText();
2844 [ # # ]: 0 : rWorkShell.SetNumberingRestart();
2845 [ # # ]: 0 : if( bSynchronizedDoc )
2846 : : {
2847 [ # # ]: 0 : lcl_RemoveSectionLinks( rWorkShell );
2848 : : }
2849 : :
2850 : : // insert the document into the target document
2851 [ # # ]: 0 : rWorkShell.SttEndDoc(sal_False);
2852 [ # # ]: 0 : rWorkShell.SttEndDoc(sal_True);
2853 [ # # ]: 0 : rWorkShell.SelAll();
2854 [ # # ]: 0 : pTargetShell->SttEndDoc(sal_False);
2855 : :
2856 : : //#i63806# put the styles to the target document
2857 : : //if the source uses headers or footers each new copy need to copy a new page styles
2858 [ # # ]: 0 : if(bPageStylesWithHeaderFooter)
2859 : : {
2860 : : //create a new pagestyle
2861 : : //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
2862 : :
2863 : 0 : SwDoc* pTargetDoc = pTargetShell->GetDoc();
2864 [ # # ]: 0 : String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
2865 [ # # ]: 0 : pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName );
2866 [ # # ]: 0 : SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
2867 [ # # ]: 0 : const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
2868 : :
2869 [ # # ][ # # ]: 0 : if(pWorkPageDesc && pTargetPageDesc)
2870 : : {
2871 [ # # ]: 0 : pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, sal_False );
2872 [ # # ]: 0 : sModifiedStartingPageDesc = sNewPageDescName;
2873 [ # # ]: 0 : lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
2874 [ # # ]: 0 : }
2875 : : }
2876 [ # # ][ # # ]: 0 : if(nDocNo == 1 || bPageStylesWithHeaderFooter)
2877 : : {
2878 [ # # ][ # # ]: 0 : pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), sal_True );
[ # # ]
2879 : : }
2880 [ # # ]: 0 : if(nDocNo > 1)
2881 : : {
2882 [ # # ]: 0 : pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
2883 : : }
2884 : : else
2885 : : {
2886 [ # # ]: 0 : pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
2887 : : }
2888 [ # # ]: 0 : sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
2889 : : OSL_ENSURE(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
2890 : : //#i51359# add a second paragraph in case there's only one
2891 : : {
2892 [ # # ][ # # ]: 0 : SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
2893 [ # # ]: 0 : SwPosition aTestPos( aIdx );
2894 [ # # ]: 0 : SwCursor aTestCrsr(aTestPos,0,false);
2895 [ # # ][ # # ]: 0 : if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
2896 : : {
2897 : : //append a paragraph
2898 [ # # ]: 0 : pWorkDoc->AppendTxtNode( aTestPos );
2899 [ # # ][ # # ]: 0 : }
[ # # ]
2900 : : }
2901 [ # # ]: 0 : pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );
2902 : : //convert fields in page styles (header/footer - has to be done after the first document has been pasted
2903 [ # # ]: 0 : if(1 == nDocNo)
2904 : : {
2905 [ # # ]: 0 : pTargetShell->CalcLayout();
2906 [ # # ]: 0 : pTargetShell->ConvertFieldsToText();
2907 : : }
2908 : : //add the document info to the config item
2909 : : SwDocMergeInfo aMergeInfo;
2910 : 0 : aMergeInfo.nStartPageInTarget = nPageCountBefore;
2911 : : //#i72820# calculate layout to be able to find the correct page index
2912 [ # # ]: 0 : pTargetShell->CalcLayout();
2913 [ # # ]: 0 : aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt();
2914 : 0 : aMergeInfo.nDBRow = nStartRow;
2915 [ # # ]: 0 : rMMConfig.AddMergedDocument( aMergeInfo );
2916 : 0 : ++nRet;
2917 : :
2918 : : // the print monitor needs some time to act
2919 [ # # ]: 0 : for( sal_uInt16 i = 0; i < 25; i++)
2920 [ # # ]: 0 : Application::Reschedule();
2921 : :
2922 : : //restore the ole DBMgr
2923 : 0 : pWorkDoc->SetNewDBMgr( pWorkDBMgr );
2924 : : //now the temporary document should be closed
2925 [ # # ]: 0 : SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
2926 [ # # ]: 0 : xDocSh->DoClose();
2927 [ # # ][ # # ]: 0 : nEndRow = pImpl->pMergeData->xResultSet->getRow();
2928 [ # # ][ # # ]: 0 : ++nDocNo;
2929 : 0 : } while( !bCancel &&
2930 [ # # ][ # # ]: 0 : (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
[ # # ]
2931 : :
2932 : : //deselect all, go out of the frame and go to the beginning of the document
2933 : 0 : Point aPt(LONG_MIN, LONG_MIN);
2934 [ # # ]: 0 : pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME);
2935 [ # # ]: 0 : if (pTargetShell->IsSelFrmMode())
2936 : : {
2937 [ # # ]: 0 : pTargetShell->UnSelectFrm();
2938 [ # # ]: 0 : pTargetShell->LeaveSelFrmMode();
2939 : : }
2940 [ # # ]: 0 : pTargetShell->EnterStdMode();
2941 [ # # ][ # # ]: 0 : pTargetShell->SttDoc();
[ # # ]
2942 : :
2943 : : }
2944 [ # # ]: 0 : catch(const Exception&)
2945 : : {
2946 : : OSL_FAIL("exception caught in SwNewDBMgr::MergeDocuments");
2947 : : }
2948 [ # # ][ # # ]: 0 : DELETEZ(pImpl->pMergeData);
2949 : 0 : bInMerge = sal_False;
2950 [ # # ][ # # ]: 0 : return nRet;
[ # # ]
2951 : : }
2952 : :
2953 : 1549 : SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr) :
2954 : 1549 : rDBMgr(rMgr)
2955 : : {
2956 : 1549 : };
2957 : :
2958 : 1458 : SwConnectionDisposedListener_Impl::~SwConnectionDisposedListener_Impl()
2959 : : {
2960 [ - + ]: 2916 : };
2961 : :
2962 : 0 : void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource )
2963 : : throw (RuntimeException)
2964 : : {
2965 [ # # ]: 0 : ::SolarMutexGuard aGuard;
2966 [ # # ]: 0 : uno::Reference<XConnection> xSource(rSource.Source, UNO_QUERY);
2967 [ # # ]: 0 : for(sal_uInt16 nPos = rDBMgr.aDataSourceParams.size(); nPos; nPos--)
2968 : : {
2969 [ # # ]: 0 : SwDSParam* pParam = &rDBMgr.aDataSourceParams[nPos - 1];
2970 [ # # ][ # # ]: 0 : if(pParam->xConnection.is() &&
[ # # ]
2971 [ # # ]: 0 : (xSource == pParam->xConnection))
2972 : : {
2973 [ # # ][ # # ]: 0 : rDBMgr.aDataSourceParams.erase(rDBMgr.aDataSourceParams.begin() + nPos - 1);
[ # # ][ # # ]
2974 : : }
2975 [ # # ]: 0 : }
2976 : 0 : }
2977 : :
2978 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|