UIDnDMIMEData.cpp revision a3011b448b38c39a7222f2f1eb40c8349023f650
/* $Id$ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
* UIDnDMIMEData class implementation
*/
/*
* Copyright (C) 2011-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/* Qt includes: */
#include <QApplication>
#include <QKeyEvent>
#include <QMimeData>
#include <QStringList>
#include <QTimer>
#ifdef LOG_GROUP
#endif
#define LOG_GROUP LOG_GROUP_GUEST_DND
/* GUI includes: */
#include "UIDnDMIMEData.h"
#include "UIMessageCenter.h"
{
/*
* This is unbelievable hacky, but I didn't find another way. Stupid
* Qt QDrag interface is so less verbose, that we in principle know
* nothing about what happens when the user drag something around. It
* is possible that the target on the host requests data
* (@sa retrieveData) while the mouse button still is pressed. This
* isn't something we should support, because it would mean transferring
* the data from the guest while the mouse is still moving (think of
* transferring a 2GB file from the guest to the host ...). So the idea is
* to detect the mouse release event and only after this happened, allow
* data to be retrieved. Unfortunately the QDrag object eats all events
* while a drag is going on (see QDragManager in the Qt src's).
*
* So what we now are going to do is installing an event filter after the
* QDrag::exec is called, so that this event filter then would be
* the last in the event filter queue and therefore called before the
* one installed by the QDrag object (which then in turn would
* munch all events).
*
** @todo Test this on all supported platforms (X11 works).
*
* Note: On Windows the above hack is not needed because as soon as Qt calls
* OLE's DoDragDrop routine internally (via QtDrag::exec), no mouse
* events will come through anymore. At this point DoDragDrop is modal
* and will take care of all the input handling. */
#ifndef RT_OS_WINDOWS
#endif
#ifdef DEBUG
#endif
}
{
}
{
return m_lstFormats;
}
{
LogFlowFunc(("%s: %RTbool (QtMimeData: %RTbool)\n",
return fRc;
}
{
LogFlowFunc(("m_enmState=%d, mimeType=%s, type=%d\n",
bool fCanDrop = true;
#if 0
#ifdef RT_OS_WINDOWS
if (fLeftBtnDown)
# ifdef DEBUG_andy
LogFlowFunc(("mouseButtons=0x%x, GetAsyncKeyState(VK_LBUTTON)=%RTbool\n",
# endif
#endif
#endif
#ifdef RT_OS_WINDOWS
/* On Windows we only will get into this function if OLE's DoDragDrop
* routine (called by QtDrag) decides that a drop event just happened.
* So just update our internal state to reflect the same as on other
* platforms. */
#else
/* Mouse button released? See eventFilter for more information. */
if (m_enmState != Dropped)
fCanDrop = false;
#endif
#if defined (RT_OS_WINDOWS) || defined (RT_OS_MACOS)
/* Special MIME handling. Later. */
#endif
/* Do we support the requested MIME type? */
if ( fCanDrop
{
LogFlowFunc(("Unsupported MIME type=%s\n",
fCanDrop = false;
}
/* Supported types. See below in the switch statement. */
if ( fCanDrop
&& !( /* Regular text. */
/* Binary data. */
/* URI list. */
{
LogFlowFunc(("Unsupported data type=%d (%s)\n",
fCanDrop = false;
}
if (!fCanDrop)
{
LogFlowFunc(("Skipping request, m_enmState=%d ...\n",
m_enmState));
return QVariant();
}
/* Start getting the data from the guest. First inform the guest we
* want the data in the specified MIME type. */
{
if (!progress.GetCanceled())
{
&& progress.GetResultCode() == 0)
{
/** @todo What about retrieving bigger files? Loop? */
/* After the data successfully arrived from the guest, we query it from Main. */
{
switch (type)
{
{
break;
}
{
break;
}
{
/** @todo Support URIs. */
break;
}
default:
AssertMsgFailed(("Should never happen, d'oh!\n"));
break;
}
}
/** @todo How often to retry on empty data received? */
}
else
}
else
}
else
return m_data;
}
#ifndef RT_OS_WINDOWS
{
if (pEvent)
{
{
#ifdef DEBUG_andy
{
LogFlowFunc(("MouseMove: x=%d, y=%d, buttons=0x%x\n",
break;
}
#endif
case QEvent::MouseButtonRelease:
{
LogFlowFunc(("MouseButtonRelease\n"));
break;
}
{
/* ESC pressed? */
{
LogFlowFunc(("ESC pressed, cancelling drag'n drop operation\n"));
}
break;
}
default:
break;
}
}
/* Propagate the event further. */
return false;
}
void UIDnDMimeData::sltInstallEventFilter(void)
{
LogFlowFunc(("Installing event filter ...\n"));
qApp->installEventFilter(this);
}
#endif /* RT_OS_WINDOWS */