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
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>
69 #define _SVSTDARR_STRINGSDTOR
70 #include <svtools/svstdarr.hxx>
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>
82 #include <swmodule.hxx>
92 #include <swprtopt.hxx>
93 #include <shellio.hxx>
98 #include <swunohelper.hxx>
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>
133 #include <swcrsr.hxx>
134 #include <swevent.hxx>
135 #include <osl/file.hxx>
136 #include <swabstdlg.hxx>
137 #include <fmthdft.hxx>
139 #include <envelp.hrc>
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
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 // -----------------------------------------------------------------------------
179 bool lcl_getCountFromResultSet( sal_Int32
& rCount
, const uno::Reference
<XResultSet
>& xResultSet
)
181 uno::Reference
<XPropertySet
> xPrSet(xResultSet
, UNO_QUERY
);
186 sal_Bool bFinal
= sal_False
;
187 Any aFinal
= xPrSet
->getPropertyValue(C2U("IsRowCountFinal"));
194 Any aCount
= xPrSet
->getPropertyValue(C2U("RowCount"));
195 if( aCount
>>= rCount
)
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
>
230 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
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
)
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();
257 uno::Reference
<XInterface
> xInstance
= xMgr
->createInstance( C2U( "com.sun.star.util.NumberFormatter" ));
258 rParam
.xFormatter
= uno::Reference
<util::XNumberFormatter
>(xInstance
, UNO_QUERY
) ;
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
;
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
)
290 if(pParam
->bScrollable
)
292 bRet
= pParam
->xResultSet
->absolute( nAbsPos
);
296 DBG_ERROR("no absolute positioning available");
299 catch(Exception aExcept
)
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
))
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
);
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!");
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())
371 pImpl
->pMergeData
= new SwDSParam(aData
, xResSet
, aSelection
);
372 SwDSParam
* pTemp
= FindDSData(aData
, FALSE
);
374 *pTemp
= *pImpl
->pMergeData
;
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
);
384 *pTemp
= *pImpl
->pMergeData
;
387 SwDSParam
* pInsert
= new SwDSParam(*pImpl
->pMergeData
);
388 aDataSourceParams
.Insert(pInsert
, aDataSourceParams
.Count());
391 uno::Reference
<XComponent
> xComponent(pInsert
->xConnection
, UNO_QUERY
);
393 xComponent
->addEventListener(pImpl
->xDisposeListener
);
400 if(!pImpl
->pMergeData
->xConnection
.is())
401 pImpl
->pMergeData
->xConnection
= xConnection
;
402 // add an XEventListener
405 //set to start position
406 if(pImpl
->pMergeData
->aSelection
.getLength())
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
;
417 pImpl
->pMergeData
->bEndOfDB
= !pImpl
->pMergeData
->xResultSet
->first();
418 pImpl
->pMergeData
->CheckEndOfDB();
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
);
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
;
443 sDBName
+= (String
)aInsertData
.sCommand
;
445 sDBName
+= String::CreateFromInt32(aInsertData
.nCommandType
);
446 rMergeDesc
.rSh
.ChangeDBFields( aDBNames
, sDBName
);
447 SetInitDBFields(FALSE
);
451 switch(rMergeDesc
.nMergeType
)
454 bRet
= Merge(&rMergeDesc
.rSh
); // Mischen
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
,
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.
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
,
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
,
539 default: // Einfuegen der selektierten Eintraege
540 // (war: InsertRecord)
541 ImportFromConnection(&rMergeDesc
.rSh
);
549 /*--------------------------------------------------------------------
550 Beschreibung: Daten importieren
551 --------------------------------------------------------------------*/
554 BOOL
SwNewDBMgr::Merge(SwWrtShell
* pSh
)
556 pSh
->StartAllAction();
558 pSh
->ViewShell::UpdateFlds(TRUE
);
566 /*--------------------------------------------------------------------
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() )
590 pWait
= new SwWait( *pSh
->GetView().GetDocShell(), TRUE
);
592 } while(ToNextMergeRecord());
595 pSh
->DoGroupUndo(bGroupUndo
);
596 pSh
->EndUndo(UNDO_EMPTY
);
602 /*-----------------24.02.97 10.30-------------------
604 --------------------------------------------------*/
606 String
lcl_FindColumn(const String
& sFormatStr
,USHORT
&nUsedPos
, BYTE
&nSeparator
)
609 USHORT nLen
= sFormatStr
.Len();
611 while(nUsedPos
< nLen
&& nSeparator
== 0xff)
613 sal_Unicode cAkt
= sFormatStr
.GetChar(nUsedPos
);
617 nSeparator
= DB_SEP_SPACE
;
620 nSeparator
= DB_SEP_RETURN
;
623 nSeparator
= DB_SEP_TAB
;
626 nSeparator
= DB_SEP_NEWLINE
;
637 /*--------------------------------------------------------------------
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();
647 USHORT nFmtLen
= sFormatStr
.Len();
650 const char cSpace
= ' ';
651 const char cTab
= '\t';
654 String sColumn
= lcl_FindColumn(sFormatStr
, nUsedPos
, nSeparator
);
655 while( sColumn
.Len() )
657 if(!xCols
->hasByName(sColumn
))
659 Any aCol
= xCols
->getByName(sColumn
);
660 uno::Reference
< XPropertySet
> xColumnProp
;
661 aCol
>>= xColumnProp
;
664 SwDBFormatData aDBFormat
;
665 String sInsert
= GetDBField( xColumnProp
, aDBFormat
);
666 if( DB_SEP_SPACE
== nSeparator
)
668 else if( DB_SEP_TAB
== nSeparator
)
670 pSh
->Insert(sInsert
);
671 if( DB_SEP_RETURN
== nSeparator
)
673 else if(DB_SEP_NEWLINE
== nSeparator
)
674 pSh
->InsertLineBreak();
678 // Spalte nicht gefunden -> Fehler anzeigen
679 String sInsert
= '?';
682 pSh
->Insert(sInsert
);
684 sColumn
= lcl_FindColumn(sFormatStr
, nUsedPos
, nSeparator
);
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
);
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
)
715 String
sOldTableName(pListBox
->GetSelectEntry());
717 SwDSParam
* pParam
= FindDSConnection(rDBName
, FALSE
);
718 uno::Reference
< XConnection
> xConnection
;
719 if(pParam
&& pParam
->xConnection
.is())
720 xConnection
= pParam
->xConnection
;
723 rtl::OUString
sDBName(rDBName
);
724 xConnection
= RegisterConnection( sDBName
);
728 uno::Reference
<XTablesSupplier
> xTSupplier
= uno::Reference
<XTablesSupplier
>(xConnection
, UNO_QUERY
);
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
);
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
);
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
)
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
;
777 rtl::OUString
sDBName(rDBName
);
778 xConnection
= RegisterConnection( sDBName
);
780 uno::Reference
< XColumnsSupplier
> xColsSupp
= SwNewDBMgr::GetColumnSupplier(xConnection
, rTableName
);
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
);
794 /* -----------------------------08.06.01 15:11--------------------------------
796 ---------------------------------------------------------------------------*/
797 BOOL
SwNewDBMgr::GetColumnNames(ListBox
* pListBox
,
798 uno::Reference
< XConnection
> xConnection
,
799 const String
& rTableName
, BOOL bAppend
)
803 uno::Reference
< XColumnsSupplier
> xColsSupp
= SwNewDBMgr::GetColumnSupplier(xConnection
, rTableName
);
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
);
818 /*--------------------------------------------------------------------
820 --------------------------------------------------------------------*/
822 SwNewDBMgr::SwNewDBMgr() :
823 nMergeType(DBMGR_INSERT
),
824 bInitDBFields(FALSE
),
828 pImpl(new SwNewDBMgr_Impl(*this)),
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
);
848 catch(const RuntimeException
& )
850 //may be disposed already since multiple entries may have used the same connection
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
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())
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
,
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
);
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()));
940 // launch MailMergeEvent if required
941 const SwXMailMerge
*pEvtSrc
= GetMailMergeEvtSrc();
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;
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() );
971 else if( pSh
->Prt( rOpt
, &rProgress
) )
975 if( !pPrt
->IsJobActive() )
981 if( !rOpt
.IsPrintSingleJobs() )
983 String
& rJNm
= (String
&)rOpt
.GetJobName();
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
);
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());
1010 pVw
->GetEditWin().Invalidate();
1011 pTmpFrm
= pTmpFrm
->GetNext(*pTmpFrm
, pDocSh
);
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
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
,
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");
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
);
1092 // launch MailMergeEvent if required
1093 const SwXMailMerge
*pEvtSrc
= GetMailMergeEvtSrc();
1096 uno::Reference
< XInterface
> xRef( (XMailMergeBroadcaster
*) pEvtSrc
);
1097 text::MailMergeEvent
aEvt( xRef
, rView
.GetDocShell()->GetModel() );
1098 pEvtSrc
->LaunchMailMergeEvent( aEvt
);
1102 aTmp
+= String::CreateFromInt32( rDocInfo
.nStartPageInTarget
);
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;
1120 if(rOpt
.IsPrintProspect())
1122 if( pPrt
->IsJobActive() || pPrt
->StartJob( rOpt
.GetJobName() ))
1124 pSh
->PrintProspect( rOpt
, rProgress
, rOpt
.IsPrintProspect_RTL() );
1128 else if( pSh
->Prt( rOpt
, &rProgress
) )
1132 if( !pPrt
->IsJobActive() )
1138 if( !rOpt
.IsPrintSingleJobs() )
1140 String
& rJNm
= (String
&)rOpt
.GetJobName();
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
);
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());
1165 pVw
->GetEditWin().Invalidate();
1166 pTmpFrm
= pTmpFrm
->GetNext(*pTmpFrm
, pDocSh
);
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
) )
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,
1197 RES_UNKNOWNATR_BEGIN
, RES_UNKNOWNATR_END
-1,
1201 SfxItemSet
aNewDefaults( rTarget
.GetAttrPool(), aRangeOfDefaults
);
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
);
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;
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();
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();
1267 ::rtl::OUString::createFromAscii("text/plain; charset=UTF-8; format=flowed");
1270 uno::Reference
< XPropertySet
> xColumnProp
;
1272 BOOL bColumnName
= sEMailAddrFld
.Len() > 0;
1276 uno::Reference
< XColumnsSupplier
> xColsSupp( pImpl
->pMergeData
->xResultSet
, UNO_QUERY
);
1277 uno::Reference
<XNameAccess
> xCols
= xColsSupp
->getColumns();
1278 if(!xCols
->hasByName(sEMailAddrFld
))
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
);
1310 pStoreToFilter
= pFilter
;
1311 if(rMergeDescriptor
.sSaveToFilterOptions
.Len())
1312 pStoreToFilterOptions
= &rMergeDescriptor
.sSaveToFilterOptions
;
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() );
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())
1370 // Progress, um KeyInputs zu unterbinden
1371 SfxProgress
aProgress(pSourrceDocSh
, ::aEmptyStr
, 1);
1373 // Alle Dispatcher sperren
1374 SfxViewFrame
* pViewFrm
= SfxViewFrame::GetFirst(pSourrceDocSh
);
1377 pViewFrm
->GetDispatcher()->Lock(TRUE
);
1378 pViewFrm
= SfxViewFrame::GetNext(*pViewFrm
, pSourrceDocSh
);
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
);
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())
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
);
1408 //#i97667# if the name is from a database field then it will be used _as is_
1409 if( sAddress
.Len() )
1410 sLeading
= sAddress
;
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
));
1420 aTempFile
->EnableKillingFile();
1423 if( !aTempFile
->IsValid() )
1425 ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED
);
1431 INetURLObject
aTempFileURL(aTempFile
->GetURL());
1432 aPrtMonDlg
.aPrinter
.SetText( aTempFileURL
.GetBase() );
1433 String
sStat(SW_RES(STR_STATSTR_LETTER
)); // Brief
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();
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
);
1510 pTargetShell
->InsertPageBreak( &sModifiedStartingPageDesc
, nStartingPageNo
);
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
1530 pTargetShell
->CalcLayout();
1531 pTargetShell
->ConvertFieldsToText();
1536 String sFileURL
= aTempFileURL
.GetMainURL( INetURLObject::NO_DECODE
);
1537 SfxMedium
* pDstMed
= new SfxMedium(
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() )
1558 ErrorHandler::HandleError( xWorkDocSh
->GetError() );
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");
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(
1588 rMergeDescriptor
.sAttachmentName
,
1589 pStoreToFilter
->GetMimeType());
1590 aAttach
.ReadableName
= rMergeDescriptor
.sAttachmentName
;
1591 pMessage
->addAttachment( aAttach
);
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?");
1602 pInStream
->SetStreamCharSet( eEncoding
);
1604 sal_Bool bDone
= pInStream
->ReadLine( sLine
);
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(
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();
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() )
1672 ErrorHandler::HandleError( xTargetDocShell
->GetError() );
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
);
1688 pViewFrm
->GetDispatcher()->Lock(FALSE
);
1689 pViewFrm
= SfxViewFrame::GetNext(*pViewFrm
, pSourrceDocSh
);
1692 SW_MOD()->SetView(&pSourceShell
->GetView());
1695 nMergeType
= DBMGR_INSERT
;
1700 xMailDispatcher
->stop();
1701 xMailDispatcher
->shutdown();
1708 /*--------------------------------------------------------------------
1710 --------------------------------------------------------------------*/
1712 IMPL_LINK_INLINE_START( SwNewDBMgr
, PrtCancelHdl
, Button
*, pButton
)
1714 pButton
->GetParent()->Hide();
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
,
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())
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
);
1762 rtl::OUString
sDBName(rDBName
);
1763 xConnection
= RegisterConnection( sDBName
);
1764 bDisposeConnection
= true;
1767 pImpl
->pMergeData
->xConnection
= xConnection
;
1769 bool bDispose
= !xColsSupp
.is();
1772 xColsSupp
= SwNewDBMgr::GetColumnSupplier(xConnection
, rTableName
);
1776 uno::Reference
<XNameAccess
> xCols
;
1779 xCols
= xColsSupp
->getColumns();
1783 DBG_ERROR("Exception in getColumns()");
1785 if(!xCols
.is() || !xCols
->hasByName(rColNm
))
1787 Any aCol
= xCols
->getByName(rColNm
);
1788 uno::Reference
< XPropertySet
> xColumn
;
1790 nRet
= GetColumnFmt(xSource
, xConnection
, xColumn
, pNFmtr
, nLanguage
);
1793 ::comphelper::disposeComponent( xColsSupp
);
1795 if(bDisposeConnection
)
1797 ::comphelper::disposeComponent( xConnection
);
1801 nRet
= pNFmtr
->GetFormatIndex( NF_NUMBER_STANDARD
, LANGUAGE_SYSTEM
);
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
,
1814 //JP 12.01.99: ggfs. das NumberFormat im Doc setzen
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
;
1843 xNumberFormats
= xSuppl
->getNumberFormats();
1847 bool bUseDefault
= true;
1850 Any aFormatKey
= xColumn
->getPropertyValue(C2U("FormatKey"));
1851 if(aFormatKey
.hasValue())
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
;
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
);
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");
1884 nRet
= SwNewDBMgr::GetDbtoolsClient().getDefaultNumberFormat(xColumn
, xDocNumberFormatTypes
, aLocale
);
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
;
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
);
1912 rtl::OUString
sDBName(rDBName
);
1913 xConnection
= RegisterConnection( sDBName
);
1915 if( !xColsSupp
.is() )
1917 xColsSupp
= SwNewDBMgr::GetColumnSupplier(xConnection
, rTableName
);
1922 uno::Reference
<XNameAccess
> xCols
= xColsSupp
->getColumns();
1923 if(xCols
->hasByName(rColNm
))
1925 Any aCol
= xCols
->getByName(rColNm
);
1926 uno::Reference
<XPropertySet
> xCol
;
1928 Any aType
= xCol
->getPropertyValue(C2S("Type"));
1932 ::comphelper::disposeComponent( xColsSupp
);
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
&) {}
1960 /* -----------------------------03.07.00 17:12--------------------------------
1962 ---------------------------------------------------------------------------*/
1963 uno::Reference
< sdbcx::XColumnsSupplier
> SwNewDBMgr::GetColumnSupplier(uno::Reference
<sdbc::XConnection
> xConnection
,
1964 const String
& rTableOrQuery
,
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
);
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
));
2002 xRet
= Reference
<XColumnsSupplier
>( xRowSet
, UNO_QUERY
);
2004 catch( const uno::Exception
& )
2006 DBG_ERROR("Exception in SwDBMgr::GetColumnSupplier");
2011 /* -----------------------------05.07.00 13:44--------------------------------
2013 ---------------------------------------------------------------------------*/
2014 String
SwNewDBMgr::GetDBField(uno::Reference
<XPropertySet
> xColumnProps
,
2015 const SwDBFormatData
& rDBFormatData
,
2018 uno::Reference
< XColumn
> xColumn(xColumnProps
, UNO_QUERY
);
2020 DBG_ASSERT(xColumn
.is(), "SwNewDBMgr::::ImportDBField: illegal arguments");
2024 Any aType
= xColumnProps
->getPropertyValue(C2U("Type"));
2025 sal_Int32 eDataType
= 0;
2026 aType
>>= eDataType
;
2029 case DataType::CHAR
:
2030 case DataType::VARCHAR
:
2031 case DataType::LONGVARCHAR
:
2034 sRet
= xColumn
->getString();
2036 catch( SQLException
& )
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(
2063 rDBFormatData
.xFormatter
,
2064 rDBFormatData
.aLocale
,
2065 rDBFormatData
.aNullDate
);
2068 double fVal
= xColumn
->getDouble();
2069 if(!xColumn
->wasNull())
2077 DBG_ERROR("exception caught");
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:
2099 // SFX_ITEMSET_GET(*pCol, pFormatItem, SfxUInt32Item, SBA_DEF_FMTVALUE, sal_True);
2100 // *pFormat = pFormatItem->GetValue();
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");
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
)
2133 aData
.sDataSource
= rDataSource
;
2134 aData
.sCommand
= rTableOrQuery
;
2135 aData
.nCommandType
= -1;
2136 SwDSParam
* pFound
= FindDSData(aData
, FALSE
);
2137 return (pFound
&& pFound
->xResultSet
.is());
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
,
2147 String
& rResult
, double* pNumber
)
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
;
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
))
2182 if(pFound
&& pFound
->xResultSet
.is() && !pFound
->bAfterSelection
)
2184 sal_Int32 nOldRow
= 0;
2187 nOldRow
= pFound
->xResultSet
->getRow();
2189 catch(const Exception
& )
2193 //position to the desired index
2195 if ( nOldRow
!= static_cast<sal_Int32
>(nAbsRecordId
) )
2196 bMove
= lcl_MoveAbsolute(pFound
, nAbsRecordId
);
2199 bRet
= lcl_GetColumnCnt(pFound
, rColumnName
, nLanguage
, rResult
, pNumber
);
2201 if ( nOldRow
!= static_cast<sal_Int32
>(nAbsRecordId
) )
2202 bMove
= lcl_MoveAbsolute(pFound
, nOldRow
);
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
)
2218 BOOL bRet
= lcl_GetColumnCnt(pImpl
->pMergeData
, rColumnName
, nLanguage
, rResult
, pNumber
);
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
;
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
)
2256 if(!pParam
|| !pParam
->xResultSet
.is() || pParam
->bEndOfDB
||
2257 (pParam
->aSelection
.getLength() && pParam
->aSelection
.getLength() <= pParam
->nSelectionIndex
))
2260 pParam
->CheckEndOfDB();
2265 if(pParam
->aSelection
.getLength())
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
;
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
;
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())
2316 nRet
= pImpl
->pMergeData
->xResultSet
->getRow();
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)
2331 sal_Bool bRet
= FALSE
;
2332 sal_Int32 nAbsPos
= nSet
;
2336 bRet
= lcl_MoveAbsolute(pImpl
->pMergeData
, nAbsPos
);
2337 pImpl
->pMergeData
->bEndOfDB
= !bRet
;
2338 pImpl
->pMergeData
->CheckEndOfDB();
2343 /* -----------------------------17.07.00 14:17--------------------------------
2345 ---------------------------------------------------------------------------*/
2346 BOOL
SwNewDBMgr::OpenDataSource(const String
& rDataSource
, const String
& rTableOrQuery
,
2347 sal_Int32 nCommandType
, bool bCreate
)
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())
2358 SwDSParam
* pParam
= FindDSConnection(rDataSource
, FALSE
);
2359 uno::Reference
< XConnection
> xConnection
;
2360 if(pParam
&& pParam
->xConnection
.is())
2361 pFound
->xConnection
= pParam
->xConnection
;
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
);
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
;
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
);
2420 xComponent
->addEventListener(pImpl
->xDisposeListener
);
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();
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
;
2461 nRet
= pFound
->xResultSet
->getRow();
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();
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
;
2530 pFound
= new SwDSParam(rData
);
2531 aDataSourceParams
.Insert(pFound
, aDataSourceParams
.Count());
2534 uno::Reference
<XComponent
> xComponent(pFound
->xConnection
, UNO_QUERY
);
2536 xComponent
->addEventListener(pImpl
->xDisposeListener
);
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
)
2566 if(bCreate
&& !pFound
)
2569 aData
.sDataSource
= rDataSource
;
2570 pFound
= new SwDSParam(aData
);
2571 aDataSourceParams
.Insert(pFound
, aDataSourceParams
.Count());
2574 uno::Reference
<XComponent
> xComponent(pFound
->xConnection
, UNO_QUERY
);
2576 xComponent
->addEventListener(pImpl
->xDisposeListener
);
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() );
2601 uno::Reference
<XInterface
> xInstance
= xMgr
->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
2602 xDBContext
= uno::Reference
<XNameAccess
>(xInstance
, UNO_QUERY
) ;
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
));
2632 String
sFilterMDB(SW_RES(STR_FILTER_MDB
));
2633 String
sFilterACCDB(SW_RES(STR_FILTER_ACCDB
));
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") );
2645 xFltMgr
->appendFilter( sFilterMDB
, C2U("*.mdb") );
2646 xFltMgr
->appendFilter( sFilterACCDB
, C2U("*.accdb") );
2649 xFltMgr
->setCurrentFilter( sFilterAll
) ;
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() );
2659 Any aTableFilterAny
;
2660 Any aSuppressVersionsAny
;
2662 INetURLObject
aTempURL(aURL
);
2664 if(sExt
.EqualsAscii("odb"))
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
);
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
);
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
);
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
;
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();
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();
2718 aSuppressVersionsAny
<<= makeAny(true);
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(),
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
2737 sal_Int32 nIndex
= 0;
2738 while(xDBContext
->hasByName(sFind
))
2741 sFind
+= String::CreateFromInt32(++nIndex
);
2744 Reference
<XInterface
> xNewInstance
;
2748 Any aDataSource
= xDBContext
->getByName(aTempURL
.GetMainURL(INetURLObject::NO_DECODE
));
2749 aDataSource
>>= xNewInstance
;
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
),
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");
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
);
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
)
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");
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
,
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();
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
)
2883 if( xDocShell
->GetError() )
2886 ErrorHandler::HandleError( xDocShell
->GetError() );
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
);
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
2931 aDescriptor
[daCursor
] <<= xResSet
;
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
);
2946 catch(const RuntimeException
& )
2948 //may be disposed already since multiple entries may have used the same connection
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");
2996 uno::Reference
< XMultiServiceFactory
> xMgr( ::comphelper::getProcessServiceFactory() );
2997 uno::Reference
<XDataSource
> xSource
;
2998 uno::Reference
<XChild
> xChild(xConnection
, UNO_QUERY
);
3000 xSource
= uno::Reference
<XDataSource
>(xChild
->getParent(), UNO_QUERY
);
3002 xSource
= SwNewDBMgr::GetDbtoolsClient().getDataSource(sDataSource
, xMgr
);
3003 uno::Reference
< XColumnsSupplier
> xColSupp( xResSet
, UNO_QUERY
);
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(),
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
);
3029 DBG_ERROR("exception caught");
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
;
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
);
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");
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() );
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
);
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!");
3116 /*-- 13.05.2004 16:14:15---------------------------------------------------
3117 merge all data into one resulting document and return the number of
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())
3130 pImpl
->pMergeData
= new SwDSParam(
3131 rMMConfig
.GetCurrentDBData(), xResultSet
, rMMConfig
.GetSelection());
3134 //set to start position
3135 if(pImpl
->pMergeData
->aSelection
.getLength())
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
;
3146 pImpl
->pMergeData
->bEndOfDB
= !pImpl
->pMergeData
->xResultSet
->first();
3147 pImpl
->pMergeData
->CheckEndOfDB();
3152 pImpl
->pMergeData
->bEndOfDB
= TRUE
;
3153 pImpl
->pMergeData
->CheckEndOfDB();
3154 DBG_ERROR("exception in MergeNew()");
3157 //bCancel is set from the PrintMonitor
3160 CreateMonitor
aMonitorDlg(&rSourceView
.GetEditWin());
3161 aMonitorDlg
.SetCancelHdl(LINK(this, SwNewDBMgr
, PrtCancelHdl
));
3162 if (!IsMergeSilent())
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();
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
;
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
;
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();
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.
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())
3258 // #i69485# lock fields to prevent access to the result set while calculating layout
3259 rWorkShell
.LockExpFlds();
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
);
3305 pTargetShell
->InsertPageBreak( &sModifiedStartingPageDesc
, nStartingPageNo
);
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
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
);
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());
3350 nEndRow
= pImpl
->pMergeData
->xResultSet
->getRow();
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();
3369 DBG_ERROR("exception caught in SwNewDBMgr::MergeDocuments");
3371 DELETEZ(pImpl
->pMergeData
);
3375 /* -----------------09.12.2002 12:38-----------------
3377 * --------------------------------------------------*/
3378 SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwNewDBMgr
& 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);