Beispiel #1
0
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;
}
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);
}
Beispiel #5
0
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);
}