1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2012-09-07
7 * Description : Qt Model for ImportUI - drag and drop handling
8 *
9 * Copyright (C) 2012 by Islam Wazery <wazery at ubuntu dot com>
10 * Copyright (C) 2013-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 *
12 * This program is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation;
15 * either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * ============================================================ */
24
25 #include "importdragdrop.h"
26
27 // Qt includes
28
29 #include <QDropEvent>
30 #include <QIcon>
31
32 // KDE includes
33
34 #include <klocalizedstring.h>
35
36 // Local includes
37
38 #include "digikam_debug.h"
39 #include "importiconview.h"
40 #include "importui.h"
41 #include "ddragobjects.h"
42 #include "importcategorizedview.h"
43 #include "camiteminfo.h"
44 #include "albummanager.h"
45 #include "digikamapp.h"
46 #include "itemiconview.h"
47
48 namespace Digikam
49 {
50
ImportDragDropHandler(ImportItemModel * const model)51 ImportDragDropHandler::ImportDragDropHandler(ImportItemModel* const model)
52 : AbstractItemDragDropHandler(model)
53 {
54 }
55
addGroupAction(QMenu * const menu)56 QAction* ImportDragDropHandler::addGroupAction(QMenu* const menu)
57 {
58 return menu->addAction(QIcon::fromTheme(QLatin1String("go-bottom")),
59 i18nc("@action:inmenu Group images with this image", "Group here"));
60 }
61
addCancelAction(QMenu * const menu)62 QAction* ImportDragDropHandler::addCancelAction(QMenu* const menu)
63 {
64 return menu->addAction(QIcon::fromTheme(QLatin1String("dialog-cancel")), i18n("C&ancel"));
65 }
66
copyOrMove(const QDropEvent * e,QWidget * const view,bool allowMove,bool askForGrouping)67 ImportDragDropHandler::DropAction ImportDragDropHandler::copyOrMove(const QDropEvent* e,
68 QWidget* const view,
69 bool allowMove,
70 bool askForGrouping)
71 {
72 if (e->keyboardModifiers() & Qt::ControlModifier)
73 {
74 return CopyAction;
75 }
76 else if (e->keyboardModifiers() & Qt::ShiftModifier)
77 {
78 return MoveAction;
79 }
80
81 if (!allowMove && !askForGrouping)
82 {
83 switch (e->proposedAction())
84 {
85 case Qt::CopyAction:
86 {
87 return CopyAction;
88 }
89
90 case Qt::MoveAction:
91 {
92 return MoveAction;
93 }
94
95 default:
96 {
97 return NoAction;
98 }
99 }
100 }
101
102 QMenu popMenu(view);
103
104 QAction* moveAction = nullptr;
105
106 if (allowMove)
107 {
108 moveAction = popMenu.addAction(QIcon::fromTheme(QLatin1String("go-jump")), i18n("&Move Here"));
109 }
110
111 QAction* const copyAction = popMenu.addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18n("&Copy Here"));
112 popMenu.addSeparator();
113
114 QAction* groupAction = nullptr;
115
116 if (askForGrouping)
117 {
118 groupAction = addGroupAction(&popMenu);
119 popMenu.addSeparator();
120 }
121
122 addCancelAction(&popMenu);
123
124 popMenu.setMouseTracking(true);
125 QAction* const choice = popMenu.exec(QCursor::pos());
126
127 if (moveAction && (choice == moveAction))
128 {
129 return MoveAction;
130 }
131 else if (choice == copyAction)
132 {
133 return CopyAction;
134 }
135 else if (groupAction && (choice == groupAction))
136 {
137 return GroupAction;
138 }
139
140 return NoAction;
141 }
142
143 /*
144 static DropAction tagAction(const QDropEvent*, QWidget* view, bool askForGrouping)
145 {
146 }
147
148 static DropAction groupAction(const QDropEvent*, QWidget* view)
149 {
150 }
151 */
152
dropEvent(QAbstractItemView * abstractview,const QDropEvent * e,const QModelIndex & droppedOn)153 bool ImportDragDropHandler::dropEvent(QAbstractItemView* abstractview,
154 const QDropEvent* e,
155 const QModelIndex& droppedOn)
156 {
157 ImportCategorizedView* const view = static_cast<ImportCategorizedView*>(abstractview);
158
159 if (accepts(e, droppedOn) == Qt::IgnoreAction)
160 {
161 return false;
162 }
163
164 if (DItemDrag::canDecode(e->mimeData()))
165 {
166 QList<QUrl> lst = DigikamApp::instance()->view()->selectedUrls();
167
168 QMenu popMenu(view);
169 popMenu.addSection(QIcon::fromTheme(QLatin1String("digikam")), i18n("Exporting"));
170 QAction* const upAction = popMenu.addAction(QIcon::fromTheme(QLatin1String("media-flash-sd-mmc")),
171 i18n("Upload to Camera"));
172 popMenu.addSeparator();
173 popMenu.addAction(QIcon::fromTheme(QLatin1String("dialog-cancel")), i18n("C&ancel"));
174 popMenu.setMouseTracking(true);
175 QAction* const choice = popMenu.exec(view->mapToGlobal(e->pos()));
176
177 if (choice)
178 {
179 if (choice == upAction)
180 {
181 ImportUI::instance()->slotUploadItems(lst);
182 }
183 }
184
185 return true;
186 }
187 /*
188 TODO: Implement tag dropping in import tool.
189 else if (DTagListDrag::canDecode(e->mimeData()))
190 {
191 }
192 */
193 return false;
194 }
195
accepts(const QDropEvent * e,const QModelIndex &)196 Qt::DropAction ImportDragDropHandler::accepts(const QDropEvent* e, const QModelIndex& /*dropIndex*/)
197 {
198 if (DItemDrag::canDecode(e->mimeData()) || e->mimeData()->hasUrls())
199 {
200 if (e->keyboardModifiers() & Qt::ControlModifier)
201 {
202 return Qt::CopyAction;
203 }
204 else if (e->keyboardModifiers() & Qt::ShiftModifier)
205 {
206 return Qt::MoveAction;
207 }
208
209 return Qt::MoveAction;
210 }
211
212 if (DTagListDrag::canDecode(e->mimeData()) ||
213 DCameraItemListDrag::canDecode(e->mimeData()) ||
214 DCameraDragObject::canDecode(e->mimeData()))
215 {
216 return Qt::MoveAction;
217 }
218
219 return Qt::IgnoreAction;
220 }
221
mimeTypes() const222 QStringList ImportDragDropHandler::mimeTypes() const
223 {
224 QStringList mimeTypes;
225 mimeTypes << DItemDrag::mimeTypes()
226 << DTagListDrag::mimeTypes()
227 << DCameraItemListDrag::mimeTypes()
228 << DCameraDragObject::mimeTypes()
229 << QLatin1String("text/uri-list");
230
231 return mimeTypes;
232 }
233
createMimeData(const QList<QModelIndex> & indexes)234 QMimeData* ImportDragDropHandler::createMimeData(const QList<QModelIndex>& indexes)
235 {
236 QList<CamItemInfo> infos = model()->camItemInfos(indexes);
237
238 QStringList lst;
239
240 foreach (const CamItemInfo& info, infos)
241 {
242 lst.append(info.folder + info.name);
243 }
244
245 if (lst.isEmpty())
246 {
247 return nullptr;
248 }
249
250 return (new DCameraItemListDrag(lst));
251 }
252
model() const253 ImportItemModel* ImportDragDropHandler::model() const
254 {
255 return static_cast<ImportItemModel*>(m_model);
256 }
257
258 } // namespace Digikam
259