kmail

antispamwizard.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of KMail.
00003     Copyright (c) 2003 Andreas Gungl <a.gungl@gmx.de>
00004 
00005     KMail is free software; you can redistribute it and/or modify it
00006     under the terms of the GNU General Public License, version 2, as
00007     published by the Free Software Foundation.
00008 
00009     KMail is distributed in the hope that it will be useful, but
00010     WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017 
00018     In addition, as a special exception, the copyright holders give
00019     permission to link the code of this program with any edition of
00020     the Qt library by Trolltech AS, Norway (or with modified versions
00021     of Qt that use the same license as Qt), and distribute linked
00022     combinations including the two.  You must obey the GNU General
00023     Public License in all respects for all of the code used other than
00024     Qt.  If you modify this file, you may extend this exception to
00025     your version of the file, but you are not obligated to do so.  If
00026     you do not wish to do so, delete this exception statement from
00027     your version.
00028 */
00029 
00030 #include "antispamwizard.h"
00031 #include "kcursorsaver.h"
00032 #include "accountmanager.h"
00033 #include "kmfilter.h"
00034 #include "kmfilteraction.h"
00035 #include "kmfiltermgr.h"
00036 #include "kmkernel.h"
00037 #include "kmfolderseldlg.h"
00038 #include "kmfoldertree.h"
00039 #include "kmmainwin.h"
00040 #include "networkaccount.h"
00041 #include "folderrequester.h"
00042 
00043 #include <kaction.h>
00044 #include <kapplication.h>
00045 #include <kdebug.h>
00046 #include <kdialog.h>
00047 #include <kiconloader.h>
00048 #include <klocale.h>
00049 #include <kmessagebox.h>
00050 #include <kprocess.h>
00051 
00052 #include <qdom.h>
00053 #include <qlabel.h>
00054 #include <qlayout.h>
00055 #include <qtooltip.h>
00056 #include <qwhatsthis.h>
00057 
00058 using namespace KMail;
00059 
00060 AntiSpamWizard::AntiSpamWizard( WizardMode mode,
00061                                 QWidget* parent, KMFolderTree * mainFolderTree )
00062   : KWizard( parent ),
00063     mInfoPage( 0 ),
00064     mSpamRulesPage( 0 ),
00065     mVirusRulesPage( 0 ),
00066     mSummaryPage( 0 ),
00067     mMode( mode )
00068 {
00069   // read the configuration for the anti-spam tools
00070   ConfigReader reader( mMode, mToolList );
00071   reader.readAndMergeConfig();
00072   mToolList = reader.getToolList();
00073 
00074 #ifndef NDEBUG
00075   if ( mMode == AntiSpam )
00076     kdDebug(5006) << endl << "Considered anti-spam tools: " << endl;
00077   else
00078     kdDebug(5006) << endl << "Considered anti-virus tools: " << endl;
00079 #endif
00080   for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00081         it != mToolList.end(); ++it ) {
00082 #ifndef NDEBUG
00083     kdDebug(5006) << "Predefined tool: " << (*it).getId() << endl;
00084     kdDebug(5006) << "Config version: " << (*it).getVersion() << endl;
00085     kdDebug(5006) << "Selection priority: " << (*it).getPrio() << endl;
00086     kdDebug(5006) << "Displayed name: " << (*it).getVisibleName() << endl;
00087     kdDebug(5006) << "Executable: " << (*it).getExecutable() << endl;
00088     kdDebug(5006) << "WhatsThis URL: " << (*it).getWhatsThisText() << endl;
00089     kdDebug(5006) << "Filter name: " << (*it).getFilterName() << endl;
00090     kdDebug(5006) << "Detection command: " << (*it).getDetectCmd() << endl;
00091     kdDebug(5006) << "Learn spam command: " << (*it).getSpamCmd() << endl;
00092     kdDebug(5006) << "Learn ham command: " << (*it).getHamCmd() << endl;
00093     kdDebug(5006) << "Detection header: " << (*it).getDetectionHeader() << endl;
00094     kdDebug(5006) << "Detection pattern: " << (*it).getDetectionPattern() << endl;
00095     kdDebug(5006) << "Use as RegExp: " << (*it).isUseRegExp() << endl;
00096     kdDebug(5006) << "Supports Bayes Filter: " << (*it).useBayesFilter() << endl;
00097     kdDebug(5006) << "Type: " << (*it).getType() << endl << endl;
00098 #endif
00099   }
00100 
00101   setCaption( ( mMode == AntiSpam ) ? i18n( "Anti-Spam Wizard" )
00102                                     : i18n( "Anti-Virus Wizard" ) );
00103   mInfoPage = new ASWizInfoPage( mMode, 0, "" );
00104   addPage( mInfoPage,
00105            ( mMode == AntiSpam )
00106            ? i18n( "Welcome to the KMail Anti-Spam Wizard" )
00107            : i18n( "Welcome to the KMail Anti-Virus Wizard" ) );
00108   connect( mInfoPage, SIGNAL( selectionChanged( void ) ),
00109             this, SLOT( checkProgramsSelections( void ) ) );
00110 
00111   if ( mMode == AntiSpam ) {
00112     mSpamRulesPage = new ASWizSpamRulesPage( 0, "", mainFolderTree );
00113     addPage( mSpamRulesPage, i18n( "Options to fine-tune the handling of spam messages" ));
00114     connect( mSpamRulesPage, SIGNAL( selectionChanged( void ) ),
00115              this, SLOT( slotBuildSummary( void ) ) );
00116   }
00117   else {
00118     mVirusRulesPage = new ASWizVirusRulesPage( 0, "", mainFolderTree );
00119     addPage( mVirusRulesPage, i18n( "Options to fine-tune the handling of virus messages" ));
00120     connect( mVirusRulesPage, SIGNAL( selectionChanged( void ) ),
00121              this, SLOT( checkVirusRulesSelections( void ) ) );
00122   }
00123 
00124   connect( this, SIGNAL( helpClicked( void) ),
00125             this, SLOT( slotHelpClicked( void ) ) );
00126 
00127   setNextEnabled( mInfoPage, false );
00128 
00129   if ( mMode == AntiSpam ) {
00130     mSummaryPage = new ASWizSummaryPage( 0, "" );
00131     addPage( mSummaryPage, i18n( "Summary of changes to be made by this wizard" ) );
00132     setNextEnabled( mSpamRulesPage, true );
00133     setFinishEnabled( mSummaryPage, true );
00134   }
00135 
00136   QTimer::singleShot( 0, this, SLOT( checkToolAvailability( void ) ) );
00137 }
00138 
00139 
00140 void AntiSpamWizard::accept()
00141 {
00142   if ( mSpamRulesPage ) {
00143     kdDebug( 5006 ) << "Folder name for messages classified as spam is "
00144                     << mSpamRulesPage->selectedSpamFolderName() << endl;
00145     kdDebug( 5006 ) << "Folder name for messages classified as unsure is "
00146                     << mSpamRulesPage->selectedUnsureFolderName() << endl;
00147   }
00148   if ( mVirusRulesPage )
00149     kdDebug( 5006 ) << "Folder name for viruses is "
00150                     << mVirusRulesPage->selectedFolderName() << endl;
00151 
00152   KMFilterActionDict dict;
00153   QValueList<KMFilter*> filterList;
00154   bool replaceExistingFilters = false;
00155 
00156   // Let's start with virus detection and handling,
00157   // so we can avoid spam checks for viral messages
00158   if ( mMode == AntiVirus ) {
00159     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00160           it != mToolList.end(); ++it ) {
00161       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
00162          ( mVirusRulesPage->pipeRulesSelected() && (*it).isVirusTool() ) )
00163       {
00164         // pipe messages through the anti-virus tools,
00165         // one single filter for each tool
00166         // (could get combined but so it's easier to understand for the user)
00167         KMFilter* pipeFilter = new KMFilter();
00168         QPtrList<KMFilterAction>* pipeFilterActions = pipeFilter->actions();
00169         KMFilterAction* pipeFilterAction = dict["filter app"]->create();
00170         pipeFilterAction->argsFromString( (*it).getDetectCmd() );
00171         pipeFilterActions->append( pipeFilterAction );
00172         KMSearchPattern* pipeFilterPattern = pipeFilter->pattern();
00173         pipeFilterPattern->setName( uniqueNameFor( (*it).getFilterName() ) );
00174         pipeFilterPattern->append( KMSearchRule::createInstance( "<size>",
00175                                    KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
00176         pipeFilter->setApplyOnOutbound( false);
00177         pipeFilter->setApplyOnInbound();
00178         pipeFilter->setApplyOnExplicit();
00179         pipeFilter->setStopProcessingHere( false );
00180         pipeFilter->setConfigureShortcut( false );
00181 
00182         filterList.append( pipeFilter );
00183       }
00184     }
00185 
00186     if ( mVirusRulesPage->moveRulesSelected() )
00187     {
00188       // Sort out viruses depending on header fields set by the tools
00189       KMFilter* virusFilter = new KMFilter();
00190       QPtrList<KMFilterAction>* virusFilterActions = virusFilter->actions();
00191       KMFilterAction* virusFilterAction1 = dict["transfer"]->create();
00192       virusFilterAction1->argsFromString( mVirusRulesPage->selectedFolderName() );
00193       virusFilterActions->append( virusFilterAction1 );
00194       if ( mVirusRulesPage->markReadRulesSelected() ) {
00195         KMFilterAction* virusFilterAction2 = dict["set status"]->create();
00196         virusFilterAction2->argsFromString( "R" ); // Read
00197         virusFilterActions->append( virusFilterAction2 );
00198       }
00199       KMSearchPattern* virusFilterPattern = virusFilter->pattern();
00200       virusFilterPattern->setName( uniqueNameFor( i18n( "Virus handling" ) ) );
00201       virusFilterPattern->setOp( KMSearchPattern::OpOr );
00202       for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00203             it != mToolList.end(); ++it ) {
00204         if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ))
00205         {
00206           if ( (*it).isVirusTool() )
00207           {
00208               const QCString header = (*it).getDetectionHeader().ascii();
00209               const QString & pattern = (*it).getDetectionPattern();
00210               if ( (*it).isUseRegExp() )
00211                 virusFilterPattern->append(
00212                   KMSearchRule::createInstance( header,
00213                   KMSearchRule::FuncRegExp, pattern ) );
00214               else
00215                 virusFilterPattern->append(
00216                   KMSearchRule::createInstance( header,
00217                   KMSearchRule::FuncContains, pattern ) );
00218           }
00219         }
00220       }
00221       virusFilter->setApplyOnOutbound( false);
00222       virusFilter->setApplyOnInbound();
00223       virusFilter->setApplyOnExplicit();
00224       virusFilter->setStopProcessingHere( true );
00225       virusFilter->setConfigureShortcut( false );
00226 
00227       filterList.append( virusFilter );
00228     }
00229   }
00230   else { // AntiSpam mode
00231     // TODO Existing filters with same name are replaced. This is hardcoded
00232     // ATM and needs to be replaced with a value from a (still missing)
00233     // checkbox in the GUI. At least, the replacement is announced in the GUI.
00234     replaceExistingFilters = true;
00235     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00236           it != mToolList.end(); ++it ) {
00237       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
00238          (*it).isSpamTool() && !(*it).isDetectionOnly() )
00239       {
00240         // pipe messages through the anti-spam tools,
00241         // one single filter for each tool
00242         // (could get combined but so it's easier to understand for the user)
00243         KMFilter* pipeFilter = new KMFilter();
00244         QPtrList<KMFilterAction>* pipeFilterActions = pipeFilter->actions();
00245         KMFilterAction* pipeFilterAction = dict["filter app"]->create();
00246         pipeFilterAction->argsFromString( (*it).getDetectCmd() );
00247         pipeFilterActions->append( pipeFilterAction );
00248         KMSearchPattern* pipeFilterPattern = pipeFilter->pattern();
00249         if ( replaceExistingFilters )
00250           pipeFilterPattern->setName( (*it).getFilterName() );
00251         else
00252           pipeFilterPattern->setName( uniqueNameFor( (*it).getFilterName() ) );
00253         pipeFilterPattern->append( KMSearchRule::createInstance( "<size>",
00254                                    KMSearchRule::FuncIsLessOrEqual, "256000" ) );
00255         pipeFilter->setApplyOnOutbound( false);
00256         pipeFilter->setApplyOnInbound();
00257         pipeFilter->setApplyOnExplicit();
00258         pipeFilter->setStopProcessingHere( false );
00259         pipeFilter->setConfigureShortcut( false );
00260 
00261         filterList.append( pipeFilter );
00262       }
00263     }
00264 
00265     // Sort out spam depending on header fields set by the tools
00266     KMFilter* spamFilter = new KMFilter();
00267     QPtrList<KMFilterAction>* spamFilterActions = spamFilter->actions();
00268     if ( mSpamRulesPage->moveSpamSelected() )
00269     {
00270       KMFilterAction* spamFilterAction1 = dict["transfer"]->create();
00271       spamFilterAction1->argsFromString( mSpamRulesPage->selectedSpamFolderName() );
00272       spamFilterActions->append( spamFilterAction1 );
00273     }
00274     KMFilterAction* spamFilterAction2 = dict["set status"]->create();
00275     spamFilterAction2->argsFromString( "P" ); // Spam
00276     spamFilterActions->append( spamFilterAction2 );
00277     if ( mSpamRulesPage->markAsReadSelected() ) {
00278       KMFilterAction* spamFilterAction3 = dict["set status"]->create();
00279       spamFilterAction3->argsFromString( "R" ); // Read
00280       spamFilterActions->append( spamFilterAction3 );
00281     }
00282     KMSearchPattern* spamFilterPattern = spamFilter->pattern();
00283     if ( replaceExistingFilters )
00284       spamFilterPattern->setName( i18n( "Spam handling" ) );
00285     else
00286       spamFilterPattern->setName( uniqueNameFor( i18n( "Spam handling" ) ) );
00287     spamFilterPattern->setOp( KMSearchPattern::OpOr );
00288     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00289           it != mToolList.end(); ++it ) {
00290       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
00291       {
00292           if ( (*it).isSpamTool() )
00293           {
00294             const QCString header = (*it).getDetectionHeader().ascii();
00295             const QString & pattern = (*it).getDetectionPattern();
00296             if ( (*it).isUseRegExp() )
00297               spamFilterPattern->append(
00298                 KMSearchRule::createInstance( header,
00299                 KMSearchRule::FuncRegExp, pattern ) );
00300             else
00301               spamFilterPattern->append(
00302                 KMSearchRule::createInstance( header,
00303                 KMSearchRule::FuncContains, pattern ) );
00304           }
00305       }
00306     }
00307     spamFilter->setApplyOnOutbound( false);
00308     spamFilter->setApplyOnInbound();
00309     spamFilter->setApplyOnExplicit();
00310     spamFilter->setStopProcessingHere( true );
00311     spamFilter->setConfigureShortcut( false );
00312     filterList.append( spamFilter );
00313 
00314     if ( mSpamRulesPage->moveUnsureSelected() )
00315     {
00316       // Sort out messages classified as unsure
00317       bool atLeastOneUnsurePattern = false;
00318       KMFilter* unsureFilter = new KMFilter();
00319       QPtrList<KMFilterAction>* unsureFilterActions = unsureFilter->actions();
00320       KMFilterAction* unsureFilterAction1 = dict["transfer"]->create();
00321       unsureFilterAction1->argsFromString( mSpamRulesPage->selectedUnsureFolderName() );
00322       unsureFilterActions->append( unsureFilterAction1 );
00323       KMSearchPattern* unsureFilterPattern = unsureFilter->pattern();
00324       if ( replaceExistingFilters )
00325         unsureFilterPattern->setName( i18n( "Semi spam (unsure) handling" ) );
00326       else
00327         unsureFilterPattern->setName( uniqueNameFor( i18n( "Semi spam (unsure) handling" ) ) );
00328       unsureFilterPattern->setOp( KMSearchPattern::OpOr );
00329       for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00330             it != mToolList.end(); ++it ) {
00331         if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
00332         {
00333             if ( (*it).isSpamTool() && (*it).hasTristateDetection())
00334             {
00335               atLeastOneUnsurePattern = true;
00336               const QCString header = (*it).getDetectionHeader().ascii();
00337               const QString & pattern = (*it).getDetectionPattern2();
00338               if ( (*it).isUseRegExp() )
00339                 unsureFilterPattern->append(
00340                   KMSearchRule::createInstance( header,
00341                   KMSearchRule::FuncRegExp, pattern ) );
00342               else
00343                 unsureFilterPattern->append(
00344                   KMSearchRule::createInstance( header,
00345                   KMSearchRule::FuncContains, pattern ) );
00346             }
00347         }
00348       }
00349       unsureFilter->setApplyOnOutbound( false);
00350       unsureFilter->setApplyOnInbound();
00351       unsureFilter->setApplyOnExplicit();
00352       unsureFilter->setStopProcessingHere( true );
00353       unsureFilter->setConfigureShortcut( false );
00354 
00355       if ( atLeastOneUnsurePattern )
00356         filterList.append( unsureFilter );
00357       else
00358         delete unsureFilter;
00359     }
00360 
00361     // Classify messages manually as Spam
00362     KMFilter* classSpamFilter = new KMFilter();
00363     classSpamFilter->setIcon( "mail_spam" );
00364     QPtrList<KMFilterAction>* classSpamFilterActions = classSpamFilter->actions();
00365     KMFilterAction* classSpamFilterActionFirst = dict["set status"]->create();
00366     classSpamFilterActionFirst->argsFromString( "P" );
00367     classSpamFilterActions->append( classSpamFilterActionFirst );
00368     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00369           it != mToolList.end(); ++it ) {
00370       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
00371           && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
00372       {
00373         KMFilterAction* classSpamFilterAction = dict["execute"]->create();
00374         classSpamFilterAction->argsFromString( (*it).getSpamCmd() );
00375         classSpamFilterActions->append( classSpamFilterAction );
00376       }
00377     }
00378     if ( mSpamRulesPage->moveSpamSelected() )
00379     {
00380       KMFilterAction* classSpamFilterActionLast = dict["transfer"]->create();
00381       classSpamFilterActionLast->argsFromString( mSpamRulesPage->selectedSpamFolderName() );
00382       classSpamFilterActions->append( classSpamFilterActionLast );
00383     }
00384 
00385     KMSearchPattern* classSpamFilterPattern = classSpamFilter->pattern();
00386     if ( replaceExistingFilters )
00387       classSpamFilterPattern->setName( i18n( "Classify as spam" ) );
00388     else
00389       classSpamFilterPattern->setName( uniqueNameFor( i18n( "Classify as spam" ) ) );
00390     classSpamFilterPattern->append( KMSearchRule::createInstance( "<size>",
00391                                     KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
00392     classSpamFilter->setApplyOnOutbound( false);
00393     classSpamFilter->setApplyOnInbound( false );
00394     classSpamFilter->setApplyOnExplicit( false );
00395     classSpamFilter->setStopProcessingHere( true );
00396     classSpamFilter->setConfigureShortcut( true );
00397     classSpamFilter->setConfigureToolbar( true );
00398     filterList.append( classSpamFilter );
00399 
00400     // Classify messages manually as not Spam / as Ham
00401     KMFilter* classHamFilter = new KMFilter();
00402     classHamFilter->setIcon( "mail_ham" );
00403     QPtrList<KMFilterAction>* classHamFilterActions = classHamFilter->actions();
00404     KMFilterAction* classHamFilterActionFirst = dict["set status"]->create();
00405     classHamFilterActionFirst->argsFromString( "H" );
00406     classHamFilterActions->append( classHamFilterActionFirst );
00407     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00408           it != mToolList.end(); ++it ) {
00409       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
00410           && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
00411       {
00412         KMFilterAction* classHamFilterAction = dict["execute"]->create();
00413         classHamFilterAction->argsFromString( (*it).getHamCmd() );
00414         classHamFilterActions->append( classHamFilterAction );
00415       }
00416     }
00417     KMSearchPattern* classHamFilterPattern = classHamFilter->pattern();
00418     if ( replaceExistingFilters )
00419       classHamFilterPattern->setName( i18n( "Classify as NOT spam" ) );
00420     else
00421       classHamFilterPattern->setName( uniqueNameFor( i18n( "Classify as NOT spam" ) ) );
00422     classHamFilterPattern->append( KMSearchRule::createInstance( "<size>",
00423                                     KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
00424     classHamFilter->setApplyOnOutbound( false);
00425     classHamFilter->setApplyOnInbound( false );
00426     classHamFilter->setApplyOnExplicit( false );
00427     classHamFilter->setStopProcessingHere( true );
00428     classHamFilter->setConfigureShortcut( true );
00429     classHamFilter->setConfigureToolbar( true );
00430     filterList.append( classHamFilter );
00431   }
00432 
00433   /* Now that all the filters have been added to the list, tell
00434    * the filter manager about it. That will emit filterListUpdate
00435    * which will result in the filter list in kmmainwidget being
00436    * initialized. This should happend only once. */
00437   if ( !filterList.isEmpty() )
00438     KMKernel::self()->filterMgr()->appendFilters(
00439           filterList, replaceExistingFilters );
00440 
00441   QDialog::accept();
00442 }
00443 
00444 
00445 void AntiSpamWizard::checkProgramsSelections()
00446 {
00447   bool status = false;
00448   bool supportUnsure = false;
00449 
00450   mSpamToolsUsed = false;
00451   mVirusToolsUsed = false;
00452   for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00453         it != mToolList.end(); ++it ) {
00454     if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
00455     {
00456       status = true;
00457       if ( (*it).isSpamTool() ) {
00458         mSpamToolsUsed = true;
00459         if ( (*it).hasTristateDetection() )
00460           supportUnsure = true;
00461       }
00462       if ( (*it).isVirusTool() )
00463         mVirusToolsUsed = true;
00464     }
00465   }
00466 
00467   if ( mMode == AntiSpam ) {
00468     mSpamRulesPage->allowUnsureFolderSelection( supportUnsure );
00469     slotBuildSummary();
00470   }
00471 
00472   if ( ( mMode == AntiVirus ) && mVirusToolsUsed )
00473     checkVirusRulesSelections();
00474 
00475   setNextEnabled( mInfoPage, status );
00476 }
00477 
00478 
00479 void AntiSpamWizard::checkVirusRulesSelections()
00480 {
00481   setFinishEnabled( mVirusRulesPage, anyVirusOptionChecked() );
00482 }
00483 
00484 
00485 void AntiSpamWizard::checkToolAvailability()
00486 {
00487   // this can take some time to find the tools
00488   KCursorSaver busy( KBusyPtr::busy() );
00489 
00490   bool found = false;
00491   for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00492         it != mToolList.end(); ++it ) {
00493     QString text( i18n("Scanning for %1...").arg( (*it).getId() ) );
00494     mInfoPage->setScanProgressText( text );
00495     if ( (*it).isSpamTool() && (*it).isServerBased() ) {
00496       // check the configured account for pattern in <server>
00497       QString pattern = (*it).getServerPattern();
00498       kdDebug(5006) << "Testing for server pattern:" << pattern << endl;
00499 
00500       AccountManager* mgr = kmkernel->acctMgr();
00501       KMAccount* account = mgr->first();
00502       while ( account ) {
00503         if ( account->type() == "pop" || account->type().contains( "imap" ) ) {
00504           const NetworkAccount * n = dynamic_cast<const NetworkAccount*>( account );
00505           if ( n && n->host().lower().contains( pattern.lower() ) ) {
00506             mInfoPage->addAvailableTool( (*it).getVisibleName() );
00507             found = true;
00508           }
00509         }
00510         account = mgr->next();
00511       }
00512     }
00513     else {
00514       // check the availability of the application
00515       KApplication::kApplication()->processEvents( 200 );
00516       if ( !checkForProgram( (*it).getExecutable() ) ) {
00517         mInfoPage->addAvailableTool( (*it).getVisibleName() );
00518         found = true;
00519       }
00520     }
00521   }
00522   if ( found )
00523     mInfoPage->setScanProgressText( ( mMode == AntiSpam )
00524                                     ? i18n("Scanning for anti-spam tools finished.")
00525                                     : i18n("Scanning for anti-virus tools finished.") );
00526   else
00527     mInfoPage->setScanProgressText( ( mMode == AntiSpam )
00528                                     ? i18n("<p>No spam detection tools have been found. "
00529                                            "Install your spam detection software and "
00530                                            "re-run this wizard.</p>")
00531                                     : i18n("Scanning complete. No anti-virus tools found.") );
00532 }
00533 
00534 
00535 void AntiSpamWizard::slotHelpClicked()
00536 {
00537   if ( mMode == AntiSpam )
00538     kapp->invokeHelp( "the-anti-spam-wizard", "kmail" );
00539   else
00540     kapp->invokeHelp( "the-anti-virus-wizard", "kmail" );
00541 }
00542 
00543 
00544 void AntiSpamWizard::slotBuildSummary()
00545 {
00546   QString text;
00547   QString newFilters;
00548   QString replaceFilters;
00549 
00550   if ( mMode == AntiVirus ) {
00551     text = ""; // TODO add summary for the virus part
00552   }
00553   else { // AntiSpam mode
00554     if ( mSpamRulesPage->markAsReadSelected() )
00555       text = i18n( "<p>Messages classified as spam are marked as read." );
00556     else
00557       text = i18n( "<p>Messages classified as spam are not marked as read." );
00558 
00559     if ( mSpamRulesPage->moveSpamSelected() )
00560       text += i18n( "<br>Spam messages are moved into the folder named <i>" )
00561             + mSpamRulesPage->selectedSpamFolderName() + "</i>.</p>";
00562     else
00563       text += i18n( "<br>Spam messages are not moved into a certain folder.</p>" );
00564 
00565     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00566           it != mToolList.end(); ++it ) {
00567       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
00568          (*it).isSpamTool() && !(*it).isDetectionOnly() ) {
00569         sortFilterOnExistance( (*it).getFilterName(), newFilters, replaceFilters );
00570       }
00571     }
00572     sortFilterOnExistance( i18n( "Spam handling" ), newFilters, replaceFilters );
00573 
00574     // The need for a andling of status "probably spam" depends on the tools chosen
00575     if ( mSpamRulesPage->moveUnsureSelected() ) {
00576       bool atLeastOneUnsurePattern = false;
00577       for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00578             it != mToolList.end(); ++it ) {
00579         if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) ) {
00580             if ( (*it).isSpamTool() && (*it).hasTristateDetection())
00581               atLeastOneUnsurePattern = true;
00582         }
00583       }
00584       if ( atLeastOneUnsurePattern ) {
00585         sortFilterOnExistance( i18n( "Semi spam (unsure) handling" ),
00586                                newFilters, replaceFilters );
00587         text += i18n( "<p>The folder for messages classified as unsure (probably spam) is <i>" )
00588               + mSpamRulesPage->selectedUnsureFolderName() + "</i>.</p>";
00589       }
00590     }
00591 
00592     // Manual classification via toolbar icon / manually applied filter action
00593     sortFilterOnExistance( i18n( "Classify as spam" ),
00594                             newFilters, replaceFilters );
00595     sortFilterOnExistance( i18n( "Classify as NOT spam" ),
00596                             newFilters, replaceFilters );
00597 
00598     // Show the filters in the summary
00599     if ( !newFilters.isEmpty() )
00600       text += i18n( "<p>The wizard will create the following filters:<ul>" )
00601             + newFilters + "</ul></p>";
00602     if ( !replaceFilters.isEmpty() )
00603       text += i18n( "<p>The wizard will replace the following filters:<ul>" )
00604             + replaceFilters + "</ul></p>";
00605   }
00606 
00607   mSummaryPage->setSummaryText( text );
00608 }
00609 
00610 
00611 int AntiSpamWizard::checkForProgram( const QString &executable )
00612 {
00613   kdDebug(5006) << "Testing for executable:" << executable << endl;
00614   KProcess process;
00615   process << executable;
00616   process.setUseShell( true );
00617   process.start( KProcess::Block );
00618   return process.exitStatus();
00619 }
00620 
00621 
00622 bool AntiSpamWizard::anyVirusOptionChecked()
00623 {
00624   return ( mVirusRulesPage->moveRulesSelected()
00625            || mVirusRulesPage->pipeRulesSelected() );
00626 }
00627 
00628 
00629 const QString AntiSpamWizard::uniqueNameFor( const QString & name )
00630 {
00631   return KMKernel::self()->filterMgr()->createUniqueName( name );
00632 }
00633 
00634 
00635 void AntiSpamWizard::sortFilterOnExistance(
00636         const QString & intendedFilterName,
00637         QString & newFilters, QString & replaceFilters )
00638 {
00639   if ( uniqueNameFor( intendedFilterName ) == intendedFilterName )
00640     newFilters += "<li>" + intendedFilterName + "</li>";
00641   else
00642     replaceFilters += "<li>" + intendedFilterName + "</li>";
00643 }
00644 
00645 
00646 //---------------------------------------------------------------------------
00647 AntiSpamWizard::SpamToolConfig::SpamToolConfig( QString toolId,
00648       int configVersion, int prio, QString name, QString exec,
00649       QString url, QString filter, QString detection, QString spam, QString ham,
00650       QString header, QString pattern, QString pattern2, QString serverPattern,
00651       bool detectionOnly, bool regExp, bool bayesFilter, bool tristateDetection,
00652       WizardMode type )
00653   : mId( toolId ), mVersion( configVersion ), mPrio( prio ),
00654     mVisibleName( name ), mExecutable( exec ), mWhatsThisText( url ),
00655     mFilterName( filter ), mDetectCmd( detection ), mSpamCmd( spam ),
00656     mHamCmd( ham ), mDetectionHeader( header ), mDetectionPattern( pattern ),
00657     mDetectionPattern2( pattern2 ), mServerPattern( serverPattern ),
00658     mDetectionOnly( detectionOnly ),
00659     mUseRegExp( regExp ), mSupportsBayesFilter( bayesFilter ),
00660     mSupportsUnsure( tristateDetection ), mType( type )
00661 {
00662 }
00663 
00664 
00665 bool AntiSpamWizard::SpamToolConfig::isServerBased() const
00666 {
00667   return !mServerPattern.isEmpty();
00668 }
00669 
00670 
00671 //---------------------------------------------------------------------------
00672 AntiSpamWizard::ConfigReader::ConfigReader( WizardMode mode,
00673                                             QValueList<SpamToolConfig> & configList )
00674   : mToolList( configList ),
00675     mMode( mode )
00676 {
00677   if ( mMode == AntiSpam )
00678     mConfig = new KConfig( "kmail.antispamrc", true );
00679   else
00680     mConfig = new KConfig( "kmail.antivirusrc", true );
00681 }
00682 
00683 AntiSpamWizard::ConfigReader::~ConfigReader( )
00684 {
00685   delete mConfig;
00686 }
00687 
00688 
00689 void AntiSpamWizard::ConfigReader::readAndMergeConfig()
00690 {
00691   QString groupName = ( mMode == AntiSpam )
00692                       ? QString("Spamtool #%1")
00693                       : QString("Virustool #%1");
00694   // read the configuration from the global config file
00695   mConfig->setReadDefaults( true );
00696   KConfigGroup general( mConfig, "General" );
00697   int registeredTools = general.readNumEntry( "tools", 0 );
00698   for (int i = 1; i <= registeredTools; i++)
00699   {
00700     KConfigGroup toolConfig( mConfig, groupName.arg( i ) );
00701     if( !toolConfig.readBoolEntry( "HeadersOnly", false ) )
00702       mToolList.append( readToolConfig( toolConfig ) );
00703   }
00704 
00705   // read the configuration from the user config file
00706   // and merge newer config data
00707   mConfig->setReadDefaults( false );
00708   KConfigGroup user_general( mConfig, "General" );
00709   int user_registeredTools = user_general.readNumEntry( "tools", 0 );
00710   for (int i = 1; i <= user_registeredTools; i++)
00711   {
00712     KConfigGroup toolConfig( mConfig, groupName.arg( i ) );
00713     if( !toolConfig.readBoolEntry( "HeadersOnly", false ) )
00714       mergeToolConfig( readToolConfig( toolConfig ) );
00715   }
00716   // Make sure to have add least one tool listed even when the
00717   // config file was not found or whatever went wrong
00718   // Currently only works for spam tools
00719   if ( mMode == AntiSpam ) {
00720     if ( registeredTools < 1 && user_registeredTools < 1 )
00721       mToolList.append( createDummyConfig() );
00722     sortToolList();
00723   }
00724 }
00725 
00726 
00727 AntiSpamWizard::SpamToolConfig
00728     AntiSpamWizard::ConfigReader::readToolConfig( KConfigGroup & configGroup )
00729 {
00730   QString id = configGroup.readEntry( "Ident" );
00731   int version = configGroup.readNumEntry( "Version" );
00732 #ifndef NDEBUG
00733   kdDebug(5006) << "Found predefined tool: " << id << endl;
00734   kdDebug(5006) << "With config version  : " << version << endl;
00735 #endif
00736   int prio = configGroup.readNumEntry( "Priority", 1 );
00737   QString name = configGroup.readEntry( "VisibleName" );
00738   QString executable = configGroup.readEntry( "Executable" );
00739   QString url = configGroup.readEntry( "URL" );
00740   QString filterName = configGroup.readEntry( "PipeFilterName" );
00741   QString detectCmd = configGroup.readEntry( "PipeCmdDetect" );
00742   QString spamCmd = configGroup.readEntry( "ExecCmdSpam" );
00743   QString hamCmd = configGroup.readEntry( "ExecCmdHam" );
00744   QString header = configGroup.readEntry( "DetectionHeader" );
00745   QString pattern = configGroup.readEntry( "DetectionPattern" );
00746   QString pattern2 = configGroup.readEntry( "DetectionPattern2" );
00747   QString serverPattern = configGroup.readEntry( "ServerPattern" );
00748   bool detectionOnly = configGroup.readBoolEntry( "DetectionOnly", false );
00749   bool useRegExp = configGroup.readBoolEntry( "UseRegExp" );
00750   bool supportsBayes = configGroup.readBoolEntry( "SupportsBayes", false );
00751   bool supportsUnsure = configGroup.readBoolEntry( "SupportsUnsure", false );
00752   return SpamToolConfig( id, version, prio, name, executable, url,
00753                          filterName, detectCmd, spamCmd, hamCmd,
00754                          header, pattern, pattern2, serverPattern,
00755                          detectionOnly, useRegExp,
00756                          supportsBayes, supportsUnsure, mMode );
00757 }
00758 
00759 
00760 AntiSpamWizard::SpamToolConfig AntiSpamWizard::ConfigReader::createDummyConfig()
00761 {
00762   return SpamToolConfig( "spamassassin", 0, 1,
00763                         "SpamAssassin", "spamassassin -V",
00764                         "http://spamassassin.org", "SpamAssassin Check",
00765                         "spamassassin -L",
00766                         "sa-learn -L --spam --no-rebuild --single",
00767                         "sa-learn -L --ham --no-rebuild --single",
00768                         "X-Spam-Flag", "yes", "", "",
00769                         false, false, true, false, AntiSpam );
00770 }
00771 
00772 
00773 void AntiSpamWizard::ConfigReader::mergeToolConfig( AntiSpamWizard::SpamToolConfig config )
00774 {
00775   bool found = false;
00776   for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00777         it != mToolList.end(); ++it ) {
00778 #ifndef NDEBUG
00779     kdDebug(5006) << "Check against tool: " << (*it).getId() << endl;
00780     kdDebug(5006) << "Against version   : " << (*it).getVersion() << endl;
00781 #endif
00782     if ( (*it).getId() == config.getId() )
00783     {
00784       found = true;
00785       if ( (*it).getVersion() < config.getVersion() )
00786       {
00787 #ifndef NDEBUG
00788         kdDebug(5006) << "Replacing config ..." << endl;
00789 #endif
00790         mToolList.remove( it );
00791         mToolList.append( config );
00792       }
00793       break;
00794     }
00795   }
00796   if ( !found )
00797     mToolList.append( config );
00798 }
00799 
00800 
00801 void AntiSpamWizard::ConfigReader::sortToolList()
00802 {
00803   QValueList<SpamToolConfig> tmpList;
00804   SpamToolConfig config;
00805 
00806   while ( !mToolList.isEmpty() ) {
00807     QValueListIterator<SpamToolConfig> highest;
00808     int priority = 0; // ascending
00809     for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00810           it != mToolList.end(); ++it ) {
00811       if ( (*it).getPrio() > priority ) {
00812         priority = (*it).getPrio();
00813         highest = it;
00814       }
00815     }
00816     config = (*highest);
00817     tmpList.append( config );
00818     mToolList.remove( highest );
00819   }
00820   for ( QValueListIterator<SpamToolConfig> it = tmpList.begin();
00821         it != tmpList.end(); ++it ) {
00822     mToolList.append( (*it) );
00823   }
00824 }
00825 
00826 
00827 //---------------------------------------------------------------------------
00828 ASWizPage::ASWizPage( QWidget * parent, const char * name,
00829                       const QString *bannerName )
00830   : QWidget( parent, name )
00831 {
00832   QString banner = "kmwizard.png";
00833   if ( bannerName && !bannerName->isEmpty() )
00834     banner = *bannerName;
00835 
00836   mLayout = new QHBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
00837   mPixmap = new QPixmap( UserIcon(banner) );
00838   mBannerLabel = new QLabel( this );
00839   mBannerLabel->setPixmap( *mPixmap );
00840   mBannerLabel->setScaledContents( false );
00841   mBannerLabel->setFrameShape( QFrame::StyledPanel );
00842   mBannerLabel->setFrameShadow( QFrame::Sunken );
00843 
00844   mLayout->addWidget( mBannerLabel );
00845   mLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
00846 }
00847 
00848 
00849 //---------------------------------------------------------------------------
00850 ASWizInfoPage::ASWizInfoPage( AntiSpamWizard::WizardMode mode,
00851                               QWidget * parent, const char * name )
00852   : ASWizPage( parent, name )
00853 {
00854   QBoxLayout * layout = new QVBoxLayout( mLayout );
00855 
00856   mIntroText = new QLabel( this );
00857   mIntroText->setText(
00858     ( mode == AntiSpamWizard::AntiSpam )
00859     ? i18n(
00860       "The wizard will search for any tools to do spam detection\n"
00861       "and setup KMail to work with them."
00862       )
00863     : i18n(
00864       "<p>Here you can get some assistance in setting up KMail's filter "
00865       "rules to use some commonly-known anti-virus tools.</p>"
00866       "<p>The wizard can detect those tools on your computer as "
00867       "well as create filter rules to classify messages using these "
00868       "tools and to separate messages containing viruses. "
00869       "The wizard will not take any existing filter "
00870       "rules into consideration: it will always append the new rules.</p>"
00871       "<p><b>Warning:</b> As KMail appears to be frozen during the scan of the "
00872       "messages for viruses, you may encounter problems with "
00873       "the responsiveness of KMail because anti-virus tool "
00874       "operations are usually time consuming; please consider "
00875       "deleting the filter rules created by the wizard to get "
00876       "back to the former behavior."
00877       ) );
00878   layout->addWidget( mIntroText );
00879 
00880   mScanProgressText = new QLabel( this );
00881   mScanProgressText->setText( "" ) ;
00882   layout->addWidget( mScanProgressText );
00883 
00884   mToolsList = new KListBox( this );
00885   mToolsList->hide();
00886   mToolsList->setSelectionMode( QListBox::Multi );
00887   mToolsList->setRowMode( QListBox::FixedNumber );
00888   mToolsList->setRowMode( 10 );
00889   layout->addWidget( mToolsList );
00890   connect( mToolsList, SIGNAL(selectionChanged()),
00891            this, SLOT(processSelectionChange(void)) );
00892 
00893   mSelectionHint = new QLabel( this );
00894   mSelectionHint->setText( "" );
00895   layout->addWidget( mSelectionHint );
00896 
00897   layout->addStretch();
00898 }
00899 
00900 
00901 void ASWizInfoPage::setScanProgressText( const QString &toolName )
00902 {
00903   mScanProgressText->setText( toolName );
00904 }
00905 
00906 
00907 void ASWizInfoPage::addAvailableTool( const QString &visibleName )
00908 {
00909   QString listName = visibleName;
00910   mToolsList->insertItem( listName );
00911   if ( !mToolsList->isVisible() )
00912   {
00913     mToolsList->show();
00914     mToolsList->setSelected( 0, true );
00915     mSelectionHint->setText( i18n("<p>Please select the tools to be used "
00916                                   "for the detection and go "
00917                                   "to the next page.</p>") );
00918   }
00919 }
00920 
00921 bool ASWizInfoPage::isProgramSelected( const QString &visibleName )
00922 {
00923   QString listName = visibleName;
00924   return mToolsList->isSelected( mToolsList->findItem( listName ) );
00925 }
00926 
00927 
00928 void ASWizInfoPage::processSelectionChange()
00929 {
00930   emit selectionChanged();
00931 }
00932 
00933 
00934 //---------------------------------------------------------------------------
00935 ASWizSpamRulesPage::ASWizSpamRulesPage( QWidget * parent, const char * name,
00936                                         KMFolderTree * mainFolderTree )
00937   : ASWizPage( parent, name )
00938 {
00939   QVBoxLayout *layout = new QVBoxLayout( mLayout );
00940 
00941   mMarkRules = new QCheckBox( i18n("&Mark detected spam messages as read"), this );
00942   QWhatsThis::add( mMarkRules,
00943       i18n( "Mark messages which have been classified as spam as read.") );
00944   layout->addWidget( mMarkRules);
00945 
00946   mMoveSpamRules = new QCheckBox( i18n("Move &known spam to:"), this );
00947   QWhatsThis::add( mMoveSpamRules,
00948       i18n( "The default folder for spam messages is the trash folder, "
00949             "but you may change that in the folder view below.") );
00950   layout->addWidget( mMoveSpamRules );
00951 
00952   mFolderReqForSpamFolder = new FolderRequester( this, mainFolderTree );
00953   mFolderReqForSpamFolder->setFolder( "trash" );
00954   mFolderReqForSpamFolder->setMustBeReadWrite( true );
00955   mFolderReqForSpamFolder->setShowOutbox( false );
00956   mFolderReqForSpamFolder->setShowImapFolders( false );
00957 
00958   QHBoxLayout *hLayout1 = new QHBoxLayout( layout );
00959   hLayout1->addSpacing( KDialog::spacingHint() * 3 );
00960   hLayout1->addWidget( mFolderReqForSpamFolder );
00961 
00962   mMoveUnsureRules = new QCheckBox( i18n("Move &probable spam to:"), this );
00963   QWhatsThis::add( mMoveUnsureRules,
00964       i18n( "The default folder is the inbox folder, but you may change that "
00965             "in the folder view below.<p>"
00966             "Not all tools support a classification as unsure. If you haven't "
00967             "selected a capable tool, you can't select a folder as well.") );
00968   layout->addWidget( mMoveUnsureRules );
00969 
00970   mFolderReqForUnsureFolder = new FolderRequester( this, mainFolderTree );
00971   mFolderReqForUnsureFolder->setFolder( "inbox" );
00972   mFolderReqForUnsureFolder->setMustBeReadWrite( true );
00973   mFolderReqForUnsureFolder->setShowOutbox( false );
00974   mFolderReqForUnsureFolder->setShowImapFolders( false );
00975 
00976   QHBoxLayout *hLayout2 = new QHBoxLayout( layout );
00977   hLayout2->addSpacing( KDialog::spacingHint() * 3 );
00978   hLayout2->addWidget( mFolderReqForUnsureFolder );
00979 
00980   layout->addStretch();
00981 
00982   connect( mMarkRules, SIGNAL(clicked()),
00983             this, SLOT(processSelectionChange(void)) );
00984   connect( mMoveSpamRules, SIGNAL(clicked()),
00985             this, SLOT(processSelectionChange(void)) );
00986   connect( mMoveUnsureRules, SIGNAL(clicked()),
00987             this, SLOT(processSelectionChange(void)) );
00988   connect( mFolderReqForSpamFolder, SIGNAL(folderChanged(KMFolder*)),
00989             this, SLOT(processSelectionChange(KMFolder*)) );
00990   connect( mFolderReqForUnsureFolder, SIGNAL(folderChanged(KMFolder*)),
00991             this, SLOT(processSelectionChange(KMFolder*)) );
00992 
00993   mMarkRules->setChecked( true );
00994   mMoveSpamRules->setChecked( true );
00995 }
00996 
00997 
00998 bool ASWizSpamRulesPage::markAsReadSelected() const
00999 {
01000   return mMarkRules->isChecked();
01001 }
01002 
01003 
01004 bool ASWizSpamRulesPage::moveSpamSelected() const
01005 {
01006   return mMoveSpamRules->isChecked();
01007 }
01008 
01009 
01010 bool ASWizSpamRulesPage::moveUnsureSelected() const
01011 {
01012   return mMoveUnsureRules->isChecked();
01013 }
01014 
01015 
01016 QString ASWizSpamRulesPage::selectedSpamFolderName() const
01017 {
01018   QString name = "trash";
01019   if ( mFolderReqForSpamFolder->folder() )
01020     name = mFolderReqForSpamFolder->folder()->idString();
01021   return name;
01022 }
01023 
01024 
01025 QString ASWizSpamRulesPage::selectedUnsureFolderName() const
01026 {
01027   QString name = "inbox";
01028   if ( mFolderReqForUnsureFolder->folder() )
01029     name = mFolderReqForUnsureFolder->folder()->idString();
01030   return name;
01031 }
01032 
01033 
01034 void ASWizSpamRulesPage::processSelectionChange()
01035 {
01036   mFolderReqForSpamFolder->setEnabled( mMoveSpamRules->isChecked() );
01037   mFolderReqForUnsureFolder->setEnabled( mMoveUnsureRules->isChecked() );
01038   emit selectionChanged();
01039 }
01040 
01041 
01042 void ASWizSpamRulesPage::processSelectionChange( KMFolder* )
01043 {
01044   processSelectionChange();
01045 }
01046 
01047 
01048 void ASWizSpamRulesPage::allowUnsureFolderSelection( bool enabled )
01049 {
01050   mMoveUnsureRules->setEnabled( enabled );
01051   mMoveUnsureRules->setShown( enabled );
01052   mFolderReqForUnsureFolder->setEnabled( enabled );
01053   mFolderReqForUnsureFolder->setShown( enabled );
01054 }
01055 
01056 
01057 //---------------------------------------------------------------------------
01058 ASWizVirusRulesPage::ASWizVirusRulesPage( QWidget * parent, const char * name,
01059                                   KMFolderTree * mainFolderTree )
01060   : ASWizPage( parent, name )
01061 {
01062   QGridLayout *grid = new QGridLayout( mLayout, 5, 1, KDialog::spacingHint() );
01063 
01064   mPipeRules = new QCheckBox( i18n("Check messages using the anti-virus tools"), this );
01065   QWhatsThis::add( mPipeRules,
01066       i18n( "Let the anti-virus tools check your messages. The wizard "
01067             "will create appropriate filters. The messages are usually "
01068             "marked by the tools so that following filters can react "
01069             "on this and, for example, move virus messages to a special folder.") );
01070   grid->addWidget( mPipeRules, 0, 0 );
01071 
01072   mMoveRules = new QCheckBox( i18n("Move detected viral messages to the selected folder"), this );
01073   QWhatsThis::add( mMoveRules,
01074       i18n( "A filter to detect messages classified as virus-infected and to move "
01075             "those messages into a predefined folder is created. The "
01076             "default folder is the trash folder, but you may change that "
01077             "in the folder view.") );
01078   grid->addWidget( mMoveRules, 1, 0 );
01079 
01080   mMarkRules = new QCheckBox( i18n("Additionally, mark detected viral messages as read"), this );
01081   mMarkRules->setEnabled( false );
01082   QWhatsThis::add( mMarkRules,
01083       i18n( "Mark messages which have been classified as "
01084             "virus-infected as read, as well as moving them "
01085             "to the selected folder.") );
01086   grid->addWidget( mMarkRules, 2, 0 );
01087 
01088   QString s = "trash";
01089   mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true );
01090   grid->addWidget( mFolderTree, 3, 0 );
01091 
01092   connect( mPipeRules, SIGNAL(clicked()),
01093             this, SLOT(processSelectionChange(void)) );
01094   connect( mMoveRules, SIGNAL(clicked()),
01095             this, SLOT(processSelectionChange(void)) );
01096   connect( mMarkRules, SIGNAL(clicked()),
01097             this, SLOT(processSelectionChange(void)) );
01098   connect( mMoveRules, SIGNAL( toggled( bool ) ),
01099            mMarkRules, SLOT( setEnabled( bool ) ) );
01100 }
01101 
01102 bool ASWizVirusRulesPage::pipeRulesSelected() const
01103 {
01104   return mPipeRules->isChecked();
01105 }
01106 
01107 
01108 bool ASWizVirusRulesPage::moveRulesSelected() const
01109 {
01110   return mMoveRules->isChecked();
01111 }
01112 
01113 bool ASWizVirusRulesPage::markReadRulesSelected() const
01114 {
01115   return mMarkRules->isChecked();
01116 }
01117 
01118 
01119 QString ASWizVirusRulesPage::selectedFolderName() const
01120 {
01121   QString name = "trash";
01122   if ( mFolderTree->folder() )
01123     name = mFolderTree->folder()->idString();
01124   return name;
01125 }
01126 
01127 void ASWizVirusRulesPage::processSelectionChange()
01128 {
01129   emit selectionChanged();
01130 }
01131 
01132 
01133 //---------------------------------------------------------------------------
01134 ASWizSummaryPage::ASWizSummaryPage( QWidget * parent, const char * name )
01135   : ASWizPage( parent, name )
01136 {
01137   QBoxLayout * layout = new QVBoxLayout( mLayout );
01138 
01139   mSummaryText = new QLabel( this );
01140   layout->addWidget( mSummaryText );
01141   layout->addStretch();
01142 }
01143 
01144 
01145 void ASWizSummaryPage::setSummaryText( const QString & text )
01146 {
01147   mSummaryText->setText( text );
01148 }
01149 
01150 
01151 #include "antispamwizard.moc"