20#include "dragdropmanager_p.h"
21#include "specialcollectionattribute_p.h"
22#include "collectionutils_p.h"
24#include <QApplication>
30#include <KDE/KLocalizedString>
33#include "akonadi/collection.h"
34#include "akonadi/entitytreemodel.h"
38DragDropManager::DragDropManager(QAbstractItemView *view)
39 : mShowDropActionMenu(true)
40 , mIsManualSortingActive(false)
47 const QModelIndex index = m_view->indexAt(event->pos());
49 if (!collection.isValid()) {
59bool DragDropManager::dropAllowed(QDragMoveEvent *event)
const
62 const Collection targetCollection = currentDropTarget(event);
63 if (targetCollection.
isValid()) {
64 const QStringList supportedContentTypes = targetCollection.
contentMimeTypes();
66 const QMimeData *data =
event->mimeData();
67 const KUrl::List urls = KUrl::List::fromMimeData(data);
68 foreach (
const KUrl &url, urls) {
70 if (collection.isValid()) {
77 if (hasAncestor(m_view->indexAt(event->pos()), collection.id())) {
81 const QString type = url.queryItems()[QString::fromLatin1(
"type")];
82 if (!supportedContentTypes.contains(type)) {
94bool DragDropManager::hasAncestor(
const QModelIndex &_index,
Collection::Id parentId)
const
96 QModelIndex index(_index);
97 while (index.isValid()) {
102 index = index.parent();
108bool DragDropManager::processDropEvent(QDropEvent *event,
bool &menuCanceled,
bool dropOnItem)
110 const Collection targetCollection = currentDropTarget(event);
111 if (!targetCollection.
isValid()) {
115 if (!mIsManualSortingActive && !dropOnItem) {
119 const QStringList supportedContentTypes = targetCollection.
contentMimeTypes();
121 const QMimeData *data =
event->mimeData();
122 const KUrl::List urls = KUrl::List::fromMimeData(data);
123 foreach (
const KUrl &url, urls) {
125 if (!collection.isValid()) {
133 Qt::DropAction defaultAction;
136 bool moveAllowed, copyAllowed, linkAllowed;
137 moveAllowed = copyAllowed = linkAllowed =
false;
140 (event->possibleActions() & Qt::MoveAction)) {
144 (event->possibleActions() & Qt::CopyAction)) {
149 (event->possibleActions() & Qt::LinkAction)) {
153 if (mIsManualSortingActive && !dropOnItem) {
159 if (!moveAllowed && !copyAllowed && !linkAllowed) {
160 kDebug() <<
"Cannot drop here:" <<
event->possibleActions() << m_view->model()->supportedDragActions() << m_view->model()->supportedDropActions();
165 if ((QApplication::keyboardModifiers() & Qt::ControlModifier) &&
166 (QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
168 defaultAction = Qt::LinkAction;
173 }
else if ((QApplication::keyboardModifiers() & Qt::ControlModifier)) {
175 defaultAction = Qt::CopyAction;
180 }
else if ((QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
182 defaultAction = Qt::MoveAction;
189 if (actionCount == 1) {
190 kDebug() <<
"Selecting drop action" << defaultAction <<
", there are no other possibilities";
191 event->setDropAction(defaultAction);
195 if (!mShowDropActionMenu) {
197 defaultAction = Qt::MoveAction;
198 }
else if (copyAllowed) {
199 defaultAction = Qt::CopyAction;
200 }
else if (linkAllowed) {
201 defaultAction = Qt::LinkAction;
205 event->setDropAction(defaultAction);
211 QAction *moveDropAction = 0;
212 QAction *copyDropAction = 0;
213 QAction *linkAction = 0;
217 sequence = QKeySequence(Qt::ShiftModifier).toString();
219 moveDropAction = popup.addAction(KIcon(QString::fromLatin1(
"go-jump")), i18n(
"&Move Here") + QLatin1Char(
'\t') + sequence);
223 sequence = QKeySequence(Qt::ControlModifier).toString();
225 copyDropAction = popup.addAction(KIcon(QString::fromLatin1(
"edit-copy")), i18n(
"&Copy Here") + QLatin1Char(
'\t') + sequence);
229 sequence = QKeySequence(Qt::ControlModifier + Qt::ShiftModifier).toString();
231 linkAction = popup.addAction(KIcon(QLatin1String(
"edit-link")), i18n(
"&Link Here") + QLatin1Char(
'\t') + sequence);
234 popup.addSeparator();
235 popup.addAction(KIcon(QString::fromLatin1(
"process-stop")), i18n(
"C&ancel") + QLatin1Char(
'\t') + QKeySequence(Qt::Key_Escape).toString());
237 QAction *activatedAction = popup.exec(QCursor::pos());
238 if (!activatedAction) {
241 }
else if (activatedAction == moveDropAction) {
242 event->setDropAction(Qt::MoveAction);
243 }
else if (activatedAction == copyDropAction) {
244 event->setDropAction(Qt::CopyAction);
245 }
else if (activatedAction == linkAction) {
246 event->setDropAction(Qt::LinkAction);
254void DragDropManager::startDrag(Qt::DropActions supportedActions)
256 QModelIndexList indexes;
257 bool sourceDeletable =
true;
258 foreach (
const QModelIndex &index, m_view->selectionModel()->selectedRows()) {
259 if (!m_view->model()->flags(index).testFlag(Qt::ItemIsDragEnabled)) {
263 if (sourceDeletable) {
274 indexes.append(index);
277 if (indexes.isEmpty()) {
281 QMimeData *mimeData = m_view->model()->mimeData(indexes);
286 QDrag *drag =
new QDrag(m_view);
287 drag->setMimeData(mimeData);
288 if (indexes.size() > 1) {
289 drag->setPixmap(KIcon(QLatin1String(
"document-multiple")).pixmap(QSize(22, 22)));
291 QPixmap pixmap = indexes.first().data(Qt::DecorationRole).value<QIcon>().pixmap(QSize(22, 22));
292 if (pixmap.isNull()) {
293 pixmap = KIcon(QLatin1String(
"text-plain")).pixmap(QSize(22, 22));
295 drag->setPixmap(pixmap);
298 if (!sourceDeletable) {
299 supportedActions &= ~Qt::MoveAction;
302 Qt::DropAction defaultAction = Qt::IgnoreAction;
303 if ((QApplication::keyboardModifiers() & Qt::ControlModifier) &&
304 (QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
305 defaultAction = Qt::LinkAction;
306 }
else if ((QApplication::keyboardModifiers() & Qt::ControlModifier)) {
307 defaultAction = Qt::CopyAction;
308 }
else if ((QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
309 defaultAction = Qt::MoveAction;
312 drag->exec(supportedActions, defaultAction);
315bool DragDropManager::showDropActionMenu()
const
317 return mShowDropActionMenu;
320void DragDropManager::setShowDropActionMenu(
bool show)
322 mShowDropActionMenu = show;
325bool DragDropManager::isManualSortingActive()
const
327 return mIsManualSortingActive;
330void DragDropManager::setManualSortingActive(
bool active)
332 mIsManualSortingActive = active;
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.
Rights rights() const
Returns the rights the user has on the collection.
static Collection fromUrl(const KUrl &url)
Creates a collection from the given url.
@ CanDeleteItem
Can delete items in this collection.
@ CanDeleteCollection
Can delete this collection.
@ CanCreateItem
Can create new items in this collection.
@ CanLinkItem
Can create links to existing items in this virtual collection.
@ CanCreateCollection
Can create new subcollections in this collection.
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
@ ParentCollectionRole
The parent collection of the entity.
@ CollectionRole
The collection.
@ CollectionIdRole
The collection id.
bool isValid() const
Returns whether the entity is valid.
bool hasAttribute(const QByteArray &name) const
Returns true if the entity has an attribute of the given type name, false otherwise.
qint64 Id
Describes the unique id type.
An Attribute that stores the special collection type of a collection.
FreeBusyManager::Singleton.