20#include "standardactionmanager.h"
22#include "actionstatemanager_p.h"
23#include "agentfilterproxymodel.h"
24#include "agentinstancecreatejob.h"
25#include "agentmanager.h"
26#include "agenttypedialog.h"
27#include "collectioncreatejob.h"
28#include "collectiondeletejob.h"
29#include "collectiondialog.h"
30#include "collectionmodel.h"
31#include "collectionutils_p.h"
32#include "entitytreemodel.h"
33#include "favoritecollectionsmodel.h"
34#include "itemdeletejob.h"
37#include "pastehelper_p.h"
38#include "specialcollectionattribute_p.h"
39#include "collectionpropertiesdialog.h"
40#include "subscriptiondialog_p.h"
41#include "renamefavoritedialog.h"
43#include "trashrestorejob.h"
44#include "entitydeletedattribute.h"
45#include "recentcollectionaction_p.h"
49#include <KActionCollection>
52#include <KInputDialog>
53#include <KLocalizedString>
56#include <KToggleAction>
58#include <QtCore/QMimeData>
59#include <QApplication>
61#include <QItemSelectionModel>
63#include <QWeakPointer>
65#include <boost/static_assert.hpp>
74 ActionWithAlternative,
83 const char *iconLabel;
87 ActionType actionType;
88} standardActionData[] = {
89 {
"akonadi_collection_create", I18N_NOOP(
"&New Folder..."), I18N_NOOP(
"New"),
"folder-new", 0, SLOT(slotCreateCollection()), NormalAction },
90 {
"akonadi_collection_copy", 0, 0,
"edit-copy", 0, SLOT(slotCopyCollections()), NormalAction },
91 {
"akonadi_collection_delete", I18N_NOOP(
"&Delete Folder"), I18N_NOOP(
"Delete"),
"edit-delete", 0, SLOT(slotDeleteCollection()), NormalAction },
92 {
"akonadi_collection_sync", I18N_NOOP(
"&Synchronize Folder"), I18N_NOOP(
"Synchronize"),
"view-refresh", Qt::Key_F5, SLOT(slotSynchronizeCollection()), NormalAction },
93 {
"akonadi_collection_properties", I18N_NOOP(
"Folder &Properties"), I18N_NOOP(
"Properties"),
"configure", 0, SLOT(slotCollectionProperties()), NormalAction },
94 {
"akonadi_item_copy", 0, 0,
"edit-copy", 0, SLOT(slotCopyItems()), NormalAction },
95 {
"akonadi_paste", I18N_NOOP(
"&Paste"), I18N_NOOP(
"Paste"),
"edit-paste", Qt::CTRL + Qt::Key_V, SLOT(slotPaste()), NormalAction },
96 {
"akonadi_item_delete", 0, 0,
"edit-delete", Qt::Key_Delete, SLOT(slotDeleteItems()), NormalAction },
97 {
"akonadi_manage_local_subscriptions", I18N_NOOP(
"Manage Local &Subscriptions..."), I18N_NOOP(
"Manage Local Subscriptions"),
"folder-bookmarks", 0, SLOT(slotLocalSubscription()), NormalAction },
98 {
"akonadi_collection_add_to_favorites", I18N_NOOP(
"Add to Favorite Folders"), I18N_NOOP(
"Add to Favorite"),
"bookmark-new", 0, SLOT(slotAddToFavorites()), NormalAction },
99 {
"akonadi_collection_remove_from_favorites", I18N_NOOP(
"Remove from Favorite Folders"), I18N_NOOP(
"Remove from Favorite"),
"edit-delete", 0, SLOT(slotRemoveFromFavorites()), NormalAction },
100 {
"akonadi_collection_rename_favorite", I18N_NOOP(
"Rename Favorite..."), I18N_NOOP(
"Rename"),
"edit-rename", 0, SLOT(slotRenameFavorite()), NormalAction },
101 {
"akonadi_collection_copy_to_menu", I18N_NOOP(
"Copy Folder To..."), I18N_NOOP(
"Copy To"),
"edit-copy", 0, SLOT(slotCopyCollectionTo(QAction*)), MenuAction },
102 {
"akonadi_item_copy_to_menu", I18N_NOOP(
"Copy Item To..."), I18N_NOOP(
"Copy To"),
"edit-copy", 0, SLOT(slotCopyItemTo(QAction*)), MenuAction },
103 {
"akonadi_item_move_to_menu", I18N_NOOP(
"Move Item To..."), I18N_NOOP(
"Move To"),
"go-jump", 0, SLOT(slotMoveItemTo(QAction*)), MenuAction },
104 {
"akonadi_collection_move_to_menu", I18N_NOOP(
"Move Folder To..."), I18N_NOOP(
"Move To"),
"go-jump", 0, SLOT(slotMoveCollectionTo(QAction*)), MenuAction },
105 {
"akonadi_item_cut", I18N_NOOP(
"&Cut Item"), I18N_NOOP(
"Cut"),
"edit-cut", Qt::CTRL + Qt::Key_X, SLOT(slotCutItems()), NormalAction },
106 {
"akonadi_collection_cut", I18N_NOOP(
"&Cut Folder"), I18N_NOOP(
"Cut"),
"edit-cut", Qt::CTRL + Qt::Key_X, SLOT(slotCutCollections()), NormalAction },
107 {
"akonadi_resource_create", I18N_NOOP(
"Create Resource"), 0,
"folder-new", 0, SLOT(slotCreateResource()), NormalAction },
108 {
"akonadi_resource_delete", I18N_NOOP(
"Delete Resource"), 0,
"edit-delete", 0, SLOT(slotDeleteResource()), NormalAction },
109 {
"akonadi_resource_properties", I18N_NOOP(
"&Resource Properties"), I18N_NOOP(
"Properties"),
"configure", 0, SLOT(slotResourceProperties()), NormalAction },
110 {
"akonadi_resource_synchronize", I18N_NOOP(
"Synchronize Resource"), I18N_NOOP(
"Synchronize"),
"view-refresh", 0, SLOT(slotSynchronizeResource()), NormalAction },
111 {
"akonadi_work_offline", I18N_NOOP(
"Work Offline"), 0,
"user-offline", 0, SLOT(slotToggleWorkOffline(
bool)), ToggleAction },
112 {
"akonadi_collection_copy_to_dialog", I18N_NOOP(
"Copy Folder To..."), I18N_NOOP(
"Copy To"),
"edit-copy", 0, SLOT(slotCopyCollectionTo()), NormalAction },
113 {
"akonadi_collection_move_to_dialog", I18N_NOOP(
"Move Folder To..."), I18N_NOOP(
"Move To"),
"go-jump", 0, SLOT(slotMoveCollectionTo()), NormalAction },
114 {
"akonadi_item_copy_to_dialog", I18N_NOOP(
"Copy Item To..."), I18N_NOOP(
"Copy To"),
"edit-copy", 0, SLOT(slotCopyItemTo()), NormalAction },
115 {
"akonadi_item_move_to_dialog", I18N_NOOP(
"Move Item To..."), I18N_NOOP(
"Move To"),
"go-jump", 0, SLOT(slotMoveItemTo()), NormalAction },
116 {
"akonadi_collection_sync_recursive", I18N_NOOP(
"&Synchronize Folder Recursively"), I18N_NOOP(
"Synchronize Recursively"),
"view-refresh", Qt::CTRL + Qt::Key_F5, SLOT(slotSynchronizeCollectionRecursive()), NormalAction },
117 {
"akonadi_move_collection_to_trash", I18N_NOOP(
"&Move Folder To Trash"), I18N_NOOP(
"Move Folder To Trash"),
"user-trash", 0, SLOT(slotMoveCollectionToTrash()), NormalAction },
118 {
"akonadi_move_item_to_trash", I18N_NOOP(
"&Move Item To Trash"), I18N_NOOP(
"Move Item To Trash"),
"user-trash", 0, SLOT(slotMoveItemToTrash()), NormalAction },
119 {
"akonadi_restore_collection_from_trash", I18N_NOOP(
"&Restore Folder From Trash"), I18N_NOOP(
"Restore Folder From Trash"),
"view-refresh", 0, SLOT(slotRestoreCollectionFromTrash()), NormalAction },
120 {
"akonadi_restore_item_from_trash", I18N_NOOP(
"&Restore Item From Trash"), I18N_NOOP(
"Restore Item From Trash"),
"view-refresh", 0, SLOT(slotRestoreItemFromTrash()), NormalAction },
121 {
"akonadi_collection_trash_restore", I18N_NOOP(
"&Restore Folder From Trash"), I18N_NOOP(
"Restore Folder From Trash"),
"user-trash", 0, SLOT(slotTrashRestoreCollection()), ActionWithAlternative },
122 { 0, I18N_NOOP(
"&Restore Collection From Trash"), I18N_NOOP(
"Restore Collection From Trash"),
"view-refresh", 0, 0, ActionAlternative },
123 {
"akonadi_item_trash_restore", I18N_NOOP(
"&Restore Item From Trash"), I18N_NOOP(
"Restore Item From Trash"),
"user-trash", 0, SLOT(slotTrashRestoreItem()), ActionWithAlternative },
124 { 0, I18N_NOOP(
"&Restore Item From Trash"), I18N_NOOP(
"Restore Item From Trash"),
"view-refresh", 0, 0, ActionAlternative },
125 {
"akonadi_collection_sync_favorite_folders", I18N_NOOP(
"&Synchronize Favorite Folders"), I18N_NOOP(
"Synchronize Favorite Folders"),
"view-refresh", Qt::CTRL + Qt::SHIFT + Qt::Key_L , SLOT(slotSynchronizeFavoriteCollections()), NormalAction }
128static const int numStandardActionData =
sizeof standardActionData /
sizeof * standardActionData;
130BOOST_STATIC_ASSERT(numStandardActionData == StandardActionManager::LastType);
153static void setWorkOffline(
bool offline)
155 KConfig config(QLatin1String(
"akonadikderc"));
156 KConfigGroup group(&config, QLatin1String(
"Actions"));
158 group.writeEntry(
"WorkOffline", offline);
161static bool workOffline()
163 KConfig config(QLatin1String(
"akonadikderc"));
164 const KConfigGroup group(&config, QLatin1String(
"Actions"));
166 return group.readEntry(
"WorkOffline",
false);
169static QModelIndexList safeSelectedRows(QItemSelectionModel *selectionModel)
171 QModelIndexList selectedRows = selectionModel->selectedRows();
172 if (!selectedRows.isEmpty()) {
177 foreach (
const QItemSelectionRange &range, selectionModel->selection()) {
178 if (!range.isValid() || range.isEmpty()) {
181 const QModelIndex parent = range.parent();
182 for (
int row = range.top(); row <= range.bottom(); ++row) {
183 const QModelIndex index = range.model()->index(row, range.left(), parent);
184 const Qt::ItemFlags flags = range.model()->flags(index);
185 if ((flags &Qt::ItemIsSelectable) && (flags &Qt::ItemIsEnabled)) {
186 selectedRows.push_back(index);
197class StandardActionManager::Private
202 , actionCollection(0)
204 , collectionSelectionModel(0)
205 , itemSelectionModel(0)
207 , favoriteSelectionModel(0)
208 , insideSelectionSlot(false)
210 actions.fill(0, StandardActionManager::LastType);
212 pluralLabels.insert(StandardActionManager::CopyCollections,
213 ki18np(
"&Copy Folder",
"&Copy %1 Folders"));
214 pluralLabels.insert(StandardActionManager::CopyItems,
215 ki18np(
"&Copy Item",
"&Copy %1 Items"));
216 pluralLabels.insert(StandardActionManager::CutItems,
217 ki18np(
"&Cut Item",
"&Cut %1 Items"));
218 pluralLabels.insert(StandardActionManager::CutCollections,
219 ki18np(
"&Cut Folder",
"&Cut %1 Folders"));
220 pluralLabels.insert(StandardActionManager::DeleteItems,
221 ki18np(
"&Delete Item",
"&Delete %1 Items"));
222 pluralLabels.insert(StandardActionManager::DeleteCollections,
223 ki18np(
"&Delete Folder",
"&Delete %1 Folders"));
224 pluralLabels.insert(StandardActionManager::SynchronizeCollections,
225 ki18np(
"&Synchronize Folder",
"&Synchronize %1 Folders"));
226 pluralLabels.insert(StandardActionManager::DeleteResources,
227 ki18np(
"&Delete Resource",
"&Delete %1 Resources"));
228 pluralLabels.insert(StandardActionManager::SynchronizeResources,
229 ki18np(
"&Synchronize Resource",
"&Synchronize %1 Resources"));
231 pluralIconLabels.insert(StandardActionManager::CopyCollections,
232 ki18np(
"Copy Folder",
"Copy %1 Folders"));
233 pluralIconLabels.insert(StandardActionManager::CopyItems,
234 ki18np(
"Copy Item",
"Copy %1 Items"));
235 pluralIconLabels.insert(StandardActionManager::CutItems,
236 ki18np(
"Cut Item",
"Cut %1 Items"));
237 pluralIconLabels.insert(StandardActionManager::CutCollections,
238 ki18np(
"Cut Folder",
"Cut %1 Folders"));
239 pluralIconLabels.insert(StandardActionManager::DeleteItems,
240 ki18np(
"Delete Item",
"Delete %1 Items"));
241 pluralIconLabels.insert(StandardActionManager::DeleteCollections,
242 ki18np(
"Delete Folder",
"Delete %1 Folders"));
243 pluralIconLabels.insert(StandardActionManager::SynchronizeCollections,
244 ki18np(
"Synchronize Folder",
"Synchronize %1 Folders"));
245 pluralIconLabels.insert(StandardActionManager::DeleteResources,
246 ki18np(
"Delete Resource",
"Delete %1 Resources"));
247 pluralIconLabels.insert(StandardActionManager::SynchronizeResources,
248 ki18np(
"Synchronize Resource",
"Synchronize %1 Resources"));
250 setContextText(StandardActionManager::CreateCollection, StandardActionManager::DialogTitle,
251 i18nc(
"@title:window",
"New Folder"));
252 setContextText(StandardActionManager::CreateCollection, StandardActionManager::DialogText,
253 i18nc(
"@label:textbox name of a thing",
"Name"));
254 setContextText(StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageText,
255 ki18n(
"Could not create folder: %1"));
256 setContextText(StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageTitle,
257 i18n(
"Folder creation failed"));
259 setContextText(StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxText,
260 ki18np(
"Do you really want to delete this folder and all its sub-folders?",
261 "Do you really want to delete %1 folders and all their sub-folders?"));
262 setContextText(StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxTitle,
263 ki18ncp(
"@title:window",
"Delete folder?",
"Delete folders?"));
264 setContextText(StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageText,
265 ki18n(
"Could not delete folder: %1"));
266 setContextText(StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageTitle,
267 i18n(
"Folder deletion failed"));
269 setContextText(StandardActionManager::CollectionProperties, StandardActionManager::DialogTitle,
270 ki18nc(
"@title:window",
"Properties of Folder %1"));
272 setContextText(StandardActionManager::DeleteItems, StandardActionManager::MessageBoxText,
273 ki18np(
"Do you really want to delete the selected item?",
274 "Do you really want to delete %1 items?"));
275 setContextText(StandardActionManager::DeleteItems, StandardActionManager::MessageBoxTitle,
276 ki18ncp(
"@title:window",
"Delete item?",
"Delete items?"));
277 setContextText(StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageText,
278 ki18n(
"Could not delete item: %1"));
279 setContextText(StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageTitle,
280 i18n(
"Item deletion failed"));
282 setContextText(StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogTitle,
283 i18nc(
"@title:window",
"Rename Favorite"));
284 setContextText(StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogText,
285 i18nc(
"@label:textbox name of the folder",
"Name:"));
287 setContextText(StandardActionManager::CreateResource, StandardActionManager::DialogTitle,
288 i18nc(
"@title:window",
"New Resource"));
289 setContextText(StandardActionManager::CreateResource, StandardActionManager::ErrorMessageText,
290 ki18n(
"Could not create resource: %1"));
291 setContextText(StandardActionManager::CreateResource, StandardActionManager::ErrorMessageTitle,
292 i18n(
"Resource creation failed"));
294 setContextText(StandardActionManager::DeleteResources, StandardActionManager::MessageBoxText,
295 ki18np(
"Do you really want to delete this resource?",
296 "Do you really want to delete %1 resources?"));
297 setContextText(StandardActionManager::DeleteResources, StandardActionManager::MessageBoxTitle,
298 ki18ncp(
"@title:window",
"Delete Resource?",
"Delete Resources?"));
300 setContextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageText,
301 ki18n(
"Could not paste data: %1"));
302 setContextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle,
303 i18n(
"Paste failed"));
305 qRegisterMetaType<Akonadi::Item::List>(
"Akonadi::Item::List");
307 void enableAction(
int type,
bool enable)
314 Q_ASSERT(type < StandardActionManager::LastType);
316 actions[type]->setEnabled(enable);
320 KActionMenu *actionMenu = qobject_cast<KActionMenu *>(actions[type]);
323 KMenu *menu = actionMenu->menu();
325 if (menu->property(
"actionType").isValid() && menu->isEmpty()) {
328 mRecentCollectionsMenu.remove(type);
332 menu->setProperty(
"actionType",
static_cast<int>(type));
333 q->connect(menu, SIGNAL(aboutToShow()), SLOT(aboutToShowMenu()));
334 q->connect(menu, SIGNAL(triggered(QAction*)), standardActionData[type].slot);
335 actionMenu->setMenu(menu);
339 void aboutToShowMenu()
341 QMenu *menu = qobject_cast<QMenu *>(q->sender());
346 if (!menu->isEmpty()) {
353 QWeakPointer<RecentCollectionAction> recentCollection =
new RecentCollectionAction(type, selectedCollectionsList, collectionSelectionModel->model(), menu);
354 mRecentCollectionsMenu.insert(type, recentCollection);
355 const QSet<QString> mimeTypes = mimeTypesOfSelection(type);
356 fillFoldersMenu(selectedCollectionsList,
360 collectionSelectionModel->model(),
366 if (type == CopyCollectionToMenu ||
367 type == CopyItemToMenu ||
368 type == MoveItemToMenu ||
369 type == MoveCollectionToMenu)
373 const QSet<QString> mimeTypes = mimeTypesOfSelection(type);
374 fillFoldersMenu(selectedCollectionsList,
378 collectionSelectionModel->model(),
383 void updateAlternatingAction(
int type)
390 Q_ASSERT(type < StandardActionManager::LastType);
391 if (!actions[type]) {
399 if ((standardActionData[type].actionType == ActionWithAlternative) || (standardActionData[type].actionType == ActionAlternative)) {
400 actions[type]->setText(i18n(standardActionData[type].label));
401 actions[type]->setIcon(KIcon(QString::fromLatin1(standardActionData[type].icon)));
403 if (pluralLabels.contains(type) && !pluralLabels.value(type).isEmpty()) {
404 actions[type]->setText(pluralLabels.value(type).subs(1).toString());
405 }
else if (standardActionData[type].label) {
406 actions[type]->setText(i18n(standardActionData[type].label));
409 if (pluralIconLabels.contains(type) && !pluralIconLabels.value(type).isEmpty()) {
410 actions[type]->setIconText(pluralIconLabels.value(type).subs(1).toString());
411 }
else if (standardActionData[type].iconLabel) {
412 actions[type]->setIconText(i18n(standardActionData[type].iconLabel));
415 if (standardActionData[type].icon) {
416 actions[type]->setIcon(KIcon(QString::fromLatin1(standardActionData[type].icon)));
432 void updatePluralLabel(
int type,
int count)
439 Q_ASSERT(type < StandardActionManager::LastType);
440 if (actions[type] && pluralLabels.contains(type) && !pluralLabels.value(type).isEmpty()) {
441 actions[type]->setText(pluralLabels.value(type).subs(qMax(count, 1)).toString());
447 if (!favoritesModel) {
451 return favoritesModel->collectionIds().contains(collection.id());
454 void encodeToClipboard(QItemSelectionModel *selectionModel,
bool cut =
false)
456 Q_ASSERT(selectionModel);
457 if (safeSelectedRows(selectionModel).count() <= 0) {
461#ifndef QT_NO_CLIPBOARD
462 QAbstractItemModel *model =
const_cast<QAbstractItemModel *
>(selectionModel->model());
463 QMimeData *mimeData = selectionModel->model()->mimeData(safeSelectedRows(selectionModel));
464 model->setData(QModelIndex(),
false, EntityTreeModel::PendingCutRole);
465 markCutAction(mimeData, cut);
466 QApplication::clipboard()->setMimeData(mimeData);
468 foreach (
const QModelIndex &index, safeSelectedRows(selectionModel)) {
469 model->setData(index,
true, EntityTreeModel::PendingCutRole);
477 if (collectionSelectionModel) {
478 const QModelIndexList rows = safeSelectedRows(collectionSelectionModel);
479 foreach (
const QModelIndex &index, rows) {
481 if (!collection.isValid()) {
485 const Collection parentCollection = index.data(EntityTreeModel::ParentCollectionRole).value<
Collection>();
486 collection.setParentCollection(parentCollection);
488 selectedCollectionsList << collection;
493 Item::List selectedItems;
494 if (itemSelectionModel) {
495 const QModelIndexList rows = safeSelectedRows(itemSelectionModel);
496 foreach (
const QModelIndex &index, rows) {
497 Item item = index.data(EntityTreeModel::ItemRole).value<Item>();
498 if (!item.isValid()) {
502 const Collection parentCollection = index.data(EntityTreeModel::ParentCollectionRole).value<
Collection>();
503 item.setParentCollection(parentCollection);
505 selectedItems << item;
509 mActionStateManager.updateState(selectedCollectionsList, selectedItems);
510 if (favoritesModel) {
511 enableAction(StandardActionManager::SynchronizeFavoriteCollections, (favoritesModel->rowCount() > 0));
513 emit q->actionStateUpdated();
516#ifndef QT_NO_CLIPBOARD
517 void clipboardChanged(QClipboard::Mode mode)
519 if (mode == QClipboard::Clipboard) {
525 QItemSelection mapToEntityTreeModel(
const QAbstractItemModel *model,
const QItemSelection &selection)
const
527 const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(model);
529 return mapToEntityTreeModel(proxy->sourceModel(), proxy->mapSelectionToSource(selection));
535 QItemSelection mapFromEntityTreeModel(
const QAbstractItemModel *model,
const QItemSelection &selection)
const
537 const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(model);
539 const QItemSelection select = mapFromEntityTreeModel(proxy->sourceModel(), selection);
540 return proxy->mapSelectionFromSource(select);
547 class InsideSelectionSlotBlocker {
549 InsideSelectionSlotBlocker(Private *p)
552 Q_ASSERT(!p->insideSelectionSlot);
553 p->insideSelectionSlot =
true;
556 ~InsideSelectionSlotBlocker()
558 Q_ASSERT(_p->insideSelectionSlot);
559 _p->insideSelectionSlot =
false;
565 void collectionSelectionChanged()
567 if (insideSelectionSlot) {
570 InsideSelectionSlotBlocker block(
this);
571 QItemSelection selection = collectionSelectionModel->selection();
572 selection = mapToEntityTreeModel(collectionSelectionModel->model(), selection);
573 selection = mapFromEntityTreeModel(favoritesModel, selection);
575 if (favoriteSelectionModel) {
576 favoriteSelectionModel->select(selection, QItemSelectionModel::ClearAndSelect);
582 void favoriteSelectionChanged()
584 if (insideSelectionSlot) {
587 QItemSelection selection = favoriteSelectionModel->selection();
588 if (selection.isEmpty()) {
592 selection = mapToEntityTreeModel(favoritesModel, selection);
593 selection = mapFromEntityTreeModel(collectionSelectionModel->model(), selection);
595 InsideSelectionSlotBlocker block(
this);
596 collectionSelectionModel->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
599 collectionSelectionModel->setCurrentIndex(selection.indexes().first(), QItemSelectionModel::NoUpdate);
604 void slotCreateCollection()
606 Q_ASSERT(collectionSelectionModel);
607 if (collectionSelectionModel->selection().indexes().isEmpty()) {
611 const QModelIndex index = collectionSelectionModel->selection().indexes().at(0);
612 Q_ASSERT(index.isValid());
613 const Collection parentCollection = index.data(CollectionModel::CollectionRole).value<
Collection>();
614 Q_ASSERT(parentCollection.
isValid());
616 if (!canCreateCollection(parentCollection)) {
620 QString name = KInputDialog::getText(contextText(StandardActionManager::CreateCollection, StandardActionManager::DialogTitle),
621 contextText(StandardActionManager::CreateCollection, StandardActionManager::DialogText),
622 QString(), 0, parentWidget);
623 name = name.trimmed();
624 if (name.isEmpty()) {
628 if (name.contains(QLatin1Char(
'/'))) {
629 KMessageBox::error(parentWidget,
630 i18n(
"We can not add \"/\" in folder name."),
631 i18n(
"Create new folder error"));
634 if (name.startsWith(QLatin1Char(
'.')) ||
635 name.endsWith(QLatin1Char(
'.'))) {
636 KMessageBox::error(parentWidget,
637 i18n(
"We can not add \".\" at begin or end of folder name."),
638 i18n(
"Create new folder error"));
643 collection.setName(name);
644 collection.setParentCollection(parentCollection);
645 if (actions[StandardActionManager::CreateCollection]) {
646 const QStringList mts = actions[StandardActionManager::CreateCollection]->property(
"ContentMimeTypes").toStringList();
647 if (!mts.isEmpty()) {
648 collection.setContentMimeTypes(mts);
651 if (parentCollection.
contentMimeTypes().contains(Collection::virtualMimeType())) {
652 collection.setVirtual(
true);
653 collection.setContentMimeTypes(collection.contentMimeTypes()
654 << Collection::virtualMimeType());
658 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(collectionCreationResult(KJob*)));
661 void slotCopyCollections()
663 encodeToClipboard(collectionSelectionModel);
666 void slotCutCollections()
668 encodeToClipboard(collectionSelectionModel,
true);
675 Q_ASSERT(collectionSelectionModel);
677 foreach (
const QModelIndex &index, safeSelectedRows(collectionSelectionModel)) {
678 Q_ASSERT(index.isValid());
680 Q_ASSERT(collection.isValid());
682 collections << collection;
688 void slotDeleteCollection()
691 if (collections.isEmpty()) {
695 const QString collectionName = collections.first().name();
696 const QString text = contextText(StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxText,
697 collections.count(), collectionName);
699 if (KMessageBox::questionYesNo(parentWidget, text,
700 contextText(StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxTitle, collections.count(), collectionName),
701 KStandardGuiItem::del(), KStandardGuiItem::cancel(),
702 QString(), KMessageBox::Dangerous) != KMessageBox::Yes) {
706 foreach (
const Collection &collection, collections) {
708 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(collectionDeletionResult(KJob*)));
712 void slotMoveCollectionToTrash()
715 if (collections.isEmpty()) {
719 foreach (
const Collection &collection, collections) {
721 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(moveCollectionToTrashResult(KJob*)));
725 void slotRestoreCollectionFromTrash()
728 if (collections.isEmpty()) {
732 foreach (
const Collection &collection, collections) {
734 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(moveCollectionToTrashResult(KJob*)));
738 Item::List selectedItems()
const
742 Q_ASSERT(itemSelectionModel);
744 foreach (
const QModelIndex &index, safeSelectedRows(itemSelectionModel)) {
745 Q_ASSERT(index.isValid());
746 const Item item = index.data(ItemModel::ItemRole).value<Item>();
747 Q_ASSERT(item.isValid());
755 void slotMoveItemToTrash()
757 const Item::List items = selectedItems();
758 if (items.isEmpty()) {
763 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(moveItemToTrashResult(KJob*)));
766 void slotRestoreItemFromTrash()
768 const Item::List items = selectedItems();
769 if (items.isEmpty()) {
774 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(moveItemToTrashResult(KJob*)));
777 void slotTrashRestoreCollection()
780 if (collections.isEmpty()) {
784 bool collectionsAreInTrash =
false;
785 foreach (
const Collection &collection, collections) {
787 collectionsAreInTrash =
true;
792 if (collectionsAreInTrash) {
793 slotRestoreCollectionFromTrash();
795 slotMoveCollectionToTrash();
799 void slotTrashRestoreItem()
801 const Item::List items = selectedItems();
802 if (items.isEmpty()) {
806 bool itemsAreInTrash =
false;
807 foreach (
const Item &item, items) {
809 itemsAreInTrash =
true;
814 if (itemsAreInTrash) {
815 slotRestoreItemFromTrash();
817 slotMoveItemToTrash();
821 void slotSynchronizeCollection()
823 Q_ASSERT(collectionSelectionModel);
824 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
825 if (list.isEmpty()) {
830 if (collections.isEmpty()) {
834 foreach (
const Collection &collection, collections) {
835 if (!testAndSetOnlineResources(collection)) {
838 AgentManager::self()->synchronizeCollection(collection,
false);
850 if (collection.resource() == QLatin1String(
"akonadi_search_resource")) {
856 if (KMessageBox::questionYesNo(parentWidget,
857 i18n(
"Before syncing folder \"%1\" it is necessary to have the resource online. Do you want to make it online?", collection.displayName()),
858 i18n(
"Account \"%1\" is offline", instance.
name()),
859 KGuiItem(i18nc(
"@action:button",
"Go Online")), KStandardGuiItem::cancel()) != KMessageBox::Yes) {
867 void slotSynchronizeCollectionRecursive()
869 Q_ASSERT(collectionSelectionModel);
870 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
871 if (list.isEmpty()) {
876 if (collections.isEmpty()) {
880 foreach (
const Collection &collection, collections) {
881 if (!testAndSetOnlineResources(collection)) {
884 AgentManager::self()->synchronizeCollection(collection,
true);
888 void slotCollectionProperties()
890 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
891 if (list.isEmpty()) {
895 const QModelIndex index = list.first();
896 Q_ASSERT(index.isValid());
899 Q_ASSERT(collection.isValid());
902 dlg->setCaption(contextText(StandardActionManager::CollectionProperties, StandardActionManager::DialogTitle, collection.displayName()));
908 encodeToClipboard(itemSelectionModel);
913 encodeToClipboard(itemSelectionModel,
true);
918 Q_ASSERT(collectionSelectionModel);
920 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
921 if (list.isEmpty()) {
925 const QModelIndex index = list.first();
926 Q_ASSERT(index.isValid());
928#ifndef QT_NO_CLIPBOARD
930 QAbstractItemModel *model =
const_cast<QAbstractItemModel *
>(collectionSelectionModel->model());
931 const QMimeData *mimeData = QApplication::clipboard()->mimeData();
932 model->dropMimeData(mimeData, isCutAction(mimeData) ? Qt::MoveAction : Qt::CopyAction, -1, -1, index);
933 model->setData(QModelIndex(),
false, EntityTreeModel::PendingCutRole);
934 QApplication::clipboard()->clear();
938 void slotDeleteItems()
940 Q_ASSERT(itemSelectionModel);
943 foreach (
const QModelIndex &index, safeSelectedRows(itemSelectionModel)) {
945 const qlonglong
id = index.data(ItemModel::IdRole).toLongLong(&ok);
950 if (items.isEmpty()) {
954 QMetaObject::invokeMethod(q,
"slotDeleteItemsDeferred",
955 Qt::QueuedConnection,
956 Q_ARG(Akonadi::Item::List, items));
959 void slotDeleteItemsDeferred(
const Akonadi::Item::List &items)
961 Q_ASSERT(itemSelectionModel);
963 if (KMessageBox::questionYesNo(parentWidget,
964 contextText(StandardActionManager::DeleteItems, StandardActionManager::MessageBoxText, items.count(), QString()),
965 contextText(StandardActionManager::DeleteItems, StandardActionManager::MessageBoxTitle, items.count(), QString()),
966 KStandardGuiItem::del(), KStandardGuiItem::cancel(),
967 QString(), KMessageBox::Dangerous) != KMessageBox::Yes) {
972 q->connect(job, SIGNAL(result(KJob*)), q, SLOT(itemDeletionResult(KJob*)));
975 void slotLocalSubscription()
982 void slotAddToFavorites()
984 Q_ASSERT(collectionSelectionModel);
985 Q_ASSERT(favoritesModel);
986 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
987 if (list.isEmpty()) {
991 foreach (
const QModelIndex &index, list) {
992 Q_ASSERT(index.isValid());
994 Q_ASSERT(collection.isValid());
996 favoritesModel->addCollection(collection);
1002 void slotRemoveFromFavorites()
1004 Q_ASSERT(collectionSelectionModel);
1005 Q_ASSERT(favoritesModel);
1006 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
1007 if (list.isEmpty()) {
1011 foreach (
const QModelIndex &index, list) {
1012 Q_ASSERT(index.isValid());
1014 Q_ASSERT(collection.isValid());
1016 favoritesModel->removeCollection(collection);
1022 void slotRenameFavorite()
1024 Q_ASSERT(collectionSelectionModel);
1025 Q_ASSERT(favoritesModel);
1026 const QModelIndexList list = safeSelectedRows(collectionSelectionModel);
1027 if (list.isEmpty()) {
1030 const QModelIndex index = list.first();
1031 Q_ASSERT(index.isValid());
1033 Q_ASSERT(collection.isValid());
1035 QPointer<RenameFavoriteDialog> dlg(
new RenameFavoriteDialog(contextText(StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogTitle), contextText(StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogText) , favoritesModel->favoriteLabel(collection), collection.displayName(), parentWidget));
1036 if (dlg->exec() == QDialog::Accepted && dlg != 0) {
1037 favoritesModel->setFavoriteLabel(collection, dlg->newName());
1042 void slotSynchronizeFavoriteCollections()
1044 Q_ASSERT(favoritesModel);
1045 foreach (
const Collection &collection, favoritesModel->collections()) {
1048 if (!collection.resource().isEmpty()) {
1049 AgentManager::self()->synchronizeCollection(collection,
false);
1054 void slotCopyCollectionTo()
1056 pasteTo(collectionSelectionModel, collectionSelectionModel->model(), CopyCollectionToMenu, Qt::CopyAction);
1059 void slotCopyItemTo()
1061 pasteTo(itemSelectionModel, collectionSelectionModel->model(), CopyItemToMenu, Qt::CopyAction);
1064 void slotMoveCollectionTo()
1066 pasteTo(collectionSelectionModel, collectionSelectionModel->model(), MoveCollectionToMenu, Qt::MoveAction);
1069 void slotMoveItemTo()
1071 pasteTo(itemSelectionModel, collectionSelectionModel->model(), MoveItemToMenu, Qt::MoveAction);
1074 void slotCopyCollectionTo(QAction *action)
1076 pasteTo(collectionSelectionModel, action, Qt::CopyAction);
1079 void slotCopyItemTo(QAction *action)
1081 pasteTo(itemSelectionModel, action, Qt::CopyAction);
1084 void slotMoveCollectionTo(QAction *action)
1086 pasteTo(collectionSelectionModel, action, Qt::MoveAction);
1089 void slotMoveItemTo(QAction *action)
1091 pasteTo(itemSelectionModel, action, Qt::MoveAction);
1098 Q_ASSERT(collectionSelectionModel);
1099 if (collectionSelectionModel->selection().indexes().isEmpty()) {
1103 foreach (
const QModelIndex &index, collectionSelectionModel->selection().indexes()) {
1104 Q_ASSERT(index.isValid());
1106 Q_ASSERT(collection.isValid());
1108 if (collection.isValid()) {
1109 const QString identifier = collection.resource();
1110 instances << AgentManager::self()->instance(identifier);
1121 if (instances.isEmpty()) {
1125 return instances.first();
1128 void slotCreateResource()
1131 dlg->setCaption(contextText(StandardActionManager::CreateResource, StandardActionManager::DialogTitle));
1133 foreach (
const QString &mimeType, mMimeTypeFilter) {
1134 dlg->agentFilterProxyModel()->addMimeTypeFilter(mimeType);
1137 foreach (
const QString &capability, mCapabilityFilter) {
1138 dlg->agentFilterProxyModel()->addCapabilityFilter(capability);
1141 if (dlg->exec() == QDialog::Accepted && dlg != 0) {
1142 const AgentType agentType = dlg->agentType();
1146 q->connect(job, SIGNAL(result(KJob*)), SLOT(resourceCreationResult(KJob*)));
1154 void slotDeleteResource()
1157 if (instances.isEmpty()) {
1161 if (KMessageBox::questionYesNo(parentWidget,
1162 contextText(StandardActionManager::DeleteResources, StandardActionManager::MessageBoxText, instances.count(), instances.first().name()),
1163 contextText(StandardActionManager::DeleteResources, StandardActionManager::MessageBoxTitle, instances.count(), instances.first().name()),
1164 KStandardGuiItem::del(), KStandardGuiItem::cancel(),
1165 QString(), KMessageBox::Dangerous) != KMessageBox::Yes) {
1170 AgentManager::self()->removeInstance(instance);
1174 void slotSynchronizeResource()
1177 if (instances.isEmpty()) {
1186 void slotResourceProperties()
1196 void slotToggleWorkOffline(
bool offline)
1198 setWorkOffline(offline);
1206 void pasteTo(QItemSelectionModel *selectionModel,
const QAbstractItemModel *model,
StandardActionManager::Type type, Qt::DropAction dropAction)
1208 const QSet<QString> mimeTypes = mimeTypesOfSelection(type);
1210 QPointer<CollectionDialog> dlg(
new CollectionDialog(
const_cast<QAbstractItemModel *
>(model)));
1211 dlg->setMimeTypeFilter(mimeTypes.toList());
1213 if (type == CopyItemToMenu || type == MoveItemToMenu) {
1214 dlg->setAccessRightsFilter(Collection::CanCreateItem);
1215 }
else if (type == CopyCollectionToMenu || type == MoveCollectionToMenu) {
1216 dlg->setAccessRightsFilter(Collection::CanCreateCollection);
1219 if (dlg->exec() == QDialog::Accepted && dlg != 0) {
1220 const QModelIndex index = EntityTreeModel::modelIndexForCollection(collectionSelectionModel->model(), dlg->selectedCollection());
1221 if (!index.isValid()) {
1225 const QMimeData *mimeData = selectionModel->model()->mimeData(safeSelectedRows(selectionModel));
1227 QAbstractItemModel *model =
const_cast<QAbstractItemModel *
>(index.model());
1228 model->dropMimeData(mimeData, dropAction, -1, -1, index);
1233 void pasteTo(QItemSelectionModel *selectionModel, QAction *action, Qt::DropAction dropAction)
1235 Q_ASSERT(selectionModel);
1238 if (safeSelectedRows(selectionModel).count() <= 0) {
1242 const QMimeData *mimeData = selectionModel->model()->mimeData(selectionModel->selectedRows());
1244 const QModelIndex index = action->data().value<QModelIndex>();
1245 Q_ASSERT(index.isValid());
1247 QAbstractItemModel *model =
const_cast<QAbstractItemModel *
>(index.model());
1249 addRecentCollection(collection.id());
1250 model->dropMimeData(mimeData, dropAction, -1, -1, index);
1255 QMapIterator<StandardActionManager::Type, QWeakPointer<RecentCollectionAction> > item(mRecentCollectionsMenu);
1256 while (item.hasNext()) {
1258 if (item.value().data()) {
1259 item.value().data()->addRecentCollection(item.key(),
id);
1264 void collectionCreationResult(KJob *job)
1267 KMessageBox::error(parentWidget,
1268 contextText(StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageText, job->errorString()),
1269 contextText(StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageTitle));
1273 void collectionDeletionResult(KJob *job)
1276 KMessageBox::error(parentWidget,
1277 contextText(StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageText, job->errorString()),
1278 contextText(StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageTitle));
1282 void moveCollectionToTrashResult(KJob *job)
1285 KMessageBox::error(parentWidget,
1286 contextText(StandardActionManager::MoveCollectionsToTrash, StandardActionManager::ErrorMessageText, job->errorString()),
1287 contextText(StandardActionManager::MoveCollectionsToTrash, StandardActionManager::ErrorMessageTitle));
1291 void moveItemToTrashResult(KJob *job)
1294 KMessageBox::error(parentWidget,
1295 contextText(StandardActionManager::MoveItemsToTrash, StandardActionManager::ErrorMessageText, job->errorString()),
1296 contextText(StandardActionManager::MoveItemsToTrash, StandardActionManager::ErrorMessageTitle));
1300 void itemDeletionResult(KJob *job)
1303 KMessageBox::error(parentWidget,
1304 contextText(StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageText, job->errorString()),
1305 contextText(StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageTitle));
1309 void resourceCreationResult(KJob *job)
1312 KMessageBox::error(parentWidget,
1313 contextText(StandardActionManager::CreateResource, StandardActionManager::ErrorMessageText, job->errorString()),
1314 contextText(StandardActionManager::CreateResource, StandardActionManager::ErrorMessageTitle));
1318 void pasteResult(KJob *job)
1321 KMessageBox::error(parentWidget,
1322 contextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageText, job->errorString()),
1323 contextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle));
1332 QModelIndexList list;
1333 QSet<QString> mimeTypes;
1335 const bool isItemAction = (type == CopyItemToMenu || type == MoveItemToMenu);
1336 const bool isCollectionAction = (type == CopyCollectionToMenu || type == MoveCollectionToMenu);
1339 list = safeSelectedRows(itemSelectionModel);
1340 foreach (
const QModelIndex &index, list) {
1341 mimeTypes << index.data(EntityTreeModel::MimeTypeRole).toString();
1345 if (isCollectionAction) {
1346 list = safeSelectedRows(collectionSelectionModel);
1347 foreach (
const QModelIndex &index, list) {
1351 mimeTypes = AgentManager::self()->instance(collection.resource()).type().mimeTypes().toSet();
1363 if (collection.isVirtual()) {
1367 const bool isItemAction = (type == CopyItemToMenu || type == MoveItemToMenu);
1368 const bool isCollectionAction = (type == CopyCollectionToMenu || type == MoveCollectionToMenu);
1370 const bool canContainRequiredMimeTypes = !collection.contentMimeTypes().toSet().intersect(mimeTypes).isEmpty();
1371 const bool canCreateNewItems = (collection.rights() & Collection::CanCreateItem);
1373 const bool canCreateNewCollections = (collection.rights() & Collection::CanCreateCollection);
1374 const bool canContainCollections = collection.contentMimeTypes().contains(Collection::mimeType()) || collection.contentMimeTypes().contains(Collection::virtualMimeType());
1375 const bool resourceAllowsRequiredMimeTypes = AgentManager::self()->instance(collection.resource()).type().mimeTypes().toSet().contains(mimeTypes);
1377 const bool isReadOnlyForItems = (isItemAction && (!canCreateNewItems || !canContainRequiredMimeTypes));
1378 const bool isReadOnlyForCollections = (isCollectionAction && (!canCreateNewCollections || !canContainCollections || !resourceAllowsRequiredMimeTypes));
1380 return !(CollectionUtils::isStructural(collection) || isReadOnlyForItems || isReadOnlyForCollections);
1384 const QAbstractItemModel *model, QModelIndex parentIndex)
1386 const int rowCount = model->rowCount(parentIndex);
1388 for (
int row = 0; row < rowCount; ++row) {
1389 const QModelIndex index = model->index(row, 0, parentIndex);
1390 const Collection collection = model->data(index, CollectionModel::CollectionRole).value<
Collection>();
1392 if (collection.isVirtual()) {
1396 const bool readOnly = !isWritableTargetCollectionForMimeTypes( collection, mimeTypes, type );
1397 const bool collectionIsSelected = selectedCollectionsList.contains( collection );
1398 if (type == MoveCollectionToMenu && collectionIsSelected) {
1402 QString label = model->data(index).toString();
1403 label.replace(QLatin1String(
"&"), QLatin1String(
"&&"));
1405 const QIcon icon = model->data(index, Qt::DecorationRole).value<QIcon>();
1407 if (model->rowCount(index) > 0) {
1409 QMenu *popup =
new QMenu(menu);
1410 const bool moveAction = (type == MoveCollectionToMenu || type == MoveItemToMenu);
1411 popup->setObjectName(QString::fromUtf8(
"subMenu"));
1412 popup->setTitle(label);
1413 popup->setIcon(icon);
1415 fillFoldersMenu(selectedCollectionsList, mimeTypes, type, popup, model, index);
1417 if (!(type == CopyCollectionToMenu && collectionIsSelected)) {
1419 popup->addSeparator();
1421 QAction *action = popup->addAction( moveAction ? i18n(
"Move to This Folder" ) : i18n(
"Copy to This Folder" ) );
1422 action->setData( QVariant::fromValue<QModelIndex>( index ) );
1426 menu->addMenu(popup);
1430 QAction *action = menu->addAction(icon, label);
1431 action->setData(QVariant::fromValue<QModelIndex>(index));
1432 action->setEnabled(!readOnly && !collectionIsSelected);
1437 void checkModelsConsistency()
1439 if (favoritesModel == 0 || favoriteSelectionModel == 0) {
1445 const QAbstractItemModel *favModel = favoritesModel;
1446 while (
const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(favModel)) {
1447 favModel = proxy->sourceModel();
1452 if (collectionSelectionModel != 0) {
1453 const QAbstractItemModel *model = collectionSelectionModel->model();
1454 while (
const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(model)) {
1455 model = proxy->sourceModel();
1458 Q_ASSERT(model == favModel);
1462 const QAbstractItemModel *model = favoriteSelectionModel->model();
1463 while (
const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(model)) {
1464 model = proxy->sourceModel();
1466 Q_ASSERT(model == favModel);
1469 void markCutAction(QMimeData *mimeData,
bool cut)
const
1475 const QByteArray cutSelectionData =
"1";
1476 mimeData->setData(QLatin1String(
"application/x-kde.akonadi-cutselection"), cutSelectionData);
1479 bool isCutAction(
const QMimeData *mimeData)
const
1481 const QByteArray data = mimeData->data(QLatin1String(
"application/x-kde.akonadi-cutselection"));
1482 if (data.isEmpty()) {
1485 return (data.at(0) ==
'1');
1491 ContextTextEntry entry;
1494 contextTexts[type].insert(context, entry);
1499 ContextTextEntry entry;
1500 entry.localizedText = data;
1502 contextTexts[type].insert(context, entry);
1507 return contextTexts[type].value(context).text;
1512 KLocalizedString text = contextTexts[type].value(context).localizedText;
1513 if (text.isEmpty()) {
1514 return contextTexts[type].value(context).text;
1517 return text.subs(value).toString();
1522 KLocalizedString text = contextTexts[type].value(context).localizedText;
1523 if (text.isEmpty()) {
1524 return contextTexts[type].value(context).text;
1527 const QString str = text.subs(count).toString();
1528 const int argCount = str.count(QRegExp(QLatin1String(
"%[0-9]")));
1530 return text.subs(count).subs(value).toString();
1532 return text.subs(count).toString();
1537 KActionCollection *actionCollection;
1538 QWidget *parentWidget;
1539 QItemSelectionModel *collectionSelectionModel;
1540 QItemSelectionModel *itemSelectionModel;
1542 QItemSelectionModel *favoriteSelectionModel;
1543 bool insideSelectionSlot;
1544 QVector<KAction *> actions;
1545 QHash<StandardActionManager::Type, KLocalizedString> pluralLabels;
1546 QHash<StandardActionManager::Type, KLocalizedString> pluralIconLabels;
1548 struct ContextTextEntry
1551 KLocalizedString localizedText;
1555 typedef QHash<StandardActionManager::TextContext, ContextTextEntry> ContextTexts;
1556 QHash<StandardActionManager::Type, ContextTexts> contextTexts;
1560 QStringList mMimeTypeFilter;
1561 QStringList mCapabilityFilter;
1562 QStringList mCollectionPropertiesPageNames;
1563 QMap<StandardActionManager::Type, QWeakPointer<RecentCollectionAction> > mRecentCollectionsMenu;
1568StandardActionManager::StandardActionManager(KActionCollection *actionCollection, QWidget *parent)
1570 , d(new Private(this))
1572 d->parentWidget = parent;
1573 d->actionCollection = actionCollection;
1574 d->mActionStateManager.setReceiver(
this);
1575#ifndef QT_NO_CLIPBOARD
1576 connect(QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), SLOT(clipboardChanged(QClipboard::Mode)));
1580StandardActionManager::~ StandardActionManager()
1587 d->collectionSelectionModel = selectionModel;
1588 connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
1589 SLOT(collectionSelectionChanged()));
1591 d->checkModelsConsistency();
1596 d->itemSelectionModel = selectionModel;
1597 connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
1598 SLOT(updateActions()));
1603 d->favoritesModel = favoritesModel;
1604 d->checkModelsConsistency();
1609 d->favoriteSelectionModel = selectionModel;
1610 connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
1611 SLOT(favoriteSelectionChanged()));
1612 d->checkModelsConsistency();
1618 if (d->actions[type]) {
1619 return d->actions[type];
1622 switch (standardActionData[type].actionType) {
1624 case ActionWithAlternative:
1625 action =
new KAction(d->parentWidget);
1627 case ActionAlternative:
1628 d->actions[type] = d->actions[type - 1];
1629 Q_ASSERT(d->actions[type]);
1630 if ((
LastType > type + 1) && (standardActionData[type + 1].actionType == ActionAlternative)) {
1633 return d->actions[type];
1635 action =
new KActionMenu(d->parentWidget);
1638 action =
new KToggleAction(d->parentWidget);
1642 if (d->pluralLabels.contains(type) && !d->pluralLabels.value(type).isEmpty()) {
1643 action->setText(d->pluralLabels.value(type).subs(1).toString());
1644 }
else if (standardActionData[type].label) {
1645 action->setText(i18n(standardActionData[type].label));
1648 if (d->pluralIconLabels.contains(type) && !d->pluralIconLabels.value(type).isEmpty()) {
1649 action->setIconText(d->pluralIconLabels.value(type).subs(1).toString());
1650 }
else if (standardActionData[type].iconLabel) {
1651 action->setIconText(i18n(standardActionData[type].iconLabel));
1654 if (standardActionData[type].icon) {
1655 action->setIcon(KIcon(QString::fromLatin1(standardActionData[type].icon)));
1658 action->setShortcut(standardActionData[type].shortcut);
1660 if (standardActionData[type].slot) {
1661 switch (standardActionData[type].actionType) {
1663 case ActionWithAlternative:
1664 connect(
action, SIGNAL(triggered()), standardActionData[type].slot);
1667 KActionMenu *actionMenu = qobject_cast<KActionMenu *>(
action);
1668 connect(actionMenu->menu(), SIGNAL(triggered(QAction*)), standardActionData[type].slot);
1671 case ToggleAction: {
1672 connect(
action, SIGNAL(triggered(
bool)), standardActionData[type].slot);
1675 case ActionAlternative:
1682 disconnect(
action, SIGNAL(triggered(
bool)),
this, standardActionData[type].slot);
1683 action->setChecked(workOffline());
1684 connect(
action, SIGNAL(triggered(
bool)),
this, standardActionData[type].slot);
1689 Q_ASSERT(standardActionData[type].name);
1690 d->actionCollection->addAction(QString::fromLatin1(standardActionData[type].name),
action);
1691 d->actions[type] =
action;
1692 if ((standardActionData[type].actionType == ActionWithAlternative) && (standardActionData[type + 1].actionType == ActionAlternative)) {
1701 for (uint i = 0; i <
LastType; ++i) {
1709 return d->actions[type];
1715 d->pluralLabels.insert(type, text);
1723 const KAction *
action = d->actions[type];
1730 disconnect(
action, SIGNAL(triggered()),
this, standardActionData[type].slot);
1732 connect(
action, SIGNAL(triggered()), standardActionData[type].slot);
1740 if (!d->collectionSelectionModel) {
1744 foreach (
const QModelIndex &index, safeSelectedRows(d->collectionSelectionModel)) {
1746 if (collection.isValid()) {
1747 collections << collection;
1758 if (!d->itemSelectionModel) {
1762 foreach (
const QModelIndex &index, safeSelectedRows(d->itemSelectionModel)) {
1764 if (item.isValid()) {
1774 d->setContextText(type, context, text);
1779 d->setContextText(type, context, text);
1784 d->mMimeTypeFilter = mimeTypes;
1789 d->mCapabilityFilter = capabilities;
1794 d->mCollectionPropertiesPageNames = names;
1799 d->createActionFolderMenu(menu, type);
1802#include "moc_standardactionmanager.cpp"
A helper class to manage action states.
Job for creating new agent instances.
void start()
Starts the instance creation.
void configure(QWidget *parent=0)
Setup the job to show agent configuration dialog once the agent instance has been successfully starte...
A representation of an agent instance.
void configure(QWidget *parent=0)
Triggers the agent instance to show its configuration dialog.
void synchronize()
Triggers the agent instance to start synchronization.
bool isValid() const
Returns whether the agent instance object is valid.
void setIsOnline(bool online)
Sets online status of the agent instance.
QList< AgentInstance > List
Describes a list of agent instances.
QString name() const
Returns the user visible name of the agent instance.
bool isOnline() const
Returns whether the agent instance is online currently.
static AgentManager * self()
Returns the global instance of the agent manager.
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
A dialog to select an available agent type.
A representation of an agent type.
bool isValid() const
Returns whether the agent type is valid.
Job that creates a new collection in the Akonadi storage.
Job that deletes a collection in the Akonadi storage.
A collection selection dialog.
A generic and extensible dialog for collection properties.
Represents a collection of PIM items.
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
static QString mimeType()
Returns the mimetype used for collections.
static QString virtualMimeType()
Returns the mimetype used for virtual collections.
QList< Collection > List
Describes a list of collections.
@ CanCreateCollection
Can create new subcollections in this collection.
An Attribute that marks that an entity was marked as deleted.
@ CollectionRole
The collection.
bool isValid() const
Returns whether the entity is valid.
qint64 Id
Describes the unique id type.
A model that lists a set of favorite collections.
Job that deletes items from the Akonadi storage.
Manages generic actions for collection and item views.
void setCollectionSelectionModel(QItemSelectionModel *selectionModel)
Sets the collection selection model based on which the collection related actions should operate.
void setItemSelectionModel(QItemSelectionModel *selectionModel)
Sets the item selection model based on which the item related actions should operate.
KAction * createAction(Type type)
Creates the action of the given type and adds it to the action collection specified in the constructo...
KAction * action(Type type) const
Returns the action of the given type, 0 if it has not been created (yet).
void setContextText(Type type, TextContext context, const QString &text)
Sets the text of the action type for the given context.
Type
Describes the supported actions.
@ LastType
Marks last action.
@ ToggleWorkOffline
Toggles the work offline state of all resources.
void setCapabilityFilter(const QStringList &capabilities)
Sets the capability filter that will be used when creating new resources.
void createActionFolderMenu(QMenu *menu, Type type)
Create a popup menu.
void createAllActions()
Convenience method to create all standard actions.
void setActionText(Type type, const KLocalizedString &text)
Sets the label of the action type to text, which is used during updating the action state and substit...
void setFavoriteCollectionsModel(FavoriteCollectionsModel *favoritesModel)
Sets the favorite collections model based on which the collection relatedactions should operate.
void setCollectionPropertiesPageNames(const QStringList &names)
Sets the page names of the config pages that will be used by the built-in collection properties dialo...
void interceptAction(Type type, bool intercept=true)
Sets whether the default implementation for the given action type shall be executed when the action i...
void setMimeTypeFilter(const QStringList &mimeTypes)
Sets the mime type filter that will be used when creating new resources.
Akonadi::Collection::List selectedCollections() const
Returns the list of collections that are currently selected.
Akonadi::Item::List selectedItems() const
Returns the list of items that are currently selected.
TextContext
Describes the text context that can be customized.
void setFavoriteSelectionModel(QItemSelectionModel *selectionModel)
Sets the favorite collection selection model based on which the favorite collection related actions s...
void showHiddenCollection(bool showHidden)
Job that moves items/collection to trash.
Job that restores entites from trash.
FreeBusyManager::Singleton.