File indexing completed on 2024-05-19 15:09:22

0001 /*
0002     SPDX-FileCopyrightText: 2010 BetterInbox <contact@betterinbox.com>
0003     SPDX-FileContributor: Gregory Schlomoff <greg@betterinbox.com>
0004 
0005     SPDX-License-Identifier: MIT
0006 */
0007 
0008 #include "DeclarativeDropArea.h"
0009 #include "DeclarativeDragDropEvent.h"
0010 
0011 DeclarativeDropArea::DeclarativeDropArea(QQuickItem *parent)
0012     : QQuickItem(parent)
0013     , m_enabled(true)
0014     , m_preventStealing(false)
0015     , m_temporaryInhibition(false)
0016     , m_containsDrag(false)
0017 {
0018     setFlag(ItemAcceptsDrops, m_enabled);
0019 }
0020 
0021 void DeclarativeDropArea::temporaryInhibitParent(bool inhibit)
0022 {
0023     QQuickItem *candidate = parentItem();
0024 
0025     while (candidate) {
0026         if (DeclarativeDropArea *da = qobject_cast<DeclarativeDropArea *>(candidate)) {
0027             da->m_temporaryInhibition = inhibit;
0028             if (inhibit) {
0029                 Q_EMIT da->dragLeaveEvent(nullptr);
0030             }
0031         }
0032         candidate = candidate->parentItem();
0033     }
0034 }
0035 
0036 void DeclarativeDropArea::dragEnterEvent(QDragEnterEvent *event)
0037 {
0038     if (!m_enabled || m_temporaryInhibition) {
0039         return;
0040     }
0041 
0042     DeclarativeDragDropEvent dde(event, this);
0043     event->accept();
0044 
0045     Q_EMIT dragEnter(&dde);
0046 
0047     if (!event->isAccepted()) {
0048         return;
0049     }
0050 
0051     if (m_preventStealing) {
0052         temporaryInhibitParent(true);
0053     }
0054 
0055     m_oldDragMovePos = event->pos();
0056     setContainsDrag(true);
0057 }
0058 
0059 void DeclarativeDropArea::dragLeaveEvent(QDragLeaveEvent *event)
0060 {
0061     // do it anyways, in the unlikely case m_preventStealing
0062     // was changed while drag
0063     temporaryInhibitParent(false);
0064 
0065     m_oldDragMovePos = QPoint(-1, -1);
0066     DeclarativeDragDropEvent dde(event, this);
0067     Q_EMIT dragLeave(&dde);
0068     setContainsDrag(false);
0069 }
0070 
0071 void DeclarativeDropArea::dragMoveEvent(QDragMoveEvent *event)
0072 {
0073     if (!m_enabled || m_temporaryInhibition) {
0074         event->ignore();
0075         return;
0076     }
0077     event->accept();
0078     // if the position we export didn't change, don't generate the move event
0079     if (event->pos() == m_oldDragMovePos) {
0080         return;
0081     }
0082 
0083     m_oldDragMovePos = event->pos();
0084     DeclarativeDragDropEvent dde(event, this);
0085     Q_EMIT dragMove(&dde);
0086 }
0087 
0088 void DeclarativeDropArea::dropEvent(QDropEvent *event)
0089 {
0090     // do it anyways, in the unlikely case m_preventStealing
0091     // was changed while drag, do it after a loop,
0092     // so the parent dropevent doesn't get delivered
0093     metaObject()->invokeMethod(this, "temporaryInhibitParent", Qt::QueuedConnection, Q_ARG(bool, false));
0094 
0095     m_oldDragMovePos = QPoint(-1, -1);
0096 
0097     if (!m_enabled || m_temporaryInhibition) {
0098         return;
0099     }
0100 
0101     DeclarativeDragDropEvent dde(event, this);
0102     Q_EMIT drop(&dde);
0103     setContainsDrag(false);
0104 }
0105 
0106 bool DeclarativeDropArea::isEnabled() const
0107 {
0108     return m_enabled;
0109 }
0110 
0111 void DeclarativeDropArea::setEnabled(bool enabled)
0112 {
0113     if (enabled == m_enabled) {
0114         return;
0115     }
0116 
0117     m_enabled = enabled;
0118     setFlag(ItemAcceptsDrops, m_enabled);
0119     Q_EMIT enabledChanged();
0120 }
0121 
0122 bool DeclarativeDropArea::preventStealing() const
0123 {
0124     return m_preventStealing;
0125 }
0126 
0127 void DeclarativeDropArea::setPreventStealing(bool prevent)
0128 {
0129     if (prevent == m_preventStealing) {
0130         return;
0131     }
0132 
0133     m_preventStealing = prevent;
0134     Q_EMIT preventStealingChanged();
0135 }
0136 
0137 void DeclarativeDropArea::setContainsDrag(bool dragging)
0138 {
0139     if (m_containsDrag != dragging) {
0140         m_containsDrag = dragging;
0141         Q_EMIT containsDragChanged(m_containsDrag);
0142     }
0143 }
0144 
0145 bool DeclarativeDropArea::containsDrag() const
0146 {
0147     return m_containsDrag;
0148 }
0149 
0150 #include "moc_DeclarativeDropArea.cpp"