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 <tqdom.h>
00052 #include <tqlabel.h>
00053 #include <tqlayout.h>
00054 #include <tqtooltip.h>
00055 #include <tqwhatsthis.h>
00056 
00057 using namespace KMail;
00058 
00059 AntiSpamWizard::AntiSpamWizard( WizardMode mode,
00060                                 TQWidget* 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 ( TQValueListIterator<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, TQT_SIGNAL( selectionChanged( void ) ),
00108             this, TQT_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, TQT_SIGNAL( selectionChanged( void ) ),
00114              this, TQT_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, TQT_SIGNAL( selectionChanged( void ) ),
00120              this, TQT_SLOT( checkVirusRulesSelections( void ) ) );
00121   }
00122 
00123   connect( this, TQT_SIGNAL( helpClicked( void) ),
00124             this, TQT_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   TQTimer::singleShot( 0, this, TQT_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   TQValueList<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 ( TQValueListIterator<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         TQPtrList<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       TQPtrList<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 ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
00202             it != mToolList.end(); ++it ) {
00203         if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ))
00204         {
00205           if ( (*it).isVirusTool() )
00206           {
00207               const TQCString header = (*it).getDetectionHeader().ascii();
00208               const TQString & 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 ( TQValueListIterator<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         TQPtrList<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     TQPtrList<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 ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
00288           it != mToolList.end(); ++it ) {
00289       if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
00290       {
00291           if ( (*it).isSpamTool() )
00292           {
00293             const TQCString header = (*it).getDetectionHeader().ascii();
00294             const TQString & 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       TQPtrList<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 ( TQValueListIterator<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 TQCString header = (*it).getDetectionHeader().ascii();
00336               const TQString & 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     TQPtrList<KMFilterAction>* classSpamFilterActions = classSpamFilter->actions();
00364     KMFilterAction* classSpamFilterActionFirst = dict["set status"]->create();
00365     classSpamFilterActionFirst->argsFromString( "P" );
00366     classSpamFilterActions->append( classSpamFilterActionFirst );
00367     for ( TQValueListIterator<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     TQPtrList<KMFilterAction>* classHamFilterActions = classHamFilter->actions();
00403     KMFilterAction* classHamFilterActionFirst = dict["set status"]->create();
00404     classHamFilterActionFirst->argsFromString( "H" );
00405     classHamFilterActions->append( classHamFilterActionFirst );
00406     for ( TQValueListIterator<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   TQDialog::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 ( TQValueListIterator<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 ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
00497         it != mToolList.end(); ++it ) {
00498     TQString 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       TQString 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   TQString text;
00552   TQString newFilters;
00553   TQString 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 ( TQValueListIterator<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 ( TQValueListIterator<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 TQString &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 TQString AntiSpamWizard::uniqueNameFor( const TQString & name )
00635 {
00636   return KMKernel::self()->filterMgr()->createUniqueName( name );
00637 }
00638 
00639 
00640 void AntiSpamWizard::sortFilterOnExistance(
00641         const TQString & intendedFilterName,
00642         TQString & newFilters, TQString & 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( TQString toolId,
00653       int configVersion, int prio, TQString name, TQString exec,
00654       TQString url, TQString filter, TQString detection, TQString spam, TQString ham,
00655       TQString header, TQString pattern, TQString pattern2, TQString 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                                             TQValueList<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   TQString groupName = ( mMode == AntiSpam )
00697                       ? TQString("Spamtool #%1")
00698                       : TQString("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   TQString 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   TQString name = configGroup.readEntry( "VisibleName" );
00743   TQString executable = configGroup.readEntry( "Executable" );
00744   TQString url = configGroup.readEntry( "URL" );
00745   TQString filterName = configGroup.readEntry( "PipeFilterName" );
00746   TQString detectCmd = configGroup.readEntry( "PipeCmdDetect" );
00747   TQString spamCmd = configGroup.readEntry( "ExecCmdSpam" );
00748   TQString hamCmd = configGroup.readEntry( "ExecCmdHam" );
00749   TQString header = configGroup.readEntry( "DetectionHeader" );
00750   TQString pattern = configGroup.readEntry( "DetectionPattern" );
00751   TQString pattern2 = configGroup.readEntry( "DetectionPattern2" );
00752   TQString 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 ( TQValueListIterator<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   TQValueList<SpamToolConfig> tmpList;
00809   SpamToolConfig config;
00810 
00811   while ( !mToolList.isEmpty() ) {
00812     TQValueListIterator<SpamToolConfig> highest;
00813     int priority = 0; // ascending
00814     for ( TQValueListIterator<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 ( TQValueListIterator<SpamToolConfig> it = tmpList.begin();
00826         it != tmpList.end(); ++it ) {
00827     mToolList.append( (*it) );
00828   }
00829 }
00830 
00831 
00832 //---------------------------------------------------------------------------
00833 ASWizPage::ASWizPage( TQWidget * parent, const char * name,
00834                       const TQString *bannerName )
00835   : TQWidget( parent, name )
00836 {
00837   TQString banner = "kmwizard.png";
00838   if ( bannerName && !bannerName->isEmpty() )
00839     banner = *bannerName;
00840 
00841   mLayout = new TQHBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
00842   mBannerLabel = new TQLabel( this );
00843   mBannerLabel->setPixmap( UserIcon(banner) );
00844   mBannerLabel->setScaledContents( false );
00845   mBannerLabel->setFrameShape( TQFrame::StyledPanel );
00846   mBannerLabel->setFrameShadow( TQFrame::Sunken );
00847 
00848   mLayout->addWidget( mBannerLabel );
00849   mLayout->addItem( new TQSpacerItem( 5, 5, TQSizePolicy::Minimum, TQSizePolicy::Expanding ) );
00850 }
00851 
00852 
00853 //---------------------------------------------------------------------------
00854 ASWizInfoPage::ASWizInfoPage( AntiSpamWizard::WizardMode mode,
00855                               TQWidget * parent, const char * name )
00856   : ASWizPage( parent, name )
00857 {
00858   TQBoxLayout * layout = new TQVBoxLayout( mLayout );
00859 
00860   mIntroText = new TQLabel( this );
00861   mIntroText->setText(
00862     ( mode == AntiSpamWizard::AntiSpam )
00863     ? i18n(
00864       "The wizard will search for any tools to do spam detection\n"
00865       "and setup KMail to work with them."
00866       )
00867     : i18n(
00868       "<p>Here you can get some assistance in setting up KMail's filter "
00869       "rules to use some commonly-known anti-virus tools.</p>"
00870       "<p>The wizard can detect those tools on your computer as "
00871       "well as create filter rules to classify messages using these "
00872       "tools and to separate messages containing viruses. "
00873       "The wizard will not take any existing filter "
00874       "rules into consideration: it will always append the new rules.</p>"
00875       "<p><b>Warning:</b> As KMail appears to be frozen during the scan of the "
00876       "messages for viruses, you may encounter problems with "
00877       "the responsiveness of KMail because anti-virus tool "
00878       "operations are usually time consuming; please consider "
00879       "deleting the filter rules created by the wizard to get "
00880       "back to the former behavior."
00881       ) );
00882   layout->addWidget( mIntroText );
00883 
00884   mScanProgressText = new TQLabel( this );
00885   mScanProgressText->setText( "" ) ;
00886   layout->addWidget( mScanProgressText );
00887 
00888   mToolsList = new KListBox( this );
00889   mToolsList->hide();
00890   mToolsList->setSelectionMode( TQListBox::Multi );
00891   mToolsList->setRowMode( TQListBox::FixedNumber );
00892   mToolsList->setRowMode( 10 );
00893   layout->addWidget( mToolsList );
00894   connect( mToolsList, TQT_SIGNAL(selectionChanged()),
00895            this, TQT_SLOT(processSelectionChange(void)) );
00896 
00897   mSelectionHint = new TQLabel( this );
00898   mSelectionHint->setText( "" );
00899   layout->addWidget( mSelectionHint );
00900 
00901   layout->addStretch();
00902 }
00903 
00904 
00905 void ASWizInfoPage::setScanProgressText( const TQString &toolName )
00906 {
00907   mScanProgressText->setText( toolName );
00908 }
00909 
00910 
00911 void ASWizInfoPage::addAvailableTool( const TQString &visibleName )
00912 {
00913   TQString listName = visibleName;
00914   mToolsList->insertItem( listName );
00915   if ( !mToolsList->isVisible() )
00916   {
00917     mToolsList->show();
00918     mToolsList->setSelected( 0, true );
00919     mSelectionHint->setText( i18n("<p>Please select the tools to be used "
00920                                   "for the detection and go "
00921                                   "to the next page.</p>") );
00922   }
00923 }
00924 
00925 bool ASWizInfoPage::isProgramSelected( const TQString &visibleName )
00926 {
00927   TQString listName = visibleName;
00928   return mToolsList->isSelected( mToolsList->findItem( listName ) );
00929 }
00930 
00931 
00932 void ASWizInfoPage::processSelectionChange()
00933 {
00934   emit selectionChanged();
00935 }
00936 
00937 
00938 //---------------------------------------------------------------------------
00939 ASWizSpamRulesPage::ASWizSpamRulesPage( TQWidget * parent, const char * name,
00940                                         KMFolderTree * mainFolderTree )
00941   : ASWizPage( parent, name )
00942 {
00943   TQVBoxLayout *layout = new TQVBoxLayout( mLayout );
00944 
00945   mMarkRules = new TQCheckBox( i18n("&Mark detected spam messages as read"), this );
00946   TQWhatsThis::add( mMarkRules,
00947       i18n( "Mark messages which have been classified as spam as read.") );
00948   layout->addWidget( mMarkRules);
00949 
00950   mMoveSpamRules = new TQCheckBox( i18n("Move &known spam to:"), this );
00951   TQWhatsThis::add( mMoveSpamRules,
00952       i18n( "The default folder for spam messages is the trash folder, "
00953             "but you may change that in the folder view below.") );
00954   layout->addWidget( mMoveSpamRules );
00955 
00956   mFolderReqForSpamFolder = new FolderRequester( this, mainFolderTree );
00957   mFolderReqForSpamFolder->setFolder( "trash" );
00958   mFolderReqForSpamFolder->setMustBeReadWrite( true );
00959   mFolderReqForSpamFolder->setShowOutbox( false );
00960   mFolderReqForSpamFolder->setShowImapFolders( false );
00961 
00962   TQHBoxLayout *hLayout1 = new TQHBoxLayout( layout );
00963   hLayout1->addSpacing( KDialog::spacingHint() * 3 );
00964   hLayout1->addWidget( mFolderReqForSpamFolder );
00965 
00966   mMoveUnsureRules = new TQCheckBox( i18n("Move &probable spam to:"), this );
00967   TQWhatsThis::add( mMoveUnsureRules,
00968       i18n( "The default folder is the inbox folder, but you may change that "
00969             "in the folder view below.<p>"
00970             "Not all tools support a classification as unsure. If you haven't "
00971             "selected a capable tool, you can't select a folder as well.") );
00972   layout->addWidget( mMoveUnsureRules );
00973 
00974   mFolderReqForUnsureFolder = new FolderRequester( this, mainFolderTree );
00975   mFolderReqForUnsureFolder->setFolder( "inbox" );
00976   mFolderReqForUnsureFolder->setMustBeReadWrite( true );
00977   mFolderReqForUnsureFolder->setShowOutbox( false );
00978   mFolderReqForUnsureFolder->setShowImapFolders( false );
00979 
00980   TQHBoxLayout *hLayout2 = new TQHBoxLayout( layout );
00981   hLayout2->addSpacing( KDialog::spacingHint() * 3 );
00982   hLayout2->addWidget( mFolderReqForUnsureFolder );
00983 
00984   layout->addStretch();
00985 
00986   connect( mMarkRules, TQT_SIGNAL(clicked()),
00987             this, TQT_SLOT(processSelectionChange(void)) );
00988   connect( mMoveSpamRules, TQT_SIGNAL(clicked()),
00989             this, TQT_SLOT(processSelectionChange(void)) );
00990   connect( mMoveUnsureRules, TQT_SIGNAL(clicked()),
00991             this, TQT_SLOT(processSelectionChange(void)) );
00992   connect( mFolderReqForSpamFolder, TQT_SIGNAL(folderChanged(KMFolder*)),
00993             this, TQT_SLOT(processSelectionChange(KMFolder*)) );
00994   connect( mFolderReqForUnsureFolder, TQT_SIGNAL(folderChanged(KMFolder*)),
00995             this, TQT_SLOT(processSelectionChange(KMFolder*)) );
00996 
00997   mMarkRules->setChecked( true );
00998   mMoveSpamRules->setChecked( true );
00999 }
01000 
01001 
01002 bool ASWizSpamRulesPage::markAsReadSelected() const
01003 {
01004   return mMarkRules->isChecked();
01005 }
01006 
01007 
01008 bool ASWizSpamRulesPage::moveSpamSelected() const
01009 {
01010   return mMoveSpamRules->isChecked();
01011 }
01012 
01013 
01014 bool ASWizSpamRulesPage::moveUnsureSelected() const
01015 {
01016   return mMoveUnsureRules->isChecked();
01017 }
01018 
01019 
01020 TQString ASWizSpamRulesPage::selectedSpamFolderName() const
01021 {
01022   TQString name = "trash";
01023   if ( mFolderReqForSpamFolder->folder() )
01024     name = mFolderReqForSpamFolder->folder()->idString();
01025   return name;
01026 }
01027 
01028 
01029 TQString ASWizSpamRulesPage::selectedUnsureFolderName() const
01030 {
01031   TQString name = "inbox";
01032   if ( mFolderReqForUnsureFolder->folder() )
01033     name = mFolderReqForUnsureFolder->folder()->idString();
01034   return name;
01035 }
01036 
01037 
01038 void ASWizSpamRulesPage::processSelectionChange()
01039 {
01040   mFolderReqForSpamFolder->setEnabled( mMoveSpamRules->isChecked() );
01041   mFolderReqForUnsureFolder->setEnabled( mMoveUnsureRules->isChecked() );
01042   emit selectionChanged();
01043 }
01044 
01045 
01046 void ASWizSpamRulesPage::processSelectionChange( KMFolder* )
01047 {
01048   processSelectionChange();
01049 }
01050 
01051 
01052 void ASWizSpamRulesPage::allowUnsureFolderSelection( bool enabled )
01053 {
01054   mMoveUnsureRules->setEnabled( enabled );
01055   mMoveUnsureRules->setShown( enabled );
01056   mFolderReqForUnsureFolder->setEnabled( enabled );
01057   mFolderReqForUnsureFolder->setShown( enabled );
01058 }
01059 
01060 
01061 //---------------------------------------------------------------------------
01062 ASWizVirusRulesPage::ASWizVirusRulesPage( TQWidget * parent, const char * name,
01063                                   KMFolderTree * mainFolderTree )
01064   : ASWizPage( parent, name )
01065 {
01066   TQGridLayout *grid = new TQGridLayout( mLayout, 5, 1, KDialog::spacingHint() );
01067 
01068   mPipeRules = new TQCheckBox( i18n("Check messages using the anti-virus tools"), this );
01069   TQWhatsThis::add( mPipeRules,
01070       i18n( "Let the anti-virus tools check your messages. The wizard "
01071             "will create appropriate filters. The messages are usually "
01072             "marked by the tools so that following filters can react "
01073             "on this and, for example, move virus messages to a special folder.") );
01074   grid->addWidget( mPipeRules, 0, 0 );
01075 
01076   mMoveRules = new TQCheckBox( i18n("Move detected viral messages to the selected folder"), this );
01077   TQWhatsThis::add( mMoveRules,
01078       i18n( "A filter to detect messages classified as virus-infected and to move "
01079             "those messages into a predefined folder is created. The "
01080             "default folder is the trash folder, but you may change that "
01081             "in the folder view.") );
01082   grid->addWidget( mMoveRules, 1, 0 );
01083 
01084   mMarkRules = new TQCheckBox( i18n("Additionally, mark detected viral messages as read"), this );
01085   mMarkRules->setEnabled( false );
01086   TQWhatsThis::add( mMarkRules,
01087       i18n( "Mark messages which have been classified as "
01088             "virus-infected as read, as well as moving them "
01089             "to the selected folder.") );
01090   grid->addWidget( mMarkRules, 2, 0 );
01091 
01092   TQString s = "trash";
01093   mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true );
01094   grid->addWidget( mFolderTree, 3, 0 );
01095 
01096   connect( mPipeRules, TQT_SIGNAL(clicked()),
01097             this, TQT_SLOT(processSelectionChange(void)) );
01098   connect( mMoveRules, TQT_SIGNAL(clicked()),
01099             this, TQT_SLOT(processSelectionChange(void)) );
01100   connect( mMarkRules, TQT_SIGNAL(clicked()),
01101             this, TQT_SLOT(processSelectionChange(void)) );
01102   connect( mMoveRules, TQT_SIGNAL( toggled( bool ) ),
01103            mMarkRules, TQT_SLOT( setEnabled( bool ) ) );
01104 }
01105 
01106 bool ASWizVirusRulesPage::pipeRulesSelected() const
01107 {
01108   return mPipeRules->isChecked();
01109 }
01110 
01111 
01112 bool ASWizVirusRulesPage::moveRulesSelected() const
01113 {
01114   return mMoveRules->isChecked();
01115 }
01116 
01117 bool ASWizVirusRulesPage::markReadRulesSelected() const
01118 {
01119   return mMarkRules->isChecked();
01120 }
01121 
01122 
01123 TQString ASWizVirusRulesPage::selectedFolderName() const
01124 {
01125   TQString name = "trash";
01126   if ( mFolderTree->folder() )
01127     name = mFolderTree->folder()->idString();
01128   return name;
01129 }
01130 
01131 void ASWizVirusRulesPage::processSelectionChange()
01132 {
01133   emit selectionChanged();
01134 }
01135 
01136 
01137 //---------------------------------------------------------------------------
01138 ASWizSummaryPage::ASWizSummaryPage( TQWidget * parent, const char * name )
01139   : ASWizPage( parent, name )
01140 {
01141   TQBoxLayout * layout = new TQVBoxLayout( mLayout );
01142 
01143   mSummaryText = new TQLabel( this );
01144   layout->addWidget( mSummaryText );
01145   layout->addStretch();
01146 }
01147 
01148 
01149 void ASWizSummaryPage::setSummaryText( const TQString & text )
01150 {
01151   mSummaryText->setText( text );
01152 }
01153 
01154 
01155 #include "antispamwizard.moc"