File indexing completed on 2024-11-24 04:39:35

0001 /*
0002     This file is part of Akonadi Contact.
0003 
0004     Copyright (c) 2009 - 2010 Tobias Koenig <tokoe@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "standardcontactactionmanager.h"
0010 
0011 #include "contacteditordialog.h"
0012 #include "contactgroupeditordialog.h"
0013 
0014 #include <Akonadi/EntityTreeModel>
0015 #include <Akonadi/MimeTypeChecker>
0016 #include <KContacts/Addressee>
0017 #include <KContacts/ContactGroup>
0018 
0019 #include <KActionCollection>
0020 #include <KLocalizedString>
0021 #include <KMessageBox>
0022 #include <QAction>
0023 
0024 #include <QItemSelectionModel>
0025 #include <QPointer>
0026 
0027 using namespace Akonadi;
0028 using namespace Akonadi;
0029 class Akonadi::StandardContactActionManagerPrivate
0030 {
0031 public:
0032     StandardContactActionManagerPrivate(KActionCollection *actionCollection, QWidget *parentWidget, StandardContactActionManager *parent)
0033         : mActionCollection(actionCollection)
0034         , mParentWidget(parentWidget)
0035         , mParent(parent)
0036     {
0037         mGenericManager = new StandardActionManager(actionCollection, parentWidget);
0038         mParent->connect(mGenericManager, &StandardActionManager::actionStateUpdated, mParent, &StandardContactActionManager::actionStateUpdated);
0039 
0040         mGenericManager->setMimeTypeFilter(QStringList() << KContacts::Addressee::mimeType() << KContacts::ContactGroup::mimeType());
0041 
0042         mGenericManager->setCapabilityFilter(QStringList() << QStringLiteral("Resource"));
0043     }
0044 
0045     ~StandardContactActionManagerPrivate()
0046     {
0047         delete mGenericManager;
0048     }
0049 
0050     void updateGenericAllActions()
0051     {
0052         updateGenericAction(StandardActionManager::CreateCollection);
0053         updateGenericAction(StandardActionManager::CopyCollections);
0054         updateGenericAction(StandardActionManager::DeleteCollections);
0055         updateGenericAction(StandardActionManager::SynchronizeCollections);
0056         updateGenericAction(StandardActionManager::CollectionProperties);
0057         updateGenericAction(StandardActionManager::CopyItems);
0058         updateGenericAction(StandardActionManager::Paste);
0059         updateGenericAction(StandardActionManager::DeleteItems);
0060         updateGenericAction(StandardActionManager::ManageLocalSubscriptions);
0061         updateGenericAction(StandardActionManager::AddToFavoriteCollections);
0062         updateGenericAction(StandardActionManager::RemoveFromFavoriteCollections);
0063         updateGenericAction(StandardActionManager::RenameFavoriteCollection);
0064         updateGenericAction(StandardActionManager::CopyCollectionToMenu);
0065         updateGenericAction(StandardActionManager::CopyItemToMenu);
0066         updateGenericAction(StandardActionManager::MoveItemToMenu);
0067         updateGenericAction(StandardActionManager::MoveCollectionToMenu);
0068         updateGenericAction(StandardActionManager::CutItems);
0069         updateGenericAction(StandardActionManager::CutCollections);
0070         updateGenericAction(StandardActionManager::CreateResource);
0071         updateGenericAction(StandardActionManager::DeleteResources);
0072         updateGenericAction(StandardActionManager::ResourceProperties);
0073         updateGenericAction(StandardActionManager::SynchronizeResources);
0074         updateGenericAction(StandardActionManager::ToggleWorkOffline);
0075         updateGenericAction(StandardActionManager::CopyCollectionToDialog);
0076         updateGenericAction(StandardActionManager::MoveCollectionToDialog);
0077         updateGenericAction(StandardActionManager::CopyItemToDialog);
0078         updateGenericAction(StandardActionManager::MoveItemToDialog);
0079         updateGenericAction(StandardActionManager::SynchronizeCollectionsRecursive);
0080         updateGenericAction(StandardActionManager::MoveCollectionsToTrash);
0081         updateGenericAction(StandardActionManager::MoveItemsToTrash);
0082         updateGenericAction(StandardActionManager::RestoreCollectionsFromTrash);
0083         updateGenericAction(StandardActionManager::RestoreItemsFromTrash);
0084         updateGenericAction(StandardActionManager::MoveToTrashRestoreCollection);
0085         updateGenericAction(StandardActionManager::MoveToTrashRestoreCollectionAlternative);
0086         updateGenericAction(StandardActionManager::MoveToTrashRestoreItem);
0087         updateGenericAction(StandardActionManager::MoveToTrashRestoreItemAlternative);
0088         updateGenericAction(StandardActionManager::SynchronizeFavoriteCollections);
0089     }
0090 
0091     void updateGenericAction(StandardActionManager::Type type)
0092     {
0093         switch (type) {
0094         case Akonadi::StandardActionManager::CreateCollection:
0095             mGenericManager->action(Akonadi::StandardActionManager::CreateCollection)->setText(i18n("Add Address Book Folder..."));
0096 
0097             mGenericManager->action(Akonadi::StandardActionManager::CreateCollection)
0098                 ->setWhatsThis(i18n("Add a new address book folder to the currently selected address book folder."));
0099             mGenericManager->setContextText(StandardActionManager::CreateCollection,
0100                                             StandardActionManager::DialogTitle,
0101                                             i18nc("@title:window", "New Address Book Folder"));
0102 
0103             mGenericManager->setContextText(StandardActionManager::CreateCollection,
0104                                             StandardActionManager::ErrorMessageText,
0105                                             ki18n("Could not create address book folder: %1"));
0106 
0107             mGenericManager->setContextText(StandardActionManager::CreateCollection,
0108                                             StandardActionManager::ErrorMessageTitle,
0109                                             i18n("Address book folder creation failed"));
0110             mGenericManager->action(Akonadi::StandardActionManager::CreateCollection)
0111                 ->setProperty("ContentMimeTypes", QStringList() << QStringLiteral("application/x-vnd.kde.contactgroup") << QStringLiteral("text/directory"));
0112 
0113             break;
0114         case Akonadi::StandardActionManager::CopyCollections:
0115             mGenericManager->setActionText(Akonadi::StandardActionManager::CopyCollections, ki18np("Copy Address Book Folder", "Copy %1 Address Book Folders"));
0116             mGenericManager->action(Akonadi::StandardActionManager::CopyCollections)
0117                 ->setWhatsThis(i18n("Copy the selected address book folders to the clipboard."));
0118             break;
0119         case Akonadi::StandardActionManager::DeleteCollections:
0120             mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteCollections,
0121                                            ki18np("Delete Address Book Folder", "Delete %1 Address Book Folders"));
0122             mGenericManager->action(Akonadi::StandardActionManager::DeleteCollections)
0123                 ->setWhatsThis(i18n("Delete the selected address book folders from the address book."));
0124 
0125             mGenericManager->setContextText(StandardActionManager::DeleteCollections,
0126                                             StandardActionManager::MessageBoxText,
0127                                             ki18np("Do you really want to delete this address book folder and all its sub-folders?",
0128                                                    "Do you really want to delete %1 address book folders and all their sub-folders?"));
0129             mGenericManager->setContextText(StandardActionManager::DeleteCollections,
0130                                             StandardActionManager::MessageBoxTitle,
0131                                             ki18ncp("@title:window", "Delete address book folder?", "Delete address book folders?"));
0132 
0133             mGenericManager->setContextText(StandardActionManager::DeleteCollections,
0134                                             StandardActionManager::ErrorMessageText,
0135                                             ki18n("Could not delete address book folder: %1"));
0136 
0137             mGenericManager->setContextText(StandardActionManager::DeleteCollections,
0138                                             StandardActionManager::ErrorMessageTitle,
0139                                             i18n("Address book folder deletion failed"));
0140             break;
0141         case Akonadi::StandardActionManager::SynchronizeCollections:
0142             mGenericManager->setActionText(Akonadi::StandardActionManager::SynchronizeCollections,
0143                                            ki18np("Update Address Book Folder", "Update %1 Address Book Folders"));
0144             mGenericManager->action(Akonadi::StandardActionManager::SynchronizeCollections)
0145                 ->setWhatsThis(i18n("Update the content of the selected address book folders."));
0146             break;
0147         case Akonadi::StandardActionManager::CutCollections:
0148             mGenericManager->setActionText(Akonadi::StandardActionManager::CutCollections, ki18np("Cut Address Book Folder", "Cut %1 Address Book Folders"));
0149             mGenericManager->action(Akonadi::StandardActionManager::CutCollections)
0150                 ->setWhatsThis(i18n("Cut the selected address book folders from the address book."));
0151             break;
0152         case Akonadi::StandardActionManager::CollectionProperties:
0153             mGenericManager->action(Akonadi::StandardActionManager::CollectionProperties)->setText(i18n("Folder Properties..."));
0154             mGenericManager->action(Akonadi::StandardActionManager::CollectionProperties)
0155                 ->setWhatsThis(i18n("Open a dialog to edit the properties of the selected address book folder."));
0156             mGenericManager->setContextText(StandardActionManager::CollectionProperties,
0157                                             StandardActionManager::DialogTitle,
0158                                             ki18nc("@title:window", "Properties of Address Book Folder %1"));
0159             break;
0160         case Akonadi::StandardActionManager::CopyItems:
0161             mGenericManager->setActionText(Akonadi::StandardActionManager::CopyItems, ki18np("Copy Contact", "Copy %1 Contacts"));
0162             mGenericManager->action(Akonadi::StandardActionManager::CopyItems)->setWhatsThis(i18n("Copy the selected contacts to the clipboard."));
0163             break;
0164         case Akonadi::StandardActionManager::DeleteItems:
0165             mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteItems, ki18np("Delete Contact", "Delete %1 Contacts"));
0166             mGenericManager->action(Akonadi::StandardActionManager::DeleteItems)->setWhatsThis(i18n("Delete the selected contacts from the address book."));
0167             mGenericManager->setContextText(StandardActionManager::DeleteItems,
0168                                             StandardActionManager::MessageBoxText,
0169                                             ki18np("Do you really want to delete the selected contact?", "Do you really want to delete %1 contacts?"));
0170 
0171             mGenericManager->setContextText(StandardActionManager::DeleteItems,
0172                                             StandardActionManager::MessageBoxTitle,
0173                                             ki18ncp("@title:window", "Delete Contact?", "Delete Contacts?"));
0174 
0175             mGenericManager->setContextText(StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageText, ki18n("Could not delete contact: %1"));
0176 
0177             mGenericManager->setContextText(StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageTitle, i18n("Contact deletion failed"));
0178             break;
0179         case Akonadi::StandardActionManager::CutItems:
0180             mGenericManager->setActionText(Akonadi::StandardActionManager::CutItems, ki18np("Cut Contact", "Cut %1 Contacts"));
0181             mGenericManager->action(Akonadi::StandardActionManager::CutItems)->setWhatsThis(i18n("Cut the selected contacts from the address book."));
0182             break;
0183         case Akonadi::StandardActionManager::CreateResource:
0184             mGenericManager->action(Akonadi::StandardActionManager::CreateResource)->setText(i18n("Add &Address Book..."));
0185             mGenericManager->action(Akonadi::StandardActionManager::CreateResource)
0186                 ->setWhatsThis(i18n("Add a new address book<p>"
0187                                     "You will be presented with a dialog where you can select "
0188                                     "the type of the address book that shall be added.</p>"));
0189             mGenericManager->setContextText(StandardActionManager::CreateResource,
0190                                             StandardActionManager::DialogTitle,
0191                                             i18nc("@title:window", "Add Address Book"));
0192 
0193             mGenericManager->setContextText(StandardActionManager::CreateResource,
0194                                             StandardActionManager::ErrorMessageText,
0195                                             ki18n("Could not create address book: %1"));
0196 
0197             mGenericManager->setContextText(StandardActionManager::CreateResource,
0198                                             StandardActionManager::ErrorMessageTitle,
0199                                             i18n("Address book creation failed"));
0200             break;
0201         case Akonadi::StandardActionManager::DeleteResources:
0202 
0203             mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteResources, ki18np("&Delete Address Book", "&Delete %1 Address Books"));
0204             mGenericManager->action(Akonadi::StandardActionManager::DeleteResources)
0205                 ->setWhatsThis(i18n("Delete the selected address books<p>"
0206                                     "The currently selected address books will be deleted, "
0207                                     "along with all the contacts and contact groups they contain.</p>"));
0208             mGenericManager->setContextText(StandardActionManager::DeleteResources,
0209                                             StandardActionManager::MessageBoxText,
0210                                             ki18np("Do you really want to delete this address book?", "Do you really want to delete %1 address books?"));
0211 
0212             mGenericManager->setContextText(StandardActionManager::DeleteResources,
0213                                             StandardActionManager::MessageBoxTitle,
0214                                             ki18ncp("@title:window", "Delete Address Book?", "Delete Address Books?"));
0215 
0216             break;
0217         case Akonadi::StandardActionManager::ResourceProperties:
0218 
0219             mGenericManager->action(Akonadi::StandardActionManager::ResourceProperties)->setText(i18n("Address Book Properties..."));
0220             mGenericManager->action(Akonadi::StandardActionManager::ResourceProperties)
0221                 ->setWhatsThis(i18n("Open a dialog to edit properties of the selected address book."));
0222             break;
0223         case Akonadi::StandardActionManager::SynchronizeResources:
0224             mGenericManager->setActionText(Akonadi::StandardActionManager::SynchronizeResources, ki18np("Update Address Book", "Update %1 Address Books"));
0225 
0226             mGenericManager->action(Akonadi::StandardActionManager::SynchronizeResources)
0227                 ->setWhatsThis(i18n("Updates the content of all folders of the selected address books."));
0228 
0229             break;
0230         case StandardActionManager::Paste:
0231             mGenericManager->setContextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageText, ki18n("Could not paste contact: %1"));
0232 
0233             mGenericManager->setContextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle, i18n("Paste failed"));
0234             break;
0235         default:
0236             break;
0237         }
0238     }
0239 
0240     static bool hasWritableCollection(const QModelIndex &index, const QString &mimeType)
0241     {
0242         const auto collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
0243         if (collection.isValid()) {
0244             if (collection.contentMimeTypes().contains(mimeType) && (collection.rights() & Akonadi::Collection::CanCreateItem)) {
0245                 return true;
0246             }
0247         }
0248 
0249         const QAbstractItemModel *model = index.model();
0250         if (!model) {
0251             return false;
0252         }
0253 
0254         for (int row = 0; row < model->rowCount(index); ++row) {
0255             if (hasWritableCollection(model->index(row, 0, index), mimeType)) {
0256                 return true;
0257             }
0258         }
0259 
0260         return false;
0261     }
0262 
0263     bool hasWritableCollection(const QString &mimeType) const
0264     {
0265         if (!mCollectionSelectionModel) {
0266             return false;
0267         }
0268 
0269         const QAbstractItemModel *collectionModel = mCollectionSelectionModel->model();
0270         for (int row = 0; row < collectionModel->rowCount(); ++row) {
0271             if (hasWritableCollection(collectionModel->index(row, 0, QModelIndex()), mimeType)) {
0272                 return true;
0273             }
0274         }
0275 
0276         return false;
0277     }
0278 
0279     void updateActions()
0280     {
0281         int itemCount = 0;
0282         if (mItemSelectionModel) {
0283             itemCount = mItemSelectionModel->selectedRows().count();
0284             if (itemCount == 1) {
0285                 const QModelIndex index = mItemSelectionModel->selectedRows().first();
0286                 if (index.isValid()) {
0287                     const QString mimeType = index.data(EntityTreeModel::MimeTypeRole).toString();
0288                     if (mimeType == KContacts::Addressee::mimeType()) {
0289                         if (mGenericManager->action(Akonadi::StandardActionManager::CopyItems)) {
0290                             mGenericManager->setActionText(Akonadi::StandardActionManager::CopyItems, ki18np("Copy Contact", "Copy %1 Contacts"));
0291                         }
0292                         QAction *act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToMenu);
0293                         if (act) {
0294                             act->setText(i18n("Copy Contact To"));
0295                         }
0296                         act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToDialog);
0297                         if (act) {
0298                             act->setText(i18n("Copy Contact To"));
0299                         }
0300                         if (mGenericManager->action(Akonadi::StandardActionManager::DeleteItems)) {
0301                             mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteItems, ki18np("Delete Contact", "Delete %1 Contacts"));
0302                         }
0303                         if (mGenericManager->action(Akonadi::StandardActionManager::CutItems)) {
0304                             mGenericManager->setActionText(Akonadi::StandardActionManager::CutItems, ki18np("Cut Contact", "Cut %1 Contacts"));
0305                         }
0306                         act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToMenu);
0307                         if (act) {
0308                             act->setText(i18n("Move Contact To"));
0309                         }
0310                         act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToDialog);
0311                         if (act) {
0312                             act->setText(i18n("Move Contact To"));
0313                         }
0314                         act = mActions.value(StandardContactActionManager::EditItem);
0315                         if (act) {
0316                             act->setText(i18n("Edit Contact..."));
0317                         }
0318                     } else if (mimeType == KContacts::ContactGroup::mimeType()) {
0319                         if (mGenericManager->action(Akonadi::StandardActionManager::CopyItems)) {
0320                             mGenericManager->setActionText(Akonadi::StandardActionManager::CopyItems, ki18np("Copy Group", "Copy %1 Groups"));
0321                         }
0322                         QAction *act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToMenu);
0323                         if (act) {
0324                             act->setText(i18n("Copy Group To"));
0325                         }
0326                         act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToDialog);
0327                         if (act) {
0328                             act->setText(i18n("Copy Group To"));
0329                         }
0330                         if (mGenericManager->action(Akonadi::StandardActionManager::DeleteItems)) {
0331                             mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteItems, ki18np("Delete Group", "Delete %1 Groups"));
0332                         }
0333                         if (mGenericManager->action(Akonadi::StandardActionManager::CutItems)) {
0334                             mGenericManager->setActionText(Akonadi::StandardActionManager::CutItems, ki18np("Cut Group", "Cut %1 Groups"));
0335                         }
0336                         act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToMenu);
0337                         if (act) {
0338                             act->setText(i18n("Move Group To"));
0339                         }
0340                         act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToDialog);
0341                         if (act) {
0342                             act->setText(i18n("Move Group To"));
0343                         }
0344                         act = mActions.value(StandardContactActionManager::EditItem);
0345                         if (act) {
0346                             act->setText(i18n("Edit Group..."));
0347                         }
0348                     }
0349                 }
0350             }
0351         }
0352 
0353         if (mActions.contains(StandardContactActionManager::CreateContact)) {
0354             mActions[StandardContactActionManager::CreateContact]->setEnabled(hasWritableCollection(KContacts::Addressee::mimeType()));
0355         }
0356         if (mActions.contains(StandardContactActionManager::CreateContactGroup)) {
0357             mActions[StandardContactActionManager::CreateContactGroup]->setEnabled(hasWritableCollection(KContacts::ContactGroup::mimeType()));
0358         }
0359 
0360         if (mActions.contains(StandardContactActionManager::EditItem)) {
0361             bool canEditItem = true;
0362 
0363             // only one selected item can be edited
0364             canEditItem = canEditItem && (itemCount == 1);
0365 
0366             // check whether parent collection allows changing the item
0367             const QModelIndexList rows = mItemSelectionModel->selectedRows();
0368             if (rows.count() == 1) {
0369                 const QModelIndex index = rows.first();
0370                 const auto parentCollection = index.data(EntityTreeModel::ParentCollectionRole).value<Collection>();
0371                 if (parentCollection.isValid()) {
0372                     canEditItem = canEditItem && (parentCollection.rights() & Collection::CanChangeItem);
0373                 }
0374             }
0375 
0376             mActions.value(StandardContactActionManager::EditItem)->setEnabled(canEditItem);
0377         }
0378 
0379         Q_EMIT mParent->actionStateUpdated();
0380     }
0381 
0382     Collection selectedCollection() const
0383     {
0384         if (!mCollectionSelectionModel) {
0385             return {};
0386         }
0387 
0388         if (mCollectionSelectionModel->selectedIndexes().isEmpty()) {
0389             return {};
0390         }
0391 
0392         const QModelIndex index = mCollectionSelectionModel->selectedIndexes().first();
0393         if (!index.isValid()) {
0394             return {};
0395         }
0396 
0397         return index.data(EntityTreeModel::CollectionRole).value<Collection>();
0398     }
0399 
0400     void slotCreateContact()
0401     {
0402         if (mInterceptedActions.contains(StandardContactActionManager::CreateContact)) {
0403             return;
0404         }
0405 
0406         QPointer<Akonadi::ContactEditorDialog> dlg = new Akonadi::ContactEditorDialog(Akonadi::ContactEditorDialog::CreateMode, mParentWidget);
0407         dlg->setDefaultAddressBook(selectedCollection());
0408         dlg->exec();
0409         delete dlg;
0410     }
0411 
0412     void slotCreateContactGroup()
0413     {
0414         if (mInterceptedActions.contains(StandardContactActionManager::CreateContactGroup)) {
0415             return;
0416         }
0417 
0418         QPointer<Akonadi::ContactGroupEditorDialog> dlg = new Akonadi::ContactGroupEditorDialog(Akonadi::ContactGroupEditorDialog::CreateMode, mParentWidget);
0419         dlg->setDefaultAddressBook(selectedCollection());
0420         dlg->exec();
0421         delete dlg;
0422     }
0423 
0424     void slotEditItem()
0425     {
0426         if (mInterceptedActions.contains(StandardContactActionManager::EditItem)) {
0427             return;
0428         }
0429 
0430         if (!mItemSelectionModel) {
0431             return;
0432         }
0433 
0434         if (mItemSelectionModel->selectedIndexes().isEmpty()) {
0435             return;
0436         }
0437 
0438         const QModelIndex index = mItemSelectionModel->selectedIndexes().first();
0439         if (!index.isValid()) {
0440             return;
0441         }
0442 
0443         const Item item = index.data(EntityTreeModel::ItemRole).value<Item>();
0444         if (!item.isValid()) {
0445             return;
0446         }
0447 
0448         if (Akonadi::MimeTypeChecker::isWantedItem(item, KContacts::Addressee::mimeType())) {
0449             QPointer<Akonadi::ContactEditorDialog> dlg = new Akonadi::ContactEditorDialog(Akonadi::ContactEditorDialog::EditMode, mParentWidget);
0450             QObject::connect(dlg.data(), &Akonadi::ContactEditorDialog::error, mParent, [this](const QString &error) {
0451                 slotContactEditorError(error);
0452             });
0453             dlg->setContact(item);
0454             dlg->exec();
0455             delete dlg;
0456         } else if (Akonadi::MimeTypeChecker::isWantedItem(item, KContacts::ContactGroup::mimeType())) {
0457             QPointer<Akonadi::ContactGroupEditorDialog> dlg = new Akonadi::ContactGroupEditorDialog(Akonadi::ContactGroupEditorDialog::EditMode, mParentWidget);
0458             dlg->setContactGroup(item);
0459             dlg->exec();
0460             delete dlg;
0461         }
0462     }
0463 
0464     void slotContactEditorError(const QString &error)
0465     {
0466         KMessageBox::error(mParentWidget, i18n("Contact cannot be stored: %1", error), i18nc("@title:window", "Failed to store contact"));
0467     }
0468 
0469     KActionCollection *const mActionCollection;
0470     QWidget *const mParentWidget;
0471     StandardActionManager *mGenericManager = nullptr;
0472     QItemSelectionModel *mCollectionSelectionModel = nullptr;
0473     QItemSelectionModel *mItemSelectionModel = nullptr;
0474     QHash<StandardContactActionManager::Type, QAction *> mActions;
0475     QSet<StandardContactActionManager::Type> mInterceptedActions;
0476     StandardContactActionManager *const mParent;
0477 };
0478 
0479 StandardContactActionManager::StandardContactActionManager(KActionCollection *actionCollection, QWidget *parent)
0480     : QObject(parent)
0481     , d(new StandardContactActionManagerPrivate(actionCollection, parent, this))
0482 {
0483 }
0484 
0485 StandardContactActionManager::~StandardContactActionManager() = default;
0486 
0487 void StandardContactActionManager::setCollectionSelectionModel(QItemSelectionModel *selectionModel)
0488 {
0489     d->mCollectionSelectionModel = selectionModel;
0490     d->mGenericManager->setCollectionSelectionModel(selectionModel);
0491 
0492     connect(selectionModel->model(), &QAbstractItemModel::rowsInserted, this, [this]() {
0493         d->updateActions();
0494     });
0495     connect(selectionModel->model(), &QAbstractItemModel::rowsRemoved, this, [this]() {
0496         d->updateActions();
0497     });
0498     connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() {
0499         d->updateActions();
0500     });
0501 
0502     d->updateActions();
0503 }
0504 
0505 void StandardContactActionManager::setItemSelectionModel(QItemSelectionModel *selectionModel)
0506 {
0507     d->mItemSelectionModel = selectionModel;
0508     d->mGenericManager->setItemSelectionModel(selectionModel);
0509 
0510     connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() {
0511         d->updateActions();
0512     });
0513 
0514     d->updateActions();
0515 }
0516 
0517 QAction *StandardContactActionManager::createAction(Type type)
0518 {
0519     QAction *action = d->mActions.value(type);
0520     if (action) {
0521         return action;
0522     }
0523 
0524     switch (type) {
0525     case CreateContact:
0526         action = new QAction(d->mParentWidget);
0527         action->setIcon(QIcon::fromTheme(QStringLiteral("contact-new")));
0528         action->setText(i18n("New &Contact..."));
0529         action->setWhatsThis(i18n(
0530             "Create a new contact<p>You will be presented with a dialog where you can add data about a person, including addresses and phone numbers.</p>"));
0531         d->mActions.insert(CreateContact, action);
0532         d->mActionCollection->addAction(QStringLiteral("akonadi_contact_create"), action);
0533         d->mActionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_N));
0534         connect(action, &QAction::triggered, this, [this]() {
0535             d->slotCreateContact();
0536         });
0537         break;
0538     case CreateContactGroup:
0539         action = new QAction(d->mParentWidget);
0540         action->setIcon(QIcon::fromTheme(QStringLiteral("user-group-new")));
0541         action->setText(i18n("New &Group..."));
0542         action->setWhatsThis(i18n("Create a new group<p>You will be presented with a dialog where you can add a new group of contacts.</p>"));
0543         d->mActions.insert(CreateContactGroup, action);
0544         d->mActionCollection->addAction(QStringLiteral("akonadi_contact_group_create"), action);
0545         d->mActionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_G));
0546         connect(action, &QAction::triggered, this, [this]() {
0547             d->slotCreateContactGroup();
0548         });
0549         break;
0550     case EditItem:
0551         action = new QAction(d->mParentWidget);
0552         action->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
0553         action->setText(i18n("Edit Contact..."));
0554         action->setWhatsThis(
0555             i18n("Edit the selected contact<p>You will be presented with a dialog where you can edit the data stored about a person, including addresses and "
0556                  "phone numbers.</p>"));
0557         action->setEnabled(false);
0558         d->mActions.insert(EditItem, action);
0559         d->mActionCollection->addAction(QStringLiteral("akonadi_contact_item_edit"), action);
0560         d->mActionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_E));
0561 
0562         connect(action, &QAction::triggered, this, [this]() {
0563             d->slotEditItem();
0564         });
0565         break;
0566     default:
0567         Q_ASSERT(false); // should never happen
0568         break;
0569     }
0570 
0571     return action;
0572 }
0573 
0574 QAction *StandardContactActionManager::createAction(StandardActionManager::Type type)
0575 {
0576     QAction *act = d->mGenericManager->action(type);
0577     if (!act) {
0578         act = d->mGenericManager->createAction(type);
0579     }
0580     d->updateGenericAction(type);
0581     return act;
0582 }
0583 
0584 void StandardContactActionManager::createAllActions()
0585 {
0586     createAction(CreateContact);
0587     createAction(CreateContactGroup);
0588     createAction(EditItem);
0589 
0590     d->mGenericManager->createAllActions();
0591     d->updateGenericAllActions();
0592 
0593     d->updateActions();
0594 }
0595 
0596 QAction *StandardContactActionManager::action(Type type) const
0597 {
0598     if (d->mActions.contains(type)) {
0599         return d->mActions.value(type);
0600     }
0601 
0602     return nullptr;
0603 }
0604 
0605 QAction *StandardContactActionManager::action(StandardActionManager::Type type) const
0606 {
0607     return d->mGenericManager->action(type);
0608 }
0609 
0610 void StandardContactActionManager::setActionText(StandardActionManager::Type type, const KLocalizedString &text)
0611 {
0612     d->mGenericManager->setActionText(type, text);
0613 }
0614 
0615 void StandardContactActionManager::interceptAction(Type type, bool intercept)
0616 {
0617     if (intercept) {
0618         d->mInterceptedActions.insert(type);
0619     } else {
0620         d->mInterceptedActions.remove(type);
0621     }
0622 }
0623 
0624 void StandardContactActionManager::interceptAction(StandardActionManager::Type type, bool intercept)
0625 {
0626     d->mGenericManager->interceptAction(type, intercept);
0627 }
0628 
0629 Akonadi::Collection::List StandardContactActionManager::selectedCollections() const
0630 {
0631     return d->mGenericManager->selectedCollections();
0632 }
0633 
0634 Akonadi::Item::List StandardContactActionManager::selectedItems() const
0635 {
0636     return d->mGenericManager->selectedItems();
0637 }
0638 
0639 void StandardContactActionManager::setCollectionPropertiesPageNames(const QStringList &names)
0640 {
0641     d->mGenericManager->setCollectionPropertiesPageNames(names);
0642 }
0643 
0644 #include "moc_standardcontactactionmanager.cpp"