File indexing completed on 2024-12-22 05:15:20
0001 /* 0002 SPDX-FileCopyrightText: 2013 Eike Hein <hein@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "draghelper.h" 0008 0009 #include <QApplication> 0010 #include <QDrag> 0011 #include <QMimeData> 0012 #include <QQuickItem> 0013 #include <QQuickWindow> 0014 #include <QTimer> 0015 0016 DragHelper::DragHelper(QObject *parent) 0017 : QObject(parent) 0018 { 0019 } 0020 0021 DragHelper::~DragHelper() 0022 { 0023 } 0024 0025 int DragHelper::dragIconSize() const 0026 { 0027 return m_dragIconSize; 0028 } 0029 0030 void DragHelper::setDragIconSize(int size) 0031 { 0032 if (m_dragIconSize != size) { 0033 m_dragIconSize = size; 0034 0035 Q_EMIT dragIconSizeChanged(); 0036 } 0037 } 0038 0039 bool DragHelper::isDrag(int oldX, int oldY, int newX, int newY) const 0040 { 0041 return ((QPoint(oldX, oldY) - QPoint(newX, newY)).manhattanLength() >= QApplication::startDragDistance()); 0042 } 0043 0044 void DragHelper::startDrag(QQuickItem *item, const QUrl &url, const QIcon &icon, const QString &extraMimeType, const QString &extraMimeData) 0045 { 0046 // This allows the caller to return, making sure we don't crash if 0047 // the caller is destroyed mid-drag (as can happen due to a sycoca 0048 // change). 0049 0050 QMetaObject::invokeMethod(this, 0051 "doDrag", 0052 Qt::QueuedConnection, 0053 Q_ARG(QQuickItem *, item), 0054 Q_ARG(QUrl, url), 0055 Q_ARG(QIcon, icon), 0056 Q_ARG(QString, extraMimeType), 0057 Q_ARG(QString, extraMimeData)); 0058 } 0059 0060 void DragHelper::doDrag(QQuickItem *item, const QUrl &url, const QIcon &icon, const QString &extraMimeType, const QString &extraMimeData) 0061 { 0062 setDragging(true); 0063 0064 if (item && item->window() && item->window()->mouseGrabberItem()) { 0065 item->window()->mouseGrabberItem()->ungrabMouse(); 0066 } 0067 0068 QDrag *drag = new QDrag(item); 0069 0070 QMimeData *mimeData = new QMimeData(); 0071 0072 if (!url.isEmpty()) { 0073 mimeData->setUrls(QList<QUrl>() << url); 0074 } 0075 0076 if (!extraMimeType.isEmpty() && !extraMimeData.isEmpty()) { 0077 mimeData->setData(extraMimeType, extraMimeData.toLatin1()); 0078 } 0079 0080 drag->setMimeData(mimeData); 0081 0082 if (!icon.isNull()) { 0083 drag->setPixmap(icon.pixmap(m_dragIconSize, m_dragIconSize)); 0084 } 0085 0086 drag->exec(); 0087 0088 Q_EMIT dropped(); 0089 0090 // Ensure dragging is still true when onRelease is called. 0091 QTimer::singleShot(0, qApp, [this] { 0092 setDragging(false); 0093 }); 0094 } 0095 0096 void DragHelper::setDragging(bool dragging) 0097 { 0098 if (m_dragging == dragging) 0099 return; 0100 m_dragging = dragging; 0101 Q_EMIT draggingChanged(); 0102 }