kmail

antispamwizard.cpp

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