File indexing completed on 2024-05-12 17:08:47

0001 /*
0002     SPDX-FileCopyrightText: 2022 Kai Uwe Broulik <kde@broulik.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "draghelper.h"
0008 
0009 #include <QDrag>
0010 #include <QGuiApplication>
0011 #include <QMetaObject>
0012 #include <QMimeData>
0013 #include <QQuickWindow>
0014 #include <QStyleHints>
0015 
0016 DragHelper::DragHelper(QObject *parent)
0017     : QObject(parent)
0018 {
0019 }
0020 
0021 DragHelper::~DragHelper() = default;
0022 
0023 bool DragHelper::dragActive() const
0024 {
0025     return m_dragActive;
0026 }
0027 
0028 int DragHelper::dragPixmapSize() const
0029 {
0030     return m_dragPixmapSize;
0031 }
0032 
0033 void DragHelper::setDragPixmapSize(int dragPixmapSize)
0034 {
0035     if (m_dragPixmapSize != dragPixmapSize) {
0036         m_dragPixmapSize = dragPixmapSize;
0037         Q_EMIT dragPixmapSizeChanged();
0038     }
0039 }
0040 
0041 bool DragHelper::isDrag(int oldX, int oldY, int newX, int newY) const
0042 {
0043     return ((QPoint(oldX, oldY) - QPoint(newX, newY)).manhattanLength() >= qApp->styleHints()->startDragDistance());
0044 }
0045 
0046 void DragHelper::startDrag(QQuickItem *item, const QUrl &url, const QString &iconName)
0047 {
0048     startDrag(item, url, QIcon::fromTheme(iconName).pixmap(m_dragPixmapSize, m_dragPixmapSize));
0049 }
0050 
0051 void DragHelper::startDrag(QQuickItem *item, const QUrl &url, const QPixmap &pixmap)
0052 {
0053     // This allows the caller to return, making sure we don't crash if
0054     // the caller is destroyed mid-drag
0055 
0056     QMetaObject::invokeMethod(this, "doDrag", Qt::QueuedConnection, Q_ARG(QQuickItem *, item), Q_ARG(QUrl, url), Q_ARG(QPixmap, pixmap));
0057 }
0058 
0059 void DragHelper::doDrag(QQuickItem *item, const QUrl &url, const QPixmap &pixmap)
0060 {
0061     if (item && item->window() && item->window()->mouseGrabberItem()) {
0062         item->window()->mouseGrabberItem()->ungrabMouse();
0063     }
0064 
0065     QDrag *drag = new QDrag(item);
0066 
0067     QMimeData *mimeData = new QMimeData();
0068 
0069     if (!url.isEmpty()) {
0070         mimeData->setUrls(QList<QUrl>() << url);
0071     }
0072 
0073     drag->setMimeData(mimeData);
0074 
0075     if (!pixmap.isNull()) {
0076         drag->setPixmap(pixmap);
0077     }
0078 
0079     m_dragActive = true;
0080     Q_EMIT dragActiveChanged();
0081 
0082     drag->exec();
0083 
0084     m_dragActive = false;
0085     Q_EMIT dragActiveChanged();
0086 }