[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - sw/inc sw/source

Jan-Marek Glogowski glogow at fbihome.de
Mon Feb 13 08:21:20 UTC 2017


 sw/inc/dbmgr.hxx                |    1 
 sw/source/uibase/dbui/dbmgr.cxx |   78 +++++++++++++++++++++++++++++++++-------
 2 files changed, 67 insertions(+), 12 deletions(-)

New commits:
commit 25b0442d98e69072c961e403f5f03433c7a05b54
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jan 12 15:48:52 2017 +0100

    tdf#105288 MM wait until all emails are send
    
    Seems mail merge is now much faster then the sending of the merged
    documents via email. This is why the attached workaround patch to
    the tdf#103919 bug report, which simply sleeps after queuing a new
    message, helped solving the problem. It slows down the mail merge
    and gives time to the mail dispatcher thread.
    
    But we actually want to wait until all mails are send, so we have
    to add a listener and wait for the mail thread to become idle.
    
    This listener also allows us to cancel further mail merge when an
    SMTP error has occured.
    
    Reviewed-on: https://gerrit.libreoffice.org/33989
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit 5f2e1eda4532a52fe9f0f9d2017b37d566f25f33)
    
    Change-Id: I9d13bcd8f0d0ff084b20d72ab96f70afa3a764ba
    Reviewed-on: https://gerrit.libreoffice.org/34125
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index b124106..7a3d6d1 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -239,6 +239,7 @@ class SwDoc;
 class SW_DLLPUBLIC SwDBManager
 {
 friend class SwConnectionDisposedListener_Impl;
+    class MailDispatcherListener_Impl;
 
     enum class MergeStatus
     {
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 6052e11..2d85ff7 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -136,6 +136,7 @@
 #include <calc.hxx>
 #include <dbfld.hxx>
 #include <IDocumentState.hxx>
+#include <imaildsplistener.hxx>
 
 #include <memory>
 #include <comphelper/propertysequence.hxx>
@@ -300,10 +301,12 @@ void SwDataSourceRemovedListener::Dispose()
 
 struct SwDBManager_Impl
 {
-    SwDSParam*                    pMergeData;
+    SwDSParam                    *pMergeData;
     VclPtr<AbstractMailMergeDlg>  pMergeDialog;
     ::rtl::Reference<SwConnectionDisposedListener_Impl> m_xDisposeListener;
     rtl::Reference<SwDataSourceRemovedListener> m_xDataSourceRemovedListener;
+    osl::Mutex                    m_aAllEmailSendMutex;
+    uno::Reference< mail::XMailMessage> m_xLastMessage;
 
     explicit SwDBManager_Impl(SwDBManager& rDBManager)
        :pMergeData(nullptr)
@@ -1026,14 +1029,13 @@ static SfxObjectShell* lcl_CreateWorkingDocument(
     return xWorkObjectShell.get();
 }
 
-uno::Reference< mail::XMailMessage > lcl_CreateMailFromDoc(
+static SwMailMessage* lcl_CreateMailFromDoc(
     const SwMergeDescriptor &rMergeDescriptor,
     const OUString &sFileURL, const OUString &sMailRecipient,
     const OUString &sMailBodyMimeType, rtl_TextEncoding sMailEncoding,
     const OUString &sAttachmentMimeType )
 {
     SwMailMessage* pMessage = new SwMailMessage;
-    uno::Reference< mail::XMailMessage > xMessage = pMessage;
     if( rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo() )
         pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo());
     pMessage->addRecipient( sMailRecipient );
@@ -1056,7 +1058,7 @@ uno::Reference< mail::XMailMessage > lcl_CreateMailFromDoc(
         SvStream* pInStream = aMedium.GetInStream();
         assert( pInStream && "no output file created?" );
         if( !pInStream )
-            return xMessage;
+            return pMessage;
 
         pInStream->SetStreamCharSet( sMailEncoding );
         OString sLine;
@@ -1076,10 +1078,39 @@ uno::Reference< mail::XMailMessage > lcl_CreateMailFromDoc(
     for( const OUString& sBccRecipient : rMergeDescriptor.aBlindCopiesTo )
         pMessage->addBccRecipient( sBccRecipient );
 
-    xMessage = pMessage;
-    return xMessage;
+    return pMessage;
 }
 
+class SwDBManager::MailDispatcherListener_Impl : public IMailDispatcherListener
+{
+    SwDBManager &m_rDBManager;
+
+public:
+    explicit MailDispatcherListener_Impl( SwDBManager &rDBManager )
+        : m_rDBManager( rDBManager ) {}
+
+    virtual void started( ::rtl::Reference<MailDispatcher> ) override {};
+    virtual void stopped( ::rtl::Reference<MailDispatcher> ) override {};
+    virtual void idle( ::rtl::Reference<MailDispatcher> ) override {};
+
+    virtual void mailDelivered( ::rtl::Reference<MailDispatcher>,
+                 uno::Reference< mail::XMailMessage> xMessage ) override
+    {
+        osl::MutexGuard aGuard( m_rDBManager.pImpl->m_aAllEmailSendMutex );
+        if ( m_rDBManager.pImpl->m_xLastMessage == xMessage )
+            m_rDBManager.pImpl->m_xLastMessage.clear();
+    }
+
+    virtual void mailDeliveryError( ::rtl::Reference<MailDispatcher> xMailDispatcher,
+                uno::Reference< mail::XMailMessage>, const OUString& ) override
+    {
+        osl::MutexGuard aGuard( m_rDBManager.pImpl->m_aAllEmailSendMutex );
+        m_rDBManager.m_aMergeStatus = MergeStatus::ERROR;
+        m_rDBManager.pImpl->m_xLastMessage.clear();
+        xMailDispatcher->stop();
+    }
+};
+
 /**
  * Please have a look at the README in the same directory, before you make
  * larger changes in this function!
@@ -1126,7 +1157,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
             nMaxDumpDocs = OUString(sMaxDumpDocs, strlen(sMaxDumpDocs), osl_getThreadTextEncoding()).toInt32();
     }
 
-    ::rtl::Reference< MailDispatcher >  xMailDispatcher;
+    ::rtl::Reference< MailDispatcher >          xMailDispatcher;
+    ::rtl::Reference< IMailDispatcherListener > xMailListener;
     OUString                            sMailBodyMimeType;
     rtl_TextEncoding                    sMailEncoding = ::osl_getThreadTextEncoding();
 
@@ -1154,7 +1186,12 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
 
         if( bMT_EMAIL )
         {
-            xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer));
+            // Reset internal mail accounting data
+            pImpl->m_xLastMessage.clear();
+
+            xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer) );
+            xMailListener = new MailDispatcherListener_Impl( *this );
+            xMailDispatcher->addListener( xMailListener );
             if(!rMergeDescriptor.bSendAsAttachment && rMergeDescriptor.bSendAsHTML)
             {
                 sMailBodyMimeType = "text/html; charset=";
@@ -1491,6 +1528,8 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                             sMailEncoding, pStoreToFilter->GetMimeType() );
                         if( xMessage.is() )
                         {
+                            osl::MutexGuard aGuard( pImpl->m_aAllEmailSendMutex );
+                            pImpl->m_xLastMessage.set( xMessage );
                             xMailDispatcher->enqueueMailMessage( xMessage );
                             if( !xMailDispatcher->isStarted() )
                                 xMailDispatcher->start();
@@ -1600,10 +1639,6 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
 
     pProgressDlg.disposeAndClear();
 
-    // remove the temporary files
-    for( const OUString &sFileURL : aFilesToRemove )
-        SWUnoHelper::UCB_DeleteFile( sFileURL );
-
     // unlock all dispatchers
     pViewFrame = SfxViewFrame::GetFirst(pSourceDocSh);
     while (pViewFrame)
@@ -1616,10 +1651,29 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
 
     if( xMailDispatcher.is() )
     {
+        if( IsMergeOk() )
+        {
+            // TODO: Instead of polling via an AutoTimer, post an Idle event,
+            // if the main loop has been made thread-safe.
+            AutoTimer aEmailDispatcherPollTimer;
+            aEmailDispatcherPollTimer.SetDebugName(
+                "sw::SwDBManager aEmailDispatcherPollTimer" );
+            aEmailDispatcherPollTimer.SetTimeout( 500 );
+            aEmailDispatcherPollTimer.Start();
+            while( IsMergeOk() && pImpl->m_xLastMessage.is() )
+                Application::Yield();
+            aEmailDispatcherPollTimer.Stop();
+        }
         xMailDispatcher->stop();
         xMailDispatcher->shutdown();
     }
 
+    // remove the temporary files
+    // has to be done after xMailDispatcher is finished, as mails may be
+    // delivered as message attachments!
+    for( const OUString &sFileURL : aFilesToRemove )
+        SWUnoHelper::UCB_DeleteFile( sFileURL );
+
     return !IsMergeError();
 }
 


More information about the Libreoffice-commits mailing list