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