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 @@
#include <sfx2/basedlgs.hxx>
#include <svtools/svtabbx.hxx>
#include <svtools/headbar.hxx>
#include "swdllapi.h"
#include "mailmergehelper.hxx"
class SwMailMergeWizard;
......@@ -140,7 +139,7 @@ struct SwMailDescriptor
};
struct SwSendMailDialog_Impl;
class SwMailMergeConfigItem;
class SW_DLLPUBLIC SwSendMailDialog : public ModelessDialog //SfxModalDialog
class SwSendMailDialog : public ModelessDialog //SfxModalDialog
{
FixedLine m_aStatusFL;
FixedText m_aStatusFT;
......
......@@ -58,4 +58,573 @@ IMPL_LINK_NOARG(SwMailMergeOutputTypePage, TypeHdl_Impl)
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: */
......@@ -25,18 +25,8 @@
#include <view.hxx>
#include <edtwin.hxx>
#include <vcl/layout.hxx>
#include <vcl/svapp.hxx>
#include <mailmergechildwindow.hxx>
#include <../../ui/dbui/mmoutputpage.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 <vcl/msgbox.hxx>
#include <vcl/image.hxx>
......@@ -111,556 +101,4 @@ void SwMailMergeChildWin::FillInfo(SfxChildWinInfo& rInfo) const
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: */
......@@ -28,6 +28,8 @@
#include <list>
#include <swdllapi.h>
class IMailDispatcherListener;
/**
......@@ -37,7 +39,9 @@ class IMailDispatcherListener;
must not be shared among different client threads. Instead each client
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:
// bringing operator new/delete into scope
......
......@@ -200,7 +200,7 @@ public:
throw(com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
};
class SwMailTransferable :
class SW_DLLPUBLIC SwMailTransferable :
public SwMutexBase,
public cppu::WeakComponentImplHelper2
<
......@@ -239,7 +239,7 @@ class SwMailTransferable :
};
class SwMailMessage :
class SW_DLLPUBLIC SwMailMessage :
public SwMutexBase,
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