Permalink
Cannot retrieve contributors at this time
Fetching contributors…

/************************************************************************* | |
* | |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
* | |
* Copyright 2000, 2010 Oracle and/or its affiliates. | |
* | |
* OpenOffice.org - a multi-platform office productivity suite | |
* | |
* This file is part of OpenOffice.org. | |
* | |
* OpenOffice.org is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU Lesser General Public License version 3 | |
* only, as published by the Free Software Foundation. | |
* | |
* OpenOffice.org is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU Lesser General Public License version 3 for more details | |
* (a copy is included in the LICENSE file that accompanied this code). | |
* | |
* You should have received a copy of the GNU Lesser General Public License | |
* version 3 along with OpenOffice.org. If not, see | |
* <http://www.openoffice.org/license.html> | |
* for a copy of the LGPLv3 License. | |
* | |
************************************************************************/ | |
// MARKER(update_precomp.py): autogen include statement, do not remove | |
#include "precompiled_sw.hxx" | |
#include <vcl/svapp.hxx> | |
#include <vos/mutex.hxx> | |
#include <osl/mutex.hxx> | |
#include <svl/itemprop.hxx> | |
#include <svl/urihelper.hxx> | |
#include <svx/dataaccessdescriptor.hxx> | |
#include <tools/shl.hxx> // GetAppData | |
#include <tools/tempfile.hxx> | |
#include <sfx2/app.hxx> | |
#include <sfx2/docfile.hxx> | |
#include <sfx2/docfilt.hxx> | |
#include <comphelper/processfactory.hxx> | |
#include <vcl/timer.hxx> | |
#include <com/sun/star/sdb/CommandType.hpp> | |
#include <com/sun/star/text/MailMergeType.hpp> | |
#include <com/sun/star/text/MailMergeEvent.hpp> | |
#include <com/sun/star/text/XMailMergeListener.hpp> | |
#include <com/sun/star/text/XMailMergeBroadcaster.hpp> | |
#include <com/sun/star/beans/PropertyAttribute.hpp> | |
#include <com/sun/star/lang/XUnoTunnel.hpp> | |
#include <com/sun/star/sdbc/XResultSet.hpp> | |
#include <com/sun/star/sdbc/XConnection.hpp> | |
#include <com/sun/star/sdbc/XRowSet.hpp> | |
#include <com/sun/star/frame/XComponentLoader.hpp> | |
#include <com/sun/star/util/XCloseable.hpp> | |
#ifndef _COM_SUN_STAR_UTIL_CloseVetoException_HPP_ | |
#include <com/sun/star/util/CloseVetoException.hpp> | |
#endif | |
#include <com/sun/star/sdbcx/XRowLocate.hpp> | |
#include <com/sun/star/frame/XStorable.hpp> | |
#include "com/sun/star/mail/XSmtpService.hpp" | |
#include <sfx2/viewfrm.hxx> | |
#include <sfx2/event.hxx> | |
#include <swevent.hxx> | |
#include <unomailmerge.hxx> | |
#include <swdll.hxx> | |
#include <swmodule.hxx> | |
#include <unoprnms.hxx> | |
#include <unomap.hxx> | |
#include <swunohelper.hxx> | |
#include <docsh.hxx> | |
#ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED | |
#include <IDocumentDeviceAccess.hxx> | |
#endif | |
#include <view.hxx> | |
#include <dbmgr.hxx> | |
#include <unotxdoc.hxx> | |
#include <prtopt.hxx> | |
#include <wrtsh.hxx> | |
#include <shellio.hxx> | |
#include <mmconfigitem.hxx> | |
#include <mailmergehelper.hxx> | |
#include <memory> | |
#include <unomid.h> | |
#define SN_MAIL_MERGE "com.sun.star.text.MailMerge" | |
#define SN_DATA_ACCESS_DESCRIPTOR "com.sun.star.sdb.DataAccessDescriptor" | |
using namespace ::com::sun::star; | |
using namespace ::com::sun::star::frame; | |
using namespace ::com::sun::star::uno; | |
using namespace ::com::sun::star::lang; | |
using namespace ::com::sun::star::beans; | |
using namespace ::com::sun::star::text; | |
using ::rtl::OUString; | |
using namespace SWUnoHelper; | |
//////////////////////////////////////////////////////////// | |
typedef ::utl::SharedUNOComponent< XInterface > SharedComponent; | |
//////////////////////////////////////////////////////////// | |
osl::Mutex & GetMailMergeMutex() | |
{ | |
static osl::Mutex aMutex; | |
return aMutex; | |
} | |
//////////////////////////////////////////////////////////// | |
enum CloseResult | |
{ | |
eSuccess, // successfully closed | |
eVetoed, // vetoed, ownership transfered to the vetoing instance | |
eFailed // failed for some unknown reason | |
}; | |
static CloseResult CloseModelAndDocSh( | |
Reference< frame::XModel > &rxModel, | |
SfxObjectShellRef &rxDocSh ) | |
{ | |
CloseResult eResult = eSuccess; | |
rxDocSh = 0; | |
//! models/documents should never be disposed (they may still be | |
//! used for printing which is called asynchronously for example) | |
//! instead call close | |
Reference< util::XCloseable > xClose( rxModel, UNO_QUERY ); | |
if (xClose.is()) | |
{ | |
try | |
{ | |
//! 'sal_True' -> transfer ownership to vetoing object if vetoed! | |
//! I.e. now that object is responsible for closing the model and doc shell. | |
xClose->close( sal_True ); | |
} | |
catch (util::CloseVetoException &) | |
{ | |
//! here we have the problem that the temporary file that is | |
//! currently being printed will never be deleted. :-( | |
eResult = eVetoed; | |
} | |
catch ( const uno::RuntimeException& ) | |
{ | |
eResult = eFailed; | |
} | |
} | |
return eResult; | |
} | |
//////////////////////////////////////////////////////////// | |
static BOOL LoadFromURL_impl( | |
Reference< frame::XModel > &rxModel, | |
SfxObjectShellRef &rxDocSh, | |
const String &rURL, | |
BOOL bClose ) | |
throw (RuntimeException) | |
{ | |
// try to open the document readonly and hidden | |
Reference< frame::XModel > xTmpModel; | |
Sequence < PropertyValue > aArgs( 1 ); | |
aArgs[0].Name = C2U("Hidden"); | |
sal_Bool bVal = sal_True; | |
aArgs[0].Value <<= bVal; | |
try | |
{ | |
Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()-> | |
createInstance( C2U("com.sun.star.frame.Desktop") ), UNO_QUERY ); | |
xTmpModel = Reference < XModel >( xDesktop->loadComponentFromURL( | |
rURL, C2U("_blank"), 0, aArgs ), UNO_QUERY ); | |
} | |
catch( Exception & ) | |
{ | |
return FALSE; | |
} | |
// try to get the DocShell | |
SwDocShell *pTmpDocShell = 0; | |
Reference < XUnoTunnel > xTunnel( xTmpModel, UNO_QUERY ); | |
if (xTunnel.is()) | |
{ | |
SwXTextDocument* pTextDoc = reinterpret_cast<SwXTextDocument *>( | |
xTunnel->getSomething( SwXTextDocument::getUnoTunnelId() )); | |
pTmpDocShell = pTextDoc ? pTextDoc->GetDocShell() : 0; | |
} | |
BOOL bRes = FALSE; | |
if (xTmpModel.is() && pTmpDocShell) // everything available? | |
{ | |
if (bClose) | |
CloseModelAndDocSh( rxModel, rxDocSh ); | |
// set new stuff | |
rxModel = xTmpModel; | |
rxDocSh = pTmpDocShell; | |
bRes = TRUE; | |
} | |
else | |
{ | |
SfxObjectShellRef xTmpDocSh = pTmpDocShell; | |
CloseModelAndDocSh( xTmpModel, xTmpDocSh ); | |
} | |
return bRes; | |
} | |
//========================================================== | |
namespace | |
{ | |
class DelayedFileDeletion : public ::cppu::WeakImplHelper1< util::XCloseListener > | |
{ | |
protected: | |
::osl::Mutex m_aMutex; | |
Reference< util::XCloseable > m_xDocument; | |
Timer m_aDeleteTimer; | |
String m_sTemporaryFile; | |
sal_Int32 m_nPendingDeleteAttempts; | |
public: | |
DelayedFileDeletion( const Reference< XModel >& _rxModel, | |
const String& _rTemporaryFile ); | |
protected: | |
~DelayedFileDeletion( ); | |
// XCloseListener | |
virtual void SAL_CALL queryClosing( const EventObject& _rSource, sal_Bool _bGetsOwnership ) throw (util::CloseVetoException, RuntimeException); | |
virtual void SAL_CALL notifyClosing( const EventObject& _rSource ) throw (RuntimeException); | |
// XEventListener | |
virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); | |
private: | |
void implTakeOwnership( ); | |
DECL_LINK( OnTryDeleteFile, void* ); | |
private: | |
DelayedFileDeletion( const DelayedFileDeletion& ); // never implemented | |
DelayedFileDeletion& operator=( const DelayedFileDeletion& ); // never implemented | |
}; | |
DBG_NAME( DelayedFileDeletion ) | |
//------------------------------------------------------ | |
DelayedFileDeletion::DelayedFileDeletion( const Reference< XModel >& _rxModel, const String& _rTemporaryFile ) | |
: | |
m_xDocument( _rxModel, UNO_QUERY ) | |
,m_sTemporaryFile( _rTemporaryFile ) | |
,m_nPendingDeleteAttempts( 0 ) | |
{ | |
DBG_CTOR( DelayedFileDeletion, NULL ); | |
osl_incrementInterlockedCount( &m_refCount ); | |
try | |
{ | |
if ( m_xDocument.is() ) | |
{ | |
m_xDocument->addCloseListener( this ); | |
// successfully added -> keep ourself alive | |
acquire(); | |
} | |
else { | |
DBG_ERROR( "DelayedFileDeletion::DelayedFileDeletion: model is no component!" ); | |
} | |
} | |
catch( const Exception& ) | |
{ | |
DBG_ERROR( "DelayedFileDeletion::DelayedFileDeletion: could not register as event listener at the model!" ); | |
} | |
osl_decrementInterlockedCount( &m_refCount ); | |
} | |
//-------------------------------------------------------------------- | |
IMPL_LINK( DelayedFileDeletion, OnTryDeleteFile, void*, EMPTYARG ) | |
{ | |
::osl::ClearableMutexGuard aGuard( m_aMutex ); | |
sal_Bool bSuccess = sal_False; | |
try | |
{ | |
sal_Bool bDeliverOwnership = ( 0 == m_nPendingDeleteAttempts ); | |
// if this is our last attemt, then anybody which vetoes this has to take the consequences | |
// (means take the ownership) | |
m_xDocument->close( bDeliverOwnership ); | |
bSuccess = sal_True; | |
} | |
catch( const util::CloseVetoException& ) | |
{ | |
// somebody vetoed -> next try | |
if ( m_nPendingDeleteAttempts ) | |
{ | |
// next attempt | |
--m_nPendingDeleteAttempts; | |
m_aDeleteTimer.Start(); | |
} | |
else | |
bSuccess = sal_True; // can't do anything here ... | |
} | |
catch( const Exception& ) | |
{ | |
DBG_ERROR( "DelayedFileDeletion::OnTryDeleteFile: caught a strange exception!" ); | |
bSuccess = sal_True; | |
// can't do anything here ... | |
} | |
if ( bSuccess ) | |
{ | |
SWUnoHelper::UCB_DeleteFile( m_sTemporaryFile ); | |
aGuard.clear(); | |
release(); // this should be our last reference, we should be dead after this | |
} | |
return 0L; | |
} | |
//-------------------------------------------------------------------- | |
void DelayedFileDeletion::implTakeOwnership( ) | |
{ | |
// revoke ourself as listener | |
try | |
{ | |
m_xDocument->removeCloseListener( this ); | |
} | |
catch( const Exception & ) | |
{ | |
DBG_ERROR( "DelayedFileDeletion::implTakeOwnership: could not revoke the listener!" ); | |
} | |
m_aDeleteTimer.SetTimeout( 3000 ); // 3 seconds | |
m_aDeleteTimer.SetTimeoutHdl( LINK( this, DelayedFileDeletion, OnTryDeleteFile ) ); | |
m_nPendingDeleteAttempts = 3; // try 3 times at most | |
m_aDeleteTimer.Start( ); | |
} | |
//-------------------------------------------------------------------- | |
void SAL_CALL DelayedFileDeletion::queryClosing( const EventObject& , sal_Bool _bGetsOwnership ) throw (util::CloseVetoException, RuntimeException) | |
{ | |
::osl::MutexGuard aGuard( m_aMutex ); | |
if ( _bGetsOwnership ) | |
implTakeOwnership( ); | |
// always veto: We want to take the ownership ourself, as this is the only chance to delete | |
// the temporary file which the model is based on | |
throw util::CloseVetoException( ); | |
} | |
//-------------------------------------------------------------------- | |
void SAL_CALL DelayedFileDeletion::notifyClosing( const EventObject& ) throw (RuntimeException) | |
{ | |
DBG_ERROR( "DelayedFileDeletion::notifyClosing: how this?" ); | |
// this should not happen: | |
// Either, a foreign instance closes the document, then we should veto this, and take the ownership | |
// Or, we ourself close the document, then we should not be a listener anymore | |
} | |
//------------------------------------------------------ | |
void SAL_CALL DelayedFileDeletion::disposing( const EventObject& ) throw (RuntimeException) | |
{ | |
DBG_ERROR( "DelayedFileDeletion::disposing: how this?" ); | |
// this should not happen: | |
// Either, a foreign instance closes the document, then we should veto this, and take the ownership | |
// Or, we ourself close the document, then we should not be a listener anymore | |
} | |
//------------------------------------------------------ | |
DelayedFileDeletion::~DelayedFileDeletion( ) | |
{ | |
DBG_DTOR( DelayedFileDeletion, NULL ); | |
} | |
} | |
//////////////////////////////////////////////////////////// | |
static BOOL DeleteTmpFile_Impl( | |
Reference< frame::XModel > &rxModel, | |
SfxObjectShellRef &rxDocSh, | |
const String &rTmpFileURL ) | |
{ | |
BOOL bRes = FALSE; | |
if (rTmpFileURL.Len()) | |
{ | |
BOOL bDelete = TRUE; | |
if ( eVetoed == CloseModelAndDocSh( rxModel, rxDocSh ) ) | |
{ | |
// somebody vetoed the closing, and took the ownership of the document | |
// -> ensure that the temporary file is deleted later on | |
Reference< XEventListener > xEnsureDelete( new DelayedFileDeletion( rxModel, rTmpFileURL ) ); | |
// note: as soon as #106931# is fixed, the whole DelayedFileDeletion is to be superseeded by | |
// a better solution | |
bDelete = FALSE; | |
} | |
rxModel = 0; | |
rxDocSh = 0; // destroy doc shell | |
if ( bDelete ) | |
{ | |
if ( !SWUnoHelper::UCB_DeleteFile( rTmpFileURL ) ) | |
{ | |
Reference< XEventListener > xEnsureDelete( new DelayedFileDeletion( rxModel, rTmpFileURL ) ); | |
// same not as above: as soon as #106931#, ... | |
} | |
} | |
else | |
bRes = TRUE; // file will be deleted delayed | |
} | |
return bRes; | |
} | |
//////////////////////////////////////////////////////////// | |
SwXMailMerge::SwXMailMerge() : | |
aEvtListeners ( GetMailMergeMutex() ), | |
aMergeListeners ( GetMailMergeMutex() ), | |
aPropListeners ( GetMailMergeMutex() ), | |
pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_MAILMERGE ) ), | |
bSendAsHTML(sal_False), | |
bSendAsAttachment(sal_False), | |
bSaveAsSingleFile(sal_False) | |
{ | |
// create empty document | |
// like in: SwModule::InsertEnv (appenv.cxx) | |
SwDocShell *pDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD ); | |
xDocSh = pDocShell; | |
xDocSh->DoInitNew( 0 ); | |
SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 ); | |
SwView *pView = (SwView*) pFrame->GetViewShell(); | |
pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird. | |
xModel = pDocShell->GetModel(); | |
nDataCommandType = sdb::CommandType::TABLE; | |
nOutputType = MailMergeType::PRINTER; | |
bEscapeProcessing = sal_True; //!! allow to process properties like "Filter", "Order", ... | |
bSinglePrintJobs = sal_False; | |
bFileNameFromColumn = sal_False; | |
bDisposing = sal_False; | |
} | |
SwXMailMerge::~SwXMailMerge() | |
{ | |
if (aTmpFileName.Len()) | |
DeleteTmpFile_Impl( xModel, xDocSh, aTmpFileName ); | |
else // there was no temporary file in use | |
{ | |
//! we still need to close the model and doc shell manually | |
//! because there is no automatism that will do that later. | |
//! #120086# | |
if ( eVetoed == CloseModelAndDocSh( xModel, xDocSh ) ) | |
DBG_WARNING( "owner ship transfered to vetoing object!" ); | |
xModel = 0; | |
xDocSh = 0; // destroy doc shell | |
} | |
} | |
uno::Any SAL_CALL SwXMailMerge::execute( | |
const uno::Sequence< beans::NamedValue >& rArguments ) | |
throw (IllegalArgumentException, Exception, RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
// | |
// get property values to be used | |
// (use values from the service as default and override them with | |
// the values that are provided as arguments) | |
// | |
uno::Sequence< uno::Any > aCurSelection = aSelection; | |
uno::Reference< sdbc::XResultSet > xCurResultSet = xResultSet; | |
uno::Reference< sdbc::XConnection > xCurConnection = xConnection; | |
uno::Reference< frame::XModel > xCurModel = xModel; | |
OUString aCurDataSourceName = aDataSourceName; | |
OUString aCurDataCommand = aDataCommand; | |
OUString aCurFilter = aFilter; | |
OUString aCurDocumentURL = aDocumentURL; | |
OUString aCurOutputURL = aOutputURL; | |
OUString aCurFileNamePrefix = aFileNamePrefix; | |
sal_Int32 nCurDataCommandType = nDataCommandType; | |
sal_Int16 nCurOutputType = nOutputType; | |
sal_Bool bCurEscapeProcessing = bEscapeProcessing; | |
sal_Bool bCurSinglePrintJobs = bSinglePrintJobs; | |
sal_Bool bCurFileNameFromColumn = bFileNameFromColumn; | |
// | |
SfxObjectShellRef xCurDocSh = xDocSh; // the document | |
// | |
const beans::NamedValue *pArguments = rArguments.getConstArray(); | |
sal_Int32 nArgs = rArguments.getLength(); | |
for (sal_Int32 i = 0; i < nArgs; ++i) | |
{ | |
const OUString &rName = pArguments[i].Name; | |
const Any &rValue = pArguments[i].Value; | |
BOOL bOK = TRUE; | |
if (rName.equalsAscii( GetPropName( UNO_NAME_SELECTION ) )) | |
bOK = rValue >>= aCurSelection; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_RESULT_SET ) )) | |
bOK = rValue >>= xCurResultSet; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_CONNECTION ) )) | |
bOK = rValue >>= xCurConnection; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_MODEL ) )) | |
throw PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rName, static_cast < cppu::OWeakObject * > ( this ) ); | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_DATA_SOURCE_NAME ) )) | |
bOK = rValue >>= aCurDataSourceName; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_DAD_COMMAND ) )) | |
bOK = rValue >>= aCurDataCommand; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_FILTER ) )) | |
bOK = rValue >>= aCurFilter; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_DOCUMENT_URL ) )) | |
{ | |
bOK = rValue >>= aCurDocumentURL; | |
if (aCurDocumentURL.getLength() | |
&& !LoadFromURL_impl( xCurModel, xCurDocSh, aCurDocumentURL, FALSE )) | |
throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to create document from URL: " ) ) + aCurDocumentURL, static_cast < cppu::OWeakObject * > ( this ) ); | |
} | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_OUTPUT_URL ) )) | |
{ | |
bOK = rValue >>= aCurOutputURL; | |
if (aCurOutputURL.getLength()) | |
{ | |
if (!UCB_IsDirectory(aCurOutputURL)) | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL does not point to a directory: " ) ) + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
if (UCB_IsReadOnlyFileName(aCurOutputURL)) | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL is read-only: " ) ) + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
} | |
} | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_FILE_NAME_PREFIX ) )) | |
bOK = rValue >>= aCurFileNamePrefix; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_DAD_COMMAND_TYPE ) )) | |
bOK = rValue >>= nCurDataCommandType; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_OUTPUT_TYPE ) )) | |
bOK = rValue >>= nCurOutputType; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_ESCAPE_PROCESSING ) )) | |
bOK = rValue >>= bCurEscapeProcessing; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SINGLE_PRINT_JOBS ) )) | |
bOK = rValue >>= bCurSinglePrintJobs; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_FILE_NAME_FROM_COLUMN ) )) | |
bOK = rValue >>= bCurFileNameFromColumn; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SUBJECT ) )) | |
bOK = rValue >>= sSubject; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_ADDRESS_FROM_COLUMN ) )) | |
bOK = rValue >>= sAddressFromColumn; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SEND_AS_HTML ) )) | |
bOK = rValue >>= bSendAsHTML; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_MAIL_BODY ) )) | |
bOK = rValue >>= sMailBody; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_ATTACHMENT_NAME ) )) | |
bOK = rValue >>= sAttachmentName; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_ATTACHMENT_FILTER ) )) | |
bOK = rValue >>= sAttachmentFilter; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_COPIES_TO ) )) | |
bOK = rValue >>= aCopiesTo; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_BLIND_COPIES_TO ) )) | |
bOK = rValue >>= aBlindCopiesTo; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SEND_AS_ATTACHMENT ) )) | |
bOK = rValue >>= bSendAsAttachment; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_PRINT_OPTIONS ) )) | |
bOK = rValue >>= aPrintSettings; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_AS_SINGLE_FILE ) )) | |
bOK = rValue >>= bSaveAsSingleFile; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER ) )) | |
bOK = rValue >>= sSaveFilter; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER_OPTIONS ) )) | |
bOK = rValue >>= sSaveFilterOptions; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER_DATA ) )) | |
bOK = rValue >>= aSaveFilterData; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_IN_SERVER_PASSWORD ) )) | |
bOK = rValue >>= sInServerPassword; | |
else if (rName.equalsAscii( GetPropName( UNO_NAME_OUT_SERVER_PASSWORD ) )) | |
bOK = rValue >>= sOutServerPassword; | |
else | |
throw UnknownPropertyException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is unknown: " ) ) + rName, static_cast < cppu::OWeakObject * > ( this ) ); | |
if (!bOK) | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property type mismatch or property not set: " ) ) + rName, static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
} | |
// need to translate the selection: the API here requires a sequence of bookmarks, but the MergeNew | |
// method we will call below requires a sequence of indicies. | |
if ( aCurSelection.getLength() ) | |
{ | |
Sequence< Any > aTranslated( aCurSelection.getLength() ); | |
sal_Bool bValid = sal_False; | |
Reference< sdbcx::XRowLocate > xRowLocate( xCurResultSet, UNO_QUERY ); | |
if ( xRowLocate.is() ) | |
{ | |
const Any* pBookmarks = aCurSelection.getConstArray(); | |
const Any* pBookmarksEnd = pBookmarks + aCurSelection.getLength(); | |
Any* pTranslated = aTranslated.getArray(); | |
try | |
{ | |
sal_Bool bEverythingsFine = sal_True; | |
for ( ; ( pBookmarks != pBookmarksEnd ) && bEverythingsFine; ++pBookmarks ) | |
{ | |
if ( xRowLocate->moveToBookmark( *pBookmarks ) ) | |
*pTranslated <<= xCurResultSet->getRow(); | |
else | |
bEverythingsFine = sal_False; | |
} | |
if ( bEverythingsFine ) | |
bValid = sal_True; | |
} | |
catch( const Exception& ) | |
{ | |
bValid = sal_False; | |
} | |
} | |
if ( !bValid ) | |
{ | |
throw IllegalArgumentException( | |
OUString ( RTL_CONSTASCII_USTRINGPARAM ( "The current 'Selection' does not describe a valid array of bookmarks, relative to the current 'ResultSet'." ) ), | |
static_cast < cppu::OWeakObject * > ( this ), | |
0 | |
); | |
} | |
aCurSelection = aTranslated; | |
} | |
SfxViewFrame* pFrame = SfxViewFrame::GetFirst( xCurDocSh, FALSE); | |
SwView *pView = PTR_CAST( SwView, pFrame->GetViewShell() ); | |
if (!pView) | |
throw RuntimeException(); | |
SwWrtShell &rSh = *pView->GetWrtShellPtr(); | |
// avoid assertion in 'Update' from Sfx by supplying a shell | |
// and thus avoiding the SelectShell call in Writers GetState function | |
// while still in Update of Sfx. | |
// (GetSelection in Update is not allowed) | |
if (pView && aCurDocumentURL.getLength()) | |
pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird. | |
SharedComponent aRowSetDisposeHelper; | |
if (!xCurResultSet.is()) | |
{ | |
if (!aCurDataSourceName.getLength() || !aCurDataCommand.getLength() ) | |
{ | |
DBG_ERROR("PropertyValues missing or unset"); | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Either the ResultSet or DataSourceName and DataCommand must be set." ) ), static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
} | |
// | |
// build ResultSet from DataSourceName, DataCommand and DataCommandType | |
// | |
Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); | |
if (xMgr.is()) | |
{ | |
Reference< XInterface > xInstance = xMgr->createInstance( | |
C2U( "com.sun.star.sdb.RowSet" )); | |
aRowSetDisposeHelper.reset( xInstance, SharedComponent::TakeOwnership ); | |
Reference< XPropertySet > xRowSetPropSet( xInstance, UNO_QUERY ); | |
DBG_ASSERT( xRowSetPropSet.is(), "failed to get XPropertySet interface from RowSet" ); | |
if (xRowSetPropSet.is()) | |
{ | |
if (xCurConnection.is()) | |
xRowSetPropSet->setPropertyValue( C2U("ActiveConnection"), makeAny( xCurConnection ) ); | |
xRowSetPropSet->setPropertyValue( C2U("DataSourceName"), makeAny( aCurDataSourceName ) ); | |
xRowSetPropSet->setPropertyValue( C2U("Command"), makeAny( aCurDataCommand ) ); | |
xRowSetPropSet->setPropertyValue( C2U("CommandType"), makeAny( nCurDataCommandType ) ); | |
xRowSetPropSet->setPropertyValue( C2U("EscapeProcessing"), makeAny( bCurEscapeProcessing ) ); | |
xRowSetPropSet->setPropertyValue( C2U("ApplyFilter"), makeAny( sal_True ) ); | |
xRowSetPropSet->setPropertyValue( C2U("Filter"), makeAny( aCurFilter ) ); | |
Reference< sdbc::XRowSet > xRowSet( xInstance, UNO_QUERY ); | |
if (xRowSet.is()) | |
xRowSet->execute(); // build ResultSet from properties | |
if( !xCurConnection.is() ) | |
xCurConnection.set( xRowSetPropSet->getPropertyValue( C2U( "ActiveConnection" )), UNO_QUERY ); | |
xCurResultSet = Reference< sdbc::XResultSet >( xRowSet, UNO_QUERY ); | |
DBG_ASSERT( xCurResultSet.is(), "failed to build ResultSet" ); | |
} | |
} | |
} | |
svx::ODataAccessDescriptor aDescriptor; | |
aDescriptor.setDataSource(aCurDataSourceName); | |
aDescriptor[ svx::daConnection ] <<= xCurConnection; | |
aDescriptor[ svx::daCommand ] <<= aCurDataCommand; | |
aDescriptor[ svx::daCommandType ] <<= nCurDataCommandType; | |
aDescriptor[ svx::daEscapeProcessing ] <<= bCurEscapeProcessing; | |
aDescriptor[ svx::daCursor ] <<= xCurResultSet; | |
// aDescriptor[ svx::daColumnName ] not used | |
// aDescriptor[ svx::daColumnObject ] not used | |
aDescriptor[ svx::daSelection ] <<= aCurSelection; | |
USHORT nMergeType; | |
switch (nCurOutputType) | |
{ | |
case MailMergeType::PRINTER : nMergeType = DBMGR_MERGE_MAILMERGE; break; | |
case MailMergeType::FILE : nMergeType = DBMGR_MERGE_MAILFILES; break; | |
case MailMergeType::MAIL : nMergeType = DBMGR_MERGE_MAILING; break; | |
default: | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Invalid value of property:" ) ) + C2U("OutputType"), static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
} | |
SwNewDBMgr* pMgr = rSh.GetNewDBMgr(); | |
//force layout creation | |
rSh.CalcLayout(); | |
DBG_ASSERT( pMgr, "database manager missing" ); | |
SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor ); | |
std::auto_ptr< SwMailMergeConfigItem > pMMConfigItem; | |
uno::Reference< mail::XMailService > xInService; | |
if (MailMergeType::PRINTER == nCurOutputType) | |
{ | |
SwPrintData aPrtData = *SW_MOD()->GetPrtOptions( FALSE ); | |
IDocumentDeviceAccess* pIDDA = rSh.getIDocumentDeviceAccess(); | |
SwPrintData* pShellPrintData = pIDDA->getPrintData(); | |
if (pShellPrintData) | |
aPrtData = *pShellPrintData; | |
aPrtData.SetPrintSingleJobs( bCurSinglePrintJobs ); | |
pIDDA->setPrintData( aPrtData ); | |
// #i25686# printing should not be done asynchronously to prevent dangling offices | |
// when mail merge is called as command line macro | |
aMergeDesc.bPrintAsync = sal_False; | |
aMergeDesc.aPrintOptions = aPrintSettings; | |
aMergeDesc.bCreateSingleFile = true; | |
} | |
else /* FILE and MAIL*/ | |
{ | |
INetURLObject aURLObj; | |
aURLObj.SetSmartProtocol( INET_PROT_FILE ); | |
if (aCurDocumentURL.getLength()) | |
{ | |
// if OutputURL or FileNamePrefix are missing get | |
// them from DocumentURL | |
aURLObj.SetSmartURL( aCurDocumentURL ); | |
if (!aCurFileNamePrefix.getLength()) | |
aCurFileNamePrefix = aURLObj.GetBase(); // filename without extension | |
if (!aCurOutputURL.getLength()) | |
{ | |
//aCurOutputURL = aURLObj.GetURLPath(); | |
aURLObj.removeSegment(); | |
aCurOutputURL = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI ); | |
} | |
} | |
else // default empty document without URL | |
{ | |
if (!aCurOutputURL.getLength()) | |
throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "OutputURL is not set and can not be obtained." ) ), static_cast < cppu::OWeakObject * > ( this ) ); | |
} | |
aURLObj.SetSmartURL( aCurOutputURL ); | |
String aPath = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI ); | |
String aDelim( INET_PATH_TOKEN ); | |
if (aPath.Len() >= aDelim.Len() && | |
aPath.Copy( aPath.Len()-aDelim.Len() ).CompareTo( aDelim ) != COMPARE_EQUAL) | |
aPath += aDelim; | |
if (bCurFileNameFromColumn) | |
pMgr->SetEMailColumn( aCurFileNamePrefix ); | |
else | |
{ | |
aPath += String( aCurFileNamePrefix ); | |
pMgr->SetEMailColumn( String() ); | |
} | |
pMgr->SetSubject( aPath ); | |
if(MailMergeType::FILE == nCurOutputType) | |
{ | |
aMergeDesc.sSaveToFilter = sSaveFilter; | |
aMergeDesc.sSaveToFilterOptions = sSaveFilterOptions; | |
aMergeDesc.aSaveToFilterData = aSaveFilterData; | |
aMergeDesc.bCreateSingleFile = bSaveAsSingleFile; | |
} | |
else /*if(MailMergeType::MAIL == nCurOutputType)*/ | |
{ | |
pMgr->SetEMailColumn( sAddressFromColumn ); | |
if(!sAddressFromColumn.getLength()) | |
throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Mail address column not set." ) ), static_cast < cppu::OWeakObject * > ( this ) ); | |
aMergeDesc.sSaveToFilter = sAttachmentFilter; | |
aMergeDesc.sSubject = sSubject; | |
aMergeDesc.sMailBody = sMailBody; | |
aMergeDesc.sAttachmentName = sAttachmentName; | |
aMergeDesc.aCopiesTo = aCopiesTo; | |
aMergeDesc.aBlindCopiesTo = aBlindCopiesTo; | |
aMergeDesc.bSendAsHTML = bSendAsHTML; | |
aMergeDesc.bSendAsAttachment = bSendAsAttachment; | |
aMergeDesc.bCreateSingleFile = sal_False; | |
pMMConfigItem = std::auto_ptr< SwMailMergeConfigItem >(new SwMailMergeConfigItem); | |
aMergeDesc.pMailMergeConfigItem = pMMConfigItem.get(); | |
aMergeDesc.xSmtpServer = SwMailMergeHelper::ConnectToSmtpServer( | |
*pMMConfigItem, | |
xInService, | |
sInServerPassword, sOutServerPassword ); | |
if( !aMergeDesc.xSmtpServer.is() || !aMergeDesc.xSmtpServer->isConnected()) | |
throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to connect to mail server." ) ), static_cast < cppu::OWeakObject * > ( this ) ); | |
} | |
} | |
// save document with temporary filename | |
const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat( | |
String::CreateFromAscii( FILTER_XML ), | |
SwDocShell::Factory().GetFilterContainer() ); | |
String aExtension( pSfxFlt->GetDefaultExtension() ); | |
aExtension.EraseLeadingChars( '*' ); | |
TempFile aTempFile( C2U("SwMM"), &aExtension ); | |
aTmpFileName = aTempFile.GetName(); | |
Reference< XStorable > xStorable( xCurModel, UNO_QUERY ); | |
sal_Bool bStoredAsTemporary = sal_False; | |
if ( xStorable.is() ) | |
{ | |
try | |
{ | |
xStorable->storeAsURL( aTmpFileName, Sequence< PropertyValue >() ); | |
bStoredAsTemporary = sal_True; | |
} | |
catch( const Exception& ) | |
{ | |
} | |
} | |
if ( !bStoredAsTemporary ) | |
throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to save temporary file." ) ), static_cast < cppu::OWeakObject * > ( this ) ); | |
pMgr->SetMergeSilent( TRUE ); // suppress dialogs, message boxes, etc. | |
const SwXMailMerge *pOldSrc = pMgr->GetMailMergeEvtSrc(); | |
DBG_ASSERT( !pOldSrc || pOldSrc == this, "Ooops... different event source already set." ); | |
pMgr->SetMailMergeEvtSrc( this ); // launch events for listeners | |
SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xCurDocSh)); | |
BOOL bSucc = pMgr->MergeNew( aMergeDesc ); | |
SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), xCurDocSh)); | |
pMgr->SetMailMergeEvtSrc( pOldSrc ); | |
if ( xCurModel.get() != xModel.get() ) | |
{ // in case it was a temporary model -> close it, and delete the file | |
DeleteTmpFile_Impl( xCurModel, xCurDocSh, aTmpFileName ); | |
aTmpFileName.Erase(); | |
} | |
// (in case it wasn't a temporary model, it will be closed in the dtor, at the latest) | |
if (!bSucc) | |
throw Exception( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Mail merge failed. Sorry, no further information available." ) ), static_cast < cppu::OWeakObject * > ( this ) ); | |
//de-initialize services | |
if(xInService.is() && xInService->isConnected()) | |
xInService->disconnect(); | |
if(aMergeDesc.xSmtpServer.is() && aMergeDesc.xSmtpServer->isConnected()) | |
aMergeDesc.xSmtpServer->disconnect(); | |
return makeAny( sal_True ); | |
} | |
void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const | |
{ | |
cppu::OInterfaceIteratorHelper aIt( ((SwXMailMerge *) this)->aMergeListeners ); | |
while (aIt.hasMoreElements()) | |
{ | |
Reference< XMailMergeListener > xRef( aIt.next(), UNO_QUERY ); | |
if (xRef.is()) | |
xRef->notifyMailMergeEvent( rEvt ); | |
} | |
} | |
void SwXMailMerge::launchEvent( const PropertyChangeEvent &rEvt ) const | |
{ | |
cppu::OInterfaceContainerHelper *pContainer = | |
aPropListeners.getContainer( rEvt.PropertyHandle ); | |
if (pContainer) | |
{ | |
cppu::OInterfaceIteratorHelper aIt( *pContainer ); | |
while (aIt.hasMoreElements()) | |
{ | |
Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY ); | |
if (xRef.is()) | |
xRef->propertyChange( rEvt ); | |
} | |
} | |
} | |
uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXMailMerge::getPropertySetInfo( ) | |
throw (RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
static Reference< XPropertySetInfo > aRef = pPropSet->getPropertySetInfo(); | |
return aRef; | |
} | |
void SAL_CALL SwXMailMerge::setPropertyValue( | |
const OUString& rPropertyName, const uno::Any& rValue ) | |
throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName ); | |
if (!pCur) | |
throw UnknownPropertyException(); | |
else if (pCur->nFlags & PropertyAttribute::READONLY) | |
throw PropertyVetoException(); | |
else | |
{ | |
void *pData = NULL; | |
const uno::Type* pType = pCur->pType; | |
switch (pCur->nWID) | |
{ | |
case WID_SELECTION : pData = &aSelection; break; | |
case WID_RESULT_SET : pData = &xResultSet; break; | |
case WID_CONNECTION : pData = &xConnection; break; | |
case WID_MODEL : pData = &xModel; break; | |
case WID_DATA_SOURCE_NAME : pData = &aDataSourceName; break; | |
case WID_DATA_COMMAND : pData = &aDataCommand; break; | |
case WID_FILTER : pData = &aFilter; break; | |
case WID_DOCUMENT_URL : pData = &aDocumentURL; break; | |
case WID_OUTPUT_URL : pData = &aOutputURL; break; | |
case WID_DATA_COMMAND_TYPE : pData = &nDataCommandType; break; | |
case WID_OUTPUT_TYPE : pData = &nOutputType; break; | |
case WID_ESCAPE_PROCESSING : pData = &bEscapeProcessing; break; | |
case WID_SINGLE_PRINT_JOBS : pData = &bSinglePrintJobs; break; | |
case WID_FILE_NAME_FROM_COLUMN : pData = &bFileNameFromColumn; break; | |
case WID_FILE_NAME_PREFIX : pData = &aFileNamePrefix; break; | |
case WID_MAIL_SUBJECT: pData = &sSubject; break; | |
case WID_ADDRESS_FROM_COLUMN: pData = &sAddressFromColumn; break; | |
case WID_SEND_AS_HTML: pData = &bSendAsHTML; break; | |
case WID_SEND_AS_ATTACHMENT: pData = &bSendAsAttachment; break; | |
case WID_MAIL_BODY: pData = &sMailBody; break; | |
case WID_ATTACHMENT_NAME: pData = &sAttachmentName; break; | |
case WID_ATTACHMENT_FILTER: pData = &sAttachmentFilter;break; | |
case WID_PRINT_OPTIONS: pData = &aPrintSettings; break; | |
case WID_SAVE_AS_SINGLE_FILE: pData = &bSaveAsSingleFile; break; | |
case WID_SAVE_FILTER: pData = &sSaveFilter; break; | |
case WID_SAVE_FILTER_OPTIONS: pData = &sSaveFilterOptions; break; | |
case WID_SAVE_FILTER_DATA: pData = &aSaveFilterData; break; | |
case WID_COPIES_TO: pData = &aCopiesTo; break; | |
case WID_BLIND_COPIES_TO: pData = &aBlindCopiesTo;break; | |
case WID_IN_SERVER_PASSWORD: pData = &sInServerPassword; break; | |
case WID_OUT_SERVER_PASSWORD: pData = &sOutServerPassword; break; | |
default : | |
DBG_ERROR("unknown WID"); | |
} | |
Any aOld( pData, *pType ); | |
sal_Bool bChanged = sal_False; | |
sal_Bool bOK = sal_True; | |
if (aOld != rValue) | |
{ | |
if (pData == &aSelection) | |
bOK = rValue >>= aSelection; | |
else if (pData == &xResultSet) | |
bOK = rValue >>= xResultSet; | |
else if (pData == &xConnection) | |
bOK = rValue >>= xConnection; | |
else if (pData == &xModel) | |
bOK = rValue >>= xModel; | |
else if (pData == &aDataSourceName) | |
bOK = rValue >>= aDataSourceName; | |
else if (pData == &aDataCommand) | |
bOK = rValue >>= aDataCommand; | |
else if (pData == &aFilter) | |
bOK = rValue >>= aFilter; | |
else if (pData == &aDocumentURL) | |
{ | |
OUString aText; | |
bOK = rValue >>= aText; | |
if (aText.getLength() | |
&& !LoadFromURL_impl( xModel, xDocSh, aText, TRUE )) | |
throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to create document from URL: " ) ) + aText, static_cast < cppu::OWeakObject * > ( this ) ); | |
aDocumentURL = aText; | |
} | |
else if (pData == &aOutputURL) | |
{ | |
OUString aText; | |
bOK = rValue >>= aText; | |
if (aText.getLength()) | |
{ | |
if (!UCB_IsDirectory(aText)) | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL does not point to a directory: " ) ) + aText, static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
if (UCB_IsReadOnlyFileName(aText)) | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL is read-only: " ) ) + aText, static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
} | |
aOutputURL = aText; | |
} | |
else if (pData == &nDataCommandType) | |
bOK = rValue >>= nDataCommandType; | |
else if (pData == &nOutputType) | |
bOK = rValue >>= nOutputType; | |
else if (pData == &bEscapeProcessing) | |
bOK = rValue >>= bEscapeProcessing; | |
else if (pData == &bSinglePrintJobs) | |
bOK = rValue >>= bSinglePrintJobs; | |
else if (pData == &bFileNameFromColumn) | |
bOK = rValue >>= bFileNameFromColumn; | |
else if (pData == &aFileNamePrefix) | |
bOK = rValue >>= aFileNamePrefix; | |
else if (pData == &sSubject) | |
bOK = rValue >>= sSubject; | |
else if (pData == &sAddressFromColumn) | |
bOK = rValue >>= sAddressFromColumn; | |
else if (pData == &bSendAsHTML) | |
bOK = rValue >>= bSendAsHTML; | |
else if (pData == &bSendAsAttachment) | |
bOK = rValue >>= bSendAsAttachment; | |
else if (pData == &sMailBody) | |
bOK = rValue >>= sMailBody; | |
else if (pData == &sAttachmentName) | |
bOK = rValue >>= sAttachmentName; | |
else if (pData == &sAttachmentFilter) | |
bOK = rValue >>= sAttachmentFilter; | |
else if (pData == &aPrintSettings) | |
bOK = rValue >>= aPrintSettings; | |
else if (pData == &bSaveAsSingleFile) | |
bOK = rValue >>= bSaveAsSingleFile; | |
else if (pData == &sSaveFilter) | |
bOK = rValue >>= sSaveFilter; | |
else if (pData == &sSaveFilterOptions) | |
bOK = rValue >>= sSaveFilterOptions; | |
else if (pData == &aSaveFilterData) | |
bOK = rValue >>= aSaveFilterData; | |
else if (pData == &aCopiesTo) | |
bOK = rValue >>= aCopiesTo; | |
else if (pData == &aBlindCopiesTo) | |
bOK = rValue >>= aBlindCopiesTo; | |
else if(pData == &sInServerPassword) | |
bOK = rValue >>= sInServerPassword; | |
else if(pData == &sOutServerPassword) | |
bOK = rValue >>= sInServerPassword; | |
else { | |
DBG_ERROR( "invalid pointer" ); | |
} | |
DBG_ASSERT( bOK, "set value failed" ); | |
bChanged = sal_True; | |
} | |
if (!bOK) | |
throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property type mismatch or property not set: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ), 0 ); | |
if (bChanged) | |
{ | |
PropertyChangeEvent aChgEvt( (XPropertySet *) this, rPropertyName, | |
FALSE, pCur->nWID, aOld, rValue ); | |
launchEvent( aChgEvt ); | |
} | |
} | |
} | |
uno::Any SAL_CALL SwXMailMerge::getPropertyValue( | |
const OUString& rPropertyName ) | |
throw (UnknownPropertyException, WrappedTargetException, RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
Any aRet; | |
const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName ); | |
if (!pCur) | |
throw UnknownPropertyException(); | |
else | |
{ | |
switch (pCur->nWID) | |
{ | |
case WID_SELECTION : aRet <<= aSelection; break; | |
case WID_RESULT_SET : aRet <<= xResultSet; break; | |
case WID_CONNECTION : aRet <<= xConnection; break; | |
case WID_MODEL : aRet <<= xModel; break; | |
case WID_DATA_SOURCE_NAME : aRet <<= aDataSourceName; break; | |
case WID_DATA_COMMAND : aRet <<= aDataCommand; break; | |
case WID_FILTER : aRet <<= aFilter; break; | |
case WID_DOCUMENT_URL : aRet <<= aDocumentURL; break; | |
case WID_OUTPUT_URL : aRet <<= aOutputURL; break; | |
case WID_DATA_COMMAND_TYPE : aRet <<= nDataCommandType; break; | |
case WID_OUTPUT_TYPE : aRet <<= nOutputType; break; | |
case WID_ESCAPE_PROCESSING : aRet <<= bEscapeProcessing; break; | |
case WID_SINGLE_PRINT_JOBS : aRet <<= bSinglePrintJobs; break; | |
case WID_FILE_NAME_FROM_COLUMN : aRet <<= bFileNameFromColumn; break; | |
case WID_FILE_NAME_PREFIX : aRet <<= aFileNamePrefix; break; | |
case WID_MAIL_SUBJECT: aRet <<= sSubject; break; | |
case WID_ADDRESS_FROM_COLUMN: aRet <<= sAddressFromColumn; break; | |
case WID_SEND_AS_HTML: aRet <<= bSendAsHTML; break; | |
case WID_SEND_AS_ATTACHMENT: aRet <<= bSendAsAttachment; break; | |
case WID_MAIL_BODY: aRet <<= sMailBody; break; | |
case WID_ATTACHMENT_NAME: aRet <<= sAttachmentName; break; | |
case WID_ATTACHMENT_FILTER: aRet <<= sAttachmentFilter;break; | |
case WID_PRINT_OPTIONS: aRet <<= aPrintSettings; break; | |
case WID_SAVE_AS_SINGLE_FILE: aRet <<= bSaveAsSingleFile; break; | |
case WID_SAVE_FILTER: aRet <<= sSaveFilter; break; | |
case WID_SAVE_FILTER_OPTIONS: aRet <<= sSaveFilterOptions; break; | |
case WID_SAVE_FILTER_DATA: aRet <<= aSaveFilterData; break; | |
case WID_COPIES_TO: aRet <<= aCopiesTo; break; | |
case WID_BLIND_COPIES_TO: aRet <<= aBlindCopiesTo;break; | |
case WID_IN_SERVER_PASSWORD: aRet <<= sInServerPassword; break; | |
case WID_OUT_SERVER_PASSWORD: aRet <<= sOutServerPassword; break; | |
default : | |
DBG_ERROR("unknown WID"); | |
} | |
} | |
return aRet; | |
} | |
void SAL_CALL SwXMailMerge::addPropertyChangeListener( | |
const OUString& rPropertyName, | |
const uno::Reference< beans::XPropertyChangeListener >& rListener ) | |
throw (UnknownPropertyException, WrappedTargetException, RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing && rListener.is()) | |
{ | |
const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName ); | |
if (pCur) | |
aPropListeners.addInterface( pCur->nWID, rListener ); | |
else | |
throw UnknownPropertyException(); | |
} | |
} | |
void SAL_CALL SwXMailMerge::removePropertyChangeListener( | |
const OUString& rPropertyName, | |
const uno::Reference< beans::XPropertyChangeListener >& rListener ) | |
throw (UnknownPropertyException, WrappedTargetException, RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing && rListener.is()) | |
{ | |
const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName ); | |
if (pCur) | |
aPropListeners.removeInterface( pCur->nWID, rListener ); | |
else | |
throw UnknownPropertyException(); | |
} | |
} | |
void SAL_CALL SwXMailMerge::addVetoableChangeListener( | |
const OUString& /*rPropertyName*/, | |
const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ ) | |
throw (UnknownPropertyException, WrappedTargetException, RuntimeException) | |
{ | |
// no vetoable property, thus no support for vetoable change listeners | |
DBG_WARNING( "not implemented"); | |
} | |
void SAL_CALL SwXMailMerge::removeVetoableChangeListener( | |
const OUString& /*rPropertyName*/, | |
const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ ) | |
throw (UnknownPropertyException, WrappedTargetException, RuntimeException) | |
{ | |
// no vetoable property, thus no support for vetoable change listeners | |
DBG_WARNING( "not implemented"); | |
} | |
void SAL_CALL SwXMailMerge::dispose() | |
throw(RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing) | |
{ | |
bDisposing = sal_True; | |
EventObject aEvtObj( (XPropertySet *) this ); | |
aEvtListeners.disposeAndClear( aEvtObj ); | |
aMergeListeners.disposeAndClear( aEvtObj ); | |
aPropListeners.disposeAndClear( aEvtObj ); | |
} | |
} | |
void SAL_CALL SwXMailMerge::addEventListener( | |
const Reference< XEventListener >& rxListener ) | |
throw(RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing && rxListener.is()) | |
aEvtListeners.addInterface( rxListener ); | |
} | |
void SAL_CALL SwXMailMerge::removeEventListener( | |
const Reference< XEventListener >& rxListener ) | |
throw(RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing && rxListener.is()) | |
aEvtListeners.removeInterface( rxListener ); | |
} | |
void SAL_CALL SwXMailMerge::addMailMergeEventListener( | |
const uno::Reference< XMailMergeListener >& rxListener ) | |
throw (RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing && rxListener.is()) | |
aMergeListeners.addInterface( rxListener ); | |
} | |
void SAL_CALL SwXMailMerge::removeMailMergeEventListener( | |
const uno::Reference< XMailMergeListener >& rxListener ) | |
throw (RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
if (!bDisposing && rxListener.is()) | |
aMergeListeners.removeInterface( rxListener ); | |
} | |
OUString SAL_CALL SwXMailMerge::getImplementationName() | |
throw(RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
return SwXMailMerge_getImplementationName(); | |
} | |
sal_Bool SAL_CALL SwXMailMerge::supportsService( const OUString& rServiceName ) | |
throw(RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
return C2U( SN_MAIL_MERGE ) == rServiceName || | |
C2U( SN_DATA_ACCESS_DESCRIPTOR ) == rServiceName; | |
} | |
uno::Sequence< OUString > SAL_CALL SwXMailMerge::getSupportedServiceNames() | |
throw(RuntimeException) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
return SwXMailMerge_getSupportedServiceNames(); | |
} | |
//////////////////////////////////////////////////////////// | |
uno::Sequence< OUString > SAL_CALL SwXMailMerge_getSupportedServiceNames() | |
throw() | |
{ | |
uno::Sequence< OUString > aNames(2); | |
OUString *pName = aNames.getArray(); | |
pName[0] = C2U( SN_MAIL_MERGE ); | |
pName[1] = C2U( SN_DATA_ACCESS_DESCRIPTOR ); | |
return aNames; | |
} | |
OUString SAL_CALL SwXMailMerge_getImplementationName() | |
throw() | |
{ | |
return OUString( C2U( "SwXMailMerge" ) ); | |
} | |
uno::Reference< uno::XInterface > SAL_CALL SwXMailMerge_createInstance( | |
const uno::Reference< XMultiServiceFactory > & /*rSMgr*/) | |
throw( uno::Exception ) | |
{ | |
vos::OGuard aGuard( Application::GetSolarMutex() ); | |
//the module may not be loaded | |
SwDLL::Init(); | |
uno::Reference< uno::XInterface > xRef = (cppu::OWeakObject *) new SwXMailMerge(); | |
return xRef; | |
} | |