1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : Modified context menu helper for import tool
9
* Copyright (C) 2012 by Islam Wazery <wazery at ubuntu dot com>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
24
#include "importcontextmenu.moc"
33
#include <kactionmenu.h>
34
#include <kactioncollection.h>
35
#include <kapplication.h>
37
#include <kmimetype.h>
38
#include <kmimetypetrader.h>
39
#include <kopenwithdialog.h>
41
#include <kstandardaction.h>
46
#include "picklabelwidget.h"
47
#include "colorlabelwidget.h"
48
#include "ratingwidget.h"
49
#include "tagmodificationhelper.h"
50
#include "tagspopupmenu.h"
51
#include "fileactionmngr.h"
56
class ImportContextMenuHelper::Private
60
explicit Private(ImportContextMenuHelper* const q) :
64
stdActionCollection(0),
68
QList<qlonglong> selectedIds;
69
KUrl::List selectedItems;
71
QMap<int, QAction*> queueActions;
72
QMap<QString, KService::Ptr> servicesMap;
74
ImportFilterModel* importFilterModel;
79
KActionCollection* stdActionCollection;
81
ImportContextMenuHelper* q;
85
QAction* copyFromMainCollection(const char* name)
87
QAction* mainAction = stdActionCollection->action(name);
94
QAction* action = new QAction(mainAction->icon(), mainAction->text(), q);
95
action->setToolTip(mainAction->toolTip());
100
ImportContextMenuHelper::ImportContextMenuHelper(QMenu* const parent, KActionCollection* const actionCollection)
101
: QObject(parent), d(new Private(this))
105
if (!actionCollection)
107
d->stdActionCollection = ImportUI::instance()->actionCollection();
111
d->stdActionCollection = actionCollection;
115
ImportContextMenuHelper::~ImportContextMenuHelper()
120
void ImportContextMenuHelper::addAction(const char* name, bool addDisabled)
122
QAction* action = d->stdActionCollection->action(name);
123
addAction(action, addDisabled);
126
void ImportContextMenuHelper::addAction(QAction* action, bool addDisabled)
133
if (action->isEnabled() || addDisabled)
135
d->parent->addAction(action);
139
void ImportContextMenuHelper::addSubMenu(KMenu* subMenu)
141
d->parent->addMenu(subMenu);
144
void ImportContextMenuHelper::addSeparator()
146
d->parent->addSeparator();
149
void ImportContextMenuHelper::addAction(QAction* action, QObject* recv, const char* slot,
157
connect(action, SIGNAL(triggered()),
160
addAction(action, addDisabled);
163
void ImportContextMenuHelper::addServicesMenu(const KUrl::List& selectedItems)
165
setSelectedItems(selectedItems);
167
// This code is inspired by KonqMenuActions:
168
// kdebase/apps/lib/konq/konq_menuactions.cpp
170
QStringList mimeTypes;
171
KService::List offers;
173
foreach(const KUrl& item, d->selectedItems)
175
const QString mimeType = KMimeType::findByUrl(item, 0, true, true)->name();
177
if (!mimeTypes.contains(mimeType))
179
mimeTypes << mimeType;
183
if (!mimeTypes.isEmpty())
186
const QString firstMimeType = mimeTypes.takeFirst();
187
const QString constraintTemplate = "'%1' in ServiceTypes";
188
QStringList constraints;
190
foreach(const QString& mimeType, mimeTypes)
192
constraints << constraintTemplate.arg(mimeType);
195
offers = KMimeTypeTrader::self()->query(firstMimeType, "Application", constraints.join(" and "));
197
// remove duplicate service entries
198
QSet<QString> seenApps;
200
for (KService::List::iterator it = offers.begin(); it != offers.end();)
202
const QString appName((*it)->name());
204
if (!seenApps.contains(appName))
206
seenApps.insert(appName);
211
it = offers.erase(it);
216
if (!offers.isEmpty())
218
KMenu* servicesMenu = new KMenu(d->parent);
219
qDeleteAll(servicesMenu->actions());
221
QAction* serviceAction = servicesMenu->menuAction();
222
serviceAction->setText(i18n("Open With"));
224
foreach(KService::Ptr service, offers)
226
QString name = service->name().replace('&', "&&");
227
QAction* action = servicesMenu->addAction(name);
228
action->setIcon(KIcon(service->icon()));
229
action->setData(service->name());
230
d->servicesMap[name] = service;
233
servicesMenu->addSeparator();
234
servicesMenu->addAction(i18n("Other..."));
236
addAction(serviceAction);
238
connect(servicesMenu, SIGNAL(triggered(QAction*)),
239
this, SLOT(slotOpenWith(QAction*)));
243
QAction* serviceAction = new QAction(i18n("Open With..."), this);
244
addAction(serviceAction);
246
connect(serviceAction, SIGNAL(triggered()),
247
this, SLOT(slotOpenWith()));
251
void ImportContextMenuHelper::slotOpenWith()
253
// call the slot with an "empty" action
257
void ImportContextMenuHelper::slotOpenWith(QAction* action)
259
KService::Ptr service;
260
KUrl::List list = d->selectedItems;
262
QString name = action ? action->data().toString() : QString();
266
QPointer<KOpenWithDialog> dlg = new KOpenWithDialog(list);
268
if (!dlg->exec() == KOpenWithDialog::Accepted)
274
service = dlg->service();
278
// User entered a custom command
279
if (!dlg->text().isEmpty())
281
KRun::run(dlg->text(), list, d->parent);
292
service = d->servicesMap[name];
295
KRun::run(*service, list, d->parent);
298
void ImportContextMenuHelper::addRotateMenu(itemIds& /*ids*/)
300
// setSelectedIds(ids);
302
// KMenu* imageRotateMenu = new KMenu(i18n("Rotate"), d->parent);
303
// imageRotateMenu->setIcon(KIcon("object-rotate-right"));
305
// KAction* left = new KAction(this);
306
// left->setObjectName("rotate_ccw");
307
// left->setText(i18nc("rotate image left", "Left"));
308
// connect(left, SIGNAL(triggered(bool)),
309
// this, SLOT(slotRotate()));
310
// imageRotateMenu->addAction(left);
312
// KAction* right = new KAction(this);
313
// right->setObjectName("rotate_cw");
314
// right->setText(i18nc("rotate image right", "Right"));
315
// connect(right, SIGNAL(triggered(bool)),
316
// this, SLOT(slotRotate()));
317
// imageRotateMenu->addAction(right);
319
// d->parent->addMenu(imageRotateMenu);
322
void ImportContextMenuHelper::slotRotate()
324
//TODO: Implement rotate in import tool.
325
// if (sender()->objectName() == "rotate_ccw")
327
// FileActionMngr::instance()->transform(CamItemInfoList(d->selectedIds), KExiv2Iface::RotationMatrix::Rotate270);
331
// FileActionMngr::instance()->transform(CamItemInfoList(d->selectedIds), KExiv2Iface::RotationMatrix::Rotate90);
335
void ImportContextMenuHelper::addAssignTagsMenu(itemIds& ids)
339
KMenu* assignTagsPopup = new TagsPopupMenu(ids, TagsPopupMenu::RECENTLYASSIGNED, d->parent);
340
assignTagsPopup->menuAction()->setText(i18n("Assign Tag"));
341
assignTagsPopup->menuAction()->setIcon(SmallIcon("tag"));
342
d->parent->addMenu(assignTagsPopup);
344
connect(assignTagsPopup, SIGNAL(signalTagActivated(int)),
345
this, SIGNAL(signalAssignTag(int)));
347
connect(assignTagsPopup, SIGNAL(signalPopupTagsView()),
348
this, SIGNAL(signalPopupTagsView()));
351
void ImportContextMenuHelper::addRemoveTagsMenu(itemIds& ids)
355
KMenu* removeTagsPopup = new TagsPopupMenu(ids, TagsPopupMenu::REMOVE, d->parent);
356
removeTagsPopup->menuAction()->setText(i18n("Remove Tag"));
357
removeTagsPopup->menuAction()->setIcon(SmallIcon("tag"));
358
d->parent->addMenu(removeTagsPopup);
360
connect(removeTagsPopup, SIGNAL(signalTagActivated(int)),
361
this, SIGNAL(signalRemoveTag(int)));
364
void ImportContextMenuHelper::addLabelsAction()
366
KMenu* menuLabels = new KMenu(i18n("Assign Labels"), d->parent);
367
PickLabelMenuAction* pmenu = new PickLabelMenuAction(d->parent);
368
ColorLabelMenuAction* cmenu = new ColorLabelMenuAction(d->parent);
369
RatingMenuAction* rmenu = new RatingMenuAction(d->parent);
370
menuLabels->addAction(pmenu);
371
menuLabels->addAction(cmenu);
372
menuLabels->addAction(rmenu);
373
addSubMenu(menuLabels);
375
connect(pmenu, SIGNAL(signalPickLabelChanged(int)),
376
this, SIGNAL(signalAssignPickLabel(int)));
378
connect(cmenu, SIGNAL(signalColorLabelChanged(int)),
379
this, SIGNAL(signalAssignColorLabel(int)));
381
connect(rmenu, SIGNAL(signalRatingChanged(int)),
382
this, SIGNAL(signalAssignRating(int)));
385
void ImportContextMenuHelper::slotABCMenuTriggered(QAction* action)
387
QString name = action->iconText();
388
emit signalAddNewTagFromABCMenu(name);
391
void ImportContextMenuHelper::setImportFilterModel(ImportFilterModel* model)
393
d->importFilterModel = model;
396
QAction* ImportContextMenuHelper::exec(const QPoint& pos, QAction* at)
398
QAction* choice = d->parent->exec(pos, at);
402
// check if a BQM action has been triggered
403
for (QMap<int, QAction*>::const_iterator it = d->queueActions.constBegin();
404
it != d->queueActions.constEnd(); ++it)
406
if (choice == it.value())
408
//emit signalAddToExistingQueue(it.key());
417
void ImportContextMenuHelper::setSelectedIds(itemIds& ids)
419
if (d->selectedIds.isEmpty())
421
d->selectedIds = ids;
425
void ImportContextMenuHelper::setSelectedItems(const KUrl::List& urls)
427
if (d->selectedItems.isEmpty())
429
d->selectedItems = urls;
433
} // namespace Digikam