From 3d2b75f877533d381b42c96b6e9b82d0c78cd54f Mon Sep 17 00:00:00 2001 From: Stefan Taferner Date: Wed, 18 Mar 1998 22:29:30 +0000 Subject: [PATCH] * Reader: improved detection of urls and email addresses to ignore special characters at the end, e.g. "." or ")". * Messagelist: finally fixed sorting of messages. Also implemented ascending/descending/none sorting (use multiple clicks on the column headers to switch). Sorting order "none" is what was IMO missing for the trash folder :-) svn path=/trunk/kdenetwork/kmail/; revision=6198 --- ChangeLog | 12 ++++++++- kmfolder.cpp | 4 +-- kmfolder.h | 2 +- kmheaders.cpp | 45 +++++++++++++++++++++++++++++---- kmheaders.h | 4 +++ kmmsgbase.cpp | 12 +++++++-- kmmsgbase.h | 3 +++ kmmsglist.cpp | 66 ++++++++++++++++++++++++++----------------------- kmmsglist.h | 6 ++--- kmreaderwin.cpp | 19 +++++++++++--- 10 files changed, 125 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d8ffec05..5eedcbba0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ +1998-03-18 Stefan Taferner (KMail-0.6.4) + + * Reader: improved detection of urls and email addresses + to ignore special characters at the end, e.g. "." or ")". + + * Messagelist: finally fixed sorting of messages. Also + implemented ascending/descending/none sorting (use multiple + clicks on the column headers to switch). Sorting order "none" + is what was IMO missing for the trash folder :-) + 1998-03-17 Stefan Taferner (KMail-0.6.3) - * Composer: in menu view, when "all headers" view is + * Composer: in menu view, when 'all headers' view is activated, then the individual header line menu entries are disabled now. diff --git a/kmfolder.cpp b/kmfolder.cpp index d5859806c..6f12ab0b0 100644 --- a/kmfolder.cpp +++ b/kmfolder.cpp @@ -897,9 +897,9 @@ int KMFolder::sync(void) //----------------------------------------------------------------------------- -void KMFolder::sort(KMMsgList::SortField aField) +void KMFolder::sort(KMMsgList::SortField aField, bool aDesc) { - mMsgList.sort(aField); + mMsgList.sort(aField, aDesc); if (!mQuiet) emit changed(); mDirty = TRUE; } diff --git a/kmfolder.h b/kmfolder.h index 213376942..46741972d 100644 --- a/kmfolder.h +++ b/kmfolder.h @@ -162,7 +162,7 @@ public: virtual void quiet(bool beQuiet); /** Sort folder by given field. Actually sorts the index. */ - virtual void sort(KMMsgList::SortField field=KMMsgList::sfDate); + virtual void sort(KMMsgList::SortField field=KMMsgList::sfDate, bool descending=FALSE); /** Is the folder read-only? */ virtual bool isReadOnly(void) const { return !mFilesLocked; } diff --git a/kmheaders.cpp b/kmheaders.cpp index 9028e2dcf..e3630c64a 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -33,6 +33,7 @@ KMHeaders::KMHeaders(KMMainWin *aOwner, QWidget *parent, mFolder = NULL; getMsgIndex = -1; mSortCol = KMMsgList::sfDate; + mSortDescending = FALSE; setColumn(0, i18n("F"), 17, KMHeadersInherited::PixmapColumn); setColumn(1, i18n("Sender"), 200); @@ -89,7 +90,9 @@ void KMHeaders::readFolderConfig (void) setColumnWidth(2, config->readNumEntry("SubjectWidth", 270)); setColumnWidth(3, config->readNumEntry("DateWidth", 300)); mSortCol = config->readNumEntry("SortColumn", (int)KMMsgList::sfDate); - mFolder->sort((KMMsgList::SortField)mSortCol); + mSortDescending = (mSortCol < 0); + mSortCol = abs(mSortCol); + sort(); } @@ -103,7 +106,7 @@ void KMHeaders::writeFolderConfig (void) config->writeEntry("SenderWidth", columnWidth(1)); config->writeEntry("SubjectWidth", columnWidth(2)); config->writeEntry("DateWidth", columnWidth(3)); - config->writeEntry("SortColumn", mSortCol); + config->writeEntry("SortColumn", (mSortDescending ? -mSortCol : mSortCol)); } @@ -204,14 +207,39 @@ void KMHeaders::headerClicked(int column) { int idx = currentItem(); KMMsgBasePtr cur; - + const char* sortStr = "(unknown)"; + QString msg; + if (idx >= 0) cur = (*mFolder)[idx]; else cur = NULL; - mSortCol = column; + if (mSortCol == column) + { + if (!mSortDescending) mSortDescending = TRUE; + else + { + mSortCol = (int)KMMsgList::sfNone; + mSortDescending = FALSE; + sortStr = i18n("order of arrival"); + } + } + else + { + mSortCol = column; + mSortDescending = FALSE; + } + + if (mSortCol==(int)KMMsgList::sfSubject) sortStr = i18n("subject"); + else if (mSortCol==(int)KMMsgList::sfDate) sortStr = i18n("date"); + else if (mSortCol==(int)KMMsgList::sfFrom) sortStr = i18n("sender"); + else if (mSortCol==(int)KMMsgList::sfStatus) sortStr = i18n("status"); + + if (mSortDescending) msg.sprintf(i18n("Sorting messages descending by %s"), sortStr); + else msg.sprintf(i18n("Sorting messages ascending by %s"), sortStr); + mOwner->statusMsg(msg); kbp->busy(); - mFolder->sort((KMMsgList::SortField)mSortCol); + sort(); kbp->idle(); if (cur) idx = mFolder->find(cur); @@ -671,5 +699,12 @@ bool KMHeaders :: prepareForDrag (int /*aCol*/, int /*aRow*/, char** data, } +//----------------------------------------------------------------------------- +void KMHeaders::sort(void) +{ + mFolder->sort((KMMsgList::SortField)mSortCol, mSortDescending); +} + + //----------------------------------------------------------------------------- #include "kmheaders.moc" diff --git a/kmheaders.h b/kmheaders.h index 57400153d..27026b99d 100644 --- a/kmheaders.h +++ b/kmheaders.h @@ -101,6 +101,9 @@ protected: virtual void mouseReleaseEvent (QMouseEvent*); + /** Sort message list by current sort settings. */ + virtual void sort(void); + private: virtual void updateMessageList(void); KMFolder* mFolder; @@ -108,6 +111,7 @@ private: int getMsgIndex; bool getMsgMulti; KMMessageList mSelMsgList; + bool mSortDescending; }; #endif diff --git a/kmmsgbase.cpp b/kmmsgbase.cpp index 9e7d2ac98..6cc68e249 100644 --- a/kmmsgbase.cpp +++ b/kmmsgbase.cpp @@ -190,10 +190,18 @@ int KMMsgBase::indexStringLength(void) } +//----------------------------------------------------------------------------- +int KMMsgBase::compareByIndex(const KMMsgBase* other) const +{ + return (mFolderOffset - other->mFolderOffset); +} + + //----------------------------------------------------------------------------- int KMMsgBase::compareBySubject(const KMMsgBase* other) const { - const char *subjStr, *otherSubjStr; + //const char *subjStr, *otherSubjStr; + QString subjStr, otherSubjStr; bool hasKeywd, otherHasKeywd; int rc; @@ -201,7 +209,7 @@ int KMMsgBase::compareBySubject(const KMMsgBase* other) const otherSubjStr = skipKeyword(other->subject(), ':', &otherHasKeywd); rc = stricmp(subjStr, otherSubjStr); - //debug("\"%s\" =?= \"%s\": %d", subjStr, otherSubjStr, rc); + //debug("\"%s\" =?= \"%s\": %d", (const char*)subjStr, (const char*)otherSubjStr, rc); if (rc) return rc; diff --git a/kmmsgbase.h b/kmmsgbase.h index 1863b1d39..ff0abdb64 100644 --- a/kmmsgbase.h +++ b/kmmsgbase.h @@ -98,6 +98,9 @@ public: /** Compare with other message by From. Returns -1/0/1 like strcmp.*/ int compareByFrom(const KMMsgBase* other) const; + /** Compare with other message by position in folder. Returns -1/0/1 like strcmp.*/ + int compareByIndex(const KMMsgBase* other) const; + /** Skip leading keyword if keyword has given character at it's end * (e.g. ':' or ',') and skip the then following blanks (if any) too. * If keywordFound is specified it will be TRUE if a keyword was skipped diff --git a/kmmsglist.cpp b/kmmsglist.cpp index c0ae3810c..53954e530 100644 --- a/kmmsglist.cpp +++ b/kmmsglist.cpp @@ -8,6 +8,7 @@ static KMMsgList::SortField sortCriteria; static int* sortIndex; static KMMsgList* sortList; +static bool sortDescending; //----------------------------------------------------------------------------- KMMsgList::KMMsgList(int initSize): KMMsgListInherited(initSize) @@ -187,50 +188,53 @@ void KMMsgList::rethinkHigh(void) //----------------------------------------------------------------------------- -void KMMsgList::sort(SortField aField) +void KMMsgList::sort(SortField aField, bool aDescending) { - int i; - KMMsgBasePtr ptrList[mHigh]; + int i, j; + KMMsgBasePtr ptrList[mHigh+1]; + KMMsgBasePtr mb; if (mHigh < 2) return; - sortIndex = new int[mHigh]; - sortCriteria = aField; - sortList = this; - - for (i=0; i 0) + { + mb = KMMsgListInherited::at(i); + KMMsgListInherited::at(i) = KMMsgListInherited::at(i+1); + KMMsgListInherited::at(i+1) = mb; + } + } + } } //----------------------------------------------------------------------------- -int KMMsgList::msgSortCompFunc(const void* a, const void* b) +int KMMsgList::msgSortCompFunc(KMMsgBasePtr mbA, KMMsgBasePtr mbB, + KMMsgList::SortField sortCriteria, bool desc) { - KMMsgBasePtr mbA = sortList->at(*(int*)a); - KMMsgBasePtr mbB = sortList->at(*(int*)b); - int res = 0; + int res = 0; - if (sortCriteria==sfStatus) - res = mbA->compareByStatus(mbB); + if (sortCriteria==sfNone) + res = mbA->compareByIndex(mbB); + else + { + if (sortCriteria==sfStatus) + res = mbA->compareByStatus(mbB); - else if (sortCriteria==sfFrom) - res = mbA->compareByFrom(mbB); + else if (sortCriteria==sfFrom) + res = mbA->compareByFrom(mbB); - else if (res==0 || sortCriteria==sfSubject) - res = mbA->compareBySubject(mbB); + else if (res==0 || sortCriteria==sfSubject) + res = mbA->compareBySubject(mbB); - if (res==0 || sortCriteria==sfDate) - res = mbA->compareByDate(mbB); + if (res==0 || sortCriteria==sfDate) + res = mbA->compareByDate(mbB); + } + if (desc) return -res; return res; } diff --git a/kmmsglist.h b/kmmsglist.h index 46629e540..5da4a4b89 100644 --- a/kmmsglist.h +++ b/kmmsglist.h @@ -14,7 +14,7 @@ class KMMsgList: public QArray { public: /** Valid parameters for sort() */ - typedef enum { sfStatus=0, sfFrom=1, sfSubject=2, sfDate=3 } SortField; + typedef enum { sfNone=99, sfStatus=0, sfFrom=1, sfSubject=2, sfDate=3 } SortField; /** Constructor with optional initial size. */ KMMsgList(int initialSize=32); @@ -59,7 +59,7 @@ public: virtual void set(int idx, KMMsgBasePtr msg); /** Sort messages by given field. */ - virtual void sort(SortField byField=sfDate); + virtual void sort(SortField byField=sfDate, bool descending=FALSE); /** Returns first unused index (index of last message plus one). */ int high(void) const { return mHigh; } @@ -75,7 +75,7 @@ protected: void rethinkHigh(void); /** Function that does the compare in sort() method. */ - static int msgSortCompFunc(const void* a, const void* b); + static int msgSortCompFunc(KMMsgBasePtr, KMMsgBasePtr, KMMsgList::SortField, bool); int mHigh, mCount; }; diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 24c0d7837..b287715ac 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -478,7 +478,7 @@ const QString KMReaderWin::strToHtml(const QString aStr, bool aDecodeQP, { QString htmlStr, qpstr, iStr; char ch, *pos, str[256]; - int i,i1, x; + int i, i1, x, len; if (aDecodeQP) qpstr = KMMsgBase::decodeRFC1522String(aStr); else qpstr = aStr; @@ -516,8 +516,13 @@ const QString KMReaderWin::strToHtml(const QString aStr, bool aDecodeQP, { for (i=0; *pos && *pos>' ' && i<255; i++, pos++) str[i] = *pos; - str[i] = '\0'; pos--; + while (i>0 && ispunct(str[i-1]) && str[i-1]!='/') + { + i--; + pos--; + } + str[i] = '\0'; htmlStr += ""; @@ -537,7 +542,15 @@ const QString KMReaderWin::strToHtml(const QString aStr, bool aDecodeQP, { iStr += *pos; } - pos--; + pos--; + len = iStr.length(); + while (len>2 && ispunct(*pos)) + { + len--; + pos--; + } + iStr.truncate(len); + htmlStr.truncate(htmlStr.length() - i1 + 1); if (iStr.length()>3) htmlStr += "" + iStr + "";