diff --git a/ChangeLog b/ChangeLog index d254ffd99..f3b77b8df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,18 @@ -Sat Feb 14 10:03:09 1998 Stefan Taferner +1998-03-09 Stefan Taferner + + * Reader: "_" was not considered part of a smart-detected email + address (auto detection of @). + + * Reader: attachments of type message/rfc822 are now shown + in an external reader window if open or view from the attachment + popup menu is chosen. + + * Composer: finally got insertion of tabs into message + working. + +(some changes are missing here) + +1998-02-14 Stefan Taferner * Startup: when recovering dead letters the auto signature was appended twice. Fixed now. diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 038e1cff1..bdf868d88 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -89,8 +89,9 @@ WindowList* windowList=new WindowList; //----------------------------------------------------------------------------- KMComposeWin::KMComposeWin(KMMessage *aMsg) : KMComposeWinInherited(), mMainWidget(this), - mEdtFrom(&mMainWidget), mEdtReplyTo(&mMainWidget), mEdtTo(&mMainWidget), - mEdtCc(&mMainWidget), mEdtBcc(&mMainWidget), mEdtSubject(&mMainWidget), + mEdtFrom(this,&mMainWidget), mEdtReplyTo(this,&mMainWidget), + mEdtTo(this,&mMainWidget), mEdtCc(this,&mMainWidget), + mEdtBcc(this,&mMainWidget), mEdtSubject(this,&mMainWidget), mLblFrom(&mMainWidget), mLblReplyTo(&mMainWidget), mLblTo(&mMainWidget), mLblCc(&mMainWidget), mLblBcc(&mMainWidget), mLblSubject(&mMainWidget), mBtnTo("...",&mMainWidget), mBtnCc("...",&mMainWidget), @@ -98,7 +99,7 @@ KMComposeWin::KMComposeWin(KMMessage *aMsg) : KMComposeWinInherited(), mBtnReplyTo("...",&mMainWidget) #ifdef KRN /* start added for KRN */ - ,mEdtNewsgroups(&mMainWidget),mEdtFollowupTo(&mMainWidget), + ,mEdtNewsgroups(this,&mMainWidget),mEdtFollowupTo(this,&mMainWidget), mLblNewsgroups(&mMainWidget),mLblFollowupTo(&mMainWidget) /* end added for KRN */ #endif @@ -598,8 +599,10 @@ void KMComposeWin::setupStatusBar(void) setStatusBar(mStatusBar); } -void KMComposeWin::updateCursorPosition() { +//----------------------------------------------------------------------------- +void KMComposeWin::updateCursorPosition() +{ int col,line; QString temp; line = mEditor->currentLine(); @@ -608,14 +611,14 @@ void KMComposeWin::updateCursorPosition() { mStatusBar->changeItem(temp,1); temp.sprintf("%s: %i", i18n("Column"), (col+1)); mStatusBar->changeItem(temp,2); - } + //----------------------------------------------------------------------------- void KMComposeWin::setupEditor(void) { QPopupMenu* menu; - mEditor = new KMEdit(kapp, &mMainWidget); + mEditor = new KMEdit(kapp, &mMainWidget, this); mEditor->toggleModified(FALSE); mEditor->setFocusPolicy(QWidget::ClickFocus); @@ -955,6 +958,7 @@ void KMComposeWin::addAttach(const QString aUrl) msgPart->setCteStr(mDefEncoding); msgPart->setBodyEncoded(str); msgPart->magicSetType(); + msgPart->setContentDisposition("attachment; filename=\""+name+"\""); // show properties dialog kbp->idle(); @@ -1632,6 +1636,7 @@ void KMComposeWin::slotConfigureCharsets() #endif } + //----------------------------------------------------------------------------- void KMComposeWin::slotSetCharsets(const char *message,const char *composer, bool ascii,bool quote,bool def) @@ -1652,6 +1657,7 @@ void KMComposeWin::slotSetCharsets(const char *message,const char *composer, #endif } + #ifdef CHARSETS //----------------------------------------------------------------------------- bool KMComposeWin::is8Bit(const QString str) @@ -1670,6 +1676,7 @@ bool KMComposeWin::is8Bit(const QString str) return FALSE; } + //----------------------------------------------------------------------------- QString KMComposeWin::convertToLocal(const QString str) { @@ -1738,8 +1745,10 @@ void KMComposeWin::transcodeMessageTo(const QString charset) mEditor->setText(result.copy()); } -void KMComposeWin::setEditCharset(){ +//----------------------------------------------------------------------------- +void KMComposeWin::setEditCharset() +{ QFont fnt=mSavedEditorFont; KCharset kcharset; if (mComposeCharset=="default") kcharset=klocale->charset(); @@ -1755,7 +1764,10 @@ void KMComposeWin::focusNextPrevEdit(const QLineEdit* aCur, bool aNext) { QLineEdit* cur; - if (!aCur) cur=mEdtList.last(); + if (!aCur) + { + cur=mEdtList.last(); + } else { for (cur=mEdtList.first(); aCur!=cur && cur; cur=mEdtList.next()) @@ -1764,8 +1776,8 @@ void KMComposeWin::focusNextPrevEdit(const QLineEdit* aCur, bool aNext) if (aNext) cur = mEdtList.next(); else cur = mEdtList.prev(); } - if (!cur) return; - cur->setFocus(); + if (cur) cur->setFocus(); + else mEditor->setFocus(); } @@ -1775,13 +1787,13 @@ void KMComposeWin::focusNextPrevEdit(const QLineEdit* aCur, bool aNext) // Class KMLineEdit // //============================================================================= -KMLineEdit::KMLineEdit(QWidget *parent, const char *name) - :QLineEdit(parent,name) +KMLineEdit::KMLineEdit(KMComposeWin* composer, QWidget *parent, + const char *name): KMLineEditInherited(parent,name) { + mComposer = composer; } //----------------------------------------------------------------------------- - void KMLineEdit::mousePressEvent(QMouseEvent *e) { if(e->button() == MidButton) @@ -1804,6 +1816,16 @@ void KMLineEdit::mousePressEvent(QMouseEvent *e) else QLineEdit::mousePressEvent(e); } +//----------------------------------------------------------------------------- +void KMLineEdit::keyPressEvent(QKeyEvent* e) +{ + if (e->key()==Key_Backtab && mComposer) + mComposer->focusNextPrevEdit(this,FALSE); + else if ((e->key()==Key_Tab || e->key()==Key_Return) && mComposer) + mComposer->focusNextPrevEdit(this,TRUE); + else KMLineEditInherited::keyPressEvent(e); +} + //----------------------------------------------------------------------------- void KMLineEdit::copy() { @@ -1843,21 +1865,18 @@ void KMLineEdit::markAll() // Class KMEdit // //============================================================================= -KMEdit::KMEdit(KApplication *a,QWidget *parent, const char *name, - const char *filename): +KMEdit::KMEdit(KApplication *a,QWidget *parent, KMComposeWin* composer, + const char *name, const char *filename): KMEditInherited(a, parent, name, filename) { initMetaObject(); + mComposer = composer; } - //----------------------------------------------------------------------------- void KMEdit::keyPressEvent(QKeyEvent* e) { - if (e->key()==Key_Tab && (e->state() & ShiftButton)) - { - printf("shift-tab\n"); - parent()->focusNextPrevEdit(NULL,FALSE); - } + if (e->key()==Key_Backtab && mComposer) + mComposer->focusNextPrevEdit(NULL,FALSE); else KMEditInherited::keyPressEvent(e); } diff --git a/kmcomposewin.h b/kmcomposewin.h index a195baa69..4b897f33b 100644 --- a/kmcomposewin.h +++ b/kmcomposewin.h @@ -46,22 +46,23 @@ class KMEdit: public KEdit { Q_OBJECT public: - KMEdit(KApplication *a=NULL,QWidget *parent=NULL, const char *name=NULL, - const char *filename=NULL); - KMComposeWin* parent(void) const - { return (KMComposeWin*)KMEditInherited::parent(); } + KMEdit(KApplication *a=NULL,QWidget *parent=NULL,KMComposeWin* composer=NULL, + const char *name=NULL, const char *filename=NULL); protected: virtual void keyPressEvent(QKeyEvent*); + KMComposeWin* mComposer; }; //----------------------------------------------------------------------------- +#define KMLineEditInherited QLineEdit class KMLineEdit : public QLineEdit { Q_OBJECT public: - KMLineEdit(QWidget *parent = NULL, const char *name = NULL); + KMLineEdit(KMComposeWin* composer = NULL, QWidget *parent = NULL, + const char *name = NULL); public slots: void copy(); @@ -71,6 +72,8 @@ public slots: protected: virtual void mousePressEvent(QMouseEvent *); + virtual void keyPressEvent(QKeyEvent*); + KMComposeWin* mComposer; }; diff --git a/kmheaders.cpp b/kmheaders.cpp index e78c1a385..9028e2dcf 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -189,7 +189,8 @@ void KMHeaders::msgHeaderChanged(int msgId) flag = mb->status(); hdr.sprintf("%c\n%.100s\n %.100s\n%.40s", (char)flag, - (const char*)mb->from(), (const char*)mb->subject(), + (const char*)KMMessage::stripEmailAddr(mb->from()), + (const char*)mb->subject(), (const char*)mb->dateStr()); changeItem(hdr, msgId); diff --git a/kmmessage.cpp b/kmmessage.cpp index 22d59131f..166ffb4c1 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -223,10 +223,20 @@ const QString KMMessage::headerAsString(void) //----------------------------------------------------------------------------- void KMMessage::fromString(const QString aStr) { + int i, j, len; + if (mMsg) delete mMsg; mMsg = new DwMessage; - result = aStr; + // copy string and throw out obsolete control characters + len = aStr.length(); + result.resize(len); + for (i=0,j=0; i=' ' || aStr[i]=='\t' || aStr[i]=='\n') + result[j++] = aStr[i]; + } + mMsg->FromString((const char*)aStr); mMsg->Parse(); mNeedsAssembly = FALSE; @@ -1146,7 +1156,7 @@ void KMMessage::viewSource(const QString aCaption) const const QString KMMessage::stripEmailAddr(const QString aStr) { int i, j; - QString partA, partB; + QString partA, partB, result; char endCh = '>'; i = aStr.find('<'); @@ -1161,8 +1171,13 @@ const QString KMMessage::stripEmailAddr(const QString aStr) if (j<0) return aStr; partB = aStr.mid(i+1, j-i-1); - if (partA.find('@') >= 0) return partB.stripWhiteSpace(); - return partA.stripWhiteSpace(); + if (partA.find('@') >= 0) + result = partB.stripWhiteSpace(); + else result = partA.stripWhiteSpace(); + + if (result[0]=='"' && result[result.length()-1]=='"') + result = result.mid(1, result.length()-2); + return result; } diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 45c2fdfbb..630e79573 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -59,6 +59,7 @@ KMReaderWin::KMReaderWin(QWidget *aParent, const char *aName, int aFlags) initMetaObject(); mPicsDir = app->kde_datadir()+"/kmail/pics/"; + mAutoDelete = FALSE; mMsg = NULL; initHtmlWidget(); @@ -69,6 +70,7 @@ KMReaderWin::KMReaderWin(QWidget *aParent, const char *aName, int aFlags) //----------------------------------------------------------------------------- KMReaderWin::~KMReaderWin() { + if (mAutoDelete) delete mMsg; } @@ -203,10 +205,6 @@ void KMReaderWin::setMsg(KMMessage* aMsg) //----------------------------------------------------------------------------- void KMReaderWin::parseMsg(void) { - KMMessagePart msgPart; - int i, numParts; - QString type, subtype, str, contDisp; - bool asIcon; assert(mMsg!=NULL); mViewer->begin(mPicsDir); @@ -216,14 +214,31 @@ void KMReaderWin::parseMsg(void) mViewer->setCharset(mMsg->charset()); #endif + parseMsg(mMsg); + + mViewer->write("
"); + mViewer->end(); + mViewer->parse(); +} + + +//----------------------------------------------------------------------------- +void KMReaderWin::parseMsg(KMMessage* aMsg) +{ + KMMessagePart msgPart; + int i, numParts; + QString type, subtype, str, contDisp; + bool asIcon; + + assert(aMsg!=NULL); writeMsgHeader(); - numParts = mMsg->numBodyParts(); + numParts = aMsg->numBodyParts(); if (numParts > 0) { for (i=0; ibodyPart(i, &msgPart); + aMsg->bodyPart(i, &msgPart); type = msgPart.typeStr(); subtype = msgPart.subtypeStr(); contDisp = msgPart.contentDisposition(); @@ -241,7 +256,7 @@ void KMReaderWin::parseMsg(void) if (!asIcon) { - if (i<=0 || stricmp(type, "text")==0 || stricmp(type, "message")==0) + if (i<=0 || stricmp(type, "text")==0)//||stricmp(type, "message")==0) { str = msgPart.bodyDecoded(); if (i>0) mViewer->write("


"); @@ -259,12 +274,8 @@ void KMReaderWin::parseMsg(void) } else { - writeBodyStr(mMsg->bodyDecoded()); + writeBodyStr(aMsg->bodyDecoded()); } - - mViewer->write("
"); - mViewer->end(); - mViewer->parse(); } @@ -515,13 +526,13 @@ const QString KMReaderWin::strToHtml(const QString aStr, bool aDecodeQP, else if (ch=='@') { for (i=0; *pos && (isalnum(*pos) || *pos=='@' || *pos=='.' || - *pos=='-') && i<255; i++, pos--) + *pos=='_'||*pos=='-') && i<255; i++, pos--) { } i1 = i; pos++; - for (i=0; *pos && (isalnum(*pos)||*pos=='@' || *pos=='.' || - *pos=='-') && i<255; i++, pos++) + for (i=0; *pos && (isalnum(*pos)||*pos=='@'||*pos=='.'|| + *pos=='_'||*pos=='-') && i<255; i++, pos++) { iStr += *pos; } @@ -634,6 +645,20 @@ void KMReaderWin::slotUrlPopup(const char* aUrl, const QPoint& aPos) } +//----------------------------------------------------------------------------- +void KMReaderWin::atmViewMsg(KMMessagePart* aMsgPart) +{ + KMMessage* msg = new KMMessage; + KMReaderWin* win = new KMReaderWin; + assert(aMsgPart!=NULL); + + msg->fromString(aMsgPart->bodyDecoded()); + win->setMsg(msg); + win->setAutoDelete(TRUE); + win->show(); +} + + //----------------------------------------------------------------------------- void KMReaderWin::slotAtmView() { @@ -646,6 +671,12 @@ void KMReaderWin::slotAtmView() if (pname.isEmpty()) pname=msgPart.contentDescription(); if (pname.isEmpty()) pname="unnamed"; + if (stricmp(msgPart.typeStr(), "message")==0) + { + atmViewMsg(&msgPart); + return; + } + kbp->busy(); str = msgPart.bodyDecoded(); @@ -668,6 +699,12 @@ void KMReaderWin::slotAtmOpen() mMsg->bodyPart(mAtmCurrent, &msgPart); + if (stricmp(msgPart.typeStr(), "message")==0) + { + atmViewMsg(&msgPart); + return; + } + pname = msgPart.name(); if (pname.isEmpty()) pname="unnamed"; tmpName = tempnam(NULL, NULL); diff --git a/kmreaderwin.h b/kmreaderwin.h index 8c185f677..6cb0a3bae 100644 --- a/kmreaderwin.h +++ b/kmreaderwin.h @@ -68,6 +68,10 @@ public: /** Return selected text */ QString copyText(); + /** Get/set auto-delete msg flag. */ + bool autoDelete(void) const { return mAutoDelete; } + void setAutoDelete(bool f) { mAutoDelete=f; } + signals: /** Emitted to show a text on the status line. */ void statusMsg(const char* text); @@ -107,9 +111,13 @@ protected slots: void slotAtmProperties(); protected: - /** Feeds the HTML viewer with the contents of the current message. */ + /** Feeds the HTML viewer with the contents of the given message. + HTML begin/end parts are written around the message. */ virtual void parseMsg(void); + /** Parse given message and add it's contents to the reader window. */ + virtual void parseMsg(KMMessage* msg); + /** Creates a nice mail header depending on the current selected header style. */ virtual void writeMsgHeader(void); @@ -139,6 +147,9 @@ protected: /** Returns id of message part from given URL or -1 if invalid. */ virtual int msgPartFromUrl(const char* url); + /** View message part of type message/RFC822 in extra viewer window. */ + virtual void atmViewMsg(KMMessagePart* msgPart); + protected: int mAtmInline; int mAtmCurrent; @@ -148,6 +159,7 @@ protected: QString mPicsDir; HeaderStyle mHeaderStyle; AttachmentStyle mAttachmentStyle; + bool mAutoDelete; };