24 #include "standardmailactionmanager.h"
26 #include "emptytrashcommand_p.h"
27 #include "markascommand_p.h"
28 #include "movetotrashcommand_p.h"
29 #include "removeduplicatescommand_p.h"
30 #include "specialmailcollections.h"
32 #include "akonadi/agentfilterproxymodel.h"
33 #include "akonadi/agentinstance.h"
34 #include "akonadi/agentinstancecreatejob.h"
35 #include "akonadi/agentmanager.h"
36 #include "akonadi/agenttypedialog.h"
37 #include "akonadi/collectionstatistics.h"
38 #include "akonadi/entitytreemodel.h"
39 #include "akonadi/kmime/messagestatus.h"
40 #include "akonadi/mimetypechecker.h"
41 #include "akonadi/subscriptiondialog_p.h"
44 #include <kactioncollection.h>
46 #include <kmessagebox.h>
47 #include <kmime/kmime_message.h>
49 #include <QtCore/QPointer>
50 #include <QtGui/QItemSelectionModel>
52 using namespace Akonadi;
54 class StandardMailActionManager::Private
58 : mActionCollection( actionCollection ),
59 mParentWidget( parentWidget ),
60 mCollectionSelectionModel( 0 ),
61 mItemSelectionModel( 0 ),
70 mGenericManager->setMimeTypeFilter( QStringList() << KMime::Message::mimeType() );
71 mGenericManager->setCapabilityFilter( QStringList() << QLatin1String(
"Resource" ) );
76 delete mGenericManager;
79 void updateGenericAllActions()
124 i18n(
"Add Folder..." ) );
126 i18n(
"Add a new folder to the currently selected account." ) );
127 mGenericManager->setContextText(
129 i18nc(
"@title:window",
"New Folder" ) );
131 mGenericManager->setContextText(
133 ki18n(
"Could not create folder: %1" ) );
135 mGenericManager->setContextText(
137 i18n(
"Folder creation failed" ) );
142 ki18np(
"Copy Folder",
"Copy %1 Folders" ) );
144 i18n(
"Copy the selected folders to the clipboard." ) );
145 mGenericManager->setContextText(
147 ki18nc(
"@title:window",
"Properties of Folder %1" ) );
152 ki18np(
"Delete Folder",
"Delete %1 Folders" ) );
154 i18n(
"Delete the selected folders from the account." ) );
155 mGenericManager->setContextText(
157 ki18np(
"Do you really want to delete this folder and all its sub-folders?",
158 "Do you really want to delete %1 folders and all their sub-folders?" ) );
160 mGenericManager->setContextText(
162 ki18ncp(
"@title:window",
"Delete folder?",
"Delete folders?" ) );
164 mGenericManager->setContextText(
166 ki18n(
"Could not delete folder: %1" ) );
168 mGenericManager->setContextText(
170 i18n(
"Folder deletion failed" ) );
175 ki18np(
"Update Folder",
"Update Folders" ) );
178 i18n(
"Update the content of the selected folders." ) );
182 ki18np(
"Cut Folder",
"Cut %1 Folders" ) );
184 i18n(
"Cut the selected folders from the account." ) );
188 i18n(
"Folder Properties..." ) );
190 i18n(
"Open a dialog to edit the properties of the selected folder." ) );
194 ki18np(
"Copy Email",
"Copy %1 Emails" ) );
196 i18n(
"Copy the selected emails to the clipboard." ) );
200 ki18np(
"Delete Email",
"Delete %1 Emails" ) );
202 i18n(
"Delete the selected emails from the folder." ) );
203 mGenericManager->setContextText(
205 ki18np(
"Do you really want to delete the selected email?",
206 "Do you really want to delete %1 emails?" ) );
208 mGenericManager->setContextText(
210 ki18ncp(
"@title:window",
"Delete Email?",
"Delete Emails?" ) );
212 mGenericManager->setContextText(
214 ki18n(
"Could not delete email: %1" ) );
216 mGenericManager->setContextText(
218 i18n(
"Email deletion failed" ) );
222 ki18np(
"Cut Email",
"Cut %1 Emails" ) );
224 i18n(
"Cut the selected emails from the folder." ) );
228 i18n(
"Add &Account..." ) );
230 i18n(
"Add a new account<p>"
231 "You will be presented with a dialog where you can select "
232 "the type of the account that shall be added.</p>" ) );
233 mGenericManager->setContextText(
235 i18nc(
"@title:window",
"Add Account" ) );
237 mGenericManager->setContextText(
239 ki18n(
"Could not create account: %1" ) );
241 mGenericManager->setContextText(
243 i18n(
"Account creation failed" ) );
247 ki18np(
"&Delete Account",
"&Delete %1 Accounts" ) );
249 i18n(
"Delete the selected accounts<p>"
250 "The currently selected accounts will be deleted, "
251 "along with all the emails they contain.</p>" ) );
252 mGenericManager->setContextText(
254 ki18np(
"Do you really want to delete this account?",
255 "Do you really want to delete %1 accounts?" ) );
257 mGenericManager->setContextText(
259 ki18ncp(
"@title:window",
"Delete Account?",
"Delete Accounts?" ) );
263 i18n(
"Account Properties..." ) );
265 i18n(
"Open a dialog to edit properties of the selected account." ) );
269 ki18np(
"Update Account",
"Update %1 Accounts" ) );
271 i18n(
"Updates the content of all folders of the selected accounts." ) );
277 ki18np(
"Update folder and its subfolders",
"Update folders and their subfolders" ) );
280 i18n(
"Update the content of the selected folders and their subfolders." ) );
283 mGenericManager->setContextText(
285 ki18n(
"Could not paste email: %1" ) );
287 mGenericManager->setContextText(
289 i18n(
"Paste failed" ) );
302 bool itemIsSelected = !selectedItems.isEmpty();
303 bool collectionIsSelected = !selectedCollections.isEmpty();
305 if ( itemIsSelected ) {
306 bool allMarkedAsImportant =
true;
307 bool allMarkedAsRead =
true;
308 bool allMarkedAsUnread =
true;
309 bool allMarkedAsActionItem =
true;
315 allMarkedAsImportant =
false;
317 allMarkedAsRead=
false;
319 allMarkedAsUnread =
false;
321 allMarkedAsActionItem =
false;
326 updateMarkAction( action, allMarkedAsRead );
327 if ( allMarkedAsRead )
328 action->setEnabled(
false);
330 action->setEnabled(
true );
335 updateMarkAction( action, allMarkedAsUnread );
336 if ( allMarkedAsUnread )
337 action->setEnabled(
false);
339 action->setEnabled(
true );
344 updateMarkAction( action, allMarkedAsImportant );
345 if ( allMarkedAsImportant )
346 action->setText( i18n(
"Remove Important Mark" ) );
348 action->setText( i18n(
"&Mark Mail as Important" ) );
349 action->setEnabled(
true );
354 updateMarkAction( action, allMarkedAsActionItem );
355 if ( allMarkedAsActionItem )
356 action->setText( i18n(
"Remove Action Item Mark" ) );
358 action->setText( i18n(
"&Mark Mail as Action Item" ) );
359 action->setEnabled(
true );
364 action->setEnabled(
false );
368 action->setEnabled(
false );
372 action->setEnabled(
false );
375 bool enableMarkAllAsRead =
false;
376 bool enableMarkAllAsUnread =
false;
377 bool canDeleteItem =
true;
378 bool isSystemFolder =
false;
379 if ( collectionIsSelected ) {
380 foreach(
const Collection &collection, selectedCollections )
384 if ( !enableMarkAllAsRead )
386 if ( !enableMarkAllAsUnread )
390 if ( !isSystemFolder ) {
399 if ( enableMarkAllAsRead && enableMarkAllAsUnread && !canDeleteItem && isSystemFolder )
404 if ( isSystemFolder ) {
417 action->setEnabled( enableMarkAllAsRead );
422 action->setEnabled( enableMarkAllAsUnread );
425 emit mParent->actionStateUpdated();
428 void updateMarkAction( QAction* action,
bool allMarked )
430 QByteArray data = action->data().toByteArray();
432 if ( !data.startsWith(
'!' ) )
435 if ( data.startsWith(
'!' ) )
436 data = data.mid( 1 );
438 action->setData( data );
443 const QAction *action = qobject_cast<QAction*>( mParent->sender() );
447 if ( items.isEmpty() )
450 QByteArray typeStr = action->data().toByteArray();
451 kDebug() <<
"Mark mail as: " << typeStr;
454 if ( typeStr.startsWith(
'!' ) ) {
456 typeStr = typeStr.mid( 1 );
463 if ( typeStr ==
"U" ) {
467 }
else if ( typeStr ==
"K" )
469 else if ( typeStr ==
"G" )
472 if ( mInterceptedActions.contains( type ) )
475 MarkAsCommand *command =
new MarkAsCommand( targetStatus, items, invert, mParent );
481 const QAction *action = qobject_cast<QAction*>( mParent->sender() );
484 QByteArray typeStr = action->data().toByteArray();
485 kDebug() <<
"Mark all as: " << typeStr;
488 if ( collections.isEmpty() )
495 if ( typeStr.startsWith(
'!' ) ) {
497 typeStr = typeStr.mid( 1 );
501 if ( typeStr ==
"U" ) {
505 }
else if ( typeStr ==
"K" )
507 else if ( typeStr ==
"G" )
510 if ( mInterceptedActions.contains( type ) )
513 MarkAsCommand *command =
new MarkAsCommand( targetStatus, collections, invert, mParent );
517 void slotMoveToTrash()
522 if ( mCollectionSelectionModel->selection().indexes().isEmpty() )
525 const Item::List items = mGenericManager->selectedItems();
526 if ( items.isEmpty() )
529 MoveToTrashCommand *command =
new MoveToTrashCommand( mCollectionSelectionModel->model(), items, mParent );
533 void slotMoveAllToTrash()
538 if ( mCollectionSelectionModel->selection().indexes().isEmpty() )
541 const Collection::List collections = mGenericManager->selectedCollections();
542 if ( collections.isEmpty() )
545 MoveToTrashCommand *command =
new MoveToTrashCommand( mCollectionSelectionModel->model(), collections, mParent );
549 void slotRemoveDuplicates()
554 const Collection::List collections = mGenericManager->selectedCollections();
555 if ( collections.isEmpty() )
558 RemoveDuplicatesCommand *command =
new RemoveDuplicatesCommand( mCollectionSelectionModel->model(), collections, mParent );
562 void slotEmptyAllTrash()
567 EmptyTrashCommand *command =
new EmptyTrashCommand( const_cast<QAbstractItemModel*>( mCollectionSelectionModel->model() ), mParent );
571 void slotEmptyTrash()
576 if ( mCollectionSelectionModel->selection().indexes().isEmpty() )
579 const Collection::List collections = mGenericManager->selectedCollections();
580 if ( collections.count() != 1 )
583 EmptyTrashCommand *command =
new EmptyTrashCommand( collections.first(), mParent );
587 KActionCollection *mActionCollection;
588 QWidget *mParentWidget;
590 QItemSelectionModel *mCollectionSelectionModel;
591 QItemSelectionModel *mItemSelectionModel;
592 QHash<StandardMailActionManager::Type, KAction*> mActions;
593 QSet<StandardMailActionManager::Type> mInterceptedActions;
599 : QObject( parent ), d( new Private( actionCollection, parent, this ) )
610 d->mCollectionSelectionModel = selectionModel;
611 d->mGenericManager->setCollectionSelectionModel( selectionModel );
613 connect( selectionModel->model(), SIGNAL(rowsInserted(QModelIndex,
int,
int)),
614 SLOT(updateActions()) );
615 connect( selectionModel->model(), SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
616 SLOT(updateActions()) );
617 connect( selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
618 SLOT(updateActions()) );
625 d->mItemSelectionModel = selectionModel;
626 d->mGenericManager->setItemSelectionModel( selectionModel );
628 connect( selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
629 SLOT(updateActions()) );
632 connect( selectionModel->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
633 SLOT(updateActions()) );
640 if ( d->mActions.contains( type ) )
641 return d->mActions.value( type );
647 action =
new KAction( d->mParentWidget );
648 action->setIcon( KIcon( QLatin1String(
"mail-mark-read" ) ) );
649 action->setText( i18n(
"&Mark Mail as Read" ) );
650 action->setIconText( i18n(
"Mark as Read" ) );
651 action->setWhatsThis( i18n(
"Mark selected messages as read" ) );
653 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_as_read" ), action );
654 action->setData( QByteArray(
"R" ) );
655 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAs()) );
658 action =
new KAction( d->mParentWidget );
659 action->setText( i18n(
"&Mark Mail as Unread" ) );
660 action->setIconText( i18n(
"Mark as Unread" ) );
661 action->setIcon( KIcon( QLatin1String(
"mail-mark-unread" ) ) );
663 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_as_unread" ), action );
664 action->setShortcut( Qt::CTRL+Qt::Key_U );
665 action->setData( QByteArray(
"U" ) );
666 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAs()) );
669 action =
new KAction( d->mParentWidget );
670 action->setIcon( KIcon( QLatin1String(
"mail-mark-important" ) ) );
671 action->setText( i18n(
"&Mark Mail as Important" ) );
672 action->setIconText( i18n(
"Mark as Important" ) );
674 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_as_important" ), action );
675 action->setData( QByteArray(
"G" ) );
676 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAs()) );
679 action =
new KAction( d->mParentWidget );
680 action->setText( i18n(
"&Mark Mail as Action Item" ) );
681 action->setIconText( i18n(
"Mark as Action Item" ) );
682 action->setIcon( KIcon( QLatin1String(
"mail-mark-task" ) ) );
684 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_as_action_item" ), action );
685 action->setData( QByteArray(
"K" ) );
686 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAs()) );
689 action =
new KAction( d->mParentWidget );
690 action->setIcon( KIcon( QLatin1String(
"mail-mark-read" ) ) );
691 action->setText( i18n(
"Mark &All Mails as Read" ) );
692 action->setIconText( i18n(
"Mark All as Read" ) );
694 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_all_as_read" ), action );
695 action->setData( QByteArray(
"R" ) );
696 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAllAs()) );
699 action =
new KAction( d->mParentWidget );
700 action->setText( i18n(
"Mark &All Mails as Unread" ) );
701 action->setIconText( i18n(
"Mark All as Unread" ) );
702 action->setIcon( KIcon( QLatin1String(
"mail-mark-unread" ) ) );
704 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_all_as_unread" ), action );
705 action->setData( QByteArray(
"U" ) );
706 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAllAs()) );
709 action =
new KAction( d->mParentWidget );
710 action->setText( i18n(
"Mark &All Mails as Important" ) );
711 action->setIconText( i18n(
"Mark All as Important" ) );
712 action->setIcon( KIcon( QLatin1String(
"mail-mark-important" ) ) );
714 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_all_as_important" ), action );
715 action->setData( QByteArray(
"G" ) );
716 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAllAs()) );
719 action =
new KAction( d->mParentWidget );
720 action->setText( i18n(
"Mark &All Mails as Action Item" ) );
721 action->setIconText( i18n(
"Mark All as Action Item" ) );
722 action->setIcon( KIcon( QLatin1String(
"mail-mark-task" ) ) );
724 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_mark_all_as_action_item" ), action );
725 action->setData( QByteArray(
"K") );
726 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMarkAllAs()) );
729 action =
new KAction( d->mParentWidget );
730 action->setIcon( KIcon( QLatin1String(
"user-trash" ) ) );
731 action->setText( i18n(
"Move to &Trash" ) );
732 action->setShortcut( QKeySequence( Qt::Key_Delete ) );
733 action->setWhatsThis( i18n(
"Move message to trashcan" ) );
735 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_move_to_trash" ), action );
736 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMoveToTrash()) );
739 action =
new KAction( d->mParentWidget );
740 action->setIcon( KIcon( QLatin1String(
"user-trash" ) ) );
741 action->setText( i18n(
"Move All to &Trash" ) );
743 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_move_all_to_trash" ), action );
744 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotMoveAllToTrash()) );
747 action =
new KAction( d->mParentWidget );
748 action->setText( i18n(
"Remove &Duplicate Mails" ) );
749 action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_Asterisk ) );
751 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_remove_duplicates" ), action );
752 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotRemoveDuplicates()) );
755 action =
new KAction( d->mParentWidget );
756 action->setText( i18n(
"Empty All &Trash Folders" ) );
758 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_empty_all_trash" ), action );
759 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotEmptyAllTrash()) );
762 action =
new KAction( d->mParentWidget );
763 action->setText( i18n(
"E&mpty Trash" ) );
765 d->mActionCollection->addAction( QString::fromLatin1(
"akonadi_empty_trash" ), action );
766 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotEmptyTrash()) );
778 KAction *act = d->mGenericManager->action(type);
780 act = d->mGenericManager->createAction( type );
781 d->updateGenericAction(type);
801 d->mGenericManager->createAllActions();
802 d->updateGenericAllActions();
809 if ( d->mActions.contains( type ) )
810 return d->mActions.value( type );
817 return d->mGenericManager->action( type );
822 d->mGenericManager->setActionText( type, text );
828 d->mInterceptedActions.insert( type );
830 d->mInterceptedActions.remove( type );
835 d->mGenericManager->interceptAction( type, intercept );
840 return d->mGenericManager->selectedCollections();
845 return d->mGenericManager->selectedItems();
850 d->mGenericManager->setFavoriteCollectionsModel( favoritesModel );
855 d->mGenericManager->setFavoriteSelectionModel( selectionModel );
858 void StandardMailActionManager::setCollectionPropertiesPageNames(
const QStringList &names )
860 d->mGenericManager->setCollectionPropertiesPageNames( names );
865 return d->mGenericManager;
869 #include "standardmailactionmanager.moc"