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