• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kmail

  • sources
  • kde-4.14
  • kdepim
  • kmail
  • antispam-virus
antispamwizard.cpp
Go to the documentation of this file.
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 Qt library by Trolltech AS, Norway (or with modified versions
21  of Qt that use the same license as Qt), 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  Qt. 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 
31 #include "antispamwizard.h"
32 #ifndef QT_NO_CURSOR
33 #include "messageviewer/utils/kcursorsaver.h"
34 #endif
35 #include "kmkernel.h"
36 #include "kmmainwin.h"
37 #include "folderrequester.h"
38 #include "foldertreewidget.h"
39 #include "foldertreeview.h"
40 #include "foldertreewidgetproxymodel.h"
41 #include "mailcommon/pop3settings.h"
42 #include "mailcommon/util/mailutil.h"
43 #include "pimcommon/imapresourcesettings.h"
44 #include "mailcommon/kernel/mailkernel.h"
45 #include "mailcommon/filter/mailfilter.h"
46 #include "mailcommon/filter/filteractions/filteraction.h"
47 #include "mailcommon/filter/filteractions/filteractiondict.h"
48 #include "mailcommon/filter/filtermanager.h"
49 
50 #include "pimcommon/util/pimutil.h"
51 
52 #include <Akonadi/AgentInstance>
53 
54 #include <kdebug.h>
55 #include <kdialog.h>
56 #include <kiconloader.h>
57 #include <klocale.h>
58 #include <KProcess>
59 #include <ktoolinvocation.h>
60 #include <kconfiggroup.h>
61 
62 #include <QLabel>
63 #include <QTextEdit>
64 #include <QTimer>
65 #include <QGridLayout>
66 #include <QHBoxLayout>
67 #include <QBoxLayout>
68 #include <QVBoxLayout>
69 #include <QCheckBox>
70 #include <QListWidget>
71 
72 using namespace KMail;
73 using namespace MailCommon;
74 
75 AntiSpamWizard::AntiSpamWizard( WizardMode mode,
76  QWidget* parent )
77  : KAssistantDialog( parent ),
78  mInfoPage( 0 ),
79  mSpamRulesPage( 0 ),
80  mVirusRulesPage( 0 ),
81  mSummaryPage( 0 ),
82  mMode( mode )
83 {
84  // read the configuration for the anti-spam tools
85  ConfigReader reader( mMode, mToolList );
86  reader.readAndMergeConfig();
87  mToolList = reader.getToolList();
88 
89 #ifndef NDEBUG
90  if ( mMode == AntiSpam )
91  kDebug() << endl <<"Considered anti-spam tools:";
92  else
93  kDebug() << endl <<"Considered anti-virus tools:";
94  QList<SpamToolConfig>::ConstIterator end( mToolList.constEnd() );
95  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
96  it != end; ++it ) {
97  kDebug() << "Predefined tool:" << (*it).getId();
98  kDebug() << "Config version:" << (*it).getVersion();
99  kDebug() << "Selection priority:" << (*it).getPrio();
100  kDebug() << "Displayed name:" << (*it).getVisibleName();
101  kDebug() << "Executable:" << (*it).getExecutable();
102  kDebug() << "WhatsThis URL:" << (*it).getWhatsThisText();
103  kDebug() << "Filter name:" << (*it).getFilterName();
104  kDebug() << "Detection command:" << (*it).getDetectCmd();
105  kDebug() << "Learn spam command:" << (*it).getSpamCmd();
106  kDebug() << "Learn ham command:" << (*it).getHamCmd();
107  kDebug() << "Detection header:" << (*it).getDetectionHeader();
108  kDebug() << "Detection pattern:" << (*it).getDetectionPattern();
109  kDebug() << "Use as RegExp:" << (*it).isUseRegExp();
110  kDebug() << "Supports Bayes Filter:" << (*it).useBayesFilter();
111  kDebug() << "Type:" << (*it).getType();
112  }
113 #endif
114 
115  const bool isAntiSpam = (mMode == AntiSpam);
116  setWindowTitle( isAntiSpam ? i18n( "Anti-Spam Wizard" )
117  : i18n( "Anti-Virus Wizard" ) );
118  mInfoPage = new ASWizInfoPage( mMode, 0, QString() );
119  mInfoPageItem = addPage( mInfoPage,
120  isAntiSpam
121  ? i18n( "Welcome to the KMail Anti-Spam Wizard" )
122  : i18n( "Welcome to the KMail Anti-Virus Wizard" ) );
123  connect( mInfoPage, SIGNAL(selectionChanged()),
124  this, SLOT(checkProgramsSelections()) );
125 
126  if ( isAntiSpam ) {
127  mSpamRulesPage = new ASWizSpamRulesPage( 0, QString() );
128  mSpamRulesPageItem = addPage( mSpamRulesPage, i18n( "Options to fine-tune the handling of spam messages" ));
129  connect( mSpamRulesPage, SIGNAL(selectionChanged()),
130  this, SLOT(slotBuildSummary()) );
131 
132  mSummaryPage = new ASWizSummaryPage( 0, QString() );
133  mSummaryPageItem = addPage( mSummaryPage, i18n( "Summary of changes to be made by this wizard" ) );
134  } else {
135  mVirusRulesPage = new ASWizVirusRulesPage( 0, QString() );
136  mVirusRulesPageItem = addPage( mVirusRulesPage, i18n( "Options to fine-tune the handling of virus messages" ));
137  connect( mVirusRulesPage, SIGNAL(selectionChanged()),
138  this, SLOT(checkVirusRulesSelections()) );
139  }
140 
141  connect( this, SIGNAL(helpClicked()),
142  this, SLOT(slotHelpClicked()) );
143 
144  QTimer::singleShot( 0, this, SLOT(checkToolAvailability()) );
145 }
146 
147 
148 void AntiSpamWizard::accept()
149 {
150  if ( mSpamRulesPage ) {
151  kDebug() << "Folder name for messages classified as spam is"
152  << mSpamRulesPage->selectedSpamCollectionId();
153  kDebug() << "Folder name for messages classified as unsure is"
154  << mSpamRulesPage->selectedUnsureCollectionId();
155  }
156  if ( mVirusRulesPage ) {
157  kDebug() << "Folder name for viruses is"
158  << mVirusRulesPage->selectedFolderName();
159  }
160 
161  FilterActionDict dict;
162  QList<MailFilter*> filterList;
163  bool replaceExistingFilters = false;
164 
165  // Let's start with virus detection and handling,
166  // so we can avoid spam checks for viral messages
167  if ( mMode == AntiVirus ) {
168  if ( !mVirusToolsUsed ) {
169  KDialog::accept();
170  return;
171  }
172  QList<SpamToolConfig>::const_iterator end( mToolList.constEnd() );
173  for ( QList<SpamToolConfig>::const_iterator it = mToolList.constBegin();
174  it != end; ++it ) {
175  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
176  ( mVirusRulesPage->pipeRulesSelected() && (*it).isVirusTool() ) ) {
177  // pipe messages through the anti-virus tools,
178  // one single filter for each tool
179  // (could get combined but so it's easier to understand for the user)
180  MailFilter* pipeFilter = new MailFilter();
181  QList<FilterAction*> *pipeFilterActions = pipeFilter->actions();
182  FilterAction* pipeFilterAction = dict.value( QLatin1String("filter app") )->create();
183  pipeFilterAction->argsFromString( (*it).getDetectCmd() );
184  pipeFilterActions->append( pipeFilterAction );
185  SearchPattern* pipeFilterPattern = pipeFilter->pattern();
186  pipeFilterPattern->setName( uniqueNameFor( (*it).getFilterName() ) );
187  pipeFilterPattern->append( SearchRule::createInstance( "<size>",
188  SearchRule::FuncIsGreaterOrEqual, QLatin1String("0") ) );
189  pipeFilter->setApplyOnOutbound( false);
190  pipeFilter->setApplyOnInbound();
191  pipeFilter->setApplyOnExplicit();
192  pipeFilter->setStopProcessingHere( false );
193  pipeFilter->setConfigureShortcut( false );
194 
195  filterList.append( pipeFilter );
196  }
197  }
198 
199  if ( mVirusRulesPage->moveRulesSelected() ) {
200  // Sort out viruses depending on header fields set by the tools
201  MailFilter* virusFilter = new MailFilter();
202  QList<FilterAction*> *virusFilterActions = virusFilter->actions();
203  FilterAction* virusFilterAction1 = dict.value( QLatin1String("transfer") )->create();
204  virusFilterAction1->argsFromString( mVirusRulesPage->selectedFolderName() );
205  virusFilterActions->append( virusFilterAction1 );
206  if ( mVirusRulesPage->markReadRulesSelected() ) {
207  FilterAction* virusFilterAction2 = dict.value( QLatin1String("set status" ))->create();
208  virusFilterAction2->argsFromString( QLatin1String("R") ); // Read
209  virusFilterActions->append( virusFilterAction2 );
210  }
211  SearchPattern* virusFilterPattern = virusFilter->pattern();
212  virusFilterPattern->setName( uniqueNameFor( i18n( "Virus handling" ) ) );
213  virusFilterPattern->setOp( SearchPattern::OpOr );
214  QList<SpamToolConfig>::ConstIterator endSpamTool( mToolList.constEnd() );
215  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
216  it != endSpamTool; ++it ) {
217  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )) {
218  if ( (*it).isVirusTool() ) {
219  const QByteArray header = (*it).getDetectionHeader().toLatin1();
220  const QString & pattern = (*it).getDetectionPattern();
221  if ( (*it).isUseRegExp() )
222  virusFilterPattern->append(
223  SearchRule::createInstance( header,
224  SearchRule::FuncRegExp, pattern ) );
225  else
226  virusFilterPattern->append(
227  SearchRule::createInstance( header,
228  SearchRule::FuncContains, pattern ) );
229  }
230  }
231  }
232  virusFilter->setApplyOnOutbound( false);
233  virusFilter->setApplyOnInbound();
234  virusFilter->setApplyOnExplicit();
235  virusFilter->setStopProcessingHere( true );
236  virusFilter->setConfigureShortcut( false );
237 
238  filterList.append( virusFilter );
239  }
240  } else { // AntiSpam mode
241  if ( !mSpamToolsUsed ) {
242  KDialog::accept();
243  return;
244  }
245  // TODO Existing filters with same name are replaced. This is hardcoded
246  // ATM and needs to be replaced with a value from a (still missing)
247  // checkbox in the GUI. At least, the replacement is announced in the GUI.
248  replaceExistingFilters = true;
249  QList<SpamToolConfig>::ConstIterator end( mToolList.constEnd() );
250  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
251  it != end; ++it ) {
252  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
253  (*it).isSpamTool() && !(*it).isDetectionOnly() ) {
254  // pipe messages through the anti-spam tools,
255  // one single filter for each tool
256  // (could get combined but so it's easier to understand for the user)
257  MailFilter* pipeFilter = new MailFilter();
258  QList<FilterAction*> *pipeFilterActions = pipeFilter->actions();
259  FilterAction* pipeFilterAction = dict.value(QLatin1String("filter app") )->create();
260  pipeFilterAction->argsFromString( (*it).getDetectCmd() );
261  pipeFilterActions->append( pipeFilterAction );
262  SearchPattern* pipeFilterPattern = pipeFilter->pattern();
263  if ( replaceExistingFilters )
264  pipeFilterPattern->setName( (*it).getFilterName() );
265  else
266  pipeFilterPattern->setName( uniqueNameFor( (*it).getFilterName() ) );
267  pipeFilterPattern->append( SearchRule::createInstance( "<size>",
268  SearchRule::FuncIsLessOrEqual, QLatin1String("256000") ) );
269  pipeFilter->setApplyOnOutbound( false);
270  pipeFilter->setApplyOnInbound();
271  pipeFilter->setApplyOnExplicit();
272  pipeFilter->setStopProcessingHere( false );
273  pipeFilter->setConfigureShortcut( false );
274 
275  filterList.append( pipeFilter );
276  }
277  }
278 
279  // Sort out spam depending on header fields set by the tools
280  MailFilter* spamFilter = new MailFilter();
281  QList<FilterAction*> *spamFilterActions = spamFilter->actions();
282  if ( mSpamRulesPage->moveSpamSelected() ) {
283  FilterAction* spamFilterAction1 = dict.value( QLatin1String("transfer") )->create();
284  spamFilterAction1->argsFromString( mSpamRulesPage->selectedSpamCollectionId() );
285  spamFilterActions->append( spamFilterAction1 );
286  }
287  FilterAction* spamFilterAction2 = dict.value( QLatin1String("set status") )->create();
288  spamFilterAction2->argsFromString( QLatin1String("P") ); // Spam
289  spamFilterActions->append( spamFilterAction2 );
290  if ( mSpamRulesPage->markAsReadSelected() ) {
291  FilterAction* spamFilterAction3 = dict.value( QLatin1String("set status") )->create();
292  spamFilterAction3->argsFromString( QLatin1String("R") ); // Read
293  spamFilterActions->append( spamFilterAction3 );
294  }
295  SearchPattern* spamFilterPattern = spamFilter->pattern();
296  if ( replaceExistingFilters )
297  spamFilterPattern->setName( i18n( "Spam Handling" ) );
298  else
299  spamFilterPattern->setName( uniqueNameFor( i18n( "Spam Handling" ) ) );
300  spamFilterPattern->setOp( SearchPattern::OpOr );
301  QList<SpamToolConfig>::ConstIterator endToolList( mToolList.constEnd() );
302  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
303  it != endToolList; ++it ) {
304  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) ) {
305  if ( (*it).isSpamTool() ) {
306  const QByteArray header = (*it).getDetectionHeader().toLatin1();
307  const QString & pattern = (*it).getDetectionPattern();
308  if ( (*it).isUseRegExp() )
309  spamFilterPattern->append(
310  SearchRule::createInstance( header,
311  SearchRule::FuncRegExp, pattern ) );
312  else
313  spamFilterPattern->append(
314  SearchRule::createInstance( header,
315  SearchRule::FuncContains, pattern ) );
316  }
317  }
318  }
319  spamFilter->setApplyOnOutbound( false);
320  spamFilter->setApplyOnInbound();
321  spamFilter->setApplyOnExplicit();
322  spamFilter->setStopProcessingHere( true );
323  spamFilter->setConfigureShortcut( false );
324  filterList.append( spamFilter );
325 
326  if ( mSpamRulesPage->moveUnsureSelected() ) {
327  // Sort out messages classified as unsure
328  bool atLeastOneUnsurePattern = false;
329  MailFilter* unsureFilter = new MailFilter();
330  QList<FilterAction*> *unsureFilterActions = unsureFilter->actions();
331  FilterAction* unsureFilterAction1 = dict.value( QLatin1String("transfer") )->create();
332  unsureFilterAction1->argsFromString( mSpamRulesPage->selectedUnsureCollectionId() );
333  unsureFilterActions->append( unsureFilterAction1 );
334  SearchPattern* unsureFilterPattern = unsureFilter->pattern();
335  if ( replaceExistingFilters )
336  unsureFilterPattern->setName( i18n( "Semi spam (unsure) handling" ) );
337  else
338  unsureFilterPattern->setName( uniqueNameFor( i18n( "Semi spam (unsure) handling" ) ) );
339  unsureFilterPattern->setOp( SearchPattern::OpOr );
340  QList<SpamToolConfig>::ConstIterator end( mToolList.constEnd() );
341  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
342  it != end; ++it ) {
343  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) )
344  {
345  if ( (*it).isSpamTool() && (*it).hasTristateDetection())
346  {
347  atLeastOneUnsurePattern = true;
348  const QByteArray header = (*it).getDetectionHeader().toLatin1();
349  const QString & pattern = (*it).getDetectionPattern2();
350  if ( (*it).isUseRegExp() )
351  unsureFilterPattern->append(
352  SearchRule::createInstance( header,
353  SearchRule::FuncRegExp, pattern ) );
354  else
355  unsureFilterPattern->append(
356  SearchRule::createInstance( header,
357  SearchRule::FuncContains, pattern ) );
358  }
359  }
360  }
361  unsureFilter->setApplyOnOutbound( false);
362  unsureFilter->setApplyOnInbound();
363  unsureFilter->setApplyOnExplicit();
364  unsureFilter->setStopProcessingHere( true );
365  unsureFilter->setConfigureShortcut( false );
366 
367  if ( atLeastOneUnsurePattern )
368  filterList.append( unsureFilter );
369  else
370  delete unsureFilter;
371  }
372 
373  // Classify messages manually as Spam
374  MailFilter* classSpamFilter = new MailFilter();
375  classSpamFilter->setIcon( QLatin1String("mail-mark-junk") );
376  QList<FilterAction*> *classSpamFilterActions = classSpamFilter->actions();
377  FilterAction* classSpamFilterActionFirst = dict.value( QLatin1String("set status") )->create();
378  classSpamFilterActionFirst->argsFromString( QLatin1String("P") );
379  classSpamFilterActions->append( classSpamFilterActionFirst );
380  QList<SpamToolConfig>::ConstIterator endToolList2( mToolList.constEnd() );
381  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
382  it != endToolList2; ++it ) {
383  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
384  && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
385  {
386  FilterAction* classSpamFilterAction = dict.value( QLatin1String("execute") )->create();
387  classSpamFilterAction->argsFromString( (*it).getSpamCmd() );
388  classSpamFilterActions->append( classSpamFilterAction );
389  }
390  }
391  if ( mSpamRulesPage->moveSpamSelected() ) {
392  FilterAction* classSpamFilterActionLast = dict.value( QLatin1String("transfer" ))->create();
393  classSpamFilterActionLast->argsFromString( mSpamRulesPage->selectedSpamCollectionId() );
394  classSpamFilterActions->append( classSpamFilterActionLast );
395  }
396 
397  SearchPattern* classSpamFilterPattern = classSpamFilter->pattern();
398  if ( replaceExistingFilters )
399  classSpamFilterPattern->setName( i18n( "Classify as Spam" ) );
400  else
401  classSpamFilterPattern->setName( uniqueNameFor( i18n( "Classify as Spam" ) ) );
402  classSpamFilterPattern->append( SearchRule::createInstance( "<size>",
403  SearchRule::FuncIsGreaterOrEqual, QLatin1String("0") ) );
404  classSpamFilter->setApplyOnOutbound( false);
405  classSpamFilter->setApplyOnInbound( false );
406  classSpamFilter->setApplyOnExplicit( false );
407  classSpamFilter->setStopProcessingHere( true );
408  classSpamFilter->setConfigureShortcut( true );
409  classSpamFilter->setConfigureToolbar( true );
410  classSpamFilter->setToolbarName( i18n( "Spam" ) );
411  filterList.append( classSpamFilter );
412 
413  // Classify messages manually as not Spam / as Ham
414  MailFilter* classHamFilter = new MailFilter();
415  classHamFilter->setIcon( QLatin1String("mail-mark-notjunk") );
416  QList<FilterAction*> *classHamFilterActions = classHamFilter->actions();
417  FilterAction* classHamFilterActionFirst = dict.value( QLatin1String("set status") )->create();
418  classHamFilterActionFirst->argsFromString( QLatin1String("H") );
419  classHamFilterActions->append( classHamFilterActionFirst );
420  end = mToolList.constEnd();
421  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
422  it != end; ++it ) {
423  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
424  && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
425  {
426  FilterAction* classHamFilterAction = dict.value( QLatin1String("execute") )->create();
427  classHamFilterAction->argsFromString( (*it).getHamCmd() );
428  classHamFilterActions->append( classHamFilterAction );
429  }
430  }
431  end = mToolList.constEnd();
432  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
433  it != end; ++it ) {
434  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() )
435  && (*it).useBayesFilter() && !(*it).isDetectionOnly() )
436  {
437  FilterAction* classHamFilterAction = dict.value( QLatin1String("filter app") )->create();
438  classHamFilterAction->argsFromString( (*it).getNoSpamCmd() );
439  classHamFilterActions->append( classHamFilterAction );
440  }
441  }
442  SearchPattern* classHamFilterPattern = classHamFilter->pattern();
443  if ( replaceExistingFilters )
444  classHamFilterPattern->setName( i18n( "Classify as NOT Spam" ) );
445  else
446  classHamFilterPattern->setName( uniqueNameFor( i18n( "Classify as NOT Spam" ) ) );
447  classHamFilterPattern->append( SearchRule::createInstance( "<size>",
448  SearchRule::FuncIsGreaterOrEqual, QLatin1String("0") ) );
449  classHamFilter->setApplyOnOutbound( false);
450  classHamFilter->setApplyOnInbound( false );
451  classHamFilter->setApplyOnExplicit( false );
452  classHamFilter->setStopProcessingHere( true );
453  classHamFilter->setConfigureShortcut( true );
454  classHamFilter->setConfigureToolbar( true );
455  classHamFilter->setToolbarName( i18n( "Ham" ) );
456  filterList.append( classHamFilter );
457  }
458 
459  /* Now that all the filters have been added to the list, tell
460  * the filter manager about it. That will emit filterListUpdate
461  * which will result in the filter list in kmmainwidget being
462  * initialized. This should happend only once. */
463  if ( !filterList.isEmpty() )
464  MailCommon::FilterManager::instance()->appendFilters( filterList, replaceExistingFilters );
465 
466  KDialog::accept();
467 }
468 
469 
470 void AntiSpamWizard::checkProgramsSelections()
471 {
472  bool supportUnsure = false;
473 
474  mSpamToolsUsed = false;
475  mVirusToolsUsed = false;
476  QList<SpamToolConfig>::ConstIterator end( mToolList.constEnd() );
477  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
478  it != end; ++it ) {
479  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) ) {
480  if ( (*it).isSpamTool() ) {
481  mSpamToolsUsed = true;
482  if ( (*it).hasTristateDetection() )
483  supportUnsure = true;
484  }
485  if ( (*it).isVirusTool() )
486  mVirusToolsUsed = true;
487 
488  if ( mSpamToolsUsed && mVirusToolsUsed && supportUnsure )
489  break;
490  }
491  }
492 
493  if ( mMode == AntiSpam ) {
494  mSpamRulesPage->allowUnsureFolderSelection( supportUnsure );
495  mSpamRulesPage->allowMoveSpam( mSpamToolsUsed );
496  slotBuildSummary();
497  setAppropriate( mSpamRulesPageItem, mSpamToolsUsed );
498  setAppropriate( mSummaryPageItem, mSpamToolsUsed );
499  }
500  else if ( mMode == AntiVirus ) {
501  if ( mVirusToolsUsed )
502  checkVirusRulesSelections();
503  setAppropriate( mVirusRulesPageItem, mVirusToolsUsed );
504  }
505 }
506 
507 
508 void AntiSpamWizard::checkVirusRulesSelections()
509 {
510  //setFinishEnabled( mVirusRulesPage, anyVirusOptionChecked() );
511 }
512 
513 
514 void AntiSpamWizard::checkToolAvailability()
515 {
516  // this can take some time to find the tools
517 #ifndef QT_NO_CURSOR
518  MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
519 #endif
520  bool found = false;
521  QList<SpamToolConfig>::ConstIterator end( mToolList.constEnd() );
522  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
523  it != end; ++it ) {
524  const QString text( i18n("Scanning for %1...", (*it).getId() ) );
525  mInfoPage->setScanProgressText( text );
526  if ( (*it).isSpamTool() && (*it).isServerBased() ) {
527  // check the configured account for pattern in <server>
528  const QString pattern = (*it).getServerPattern();
529  kDebug() << "Testing for server pattern:" << pattern;
530  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
531  foreach( const Akonadi::AgentInstance& type, lst ) {
532  if ( type.status() == Akonadi::AgentInstance::Broken )
533  continue;
534  if ( PimCommon::Util::isImapResource(type.identifier()) ) {
535  OrgKdeAkonadiImapSettingsInterface *iface = PimCommon::Util::createImapSettingsInterface( type.identifier() );
536  if ( iface->isValid() ) {
537  const QString host = iface->imapServer();
538  if ( host.toLower().contains( pattern.toLower() ) ) {
539  mInfoPage->addAvailableTool( (*it).getVisibleName() );
540  found = true;
541  }
542  }
543  delete iface;
544  }
545  else if ( type.identifier().contains( POP3_RESOURCE_IDENTIFIER ) ) {
546  OrgKdeAkonadiPOP3SettingsInterface *iface = MailCommon::Util::createPop3SettingsInterface( type.identifier() );
547  if ( iface->isValid() ) {
548  const QString host = iface->host();
549  if ( host.toLower().contains( pattern.toLower() ) ) {
550  mInfoPage->addAvailableTool( (*it).getVisibleName() );
551  found = true;
552  }
553  }
554  delete iface;
555  }
556  }
557  }
558  else {
559  // check the availability of the application
560  qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 200 );
561  if ( !checkForProgram( (*it).getExecutable() ) ) {
562  mInfoPage->addAvailableTool( (*it).getVisibleName() );
563  found = true;
564  }
565  }
566  }
567  if ( found )
568  mInfoPage->setScanProgressText( ( mMode == AntiSpam )
569  ? i18n("Scanning for anti-spam tools finished.")
570  : i18n("Scanning for anti-virus tools finished.") );
571  else {
572  mInfoPage->setScanProgressText( ( mMode == AntiSpam )
573  ? i18n("<p>Sorry, no spam detection tools have been found. "
574  "Install your spam detection software and "
575  "re-run this wizard.</p>")
576  : i18n("Scanning complete. No anti-virus tools found.") );
577  }
578  checkProgramsSelections();
579 }
580 
581 
582 void AntiSpamWizard::slotHelpClicked()
583 {
584  KToolInvocation::invokeHelp( (mMode == AntiSpam) ? QLatin1String("the-anti-spam-wizard") : QLatin1String("the-anti-virus-wizard") , QLatin1String("kmail") );
585 }
586 
587 
588 void AntiSpamWizard::slotBuildSummary()
589 {
590  QString text;
591  QString newFilters;
592  QString replaceFilters;
593 
594  if ( mMode == AntiVirus ) {
595  text.clear(); // TODO add summary for the virus part
596  }
597  else { // AntiSpam mode
598  if ( mSpamRulesPage->markAsReadSelected() ) {
599  if ( mSpamRulesPage->moveSpamSelected() )
600  text = i18n( "<p>Messages classified as spam are marked as read."
601  "<br />Spam messages are moved into the folder named <i>%1</i>.</p>"
602  , mSpamRulesPage->selectedSpamCollectionName() );
603  else
604  text = i18n( "<p>Messages classified as spam are marked as read."
605  "<br />Spam messages are not moved into a certain folder.</p>" );
606  }
607  else {
608  if ( mSpamRulesPage->moveSpamSelected() )
609  text = i18n( "<p>Messages classified as spam are not marked as read."
610  "<br />Spam messages are moved into the folder named <i>%1</i>.</p>"
611  , mSpamRulesPage->selectedSpamCollectionName() );
612  else
613  text = i18n( "<p>Messages classified as spam are not marked as read."
614  "<br />Spam messages are not moved into a certain folder.</p>" );
615  }
616  QList<SpamToolConfig>::ConstIterator end( mToolList.constEnd() );
617  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
618  it != end; ++it ) {
619  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) &&
620  (*it).isSpamTool() && !(*it).isDetectionOnly() ) {
621  sortFilterOnExistance( (*it).getFilterName(), newFilters, replaceFilters );
622  }
623  }
624  sortFilterOnExistance( i18n( "Spam Handling" ), newFilters, replaceFilters );
625 
626  // The need for a andling of status "probably spam" depends on the tools chosen
627  if ( mSpamRulesPage->moveUnsureSelected() ) {
628  bool atLeastOneUnsurePattern = false;
629  end = mToolList.constEnd();
630  for ( QList<SpamToolConfig>::ConstIterator it = mToolList.constBegin();
631  it != end; ++it ) {
632  if ( mInfoPage->isProgramSelected( (*it).getVisibleName() ) ) {
633  if ( (*it).isSpamTool() && (*it).hasTristateDetection()) {
634  atLeastOneUnsurePattern = true;
635  break;
636  }
637  }
638  }
639  if ( atLeastOneUnsurePattern ) {
640  sortFilterOnExistance( i18n( "Semi spam (unsure) handling" ),
641  newFilters, replaceFilters );
642  text += i18n( "<p>The folder for messages classified as unsure (probably spam) is <i>%1</i>.</p>"
643  , mSpamRulesPage->selectedUnsureCollectionName() );
644  }
645  }
646 
647  // Manual classification via toolbar icon / manually applied filter action
648  sortFilterOnExistance( i18n( "Classify as Spam" ),
649  newFilters, replaceFilters );
650  sortFilterOnExistance( i18n( "Classify as NOT Spam" ),
651  newFilters, replaceFilters );
652 
653  // Show the filters in the summary
654  if ( !newFilters.isEmpty() )
655  text += i18n( "<p>The wizard will create the following filters:<ul>%1</ul></p>"
656  , newFilters );
657  if ( !replaceFilters.isEmpty() )
658  text += i18n( "<p>The wizard will replace the following filters:<ul>%1</ul></p>"
659  , replaceFilters );
660  }
661 
662  mSummaryPage->setSummaryText( text );
663 }
664 
665 
666 int AntiSpamWizard::checkForProgram( const QString &executable ) const
667 {
668  kDebug() << "Testing for executable:" << executable;
669  KProcess process;
670  process.setShellCommand( executable );
671  return process.execute ();
672 }
673 
674 
675 bool AntiSpamWizard::anyVirusOptionChecked() const
676 {
677  return ( mVirusRulesPage->moveRulesSelected()
678  || mVirusRulesPage->pipeRulesSelected() );
679 }
680 
681 
682 const QString AntiSpamWizard::uniqueNameFor( const QString & name )
683 {
684  return MailCommon::FilterManager::instance()->createUniqueFilterName( name );
685 }
686 
687 
688 void AntiSpamWizard::sortFilterOnExistance(
689  const QString & intendedFilterName,
690  QString & newFilters, QString & replaceFilters )
691 {
692  if ( uniqueNameFor( intendedFilterName ) == intendedFilterName )
693  newFilters += QLatin1String("<li>") + intendedFilterName + QLatin1String("</li>");
694  else
695  replaceFilters += QLatin1String("<li>") + intendedFilterName + QLatin1String("</li>");
696 }
697 
698 
699 //---------------------------------------------------------------------------
700 AntiSpamWizard::SpamToolConfig::SpamToolConfig( const QString &toolId,
701  int configVersion, int prio, const QString &name, const QString &exec,
702  const QString &url, const QString &filter, const QString &detection,
703  const QString &spam, const QString &ham, const QString &noSpam,
704  const QString &header, const QString &pattern, const QString &pattern2,
705  const QString &serverPattern, bool detectionOnly, bool regExp,
706  bool bayesFilter, bool tristateDetection, WizardMode type )
707  : mId( toolId ), mVersion( configVersion ), mPrio( prio ),
708  mVisibleName( name ), mExecutable( exec ), mWhatsThisText( url ),
709  mFilterName( filter ), mDetectCmd( detection ), mSpamCmd( spam ),
710  mHamCmd( ham ), mNoSpamCmd( noSpam ), mDetectionHeader( header ),
711  mDetectionPattern( pattern ), mDetectionPattern2( pattern2 ),
712  mServerPattern( serverPattern ), mDetectionOnly( detectionOnly ),
713  mUseRegExp( regExp ), mSupportsBayesFilter( bayesFilter ),
714  mSupportsUnsure( tristateDetection ), mType( type )
715 {
716 }
717 
718 
719 bool AntiSpamWizard::SpamToolConfig::isServerBased() const
720 {
721  return !mServerPattern.isEmpty();
722 }
723 
724 
725 //---------------------------------------------------------------------------
726 AntiSpamWizard::ConfigReader::ConfigReader( WizardMode mode,
727  QList<SpamToolConfig> & configList )
728  : mToolList( configList ),
729  mMode( mode )
730 {
731  if ( mMode == AntiSpam )
732  mConfig = KSharedConfig::openConfig( QLatin1String("kmail.antispamrc") );
733  else
734  mConfig = KSharedConfig::openConfig( QLatin1String("kmail.antivirusrc") );
735 }
736 
737 AntiSpamWizard::ConfigReader::~ConfigReader( )
738 {
739 }
740 
741 
742 void AntiSpamWizard::ConfigReader::readAndMergeConfig()
743 {
744  QString groupName = ( mMode == AntiSpam )
745  ? QString::fromLatin1("Spamtool #%1")
746  : QString::fromLatin1("Virustool #%1");
747  // read the configuration from the global config file
748  mConfig->setReadDefaults( true );
749  KConfigGroup general( mConfig, "General" );
750  const int registeredTools = general.readEntry( "tools", 0 );
751  for (int i = 1; i <= registeredTools; ++i)
752  {
753  KConfigGroup toolConfig( mConfig, groupName.arg( i ) );
754  if( !toolConfig.readEntry( "HeadersOnly", false ) )
755  mToolList.append( readToolConfig( toolConfig ) );
756  }
757 
758  // read the configuration from the user config file
759  // and merge newer config data
760  mConfig->setReadDefaults( false );
761  KConfigGroup user_general( mConfig, "General" );
762  const int user_registeredTools = user_general.readEntry( "tools", 0 );
763  for (int i = 1; i <= user_registeredTools; ++i)
764  {
765  KConfigGroup toolConfig( mConfig, groupName.arg( i ) );
766  if( !toolConfig.readEntry( "HeadersOnly", false ) )
767  mergeToolConfig( readToolConfig( toolConfig ) );
768  }
769  // Make sure to have add least one tool listed even when the
770  // config file was not found or whatever went wrong
771  // Currently only works for spam tools
772  if ( mMode == AntiSpam ) {
773  if ( registeredTools < 1 && user_registeredTools < 1 )
774  mToolList.append( createDummyConfig() );
775  sortToolList();
776  }
777 }
778 
779 
780 AntiSpamWizard::SpamToolConfig
781 AntiSpamWizard::ConfigReader::readToolConfig( KConfigGroup & configGroup )
782 {
783  const QString id = configGroup.readEntry( "Ident" );
784  const int version = configGroup.readEntry( "Version", 0 );
785 #ifndef NDEBUG
786  kDebug() << "Found predefined tool:" << id;
787  kDebug() << "With config version :" << version;
788 #endif
789  const int prio = configGroup.readEntry( "Priority", 1 );
790  const QString name = configGroup.readEntry( "VisibleName" );
791  const QString executable = configGroup.readEntry( "Executable" );
792  const QString url = configGroup.readEntry( "URL" );
793  const QString filterName = configGroup.readEntry( "PipeFilterName" );
794  const QString detectCmd = configGroup.readEntry( "PipeCmdDetect" );
795  const QString spamCmd = configGroup.readEntry( "ExecCmdSpam" );
796  const QString hamCmd = configGroup.readEntry( "ExecCmdHam" );
797  const QString noSpamCmd = configGroup.readEntry( "PipeCmdNoSpam" );
798  const QString header = configGroup.readEntry( "DetectionHeader" );
799  const QString pattern = configGroup.readEntry( "DetectionPattern" );
800  const QString pattern2 = configGroup.readEntry( "DetectionPattern2" );
801  const QString serverPattern = configGroup.readEntry( "ServerPattern" );
802  const bool detectionOnly = configGroup.readEntry( "DetectionOnly", false );
803  const bool useRegExp = configGroup.readEntry( "UseRegExp", false );
804  const bool supportsBayes = configGroup.readEntry( "SupportsBayes", false );
805  const bool supportsUnsure = configGroup.readEntry( "SupportsUnsure", false );
806  return SpamToolConfig( id, version, prio, name, executable, url,
807  filterName, detectCmd, spamCmd, hamCmd, noSpamCmd,
808  header, pattern, pattern2, serverPattern,
809  detectionOnly, useRegExp,
810  supportsBayes, supportsUnsure, mMode );
811 }
812 
813 
814 AntiSpamWizard::SpamToolConfig AntiSpamWizard::ConfigReader::createDummyConfig()
815 {
816  return SpamToolConfig( QLatin1String("spamassassin"), 0, 1,
817  QLatin1String("SpamAssassin"), QLatin1String("spamassassin -V"),
818  QLatin1String("http://spamassassin.org"), QLatin1String("SpamAssassin Check"),
819  QLatin1String("spamassassin -L"),
820  QLatin1String("sa-learn -L --spam --no-sync --single"),
821  QLatin1String("sa-learn -L --ham --no-sync --single"),
822  QLatin1String("spamassassin -d"),
823  QLatin1String("X-Spam-Flag"), QLatin1String("yes"), QString(), QString(),
824  false, false, true, false, AntiSpam );
825 }
826 
827 
828 void AntiSpamWizard::ConfigReader::mergeToolConfig( const AntiSpamWizard::SpamToolConfig &config )
829 {
830  bool found = false;
831  QList<SpamToolConfig>::Iterator end( mToolList.end() );
832  for ( QList<SpamToolConfig>::Iterator it = mToolList.begin();
833  it != end; ++it ) {
834 #ifndef NDEBUG
835  kDebug() << "Check against tool:" << (*it).getId();
836  kDebug() << "Against version :" << (*it).getVersion();
837 #endif
838  if ( (*it).getId() == config.getId() )
839  {
840  found = true;
841  if ( (*it).getVersion() < config.getVersion() )
842  {
843 #ifndef NDEBUG
844  kDebug() << "Replacing config ...";
845 #endif
846  mToolList.erase( it );
847  mToolList.append( config );
848  }
849  break;
850  }
851  }
852  if ( !found )
853  mToolList.append( config );
854 }
855 
856 
857 void AntiSpamWizard::ConfigReader::sortToolList()
858 {
859  QList<SpamToolConfig> tmpList;
860  SpamToolConfig config;
861 
862  while ( !mToolList.isEmpty() ) {
863  QList<SpamToolConfig>::Iterator highest;
864  int priority = 0; // ascending
865  QList<SpamToolConfig>::Iterator end( mToolList.end() );
866  for ( QList<SpamToolConfig>::Iterator it = mToolList.begin();
867  it != end; ++it ) {
868  if ( (*it).getPrio() > priority ) {
869  priority = (*it).getPrio();
870  highest = it;
871  }
872  }
873  config = (*highest);
874  tmpList.append( config );
875  mToolList.erase( highest );
876  }
877  QList<SpamToolConfig>::ConstIterator end( tmpList.constEnd() );
878  for ( QList<SpamToolConfig>::ConstIterator it = tmpList.constBegin();
879  it != end; ++it ) {
880  mToolList.append( (*it) );
881  }
882 }
883 
884 
885 //---------------------------------------------------------------------------
886 ASWizPage::ASWizPage( QWidget * parent, const QString & name)
887  : QWidget( parent )
888 {
889  setObjectName( name );
890  const QString banner = QLatin1String("kmwizard.png");
891  mLayout = new QHBoxLayout( this );
892  mLayout->setSpacing( KDialog::spacingHint() );
893  mLayout->setMargin( KDialog::marginHint() );
894 
895  QVBoxLayout * sideLayout = new QVBoxLayout();
896  mLayout->addItem( sideLayout );
897  mLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
898 
899  QLabel *bannerLabel = new QLabel( this );
900  bannerLabel->setPixmap( UserIcon(banner) );
901  bannerLabel->setScaledContents( false );
902  bannerLabel->setFrameShape( QFrame::StyledPanel );
903  bannerLabel->setFrameShadow( QFrame::Sunken );
904  bannerLabel->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
905 
906  sideLayout->addWidget( bannerLabel );
907  sideLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
908 }
909 
910 
911 //---------------------------------------------------------------------------
912 ASWizInfoPage::ASWizInfoPage(AntiSpamWizard::WizardMode mode,
913  QWidget * parent, const QString &name )
914  : ASWizPage( parent, name )
915 {
916  QBoxLayout * layout = new QVBoxLayout();
917  mLayout->addItem( layout );
918 
919  QTextEdit *introText = new QTextEdit( this );
920  introText->setText(
921  ( mode == AntiSpamWizard::AntiSpam )
922  ? i18n(
923  "The wizard will search for any tools to do spam detection\n"
924  "and setup KMail to work with them."
925  )
926  : i18n(
927  "<p>Here you can get some assistance in setting up KMail's filter "
928  "rules to use some commonly-known anti-virus tools.</p>"
929  "<p>The wizard can detect those tools on your computer as "
930  "well as create filter rules to classify messages using these "
931  "tools and to separate messages containing viruses. "
932  "The wizard will not take any existing filter "
933  "rules into consideration: it will always append the new rules.</p>"
934  "<p><b>Warning:</b> As KMail appears to be frozen during the scan of the "
935  "messages for viruses, you may encounter problems with "
936  "the responsiveness of KMail because anti-virus tool "
937  "operations are usually time consuming; please consider "
938  "deleting the filter rules created by the wizard to get "
939  "back to the former behavior.</p>"
940  ) );
941  introText->setReadOnly( true );
942  introText->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
943  layout->addWidget( introText );
944 
945  mScanProgressText = new QLabel( this );
946  mScanProgressText->clear();
947  mScanProgressText->setWordWrap( true );
948  layout->addWidget( mScanProgressText );
949 
950  mToolsList = new QListWidget( this );
951  mToolsList->hide();
952  mToolsList->setSelectionMode( QAbstractItemView::MultiSelection );
953  mToolsList->setLayoutMode( QListView::Batched );
954  mToolsList->setBatchSize( 10 );
955  mToolsList->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum ) );
956  layout->addWidget( mToolsList );
957  connect( mToolsList->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
958  this, SLOT(processSelectionChange()) );
959 
960  mSelectionHint = new QLabel( this );
961  mSelectionHint->clear();
962  mSelectionHint->setWordWrap( true );
963  layout->addWidget( mSelectionHint );
964 }
965 
966 
967 void ASWizInfoPage::setScanProgressText( const QString &toolName )
968 {
969  mScanProgressText->setText( toolName );
970 }
971 
972 
973 void ASWizInfoPage::addAvailableTool( const QString &visibleName )
974 {
975  mToolsList->addItem( visibleName );
976  if ( !mToolsList->isVisible() )
977  {
978  mToolsList->show();
979  mToolsList->selectionModel()->clearSelection();
980  mToolsList->setCurrentRow( 0 );
981  mSelectionHint->setText( i18n("<p>Please select the tools to be used "
982  "for the detection and go "
983  "to the next page.</p>") );
984  }
985 }
986 
987 bool ASWizInfoPage::isProgramSelected( const QString &visibleName ) const
988 {
989  const QList<QListWidgetItem*> foundItems = mToolsList->findItems( visibleName, Qt::MatchFixedString );
990  return (!foundItems.isEmpty() && foundItems[0]->isSelected());
991 }
992 
993 
994 void ASWizInfoPage::processSelectionChange()
995 {
996  emit selectionChanged();
997 }
998 
999 
1000 //---------------------------------------------------------------------------
1001 ASWizSpamRulesPage::ASWizSpamRulesPage( QWidget * parent, const QString &name)
1002  : ASWizPage( parent, name )
1003 {
1004  QVBoxLayout *layout = new QVBoxLayout();
1005  mLayout->addItem( layout );
1006 
1007  mMarkRules = new QCheckBox( i18n("&Mark detected spam messages as read"), this );
1008  mMarkRules->setWhatsThis(
1009  i18n( "Mark messages which have been classified as spam as read.") );
1010  layout->addWidget( mMarkRules);
1011 
1012  mMoveSpamRules = new QCheckBox( i18n("Move &known spam to:"), this );
1013  mMoveSpamRules->setWhatsThis(
1014  i18n( "The default folder for spam messages is the trash folder, "
1015  "but you may change that in the folder view below.") );
1016  layout->addWidget( mMoveSpamRules );
1017 
1018  mFolderReqForSpamFolder = new FolderRequester( this );
1019  mFolderReqForSpamFolder->setCollection( CommonKernel->trashCollectionFolder() );
1020  mFolderReqForSpamFolder->setMustBeReadWrite( true );
1021  mFolderReqForSpamFolder->setShowOutbox( false );
1022 
1023  QHBoxLayout *hLayout1 = new QHBoxLayout();
1024  layout->addItem( hLayout1 );
1025  hLayout1->addSpacing( KDialog::spacingHint() * 3 );
1026  hLayout1->addWidget( mFolderReqForSpamFolder );
1027 
1028  mMoveUnsureRules = new QCheckBox( i18n("Move &probable spam to:"), this );
1029  mMoveUnsureRules->setWhatsThis(
1030  i18n( "The default folder is the inbox folder, but you may change that "
1031  "in the folder view below.<p>"
1032  "Not all tools support a classification as unsure. If you have not "
1033  "selected a capable tool, you cannot select a folder as well.</p>") );
1034  layout->addWidget( mMoveUnsureRules );
1035 
1036  mFolderReqForUnsureFolder = new FolderRequester( this );
1037  mFolderReqForUnsureFolder->setCollection( CommonKernel->inboxCollectionFolder() );
1038  mFolderReqForUnsureFolder->setMustBeReadWrite( true );
1039  mFolderReqForUnsureFolder->setShowOutbox( false );
1040 
1041  QHBoxLayout *hLayout2 = new QHBoxLayout();
1042  layout->addItem( hLayout2 );
1043  hLayout2->addSpacing( KDialog::spacingHint() * 3 );
1044  hLayout2->addWidget( mFolderReqForUnsureFolder );
1045 
1046  layout->addStretch();
1047 
1048  connect( mMarkRules, SIGNAL(clicked()),
1049  this, SLOT(processSelectionChange()) );
1050  connect( mMoveSpamRules, SIGNAL(clicked()),
1051  this, SLOT(processSelectionChange()) );
1052  connect( mMoveUnsureRules, SIGNAL(clicked()),
1053  this, SLOT(processSelectionChange()) );
1054  connect( mFolderReqForSpamFolder, SIGNAL(folderChanged(Akonadi::Collection)),
1055  this, SLOT(processSelectionChange(Akonadi::Collection)) );
1056  connect( mFolderReqForUnsureFolder, SIGNAL(folderChanged(Akonadi::Collection)),
1057  this, SLOT(processSelectionChange(Akonadi::Collection)) );
1058 
1059  mMarkRules->setChecked( true );
1060  mMoveSpamRules->setChecked( true );
1061 }
1062 
1063 
1064 bool ASWizSpamRulesPage::markAsReadSelected() const
1065 {
1066  return mMarkRules->isChecked();
1067 }
1068 
1069 
1070 bool ASWizSpamRulesPage::moveSpamSelected() const
1071 {
1072  return mMoveSpamRules->isChecked();
1073 }
1074 
1075 
1076 bool ASWizSpamRulesPage::moveUnsureSelected() const
1077 {
1078  return mMoveUnsureRules->isChecked();
1079 }
1080 
1081 QString ASWizSpamRulesPage::selectedSpamCollectionId() const
1082 {
1083  return QString::number( selectedSpamCollection().id() );
1084 }
1085 
1086 QString ASWizSpamRulesPage::selectedSpamCollectionName() const
1087 {
1088  return selectedSpamCollection().name();
1089 }
1090 
1091 Akonadi::Collection ASWizSpamRulesPage::selectedSpamCollection() const
1092 {
1093  if ( mFolderReqForSpamFolder->hasCollection() )
1094  return mFolderReqForSpamFolder->collection();
1095  else
1096  return CommonKernel->trashCollectionFolder();
1097 }
1098 
1099 
1100 Akonadi::Collection ASWizSpamRulesPage::selectedUnsureCollection() const
1101 {
1102  if ( mFolderReqForUnsureFolder->hasCollection() )
1103  return mFolderReqForUnsureFolder->collection();
1104  else
1105  return CommonKernel->inboxCollectionFolder();
1106 }
1107 
1108 QString ASWizSpamRulesPage::selectedUnsureCollectionName() const
1109 {
1110  return selectedUnsureCollection().name();
1111 }
1112 
1113 QString ASWizSpamRulesPage::selectedUnsureCollectionId() const
1114 {
1115  return QString::number( selectedUnsureCollection().id() );
1116 }
1117 
1118 
1119 void ASWizSpamRulesPage::processSelectionChange()
1120 {
1121  mFolderReqForSpamFolder->setEnabled( mMoveSpamRules->isChecked() );
1122  mFolderReqForUnsureFolder->setEnabled( mMoveUnsureRules->isChecked() );
1123  emit selectionChanged();
1124 }
1125 
1126 
1127 void ASWizSpamRulesPage::processSelectionChange( const Akonadi::Collection& )
1128 {
1129  processSelectionChange();
1130 }
1131 
1132 
1133 void ASWizSpamRulesPage::allowUnsureFolderSelection( bool enabled )
1134 {
1135  mMoveUnsureRules->setEnabled( enabled );
1136  mMoveUnsureRules->setVisible( enabled );
1137  mFolderReqForUnsureFolder->setEnabled( enabled );
1138  mFolderReqForUnsureFolder->setVisible( enabled );
1139 }
1140 
1141 void ASWizSpamRulesPage::allowMoveSpam( bool enabled )
1142 {
1143  mMarkRules->setEnabled( enabled );
1144  mMarkRules->setChecked( enabled );
1145  mMoveSpamRules->setEnabled( enabled );
1146  mMoveSpamRules->setChecked( enabled );
1147 }
1148 
1149 
1150 //---------------------------------------------------------------------------
1151 ASWizVirusRulesPage::ASWizVirusRulesPage( QWidget * parent, const QString & name )
1152  : ASWizPage( parent, name )
1153 {
1154  QGridLayout *grid = new QGridLayout();
1155  mLayout->addItem( grid );
1156  grid->setSpacing( KDialog::spacingHint() );
1157 
1158  mPipeRules = new QCheckBox( i18n("Check messages using the anti-virus tools"), this );
1159  mPipeRules->setWhatsThis(
1160  i18n( "Let the anti-virus tools check your messages. The wizard "
1161  "will create appropriate filters. The messages are usually "
1162  "marked by the tools so that following filters can react "
1163  "on this and, for example, move virus messages to a special folder.") );
1164  grid->addWidget( mPipeRules, 0, 0 );
1165 
1166  mMoveRules = new QCheckBox( i18n("Move detected viral messages to the selected folder"), this );
1167  mMoveRules->setWhatsThis(
1168  i18n( "A filter to detect messages classified as virus-infected and to move "
1169  "those messages into a predefined folder is created. The "
1170  "default folder is the trash folder, but you may change that "
1171  "in the folder view.") );
1172  grid->addWidget( mMoveRules, 1, 0 );
1173 
1174  mMarkRules = new QCheckBox( i18n("Additionally, mark detected viral messages as read"), this );
1175  mMarkRules->setEnabled( false );
1176  mMarkRules->setWhatsThis(
1177  i18n( "Mark messages which have been classified as "
1178  "virus-infected as read, as well as moving them "
1179  "to the selected folder.") );
1180  grid->addWidget( mMarkRules, 2, 0 );
1181  FolderTreeWidget::TreeViewOptions opt = FolderTreeWidget::None;
1182  opt |= FolderTreeWidget::UseDistinctSelectionModel;
1183 
1184  FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModelOptions optReadableProxy = FolderTreeWidgetProxyModel::None;
1185  optReadableProxy |= FolderTreeWidgetProxyModel::HideVirtualFolder;
1186  optReadableProxy |= FolderTreeWidgetProxyModel::HideOutboxFolder;
1187 
1188  mFolderTree = new FolderTreeWidget( this, 0, opt, optReadableProxy );
1189  mFolderTree->readConfig();
1190  mFolderTree->folderTreeView()->expandAll();
1191  mFolderTree->folderTreeWidgetProxyModel()->setAccessRights( Akonadi::Collection::CanCreateCollection );
1192 
1193  mFolderTree->selectCollectionFolder( CommonKernel->trashCollectionFolder() );
1194  mFolderTree->folderTreeView()->setDragDropMode( QAbstractItemView::NoDragDrop );
1195 
1196  mFolderTree->disableContextMenuAndExtraColumn();
1197  grid->addWidget( mFolderTree, 3, 0 );
1198 
1199  connect( mPipeRules, SIGNAL(clicked()),
1200  this, SLOT(processSelectionChange()) );
1201  connect( mMoveRules, SIGNAL(clicked()),
1202  this, SLOT(processSelectionChange()) );
1203  connect( mMarkRules, SIGNAL(clicked()),
1204  this, SLOT(processSelectionChange()) );
1205  connect( mMoveRules, SIGNAL(toggled(bool)),
1206  mMarkRules, SLOT(setEnabled(bool)) );
1207 
1208 }
1209 
1210 bool ASWizVirusRulesPage::pipeRulesSelected() const
1211 {
1212  return mPipeRules->isChecked();
1213 }
1214 
1215 
1216 bool ASWizVirusRulesPage::moveRulesSelected() const
1217 {
1218  return mMoveRules->isChecked();
1219 }
1220 
1221 bool ASWizVirusRulesPage::markReadRulesSelected() const
1222 {
1223  return mMarkRules->isChecked();
1224 }
1225 
1226 
1227 QString ASWizVirusRulesPage::selectedFolderName() const
1228 {
1229  if ( mFolderTree->selectedCollection().isValid() )
1230  return QString::number( mFolderTree->selectedCollection().id() );
1231  else
1232  return QString::number( CommonKernel->trashCollectionFolder().id() );
1233 }
1234 
1235 void ASWizVirusRulesPage::processSelectionChange()
1236 {
1237  emit selectionChanged();
1238 }
1239 
1240 
1241 //---------------------------------------------------------------------------
1242 ASWizSummaryPage::ASWizSummaryPage(QWidget * parent, const QString &name )
1243  : ASWizPage( parent, name )
1244 {
1245  QBoxLayout * layout = new QVBoxLayout();
1246  mLayout->addItem( layout );
1247 
1248  mSummaryText = new QLabel( this );
1249  layout->addWidget( mSummaryText );
1250  layout->addStretch();
1251 }
1252 
1253 
1254 void ASWizSummaryPage::setSummaryText( const QString & text )
1255 {
1256  mSummaryText->setText( text );
1257 }
1258 
1259 
QWidget::layout
QLayout * layout() const
KMail::ASWizSpamRulesPage::selectedUnsureCollection
Akonadi::Collection selectedUnsureCollection() const
Definition: antispamwizard.cpp:1100
QSpacerItem
KMail::ASWizSummaryPage::setSummaryText
void setSummaryText(const QString &text)
Definition: antispamwizard.cpp:1254
KMail::ASWizSpamRulesPage::selectedUnsureCollectionName
QString selectedUnsureCollectionName() const
Definition: antispamwizard.cpp:1108
QWidget
QString::append
QString & append(QChar ch)
KMail::ASWizInfoPage::addAvailableTool
void addAvailableTool(const QString &visibleName)
Definition: antispamwizard.cpp:973
antispamwizard.h
KMail::ASWizSpamRulesPage::markAsReadSelected
bool markAsReadSelected() const
Definition: antispamwizard.cpp:1064
KMail::AntiSpamWizard::checkProgramsSelections
void checkProgramsSelections()
Modify the status of the wizard to reflect the selection of spam tools.
Definition: antispamwizard.cpp:470
QAbstractItemView::setSelectionMode
void setSelectionMode(QAbstractItemView::SelectionMode mode)
KMail::ASWizPage::mLayout
QBoxLayout * mLayout
Definition: antispamwizard.h:299
KMail::ASWizSpamRulesPage::selectedSpamCollectionName
QString selectedSpamCollectionName() const
Definition: antispamwizard.cpp:1086
QGridLayout::addWidget
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
QByteArray
QAbstractItemView::selectionModel
QItemSelectionModel * selectionModel() const
text
virtual QByteArray text(quint32 serialNumber) const =0
QFrame::setFrameShape
void setFrameShape(Shape)
KMail::AntiSpamWizard::WizardMode
WizardMode
The wizard can be used for setting up anti-spam tools and for setting up anti-virus tools...
Definition: antispamwizard.h:112
QLabel::setPixmap
void setPixmap(const QPixmap &)
QSizePolicy
KMail::AntiSpamWizard::SpamToolConfig::isServerBased
bool isServerBased() const
Definition: antispamwizard.cpp:719
KMail::AntiSpamWizard::ConfigReader::readAndMergeConfig
void readAndMergeConfig()
Definition: antispamwizard.cpp:742
QWidget::isVisible
bool isVisible() const
QHBoxLayout
QListView::setLayoutMode
void setLayoutMode(LayoutMode mode)
KMail::ASWizSpamRulesPage::selectionChanged
void selectionChanged()
QGridLayout
KMail::ASWizVirusRulesPage
Definition: antispamwizard.h:369
QLabel::clear
void clear()
kmmainwin.h
KMail::ASWizSummaryPage::ASWizSummaryPage
ASWizSummaryPage(QWidget *parent, const QString &name)
Definition: antispamwizard.cpp:1242
QBoxLayout::addSpacing
void addSpacing(int size)
QListWidget
QList::const_iterator
QListWidget::addItem
void addItem(const QString &label)
KMail::ASWizPage
Definition: antispamwizard.h:293
QGridLayout::setSpacing
void setSpacing(int spacing)
QList::value
T value(int i) const
QString::clear
void clear()
KAssistantDialog
KMail::ASWizInfoPage
Definition: antispamwizard.h:304
KMail::ASWizSpamRulesPage::moveUnsureSelected
bool moveUnsureSelected() const
Definition: antispamwizard.cpp:1076
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QString::number
QString number(int n, int base)
KMail::ASWizVirusRulesPage::selectionChanged
void selectionChanged()
QList::append
void append(const T &value)
KMail::AntiSpamWizard::ConfigReader::getToolList
QList< SpamToolConfig > & getToolList()
Definition: antispamwizard.h:226
QCheckBox
KMail::ASWizSpamRulesPage
Definition: antispamwizard.h:329
KMail::AntiSpamWizard::AntiSpamWizard
AntiSpamWizard(WizardMode mode, QWidget *parent)
Constructor that needs to initialize from the main folder tree of KMail.
Definition: antispamwizard.cpp:75
QList::isEmpty
bool isEmpty() const
QBoxLayout::addItem
virtual void addItem(QLayoutItem *item)
KMail::ASWizVirusRulesPage::selectedFolderName
QString selectedFolderName() const
Definition: antispamwizard.cpp:1227
QObject::setObjectName
void setObjectName(const QString &name)
QString::isEmpty
bool isEmpty() const
KMail::ASWizVirusRulesPage::ASWizVirusRulesPage
ASWizVirusRulesPage(QWidget *parent, const QString &name)
Definition: antispamwizard.cpp:1151
QLabel::setScaledContents
void setScaledContents(bool)
QVBoxLayout
KMail::AntiSpamWizard::SpamToolConfig::getVersion
int getVersion() const
Definition: antispamwizard.h:145
QLabel::setText
void setText(const QString &)
QItemSelectionModel::clearSelection
void clearSelection()
QString
QList
QWidget::hide
void hide()
QLayout::setMargin
void setMargin(int margin)
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
QListWidget::setCurrentRow
void setCurrentRow(int row)
KMail::ASWizSummaryPage
Definition: antispamwizard.h:395
QString::toLower
QString toLower() const
KMail::ASWizSpamRulesPage::selectedUnsureCollectionId
QString selectedUnsureCollectionId() const
Definition: antispamwizard.cpp:1113
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
KMail::ASWizVirusRulesPage::markReadRulesSelected
bool markReadRulesSelected() const
Definition: antispamwizard.cpp:1221
QFrame::setFrameShadow
void setFrameShadow(Shadow)
QAbstractButton::setChecked
void setChecked(bool)
QItemSelection
kmkernel.h
KMail::ASWizInfoPage::selectionChanged
void selectionChanged()
KMail::AntiSpamWizard::ConfigReader::~ConfigReader
~ConfigReader()
Definition: antispamwizard.cpp:737
QWidget::setWhatsThis
void setWhatsThis(const QString &)
KMail::AntiSpamWizard::ConfigReader::ConfigReader
ConfigReader(WizardMode mode, QList< SpamToolConfig > &configList)
Definition: antispamwizard.cpp:726
KMail::AntiSpamWizard::slotBuildSummary
void slotBuildSummary()
Create the summary text based on the current settings.
Definition: antispamwizard.cpp:588
QLatin1String
QBoxLayout::addStretch
void addStretch(int stretch)
KMail::AntiSpamWizard::SpamToolConfig::getId
QString getId() const
Definition: antispamwizard.h:147
KMail::AntiSpamWizard::SpamToolConfig::SpamToolConfig
SpamToolConfig()
Definition: antispamwizard.h:134
KMail::AntiSpamWizard::SpamToolConfig
Instances of this class store the settings for one tool as read from the config file.
Definition: antispamwizard.h:131
KMail::ASWizInfoPage::setScanProgressText
void setScanProgressText(const QString &toolName)
Definition: antispamwizard.cpp:967
KMail::AntiSpamWizard::AntiSpam
Definition: antispamwizard.h:112
KMail::AntiSpamWizard::accept
void accept()
Evaluate the settings made and create the appropriate filter rules.
Definition: antispamwizard.cpp:148
KMail::ASWizSpamRulesPage::allowUnsureFolderSelection
void allowUnsureFolderSelection(bool enabled)
Definition: antispamwizard.cpp:1133
KMail::ASWizInfoPage::isProgramSelected
bool isProgramSelected(const QString &visibleName) const
Definition: antispamwizard.cpp:987
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QListWidget::findItems
QList< QListWidgetItem * > findItems(const QString &text, QFlags< Qt::MatchFlag > flags) const
QWidget::show
void show()
QTextEdit::setReadOnly
void setReadOnly(bool ro)
KMail::ASWizSpamRulesPage::selectedSpamCollection
Akonadi::Collection selectedSpamCollection() const
Definition: antispamwizard.cpp:1091
QListView::setBatchSize
void setBatchSize(int batchSize)
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
KMail::AntiSpamWizard::ConfigReader
Instances of this class control reading the configuration of the anti-spam tools from global and user...
Definition: antispamwizard.h:219
KMail::ASWizSpamRulesPage::ASWizSpamRulesPage
ASWizSpamRulesPage(QWidget *parent, const QString &name)
Definition: antispamwizard.cpp:1001
KMail::ASWizSpamRulesPage::allowMoveSpam
void allowMoveSpam(bool enabled)
Definition: antispamwizard.cpp:1141
KMail::ASWizPage::ASWizPage
ASWizPage(QWidget *parent, const QString &name)
Definition: antispamwizard.cpp:886
KMail::ASWizVirusRulesPage::pipeRulesSelected
bool pipeRulesSelected() const
Definition: antispamwizard.cpp:1210
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QLabel
QTextEdit
KMail::AntiSpamWizard::slotHelpClicked
void slotHelpClicked()
Show a help topic.
Definition: antispamwizard.cpp:582
QTextEdit::setText
void setText(const QString &text)
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KMail::AntiSpamWizard::checkVirusRulesSelections
void checkVirusRulesSelections()
Modify the status of the wizard to reflect the selected functionality.
Definition: antispamwizard.cpp:508
KMail::ASWizVirusRulesPage::moveRulesSelected
bool moveRulesSelected() const
Definition: antispamwizard.cpp:1216
QBoxLayout
KMail::AntiSpamWizard::AntiVirus
Definition: antispamwizard.h:112
QLabel::setWordWrap
void setWordWrap(bool on)
KMail::ASWizSpamRulesPage::moveSpamSelected
bool moveSpamSelected() const
Definition: antispamwizard.cpp:1070
QBoxLayout::setSpacing
void setSpacing(int spacing)
KMail::ASWizSpamRulesPage::selectedSpamCollectionId
QString selectedSpamCollectionId() const
Definition: antispamwizard.cpp:1081
KMail::ASWizInfoPage::ASWizInfoPage
ASWizInfoPage(AntiSpamWizard::WizardMode mode, QWidget *parent, const QString &name)
Definition: antispamwizard.cpp:912
QTimer::singleShot
singleShot
KMail::AntiSpamWizard::checkToolAvailability
void checkToolAvailability()
Check if the spam tools are available via the PATH.
Definition: antispamwizard.cpp:514
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:32 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kmail

Skip menu "kmail"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal