37 #include <Akonadi/AgentInstance>
38 #include <Akonadi/AgentType>
39 #include <Akonadi/ItemFetchJob>
42 #include <KConfigGroup>
44 #include <KIconDialog>
45 #include <KIconLoader>
46 #include <KInputDialog>
48 #include <KKeySequenceWidget>
49 #include <KListWidgetSearchLine>
51 #include <KMessageBox>
52 #include <KPushButton>
54 #include <KWindowSystem>
56 #include <QApplication>
57 #include <QHeaderView>
58 #include <QButtonGroup>
60 #include <QGridLayout>
62 #include <QListWidget>
64 #include <QRadioButton>
65 #include <QTreeWidget>
66 #include <QVBoxLayout>
72 using namespace MailCommon;
74 namespace MailCommon {
76 AccountList::AccountList(
QWidget *parent )
80 QStringList headerNames;
81 headerNames << i18n(
"Account Name" ) << i18n(
"Type" );
82 setHeaderItem(
new QTreeWidgetItem( headerNames ) );
83 setAllColumnsShowFocus(
true );
84 setFrameStyle( QFrame::WinPanel + QFrame::Sunken );
85 setSortingEnabled(
false );
86 setRootIsDecorated(
false );
87 setSortingEnabled(
true );
88 sortByColumn( 0, Qt::AscendingOrder );
89 header()->setMovable(
false );
100 QTreeWidgetItem *top = 0;
104 blockSignals(
true );
106 const int nbAccount = lst.count();
107 for (
int i = 0; i <nbAccount; ++i ) {
108 const Akonadi::AgentInstance agent = lst.at( i );
109 QTreeWidgetItem *listItem =
new QTreeWidgetItem(
this, top );
110 listItem->setText( 0, agent.name() );
111 listItem->setText( 1, agent.type().name() );
112 listItem->setText( 2, agent.identifier() );
114 listItem->setCheckState( 0,
121 blockSignals(
false );
125 resizeColumnToContents( 0 );
126 resizeColumnToContents( 1 );
128 top = topLevelItem( 0 );
130 setCurrentItem( top );
136 QTreeWidgetItemIterator it(
this );
138 while ( QTreeWidgetItem *item = *it ) {
139 const QString
id = item->text( 2 );
149 QTreeWidgetItem *top = 0;
153 blockSignals(
true );
155 const int nbAccount = lst.count();
156 for (
int i = 0; i <nbAccount; ++i ) {
157 const Akonadi::AgentInstance agent = lst.at( i );
158 QTreeWidgetItem *listItem =
new QTreeWidgetItem(
this, top );
159 listItem->setText( 0, agent.name() );
160 listItem->setText( 1, agent.type().name() );
161 listItem->setText( 2, agent.identifier() );
162 listItem->setCheckState( 0, lstAccount.contains( agent.identifier() ) ?
163 Qt::Checked : Qt::Unchecked );
166 blockSignals(
false );
170 resizeColumnToContents( 0 );
171 resizeColumnToContents( 1 );
173 top = topLevelItem( 0 );
175 setCurrentItem( top );
181 QStringList lstAccount;
182 QTreeWidgetItemIterator it(
this );
184 while ( QTreeWidgetItem *item = *it ) {
185 if ( item->checkState( 0 ) == Qt::Checked ) {
186 lstAccount << item->text( 2 );
206 setCheckState( filter->
isEnabled() ? Qt::Checked : Qt::Unchecked );
216 I18N_NOOP(
"<qt><p>This is the list of defined filters. "
217 "They are processed top-to-bottom.</p>"
218 "<p>Click on any filter to edit it "
219 "using the controls in the right-hand half "
220 "of the dialog.</p></qt>" );
223 I18N_NOOP(
"<qt><p>Click this button to create a new filter.</p>"
224 "<p>The filter will be inserted just before the currently-"
225 "selected one, but you can always change that "
227 "<p>If you have clicked this button accidentally, you can undo this "
228 "by clicking on the <em>Delete</em> button.</p></qt>" );
231 I18N_NOOP(
"<qt><p>Click this button to copy a filter.</p>"
232 "<p>If you have clicked this button accidentally, you can undo this "
233 "by clicking on the <em>Delete</em> button.</p></qt>" );
236 I18N_NOOP(
"<qt><p>Click this button to <em>delete</em> the currently-"
237 "selected filter from the list above.</p>"
238 "<p>There is no way to get the filter back once "
239 "it is deleted, but you can always leave the "
240 "dialog by clicking <em>Cancel</em> to discard the "
241 "changes made.</p></qt>" );
244 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
245 "selected filter <em>up</em> one in the list above.</p>"
246 "<p>This is useful since the order of the filters in the list "
247 "determines the order in which they are tried on messages: "
248 "The topmost filter gets tried first.</p>"
249 "<p>If you have clicked this button accidentally, you can undo this "
250 "by clicking on the <em>Down</em> button.</p></qt>" );
253 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
254 "selected filter <em>down</em> one in the list above.</p>"
255 "<p>This is useful since the order of the filters in the list "
256 "determines the order in which they are tried on messages: "
257 "The topmost filter gets tried first.</p>"
258 "<p>If you have clicked this button accidentally, you can undo this "
259 "by clicking on the <em>Up</em> button.</p></qt>" );
262 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
263 "selected filter to top of list.</p>"
264 "<p>This is useful since the order of the filters in the list "
265 "determines the order in which they are tried on messages: "
266 "The topmost filter gets tried first.</p></qt>" );
269 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
270 "selected filter to bottom of list.</p>"
271 "<p>This is useful since the order of the filters in the list "
272 "determines the order in which they are tried on messages: "
273 "The topmost filter gets tried first.</p></qt>" );
276 I18N_NOOP(
"<qt><p>Click this button to rename the currently-selected filter.</p>"
277 "<p>Filters are named automatically, as long as they start with "
279 "<p>If you have renamed a filter accidentally and want automatic "
280 "naming back, click this button and select <em>Clear</em> followed "
281 "by <em>OK</em> in the appearing dialog.</p></qt>" );
284 I18N_NOOP(
"<qt><p>Check this button to force the confirmation dialog to be "
285 "displayed.</p><p>This is useful if you have defined a ruleset that tags "
286 "messages to be downloaded later. Without the possibility to force "
287 "the dialog popup, these messages could never be downloaded if no "
288 "other large messages were waiting on the server, or if you wanted to "
289 "change the ruleset to tag the messages differently.</p></qt>" );
300 QWidget *parent,
bool createDummyFilter )
303 mDoNotClose( false ),
304 mIgnoreFilterUpdates( true )
306 setCaption( i18n(
"Filter Rules" ) );
307 setButtons( Help|Ok|Apply|Cancel|User1|User2|User3);
309 setButtonFocus( Ok );
310 KWindowSystem::setIcons( winId(),
311 qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
312 IconSize( KIconLoader::Desktop ) ),
313 qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
314 IconSize( KIconLoader::Small ) ) );
315 setHelp( QLatin1String(
"filters"), QLatin1String(
"kmail") );
316 setButtonText( User1, i18n(
"Import..." ) );
317 setButtonText( User2, i18n(
"Export..." ) );
318 setButtonText( User3, i18n(
"Convert to..." ) );
319 QMenu *menu =
new QMenu();
321 QAction *act =
new QAction( i18n(
"KMail filters" ),
this );
323 menu->addAction( act );
325 act =
new QAction( i18n(
"Thunderbird filters" ),
this );
327 menu->addAction( act );
329 act =
new QAction( i18n(
"Evolution filters" ),
this );
331 menu->addAction( act );
333 act =
new QAction( i18n(
"Sylpheed filters" ),
this );
335 menu->addAction( act );
337 act =
new QAction( i18n(
"Procmail filters" ),
this );
339 menu->addAction( act );
341 act =
new QAction( i18n(
"Balsa filters" ),
this );
343 menu->addAction( act );
345 act =
new QAction( i18n(
"Claws Mail filters" ),
this );
347 menu->addAction( act );
349 connect( menu, SIGNAL(triggered(QAction*)), SLOT(
slotImportFilter(QAction*)) );
351 button( KDialog::User1 )->setMenu( menu );
355 act =
new QAction( i18n(
"Sieve script" ),
this );
356 connect(act, SIGNAL(triggered(
bool)), SLOT(slotExportAsSieveScript()));
357 menu->addAction( act );
358 button( KDialog::User3 )->setMenu( menu );
361 connect(
this, SIGNAL(user2Clicked()),
363 enableButtonApply(
false );
367 QVBoxLayout *topVLayout =
new QVBoxLayout( w );
368 QHBoxLayout *topLayout =
new QHBoxLayout;
369 topVLayout->addLayout( topLayout );
370 topLayout->setSpacing( spacingHint() );
371 topLayout->setMargin( 0 );
372 QVBoxLayout *vbl2 = 0;
374 QSplitter *splitter =
new QSplitter;
375 splitter->setChildrenCollapsible(
false);
376 topLayout->addWidget(splitter);
380 KTabWidget *tabWidget =
new KTabWidget;
381 splitter->addWidget(tabWidget);
384 tabWidget->addTab( page1, i18nc(
"General mail filter settings.",
"General" ) );
385 QHBoxLayout * hbl =
new QHBoxLayout( page1 );
386 hbl->setSpacing( spacingHint() );
387 hbl->setMargin( marginHint() );
390 tabWidget->addTab( page2, i18nc(
"Advanced mail filter settings.",
"Advanced" ) );
391 vbl2 =
new QVBoxLayout( page2 );
392 vbl2->setSpacing( spacingHint() );
393 vbl2->setMargin( marginHint() );
395 QVBoxLayout *vbl =
new QVBoxLayout();
396 hbl->addLayout( vbl );
397 vbl->setSpacing( spacingHint() );
398 hbl->setStretchFactor( vbl, 2 );
401 QHBoxLayout *layout =
new QHBoxLayout( patternGroupBox );
407 vbl->addWidget( patternGroupBox, 0, Qt::AlignTop );
410 QHBoxLayout *layout2 =
new QHBoxLayout;
413 agb->setLayout( layout2 );
414 vbl->addWidget( agb, 0, Qt::AlignTop );
418 QGridLayout *gl =
new QGridLayout();
419 QVBoxLayout *vbl3 =
new QVBoxLayout();
420 gl->addLayout( vbl3, 0, 0 );
421 vbl3->setSpacing( spacingHint() );
422 vbl3->addStretch( 1 );
434 new QRadioButton( i18n(
"from all but online IMAP accounts" ),
mAdvOptsGroup );
439 new QRadioButton( i18n(
"from checked accounts only" ),
mAdvOptsGroup );
442 vbl3->addStretch( 2 );
448 new QCheckBox( i18n(
"Apply this filter to &sent messages" ),
mAdvOptsGroup );
450 i18n(
"<p>The filter will be triggered <b>after</b> the message is sent "
451 "and it will only affect the local copy of the message.</p>"
452 "<p>If the recipient's copy also needs to be modified, "
453 "please use \"Apply this filter <b>before</b> sending messages\".</p>" ) );
457 new QCheckBox( i18n(
"Apply this filter &before sending messages" ),
mAdvOptsGroup );
459 i18n(
"<p>The filter will be triggered <b>before</b> the message is sent "
460 "and it will affect both the local copy and the sent copy of the message.</p>"
461 "<p>This is required if the recipient's copy also needs to be modified.</p>" ) );
466 new QCheckBox( i18n(
"Apply this filter on manual &filtering" ),
mAdvOptsGroup );
470 new QCheckBox( i18n(
"If this filter &matches, stop processing here" ),
mAdvOptsGroup );
474 new QCheckBox( i18n(
"Add this filter to the Apply Filter menu" ),
mAdvOptsGroup );
477 QLabel *keyButtonLabel =
new QLabel( i18n(
"Shortcut:" ),
mAdvOptsGroup );
478 keyButtonLabel->setAlignment( Qt::AlignVCenter | Qt::AlignRight );
479 gl->addWidget( keyButtonLabel, 8, 2, 1, 1 );
482 mKeySeqWidget->setObjectName( QLatin1String(
"FilterShortcutSelector") );
486 mKeySeqWidget->setCheckActionCollections( actionCollection );
489 new QCheckBox( i18n(
"Additionally add this filter to the toolbar" ),
mAdvOptsGroup );
504 gl->addWidget( hbox, 10, 0, 1, 4 );
510 QHBoxLayout *applySpecificFiltersLayout =
new QHBoxLayout;
511 QLabel *lab =
new QLabel( i18n(
"Run selected filter(s) on: " ) );
512 applySpecificFiltersLayout->addWidget( lab );
518 mRunNow =
new KPushButton( i18n(
"Run Now" ) );
520 applySpecificFiltersLayout->addWidget(
mRunNow );
522 topVLayout->addLayout( applySpecificFiltersLayout );
524 vbl->addStretch( 1 );
546 connect(
mAccountList, SIGNAL(itemChanged(QTreeWidgetItem*,
int)),
557 connect(
mKeySeqWidget, SIGNAL(keySequenceChanged(QKeySequence)),
578 connect(
this, SIGNAL(buttonClicked(KDialog::ButtonCode)),
579 mFilterList, SLOT(slotApplyFilterChanges(KDialog::ButtonCode)) );
580 connect( button( KDialog::Apply ), SIGNAL(clicked(
bool)),
this, SLOT(
slotApply()) );
583 connect(
this, SIGNAL(okClicked()),
587 connect(
this, SIGNAL(closeClicked()),
589 connect(
this, SIGNAL(cancelClicked()),
607 KConfigGroup myGroup(
KernelIf->config(),
"Geometry" );
608 const QSize size = myGroup.readEntry(
"filterDialogSize", QSize() );
609 if ( size != QSize() ) {
632 enableButtonApply(
false );
642 mRunNow->setEnabled( collection.isValid() );
648 KMessageBox::information(
651 "Unable to apply this filter since there are no folders selected." ),
652 i18n(
"No folder selected." ) );
656 if ( isButtonEnabled( KDialog::Apply ) ) {
657 KMessageBox::information(
660 "Some filters were changed and not saved yet. "
661 "You must save your filters before they can be applied." ),
662 i18n(
"Filters changed." ) );
667 if ( selectedFiltersId.isEmpty() ) {
668 KMessageBox::information(
671 "Unable to apply a filter since there are no filters currently selected." ),
672 i18n(
"No filters selected." ) );
676 job->setProperty(
"requiredPart", QVariant::fromValue( requiredPart ) );
677 job->setProperty(
"listFilters", QVariant::fromValue( selectedFiltersId ) );
679 connect( job, SIGNAL(result(KJob*)),
687 Akonadi::ItemFetchJob *fjob =
dynamic_cast<Akonadi::ItemFetchJob*
>( job );
690 QStringList filtersId;
691 if ( fjob->property(
"listFilters" ).isValid() ) {
692 filtersId = fjob->property(
"listFilters" ).toStringList();
696 if ( fjob->property(
"requiredPart" ).isValid() ) {
699 Akonadi::Item::List items = fjob->items();
705 KConfigGroup myGroup(
KernelIf->config(),
"Geometry" );
706 myGroup.writeEntry(
"filterDialogSize", size() );
738 const QString icon = aFilter->
icon();
739 const KShortcut shortcut( aFilter->
shortcut() );
756 KKeySequenceWidget::NoValidate );
804 kDebug() <<
"Setting filter to be applied at"
819 while ( QTreeWidgetItem *item = *it ) {
820 const QString
id = item->text( 2 );
897 QVBoxLayout *layout =
new QVBoxLayout();
903 mListWidget->setDragDropMode( QAbstractItemView::InternalMove );
904 mListWidget->setSelectionMode( QAbstractItemView::ExtendedSelection );
906 SIGNAL(rowsMoved(QModelIndex,
int,
int,QModelIndex,
int)),
909 KListWidgetSearchLine *mSearchListWidget =
new KListWidgetSearchLine(
this,
mListWidget );
910 mSearchListWidget->setTrapReturnKey(
true );
911 mSearchListWidget->setClickMessage(
912 i18nc(
"@info/plain Displayed grayed-out inside the textbox, verb to search",
915 layout->addWidget( mSearchListWidget );
922 mBtnTop =
new KPushButton( QString(), hb );
923 mBtnTop->setIcon( KIcon( QLatin1String(
"go-top") ) );
924 mBtnTop->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
927 mBtnUp =
new KPushButton( QString(), hb );
928 mBtnUp->setAutoRepeat(
true );
929 mBtnUp->setIcon( KIcon( QLatin1String(
"go-up") ) );
930 mBtnUp->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
932 mBtnDown =
new KPushButton( QString(), hb );
934 mBtnDown->setIcon( KIcon( QLatin1String(
"go-down") ) );
935 mBtnDown->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
938 mBtnBottom =
new KPushButton( QString(), hb );
939 mBtnBottom->setIcon( KIcon( QLatin1String(
"go-bottom") ) );
940 mBtnBottom->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
943 mBtnUp->setToolTip( i18nc(
"Move selected filter up.",
"Up" ) );
944 mBtnDown->setToolTip( i18nc(
"Move selected filter down.",
"Down" ) );
945 mBtnTop->setToolTip( i18nc(
"Move selected filter to the top.",
"Top" ) );
946 mBtnBottom->setToolTip( i18nc(
"Move selected filter to the bottom.",
"Bottom" ) );
947 mBtnUp->setWhatsThis( i18n( _wt_filterlist_up ) );
948 mBtnDown->setWhatsThis( i18n( _wt_filterlist_down ) );
949 mBtnBottom->setWhatsThis( i18n( _wt_filterlist_bottom ) );
950 mBtnTop->setWhatsThis( i18n( _wt_filterlist_top ) );
952 layout->addWidget( hb );
955 hb =
new KHBox(
this );
957 mBtnNew =
new QPushButton( QString(), hb );
958 mBtnNew->setIcon( KIcon( QLatin1String(
"document-new") ) );
959 mBtnNew->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
961 mBtnCopy =
new QPushButton( QString(), hb );
962 mBtnCopy->setIcon( KIcon( QLatin1String(
"edit-copy") ) );
963 mBtnCopy->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
965 mBtnDelete =
new QPushButton( QString(), hb );
966 mBtnDelete->setIcon( KIcon( QLatin1String(
"edit-delete") ) );
967 mBtnDelete->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
969 mBtnRename =
new QPushButton( i18n(
"Rename..." ), hb );
970 mBtnNew->setToolTip( i18nc(
"@action:button in filter list manipulator",
"New" ) );
971 mBtnCopy->setToolTip( i18n(
"Copy" ) );
973 mBtnNew->setWhatsThis( i18n( _wt_filterlist_new ) );
974 mBtnCopy->setWhatsThis( i18n( _wt_filterlist_copy ) );
975 mBtnDelete->setWhatsThis( i18n( _wt_filterlist_delete ) );
976 mBtnRename->setWhatsThis( i18n( _wt_filterlist_rename ) );
978 layout->addWidget( hb );
981 QShortcut *shortcut =
new QShortcut(
this );
982 shortcut->setKey( Qt::Key_Delete );
983 connect( shortcut, SIGNAL(activated()), SLOT(
slotDelete()) );
986 connect(
mListWidget, SIGNAL(currentRowChanged(
int)),
993 connect(
mListWidget, SIGNAL(itemSelectionChanged()),
996 connect(
mBtnUp, SIGNAL(clicked()),
998 connect(
mBtnDown, SIGNAL(clicked()),
1000 connect(
mBtnTop, SIGNAL(clicked()),
1005 connect(
mBtnNew, SIGNAL(clicked()),
1007 connect(
mBtnCopy, SIGNAL(clicked()),
1026 kDebug() <<
"Called while no filter is selected, ignoring.";
1029 if ( item->isHidden() ) {
1038 kDebug() <<
"Called while no filter is selected, ignoring.";
1043 filter->
setEnabled( ( item->checkState() == Qt::Checked ) );
1048 int sourcestart,
int sourceEnd,
1049 const QModelIndex &,
int destinationRow )
1051 Q_UNUSED( sourceEnd );
1052 Q_UNUSED( sourcestart );
1053 Q_UNUSED( destinationRow );
1064 newFilter->
pattern()->append( newRule );
1065 newFilter->
pattern()->
setName( QString::fromLatin1(
"<%1>: %2" ).
1066 arg( QString::fromLatin1( field ) ).
1082 kDebug() <<
"Called while no filter is selected, ignoring.";
1093 QString shouldBeName = p->
name();
1094 QString displayedName = itemFilter->text();
1096 if ( shouldBeName.trimmed().isEmpty() ) {
1102 if ( !p->isEmpty() && p->first() && !p->first()->field().trimmed().isEmpty() ) {
1103 shouldBeName = QString::fromLatin1(
"<%1>: %2" ).
1104 arg( QString::fromLatin1( p->first()->field() ) ).
1105 arg( p->first()->contents() );
1107 shouldBeName = QLatin1Char(
'<') + i18n(
"unnamed" ) + QLatin1Char(
'>');
1112 if ( displayedName == shouldBeName ) {
1119 itemFilter->setText( shouldBeName );
1125 bool closeAfterSaving;
1126 if ( button == KDialog::Ok ) {
1127 closeAfterSaving =
true;
1128 }
else if ( button == KDialog::Apply ) {
1129 closeAfterSaving =
false;
1151 QStringList emptyFilters;
1153 for (
int i = 0; i <numberOfFilter; ++i ) {
1161 filters.append( f );
1164 emptyFilters << f->
name();
1170 if ( !emptyFilters.empty() ) {
1171 if ( closeAfterSaving ) {
1174 KMessageBox::warningContinueCancelList(
1176 i18n(
"The following filters are invalid (e.g. containing no actions "
1177 "or no search rules). Discard or edit invalid filters?" ),
1180 KGuiItem( i18n(
"Discard" ) ),
1181 KStandardGuiItem::cancel(),
1182 QLatin1String(
"ShowInvalidFilterWarning") );
1183 if ( response == KMessageBox::Cancel ) {
1188 KMessageBox::informationList(
1190 i18n(
"The following filters have not been saved because they were invalid "
1191 "(e.g. containing no actions or no search rules)." ),
1194 QLatin1String(
"ShowInvalidFilterWarning") );
1210 if ( aIdx >= 0 && aIdx < mListWidget->count() ) {
1229 if ( item && item->isHidden() ) {
1240 if ( !itemIsValid( item ) ) {
1265 if ( !itemIsValid( itemFirst ) ) {
1268 const bool uniqFilterSelected = (
mListWidget->selectedItems().count() == 1 );
1272 const QString filterName = filter->
pattern()->
name();
1273 if ( uniqFilterSelected ) {
1274 if ( KMessageBox::questionYesNo(
1276 i18n(
"Do you want to remove the filter \"%1\"?",filterName ),
1277 i18n(
"Remove Filter" ) ) == KMessageBox::No ) {
1281 if ( KMessageBox::questionYesNo(
1283 i18n(
"Do you want to remove selected filters?" ),
1284 i18n(
"Remove Filters" ) ) == KMessageBox::No ) {
1289 const int oIdxSelItem =
mListWidget->currentRow();
1306 if ( count > oIdxSelItem ) {
1309 }
else if ( count ) {
1320 if ( oIdxSelItem == 0 ) {
1331 if ( listWidgetItem.isEmpty() ) {
1335 const int numberOfItem( listWidgetItem.count() );
1336 if ( ( numberOfItem == 1 ) && (
mListWidget->currentRow() == 0 ) ) {
1337 kDebug() <<
"Called while the _topmost_ filter is selected, ignoring.";
1342 bool wasMoved =
false;
1343 for (
int i = 0; i<numberOfItem; ++i ) {
1344 const int posItem =
mListWidget->row( listWidgetItem.at( i ) );
1345 if ( posItem == i ) {
1363 for (
int i = 0; i<numberOfFilters; ++i ) {
1368 return listWidgetItem;
1373 QStringList listFilterId;
1376 for (
int i = 0; i <numberOfFilters; ++i ) {
1381 requiredPart = qMax(requiredPart,
1382 static_cast<QListWidgetFilterItem*>(
mListWidget->item( i ) )->filter()->requiredPart(resource));
1385 return listFilterId;
1391 if ( listWidgetItem.isEmpty() ) {
1395 const int numberOfElement(
mListWidget->count() );
1396 const int numberOfItem( listWidgetItem.count() );
1397 if ( ( numberOfItem == 1 ) && (
mListWidget->currentRow() == numberOfElement - 1 ) ) {
1398 kDebug() <<
"Called while the _last_ filter is selected, ignoring.";
1404 bool wasMoved =
false;
1405 for (
int i = numberOfItem-1; i>= 0; --i, j++ ) {
1406 const int posItem =
mListWidget->row( listWidgetItem.at( i ) );
1407 if ( posItem == ( numberOfElement-1 -j ) ) {
1411 mListWidget->insertItem( numberOfElement-j, item );
1424 if ( listWidgetItem.isEmpty() ) {
1428 const int numberOfItem( listWidgetItem.count() );
1429 if ( ( numberOfItem == 1 ) && (
mListWidget->currentRow() == 0 ) ) {
1430 kDebug() <<
"Called while the _topmost_ filter is selected, ignoring.";
1433 bool wasMoved =
false;
1435 for (
int i = 0; i<numberOfItem; ++i ) {
1436 const int posItem =
mListWidget->row( listWidgetItem.at( i ) );
1437 if ( posItem == i ) {
1440 swapNeighbouringFilters( posItem, posItem - 1 );
1452 if ( listWidgetItem.isEmpty() ) {
1456 const int numberOfElement(
mListWidget->count() );
1457 const int numberOfItem( listWidgetItem.count() );
1458 if ( ( numberOfItem == 1 ) && (
mListWidget->currentRow() == numberOfElement - 1 ) ) {
1459 kDebug() <<
"Called while the _last_ filter is selected, ignoring.";
1464 bool wasMoved =
false;
1465 for (
int i = numberOfItem-1; i>= 0; --i, j++ ) {
1466 const int posItem =
mListWidget->row( listWidgetItem.at( i ) );
1467 if ( posItem == ( numberOfElement-1 -j ) ) {
1470 swapNeighbouringFilters( posItem, posItem + 1 );
1483 if ( !itemIsValid(item) ) {
1488 bool okPressed =
false;
1496 QValidator *validator =
new QRegExpValidator( QRegExp( QLatin1String(
".*") ), 0 );
1498 KInputDialog::getText (
1499 i18n(
"Rename Filter" ),
1500 i18n(
"Rename filter \"%1\" to:\n(leave the field empty for automatic naming)",
1512 if ( newName.isEmpty() ) {
1527 void KMFilterListBox::enableControls()
1529 const int currentIndex =
mListWidget->currentRow();
1530 const bool theFirst = ( currentIndex == 0 );
1531 const int numberOfElement(
mListWidget->count() );
1532 const bool theLast = ( currentIndex >= numberOfElement - 1 );
1533 const bool aFilterIsSelected = ( currentIndex >= 0 );
1535 const int numberOfSelectedItem(
mListWidget->selectedItems().count() );
1536 const bool uniqFilterSelected = ( numberOfSelectedItem == 1 );
1537 const bool allItemSelected = ( numberOfSelectedItem == numberOfElement );
1539 mBtnUp->setEnabled( aFilterIsSelected && ( ( uniqFilterSelected && !theFirst ) ||
1540 ( !uniqFilterSelected ) ) && !allItemSelected );
1541 mBtnDown->setEnabled( aFilterIsSelected &&
1542 ( ( uniqFilterSelected && !theLast ) ||
1543 ( !uniqFilterSelected ) ) && !allItemSelected );
1545 mBtnCopy->setEnabled( aFilterIsSelected && uniqFilterSelected );
1547 mBtnRename->setEnabled( aFilterIsSelected && uniqFilterSelected );
1549 mBtnTop->setEnabled( aFilterIsSelected &&
1550 ( ( uniqFilterSelected && !theFirst ) ||
1551 ( !uniqFilterSelected ) ) && !allItemSelected );
1554 ( ( uniqFilterSelected && !theLast ) ||
1555 ( !uniqFilterSelected ) ) && !allItemSelected );
1556 if ( aFilterIsSelected ) {
1564 setEnabled(
false );
1568 blockSignals(
true );
1581 blockSignals(
false);
1588 if ( !numberOfItem && createDummyFilter ) {
1592 if ( numberOfItem > 0 ) {
1602 Q_ASSERT( aFilter );
1603 const int currentIndex =
mListWidget->currentRow();
1609 if ( currentIndex < 0 ) {
1631 void KMFilterListBox::swapNeighbouringFilters(
int untouchedOne,
int movedOne )
1634 Q_ASSERT( untouchedOne - movedOne == 1 || movedOne - untouchedOne == 1 );
1654 bool canceled =
false;
1660 if ( filters.isEmpty() ) {
1661 KMessageBox::information(
this, i18n(
"No filter was imported." ) );
1664 QStringList listOfFilter;
1669 listOfFilter << (*it)->name();
1672 KMessageBox::informationList(
1674 i18n(
"Filters which were imported:" ),
1692 kDebug() <<
"Detected a change in data bound to the dialog!";
1694 enableButtonApply(
true );
1698 void KMFilterDialog::slotExportAsSieveScript()
1700 if ( isButtonEnabled( KDialog::Apply ) ) {
1701 KMessageBox::information(
1704 "Some filters were changed and not saved yet. "
1705 "You must save your filters before they can be exported." ),
1706 i18n(
"Filters changed." ) );
1709 KMessageBox::information(
this, i18n(
"We cannot convert all KMail filters to sieve scripts but we can try :)"), i18n(
"Convert KMail filters to sieve scripts"));
1712 dlg->setFilters( filters );
1713 if ( dlg->exec() == QDialog::Accepted ) {
1715 if (!lst.isEmpty()) {
1726 #include "kmfilterdialog.moc"
~KMFilterListBox()
Destructor.
KKeySequenceWidget * mKeySeqWidget
void setConfigureShortcut(bool aShort)
Set whether this filter should be plugged into the filter menu.
void setFilters(const QList< MailCommon::MailFilter * > &filters)
Replace the list of filters of the filter manager with the given list of filters. ...
MAILCOMMON_EXPORT Akonadi::AgentInstance::List agentInstances(bool excludeMailTransport=true)
bool applyOnExplicit() const
QCheckBox * mApplyOnCtrlJ
QPushButton * mBtnNew
The various action buttons.
void filterRemoved(const QList< MailCommon::MailFilter * > &filter)
Emitted when a filter is deleted.
void updateSearchPattern()
Updates the search pattern according to the current widget values.
QCheckBox * mApplyOnIn
Lets the user select whether to apply this filter on inbound/outbound messages, both, or only on explicit CTRL-J.
KIconButton * mFilterActionIconButton
void slotDown()
Called when the user clicks the 'Down' button.
bool isEmpty() const
Check for empty pattern and action list.
const char * _wt_filterlist_down
void slotUpdateFilterName()
Called when the name of a filter might have changed (e.g.
const char * _wt_filterdlg_showLater
void slotApply()
Called wherenever the apply button is pressed.
void slotStopProcessingButtonToggled(bool aChecked)
void slotFilterActionIconChanged(const QString &icon)
const KShortcut & shortcut() const
void slotApplicableAccountsChanged()
void setApplyOnOutbound(bool aApply=true)
Set whether this filter should be applied on outbound messages (aApply == true) or not...
QCheckBox * mConfigureShortcut
void setShortcut(const KShortcut &shortcut)
Set the shortcut to be used if plugged into the filter menu or toolbar.
void abortClosing() const
Emitted when the user decides to continue editing after being warned about invalid filters...
QGroupBox * mAdvOptsGroup
void slotFinished()
Called when the dialog is closed (finished).
QList< FilterAction * > * actions()
Provides a reference to the internal action list.
boost::shared_ptr< SearchRule > Ptr
Defines a pointer to a search rule.
MailCommon::FilterActionWidgetLister * mActionLister
The widget that allows editing of the filter actions.
QListWidget * mListWidget
The listbox displaying the filter list.
const char * _wt_filterlist_delete
void insertFilter(MailCommon::MailFilter *aFilter)
MailCommon::SearchPatternEdit * mPatternEdit
The widget that allows editing of the filter pattern.
void filter(const Akonadi::Item &item, const QString &identifier, const QString &resourceId) const
Apply filters interface.
void purify()
Remove empty rules (and actions one day).
void applyWidgets()
Emitted when this widget wants the edit widgets to apply the changes to the current filter...
Akonadi::Collection collection() const
Returns the selected collection.
void slotDisableAccept()
Called when a user decides to continue editing invalid filters.
void setStopProcessingHere(bool aStop)
const char * _wt_filterlist_bottom
void slotFolderChanged(const Akonadi::Collection &)
void setApplyBeforeOutbound(bool aApply=true)
Set whether this filter should be applied on outbound messages before sending (aApply == TRUE) or not...
MailCommon::FolderRequester * mFolderRequester
void slotFilterEnabledChanged(QListWidgetItem *item)
QStringList selectedAccount()
void slotFilterSelected(MailCommon::MailFilter *aFilter)
Internally connected to KMFilterListBox::filterSelected.
Utility class that provides persisting of filters to/from KConfig.
void slotBottom()
Called when the user clicks the 'Bottom' button.
const char * _wt_filterlist_up
void setToolbarName(const QString &toolbarName)
This sets the toolbar name for this filter.
void slotFetchItemsForFolderDone(KJob *job)
A widget that contains a KLineEdit which shows the current folder and a button that fires a FolderSel...
void reset()
Called when the widget should let go of the currently referenced filter and disable itself...
bool applyOnOutbound() const
bool configureShortcut() const
bool configureToolbar() const
void filterSelected(MailCommon::MailFilter *filter)
Emitted when a new filter has been selected by the user or if the current filter has changed after a ...
QList< MailCommon::MailFilter * > filtersForSaving(bool closeAfterSaving) const
Returns a list of copies of the current list of filters.
This class is an abstraction of a search over messages.
void filterUpdated(MailCommon::MailFilter *filter)
Emitted when a filter is updated (e.g.
bool applyOnAccount(const QString &id) const
bool isEnabled() const
Return if filter is enabled or not.
void appendFilter(MailCommon::MailFilter *aFilter)
bool applyOnInbound() const
void createFilter(const QByteArray &field, const QString &value)
Called from KMFilterDialog.
void loadFilterList(bool createDummyFilter)
Loads the filter list and selects the first filter.
void filterCreated()
Emitted when a new filter is created.
QRadioButton * mApplyOnForChecked
const char * _wt_filterlist
bool stopProcessingHere() const
static FilterManager * instance()
Returns the global filter manager object.
void slotConfigureToolbarButtonToggled(bool aChecked)
void setNotAllowToCreateNewFolder(bool notCreateNewFolder)
Auxiliary struct for FilterActionDict.
static FilterActionDict * filterActionDict()
Returns the global filter action dictionary.
void slotNew()
Called when the user clicks the 'New' button.
void slotCopy()
Called when the user clicks the 'Copy' button.
void slotExportFilters()
Called when a user clicks the export filters button.
AccountList * mAccountList
ListView that shows the accounts in the advanced tab.
void slotApplyFilterChanges(KDialog::ButtonCode)
Called when the user clicks either 'Apply' or 'OK' in KMFilterDialog.
QRadioButton * mApplyOnForAll
For a filter applied to inbound messages selects whether to apply this filter to all accounts or to s...
const char * _wt_filterlist_new
KMFilterListBox(const QString &title, QWidget *parent=0)
Constructor.
void slotSelectionChanged()
void setSearchPattern(MailCommon::SearchPattern *aPattern)
Sets the search pattern.
void setIcon(const QString &icon)
Set the icon to be used if plugged into the filter menu or toolbar.
void exportFilters(const QList< MailFilter * > &filters, const KUrl &fileName=KUrl(), bool saveAll=false)
Exports the given filters to a file which is asked from the user.
AccountType applicability() const
void slotTop()
Called when the user clicks the 'Top' button.
void setApplicability(AccountType aApply=All)
Set whether this filter should be applied on inbound messages for all accounts (aApply == All) or inb...
void slotRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)
void resetWidgets()
Emitted when this widget wants the edit widgets to let go of their filter reference.
void slotUpdateAccountList()
Update the list of accounts shown in the advanced tab.
void slotApplicabilityChanged()
KMFilterDialog(const QList< KActionCollection * > &actionCollection, QWidget *parent=0, bool createDummyFilter=true)
Creates the filter dialog.
void slotShortcutChanged(const QKeySequence &newSeq)
void setConfigureToolbar(bool aTool)
Set whether this filter should be plugged into the toolbar.
KMFilterListBox * mFilterList
The widget that contains the ListBox showing the filters, and the controls to remove filters...
void setAutoNaming(bool useAutomaticNames)
Set the mode for using automatic naming for the filter.
QString name() const
Equivalent to ()->name().
void updateAccountList(MailCommon::MailFilter *filter)
void slotConfigureShortcutButtonToggled(bool aChecked)
QList< MailCommon::MailFilter * > filters() const
Returns the filter list of the manager.
void slotDialogUpdated()
Called whenever a change in the filters configuration is detected, to enable the Apply button...
FilterActionNewFunc create
QRadioButton * mApplyOnForTraditional
void setApplyOnExplicit(bool aApply=true)
Set whether this filter should be applied on explicit (CTRL-J) filtering (aApply == true) or not...
const char * _wt_filterlist_top
void setApplyOnInbound(bool aApply=true)
Set whether this filter should be applied on inbound messages (aApply == true) or not...
QCheckBox * mConfigureToolbar
QLabel * mFilterActionLabel
const char * _wt_filterlist_copy
static SearchRule::Ptr createInstance(const QByteArray &field=0, Function function=FuncContains, const QString &contents=QString())
Creates a new search rule of a certain type by instantiating the appropriate subclass depending on th...
void setApplyOnAccount(const QString &id, bool aApply=true)
Set whether this filter should be applied on inbound messages for the account with id (id)...
bool applyBeforeOutbound() const
MailCommon::MailFilter * mFilter
const char * _wt_filterlist_rename
void slotUp()
Called when the user clicks the 'Up' button.
bool isAutoNaming() const
virtual void accept()
Override QDialog::accept to allow disabling close.
void applyOnAccount(MailCommon::MailFilter *filter)
SearchPattern * pattern()
Provides a reference to the internal pattern.
void slotRename()
Called when the user clicks the 'Rename' button.
QStringList selectedFilterId(SearchRule::RequiredPart &requiredPart, const QString &resource) const
QCheckBox * mStopProcessingHere
void setName(const QString &newName)
Sets the name of the search pattern.
void slotSelected(int aIdx)
Called when the user clicks on a filter in the filter list.
bool mIgnoreFilterUpdates
void slotDelete()
Called when the user clicks the 'Delete' button.
QString name() const
Returns the name of the search pattern.
void filterOrderAltered()
Emitted whenever the order in which the filters are displayed is changed.
QCheckBox * mApplyBeforeOut
void slotImportFilter(QAction *)
Called when a user clicks the import filters button.