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 }