From f50e29fc5630d38e85e2c0fa39bc2f92d46ef90c Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Tue, 17 Apr 2001 12:36:23 +0000 Subject: [PATCH] commiting my revision of Don's rapidfilter patch. Also automatic detection of Mailing lists added (idea borrowed from evolution) svn path=/trunk/kdenetwork/kmail/; revision=92483 --- Makefile.am | 8 +- kmfilterdlg.cpp | 26 +++++ kmfilterdlg.h | 2 + kmfiltermgr.cpp | 8 ++ kmfiltermgr.h | 1 + kmheaders.cpp | 25 +++-- kmmainwin.cpp | 218 +++++++++++++++++++++++++++++++++--------- kmmainwin.h | 15 ++- kmmainwin.rc | 13 +-- mailinglist-magic.cpp | 152 +++++++++++++++++++++++++++++ mailinglist-magic.h | 13 +++ 11 files changed, 403 insertions(+), 78 deletions(-) create mode 100644 mailinglist-magic.cpp create mode 100644 mailinglist-magic.h diff --git a/Makefile.am b/Makefile.am index b68a0d9dc..a82e5ab68 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,12 @@ KDE_CXXFLAGS = $(USE_RTTI) -UQT_NO_ASCII_CAST -UQT_NO_COMPAT -SUBDIRS = about pics +SUBDIRS = . about pics INCLUDES = -I$(top_srcdir)/libkdenetwork $(all_includes) -LDADD = $(LIB_KHTML) -lkdenetwork -lkspell -lmimelib -lkab $(LIB_KFILE) +LDADD = $(LIB_KHTML) ../libkdenetwork/libkdenetwork.la -lkspell -lmimelib $(LIB_KAB) bin_PROGRAMS = kmail -kmail_LDFLAGS = -L../libkdenetwork $(all_libraries) $(KDE_RPATH) +kmail_LDFLAGS = $(all_libraries) $(KDE_RPATH) kmail_SOURCES = kmmessage.cpp kmmainwin.cpp \ kmfolderdia.cpp kmfoldertree.cpp \ kmaccount.cpp kmheaders.cpp \ @@ -29,7 +29,7 @@ kmail_SOURCES = kmmessage.cpp kmmainwin.cpp \ kmkernel.cpp kmailIface.skel kmailIface.stub main.cpp \ accountdialog.cpp kmfldsearch.cpp addtoaddressbook.cpp \ kmdisplayvcard.cpp vcard.cpp md5.c \ - smtp.cpp smtp.h + smtp.cpp mailinglist-magic.cpp include_HEADERS = kmailIface.h diff --git a/kmfilterdlg.cpp b/kmfilterdlg.cpp index 71ce58a08..6bb289557 100644 --- a/kmfilterdlg.cpp +++ b/kmfilterdlg.cpp @@ -755,5 +755,31 @@ void KMFilterDlg::enableControls() mRuleValueB->setEnabled( deleteEnabled ); mRuleOp->setEnabled( deleteEnabled ); } + + +//----------------------------------------------------------------------------- +void KMFilterDlg::createFilter(const QString field, const QString value) +{ + int idx; + KMFilter* filter = new KMFilter; + filter->setName(i18n("Unnamed")); + filter->ruleA().init( field, KMFilterRule::FuncEquals, value ); + applyFilterChanges(); + mCurFilterIdx = -1; + + idx = mFilterList->currentItem(); + if (idx >= 0) kernel->filterMgr()->insert(idx, filter); + else kernel->filterMgr()->append(filter); + idx = kernel->filterMgr()->find(filter); + mFilterList->insertItem(filter->name(), idx); + mFilterList->setCurrentItem(idx); + slotFilterSelected(idx); + updateCurFilterName( "" ); + mFaType[0]->setCurrentItem( 1 ); //transfer type + slotActionTypeSelected( mFaType[0], 1 ); + enableControls(); +} + + //----------------------------------------------------------------------------- #include "kmfilterdlg.moc" diff --git a/kmfilterdlg.h b/kmfilterdlg.h index c159c3bf4..8e8b7f420 100644 --- a/kmfilterdlg.h +++ b/kmfilterdlg.h @@ -55,6 +55,8 @@ public: virtual QLineEdit* createEdit(const QString txt=0); + virtual void createFilter( const QString field, const QString value ); + protected slots: void updateCurFilterName(const QString &text); void slotBtnUp(); diff --git a/kmfiltermgr.cpp b/kmfiltermgr.cpp index bd57a5830..a4261c692 100644 --- a/kmfiltermgr.cpp +++ b/kmfiltermgr.cpp @@ -152,6 +152,14 @@ void KMFilterMgr::openDialog( QWidget *parent ) } +//----------------------------------------------------------------------------- +void KMFilterMgr::createFilter( const QString field, const QString value ) +{ + openDialog( 0 ); + mEditDialog->createFilter( field, value ); +} + + //----------------------------------------------------------------------------- bool KMFilterMgr::folderRemoved(KMFolder* aFolder, KMFolder* aNewFolder) { diff --git a/kmfiltermgr.h b/kmfiltermgr.h index 26e5524ff..2268719ce 100644 --- a/kmfiltermgr.h +++ b/kmfiltermgr.h @@ -27,6 +27,7 @@ public: /** Open an edit dialog. */ virtual void openDialog( QWidget *parent ); + virtual void createFilter( const QString field, const QString value ); /** Process given message by applying the filter rules one by one. Returns 2 if a critical error occurred (eg out of disk space) diff --git a/kmheaders.cpp b/kmheaders.cpp index ba27b7006..5dff45431 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -37,6 +37,7 @@ #include "kmundostack.h" #include "kmreaderwin.h" #include "kmacctimap.h" +#include "mailinglist-magic.h" #include #include @@ -2232,13 +2233,15 @@ void KMHeaders::slotRMB() mMenuToFolder.clear(); + mOwner->updateMessageMenu(); + QPopupMenu *msgMoveMenu = new QPopupMenu(); mOwner->folderToPopupMenu( NULL, TRUE, this, &mMenuToFolder, msgMoveMenu ); QPopupMenu *msgCopyMenu = new QPopupMenu(); mOwner->folderToPopupMenu( NULL, FALSE, this, &mMenuToFolder, msgCopyMenu ); - QPopupMenu *setStatusMenu = new QPopupMenu(); - if ((mFolder == kernel->outboxFolder()) || (mFolder == kernel->draftsFolder())) + bool out_folder = (mFolder == kernel->outboxFolder()) || (mFolder == kernel->draftsFolder()); + if ( out_folder ) mOwner->editAction->plug(menu); else { mOwner->replyAction->plug(menu); @@ -2248,19 +2251,15 @@ void KMHeaders::slotRMB() mOwner->bounceAction->plug(menu); } menu->insertSeparator(); + + if ( !out_folder ) + mOwner->filterMenu->plug( menu ); + menu->insertItem(i18n("&Move to"), msgMoveMenu); menu->insertItem(i18n("&Copy to"), msgCopyMenu); - if ((mFolder != kernel->outboxFolder()) && (mFolder != kernel->draftsFolder())) - { - menu->insertItem(i18n("&Set Status"), setStatusMenu); - mOwner->newAction->plug(setStatusMenu); - mOwner->unreadAction->plug(setStatusMenu); - mOwner->readAction->plug(setStatusMenu); - mOwner->repliedAction->plug(setStatusMenu); - mOwner->queueAction->plug(setStatusMenu); - mOwner->sentAction->plug(setStatusMenu); - mOwner->flagAction->plug(setStatusMenu); - } + if ( !out_folder ) + mOwner->statusMenu->plug( menu ); + menu->insertSeparator(); mOwner->printAction->plug(menu); mOwner->saveAsAction->plug(menu); diff --git a/kmmainwin.cpp b/kmmainwin.cpp index c40311cf6..3e3363b38 100644 --- a/kmmainwin.cpp +++ b/kmmainwin.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "mailinglist-magic.h" #include #include @@ -255,6 +256,7 @@ void KMMainWin::readConfig(void) mMsgView->setMsg( mFolder->getMsg(aIdx), true ); else mMsgView->setMsg( 0, true ); + updateMessageMenu(); show(); // sanders - Maybe this fixes a bug? @@ -333,6 +335,8 @@ void KMMainWin::createWidgets(void) this, SLOT(slotMsgSelected(KMMessage*))); connect(mHeaders, SIGNAL(activated(KMMessage*)), this, SLOT(slotMsgActivated(KMMessage*))); + connect( mHeaders, SIGNAL( selectionChanged() ), + SLOT( updateMessageMenu() ) ); accel->connectItem(accel->insertItem(Key_Left), mHeaders, SLOT(prevMessage())); accel->connectItem(accel->insertItem(Key_Right), @@ -750,6 +754,7 @@ void KMMainWin::slotEmptyFolder() mHeaders->setFolder(mFolder); kernel->kbp()->idle(); + updateMessageMenu(); } @@ -1152,6 +1157,39 @@ void KMMainWin::slotUpdateImapMessage(KMMessage *msg) if (((KMMsgBase*)msg)->isMessage()) mMsgView->setMsg(msg, TRUE); } +//----------------------------------------------------------------------------- +void KMMainWin::slotSubjectFilter() +{ + KMMessage* msg = mHeaders->getMsg(-1); + if (msg) + kernel->filterMgr()->createFilter( "Subject", msg->headerField( "Subject" )); +} + +void KMMainWin::slotMailingListFilter() +{ + KMMessage* msg = mHeaders->getMsg(-1); + if (msg) { + QString name, value; + if ( !detect_list( msg, name, value ).isNull() ) + kernel->filterMgr()->createFilter( name, value ); + } +} + +//----------------------------------------------------------------------------- +void KMMainWin::slotFromFilter() +{ + KMMessage* msg = mHeaders->getMsg(-1); + if (msg) + kernel->filterMgr()->createFilter( "From", msg->headerField( "From" )); +} + +//----------------------------------------------------------------------------- +void KMMainWin::slotToFilter() +{ + KMMessage* msg = mHeaders->getMsg(-1); + if (msg) + kernel->filterMgr()->createFilter( "To", msg->headerField( "To" )); +} //----------------------------------------------------------------------------- void KMMainWin::slotSetMsgStatusNew() @@ -1414,11 +1452,8 @@ void KMMainWin::slotUrlOpen() //----------------------------------------------------------------------------- void KMMainWin::slotMsgPopup(const KURL &aUrl, const QPoint& aPoint) { - KPopupMenu* menu = new KPopupMenu; - KPopupMenu *setStatusMenu = new KPopupMenu(); - (void) KMMainWin::updateMessageMenu(); - + updateMessageMenu(); mUrlCurrent = aUrl; @@ -1460,8 +1495,9 @@ void KMMainWin::slotMsgPopup(const KURL &aUrl, const QPoint& aPoint) } else { - if ((mFolder == kernel->outboxFolder()) || - (mFolder == kernel->draftsFolder())) + bool out_folder = (mFolder == kernel->outboxFolder()) || + (mFolder == kernel->draftsFolder()); + if ( out_folder ) editAction->plug(menu); else { replyAction->plug(menu); @@ -1471,20 +1507,14 @@ void KMMainWin::slotMsgPopup(const KURL &aUrl, const QPoint& aPoint) bounceAction->plug(menu); } menu->insertSeparator(); - menu->insertItem(i18n("&Move to"), moveMenu); - menu->insertItem(i18n("&Copy to"), copyMenu); - if ((mFolder != kernel->outboxFolder()) && - (mFolder != kernel->draftsFolder())) - { - menu->insertItem(i18n("&Set Status"), setStatusMenu); - newAction->plug(setStatusMenu); - unreadAction->plug(setStatusMenu); - readAction->plug(setStatusMenu); - repliedAction->plug(setStatusMenu); - queueAction->plug(setStatusMenu); - sentAction->plug(setStatusMenu); - flagAction->plug(setStatusMenu); + if ( !out_folder ) { + filterMenu->plug( menu ); + statusMenu->plug( menu ); } + + moveActionMenu->plug( menu ); + copyActionMenu->plug( menu ); + menu->insertSeparator(); printAction->plug(menu); saveAsAction->plug(menu); @@ -1630,7 +1660,7 @@ void KMMainWin::setupMenuBar() bounceAction = new KAction( i18n("&Bounce..."), 0, this, SLOT(slotBounceMsg()), actionCollection(), "bounce" ); - (void) new KAction( i18n("Send again..."), 0, this, + sendAgainAction = new KAction( i18n("Send again..."), 0, this, SLOT(slotResendMsg()), actionCollection(), "send_again" ); //----- Message-Encoding Submenu @@ -1652,30 +1682,72 @@ void KMMainWin::setupMenuBar() editAction = new KAction( i18n("Edi&t"), Key_T, this, SLOT(slotEditMsg()), actionCollection(), "edit" ); + //----- Create filter submenu + filterMenu = new KActionMenu( i18n("&Create Filter"), actionCollection(), "create_filter" ); + + KAction *subjectFilterAction = new KAction( i18n("Filter on Subject..."), 0, this, + SLOT(slotSubjectFilter()), + actionCollection(), "subject_filter"); + filterMenu->insert( subjectFilterAction ); + + KAction *fromFilterAction = new KAction( i18n("Filter on From..."), 0, this, + SLOT(slotFromFilter()), + actionCollection(), "from_filter"); + filterMenu->insert( fromFilterAction ); + + KAction *toFilterAction = new KAction( i18n("Filter on To..."), 0, this, + SLOT(slotToFilter()), + actionCollection(), "to_filter"); + filterMenu->insert( toFilterAction ); + + mlistFilterAction = new KAction( i18n("Filter on Mailing-List..."), 0, this, + SLOT(slotMailingListFilter()), actionCollection(), + "mlist_filter"); + filterMenu->insert( mlistFilterAction ); + + statusMenu = new KActionMenu ( i18n( "Set Status" ), actionCollection(), "set_status" ); + //----- Set status submenu - newAction= new KAction( i18n("&New"), "kmmsgnew", 0, this, - SLOT(slotSetMsgStatusNew()), actionCollection(), "status_new"); - unreadAction=new KAction( i18n("&Unread"), "kmmsgunseen", 0, this, - SLOT(slotSetMsgStatusUnread()), actionCollection(), "status_unread"); - readAction=new KAction( i18n("&Read"), "kmmsgold", 0, this, - SLOT(slotSetMsgStatusRead()), actionCollection(), "status_read"); - repliedAction= new KAction( i18n("R&eplied"), "kmmsgreplied", 0, this, - SLOT(slotSetMsgStatusReplied()), actionCollection(), "status_replied"); - queueAction=new KAction( i18n("&Queued"), "kmmsgqueued", 0, this, - SLOT(slotSetMsgStatusQueued()), actionCollection(), "status_queued"); - sentAction=new KAction( i18n("&Sent"), "kmmsgsent", 0, this, - SLOT(slotSetMsgStatusSent()), actionCollection(), "status_sent"); - flagAction=new KAction( i18n("&Flagged"), "kmmsgflag", 0, this, - SLOT(slotSetMsgStatusFlag()), actionCollection(), "status_flag"); - - - KActionMenu *moveActionMenu = new KActionMenu( i18n("&Move to" ), + KAction *newAction= new KAction( i18n("&New"), "kmmsgnew", 0, this, + SLOT(slotSetMsgStatusNew()), + actionCollection(), "status_new"); + statusMenu->insert( newAction ); + + KAction *unreadAction=new KAction( i18n("&Unread"), "kmmsgunseen", 0, this, + SLOT(slotSetMsgStatusUnread()), + actionCollection(), "status_unread"); + statusMenu->insert( unreadAction ); + + KAction *readAction=new KAction( i18n("&Read"), "kmmsgold", 0, this, + SLOT(slotSetMsgStatusRead()), actionCollection(), + "status_read"); + statusMenu->insert( readAction ); + + KAction *repliedAction= new KAction( i18n("R&eplied"), "kmmsgreplied", 0, this, + SLOT(slotSetMsgStatusReplied()), + actionCollection(), "status_replied"); + statusMenu->insert( repliedAction ); + + KAction *queueAction=new KAction( i18n("&Queued"), "kmmsgqueued", 0, this, + SLOT(slotSetMsgStatusQueued()), + actionCollection(), "status_queued"); + statusMenu->insert( queueAction ); + + KAction *sentAction=new KAction( i18n("&Sent"), "kmmsgsent", 0, this, + SLOT(slotSetMsgStatusSent()), + actionCollection(), "status_sent"); + statusMenu->insert( sentAction ); + + KAction *flagAction=new KAction( i18n("&Flagged"), "kmmsgflag", 0, this, + SLOT(slotSetMsgStatusFlag()), + actionCollection(), "status_flag"); + statusMenu->insert( flagAction ); + + moveActionMenu = new KActionMenu( i18n("&Move to" ), actionCollection(), "move_to" ); - moveMenu = moveActionMenu->popupMenu(); - KActionMenu *copyActionMenu = new KActionMenu( i18n("&Copy to" ), + copyActionMenu = new KActionMenu( i18n("&Copy to" ), actionCollection(), "copy_to" ); - copyMenu = copyActionMenu->popupMenu(); (void) new KAction( i18n("Apply filters"), CTRL+Key_J, this, SLOT(slotApplyFilters()), actionCollection(), "apply_filters" ); @@ -1729,6 +1801,8 @@ void KMMainWin::setupMenuBar() SIGNAL( aboutToShow() ), this, SLOT( updateMessageMenu() )); conserveMemory(); + updateMessageMenu(); + } @@ -1766,7 +1840,6 @@ void KMMainWin::slotEditKeys() KKeyDialog::configureKeys(actionCollection(), xmlFile(), true, this); } - //----------------------------------------------------------------------------- void KMMainWin::setupStatusBar() { @@ -1843,6 +1916,8 @@ QPopupMenu* KMMainWin::folderToPopupMenu(KMFolderTreeItem* fti, { int menuId; QString label; + menu->clear(); + if (!fti) fti = static_cast(mFolderTree->firstChild()); if (move) { @@ -1893,10 +1968,63 @@ QPopupMenu* KMMainWin::folderToPopupMenu(KMFolderTreeItem* fti, void KMMainWin::updateMessageMenu() { mMenuToFolder.clear(); - moveMenu->clear(); - folderToPopupMenu( NULL, TRUE, this, &mMenuToFolder, moveMenu ); - copyMenu->clear(); - folderToPopupMenu( NULL, FALSE, this, &mMenuToFolder, copyMenu ); + folderToPopupMenu( 0, true, this, &mMenuToFolder, moveActionMenu->popupMenu() ); + folderToPopupMenu( 0, false, this, &mMenuToFolder, copyActionMenu->popupMenu() ); + + int count = 0; + + if ( mFolder ) { + for (QListViewItem *item = mHeaders->firstChild(); item; item = item->itemBelow()) + if (item->isSelected() ) + count++; + if ( !count && mFolder->count() ) // there will always be one in mMsgView + count = 1; + } + + mlistFilterAction->setText( i18n("Filter on Mailing-List...") ); + + bool mass_actions = count >= 1; + statusMenu->setEnabled( mass_actions ); + moveActionMenu->setEnabled( mass_actions ); + copyActionMenu->setEnabled( mass_actions ); + deleteAction->setEnabled( mass_actions ); + action( "apply_filters" )->setEnabled( mass_actions ); + + bool single_actions = count == 1; + filterMenu->setEnabled( single_actions ); + editAction->setEnabled( single_actions ); + bounceAction->setEnabled( single_actions ); + replyAction->setEnabled( single_actions ); + noQuoteReplyAction->setEnabled( single_actions ); + replyAllAction->setEnabled( single_actions ); + replyListAction->setEnabled( single_actions ); + forwardAction->setEnabled( single_actions ); + redirectAction->setEnabled( single_actions ); + sendAgainAction->setEnabled( single_actions ); + printAction->setEnabled( single_actions ); + saveAsAction->setEnabled( single_actions ); + action( "view_source" )->setEnabled( single_actions ); + + if ( count == 1 ) { + KMMessage* msg = mMsgView->msg(); + if ( !msg ) + return; + + QString name, value; + QString lname = detect_list( msg, name, value ); + if ( lname.isNull() ) + mlistFilterAction->setEnabled( false ); + else { + mlistFilterAction->setEnabled( true ); + mlistFilterAction->setText( i18n( "Filter on Mailing-List %1..." ).arg( lname ) ); + } + } + + bool mails = mFolder && mFolder->count(); + action( "next" )->setEnabled( mails ); + action( "next_unread" )->setEnabled( mails ); + action( "previous" )->setEnabled( mails ); + action( "previous_unread" )->setEnabled( mails ); } diff --git a/kmmainwin.h b/kmmainwin.h index 6f7917799..91e8e5731 100644 --- a/kmmainwin.h +++ b/kmmainwin.h @@ -79,8 +79,8 @@ public: KAction *replyAction, *noQuoteReplyAction, *replyAllAction, *replyListAction, *forwardAction, *redirectAction, *deleteAction, *saveAsAction, *bounceAction, *editAction, - *newAction, *unreadAction, *readAction, *repliedAction, *queueAction, - *sentAction, *flagAction, *printAction; + *printAction, *sendAgainAction; + KActionMenu *filterMenu, *statusMenu, *moveActionMenu, *copyActionMenu; void folderSelected(KMFolder*, bool jumpToUnread); @@ -101,6 +101,9 @@ public slots: void slotSelectFolder(KMFolder*); void slotSelectMessage(KMMessage*); + // Update the "Move to" and "Copy to" popoutmenus in the Messages menu. + virtual void updateMessageMenu(); + protected: void setupMenuBar(); void setupStatusBar(); @@ -148,6 +151,10 @@ protected slots: void slotCopyMsg(); void slotResendMsg(); void slotApplyFilters(); + void slotSubjectFilter(); + void slotMailingListFilter(); + void slotFromFilter(); + void slotToFilter(); void slotSetMsgStatusNew(); void slotSetMsgStatusUnread(); void slotSetMsgStatusRead(); @@ -191,8 +198,6 @@ protected slots: virtual void moveSelectedToFolder( int menuId ); // Copy selected messages to folder with corresponding to given menuid virtual void copySelectedToFolder( int menuId ); - // Update the "Move to" and "Copy to" popoutmenus in the Messages menu. - virtual void updateMessageMenu(); // Update html and threaded messages preferences in Folder menu. virtual void updateFolderMenu(); @@ -212,6 +217,7 @@ protected: QTextCodec *mCodec; QPopupMenu *mViewMenu, *mBodyPartsMenu; KSelectAction *mEncoding; + KAction *mlistFilterAction; QString mEncodingStr; bool mIntegrated; bool mSendOnCheck; @@ -237,7 +243,6 @@ protected: KAction *modifyFolderAction, *removeFolderAction; KToggleAction *preferHtmlAction, *threadMessagesAction; KToggleAction *toolbarAction, *statusbarAction; - QPopupMenu *copyMenu, *moveMenu; }; #endif diff --git a/kmmainwin.rc b/kmmainwin.rc index 7cd505a44..822931f8f 100644 --- a/kmmainwin.rc +++ b/kmmainwin.rc @@ -1,4 +1,4 @@ - + &File @@ -62,16 +62,7 @@ - - Set status - - - - - - - - + diff --git a/mailinglist-magic.cpp b/mailinglist-magic.cpp new file mode 100644 index 000000000..a2e2519bd --- /dev/null +++ b/mailinglist-magic.cpp @@ -0,0 +1,152 @@ +#include +#include + +typedef QString (*MagicDetectorFunc) (const KMMessage *, QString &, QString &); + +/* Sender: (owner-([^@]+)|([^@+]-owner)@ */ +static QString check_sender(const KMMessage *message, + QString &header_name, + QString &header_value ) +{ + QString header = message->headerField( "Sender" ); + + if ( header.isEmpty() ) + return QString::null; + + if ( header.left( 6 ) == "owner-" ) + { + header_name = "Sender"; + header_value = header; + header = header.mid( 6, header.find( "@" ) - 6 ); + + } else { + int index = header.find( "-owner@ " ); + if ( index == -1 ) + return QString::null; + + header = header.left( index ); + header_name = "Sender"; + header_value = header; + } + + return header; +} + +/* X-BeenThere: ([^@]+) */ +static QString check_x_beenthere(const KMMessage *message, + QString &header_name, + QString &header_value ) +{ + QString header = message->headerField( "X-BeenThere" ); + if ( header.isNull() || header.find( "@" ) == -1 ) + return QString::null; + + header_name = "X-BeenThere"; + header_value = header; + header = header.left( header.find( "@" ) ); + return header; +} + +/* X-Mailing-List: <([^@]+) */ +static QString check_delivered_to(const KMMessage *message, + QString &header_name, + QString &header_value ) +{ + QString header = message->headerField( "Delivered-To" ); + if ( header.isNull() || header.left(13 ) != "mailing list" + || header.find( "@" ) == -1 ) + return QString::null; + + header_name = "Delivered-To"; + header_value = header; + + return header.mid( 13, header.find( "@" ) - 13 ); +} + +/* X-Mailing-List: <([^@]+) */ +static QString check_x_mailing_list(const KMMessage *message, + QString &header_name, + QString &header_value ) +{ + QString header = message->headerField( "X-Mailing-List"); + if ( header.isEmpty() ) + return QString::null; + + if (header.at( 0 ) != '<' || header.find( "@" ) < 2 || + header.at( header.length() - 1 ) != '>') + return QString::null; + + header_name = "X-Mailing-List"; + header_value = header; + header = header.mid(1, header.find( "@" ) - 1); + return header; +} + +/* Mailing-List: list ([^@]+) */ +static QString check_mailing_list(const KMMessage *message, + QString &header_name, + QString &header_value ) +{ + QString header = message->headerField( "Mailing-List"); + if ( header.isEmpty() ) + return QString::null; + + if (header.left( 5 ) != "list " || header.find( "@" ) < 5 ) + return QString::null; + + header_name = "Mailing-List"; + header_value = header; + header = header.mid(5, header.find( "@" ) - 5); + return header; +} + + +/* X-Loop: ([^@]+) */ +static QString check_x_loop(const KMMessage *message, + QString &header_name, + QString &header_value ){ + QString header = message->headerField( "X-Loop"); + if ( header.isEmpty() ) + return QString::null; + + if (header.find( "@" ) < 2 ) + return QString::null; + + header_name = "X-Loop"; + header_value = header; + header = header.left(header.find( "@" )); + return header; +} + +MagicDetectorFunc magic_detector[] = +{ + check_sender, + check_x_mailing_list, + check_mailing_list, + check_delivered_to, + check_x_beenthere, + check_x_loop +}; + +static const int num_detectors = sizeof (magic_detector) / sizeof (magic_detector[0]); + +QString detect_list(const KMMessage *message, + QString &header_name, + QString &header_value ) +{ + header_name = QString::null; + header_value = QString::null; + + if ( !message ) + return QString::null; + + QString list; + + for (int i = 0; i < num_detectors; i++) { + list = magic_detector[i] (message, header_name, header_value); + if ( !list.isNull() ) + return list; + } + + return QString::null; +} diff --git a/mailinglist-magic.h b/mailinglist-magic.h new file mode 100644 index 000000000..717ed4abb --- /dev/null +++ b/mailinglist-magic.h @@ -0,0 +1,13 @@ +#ifndef MAILING_LIST_MAGIC_H +#define MAILING_LIST_MAGIC_H + +#include + +class KMMessage; + +QString detect_list(const KMMessage *message, + QString &header_name, + QString &header_value ); + +#endif +