kmail

antispamwizard.cpp
1 /*
2  This file is part of KMail.
3  Copyright (c) 2003 Andreas Gungl <a.gungl@gmx.de>
4 
5  KMail is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License, version 2, as
7  published by the Free Software Foundation.
8 
9  KMail is distributed in the hope that it will be useful, but
10  WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 
18  In addition, as a special exception, the copyright holders give
19  permission to link the code of this program with any edition of
20  the TQt library by Trolltech AS, Norway (or with modified versions
21  of TQt that use the same license as TQt), and distribute linked
22  combinations including the two. You must obey the GNU General
23  Public License in all respects for all of the code used other than
24  TQt. If you modify this file, you may extend this exception to
25  your version of the file, but you are not obligated to do so. If
26  you do not wish to do so, delete this exception statement from
27  your version.
28 */
29 
30 #include "antispamwizard.h"
31 #include "kcursorsaver.h"
32 #include "accountmanager.h"
33 #include "kmfilter.h"
34 #include "kmfilteraction.h"
35 #include "kmfiltermgr.h"
36 #include "kmkernel.h"
37 #include "kmfoldertree.h"
38 #include "kmmainwin.h"
39 #include "networkaccount.h"
40 #include "folderrequester.h"
41 
42 #include <tdeaction.h>
43 #include <tdeapplication.h>
44 #include <kdebug.h>
45 #include <kdialog.h>
46 #include <kiconloader.h>
47 #include <tdelocale.h>
48 #include <tdemessagebox.h>
49 #include <tdeprocess.h>
50 
51 #include <tqdom.h>
52 #include <tqlabel.h>
53 #include <tqlayout.h>
54 #include <tqtooltip.h>
55 #include <tqwhatsthis.h>
56 
57 using namespace KMail;
58 
60  TQWidget* parent, KMFolderTree * mainFolderTree )
61  : KWizard( parent ),
62  mInfoPage( 0 ),
63  mSpamRulesPage( 0 ),
64  mVirusRulesPage( 0 ),
65  mSummaryPage( 0 ),
66  mMode( mode )
67 {
68  // read the configuration for the anti-spam tools
69  ConfigReader reader( mMode, mToolList );
70  reader.readAndMergeConfig();
71  mToolList = reader.getToolList();
72 
73 #ifndef NDEBUG
74  if ( mMode == AntiSpam )
75  kdDebug(5006) << endl << "Considered anti-spam tools: " << endl;
76  else
77  kdDebug(5006) << endl << "Considered anti-virus tools: " << endl;
78 #endif
79  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
80  it != mToolList.end(); ++it ) {
81 #ifndef NDEBUG
82  kdDebug(5006) << "Predefined tool: " << (*it).getId() << endl;
83  kdDebug(5006) << "Config version: " << (*it).getVersion() << endl;
84  kdDebug(5006) << "Selection priority: " << (*it).getPrio() << endl;
85  kdDebug(5006) << "Displayed name: " << (*it).getVisibleName() << endl;
86  kdDebug(5006) << "Executable: " << (*it).getExecutable() << endl;
87  kdDebug(5006) << "WhatsThis URL: " << (*it).getWhatsThisText() << endl;
88  kdDebug(5006) << "Filter name: " << (*it).getFilterName() << endl;
89  kdDebug(5006) << "Detection command: " << (*it).getDetectCmd() << endl;
90  kdDebug(5006) << "Learn spam command: " << (*it).getSpamCmd() << endl;
91  kdDebug(5006) << "Learn ham command: " << (*it).getHamCmd() << endl;
92  kdDebug(5006) << "Detection header: " << (*it).getDetectionHeader() << endl;
93  kdDebug(5006) << "Detection pattern: " << (*it).getDetectionPattern() << endl;
94  kdDebug(5006) << "Use as RegExp: " << (*it).isUseRegExp() << endl;
95  kdDebug(5006) << "Supports Bayes Filter: " << (*it).useBayesFilter() << endl;
96  kdDebug(5006) << "Type: " << (*it).getType() << endl << endl;
97 #endif
98  }
99 
100  setCaption( ( mMode == AntiSpam ) ? i18n( "Anti-Spam Wizard" )
101  : i18n( "Anti-Virus Wizard" ) );
102  mInfoPage = new ASWizInfoPage( mMode, 0, "" );
103  addPage( mInfoPage,
104  ( mMode == AntiSpam )
105  ? i18n( "Welcome to the KMail Anti-Spam Wizard" )
106  : i18n( "Welcome to the KMail Anti-Virus Wizard" ) );
107  connect( mInfoPage, TQ_SIGNAL( selectionChanged( void ) ),
108  this, TQ_SLOT( checkProgramsSelections( void ) ) );
109 
110  if ( mMode == AntiSpam ) {
111  mSpamRulesPage = new ASWizSpamRulesPage( 0, "", mainFolderTree );
112  addPage( mSpamRulesPage, i18n( "Options to fine-tune the handling of spam messages" ));
113  connect( mSpamRulesPage, TQ_SIGNAL( selectionChanged( void ) ),
114  this, TQ_SLOT( slotBuildSummary( void ) ) );
115  }
116  else {
117  mVirusRulesPage = new ASWizVirusRulesPage( 0, "", mainFolderTree );
118  addPage( mVirusRulesPage, i18n( "Options to fine-tune the handling of virus messages" ));
119  connect( mVirusRulesPage, TQ_SIGNAL( selectionChanged( void ) ),
120  this, TQ_SLOT( checkVirusRulesSelections( void ) ) );
121  }
122 
123  connect( this, TQ_SIGNAL( helpClicked( void) ),
124  this, TQ_SLOT( slotHelpClicked( void ) ) );
125 
126  setNextEnabled( mInfoPage, false );
127 
128  if ( mMode == AntiSpam ) {
129  mSummaryPage = new ASWizSummaryPage( 0, "" );
130  addPage( mSummaryPage, i18n( "Summary of changes to be made by this wizard" ) );
131  setNextEnabled( mSpamRulesPage, true );
132  setFinishEnabled( mSummaryPage, true );
133  }
134 
135  TQTimer::singleShot( 0, this, TQ_SLOT( checkToolAvailability( void ) ) );
136 }
137 
138 
140 {
141  if ( mSpamRulesPage ) {
142  kdDebug( 5006 ) << "Folder name for messages classified as spam is "
143  << mSpamRulesPage->selectedSpamFolderName() << endl;
144  kdDebug( 5006 ) << "Folder name for messages classified as unsure is "
145  << mSpamRulesPage->selectedUnsureFolderName() << endl;
146  }
147  if ( mVirusRulesPage )
148  kdDebug( 5006 ) << "Folder name for viruses is "
149  << mVirusRulesPage->selectedFolderName() << endl;
150 
151  KMFilterActionDict dict;
152  TQValueList<KMFilter*> filterList;
153  bool replaceExistingFilters = false;
154 
155  // Let's start with virus detection and handling,
156  // so we can avoid spam checks for viral messages
157  if ( mMode == AntiVirus ) {
158  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
159  it != mToolList.end(); ++it ) {
160  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
161  ( mVirusRulesPage->pipeRulesSelected() && (*it).isVirusTool() ) )
162  {
163  // pipe messages through the anti-virus tools,
164  // one single filter for each tool
165  // (could get combined but so it's easier to understand for the user)
166  KMFilter* pipeFilter = new KMFilter();
167  TQPtrList<KMFilterAction>* pipeFilterActions = pipeFilter->actions();
168  KMFilterAction* pipeFilterAction = dict["filter app"]->create();
169  pipeFilterAction->argsFromString( (*it).getDetectCmd() );
170  pipeFilterActions->append( pipeFilterAction );
171  KMSearchPattern* pipeFilterPattern = pipeFilter->pattern();
172  pipeFilterPattern->setName( uniqueNameFor( (*it).getFilterName() ) );
173  pipeFilterPattern->append( KMSearchRule::createInstance( "<size>",
174  KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
175  pipeFilter->setApplyOnOutbound( false);
176  pipeFilter->setApplyOnInbound();
177  pipeFilter->setApplyOnExplicit();
178  pipeFilter->setStopProcessingHere( false );
179  pipeFilter->setConfigureShortcut( false );
180 
181  filterList.append( pipeFilter );
182  }
183  }
184 
185  if ( mVirusRulesPage->moveRulesSelected() )
186  {
187  // Sort out viruses depending on header fields set by the tools
188  KMFilter* virusFilter = new KMFilter();
189  TQPtrList<KMFilterAction>* virusFilterActions = virusFilter->actions();
190  KMFilterAction* virusFilterAction1 = dict["transfer"]->create();
191  virusFilterAction1->argsFromString( mVirusRulesPage->selectedFolderName() );
192  virusFilterActions->append( virusFilterAction1 );
193  if ( mVirusRulesPage->markReadRulesSelected() ) {
194  KMFilterAction* virusFilterAction2 = dict["set status"]->create();
195  virusFilterAction2->argsFromString( "R" ); // Read
196  virusFilterActions->append( virusFilterAction2 );
197  }
198  KMSearchPattern* virusFilterPattern = virusFilter->pattern();
199  virusFilterPattern->setName( uniqueNameFor( i18n( "Virus handling" ) ) );
200  virusFilterPattern->setOp( KMSearchPattern::OpOr );
201  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
202  it != mToolList.end(); ++it ) {
203  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ))
204  {
205  if ( (*it).isVirusTool() )
206  {
207  const TQCString header = (*it).getDetectionHeader().ascii();
208  const TQString & pattern = (*it).getDetectionPattern();
209  if ( (*it).isUseRegExp() )
210  virusFilterPattern->append(
212  KMSearchRule::FuncRegExp, pattern ) );
213  else
214  virusFilterPattern->append(
216  KMSearchRule::FuncContains, pattern ) );
217  }
218  }
219  }
220  virusFilter->setApplyOnOutbound( false);
221  virusFilter->setApplyOnInbound();
222  virusFilter->setApplyOnExplicit();
223  virusFilter->setStopProcessingHere( true );
224  virusFilter->setConfigureShortcut( false );
225 
226  filterList.append( virusFilter );
227  }
228  }
229  else { // AntiSpam mode
230  // TODO Existing filters with same name are replaced. This is hardcoded
231  // ATM and needs to be replaced with a value from a (still missing)
232  // checkbox in the GUI. At least, the replacement is announced in the GUI.
233  replaceExistingFilters = true;
234  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
235  it != mToolList.end(); ++it ) {
236  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
237  (*it).isSpamTool() && !(*it).isDetectionOnly() )
238  {
239  // pipe messages through the anti-spam tools,
240  // one single filter for each tool
241  // (could get combined but so it's easier to understand for the user)
242  KMFilter* pipeFilter = new KMFilter();
243  TQPtrList<KMFilterAction>* pipeFilterActions = pipeFilter->actions();
244  KMFilterAction* pipeFilterAction = dict["filter app"]->create();
245  pipeFilterAction->argsFromString( (*it).getDetectCmd() );
246  pipeFilterActions->append( pipeFilterAction );
247  KMSearchPattern* pipeFilterPattern = pipeFilter->pattern();
248  if ( replaceExistingFilters )
249  pipeFilterPattern->setName( (*it).getFilterName() );
250  else
251  pipeFilterPattern->setName( uniqueNameFor( (*it).getFilterName() ) );
252  pipeFilterPattern->append( KMSearchRule::createInstance( "<size>",
253  KMSearchRule::FuncIsLessOrEqual, "256000" ) );
254  pipeFilter->setApplyOnOutbound( false);
255  pipeFilter->setApplyOnInbound();
256  pipeFilter->setApplyOnExplicit();
257  pipeFilter->setStopProcessingHere( false );
258  pipeFilter->setConfigureShortcut( false );
259 
260  filterList.append( pipeFilter );
261  }
262  }
263 
264  // Sort out spam depending on header fields set by the tools
265  KMFilter* spamFilter = new KMFilter();
266  TQPtrList<KMFilterAction>* spamFilterActions = spamFilter->actions();
267  if ( mSpamRulesPage->moveSpamSelected() )
268  {
269  KMFilterAction* spamFilterAction1 = dict["transfer"]->create();
270  spamFilterAction1->argsFromString( mSpamRulesPage->selectedSpamFolderName() );
271  spamFilterActions->append( spamFilterAction1 );
272  }
273  KMFilterAction* spamFilterAction2 = dict["set status"]->create();
274  spamFilterAction2->argsFromString( "P" ); // Spam
275  spamFilterActions->append( spamFilterAction2 );
276  if ( mSpamRulesPage->markAsReadSelected() ) {
277  KMFilterAction* spamFilterAction3 = dict["set status"]->create();
278  spamFilterAction3->argsFromString( "R" ); // Read
279  spamFilterActions->append( spamFilterAction3 );
280  }
281  KMSearchPattern* spamFilterPattern = spamFilter->pattern();
282  if ( replaceExistingFilters )
283  spamFilterPattern->setName( i18n( "Spam handling" ) );
284  else
285  spamFilterPattern->setName( uniqueNameFor( i18n( "Spam handling" ) ) );
286  spamFilterPattern->setOp( KMSearchPattern::OpOr );
287  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
288  it != mToolList.end(); ++it ) {
289  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
290  {
291  if ( (*it).isSpamTool() )
292  {
293  const TQCString header = (*it).getDetectionHeader().ascii();
294  const TQString & pattern = (*it).getDetectionPattern();
295  if ( (*it).isUseRegExp() )
296  spamFilterPattern->append(
298  KMSearchRule::FuncRegExp, pattern ) );
299  else
300  spamFilterPattern->append(
302  KMSearchRule::FuncContains, pattern ) );
303  }
304  }
305  }
306  spamFilter->setApplyOnOutbound( false);
307  spamFilter->setApplyOnInbound();
308  spamFilter->setApplyOnExplicit();
309  spamFilter->setStopProcessingHere( true );
310  spamFilter->setConfigureShortcut( false );
311  filterList.append( spamFilter );
312 
313  if ( mSpamRulesPage->moveUnsureSelected() )
314  {
315  // Sort out messages classified as unsure
316  bool atLeastOneUnsurePattern = false;
317  KMFilter* unsureFilter = new KMFilter();
318  TQPtrList<KMFilterAction>* unsureFilterActions = unsureFilter->actions();
319  KMFilterAction* unsureFilterAction1 = dict["transfer"]->create();
320  unsureFilterAction1->argsFromString( mSpamRulesPage->selectedUnsureFolderName() );
321  unsureFilterActions->append( unsureFilterAction1 );
322  KMSearchPattern* unsureFilterPattern = unsureFilter->pattern();
323  if ( replaceExistingFilters )
324  unsureFilterPattern->setName( i18n( "Semi spam (unsure) handling" ) );
325  else
326  unsureFilterPattern->setName( uniqueNameFor( i18n( "Semi spam (unsure) handling" ) ) );
327  unsureFilterPattern->setOp( KMSearchPattern::OpOr );
328  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
329  it != mToolList.end(); ++it ) {
330  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
331  {
332  if ( (*it).isSpamTool() && (*it).hasTristateDetection())
333  {
334  atLeastOneUnsurePattern = true;
335  const TQCString header = (*it).getDetectionHeader().ascii();
336  const TQString & pattern = (*it).getDetectionPattern2();
337  if ( (*it).isUseRegExp() )
338  unsureFilterPattern->append(
340  KMSearchRule::FuncRegExp, pattern ) );
341  else
342  unsureFilterPattern->append(
344  KMSearchRule::FuncContains, pattern ) );
345  }
346  }
347  }
348  unsureFilter->setApplyOnOutbound( false);
349  unsureFilter->setApplyOnInbound();
350  unsureFilter->setApplyOnExplicit();
351  unsureFilter->setStopProcessingHere( true );
352  unsureFilter->setConfigureShortcut( false );
353 
354  if ( atLeastOneUnsurePattern )
355  filterList.append( unsureFilter );
356  else
357  delete unsureFilter;
358  }
359 
360  // Classify messages manually as Spam
361  KMFilter* classSpamFilter = new KMFilter();
362  classSpamFilter->setIcon( "mail_spam" );
363  TQPtrList<KMFilterAction>* classSpamFilterActions = classSpamFilter->actions();
364  KMFilterAction* classSpamFilterActionFirst = dict["set status"]->create();
365  classSpamFilterActionFirst->argsFromString( "P" );
366  classSpamFilterActions->append( classSpamFilterActionFirst );
367  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
368  it != mToolList.end(); ++it ) {
369  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
370  && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
371  {
372  KMFilterAction* classSpamFilterAction = dict["execute"]->create();
373  classSpamFilterAction->argsFromString( (*it).getSpamCmd() );
374  classSpamFilterActions->append( classSpamFilterAction );
375  }
376  }
377  if ( mSpamRulesPage->moveSpamSelected() )
378  {
379  KMFilterAction* classSpamFilterActionLast = dict["transfer"]->create();
380  classSpamFilterActionLast->argsFromString( mSpamRulesPage->selectedSpamFolderName() );
381  classSpamFilterActions->append( classSpamFilterActionLast );
382  }
383 
384  KMSearchPattern* classSpamFilterPattern = classSpamFilter->pattern();
385  if ( replaceExistingFilters )
386  classSpamFilterPattern->setName( i18n( "Classify as spam" ) );
387  else
388  classSpamFilterPattern->setName( uniqueNameFor( i18n( "Classify as spam" ) ) );
389  classSpamFilterPattern->append( KMSearchRule::createInstance( "<size>",
390  KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
391  classSpamFilter->setApplyOnOutbound( false);
392  classSpamFilter->setApplyOnInbound( false );
393  classSpamFilter->setApplyOnExplicit( false );
394  classSpamFilter->setStopProcessingHere( true );
395  classSpamFilter->setConfigureShortcut( true );
396  classSpamFilter->setConfigureToolbar( true );
397  filterList.append( classSpamFilter );
398 
399  // Classify messages manually as not Spam / as Ham
400  KMFilter* classHamFilter = new KMFilter();
401  classHamFilter->setIcon( "mail_ham" );
402  TQPtrList<KMFilterAction>* classHamFilterActions = classHamFilter->actions();
403  KMFilterAction* classHamFilterActionFirst = dict["set status"]->create();
404  classHamFilterActionFirst->argsFromString( "H" );
405  classHamFilterActions->append( classHamFilterActionFirst );
406  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
407  it != mToolList.end(); ++it ) {
408  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
409  && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
410  {
411  KMFilterAction* classHamFilterAction = dict["execute"]->create();
412  classHamFilterAction->argsFromString( (*it).getHamCmd() );
413  classHamFilterActions->append( classHamFilterAction );
414  }
415  }
416  KMSearchPattern* classHamFilterPattern = classHamFilter->pattern();
417  if ( replaceExistingFilters )
418  classHamFilterPattern->setName( i18n( "Classify as NOT spam" ) );
419  else
420  classHamFilterPattern->setName( uniqueNameFor( i18n( "Classify as NOT spam" ) ) );
421  classHamFilterPattern->append( KMSearchRule::createInstance( "<size>",
422  KMSearchRule::FuncIsGreaterOrEqual, "0" ) );
423  classHamFilter->setApplyOnOutbound( false);
424  classHamFilter->setApplyOnInbound( false );
425  classHamFilter->setApplyOnExplicit( false );
426  classHamFilter->setStopProcessingHere( true );
427  classHamFilter->setConfigureShortcut( true );
428  classHamFilter->setConfigureToolbar( true );
429  filterList.append( classHamFilter );
430  }
431 
432  /* Now that all the filters have been added to the list, tell
433  * the filter manager about it. That will emit filterListUpdate
434  * which will result in the filter list in kmmainwidget being
435  * initialized. This should happend only once. */
436  KMKernel::self()->filterMgr()->appendFilters( filterList );
437 
438  /* Now that all the filters have been added to the list, tell
439  * the filter manager about it. That will emit filterListUpdate
440  * which will result in the filter list in kmmainwidget being
441  * initialized. This should happend only once. */
442  if ( !filterList.isEmpty() )
443  KMKernel::self()->filterMgr()->appendFilters(
444  filterList, replaceExistingFilters );
445 
446  TQDialog::accept();
447 }
448 
449 
451 {
452  bool status = false;
453  bool supportUnsure = false;
454 
455  mSpamToolsUsed = false;
456  mVirusToolsUsed = false;
457  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
458  it != mToolList.end(); ++it ) {
459  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
460  {
461  status = true;
462  if ( (*it).isSpamTool() ) {
463  mSpamToolsUsed = true;
464  if ( (*it).hasTristateDetection() )
465  supportUnsure = true;
466  }
467  if ( (*it).isVirusTool() )
468  mVirusToolsUsed = true;
469  }
470  }
471 
472  if ( mMode == AntiSpam ) {
473  mSpamRulesPage->allowUnsureFolderSelection( supportUnsure );
475  }
476 
477  if ( ( mMode == AntiVirus ) && mVirusToolsUsed )
479 
480  setNextEnabled( mInfoPage, status );
481 }
482 
483 
485 {
486  setFinishEnabled( mVirusRulesPage, anyVirusOptionChecked() );
487 }
488 
489 
491 {
492  // this can take some time to find the tools
493  KCursorSaver busy( KBusyPtr::busy() );
494 
495  bool found = false;
496  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
497  it != mToolList.end(); ++it ) {
498  TQString text( i18n("Scanning for %1...").arg( (*it).getId() ) );
499  mInfoPage->setScanProgressText( text );
500  if ( (*it).isSpamTool() && (*it).isServerBased() ) {
501  // check the configured account for pattern in <server>
502  TQString pattern = (*it).getServerPattern();
503  kdDebug(5006) << "Testing for server pattern:" << pattern << endl;
504 
505  AccountManager* mgr = kmkernel->acctMgr();
506  KMAccount* account = mgr->first();
507  while ( account ) {
508  if ( account->type() == "pop" || account->type().contains( "imap" ) ) {
509  const NetworkAccount * n = dynamic_cast<const NetworkAccount*>( account );
510  if ( n && n->host().lower().contains( pattern.lower() ) ) {
511  mInfoPage->addAvailableTool( (*it).getVisibleName() );
512  found = true;
513  }
514  }
515  account = mgr->next();
516  }
517  }
518  else {
519  // check the availability of the application
520  TDEApplication::kApplication()->processEvents( 200 );
521  if ( !checkForProgram( (*it).getExecutable() ) ) {
522  mInfoPage->addAvailableTool( (*it).getVisibleName() );
523  found = true;
524  }
525  }
526  }
527  if ( found )
528  mInfoPage->setScanProgressText( ( mMode == AntiSpam )
529  ? i18n("Scanning for anti-spam tools finished.")
530  : i18n("Scanning for anti-virus tools finished.") );
531  else
532  mInfoPage->setScanProgressText( ( mMode == AntiSpam )
533  ? i18n("<p>No spam detection tools have been found. "
534  "Install your spam detection software and "
535  "re-run this wizard.</p>")
536  : i18n("Scanning complete. No anti-virus tools found.") );
537 }
538 
539 
541 {
542  if ( mMode == AntiSpam )
543  kapp->invokeHelp( "the-anti-spam-wizard", "kmail" );
544  else
545  kapp->invokeHelp( "the-anti-virus-wizard", "kmail" );
546 }
547 
548 
550 {
551  TQString text;
552  TQString newFilters;
553  TQString replaceFilters;
554 
555  if ( mMode == AntiVirus ) {
556  text = ""; // TODO add summary for the virus part
557  }
558  else { // AntiSpam mode
559  if ( mSpamRulesPage->markAsReadSelected() )
560  text = i18n( "<p>Messages classified as spam are marked as read." );
561  else
562  text = i18n( "<p>Messages classified as spam are not marked as read." );
563 
564  if ( mSpamRulesPage->moveSpamSelected() )
565  text += i18n( "<br>Spam messages are moved into the folder named <i>" )
566  + mSpamRulesPage->selectedSpamFolderName() + "</i>.</p>";
567  else
568  text += i18n( "<br>Spam messages are not moved into a certain folder.</p>" );
569 
570  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
571  it != mToolList.end(); ++it ) {
572  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
573  (*it).isSpamTool() && !(*it).isDetectionOnly() ) {
574  sortFilterOnExistance( (*it).getFilterName(), newFilters, replaceFilters );
575  }
576  }
577  sortFilterOnExistance( i18n( "Spam handling" ), newFilters, replaceFilters );
578 
579  // The need for a andling of status "probably spam" depends on the tools chosen
580  if ( mSpamRulesPage->moveUnsureSelected() ) {
581  bool atLeastOneUnsurePattern = false;
582  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
583  it != mToolList.end(); ++it ) {
584  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) ) {
585  if ( (*it).isSpamTool() && (*it).hasTristateDetection())
586  atLeastOneUnsurePattern = true;
587  }
588  }
589  if ( atLeastOneUnsurePattern ) {
590  sortFilterOnExistance( i18n( "Semi spam (unsure) handling" ),
591  newFilters, replaceFilters );
592  text += i18n( "<p>The folder for messages classified as unsure (probably spam) is <i>" )
593  + mSpamRulesPage->selectedUnsureFolderName() + "</i>.</p>";
594  }
595  }
596 
597  // Manual classification via toolbar icon / manually applied filter action
598  sortFilterOnExistance( i18n( "Classify as spam" ),
599  newFilters, replaceFilters );
600  sortFilterOnExistance( i18n( "Classify as NOT spam" ),
601  newFilters, replaceFilters );
602 
603  // Show the filters in the summary
604  if ( !newFilters.isEmpty() )
605  text += i18n( "<p>The wizard will create the following filters:<ul>" )
606  + newFilters + "</ul></p>";
607  if ( !replaceFilters.isEmpty() )
608  text += i18n( "<p>The wizard will replace the following filters:<ul>" )
609  + replaceFilters + "</ul></p>";
610  }
611 
612  mSummaryPage->setSummaryText( text );
613 }
614 
615 
616 int AntiSpamWizard::checkForProgram( const TQString &executable )
617 {
618  kdDebug(5006) << "Testing for executable:" << executable << endl;
619  TDEProcess process;
620  process << executable;
621  process.setUseShell( true );
622  process.start( TDEProcess::Block );
623  return process.exitStatus();
624 }
625 
626 
627 bool AntiSpamWizard::anyVirusOptionChecked()
628 {
629  return ( mVirusRulesPage->moveRulesSelected()
630  || mVirusRulesPage->pipeRulesSelected() );
631 }
632 
633 
634 const TQString AntiSpamWizard::uniqueNameFor( const TQString & name )
635 {
636  return KMKernel::self()->filterMgr()->createUniqueName( name );
637 }
638 
639 
640 void AntiSpamWizard::sortFilterOnExistance(
641  const TQString & intendedFilterName,
642  TQString & newFilters, TQString & replaceFilters )
643 {
644  if ( uniqueNameFor( intendedFilterName ) == intendedFilterName )
645  newFilters += "<li>" + intendedFilterName + "</li>";
646  else
647  replaceFilters += "<li>" + intendedFilterName + "</li>";
648 }
649 
650 
651 //---------------------------------------------------------------------------
652 AntiSpamWizard::SpamToolConfig::SpamToolConfig( TQString toolId,
653  int configVersion, int prio, TQString name, TQString exec,
654  TQString url, TQString filter, TQString detection, TQString spam, TQString ham,
655  TQString header, TQString pattern, TQString pattern2, TQString serverPattern,
656  bool detectionOnly, bool regExp, bool bayesFilter, bool tristateDetection,
657  WizardMode type )
658  : mId( toolId ), mVersion( configVersion ), mPrio( prio ),
659  mVisibleName( name ), mExecutable( exec ), mWhatsThisText( url ),
660  mFilterName( filter ), mDetectCmd( detection ), mSpamCmd( spam ),
661  mHamCmd( ham ), mDetectionHeader( header ), mDetectionPattern( pattern ),
662  mDetectionPattern2( pattern2 ), mServerPattern( serverPattern ),
663  mDetectionOnly( detectionOnly ),
664  mUseRegExp( regExp ), mSupportsBayesFilter( bayesFilter ),
665  mSupportsUnsure( tristateDetection ), mType( type )
666 {
667 }
668 
669 
670 bool AntiSpamWizard::SpamToolConfig::isServerBased() const
671 {
672  return !mServerPattern.isEmpty();
673 }
674 
675 
676 //---------------------------------------------------------------------------
677 AntiSpamWizard::ConfigReader::ConfigReader( WizardMode mode,
678  TQValueList<SpamToolConfig> & configList )
679  : mToolList( configList ),
680  mMode( mode )
681 {
682  if ( mMode == AntiSpam )
683  mConfig = new TDEConfig( "kmail.antispamrc", true );
684  else
685  mConfig = new TDEConfig( "kmail.antivirusrc", true );
686 }
687 
688 AntiSpamWizard::ConfigReader::~ConfigReader( )
689 {
690  delete mConfig;
691 }
692 
693 
694 void AntiSpamWizard::ConfigReader::readAndMergeConfig()
695 {
696  TQString groupName = ( mMode == AntiSpam )
697  ? TQString("Spamtool #%1")
698  : TQString("Virustool #%1");
699  // read the configuration from the global config file
700  mConfig->setReadDefaults( true );
701  TDEConfigGroup general( mConfig, "General" );
702  int registeredTools = general.readNumEntry( "tools", 0 );
703  for (int i = 1; i <= registeredTools; i++)
704  {
705  TDEConfigGroup toolConfig( mConfig, groupName.arg( i ) );
706  if( !toolConfig.readBoolEntry( "HeadersOnly", false ) )
707  mToolList.append( readToolConfig( toolConfig ) );
708  }
709 
710  // read the configuration from the user config file
711  // and merge newer config data
712  mConfig->setReadDefaults( false );
713  TDEConfigGroup user_general( mConfig, "General" );
714  int user_registeredTools = user_general.readNumEntry( "tools", 0 );
715  for (int i = 1; i <= user_registeredTools; i++)
716  {
717  TDEConfigGroup toolConfig( mConfig, groupName.arg( i ) );
718  if( !toolConfig.readBoolEntry( "HeadersOnly", false ) )
719  mergeToolConfig( readToolConfig( toolConfig ) );
720  }
721  // Make sure to have add least one tool listed even when the
722  // config file was not found or whatever went wrong
723  // Currently only works for spam tools
724  if ( mMode == AntiSpam ) {
725  if ( registeredTools < 1 && user_registeredTools < 1 )
726  mToolList.append( createDummyConfig() );
727  sortToolList();
728  }
729 }
730 
731 
733  AntiSpamWizard::ConfigReader::readToolConfig( TDEConfigGroup & configGroup )
734 {
735  TQString id = configGroup.readEntry( "Ident" );
736  int version = configGroup.readNumEntry( "Version" );
737 #ifndef NDEBUG
738  kdDebug(5006) << "Found predefined tool: " << id << endl;
739  kdDebug(5006) << "With config version : " << version << endl;
740 #endif
741  int prio = configGroup.readNumEntry( "Priority", 1 );
742  TQString name = configGroup.readEntry( "VisibleName" );
743  TQString executable = configGroup.readEntry( "Executable" );
744  TQString url = configGroup.readEntry( "URL" );
745  TQString filterName = configGroup.readEntry( "PipeFilterName" );
746  TQString detectCmd = configGroup.readEntry( "PipeCmdDetect" );
747  TQString spamCmd = configGroup.readEntry( "ExecCmdSpam" );
748  TQString hamCmd = configGroup.readEntry( "ExecCmdHam" );
749  TQString header = configGroup.readEntry( "DetectionHeader" );
750  TQString pattern = configGroup.readEntry( "DetectionPattern" );
751  TQString pattern2 = configGroup.readEntry( "DetectionPattern2" );
752  TQString serverPattern = configGroup.readEntry( "ServerPattern" );
753  bool detectionOnly = configGroup.readBoolEntry( "DetectionOnly", false );
754  bool useRegExp = configGroup.readBoolEntry( "UseRegExp" );
755  bool supportsBayes = configGroup.readBoolEntry( "SupportsBayes", false );
756  bool supportsUnsure = configGroup.readBoolEntry( "SupportsUnsure", false );
757  return SpamToolConfig( id, version, prio, name, executable, url,
758  filterName, detectCmd, spamCmd, hamCmd,
759  header, pattern, pattern2, serverPattern,
760  detectionOnly, useRegExp,
761  supportsBayes, supportsUnsure, mMode );
762 }
763 
764 
765 AntiSpamWizard::SpamToolConfig AntiSpamWizard::ConfigReader::createDummyConfig()
766 {
767  return SpamToolConfig( "spamassassin", 0, 1,
768  "SpamAssassin", "spamassassin -V",
769  "http://spamassassin.org", "SpamAssassin Check",
770  "spamassassin -L",
771  "sa-learn -L --spam --no-rebuild --single",
772  "sa-learn -L --ham --no-rebuild --single",
773  "X-Spam-Flag", "yes", "", "",
774  false, false, true, false, AntiSpam );
775 }
776 
777 
778 void AntiSpamWizard::ConfigReader::mergeToolConfig( AntiSpamWizard::SpamToolConfig config )
779 {
780  bool found = false;
781  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
782  it != mToolList.end(); ++it ) {
783 #ifndef NDEBUG
784  kdDebug(5006) << "Check against tool: " << (*it).getId() << endl;
785  kdDebug(5006) << "Against version : " << (*it).getVersion() << endl;
786 #endif
787  if ( (*it).getId() == config.getId() )
788  {
789  found = true;
790  if ( (*it).getVersion() < config.getVersion() )
791  {
792 #ifndef NDEBUG
793  kdDebug(5006) << "Replacing config ..." << endl;
794 #endif
795  mToolList.remove( it );
796  mToolList.append( config );
797  }
798  break;
799  }
800  }
801  if ( !found )
802  mToolList.append( config );
803 }
804 
805 
806 void AntiSpamWizard::ConfigReader::sortToolList()
807 {
808  TQValueList<SpamToolConfig> tmpList;
809  SpamToolConfig config;
810 
811  while ( !mToolList.isEmpty() ) {
812  TQValueListIterator<SpamToolConfig> highest;
813  int priority = 0; // ascending
814  for ( TQValueListIterator<SpamToolConfig> it = mToolList.begin();
815  it != mToolList.end(); ++it ) {
816  if ( (*it).getPrio() > priority ) {
817  priority = (*it).getPrio();
818  highest = it;
819  }
820  }
821  config = (*highest);
822  tmpList.append( config );
823  mToolList.remove( highest );
824  }
825  for ( TQValueListIterator<SpamToolConfig> it = tmpList.begin();
826  it != tmpList.end(); ++it ) {
827  mToolList.append( (*it) );
828  }
829 }
830 
831 
832 //---------------------------------------------------------------------------
833 ASWizPage::ASWizPage( TQWidget * parent, const char * name,
834  const TQString *bannerName )
835  : TQWidget( parent, name )
836 {
837  TQString banner = "kmwizard.png";
838  if ( bannerName && !bannerName->isEmpty() )
839  banner = *bannerName;
840 
841  mLayout = new TQHBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
842  mBannerLabel = new TQLabel( this );
843  mBannerLabel->setPixmap( UserIcon(banner) );
844  mBannerLabel->setScaledContents( false );
845  mBannerLabel->setFrameShape( TQFrame::StyledPanel );
846  mBannerLabel->setFrameShadow( TQFrame::Sunken );
847 
848  mLayout->addWidget( mBannerLabel );
849  mLayout->addItem( new TQSpacerItem( 5, 5, TQSizePolicy::Minimum, TQSizePolicy::Expanding ) );
850 }
851 
852 
853 //---------------------------------------------------------------------------
854 ASWizInfoPage::ASWizInfoPage( AntiSpamWizard::WizardMode mode,
855  TQWidget * parent, const char * name )
856  : ASWizPage( parent, name )
857 {
858  TQBoxLayout * layout = new TQVBoxLayout( mLayout );
859 
860  mIntroText = new TQLabel( this );
861  mIntroText->setText(
862  ( mode == AntiSpamWizard::AntiSpam )
863  ? i18n(
864  "The wizard will search for any tools to do spam detection\n"
865  "and setup KMail to work with them."
866  )
867  : i18n(
868  "<p>Here you can get some assistance in setting up KMail's filter "
869  "rules to use some commonly-known anti-virus tools.</p>"
870  "<p>The wizard can detect those tools on your computer as "
871  "well as create filter rules to classify messages using these "
872  "tools and to separate messages containing viruses. "
873  "The wizard will not take any existing filter "
874  "rules into consideration: it will always append the new rules.</p>"
875  "<p><b>Warning:</b> As KMail appears to be frozen during the scan of the "
876  "messages for viruses, you may encounter problems with "
877  "the responsiveness of KMail because anti-virus tool "
878  "operations are usually time consuming; please consider "
879  "deleting the filter rules created by the wizard to get "
880  "back to the former behavior."
881  ) );
882  layout->addWidget( mIntroText );
883 
884  mScanProgressText = new TQLabel( this );
885  mScanProgressText->setText( "" ) ;
886  layout->addWidget( mScanProgressText );
887 
888  mToolsList = new TDEListBox( this );
889  mToolsList->hide();
890  mToolsList->setSelectionMode( TQListBox::Multi );
891  mToolsList->setRowMode( TQListBox::FixedNumber );
892  mToolsList->setRowMode( 10 );
893  layout->addWidget( mToolsList );
894  connect( mToolsList, TQ_SIGNAL(selectionChanged()),
895  this, TQ_SLOT(processSelectionChange(void)) );
896 
897  mSelectionHint = new TQLabel( this );
898  mSelectionHint->setText( "" );
899  layout->addWidget( mSelectionHint );
900 
901  layout->addStretch();
902 }
903 
904 
905 void ASWizInfoPage::setScanProgressText( const TQString &toolName )
906 {
907  mScanProgressText->setText( toolName );
908 }
909 
910 
911 void ASWizInfoPage::addAvailableTool( const TQString &visibleName )
912 {
913  TQString listName = visibleName;
914  mToolsList->insertItem( listName );
915  if ( !mToolsList->isVisible() )
916  {
917  mToolsList->show();
918  mToolsList->setSelected( 0, true );
919  mSelectionHint->setText( i18n("<p>Please select the tools to be used "
920  "for the detection and go "
921  "to the next page.</p>") );
922  }
923 }
924 
925 bool ASWizInfoPage::isProgramSelected( const TQString &visibleName )
926 {
927  TQString listName = visibleName;
928  return mToolsList->isSelected( mToolsList->findItem( listName ) );
929 }
930 
931 
932 void ASWizInfoPage::processSelectionChange()
933 {
934  emit selectionChanged();
935 }
936 
937 
938 //---------------------------------------------------------------------------
939 ASWizSpamRulesPage::ASWizSpamRulesPage( TQWidget * parent, const char * name,
940  KMFolderTree * mainFolderTree )
941  : ASWizPage( parent, name )
942 {
943  TQVBoxLayout *layout = new TQVBoxLayout( mLayout );
944 
945  mMarkRules = new TQCheckBox( i18n("&Mark detected spam messages as read"), this );
946  TQWhatsThis::add( mMarkRules,
947  i18n( "Mark messages which have been classified as spam as read.") );
948  layout->addWidget( mMarkRules);
949 
950  mMoveSpamRules = new TQCheckBox( i18n("Move &known spam to:"), this );
951  TQWhatsThis::add( mMoveSpamRules,
952  i18n( "The default folder for spam messages is the trash folder, "
953  "but you may change that in the folder view below.") );
954  layout->addWidget( mMoveSpamRules );
955 
956  mFolderReqForSpamFolder = new FolderRequester( this, mainFolderTree );
957  mFolderReqForSpamFolder->setFolder( "trash" );
958  mFolderReqForSpamFolder->setMustBeReadWrite( true );
959  mFolderReqForSpamFolder->setShowOutbox( false );
960  mFolderReqForSpamFolder->setShowImapFolders( false );
961 
962  TQHBoxLayout *hLayout1 = new TQHBoxLayout( layout );
963  hLayout1->addSpacing( KDialog::spacingHint() * 3 );
964  hLayout1->addWidget( mFolderReqForSpamFolder );
965 
966  mMoveUnsureRules = new TQCheckBox( i18n("Move &probable spam to:"), this );
967  TQWhatsThis::add( mMoveUnsureRules,
968  i18n( "The default folder is the inbox folder, but you may change that "
969  "in the folder view below.<p>"
970  "Not all tools support a classification as unsure. If you haven't "
971  "selected a capable tool, you can't select a folder as well.") );
972  layout->addWidget( mMoveUnsureRules );
973 
974  mFolderReqForUnsureFolder = new FolderRequester( this, mainFolderTree );
975  mFolderReqForUnsureFolder->setFolder( "inbox" );
976  mFolderReqForUnsureFolder->setMustBeReadWrite( true );
977  mFolderReqForUnsureFolder->setShowOutbox( false );
978  mFolderReqForUnsureFolder->setShowImapFolders( false );
979 
980  TQHBoxLayout *hLayout2 = new TQHBoxLayout( layout );
981  hLayout2->addSpacing( KDialog::spacingHint() * 3 );
982  hLayout2->addWidget( mFolderReqForUnsureFolder );
983 
984  layout->addStretch();
985 
986  connect( mMarkRules, TQ_SIGNAL(clicked()),
987  this, TQ_SLOT(processSelectionChange(void)) );
988  connect( mMoveSpamRules, TQ_SIGNAL(clicked()),
989  this, TQ_SLOT(processSelectionChange(void)) );
990  connect( mMoveUnsureRules, TQ_SIGNAL(clicked()),
991  this, TQ_SLOT(processSelectionChange(void)) );
992  connect( mFolderReqForSpamFolder, TQ_SIGNAL(folderChanged(KMFolder*)),
993  this, TQ_SLOT(processSelectionChange(KMFolder*)) );
994  connect( mFolderReqForUnsureFolder, TQ_SIGNAL(folderChanged(KMFolder*)),
995  this, TQ_SLOT(processSelectionChange(KMFolder*)) );
996 
997  mMarkRules->setChecked( true );
998  mMoveSpamRules->setChecked( true );
999 }
1000 
1001 
1002 bool ASWizSpamRulesPage::markAsReadSelected() const
1003 {
1004  return mMarkRules->isChecked();
1005 }
1006 
1007 
1008 bool ASWizSpamRulesPage::moveSpamSelected() const
1009 {
1010  return mMoveSpamRules->isChecked();
1011 }
1012 
1013 
1014 bool ASWizSpamRulesPage::moveUnsureSelected() const
1015 {
1016  return mMoveUnsureRules->isChecked();
1017 }
1018 
1019 
1020 TQString ASWizSpamRulesPage::selectedSpamFolderName() const
1021 {
1022  TQString name = "trash";
1023  if ( mFolderReqForSpamFolder->folder() )
1024  name = mFolderReqForSpamFolder->folder()->idString();
1025  return name;
1026 }
1027 
1028 
1029 TQString ASWizSpamRulesPage::selectedUnsureFolderName() const
1030 {
1031  TQString name = "inbox";
1032  if ( mFolderReqForUnsureFolder->folder() )
1033  name = mFolderReqForUnsureFolder->folder()->idString();
1034  return name;
1035 }
1036 
1037 
1038 void ASWizSpamRulesPage::processSelectionChange()
1039 {
1040  mFolderReqForSpamFolder->setEnabled( mMoveSpamRules->isChecked() );
1041  mFolderReqForUnsureFolder->setEnabled( mMoveUnsureRules->isChecked() );
1042  emit selectionChanged();
1043 }
1044 
1045 
1046 void ASWizSpamRulesPage::processSelectionChange( KMFolder* )
1047 {
1048  processSelectionChange();
1049 }
1050 
1051 
1052 void ASWizSpamRulesPage::allowUnsureFolderSelection( bool enabled )
1053 {
1054  mMoveUnsureRules->setEnabled( enabled );
1055  mMoveUnsureRules->setShown( enabled );
1056  mFolderReqForUnsureFolder->setEnabled( enabled );
1057  mFolderReqForUnsureFolder->setShown( enabled );
1058 }
1059 
1060 
1061 //---------------------------------------------------------------------------
1062 ASWizVirusRulesPage::ASWizVirusRulesPage( TQWidget * parent, const char * name,
1063  KMFolderTree * mainFolderTree )
1064  : ASWizPage( parent, name )
1065 {
1066  TQGridLayout *grid = new TQGridLayout( mLayout, 5, 1, KDialog::spacingHint() );
1067 
1068  mPipeRules = new TQCheckBox( i18n("Check messages using the anti-virus tools"), this );
1069  TQWhatsThis::add( mPipeRules,
1070  i18n( "Let the anti-virus tools check your messages. The wizard "
1071  "will create appropriate filters. The messages are usually "
1072  "marked by the tools so that following filters can react "
1073  "on this and, for example, move virus messages to a special folder.") );
1074  grid->addWidget( mPipeRules, 0, 0 );
1075 
1076  mMoveRules = new TQCheckBox( i18n("Move detected viral messages to the selected folder"), this );
1077  TQWhatsThis::add( mMoveRules,
1078  i18n( "A filter to detect messages classified as virus-infected and to move "
1079  "those messages into a predefined folder is created. The "
1080  "default folder is the trash folder, but you may change that "
1081  "in the folder view.") );
1082  grid->addWidget( mMoveRules, 1, 0 );
1083 
1084  mMarkRules = new TQCheckBox( i18n("Additionally, mark detected viral messages as read"), this );
1085  mMarkRules->setEnabled( false );
1086  TQWhatsThis::add( mMarkRules,
1087  i18n( "Mark messages which have been classified as "
1088  "virus-infected as read, as well as moving them "
1089  "to the selected folder.") );
1090  grid->addWidget( mMarkRules, 2, 0 );
1091 
1092  TQString s = "trash";
1093  mFolderTree = new SimpleFolderTree( this, mainFolderTree, s, true );
1094  grid->addWidget( mFolderTree, 3, 0 );
1095 
1096  connect( mPipeRules, TQ_SIGNAL(clicked()),
1097  this, TQ_SLOT(processSelectionChange(void)) );
1098  connect( mMoveRules, TQ_SIGNAL(clicked()),
1099  this, TQ_SLOT(processSelectionChange(void)) );
1100  connect( mMarkRules, TQ_SIGNAL(clicked()),
1101  this, TQ_SLOT(processSelectionChange(void)) );
1102  connect( mMoveRules, TQ_SIGNAL( toggled( bool ) ),
1103  mMarkRules, TQ_SLOT( setEnabled( bool ) ) );
1104 }
1105 
1106 bool ASWizVirusRulesPage::pipeRulesSelected() const
1107 {
1108  return mPipeRules->isChecked();
1109 }
1110 
1111 
1112 bool ASWizVirusRulesPage::moveRulesSelected() const
1113 {
1114  return mMoveRules->isChecked();
1115 }
1116 
1117 bool ASWizVirusRulesPage::markReadRulesSelected() const
1118 {
1119  return mMarkRules->isChecked();
1120 }
1121 
1122 
1123 TQString ASWizVirusRulesPage::selectedFolderName() const
1124 {
1125  TQString name = "trash";
1126  if ( mFolderTree->folder() )
1127  name = mFolderTree->folder()->idString();
1128  return name;
1129 }
1130 
1131 void ASWizVirusRulesPage::processSelectionChange()
1132 {
1133  emit selectionChanged();
1134 }
1135 
1136 
1137 //---------------------------------------------------------------------------
1138 ASWizSummaryPage::ASWizSummaryPage( TQWidget * parent, const char * name )
1139  : ASWizPage( parent, name )
1140 {
1141  TQBoxLayout * layout = new TQVBoxLayout( mLayout );
1142 
1143  mSummaryText = new TQLabel( this );
1144  layout->addWidget( mSummaryText );
1145  layout->addStretch();
1146 }
1147 
1148 
1149 void ASWizSummaryPage::setSummaryText( const TQString & text )
1150 {
1151  mSummaryText->setText( text );
1152 }
1153 
1154 
1155 #include "antispamwizard.moc"
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
Definition: kcursorsaver.h:14
Dictionary that contains a list of all registered filter actions with their creation functions.
Abstract base class for KMail's filter actions.
virtual void argsFromString(const TQString argsStr)=0
Read extra arguments from given string.
Mail folder.
Definition: kmfolder.h:69
static KMKernel * self()
normal control stuff
Definition: kmkernel.h:259
This class is an abstraction of a search over messages.
void setOp(KMSearchPattern::Operator aOp)
Set the filter operator.
void setName(const TQString &newName)
Set the name of the search pattern.
static KMSearchRule * createInstance(const TQCString &field=0, Function function=FuncContains, const TQString &contents=TQString())
Create a search rule of a certain type by instantiating the appro- priate subclass depending on the f...
The account manager is responsible for creating accounts of various types via the factory method crea...
const KMAccount * first() const
First account of the list.
const KMAccount * next() const
Next account of the list.
Instances of this class control reading the configuration of the anti-spam tools from global and user...
Instances of this class store the settings for one tool as read from the config file.
void slotBuildSummary()
Create the summary text based on the current settings.
void checkToolAvailability()
Check if the spam tools are available via the PATH.
void checkProgramsSelections()
Modify the status of the wizard to reflect the selection of spam tools.
AntiSpamWizard(WizardMode mode, TQWidget *parent, KMFolderTree *mainFolderTree)
Constructor that needs to initialize from the main folder tree of KMail.
WizardMode
The wizard can be used for setting up anti-spam tools and for setting up anti-virus tools.
void checkVirusRulesSelections()
Modify the status of the wizard to reflect the selected functionality.
void slotHelpClicked()
Show a help topic.
void accept()
Evaluate the settings made and create the appropriate filter rules.
A widget that contains a KLineEdit which shows the current folder and a button that fires a KMFolderS...
folderdiaquotatab.h
Definition: aboutdata.cpp:40