Kaydet (Commit) 1a12777f authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski Kaydeden (comit) Michael Stahl

Export MailMerge cancel functionality via UNO.

If you start a mail merge jobs via UNO, there is no way to cancel
it. But the functionality is already implemented and used by the
LO internal mail merge dialogs.

This patch adds an optional XCancellable interface to the MailMerge
service and implements it in the SwXMailMerge class.

As the XJob::execute function already uses the SolarMutex to
prevent parallel runs, XCancellable::cancel can be implemented by
storing the SwNewDBMgr in the private variable m_pMgr, protected by
a mutex.

The bCancel member has to be converted from a bitfield value to a
real boolean, because otherwise all bitfield values would have to
be protected by a mutex. Bitfield assignments aren't atomic as you
always have to replace at least a byte.

Change-Id: I007cc23fdf04ccfca7d3cd6180b0e17e99f53061
Reviewed-on: https://gerrit.libreoffice.org/7190Reviewed-by: 's avatarMichael Stahl <mstahl@redhat.com>
Tested-by: 's avatarMichael Stahl <mstahl@redhat.com>
üst 2eb142f4
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <com/sun/star/beans/XPropertySet.idl> #include <com/sun/star/beans/XPropertySet.idl>
#include <com/sun/star/text/XMailMergeBroadcaster.idl> #include <com/sun/star/text/XMailMergeBroadcaster.idl>
#include <com/sun/star/sdb/DataAccessDescriptor.idl> #include <com/sun/star/sdb/DataAccessDescriptor.idl>
#include <com/sun/star/util/XCancellable.idl>
module com { module sun { module star { module text { module com { module sun { module star { module text {
...@@ -51,6 +52,12 @@ published service MailMerge ...@@ -51,6 +52,12 @@ published service MailMerge
*/ */
interface com::sun::star::task::XJob; interface com::sun::star::task::XJob;
/** interface to cancel the current mail merge job.
@since LibreOffice 4.3
*/
[optional] interface com::sun::star::util::XCancellable;
/** interface to access the services properties. /** interface to access the services properties.
*/ */
interface com::sun::star::beans::XPropertySet; interface com::sun::star::beans::XPropertySet;
......
...@@ -190,10 +190,9 @@ friend class SwConnectionDisposedListener_Impl; ...@@ -190,10 +190,9 @@ friend class SwConnectionDisposedListener_Impl;
OUString sEMailAddrFld; ///< Mailing: Column name of email address. OUString sEMailAddrFld; ///< Mailing: Column name of email address.
OUString sSubject; ///< Mailing: Subject OUString sSubject; ///< Mailing: Subject
OUString sAttached; ///< Mailing: Attached Files. OUString sAttached; ///< Mailing: Attached Files.
sal_Bool bCancel; ///< Mail merge canceled.
sal_Bool bInitDBFields : 1; sal_Bool bInitDBFields : 1;
sal_Bool bSingleJobs : 1; ///< Printing job when called from Basic. sal_Bool bSingleJobs : 1; ///< Printing job when called from Basic.
sal_Bool bCancel : 1; ///< Mail merge save canceled.
sal_Bool bInMerge : 1; ///< merge process active sal_Bool bInMerge : 1; ///< merge process active
sal_Bool bMergeSilent : 1; ///< suppress display of dialogs/boxes (used when called over API) sal_Bool bMergeSilent : 1; ///< suppress display of dialogs/boxes (used when called over API)
sal_Bool bMergeLock : 1; /**< prevent update of database fields while document is sal_Bool bMergeLock : 1; /**< prevent update of database fields while document is
...@@ -233,6 +232,7 @@ public: ...@@ -233,6 +232,7 @@ public:
/// Merging of data records into fields. /// Merging of data records into fields.
sal_Bool MergeNew( const SwMergeDescriptor& rMergeDesc ); sal_Bool MergeNew( const SwMergeDescriptor& rMergeDesc );
sal_Bool Merge(SwWrtShell* pSh); sal_Bool Merge(SwWrtShell* pSh);
void MergeCancel();
/// Initialize data fields that lack name of database. /// Initialize data fields that lack name of database.
inline sal_Bool IsInitDBFields() const { return bInitDBFields; } inline sal_Bool IsInitDBFields() const { return bInitDBFields; }
......
...@@ -1355,10 +1355,15 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell, ...@@ -1355,10 +1355,15 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
return bNoError; return bNoError;
} }
void SwNewDBMgr::MergeCancel()
{
bCancel = sal_True;
}
IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton ) IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
{ {
pButton->GetParent()->Hide(); pButton->GetParent()->Hide();
bCancel = sal_True; MergeCancel();
return 0; return 0;
} }
IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton ) IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#ifndef INCLUDED_SW_SOURCE_UI_INC_UNOMAILMERGE_HXX #ifndef INCLUDED_SW_SOURCE_UI_INC_UNOMAILMERGE_HXX
#define INCLUDED_SW_SOURCE_UI_INC_UNOMAILMERGE_HXX #define INCLUDED_SW_SOURCE_UI_INC_UNOMAILMERGE_HXX
#include <cppuhelper/implbase5.hxx> #include <cppuhelper/implbase6.hxx>
#include <cppuhelper/interfacecontainer.hxx> #include <cppuhelper/interfacecontainer.hxx>
#include <unotools/configitem.hxx> #include <unotools/configitem.hxx>
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/PropertyChangeEvent.hpp> #include <com/sun/star/beans/PropertyChangeEvent.hpp>
#include <com/sun/star/text/XMailMergeBroadcaster.hpp> #include <com/sun/star/text/XMailMergeBroadcaster.hpp>
#include <com/sun/star/util/XCancellable.hpp>
#include <svl/itemprop.hxx> #include <svl/itemprop.hxx>
#include <sfx2/objsh.hxx> #include <sfx2/objsh.hxx>
...@@ -76,16 +77,22 @@ typedef cppu::OMultiTypeInterfaceContainerHelperVar ...@@ -76,16 +77,22 @@ typedef cppu::OMultiTypeInterfaceContainerHelperVar
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SwNewDBMgr;
class MailMergeExecuteFinalizer;
class SwXMailMerge : class SwXMailMerge :
public cppu::WeakImplHelper5 public cppu::WeakImplHelper6
< <
com::sun::star::task::XJob, com::sun::star::task::XJob,
com::sun::star::util::XCancellable,
com::sun::star::beans::XPropertySet, com::sun::star::beans::XPropertySet,
com::sun::star::text::XMailMergeBroadcaster, com::sun::star::text::XMailMergeBroadcaster,
com::sun::star::lang::XComponent, com::sun::star::lang::XComponent,
com::sun::star::lang::XServiceInfo com::sun::star::lang::XServiceInfo
> >
{ {
friend class MailMergeExecuteFinalizer;
cppu::OInterfaceContainerHelper aEvtListeners; cppu::OInterfaceContainerHelper aEvtListeners;
cppu::OInterfaceContainerHelper aMergeListeners; cppu::OInterfaceContainerHelper aMergeListeners;
OPropertyListenerContainerHelper aPropListeners; OPropertyListenerContainerHelper aPropListeners;
...@@ -133,6 +140,7 @@ class SwXMailMerge : ...@@ -133,6 +140,7 @@ class SwXMailMerge :
com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aSaveFilterData; com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aSaveFilterData;
sal_Bool bDisposing; sal_Bool bDisposing;
SwNewDBMgr *m_pMgr;
void launchEvent( const com::sun::star::beans::PropertyChangeEvent &rEvt ) const; void launchEvent( const com::sun::star::beans::PropertyChangeEvent &rEvt ) const;
...@@ -150,6 +158,9 @@ public: ...@@ -150,6 +158,9 @@ public:
// XJob // XJob
virtual ::com::sun::star::uno::Any SAL_CALL execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Any SAL_CALL execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
// XCancellable
virtual void SAL_CALL cancel() throw (com::sun::star::uno::RuntimeException);
// XPropertySet // XPropertySet
virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
......
...@@ -382,7 +382,8 @@ SwXMailMerge::SwXMailMerge() : ...@@ -382,7 +382,8 @@ SwXMailMerge::SwXMailMerge() :
bSendAsHTML(sal_False), bSendAsHTML(sal_False),
bSendAsAttachment(sal_False), bSendAsAttachment(sal_False),
bSaveAsSingleFile(sal_False), bSaveAsSingleFile(sal_False),
bDisposing(sal_False) bDisposing(sal_False),
m_pMgr(0)
{ {
// create empty document // create empty document
// like in: SwModule::InsertEnv (appenv.cxx) // like in: SwModule::InsertEnv (appenv.cxx)
...@@ -411,11 +412,31 @@ SwXMailMerge::~SwXMailMerge() ...@@ -411,11 +412,31 @@ SwXMailMerge::~SwXMailMerge()
} }
} }
// Guarantee object consistence in case of an exception
class MailMergeExecuteFinalizer {
public:
MailMergeExecuteFinalizer(SwXMailMerge *mailmerge) {
OSL_ENSURE( mailmerge, "mailmerge object missing" );
this->m_aMailMerge = mailmerge;
}
~MailMergeExecuteFinalizer() {
osl::MutexGuard pMgrGuard( GetMailMergeMutex() );
m_aMailMerge->m_pMgr = 0;
}
private:
// Disallow copy
MailMergeExecuteFinalizer(const MailMergeExecuteFinalizer&) {}
SwXMailMerge *m_aMailMerge;
};
uno::Any SAL_CALL SwXMailMerge::execute( uno::Any SAL_CALL SwXMailMerge::execute(
const uno::Sequence< beans::NamedValue >& rArguments ) const uno::Sequence< beans::NamedValue >& rArguments )
throw (IllegalArgumentException, Exception, RuntimeException) throw (IllegalArgumentException, Exception, RuntimeException)
{ {
SolarMutexGuard aGuard; SolarMutexGuard aGuard;
MailMergeExecuteFinalizer aFinalizer(this);
// get property values to be used // get property values to be used
// (use values from the service as default and override them with // (use values from the service as default and override them with
...@@ -655,6 +676,7 @@ uno::Any SAL_CALL SwXMailMerge::execute( ...@@ -655,6 +676,7 @@ uno::Any SAL_CALL SwXMailMerge::execute(
//force layout creation //force layout creation
rSh.CalcLayout(); rSh.CalcLayout();
OSL_ENSURE( pMgr, "database manager missing" ); OSL_ENSURE( pMgr, "database manager missing" );
m_pMgr = pMgr;
SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor ); SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor );
...@@ -798,6 +820,15 @@ uno::Any SAL_CALL SwXMailMerge::execute( ...@@ -798,6 +820,15 @@ uno::Any SAL_CALL SwXMailMerge::execute(
return makeAny( sal_True ); return makeAny( sal_True );
} }
void SAL_CALL SwXMailMerge::cancel() throw (com::sun::star::uno::RuntimeException)
{
// Cancel may be called from a second thread, so this protects from m_pMgr
/// cleanup in the execute function.
osl::MutexGuard pMgrGuard( GetMailMergeMutex() );
if (m_pMgr)
m_pMgr->MergeCancel();
}
void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const
{ {
cppu::OInterfaceIteratorHelper aIt( ((SwXMailMerge *) this)->aMergeListeners ); cppu::OInterfaceIteratorHelper aIt( ((SwXMailMerge *) this)->aMergeListeners );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment