merge the formfield patch from ooo-build
[ooovba.git] / sw / source / ui / dbui / dbmgr.cxx
blobef1bc3375cbc3932a19fd98116dd49d089bc4746
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbmgr.cxx,v $
10 * $Revision: 1.132.44.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #if STLPORT_VERSION>=321
34 #include <cstdarg>
35 #endif
37 #include <stdio.h>
38 #include <unotxdoc.hxx>
39 #include <com/sun/star/text/NotePrintMode.hpp>
40 #include <sfx2/app.hxx>
41 #include <com/sun/star/sdb/CommandType.hpp>
42 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
43 #include <com/sun/star/frame/XComponentLoader.hpp>
44 #include <com/sun/star/lang/DisposedException.hpp>
45 #include <com/sun/star/lang/XEventListener.hpp>
46 #include <com/sun/star/util/XNumberFormatter.hpp>
47 #include <com/sun/star/sdb/XCompletedConnection.hpp>
48 #include <com/sun/star/sdb/XCompletedExecution.hpp>
49 #include <com/sun/star/container/XChild.hpp>
50 #include <com/sun/star/text/MailMergeEvent.hpp>
51 #include <com/sun/star/frame/XStorable.hpp>
52 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
53 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
54 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
55 #include <com/sun/star/uno/XNamingService.hpp>
56 #include <com/sun/star/util/XCloseable.hpp>
57 #include <com/sun/star/beans/XPropertySet.hpp>
58 #include <sfx2/fcontnr.hxx>
59 #include <sfx2/filedlghelper.hxx>
60 #include <sfx2/viewfrm.hxx>
61 #include <dbconfig.hxx>
62 #include <swdbtoolsclient.hxx>
63 #include <pagedesc.hxx>
64 #include <vcl/lstbox.hxx>
65 #include <unotools/tempfile.hxx>
66 #include <svtools/pathoptions.hxx>
67 #include <svtools/urihelper.hxx>
68 #ifndef _SVSTDARR_HXX
69 #define _SVSTDARR_STRINGSDTOR
70 #include <svtools/svstdarr.hxx>
71 #endif
72 #include <svtools/zforlist.hxx>
73 #include <svtools/zformat.hxx>
74 #include <svtools/stritem.hxx>
75 #include <svtools/eitem.hxx>
76 #include <sfx2/printer.hxx>
77 #include <sfx2/docfile.hxx>
78 #include <sfx2/progress.hxx>
79 #include <sfx2/dispatch.hxx>
80 #include <goodies/mailenum.hxx>
81 #include <cmdid.h>
82 #include <swmodule.hxx>
83 #include <view.hxx>
84 #include <docsh.hxx>
85 #include <edtwin.hxx>
86 #include <wrtsh.hxx>
87 #include <fldbas.hxx>
88 #include <initui.hxx>
89 #include <swundo.hxx>
90 #include <flddat.hxx>
91 #include <modcfg.hxx>
92 #include <swprtopt.hxx>
93 #include <shellio.hxx>
94 #include <dbui.hxx>
95 #include <dbmgr.hxx>
96 #include <doc.hxx>
97 #include <swwait.hxx>
98 #include <swunohelper.hxx>
99 #include <dbui.hrc>
100 #include <globals.hrc>
101 #include <statstr.hrc>
102 #include <mmconfigitem.hxx>
103 #include <sfx2/request.hxx>
104 #include <hintids.hxx>
105 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
106 #include <com/sun/star/sdbc/XRowSet.hpp>
107 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
108 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
109 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
110 #include <com/sun/star/sdb/XColumn.hpp>
111 #include <com/sun/star/sdbc/DataType.hpp>
112 #include <com/sun/star/sdbc/ResultSetType.hpp>
113 #include <com/sun/star/mail/MailAttachment.hpp>
114 #include <comphelper/processfactory.hxx>
115 #include <comphelper/types.hxx>
116 #include <comphelper/property.hxx>
117 #include <mailmergehelper.hxx>
118 #include <maildispatcher.hxx>
119 #include <svx/htmlcfg.hxx>
120 #include <i18npool/mslangid.hxx>
121 #include <com/sun/star/util/XNumberFormatTypes.hpp>
122 #include <svx/langitem.hxx>
123 #include <svtools/numuno.hxx>
125 #include <unomailmerge.hxx>
126 #include <sfx2/event.hxx>
127 #include <vcl/msgbox.hxx>
128 #include <svx/dataaccessdescriptor.hxx>
129 #include <vos/mutex.hxx>
130 #include <rtl/textenc.h>
131 #include <ndindex.hxx>
132 #include <pam.hxx>
133 #include <swcrsr.hxx>
134 #include <swevent.hxx>
135 #include <osl/file.hxx>
136 #include <swabstdlg.hxx>
137 #include <fmthdft.hxx>
138 #include <dbui.hrc>
139 #include <envelp.hrc>
140 #include <memory>
141 #include <vector>
142 #include <unomid.h>
144 using namespace ::osl;
145 using namespace ::svx;
146 using namespace ::com::sun::star;
147 using namespace ::com::sun::star::text;
148 using namespace ::com::sun::star::uno;
149 using namespace ::com::sun::star::container;
150 using namespace ::com::sun::star::frame;
151 using namespace ::com::sun::star::lang;
152 using namespace ::com::sun::star::sdb;
153 using namespace ::com::sun::star::sdbc;
154 using namespace ::com::sun::star::sdbcx;
155 using namespace ::com::sun::star::beans;
156 using namespace ::com::sun::star::util;
157 using namespace ::com::sun::star::task;
158 using namespace ::com::sun::star::ui::dialogs;
160 #define DB_SEP_SPACE 0
161 #define DB_SEP_TAB 1
162 #define DB_SEP_RETURN 2
163 #define DB_SEP_NEWLINE 3
165 SV_IMPL_PTRARR(SwDSParamArr, SwDSParamPtr);
166 const sal_Char cCursor[] = "Cursor";
167 const sal_Char cCommand[] = "Command";
168 const sal_Char cCommandType[] = "CommandType";
169 const sal_Char cDataSourceName[] = "DataSourceName";
170 const sal_Char cSelection[] = "Selection";
171 const sal_Char cActiveConnection[] = "ActiveConnection";
173 // -----------------------------------------------------------------------------
174 // Use nameless namespace to avoid to rubbish the global namespace
175 // -----------------------------------------------------------------------------
176 namespace
179 bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference<XResultSet>& xResultSet )
181 uno::Reference<XPropertySet> xPrSet(xResultSet, UNO_QUERY);
182 if(xPrSet.is())
186 sal_Bool bFinal = sal_False;
187 Any aFinal = xPrSet->getPropertyValue(C2U("IsRowCountFinal"));
188 aFinal >>= bFinal;
189 if(!bFinal)
191 xResultSet->last();
192 xResultSet->first();
194 Any aCount = xPrSet->getPropertyValue(C2U("RowCount"));
195 if( aCount >>= rCount )
196 return true;
198 catch(Exception&)
202 return false;
204 // #122799# copy compatibility options
205 void lcl_CopyCompatibilityOptions( SwWrtShell& rSourceShell, SwWrtShell& rTargetShell)
207 IDocumentSettingAccess* pIDsa = rSourceShell.getIDocumentSettingAccess();
209 rTargetShell.SetParaSpaceMax( pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX));
210 rTargetShell.SetParaSpaceMaxAtPages(pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES));
211 rTargetShell.SetTabCompat( pIDsa->get(IDocumentSettingAccess::TAB_COMPAT));
212 rTargetShell.SetAddExtLeading( pIDsa->get(IDocumentSettingAccess::ADD_EXT_LEADING));
213 rTargetShell.SetUseVirDev( pIDsa->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE));
214 rTargetShell.SetAddParaSpacingToTableCells( pIDsa->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS));
215 rTargetShell.SetUseFormerLineSpacing( pIDsa->get(IDocumentSettingAccess::OLD_LINE_SPACING));
216 rTargetShell.SetUseFormerObjectPositioning( pIDsa->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS));
217 rTargetShell.SetConsiderWrapOnObjPos( pIDsa->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION));
218 rTargetShell.SetUseFormerTextWrapping( pIDsa->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING));
221 /* -----------------09.12.2002 12:35-----------------
223 * --------------------------------------------------*/
225 class SwConnectionDisposedListener_Impl : public cppu::WeakImplHelper1
226 < lang::XEventListener >
228 SwNewDBMgr& rDBMgr;
230 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
231 public:
232 SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr);
233 ~SwConnectionDisposedListener_Impl();
236 // -----------------------------------------------------------------------------
237 struct SwNewDBMgr_Impl
239 SwDSParam* pMergeData;
240 AbstractMailMergeDlg* pMergeDialog;
241 uno::Reference<lang::XEventListener> xDisposeListener;
243 SwNewDBMgr_Impl(SwNewDBMgr& rDBMgr)
244 :pMergeData(0)
245 ,pMergeDialog(0)
246 ,xDisposeListener(new SwConnectionDisposedListener_Impl(rDBMgr))
249 /*-- 24.10.2003 15:54:18---------------------------------------------------
251 -----------------------------------------------------------------------*/
252 void lcl_InitNumberFormatter(SwDSParam& rParam, uno::Reference<XDataSource> xSource)
254 uno::Reference<XMultiServiceFactory> xMgr = ::comphelper::getProcessServiceFactory();
255 if( xMgr.is() )
257 uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.util.NumberFormatter" ));
258 rParam.xFormatter = uno::Reference<util::XNumberFormatter>(xInstance, UNO_QUERY) ;
260 if(!xSource.is())
261 xSource = SwNewDBMgr::getDataSourceAsParent(rParam.xConnection, rParam.sDataSource);
263 uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
264 if(xSourceProps.is())
266 Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier"));
267 if(aFormats.hasValue())
269 uno::Reference<XNumberFormatsSupplier> xSuppl;
270 aFormats >>= xSuppl;
271 if(xSuppl.is())
273 uno::Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings();
274 Any aNull = xSettings->getPropertyValue(C2U("NullDate"));
275 aNull >>= rParam.aNullDate;
276 if(rParam.xFormatter.is())
277 rParam.xFormatter->attachNumberFormatsSupplier(xSuppl);
282 /* -----------------------------17.07.00 17:04--------------------------------
284 ---------------------------------------------------------------------------*/
285 BOOL lcl_MoveAbsolute(SwDSParam* pParam, long nAbsPos)
287 BOOL bRet = FALSE;
290 if(pParam->bScrollable)
292 bRet = pParam->xResultSet->absolute( nAbsPos );
294 else
296 DBG_ERROR("no absolute positioning available");
299 catch(Exception aExcept)
302 return bRet;
304 /* -----------------------------17.07.00 17:23--------------------------------
306 ---------------------------------------------------------------------------*/
307 BOOL lcl_GetColumnCnt(SwDSParam* pParam,
308 const String& rColumnName, long nLanguage, String& rResult, double* pNumber)
310 uno::Reference< XColumnsSupplier > xColsSupp( pParam->xResultSet, UNO_QUERY );
311 uno::Reference<XNameAccess> xCols;
314 xCols = xColsSupp->getColumns();
316 catch( lang::DisposedException& )
319 if(!xCols.is() || !xCols->hasByName(rColumnName))
320 return FALSE;
321 Any aCol = xCols->getByName(rColumnName);
322 uno::Reference< XPropertySet > xColumnProps;
323 aCol >>= xColumnProps;
325 SwDBFormatData aFormatData;
326 if(!pParam->xFormatter.is())
328 uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(
329 pParam->xConnection,pParam->sDataSource);
330 lcl_InitNumberFormatter(*pParam, xSource );
332 aFormatData.aNullDate = pParam->aNullDate;
333 aFormatData.xFormatter = pParam->xFormatter;
335 MsLangId::convertLanguageToLocale( (LanguageType)nLanguage, aFormatData.aLocale );
337 rResult = SwNewDBMgr::GetDBField( xColumnProps, aFormatData, pNumber);
338 return TRUE;
340 /*--------------------------------------------------------------------
341 Beschreibung: Daten importieren
342 --------------------------------------------------------------------*/
343 BOOL SwNewDBMgr::MergeNew(const SwMergeDescriptor& rMergeDesc )
345 SetMergeType( rMergeDesc.nMergeType );
347 DBG_ASSERT(!bInMerge && !pImpl->pMergeData, "merge already activated!");
349 SwDBData aData;
350 aData.nCommandType = CommandType::TABLE;
351 uno::Reference<XResultSet> xResSet;
352 Sequence<Any> aSelection;
353 uno::Reference< XConnection> xConnection;
355 aData.sDataSource = rMergeDesc.rDescriptor.getDataSource();
356 rMergeDesc.rDescriptor[daCommand] >>= aData.sCommand;
357 rMergeDesc.rDescriptor[daCommandType] >>= aData.nCommandType;
359 if ( rMergeDesc.rDescriptor.has(daCursor) )
360 rMergeDesc.rDescriptor[daCursor] >>= xResSet;
361 if ( rMergeDesc.rDescriptor.has(daSelection) )
362 rMergeDesc.rDescriptor[daSelection] >>= aSelection;
363 if ( rMergeDesc.rDescriptor.has(daConnection) )
364 rMergeDesc.rDescriptor[daConnection] >>= xConnection;
366 if(!aData.sDataSource.getLength() || !aData.sCommand.getLength() || !xResSet.is())
368 return FALSE;
371 pImpl->pMergeData = new SwDSParam(aData, xResSet, aSelection);
372 SwDSParam* pTemp = FindDSData(aData, FALSE);
373 if(pTemp)
374 *pTemp = *pImpl->pMergeData;
375 else
377 //#94779# calls from the calculator may have added a connection with an invalid commandtype
378 //"real" data base connections added here have to re-use the already available
379 //DSData and set the correct CommandType
380 SwDBData aTempData(aData);
381 aData.nCommandType = -1;
382 pTemp = FindDSData(aData, FALSE);
383 if(pTemp)
384 *pTemp = *pImpl->pMergeData;
385 else
387 SwDSParam* pInsert = new SwDSParam(*pImpl->pMergeData);
388 aDataSourceParams.Insert(pInsert, aDataSourceParams.Count());
391 uno::Reference<XComponent> xComponent(pInsert->xConnection, UNO_QUERY);
392 if(xComponent.is())
393 xComponent->addEventListener(pImpl->xDisposeListener);
395 catch(Exception&)
400 if(!pImpl->pMergeData->xConnection.is())
401 pImpl->pMergeData->xConnection = xConnection;
402 // add an XEventListener
404 try{
405 //set to start position
406 if(pImpl->pMergeData->aSelection.getLength())
408 sal_Int32 nPos = 0;
409 pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
410 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
411 pImpl->pMergeData->CheckEndOfDB();
412 if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
413 pImpl->pMergeData->bEndOfDB = TRUE;
415 else
417 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
418 pImpl->pMergeData->CheckEndOfDB();
421 catch(Exception&)
423 pImpl->pMergeData->bEndOfDB = TRUE;
424 pImpl->pMergeData->CheckEndOfDB();
425 DBG_ERROR("exception in MergeNew()");
428 uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,aData.sDataSource);
430 lcl_InitNumberFormatter(*pImpl->pMergeData, xSource);
432 rMergeDesc.rSh.ChgDBData(aData);
433 bInMerge = TRUE;
435 if (IsInitDBFields())
437 // Bei Datenbankfeldern ohne DB-Name DB-Name von Dok einsetzen
438 SvStringsDtor aDBNames(1, 1);
439 aDBNames.Insert( new String(), 0);
440 SwDBData aInsertData = rMergeDesc.rSh.GetDBData();
441 String sDBName = aInsertData.sDataSource;
442 sDBName += DB_DELIM;
443 sDBName += (String)aInsertData.sCommand;
444 sDBName += DB_DELIM;
445 sDBName += String::CreateFromInt32(aInsertData.nCommandType);
446 rMergeDesc.rSh.ChangeDBFields( aDBNames, sDBName);
447 SetInitDBFields(FALSE);
450 BOOL bRet = TRUE;
451 switch(rMergeDesc.nMergeType)
453 case DBMGR_MERGE:
454 bRet = Merge(&rMergeDesc.rSh); // Mischen
455 break;
457 case DBMGR_MERGE_MAILMERGE: // Serienbrief
459 SwView& rView = rMergeDesc.rSh.GetView();
460 SfxDispatcher *pDis = rView.GetViewFrame()->GetDispatcher();
461 SfxItemSet aPrintArgs( rView.GetPool(),
462 SID_SILENT, SID_SILENT, //5528
463 SID_ASYNCHRON, SID_ASYNCHRON, //5811
464 SID_PRINT_FIRST_PAGE, SID_PRINT_FIRST_PAGE, // 5001
465 SID_PRINT_LAST_PAGE, SID_PRINT_LAST_PAGE, // 5002
466 SID_PRINT_COPIES, SID_PRINT_COPIES, // 5003
467 SID_PRINTER_NAME, SID_PRINTER_NAME, //5322
468 SID_SELECTION, SID_SELECTION, //5346
469 SID_FILE_NAME, SID_FILE_NAME, // 5507
470 SID_PRINT_PAGES, SID_PRINT_PAGES, //6589
471 SID_PRINT_COLLATE, SID_PRINT_COLLATE, //6590
472 FN_QRY_MERGE, FN_QRY_MERGE,
473 0 );
474 aPrintArgs.Put(SfxBoolItem(FN_QRY_MERGE, TRUE) );
476 // !! Currently (Jan-2003) silent is defined by supplying *any*
477 // !! item!! (Thus according to OS it would be silent even when
478 // !! other items then SID_SILENT would be supplied!)
479 // !! Therefore it has to be the 0 pointer when not silent.
480 if(IsMergeSilent())
482 aPrintArgs.Put( SfxBoolItem(SID_SILENT, TRUE) );
483 // #i25686# printing should be done asynchronously to prevent dangling offices
484 // when mail merge is called as command line macro
485 // #i52629# aynchronous printing should only be done in silent mode - otherwise
486 // the printer dialog does not come up
487 aPrintArgs.Put( SfxBoolItem( SID_ASYNCHRON, rMergeDesc.bPrintAsync ));
489 // convert PropertyValues
490 const beans::PropertyValue* pPrintOptions = rMergeDesc.aPrintOptions.getConstArray();
491 for( sal_Int32 nOption = 0; nOption < rMergeDesc.aPrintOptions.getLength(); ++nOption)
493 if( pPrintOptions[nOption].Name.equalsAscii( "CopyCount" ))
495 sal_Int16 nCopies = 0;
496 if((pPrintOptions[nOption].Value >>= nCopies) && nCopies > 0)
497 aPrintArgs.Put( SfxInt16Item( SID_PRINT_COPIES, nCopies ));
499 else if( pPrintOptions[nOption].Name.equalsAscii( "FileName" ))
501 ::rtl::OUString sFileName;
502 if( (pPrintOptions[nOption].Value >>= sFileName) && sFileName.getLength() > 0)
503 aPrintArgs.Put( SfxStringItem( SID_FILE_NAME, sFileName ));
505 else if( pPrintOptions[nOption].Name.equalsAscii( "Collate" ))
507 sal_Bool bCollate = sal_False;
508 if( pPrintOptions[nOption].Value >>= bCollate )
509 aPrintArgs.Put( SfxBoolItem( SID_PRINT_COLLATE, bCollate ));
511 else if( pPrintOptions[nOption].Name.equalsAscii( "Pages" ))
513 ::rtl::OUString sPages;
514 if( (pPrintOptions[nOption].Value >>= sPages) && sPages.getLength() )
515 aPrintArgs.Put( SfxStringItem( SID_PRINT_PAGES, sPages ));
517 else if( pPrintOptions[nOption].Name.equalsAscii( "Wait" ))
519 sal_Bool bWait = sal_False;
520 if( pPrintOptions[nOption].Value >>= bWait )
521 aPrintArgs.Put( SfxBoolItem( SID_ASYNCHRON, !bWait ));
525 pDis->Execute( SID_PRINTDOC,
526 SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD,
527 aPrintArgs );
529 break;
531 case DBMGR_MERGE_MAILING:
532 case DBMGR_MERGE_MAILFILES:
533 case DBMGR_MERGE_SINGLE_FILE:
534 // save files and send them as e-Mail if required
535 bRet = MergeMailFiles(&rMergeDesc.rSh,
536 rMergeDesc);
537 break;
539 default: // Einfuegen der selektierten Eintraege
540 // (war: InsertRecord)
541 ImportFromConnection(&rMergeDesc.rSh);
542 break;
545 EndMerge();
546 return bRet;
549 /*--------------------------------------------------------------------
550 Beschreibung: Daten importieren
551 --------------------------------------------------------------------*/
554 BOOL SwNewDBMgr::Merge(SwWrtShell* pSh)
556 pSh->StartAllAction();
558 pSh->ViewShell::UpdateFlds(TRUE);
559 pSh->SetModified();
561 pSh->EndAllAction();
563 return TRUE;
566 /*--------------------------------------------------------------------
567 Beschreibung:
568 --------------------------------------------------------------------*/
569 void SwNewDBMgr::ImportFromConnection( SwWrtShell* pSh )
571 if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB)
574 pSh->StartAllAction();
575 pSh->StartUndo(UNDO_EMPTY);
576 BOOL bGroupUndo(pSh->DoesGroupUndo());
577 pSh->DoGroupUndo(FALSE);
579 if( pSh->HasSelection() )
580 pSh->DelRight();
582 SwWait *pWait = 0;
585 ULONG i = 0;
586 do {
588 ImportDBEntry(pSh);
589 if( 10 == ++i )
590 pWait = new SwWait( *pSh->GetView().GetDocShell(), TRUE);
592 } while(ToNextMergeRecord());
595 pSh->DoGroupUndo(bGroupUndo);
596 pSh->EndUndo(UNDO_EMPTY);
597 pSh->EndAllAction();
598 delete pWait;
602 /*-----------------24.02.97 10.30-------------------
604 --------------------------------------------------*/
606 String lcl_FindColumn(const String& sFormatStr,USHORT &nUsedPos, BYTE &nSeparator)
608 String sReturn;
609 USHORT nLen = sFormatStr.Len();
610 nSeparator = 0xff;
611 while(nUsedPos < nLen && nSeparator == 0xff)
613 sal_Unicode cAkt = sFormatStr.GetChar(nUsedPos);
614 switch(cAkt)
616 case ',':
617 nSeparator = DB_SEP_SPACE;
618 break;
619 case ';':
620 nSeparator = DB_SEP_RETURN;
621 break;
622 case ':':
623 nSeparator = DB_SEP_TAB;
624 break;
625 case '#':
626 nSeparator = DB_SEP_NEWLINE;
627 break;
628 default:
629 sReturn += cAkt;
631 nUsedPos++;
634 return sReturn;
637 /*--------------------------------------------------------------------
638 Beschreibung:
639 --------------------------------------------------------------------*/
640 void SwNewDBMgr::ImportDBEntry(SwWrtShell* pSh)
642 if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB)
644 uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
645 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
646 String sFormatStr;
647 USHORT nFmtLen = sFormatStr.Len();
648 if( nFmtLen )
650 const char cSpace = ' ';
651 const char cTab = '\t';
652 USHORT nUsedPos = 0;
653 BYTE nSeparator;
654 String sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator);
655 while( sColumn.Len() )
657 if(!xCols->hasByName(sColumn))
658 return;
659 Any aCol = xCols->getByName(sColumn);
660 uno::Reference< XPropertySet > xColumnProp;
661 aCol >>= xColumnProp;
662 if(xColumnProp.is())
664 SwDBFormatData aDBFormat;
665 String sInsert = GetDBField( xColumnProp, aDBFormat);
666 if( DB_SEP_SPACE == nSeparator )
667 sInsert += cSpace;
668 else if( DB_SEP_TAB == nSeparator)
669 sInsert += cTab;
670 pSh->Insert(sInsert);
671 if( DB_SEP_RETURN == nSeparator)
672 pSh->SplitNode();
673 else if(DB_SEP_NEWLINE == nSeparator)
674 pSh->InsertLineBreak();
676 else
678 // Spalte nicht gefunden -> Fehler anzeigen
679 String sInsert = '?';
680 sInsert += sColumn;
681 sInsert += '?';
682 pSh->Insert(sInsert);
684 sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator);
686 pSh->SplitNode();
688 else
690 String sStr;
691 Sequence<rtl::OUString> aColNames = xCols->getElementNames();
692 const rtl::OUString* pColNames = aColNames.getConstArray();
693 long nLength = aColNames.getLength();
694 for(long i = 0; i < nLength; i++)
696 Any aCol = xCols->getByName(pColNames[i]);
697 uno::Reference< XPropertySet > xColumnProp;
698 aCol >>= xColumnProp;
699 SwDBFormatData aDBFormat;
700 sStr += GetDBField( xColumnProp, aDBFormat);
701 if (i < nLength - 1)
702 sStr += '\t';
704 pSh->SwEditShell::Insert2(sStr);
705 pSh->SwFEShell::SplitNode(); // Zeilenvorschub
709 /*--------------------------------------------------------------------
710 Beschreibung: Listbox mit Tabellenliste fuellen
711 --------------------------------------------------------------------*/
712 BOOL SwNewDBMgr::GetTableNames(ListBox* pListBox, const String& rDBName)
714 BOOL bRet = FALSE;
715 String sOldTableName(pListBox->GetSelectEntry());
716 pListBox->Clear();
717 SwDSParam* pParam = FindDSConnection(rDBName, FALSE);
718 uno::Reference< XConnection> xConnection;
719 if(pParam && pParam->xConnection.is())
720 xConnection = pParam->xConnection;
721 else
723 rtl::OUString sDBName(rDBName);
724 xConnection = RegisterConnection( sDBName );
726 if(xConnection.is())
728 uno::Reference<XTablesSupplier> xTSupplier = uno::Reference<XTablesSupplier>(xConnection, UNO_QUERY);
729 if(xTSupplier.is())
731 uno::Reference<XNameAccess> xTbls = xTSupplier->getTables();
732 Sequence<rtl::OUString> aTbls = xTbls->getElementNames();
733 const rtl::OUString* pTbls = aTbls.getConstArray();
734 for(long i = 0; i < aTbls.getLength(); i++)
736 USHORT nEntry = pListBox->InsertEntry(pTbls[i]);
737 pListBox->SetEntryData(nEntry, (void*)0);
740 uno::Reference<XQueriesSupplier> xQSupplier = uno::Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
741 if(xQSupplier.is())
743 uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries();
744 Sequence<rtl::OUString> aQueries = xQueries->getElementNames();
745 const rtl::OUString* pQueries = aQueries.getConstArray();
746 for(long i = 0; i < aQueries.getLength(); i++)
748 USHORT nEntry = pListBox->InsertEntry(pQueries[i]);
749 pListBox->SetEntryData(nEntry, (void*)1);
752 if (sOldTableName.Len())
753 pListBox->SelectEntry(sOldTableName);
754 bRet = TRUE;
756 return bRet;
759 /*--------------------------------------------------------------------
760 Beschreibung: Listbox mit Spaltennamen einer Datenbank fuellen
761 --------------------------------------------------------------------*/
762 BOOL SwNewDBMgr::GetColumnNames(ListBox* pListBox,
763 const String& rDBName, const String& rTableName, BOOL bAppend)
765 if (!bAppend)
766 pListBox->Clear();
767 SwDBData aData;
768 aData.sDataSource = rDBName;
769 aData.sCommand = rTableName;
770 aData.nCommandType = -1;
771 SwDSParam* pParam = FindDSData(aData, FALSE);
772 uno::Reference< XConnection> xConnection;
773 if(pParam && pParam->xConnection.is())
774 xConnection = pParam->xConnection;
775 else
777 rtl::OUString sDBName(rDBName);
778 xConnection = RegisterConnection( sDBName );
780 uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
781 if(xColsSupp.is())
783 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
784 const Sequence<rtl::OUString> aColNames = xCols->getElementNames();
785 const rtl::OUString* pColNames = aColNames.getConstArray();
786 for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
788 pListBox->InsertEntry(pColNames[nCol]);
790 ::comphelper::disposeComponent( xColsSupp );
792 return(TRUE);
794 /* -----------------------------08.06.01 15:11--------------------------------
796 ---------------------------------------------------------------------------*/
797 BOOL SwNewDBMgr::GetColumnNames(ListBox* pListBox,
798 uno::Reference< XConnection> xConnection,
799 const String& rTableName, BOOL bAppend)
801 if (!bAppend)
802 pListBox->Clear();
803 uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
804 if(xColsSupp.is())
806 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
807 const Sequence<rtl::OUString> aColNames = xCols->getElementNames();
808 const rtl::OUString* pColNames = aColNames.getConstArray();
809 for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
811 pListBox->InsertEntry(pColNames[nCol]);
813 ::comphelper::disposeComponent( xColsSupp );
815 return(TRUE);
818 /*--------------------------------------------------------------------
819 Beschreibung: CTOR
820 --------------------------------------------------------------------*/
822 SwNewDBMgr::SwNewDBMgr() :
823 nMergeType(DBMGR_INSERT),
824 bInitDBFields(FALSE),
825 bInMerge(FALSE),
826 bMergeSilent(FALSE),
827 bMergeLock(FALSE),
828 pImpl(new SwNewDBMgr_Impl(*this)),
829 pMergeEvtSrc(NULL)
832 /* -----------------------------18.07.00 08:56--------------------------------
834 ---------------------------------------------------------------------------*/
835 SwNewDBMgr::~SwNewDBMgr()
837 for(USHORT nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
839 SwDSParam* pParam = aDataSourceParams[nPos];
840 if(pParam->xConnection.is())
844 uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY);
845 if(xComp.is())
846 xComp->dispose();
848 catch(const RuntimeException& )
850 //may be disposed already since multiple entries may have used the same connection
854 delete pImpl;
856 /*--------------------------------------------------------------------
857 Beschreibung: Serienbrief drucken
858 --------------------------------------------------------------------*/
861 BOOL SwNewDBMgr::MergePrint( SwView& rView,
862 SwPrtOptions& rOpt, SfxProgress& rProgress, BOOL bIsAPI )
864 SwWrtShell* pSh = &rView.GetWrtShell();
865 //check if the doc is synchronized and contains at least one linked section
866 BOOL bSynchronizedDoc = pSh->IsLabelDoc() && pSh->GetSectionFmtCount() > 1;
867 //merge source is already open
868 rOpt.nMergeCnt = 0;
869 //#i56195# no field update while printing mail merge documents
870 rOpt.bUpdateFieldsInPrinting = sal_False;
871 if(pImpl->pMergeData)
873 if(pImpl->pMergeData->aSelection.getLength())
874 rOpt.nMergeCnt = pImpl->pMergeData->aSelection.getLength();
875 else if(pImpl->pMergeData->xResultSet.is())
877 sal_Int32 nCount;
878 if( lcl_getCountFromResultSet( nCount, pImpl->pMergeData->xResultSet ) )
879 rOpt.nMergeCnt = (ULONG)nCount;
883 SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
884 pModOpt->SetSinglePrintJob(rOpt.IsPrintSingleJobs());
886 SfxPrinter *pPrt = pSh->getIDocumentDeviceAccess()->getPrinter( false );
887 Link aSfxSaveLnk = pPrt->GetEndPrintHdl();
888 if( rOpt.IsPrintSingleJobs() )
889 pPrt->SetEndPrintHdl( Link() );
891 BOOL bUserBreak = FALSE,
892 bRet = FALSE;
893 long nStartRow, nEndRow;
894 //calculate number of data sets to be printed
896 Sequence<PropertyValue> aViewProperties(16);
897 PropertyValue* pViewProperties = aViewProperties.getArray();
898 pViewProperties[0].Name = C2U("MailMergeCount");
899 pViewProperties[0].Value <<= (sal_Int32)rOpt.nMergeCnt;
900 pViewProperties[1].Name = C2U("PrintGraphics");
901 pViewProperties[1].Value <<= (sal_Bool)rOpt.IsPrintGraphic();
902 pViewProperties[2].Name = C2U("PrintTables");
903 pViewProperties[2].Value <<= (sal_Bool)rOpt.IsPrintTable();
904 pViewProperties[3].Name = C2U("PrintDrawings");
905 pViewProperties[3].Value <<= (sal_Bool)rOpt.IsPrintDraw();
906 pViewProperties[4].Name = C2U("PrintLeftPages");
907 pViewProperties[4].Value <<= (sal_Bool)rOpt.IsPrintLeftPage();
908 pViewProperties[5].Name = C2U("PrintRightPages");
909 pViewProperties[5].Value <<= (sal_Bool)rOpt.IsPrintRightPage();
910 pViewProperties[6].Name = C2U("PrintControls");
911 pViewProperties[6].Value <<= (sal_Bool)rOpt.IsPrintControl();
912 pViewProperties[7].Name = C2U("PrintReversed");
913 pViewProperties[7].Value <<= (sal_Bool)rOpt.IsPrintReverse();
914 pViewProperties[8].Name = C2U("PrintPaperFromSetup");
915 pViewProperties[8].Value <<= (sal_Bool)rOpt.IsPaperFromSetup();
916 pViewProperties[9].Name = C2U("PrintFaxName");
917 pViewProperties[9].Value <<= rOpt.GetFaxName();
918 pViewProperties[10].Name = C2U("PrintAnnotationMode");
919 pViewProperties[10].Value <<= (text::NotePrintMode) rOpt.GetPrintPostIts();
920 pViewProperties[11].Name = C2U("PrintProspect");
921 pViewProperties[11].Value <<= (sal_Bool)rOpt.IsPrintProspect();
922 pViewProperties[12].Name = C2U("PrintPageBackground");
923 pViewProperties[12].Value <<= (sal_Bool)rOpt.IsPrintPageBackground();
924 pViewProperties[13].Name = C2U("PrintBlackFonts");
925 pViewProperties[13].Value <<= (sal_Bool)rOpt.IsPrintBlackFont();
926 pViewProperties[14].Name = C2U("IsSinglePrintJob");
927 pViewProperties[14].Value <<= (sal_Bool)rOpt.IsPrintSingleJobs();
928 pViewProperties[15].Name = C2U("PrintEmptyPages");
929 pViewProperties[15].Value <<= (sal_Bool)rOpt.IsPrintEmptyPages();
931 rView.SetAdditionalPrintOptions(aViewProperties);
932 do {
933 nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
935 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), pSh->GetView().GetViewFrame()->GetObjectShell()));
936 pSh->ViewShell::UpdateFlds();
937 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), pSh->GetView().GetViewFrame()->GetObjectShell()));
938 ++rOpt.nMergeAct;
940 // launch MailMergeEvent if required
941 const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
942 if (pEvtSrc)
944 uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc );
945 text::MailMergeEvent aEvt( xRef, rView.GetDocShell()->GetModel() );
946 pEvtSrc->LaunchMailMergeEvent( aEvt );
949 rView.SfxViewShell::Print( rProgress, bIsAPI ); // ggf Basic-Macro ausfuehren
950 if( rOpt.IsPrintSingleJobs() && bRet )
952 //rOpt.bJobStartet = FALSE;
953 bRet = FALSE;
956 bMergeLock = TRUE;
957 if(rOpt.IsPrintProspect())
959 if( ! pPrt->IsJobActive() )
961 pPrt->SetJobValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ),
962 String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
963 pPrt->StartJob( rOpt.GetJobName() );
965 if( pPrt->IsJobActive() )
967 pSh->PrintProspect( rOpt, rProgress, rOpt.IsPrintProspect_RTL() );
968 bRet = TRUE;
971 else if( pSh->Prt( rOpt, &rProgress ) )
972 bRet = TRUE;
973 bMergeLock = FALSE;
975 if( !pPrt->IsJobActive() )
977 bUserBreak = TRUE;
978 bRet = FALSE;
979 break;
981 if( !rOpt.IsPrintSingleJobs() )
983 String& rJNm = (String&)rOpt.GetJobName();
984 rJNm.Erase();
987 nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
988 } while( bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord());
990 if( rOpt.IsPrintSingleJobs() )
992 SfxPrinter* pTmpPrinter = pSh->getIDocumentDeviceAccess()->getPrinter( true );
993 pTmpPrinter->SetEndPrintHdl( aSfxSaveLnk );
994 if ( !bUserBreak && !pTmpPrinter->IsJobActive() ) //Schon zu spaet?
995 aSfxSaveLnk.Call( pTmpPrinter );
998 rOpt.nMergeCnt = 0;
999 rOpt.nMergeAct = 0;
1001 nMergeType = DBMGR_INSERT;
1003 SwDocShell* pDocSh = rView.GetDocShell();
1004 SfxViewFrame *pTmpFrm = SfxViewFrame::GetFirst(pDocSh);
1006 while (pTmpFrm) // Alle Views Invalidieren
1008 SwView *pVw = PTR_CAST(SwView, pTmpFrm->GetViewShell());
1009 if (pVw)
1010 pVw->GetEditWin().Invalidate();
1011 pTmpFrm = pTmpFrm->GetNext(*pTmpFrm, pDocSh);
1014 return bRet;
1016 /*-- 21.06.2004 09:08:16---------------------------------------------------
1018 -----------------------------------------------------------------------*/
1019 BOOL SwNewDBMgr::MergePrintDocuments( SwView& rView,
1020 SwPrtOptions& rOpt, SfxProgress& rProgress, BOOL bIsAPI )
1022 SwWrtShell* pSh = &rView.GetWrtShell();
1023 //check if the doc is synchronized and contains at least one linked section
1024 //merge source is already open
1025 rOpt.nMergeCnt = 0;
1026 rOpt.SetPrintSingleJobs( sal_True );
1028 SfxPrinter *pPrt = pSh->getIDocumentDeviceAccess()->getPrinter( false );
1029 Link aSfxSaveLnk = pPrt->GetEndPrintHdl();
1030 if( rOpt.IsPrintSingleJobs() )
1031 pPrt->SetEndPrintHdl( Link() );
1033 BOOL bUserBreak = FALSE,
1034 bRet = FALSE;
1035 //calculate number of data sets to be printed
1037 Sequence<PropertyValue> aViewProperties(16);
1038 PropertyValue* pViewProperties = aViewProperties.getArray();
1039 pViewProperties[0].Name = C2U("MailMergeCount");
1040 pViewProperties[0].Value <<= (sal_Int32)rOpt.nMergeCnt;
1041 pViewProperties[1].Name = C2U("PrintGraphics");
1042 pViewProperties[1].Value <<= (sal_Bool)rOpt.IsPrintGraphic();
1043 pViewProperties[2].Name = C2U("PrintTables");
1044 pViewProperties[2].Value <<= (sal_Bool)rOpt.IsPrintTable();
1045 pViewProperties[3].Name = C2U("PrintDrawings");
1046 pViewProperties[3].Value <<= (sal_Bool)rOpt.IsPrintDraw();
1047 pViewProperties[4].Name = C2U("PrintLeftPages");
1048 pViewProperties[4].Value <<= (sal_Bool)rOpt.IsPrintLeftPage();
1049 pViewProperties[5].Name = C2U("PrintRightPages");
1050 pViewProperties[5].Value <<= (sal_Bool)rOpt.IsPrintRightPage();
1051 pViewProperties[6].Name = C2U("PrintControls");
1052 pViewProperties[6].Value <<= (sal_Bool)rOpt.IsPrintControl();
1053 pViewProperties[7].Name = C2U("PrintReversed");
1054 pViewProperties[7].Value <<= (sal_Bool)rOpt.IsPrintReverse();
1055 pViewProperties[8].Name = C2U("PrintPaperFromSetup");
1056 pViewProperties[8].Value <<= (sal_Bool)rOpt.IsPaperFromSetup();
1057 pViewProperties[9].Name = C2U("PrintFaxName");
1058 pViewProperties[9].Value <<= rOpt.GetFaxName();
1059 pViewProperties[10].Name = C2U("PrintAnnotationMode");
1060 pViewProperties[10].Value <<= (text::NotePrintMode) rOpt.GetPrintPostIts();
1061 pViewProperties[11].Name = C2U("PrintProspect");
1062 pViewProperties[11].Value <<= (sal_Bool)rOpt.IsPrintProspect();
1063 pViewProperties[12].Name = C2U("PrintPageBackground");
1064 pViewProperties[12].Value <<= (sal_Bool)rOpt.IsPrintPageBackground();
1065 pViewProperties[13].Name = C2U("PrintBlackFonts");
1066 pViewProperties[13].Value <<= (sal_Bool)rOpt.IsPrintBlackFont();
1067 pViewProperties[14].Name = C2U("IsSinglePrintJob");
1068 pViewProperties[14].Value <<= (sal_Bool)rOpt.IsPrintSingleJobs();
1069 pViewProperties[15].Name = C2U("PrintEmptyPages");
1070 pViewProperties[15].Value <<= (sal_Bool)rOpt.IsPrintEmptyPages();
1072 rView.SetAdditionalPrintOptions(aViewProperties);
1074 SwMailMergeConfigItem* pConfigItem = rView.GetMailMergeConfigItem();
1075 DBG_ASSERT(pConfigItem, "mail merge config item is missing");
1076 if(!pConfigItem)
1077 return sal_False;
1079 USHORT nDocStart = pConfigItem->GetPrintRangeStart();
1080 USHORT nDocEnd = pConfigItem->GetPrintRangeEnd();
1081 DBG_ASSERT(nDocStart < nDocEnd && nDocEnd <= pConfigItem->GetMergedDocumentCount(),
1082 "merge print settings are not correct");
1084 for( sal_uInt32 nPrintDocument = nDocStart; nPrintDocument < nDocEnd; ++nPrintDocument)
1086 SwDocMergeInfo& rDocInfo = pConfigItem->GetDocumentMergeInfo(nPrintDocument);
1087 rOpt.aMulti.SelectAll(FALSE);
1088 rOpt.aMulti.Select(Range( rDocInfo.nStartPageInTarget, rDocInfo.nEndPageInTarget ), TRUE );
1090 ++rOpt.nMergeAct;
1092 // launch MailMergeEvent if required
1093 const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
1094 if (pEvtSrc)
1096 uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc );
1097 text::MailMergeEvent aEvt( xRef, rView.GetDocShell()->GetModel() );
1098 pEvtSrc->LaunchMailMergeEvent( aEvt );
1101 String aTmp;
1102 aTmp += String::CreateFromInt32( rDocInfo.nStartPageInTarget );
1103 aTmp += '-';
1104 aTmp += String::CreateFromInt32( rDocInfo.nEndPageInTarget );
1106 Sequence<PropertyValue> aAddViewProperties(1);
1107 PropertyValue* pAddViewProperties = aAddViewProperties.getArray();
1108 pAddViewProperties[0].Name = C2U("Pages");
1109 pAddViewProperties[0].Value <<= ::rtl::OUString( aTmp );
1110 rView.SetAdditionalPrintOptions(aAddViewProperties);
1112 rView.SfxViewShell::Print( rProgress, bIsAPI ); // ggf Basic-Macro ausfuehren
1113 if( rOpt.IsPrintSingleJobs() && bRet )
1115 //rOpt.bJobStartet = FALSE;
1116 bRet = FALSE;
1119 bMergeLock = TRUE;
1120 if(rOpt.IsPrintProspect())
1122 if( pPrt->IsJobActive() || pPrt->StartJob( rOpt.GetJobName() ))
1124 pSh->PrintProspect( rOpt, rProgress, rOpt.IsPrintProspect_RTL() );
1125 bRet = TRUE;
1128 else if( pSh->Prt( rOpt, &rProgress ) )
1129 bRet = TRUE;
1130 bMergeLock = FALSE;
1132 if( !pPrt->IsJobActive() )
1134 bUserBreak = TRUE;
1135 bRet = FALSE;
1136 break;
1138 if( !rOpt.IsPrintSingleJobs() )
1140 String& rJNm = (String&)rOpt.GetJobName();
1141 rJNm.Erase();
1145 if( rOpt.IsPrintSingleJobs() )
1147 SfxPrinter* pTmpPrinter = pSh->getIDocumentDeviceAccess()->getPrinter( true );
1148 pTmpPrinter->SetEndPrintHdl( aSfxSaveLnk );
1149 if ( !bUserBreak && !pTmpPrinter->IsJobActive() ) //Schon zu spaet?
1150 aSfxSaveLnk.Call( pTmpPrinter );
1153 rOpt.nMergeCnt = 0;
1154 rOpt.nMergeAct = 0;
1156 nMergeType = DBMGR_INSERT;
1158 SwDocShell* pDocSh = rView.GetDocShell();
1159 SfxViewFrame *pTmpFrm = SfxViewFrame::GetFirst(pDocSh);
1161 while (pTmpFrm) // Alle Views Invalidieren
1163 SwView *pVw = PTR_CAST(SwView, pTmpFrm->GetViewShell());
1164 if (pVw)
1165 pVw->GetEditWin().Invalidate();
1166 pTmpFrm = pTmpFrm->GetNext(*pTmpFrm, pDocSh);
1169 return bRet;
1174 /*--------------------------------------------------------------------
1175 Beschreibung: Serienbriefe als einzelne Dokumente speichern
1176 --------------------------------------------------------------------*/
1177 String lcl_FindUniqueName(SwWrtShell* pTargetShell, const String& rStartingPageDesc, ULONG nDocNo )
1181 String sTest = rStartingPageDesc;
1182 sTest += String::CreateFromInt32( nDocNo );
1183 if( !pTargetShell->FindPageDescByName( sTest ) )
1184 return sTest;
1185 ++nDocNo;
1186 }while(true);
1188 void lcl_CopyDynamicDefaults( const SwDoc& rSource, SwDoc& rTarget )
1190 USHORT __FAR_DATA aRangeOfDefaults[] = {
1191 RES_FRMATR_BEGIN, RES_FRMATR_END-1,
1192 RES_CHRATR_BEGIN, RES_CHRATR_END-1,
1193 RES_PARATR_BEGIN, RES_PARATR_END-1,
1194 // --> OD 2008-02-25 #refactorlists##
1195 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
1196 // <--
1197 RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
1201 SfxItemSet aNewDefaults( rTarget.GetAttrPool(), aRangeOfDefaults );
1203 USHORT nWhich;
1204 USHORT nRange = 0;
1205 while( aRangeOfDefaults[nRange] != 0)
1207 for( nWhich = aRangeOfDefaults[nRange]; nWhich < aRangeOfDefaults[nRange + 1]; ++nWhich )
1209 const SfxPoolItem& rSourceAttr = rSource.GetDefault( nWhich );
1210 if( rSourceAttr != rTarget.GetDefault( nWhich ) )
1211 aNewDefaults.Put( rSourceAttr );
1213 nRange += 2;
1215 if( aNewDefaults.Count() )
1216 rTarget.SetDefault( aNewDefaults );
1218 void lcl_CopyFollowPageDesc(
1219 SwWrtShell& rTargetShell,
1220 const SwPageDesc& rSourcePageDesc,
1221 const SwPageDesc& rTargetPageDesc,
1222 const ULONG nDocNo )
1224 //now copy the follow page desc, too
1225 const SwPageDesc* pFollowPageDesc = rSourcePageDesc.GetFollow();
1226 String sFollowPageDesc = pFollowPageDesc->GetName();
1227 if( sFollowPageDesc != rSourcePageDesc.GetName() )
1229 SwDoc* pTargetDoc = rTargetShell.GetDoc();
1230 String sNewFollowPageDesc = lcl_FindUniqueName(&rTargetShell, sFollowPageDesc, nDocNo );
1231 sal_uInt16 nNewDesc = pTargetDoc->MakePageDesc( sNewFollowPageDesc );
1232 SwPageDesc& rTargetFollowPageDesc = pTargetDoc->_GetPageDesc( nNewDesc );
1234 pTargetDoc->CopyPageDesc( *pFollowPageDesc, rTargetFollowPageDesc, sal_False );
1235 SwPageDesc aDesc( rTargetPageDesc );
1236 aDesc.SetFollow( &rTargetFollowPageDesc );
1237 pTargetDoc->ChgPageDesc( rTargetPageDesc.GetName(), aDesc );
1241 BOOL SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
1242 const SwMergeDescriptor& rMergeDescriptor)
1244 //check if the doc is synchronized and contains at least one linked section
1245 BOOL bSynchronizedDoc = pSourceShell->IsLabelDoc() && pSourceShell->GetSectionFmtCount() > 1;
1246 BOOL bLoop = TRUE;
1247 BOOL bEMail = rMergeDescriptor.nMergeType == DBMGR_MERGE_MAILING;
1248 const bool bAsSingleFile = rMergeDescriptor.nMergeType == DBMGR_MERGE_SINGLE_FILE;
1250 ::rtl::Reference< MailDispatcher > xMailDispatcher;
1251 ::rtl::OUString sBodyMimeType;
1252 rtl_TextEncoding eEncoding = ::gsl_getSystemTextEncoding();
1254 if(bEMail)
1256 xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer));
1257 if(!rMergeDescriptor.bSendAsAttachment && rMergeDescriptor.bSendAsHTML)
1259 sBodyMimeType = ::rtl::OUString::createFromAscii("text/html; charset=");
1260 sBodyMimeType += ::rtl::OUString::createFromAscii(
1261 rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
1262 SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
1263 eEncoding = pHtmlOptions->GetTextEncoding();
1265 else
1266 sBodyMimeType =
1267 ::rtl::OUString::createFromAscii("text/plain; charset=UTF-8; format=flowed");
1270 uno::Reference< XPropertySet > xColumnProp;
1272 BOOL bColumnName = sEMailAddrFld.Len() > 0;
1274 if (bColumnName)
1276 uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
1277 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
1278 if(!xCols->hasByName(sEMailAddrFld))
1279 return FALSE;
1280 Any aCol = xCols->getByName(sEMailAddrFld);
1281 aCol >>= xColumnProp;
1284 SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher();
1285 SwDocShell* pSourrceDocSh = pSourceShell->GetView().GetDocShell();
1286 pSfxDispatcher->Execute( pSourrceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD);
1287 // has document been saved successfully?
1288 if( !pSourrceDocSh->IsModified() )
1290 SfxMedium* pOrig = pSourceShell->GetView().GetDocShell()->GetMedium();
1291 String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ));
1292 const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter(
1293 sSourceDocumentURL, ::aEmptyStr );
1294 const SfxFilter* pStoreToFilter = pSfxFlt;
1295 SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
1296 const String* pStoreToFilterOptions = 0;
1297 // if a save_to filter is set then use it - otherwise use the default
1298 if( bEMail && !rMergeDescriptor.bSendAsAttachment )
1300 String sExtension( String::CreateFromAscii(
1301 rMergeDescriptor.bSendAsHTML ? "html" : "txt" ));
1302 pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SFX_FILTER_EXPORT);
1304 else if( rMergeDescriptor.sSaveToFilter.Len())
1306 const SfxFilter* pFilter =
1307 pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter );
1308 if(pFilter)
1310 pStoreToFilter = pFilter;
1311 if(rMergeDescriptor.sSaveToFilterOptions.Len())
1312 pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions;
1315 bCancel = FALSE;
1317 // in case of creating a single resulting file this has to be created here
1318 SwWrtShell* pTargetShell = 0;
1319 SfxObjectShellRef xTargetDocShell;
1320 std::auto_ptr< utl::TempFile > aTempFile;
1321 String sModifiedStartingPageDesc;
1322 String sStartingPageDesc;
1323 USHORT nStartingPageNo = 0;
1324 bool bPageStylesWithHeaderFooter = false;
1325 if(bAsSingleFile || rMergeDescriptor.bCreateSingleFile)
1327 // create a target docshell to put the merged document into
1328 xTargetDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD );
1329 xTargetDocShell->DoInitNew( 0 );
1330 SfxViewFrame* pTargetFrame = SfxViewFrame::CreateViewFrame( *xTargetDocShell, 0, TRUE );
1332 SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
1334 //initiate SelectShell() to create sub shells
1335 pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
1336 pTargetShell = pTargetView->GetWrtShellPtr();
1337 //copy the styles from the source to the target document
1338 SwgReaderOption aOpt;
1339 aOpt.SetTxtFmts( sal_True );
1340 aOpt.SetFrmFmts( sal_True );
1341 aOpt.SetPageDescs( sal_True );
1342 aOpt.SetNumRules( sal_True );
1343 aOpt.SetMerge( sal_False );
1344 pTargetView->GetDocShell()->LoadStylesFromFile(
1345 sSourceDocumentURL, aOpt, sal_True );
1346 //determine the page style and number used at the start of the source document
1347 pSourceShell->SttEndDoc(TRUE);
1348 nStartingPageNo = pSourceShell->GetVirtPageNum();
1349 sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc(
1350 pSourceShell->GetCurPageDesc()).GetName();
1351 // #122799# copy compatibility options
1352 lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell);
1353 // #72821# copy dynamic defaults
1354 lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() );
1355 // #i72517#
1356 const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc );
1357 const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
1358 bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() ||
1359 rMaster.GetFooter().IsActive();
1363 PrintMonitor aPrtMonDlg(&pSourceShell->GetView().GetEditWin(), PrintMonitor::MONITOR_TYPE_PRINT);
1364 aPrtMonDlg.aDocName.SetText(pSourceShell->GetView().GetDocShell()->GetTitle(22));
1366 aPrtMonDlg.aCancel.SetClickHdl(LINK(this, SwNewDBMgr, PrtCancelHdl));
1367 if (!IsMergeSilent())
1368 aPrtMonDlg.Show();
1370 // Progress, um KeyInputs zu unterbinden
1371 SfxProgress aProgress(pSourrceDocSh, ::aEmptyStr, 1);
1373 // Alle Dispatcher sperren
1374 SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
1375 while (pViewFrm)
1377 pViewFrm->GetDispatcher()->Lock(TRUE);
1378 pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
1380 ULONG nDocNo = 1;
1382 long nStartRow, nEndRow;
1383 // collect temporary files
1384 ::std::vector< String> aFilesToRemove;
1387 nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
1389 String sPath(sSubject);
1391 String sAddress;
1392 if( !bEMail && bColumnName )
1394 SwDBFormatData aDBFormat;
1395 aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
1396 aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
1397 sAddress = GetDBField( xColumnProp, aDBFormat);
1398 if (!sAddress.Len())
1399 sAddress = '_';
1400 sPath += sAddress;
1403 // create a new temporary file name - only done once in case of bCreateSingleFile
1404 if( 1 == nDocNo || (!rMergeDescriptor.bCreateSingleFile && !bAsSingleFile) )
1406 INetURLObject aEntry(sPath);
1407 String sLeading;
1408 //#i97667# if the name is from a database field then it will be used _as is_
1409 if( sAddress.Len() )
1410 sLeading = sAddress;
1411 else
1412 sLeading = aEntry.GetBase();
1413 aEntry.removeSegment();
1414 sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE );
1415 String sExt( pStoreToFilter->GetDefaultExtension() );
1416 sExt.EraseLeadingChars('*');
1417 aTempFile = std::auto_ptr< utl::TempFile >(
1418 new utl::TempFile(sLeading,&sExt,&sPath ));
1419 if( bAsSingleFile )
1420 aTempFile->EnableKillingFile();
1423 if( !aTempFile->IsValid() )
1425 ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
1426 bLoop = FALSE;
1427 bCancel = TRUE;
1429 else
1431 INetURLObject aTempFileURL(aTempFile->GetURL());
1432 aPrtMonDlg.aPrinter.SetText( aTempFileURL.GetBase() );
1433 String sStat(SW_RES(STR_STATSTR_LETTER)); // Brief
1434 sStat += ' ';
1435 sStat += String::CreateFromInt32( nDocNo );
1436 aPrtMonDlg.aPrintInfo.SetText(sStat);
1438 // Rechenzeit fuer Save-Monitor:
1439 for (USHORT i = 0; i < 10; i++)
1440 Application::Reschedule();
1442 // Neues Dokument erzeugen und speichern
1443 SfxObjectShellRef xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
1444 SfxMedium* pWorkMed = new SfxMedium( sSourceDocumentURL, STREAM_STD_READ, TRUE );
1445 pWorkMed->SetFilter( pSfxFlt );
1447 if (xWorkDocSh->DoLoad(pWorkMed))
1449 //create a view frame for the document
1450 SfxViewFrame* pWorkFrame = SfxViewFrame::CreateViewFrame( *xWorkDocSh, 0, TRUE );
1451 //request the layout calculation
1452 SwWrtShell& rWorkShell =
1453 static_cast< SwView* >(pWorkFrame->GetViewShell())->GetWrtShell();
1454 rWorkShell.CalcLayout();
1455 SwDoc* pWorkDoc = ((SwDocShell*)(&xWorkDocSh))->GetDoc();
1456 SwNewDBMgr* pOldDBMgr = pWorkDoc->GetNewDBMgr();
1457 pWorkDoc->SetNewDBMgr( this );
1458 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh));
1459 pWorkDoc->UpdateFlds(NULL, false);
1460 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh));
1462 // alle versteckten Felder/Bereiche entfernen
1463 pWorkDoc->RemoveInvisibleContent();
1465 // launch MailMergeEvent if required
1466 const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
1467 if(pEvtSrc)
1469 uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc );
1470 text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() );
1471 pEvtSrc->LaunchMailMergeEvent( aEvt );
1474 if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile )
1476 DBG_ASSERT( pTargetShell, "no target shell available!" );
1477 // copy created file into the target document
1478 rWorkShell.ConvertFieldsToText();
1479 rWorkShell.SetNumberingRestart();
1481 // insert the document into the target document
1482 rWorkShell.SttEndDoc(FALSE);
1483 rWorkShell.SttEndDoc(TRUE);
1484 rWorkShell.SelAll();
1485 pTargetShell->SwCrsrShell::SttEndDoc( FALSE );
1486 //#i72517# the headers and footers are still those from the source - update in case of fields inside header/footer
1487 if( !nDocNo && bPageStylesWithHeaderFooter )
1488 pTargetShell->GetView().GetDocShell()->_LoadStyles( *rWorkShell.GetView().GetDocShell(), sal_True );
1489 //#i72517# put the styles to the target document
1490 //if the source uses headers or footers each new copy need to copy a new page styles
1491 if(bPageStylesWithHeaderFooter)
1493 //create a new pagestyle
1494 //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
1496 SwDoc* pTargetDoc = pTargetShell->GetDoc();
1497 SwPageDesc* pSourcePageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
1498 String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
1499 pTargetDoc->MakePageDesc( sNewPageDescName );
1500 SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
1501 if(pSourcePageDesc && pTargetPageDesc)
1503 pTargetDoc->CopyPageDesc( *pSourcePageDesc, *pTargetPageDesc, sal_False );
1504 sModifiedStartingPageDesc = sNewPageDescName;
1505 lcl_CopyFollowPageDesc( *pTargetShell, *pSourcePageDesc, *pTargetPageDesc, nDocNo );
1509 if(nDocNo > 1)
1510 pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
1511 else
1512 pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
1513 DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
1514 //#i51359# add a second paragraph in case there's only one
1516 SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
1517 SwPosition aTestPos( aIdx );
1518 SwCursor aTestCrsr(aTestPos,0,false);
1519 if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
1521 //append a paragraph
1522 pWorkDoc->AppendTxtNode( aTestPos );
1525 pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );
1527 //convert fields in page styles (header/footer - has to be done after the first document has been pasted
1528 if(1 == nDocNo)
1530 pTargetShell->CalcLayout();
1531 pTargetShell->ConvertFieldsToText();
1534 else
1536 String sFileURL = aTempFileURL.GetMainURL( INetURLObject::NO_DECODE );
1537 SfxMedium* pDstMed = new SfxMedium(
1538 sFileURL,
1539 STREAM_STD_READWRITE, TRUE );
1540 pDstMed->SetFilter( pStoreToFilter );
1541 if(pDstMed->GetItemSet())
1543 if(pStoreToFilterOptions )
1544 pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
1545 if(rMergeDescriptor.aSaveToFilterData.getLength())
1546 pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData)));
1549 //convert fields to text if we are exporting to PDF
1550 //this prevents a second merge while updating the fields in SwXTextDocument::getRendererCount()
1551 if( pStoreToFilter && pStoreToFilter->GetFilterName().EqualsAscii("writer_pdf_Export"))
1552 rWorkShell.ConvertFieldsToText();
1553 xWorkDocSh->DoSaveAs(*pDstMed);
1554 xWorkDocSh->DoSaveCompleted(pDstMed);
1555 if( xWorkDocSh->GetError() )
1557 // error message ??
1558 ErrorHandler::HandleError( xWorkDocSh->GetError() );
1559 bCancel = TRUE;
1560 bLoop = FALSE;
1562 if( bEMail )
1564 SwDBFormatData aDBFormat;
1565 aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
1566 aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
1567 String sMailAddress = GetDBField( xColumnProp, aDBFormat);
1568 if(!SwMailMergeHelper::CheckMailAddress( sMailAddress ))
1570 DBG_ERROR("invalid e-Mail address in database column");
1572 else
1574 SwMailMessage* pMessage = 0;
1575 uno::Reference< mail::XMailMessage > xMessage =
1576 pMessage = new SwMailMessage;
1577 if(rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo())
1578 pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo());
1579 pMessage->addRecipient( sMailAddress );
1580 pMessage->SetSenderAddress( rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() );
1581 ::rtl::OUString sBody;
1582 if(rMergeDescriptor.bSendAsAttachment)
1584 sBody = rMergeDescriptor.sMailBody;
1585 mail::MailAttachment aAttach;
1586 aAttach.Data = new SwMailTransferable(
1587 sFileURL,
1588 rMergeDescriptor.sAttachmentName,
1589 pStoreToFilter->GetMimeType());
1590 aAttach.ReadableName = rMergeDescriptor.sAttachmentName;
1591 pMessage->addAttachment( aAttach );
1593 else
1596 //read in the temporary file and use it as mail body
1597 SfxMedium aMedium( sFileURL, STREAM_READ, TRUE);
1598 SvStream* pInStream = aMedium.GetInStream();
1599 DBG_ASSERT(pInStream, "no output file created?");
1600 if(pInStream)
1602 pInStream->SetStreamCharSet( eEncoding );
1603 ByteString sLine;
1604 sal_Bool bDone = pInStream->ReadLine( sLine );
1605 while ( bDone )
1607 sBody += String(sLine, eEncoding);
1608 sBody += ::rtl::OUString('\n');
1609 bDone = pInStream->ReadLine( sLine );
1614 pMessage->setSubject( rMergeDescriptor.sSubject );
1615 uno::Reference< datatransfer::XTransferable> xBody =
1616 new SwMailTransferable(
1617 sBody,
1618 sBodyMimeType);
1619 pMessage->setBody( xBody );
1621 if(rMergeDescriptor.aCopiesTo.getLength())
1623 const ::rtl::OUString* pCopies = rMergeDescriptor.aCopiesTo.getConstArray();
1624 for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aCopiesTo.getLength(); ++nToken)
1625 pMessage->addCcRecipient( pCopies[nToken] );
1627 if(rMergeDescriptor.aBlindCopiesTo.getLength())
1629 const ::rtl::OUString* pCopies = rMergeDescriptor.aBlindCopiesTo.getConstArray();
1630 for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aBlindCopiesTo.getLength(); ++nToken)
1631 pMessage->addBccRecipient( pCopies[nToken] );
1633 xMailDispatcher->enqueueMailMessage( xMessage );
1634 if(!xMailDispatcher->isStarted())
1635 xMailDispatcher->start();
1636 //schedule for removal
1637 aFilesToRemove.push_back(sFileURL);
1641 pWorkDoc->SetNewDBMgr( pOldDBMgr );
1643 xWorkDocSh->DoClose();
1646 nDocNo++;
1647 nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
1648 } while( !bCancel &&
1649 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
1650 // save the single output document
1651 if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile)
1653 DBG_ASSERT( aTempFile.get(), "Temporary file not available" );
1654 INetURLObject aTempFileURL(bAsSingleFile ? sSubject : aTempFile->GetURL());
1655 SfxMedium* pDstMed = new SfxMedium(
1656 aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
1657 STREAM_STD_READWRITE, TRUE );
1658 pDstMed->SetFilter( pStoreToFilter );
1659 if(pDstMed->GetItemSet())
1661 if(pStoreToFilterOptions )
1662 pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
1663 if(rMergeDescriptor.aSaveToFilterData.getLength())
1664 pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData)));
1667 xTargetDocShell->DoSaveAs(*pDstMed);
1668 xTargetDocShell->DoSaveCompleted(pDstMed);
1669 if( xTargetDocShell->GetError() )
1671 // error message ??
1672 ErrorHandler::HandleError( xTargetDocShell->GetError() );
1673 bLoop = FALSE;
1675 xTargetDocShell->DoClose();
1678 //remove the temporary files
1679 ::std::vector<String>::iterator aFileIter;
1680 for(aFileIter = aFilesToRemove.begin();
1681 aFileIter != aFilesToRemove.end(); aFileIter++)
1682 SWUnoHelper::UCB_DeleteFile( *aFileIter );
1684 // Alle Dispatcher freigeben
1685 pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
1686 while (pViewFrm)
1688 pViewFrm->GetDispatcher()->Lock(FALSE);
1689 pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
1692 SW_MOD()->SetView(&pSourceShell->GetView());
1695 nMergeType = DBMGR_INSERT;
1698 if(bEMail)
1700 xMailDispatcher->stop();
1701 xMailDispatcher->shutdown();
1705 return bLoop;
1708 /*--------------------------------------------------------------------
1709 Beschreibung:
1710 --------------------------------------------------------------------*/
1712 IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
1714 pButton->GetParent()->Hide();
1715 bCancel = TRUE;
1716 return 0;
1718 IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
1721 /*--------------------------------------------------------------------
1722 Beschreibung: Numberformat der Spalte ermitteln und ggfs. in
1723 den uebergebenen Formatter uebertragen
1724 --------------------------------------------------------------------*/
1726 ULONG SwNewDBMgr::GetColumnFmt( const String& rDBName,
1727 const String& rTableName,
1728 const String& rColNm,
1729 SvNumberFormatter* pNFmtr,
1730 long nLanguage )
1732 ULONG nRet = 0;
1733 if(pNFmtr)
1735 uno::Reference< XDataSource> xSource;
1736 uno::Reference< XConnection> xConnection;
1737 sal_Bool bUseMergeData = sal_False;
1738 uno::Reference< XColumnsSupplier> xColsSupp;
1739 bool bDisposeConnection = false;
1740 if(pImpl->pMergeData &&
1741 pImpl->pMergeData->sDataSource.equals(rDBName) && pImpl->pMergeData->sCommand.equals(rTableName))
1743 xConnection = pImpl->pMergeData->xConnection;
1744 xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,rDBName);
1745 bUseMergeData = sal_True;
1746 xColsSupp = xColsSupp.query( pImpl->pMergeData->xResultSet );
1748 if(!xConnection.is())
1750 SwDBData aData;
1751 aData.sDataSource = rDBName;
1752 aData.sCommand = rTableName;
1753 aData.nCommandType = -1;
1754 SwDSParam* pParam = FindDSData(aData, FALSE);
1755 if(pParam && pParam->xConnection.is())
1757 xConnection = pParam->xConnection;
1758 xColsSupp = xColsSupp.query( pParam->xResultSet );
1760 else
1762 rtl::OUString sDBName(rDBName);
1763 xConnection = RegisterConnection( sDBName );
1764 bDisposeConnection = true;
1766 if(bUseMergeData)
1767 pImpl->pMergeData->xConnection = xConnection;
1769 bool bDispose = !xColsSupp.is();
1770 if(bDispose)
1772 xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
1774 if(xColsSupp.is())
1776 uno::Reference<XNameAccess> xCols;
1779 xCols = xColsSupp->getColumns();
1781 catch(Exception&)
1783 DBG_ERROR("Exception in getColumns()");
1785 if(!xCols.is() || !xCols->hasByName(rColNm))
1786 return nRet;
1787 Any aCol = xCols->getByName(rColNm);
1788 uno::Reference< XPropertySet > xColumn;
1789 aCol >>= xColumn;
1790 nRet = GetColumnFmt(xSource, xConnection, xColumn, pNFmtr, nLanguage);
1791 if(bDispose)
1793 ::comphelper::disposeComponent( xColsSupp );
1795 if(bDisposeConnection)
1797 ::comphelper::disposeComponent( xConnection );
1800 else
1801 nRet = pNFmtr->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM );
1803 return nRet;
1805 /* -----------------------------07.06.01 15:43--------------------------------
1807 ---------------------------------------------------------------------------*/
1808 ULONG SwNewDBMgr::GetColumnFmt( uno::Reference< XDataSource> xSource,
1809 uno::Reference< XConnection> xConnection,
1810 uno::Reference< XPropertySet> xColumn,
1811 SvNumberFormatter* pNFmtr,
1812 long nLanguage )
1814 //JP 12.01.99: ggfs. das NumberFormat im Doc setzen
1815 ULONG nRet = 0;
1817 if(!xSource.is())
1819 uno::Reference<XChild> xChild(xConnection, UNO_QUERY);
1820 xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
1822 if(xSource.is() && xConnection.is() && xColumn.is() && pNFmtr)
1824 SvNumberFormatsSupplierObj* pNumFmt = new SvNumberFormatsSupplierObj( pNFmtr );
1825 uno::Reference< util::XNumberFormatsSupplier > xDocNumFmtsSupplier = pNumFmt;
1826 uno::Reference< XNumberFormats > xDocNumberFormats = xDocNumFmtsSupplier->getNumberFormats();
1827 uno::Reference< XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY);
1829 Locale aLocale( MsLangId::convertLanguageToLocale( (LanguageType)nLanguage ));
1831 //get the number formatter of the data source
1832 uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
1833 uno::Reference< XNumberFormats > xNumberFormats;
1834 if(xSourceProps.is())
1836 Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier"));
1837 if(aFormats.hasValue())
1839 uno::Reference<XNumberFormatsSupplier> xSuppl;
1840 aFormats >>= xSuppl;
1841 if(xSuppl.is())
1843 xNumberFormats = xSuppl->getNumberFormats();
1847 bool bUseDefault = true;
1850 Any aFormatKey = xColumn->getPropertyValue(C2U("FormatKey"));
1851 if(aFormatKey.hasValue())
1853 sal_Int32 nFmt = 0;
1854 aFormatKey >>= nFmt;
1855 if(xNumberFormats.is())
1859 uno::Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFmt );
1860 Any aFormatString = xNumProps->getPropertyValue(C2U("FormatString"));
1861 Any aLocaleVal = xNumProps->getPropertyValue(C2U("Locale"));
1862 rtl::OUString sFormat;
1863 aFormatString >>= sFormat;
1864 lang::Locale aLoc;
1865 aLocaleVal >>= aLoc;
1866 nFmt = xDocNumberFormats->queryKey( sFormat, aLoc, sal_False );
1867 if(NUMBERFORMAT_ENTRY_NOT_FOUND == sal::static_int_cast< sal_uInt32, sal_Int32>(nFmt))
1868 nFmt = xDocNumberFormats->addNew( sFormat, aLoc );
1869 nRet = nFmt;
1870 bUseDefault = false;
1872 catch(const Exception&)
1874 DBG_ERROR("illegal number format key");
1879 catch( const Exception& )
1881 DBG_ERROR("no FormatKey property found");
1883 if(bUseDefault)
1884 nRet = SwNewDBMgr::GetDbtoolsClient().getDefaultNumberFormat(xColumn, xDocNumberFormatTypes, aLocale);
1886 return nRet;
1889 /* -----------------------------17.07.00 09:47--------------------------------
1891 ---------------------------------------------------------------------------*/
1892 sal_Int32 SwNewDBMgr::GetColumnType( const String& rDBName,
1893 const String& rTableName,
1894 const String& rColNm )
1896 sal_Int32 nRet = DataType::SQLNULL;
1897 SwDBData aData;
1898 aData.sDataSource = rDBName;
1899 aData.sCommand = rTableName;
1900 aData.nCommandType = -1;
1901 SwDSParam* pParam = FindDSData(aData, FALSE);
1902 uno::Reference< XConnection> xConnection;
1903 uno::Reference< XColumnsSupplier > xColsSupp;
1904 bool bDispose = false;
1905 if(pParam && pParam->xConnection.is())
1907 xConnection = pParam->xConnection;
1908 xColsSupp = uno::Reference< XColumnsSupplier >( pParam->xResultSet, UNO_QUERY );
1910 else
1912 rtl::OUString sDBName(rDBName);
1913 xConnection = RegisterConnection( sDBName );
1915 if( !xColsSupp.is() )
1917 xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
1918 bDispose = true;
1920 if(xColsSupp.is())
1922 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
1923 if(xCols->hasByName(rColNm))
1925 Any aCol = xCols->getByName(rColNm);
1926 uno::Reference<XPropertySet> xCol;
1927 aCol >>= xCol;
1928 Any aType = xCol->getPropertyValue(C2S("Type"));
1929 aType >>= nRet;
1931 if(bDispose)
1932 ::comphelper::disposeComponent( xColsSupp );
1934 return nRet;
1937 /* -----------------------------03.07.00 17:12--------------------------------
1939 ---------------------------------------------------------------------------*/
1940 uno::Reference< sdbc::XConnection> SwNewDBMgr::GetConnection(const String& rDataSource,
1941 uno::Reference<XDataSource>& rxSource)
1943 Reference< sdbc::XConnection> xConnection;
1944 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
1947 Reference<XCompletedConnection> xComplConnection(SwNewDBMgr::GetDbtoolsClient().getDataSource(rDataSource, xMgr),UNO_QUERY);
1948 if ( xComplConnection.is() )
1950 rxSource.set(xComplConnection,UNO_QUERY);
1951 Reference< XInteractionHandler > xHandler(
1952 xMgr->createInstance( C2U( "com.sun.star.sdb.InteractionHandler" )), UNO_QUERY);
1953 xConnection = xComplConnection->connectWithCompletion( xHandler );
1956 catch(Exception&) {}
1958 return xConnection;
1960 /* -----------------------------03.07.00 17:12--------------------------------
1962 ---------------------------------------------------------------------------*/
1963 uno::Reference< sdbcx::XColumnsSupplier> SwNewDBMgr::GetColumnSupplier(uno::Reference<sdbc::XConnection> xConnection,
1964 const String& rTableOrQuery,
1965 BYTE eTableOrQuery)
1967 Reference< sdbcx::XColumnsSupplier> xRet;
1970 if(eTableOrQuery == SW_DB_SELECT_UNKNOWN)
1972 //search for a table with the given command name
1973 Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
1974 if(xTSupplier.is())
1976 Reference<XNameAccess> xTbls = xTSupplier->getTables();
1977 eTableOrQuery = xTbls->hasByName(rTableOrQuery) ?
1978 SW_DB_SELECT_TABLE : SW_DB_SELECT_QUERY;
1981 sal_Int32 nCommandType = SW_DB_SELECT_TABLE == eTableOrQuery ?
1982 CommandType::TABLE : CommandType::QUERY;
1983 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
1984 Reference<XRowSet> xRowSet(
1985 xMgr->createInstance(C2U("com.sun.star.sdb.RowSet")), UNO_QUERY);
1987 ::rtl::OUString sDataSource;
1988 Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection, sDataSource);
1989 Reference<XPropertySet> xSourceProperties(xSource, UNO_QUERY);
1990 if(xSourceProperties.is())
1992 xSourceProperties->getPropertyValue(C2U("Name")) >>= sDataSource;
1995 Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
1996 xRowProperties->setPropertyValue(C2U("DataSourceName"), makeAny(sDataSource));
1997 xRowProperties->setPropertyValue(C2U("Command"), makeAny(::rtl::OUString(rTableOrQuery)));
1998 xRowProperties->setPropertyValue(C2U("CommandType"), makeAny(nCommandType));
1999 xRowProperties->setPropertyValue(C2U("FetchSize"), makeAny((sal_Int32)10));
2000 xRowProperties->setPropertyValue(C2U("ActiveConnection"), makeAny(xConnection));
2001 xRowSet->execute();
2002 xRet = Reference<XColumnsSupplier>( xRowSet, UNO_QUERY );
2004 catch( const uno::Exception& )
2006 DBG_ERROR("Exception in SwDBMgr::GetColumnSupplier");
2009 return xRet;
2011 /* -----------------------------05.07.00 13:44--------------------------------
2013 ---------------------------------------------------------------------------*/
2014 String SwNewDBMgr::GetDBField(uno::Reference<XPropertySet> xColumnProps,
2015 const SwDBFormatData& rDBFormatData,
2016 double* pNumber)
2018 uno::Reference< XColumn > xColumn(xColumnProps, UNO_QUERY);
2019 String sRet;
2020 DBG_ASSERT(xColumn.is(), "SwNewDBMgr::::ImportDBField: illegal arguments");
2021 if(!xColumn.is())
2022 return sRet;
2024 Any aType = xColumnProps->getPropertyValue(C2U("Type"));
2025 sal_Int32 eDataType = 0;
2026 aType >>= eDataType;
2027 switch(eDataType)
2029 case DataType::CHAR:
2030 case DataType::VARCHAR:
2031 case DataType::LONGVARCHAR:
2034 sRet = xColumn->getString();
2036 catch( SQLException& )
2039 break;
2040 case DataType::BIT:
2041 case DataType::BOOLEAN:
2042 case DataType::TINYINT:
2043 case DataType::SMALLINT:
2044 case DataType::INTEGER:
2045 case DataType::BIGINT:
2046 case DataType::FLOAT:
2047 case DataType::REAL:
2048 case DataType::DOUBLE:
2049 case DataType::NUMERIC:
2050 case DataType::DECIMAL:
2051 case DataType::DATE:
2052 case DataType::TIME:
2053 case DataType::TIMESTAMP:
2055 // ::Date aTempDate(rDBFormatData.aNullDate.Day,
2056 // rDBFormatData.aNullDate.Month, rDBFormatData.aNullDate.Year);
2060 SwDbtoolsClient& aClient = SwNewDBMgr::GetDbtoolsClient();
2061 sRet = aClient.getValue(
2062 xColumnProps,
2063 rDBFormatData.xFormatter,
2064 rDBFormatData.aLocale,
2065 rDBFormatData.aNullDate);
2066 if (pNumber)
2068 double fVal = xColumn->getDouble();
2069 if(!xColumn->wasNull())
2071 *pNumber = fVal;
2075 catch(Exception& )
2077 DBG_ERROR("exception caught");
2081 break;
2083 // case DataType::BINARY:
2084 // case DataType::VARBINARY:
2085 // case DataType::LONGVARBINARY:
2086 // case DataType::SQLNULL:
2087 // case DataType::OTHER:
2088 // case DataType::OBJECT:
2089 // case DataType::DISTINCT:
2090 // case DataType::STRUCT:
2091 // case DataType::ARRAY:
2092 // case DataType::BLOB:
2093 // case DataType::CLOB:
2094 // case DataType::REF:
2095 // default:
2097 // if (pFormat)
2098 // {
2099 // SFX_ITEMSET_GET(*pCol, pFormatItem, SfxUInt32Item, SBA_DEF_FMTVALUE, sal_True);
2100 // *pFormat = pFormatItem->GetValue();
2101 // }
2103 return sRet;
2105 /* -----------------------------06.07.00 14:28--------------------------------
2106 releases the merge data source table or query after merge is completed
2107 ---------------------------------------------------------------------------*/
2108 void SwNewDBMgr::EndMerge()
2110 DBG_ASSERT(bInMerge, "merge is not active");
2111 bInMerge = FALSE;
2112 delete pImpl->pMergeData;
2113 pImpl->pMergeData = 0;
2115 /* -----------------------------06.07.00 14:28--------------------------------
2116 checks if a desired data source table or query is open
2117 ---------------------------------------------------------------------------*/
2118 BOOL SwNewDBMgr::IsDataSourceOpen(const String& rDataSource,
2119 const String& rTableOrQuery, sal_Bool bMergeOnly)
2121 if(pImpl->pMergeData)
2123 return !bMergeLock &&
2124 ((rDataSource == (String)pImpl->pMergeData->sDataSource &&
2125 rTableOrQuery == (String)pImpl->pMergeData->sCommand)
2126 ||(!rDataSource.Len() && !rTableOrQuery.Len()))
2128 pImpl->pMergeData->xResultSet.is();
2130 else if(!bMergeOnly)
2132 SwDBData aData;
2133 aData.sDataSource = rDataSource;
2134 aData.sCommand = rTableOrQuery;
2135 aData.nCommandType = -1;
2136 SwDSParam* pFound = FindDSData(aData, FALSE);
2137 return (pFound && pFound->xResultSet.is());
2139 return sal_False;
2141 /* -----------------------------17.07.00 16:44--------------------------------
2142 read column data a a specified position
2143 ---------------------------------------------------------------------------*/
2144 BOOL SwNewDBMgr::GetColumnCnt(const String& rSourceName, const String& rTableName,
2145 const String& rColumnName, sal_uInt32 nAbsRecordId,
2146 long nLanguage,
2147 String& rResult, double* pNumber)
2149 BOOL bRet = FALSE;
2150 SwDSParam* pFound = 0;
2151 //check if it's the merge data source
2152 if(pImpl->pMergeData &&
2153 rSourceName == (String)pImpl->pMergeData->sDataSource &&
2154 rTableName == (String)pImpl->pMergeData->sCommand)
2156 pFound = pImpl->pMergeData;
2158 else
2160 SwDBData aData;
2161 aData.sDataSource = rSourceName;
2162 aData.sCommand = rTableName;
2163 aData.nCommandType = -1;
2164 pFound = FindDSData(aData, FALSE);
2166 //check validity of supplied record Id
2167 if(pFound->aSelection.getLength())
2169 //the destination has to be an element of the selection
2170 const Any* pSelection = pFound->aSelection.getConstArray();
2171 sal_Bool bFound = sal_False;
2172 for(sal_Int32 nPos = 0; !bFound && nPos < pFound->aSelection.getLength(); nPos++)
2174 sal_Int32 nSelection = 0;
2175 pSelection[nPos] >>= nSelection;
2176 if(nSelection == static_cast<sal_Int32>(nAbsRecordId))
2177 bFound = sal_True;
2179 if(!bFound)
2180 return FALSE;
2182 if(pFound && pFound->xResultSet.is() && !pFound->bAfterSelection)
2184 sal_Int32 nOldRow = 0;
2187 nOldRow = pFound->xResultSet->getRow();
2189 catch(const Exception& )
2191 return FALSE;
2193 //position to the desired index
2194 BOOL bMove = TRUE;
2195 if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) )
2196 bMove = lcl_MoveAbsolute(pFound, nAbsRecordId);
2197 if(bMove)
2199 bRet = lcl_GetColumnCnt(pFound, rColumnName, nLanguage, rResult, pNumber);
2201 if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) )
2202 bMove = lcl_MoveAbsolute(pFound, nOldRow);
2204 return bRet;
2206 /* -----------------------------06.07.00 16:47--------------------------------
2207 reads the column data at the current position
2208 ---------------------------------------------------------------------------*/
2209 BOOL SwNewDBMgr::GetMergeColumnCnt(const String& rColumnName, USHORT nLanguage,
2210 String &rResult, double *pNumber, sal_uInt32 * /*pFormat*/)
2212 if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is() || pImpl->pMergeData->bAfterSelection )
2214 rResult.Erase();
2215 return FALSE;
2218 BOOL bRet = lcl_GetColumnCnt(pImpl->pMergeData, rColumnName, nLanguage, rResult, pNumber);
2219 return bRet;
2221 /* -----------------------------07.07.00 14:28--------------------------------
2223 ---------------------------------------------------------------------------*/
2224 BOOL SwNewDBMgr::ToNextMergeRecord()
2226 DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
2227 return ToNextRecord(pImpl->pMergeData);
2229 /* -----------------------------10.07.01 14:28--------------------------------
2231 ---------------------------------------------------------------------------*/
2232 BOOL SwNewDBMgr::ToNextRecord(
2233 const String& rDataSource, const String& rCommand, sal_Int32 /*nCommandType*/)
2235 SwDSParam* pFound = 0;
2236 if(pImpl->pMergeData &&
2237 rDataSource == (String)pImpl->pMergeData->sDataSource &&
2238 rCommand == (String)pImpl->pMergeData->sCommand)
2239 pFound = pImpl->pMergeData;
2240 else
2242 SwDBData aData;
2243 aData.sDataSource = rDataSource;
2244 aData.sCommand = rCommand;
2245 aData.nCommandType = -1;
2246 pFound = FindDSData(aData, FALSE);
2248 return ToNextRecord(pFound);
2250 /* -----------------------------10.07.01 14:38--------------------------------
2252 ---------------------------------------------------------------------------*/
2253 BOOL SwNewDBMgr::ToNextRecord(SwDSParam* pParam)
2255 BOOL bRet = TRUE;
2256 if(!pParam || !pParam->xResultSet.is() || pParam->bEndOfDB ||
2257 (pParam->aSelection.getLength() && pParam->aSelection.getLength() <= pParam->nSelectionIndex))
2259 if(pParam)
2260 pParam->CheckEndOfDB();
2261 return FALSE;
2265 if(pParam->aSelection.getLength())
2267 sal_Int32 nPos = 0;
2268 pParam->aSelection.getConstArray()[ pParam->nSelectionIndex++ ] >>= nPos;
2269 pParam->bEndOfDB = !pParam->xResultSet->absolute( nPos );
2270 pParam->CheckEndOfDB();
2271 bRet = !pParam->bEndOfDB;
2272 if(pParam->nSelectionIndex >= pParam->aSelection.getLength())
2273 pParam->bEndOfDB = TRUE;
2275 else
2277 sal_Int32 nBefore = pParam->xResultSet->getRow();
2278 pParam->bEndOfDB = !pParam->xResultSet->next();
2279 if( !pParam->bEndOfDB && nBefore == pParam->xResultSet->getRow())
2281 //next returned true but it didn't move
2282 pParam->bEndOfDB = sal_True;
2285 pParam->CheckEndOfDB();
2286 bRet = !pParam->bEndOfDB;
2287 ++pParam->nSelectionIndex;
2290 catch(Exception&)
2293 return bRet;
2296 /* -----------------------------13.07.00 17:23--------------------------------
2297 synchronized labels contain a next record field at their end
2298 to assure that the next page can be created in mail merge
2299 the cursor position must be validated
2300 ---------------------------------------------------------------------------*/
2301 BOOL SwNewDBMgr::ExistsNextRecord() const
2303 return pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB;
2305 /* -----------------------------13.07.00 10:41--------------------------------
2307 ---------------------------------------------------------------------------*/
2308 sal_uInt32 SwNewDBMgr::GetSelectedRecordId()
2310 sal_uInt32 nRet = 0;
2311 DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
2312 if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is())
2313 return FALSE;
2316 nRet = pImpl->pMergeData->xResultSet->getRow();
2318 catch(Exception& )
2321 return nRet;
2323 /* -----------------------------13.07.00 10:58--------------------------------
2325 ---------------------------------------------------------------------------*/
2326 sal_Bool SwNewDBMgr::ToRecordId(sal_Int32 nSet)
2328 DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
2329 if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()|| nSet < 0)
2330 return FALSE;
2331 sal_Bool bRet = FALSE;
2332 sal_Int32 nAbsPos = nSet;
2334 if(nAbsPos >= 0)
2336 bRet = lcl_MoveAbsolute(pImpl->pMergeData, nAbsPos);
2337 pImpl->pMergeData->bEndOfDB = !bRet;
2338 pImpl->pMergeData->CheckEndOfDB();
2340 return bRet;
2343 /* -----------------------------17.07.00 14:17--------------------------------
2345 ---------------------------------------------------------------------------*/
2346 BOOL SwNewDBMgr::OpenDataSource(const String& rDataSource, const String& rTableOrQuery,
2347 sal_Int32 nCommandType, bool bCreate)
2349 SwDBData aData;
2350 aData.sDataSource = rDataSource;
2351 aData.sCommand = rTableOrQuery;
2352 aData.nCommandType = nCommandType;
2354 SwDSParam* pFound = FindDSData(aData, TRUE);
2355 uno::Reference< XDataSource> xSource;
2356 if(pFound->xResultSet.is())
2357 return TRUE;
2358 SwDSParam* pParam = FindDSConnection(rDataSource, FALSE);
2359 uno::Reference< XConnection> xConnection;
2360 if(pParam && pParam->xConnection.is())
2361 pFound->xConnection = pParam->xConnection;
2362 else if(bCreate)
2364 rtl::OUString sDataSource(rDataSource);
2365 pFound->xConnection = RegisterConnection( sDataSource );
2367 if(pFound->xConnection.is())
2371 uno::Reference< sdbc::XDatabaseMetaData > xMetaData = pFound->xConnection->getMetaData();
2374 pFound->bScrollable = xMetaData
2375 ->supportsResultSetType((sal_Int32)ResultSetType::SCROLL_INSENSITIVE);
2377 catch(Exception&)
2379 //#98373# DB driver may not be ODBC 3.0 compliant
2380 pFound->bScrollable = TRUE;
2382 pFound->xStatement = pFound->xConnection->createStatement();
2383 rtl::OUString aQuoteChar = xMetaData->getIdentifierQuoteString();
2384 rtl::OUString sStatement(C2U("SELECT * FROM "));
2385 sStatement = C2U("SELECT * FROM ");
2386 sStatement += aQuoteChar;
2387 sStatement += rTableOrQuery;
2388 sStatement += aQuoteChar;
2389 pFound->xResultSet = pFound->xStatement->executeQuery( sStatement );
2391 //after executeQuery the cursor must be positioned
2392 pFound->bEndOfDB = !pFound->xResultSet->next();
2393 pFound->bAfterSelection = sal_False;
2394 pFound->CheckEndOfDB();
2395 ++pFound->nSelectionIndex;
2397 catch (Exception&)
2399 pFound->xResultSet = 0;
2400 pFound->xStatement = 0;
2401 pFound->xConnection = 0;
2404 return pFound->xResultSet.is();
2406 /* -----------------------------14.08.2001 10:26------------------------------
2408 ---------------------------------------------------------------------------*/
2409 uno::Reference< XConnection> SwNewDBMgr::RegisterConnection(rtl::OUString& rDataSource)
2411 SwDSParam* pFound = SwNewDBMgr::FindDSConnection(rDataSource, TRUE);
2412 uno::Reference< XDataSource> xSource;
2413 if(!pFound->xConnection.is())
2415 pFound->xConnection = SwNewDBMgr::GetConnection(rDataSource, xSource );
2418 uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
2419 if(xComponent.is())
2420 xComponent->addEventListener(pImpl->xDisposeListener);
2422 catch(Exception&)
2426 return pFound->xConnection;
2428 /* -----------------------------17.07.00 15:55--------------------------------
2430 ---------------------------------------------------------------------------*/
2431 sal_uInt32 SwNewDBMgr::GetSelectedRecordId(
2432 const String& rDataSource, const String& rTableOrQuery, sal_Int32 nCommandType)
2434 sal_uInt32 nRet = 0xffffffff;
2435 //check for merge data source first
2436 if(pImpl->pMergeData && rDataSource == (String)pImpl->pMergeData->sDataSource &&
2437 rTableOrQuery == (String)pImpl->pMergeData->sCommand &&
2438 (nCommandType == -1 || nCommandType == pImpl->pMergeData->nCommandType) &&
2439 pImpl->pMergeData->xResultSet.is())
2440 nRet = GetSelectedRecordId();
2441 else
2443 SwDBData aData;
2444 aData.sDataSource = rDataSource;
2445 aData.sCommand = rTableOrQuery;
2446 aData.nCommandType = nCommandType;
2447 SwDSParam* pFound = FindDSData(aData, FALSE);
2448 if(pFound && pFound->xResultSet.is())
2451 { //if a selection array is set the current row at the result set may not be set yet
2452 if(pFound->aSelection.getLength())
2454 sal_Int32 nSelIndex = pFound->nSelectionIndex;
2455 if(nSelIndex >= pFound->aSelection.getLength())
2456 nSelIndex = pFound->aSelection.getLength() -1;
2457 pFound->aSelection.getConstArray()[nSelIndex] >>= nRet;
2460 else
2461 nRet = pFound->xResultSet->getRow();
2463 catch(Exception&){}
2466 return nRet;
2469 /* -----------------------------17.07.00 14:18--------------------------------
2470 close all data sources - after fields were updated
2471 ---------------------------------------------------------------------------*/
2472 void SwNewDBMgr::CloseAll(BOOL bIncludingMerge)
2474 //the only thing done here is to reset the selection index
2475 //all connections stay open
2476 for(USHORT nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
2478 SwDSParam* pParam = aDataSourceParams[nPos];
2479 if(bIncludingMerge || pParam != pImpl->pMergeData)
2481 pParam->nSelectionIndex = 0;
2482 pParam->bAfterSelection = sal_False;
2483 pParam->bEndOfDB = sal_False;
2486 if(!bInMerge && pParam->xResultSet.is())
2487 pParam->xResultSet->first();
2489 catch(Exception& )
2494 /* -----------------------------17.07.00 14:54--------------------------------
2496 ---------------------------------------------------------------------------*/
2497 SwDSParam* SwNewDBMgr::FindDSData(const SwDBData& rData, BOOL bCreate)
2499 //prefer merge data if available
2500 if(pImpl->pMergeData && rData.sDataSource == pImpl->pMergeData->sDataSource &&
2501 rData.sCommand == pImpl->pMergeData->sCommand &&
2502 (rData.nCommandType == -1 || rData.nCommandType == pImpl->pMergeData->nCommandType ||
2503 (bCreate && pImpl->pMergeData->nCommandType == -1)))
2505 return pImpl->pMergeData;
2508 SwDSParam* pFound = 0;
2509 for(USHORT nPos = aDataSourceParams.Count(); nPos; nPos--)
2511 SwDSParam* pParam = aDataSourceParams[nPos - 1];
2512 if(rData.sDataSource == pParam->sDataSource &&
2513 rData.sCommand == pParam->sCommand &&
2514 (rData.nCommandType == -1 || rData.nCommandType == pParam->nCommandType ||
2515 (bCreate && pParam->nCommandType == -1)))
2517 //#94779# calls from the calculator may add a connection with an invalid commandtype
2518 //later added "real" data base connections have to re-use the already available
2519 //DSData and set the correct CommandType
2520 if(bCreate && pParam->nCommandType == -1)
2521 pParam->nCommandType = rData.nCommandType;
2522 pFound = pParam;
2523 break;
2526 if(bCreate)
2528 if(!pFound)
2530 pFound = new SwDSParam(rData);
2531 aDataSourceParams.Insert(pFound, aDataSourceParams.Count());
2534 uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
2535 if(xComponent.is())
2536 xComponent->addEventListener(pImpl->xDisposeListener);
2538 catch(Exception&)
2543 return pFound;
2545 /* -----------------------------14.08.2001 10:27------------------------------
2547 ---------------------------------------------------------------------------*/
2549 SwDSParam* SwNewDBMgr::FindDSConnection(const rtl::OUString& rDataSource, BOOL bCreate)
2551 //prefer merge data if available
2552 if(pImpl->pMergeData && rDataSource == pImpl->pMergeData->sDataSource )
2554 return pImpl->pMergeData;
2556 SwDSParam* pFound = 0;
2557 for(USHORT nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
2559 SwDSParam* pParam = aDataSourceParams[nPos];
2560 if(rDataSource == pParam->sDataSource)
2562 pFound = pParam;
2563 break;
2566 if(bCreate && !pFound)
2568 SwDBData aData;
2569 aData.sDataSource = rDataSource;
2570 pFound = new SwDSParam(aData);
2571 aDataSourceParams.Insert(pFound, aDataSourceParams.Count());
2574 uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
2575 if(xComponent.is())
2576 xComponent->addEventListener(pImpl->xDisposeListener);
2578 catch(Exception&)
2582 return pFound;
2585 /* -----------------------------17.07.00 14:34--------------------------------
2587 ---------------------------------------------------------------------------*/
2588 const SwDBData& SwNewDBMgr::GetAddressDBName()
2590 return SW_MOD()->GetDBConfig()->GetAddressSource();
2592 /* -----------------------------18.07.00 13:13--------------------------------
2594 ---------------------------------------------------------------------------*/
2595 Sequence<rtl::OUString> SwNewDBMgr::GetExistingDatabaseNames()
2597 uno::Reference<XNameAccess> xDBContext;
2598 uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2599 if( xMgr.is() )
2601 uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
2602 xDBContext = uno::Reference<XNameAccess>(xInstance, UNO_QUERY) ;
2604 if(xDBContext.is())
2606 return xDBContext->getElementNames();
2608 return Sequence<rtl::OUString>();
2610 /*-- 26.05.2004 14:33:13---------------------------------------------------
2612 -----------------------------------------------------------------------*/
2613 String SwNewDBMgr::LoadAndRegisterDataSource()
2615 sfx2::FileDialogHelper aDlgHelper( TemplateDescription::FILEOPEN_SIMPLE, 0 );
2616 Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker();
2618 String sHomePath(SvtPathOptions().GetWorkPath());
2619 aDlgHelper.SetDisplayDirectory( sHomePath );
2621 Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY);
2623 String sFilterAll(SW_RES(STR_FILTER_ALL));
2624 String sFilterAllData(SW_RES(STR_FILTER_ALL_DATA));
2625 String sFilterSXB(SW_RES(STR_FILTER_SXB));
2626 String sFilterSXC(SW_RES(STR_FILTER_SXC));
2627 String sFilterDBF(SW_RES(STR_FILTER_DBF));
2628 String sFilterXLS(SW_RES(STR_FILTER_XLS));
2629 String sFilterTXT(SW_RES(STR_FILTER_TXT));
2630 String sFilterCSV(SW_RES(STR_FILTER_CSV));
2631 #ifdef WNT
2632 String sFilterMDB(SW_RES(STR_FILTER_MDB));
2633 String sFilterACCDB(SW_RES(STR_FILTER_ACCDB));
2634 #endif
2635 xFltMgr->appendFilter( sFilterAll, C2U("*") );
2636 xFltMgr->appendFilter( sFilterAllData, C2U("*.ods;*.sxc;*.dbf;*.xls;*.txt;*.csv"));
2638 xFltMgr->appendFilter( sFilterSXB, C2U("*.odb") );
2639 xFltMgr->appendFilter( sFilterSXC, C2U("*.ods;*.sxc") );
2640 xFltMgr->appendFilter( sFilterDBF, C2U("*.dbf") );
2641 xFltMgr->appendFilter( sFilterXLS, C2U("*.xls") );
2642 xFltMgr->appendFilter( sFilterTXT, C2U("*.txt") );
2643 xFltMgr->appendFilter( sFilterCSV, C2U("*.csv") );
2644 #ifdef WNT
2645 xFltMgr->appendFilter( sFilterMDB, C2U("*.mdb") );
2646 xFltMgr->appendFilter( sFilterACCDB, C2U("*.accdb") );
2647 #endif
2649 xFltMgr->setCurrentFilter( sFilterAll ) ;
2650 String sFind;
2651 bool bTextConnection = false;
2652 if( ERRCODE_NONE == aDlgHelper.Execute() )
2654 String sURL = xFP->getFiles().getConstArray()[0];
2655 //data sources have to be registered depending on their extensions
2656 INetURLObject aURL( sURL );
2657 String sExt( aURL.GetExtension() );
2658 Any aURLAny;
2659 Any aTableFilterAny;
2660 Any aSuppressVersionsAny;
2661 Any aInfoAny;
2662 INetURLObject aTempURL(aURL);
2663 bool bStore = true;
2664 if(sExt.EqualsAscii("odb"))
2666 bStore = false;
2668 else if(sExt.EqualsIgnoreCaseAscii("sxc")
2669 || sExt.EqualsIgnoreCaseAscii("ods")
2670 || sExt.EqualsIgnoreCaseAscii("xls"))
2672 rtl::OUString sDBURL(C2U("sdbc:calc:"));
2673 sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
2674 aURLAny <<= sDBURL;
2676 else if(sExt.EqualsIgnoreCaseAscii("dbf"))
2678 aTempURL.removeSegment();
2679 aTempURL.removeFinalSlash();
2680 rtl::OUString sDBURL(C2U("sdbc:dbase:"));
2681 sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
2682 aURLAny <<= sDBURL;
2683 //set the filter to the file name without extension
2684 Sequence<rtl::OUString> aFilters(1);
2685 rtl::OUString sTmp(aURL.getBase());
2686 aFilters[0] = aURL.getBase();
2687 aTableFilterAny <<= aFilters;
2689 else if(sExt.EqualsIgnoreCaseAscii("csv") || sExt.EqualsIgnoreCaseAscii("txt"))
2691 aTempURL.removeSegment();
2692 aTempURL.removeFinalSlash();
2693 rtl::OUString sDBURL(C2U("sdbc:flat:"));
2694 //only the 'path' has to be added
2695 sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
2696 aURLAny <<= sDBURL;
2698 bTextConnection = true;
2699 //set the filter to the file name without extension
2700 Sequence<rtl::OUString> aFilters(1);
2701 rtl::OUString sTmp(aURL.getBase());
2702 aFilters[0] = aURL.getBase();
2703 aTableFilterAny <<= aFilters;
2705 #ifdef WNT
2706 else if(sExt.EqualsIgnoreCaseAscii("mdb"))
2708 rtl::OUString sDBURL(C2U("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="));
2709 sDBURL += aTempURL.PathToFileName();
2710 aURLAny <<= sDBURL;
2711 aSuppressVersionsAny <<= makeAny(true);
2713 else if(sExt.EqualsIgnoreCaseAscii("accdb"))
2715 rtl::OUString sDBURL(C2U("sdbc:ado:PROVIDER=Microsoft.ACE.OLEDB.12.0;DATA SOURCE="));
2716 sDBURL += aTempURL.PathToFileName();
2717 aURLAny <<= sDBURL;
2718 aSuppressVersionsAny <<= makeAny(true);
2720 #endif
2723 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2724 Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
2725 Reference<XNameAccess> xDBContext(xInstance, UNO_QUERY_THROW);
2726 Reference<XSingleServiceFactory> xFact( xDBContext, UNO_QUERY);
2728 String sNewName = INetURLObject::decode( aURL.getName(),
2729 INET_HEX_ESCAPE,
2730 INetURLObject::DECODE_UNAMBIGUOUS,
2731 RTL_TEXTENCODING_UTF8 );
2732 xub_StrLen nExtLen = static_cast< xub_StrLen >(aURL.GetExtension().getLength());
2733 sNewName.Erase( sNewName.Len() - nExtLen - 1, nExtLen + 1 );
2735 //find a unique name if sNewName already exists
2736 sFind = sNewName;
2737 sal_Int32 nIndex = 0;
2738 while(xDBContext->hasByName(sFind))
2740 sFind = sNewName;
2741 sFind += String::CreateFromInt32(++nIndex);
2744 Reference<XInterface> xNewInstance;
2745 if(!bStore)
2747 //odb-file
2748 Any aDataSource = xDBContext->getByName(aTempURL.GetMainURL(INetURLObject::NO_DECODE));
2749 aDataSource >>= xNewInstance;
2751 else
2753 xNewInstance = xFact->createInstance();
2754 Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY);
2756 if(aURLAny.hasValue())
2757 xDataProperties->setPropertyValue(C2U("URL"), aURLAny);
2758 if(aTableFilterAny.hasValue())
2759 xDataProperties->setPropertyValue(C2U("TableFilter"), aTableFilterAny);
2760 if(aSuppressVersionsAny.hasValue())
2761 xDataProperties->setPropertyValue(C2U("SuppressVersionColumns"), aSuppressVersionsAny);
2762 if(aInfoAny.hasValue())
2763 xDataProperties->setPropertyValue(C2U("Info"), aInfoAny);
2765 if( bTextConnection )
2767 uno::Reference < ui::dialogs::XExecutableDialog > xSettingsDlg(
2768 xMgr->createInstance( C2U( "com.sun.star.sdb.TextConnectionSettings" ) ), uno::UNO_QUERY);
2769 if( xSettingsDlg->execute() )
2771 uno::Any aSettings = xDataProperties->getPropertyValue( C2U( "Settings" ) );
2772 uno::Reference < beans::XPropertySet > xDSSettings;
2773 aSettings >>= xDSSettings;
2774 ::comphelper::copyProperties(
2775 uno::Reference < beans::XPropertySet >( xSettingsDlg, uno::UNO_QUERY ),
2776 xDSSettings );
2777 xDSSettings->setPropertyValue( C2U("Extension"), uno::makeAny( ::rtl::OUString( sExt )));
2781 Reference<XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW);
2782 Reference<XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW);
2783 String sOutputExt = String::CreateFromAscii(".odb");
2784 String sTmpName;
2786 utl::TempFile aTempFile(sNewName , &sOutputExt, &sHomePath);
2787 aTempFile.EnableKillingFile(sal_True);
2788 sTmpName = aTempFile.GetURL();
2790 xStore->storeAsURL(sTmpName, Sequence< PropertyValue >());
2792 Reference<XNamingService> xNaming(xDBContext, UNO_QUERY);
2793 xNaming->registerObject( sFind, xNewInstance );
2796 catch(Exception&)
2800 return sFind;
2803 /* -----------------------------10.11.00 17:10--------------------------------
2805 ---------------------------------------------------------------------------*/
2806 void SwNewDBMgr::ExecuteFormLetter( SwWrtShell& rSh,
2807 const Sequence<PropertyValue>& rProperties,
2808 BOOL bWithDataSourceBrowser)
2810 //prevent second call
2811 if(pImpl->pMergeDialog)
2812 return ;
2813 rtl::OUString sDataSource, sDataTableOrQuery;
2814 Sequence<Any> aSelection;
2816 sal_Int16 nCmdType = CommandType::TABLE;
2817 uno::Reference< XConnection> xConnection;
2819 ODataAccessDescriptor aDescriptor(rProperties);
2820 sDataSource = aDescriptor.getDataSource();
2821 aDescriptor[daCommand] >>= sDataTableOrQuery;
2822 aDescriptor[daCommandType] >>= nCmdType;
2824 if ( aDescriptor.has(daSelection) )
2825 aDescriptor[daSelection] >>= aSelection;
2826 if ( aDescriptor.has(daConnection) )
2827 aDescriptor[daConnection] >>= xConnection;
2829 if(!sDataSource.getLength() || !sDataTableOrQuery.getLength())
2831 DBG_ERROR("PropertyValues missing or unset");
2832 return;
2835 //always create a connection for the dialog and dispose it after the dialog has been closed
2836 SwDSParam* pFound = 0;
2837 if(!xConnection.is())
2839 xConnection = SwNewDBMgr::RegisterConnection(sDataSource);
2840 pFound = FindDSConnection(sDataSource, TRUE);
2842 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
2843 DBG_ASSERT(pFact, "Dialogdiet fail!");
2844 pImpl->pMergeDialog = pFact->CreateMailMergeDlg( DLG_MAILMERGE,
2845 &rSh.GetView().GetViewFrame()->GetWindow(), rSh,
2846 sDataSource,
2847 sDataTableOrQuery,
2848 nCmdType,
2849 xConnection,
2850 bWithDataSourceBrowser ? 0 : &aSelection);
2851 DBG_ASSERT(pImpl->pMergeDialog, "Dialogdiet fail!");
2852 if(pImpl->pMergeDialog->Execute() == RET_OK)
2854 aDescriptor[daSelection] <<= pImpl->pMergeDialog->GetSelection();
2856 uno::Reference<XResultSet> xResSet = pImpl->pMergeDialog->GetResultSet();
2857 if(xResSet.is())
2858 aDescriptor[daCursor] <<= xResSet;
2860 SfxObjectShellRef xDocShell = rSh.GetView().GetViewFrame()->GetObjectShell();
2861 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xDocShell));
2863 //copy rSh to aTempFile
2864 ::rtl::OUString sTempURL;
2865 const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
2866 String::CreateFromAscii( FILTER_XML ),
2867 SwDocShell::Factory().GetFilterContainer() );
2871 uno::Sequence< beans::PropertyValue > aValues(1);
2872 beans::PropertyValue* pValues = aValues.getArray();
2873 pValues[0].Name = C2U("FilterName");
2874 pValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName());
2875 uno::Reference< frame::XStorable > xStore( xDocShell->GetModel(), uno::UNO_QUERY);
2876 sTempURL = URIHelper::SmartRel2Abs( INetURLObject(), utl::TempFile::CreateTempName() );
2877 xStore->storeToURL( sTempURL, aValues );
2879 catch( const uno::Exception& rEx )
2881 (void) rEx;
2883 if( xDocShell->GetError() )
2885 // error message ??
2886 ErrorHandler::HandleError( xDocShell->GetError() );
2888 else
2890 SfxObjectShellRef xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
2891 SfxMedium* pWorkMed = new SfxMedium( sTempURL, STREAM_STD_READ, TRUE );
2892 pWorkMed->SetFilter( pSfxFlt );
2893 if( xWorkDocSh->DoLoad(pWorkMed) )
2895 SfxViewFrame *pFrame = SfxViewFrame::CreateViewFrame( *xWorkDocSh, 0, TRUE );
2896 SwView *pView = (SwView*) pFrame->GetViewShell();
2897 pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird.
2898 //set the current DBMgr
2899 SwDoc* pWorkDoc = pView->GetWrtShell().GetDoc();
2900 SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
2901 pWorkDoc->SetNewDBMgr( this );
2903 SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), pView->GetWrtShell(), aDescriptor );
2904 aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter();
2905 MergeNew(aMergeDesc);
2907 pWorkDoc->SetNewDBMgr( pWorkDBMgr );
2908 //close the temporary file
2909 uno::Reference< util::XCloseable > xClose( xWorkDocSh->GetModel(), uno::UNO_QUERY );
2910 if (xClose.is())
2914 //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
2915 //! I.e. now that object is responsible for closing the model and doc shell.
2916 xClose->close( sal_True );
2918 catch ( const uno::Exception& )
2924 //remove the temporary file
2925 SWUnoHelper::UCB_DeleteFile( sTempURL );
2927 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), rSh.GetView().GetViewFrame()->GetObjectShell()));
2929 // reset the cursor inside
2930 xResSet = NULL;
2931 aDescriptor[daCursor] <<= xResSet;
2933 if(pFound)
2935 for(USHORT nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
2937 SwDSParam* pParam = aDataSourceParams[nPos];
2938 if(pParam == pFound)
2942 uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY);
2943 if(xComp.is())
2944 xComp->dispose();
2946 catch(const RuntimeException& )
2948 //may be disposed already since multiple entries may have used the same connection
2950 break;
2952 //pFound doesn't need to be removed/deleted -
2953 //this has been done by the SwConnectionDisposedListener_Impl already
2956 DELETEZ(pImpl->pMergeDialog);
2958 /* -----------------------------13.11.00 08:20--------------------------------
2960 ---------------------------------------------------------------------------*/
2961 void SwNewDBMgr::InsertText(SwWrtShell& rSh,
2962 const Sequence< PropertyValue>& rProperties)
2964 rtl::OUString sDataSource, sDataTableOrQuery;
2965 uno::Reference<XResultSet> xResSet;
2966 Sequence<Any> aSelection;
2967 BOOL bHasSelectionProperty = FALSE;
2968 sal_Int32 nSelectionPos = 0;
2969 sal_Int16 nCmdType = CommandType::TABLE;
2970 const PropertyValue* pValues = rProperties.getConstArray();
2971 uno::Reference< XConnection> xConnection;
2972 for(sal_Int32 nPos = 0; nPos < rProperties.getLength(); nPos++)
2974 if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cDataSourceName)))
2975 pValues[nPos].Value >>= sDataSource;
2976 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommand)))
2977 pValues[nPos].Value >>= sDataTableOrQuery;
2978 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCursor)))
2979 pValues[nPos].Value >>= xResSet;
2980 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cSelection)))
2982 bHasSelectionProperty = TRUE;
2983 nSelectionPos = nPos;
2984 pValues[nPos].Value >>= aSelection;
2986 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommandType)))
2987 pValues[nPos].Value >>= nCmdType;
2988 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cActiveConnection)))
2989 pValues[nPos].Value >>= xConnection;
2991 if(!sDataSource.getLength() || !sDataTableOrQuery.getLength() || !xResSet.is())
2993 DBG_ERROR("PropertyValues missing or unset");
2994 return;
2996 uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2997 uno::Reference<XDataSource> xSource;
2998 uno::Reference<XChild> xChild(xConnection, UNO_QUERY);
2999 if(xChild.is())
3000 xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
3001 if(!xSource.is())
3002 xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(sDataSource, xMgr);
3003 uno::Reference< XColumnsSupplier > xColSupp( xResSet, UNO_QUERY );
3004 SwDBData aDBData;
3005 aDBData.sDataSource = sDataSource;
3006 aDBData.sCommand = sDataTableOrQuery;
3007 aDBData.nCommandType = nCmdType;
3009 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
3010 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
3012 AbstractSwInsertDBColAutoPilot* pDlg = pFact->CreateSwInsertDBColAutoPilot( rSh.GetView(),
3013 xSource,
3014 xColSupp,
3015 aDBData,
3016 DLG_AP_INSERT_DB_SEL );
3017 DBG_ASSERT(pDlg, "Dialogdiet fail!");
3018 if( RET_OK == pDlg->Execute() )
3020 rtl::OUString sDummy;
3021 if(!xConnection.is())
3022 xConnection = xSource->getConnection(sDummy, sDummy);
3025 pDlg->DataToDoc( aSelection , xSource, xConnection, xResSet);
3027 catch(Exception& )
3029 DBG_ERROR("exception caught");
3032 delete pDlg;
3035 /* -----------------------------30.08.2001 12:00------------------------------
3037 ---------------------------------------------------------------------------*/
3038 SwDbtoolsClient* SwNewDBMgr::pDbtoolsClient = NULL;
3040 SwDbtoolsClient& SwNewDBMgr::GetDbtoolsClient()
3042 if ( !pDbtoolsClient )
3043 pDbtoolsClient = new SwDbtoolsClient;
3044 return *pDbtoolsClient;
3046 /* -----------------13.05.2003 15:34-----------------
3048 --------------------------------------------------*/
3049 void SwNewDBMgr::RemoveDbtoolsClient()
3051 delete pDbtoolsClient;
3052 pDbtoolsClient = 0;
3054 /* -----------------------------20.08.2002 12:00------------------------------
3056 ---------------------------------------------------------------------------*/
3057 uno::Reference<XDataSource> SwNewDBMgr::getDataSourceAsParent(const uno::Reference< XConnection>& _xConnection,const ::rtl::OUString& _sDataSourceName)
3059 uno::Reference<XDataSource> xSource;
3062 uno::Reference<XChild> xChild(_xConnection, UNO_QUERY);
3063 if ( xChild.is() )
3064 xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
3065 if ( !xSource.is() )
3066 xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(_sDataSourceName, ::comphelper::getProcessServiceFactory());
3068 catch(const Exception&)
3070 DBG_ERROR("exception in getDataSourceAsParent caught");
3072 return xSource;
3074 /* -----------------------------20.08.2002 12:00------------------------------
3076 ---------------------------------------------------------------------------*/
3077 uno::Reference<XResultSet> SwNewDBMgr::createCursor(const ::rtl::OUString& _sDataSourceName,
3078 const ::rtl::OUString& _sCommand,
3079 sal_Int32 _nCommandType,
3080 const uno::Reference<XConnection>& _xConnection
3083 uno::Reference<XResultSet> xResultSet;
3086 uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
3087 if( xMgr.is() )
3089 uno::Reference<XInterface> xInstance = xMgr->createInstance(
3090 C2U( "com.sun.star.sdb.RowSet" ));
3091 uno::Reference<XPropertySet> xRowSetPropSet(xInstance, UNO_QUERY);
3092 if(xRowSetPropSet.is())
3094 xRowSetPropSet->setPropertyValue(C2U("DataSourceName"), makeAny(_sDataSourceName));
3095 xRowSetPropSet->setPropertyValue(C2U("ActiveConnection"), makeAny(_xConnection));
3096 xRowSetPropSet->setPropertyValue(C2U("Command"), makeAny(_sCommand));
3097 xRowSetPropSet->setPropertyValue(C2U("CommandType"), makeAny(_nCommandType));
3099 uno::Reference< XCompletedExecution > xRowSet(xInstance, UNO_QUERY);
3101 if ( xRowSet.is() )
3103 uno::Reference< XInteractionHandler > xHandler(xMgr->createInstance(C2U("com.sun.star.sdb.InteractionHandler")), UNO_QUERY);
3104 xRowSet->executeWithCompletion(xHandler);
3106 xResultSet = uno::Reference<XResultSet>(xRowSet, UNO_QUERY);
3110 catch(const Exception&)
3112 DBG_ASSERT(0,"Caught exception while creating a new RowSet!");
3114 return xResultSet;
3116 /*-- 13.05.2004 16:14:15---------------------------------------------------
3117 merge all data into one resulting document and return the number of
3118 merged documents
3119 -----------------------------------------------------------------------*/
3121 sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
3122 SwView& rSourceView )
3124 // check the availability of all data in the config item
3125 uno::Reference< XResultSet> xResultSet = rMMConfig.GetResultSet();
3126 if(!xResultSet.is())
3127 return false;
3128 bInMerge = TRUE;
3129 sal_Int32 nRet = 0;
3130 pImpl->pMergeData = new SwDSParam(
3131 rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection());
3133 try{
3134 //set to start position
3135 if(pImpl->pMergeData->aSelection.getLength())
3137 sal_Int32 nPos = 0;
3138 pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
3139 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
3140 pImpl->pMergeData->CheckEndOfDB();
3141 if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
3142 pImpl->pMergeData->bEndOfDB = TRUE;
3144 else
3146 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
3147 pImpl->pMergeData->CheckEndOfDB();
3150 catch(Exception&)
3152 pImpl->pMergeData->bEndOfDB = TRUE;
3153 pImpl->pMergeData->CheckEndOfDB();
3154 DBG_ERROR("exception in MergeNew()");
3157 //bCancel is set from the PrintMonitor
3158 bCancel = FALSE;
3160 CreateMonitor aMonitorDlg(&rSourceView.GetEditWin());
3161 aMonitorDlg.SetCancelHdl(LINK(this, SwNewDBMgr, PrtCancelHdl));
3162 if (!IsMergeSilent())
3164 aMonitorDlg.Show();
3165 aMonitorDlg.Invalidate();
3166 aMonitorDlg.Update();
3167 // the print monitor needs some time to act
3168 for( USHORT i = 0; i < 25; i++)
3169 Application::Reschedule();
3172 SwWrtShell& rSourceShell = rSourceView.GetWrtShell();
3173 BOOL bSynchronizedDoc = rSourceShell.IsLabelDoc() && rSourceShell.GetSectionFmtCount() > 1;
3174 //save the settings of the first
3175 rSourceShell.SttEndDoc(TRUE);
3176 USHORT nStartingPageNo = rSourceShell.GetVirtPageNum();
3177 String sModifiedStartingPageDesc;
3178 String sStartingPageDesc = sModifiedStartingPageDesc = rSourceShell.GetPageDesc(
3179 rSourceShell.GetCurPageDesc()).GetName();
3183 // create a target docshell to put the merged document into
3184 SfxObjectShellRef xTargetDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) );
3185 xTargetDocShell->DoInitNew( 0 );
3186 SfxViewFrame* pTargetFrame = SfxViewFrame::CreateViewFrame( *xTargetDocShell, 0, TRUE );
3188 //the created window has to be located at the same position as the source window
3189 Window& rTargetWindow = pTargetFrame->GetFrame()->GetWindow();
3190 Window& rSourceWindow = rSourceView.GetViewFrame()->GetFrame()->GetWindow();
3191 rTargetWindow.SetPosPixel(rSourceWindow.GetPosPixel());
3193 // pTargetFrame->GetFrame()->Appear();
3194 SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
3195 rMMConfig.SetTargetView(pTargetView);
3196 //initiate SelectShell() to create sub shells
3197 pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
3198 SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr();
3199 // #i63806#
3200 const SwPageDesc* pSourcePageDesc = rSourceShell.FindPageDescByName( sStartingPageDesc );
3201 const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
3202 bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() ||
3203 rMaster.GetFooter().IsActive();
3206 // #122799# copy compatibility options
3207 lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell);
3208 // #72821# copy dynamic defaults
3209 lcl_CopyDynamicDefaults( *rSourceShell.GetDoc(), *pTargetShell->GetDoc() );
3212 long nStartRow, nEndRow;
3213 ULONG nDocNo = 1;
3214 sal_Int32 nDocCount = 0;
3215 if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) )
3216 aMonitorDlg.SetTotalCount( nDocCount );
3220 nStartRow = pImpl->pMergeData->xResultSet->getRow();
3221 if (!IsMergeSilent())
3223 aMonitorDlg.SetCurrentPosition( nDocNo );
3224 aMonitorDlg.Invalidate();
3225 aMonitorDlg.Update();
3226 // the print monitor needs some time to act
3227 for( USHORT i = 0; i < 25; i++)
3228 Application::Reschedule();
3231 // copy the source document
3232 SfxObjectShellRef xWorkDocSh;
3233 if(nDocNo == 1 )
3235 uno::Reference< util::XCloneable > xClone( rSourceView.GetDocShell()->GetModel(), uno::UNO_QUERY);
3236 uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY);
3237 SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId()));
3238 xWorkDocSh = pWorkModel->GetDocShell();
3240 else
3242 SwDoc* pNewDoc = rSourceView.GetDocShell()->GetDoc()->CreateCopy();
3243 xWorkDocSh = new SwDocShell( pNewDoc, SFX_CREATE_MODE_STANDARD );
3244 xWorkDocSh->DoInitNew();
3246 //create a ViewFrame
3247 SwView* pWorkView = static_cast< SwView* >( SfxViewFrame::CreateViewFrame( *xWorkDocSh, 0, sal_True )->GetViewShell() );
3248 SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
3249 pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird.
3251 // merge the data
3252 SwDoc* pWorkDoc = rWorkShell.GetDoc();
3253 SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
3254 pWorkDoc->SetNewDBMgr( this );
3255 pWorkDoc->EmbedAllLinks();
3256 if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds())
3257 rWorkShell.Undo();
3258 // #i69485# lock fields to prevent access to the result set while calculating layout
3259 rWorkShell.LockExpFlds();
3260 // create a layout
3261 rWorkShell.CalcLayout();
3262 rWorkShell.UnlockExpFlds();
3263 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
3264 rWorkShell.ViewShell::UpdateFlds();
3265 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
3267 // strip invisible content and convert fields to text
3268 rWorkShell.RemoveInvisibleContent();
3269 rWorkShell.ConvertFieldsToText();
3270 rWorkShell.SetNumberingRestart();
3273 // insert the document into the target document
3274 rWorkShell.SttEndDoc(FALSE);
3275 rWorkShell.SttEndDoc(TRUE);
3276 rWorkShell.SelAll();
3277 pTargetShell->SttEndDoc(FALSE);
3279 //#i63806# put the styles to the target document
3280 //if the source uses headers or footers each new copy need to copy a new page styles
3281 if(bPageStylesWithHeaderFooter)
3283 //create a new pagestyle
3284 //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style
3286 SwDoc* pTargetDoc = pTargetShell->GetDoc();
3287 String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
3288 pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName );
3289 SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
3290 const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
3292 if(pWorkPageDesc && pTargetPageDesc)
3294 pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, sal_False );
3295 sModifiedStartingPageDesc = sNewPageDescName;
3296 lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
3299 if(nDocNo == 1 || bPageStylesWithHeaderFooter)
3301 pTargetView->GetDocShell()->_LoadStyles( *pWorkView->GetDocShell(), sal_True );
3303 if(nDocNo > 1)
3305 pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
3307 else
3309 pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
3311 USHORT nPageCountBefore = pTargetShell->GetPageCnt();
3312 DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
3313 //#i51359# add a second paragraph in case there's only one
3315 SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
3316 SwPosition aTestPos( aIdx );
3317 SwCursor aTestCrsr(aTestPos,0,false);
3318 if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
3320 //append a paragraph
3321 pWorkDoc->AppendTxtNode( aTestPos );
3324 pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );
3325 //convert fields in page styles (header/footer - has to be done after the first document has been pasted
3326 if(1 == nDocNo)
3328 pTargetShell->CalcLayout();
3329 pTargetShell->ConvertFieldsToText();
3331 //add the document info to the config item
3332 SwDocMergeInfo aMergeInfo;
3333 aMergeInfo.nStartPageInTarget = nPageCountBefore;
3334 //#i72820# calculate layout to be able to find the correct page index
3335 pTargetShell->CalcLayout();
3336 aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt();
3337 aMergeInfo.nDBRow = nStartRow;
3338 rMMConfig.AddMergedDocument( aMergeInfo );
3339 ++nRet;
3341 // the print monitor needs some time to act
3342 for( USHORT i = 0; i < 25; i++)
3343 Application::Reschedule();
3345 //restore the ole DBMgr
3346 pWorkDoc->SetNewDBMgr( pWorkDBMgr );
3347 //now the temporary document should be closed
3348 SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
3349 xDocSh->DoClose();
3350 nEndRow = pImpl->pMergeData->xResultSet->getRow();
3351 ++nDocNo;
3352 } while( !bCancel &&
3353 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
3355 //deselect all, go out of the frame and go to the beginning of the document
3356 Point aPt(LONG_MIN, LONG_MIN);
3357 pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME);
3358 if (pTargetShell->IsSelFrmMode())
3360 pTargetShell->UnSelectFrm();
3361 pTargetShell->LeaveSelFrmMode();
3363 pTargetShell->EnterStdMode();
3364 pTargetShell->SttDoc();
3367 catch( Exception& )
3369 DBG_ERROR("exception caught in SwNewDBMgr::MergeDocuments");
3371 DELETEZ(pImpl->pMergeData);
3372 bInMerge = FALSE;
3373 return nRet;
3375 /* -----------------09.12.2002 12:38-----------------
3377 * --------------------------------------------------*/
3378 SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr) :
3379 rDBMgr(rMgr)
3381 /* -----------------09.12.2002 12:39-----------------
3383 * --------------------------------------------------*/
3384 SwConnectionDisposedListener_Impl::~SwConnectionDisposedListener_Impl()
3386 /* -----------------09.12.2002 12:39-----------------
3388 * --------------------------------------------------*/
3389 void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource )
3390 throw (RuntimeException)
3392 ::vos::OGuard aGuard(Application::GetSolarMutex());
3393 uno::Reference<XConnection> xSource(rSource.Source, UNO_QUERY);
3394 for(USHORT nPos = rDBMgr.aDataSourceParams.Count(); nPos; nPos--)
3396 SwDSParam* pParam = rDBMgr.aDataSourceParams[nPos - 1];
3397 if(pParam->xConnection.is() &&
3398 (xSource == pParam->xConnection))
3400 rDBMgr.aDataSourceParams.DeleteAndDestroy(nPos - 1);