Qt::DropAction UIDnDHandler::dragEnter(ulong screenID, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData) { LogFlowFunc(("enmOpMode=%RU32, screenID=%RU32, x=%d, y=%d, action=%ld\n", m_enmOpMode, screenID, x, y, toVBoxDnDAction(proposedAction))); if ( m_enmOpMode != DNDMODE_UNKNOWN && m_enmOpMode != DNDMODE_HOSTTOGUEST) return Qt::IgnoreAction; /* Ask the guest for starting a DnD event. */ KDnDAction result = m_dndTarget.Enter(screenID, x, y, toVBoxDnDAction(proposedAction), toVBoxDnDActions(possibleActions), pMimeData->formats().toVector()); if (m_dndTarget.isOk()) { setOpMode(DNDMODE_HOSTTOGUEST); return toQtDnDAction(result); } msgCenter().cannotDropDataToGuest(m_dndTarget, m_pParent); return Qt::IgnoreAction; }
int UIDnDHandler::dragStart(ulong screenID) { int rc; #ifdef VBOX_WITH_DRAG_AND_DROP_GH NOREF(screenID); LogFlowFuncEnter(); /* Sanity checks. */ if ( !m_dataSource.lstFormats.size() || m_dataSource.defaultAction == KDnDAction_Ignore || !m_dataSource.vecActions.size()) { return VERR_INVALID_PARAMETER; } setOpMode(DNDMODE_GUESTTOHOST); rc = dragStartInternal(m_dataSource.lstFormats, toQtDnDAction(m_dataSource.defaultAction), toQtDnDActions(m_dataSource.vecActions)); #else /* !VBOX_WITH_DRAG_AND_DROP_GH */ NOREF(screenID); rc = VERR_NOT_SUPPORTED; #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ LogFlowFuncLeaveRC(rc); return rc; }
Qt::DropAction UIDnDHandler::dragHGMove(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget * /* pParent = 0 */) { /* Ask the guest for starting a DnD event. */ KDragAndDropAction result = guest.DragHGMove(screenId, x, y, toVBoxDnDAction(proposedAction), toVBoxDnDActions(possibleActions), pMimeData->formats().toVector()); /* Set the DnD action returned by the guest. */ return toQtDnDAction(result); }
Qt::DropAction UIDnDHandler::dragHGDrop(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent /* = 0 */) { /* The format the guest requests. */ QString format; /* Ask the guest for dropping data. */ KDragAndDropAction result = guest.DragHGDrop(screenId, x, y, toVBoxDnDAction(proposedAction), toVBoxDnDActions(possibleActions), pMimeData->formats().toVector(), format); /* Has the guest accepted the drop event? */ if (result != KDragAndDropAction_Ignore) { /* Get the actually data */ const QByteArray &d = pMimeData->data(format); if ( !d.isEmpty() && !format.isEmpty()) { /* We need the data in the vector format. */ QVector<uint8_t> dv(d.size()); memcpy(dv.data(), d.constData(), d.size()); CProgress progress = guest.DragHGPutData(screenId, format, dv); if (guest.isOk()) { msgCenter().showModalProgressDialog(progress, tr("Dropping data ..."), ":/progress_dnd_hg_90px.png", pParent); if (!progress.GetCanceled() && (!progress.isOk() || progress.GetResultCode() != 0)) { msgCenter().cannotDropData(progress, pParent); result = KDragAndDropAction_Ignore; } } else { msgCenter().cannotDropData(guest, pParent); result = KDragAndDropAction_Ignore; } } } return toQtDnDAction(result); }
Qt::DropAction UIDnDHandler::dragMove(ulong screenID, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData) { LogFlowFunc(("enmMode=%RU32, screenID=%RU32, x=%d, y=%d, action=%ld\n", m_enmMode, screenID, x, y, toVBoxDnDAction(proposedAction))); if (m_enmMode != DNDMODE_HOSTTOGUEST) return Qt::IgnoreAction; /* Notify the guest that the mouse has been moved while doing * a drag'n drop operation. */ KDnDAction result = m_dndTarget.Move(screenID, x, y, toVBoxDnDAction(proposedAction), toVBoxDnDActions(possibleActions), pMimeData->formats().toVector()); /* Set the DnD action returned by the guest. */ return toQtDnDAction(result); }
Qt::DropAction UIDnDHandler::dragDrop(ulong screenID, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData) { LogFlowFunc(("enmOpMode=%RU32, screenID=%RU32, x=%d, y=%d, action=%ld\n", m_enmOpMode, screenID, x, y, toVBoxDnDAction(proposedAction))); if (m_enmOpMode != DNDMODE_HOSTTOGUEST) return Qt::IgnoreAction; /* The format the guest requests. */ QString strFormat; /* Ask the guest for dropping data. */ KDnDAction enmResult = m_dndTarget.Drop(screenID, x, y, toVBoxDnDAction(proposedAction), toVBoxDnDActions(possibleActions), pMimeData->formats().toVector(), strFormat); /* Has the guest accepted the drop event? */ if ( m_dndTarget.isOk() && enmResult != KDnDAction_Ignore) { LogFlowFunc(("strFormat=%s ...\n", strFormat.toUtf8().constData())); QByteArray arrBytes; /* * Does the host support the format requested by the guest? * Lookup the format in the MIME data object. */ AssertPtr(pMimeData); if (pMimeData->formats().indexOf(strFormat) >= 0) { arrBytes = pMimeData->data(strFormat); Assert(!arrBytes.isEmpty()); } /* * The host does not support the format requested by the guest. * This can happen if the host wants to send plan text, for example, but * the guest requested something else, e.g. an URI list. * * In that case dictate the guest to use a fixed format from the host, * so instead returning the requested URI list, return the original * data format from the host. The guest has to try to deal with that then. **/ else { LogRel3(("DnD: Guest requested a different format '%s'\n", strFormat.toUtf8().constData())); LogRel3(("DnD: The host offered:\n")); #if 0 for (QStringList::iterator itFmt = pMimeData->formats().begin(); itFmt != pMimeData->formats().end(); itFmt++) { QString strTemp = *itFmt; LogRel3(("DnD: \t%s\n", strTemp.toUtf8().constData())); } #endif if (pMimeData->hasText()) { LogRel3(("DnD: Converting data to text ...\n")); arrBytes = pMimeData->text().toUtf8(); strFormat = "text/plain;charset=utf-8"; } else { LogRel(("DnD: Error: Could not convert host format to guest format\n")); enmResult = KDnDAction_Ignore; } } if (arrBytes.size()) /* Anything to send? */ { /* Convert data to a vector. */ QVector<uint8_t> vecData(arrBytes.size()); /** @todo Can this throw or anything? */ AssertReleaseMsg(vecData.size() == arrBytes.size(), ("Drag and drop format buffer size does not match")); memcpy(vecData.data(), arrBytes.constData(), arrBytes.size()); /* Send data to the guest. */ LogRel3(("DnD: Host is sending %d bytes of data as '%s'\n", vecData.size(), strFormat.toUtf8().constData())); CProgress progress = m_dndTarget.SendData(screenID, strFormat, vecData); if (m_dndTarget.isOk()) { msgCenter().showModalProgressDialog(progress, tr("Dropping data ..."), ":/progress_dnd_hg_90px.png", m_pParent); LogFlowFunc(("Transfer fCompleted=%RTbool, fCanceled=%RTbool, hr=%Rhrc\n", progress.GetCompleted(), progress.GetCanceled(), progress.GetResultCode())); BOOL fCanceled = progress.GetCanceled(); if ( !fCanceled && ( !progress.isOk() || progress.GetResultCode() != 0)) { msgCenter().cannotDropDataToGuest(progress, m_pParent); enmResult = KDnDAction_Ignore; } } else { msgCenter().cannotDropDataToGuest(m_dndTarget, m_pParent); enmResult = KDnDAction_Ignore; } } else /* Error. */ enmResult = KDnDAction_Ignore; } /* * Since the mouse button has been release this in any case marks * the end of the current transfer direction. So reset the current * mode as well here. */ setOpMode(DNDMODE_UNKNOWN); return toQtDnDAction(enmResult); }