Kaydet (Commit) 4f1293cf authored tarafından Michael Stahl's avatar Michael Stahl Kaydeden (comit) Fridrich Štrba

sw: move SwSendMailDialog etc. to swui library

It doesn't make sense to have a declaration in header in sw/source/ui
and the implementation in sw/source/uibase

Change-Id: I270b2102d1f006836bb6210bd7a6c1c2e4c1e431
üst 2467e1fd
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <sfx2/basedlgs.hxx> #include <sfx2/basedlgs.hxx>
#include <svtools/svtabbx.hxx> #include <svtools/svtabbx.hxx>
#include <svtools/headbar.hxx> #include <svtools/headbar.hxx>
#include "swdllapi.h"
#include "mailmergehelper.hxx" #include "mailmergehelper.hxx"
class SwMailMergeWizard; class SwMailMergeWizard;
...@@ -140,7 +139,7 @@ struct SwMailDescriptor ...@@ -140,7 +139,7 @@ struct SwMailDescriptor
}; };
struct SwSendMailDialog_Impl; struct SwSendMailDialog_Impl;
class SwMailMergeConfigItem; class SwMailMergeConfigItem;
class SW_DLLPUBLIC SwSendMailDialog : public ModelessDialog //SfxModalDialog class SwSendMailDialog : public ModelessDialog //SfxModalDialog
{ {
FixedLine m_aStatusFL; FixedLine m_aStatusFL;
FixedText m_aStatusFT; FixedText m_aStatusFT;
......
...@@ -58,4 +58,573 @@ IMPL_LINK_NOARG(SwMailMergeOutputTypePage, TypeHdl_Impl) ...@@ -58,4 +58,573 @@ IMPL_LINK_NOARG(SwMailMergeOutputTypePage, TypeHdl_Impl)
return 0; return 0;
} }
#include <rtl/ref.hxx>
#include <com/sun/star/mail/XSmtpService.hpp>
#include <comphelper/string.hxx>
#include <vcl/svapp.hxx>
#include <helpid.h>
#include <cmdid.h>
#include <../../uibase/dbui/mailmergechildwindow.hrc>
#include <swunohelper.hxx>
#include <mmoutputpage.hxx>
#include <maildispatcher.hxx>
#include <imaildsplistener.hxx>
using namespace ::com::sun::star;
struct SwSendMailDialog_Impl
{
friend class SwSendMailDialog;
::osl::Mutex aDescriptorMutex;
::std::vector< SwMailDescriptor > aDescriptors;
sal_uInt32 nCurrentDescriptor;
sal_uInt32 nDocumentCount;
::rtl::Reference< MailDispatcher > xMailDispatcher;
::rtl::Reference< IMailDispatcherListener> xMailListener;
uno::Reference< mail::XMailService > xConnectedMailService;
uno::Reference< mail::XMailService > xConnectedInMailService;
Timer aRemoveTimer;
SwSendMailDialog_Impl() :
nCurrentDescriptor(0),
nDocumentCount(0)
{
aRemoveTimer.SetTimeout(500);
}
~SwSendMailDialog_Impl()
{
// Shutdown must be called when the last reference to the
// mail dispatcher will be released in order to force a
// shutdown of the mail dispatcher thread.
// 'join' with the mail dispatcher thread leads to a
// deadlock (SolarMutex).
if( xMailDispatcher.is() && !xMailDispatcher->isShutdownRequested() )
xMailDispatcher->shutdown();
}
const SwMailDescriptor* GetNextDescriptor();
};
const SwMailDescriptor* SwSendMailDialog_Impl::GetNextDescriptor()
{
::osl::MutexGuard aGuard(aDescriptorMutex);
if(nCurrentDescriptor < aDescriptors.size())
{
++nCurrentDescriptor;
return &aDescriptors[nCurrentDescriptor - 1];
}
return 0;
}
using namespace ::com::sun::star;
class SwMailDispatcherListener_Impl : public IMailDispatcherListener
{
SwSendMailDialog* m_pSendMailDialog;
public:
SwMailDispatcherListener_Impl(SwSendMailDialog& rParentDlg);
virtual ~SwMailDispatcherListener_Impl();
virtual void started(::rtl::Reference<MailDispatcher> xMailDispatcher) SAL_OVERRIDE;
virtual void stopped(::rtl::Reference<MailDispatcher> xMailDispatcher) SAL_OVERRIDE;
virtual void idle(::rtl::Reference<MailDispatcher> xMailDispatcher) SAL_OVERRIDE;
virtual void mailDelivered(::rtl::Reference<MailDispatcher> xMailDispatcher,
uno::Reference< mail::XMailMessage> xMailMessage) SAL_OVERRIDE;
virtual void mailDeliveryError(::rtl::Reference<MailDispatcher> xMailDispatcher,
uno::Reference< mail::XMailMessage> xMailMessage, const OUString& sErrorMessage) SAL_OVERRIDE;
static void DeleteAttachments( uno::Reference< mail::XMailMessage >& xMessage );
};
SwMailDispatcherListener_Impl::SwMailDispatcherListener_Impl(SwSendMailDialog& rParentDlg) :
m_pSendMailDialog(&rParentDlg)
{
}
SwMailDispatcherListener_Impl::~SwMailDispatcherListener_Impl()
{
}
void SwMailDispatcherListener_Impl::started(::rtl::Reference<MailDispatcher> /*xMailDispatcher*/)
{
}
void SwMailDispatcherListener_Impl::stopped(
::rtl::Reference<MailDispatcher> /*xMailDispatcher*/)
{
}
void SwMailDispatcherListener_Impl::idle(::rtl::Reference<MailDispatcher> /*xMailDispatcher*/)
{
SolarMutexGuard aGuard;
m_pSendMailDialog->AllMailsSent();
}
void SwMailDispatcherListener_Impl::mailDelivered(
::rtl::Reference<MailDispatcher> /*xMailDispatcher*/,
uno::Reference< mail::XMailMessage> xMailMessage)
{
SolarMutexGuard aGuard;
m_pSendMailDialog->DocumentSent( xMailMessage, true, 0 );
DeleteAttachments( xMailMessage );
}
void SwMailDispatcherListener_Impl::mailDeliveryError(
::rtl::Reference<MailDispatcher> /*xMailDispatcher*/,
uno::Reference< mail::XMailMessage> xMailMessage,
const OUString& sErrorMessage)
{
SolarMutexGuard aGuard;
m_pSendMailDialog->DocumentSent( xMailMessage, false, &sErrorMessage );
DeleteAttachments( xMailMessage );
}
void SwMailDispatcherListener_Impl::DeleteAttachments( uno::Reference< mail::XMailMessage >& xMessage )
{
uno::Sequence< mail::MailAttachment > aAttachments = xMessage->getAttachments();
for(sal_Int32 nFile = 0; nFile < aAttachments.getLength(); ++nFile)
{
try
{
uno::Reference< beans::XPropertySet > xTransferableProperties( aAttachments[nFile].Data, uno::UNO_QUERY_THROW);
if( xTransferableProperties.is() )
{
OUString sURL;
xTransferableProperties->getPropertyValue("URL") >>= sURL;
if(!sURL.isEmpty())
SWUnoHelper::UCB_DeleteFile( sURL );
}
}
catch (const uno::Exception&)
{
}
}
}
class SwSendWarningBox_Impl : public MessageDialog
{
VclMultiLineEdit *m_pDetailED;
public:
SwSendWarningBox_Impl(Window* pParent, const OUString& rDetails);
};
SwSendWarningBox_Impl::SwSendWarningBox_Impl(Window* pParent, const OUString& rDetails)
: MessageDialog(pParent, "WarnEmailDialog", "modules/swriter/ui/warnemaildialog.ui")
{
get(m_pDetailED, "errors");
m_pDetailED->SetMaxTextWidth(80 * m_pDetailED->approximate_char_width());
m_pDetailED->set_width_request(80 * m_pDetailED->approximate_char_width());
m_pDetailED->set_height_request(8 * m_pDetailED->GetTextHeight());
m_pDetailED->SetText(rDetails);
}
#define ITEMID_TASK 1
#define ITEMID_STATUS 2
SwSendMailDialog::SwSendMailDialog(Window *pParent, SwMailMergeConfigItem& rConfigItem) :
ModelessDialog /*SfxModalDialog*/(pParent, SW_RES(DLG_MM_SENDMAILS)),
m_aStatusFL( this, SW_RES( FL_STATUS )),
m_aStatusFT( this, SW_RES( FT_STATUS1 )),
m_aTransferStatusFL( this, SW_RES( FL_TRANSFERSTATUS )),
m_aTransferStatusFT( this, SW_RES( FT_TRANSFERSTATUS )),
m_PausedFI(this, SW_RES( FI_PAUSED )),
m_aProgressBar( this, SW_RES( PB_PROGRESS )),
m_aErrorStatusFT( this, SW_RES( FT_ERRORSTATUS )),
m_aDetailsPB( this, SW_RES( PB_DETAILS )),
m_aStatusHB( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER ),
m_aStatusLB( this, SW_RES( LB_STATUS )),
m_aSeparatorFL( this, SW_RES( FL_SEPARATOR )),
m_aStopPB( this, SW_RES( PB_STOP )),
m_aClosePB( this, SW_RES( PB_CLOSE )),
m_sMore(m_aDetailsPB.GetText()),
m_sLess(SW_RES(ST_LESS)),
m_sContinue(SW_RES( ST_CONTINUE )),
m_sStop(m_aStopPB.GetText()),
m_sSend(SW_RES(ST_SEND)),
m_sTransferStatus(m_aTransferStatusFT.GetText()),
m_sErrorStatus( m_aErrorStatusFT.GetText()),
m_sSendingTo( SW_RES(ST_SENDINGTO )),
m_sCompleted( SW_RES(ST_COMPLETED )),
m_sFailed( SW_RES(ST_FAILED )),
m_sTerminateQuery( SW_RES( ST_TERMINATEQUERY )),
m_bCancel(false),
m_bDesctructionEnabled(false),
m_aImageList( SW_RES( ILIST ) ),
m_pImpl(new SwSendMailDialog_Impl),
m_pConfigItem(&rConfigItem),
m_nSendCount(0),
m_nErrorCount(0)
{
m_nStatusHeight = m_aSeparatorFL.GetPosPixel().Y() - m_aStatusLB.GetPosPixel().Y();
OUString sTask(SW_RES(ST_TASK));
OUString sStatus(SW_RES(ST_STATUS));
m_aStatusLB.SetHelpId(HID_MM_SENDMAILS_STATUSLB);
FreeResource();
m_aDetailsPB.SetClickHdl(LINK( this, SwSendMailDialog, DetailsHdl_Impl));
m_aStopPB.SetClickHdl(LINK( this, SwSendMailDialog, StopHdl_Impl));
m_aClosePB.SetClickHdl(LINK( this, SwSendMailDialog, CloseHdl_Impl));
Size aLBSize(m_aStatusLB.GetSizePixel());
m_aStatusHB.SetSizePixel(aLBSize);
Size aHeadSize(m_aStatusHB.CalcWindowSizePixel());
aHeadSize.Width() = aLBSize.Width();
m_aStatusHB.SetSizePixel(aHeadSize);
Point aLBPos(m_aStatusLB.GetPosPixel());
m_aStatusHB.SetPosPixel(aLBPos);
aLBPos.Y() += aHeadSize.Height();
aLBSize.Height() -= aHeadSize.Height();
m_aStatusLB.SetPosSizePixel(aLBPos, aLBSize);
Size aSz(m_aStatusHB.GetOutputSizePixel());
long nPos1 = aSz.Width()/3 * 2;
long nPos2 = aSz.Width()/3;
m_aStatusHB.InsertItem( ITEMID_TASK, sTask,
nPos1,
HIB_LEFT | HIB_VCENTER );
m_aStatusHB.InsertItem( ITEMID_STATUS, sStatus,
nPos2,
HIB_LEFT | HIB_VCENTER );
m_aStatusHB.SetHelpId(HID_MM_ADDRESSLIST_HB );
m_aStatusHB.Show();
m_aStatusLB.SetHelpId(HID_MM_MAILSTATUS_TLB);
static long nTabs[] = {3, 0, nPos1, aSz.Width() };
m_aStatusLB.SetStyle( m_aStatusLB.GetStyle() | WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP );
m_aStatusLB.SetSelectionMode( SINGLE_SELECTION );
m_aStatusLB.SetTabs(&nTabs[0], MAP_PIXEL);
m_aStatusLB.SetSpaceBetweenEntries(3);
DetailsHdl_Impl( &m_aDetailsPB );
UpdateTransferStatus();
}
SwSendMailDialog::~SwSendMailDialog()
{
if(m_pImpl->xMailDispatcher.is())
{
try
{
if(m_pImpl->xMailDispatcher->isStarted())
m_pImpl->xMailDispatcher->stop();
if(m_pImpl->xConnectedMailService.is() && m_pImpl->xConnectedMailService->isConnected())
m_pImpl->xConnectedMailService->disconnect();
if(m_pImpl->xConnectedInMailService.is() && m_pImpl->xConnectedInMailService->isConnected())
m_pImpl->xConnectedInMailService->disconnect();
uno::Reference<mail::XMailMessage> xMessage =
m_pImpl->xMailDispatcher->dequeueMailMessage();
while(xMessage.is())
{
SwMailDispatcherListener_Impl::DeleteAttachments( xMessage );
xMessage = m_pImpl->xMailDispatcher->dequeueMailMessage();
}
}
catch (const uno::Exception&)
{
}
}
delete m_pImpl;
}
void SwSendMailDialog::AddDocument( SwMailDescriptor& rDesc )
{
::osl::MutexGuard aGuard(m_pImpl->aDescriptorMutex);
m_pImpl->aDescriptors.push_back(rDesc);
// if the dialog is already running then continue sending of documents
if(m_pImpl->xMailDispatcher.is())
{
IterateMails();
}
}
void SwSendMailDialog::SetDocumentCount( sal_Int32 nAllDocuments )
{
m_pImpl->nDocumentCount = nAllDocuments;
UpdateTransferStatus();
}
static void lcl_Move(Control& rCtrl, long nYOffset)
{
Point aPos(rCtrl.GetPosPixel());
aPos.Y() += nYOffset;
rCtrl.SetPosPixel(aPos);
}
IMPL_LINK_NOARG(SwSendMailDialog, DetailsHdl_Impl)
{
long nMove = 0;
if(m_aStatusLB.IsVisible())
{
m_aStatusLB.Hide();
m_aStatusHB.Hide();
nMove = - m_nStatusHeight;
m_aDetailsPB.SetText(m_sMore);
}
else
{
m_aStatusLB.Show();
m_aStatusHB.Show();
nMove = m_nStatusHeight;
m_aDetailsPB.SetText(m_sLess);
}
lcl_Move(m_aSeparatorFL, nMove);
lcl_Move(m_aStopPB, nMove);
lcl_Move(m_aClosePB, nMove);
Size aDlgSize = GetSizePixel(); aDlgSize.Height() += nMove; SetSizePixel(aDlgSize);
return 0;
}
IMPL_LINK( SwSendMailDialog, StopHdl_Impl, PushButton*, pButton )
{
m_bCancel = true;
if(m_pImpl->xMailDispatcher.is())
{
if(m_pImpl->xMailDispatcher->isStarted())
{
m_pImpl->xMailDispatcher->stop();
pButton->SetText(m_sContinue);
m_PausedFI.Show();
}
else
{
m_pImpl->xMailDispatcher->start();
pButton->SetText(m_sStop);
m_PausedFI.Show(false);
}
}
return 0;
}
IMPL_LINK_NOARG(SwSendMailDialog, CloseHdl_Impl)
{
ModelessDialog::Show( false );
return 0;
}
IMPL_STATIC_LINK_NOINSTANCE( SwSendMailDialog, StartSendMails, SwSendMailDialog*, pDialog )
{
pDialog->SendMails();
return 0;
}
IMPL_STATIC_LINK( SwSendMailDialog, RemoveThis, Timer*, pTimer )
{
if( pThis->m_pImpl->xMailDispatcher.is() )
{
if(pThis->m_pImpl->xMailDispatcher->isStarted())
pThis->m_pImpl->xMailDispatcher->stop();
if(!pThis->m_pImpl->xMailDispatcher->isShutdownRequested())
pThis->m_pImpl->xMailDispatcher->shutdown();
}
if( pThis->m_bDesctructionEnabled &&
(!pThis->m_pImpl->xMailDispatcher.is() ||
!pThis->m_pImpl->xMailDispatcher->isRunning()))
{
delete pThis;
}
else
{
pTimer->Start();
}
return 0;
}
IMPL_STATIC_LINK_NOINSTANCE( SwSendMailDialog, StopSendMails, SwSendMailDialog*, pDialog )
{
if(pDialog->m_pImpl->xMailDispatcher.is() &&
pDialog->m_pImpl->xMailDispatcher->isStarted())
{
pDialog->m_pImpl->xMailDispatcher->stop();
pDialog->m_aStopPB.SetText(pDialog->m_sContinue);
pDialog->m_PausedFI.Show();
}
return 0;
}
void SwSendMailDialog::SendMails()
{
if(!m_pConfigItem)
{
OSL_FAIL("config item not set");
return;
}
EnterWait();
//get a mail server connection
uno::Reference< mail::XSmtpService > xSmtpServer =
SwMailMergeHelper::ConnectToSmtpServer( *m_pConfigItem,
m_pImpl->xConnectedInMailService,
aEmptyOUStr, aEmptyOUStr, this );
bool bIsLoggedIn = xSmtpServer.is() && xSmtpServer->isConnected();
LeaveWait();
if(!bIsLoggedIn)
{
OSL_FAIL("create error message");
return;
}
m_pImpl->xMailDispatcher.set( new MailDispatcher(xSmtpServer));
IterateMails();
m_pImpl->xMailListener = new SwMailDispatcherListener_Impl(*this);
m_pImpl->xMailDispatcher->addListener(m_pImpl->xMailListener);
if(!m_bCancel)
{
m_pImpl->xMailDispatcher->start();
}
}
void SwSendMailDialog::IterateMails()
{
const SwMailDescriptor* pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
while( pCurrentMailDescriptor )
{
if(!SwMailMergeHelper::CheckMailAddress( pCurrentMailDescriptor->sEMail ))
{
Image aInsertImg = m_aImageList.GetImage( FN_FORMULA_CANCEL );
OUString sMessage = m_sSendingTo;
OUString sTmp(pCurrentMailDescriptor->sEMail);
sTmp += "\t";
sTmp += m_sFailed;
m_aStatusLB.InsertEntry( sMessage.replaceFirst("%1", sTmp), aInsertImg, aInsertImg);
++m_nSendCount;
++m_nErrorCount;
UpdateTransferStatus( );
pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
continue;
}
SwMailMessage* pMessage = new SwMailMessage;
uno::Reference< mail::XMailMessage > xMessage = pMessage;
if(m_pConfigItem->IsMailReplyTo())
pMessage->setReplyToAddress(m_pConfigItem->GetMailReplyTo());
pMessage->addRecipient( pCurrentMailDescriptor->sEMail );
pMessage->SetSenderName( m_pConfigItem->GetMailDisplayName() );
pMessage->SetSenderAddress( m_pConfigItem->GetMailAddress() );
if(!pCurrentMailDescriptor->sAttachmentURL.isEmpty())
{
mail::MailAttachment aAttach;
aAttach.Data =
new SwMailTransferable(
pCurrentMailDescriptor->sAttachmentURL,
pCurrentMailDescriptor->sAttachmentName,
pCurrentMailDescriptor->sMimeType );
aAttach.ReadableName = pCurrentMailDescriptor->sAttachmentName;
pMessage->addAttachment( aAttach );
}
pMessage->setSubject( pCurrentMailDescriptor->sSubject );
uno::Reference< datatransfer::XTransferable> xBody =
new SwMailTransferable(
pCurrentMailDescriptor->sBodyContent,
pCurrentMailDescriptor->sBodyMimeType);
pMessage->setBody( xBody );
//CC and BCC are tokenized by ';'
if(!pCurrentMailDescriptor->sCC.isEmpty())
{
OUString sTokens( pCurrentMailDescriptor->sCC );
sal_uInt16 nTokens = comphelper::string::getTokenCount(sTokens, ';');
sal_Int32 nPos = 0;
for( sal_uInt16 nToken = 0; nToken < nTokens; ++nToken)
{
OUString sTmp = sTokens.getToken( 0, ';', nPos);
if( !sTmp.isEmpty() )
pMessage->addCcRecipient( sTmp );
}
}
if(!pCurrentMailDescriptor->sBCC.isEmpty())
{
OUString sTokens( pCurrentMailDescriptor->sBCC );
sal_uInt16 nTokens = comphelper::string::getTokenCount(sTokens, ';');
sal_Int32 nPos = 0;
for( sal_uInt16 nToken = 0; nToken < nTokens; ++nToken)
{
OUString sTmp = sTokens.getToken( 0, ';', nPos);
if( !sTmp.isEmpty() )
pMessage->addBccRecipient( sTmp );
}
}
m_pImpl->xMailDispatcher->enqueueMailMessage( xMessage );
pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
}
UpdateTransferStatus();
}
void SwSendMailDialog::ShowDialog()
{
Application::PostUserEvent( STATIC_LINK( this, SwSendMailDialog,
StartSendMails ), this );
ModelessDialog::Show();
}
void SwSendMailDialog::StateChanged( StateChangedType nStateChange )
{
ModelessDialog::StateChanged( nStateChange );
if(STATE_CHANGE_VISIBLE == nStateChange && !IsVisible())
{
m_pImpl->aRemoveTimer.SetTimeoutHdl( STATIC_LINK( this, SwSendMailDialog,
RemoveThis ) );
m_pImpl->aRemoveTimer.Start();
}
}
void SwSendMailDialog::DocumentSent( uno::Reference< mail::XMailMessage> xMessage,
bool bResult,
const OUString* pError )
{
//sending should stop on send errors
if(pError &&
m_pImpl->xMailDispatcher.is() && m_pImpl->xMailDispatcher->isStarted())
{
Application::PostUserEvent( STATIC_LINK( this, SwSendMailDialog,
StopSendMails ), this );
}
Image aInsertImg = m_aImageList.GetImage( bResult ? FN_FORMULA_APPLY : FN_FORMULA_CANCEL );
OUString sMessage = m_sSendingTo;
OUString sTmp(xMessage->getRecipients()[0]);
sTmp += "\t";
sTmp += bResult ? m_sCompleted : m_sFailed;
m_aStatusLB.InsertEntry( sMessage.replaceFirst("%1", sTmp), aInsertImg, aInsertImg);
++m_nSendCount;
if(!bResult)
++m_nErrorCount;
UpdateTransferStatus( );
if (pError)
{
SwSendWarningBox_Impl* pDlg = new SwSendWarningBox_Impl(0, *pError);
pDlg->Execute();
delete pDlg;
}
}
void SwSendMailDialog::UpdateTransferStatus()
{
OUString sStatus( m_sTransferStatus );
sStatus = sStatus.replaceFirst("%1", OUString::number(m_nSendCount) );
sStatus = sStatus.replaceFirst("%2", OUString::number(m_pImpl->aDescriptors.size()));
m_aTransferStatusFT.SetText(sStatus);
sStatus = m_sErrorStatus.replaceFirst("%1", OUString::number(m_nErrorCount) );
m_aErrorStatusFT.SetText(sStatus);
if(m_pImpl->aDescriptors.size())
m_aProgressBar.SetValue((sal_uInt16)(m_nSendCount * 100 / m_pImpl->aDescriptors.size()));
else
m_aProgressBar.SetValue(0);
}
void SwSendMailDialog::AllMailsSent()
{
m_aStopPB.Enable(false);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -25,18 +25,8 @@ ...@@ -25,18 +25,8 @@
#include <view.hxx> #include <view.hxx>
#include <edtwin.hxx> #include <edtwin.hxx>
#include <vcl/layout.hxx> #include <vcl/layout.hxx>
#include <vcl/svapp.hxx>
#include <mailmergechildwindow.hxx> #include <mailmergechildwindow.hxx>
#include <../../ui/dbui/mmoutputpage.hxx>
#include <mmconfigitem.hxx> #include <mmconfigitem.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/string.hxx>
#include <com/sun/star/mail/XSmtpService.hpp>
#include <com/sun/star/mail/MailServiceType.hpp>
#include <rtl/ref.hxx>
#include <maildispatcher.hxx>
#include <imaildsplistener.hxx>
#include <swunohelper.hxx>
#include <svtools/svmedit.hxx> #include <svtools/svmedit.hxx>
#include <vcl/msgbox.hxx> #include <vcl/msgbox.hxx>
#include <vcl/image.hxx> #include <vcl/image.hxx>
...@@ -111,556 +101,4 @@ void SwMailMergeChildWin::FillInfo(SfxChildWinInfo& rInfo) const ...@@ -111,556 +101,4 @@ void SwMailMergeChildWin::FillInfo(SfxChildWinInfo& rInfo) const
rInfo.bVisible = false; rInfo.bVisible = false;
} }
struct SwSendMailDialog_Impl
{
friend class SwSendMailDialog;
::osl::Mutex aDescriptorMutex;
::std::vector< SwMailDescriptor > aDescriptors;
sal_uInt32 nCurrentDescriptor;
sal_uInt32 nDocumentCount;
::rtl::Reference< MailDispatcher > xMailDispatcher;
::rtl::Reference< IMailDispatcherListener> xMailListener;
uno::Reference< mail::XMailService > xConnectedMailService;
uno::Reference< mail::XMailService > xConnectedInMailService;
Timer aRemoveTimer;
SwSendMailDialog_Impl() :
nCurrentDescriptor(0),
nDocumentCount(0)
{
aRemoveTimer.SetTimeout(500);
}
~SwSendMailDialog_Impl()
{
// Shutdown must be called when the last reference to the
// mail dispatcher will be released in order to force a
// shutdown of the mail dispatcher thread.
// 'join' with the mail dispatcher thread leads to a
// deadlock (SolarMutex).
if( xMailDispatcher.is() && !xMailDispatcher->isShutdownRequested() )
xMailDispatcher->shutdown();
}
const SwMailDescriptor* GetNextDescriptor();
};
const SwMailDescriptor* SwSendMailDialog_Impl::GetNextDescriptor()
{
::osl::MutexGuard aGuard(aDescriptorMutex);
if(nCurrentDescriptor < aDescriptors.size())
{
++nCurrentDescriptor;
return &aDescriptors[nCurrentDescriptor - 1];
}
return 0;
}
class SwMailDispatcherListener_Impl : public IMailDispatcherListener
{
SwSendMailDialog* m_pSendMailDialog;
public:
SwMailDispatcherListener_Impl(SwSendMailDialog& rParentDlg);
virtual ~SwMailDispatcherListener_Impl();
virtual void started(::rtl::Reference<MailDispatcher> xMailDispatcher) SAL_OVERRIDE;
virtual void stopped(::rtl::Reference<MailDispatcher> xMailDispatcher) SAL_OVERRIDE;
virtual void idle(::rtl::Reference<MailDispatcher> xMailDispatcher) SAL_OVERRIDE;
virtual void mailDelivered(::rtl::Reference<MailDispatcher> xMailDispatcher,
uno::Reference< mail::XMailMessage> xMailMessage) SAL_OVERRIDE;
virtual void mailDeliveryError(::rtl::Reference<MailDispatcher> xMailDispatcher,
uno::Reference< mail::XMailMessage> xMailMessage, const OUString& sErrorMessage) SAL_OVERRIDE;
static void DeleteAttachments( uno::Reference< mail::XMailMessage >& xMessage );
};
SwMailDispatcherListener_Impl::SwMailDispatcherListener_Impl(SwSendMailDialog& rParentDlg) :
m_pSendMailDialog(&rParentDlg)
{
}
SwMailDispatcherListener_Impl::~SwMailDispatcherListener_Impl()
{
}
void SwMailDispatcherListener_Impl::started(::rtl::Reference<MailDispatcher> /*xMailDispatcher*/)
{
}
void SwMailDispatcherListener_Impl::stopped(
::rtl::Reference<MailDispatcher> /*xMailDispatcher*/)
{
}
void SwMailDispatcherListener_Impl::idle(::rtl::Reference<MailDispatcher> /*xMailDispatcher*/)
{
SolarMutexGuard aGuard;
m_pSendMailDialog->AllMailsSent();
}
void SwMailDispatcherListener_Impl::mailDelivered(
::rtl::Reference<MailDispatcher> /*xMailDispatcher*/,
uno::Reference< mail::XMailMessage> xMailMessage)
{
SolarMutexGuard aGuard;
m_pSendMailDialog->DocumentSent( xMailMessage, true, 0 );
DeleteAttachments( xMailMessage );
}
void SwMailDispatcherListener_Impl::mailDeliveryError(
::rtl::Reference<MailDispatcher> /*xMailDispatcher*/,
uno::Reference< mail::XMailMessage> xMailMessage,
const OUString& sErrorMessage)
{
SolarMutexGuard aGuard;
m_pSendMailDialog->DocumentSent( xMailMessage, false, &sErrorMessage );
DeleteAttachments( xMailMessage );
}
void SwMailDispatcherListener_Impl::DeleteAttachments( uno::Reference< mail::XMailMessage >& xMessage )
{
uno::Sequence< mail::MailAttachment > aAttachments = xMessage->getAttachments();
for(sal_Int32 nFile = 0; nFile < aAttachments.getLength(); ++nFile)
{
try
{
uno::Reference< beans::XPropertySet > xTransferableProperties( aAttachments[nFile].Data, uno::UNO_QUERY_THROW);
if( xTransferableProperties.is() )
{
OUString sURL;
xTransferableProperties->getPropertyValue("URL") >>= sURL;
if(!sURL.isEmpty())
SWUnoHelper::UCB_DeleteFile( sURL );
}
}
catch (const uno::Exception&)
{
}
}
}
class SwSendWarningBox_Impl : public MessageDialog
{
VclMultiLineEdit *m_pDetailED;
public:
SwSendWarningBox_Impl(Window* pParent, const OUString& rDetails);
};
SwSendWarningBox_Impl::SwSendWarningBox_Impl(Window* pParent, const OUString& rDetails)
: MessageDialog(pParent, "WarnEmailDialog", "modules/swriter/ui/warnemaildialog.ui")
{
get(m_pDetailED, "errors");
m_pDetailED->SetMaxTextWidth(80 * m_pDetailED->approximate_char_width());
m_pDetailED->set_width_request(80 * m_pDetailED->approximate_char_width());
m_pDetailED->set_height_request(8 * m_pDetailED->GetTextHeight());
m_pDetailED->SetText(rDetails);
}
#define ITEMID_TASK 1
#define ITEMID_STATUS 2
SwSendMailDialog::SwSendMailDialog(Window *pParent, SwMailMergeConfigItem& rConfigItem) :
ModelessDialog /*SfxModalDialog*/(pParent, SW_RES(DLG_MM_SENDMAILS)),
m_aStatusFL( this, SW_RES( FL_STATUS )),
m_aStatusFT( this, SW_RES( FT_STATUS1 )),
m_aTransferStatusFL( this, SW_RES( FL_TRANSFERSTATUS )),
m_aTransferStatusFT( this, SW_RES( FT_TRANSFERSTATUS )),
m_PausedFI(this, SW_RES( FI_PAUSED )),
m_aProgressBar( this, SW_RES( PB_PROGRESS )),
m_aErrorStatusFT( this, SW_RES( FT_ERRORSTATUS )),
m_aDetailsPB( this, SW_RES( PB_DETAILS )),
m_aStatusHB( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER ),
m_aStatusLB( this, SW_RES( LB_STATUS )),
m_aSeparatorFL( this, SW_RES( FL_SEPARATOR )),
m_aStopPB( this, SW_RES( PB_STOP )),
m_aClosePB( this, SW_RES( PB_CLOSE )),
m_sMore(m_aDetailsPB.GetText()),
m_sLess(SW_RES(ST_LESS)),
m_sContinue(SW_RES( ST_CONTINUE )),
m_sStop(m_aStopPB.GetText()),
m_sSend(SW_RES(ST_SEND)),
m_sTransferStatus(m_aTransferStatusFT.GetText()),
m_sErrorStatus( m_aErrorStatusFT.GetText()),
m_sSendingTo( SW_RES(ST_SENDINGTO )),
m_sCompleted( SW_RES(ST_COMPLETED )),
m_sFailed( SW_RES(ST_FAILED )),
m_sTerminateQuery( SW_RES( ST_TERMINATEQUERY )),
m_bCancel(false),
m_bDesctructionEnabled(false),
m_aImageList( SW_RES( ILIST ) ),
m_pImpl(new SwSendMailDialog_Impl),
m_pConfigItem(&rConfigItem),
m_nSendCount(0),
m_nErrorCount(0)
{
m_nStatusHeight = m_aSeparatorFL.GetPosPixel().Y() - m_aStatusLB.GetPosPixel().Y();
OUString sTask(SW_RES(ST_TASK));
OUString sStatus(SW_RES(ST_STATUS));
m_aStatusLB.SetHelpId(HID_MM_SENDMAILS_STATUSLB);
FreeResource();
m_aDetailsPB.SetClickHdl(LINK( this, SwSendMailDialog, DetailsHdl_Impl));
m_aStopPB.SetClickHdl(LINK( this, SwSendMailDialog, StopHdl_Impl));
m_aClosePB.SetClickHdl(LINK( this, SwSendMailDialog, CloseHdl_Impl));
Size aLBSize(m_aStatusLB.GetSizePixel());
m_aStatusHB.SetSizePixel(aLBSize);
Size aHeadSize(m_aStatusHB.CalcWindowSizePixel());
aHeadSize.Width() = aLBSize.Width();
m_aStatusHB.SetSizePixel(aHeadSize);
Point aLBPos(m_aStatusLB.GetPosPixel());
m_aStatusHB.SetPosPixel(aLBPos);
aLBPos.Y() += aHeadSize.Height();
aLBSize.Height() -= aHeadSize.Height();
m_aStatusLB.SetPosSizePixel(aLBPos, aLBSize);
Size aSz(m_aStatusHB.GetOutputSizePixel());
long nPos1 = aSz.Width()/3 * 2;
long nPos2 = aSz.Width()/3;
m_aStatusHB.InsertItem( ITEMID_TASK, sTask,
nPos1,
HIB_LEFT | HIB_VCENTER );
m_aStatusHB.InsertItem( ITEMID_STATUS, sStatus,
nPos2,
HIB_LEFT | HIB_VCENTER );
m_aStatusHB.SetHelpId(HID_MM_ADDRESSLIST_HB );
m_aStatusHB.Show();
m_aStatusLB.SetHelpId(HID_MM_MAILSTATUS_TLB);
static long nTabs[] = {3, 0, nPos1, aSz.Width() };
m_aStatusLB.SetStyle( m_aStatusLB.GetStyle() | WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP );
m_aStatusLB.SetSelectionMode( SINGLE_SELECTION );
m_aStatusLB.SetTabs(&nTabs[0], MAP_PIXEL);
m_aStatusLB.SetSpaceBetweenEntries(3);
DetailsHdl_Impl( &m_aDetailsPB );
UpdateTransferStatus();
}
SwSendMailDialog::~SwSendMailDialog()
{
if(m_pImpl->xMailDispatcher.is())
{
try
{
if(m_pImpl->xMailDispatcher->isStarted())
m_pImpl->xMailDispatcher->stop();
if(m_pImpl->xConnectedMailService.is() && m_pImpl->xConnectedMailService->isConnected())
m_pImpl->xConnectedMailService->disconnect();
if(m_pImpl->xConnectedInMailService.is() && m_pImpl->xConnectedInMailService->isConnected())
m_pImpl->xConnectedInMailService->disconnect();
uno::Reference<mail::XMailMessage> xMessage =
m_pImpl->xMailDispatcher->dequeueMailMessage();
while(xMessage.is())
{
SwMailDispatcherListener_Impl::DeleteAttachments( xMessage );
xMessage = m_pImpl->xMailDispatcher->dequeueMailMessage();
}
}
catch (const uno::Exception&)
{
}
}
delete m_pImpl;
}
void SwSendMailDialog::AddDocument( SwMailDescriptor& rDesc )
{
::osl::MutexGuard aGuard(m_pImpl->aDescriptorMutex);
m_pImpl->aDescriptors.push_back(rDesc);
// if the dialog is already running then continue sending of documents
if(m_pImpl->xMailDispatcher.is())
{
IterateMails();
}
}
void SwSendMailDialog::SetDocumentCount( sal_Int32 nAllDocuments )
{
m_pImpl->nDocumentCount = nAllDocuments;
UpdateTransferStatus();
}
static void lcl_Move(Control& rCtrl, long nYOffset)
{
Point aPos(rCtrl.GetPosPixel());
aPos.Y() += nYOffset;
rCtrl.SetPosPixel(aPos);
}
IMPL_LINK_NOARG(SwSendMailDialog, DetailsHdl_Impl)
{
long nMove = 0;
if(m_aStatusLB.IsVisible())
{
m_aStatusLB.Hide();
m_aStatusHB.Hide();
nMove = - m_nStatusHeight;
m_aDetailsPB.SetText(m_sMore);
}
else
{
m_aStatusLB.Show();
m_aStatusHB.Show();
nMove = m_nStatusHeight;
m_aDetailsPB.SetText(m_sLess);
}
lcl_Move(m_aSeparatorFL, nMove);
lcl_Move(m_aStopPB, nMove);
lcl_Move(m_aClosePB, nMove);
Size aDlgSize = GetSizePixel(); aDlgSize.Height() += nMove; SetSizePixel(aDlgSize);
return 0;
}
IMPL_LINK( SwSendMailDialog, StopHdl_Impl, PushButton*, pButton )
{
m_bCancel = true;
if(m_pImpl->xMailDispatcher.is())
{
if(m_pImpl->xMailDispatcher->isStarted())
{
m_pImpl->xMailDispatcher->stop();
pButton->SetText(m_sContinue);
m_PausedFI.Show();
}
else
{
m_pImpl->xMailDispatcher->start();
pButton->SetText(m_sStop);
m_PausedFI.Show(false);
}
}
return 0;
}
IMPL_LINK_NOARG(SwSendMailDialog, CloseHdl_Impl)
{
ModelessDialog::Show( false );
return 0;
}
IMPL_STATIC_LINK_NOINSTANCE( SwSendMailDialog, StartSendMails, SwSendMailDialog*, pDialog )
{
pDialog->SendMails();
return 0;
}
IMPL_STATIC_LINK( SwSendMailDialog, RemoveThis, Timer*, pTimer )
{
if( pThis->m_pImpl->xMailDispatcher.is() )
{
if(pThis->m_pImpl->xMailDispatcher->isStarted())
pThis->m_pImpl->xMailDispatcher->stop();
if(!pThis->m_pImpl->xMailDispatcher->isShutdownRequested())
pThis->m_pImpl->xMailDispatcher->shutdown();
}
if( pThis->m_bDesctructionEnabled &&
(!pThis->m_pImpl->xMailDispatcher.is() ||
!pThis->m_pImpl->xMailDispatcher->isRunning()))
{
delete pThis;
}
else
{
pTimer->Start();
}
return 0;
}
IMPL_STATIC_LINK_NOINSTANCE( SwSendMailDialog, StopSendMails, SwSendMailDialog*, pDialog )
{
if(pDialog->m_pImpl->xMailDispatcher.is() &&
pDialog->m_pImpl->xMailDispatcher->isStarted())
{
pDialog->m_pImpl->xMailDispatcher->stop();
pDialog->m_aStopPB.SetText(pDialog->m_sContinue);
pDialog->m_PausedFI.Show();
}
return 0;
}
void SwSendMailDialog::SendMails()
{
if(!m_pConfigItem)
{
OSL_FAIL("config item not set");
return;
}
EnterWait();
//get a mail server connection
uno::Reference< mail::XSmtpService > xSmtpServer =
SwMailMergeHelper::ConnectToSmtpServer( *m_pConfigItem,
m_pImpl->xConnectedInMailService,
aEmptyOUStr, aEmptyOUStr, this );
bool bIsLoggedIn = xSmtpServer.is() && xSmtpServer->isConnected();
LeaveWait();
if(!bIsLoggedIn)
{
OSL_FAIL("create error message");
return;
}
m_pImpl->xMailDispatcher.set( new MailDispatcher(xSmtpServer));
IterateMails();
m_pImpl->xMailListener = new SwMailDispatcherListener_Impl(*this);
m_pImpl->xMailDispatcher->addListener(m_pImpl->xMailListener);
if(!m_bCancel)
{
m_pImpl->xMailDispatcher->start();
}
}
void SwSendMailDialog::IterateMails()
{
const SwMailDescriptor* pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
while( pCurrentMailDescriptor )
{
if(!SwMailMergeHelper::CheckMailAddress( pCurrentMailDescriptor->sEMail ))
{
Image aInsertImg = m_aImageList.GetImage( FN_FORMULA_CANCEL );
OUString sMessage = m_sSendingTo;
OUString sTmp(pCurrentMailDescriptor->sEMail);
sTmp += "\t";
sTmp += m_sFailed;
m_aStatusLB.InsertEntry( sMessage.replaceFirst("%1", sTmp), aInsertImg, aInsertImg);
++m_nSendCount;
++m_nErrorCount;
UpdateTransferStatus( );
pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
continue;
}
SwMailMessage* pMessage = new SwMailMessage;
uno::Reference< mail::XMailMessage > xMessage = pMessage;
if(m_pConfigItem->IsMailReplyTo())
pMessage->setReplyToAddress(m_pConfigItem->GetMailReplyTo());
pMessage->addRecipient( pCurrentMailDescriptor->sEMail );
pMessage->SetSenderName( m_pConfigItem->GetMailDisplayName() );
pMessage->SetSenderAddress( m_pConfigItem->GetMailAddress() );
if(!pCurrentMailDescriptor->sAttachmentURL.isEmpty())
{
mail::MailAttachment aAttach;
aAttach.Data =
new SwMailTransferable(
pCurrentMailDescriptor->sAttachmentURL,
pCurrentMailDescriptor->sAttachmentName,
pCurrentMailDescriptor->sMimeType );
aAttach.ReadableName = pCurrentMailDescriptor->sAttachmentName;
pMessage->addAttachment( aAttach );
}
pMessage->setSubject( pCurrentMailDescriptor->sSubject );
uno::Reference< datatransfer::XTransferable> xBody =
new SwMailTransferable(
pCurrentMailDescriptor->sBodyContent,
pCurrentMailDescriptor->sBodyMimeType);
pMessage->setBody( xBody );
//CC and BCC are tokenized by ';'
if(!pCurrentMailDescriptor->sCC.isEmpty())
{
OUString sTokens( pCurrentMailDescriptor->sCC );
sal_uInt16 nTokens = comphelper::string::getTokenCount(sTokens, ';');
sal_Int32 nPos = 0;
for( sal_uInt16 nToken = 0; nToken < nTokens; ++nToken)
{
OUString sTmp = sTokens.getToken( 0, ';', nPos);
if( !sTmp.isEmpty() )
pMessage->addCcRecipient( sTmp );
}
}
if(!pCurrentMailDescriptor->sBCC.isEmpty())
{
OUString sTokens( pCurrentMailDescriptor->sBCC );
sal_uInt16 nTokens = comphelper::string::getTokenCount(sTokens, ';');
sal_Int32 nPos = 0;
for( sal_uInt16 nToken = 0; nToken < nTokens; ++nToken)
{
OUString sTmp = sTokens.getToken( 0, ';', nPos);
if( !sTmp.isEmpty() )
pMessage->addBccRecipient( sTmp );
}
}
m_pImpl->xMailDispatcher->enqueueMailMessage( xMessage );
pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
}
UpdateTransferStatus();
}
void SwSendMailDialog::ShowDialog()
{
Application::PostUserEvent( STATIC_LINK( this, SwSendMailDialog,
StartSendMails ), this );
ModelessDialog::Show();
}
void SwSendMailDialog::StateChanged( StateChangedType nStateChange )
{
ModelessDialog::StateChanged( nStateChange );
if(STATE_CHANGE_VISIBLE == nStateChange && !IsVisible())
{
m_pImpl->aRemoveTimer.SetTimeoutHdl( STATIC_LINK( this, SwSendMailDialog,
RemoveThis ) );
m_pImpl->aRemoveTimer.Start();
}
}
void SwSendMailDialog::DocumentSent( uno::Reference< mail::XMailMessage> xMessage,
bool bResult,
const OUString* pError )
{
//sending should stop on send errors
if(pError &&
m_pImpl->xMailDispatcher.is() && m_pImpl->xMailDispatcher->isStarted())
{
Application::PostUserEvent( STATIC_LINK( this, SwSendMailDialog,
StopSendMails ), this );
}
Image aInsertImg = m_aImageList.GetImage( bResult ? FN_FORMULA_APPLY : FN_FORMULA_CANCEL );
OUString sMessage = m_sSendingTo;
OUString sTmp(xMessage->getRecipients()[0]);
sTmp += "\t";
sTmp += bResult ? m_sCompleted : m_sFailed;
m_aStatusLB.InsertEntry( sMessage.replaceFirst("%1", sTmp), aInsertImg, aInsertImg);
++m_nSendCount;
if(!bResult)
++m_nErrorCount;
UpdateTransferStatus( );
if (pError)
{
SwSendWarningBox_Impl* pDlg = new SwSendWarningBox_Impl(0, *pError);
pDlg->Execute();
delete pDlg;
}
}
void SwSendMailDialog::UpdateTransferStatus()
{
OUString sStatus( m_sTransferStatus );
sStatus = sStatus.replaceFirst("%1", OUString::number(m_nSendCount) );
sStatus = sStatus.replaceFirst("%2", OUString::number(m_pImpl->aDescriptors.size()));
m_aTransferStatusFT.SetText(sStatus);
sStatus = m_sErrorStatus.replaceFirst("%1", OUString::number(m_nErrorCount) );
m_aErrorStatusFT.SetText(sStatus);
if(m_pImpl->aDescriptors.size())
m_aProgressBar.SetValue((sal_uInt16)(m_nSendCount * 100 / m_pImpl->aDescriptors.size()));
else
m_aProgressBar.SetValue(0);
}
void SwSendMailDialog::AllMailsSent()
{
m_aStopPB.Enable(false);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <list> #include <list>
#include <swdllapi.h>
class IMailDispatcherListener; class IMailDispatcherListener;
/** /**
...@@ -37,7 +39,9 @@ class IMailDispatcherListener; ...@@ -37,7 +39,9 @@ class IMailDispatcherListener;
must not be shared among different client threads. Instead each client must not be shared among different client threads. Instead each client
thread should create an own instance of this class. thread should create an own instance of this class.
*/ */
class MailDispatcher : public ::salhelper::ReferenceObject, private ::osl::Thread class SW_DLLPUBLIC MailDispatcher
: public ::salhelper::ReferenceObject
, private ::osl::Thread
{ {
public: public:
// bringing operator new/delete into scope // bringing operator new/delete into scope
......
...@@ -200,7 +200,7 @@ public: ...@@ -200,7 +200,7 @@ public:
throw(com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; throw(com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
}; };
class SwMailTransferable : class SW_DLLPUBLIC SwMailTransferable :
public SwMutexBase, public SwMutexBase,
public cppu::WeakComponentImplHelper2 public cppu::WeakComponentImplHelper2
< <
...@@ -239,7 +239,7 @@ class SwMailTransferable : ...@@ -239,7 +239,7 @@ class SwMailTransferable :
}; };
class SwMailMessage : class SW_DLLPUBLIC SwMailMessage :
public SwMutexBase, public SwMutexBase,
public cppu::WeakComponentImplHelper1< ::com::sun::star::mail::XMailMessage > public cppu::WeakComponentImplHelper1< ::com::sun::star::mail::XMailMessage >
{ {
......
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