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: unomailmerge.cxx,v $
10 * $Revision: 1.26.206.1 $
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"
35 #include <vcl/svapp.hxx>
36 #include <vos/mutex.hxx>
37 #include <osl/mutex.hxx>
38 #include <svtools/itemprop.hxx>
39 #include <svtools/urihelper.hxx>
40 #include <svx/dataaccessdescriptor.hxx>
41 #include <tools/shl.hxx> // GetAppData
42 #include <tools/tempfile.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <sfx2/docfilt.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <vcl/timer.hxx>
48 #include <com/sun/star/sdb/CommandType.hpp>
49 #include <com/sun/star/text/MailMergeType.hpp>
50 #include <com/sun/star/text/MailMergeEvent.hpp>
51 #include <com/sun/star/text/XMailMergeListener.hpp>
52 #include <com/sun/star/text/XMailMergeBroadcaster.hpp>
53 #include <com/sun/star/beans/PropertyAttribute.hpp>
54 #include <com/sun/star/lang/XUnoTunnel.hpp>
55 #include <com/sun/star/sdbc/XResultSet.hpp>
56 #include <com/sun/star/sdbc/XConnection.hpp>
57 #include <com/sun/star/sdbc/XRowSet.hpp>
58 #include <com/sun/star/frame/XComponentLoader.hpp>
59 #include <com/sun/star/util/XCloseable.hpp>
60 #ifndef _COM_SUN_STAR_UTIL_CloseVetoException_HPP_
61 #include <com/sun/star/util/CloseVetoException.hpp>
63 #include <com/sun/star/sdbcx/XRowLocate.hpp>
64 #include <com/sun/star/frame/XStorable.hpp>
65 #include "com/sun/star/mail/XSmtpService.hpp"
66 #include <sfx2/viewfrm.hxx>
67 #include <sfx2/event.hxx>
68 #include <swevent.hxx>
69 #include <unomailmerge.hxx>
71 #include <swmodule.hxx>
72 #include <unoprnms.hxx>
74 #include <swunohelper.hxx>
76 #ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
77 #include <IDocumentDeviceAccess.hxx>
81 #include <unotxdoc.hxx>
84 #include <shellio.hxx>
85 #include <mmconfigitem.hxx>
86 #include <mailmergehelper.hxx>
92 #define SN_MAIL_MERGE "com.sun.star.text.MailMerge"
93 #define SN_DATA_ACCESS_DESCRIPTOR "com.sun.star.sdb.DataAccessDescriptor"
95 using namespace ::com::sun::star
;
96 using namespace ::com::sun::star::frame
;
97 using namespace ::com::sun::star::uno
;
98 using namespace ::com::sun::star::lang
;
99 using namespace ::com::sun::star::beans
;
100 using namespace ::com::sun::star::text
;
101 using ::rtl::OUString
;
102 using namespace SWUnoHelper
;
104 ////////////////////////////////////////////////////////////
106 typedef ::utl::SharedUNOComponent
< XInterface
> SharedComponent
;
108 ////////////////////////////////////////////////////////////
110 osl::Mutex
& GetMailMergeMutex()
112 static osl::Mutex aMutex
;
116 ////////////////////////////////////////////////////////////
120 eSuccess
, // successfully closed
121 eVetoed
, // vetoed, ownership transfered to the vetoing instance
122 eFailed
// failed for some unknown reason
124 static CloseResult
CloseModelAndDocSh(
125 Reference
< frame::XModel
> &rxModel
,
126 SfxObjectShellRef
&rxDocSh
)
128 CloseResult eResult
= eSuccess
;
132 //! models/documents should never be disposed (they may still be
133 //! used for printing which is called asynchronously for example)
134 //! instead call close
135 Reference
< util::XCloseable
> xClose( rxModel
, UNO_QUERY
);
140 //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
141 //! I.e. now that object is responsible for closing the model and doc shell.
142 xClose
->close( sal_True
);
144 catch (util::CloseVetoException
&)
146 //! here we have the problem that the temporary file that is
147 //! currently being printed will never be deleted. :-(
150 catch ( const uno::RuntimeException
& )
158 ////////////////////////////////////////////////////////////
160 static BOOL
LoadFromURL_impl(
161 Reference
< frame::XModel
> &rxModel
,
162 SfxObjectShellRef
&rxDocSh
,
165 throw (RuntimeException
)
167 // try to open the document readonly and hidden
168 Reference
< frame::XModel
> xTmpModel
;
169 Sequence
< PropertyValue
> aArgs( 1 );
170 aArgs
[0].Name
= C2U("Hidden");
171 sal_Bool bVal
= sal_True
;
172 aArgs
[0].Value
<<= bVal
;
175 Reference
< XComponentLoader
> xDesktop( ::comphelper::getProcessServiceFactory()->
176 createInstance( C2U("com.sun.star.frame.Desktop") ), UNO_QUERY
);
177 xTmpModel
= Reference
< XModel
>( xDesktop
->loadComponentFromURL(
178 rURL
, C2U("_blank"), 0, aArgs
), UNO_QUERY
);
185 // try to get the DocShell
186 SwDocShell
*pTmpDocShell
= 0;
187 Reference
< XUnoTunnel
> xTunnel( xTmpModel
, UNO_QUERY
);
190 SwXTextDocument
* pTextDoc
= reinterpret_cast<SwXTextDocument
*>(
191 xTunnel
->getSomething( SwXTextDocument::getUnoTunnelId() ));
192 pTmpDocShell
= pTextDoc
? pTextDoc
->GetDocShell() : 0;
196 if (xTmpModel
.is() && pTmpDocShell
) // everything available?
199 CloseModelAndDocSh( rxModel
, rxDocSh
);
202 rxDocSh
= pTmpDocShell
;
207 SfxObjectShellRef xTmpDocSh
= pTmpDocShell
;
208 CloseModelAndDocSh( xTmpModel
, xTmpDocSh
);
214 //==========================================================
217 class DelayedFileDeletion
: public ::cppu::WeakImplHelper1
< util::XCloseListener
>
220 ::osl::Mutex m_aMutex
;
221 Reference
< util::XCloseable
> m_xDocument
;
222 Timer m_aDeleteTimer
;
223 String m_sTemporaryFile
;
224 sal_Int32 m_nPendingDeleteAttempts
;
227 DelayedFileDeletion( const Reference
< XModel
>& _rxModel
,
228 const String
& _rTemporaryFile
);
231 ~DelayedFileDeletion( );
234 virtual void SAL_CALL
queryClosing( const EventObject
& _rSource
, sal_Bool _bGetsOwnership
) throw (util::CloseVetoException
, RuntimeException
);
235 virtual void SAL_CALL
notifyClosing( const EventObject
& _rSource
) throw (RuntimeException
);
238 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
241 void implTakeOwnership( );
242 DECL_LINK( OnTryDeleteFile
, void* );
245 DelayedFileDeletion( const DelayedFileDeletion
& ); // never implemented
246 DelayedFileDeletion
& operator=( const DelayedFileDeletion
& ); // never implemented
249 DBG_NAME( DelayedFileDeletion
)
250 //------------------------------------------------------
251 DelayedFileDeletion::DelayedFileDeletion( const Reference
< XModel
>& _rxModel
, const String
& _rTemporaryFile
)
253 m_xDocument( _rxModel
, UNO_QUERY
)
254 ,m_sTemporaryFile( _rTemporaryFile
)
255 ,m_nPendingDeleteAttempts( 0 )
257 DBG_CTOR( DelayedFileDeletion
, NULL
);
259 osl_incrementInterlockedCount( &m_refCount
);
262 if ( m_xDocument
.is() )
264 m_xDocument
->addCloseListener( this );
265 // successfully added -> keep ourself alive
269 DBG_ERROR( "DelayedFileDeletion::DelayedFileDeletion: model is no component!" );
272 catch( const Exception
& )
274 DBG_ERROR( "DelayedFileDeletion::DelayedFileDeletion: could not register as event listener at the model!" );
276 osl_decrementInterlockedCount( &m_refCount
);
279 //--------------------------------------------------------------------
280 IMPL_LINK( DelayedFileDeletion
, OnTryDeleteFile
, void*, EMPTYARG
)
282 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
284 sal_Bool bSuccess
= sal_False
;
287 sal_Bool bDeliverOwnership
= ( 0 == m_nPendingDeleteAttempts
);
288 // if this is our last attemt, then anybody which vetoes this has to take the consequences
289 // (means take the ownership)
290 m_xDocument
->close( bDeliverOwnership
);
293 catch( const util::CloseVetoException
& )
295 // somebody vetoed -> next try
296 if ( m_nPendingDeleteAttempts
)
299 --m_nPendingDeleteAttempts
;
300 m_aDeleteTimer
.Start();
303 bSuccess
= sal_True
; // can't do anything here ...
305 catch( const Exception
& )
307 DBG_ERROR( "DelayedFileDeletion::OnTryDeleteFile: caught a strange exception!" );
309 // can't do anything here ...
314 SWUnoHelper::UCB_DeleteFile( m_sTemporaryFile
);
316 release(); // this should be our last reference, we should be dead after this
321 //--------------------------------------------------------------------
322 void DelayedFileDeletion::implTakeOwnership( )
324 // revoke ourself as listener
327 m_xDocument
->removeCloseListener( this );
329 catch( const Exception
& )
331 DBG_ERROR( "DelayedFileDeletion::implTakeOwnership: could not revoke the listener!" );
334 m_aDeleteTimer
.SetTimeout( 3000 ); // 3 seconds
335 m_aDeleteTimer
.SetTimeoutHdl( LINK( this, DelayedFileDeletion
, OnTryDeleteFile
) );
336 m_nPendingDeleteAttempts
= 3; // try 3 times at most
337 m_aDeleteTimer
.Start( );
340 //--------------------------------------------------------------------
341 void SAL_CALL
DelayedFileDeletion::queryClosing( const EventObject
& , sal_Bool _bGetsOwnership
) throw (util::CloseVetoException
, RuntimeException
)
343 ::osl::MutexGuard
aGuard( m_aMutex
);
344 if ( _bGetsOwnership
)
345 implTakeOwnership( );
347 // always veto: We want to take the ownership ourself, as this is the only chance to delete
348 // the temporary file which the model is based on
349 throw util::CloseVetoException( );
352 //--------------------------------------------------------------------
353 void SAL_CALL
DelayedFileDeletion::notifyClosing( const EventObject
& ) throw (RuntimeException
)
355 DBG_ERROR( "DelayedFileDeletion::notifyClosing: how this?" );
356 // this should not happen:
357 // Either, a foreign instance closes the document, then we should veto this, and take the ownership
358 // Or, we ourself close the document, then we should not be a listener anymore
361 //------------------------------------------------------
362 void SAL_CALL
DelayedFileDeletion::disposing( const EventObject
& ) throw (RuntimeException
)
364 DBG_ERROR( "DelayedFileDeletion::disposing: how this?" );
365 // this should not happen:
366 // Either, a foreign instance closes the document, then we should veto this, and take the ownership
367 // Or, we ourself close the document, then we should not be a listener anymore
370 //------------------------------------------------------
371 DelayedFileDeletion::~DelayedFileDeletion( )
373 DBG_DTOR( DelayedFileDeletion
, NULL
);
377 ////////////////////////////////////////////////////////////
379 static BOOL
DeleteTmpFile_Impl(
380 Reference
< frame::XModel
> &rxModel
,
381 SfxObjectShellRef
&rxDocSh
,
382 const String
&rTmpFileURL
)
385 if (rTmpFileURL
.Len())
388 if ( eVetoed
== CloseModelAndDocSh( rxModel
, rxDocSh
) )
390 // somebody vetoed the closing, and took the ownership of the document
391 // -> ensure that the temporary file is deleted later on
392 Reference
< XEventListener
> xEnsureDelete( new DelayedFileDeletion( rxModel
, rTmpFileURL
) );
393 // note: as soon as #106931# is fixed, the whole DelayedFileDeletion is to be superseeded by
399 rxDocSh
= 0; // destroy doc shell
403 if ( !SWUnoHelper::UCB_DeleteFile( rTmpFileURL
) )
405 Reference
< XEventListener
> xEnsureDelete( new DelayedFileDeletion( rxModel
, rTmpFileURL
) );
406 // same not as above: as soon as #106931#, ...
410 bRes
= TRUE
; // file will be deleted delayed
415 ////////////////////////////////////////////////////////////
417 SwXMailMerge::SwXMailMerge() :
418 aEvtListeners ( GetMailMergeMutex() ),
419 aMergeListeners ( GetMailMergeMutex() ),
420 aPropListeners ( GetMailMergeMutex() ),
421 pPropSet( aSwMapProvider
.GetPropertySet( PROPERTY_MAP_MAILMERGE
) ),
422 bSendAsHTML(sal_False
),
423 bSendAsAttachment(sal_False
),
424 bSaveAsSingleFile(sal_False
)
427 // create empty document
428 // like in: SwModule::InsertEnv (appenv.cxx)
429 SwDocShell
*pDocShell
= new SwDocShell( SFX_CREATE_MODE_STANDARD
);
431 xDocSh
->DoInitNew( 0 );
432 SfxViewFrame
*pFrame
= SfxViewFrame::CreateViewFrame( *xDocSh
, 0, TRUE
);
433 SwView
*pView
= (SwView
*) pFrame
->GetViewShell();
434 pView
->AttrChangedNotify( &pView
->GetWrtShell() );//Damit SelectShell gerufen wird.
436 xModel
= pDocShell
->GetModel();
438 nDataCommandType
= sdb::CommandType::TABLE
;
439 nOutputType
= MailMergeType::PRINTER
;
440 bEscapeProcessing
= sal_True
; //!! allow to process properties like "Filter", "Order", ...
441 bSinglePrintJobs
= sal_False
;
442 bFileNameFromColumn
= sal_False
;
444 bDisposing
= sal_False
;
447 SwXMailMerge::~SwXMailMerge()
449 if (aTmpFileName
.Len())
450 DeleteTmpFile_Impl( xModel
, xDocSh
, aTmpFileName
);
451 else // there was no temporary file in use
453 //! we still need to close the model and doc shell manually
454 //! because there is no automatism that will do that later.
456 if ( eVetoed
== CloseModelAndDocSh( xModel
, xDocSh
) )
457 DBG_WARNING( "owner ship transfered to vetoing object!" );
460 xDocSh
= 0; // destroy doc shell
464 uno::Any SAL_CALL
SwXMailMerge::execute(
465 const uno::Sequence
< beans::NamedValue
>& rArguments
)
466 throw (IllegalArgumentException
, Exception
, RuntimeException
)
468 vos::OGuard
aGuard( Application::GetSolarMutex() );
471 // get property values to be used
472 // (use values from the service as default and override them with
473 // the values that are provided as arguments)
475 uno::Sequence
< uno::Any
> aCurSelection
= aSelection
;
476 uno::Reference
< sdbc::XResultSet
> xCurResultSet
= xResultSet
;
477 uno::Reference
< sdbc::XConnection
> xCurConnection
= xConnection
;
478 uno::Reference
< frame::XModel
> xCurModel
= xModel
;
479 OUString aCurDataSourceName
= aDataSourceName
;
480 OUString aCurDataCommand
= aDataCommand
;
481 OUString aCurFilter
= aFilter
;
482 OUString aCurDocumentURL
= aDocumentURL
;
483 OUString aCurOutputURL
= aOutputURL
;
484 OUString aCurFileNamePrefix
= aFileNamePrefix
;
485 sal_Int32 nCurDataCommandType
= nDataCommandType
;
486 sal_Int16 nCurOutputType
= nOutputType
;
487 sal_Bool bCurEscapeProcessing
= bEscapeProcessing
;
488 sal_Bool bCurSinglePrintJobs
= bSinglePrintJobs
;
489 sal_Bool bCurFileNameFromColumn
= bFileNameFromColumn
;
491 SfxObjectShellRef xCurDocSh
= xDocSh
; // the document
493 const beans::NamedValue
*pArguments
= rArguments
.getConstArray();
494 sal_Int32 nArgs
= rArguments
.getLength();
495 for (sal_Int32 i
= 0; i
< nArgs
; ++i
)
497 const OUString
&rName
= pArguments
[i
].Name
;
498 const Any
&rValue
= pArguments
[i
].Value
;
501 if (rName
.equalsAscii( GetPropName( UNO_NAME_SELECTION
) ))
502 bOK
= rValue
>>= aCurSelection
;
503 else if (rName
.equalsAscii( GetPropName( UNO_NAME_RESULT_SET
) ))
504 bOK
= rValue
>>= xCurResultSet
;
505 else if (rName
.equalsAscii( GetPropName( UNO_NAME_CONNECTION
) ))
506 bOK
= rValue
>>= xCurConnection
;
507 else if (rName
.equalsAscii( GetPropName( UNO_NAME_MODEL
) ))
508 throw PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rName
, static_cast < cppu::OWeakObject
* > ( this ) );
509 else if (rName
.equalsAscii( GetPropName( UNO_NAME_DATA_SOURCE_NAME
) ))
510 bOK
= rValue
>>= aCurDataSourceName
;
511 else if (rName
.equalsAscii( GetPropName( UNO_NAME_DAD_COMMAND
) ))
512 bOK
= rValue
>>= aCurDataCommand
;
513 else if (rName
.equalsAscii( GetPropName( UNO_NAME_FILTER
) ))
514 bOK
= rValue
>>= aCurFilter
;
515 else if (rName
.equalsAscii( GetPropName( UNO_NAME_DOCUMENT_URL
) ))
517 bOK
= rValue
>>= aCurDocumentURL
;
518 if (aCurDocumentURL
.getLength()
519 && !LoadFromURL_impl( xCurModel
, xCurDocSh
, aCurDocumentURL
, FALSE
))
520 throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to create document from URL: " ) ) + aCurDocumentURL
, static_cast < cppu::OWeakObject
* > ( this ) );
522 else if (rName
.equalsAscii( GetPropName( UNO_NAME_OUTPUT_URL
) ))
524 bOK
= rValue
>>= aCurOutputURL
;
525 if (aCurOutputURL
.getLength())
527 if (!UCB_IsDirectory(aCurOutputURL
))
528 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL does not point to a directory: " ) ) + aCurOutputURL
, static_cast < cppu::OWeakObject
* > ( this ), 0 );
529 if (UCB_IsReadOnlyFileName(aCurOutputURL
))
530 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL is read-only: " ) ) + aCurOutputURL
, static_cast < cppu::OWeakObject
* > ( this ), 0 );
533 else if (rName
.equalsAscii( GetPropName( UNO_NAME_FILE_NAME_PREFIX
) ))
534 bOK
= rValue
>>= aCurFileNamePrefix
;
535 else if (rName
.equalsAscii( GetPropName( UNO_NAME_DAD_COMMAND_TYPE
) ))
536 bOK
= rValue
>>= nCurDataCommandType
;
537 else if (rName
.equalsAscii( GetPropName( UNO_NAME_OUTPUT_TYPE
) ))
538 bOK
= rValue
>>= nCurOutputType
;
539 else if (rName
.equalsAscii( GetPropName( UNO_NAME_ESCAPE_PROCESSING
) ))
540 bOK
= rValue
>>= bCurEscapeProcessing
;
541 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SINGLE_PRINT_JOBS
) ))
542 bOK
= rValue
>>= bCurSinglePrintJobs
;
543 else if (rName
.equalsAscii( GetPropName( UNO_NAME_FILE_NAME_FROM_COLUMN
) ))
544 bOK
= rValue
>>= bCurFileNameFromColumn
;
545 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SUBJECT
) ))
546 bOK
= rValue
>>= sSubject
;
547 else if (rName
.equalsAscii( GetPropName( UNO_NAME_ADDRESS_FROM_COLUMN
) ))
548 bOK
= rValue
>>= sAddressFromColumn
;
549 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SEND_AS_HTML
) ))
550 bOK
= rValue
>>= bSendAsHTML
;
551 else if (rName
.equalsAscii( GetPropName( UNO_NAME_MAIL_BODY
) ))
552 bOK
= rValue
>>= sMailBody
;
553 else if (rName
.equalsAscii( GetPropName( UNO_NAME_ATTACHMENT_NAME
) ))
554 bOK
= rValue
>>= sAttachmentName
;
555 else if (rName
.equalsAscii( GetPropName( UNO_NAME_ATTACHMENT_FILTER
) ))
556 bOK
= rValue
>>= sAttachmentFilter
;
557 else if (rName
.equalsAscii( GetPropName( UNO_NAME_COPIES_TO
) ))
558 bOK
= rValue
>>= aCopiesTo
;
559 else if (rName
.equalsAscii( GetPropName( UNO_NAME_BLIND_COPIES_TO
) ))
560 bOK
= rValue
>>= aBlindCopiesTo
;
561 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SEND_AS_ATTACHMENT
) ))
562 bOK
= rValue
>>= bSendAsAttachment
;
563 else if (rName
.equalsAscii( GetPropName( UNO_NAME_PRINT_OPTIONS
) ))
564 bOK
= rValue
>>= aPrintSettings
;
565 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SAVE_AS_SINGLE_FILE
) ))
566 bOK
= rValue
>>= bSaveAsSingleFile
;
567 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER
) ))
568 bOK
= rValue
>>= sSaveFilter
;
569 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER_OPTIONS
) ))
570 bOK
= rValue
>>= sSaveFilterOptions
;
571 else if (rName
.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER_DATA
) ))
572 bOK
= rValue
>>= aSaveFilterData
;
573 else if (rName
.equalsAscii( GetPropName( UNO_NAME_IN_SERVER_PASSWORD
) ))
574 bOK
= rValue
>>= sInServerPassword
;
575 else if (rName
.equalsAscii( GetPropName( UNO_NAME_OUT_SERVER_PASSWORD
) ))
576 bOK
= rValue
>>= sOutServerPassword
;
578 throw UnknownPropertyException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is unknown: " ) ) + rName
, static_cast < cppu::OWeakObject
* > ( this ) );
581 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property type mismatch or property not set: " ) ) + rName
, static_cast < cppu::OWeakObject
* > ( this ), 0 );
584 // need to translate the selection: the API here requires a sequence of bookmarks, but the MergeNew
585 // method we will call below requires a sequence of indicies.
586 if ( aCurSelection
.getLength() )
588 Sequence
< Any
> aTranslated( aCurSelection
.getLength() );
590 sal_Bool bValid
= sal_False
;
591 Reference
< sdbcx::XRowLocate
> xRowLocate( xCurResultSet
, UNO_QUERY
);
592 if ( xRowLocate
.is() )
595 const Any
* pBookmarks
= aCurSelection
.getConstArray();
596 const Any
* pBookmarksEnd
= pBookmarks
+ aCurSelection
.getLength();
597 Any
* pTranslated
= aTranslated
.getArray();
601 sal_Bool bEverythingsFine
= sal_True
;
602 for ( ; ( pBookmarks
!= pBookmarksEnd
) && bEverythingsFine
; ++pBookmarks
)
604 if ( xRowLocate
->moveToBookmark( *pBookmarks
) )
605 *pTranslated
<<= xCurResultSet
->getRow();
607 bEverythingsFine
= sal_False
;
609 if ( bEverythingsFine
)
612 catch( const Exception
& )
620 throw IllegalArgumentException(
621 OUString ( RTL_CONSTASCII_USTRINGPARAM ( "The current 'Selection' does not describe a valid array of bookmarks, relative to the current 'ResultSet'." ) ),
622 static_cast < cppu::OWeakObject
* > ( this ),
627 aCurSelection
= aTranslated
;
630 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( xCurDocSh
, 0, FALSE
);
631 SwView
*pView
= PTR_CAST( SwView
, pFrame
->GetViewShell() );
633 throw RuntimeException();
634 SwWrtShell
&rSh
= *pView
->GetWrtShellPtr();
636 // avoid assertion in 'Update' from Sfx by supplying a shell
637 // and thus avoiding the SelectShell call in Writers GetState function
638 // while still in Update of Sfx.
639 // (GetSelection in Update is not allowed)
640 if (pView
&& aCurDocumentURL
.getLength())
641 pView
->AttrChangedNotify( &pView
->GetWrtShell() );//Damit SelectShell gerufen wird.
643 SharedComponent aRowSetDisposeHelper
;
644 if (!xCurResultSet
.is())
646 if (!aCurDataSourceName
.getLength() || !aCurDataCommand
.getLength() )
648 DBG_ERROR("PropertyValues missing or unset");
649 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Either the ResultSet or DataSourceName and DataCommand must be set." ) ), static_cast < cppu::OWeakObject
* > ( this ), 0 );
653 // build ResultSet from DataSourceName, DataCommand and DataCommandType
655 Reference
< XMultiServiceFactory
> xMgr( ::comphelper::getProcessServiceFactory() );
658 Reference
< XInterface
> xInstance
= xMgr
->createInstance(
659 C2U( "com.sun.star.sdb.RowSet" ));
660 aRowSetDisposeHelper
.reset( xInstance
, SharedComponent::TakeOwnership
);
661 Reference
< XPropertySet
> xRowSetPropSet( xInstance
, UNO_QUERY
);
662 DBG_ASSERT( xRowSetPropSet
.is(), "failed to get XPropertySet interface from RowSet" );
663 if (xRowSetPropSet
.is())
665 if (xCurConnection
.is())
666 xRowSetPropSet
->setPropertyValue( C2U("ActiveConnection"), makeAny( xCurConnection
) );
667 xRowSetPropSet
->setPropertyValue( C2U("DataSourceName"), makeAny( aCurDataSourceName
) );
668 xRowSetPropSet
->setPropertyValue( C2U("Command"), makeAny( aCurDataCommand
) );
669 xRowSetPropSet
->setPropertyValue( C2U("CommandType"), makeAny( nCurDataCommandType
) );
670 xRowSetPropSet
->setPropertyValue( C2U("EscapeProcessing"), makeAny( bCurEscapeProcessing
) );
671 xRowSetPropSet
->setPropertyValue( C2U("ApplyFilter"), makeAny( sal_True
) );
672 xRowSetPropSet
->setPropertyValue( C2U("Filter"), makeAny( aCurFilter
) );
674 Reference
< sdbc::XRowSet
> xRowSet( xInstance
, UNO_QUERY
);
676 xRowSet
->execute(); // build ResultSet from properties
677 if( !xCurConnection
.is() )
678 xCurConnection
.set( xRowSetPropSet
->getPropertyValue( C2U( "ActiveConnection" )), UNO_QUERY
);
679 xCurResultSet
= Reference
< sdbc::XResultSet
>( xRowSet
, UNO_QUERY
);
680 DBG_ASSERT( xCurResultSet
.is(), "failed to build ResultSet" );
685 svx::ODataAccessDescriptor aDescriptor
;
686 aDescriptor
.setDataSource(aCurDataSourceName
);
687 aDescriptor
[ svx::daConnection
] <<= xCurConnection
;
688 aDescriptor
[ svx::daCommand
] <<= aCurDataCommand
;
689 aDescriptor
[ svx::daCommandType
] <<= nCurDataCommandType
;
690 aDescriptor
[ svx::daEscapeProcessing
] <<= bCurEscapeProcessing
;
691 aDescriptor
[ svx::daCursor
] <<= xCurResultSet
;
692 // aDescriptor[ svx::daColumnName ] not used
693 // aDescriptor[ svx::daColumnObject ] not used
694 aDescriptor
[ svx::daSelection
] <<= aCurSelection
;
697 switch (nCurOutputType
)
699 case MailMergeType::PRINTER
: nMergeType
= DBMGR_MERGE_MAILMERGE
; break;
700 case MailMergeType::FILE : nMergeType
= DBMGR_MERGE_MAILFILES
; break;
701 case MailMergeType::MAIL
: nMergeType
= DBMGR_MERGE_MAILING
; break;
703 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Invalid value of property:" ) ) + C2U("OutputType"), static_cast < cppu::OWeakObject
* > ( this ), 0 );
706 SwNewDBMgr
* pMgr
= rSh
.GetNewDBMgr();
707 //force layout creation
709 DBG_ASSERT( pMgr
, "database manager missing" );
711 SwMergeDescriptor
aMergeDesc( nMergeType
, rSh
, aDescriptor
);
713 std::auto_ptr
< SwMailMergeConfigItem
> pMMConfigItem
;
714 uno::Reference
< mail::XMailService
> xInService
;
715 if (MailMergeType::PRINTER
== nCurOutputType
)
717 SwPrintData aPrtData
= *SW_MOD()->GetPrtOptions( FALSE
);
718 IDocumentDeviceAccess
* pIDDA
= rSh
.getIDocumentDeviceAccess();
719 SwPrintData
* pShellPrintData
= pIDDA
->getPrintData();
721 aPrtData
= *pShellPrintData
;
722 aPrtData
.SetPrintSingleJobs( bCurSinglePrintJobs
);
723 pIDDA
->setPrintData( aPrtData
);
724 // #i25686# printing should not be done asynchronously to prevent dangling offices
725 // when mail merge is called as command line macro
726 aMergeDesc
.bPrintAsync
= sal_False
;
727 aMergeDesc
.aPrintOptions
= aPrintSettings
;
729 else /* FILE and MAIL*/
731 INetURLObject aURLObj
;
732 aURLObj
.SetSmartProtocol( INET_PROT_FILE
);
734 if (aCurDocumentURL
.getLength())
736 // if OutputURL or FileNamePrefix are missing get
737 // them from DocumentURL
738 aURLObj
.SetSmartURL( aCurDocumentURL
);
739 if (!aCurFileNamePrefix
.getLength())
740 aCurFileNamePrefix
= aURLObj
.GetBase(); // filename without extension
741 if (!aCurOutputURL
.getLength())
743 //aCurOutputURL = aURLObj.GetURLPath();
744 aURLObj
.removeSegment();
745 aCurOutputURL
= aURLObj
.GetMainURL( INetURLObject::DECODE_TO_IURI
);
748 else // default empty document without URL
750 if (!aCurOutputURL
.getLength())
751 throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "OutputURL is not set and can not be obtained." ) ), static_cast < cppu::OWeakObject
* > ( this ) );
754 aURLObj
.SetSmartURL( aCurOutputURL
);
755 String aPath
= aURLObj
.GetMainURL( INetURLObject::DECODE_TO_IURI
);
757 String
aDelim( INET_PATH_TOKEN
);
758 if (aPath
.Len() >= aDelim
.Len() &&
759 aPath
.Copy( aPath
.Len()-aDelim
.Len() ).CompareTo( aDelim
) != COMPARE_EQUAL
)
761 if (bCurFileNameFromColumn
)
762 pMgr
->SetEMailColumn( aCurFileNamePrefix
);
765 aPath
+= String( aCurFileNamePrefix
);
766 pMgr
->SetEMailColumn( String() );
768 pMgr
->SetSubject( aPath
);
769 if(MailMergeType::FILE == nCurOutputType
)
771 aMergeDesc
.sSaveToFilter
= sSaveFilter
;
772 aMergeDesc
.sSaveToFilterOptions
= sSaveFilterOptions
;
773 aMergeDesc
.aSaveToFilterData
= aSaveFilterData
;
774 aMergeDesc
.bCreateSingleFile
= bSaveAsSingleFile
;
776 else /*if(MailMergeType::MAIL == nCurOutputType)*/
778 pMgr
->SetEMailColumn( sAddressFromColumn
);
779 if(!sAddressFromColumn
.getLength())
780 throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Mail address column not set." ) ), static_cast < cppu::OWeakObject
* > ( this ) );
781 aMergeDesc
.sSaveToFilter
= sAttachmentFilter
;
782 aMergeDesc
.sSubject
= sSubject
;
783 aMergeDesc
.sMailBody
= sMailBody
;
784 aMergeDesc
.sAttachmentName
= sAttachmentName
;
785 aMergeDesc
.aCopiesTo
= aCopiesTo
;
786 aMergeDesc
.aBlindCopiesTo
= aBlindCopiesTo
;
787 aMergeDesc
.bSendAsHTML
= bSendAsHTML
;
788 aMergeDesc
.bSendAsAttachment
= bSendAsAttachment
;
790 aMergeDesc
.bCreateSingleFile
= sal_False
;
791 pMMConfigItem
= std::auto_ptr
< SwMailMergeConfigItem
>(new SwMailMergeConfigItem
);
792 aMergeDesc
.pMailMergeConfigItem
= pMMConfigItem
.get();
793 aMergeDesc
.xSmtpServer
= SwMailMergeHelper::ConnectToSmtpServer(
796 sInServerPassword
, sOutServerPassword
);
797 if( !aMergeDesc
.xSmtpServer
.is() || !aMergeDesc
.xSmtpServer
->isConnected())
798 throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to connect to mail server." ) ), static_cast < cppu::OWeakObject
* > ( this ) );
803 // save document with temporary filename
804 const SfxFilter
*pSfxFlt
= SwIoSystem::GetFilterOfFormat(
805 String::CreateFromAscii( FILTER_XML
),
806 SwDocShell::Factory().GetFilterContainer() );
807 String
aExtension( pSfxFlt
->GetDefaultExtension() );
808 aExtension
.EraseLeadingChars( '*' );
809 TempFile
aTempFile( C2U("SwMM"), &aExtension
);
810 aTmpFileName
= aTempFile
.GetName();
812 Reference
< XStorable
> xStorable( xCurModel
, UNO_QUERY
);
813 sal_Bool bStoredAsTemporary
= sal_False
;
814 if ( xStorable
.is() )
818 xStorable
->storeAsURL( aTmpFileName
, Sequence
< PropertyValue
>() );
819 bStoredAsTemporary
= sal_True
;
821 catch( const Exception
& )
825 if ( !bStoredAsTemporary
)
826 throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to save temporary file." ) ), static_cast < cppu::OWeakObject
* > ( this ) );
828 pMgr
->SetMergeSilent( TRUE
); // suppress dialogs, message boxes, etc.
829 const SwXMailMerge
*pOldSrc
= pMgr
->GetMailMergeEvtSrc();
830 DBG_ASSERT( !pOldSrc
|| pOldSrc
== this, "Ooops... different event source already set." );
831 pMgr
->SetMailMergeEvtSrc( this ); // launch events for listeners
833 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE
, xCurDocSh
));
834 BOOL bSucc
= pMgr
->MergeNew( aMergeDesc
);
835 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END
, xCurDocSh
));
837 pMgr
->SetMailMergeEvtSrc( pOldSrc
);
839 if ( xCurModel
.get() != xModel
.get() )
840 { // in case it was a temporary model -> close it, and delete the file
841 DeleteTmpFile_Impl( xCurModel
, xCurDocSh
, aTmpFileName
);
842 aTmpFileName
.Erase();
844 // (in case it wasn't a temporary model, it will be closed in the dtor, at the latest)
847 throw Exception( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Mail merge failed. Sorry, no further information available." ) ), static_cast < cppu::OWeakObject
* > ( this ) );
849 //de-initialize services
850 if(xInService
.is() && xInService
->isConnected())
851 xInService
->disconnect();
852 if(aMergeDesc
.xSmtpServer
.is() && aMergeDesc
.xSmtpServer
->isConnected())
853 aMergeDesc
.xSmtpServer
->disconnect();
855 return makeAny( sal_True
);
858 void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent
&rEvt
) const
860 cppu::OInterfaceIteratorHelper
aIt( ((SwXMailMerge
*) this)->aMergeListeners
);
861 while (aIt
.hasMoreElements())
863 Reference
< XMailMergeListener
> xRef( aIt
.next(), UNO_QUERY
);
865 xRef
->notifyMailMergeEvent( rEvt
);
869 void SwXMailMerge::launchEvent( const PropertyChangeEvent
&rEvt
) const
871 cppu::OInterfaceContainerHelper
*pContainer
=
872 aPropListeners
.getContainer( rEvt
.PropertyHandle
);
875 cppu::OInterfaceIteratorHelper
aIt( *pContainer
);
876 while (aIt
.hasMoreElements())
878 Reference
< XPropertyChangeListener
> xRef( aIt
.next(), UNO_QUERY
);
880 xRef
->propertyChange( rEvt
);
886 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
SwXMailMerge::getPropertySetInfo( )
887 throw (RuntimeException
)
889 vos::OGuard
aGuard( Application::GetSolarMutex() );
890 static Reference
< XPropertySetInfo
> aRef
= pPropSet
->getPropertySetInfo();
894 void SAL_CALL
SwXMailMerge::setPropertyValue(
895 const OUString
& rPropertyName
, const uno::Any
& rValue
)
896 throw (UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
898 vos::OGuard
aGuard( Application::GetSolarMutex() );
900 const SfxItemPropertySimpleEntry
* pCur
= pPropSet
->getPropertyMap()->getByName( rPropertyName
);
902 throw UnknownPropertyException();
903 else if (pCur
->nFlags
& PropertyAttribute::READONLY
)
904 throw PropertyVetoException();
908 const uno::Type
* pType
= pCur
->pType
;
911 case WID_SELECTION
: pData
= &aSelection
; break;
912 case WID_RESULT_SET
: pData
= &xResultSet
; break;
913 case WID_CONNECTION
: pData
= &xConnection
; break;
914 case WID_MODEL
: pData
= &xModel
; break;
915 case WID_DATA_SOURCE_NAME
: pData
= &aDataSourceName
; break;
916 case WID_DATA_COMMAND
: pData
= &aDataCommand
; break;
917 case WID_FILTER
: pData
= &aFilter
; break;
918 case WID_DOCUMENT_URL
: pData
= &aDocumentURL
; break;
919 case WID_OUTPUT_URL
: pData
= &aOutputURL
; break;
920 case WID_DATA_COMMAND_TYPE
: pData
= &nDataCommandType
; break;
921 case WID_OUTPUT_TYPE
: pData
= &nOutputType
; break;
922 case WID_ESCAPE_PROCESSING
: pData
= &bEscapeProcessing
; break;
923 case WID_SINGLE_PRINT_JOBS
: pData
= &bSinglePrintJobs
; break;
924 case WID_FILE_NAME_FROM_COLUMN
: pData
= &bFileNameFromColumn
; break;
925 case WID_FILE_NAME_PREFIX
: pData
= &aFileNamePrefix
; break;
926 case WID_MAIL_SUBJECT
: pData
= &sSubject
; break;
927 case WID_ADDRESS_FROM_COLUMN
: pData
= &sAddressFromColumn
; break;
928 case WID_SEND_AS_HTML
: pData
= &bSendAsHTML
; break;
929 case WID_SEND_AS_ATTACHMENT
: pData
= &bSendAsAttachment
; break;
930 case WID_MAIL_BODY
: pData
= &sMailBody
; break;
931 case WID_ATTACHMENT_NAME
: pData
= &sAttachmentName
; break;
932 case WID_ATTACHMENT_FILTER
: pData
= &sAttachmentFilter
;break;
933 case WID_PRINT_OPTIONS
: pData
= &aPrintSettings
; break;
934 case WID_SAVE_AS_SINGLE_FILE
: pData
= &bSaveAsSingleFile
; break;
935 case WID_SAVE_FILTER
: pData
= &sSaveFilter
; break;
936 case WID_SAVE_FILTER_OPTIONS
: pData
= &sSaveFilterOptions
; break;
937 case WID_SAVE_FILTER_DATA
: pData
= &aSaveFilterData
; break;
938 case WID_COPIES_TO
: pData
= &aCopiesTo
; break;
939 case WID_BLIND_COPIES_TO
: pData
= &aBlindCopiesTo
;break;
940 case WID_IN_SERVER_PASSWORD
: pData
= &sInServerPassword
; break;
941 case WID_OUT_SERVER_PASSWORD
: pData
= &sOutServerPassword
; break;
943 DBG_ERROR("unknown WID");
945 Any
aOld( pData
, *pType
);
947 sal_Bool bChanged
= sal_False
;
948 sal_Bool bOK
= sal_True
;
951 if (pData
== &aSelection
)
952 bOK
= rValue
>>= aSelection
;
953 else if (pData
== &xResultSet
)
954 bOK
= rValue
>>= xResultSet
;
955 else if (pData
== &xConnection
)
956 bOK
= rValue
>>= xConnection
;
957 else if (pData
== &xModel
)
958 bOK
= rValue
>>= xModel
;
959 else if (pData
== &aDataSourceName
)
960 bOK
= rValue
>>= aDataSourceName
;
961 else if (pData
== &aDataCommand
)
962 bOK
= rValue
>>= aDataCommand
;
963 else if (pData
== &aFilter
)
964 bOK
= rValue
>>= aFilter
;
965 else if (pData
== &aDocumentURL
)
968 bOK
= rValue
>>= aText
;
969 if (aText
.getLength()
970 && !LoadFromURL_impl( xModel
, xDocSh
, aText
, TRUE
))
971 throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to create document from URL: " ) ) + aText
, static_cast < cppu::OWeakObject
* > ( this ) );
972 aDocumentURL
= aText
;
974 else if (pData
== &aOutputURL
)
977 bOK
= rValue
>>= aText
;
978 if (aText
.getLength())
980 if (!UCB_IsDirectory(aText
))
981 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL does not point to a directory: " ) ) + aText
, static_cast < cppu::OWeakObject
* > ( this ), 0 );
982 if (UCB_IsReadOnlyFileName(aText
))
983 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL is read-only: " ) ) + aText
, static_cast < cppu::OWeakObject
* > ( this ), 0 );
987 else if (pData
== &nDataCommandType
)
988 bOK
= rValue
>>= nDataCommandType
;
989 else if (pData
== &nOutputType
)
990 bOK
= rValue
>>= nOutputType
;
991 else if (pData
== &bEscapeProcessing
)
992 bOK
= rValue
>>= bEscapeProcessing
;
993 else if (pData
== &bSinglePrintJobs
)
994 bOK
= rValue
>>= bSinglePrintJobs
;
995 else if (pData
== &bFileNameFromColumn
)
996 bOK
= rValue
>>= bFileNameFromColumn
;
997 else if (pData
== &aFileNamePrefix
)
998 bOK
= rValue
>>= aFileNamePrefix
;
999 else if (pData
== &sSubject
)
1000 bOK
= rValue
>>= sSubject
;
1001 else if (pData
== &sAddressFromColumn
)
1002 bOK
= rValue
>>= sAddressFromColumn
;
1003 else if (pData
== &bSendAsHTML
)
1004 bOK
= rValue
>>= bSendAsHTML
;
1005 else if (pData
== &bSendAsAttachment
)
1006 bOK
= rValue
>>= bSendAsAttachment
;
1007 else if (pData
== &sMailBody
)
1008 bOK
= rValue
>>= sMailBody
;
1009 else if (pData
== &sAttachmentName
)
1010 bOK
= rValue
>>= sAttachmentName
;
1011 else if (pData
== &sAttachmentFilter
)
1012 bOK
= rValue
>>= sAttachmentFilter
;
1013 else if (pData
== &aPrintSettings
)
1014 bOK
= rValue
>>= aPrintSettings
;
1015 else if (pData
== &bSaveAsSingleFile
)
1016 bOK
= rValue
>>= bSaveAsSingleFile
;
1017 else if (pData
== &sSaveFilter
)
1018 bOK
= rValue
>>= sSaveFilter
;
1019 else if (pData
== &sSaveFilterOptions
)
1020 bOK
= rValue
>>= sSaveFilterOptions
;
1021 else if (pData
== &aSaveFilterData
)
1022 bOK
= rValue
>>= aSaveFilterData
;
1023 else if (pData
== &aCopiesTo
)
1024 bOK
= rValue
>>= aCopiesTo
;
1025 else if (pData
== &aBlindCopiesTo
)
1026 bOK
= rValue
>>= aBlindCopiesTo
;
1027 else if(pData
== &sInServerPassword
)
1028 bOK
= rValue
>>= sInServerPassword
;
1029 else if(pData
== &sOutServerPassword
)
1030 bOK
= rValue
>>= sInServerPassword
;
1032 DBG_ERROR( "invalid pointer" );
1034 DBG_ASSERT( bOK
, "set value failed" );
1035 bChanged
= sal_True
;
1038 throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property type mismatch or property not set: " ) ) + rPropertyName
, static_cast < cppu::OWeakObject
* > ( this ), 0 );
1042 PropertyChangeEvent
aChgEvt( (XPropertySet
*) this, rPropertyName
,
1043 FALSE
, pCur
->nWID
, aOld
, rValue
);
1044 launchEvent( aChgEvt
);
1049 uno::Any SAL_CALL
SwXMailMerge::getPropertyValue(
1050 const OUString
& rPropertyName
)
1051 throw (UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
1053 vos::OGuard
aGuard( Application::GetSolarMutex() );
1057 const SfxItemPropertySimpleEntry
* pCur
= pPropSet
->getPropertyMap()->getByName( rPropertyName
);
1059 throw UnknownPropertyException();
1064 case WID_SELECTION
: aRet
<<= aSelection
; break;
1065 case WID_RESULT_SET
: aRet
<<= xResultSet
; break;
1066 case WID_CONNECTION
: aRet
<<= xConnection
; break;
1067 case WID_MODEL
: aRet
<<= xModel
; break;
1068 case WID_DATA_SOURCE_NAME
: aRet
<<= aDataSourceName
; break;
1069 case WID_DATA_COMMAND
: aRet
<<= aDataCommand
; break;
1070 case WID_FILTER
: aRet
<<= aFilter
; break;
1071 case WID_DOCUMENT_URL
: aRet
<<= aDocumentURL
; break;
1072 case WID_OUTPUT_URL
: aRet
<<= aOutputURL
; break;
1073 case WID_DATA_COMMAND_TYPE
: aRet
<<= nDataCommandType
; break;
1074 case WID_OUTPUT_TYPE
: aRet
<<= nOutputType
; break;
1075 case WID_ESCAPE_PROCESSING
: aRet
<<= bEscapeProcessing
; break;
1076 case WID_SINGLE_PRINT_JOBS
: aRet
<<= bSinglePrintJobs
; break;
1077 case WID_FILE_NAME_FROM_COLUMN
: aRet
<<= bFileNameFromColumn
; break;
1078 case WID_FILE_NAME_PREFIX
: aRet
<<= aFileNamePrefix
; break;
1079 case WID_MAIL_SUBJECT
: aRet
<<= sSubject
; break;
1080 case WID_ADDRESS_FROM_COLUMN
: aRet
<<= sAddressFromColumn
; break;
1081 case WID_SEND_AS_HTML
: aRet
<<= bSendAsHTML
; break;
1082 case WID_SEND_AS_ATTACHMENT
: aRet
<<= bSendAsAttachment
; break;
1083 case WID_MAIL_BODY
: aRet
<<= sMailBody
; break;
1084 case WID_ATTACHMENT_NAME
: aRet
<<= sAttachmentName
; break;
1085 case WID_ATTACHMENT_FILTER
: aRet
<<= sAttachmentFilter
;break;
1086 case WID_PRINT_OPTIONS
: aRet
<<= aPrintSettings
; break;
1087 case WID_SAVE_AS_SINGLE_FILE
: aRet
<<= bSaveAsSingleFile
; break;
1088 case WID_SAVE_FILTER
: aRet
<<= sSaveFilter
; break;
1089 case WID_SAVE_FILTER_OPTIONS
: aRet
<<= sSaveFilterOptions
; break;
1090 case WID_SAVE_FILTER_DATA
: aRet
<<= aSaveFilterData
; break;
1091 case WID_COPIES_TO
: aRet
<<= aCopiesTo
; break;
1092 case WID_BLIND_COPIES_TO
: aRet
<<= aBlindCopiesTo
;break;
1093 case WID_IN_SERVER_PASSWORD
: aRet
<<= sInServerPassword
; break;
1094 case WID_OUT_SERVER_PASSWORD
: aRet
<<= sOutServerPassword
; break;
1096 DBG_ERROR("unknown WID");
1103 void SAL_CALL
SwXMailMerge::addPropertyChangeListener(
1104 const OUString
& rPropertyName
,
1105 const uno::Reference
< beans::XPropertyChangeListener
>& rListener
)
1106 throw (UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
1108 vos::OGuard
aGuard( Application::GetSolarMutex() );
1109 if (!bDisposing
&& rListener
.is())
1111 const SfxItemPropertySimpleEntry
* pCur
= pPropSet
->getPropertyMap()->getByName( rPropertyName
);
1113 aPropListeners
.addInterface( pCur
->nWID
, rListener
);
1115 throw UnknownPropertyException();
1119 void SAL_CALL
SwXMailMerge::removePropertyChangeListener(
1120 const OUString
& rPropertyName
,
1121 const uno::Reference
< beans::XPropertyChangeListener
>& rListener
)
1122 throw (UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
1124 vos::OGuard
aGuard( Application::GetSolarMutex() );
1125 if (!bDisposing
&& rListener
.is())
1127 const SfxItemPropertySimpleEntry
* pCur
= pPropSet
->getPropertyMap()->getByName( rPropertyName
);
1129 aPropListeners
.removeInterface( pCur
->nWID
, rListener
);
1131 throw UnknownPropertyException();
1135 void SAL_CALL
SwXMailMerge::addVetoableChangeListener(
1136 const OUString
& /*rPropertyName*/,
1137 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/ )
1138 throw (UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
1140 // no vetoable property, thus no support for vetoable change listeners
1141 DBG_WARNING( "not implemented");
1144 void SAL_CALL
SwXMailMerge::removeVetoableChangeListener(
1145 const OUString
& /*rPropertyName*/,
1146 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/ )
1147 throw (UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
1149 // no vetoable property, thus no support for vetoable change listeners
1150 DBG_WARNING( "not implemented");
1154 void SAL_CALL
SwXMailMerge::dispose()
1155 throw(RuntimeException
)
1157 vos::OGuard
aGuard( Application::GetSolarMutex() );
1161 bDisposing
= sal_True
;
1163 EventObject
aEvtObj( (XPropertySet
*) this );
1164 aEvtListeners
.disposeAndClear( aEvtObj
);
1165 aMergeListeners
.disposeAndClear( aEvtObj
);
1166 aPropListeners
.disposeAndClear( aEvtObj
);
1170 void SAL_CALL
SwXMailMerge::addEventListener(
1171 const Reference
< XEventListener
>& rxListener
)
1172 throw(RuntimeException
)
1174 vos::OGuard
aGuard( Application::GetSolarMutex() );
1175 if (!bDisposing
&& rxListener
.is())
1176 aEvtListeners
.addInterface( rxListener
);
1179 void SAL_CALL
SwXMailMerge::removeEventListener(
1180 const Reference
< XEventListener
>& rxListener
)
1181 throw(RuntimeException
)
1183 vos::OGuard
aGuard( Application::GetSolarMutex() );
1184 if (!bDisposing
&& rxListener
.is())
1185 aEvtListeners
.removeInterface( rxListener
);
1188 void SAL_CALL
SwXMailMerge::addMailMergeEventListener(
1189 const uno::Reference
< XMailMergeListener
>& rxListener
)
1190 throw (RuntimeException
)
1192 vos::OGuard
aGuard( Application::GetSolarMutex() );
1193 if (!bDisposing
&& rxListener
.is())
1194 aMergeListeners
.addInterface( rxListener
);
1197 void SAL_CALL
SwXMailMerge::removeMailMergeEventListener(
1198 const uno::Reference
< XMailMergeListener
>& rxListener
)
1199 throw (RuntimeException
)
1201 vos::OGuard
aGuard( Application::GetSolarMutex() );
1202 if (!bDisposing
&& rxListener
.is())
1203 aMergeListeners
.removeInterface( rxListener
);
1206 OUString SAL_CALL
SwXMailMerge::getImplementationName()
1207 throw(RuntimeException
)
1209 vos::OGuard
aGuard( Application::GetSolarMutex() );
1210 return SwXMailMerge_getImplementationName();
1213 sal_Bool SAL_CALL
SwXMailMerge::supportsService( const OUString
& rServiceName
)
1214 throw(RuntimeException
)
1216 vos::OGuard
aGuard( Application::GetSolarMutex() );
1217 return C2U( SN_MAIL_MERGE
) == rServiceName
||
1218 C2U( SN_DATA_ACCESS_DESCRIPTOR
) == rServiceName
;
1221 uno::Sequence
< OUString
> SAL_CALL
SwXMailMerge::getSupportedServiceNames()
1222 throw(RuntimeException
)
1224 vos::OGuard
aGuard( Application::GetSolarMutex() );
1225 return SwXMailMerge_getSupportedServiceNames();
1228 ////////////////////////////////////////////////////////////
1230 uno::Sequence
< OUString
> SAL_CALL
SwXMailMerge_getSupportedServiceNames()
1233 uno::Sequence
< OUString
> aNames(2);
1234 OUString
*pName
= aNames
.getArray();
1235 pName
[0] = C2U( SN_MAIL_MERGE
);
1236 pName
[1] = C2U( SN_DATA_ACCESS_DESCRIPTOR
);
1240 OUString SAL_CALL
SwXMailMerge_getImplementationName()
1243 return OUString( C2U( "SwXMailMerge" ) );
1246 uno::Reference
< uno::XInterface
> SAL_CALL
SwXMailMerge_createInstance(
1247 const uno::Reference
< XMultiServiceFactory
> & /*rSMgr*/)
1248 throw( uno::Exception
)
1250 vos::OGuard
aGuard( Application::GetSolarMutex() );
1252 //the module may not be loaded
1254 uno::Reference
< uno::XInterface
> xRef
= (cppu::OWeakObject
*) new SwXMailMerge();