00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "antispamwizard.h"
00031 #include "kcursorsaver.h"
00032 #include "kmfilter.h"
00033 #include "kmfilteraction.h"
00034 #include "kmfiltermgr.h"
00035 #include "kmkernel.h"
00036 #include "kmfoldertree.h"
00037 #include "kmmainwin.h"
00038
00039 #include <kaction.h>
00040 #include <kapplication.h>
00041 #include <kdebug.h>
00042 #include <kdialog.h>
00043 #include <klocale.h>
00044 #include <kmessagebox.h>
00045 #include <kprocess.h>
00046
00047 #include <qdom.h>
00048 #include <qlabel.h>
00049 #include <qlayout.h>
00050 #include <qtooltip.h>
00051 #include <qwhatsthis.h>
00052
00053 using namespace KMail;
00054
00055 AntiSpamWizard::AntiSpamWizard( WizardMode mode,
00056 QWidget* parent, KMFolderTree * mainFolderTree,
00057 KActionCollection * collection )
00058 : KWizard( parent ),
00059 mSpamRulesPage( 0 ),
00060 mVirusRulesPage( 0 ),
00061 mMode( mode )
00062 {
00063
00064 ConfigReader reader( mMode, mToolList );
00065 reader.readAndMergeConfig();
00066 mToolList = reader.getToolList();
00067
00068 #ifndef NDEBUG
00069 if ( mMode == AntiSpam )
00070 kdDebug(5006) << endl << "Considered anti-spam tools: " << endl;
00071 else
00072 kdDebug(5006) << endl << "Considered anti-virus tools: " << endl;
00073 #endif
00074 QStringList descriptionList;
00075 QStringList whatsThisList;
00076 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00077 it != mToolList.end(); ++it ) {
00078 descriptionList.append( (*it).getVisibleName() );
00079 whatsThisList.append( (*it).getWhatsThisText() );
00080 #ifndef NDEBUG
00081 kdDebug(5006) << "Predefined tool: " << (*it).getId() << endl;
00082 kdDebug(5006) << "Config version: " << (*it).getVersion() << endl;
00083 kdDebug(5006) << "Displayed name: " << (*it).getVisibleName() << endl;
00084 kdDebug(5006) << "Executable: " << (*it).getExecutable() << endl;
00085 kdDebug(5006) << "WhatsThis URL: " << (*it).getWhatsThisText() << endl;
00086 kdDebug(5006) << "Filter name: " << (*it).getFilterName() << endl;
00087 kdDebug(5006) << "Detection command: " << (*it).getDetectCmd() << endl;
00088 kdDebug(5006) << "Learn spam command: " << (*it).getSpamCmd() << endl;
00089 kdDebug(5006) << "Learn ham command: " << (*it).getHamCmd() << endl;
00090 kdDebug(5006) << "Detection header: " << (*it).getDetectionHeader() << endl;
00091 kdDebug(5006) << "Detection pattern: " << (*it).getDetectionPattern() << endl;
00092 kdDebug(5006) << "Use as RegExp: " << (*it).isUseRegExp() << endl;
00093 kdDebug(5006) << "Supports Bayes Filter: " << (*it).useBayesFilter() << endl;
00094 kdDebug(5006) << "Type: " << (*it).getType() << endl << endl;
00095 #endif
00096 }
00097
00098 mActionCollection = collection;
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 mProgramsPage = new ASWizProgramsPage( 0, "", descriptionList, whatsThisList );
00108 addPage( mProgramsPage, i18n( "Please select the tools to be used by KMail" ));
00109 connect( mProgramsPage, SIGNAL( selectionChanged( void ) ),
00110 this, SLOT( checkProgramsSelections( void ) ) );
00111
00112 if ( mMode == AntiSpam ) {
00113 mSpamRulesPage = new ASWizSpamRulesPage( 0, "", mainFolderTree );
00114 connect( mSpamRulesPage, SIGNAL( selectionChanged( void ) ),
00115 this, SLOT( checkSpamRulesSelections( void ) ) );
00116 }
00117 else {
00118 mVirusRulesPage = new ASWizVirusRulesPage( 0, "", mainFolderTree );
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 setNextEnabled( mProgramsPage, false );
00128
00129 QTimer::singleShot( 0, this, SLOT( checkToolAvailability( void ) ) );
00130 }
00131
00132
00133 void AntiSpamWizard::accept()
00134 {
00135 if ( mSpamRulesPage )
00136 kdDebug( 5006 ) << "Folder name for spam is "
00137 << mSpamRulesPage->selectedFolderName() << endl;
00138 if ( mVirusRulesPage )
00139 kdDebug( 5006 ) << "Folder name for viruses is "
00140 << mVirusRulesPage->selectedFolderName() << endl;
00141
00142 KMFilterActionDict dict;
00143 QPtrList<KMFilter> filterList;
00144
00145
00146
00147 if ( mMode == AntiVirus ) {
00148 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00149 it != mToolList.end(); ++it ) {
00150 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() ) &&
00151 ( mVirusRulesPage->pipeRulesSelected() && (*it).isVirusTool() ) )
00152 {
00153
00154
00155
00156 KMFilter* pipeFilter = new KMFilter();
00157 QPtrList<KMFilterAction>* pipeFilterActions = pipeFilter->actions();
00158 KMFilterAction* pipeFilterAction = dict["filter app"]->create();
00159 pipeFilterAction->argsFromString( (*it).getDetectCmd() );
00160 pipeFilterActions->append( pipeFilterAction );
00161 KMSearchPattern* pipeFilterPattern = pipeFilter->pattern();
00162 pipeFilterPattern->setName( (*it).getFilterName() );
00163 pipeFilterPattern->append( KMSearchRule::createInstance( "<size>",
00164 KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
00165 pipeFilter->setApplyOnOutbound( FALSE);
00166 pipeFilter->setApplyOnInbound();
00167 pipeFilter->setApplyOnExplicit();
00168 pipeFilter->setStopProcessingHere( FALSE );
00169 pipeFilter->setConfigureShortcut( FALSE );
00170
00171 filterList.append( pipeFilter );
00172 }
00173 }
00174
00175 if ( mVirusRulesPage->moveRulesSelected() )
00176 {
00177
00178 KMFilter* virusFilter = new KMFilter();
00179 QPtrList<KMFilterAction>* virusFilterActions = virusFilter->actions();
00180 KMFilterAction* virusFilterAction1 = dict["transfer"]->create();
00181 virusFilterAction1->argsFromString( mVirusRulesPage->selectedFolderName() );
00182 virusFilterActions->append( virusFilterAction1 );
00183 if ( mVirusRulesPage->markReadRulesSelected() ) {
00184 KMFilterAction* virusFilterAction2 = dict["set status"]->create();
00185 virusFilterAction2->argsFromString( "R" );
00186 virusFilterActions->append( virusFilterAction2 );
00187 }
00188 KMSearchPattern* virusFilterPattern = virusFilter->pattern();
00189 virusFilterPattern->setName( i18n( "Virus handling" ) );
00190 virusFilterPattern->setOp( KMSearchPattern::OpOr );
00191 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00192 it != mToolList.end(); ++it ) {
00193 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() ))
00194 {
00195 if ( (*it).isVirusTool() )
00196 {
00197 const QCString header = (*it).getDetectionHeader().ascii();
00198 const QString & pattern = (*it).getDetectionPattern();
00199 if ( (*it).isUseRegExp() )
00200 virusFilterPattern->append(
00201 KMSearchRule::createInstance( header,
00202 KMSearchRule::FuncRegExp, pattern ) );
00203 else
00204 virusFilterPattern->append(
00205 KMSearchRule::createInstance( header,
00206 KMSearchRule::FuncContains, pattern ) );
00207 }
00208 }
00209 }
00210 virusFilter->setApplyOnOutbound( FALSE);
00211 virusFilter->setApplyOnInbound();
00212 virusFilter->setApplyOnExplicit();
00213 virusFilter->setStopProcessingHere( TRUE );
00214 virusFilter->setConfigureShortcut( FALSE );
00215
00216 filterList.append( virusFilter );
00217 }
00218 }
00219 else {
00220 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00221 it != mToolList.end(); ++it ) {
00222 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() ) &&
00223 ( mSpamRulesPage->pipeRulesSelected() && (*it).isSpamTool() ) )
00224 {
00225
00226
00227
00228 KMFilter* pipeFilter = new KMFilter();
00229 QPtrList<KMFilterAction>* pipeFilterActions = pipeFilter->actions();
00230 KMFilterAction* pipeFilterAction = dict["filter app"]->create();
00231 pipeFilterAction->argsFromString( (*it).getDetectCmd() );
00232 pipeFilterActions->append( pipeFilterAction );
00233 KMSearchPattern* pipeFilterPattern = pipeFilter->pattern();
00234 pipeFilterPattern->setName( (*it).getFilterName() );
00235 pipeFilterPattern->append( KMSearchRule::createInstance( "<size>",
00236 KMSearchRule::FuncIsLessOrEqual, "256000" ) );
00237 pipeFilter->setApplyOnOutbound( FALSE);
00238 pipeFilter->setApplyOnInbound();
00239 pipeFilter->setApplyOnExplicit();
00240 pipeFilter->setStopProcessingHere( FALSE );
00241 pipeFilter->setConfigureShortcut( FALSE );
00242
00243 filterList.append( pipeFilter );
00244 }
00245 }
00246
00247 if ( mSpamRulesPage->moveRulesSelected() )
00248 {
00249
00250 KMFilter* spamFilter = new KMFilter();
00251 QPtrList<KMFilterAction>* spamFilterActions = spamFilter->actions();
00252 KMFilterAction* spamFilterAction1 = dict["transfer"]->create();
00253 spamFilterAction1->argsFromString( mSpamRulesPage->selectedFolderName() );
00254 spamFilterActions->append( spamFilterAction1 );
00255 KMFilterAction* spamFilterAction2 = dict["set status"]->create();
00256 spamFilterAction2->argsFromString( "P" );
00257 spamFilterActions->append( spamFilterAction2 );
00258 if ( mSpamRulesPage->markReadRulesSelected() ) {
00259 KMFilterAction* spamFilterAction3 = dict["set status"]->create();
00260 spamFilterAction3->argsFromString( "R" );
00261 spamFilterActions->append( spamFilterAction3 );
00262 }
00263 KMSearchPattern* spamFilterPattern = spamFilter->pattern();
00264 spamFilterPattern->setName( i18n( "Spam handling" ) );
00265 spamFilterPattern->setOp( KMSearchPattern::OpOr );
00266 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00267 it != mToolList.end(); ++it ) {
00268 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() ) )
00269 {
00270 if ( (*it).isSpamTool() )
00271 {
00272 const QCString header = (*it).getDetectionHeader().ascii();
00273 const QString & pattern = (*it).getDetectionPattern();
00274 if ( (*it).isUseRegExp() )
00275 spamFilterPattern->append(
00276 KMSearchRule::createInstance( header,
00277 KMSearchRule::FuncRegExp, pattern ) );
00278 else
00279 spamFilterPattern->append(
00280 KMSearchRule::createInstance( header,
00281 KMSearchRule::FuncContains, pattern ) );
00282 }
00283 }
00284 }
00285 spamFilter->setApplyOnOutbound( FALSE);
00286 spamFilter->setApplyOnInbound();
00287 spamFilter->setApplyOnExplicit();
00288 spamFilter->setStopProcessingHere( TRUE );
00289 spamFilter->setConfigureShortcut( FALSE );
00290
00291 filterList.append( spamFilter );
00292 }
00293
00294 if ( mSpamRulesPage->classifyRulesSelected() )
00295 {
00296
00297 KMFilter* classSpamFilter = new KMFilter();
00298 classSpamFilter->setIcon( "mark_as_spam" );
00299 QPtrList<KMFilterAction>* classSpamFilterActions = classSpamFilter->actions();
00300 KMFilterAction* classSpamFilterActionFirst = dict["set status"]->create();
00301 classSpamFilterActionFirst->argsFromString( "P" );
00302 classSpamFilterActions->append( classSpamFilterActionFirst );
00303 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00304 it != mToolList.end(); ++it ) {
00305 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() )
00306 && (*it).useBayesFilter() )
00307 {
00308 KMFilterAction* classSpamFilterAction = dict["execute"]->create();
00309 classSpamFilterAction->argsFromString( (*it).getSpamCmd() );
00310 classSpamFilterActions->append( classSpamFilterAction );
00311 }
00312 }
00313 KMFilterAction* classSpamFilterActionLast = dict["transfer"]->create();
00314 classSpamFilterActionLast->argsFromString( mSpamRulesPage->selectedFolderName() );
00315 classSpamFilterActions->append( classSpamFilterActionLast );
00316
00317 KMSearchPattern* classSpamFilterPattern = classSpamFilter->pattern();
00318 classSpamFilterPattern->setName( i18n( "Classify as spam" ) );
00319 classSpamFilterPattern->append( KMSearchRule::createInstance( "<size>",
00320 KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
00321 classSpamFilter->setApplyOnOutbound( FALSE);
00322 classSpamFilter->setApplyOnInbound( FALSE );
00323 classSpamFilter->setApplyOnExplicit( FALSE );
00324 classSpamFilter->setStopProcessingHere( TRUE );
00325 classSpamFilter->setConfigureShortcut( TRUE );
00326 classSpamFilter->setConfigureToolbar( TRUE );
00327 filterList.append( classSpamFilter );
00328
00329
00330 KMFilter* classHamFilter = new KMFilter();
00331 classHamFilter->setIcon( "mark_as_ham" );
00332 QPtrList<KMFilterAction>* classHamFilterActions = classHamFilter->actions();
00333 KMFilterAction* classHamFilterActionFirst = dict["set status"]->create();
00334 classHamFilterActionFirst->argsFromString( "H" );
00335 classHamFilterActions->append( classHamFilterActionFirst );
00336 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00337 it != mToolList.end(); ++it ) {
00338 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() )
00339 && (*it).useBayesFilter() )
00340 {
00341 KMFilterAction* classHamFilterAction = dict["execute"]->create();
00342 classHamFilterAction->argsFromString( (*it).getHamCmd() );
00343 classHamFilterActions->append( classHamFilterAction );
00344 }
00345 }
00346 KMSearchPattern* classHamFilterPattern = classHamFilter->pattern();
00347 classHamFilterPattern->setName( i18n( "Classify as NOT spam" ) );
00348 classHamFilterPattern->append( KMSearchRule::createInstance( "<size>",
00349 KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
00350 classHamFilter->setApplyOnOutbound( FALSE);
00351 classHamFilter->setApplyOnInbound( FALSE );
00352 classHamFilter->setApplyOnExplicit( FALSE );
00353 classHamFilter->setStopProcessingHere( TRUE );
00354 classHamFilter->setConfigureShortcut( TRUE );
00355 classHamFilter->setConfigureToolbar( TRUE );
00356 filterList.append( classHamFilter );
00357 }
00358
00359
00360
00361
00362
00363 KMKernel::self()->filterMgr()->appendFilters( filterList );
00364 }
00365
00366 QDialog::accept();
00367 }
00368
00369
00370 void AntiSpamWizard::checkProgramsSelections()
00371 {
00372 bool status = false;
00373 bool canClassify = false;
00374 mSpamToolsUsed = false;
00375 mVirusToolsUsed = false;
00376 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00377 it != mToolList.end(); ++it ) {
00378 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() ) )
00379 {
00380 status = true;
00381 if ( (*it).isSpamTool() ) {
00382 mSpamToolsUsed = true;
00383 if ( (*it).useBayesFilter() )
00384 canClassify = true;
00385 }
00386 if ( (*it).isVirusTool() )
00387 mVirusToolsUsed = true;
00388 }
00389 }
00390
00391 if ( mSpamRulesPage )
00392 mSpamRulesPage->allowClassification( canClassify );
00393
00394 if ( mSpamRulesPage )
00395 removePage( mSpamRulesPage );
00396 if ( mVirusRulesPage )
00397 removePage( mVirusRulesPage );
00398 if ( ( mMode == AntiSpam ) && mSpamToolsUsed )
00399 {
00400 addPage( mSpamRulesPage, i18n( "Please select the spam filters to be created inside KMail." ));
00401 checkSpamRulesSelections();
00402 }
00403 if ( ( mMode == AntiVirus ) && mVirusToolsUsed )
00404 {
00405 addPage( mVirusRulesPage, i18n( "Please select the virus filters to be created inside KMail." ));
00406 checkVirusRulesSelections();
00407 }
00408
00409 setNextEnabled( mProgramsPage, status );
00410 }
00411
00412
00413 void AntiSpamWizard::checkSpamRulesSelections()
00414 {
00415 setFinishEnabled( mSpamRulesPage, anySpamOptionChecked() );
00416 }
00417
00418 void AntiSpamWizard::checkVirusRulesSelections()
00419 {
00420 setFinishEnabled( mVirusRulesPage, anyVirusOptionChecked() );
00421 }
00422
00423
00424 void AntiSpamWizard::checkToolAvailability()
00425 {
00426 KCursorSaver busy(KBusyPtr::busy());
00427
00428
00429 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00430 it != mToolList.end(); ++it ) {
00431 QString text( i18n("Scanning for %1...").arg( (*it).getId() ) );
00432 mInfoPage->setScanProgressText( text );
00433 KApplication::kApplication()->processEvents( 200 );
00434 int rc = checkForProgram( (*it).getExecutable() );
00435 mProgramsPage->setProgramAsFound( (*it).getVisibleName(), !rc );
00436 }
00437 mInfoPage->setScanProgressText( ( mMode == AntiSpam )
00438 ? i18n("Scanning for anti-spam tools finished.")
00439 : i18n("Scanning for anti-virus tools finished.") );
00440 setNextEnabled( mInfoPage, true );
00441 }
00442
00443
00444 int AntiSpamWizard::checkForProgram( QString executable )
00445 {
00446 kdDebug(5006) << "Testing for executable:" << executable << endl;
00447 KProcess process;
00448 process << executable;
00449 process.setUseShell( true );
00450 process.start( KProcess::Block );
00451 return process.exitStatus();
00452 }
00453
00454
00455 void AntiSpamWizard::slotHelpClicked()
00456 {
00457 if ( mMode == AntiSpam )
00458 kapp->invokeHelp( "the-anti-spam-wizard", "kmail" );
00459 else
00460 kapp->invokeHelp( "the-anti-virus-wizard", "kmail" );
00461 }
00462
00463
00464 bool AntiSpamWizard::anySpamOptionChecked()
00465 {
00466 return ( mSpamRulesPage->moveRulesSelected()
00467 || mSpamRulesPage->pipeRulesSelected()
00468 || mSpamRulesPage->classifyRulesSelected() );
00469 }
00470
00471 bool AntiSpamWizard::anyVirusOptionChecked()
00472 {
00473 return ( mVirusRulesPage->moveRulesSelected()
00474 || mVirusRulesPage->pipeRulesSelected() );
00475 }
00476
00477
00478
00479 AntiSpamWizard::SpamToolConfig::SpamToolConfig(QString toolId,
00480 int configVersion,QString name, QString exec,
00481 QString url, QString filter, QString detection, QString spam, QString ham,
00482 QString header, QString pattern, bool regExp, bool bayesFilter, WizardMode type)
00483 : mId( toolId ), mVersion( configVersion ),
00484 mVisibleName( name ), mExecutable( exec ), mWhatsThisText( url ),
00485 mFilterName( filter ), mDetectCmd( detection ), mSpamCmd( spam ),
00486 mHamCmd( ham ), mDetectionHeader( header ), mDetectionPattern( pattern ),
00487 mUseRegExp( regExp ), mSupportsBayesFilter( bayesFilter ), mType( type )
00488 {
00489 }
00490
00491
00492
00493 AntiSpamWizard::ConfigReader::ConfigReader( WizardMode mode,
00494 QValueList<SpamToolConfig> & configList )
00495 : mToolList( configList ),
00496 mMode( mode )
00497 {
00498 if ( mMode == AntiSpam )
00499 mConfig = new KConfig( "kmail.antispamrc", true );
00500 else
00501 mConfig = new KConfig( "kmail.antivirusrc", true );
00502 }
00503
00504 AntiSpamWizard::ConfigReader::~ConfigReader( )
00505 {
00506 delete mConfig;
00507 }
00508
00509
00510 void AntiSpamWizard::ConfigReader::readAndMergeConfig()
00511 {
00512 QString groupName = ( mMode == AntiSpam )
00513 ? QString("Spamtool #%1")
00514 : QString("Virustool #%1");
00515
00516 mConfig->setReadDefaults( true );
00517 KConfigGroup general( mConfig, "General" );
00518 int registeredTools = general.readNumEntry( "tools", 0 );
00519 for (int i = 1; i <= registeredTools; i++)
00520 {
00521 KConfigGroup toolConfig( mConfig, groupName.arg( i ) );
00522 mToolList.append( readToolConfig( toolConfig ) );
00523 }
00524
00525
00526
00527 mConfig->setReadDefaults( false );
00528 KConfigGroup user_general( mConfig, "General" );
00529 int user_registeredTools = user_general.readNumEntry( "tools", 0 );
00530 for (int i = 1; i <= user_registeredTools; i++)
00531 {
00532 KConfigGroup toolConfig( mConfig, groupName.arg( i ) );
00533 mergeToolConfig( readToolConfig( toolConfig ) );
00534 }
00535
00536
00537
00538 if ( mMode == AntiSpam ) {
00539 if ( registeredTools < 1 && user_registeredTools < 1 )
00540 mToolList.append( createDummyConfig() );
00541 }
00542 }
00543
00544
00545 AntiSpamWizard::SpamToolConfig
00546 AntiSpamWizard::ConfigReader::readToolConfig( KConfigGroup & configGroup )
00547 {
00548 QString id = configGroup.readEntry( "Ident" );
00549 int version = configGroup.readNumEntry( "Version" );
00550 #ifndef NDEBUG
00551 kdDebug(5006) << "Found predefined tool: " << id << endl;
00552 kdDebug(5006) << "With config version : " << version << endl;
00553 #endif
00554 QString name = configGroup.readEntry( "VisibleName" );
00555 QString executable = configGroup.readEntry( "Executable" );
00556 QString url = configGroup.readEntry( "URL" );
00557 QString filterName = configGroup.readEntry( "PipeFilterName" );
00558 QString detectCmd = configGroup.readEntry( "PipeCmdDetect" );
00559 QString spamCmd = configGroup.readEntry( "ExecCmdSpam" );
00560 QString hamCmd = configGroup.readEntry( "ExecCmdHam" );
00561 QString header = configGroup.readEntry( "DetectionHeader" );
00562 QString pattern = configGroup.readEntry( "DetectionPattern" );
00563 bool useRegExp = configGroup.readBoolEntry( "UseRegExp" );
00564 bool supportsBayes = configGroup.readBoolEntry( "SupportsBayes", false );
00565 return SpamToolConfig( id, version, name, executable, url,
00566 filterName, detectCmd, spamCmd, hamCmd,
00567 header, pattern, useRegExp, supportsBayes, mMode );
00568 }
00569
00570
00571 AntiSpamWizard::SpamToolConfig AntiSpamWizard::ConfigReader::createDummyConfig()
00572 {
00573 return SpamToolConfig( "spamassassin", 0,
00574 "&SpamAssassin", "spamassassin -V",
00575 "http://spamassassin.org", "SpamAssassin Check",
00576 "spamassassin -L",
00577 "sa-learn -L --spam --no-rebuild --single",
00578 "sa-learn -L --ham --no-rebuild --single",
00579 "X-Spam-Flag", "yes",
00580 false, true, AntiSpam );
00581 }
00582
00583
00584 void AntiSpamWizard::ConfigReader::mergeToolConfig( AntiSpamWizard::SpamToolConfig config )
00585 {
00586 bool found = false;
00587 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin();
00588 it != mToolList.end(); ++it ) {
00589 #ifndef NDEBUG
00590 kdDebug(5006) << "Check against tool: " << (*it).getId() << endl;
00591 kdDebug(5006) << "Against version : " << (*it).getVersion() << endl;
00592 #endif
00593 if ( (*it).getId() == config.getId() )
00594 {
00595 found = true;
00596 if ( (*it).getVersion() < config.getVersion() )
00597 {
00598 #ifndef NDEBUG
00599 kdDebug(5006) << "Replacing config ..." << endl;
00600 #endif
00601 mToolList.remove( it );
00602 mToolList.append( config );
00603 }
00604 break;
00605 }
00606 }
00607 if ( !found )
00608 mToolList.append( config );
00609 }
00610
00611
00612
00613 ASWizInfoPage::ASWizInfoPage( AntiSpamWizard::WizardMode mode,
00614 QWidget * parent, const char * name )
00615 : QWidget( parent, name )
00616 {
00617 QGridLayout *grid = new QGridLayout( this, 1, 1, KDialog::marginHint(),
00618 KDialog::spacingHint() );
00619 grid->setColStretch( 1, 10 );
00620
00621 mIntroText = new QLabel( this );
00622 mIntroText->setText(
00623 ( mode == AntiSpamWizard::AntiSpam )
00624 ? i18n(
00625 "<p>Here you can get some assistance in setting up KMail's filter "
00626 "rules to use some commonly-known anti-spam tools.</p>"
00627 "<p>The wizard can detect those tools on your computer as "
00628 "well as create filter rules to classify messages using these "
00629 "tools and to separate messages classified as spam. "
00630 "The wizard will not take any existing filter "
00631 "rules into consideration: it will always append the new rules.</p>"
00632 "<p><b>Warning:</b> As KMail is blocked during the scan of the "
00633 "messages for spam, you may encounter problems with "
00634 "the responsiveness of KMail because anti-spam tool "
00635 "operations are usually time consuming; please consider "
00636 "deleting the filter rules created by the wizard to get "
00637 "back to the former behavior."
00638 )
00639 : i18n(
00640 "<p>Here you can get some assistance in setting up KMail's filter "
00641 "rules to use some commonly-known anti-virus tools.</p>"
00642 "<p>The wizard can detect those tools on your computer as "
00643 "well as create filter rules to classify messages using these "
00644 "tools and to separate messages containing viruses. "
00645 "The wizard will not take any existing filter "
00646 "rules into consideration: it will always append the new rules.</p>"
00647 "<p><b>Warning:</b> As KMail is blocked during the scan of the "
00648 "messages for viruses, you may encounter problems with "
00649 "the responsiveness of KMail because anti-virus tool "
00650 "operations are usually time consuming; please consider "
00651 "deleting the filter rules created by the wizard to get "
00652 "back to the former behavior."
00653 ) );
00654 grid->addWidget( mIntroText, 0, 0 );
00655
00656 mScanProgressText = new QLabel( this );
00657 mScanProgressText->setText( "" ) ;
00658 grid->addWidget( mScanProgressText, 1, 0 );
00659 }
00660
00661 void ASWizInfoPage::setScanProgressText( const QString &toolName )
00662 {
00663 mScanProgressText->setText( toolName );
00664 }
00665
00666
00667 ASWizProgramsPage::ASWizProgramsPage( QWidget * parent, const char * name,
00668 QStringList &checkBoxTextList,
00669 QStringList &checkBoxWhatsThisList )
00670 : QWidget( parent, name )
00671 {
00672 QGridLayout *grid = new QGridLayout( this, 3, 1, KDialog::marginHint(),
00673 KDialog::spacingHint() );
00674
00675 int row = 0;
00676 QStringList::Iterator it1 = checkBoxTextList.begin();
00677 QStringList::Iterator it2 = checkBoxWhatsThisList.begin();
00678 while ( it1 != checkBoxTextList.end() )
00679 {
00680 QCheckBox *box = new QCheckBox( *it1, this );
00681 if ( it2 != checkBoxWhatsThisList.end() )
00682 {
00683 QWhatsThis::add( box, *it2 );
00684 QToolTip::add( box, *it2 );
00685 ++it2;
00686 }
00687 grid->addWidget( box, row++, 0 );
00688 connect( box, SIGNAL(clicked()),
00689 this, SLOT(processSelectionChange(void)) );
00690 mProgramDict.insert( *it1, box );
00691 ++it1;
00692 }
00693
00694
00695 QLabel *introText = new QLabel( this );
00696 introText->setText( i18n(
00697 "<p>For these tools it is possible to let the "
00698 "wizard create filter rules. KMail tried to find the tools "
00699 "in the PATH of your system; the wizard does not allow you "
00700 "to create rules for tools which were not found: "
00701 "this is to keep your configuration consistent and "
00702 "to minimize the risk of unpredicted behavior.</p>"
00703 ) );
00704 grid->addWidget( introText, row++, 0 );
00705 }
00706
00707
00708 bool ASWizProgramsPage::isProgramSelected( const QString &visibleName )
00709 {
00710 if ( mProgramDict[visibleName] )
00711 return mProgramDict[visibleName]->isChecked();
00712 else
00713 return false;
00714 }
00715
00716
00717 void ASWizProgramsPage::setProgramAsFound( const QString &visibleName, bool found )
00718 {
00719 QCheckBox * box = mProgramDict[visibleName];
00720 if ( box )
00721 {
00722 QString foundText( i18n("(found on this system)") );
00723 QString notFoundText( i18n("(not found on this system)") );
00724 QString labelText = visibleName;
00725 labelText += " ";
00726 if ( found )
00727 labelText += foundText;
00728 else
00729 {
00730 labelText += notFoundText;
00731 box->setEnabled( false );
00732 }
00733 box->setText( labelText );
00734 }
00735 }
00736
00737
00738 void ASWizProgramsPage::processSelectionChange()
00739 {
00740 emit selectionChanged();
00741 }
00742
00743
00744 ASWizSpamRulesPage::ASWizSpamRulesPage( QWidget * parent, const char * name,
00745 KMFolderTree * mainFolderTree )
00746 : QWidget( parent, name )
00747 {
00748 QGridLayout *grid = new QGridLayout( this, 5, 1, KDialog::marginHint(),
00749 KDialog::spacingHint() );
00750
00751 mClassifyRules = new QCheckBox( i18n("Classify messages manually as spam"), this );
00752 QWhatsThis::add( mClassifyRules,
00753 i18n( "Sometimes messages are classified wrongly or even not at all; "
00754 "the latter might be by intention, because you perhaps filter "
00755 "out messages from mailing lists before you let the anti-spam "
00756 "tools classify the rest of the messages. You can correct these "
00757 "wrong or missing classifications manually by using the "
00758 "appropriate toolbar buttons which trigger special filters "
00759 "created by this wizard." ) );
00760 grid->addWidget( mClassifyRules, 0, 0 );
00761
00762 mPipeRules = new QCheckBox( i18n("Classify messages using the anti-spam tools"), this );
00763 QWhatsThis::add( mPipeRules,
00764 i18n( "Let the anti-spam tools classify your messages. The wizard "
00765 "will create appropriate filters. The messages are usually "
00766 "marked by the tools so that following filters can react "
00767 "on this and, for example, move spam messages to a special folder.") );
00768 grid->addWidget( mPipeRules, 1, 0 );
00769
00770 mMoveRules = new QCheckBox( i18n("Move detected spam messages to the selected folder"), this );
00771 QWhatsThis::add( mMoveRules,
00772 i18n( "A filter to detect messages classified as spam and to move "
00773 "those messages into a predefined folder is created. The "
00774 "default folder is the trash folder, but you may change that "
00775 "in the folder view.") );
00776 grid->addWidget( mMoveRules, 2, 0 );
00777
00778 mMarkRules = new QCheckBox( i18n("Additionally, mark detected spam messages as read"), this );
00779 mMarkRules->setEnabled( false );
00780 QWhatsThis::add( mMarkRules,
00781 i18n( "Mark messages which have been classified as "
00782 "spam as read, as well as moving them to the selected "
00783 "folder.") );
00784 grid->addWidget( mMarkRules, 3, 0 );
00785
00786 QString s = "trash";
00787 mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true );
00788 grid->addWidget( mFolderTree, 4, 0 );
00789
00790 connect( mPipeRules, SIGNAL(clicked()),
00791 this, SLOT(processSelectionChange(void)) );
00792 connect( mClassifyRules, SIGNAL(clicked()),
00793 this, SLOT(processSelectionChange(void)) );
00794 connect( mMoveRules, SIGNAL(clicked()),
00795 this, SLOT(processSelectionChange(void)) );
00796 connect( mMarkRules, SIGNAL(clicked()),
00797 this, SLOT(processSelectionChange(void)) );
00798 connect( mMoveRules, SIGNAL( toggled( bool ) ),
00799 mMarkRules, SLOT( setEnabled( bool ) ) );
00800 }
00801
00802 bool ASWizSpamRulesPage::pipeRulesSelected() const
00803 {
00804 return mPipeRules->isChecked();
00805 }
00806
00807
00808 bool ASWizSpamRulesPage::classifyRulesSelected() const
00809 {
00810 return mClassifyRules->isChecked();
00811 }
00812
00813
00814 bool ASWizSpamRulesPage::moveRulesSelected() const
00815 {
00816 return mMoveRules->isChecked();
00817 }
00818
00819 bool ASWizSpamRulesPage::markReadRulesSelected() const
00820 {
00821 return mMarkRules->isChecked();
00822 }
00823
00824
00825 QString ASWizSpamRulesPage::selectedFolderName() const
00826 {
00827 QString name = "trash";
00828 if ( mFolderTree->folder() )
00829 name = mFolderTree->folder()->idString();
00830 return name;
00831 }
00832
00833 void ASWizSpamRulesPage::processSelectionChange()
00834 {
00835 emit selectionChanged();
00836 }
00837
00838
00839 void ASWizSpamRulesPage::allowClassification( bool enabled )
00840 {
00841 if ( enabled )
00842 mClassifyRules->setEnabled( true );
00843 else
00844 {
00845 mClassifyRules->setChecked( false );
00846 mClassifyRules->setEnabled( false );
00847 }
00848 }
00849
00850
00851 ASWizVirusRulesPage::ASWizVirusRulesPage( QWidget * parent, const char * name,
00852 KMFolderTree * mainFolderTree )
00853 : QWidget( parent, name )
00854 {
00855 QGridLayout *grid = new QGridLayout( this, 5, 1, KDialog::marginHint(),
00856 KDialog::spacingHint() );
00857
00858 mPipeRules = new QCheckBox( i18n("Check messages using the anti-virus tools"), this );
00859 QWhatsThis::add( mPipeRules,
00860 i18n( "Let the anti-virus tools check your messages. The wizard "
00861 "will create appropriate filters. The messages are usually "
00862 "marked by the tools so that following filters can react "
00863 "on this and, for example, move virus messages to a special folder.") );
00864 grid->addWidget( mPipeRules, 0, 0 );
00865
00866 mMoveRules = new QCheckBox( i18n("Move detected viral messages to the selected folder"), this );
00867 QWhatsThis::add( mMoveRules,
00868 i18n( "A filter to detect messages classified as virus-infected and to move "
00869 "those messages into a predefined folder is created. The "
00870 "default folder is the trash folder, but you may change that "
00871 "in the folder view.") );
00872 grid->addWidget( mMoveRules, 1, 0 );
00873
00874 mMarkRules = new QCheckBox( i18n("Additionally, mark detected viral messages as read"), this );
00875 mMarkRules->setEnabled( false );
00876 QWhatsThis::add( mMarkRules,
00877 i18n( "Mark messages which have been classified as "
00878 "virus-infected as read, as well as moving them "
00879 "to the selected folder.") );
00880 grid->addWidget( mMarkRules, 2, 0 );
00881
00882 QString s = "trash";
00883 mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true );
00884 grid->addWidget( mFolderTree, 3, 0 );
00885
00886 connect( mPipeRules, SIGNAL(clicked()),
00887 this, SLOT(processSelectionChange(void)) );
00888 connect( mMoveRules, SIGNAL(clicked()),
00889 this, SLOT(processSelectionChange(void)) );
00890 connect( mMarkRules, SIGNAL(clicked()),
00891 this, SLOT(processSelectionChange(void)) );
00892 connect( mMoveRules, SIGNAL( toggled( bool ) ),
00893 mMarkRules, SLOT( setEnabled( bool ) ) );
00894 }
00895
00896 bool ASWizVirusRulesPage::pipeRulesSelected() const
00897 {
00898 return mPipeRules->isChecked();
00899 }
00900
00901
00902 bool ASWizVirusRulesPage::moveRulesSelected() const
00903 {
00904 return mMoveRules->isChecked();
00905 }
00906
00907 bool ASWizVirusRulesPage::markReadRulesSelected() const
00908 {
00909 return mMarkRules->isChecked();
00910 }
00911
00912
00913 QString ASWizVirusRulesPage::selectedFolderName() const
00914 {
00915 QString name = "trash";
00916 if ( mFolderTree->folder() )
00917 name = mFolderTree->folder()->idString();
00918 return name;
00919 }
00920
00921 void ASWizVirusRulesPage::processSelectionChange()
00922 {
00923 emit selectionChanged();
00924 }
00925
00926 #include "antispamwizard.moc"