standardcontactactionmanager.cpp 31.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
    This file is part of Akonadi Contact.

    Copyright (c) 2009 - 2010 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "standardcontactactionmanager.h"

24 25 26
#include "contacteditordialog.h"
#include "contactgroupeditordialog.h"

27 28
#include <entitytreemodel.h>
#include <mimetypechecker.h>
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
29 30
#include <kcontacts/addressee.h>
#include <kcontacts/contactgroup.h>
Laurent Montel's avatar
Laurent Montel committed
31

Laurent Montel's avatar
Laurent Montel committed
32
#include <QAction>
33
#include <kactioncollection.h>
Laurent Montel's avatar
Laurent Montel committed
34 35
#include <KLocalizedString>
#include <KMessageBox>
36

Laurent Montel's avatar
Laurent Montel committed
37
#include <QPointer>
38
#include <QItemSelectionModel>
39 40 41

using namespace Akonadi;

42
class Q_DECL_HIDDEN StandardContactActionManager::Private
43
{
Guy Maurel's avatar
Guy Maurel committed
44 45 46 47
public:
    Private(KActionCollection *actionCollection, QWidget *parentWidget, StandardContactActionManager *parent)
        : mActionCollection(actionCollection)
        , mParentWidget(parentWidget)
Laurent Montel's avatar
Laurent Montel committed
48 49
        , mCollectionSelectionModel(nullptr)
        , mItemSelectionModel(nullptr)
Guy Maurel's avatar
Guy Maurel committed
50
        , mParent(parent)
51
    {
Guy Maurel's avatar
Guy Maurel committed
52
        mGenericManager = new StandardActionManager(actionCollection, parentWidget);
53 54
        mParent->connect(mGenericManager, &StandardActionManager::actionStateUpdated,
                         mParent, &StandardContactActionManager::actionStateUpdated);
55

Guy Maurel's avatar
Guy Maurel committed
56 57
        mGenericManager->setMimeTypeFilter(
            QStringList() << KContacts::Addressee::mimeType() << KContacts::ContactGroup::mimeType());
58

Laurent Montel's avatar
Laurent Montel committed
59
        mGenericManager->setCapabilityFilter(QStringList() << QStringLiteral("Resource"));
60 61 62 63
    }

    ~Private()
    {
Guy Maurel's avatar
Guy Maurel committed
64
        delete mGenericManager;
65 66 67 68
    }

    void updateGenericAllActions()
    {
Guy Maurel's avatar
Guy Maurel committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        updateGenericAction(StandardActionManager::CreateCollection);
        updateGenericAction(StandardActionManager::CopyCollections);
        updateGenericAction(StandardActionManager::DeleteCollections);
        updateGenericAction(StandardActionManager::SynchronizeCollections);
        updateGenericAction(StandardActionManager::CollectionProperties);
        updateGenericAction(StandardActionManager::CopyItems);
        updateGenericAction(StandardActionManager::Paste);
        updateGenericAction(StandardActionManager::DeleteItems);
        updateGenericAction(StandardActionManager::ManageLocalSubscriptions);
        updateGenericAction(StandardActionManager::AddToFavoriteCollections);
        updateGenericAction(StandardActionManager::RemoveFromFavoriteCollections);
        updateGenericAction(StandardActionManager::RenameFavoriteCollection);
        updateGenericAction(StandardActionManager::CopyCollectionToMenu);
        updateGenericAction(StandardActionManager::CopyItemToMenu);
        updateGenericAction(StandardActionManager::MoveItemToMenu);
        updateGenericAction(StandardActionManager::MoveCollectionToMenu);
        updateGenericAction(StandardActionManager::CutItems);
        updateGenericAction(StandardActionManager::CutCollections);
        updateGenericAction(StandardActionManager::CreateResource);
        updateGenericAction(StandardActionManager::DeleteResources);
        updateGenericAction(StandardActionManager::ResourceProperties);
        updateGenericAction(StandardActionManager::SynchronizeResources);
        updateGenericAction(StandardActionManager::ToggleWorkOffline);
        updateGenericAction(StandardActionManager::CopyCollectionToDialog);
        updateGenericAction(StandardActionManager::MoveCollectionToDialog);
        updateGenericAction(StandardActionManager::CopyItemToDialog);
        updateGenericAction(StandardActionManager::MoveItemToDialog);
        updateGenericAction(StandardActionManager::SynchronizeCollectionsRecursive);
        updateGenericAction(StandardActionManager::MoveCollectionsToTrash);
        updateGenericAction(StandardActionManager::MoveItemsToTrash);
        updateGenericAction(StandardActionManager::RestoreCollectionsFromTrash);
        updateGenericAction(StandardActionManager::RestoreItemsFromTrash);
        updateGenericAction(StandardActionManager::MoveToTrashRestoreCollection);
        updateGenericAction(StandardActionManager::MoveToTrashRestoreCollectionAlternative);
        updateGenericAction(StandardActionManager::MoveToTrashRestoreItem);
        updateGenericAction(StandardActionManager::MoveToTrashRestoreItemAlternative);
        updateGenericAction(StandardActionManager::SynchronizeFavoriteCollections);
Laurent Montel's avatar
Laurent Montel committed
106 107 108 109 110

    }

    void updateGenericAction(StandardActionManager::Type type)
    {
Guy Maurel's avatar
Guy Maurel committed
111
        switch (type) {
Laurent Montel's avatar
Laurent Montel committed
112
        case Akonadi::StandardActionManager::CreateCollection:
Guy Maurel's avatar
Guy Maurel committed
113 114
            mGenericManager->action(Akonadi::StandardActionManager::CreateCollection)->setText(
                i18n("Add Address Book Folder..."));
Laurent Montel's avatar
Laurent Montel committed
115

Guy Maurel's avatar
Guy Maurel committed
116 117
            mGenericManager->action(Akonadi::StandardActionManager::CreateCollection)->setWhatsThis(
                i18n("Add a new address book folder to the currently selected address book folder."));
Laurent Montel's avatar
Laurent Montel committed
118
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
119 120
                StandardActionManager::CreateCollection, StandardActionManager::DialogTitle,
                i18nc("@title:window", "New Address Book Folder"));
Laurent Montel's avatar
Laurent Montel committed
121 122

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
123 124
                StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageText,
                ki18n("Could not create address book folder: %1"));
Laurent Montel's avatar
Laurent Montel committed
125 126

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
127 128
                StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageTitle,
                i18n("Address book folder creation failed"));
129
            mGenericManager->action(Akonadi::StandardActionManager::CreateCollection)->setProperty("ContentMimeTypes", QStringList() <<
Laurent Montel's avatar
Laurent Montel committed
130 131 132
                    QStringLiteral("application/x-vnd.kde.contactgroup") <<
                    QStringLiteral("text/directory") <<
                    QStringLiteral("application/x-vnd.kde.contactgroup"));
Laurent Montel's avatar
Laurent Montel committed
133 134 135

            break;
        case Akonadi::StandardActionManager::CopyCollections:
Guy Maurel's avatar
Guy Maurel committed
136 137 138 139 140
            mGenericManager->setActionText(Akonadi::StandardActionManager::CopyCollections,
                                           ki18np("Copy Address Book Folder",
                                                  "Copy %1 Address Book Folders"));
            mGenericManager->action(Akonadi::StandardActionManager::CopyCollections)->setWhatsThis(
                i18n("Copy the selected address book folders to the clipboard."));
Laurent Montel's avatar
Laurent Montel committed
141 142
            break;
        case Akonadi::StandardActionManager::DeleteCollections:
Guy Maurel's avatar
Guy Maurel committed
143 144 145 146 147
            mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteCollections,
                                           ki18np("Delete Address Book Folder",
                                                  "Delete %1 Address Book Folders"));
            mGenericManager->action(Akonadi::StandardActionManager::DeleteCollections)->setWhatsThis(
                i18n("Delete the selected address book folders from the address book."));
Laurent Montel's avatar
Laurent Montel committed
148 149

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
150 151 152
                StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxText,
                ki18np("Do you really want to delete this address book folder and all its sub-folders?",
                       "Do you really want to delete %1 address book folders and all their sub-folders?"));
Laurent Montel's avatar
Laurent Montel committed
153
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
154 155
                StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxTitle,
                ki18ncp("@title:window", "Delete address book folder?", "Delete address book folders?"));
Laurent Montel's avatar
Laurent Montel committed
156 157

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
158 159
                StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageText,
                ki18n("Could not delete address book folder: %1"));
Laurent Montel's avatar
Laurent Montel committed
160 161

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
162 163
                StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageTitle,
                i18n("Address book folder deletion failed"));
Laurent Montel's avatar
Laurent Montel committed
164 165
            break;
        case Akonadi::StandardActionManager::SynchronizeCollections:
Guy Maurel's avatar
Guy Maurel committed
166 167 168 169 170
            mGenericManager->setActionText(Akonadi::StandardActionManager::SynchronizeCollections,
                                           ki18np("Update Address Book Folder",
                                                  "Update %1 Address Book Folders"));
            mGenericManager->action(Akonadi::StandardActionManager::SynchronizeCollections)->setWhatsThis(
                i18n("Update the content of the selected address book folders."));
Laurent Montel's avatar
Laurent Montel committed
171 172
            break;
        case Akonadi::StandardActionManager::CutCollections:
Guy Maurel's avatar
Guy Maurel committed
173 174 175 176 177
            mGenericManager->setActionText(Akonadi::StandardActionManager::CutCollections,
                                           ki18np("Cut Address Book Folder",
                                                  "Cut %1 Address Book Folders"));
            mGenericManager->action(Akonadi::StandardActionManager::CutCollections)->setWhatsThis(
                i18n("Cut the selected address book folders from the address book."));
Laurent Montel's avatar
Laurent Montel committed
178 179
            break;
        case Akonadi::StandardActionManager::CollectionProperties:
Guy Maurel's avatar
Guy Maurel committed
180 181 182 183
            mGenericManager->action(Akonadi::StandardActionManager::CollectionProperties)->setText(
                i18n("Folder Properties..."));
            mGenericManager->action(Akonadi::StandardActionManager::CollectionProperties)->setWhatsThis(
                i18n("Open a dialog to edit the properties of the selected address book folder."));
Laurent Montel's avatar
Laurent Montel committed
184
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
185 186
                StandardActionManager::CollectionProperties, StandardActionManager::DialogTitle,
                ki18nc("@title:window", "Properties of Address Book Folder %1"));
Laurent Montel's avatar
Laurent Montel committed
187 188
            break;
        case Akonadi::StandardActionManager::CopyItems:
Guy Maurel's avatar
Guy Maurel committed
189 190 191 192
            mGenericManager->setActionText(Akonadi::StandardActionManager::CopyItems,
                                           ki18np("Copy Contact", "Copy %1 Contacts"));
            mGenericManager->action(Akonadi::StandardActionManager::CopyItems)->setWhatsThis(
                i18n("Copy the selected contacts to the clipboard."));
Laurent Montel's avatar
Laurent Montel committed
193 194
            break;
        case Akonadi::StandardActionManager::DeleteItems:
Guy Maurel's avatar
Guy Maurel committed
195 196 197 198
            mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteItems,
                                           ki18np("Delete Contact", "Delete %1 Contacts"));
            mGenericManager->action(Akonadi::StandardActionManager::DeleteItems)->setWhatsThis(
                i18n("Delete the selected contacts from the address book."));
Laurent Montel's avatar
Laurent Montel committed
199
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
200 201 202
                StandardActionManager::DeleteItems, StandardActionManager::MessageBoxText,
                ki18np("Do you really want to delete the selected contact?",
                       "Do you really want to delete %1 contacts?"));
Laurent Montel's avatar
Laurent Montel committed
203 204

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
205 206
                StandardActionManager::DeleteItems, StandardActionManager::MessageBoxTitle,
                ki18ncp("@title:window", "Delete Contact?", "Delete Contacts?"));
Laurent Montel's avatar
Laurent Montel committed
207 208

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
209 210
                StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageText,
                ki18n("Could not delete contact: %1"));
Laurent Montel's avatar
Laurent Montel committed
211 212

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
213 214
                StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageTitle,
                i18n("Contact deletion failed"));
Laurent Montel's avatar
Laurent Montel committed
215 216
            break;
        case Akonadi::StandardActionManager::CutItems:
Guy Maurel's avatar
Guy Maurel committed
217 218 219 220
            mGenericManager->setActionText(Akonadi::StandardActionManager::CutItems,
                                           ki18np("Cut Contact", "Cut %1 Contacts"));
            mGenericManager->action(Akonadi::StandardActionManager::CutItems)->setWhatsThis(
                i18n("Cut the selected contacts from the address book."));
Laurent Montel's avatar
Laurent Montel committed
221 222
            break;
        case Akonadi::StandardActionManager::CreateResource:
Guy Maurel's avatar
Guy Maurel committed
223 224 225 226 227 228
            mGenericManager->action(Akonadi::StandardActionManager::CreateResource)->setText(
                i18n("Add &Address Book..."));
            mGenericManager->action(Akonadi::StandardActionManager::CreateResource)->setWhatsThis(
                i18n("Add a new address book<p>"
                     "You will be presented with a dialog where you can select "
                     "the type of the address book that shall be added.</p>"));
Laurent Montel's avatar
Laurent Montel committed
229
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
230 231
                StandardActionManager::CreateResource, StandardActionManager::DialogTitle,
                i18nc("@title:window", "Add Address Book"));
Laurent Montel's avatar
Laurent Montel committed
232 233

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
234 235
                StandardActionManager::CreateResource, StandardActionManager::ErrorMessageText,
                ki18n("Could not create address book: %1"));
Laurent Montel's avatar
Laurent Montel committed
236 237

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
238 239
                StandardActionManager::CreateResource, StandardActionManager::ErrorMessageTitle,
                i18n("Address book creation failed"));
Laurent Montel's avatar
Laurent Montel committed
240 241 242
            break;
        case Akonadi::StandardActionManager::DeleteResources:

Guy Maurel's avatar
Guy Maurel committed
243 244 245 246 247 248 249
            mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteResources,
                                           ki18np("&Delete Address Book",
                                                  "&Delete %1 Address Books"));
            mGenericManager->action(Akonadi::StandardActionManager::DeleteResources)->setWhatsThis(
                i18n("Delete the selected address books<p>"
                     "The currently selected address books will be deleted, "
                     "along with all the contacts and contact groups they contain.</p>"));
Laurent Montel's avatar
Laurent Montel committed
250
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
251 252 253
                StandardActionManager::DeleteResources, StandardActionManager::MessageBoxText,
                ki18np("Do you really want to delete this address book?",
                       "Do you really want to delete %1 address books?"));
Laurent Montel's avatar
Laurent Montel committed
254 255

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
256 257
                StandardActionManager::DeleteResources, StandardActionManager::MessageBoxTitle,
                ki18ncp("@title:window", "Delete Address Book?", "Delete Address Books?"));
Laurent Montel's avatar
Laurent Montel committed
258 259 260 261

            break;
        case Akonadi::StandardActionManager::ResourceProperties:

Guy Maurel's avatar
Guy Maurel committed
262 263 264 265
            mGenericManager->action(Akonadi::StandardActionManager::ResourceProperties)->setText(
                i18n("Address Book Properties..."));
            mGenericManager->action(Akonadi::StandardActionManager::ResourceProperties)->setWhatsThis(
                i18n("Open a dialog to edit properties of the selected address book."));
Laurent Montel's avatar
Laurent Montel committed
266 267
            break;
        case Akonadi::StandardActionManager::SynchronizeResources:
Guy Maurel's avatar
Guy Maurel committed
268 269 270
            mGenericManager->setActionText(Akonadi::StandardActionManager::SynchronizeResources,
                                           ki18np("Update Address Book",
                                                  "Update %1 Address Books"));
Laurent Montel's avatar
Laurent Montel committed
271

Guy Maurel's avatar
Guy Maurel committed
272 273
            mGenericManager->action(Akonadi::StandardActionManager::SynchronizeResources)->setWhatsThis
            (i18n("Updates the content of all folders of the selected address books."));
Laurent Montel's avatar
Laurent Montel committed
274 275 276 277

            break;
        case StandardActionManager::Paste:
            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
278 279
                StandardActionManager::Paste, StandardActionManager::ErrorMessageText,
                ki18n("Could not paste contact: %1"));
Laurent Montel's avatar
Laurent Montel committed
280 281

            mGenericManager->setContextText(
Guy Maurel's avatar
Guy Maurel committed
282 283
                StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle,
                i18n("Paste failed"));
Laurent Montel's avatar
Laurent Montel committed
284 285 286 287
            break;
        default:
            break;
        }
Allen Winter's avatar
Allen Winter committed
288

289 290
    }

Guy Maurel's avatar
Guy Maurel committed
291
    static bool hasWritableCollection(const QModelIndex &index, const QString &mimeType)
292
    {
Guy Maurel's avatar
Guy Maurel committed
293 294 295 296
        const Akonadi::Collection collection =
            index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
        if (collection.isValid()) {
            if (collection.contentMimeTypes().contains(mimeType) &&
Laurent Montel's avatar
Laurent Montel committed
297
                    (collection.rights() & Akonadi::Collection::CanCreateItem)) {
Guy Maurel's avatar
Guy Maurel committed
298 299
                return true;
            }
Allen Winter's avatar
Allen Winter committed
300
        }
301

Guy Maurel's avatar
Guy Maurel committed
302 303 304 305
        const QAbstractItemModel *model = index.model();
        if (!model) {
            return false;
        }
306

Guy Maurel's avatar
Guy Maurel committed
307 308 309 310
        for (int row = 0; row < model->rowCount(index); ++row) {
            if (hasWritableCollection(model->index(row, 0, index), mimeType)) {
                return true;
            }
311
        }
312

Guy Maurel's avatar
Guy Maurel committed
313
        return false;
314 315
    }

Guy Maurel's avatar
Guy Maurel committed
316
    bool hasWritableCollection(const QString &mimeType) const
317
    {
Guy Maurel's avatar
Guy Maurel committed
318 319 320
        if (!mCollectionSelectionModel) {
            return false;
        }
321

Guy Maurel's avatar
Guy Maurel committed
322 323 324 325 326
        const QAbstractItemModel *collectionModel = mCollectionSelectionModel->model();
        for (int row = 0; row < collectionModel->rowCount(); ++row) {
            if (hasWritableCollection(collectionModel->index(row, 0, QModelIndex()), mimeType)) {
                return true;
            }
327
        }
328

Guy Maurel's avatar
Guy Maurel committed
329
        return false;
330 331 332 333
    }

    void updateActions()
    {
Guy Maurel's avatar
Guy Maurel committed
334 335 336 337 338 339 340 341 342 343 344 345
        int itemCount = 0;
        if (mItemSelectionModel) {
            itemCount = mItemSelectionModel->selectedRows().count();
            if (itemCount == 1) {
                const QModelIndex index = mItemSelectionModel->selectedRows().first();
                if (index.isValid()) {
                    const QString mimeType = index.data(EntityTreeModel::MimeTypeRole).toString();
                    if (mimeType == KContacts::Addressee::mimeType()) {
                        if (mGenericManager->action(Akonadi::StandardActionManager::CopyItems)) {
                            mGenericManager->setActionText(Akonadi::StandardActionManager::CopyItems,
                                                           ki18np("Copy Contact", "Copy %1 Contacts"));
                        }
Laurent Montel's avatar
Laurent Montel committed
346 347 348
                        QAction *act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToMenu);
                        if (act) {
                            act->setText(i18n("Copy Contact To"));
Guy Maurel's avatar
Guy Maurel committed
349
                        }
Laurent Montel's avatar
Laurent Montel committed
350 351 352
                        act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToDialog);
                        if (act) {
                            act->setText(i18n("Copy Contact To"));
Guy Maurel's avatar
Guy Maurel committed
353 354 355 356 357 358 359 360 361
                        }
                        if (mGenericManager->action(Akonadi::StandardActionManager::DeleteItems)) {
                            mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteItems,
                                                           ki18np("Delete Contact", "Delete %1 Contacts"));
                        }
                        if (mGenericManager->action(Akonadi::StandardActionManager::CutItems)) {
                            mGenericManager->setActionText(Akonadi::StandardActionManager::CutItems,
                                                           ki18np("Cut Contact", "Cut %1 Contacts"));
                        }
Laurent Montel's avatar
Laurent Montel committed
362 363 364
                        act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToMenu);
                        if (act) {
                            act->setText(i18n("Move Contact To"));
Guy Maurel's avatar
Guy Maurel committed
365
                        }
Laurent Montel's avatar
Laurent Montel committed
366 367 368
                        act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToDialog);
                        if (act) {
                            act->setText(i18n("Move Contact To"));
Guy Maurel's avatar
Guy Maurel committed
369
                        }
Laurent Montel's avatar
Laurent Montel committed
370 371 372
                        act = mActions.value(StandardContactActionManager::EditItem);
                        if (act) {
                            act->setText(i18n("Edit Contact..."));
Guy Maurel's avatar
Guy Maurel committed
373 374 375 376 377 378
                        }
                    } else if (mimeType == KContacts::ContactGroup::mimeType()) {
                        if (mGenericManager->action(Akonadi::StandardActionManager::CopyItems)) {
                            mGenericManager->setActionText(Akonadi::StandardActionManager::CopyItems,
                                                           ki18np("Copy Group", "Copy %1 Groups"));
                        }
Laurent Montel's avatar
Laurent Montel committed
379 380 381
                        QAction *act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToMenu);
                        if (act) {
                            act->setText(i18n("Copy Group To"));
Guy Maurel's avatar
Guy Maurel committed
382
                        }
Laurent Montel's avatar
Laurent Montel committed
383 384 385
                        act = mGenericManager->action(Akonadi::StandardActionManager::CopyItemToDialog);
                        if (act) {
                            act->setText(i18n("Copy Group To"));
Guy Maurel's avatar
Guy Maurel committed
386 387 388 389 390 391 392 393 394
                        }
                        if (mGenericManager->action(Akonadi::StandardActionManager::DeleteItems)) {
                            mGenericManager->setActionText(Akonadi::StandardActionManager::DeleteItems,
                                                           ki18np("Delete Group", "Delete %1 Groups"));
                        }
                        if (mGenericManager->action(Akonadi::StandardActionManager::CutItems)) {
                            mGenericManager->setActionText(Akonadi::StandardActionManager::CutItems,
                                                           ki18np("Cut Group", "Cut %1 Groups"));
                        }
Laurent Montel's avatar
Laurent Montel committed
395 396 397
                        act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToMenu);
                        if (act) {
                            act->setText(i18n("Move Group To"));
Guy Maurel's avatar
Guy Maurel committed
398
                        }
Laurent Montel's avatar
Laurent Montel committed
399 400 401
                        act = mGenericManager->action(Akonadi::StandardActionManager::MoveItemToDialog);
                        if (act) {
                            act->setText(i18n("Move Group To"));
Guy Maurel's avatar
Guy Maurel committed
402
                        }
Laurent Montel's avatar
Laurent Montel committed
403 404 405
                        act = mActions.value(StandardContactActionManager::EditItem);
                        if (act) {
                            act->setText(i18n("Edit Group..."));
Guy Maurel's avatar
Guy Maurel committed
406 407 408
                        }
                    }
                }
409 410
            }
        }
Guy Maurel's avatar
Guy Maurel committed
411 412 413 414 415 416

        if (mActions.contains(StandardContactActionManager::CreateContact)) {
            mActions[StandardContactActionManager::CreateContact]->setEnabled(hasWritableCollection(KContacts::Addressee::mimeType()));
        }
        if (mActions.contains(StandardContactActionManager::CreateContactGroup)) {
            mActions[StandardContactActionManager::CreateContactGroup]->setEnabled(hasWritableCollection(KContacts::ContactGroup::mimeType()));
417 418
        }

Guy Maurel's avatar
Guy Maurel committed
419 420 421 422 423
        if (mActions.contains(StandardContactActionManager::EditItem)) {
            bool canEditItem = true;

            // only one selected item can be edited
            canEditItem = canEditItem && (itemCount == 1);
424

Guy Maurel's avatar
Guy Maurel committed
425 426 427 428 429 430 431 432 433 434 435 436 437
            // check whether parent collection allows changing the item
            const QModelIndexList rows = mItemSelectionModel->selectedRows();
            if (rows.count() == 1) {
                const QModelIndex index = rows.first();
                const Collection parentCollection = index.data(EntityTreeModel::ParentCollectionRole).value<Collection>();
                if (parentCollection.isValid()) {
                    canEditItem = canEditItem && (parentCollection.rights() & Collection::CanChangeItem);
                }
            }

            mActions.value(StandardContactActionManager::EditItem)->setEnabled(canEditItem);
        }

Laurent Montel's avatar
Laurent Montel committed
438
        Q_EMIT mParent->actionStateUpdated();
439 440
    }

441 442
    Collection selectedCollection() const
    {
Guy Maurel's avatar
Guy Maurel committed
443 444 445
        if (!mCollectionSelectionModel) {
            return Collection();
        }
446

Guy Maurel's avatar
Guy Maurel committed
447 448 449
        if (mCollectionSelectionModel->selectedIndexes().isEmpty()) {
            return Collection();
        }
450

Guy Maurel's avatar
Guy Maurel committed
451 452 453 454
        const QModelIndex index = mCollectionSelectionModel->selectedIndexes().first();
        if (!index.isValid()) {
            return Collection();
        }
455

Guy Maurel's avatar
Guy Maurel committed
456
        return index.data(EntityTreeModel::CollectionRole).value<Collection>();
457 458 459 460
    }

    void slotCreateContact()
    {
Guy Maurel's avatar
Guy Maurel committed
461 462 463 464 465 466 467 468 469
        if (mInterceptedActions.contains(StandardContactActionManager::CreateContact)) {
            return;
        }

        QPointer<Akonadi::ContactEditorDialog> dlg = new Akonadi::ContactEditorDialog(
            Akonadi::ContactEditorDialog::CreateMode, mParentWidget);
        dlg->setDefaultAddressBook(selectedCollection());
        dlg->exec();
        delete dlg;
470 471 472
    }

    void slotCreateContactGroup()
473
    {
Guy Maurel's avatar
Guy Maurel committed
474 475 476 477 478 479 480 481 482
        if (mInterceptedActions.contains(StandardContactActionManager::CreateContactGroup)) {
            return;
        }

        QPointer<Akonadi::ContactGroupEditorDialog> dlg = new Akonadi::ContactGroupEditorDialog(
            Akonadi::ContactGroupEditorDialog::CreateMode, mParentWidget);
        dlg->setDefaultAddressBook(selectedCollection());
        dlg->exec();
        delete dlg;
483 484 485 486
    }

    void slotEditItem()
    {
Guy Maurel's avatar
Guy Maurel committed
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
        if (mInterceptedActions.contains(StandardContactActionManager::EditItem)) {
            return;
        }

        if (!mItemSelectionModel) {
            return;
        }

        if (mItemSelectionModel->selectedIndexes().isEmpty()) {
            return;
        }

        const QModelIndex index = mItemSelectionModel->selectedIndexes().first();
        if (!index.isValid()) {
            return;
        }

        const Item item = index.data(EntityTreeModel::ItemRole).value<Item>();
        if (!item.isValid()) {
            return;
        }

        if (Akonadi::MimeTypeChecker::isWantedItem(item, KContacts::Addressee::mimeType())) {
            QPointer<Akonadi::ContactEditorDialog> dlg = new Akonadi::ContactEditorDialog(
                Akonadi::ContactEditorDialog::EditMode, mParentWidget);
            connect(dlg, SIGNAL(error(QString)),
                    mParent, SLOT(slotContactEditorError(QString)));
            dlg->setContact(item);
            dlg->exec();
            delete dlg;
        } else if (Akonadi::MimeTypeChecker::isWantedItem(item, KContacts::ContactGroup::mimeType())) {
            QPointer<Akonadi::ContactGroupEditorDialog> dlg = new Akonadi::ContactGroupEditorDialog(
                Akonadi::ContactGroupEditorDialog::EditMode, mParentWidget);
            dlg->setContactGroup(item);
            dlg->exec();
            delete dlg;
        }
524 525
    }

Guy Maurel's avatar
Guy Maurel committed
526
    void slotContactEditorError(const QString &error)
527
    {
Yuri Chornoivan's avatar
Yuri Chornoivan committed
528
        KMessageBox::error(mParentWidget, i18n("Contact cannot be stored: %1", error), i18n("Failed to store contact"));
529 530
    }

531 532 533 534 535
    KActionCollection *mActionCollection;
    QWidget *mParentWidget;
    StandardActionManager *mGenericManager;
    QItemSelectionModel *mCollectionSelectionModel;
    QItemSelectionModel *mItemSelectionModel;
Laurent Montel's avatar
Laurent Montel committed
536
    QHash<StandardContactActionManager::Type, QAction *> mActions;
537
    QSet<StandardContactActionManager::Type> mInterceptedActions;
538 539 540
    StandardContactActionManager *mParent;
};

Guy Maurel's avatar
Guy Maurel committed
541 542 543
StandardContactActionManager::StandardContactActionManager(KActionCollection *actionCollection, QWidget *parent)
    : QObject(parent)
    , d(new Private(actionCollection, parent, this))
544 545 546 547 548
{
}

StandardContactActionManager::~StandardContactActionManager()
{
Guy Maurel's avatar
Guy Maurel committed
549
    delete d;
550 551
}

Guy Maurel's avatar
Guy Maurel committed
552
void StandardContactActionManager::setCollectionSelectionModel(QItemSelectionModel *selectionModel)
553
{
Guy Maurel's avatar
Guy Maurel committed
554 555
    d->mCollectionSelectionModel = selectionModel;
    d->mGenericManager->setCollectionSelectionModel(selectionModel);
556

Guy Maurel's avatar
Guy Maurel committed
557 558 559 560 561 562
    connect(selectionModel->model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
            SLOT(updateActions()));
    connect(selectionModel->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
            SLOT(updateActions()));
    connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            SLOT(updateActions()));
563

Guy Maurel's avatar
Guy Maurel committed
564
    d->updateActions();
565 566
}

Guy Maurel's avatar
Guy Maurel committed
567
void StandardContactActionManager::setItemSelectionModel(QItemSelectionModel *selectionModel)
568
{
Guy Maurel's avatar
Guy Maurel committed
569 570
    d->mItemSelectionModel = selectionModel;
    d->mGenericManager->setItemSelectionModel(selectionModel);
571

Guy Maurel's avatar
Guy Maurel committed
572 573
    connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            SLOT(updateActions()));
574

Guy Maurel's avatar
Guy Maurel committed
575
    d->updateActions();
576 577
}

Guy Maurel's avatar
Guy Maurel committed
578
QAction *StandardContactActionManager::createAction(Type type)
579
{
Laurent Montel's avatar
Laurent Montel committed
580 581 582
    QAction *action = d->mActions.value(type);
    if (action) {
        return action;
Guy Maurel's avatar
Guy Maurel committed
583
    }
584

Guy Maurel's avatar
Guy Maurel committed
585
    switch (type) {
586
    case CreateContact:
Guy Maurel's avatar
Guy Maurel committed
587
        action = new QAction(d->mParentWidget);
Laurent Montel's avatar
Laurent Montel committed
588
        action->setIcon(QIcon::fromTheme(QStringLiteral("contact-new")));
Guy Maurel's avatar
Guy Maurel committed
589 590 591 592 593 594 595
        action->setText(i18n("New &Contact..."));
        action->setWhatsThis(i18n("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>"));
        d->mActions.insert(CreateContact, action);
        d->mActionCollection->addAction(QStringLiteral("akonadi_contact_create"), action);
        d->mActionCollection->setDefaultShortcut(action,  QKeySequence(Qt::CTRL + Qt::Key_N));
        connect(action, SIGNAL(triggered(bool)), this, SLOT(slotCreateContact()));
        break;
596
    case CreateContactGroup:
Guy Maurel's avatar
Guy Maurel committed
597
        action = new QAction(d->mParentWidget);
Laurent Montel's avatar
Laurent Montel committed
598
        action->setIcon(QIcon::fromTheme(QStringLiteral("user-group-new")));
Guy Maurel's avatar
Guy Maurel committed
599 600 601 602 603 604 605
        action->setText(i18n("New &Group..."));
        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>"));
        d->mActions.insert(CreateContactGroup, action);
        d->mActionCollection->addAction(QStringLiteral("akonadi_contact_group_create"), action);
        d->mActionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_G));
        connect(action, SIGNAL(triggered(bool)), this, SLOT(slotCreateContactGroup()));
        break;
606
    case EditItem:
Guy Maurel's avatar
Guy Maurel committed
607
        action = new QAction(d->mParentWidget);
Laurent Montel's avatar
Laurent Montel committed
608
        action->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
Guy Maurel's avatar
Guy Maurel committed
609 610 611 612 613 614 615 616
        action->setText(i18n("Edit Contact..."));
        action->setWhatsThis(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 phone numbers.</p>"));
        action->setEnabled(false);
        d->mActions.insert(EditItem, action);
        d->mActionCollection->addAction(QStringLiteral("akonadi_contact_item_edit"), action);

        connect(action, SIGNAL(triggered(bool)), this, SLOT(slotEditItem()));
        break;
617
    default:
Guy Maurel's avatar
Guy Maurel committed
618 619 620
        Q_ASSERT(false);   // should never happen
        break;
    }
621

Guy Maurel's avatar
Guy Maurel committed
622
    return action;
623 624
}

Guy Maurel's avatar
Guy Maurel committed
625
QAction *StandardContactActionManager::createAction(StandardActionManager::Type type)
626
{
Guy Maurel's avatar
Guy Maurel committed
627 628 629 630 631 632
    QAction *act = d->mGenericManager->action(type);
    if (!act) {
        act = d->mGenericManager->createAction(type);
    }
    d->updateGenericAction(type);
    return act;
633 634
}

635 636
void StandardContactActionManager::createAllActions()
{
Guy Maurel's avatar
Guy Maurel committed
637 638 639
    createAction(CreateContact);
    createAction(CreateContactGroup);
    createAction(EditItem);
640

Guy Maurel's avatar
Guy Maurel committed
641 642
    d->mGenericManager->createAllActions();
    d->updateGenericAllActions();
643

Guy Maurel's avatar
Guy Maurel committed
644
    d->updateActions();
645 646
}

Guy Maurel's avatar
Guy Maurel committed
647
QAction *StandardContactActionManager::action(Type type) const
648
{
Guy Maurel's avatar
Guy Maurel committed
649 650 651
    if (d->mActions.contains(type)) {
        return d->mActions.value(type);
    }
652

Laurent Montel's avatar
Laurent Montel committed
653
    return nullptr;
654 655
}

Guy Maurel's avatar
Guy Maurel committed
656
QAction *StandardContactActionManager::action(StandardActionManager::Type type) const
657
{
Guy Maurel's avatar
Guy Maurel committed
658
    return d->mGenericManager->action(type);
659 660
}

Guy Maurel's avatar
Guy Maurel committed
661
void StandardContactActionManager::setActionText(StandardActionManager::Type type, const KLocalizedString &text)
662
{
Guy Maurel's avatar
Guy Maurel committed
663
    d->mGenericManager->setActionText(type, text);
664 665
}

Guy Maurel's avatar
Guy Maurel committed
666
void StandardContactActionManager::interceptAction(Type type, bool intercept)
667
{
Guy Maurel's avatar
Guy Maurel committed
668 669 670 671 672
    if (intercept) {
        d->mInterceptedActions.insert(type);
    } else {
        d->mInterceptedActions.remove(type);
    }
673
}
674

Guy Maurel's avatar
Guy Maurel committed
675
void StandardContactActionManager::interceptAction(StandardActionManager::Type type, bool intercept)
676
{
Guy Maurel's avatar
Guy Maurel committed
677
    d->mGenericManager->interceptAction(type, intercept);
678 679 680 681
}

Akonadi::Collection::List StandardContactActionManager::selectedCollections() const
{
Guy Maurel's avatar
Guy Maurel committed
682
    return d->mGenericManager->selectedCollections();
683 684 685 686
}

Akonadi::Item::List StandardContactActionManager::selectedItems() const
{
Guy Maurel's avatar
Guy Maurel committed
687
    return d->mGenericManager->selectedItems();
688 689
}

Guy Maurel's avatar
Guy Maurel committed
690
void StandardContactActionManager::setCollectionPropertiesPageNames(const QStringList &names)
691
{
Guy Maurel's avatar
Guy Maurel committed
692
    d->mGenericManager->setCollectionPropertiesPageNames(names);
693
}
694
#include "moc_standardcontactactionmanager.cpp"