Changeset 55821 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- May 12, 2015 11:43:14 AM (10 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r55477 r55821 5 5 6 6 # 7 # Copyright (C) 2006-201 4Oracle Corporation7 # Copyright (C) 2006-2015 Oracle Corporation 8 8 # 9 9 # This file is part of VirtualBox Open Source Edition (OSE), as … … 474 474 ifdef VBOX_WITH_DRAG_AND_DROP_GH 475 475 VirtualBox_QT_MOCHDRS += \ 476 src/runtime/UIDnDMIMEData.h \ 477 src/runtime/UIDnDDrag.h 476 src/runtime/UIDnDMIMEData.h 478 477 endif 479 478 endif … … 800 799 ifdef VBOX_WITH_DRAG_AND_DROP_GH 801 800 VirtualBox_SOURCES += \ 802 src/runtime/UIDnDMIMEData.cpp \ 803 src/runtime/UIDnDDrag.cpp 801 src/runtime/UIDnDMIMEData.cpp 804 802 VirtualBox_SOURCES.win += \ 805 803 src/runtime/UIDnDDropSource_win.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.cpp
r52730 r55821 35 35 #include <QStringList> 36 36 37 #include "UIDnDHandler.h" 37 38 #include "UIDnDDataObject_win.h" 38 39 #include "UIDnDEnumFormat_win.h" 39 40 40 41 41 UIDnDDataObject::UIDnDDataObject(CSession &session, 42 CDnDSource &dndSource, 43 const QStringList &lstFormats, 44 QWidget *pParent) 45 : mSession(session), 46 mDnDSource(dndSource), 47 mpParent(pParent), 48 mStatus(Uninitialized), 49 mRefCount(1), 50 mcFormats(0), 51 mpFormatEtc(NULL), 52 mpStgMedium(NULL), 53 mpvData(NULL), 54 mcbData(0) 42 UIDnDDataObject::UIDnDDataObject(UIDnDHandler *pDnDHandler, const QStringList &lstFormats) 43 : m_pDnDHandler(pDnDHandler) 44 , mStatus(Uninitialized) 45 , mRefCount(1) 46 , mcFormats(0) 47 , mpFormatEtc(NULL) 48 , mpStgMedium(NULL) 49 , mpvData(NULL) 50 , mcbData(0) 55 51 { 56 52 HRESULT hr; … … 98 94 } 99 95 100 Log FlowFunc(("Total registered native formats: %RU32 (for %d formats from guest)\n",101 96 LogRel3(("DnD: Total registered native formats: %RU32 (for %d formats from guest)\n", 97 cRegisteredFormats, lstFormats.size())); 102 98 hr = S_OK; 103 99 } … … 208 204 AssertPtrReturn(pMedium, DV_E_FORMATETC); 209 205 210 #ifdef VBOX_DND_DEBUG_FORMATS211 206 LogFlowFunc(("pFormatEtc=%p, pMedium=%p\n", pFormatEtc, pMedium)); 212 #endif213 207 214 208 ULONG lIndex; … … 229 223 if (mStatus == Dropping) 230 224 { 225 LogRel3(("DnD: Dropping\n")); 231 226 LogFlowFunc(("Waiting for event ...\n")); 232 227 int rc2 = RTSemEventWait(mSemEvent, RT_INDEFINITE_WAIT); … … 236 231 if (mStatus == Dropped) 237 232 { 238 LogFlowFunc(("cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n", 239 pThisFormat->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 240 pThisFormat->tymed, pThisFormat->dwAspect)); 241 LogFlowFunc(("Got strFormat=%s, pvData=%p, cbData=%RU32\n", 242 mstrFormat.toAscii().constData(), mpvData, mcbData)); 233 LogRel3(("DnD: Dropped\n")); 234 LogRel3(("DnD: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n", 235 pThisFormat->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 236 pThisFormat->tymed, pThisFormat->dwAspect)); 237 LogRel3(("DnD: Got strFormat=%s, pvData=%p, cbData=%RU32\n", 238 mstrFormat.toAscii().constData(), mpvData, mcbData)); 243 239 244 240 QVariant::Type vaType; … … 286 282 } 287 283 #endif 288 LogFlowFunc(("strMIMEType=%s, vaType=%ld\n", 289 strMIMEType.toAscii().constData(), vaType)); 284 LogRel3(("DnD: strMIMEType=%s, vaType=%ld\n", strMIMEType.toAscii().constData(), vaType)); 290 285 291 286 int rc; 292 287 if (!mVaData.isValid()) 293 288 { 294 rc = UIDnDDrag::RetrieveData(mSession, 295 mDnDSource, 296 /** @todo Support other actions. */ 297 Qt::CopyAction, 298 strMIMEType, vaType, mVaData, 299 mpParent); 289 /* Note: We're usig Qt::MoveAction because this speed up the whole operation 290 * significantly: Instead of copying the data from the temporary location to 291 * the final destination we just move it. 292 * 293 * Note2: The Qt::MoveAction *only* affects the behavior on the host! The desired 294 * action for the guest (e.g. moving a file from guest to host) is not affected 295 * by this setting. */ 296 rc = m_pDnDHandler->retrieveData(Qt::MoveAction, 297 strMIMEType, vaType, mVaData); 300 298 } 301 299 else … … 652 650 && pFormatEtc->dwAspect == mpFormatEtc[i].dwAspect) 653 651 { 654 #ifdef VBOX_DND_DEBUG_FORMATS 655 LogFlowFunc(("Format found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32, ulIndex=%RU32\n", 656 pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(mpFormatEtc[i].cfFormat), 657 pFormatEtc->dwAspect, i)); 658 #endif 652 LogRel3(("DnD: Format found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32, ulIndex=%RU32\n", 653 pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(mpFormatEtc[i].cfFormat), 654 pFormatEtc->dwAspect, i)); 655 659 656 if (puIndex) 660 657 *puIndex = i; … … 663 660 } 664 661 665 #ifdef VBOX_DND_DEBUG_FORMATS 666 LogFlowFunc(("Format NOT found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32\n", 667 pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 668 pFormatEtc->dwAspect)); 669 #endif 662 LogRel3(("DnD: Format NOT found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32\n", 663 pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 664 pFormatEtc->dwAspect)); 665 670 666 return false; 671 667 } -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.h
r52727 r55821 31 31 32 32 /* Forward declarations: */ 33 class UIDnD Drag;33 class UIDnDHandler; 34 34 35 35 class UIDnDDataObject : public IDataObject … … 48 48 public: 49 49 50 UIDnDDataObject( CSession &session, CDnDSource &dndSource, const QStringList &lstFormats, QWidget *pParent);50 UIDnDDataObject(UIDnDHandler *pDnDHandler, const QStringList &lstFormats); 51 51 virtual ~UIDnDDataObject(void); 52 52 … … 84 84 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL); 85 85 86 QWidget *mpParent; 87 CSession mSession; 88 CDnDSource mDnDSource; 89 Status mStatus; 90 LONG mRefCount; 91 /** Number of native formats registered. This 92 * can be a different number than supplied with 93 * mlstFormats. */ 94 ULONG mcFormats; 95 FORMATETC *mpFormatEtc; 96 STGMEDIUM *mpStgMedium; 97 RTSEMEVENT mSemEvent; 98 QStringList mlstFormats; 99 QString mstrFormat; 100 /** The retrieved data as a QVariant. Needed 101 * for buffering in case a second format needs 102 * the same data, e.g. CF_TEXT and CF_UNICODETEXT. */ 103 QVariant mVaData; 86 UIDnDHandler *m_pDnDHandler; 87 88 Status mStatus; 89 LONG mRefCount; 90 /** Number of native formats registered. This can be a different number than supplied with mlstFormats. */ 91 ULONG mcFormats; 92 FORMATETC *mpFormatEtc; 93 STGMEDIUM *mpStgMedium; 94 RTSEMEVENT mSemEvent; 95 QStringList mlstFormats; 96 QString mstrFormat; 97 /** The retrieved data as a QVariant. Needed for buffering in case a second format needs the same data, 98 * e.g. CF_TEXT and CF_UNICODETEXT. */ 99 QVariant mVaData; 104 100 /** The retrieved data as a raw buffer. */ 105 void *mpvData;101 void *mpvData; 106 102 /** Raw buffer size (in bytes). */ 107 uint32_t mcbData;103 uint32_t mcbData; 108 104 }; 109 105 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDropSource_win.h
r52727 r55821 5 5 6 6 /* 7 * Copyright (C) 2014 Oracle Corporation7 * Copyright (C) 2014-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 46 46 protected: 47 47 48 LONG mRefCount;49 QWidget *mpParent;50 DWORD mdwCurEffect;51 Qt::DropActions muCurAction;48 LONG mRefCount; 49 QWidget *mpParent; 50 DWORD mdwCurEffect; 51 Qt::DropActions muCurAction; 52 52 }; 53 53 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp
r55546 r55821 21 21 22 22 /* Qt includes: */ 23 # include <QApplication> 24 # include <QKeyEvent> 25 # include <QStringList> 26 # include <QTimer> 27 # include <QUrl> 23 #include <QApplication> 24 #include <QKeyEvent> 25 #include <QStringList> 26 #include <QTimer> 27 #include <QUrl> 28 29 /* VirtualBox interface declarations: */ 30 #ifndef VBOX_WITH_XPCOM 31 # include "VirtualBox.h" 32 #else /* !VBOX_WITH_XPCOM */ 33 # include "VirtualBox_XPCOM.h" 34 #endif /* VBOX_WITH_XPCOM */ 28 35 29 36 /* GUI includes: */ … … 31 38 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 32 39 # include "CDnDSource.h" 33 # include "UIDnDDrag.h" 34 #endif 35 # include "UIMessageCenter.h" 40 # ifdef RT_OS_WINDOWS 41 # include "UIDnDDataObject_win.h" 42 # include "UIDnDDropSource_win.h" 43 # endif 44 # include "UIDnDMIMEData.h" 45 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 46 #include "UIMessageCenter.h" 47 #include "UISession.h" 36 48 37 49 /* COM includes: */ 38 50 # include "CConsole.h" 39 # include "CDnDTarget.h"40 51 # include "CGuest.h" 52 # include "CGuestDnDSource.h" 53 # include "CGuestDnDTarget.h" 41 54 # include "CSession.h" 42 55 … … 50 63 51 64 52 UIDnDHandler *UIDnDHandler::m_pInstance = NULL; 53 54 UIDnDHandler::UIDnDHandler(void) 65 UIDnDHandler::UIDnDHandler(UISession *pSession, QWidget *pParent) 66 : m_pSession(pSession) 67 , m_pParent(pParent) 68 , m_enmMode(DNDMODE_UNKNOWN) 69 , m_fIsPending(false) 70 #ifndef RT_OS_WINDOWS 71 , m_pMIMEData(NULL) 72 #endif 73 { 74 AssertPtr(pSession); 75 m_dndSource = static_cast<CDnDSource>(pSession->guest().GetDnDSource()); 76 m_dndTarget = static_cast<CDnDTarget>(pSession->guest().GetDnDTarget()); 77 } 78 79 UIDnDHandler::~UIDnDHandler(void) 55 80 { 56 81 } … … 60 85 */ 61 86 62 Qt::DropAction UIDnDHandler::dragEnter( CDnDTarget &dndTarget, ulong screenId, int x, int y,87 Qt::DropAction UIDnDHandler::dragEnter(ulong screenID, int x, int y, 63 88 Qt::DropAction proposedAction, Qt::DropActions possibleActions, 64 const QMimeData *pMimeData, QWidget * /* pParent = NULL */) 65 { 66 LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n", 67 screenId, x, y, toVBoxDnDAction(proposedAction))); 89 const QMimeData *pMimeData) 90 { 91 LogFlowFunc(("enmMode=%RU32, screenID=%RU32, x=%d, y=%d, action=%ld\n", 92 m_enmMode, screenID, x, y, toVBoxDnDAction(proposedAction))); 93 94 if (m_enmMode != DNDMODE_UNKNOWN) 95 return Qt::IgnoreAction; 68 96 69 97 /* Ask the guest for starting a DnD event. */ 70 KDnDAction result = dndTarget.Enter(screenId, 71 x, 72 y, 73 toVBoxDnDAction(proposedAction), 74 toVBoxDnDActions(possibleActions), 75 pMimeData->formats().toVector()); 98 KDnDAction result = m_dndTarget.Enter(screenID, 99 x, 100 y, 101 toVBoxDnDAction(proposedAction), 102 toVBoxDnDActions(possibleActions), 103 pMimeData->formats().toVector()); 104 if (result != KDnDAction_Ignore) 105 m_enmMode = DNDMODE_HOSTTOGUEST; 76 106 77 107 /* Set the DnD action returned by the guest. */ … … 79 109 } 80 110 81 Qt::DropAction UIDnDHandler::dragMove( CDnDTarget &dndTarget, ulong screenId, int x, int y,111 Qt::DropAction UIDnDHandler::dragMove(ulong screenID, int x, int y, 82 112 Qt::DropAction proposedAction, Qt::DropActions possibleActions, 83 const QMimeData *pMimeData, QWidget * /* pParent = NULL */) 84 { 85 #ifdef DEBUG_andy 86 LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n", 87 screenId, x, y, toVBoxDnDAction(proposedAction))); 88 #endif 113 const QMimeData *pMimeData) 114 { 115 LogFlowFunc(("enmMode=%RU32, screenID=%RU32, x=%d, y=%d, action=%ld\n", 116 m_enmMode, screenID, x, y, toVBoxDnDAction(proposedAction))); 117 118 if (m_enmMode != DNDMODE_HOSTTOGUEST) 119 return Qt::IgnoreAction; 89 120 90 121 /* Notify the guest that the mouse has been moved while doing 91 122 * a drag'n drop operation. */ 92 KDnDAction result = dndTarget.Move(screenId,93 x,94 y,95 toVBoxDnDAction(proposedAction),96 toVBoxDnDActions(possibleActions),97 pMimeData->formats().toVector());123 KDnDAction result = m_dndTarget.Move(screenID, 124 x, 125 y, 126 toVBoxDnDAction(proposedAction), 127 toVBoxDnDActions(possibleActions), 128 pMimeData->formats().toVector()); 98 129 /* Set the DnD action returned by the guest. */ 99 130 return toQtDnDAction(result); 100 131 } 101 132 102 Qt::DropAction UIDnDHandler::dragDrop(CSession &session, CDnDTarget &dndTarget, 103 ulong screenId, int x, int y, 133 Qt::DropAction UIDnDHandler::dragDrop(ulong screenID, int x, int y, 104 134 Qt::DropAction proposedAction, Qt::DropActions possibleActions, 105 const QMimeData *pMimeData, QWidget *pParent /* = NULL */) 106 { 107 CGuest guest = session.GetConsole().GetGuest(); 108 109 LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n", 110 screenId, x, y, toVBoxDnDAction(proposedAction))); 135 const QMimeData *pMimeData) 136 { 137 LogFlowFunc(("enmMode=%RU32, screenID=%RU32, x=%d, y=%d, action=%ld\n", 138 m_enmMode, screenID, x, y, toVBoxDnDAction(proposedAction))); 139 140 if (m_enmMode != DNDMODE_HOSTTOGUEST) 141 return Qt::IgnoreAction; 111 142 112 143 /* The format the guest requests. */ 113 144 QString format; 114 145 /* Ask the guest for dropping data. */ 115 KDnDAction result = dndTarget.Drop(screenId,116 x,117 y,118 toVBoxDnDAction(proposedAction),119 toVBoxDnDActions(possibleActions),120 pMimeData->formats().toVector(), format);146 KDnDAction result = m_dndTarget.Drop(screenID, 147 x, 148 y, 149 toVBoxDnDAction(proposedAction), 150 toVBoxDnDActions(possibleActions), 151 pMimeData->formats().toVector(), format); 121 152 /* Has the guest accepted the drop event? */ 122 153 if (result != KDnDAction_Ignore) … … 132 163 memcpy(dv.data(), d.constData(), d.size()); 133 164 134 CProgress progress = dndTarget.SendData(screenId, format, dv);135 136 if ( dndTarget.isOk())165 CProgress progress = m_dndTarget.SendData(screenID, format, dv); 166 167 if (m_dndTarget.isOk()) 137 168 { 138 169 LogFlowFunc(("Transferring data to guest ...\n")); … … 140 171 msgCenter().showModalProgressDialog(progress, 141 172 tr("Dropping data ..."), ":/progress_dnd_hg_90px.png", 142 pParent);173 m_pParent); 143 174 144 175 LogFlowFunc(("Transfer fCompleted=%RTbool, fCanceled=%RTbool, hr=%Rhrc\n", … … 150 181 || progress.GetResultCode() != 0)) 151 182 { 152 msgCenter().cannotDropDataToGuest(progress, pParent);183 msgCenter().cannotDropDataToGuest(progress, m_pParent); 153 184 result = KDnDAction_Ignore; 154 185 } … … 156 187 else 157 188 { 158 msgCenter().cannotDropDataToGuest( dndTarget,pParent);189 msgCenter().cannotDropDataToGuest(m_dndTarget, m_pParent); 159 190 result = KDnDAction_Ignore; 160 191 } … … 165 196 } 166 197 167 void UIDnDHandler::dragLeave(CDnDTarget &dndTarget, 168 ulong screenId, QWidget * /* pParent = NULL */) 169 { 170 LogFlowFunc(("screenId=%RU32\n", screenId)); 171 dndTarget.Leave(screenId); 198 void UIDnDHandler::dragLeave(ulong screenID) 199 { 200 LogFlowFunc(("enmMode=%RU32, screenID=%RU32\n", m_enmMode, screenID)); 201 m_dndTarget.Leave(screenID); 202 203 if (m_enmMode == DNDMODE_HOSTTOGUEST) 204 m_enmMode = DNDMODE_UNKNOWN; 172 205 } 173 206 … … 176 209 */ 177 210 178 int UIDnDHandler::dragIsPending(CSession &session, CDnDSource &dndSource, 179 ulong screenId, QWidget *pParent /* = NULL */) 211 int UIDnDHandler::dragStart(const QStringList &lstFormats, 212 Qt::DropAction defAction, Qt::DropActions actions) 213 { 214 m_lstFormats = lstFormats; 215 m_defAction = defAction; 216 m_actions = actions; 217 218 LogFlowFunc(("m_defAction=0x%x\n", m_defAction)); 219 LogFlowFunc(("Number of formats: %d\n", m_lstFormats.size())); 220 #ifdef DEBUG 221 for (int i = 0; i < m_lstFormats.size(); i++) 222 LogFlowFunc(("\tFormat %d: %s\n", i, m_lstFormats.at(i).toAscii().constData())); 223 #endif 224 225 int rc = VINF_SUCCESS; 226 227 #ifdef RT_OS_WINDOWS 228 229 UIDnDDropSource *pDropSource = new UIDnDDropSource(m_pParent); 230 if (!pDropSource) 231 return VERR_NO_MEMORY; 232 UIDnDDataObject *pDataObject = new UIDnDDataObject(this, m_lstFormats); 233 if (!pDataObject) 234 return VERR_NO_MEMORY; 235 236 DWORD dwOKEffects = DROPEFFECT_NONE; 237 if (m_actions) 238 { 239 if (m_actions & Qt::CopyAction) 240 dwOKEffects |= DROPEFFECT_COPY; 241 if (m_actions & Qt::MoveAction) 242 dwOKEffects |= DROPEFFECT_MOVE; 243 if (m_actions & Qt::LinkAction) 244 dwOKEffects |= DROPEFFECT_LINK; 245 } 246 247 DWORD dwEffect; 248 LogRel3(("DnD: dwOKEffects=0x%x\n", dwOKEffects)); 249 HRESULT hr = ::DoDragDrop(pDataObject, pDropSource, dwOKEffects, &dwEffect); 250 LogRel3(("DnD: DoDragDrop ended with hr=%Rhrc, dwEffect=%RI32\n", hr, dwEffect)); 251 252 if (pDropSource) 253 pDropSource->Release(); 254 if (pDataObject) 255 pDataObject->Release(); 256 257 #else /* !RT_OS_WINDOWS */ 258 259 QDrag *pDrag = new QDrag(m_pParent); 260 if (!pDrag) 261 return VERR_NO_MEMORY; 262 263 /* Note: pMData is transferred to the QDrag object, so no need for deletion. */ 264 m_pMIMEData = new UIDnDMIMEData(this, m_lstFormats, m_defAction, m_actions); 265 if (!m_pMIMEData) 266 { 267 delete pDrag; 268 return VERR_NO_MEMORY; 269 } 270 271 /* Inform the MIME data object of any changes in the current action. */ 272 connect(pDrag, SIGNAL(actionChanged(Qt::DropAction)), 273 m_pMIMEData, SLOT(sltDropActionChanged(Qt::DropAction))); 274 275 /* 276 * Set MIME data object and start the (modal) drag'n drop operation on the host. 277 * This does not block Qt's event loop, however (on Windows it would). 278 */ 279 pDrag->setMimeData(m_pMIMEData); 280 Qt::DropAction dropAction = pDrag->exec(m_actions, m_defAction); 281 LogRel3(("DnD: Ended with dropAction=%ld\n", UIDnDHandler::toVBoxDnDAction(dropAction))); 282 283 /* Note: The UIDnDMimeData object will not be not accessible here anymore, 284 * since QDrag had its ownership and deleted it after the (blocking) 285 * QDrag::exec() call. */ 286 287 /* pDrag will be cleaned up by Qt automatically. */ 288 289 #endif /* !RT_OS_WINDOWS */ 290 291 LogFlowFuncLeaveRC(rc); 292 return rc; 293 } 294 295 int UIDnDHandler::dragIsPending(ulong screenID) 180 296 { 181 297 int rc; 182 298 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 183 /* 299 300 LogFlowFunc(("enmMode=%RU32, m_fIsPending=%RTbool, screenID=%RU32\n", m_enmMode, m_fIsPending, screenID)); 301 302 { 303 QMutexLocker AutoReadLock(&m_ReadLock); 304 305 if (m_enmMode != DNDMODE_UNKNOWN) /* Wrong mode set? */ 306 return VINF_SUCCESS; 307 308 if (m_fIsPending) /* Pendig operation is in progress. */ 309 return VINF_SUCCESS; 310 } 311 312 QMutexLocker AutoWriteLock(&m_ReadLock); 313 m_fIsPending = true; 314 AutoWriteLock.unlock(); 315 316 /** 184 317 * How this works: Source is asking the target if there is any DnD 185 318 * operation pending, when the mouse leaves the guest window. On … … 187 320 * (or defaultAction is KDnDAction_Ignore if not). With 188 321 * this information we create a Qt QDrag object with our own QMimeType 189 * implementation and call exec. Please note, this *blocks* until the DnD 190 * operation has finished. 322 * implementation and call exec. 323 * 324 * Note: This function *blocks* until the actual drag'n drop operation 325 * has been finished (successfully or not)! 191 326 */ 192 CGuest guest = session.GetConsole().GetGuest(); 327 CGuest guest = m_pSession->guest(); 328 193 329 QVector<QString> vecFmtGuest; 194 330 QVector<KDnDAction> vecActions; 195 KDnDAction defaultAction = dndSource.DragIsPending(screenId, vecFmtGuest, vecActions);331 KDnDAction defaultAction = m_dndSource.DragIsPending(screenID, vecFmtGuest, vecActions); 196 332 LogFlowFunc(("defaultAction=%d, numFormats=%d\n", defaultAction, vecFmtGuest.size())); 197 333 … … 199 335 if (defaultAction != KDnDAction_Ignore) 200 336 { 201 /* 337 /** 202 338 * Do guest -> host format conversion, if needed. 203 339 * On X11 this already maps to the Xdnd protocol. … … 206 342 * See: https://www.iana.org/assignments/media-types/media-types.xhtml 207 343 */ 208 Log FlowFunc(("Number of guest formats: %d\n", vecFmtGuest.size()));344 LogRel3(("DnD: Number of guest formats: %d\n", vecFmtGuest.size())); 209 345 for (int i = 0; i < vecFmtGuest.size(); i++) 210 346 { 211 347 const QString &strFmtGuest = vecFmtGuest.at(i); 212 LogFlowFunc(("\tFormat %d: %s\n", i, 213 strFmtGuest.toAscii().constData())); 348 LogRel3(("\tFormat %d: %s\n", i, strFmtGuest.toAscii().constData())); 214 349 # ifdef RT_OS_WINDOWS 215 /* CF_TEXT */350 /* CF_TEXT -> Regular text. */ 216 351 if ( strFmtGuest.contains("text/plain", Qt::CaseInsensitive) 217 352 && !lstFmtNative.contains("text/plain")) … … 219 354 lstFmtNative << "text/plain"; 220 355 } 221 /* CF_HDROP */356 /* CF_HDROP -> URI list. */ 222 357 else if ( strFmtGuest.contains("text/uri-list", Qt::CaseInsensitive) 223 358 && !lstFmtNative.contains("text/uri-list")) … … 225 360 lstFmtNative << "text/uri-list"; 226 361 } 227 # else 362 # else /* RT_OS_WINDOWS */ 363 228 364 /* On non-Windows just do a 1:1 mapping. */ 229 365 lstFmtNative << strFmtGuest; 230 366 # ifdef RT_OS_MACOS 231 /** @todo Does the mapping apply here? Don't think so ...*/367 /** @todo Does the 1:1 format mapping apply on OS X? Needs testing! */ 232 368 # endif 369 233 370 # endif /* !RT_OS_WINDOWS */ 234 371 } 235 372 236 LogFlowFunc(("Number of native formats: %d\n", lstFmtNative.size())); 237 # ifdef DEBUG 373 LogRel3(("DnD: Number of native formats: %d\n", lstFmtNative.size())); 238 374 for (int i = 0; i < lstFmtNative.size(); i++) 239 LogFlowFunc(("\tFormat %d: %s\n", i, lstFmtNative.at(i).toAscii().constData())); 240 # endif 375 LogRel3(("\tFormat %d: %s\n", i, lstFmtNative.at(i).toAscii().constData())); 241 376 } 242 377 243 378 if (!lstFmtNative.isEmpty()) 244 379 { 245 UIDnDDrag *pDrag = new UIDnDDrag(session, dndSource, lstFmtNative, 246 toQtDnDAction(defaultAction), 247 toQtDnDActions(vecActions), pParent); 248 if (pDrag) 249 { 250 rc = pDrag->DoDragDrop(); 251 delete pDrag; 252 } 253 else 254 rc = VERR_NO_MEMORY; 380 rc = dragStart(lstFmtNative, 381 toQtDnDAction(defaultAction), toQtDnDActions(vecActions)); 255 382 } 256 383 else /* No format data from the guest arrived yet. */ 257 384 rc = VERR_NO_DATA; 385 386 AutoWriteLock.relock(); 387 m_fIsPending = false; 388 AutoWriteLock.unlock(); 389 258 390 #else /* !VBOX_WITH_DRAG_AND_DROP_GH */ 259 NOREF(dndSource); 260 NOREF(session); 261 NOREF(screenId); 262 NOREF(pParent); 391 392 NOREF(screenID); 263 393 264 394 rc = VERR_NOT_SUPPORTED; 395 265 396 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 397 398 LogFlowFuncLeaveRC(rc); 399 return rc; 400 } 401 402 /** 403 * Called by UIDnDMIMEData (Linux, OS X, Solaris) or UIDnDDataObject (Windows) 404 * to start retrieving the actual data from the guest. This function will block 405 * and show a modal progress dialog until the data transfer is complete. 406 * 407 * @return IPRT return code. 408 * @param dropAction Drop action to perform. 409 * @param strMimeType MIME data type. 410 * @param vaType Qt's variant type of the MIME data. 411 * @param vaData The actual MIME data. 412 * @param pParent Pointer to parent widget. 413 */ 414 int UIDnDHandler::retrieveData( Qt::DropAction dropAction, 415 const QString &strMimeType, 416 QVariant::Type vaType, 417 QVariant &vaData) 418 { 419 LogFlowFunc(("Retrieving data as type=%s (variant type=%ld)\n", 420 strMimeType.toAscii().constData(), vaType)); 421 422 int rc = VINF_SUCCESS; 423 424 /* Start getting the data from the source. Request and transfer data 425 * from the source and display a modal progress dialog while doing this. */ 426 Assert(!m_dndSource.isNull()); 427 CProgress progress = m_dndSource.Drop(strMimeType, 428 UIDnDHandler::toVBoxDnDAction(dropAction)); 429 if (m_dndSource.isOk()) 430 { 431 msgCenter().showModalProgressDialog(progress, 432 tr("Retrieving data ..."), ":/progress_dnd_gh_90px.png", 433 m_pParent); 434 435 LogFlowFunc(("fCanceled=%RTbool, fCompleted=%RTbool, isOk=%RTbool, hrc=%Rhrc\n", 436 progress.GetCanceled(), progress.GetCompleted(), progress.isOk(), progress.GetResultCode())); 437 438 if (!progress.GetCanceled()) 439 { 440 rc = ( progress.isOk() 441 && progress.GetResultCode() == 0) 442 ? VINF_SUCCESS : VERR_GENERAL_FAILURE; /** @todo Fudge; do a GetResultCode() to rc translation. */ 443 444 if (RT_SUCCESS(rc)) 445 { 446 /* After we successfully retrieved data from the source we query it from Main. */ 447 QVector<uint8_t> vecData = m_dndSource.ReceiveData(); 448 if (!vecData.isEmpty()) 449 { 450 switch (vaType) 451 { 452 case QVariant::String: 453 { 454 vaData = QVariant(QString(reinterpret_cast<const char*>(vecData.constData()))); 455 break; 456 } 457 458 case QVariant::ByteArray: 459 { 460 QByteArray ba(reinterpret_cast<const char*>(vecData.constData()), vecData.size()); 461 vaData = QVariant(ba); 462 break; 463 } 464 465 case QVariant::StringList: 466 { 467 QString strData = QString(reinterpret_cast<const char*>(vecData.constData())); 468 QStringList lstString = strData.split("\r\n", QString::SkipEmptyParts); 469 470 vaData = QVariant(lstString); 471 break; 472 } 473 474 default: 475 rc = VERR_NOT_SUPPORTED; 476 break; 477 } 478 } 479 else 480 rc = VERR_NO_DATA; 481 } 482 else 483 msgCenter().cannotDropDataToHost(progress, m_pParent); 484 } 485 else /* Don't pop up a message. */ 486 rc = VERR_CANCELLED; 487 } 488 else 489 { 490 msgCenter().cannotDropDataToHost(m_dndSource, m_pParent); 491 rc = VERR_GENERAL_FAILURE; /** @todo Fudge; do a GetResultCode() to rc translation. */ 492 } 266 493 267 494 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.h
r52727 r55821 5 5 6 6 /* 7 * Copyright (C) 2011-201 4Oracle Corporation7 * Copyright (C) 2011-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 #define ___UIDnDHandler_h___ 20 20 21 /* Qt includes: */ 22 #include <QMimeData> 23 #include <QMutex> 24 #include <QStringList> 25 21 26 /* COM includes: */ 22 27 #include "COMEnums.h" 28 #include "CDnDTarget.h" 29 #include "CDnDSource.h" 23 30 24 31 /* Forward declarations: */ 25 32 class QMimeData; 26 class CDnDSource; 27 class CDnDTarget; 28 class CGuest; 29 class CSession; 30 class UIDnDMimeData; 33 34 class UIDnDMIMEData; 35 class UISession; 31 36 32 37 class UIDnDHandler: public QObject … … 36 41 public: 37 42 38 /* Singleton factory. */ 39 static UIDnDHandler *instance(void) 40 { 41 if (!m_pInstance) 42 m_pInstance = new UIDnDHandler(); 43 return m_pInstance; 44 } 45 46 static void destroy(void) 47 { 48 if (m_pInstance) 49 { 50 delete m_pInstance; 51 m_pInstance = NULL; 52 } 53 } 43 UIDnDHandler(UISession *pSession, QWidget *pParent); 44 virtual ~UIDnDHandler(void); 54 45 55 46 /** 56 47 * Current operation mode. 57 48 */ 58 enum Direction49 typedef enum DNDMODE 59 50 { 60 51 /** Unknown mode. */ 61 Unknown= 0,52 DNDMODE_UNKNOWN = 0, 62 53 /** Host to guest. */ 63 HostToGuest,54 DNDMODE_HOSTTOGUEST = 1, 64 55 /** Guest to host. */ 65 GuestToHost56 DNDMODE_GUESTTOHOST = 2, 66 57 /** @todo Implement guest to guest. */ 67 }; 58 /** The usual 32-bit type blow up. */ 59 DNDMODE_32BIT_HACK = 0x7fffffff 60 } DNDMODE; 68 61 69 62 /* Frontend -> Target. */ 70 Qt::DropAction dragEnter( CDnDTarget &dndTarget, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = NULL);71 Qt::DropAction dragMove ( CDnDTarget &dndTarget, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = NULL);72 Qt::DropAction dragDrop ( CSession &session, CDnDTarget &dndTarget, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = NULL);73 void dragLeave( CDnDTarget &dndTarget, ulong screenId, QWidget *pParent = NULL);63 Qt::DropAction dragEnter(ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData); 64 Qt::DropAction dragMove (ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData); 65 Qt::DropAction dragDrop (ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData); 66 void dragLeave(ulong screenId); 74 67 75 68 /* Source -> Frontend. */ 76 int dragIsPending(CSession &session, CDnDSource &dndSource, ulong screenId, QWidget *pParent = NULL); 69 int dragIsPending(ulong screenId); 70 int dragStart(const QStringList &lstFormats, Qt::DropAction defAction, Qt::DropActions actions); 71 int retrieveData(Qt::DropAction dropAction, const QString &strMimeType, QVariant::Type vaType, QVariant &vaData); 77 72 78 73 public: … … 83 78 static Qt::DropActions toQtDnDActions(const QVector<KDnDAction> &vecActions); 84 79 85 pr ivate:80 protected: 86 81 87 UIDnDHandler(void); 88 virtual ~UIDnDHandler(void) {} 82 /** Pointer to UI session. */ 83 UISession *m_pSession; 84 /** Pointer to parent widget. */ 85 QWidget *m_pParent; 89 86 90 private: 87 /** Drag and drop source instance. */ 88 CDnDSource m_dndSource; 89 /** Drag and drop target instance. */ 90 CDnDTarget m_dndTarget; 91 /** Current transfer direction. */ 92 DNDMODE m_enmMode; 93 /** Flag indicating if a drag operation is pending currently. */ 94 bool m_fIsPending; 95 QMutex m_ReadLock; 96 QMutex m_WriteLock; 91 97 92 /** Static pointer to singleton instance. */ 93 static UIDnDHandler *m_pInstance; 98 /** List of formats supported by the source. */ 99 QStringList m_lstFormats; 100 /** Default drop action from the source. */ 101 Qt::DropAction m_defAction; 102 /** List of allowed drop actions from the source. */ 103 Qt::DropActions m_actions; 104 105 #ifndef RT_OS_WINDOWS 106 /** Pointer to MIMEData instance used for handling 107 * own MIME times on non-Windows host OSes. */ 108 UIDnDMIMEData *m_pMIMEData; 109 friend class UIDnDMIMEData; 110 #endif 94 111 }; 95 96 /** Gets the singleton instance of the drag'n drop UI helper class. */97 #define DnDHandler() UIDnDHandler::instance()98 99 112 #endif /* ___UIDnDHandler_h___ */ 100 113 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp
r55180 r55821 5 5 6 6 /* 7 * Copyright (C) 2011-201 4Oracle Corporation7 * Copyright (C) 2011-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 /* GUI includes: */ 32 32 # include "UIDnDMIMEData.h" 33 # include "UIDnDDrag.h"34 33 # include "UIMessageCenter.h" 35 34 … … 41 40 42 41 43 UIDnDMimeData::UIDnDMimeData(CSession &session, 44 CDnDSource &dndSource, 45 QStringList formats, 46 Qt::DropAction defAction, Qt::DropActions actions, 47 QWidget *pParent) 48 : m_Session(session) 49 , m_DnDSource(dndSource) 50 , m_lstFormats(formats) 42 UIDnDMIMEData::UIDnDMIMEData(UIDnDHandler *pDnDHandler, 43 QStringList lstFormats, Qt::DropAction defAction, Qt::DropActions actions) 44 : m_pDnDHandler(pDnDHandler) 45 , m_lstFormats(lstFormats) 51 46 , m_defAction(defAction) 52 47 , m_actions(actions) 53 , m_pParent(pParent)54 48 , m_enmState(Dragging) 55 49 , m_vaData(QVariant::Invalid) … … 57 51 LogFlowThisFuncEnter(); 58 52 59 /* 53 #ifdef DEBUG 54 LogFlowFunc(("Number of formats: %d\n", lstFormats.size())); 55 for (int i = 0; i < lstFormats.size(); i++) 56 LogFlowFunc(("\tFormat %d: %s\n", i, lstFormats.at(i).toAscii().constData())); 57 #endif 58 59 /** 60 60 * This is unbelievable hacky, but I didn't find another way. Stupid 61 61 * Qt QDrag interface is so less verbose, that we in principle know … … 83 83 * and will take care of all the input handling. */ 84 84 #ifndef RT_OS_WINDOWS 85 /* Install the event filter in a deferred way. */ 85 86 QTimer::singleShot(0, this, SLOT(sltInstallEventFilter())); 86 87 #endif 87 88 #ifdef DEBUG 89 LogFlowFunc(("Number of formats: %d\n", formats.size())); 90 for (int i = 0; i < formats.size(); i++) 91 LogFlowFunc(("\tFormat %d: %s\n", i, formats.at(i).toAscii().constData())); 92 #endif 93 } 94 95 void UIDnDMimeData::sltDropActionChanged(Qt::DropAction dropAction) 96 { 97 LogFlowFunc(("dropAction=0x%x\n", dropAction)); 98 m_defAction = dropAction; 99 } 100 101 QStringList UIDnDMimeData::formats(void) const 88 } 89 90 QStringList UIDnDMIMEData::formats(void) const 102 91 { 103 92 return m_lstFormats; 104 93 } 105 94 106 bool UIDnDM imeData::hasFormat(const QString &strMIMEType) const95 bool UIDnDMIMEData::hasFormat(const QString &strMIMEType) const 107 96 { 108 97 bool fRc = m_lstFormats.contains(strMIMEType); 109 98 LogFlowFunc(("%s: %RTbool (QtMimeData: %RTbool)\n", 110 strMIMEType.toStdString().c_str(), 111 fRc, QMimeData::hasFormat(strMIMEType))); 99 strMIMEType.toStdString().c_str(), fRc, QMimeData::hasFormat(strMIMEType))); 112 100 return fRc; 113 101 } 114 102 115 QVariant UIDnDMimeData::retrieveData(const QString &strMIMEType, 116 QVariant::Type vaType) 117 { 118 LogFlowFunc(("m_enmState=%d, mimeType=%s, type=%d (%s)\n", 119 m_enmState, strMIMEType.toStdString().c_str(), 103 /** 104 * Called by Qt's drag'n drop operation (QDrag) for retrieving the actual drag'n drop 105 * data in case of a successful drag'n drop operation. 106 * 107 * @param strMIMEType MIME type string. 108 * @param vaType Variant containing the actual data based on the the MIME type. 109 * 110 * @return QVariant 111 */ 112 QVariant UIDnDMIMEData::retrieveData(const QString &strMIMEType, QVariant::Type vaType) const 113 { 114 LogFlowFunc(("state=%RU32, mimeType=%s, type=%d (%s)\n", m_enmState, strMIMEType.toStdString().c_str(), 120 115 vaType, QVariant::typeToName(vaType))); 121 116 … … 139 134 && !m_lstFormats.contains(strMIMEType)) 140 135 { 141 LogFlowFunc(("Unsupported MIME type=%s\n", 142 strMIMEType.toStdString().c_str())); 136 LogRel3(("DnD: Unsupported MIME type=%s\n", strMIMEType.toStdString().c_str())); 143 137 fCanDrop = false; 144 138 } … … 154 148 || vaType == QVariant::List)) 155 149 { 156 LogFlowFunc(("Unsupported data type=%d (%s)\n", 157 vaType, QVariant::typeToName(vaType))); 150 LogRel3(("DnD: Unsupported data type=%d (%s)\n", vaType, QVariant::typeToName(vaType))); 158 151 fCanDrop = false; 159 152 } 160 153 154 LogRel3(("DnD: State=%ld, fCanDrop=%RTbool\n", m_enmState, fCanDrop)); 155 161 156 if (!fCanDrop) 162 157 { 163 LogFlowFunc(("Skipping request, m_enmState=%d ...\n", 164 m_enmState)); 158 LogFlowFunc(("Skipping request, state=%RU32 ...\n", m_enmState)); 165 159 return QMimeData::retrieveData(strMIMEType, vaType); 166 160 } 167 161 168 int rc = VINF_SUCCESS; 169 if (m_enmState == Dropped) 170 { 171 rc = UIDnDDrag::RetrieveData(m_Session, 172 m_DnDSource, 173 m_defAction, 174 strMIMEType, vaType, m_vaData, 175 m_pParent); 176 if (RT_SUCCESS(rc)) 177 { 178 /* Tell ourselves that data became available. */ 179 emit sigDataAvailable(strMIMEType); 180 } 181 else 182 { 183 m_enmState = Canceled; 184 } 185 } 186 187 LogFlowFunc(("Returning rc=%Rrc, m_enmState=%ld\n", 188 rc, m_enmState)); 162 /* Note: The const_cast is used because this function needs to be const (otherwise 163 * Qt won't call it), but we need the stuff in an unconst'ed way. */ 164 int rc = const_cast<UIDnDMIMEData *>(this)->retrieveDataInternal(strMIMEType, vaType); 165 166 LogFlowFunc(("Returning rc=%Rrc, state=%RU32\n", rc, m_enmState)); 189 167 return m_vaData; 190 168 } 191 169 192 170 #ifndef RT_OS_WINDOWS 193 bool UIDnDMimeData::eventFilter(QObject *pObject, QEvent *pEvent) 194 { 171 bool UIDnDMIMEData::eventFilter(QObject *pObject, QEvent *pEvent) 172 { 173 bool fRemoveFilter = false; 174 195 175 if (pEvent) 196 176 { 197 177 switch (pEvent->type()) 198 178 { 199 #ifdef DEBUG_andy200 179 case QEvent::MouseMove: 201 180 { 202 181 QMouseEvent *pMouseEvent = (QMouseEvent*)(pEvent); 203 182 AssertPtr(pMouseEvent); 204 LogFlowFunc(("MouseMove: x=%d, y=%d\n", 205 pMouseEvent->globalX(), pMouseEvent->globalY())); 206 207 return true; 208 /* Never reached. */ 183 LogFlowFunc(("MouseMove: x=%d, y=%d\n", pMouseEvent->globalX(), pMouseEvent->globalY())); 184 185 break; 209 186 } 210 #endif 187 211 188 case QEvent::MouseButtonRelease: 212 189 { … … 214 191 m_enmState = Dropped; 215 192 216 returntrue;217 /* Never reached. */193 fRemoveFilter = true; 194 break; 218 195 } 219 196 … … 223 200 if (static_cast<QKeyEvent*>(pEvent)->key() == Qt::Key_Escape) 224 201 { 225 Log FlowFunc(("ESC pressed, cancelling drag and drop operation\n"));202 LogRel2(("DnD: ESC pressed, cancelling drag and drop operation\n")); 226 203 m_enmState = Canceled; 204 205 fRemoveFilter = true; 227 206 } 228 229 return true; 230 /* Never reached. */ 207 break; 231 208 } 232 209 … … 236 213 } 237 214 215 if (fRemoveFilter) 216 { 217 LogFlowFunc(("Removing event filter ...\n")); 218 AssertPtr(qApp); 219 qApp->removeEventFilter(this); 220 } 221 222 /* Do normal processing by Qt. */ 238 223 return QObject::eventFilter(pObject, pEvent); 239 224 } 240 241 void UIDnDMimeData::sltInstallEventFilter(void) 242 { 243 LogFlowFunc(("Installing event filter ...\n")); 244 AssertPtr(qApp); 245 qApp->installEventFilter(this); 246 } 247 #endif /* RT_OS_WINDOWS */ 248 249 int UIDnDMimeData::setData(const QString &mimeType) 225 #endif /* !RT_OS_WINDOWS */ 226 227 int UIDnDMIMEData::setData(const QString &mimeType) 250 228 { 251 229 LogFlowFunc(("mimeType=%s, dataType=%s\n", … … 275 253 { 276 254 QFileInfo fileInfo(lstData.at(i).toString()); 277 #ifdef DEBUG 255 278 256 LogFlowFunc(("\tURL: %s (fExists=%RTbool, fIsDir=%RTbool, cb=%RU64)\n", 279 257 fileInfo.absoluteFilePath().constData(), fileInfo.exists(), 280 258 fileInfo.isDir(), fileInfo.size())); 281 #endif 259 282 260 lstURL << QUrl::fromLocalFile(fileInfo.absoluteFilePath()); 283 261 } … … 298 276 } 299 277 278 int UIDnDMIMEData::retrieveDataInternal(const QString &strMIMEType, QVariant::Type vaType) 279 { 280 LogFlowFunc(("state=%RU32, mimeType=%s, type=%d (%s)\n", m_enmState, 281 strMIMEType.toStdString().c_str(), vaType, QVariant::typeToName(vaType))); 282 283 AssertPtr(m_pDnDHandler); 284 int rc = m_pDnDHandler->retrieveData(m_defAction, strMIMEType, vaType, m_vaData); 285 if (RT_SUCCESS(rc)) 286 { 287 /* Nothing to do here yet. */ 288 } 289 else if (rc == VERR_CANCELLED) 290 m_enmState = Canceled; 291 else 292 m_enmState = Error; 293 294 LogFlowFuncLeaveRC(rc); 295 return rc; 296 } 297 298 /** 299 * Issued by the QDrag object as soon as the current drop action has changed. 300 * 301 * @param dropAction New drop action to use. 302 */ 303 void UIDnDMIMEData::sltDropActionChanged(Qt::DropAction dropAction) 304 { 305 LogFlowFunc(("dropAction=0x%x\n", dropAction)); 306 m_defAction = dropAction; 307 } 308 309 #ifndef RT_OS_WINDOWS 310 /** 311 * Issued by ourselves to install the event filter. 312 */ 313 void UIDnDMIMEData::sltInstallEventFilter(void) 314 { 315 LogFlowFunc(("Installing event filter ...\n")); 316 AssertPtr(qApp); 317 qApp->installEventFilter(this); 318 } 319 #endif 320 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.h
r52727 r55821 5 5 6 6 /* 7 * Copyright (C) 2011-201 4Oracle Corporation7 * Copyright (C) 2011-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 #include "UIDnDHandler.h" 32 32 33 /* Forward declarations: */34 class UIDnDDrag;35 36 33 /** @todo Subclass QWindowsMime / QMacPasteboardMime 37 34 * to register own/more MIME types. */ … … 41 38 * handling all guest-to-host transfers. 42 39 */ 43 class UIDnDM imeData: public QMimeData40 class UIDnDMIMEData: public QMimeData 44 41 { 45 42 Q_OBJECT; … … 55 52 Dropped, 56 53 /** The operation has been canceled. */ 57 Canceled 54 Canceled, 55 /** An error occurred. */ 56 Error, 57 /** The usual 32-bit type blow up. */ 58 State_32BIT_Hack = 0x7fffffff 58 59 }; 59 60 60 61 public: 61 62 62 UIDnDM imeData(CSession &session, CDnDSource &dndSource, QStringList formats, Qt::DropAction defAction, Qt::DropActions actions, QWidget *pParent);63 UIDnDMIMEData(UIDnDHandler *pDnDHandler, QStringList formats, Qt::DropAction defAction, Qt::DropActions actions); 63 64 64 65 public: … … 77 78 virtual bool hasFormat(const QString &mimeType) const; 78 79 79 virtual QVariant retrieveData(const QString &mimeType, QVariant::Type type) ;80 virtual QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; 80 81 81 82 #ifndef RT_OS_WINDOWS … … 84 85 /** @} */ 85 86 86 signals: 87 int retrieveDataInternal(const QString &strMIMEType, QVariant::Type vaType); 87 88 88 void sigDataAvailable(const QString &mimeType) const; 89 90 private slots: 89 protected slots: 91 90 92 91 #ifndef RT_OS_WINDOWS … … 94 93 #endif 95 94 96 pr ivate:95 protected: 97 96 98 CSession m_Session;99 CDnDSource m_DnDSource; 97 UIDnDHandler *m_pDnDHandler; 98 100 99 QStringList m_lstFormats; 101 100 Qt::DropAction m_defAction; 102 101 Qt::DropActions m_actions; 103 QWidget *m_pParent; 102 104 103 mutable State m_enmState; 105 104 mutable QVariant m_vaData; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r55726 r55821 5 5 6 6 /* 7 * Copyright (C) 2010-201 2Oracle Corporation7 * Copyright (C) 2010-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 101 101 102 102 103 /* static */ 103 104 UIMachineView* UIMachineView::create( UIMachineWindow *pMachineWindow 104 105 , ulong uScreenId … … 163 164 pMachineView->sltMachineStateChanged(); 164 165 /** @todo Can we move the call to sltAdditionsStateChanged() from the 165 * subclass constructors here too? It is called for Normal and Seamless,166 * but not for Fullscreen and Scale. However for Scale it is a no op.,167 * so it would not hurt. Would it hurt for Fullscreen? */166 * subclass constructors here too? It is called for Normal and Seamless, 167 * but not for Fullscreen and Scale. However for Scale it is a no op., 168 * so it would not hurt. Would it hurt for fullscreen? */ 168 169 169 170 /* Set a preliminary maximum size: */ … … 173 174 } 174 175 176 /* static */ 175 177 void UIMachineView::destroy(UIMachineView *pMachineView) 176 178 { 179 if (!pMachineView) 180 return; 181 182 #ifdef VBOX_WITH_DRAG_AND_DROP 183 if (pMachineView->m_pDnDHandler) 184 delete pMachineView->m_pDnDHandler; 185 #endif 177 186 delete pMachineView; 178 187 } … … 675 684 676 685 #ifdef VBOX_WITH_DRAG_AND_DROP 677 /* Enable Drag & Drop. */686 /* Enable drag & drop. */ 678 687 setAcceptDrops(true); 688 689 /* Create the drag and drop handler instance. 690 * At the moment we only support one instance per machine window. */ 691 m_pDnDHandler = new UIDnDHandler(uisession(), this /* pParent */); 679 692 #endif /* VBOX_WITH_DRAG_AND_DROP */ 680 693 } … … 1402 1415 1403 1416 #ifdef VBOX_WITH_DRAG_AND_DROP 1417 /** 1418 * Host -> Guest: Issued when the host cursor enters the guest (VM) window. 1419 * The guest will receive the relative cursor coordinates of the 1420 * appropriate screen ID. 1421 * 1422 * @param pEvent Related enter event. 1423 */ 1404 1424 void UIMachineView::dragEnterEvent(QDragEnterEvent *pEvent) 1405 1425 { … … 1409 1429 const QPoint &cpnt = viewportToContents(pEvent->pos()); 1410 1430 1411 CDnDTarget dndTarget = static_cast<CDnDTarget>(guest().GetDnDTarget());1412 1413 1431 /* Ask the target for starting a DnD event. */ 1414 Qt::DropAction result = DnDHandler()->dragEnter(dndTarget, 1415 screenId(), 1432 Qt::DropAction result = m_pDnDHandler->dragEnter(screenId(), 1433 frameBuffer()->convertHostXTo(cpnt.x()), 1434 frameBuffer()->convertHostYTo(cpnt.y()), 1435 pEvent->proposedAction(), 1436 pEvent->possibleActions(), 1437 pEvent->mimeData()); 1438 1439 /* Set the DnD action returned by the guest. */ 1440 pEvent->setDropAction(result); 1441 pEvent->accept(); 1442 } 1443 1444 /** 1445 * Host -> Guest: Issued when the host cursor moves inside (over) the guest (VM) window. 1446 * The guest will receive the relative cursor coordinates of the 1447 * appropriate screen ID. 1448 * 1449 * @param pEvent Related move event. 1450 */ 1451 void UIMachineView::dragMoveEvent(QDragMoveEvent *pEvent) 1452 { 1453 AssertPtrReturnVoid(pEvent); 1454 1455 /* Get mouse-pointer location. */ 1456 const QPoint &cpnt = viewportToContents(pEvent->pos()); 1457 1458 /* Ask the guest for moving the drop cursor. */ 1459 Qt::DropAction result = m_pDnDHandler->dragMove(screenId(), 1416 1460 frameBuffer()->convertHostXTo(cpnt.x()), 1417 1461 frameBuffer()->convertHostYTo(cpnt.y()), 1418 1462 pEvent->proposedAction(), 1419 1463 pEvent->possibleActions(), 1420 pEvent->mimeData() , this /* pParent */);1464 pEvent->mimeData()); 1421 1465 1422 1466 /* Set the DnD action returned by the guest. */ … … 1425 1469 } 1426 1470 1427 void UIMachineView::dragMoveEvent(QDragMoveEvent *pEvent) 1471 /** 1472 * Host -> Guest: Issued when the host cursor leaves the guest (VM) window again. 1473 * This will ask the guest to stop any further drag'n drop operation. 1474 * 1475 * @param pEvent Related leave event. 1476 */ 1477 void UIMachineView::dragLeaveEvent(QDragLeaveEvent *pEvent) 1478 { 1479 AssertPtrReturnVoid(pEvent); 1480 1481 m_pDnDHandler->dragLeave(screenId()); 1482 1483 pEvent->accept(); 1484 } 1485 1486 /** 1487 * Guest -> Host: Checks for a pending drag and drop event within the guest 1488 * and (optionally) starts a drag and drop operation on the host. 1489 */ 1490 void UIMachineView::dragIsPending(void) 1491 { 1492 /** @todo Add guest->guest DnD functionality here by getting 1493 * the source of guest B (when copying from B to A). */ 1494 m_pDnDHandler->dragIsPending(screenId()); 1495 } 1496 1497 /** 1498 * Host -> Guest: Issued when the host drops data into the guest (VM) window. 1499 * 1500 * @param pEvent Related drop event. 1501 */ 1502 void UIMachineView::dropEvent(QDropEvent *pEvent) 1428 1503 { 1429 1504 AssertPtrReturnVoid(pEvent); … … 1432 1507 const QPoint &cpnt = viewportToContents(pEvent->pos()); 1433 1508 1434 CDnDTarget dndTarget = static_cast<CDnDTarget>(guest().GetDnDTarget());1435 1436 /* Ask the guest for moving the drop cursor. */1437 Qt::DropAction result = DnDHandler()->dragMove(dndTarget,1438 screenId(),1439 frameBuffer()->convertHostXTo(cpnt.x()),1440 frameBuffer()->convertHostYTo(cpnt.y()),1441 pEvent->proposedAction(),1442 pEvent->possibleActions(),1443 pEvent->mimeData(), this /* pParent */);1444 1445 /* Set the DnD action returned by the guest. */1446 pEvent->setDropAction(result);1447 pEvent->accept();1448 }1449 1450 void UIMachineView::dragLeaveEvent(QDragLeaveEvent *pEvent)1451 {1452 AssertPtrReturnVoid(pEvent);1453 1454 CDnDTarget dndTarget = static_cast<CDnDTarget>(guest().GetDnDTarget());1455 1456 /* Ask the guest for stopping this DnD event. */1457 DnDHandler()->dragLeave(dndTarget,1458 screenId(), this /* pParent */);1459 pEvent->accept();1460 }1461 1462 void UIMachineView::dragIsPending(void)1463 {1464 /** @todo Add guest->guest DnD functionality here by getting1465 * the source of guest B (when copying from B to A). */1466 CDnDSource dndSource = static_cast<CDnDSource>(guest().GetDnDSource());1467 1468 /* Check for a pending DnD event within the guest and if so, handle all the1469 * magic. */1470 DnDHandler()->dragIsPending(session(), dndSource, screenId(), this /* pParent */);1471 }1472 1473 void UIMachineView::dropEvent(QDropEvent *pEvent)1474 {1475 AssertPtrReturnVoid(pEvent);1476 1477 /* Get mouse-pointer location. */1478 const QPoint &cpnt = viewportToContents(pEvent->pos());1479 1480 CDnDTarget dndTarget = static_cast<CDnDTarget>(guest().GetDnDTarget());1481 1482 1509 /* Ask the guest for dropping data. */ 1483 Qt::DropAction result = DnDHandler()->dragDrop(session(), 1484 dndTarget, 1485 screenId(), 1486 frameBuffer()->convertHostXTo(cpnt.x()), 1487 frameBuffer()->convertHostYTo(cpnt.y()), 1488 pEvent->proposedAction(), 1489 pEvent->possibleActions(), 1490 pEvent->mimeData(), this /* pParent */); 1510 Qt::DropAction result = m_pDnDHandler->dragDrop(screenId(), 1511 frameBuffer()->convertHostXTo(cpnt.x()), 1512 frameBuffer()->convertHostYTo(cpnt.y()), 1513 pEvent->proposedAction(), 1514 pEvent->possibleActions(), 1515 pEvent->mimeData()); 1491 1516 1492 1517 /* Set the DnD action returned by the guest. */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
r55726 r55821 24 24 25 25 /* GUI includes: */ 26 #ifdef VBOX_WITH_DRAG_AND_DROP 27 # include "UIDnDHandler.h" 28 #endif 29 #include "UIExtraDataDefs.h" 26 30 #include "UIMachineDefs.h" 27 #include "UIExtraDataDefs.h"28 31 #ifdef Q_WS_MAC 29 32 # include <CoreFoundation/CFBase.h> … … 309 312 QPixmap m_pausePixmapScaled; 310 313 314 #ifdef VBOX_WITH_DRAG_AND_DROP 315 /** Pointer to drag and drop handler instance. */ 316 UIDnDHandler *m_pDnDHandler; 317 #endif 318 311 319 /* Friend classes: */ 312 320 friend class UIKeyboardHandler;
Note:
See TracChangeset
for help on using the changeset viewer.