1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : Qt Model for Albums - drag and drop handling
9
* Copyright (C) 2005-2006 by Joern Ahrens <joern.ahrens@kdemail.net>
10
* Copyright (C) 2006-2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
* Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
12
* Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
14
* This program is free software; you can redistribute it
15
* and/or modify it under the terms of the GNU General
16
* Public License as published by the Free Software Foundation;
17
* either version 2, or (at your option)
20
* This program is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU General Public License for more details.
25
* ============================================================ */
27
#include "albumdragdrop.moc"
35
#include <kiconloader.h>
43
#include "albummanager.h"
45
#include "ddragobjects.h"
47
#include "imageinfo.h"
48
#include "imageinfolist.h"
53
AlbumDragDropHandler::AlbumDragDropHandler(AlbumModel* model)
54
: AlbumModelDragDropHandler(model)
58
bool AlbumDragDropHandler::dropEvent(QAbstractItemView* view, const QDropEvent* e, const QModelIndex& droppedOn)
60
if (accepts(e, droppedOn) == Qt::IgnoreAction)
65
AlbumPointer<PAlbum> destAlbum = model()->albumForIndex(droppedOn);
72
if (DAlbumDrag::canDecode(e->mimeData()))
77
if (!DAlbumDrag::decode(e->mimeData(), urls, albumId))
82
AlbumPointer<PAlbum> droppedAlbum = AlbumManager::instance()->findPAlbum(albumId);
91
popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
92
QAction* moveAction = popMenu.addAction(SmallIcon("go-jump"), i18n("&Move Here"));
93
popMenu.addSeparator();
94
popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
95
popMenu.setMouseTracking(true);
96
QAction* choice = popMenu.exec(QCursor::pos());
98
if (!droppedAlbum || !destAlbum)
103
if (choice == moveAction)
105
KIO::Job* job = DIO::move(droppedAlbum, destAlbum);
106
connect(job, SIGNAL(result(KJob*)),
107
this, SIGNAL(dioResult(KJob*)));
112
else if (DItemDrag::canDecode(e->mimeData()))
118
QList<qlonglong> imageIDs;
120
if (!DItemDrag::decode(e->mimeData(), urls, kioURLs, albumIDs, imageIDs))
125
if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
130
// Check if items dropped come from outside current album.
131
// This can be the case with recursive content album mode.
133
ImageInfoList extImgInfList;
134
QList<qlonglong> extImageIDs;
136
for (QList<qlonglong>::const_iterator it = imageIDs.constBegin(); it != imageIDs.constEnd(); ++it)
140
if (info.albumId() != destAlbum->id())
142
extUrls.append(info.databaseUrl());
143
extImgInfList.append(info);
148
if (extUrls.isEmpty())
150
// Setting the dropped image as the album thumbnail
151
// If the ctrl key is pressed, when dropping the image, the
152
// thumbnail is set without a popup menu
155
if (e->keyboardModifiers() == Qt::ControlModifier)
162
popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
163
QAction* setAction = 0;
165
if (imageIDs.count() == 1)
167
setAction = popMenu.addAction(i18n("Set as Album Thumbnail"));
170
popMenu.addSeparator();
171
popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
172
popMenu.setMouseTracking(true);
173
QAction* choice = popMenu.exec(QCursor::pos());
174
set = (setAction == choice);
177
if (set && destAlbum)
180
AlbumManager::instance()->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
186
// If shift key is pressed while dragging, move the drag object without
187
// displaying popup menu -> move
188
bool move = false, copy = false, setThumbnail = false;
190
if (e->keyboardModifiers() == Qt::ShiftModifier)
194
// If ctrl key is pressed while dragging, copy the drag object without
195
// displaying popup menu -> copy
196
else if (e->keyboardModifiers() == Qt::ControlModifier)
203
popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
204
QAction* moveAction = popMenu.addAction(SmallIcon("go-jump"), i18n("&Move Here"));
205
QAction* copyAction = popMenu.addAction(SmallIcon("edit-copy"), i18n("&Copy Here"));
206
QAction* thumbnailAction = 0;
208
if (imageIDs.count() == 1)
210
thumbnailAction = popMenu.addAction(i18n("Set as Album Thumbnail"));
213
popMenu.addSeparator();
214
popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
215
popMenu.setMouseTracking(true);
216
QAction* choice = popMenu.exec(QCursor::pos());
220
if (choice == moveAction)
224
else if (choice == copyAction)
228
else if (choice == thumbnailAction)
242
KIO::Job* job = DIO::move(extUrls, extImageIDs, destAlbum);
243
connect(job, SIGNAL(result(KJob*)),
244
this, SIGNAL(dioResult(KJob*)));
248
KIO::Job* job = DIO::copy(extUrls, extImageIDs, destAlbum);
249
connect(job, SIGNAL(result(KJob*)),
250
this, SIGNAL(dioResult(KJob*)));
252
else if (setThumbnail)
255
AlbumManager::instance()->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
260
// -- DnD from Camera GUI ----------------------------
261
else if (DCameraItemListDrag::canDecode(e->mimeData()))
263
CameraUI* ui = dynamic_cast<CameraUI*>(e->source());
268
popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
269
QAction* downAction = popMenu.addAction(SmallIcon("file-export"),
270
i18n("Download From Camera"));
271
QAction* downDelAction = popMenu.addAction(SmallIcon("file-export"),
272
i18n("Download && Delete From Camera"));
273
popMenu.addSeparator();
274
popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
275
popMenu.setMouseTracking(true);
276
QAction* choice = popMenu.exec(QCursor::pos());
278
if (choice && destAlbum)
280
if (choice == downAction)
282
ui->slotDownload(true, false, destAlbum);
284
else if (choice == downDelAction)
286
ui->slotDownload(true, true, destAlbum);
291
// -- DnD from an external source ---------------------
292
else if (KUrl::List::canDecode(e->mimeData()))
294
KUrl destURL(destAlbum->databaseUrl());
296
KUrl::List srcURLs = KUrl::List::fromMimeData(e->mimeData());
298
bool move = false, copy = false;
300
// If shift key is pressed while dropping, move the drag object without
301
// displaying popup menu -> move
302
if (e->keyboardModifiers() == Qt::ShiftModifier)
306
// If ctrl key is pressed while dropping, copy the drag object without
307
// displaying popup menu -> copy
308
else if (e->keyboardModifiers() == Qt::ControlModifier)
315
popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
316
QAction* moveAction = popMenu.addAction(SmallIcon("go-jump"), i18n("&Move Here"));
317
QAction* copyAction = popMenu.addAction(SmallIcon("edit-copy"), i18n("&Copy Here"));
318
popMenu.addSeparator();
319
popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
320
popMenu.setMouseTracking(true);
321
QAction* choice = popMenu.exec(QCursor::pos());
323
if (choice == copyAction)
327
else if (choice == moveAction)
340
KIO::Job* job = DIO::move(srcURLs, destAlbum);
341
connect(job, SIGNAL(result(KJob*)),
342
this, SIGNAL(dioResult(KJob*)));
346
KIO::Job* job = DIO::copy(srcURLs, destAlbum);
347
connect(job, SIGNAL(result(KJob*)),
348
this, SIGNAL(dioResult(KJob*)));
357
Qt::DropAction AlbumDragDropHandler::accepts(const QDropEvent* e, const QModelIndex& dropIndex)
359
PAlbum* destAlbum = model()->albumForIndex(dropIndex);
361
if (DAlbumDrag::canDecode(e->mimeData()))
363
// do not allow to drop on root
364
if (dropIndex == model()->rootAlbumIndex())
366
return Qt::IgnoreAction;
371
return Qt::IgnoreAction;
377
if (!DAlbumDrag::decode(e->mimeData(), urls, albumId))
379
return Qt::IgnoreAction;
382
PAlbum* droppedAlbum = AlbumManager::instance()->findPAlbum(albumId);
386
return Qt::IgnoreAction;
389
// Dragging an item on itself makes no sense
390
if (droppedAlbum == destAlbum)
392
return Qt::IgnoreAction;
395
// Dragging a parent on its child makes no sense
396
if (droppedAlbum->isAncestorOf(destAlbum))
398
return Qt::IgnoreAction;
401
return Qt::MoveAction;
403
else if (DItemDrag::canDecode(e->mimeData()) ||
404
DCameraItemListDrag::canDecode(e->mimeData()) ||
405
KUrl::List::canDecode(e->mimeData()))
407
// Do not allow drop images on album root
408
if (destAlbum && !destAlbum->isRoot())
410
return Qt::MoveAction;
414
return Qt::IgnoreAction;
417
QStringList AlbumDragDropHandler::mimeTypes() const
419
QStringList mimeTypes;
420
mimeTypes << DAlbumDrag::mimeTypes()
421
<< DItemDrag::mimeTypes()
422
<< DCameraItemListDrag::mimeTypes()
423
<< KUrl::List::mimeDataTypes();
427
QMimeData* AlbumDragDropHandler::createMimeData(const QList<Album*>& albums)
429
if (albums.isEmpty())
434
if (albums.size() > 1)
436
kWarning() << "Dragging multiple albums is not implemented";
439
PAlbum* palbum = dynamic_cast<PAlbum*>(albums.first());
440
return new DAlbumDrag(albums.first()->databaseUrl(), albums.first()->id(),
441
palbum ? palbum->fileUrl() : KUrl());
444
} // namespace Digikam