From 8d96c2baf8df69e9943f6901572c98e71c70056f Mon Sep 17 00:00:00 2001 From: Don Sanders Date: Sat, 15 Jul 2000 00:50:27 +0000 Subject: [PATCH] Support using filter rules to set the smtp server to use when replying to a message, and also the user to select a smtp server to use when replying to a message while editing that message in the composer. svn path=/trunk/kdenetwork/kmail/; revision=56980 --- kmfilteraction.cpp | 65 +++++++++++++++++ kmmessage.cpp | 2 + kmsender.cpp | 175 ++++++++++++++++++++++++++++++++++++++------- kmsender.h | 24 +++++-- 4 files changed, 235 insertions(+), 31 deletions(-) diff --git a/kmfilteraction.cpp b/kmfilteraction.cpp index 4c557d73a..37047aebb 100644 --- a/kmfilteraction.cpp +++ b/kmfilteraction.cpp @@ -501,6 +501,69 @@ const QString KMFilterActionIdentity::argsAsString(void) const } +//============================================================================= +// Specify mail transport (smtp server) to be used when replying to a message +//============================================================================= +class KMFilterActionTransport: public KMFilterAction +{ +public: + KMFilterActionTransport(); + virtual const QString label(void) const; + virtual int process(KMMessage* msg, bool& stopIt); + virtual QWidget* createParamWidget(KMGFilterDlg* parent); + virtual void applyParamWidgetValue(QWidget* paramWidget); + virtual void argsFromString(const QString argsStr); + virtual const QString argsAsString(void) const; + static KMFilterAction* newAction(void); +protected: + QString mTransport; +}; + +KMFilterAction* KMFilterActionTransport::newAction(void) +{ + return (new KMFilterActionTransport); +} + +const QString KMFilterActionTransport::label(void) const +{ + return i18n("set transport"); +} + +KMFilterActionTransport::KMFilterActionTransport(): KMFilterAction("set transport") +{ + mTransport = kernel->msgSender()->transportString(); +} + +int KMFilterActionTransport::process(KMMessage* msg, bool& ) +{ + msg->setHeaderField( "X-KMail-Transport", mTransport ); + return -1; +} + +QWidget* KMFilterActionTransport::createParamWidget(KMGFilterDlg* aParent) +{ + QLineEdit* edt; + edt = aParent->createEdit(mTransport); + return edt; +} + +void KMFilterActionTransport::applyParamWidgetValue(QWidget* aParamWidget) +{ + QLineEdit* w = (QLineEdit*)aParamWidget; + mTransport = w->text(); +} + +void KMFilterActionTransport::argsFromString(const QString argsStr) +{ + mTransport = argsStr; +} + +const QString KMFilterActionTransport::argsAsString(void) const +{ + return mTransport; +} + + //============================================================================= // // Filter Action Dictionary @@ -510,6 +573,8 @@ void KMFilterActionDict::init(void) { insert("set identity", i18n("set identity"), KMFilterActionIdentity::newAction); + insert("set transport", i18n("set transport"), + KMFilterActionTransport::newAction); insert("transfer", i18n("transfer"), KMFilterActionMove::newAction); insert("skip rest", i18n("skip rest"), diff --git a/kmmessage.cpp b/kmmessage.cpp index 7cca86d25..512cc5026 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -661,6 +661,8 @@ KMMessage* KMMessage::createReply(bool replyToAll) QString str, replyStr, mailingListStr, replyToStr, toStr, refStr; msg->initHeader(headerField("X-KMail-Identity")); + if (!headerField("X-KMail-Transport").isEmpty()) + msg->setHeaderField("X-KMail-Transport", headerField("X-KMail-Transport")); mailingListStr = headerField("X-Mailing-List"); replyToStr = replyTo(); diff --git a/kmsender.cpp b/kmsender.cpp index 76584acca..9f9ceefdf 100644 --- a/kmsender.cpp +++ b/kmsender.cpp @@ -52,9 +52,9 @@ //----------------------------------------------------------------------------- KMSender::KMSender() { -// initMetaObject(); mSendDlg = NULL; mSendProc = NULL; + mMsgSendProc = NULL; mSendProcStarted = FALSE; mSendInProgress = FALSE; mCurrentMsg = NULL; @@ -62,7 +62,6 @@ KMSender::KMSender() quitOnDone = false; labelDialog = new QDialog(0); label = new QLabel(labelDialog); - //label->setAutoResize(true); labelDialog->setCaption("KMail"); labelDialog->setIcon(kapp->miniIcon()); } @@ -272,6 +271,16 @@ void KMSender::doSendMsg() mCurrentMsg = NULL; } + // If we have been using a message specific transport, lose it now. + // Would be more efficient to only do this when the mail transport + // (server or port) has changed + if (mMsgSendProc) { + mMsgSendProc->finish(); + delete mMsgSendProc; + mMsgSendProc = 0; + restoreTransportSettings(); + mSendProcStarted = FALSE; + } // See if there is another queued message mCurrentMsg = kernel->outboxFolder()->getMsg(0); @@ -302,14 +311,45 @@ void KMSender::doSendMsg() } setStatusMsg(i18n("Initiating sender process...")); + } + + mMethodStr = transportString(); + + QString msgTransport = mCurrentMsg->headerField("X-KMail-Transport"); + if (!msgTransport.isEmpty() && (msgTransport != mMethodStr)) { + if (mSendProcStarted && mSendProc) { + mSendProc->finish(); + mSendProcStarted = FALSE; + } + + saveTransportSettings(); + + mMsgSendProc = parseTransportFromString(mCurrentMsg->headerField("X-KMail-Transport")); + mMethodStr = transportString(); + + if (!mMsgSendProc || !mMsgSendProc->start()) { + if (mMsgSendProc) { + mMsgSendProc->finish(); + delete mMsgSendProc; + } + else + setStatusMsg(i18n("Unrecognised transport protocol, could not send message.")); + mMsgSendProc = 0; + mSendProcStarted = false; + restoreTransportSettings(); + cleanup(); + return; + } + connect(mMsgSendProc,SIGNAL(idle()),SLOT(slotIdle())); + } + else if (!mSendProcStarted) if (!mSendProc->start()) { cleanup(); return; } - mSendProcStarted = TRUE; - mSendInProgress = TRUE; - } + mSendProcStarted = TRUE; + mSendInProgress = TRUE; // remove header fields that shall not be included in sending mCurrentMsg->removeHeaderField("Status"); @@ -318,13 +358,25 @@ void KMSender::doSendMsg() mCurrentMsg->removeHeaderField("X-KMail-Transport"); // start sending the current message - mSendProc->preSendInit(); - setStatusMsg(i18n("Sending message: ")+mCurrentMsg->subject()); - if (!mSendProc->send(mCurrentMsg)) - { - cleanup(); - setStatusMsg(i18n("Failed to send (some) queued messages.")); - return; + + if (mMsgSendProc) { + mMsgSendProc->preSendInit(); + setStatusMsg(i18n("Sending message: ")+mCurrentMsg->subject()); + if (!mMsgSendProc->send(mCurrentMsg)) + { + cleanup(); + setStatusMsg(i18n("Failed to send (some) queued messages.")); + return; + } + } else { + mSendProc->preSendInit(); + setStatusMsg(i18n("Sending message: ")+mCurrentMsg->subject()); + if (!mSendProc->send(mCurrentMsg)) + { + cleanup(); + setStatusMsg(i18n("Failed to send (some) queued messages.")); + return; + } } // Do *not* add code here, after send(). It can happen that this method // is called recursively if send() emits the idle signal directly. @@ -370,23 +422,37 @@ void KMSender::slotIdle() { assert(mSendProc != NULL); //assert(!mSendProc->sending()); - if (mSendProc->sendOk()) - { + if (mMsgSendProc) { + if (mMsgSendProc->sendOk()) { + doSendMsg(); + return; + } + } else if (mSendProc->sendOk()) { // sending succeeded doSendMsg(); + return; } - else - { - // sending of message failed - QString msg; - msg = i18n("Sending failed:"); - msg += '\n'; - msg += mSendProc->message(); - msg += i18n("\nThe message will stay in the 'Outbox' folder and will be resent.\n"); - msg += i18n("Please remove it from there if you do not want the message to \nbe resent\n"); - KMessageBox::information(0,msg); - cleanup(); + + + // sending of message failed + QString msg; + msg = i18n("Sending failed:"); + msg += '\n'; + msg += mSendProc->message(); + msg += i18n("\nThe message will stay in the 'outbox' folder and will be resent.\n"); + msg += i18n("Please remove it from there if you do not want the message to \nbe resent\n"); + msg += i18n("\nThe following transport protocol was used:\n "); + msg += mMethodStr; + KMessageBox::information(0,msg); + + if (mMsgSendProc) { + mMsgSendProc->finish(); + delete mMsgSendProc; + mMsgSendProc = 0; + mSendProcStarted = false; + restoreTransportSettings(); } + cleanup(); } //----------------------------------------------------------------------------- @@ -431,6 +497,64 @@ void KMSender::setSmtpPort(unsigned short int aSmtpPort) } +//----------------------------------------------------------------------------- +void KMSender::saveTransportSettings(void) +{ + mOldMethod = mMethod; + mOldMailer = mMailer; + mOldSmtpHost = mSmtpHost; + mOldSmtpPort = mSmtpPort; +} + + +//----------------------------------------------------------------------------- +void KMSender::restoreTransportSettings(void) +{ + mMethod = mOldMethod; + mMailer = mOldMailer; + mSmtpHost = mOldSmtpHost; + mSmtpPort = mOldSmtpPort; +} + + +//----------------------------------------------------------------------------- +KMSendProc* KMSender::parseTransportFromString(QString transport) +{ + if (transport.left(7) == "smtp://") { // to i18n or not to i18n? + mMethod = smSMTP; + QString serverport = transport.mid(7); + QString server = serverport; + QString port = "25"; + int colon = serverport.find(":"); + if (colon != -1) { + server = serverport.left(colon); + port = serverport.mid(colon + 1); + } + mSmtpHost = server; + mSmtpPort = port.toInt(); + return new KMSendSMTP(this); + } + else if (transport.left(7) == "file://") { + mMethod = smMail; + mMailer = transport.mid(7); + return new KMSendSendmail(this); + } + else return 0; +} + +//----------------------------------------------------------------------------- +QString KMSender::transportString(void) const +{ + if (mMethod == smSMTP) + return QString("smtp://%1:%2").arg(mSmtpHost).arg(mSmtpPort); + else if (mMethod == smMail) + return QString("file://%1").arg(mMailer); + else + return ""; +} + + + //============================================================================= //============================================================================= KMSendProc::KMSendProc(KMSender* aSender): QObject() @@ -725,7 +849,6 @@ bool KMSendSMTP::start(void) replyCode = mClient->Helo(); // Send HELO command smtpDebug("HELO"); if (replyCode != 250) return smtpFailed("HELO", replyCode); - return TRUE; } diff --git a/kmsender.h b/kmsender.h index 4e72ee140..a457087b7 100644 --- a/kmsender.h +++ b/kmsender.h @@ -94,6 +94,9 @@ public: /** sets a status msg and emits statusMsg() */ void setStatusMsg(const QString&); + + /** returns current outgoing mail settings in string format */ + QString transportString(void) const; signals: /** Emitted regularly to inform the user of what is going on */ @@ -114,18 +117,29 @@ protected: Returns TRUE if everything is Ok. */ virtual bool settingsOk(void) const; + /** Save mMethod, mMail, mSmtpHost, and mSmtpPort */ + virtual void saveTransportSettings(void); + + /** Restore saved mMethod, mMail, mSmtpHost, and mSmtpPort */ + virtual void restoreTransportSettings(void); + + /** Parse protocol '://' (host port? | mailer) string and + set transport settings */ + virtual KMSendProc* parseTransportFromString(QString transport); + private: - Method mMethod; + Method mMethod, mOldMethod; bool mSendImmediate, mSendQuotedPrintable; - QString mMailer; - QString mSmtpHost; - unsigned short int mSmtpPort; + QString mMailer, mOldMailer; + QString mSmtpHost, mOldSmtpHost; + unsigned short int mSmtpPort, mOldSmtpPort; QString mPrecommand; bool mSentOk; QString mErrorMsg; KMIOStatusDlg* mSendDlg; - KMSendProc* mSendProc; + KMSendProc *mSendProc, *mMsgSendProc; + QString mMethodStr; bool mSendProcStarted; bool mSendInProgress; KMMessage * mCurrentMsg;