kmail Library API Documentation

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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "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 // read the configuration for the anti-spam tools 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 // Let's start with virus detection and handling, 00147 // so we can avoid spam checks for viral messages 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 // pipe messages through the anti-virus tools, 00155 // one single filter for each tool 00156 // (could get combined but so it's easier to understand for the user) 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 // Sort out viruses depending on header fields set by the tools 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" ); // Read 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 { // AntiSpam mode 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 // pipe messages through the anti-spam tools, 00227 // one single filter for each tool 00228 // (could get combined but so it's easier to understand for the user) 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 // Sort out spam depending on header fields set by the tools 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" ); // Spam 00258 spamFilterActions->append( spamFilterAction2 ); 00259 if ( mSpamRulesPage->markReadRulesSelected() ) { 00260 KMFilterAction* spamFilterAction3 = dict["set status"]->create(); 00261 spamFilterAction3->argsFromString( "R" ); // Read 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 // Classify messages manually as Spam 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 // Classify messages manually as not Spam / as Ham 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 /* Now that all the filters have been added to the list, tell 00360 * the filter manager about it. That will emit filterListUpdate 00361 * which will result in the filter list in kmmainwidget being 00362 * initialized. This should happend only once. */ 00363 KMKernel::self()->filterMgr()->appendFilters( filterList ); 00364 00365 } 00366 } 00367 00368 QDialog::accept(); 00369 } 00370 00371 00372 void AntiSpamWizard::checkProgramsSelections() 00373 { 00374 bool status = false; 00375 bool canClassify = false; 00376 mSpamToolsUsed = false; 00377 mVirusToolsUsed = false; 00378 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin(); 00379 it != mToolList.end(); ++it ) { 00380 if ( mProgramsPage->isProgramSelected( (*it).getVisibleName() ) ) 00381 { 00382 status = true; 00383 if ( (*it).isSpamTool() ) 00384 mSpamToolsUsed = true; 00385 if ( (*it).isVirusTool() ) 00386 mVirusToolsUsed = true; 00387 } 00388 if ( (*it).useBayesFilter() ) 00389 canClassify = true; 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()); // this can take some time to find the tools 00428 00429 // checkboxes for the tools 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 00506 void AntiSpamWizard::ConfigReader::readAndMergeConfig() 00507 { 00508 QString groupName = ( mMode == AntiSpam ) 00509 ? QString("Spamtool #%1") 00510 : QString("Virustool #%1"); 00511 // read the configuration from the global config file 00512 mConfig->setReadDefaults( true ); 00513 KConfigGroup general( mConfig, "General" ); 00514 int registeredTools = general.readNumEntry( "tools", 0 ); 00515 for (int i = 1; i <= registeredTools; i++) 00516 { 00517 KConfigGroup toolConfig( mConfig, groupName.arg( i ) ); 00518 mToolList.append( readToolConfig( toolConfig ) ); 00519 } 00520 00521 // read the configuration from the user config file 00522 // and merge newer config data 00523 mConfig->setReadDefaults( false ); 00524 KConfigGroup user_general( mConfig, "General" ); 00525 int user_registeredTools = user_general.readNumEntry( "tools", 0 ); 00526 for (int i = 1; i <= user_registeredTools; i++) 00527 { 00528 KConfigGroup toolConfig( mConfig, groupName.arg( i ) ); 00529 mergeToolConfig( readToolConfig( toolConfig ) ); 00530 } 00531 // Make sure to have add least one tool listed even when the 00532 // config file was not found or whatever went wrong 00533 // Currently only works for spam tools 00534 if ( mMode == AntiSpam ) { 00535 if ( registeredTools < 1 && user_registeredTools < 1 ) 00536 mToolList.append( createDummyConfig() ); 00537 } 00538 } 00539 00540 00541 AntiSpamWizard::SpamToolConfig 00542 AntiSpamWizard::ConfigReader::readToolConfig( KConfigGroup & configGroup ) 00543 { 00544 QString id = configGroup.readEntry( "Ident" ); 00545 int version = configGroup.readNumEntry( "Version" ); 00546 #ifndef NDEBUG 00547 kdDebug(5006) << "Found predefined tool: " << id << endl; 00548 kdDebug(5006) << "With config version : " << version << endl; 00549 #endif 00550 QString name = configGroup.readEntry( "VisibleName" ); 00551 QString executable = configGroup.readEntry( "Executable" ); 00552 QString url = configGroup.readEntry( "URL" ); 00553 QString filterName = configGroup.readEntry( "PipeFilterName" ); 00554 QString detectCmd = configGroup.readEntry( "PipeCmdDetect" ); 00555 QString spamCmd = configGroup.readEntry( "ExecCmdSpam" ); 00556 QString hamCmd = configGroup.readEntry( "ExecCmdHam" ); 00557 QString header = configGroup.readEntry( "DetectionHeader" ); 00558 QString pattern = configGroup.readEntry( "DetectionPattern" ); 00559 bool useRegExp = configGroup.readBoolEntry( "UseRegExp" ); 00560 bool supportsBayes = configGroup.readBoolEntry( "SupportsBayes", false ); 00561 return SpamToolConfig( id, version, name, executable, url, 00562 filterName, detectCmd, spamCmd, hamCmd, 00563 header, pattern, useRegExp, supportsBayes, mMode ); 00564 } 00565 00566 00567 AntiSpamWizard::SpamToolConfig AntiSpamWizard::ConfigReader::createDummyConfig() 00568 { 00569 return SpamToolConfig( "spamassassin", 0, 00570 "&SpamAssassin", "spamassassin -V", 00571 "http://spamassassin.org", "SpamAssassin Check", 00572 "spamassassin -L", 00573 "sa-learn -L --spam --no-rebuild --single", 00574 "sa-learn -L --ham --no-rebuild --single", 00575 "X-Spam-Flag", "yes", 00576 false, true, AntiSpam ); 00577 } 00578 00579 00580 void AntiSpamWizard::ConfigReader::mergeToolConfig( AntiSpamWizard::SpamToolConfig config ) 00581 { 00582 bool found = false; 00583 for ( QValueListIterator<SpamToolConfig> it = mToolList.begin(); 00584 it != mToolList.end(); ++it ) { 00585 #ifndef NDEBUG 00586 kdDebug(5006) << "Check against tool: " << (*it).getId() << endl; 00587 kdDebug(5006) << "Against version : " << (*it).getVersion() << endl; 00588 #endif 00589 if ( (*it).getId() == config.getId() ) 00590 { 00591 found = true; 00592 if ( (*it).getVersion() < config.getVersion() ) 00593 { 00594 #ifndef NDEBUG 00595 kdDebug(5006) << "Replacing config ..." << endl; 00596 #endif 00597 mToolList.remove( it ); 00598 mToolList.append( config ); 00599 } 00600 break; 00601 } 00602 } 00603 if ( !found ) 00604 mToolList.append( config ); 00605 } 00606 00607 00608 //--------------------------------------------------------------------------- 00609 ASWizInfoPage::ASWizInfoPage( AntiSpamWizard::WizardMode mode, 00610 QWidget * parent, const char * name ) 00611 : QWidget( parent, name ) 00612 { 00613 QGridLayout *grid = new QGridLayout( this, 1, 1, KDialog::marginHint(), 00614 KDialog::spacingHint() ); 00615 grid->setColStretch( 1, 10 ); 00616 00617 mIntroText = new QLabel( this ); 00618 mIntroText->setText( 00619 ( mode == AntiSpamWizard::AntiSpam ) 00620 ? i18n( 00621 "<p>Here you can get some assistance in setting up KMail's filter " 00622 "rules to use some commonly-known anti-spam tools.</p>" 00623 "<p>The wizard can detect those tools on your computer as " 00624 "well as create filter rules to classify messages using these " 00625 "tools and to separate messages classified as spam. " 00626 "The wizard will not take any existing filter " 00627 "rules into consideration: it will always append the new rules.</p>" 00628 "<p><b>Warning:</b> As KMail is blocked during the scan of the " 00629 "messages for spam, you may encounter problems with " 00630 "the responsiveness of KMail because anti-spam tool " 00631 "operations are usually time consuming; please consider " 00632 "deleting the filter rules created by the wizard to get " 00633 "back to the former behavior." 00634 ) 00635 : i18n( 00636 "<p>Here you can get some assistance in setting up KMail's filter " 00637 "rules to use some commonly-known anti-virus tools.</p>" 00638 "<p>The wizard can detect those tools on your computer as " 00639 "well as create filter rules to classify messages using these " 00640 "tools and to separate messages containing viruses. " 00641 "The wizard will not take any existing filter " 00642 "rules into consideration: it will always append the new rules.</p>" 00643 "<p><b>Warning:</b> As KMail is blocked during the scan of the " 00644 "messages for viruses, you may encounter problems with " 00645 "the responsiveness of KMail because anti-virus tool " 00646 "operations are usually time consuming; please consider " 00647 "deleting the filter rules created by the wizard to get " 00648 "back to the former behavior." 00649 ) ); 00650 grid->addWidget( mIntroText, 0, 0 ); 00651 00652 mScanProgressText = new QLabel( this ); 00653 mScanProgressText->setText( "" ) ; 00654 grid->addWidget( mScanProgressText, 1, 0 ); 00655 } 00656 00657 void ASWizInfoPage::setScanProgressText( const QString &toolName ) 00658 { 00659 mScanProgressText->setText( toolName ); 00660 } 00661 00662 //--------------------------------------------------------------------------- 00663 ASWizProgramsPage::ASWizProgramsPage( QWidget * parent, const char * name, 00664 QStringList &checkBoxTextList, 00665 QStringList &checkBoxWhatsThisList ) 00666 : QWidget( parent, name ) 00667 { 00668 QGridLayout *grid = new QGridLayout( this, 3, 1, KDialog::marginHint(), 00669 KDialog::spacingHint() ); 00670 // checkboxes for the tools 00671 int row = 0; 00672 QStringList::Iterator it1 = checkBoxTextList.begin(); 00673 QStringList::Iterator it2 = checkBoxWhatsThisList.begin(); 00674 while ( it1 != checkBoxTextList.end() ) 00675 { 00676 QCheckBox *box = new QCheckBox( *it1, this ); 00677 if ( it2 != checkBoxWhatsThisList.end() ) 00678 { 00679 QWhatsThis::add( box, *it2 ); 00680 QToolTip::add( box, *it2 ); 00681 ++it2; 00682 } 00683 grid->addWidget( box, row++, 0 ); 00684 connect( box, SIGNAL(clicked()), 00685 this, SLOT(processSelectionChange(void)) ); 00686 mProgramDict.insert( *it1, box ); 00687 ++it1; 00688 } 00689 00690 // hint text 00691 QLabel *introText = new QLabel( this ); 00692 introText->setText( i18n( 00693 "<p>For these tools it is possible to let the " 00694 "wizard create filter rules. KMail tried to find the tools " 00695 "in the PATH of your system; the wizard does not allow you " 00696 "to create rules for tools which were not found: " 00697 "this is to keep your configuration consistent and " 00698 "to minimize the risk of unpredicted behavior.</p>" 00699 ) ); 00700 grid->addWidget( introText, row++, 0 ); 00701 } 00702 00703 00704 bool ASWizProgramsPage::isProgramSelected( const QString &visibleName ) 00705 { 00706 if ( mProgramDict[visibleName] ) 00707 return mProgramDict[visibleName]->isChecked(); 00708 else 00709 return false; 00710 } 00711 00712 00713 void ASWizProgramsPage::setProgramAsFound( const QString &visibleName, bool found ) 00714 { 00715 QCheckBox * box = mProgramDict[visibleName]; 00716 if ( box ) 00717 { 00718 QString foundText( i18n("(found on this system)") ); 00719 QString notFoundText( i18n("(not found on this system)") ); 00720 QString labelText = visibleName; 00721 labelText += " "; 00722 if ( found ) 00723 labelText += foundText; 00724 else 00725 { 00726 labelText += notFoundText; 00727 box->setEnabled( false ); 00728 } 00729 box->setText( labelText ); 00730 } 00731 } 00732 00733 00734 void ASWizProgramsPage::processSelectionChange() 00735 { 00736 emit selectionChanged(); 00737 } 00738 00739 //--------------------------------------------------------------------------- 00740 ASWizSpamRulesPage::ASWizSpamRulesPage( QWidget * parent, const char * name, 00741 KMFolderTree * mainFolderTree ) 00742 : QWidget( parent, name ) 00743 { 00744 QGridLayout *grid = new QGridLayout( this, 5, 1, KDialog::marginHint(), 00745 KDialog::spacingHint() ); 00746 00747 mClassifyRules = new QCheckBox( i18n("Classify messages manually as spam"), this ); 00748 QWhatsThis::add( mClassifyRules, 00749 i18n( "Sometimes messages are classified wrongly or even not at all; " 00750 "the latter might be by intention, because you perhaps filter " 00751 "out messages from mailing lists before you let the anti-spam " 00752 "tools classify the rest of the messages. You can correct these " 00753 "wrong or missing classifications manually by using the " 00754 "appropriate toolbar buttons which trigger special filters " 00755 "created by this wizard." ) ); 00756 grid->addWidget( mClassifyRules, 0, 0 ); 00757 00758 mPipeRules = new QCheckBox( i18n("Classify messages using the anti-spam tools"), this ); 00759 QWhatsThis::add( mPipeRules, 00760 i18n( "Let the anti-spam tools classify your messages. The wizard " 00761 "will create appropriate filters. The messages are usually " 00762 "marked by the tools so that following filters can react " 00763 "on this and, for example, move spam messages to a special folder.") ); 00764 grid->addWidget( mPipeRules, 1, 0 ); 00765 00766 mMoveRules = new QCheckBox( i18n("Move detected spam messages to the selected folder"), this ); 00767 QWhatsThis::add( mMoveRules, 00768 i18n( "A filter to detect messages classified as spam and to move " 00769 "those messages into a predefined folder is created. The " 00770 "default folder is the trash folder, but you may change that " 00771 "in the folder view.") ); 00772 grid->addWidget( mMoveRules, 2, 0 ); 00773 00774 mMarkRules = new QCheckBox( i18n("Additionally, mark detected spam messages as read"), this ); 00775 mMarkRules->setEnabled( false ); 00776 QWhatsThis::add( mMarkRules, 00777 i18n( "Mark messages which have been classified as " 00778 "spam as read, as well as moving them to the selected " 00779 "folder.") ); 00780 grid->addWidget( mMarkRules, 3, 0 ); 00781 00782 QString s = "trash"; 00783 mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true ); 00784 grid->addWidget( mFolderTree, 4, 0 ); 00785 00786 connect( mPipeRules, SIGNAL(clicked()), 00787 this, SLOT(processSelectionChange(void)) ); 00788 connect( mClassifyRules, SIGNAL(clicked()), 00789 this, SLOT(processSelectionChange(void)) ); 00790 connect( mMoveRules, SIGNAL(clicked()), 00791 this, SLOT(processSelectionChange(void)) ); 00792 connect( mMarkRules, SIGNAL(clicked()), 00793 this, SLOT(processSelectionChange(void)) ); 00794 connect( mMoveRules, SIGNAL( toggled( bool ) ), 00795 mMarkRules, SLOT( setEnabled( bool ) ) ); 00796 } 00797 00798 bool ASWizSpamRulesPage::pipeRulesSelected() const 00799 { 00800 return mPipeRules->isChecked(); 00801 } 00802 00803 00804 bool ASWizSpamRulesPage::classifyRulesSelected() const 00805 { 00806 return mClassifyRules->isChecked(); 00807 } 00808 00809 00810 bool ASWizSpamRulesPage::moveRulesSelected() const 00811 { 00812 return mMoveRules->isChecked(); 00813 } 00814 00815 bool ASWizSpamRulesPage::markReadRulesSelected() const 00816 { 00817 return mMarkRules->isChecked(); 00818 } 00819 00820 00821 QString ASWizSpamRulesPage::selectedFolderName() const 00822 { 00823 QString name = "trash"; 00824 if ( mFolderTree->folder() ) 00825 name = mFolderTree->folder()->idString(); 00826 return name; 00827 } 00828 00829 void ASWizSpamRulesPage::processSelectionChange() 00830 { 00831 emit selectionChanged(); 00832 } 00833 00834 00835 void ASWizSpamRulesPage::allowClassification( bool enabled ) 00836 { 00837 if ( enabled ) 00838 mClassifyRules->setEnabled( true ); 00839 else 00840 { 00841 mClassifyRules->setChecked( false ); 00842 mClassifyRules->setEnabled( false ); 00843 } 00844 } 00845 00846 //--------------------------------------------------------------------------- 00847 ASWizVirusRulesPage::ASWizVirusRulesPage( QWidget * parent, const char * name, 00848 KMFolderTree * mainFolderTree ) 00849 : QWidget( parent, name ) 00850 { 00851 QGridLayout *grid = new QGridLayout( this, 5, 1, KDialog::marginHint(), 00852 KDialog::spacingHint() ); 00853 00854 mPipeRules = new QCheckBox( i18n("Check messages using the anti-virus tools"), this ); 00855 QWhatsThis::add( mPipeRules, 00856 i18n( "Let the anti-virus tools check your messages. The wizard " 00857 "will create appropriate filters. The messages are usually " 00858 "marked by the tools so that following filters can react " 00859 "on this and, for example, move virus messages to a special folder.") ); 00860 grid->addWidget( mPipeRules, 0, 0 ); 00861 00862 mMoveRules = new QCheckBox( i18n("Move detected viral messages to the selected folder"), this ); 00863 QWhatsThis::add( mMoveRules, 00864 i18n( "A filter to detect messages classified as virus-infected and to move " 00865 "those messages into a predefined folder is created. The " 00866 "default folder is the trash folder, but you may change that " 00867 "in the folder view.") ); 00868 grid->addWidget( mMoveRules, 1, 0 ); 00869 00870 mMarkRules = new QCheckBox( i18n("Additionally, mark detected viral messages as read"), this ); 00871 mMarkRules->setEnabled( false ); 00872 QWhatsThis::add( mMarkRules, 00873 i18n( "Mark messages which have been classified as " 00874 "virus-infected as read, as well as moving them " 00875 "to the selected folder.") ); 00876 grid->addWidget( mMarkRules, 2, 0 ); 00877 00878 QString s = "trash"; 00879 mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true ); 00880 grid->addWidget( mFolderTree, 3, 0 ); 00881 00882 connect( mPipeRules, SIGNAL(clicked()), 00883 this, SLOT(processSelectionChange(void)) ); 00884 connect( mMoveRules, SIGNAL(clicked()), 00885 this, SLOT(processSelectionChange(void)) ); 00886 connect( mMarkRules, SIGNAL(clicked()), 00887 this, SLOT(processSelectionChange(void)) ); 00888 connect( mMoveRules, SIGNAL( toggled( bool ) ), 00889 mMarkRules, SLOT( setEnabled( bool ) ) ); 00890 } 00891 00892 bool ASWizVirusRulesPage::pipeRulesSelected() const 00893 { 00894 return mPipeRules->isChecked(); 00895 } 00896 00897 00898 bool ASWizVirusRulesPage::moveRulesSelected() const 00899 { 00900 return mMoveRules->isChecked(); 00901 } 00902 00903 bool ASWizVirusRulesPage::markReadRulesSelected() const 00904 { 00905 return mMarkRules->isChecked(); 00906 } 00907 00908 00909 QString ASWizVirusRulesPage::selectedFolderName() const 00910 { 00911 QString name = "trash"; 00912 if ( mFolderTree->folder() ) 00913 name = mFolderTree->folder()->idString(); 00914 return name; 00915 } 00916 00917 void ASWizVirusRulesPage::processSelectionChange() 00918 { 00919 emit selectionChanged(); 00920 } 00921 00922 #include "antispamwizard.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:19:14 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003