diff -Nur kdepim-3.5.0.orig/kmail/actionscheduler.cpp kdepim-3.5.0/kmail/actionscheduler.cpp --- kdepim-3.5.0.orig/kmail/actionscheduler.cpp 2005-09-10 10:24:02.000000000 +0200 +++ kdepim-3.5.0/kmail/actionscheduler.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -570,7 +570,7 @@ (!mAccount || (mAccount && (*mFilterIt).applyOnAccount(mAccountId)))) || ((mSet & KMFilterMgr::Explicit) && (*mFilterIt).applyOnExplicit())) { - + // filter is applicable if ( FilterLog::instance()->isLogging() ) { QString logText( i18n( "Evaluating filter rules: " ) ); @@ -646,8 +646,11 @@ if (!orgMsg || !orgMsg->parent()) { // Original message is gone, no point filtering it anymore mSrcFolder->removeMsg( mSrcFolder->find( msg ) ); + kdDebug(5006) << "The original serial number is missing. " + << "Cannot complete the filtering." << endl; mExecutingLock = false; processMessageTimer->start( 0, true ); + return; } else { if (!folder) // no filter folder specified leave in current place folder = orgMsg->parent(); @@ -659,7 +662,7 @@ mSrcFolder->addMsg( msg ); mIgnore = false; - if (msg && kmkernel->folderIsTrash( folder )) + if (msg && folder && kmkernel->folderIsTrash( folder )) KMFilterAction::sendMDN( msg, KMime::MDN::Deleted ); timeOutTime = QTime::currentTime(); @@ -722,8 +725,6 @@ void ActionScheduler::copyMessageFinished( KMCommand *command ) { - // FIXME remove the debug output - kdDebug(5006) << "##### ActionScheduler::copyMessageFinished( KMCommand *command )" << endl; if ( command->result() != KMCommand::OK ) actionMessage( KMFilterAction::ErrorButGoOn ); else @@ -803,4 +804,11 @@ return sEnabled; } +bool ActionScheduler::ignoreChanges( bool ignore ) +{ + bool oldValue = mIgnore; + mIgnore = ignore; + return oldValue; +} + #include "actionscheduler.moc" diff -Nur kdepim-3.5.0.orig/kmail/actionscheduler.h kdepim-3.5.0/kmail/actionscheduler.h --- kdepim-3.5.0.orig/kmail/actionscheduler.h 2005-09-10 10:24:02.000000000 +0200 +++ kdepim-3.5.0/kmail/actionscheduler.h 2005-12-07 23:34:28.000000000 +0100 @@ -77,10 +77,10 @@ of messages left to process is empty */ void setFilterList( QValueList filters ); - /* Set the id of the account associated with this scheduler */ + /** Set the id of the account associated with this scheduler */ void setAccountId( uint id ) { mAccountId = id; mAccount = true; } - /* Clear the id of the account associated with this scheduler */ + /** Clear the id of the account associated with this scheduler */ void clearAccountId() { mAccountId = 0; mAccount = false; } /** Queue a message for filtering */ @@ -88,9 +88,16 @@ void execFilters(const QPtrList msgList); void execFilters(KMMsgBase* msgBase); void execFilters(Q_UINT32 serNum); + static QString debug(); static bool isEnabled(); + /** Allow or deny manipulations on the message to be filtered. + This is needed when using pipe-through filters, because the + changes made by the filter have to be written back. + The old value before applying the new value is returned. */ + bool ignoreChanges( bool ignore ); + signals: /** Emitted when filtering is completed */ void result(ReturnCode); diff -Nur kdepim-3.5.0.orig/kmail/kmcommands.cpp kdepim-3.5.0/kmail/kmcommands.cpp --- kdepim-3.5.0.orig/kmail/kmcommands.cpp 2005-10-10 17:02:11.000000000 +0200 +++ kdepim-3.5.0/kmail/kmcommands.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -1464,15 +1464,20 @@ KMCommand::Result KMFilterActionCommand::execute() { + KCursorSaver busy( KBusyPtr::busy() ); QPtrList msgList = retrievedMsgs(); for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) if( msg->parent() ) kmkernel->filterMgr()->tempOpenFolder(msg->parent()); + int counter = 0; for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) { msg->setTransferInProgress(false); + if ( !( ++counter % 20 ) ) + KApplication::kApplication()->processEvents( 50 ); + int filterResult = kmkernel->filterMgr()->process(msg, mFilter); if (filterResult == 2) { // something went horribly wrong (out of space?) @@ -1496,30 +1501,30 @@ void KMMetaFilterActionCommand::start() { -#if 0 // use action scheduler - KMFilterMgr::FilterSet set = KMFilterMgr::All; - QPtrList filters; - filters.append( mFilter ); - ActionScheduler *scheduler = new ActionScheduler( set, filters, mHeaders ); - scheduler->setAlwaysMatch( true ); - scheduler->setAutoDestruct( true ); - - int contentX, contentY; - HeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY ); - QPtrList msgList = *mHeaders->selectedMsgs(true); - mHeaders->finalizeMove( nextItem, contentX, contentY ); - - - for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next()) - scheduler->execFilters( msg ); -#else - KMCommand *filterCommand = new KMFilterActionCommand( mMainWidget, - *mHeaders->selectedMsgs(), mFilter); - filterCommand->start(); - int contentX, contentY; - HeaderItem *item = mHeaders->prepareMove( &contentX, &contentY ); - mHeaders->finalizeMove( item, contentX, contentY ); -#endif + if (ActionScheduler::isEnabled() ) { + // use action scheduler + KMFilterMgr::FilterSet set = KMFilterMgr::All; + QValueList filters; + filters.append( mFilter ); + ActionScheduler *scheduler = new ActionScheduler( set, filters, mHeaders ); + scheduler->setAlwaysMatch( true ); + scheduler->setAutoDestruct( true ); + + int contentX, contentY; + HeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY ); + QPtrList msgList = *mHeaders->selectedMsgs(true); + mHeaders->finalizeMove( nextItem, contentX, contentY ); + + for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next()) + scheduler->execFilters( msg ); + } else { + KMCommand *filterCommand = new KMFilterActionCommand( mMainWidget, + *mHeaders->selectedMsgs(), mFilter); + filterCommand->start(); + int contentX, contentY; + HeaderItem *item = mHeaders->prepareMove( &contentX, &contentY ); + mHeaders->finalizeMove( item, contentX, contentY ); + } } FolderShortcutCommand::FolderShortcutCommand( KMMainWidget *mainwidget, diff -Nur kdepim-3.5.0.orig/kmail/kmfilteraction.cpp kdepim-3.5.0/kmail/kmfilteraction.cpp --- kdepim-3.5.0.orig/kmail/kmfilteraction.cpp 2005-09-10 10:24:02.000000000 +0200 +++ kdepim-3.5.0/kmail/kmfilteraction.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -1617,6 +1617,9 @@ FILE *p; QByteArray ba; + // backup the serial number in case the header gets lost + QString origSerNum = mMsg->headerField( "X-KMail-Filtered" ); + p = popen(QFile::encodeName(mCmd), "r"); int len =100; char buffer[100]; @@ -1630,7 +1633,20 @@ pclose(p); if ( !ba.isEmpty() ) { KPIM::ThreadWeaver::debug (1, "PipeJob::run: %s", QString(ba).latin1() ); + KMFolder *filterFolder = mMsg->parent(); + ActionScheduler *handler = MessageProperty::filterHandler( mMsg->getMsgSerNum() ); + mMsg->fromByteArray( ba ); + if ( !origSerNum.isEmpty() ) + mMsg->setHeaderField( "X-KMail-Filtered", origSerNum ); + if ( filterFolder && handler ) { + bool oldStatus = handler->ignoreChanges( true ); + filterFolder->take( filterFolder->find( mMsg ) ); + filterFolder->addMsg( mMsg ); + handler->ignoreChanges( oldStatus ); + } else { + kdDebug(5006) << "Warning: Cannot refresh the message from the external filter." << endl; + } } KPIM::ThreadWeaver::debug (1, "PipeJob::run: done.\n" ); diff -Nur kdepim-3.5.0.orig/kmail/kmfolder.cpp kdepim-3.5.0/kmail/kmfolder.cpp --- kdepim-3.5.0.orig/kmail/kmfolder.cpp 2005-11-19 11:56:46.000000000 +0100 +++ kdepim-3.5.0/kmail/kmfolder.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -263,8 +263,13 @@ } } - mChild = new KMFolderDir( this, parent(), childName, - (folderType() == KMFolderTypeImap) ? KMImapDir : KMStandardDir); + KMFolderDirType newType = KMStandardDir; + if( folderType() == KMFolderTypeCachedImap ) + newType = KMDImapDir; + else if( folderType() == KMFolderTypeImap ) + newType = KMImapDir; + + mChild = new KMFolderDir( this, parent(), childName, newType ); if( !mChild ) return 0; mChild->reload(); diff -Nur kdepim-3.5.0.orig/kmail/kmheaders.cpp kdepim-3.5.0/kmail/kmheaders.cpp --- kdepim-3.5.0.orig/kmail/kmheaders.cpp 2005-10-10 17:02:11.000000000 +0200 +++ kdepim-3.5.0/kmail/kmheaders.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -1339,7 +1339,11 @@ CREATE_TIMER(filter); START_TIMER(filter); + KCursorSaver busy( KBusyPtr::busy() ); + int counter = 0; for (KMMsgBase* msgBase=msgList->first(); msgBase; msgBase=msgList->next()) { + if ( !( ++counter % 20 ) ) + KApplication::kApplication()->processEvents( 50 ); int idx = msgBase->parent()->find(msgBase); assert(idx != -1); KMMessage * msg = msgBase->parent()->getMsg(idx); diff -Nur kdepim-3.5.0.orig/kmail/kmkernel.cpp kdepim-3.5.0/kmail/kmkernel.cpp --- kdepim-3.5.0.orig/kmail/kmkernel.cpp 2005-11-08 23:33:29.000000000 +0100 +++ kdepim-3.5.0/kmail/kmkernel.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -1432,11 +1432,11 @@ the_msgIndex = 0; #endif -#if 0 +//#if 0 the_weaver = new KPIM::ThreadWeaver::Weaver( this ); the_weaverLogger = new KPIM::ThreadWeaver::WeaverThreadLogger(this); the_weaverLogger->attach (the_weaver); -#endif +//#endif connect( the_folderMgr, SIGNAL( folderRemoved(KMFolder*) ), this, SIGNAL( folderRemoved(KMFolder*) ) ); diff -Nur kdepim-3.5.0.orig/kmail/kmmainwidget.cpp kdepim-3.5.0/kmail/kmmainwidget.cpp --- kdepim-3.5.0.orig/kmail/kmmainwidget.cpp 2005-10-10 17:02:11.000000000 +0200 +++ kdepim-3.5.0/kmail/kmmainwidget.cpp 2005-12-07 23:34:28.000000000 +0100 @@ -1644,11 +1644,11 @@ { if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online ) { // if online; then toggle and set it offline. - actionCollection()->action( "online_status" )->setText( i18n("Network State (online)") ); + actionCollection()->action( "online_status" )->setText( i18n("Go Online") ); kmkernel->stopNetworkJobs(); BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be offline; all network jobs are suspended")); } else { - actionCollection()->action( "online_status" )->setText( i18n("Network State (offline)") ); + actionCollection()->action( "online_status" )->setText( i18n("Go Offline") ); kmkernel->resumeNetworkJobs(); BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be online; all network jobs resumed")); } @@ -3000,9 +3000,9 @@ actionCollection()->action( "send_queued" )->setEnabled( kmkernel->outboxFolder()->count() > 0 ); actionCollection()->action( "send_queued_via" )->setEnabled( kmkernel->outboxFolder()->count() > 0 ); if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online ) - actionCollection()->action( "online_status" )->setText( i18n("Network State (offline)") ); + actionCollection()->action( "online_status" )->setText( i18n("Go Offline") ); else - actionCollection()->action( "online_status" )->setText( i18n("Network State (online)") ); + actionCollection()->action( "online_status" )->setText( i18n("Go Online") ); if (action( "edit_undo" )) action( "edit_undo" )->setEnabled( mHeaders->canUndo() ); @@ -3311,6 +3311,7 @@ if(!addedSeparator) { mApplyFilterActionsMenu->popupMenu()->insertSeparator(); addedSeparator = !addedSeparator; + mFilterMenuActions.append( new KActionSeparator()); } filterAction->plug( mApplyFilterActionsMenu->popupMenu() ); mFilterMenuActions.append(filterAction);