Changeset 56497 in vbox
- Timestamp:
- Jun 18, 2015 10:50:40 AM (10 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp
r56138 r56497 104 104 pMimeData->formats().toVector()); 105 105 if (m_dndTarget.isOk()) 106 m_enmMode = DNDMODE_HOSTTOGUEST;106 setMode(DNDMODE_HOSTTOGUEST); 107 107 108 108 /* Set the DnD action returned by the guest. */ … … 201 201 * mode as well here. 202 202 */ 203 m_enmMode = DNDMODE_UNKNOWN;203 setMode(DNDMODE_UNKNOWN); 204 204 205 205 return toQtDnDAction(result); … … 213 213 { 214 214 m_dndTarget.Leave(screenID); 215 m_enmMode = DNDMODE_UNKNOWN;215 setMode(DNDMODE_UNKNOWN); 216 216 } 217 217 } … … 221 221 */ 222 222 223 int UIDnDHandler::dragStart (const QStringList &lstFormats,224 Qt::DropAction defAction, Qt::DropActions actions)223 int UIDnDHandler::dragStartInternal(const QStringList &lstFormats, 224 Qt::DropAction defAction, Qt::DropActions actions) 225 225 { 226 226 int rc = VINF_SUCCESS; … … 228 228 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 229 229 230 m_lstFormats = lstFormats; 231 m_defAction = defAction; 232 m_actions = actions; 233 234 LogFlowFunc(("m_defAction=0x%x\n", m_defAction)); 235 LogFlowFunc(("Number of formats: %d\n", m_lstFormats.size())); 230 LogFlowFunc(("defAction=0x%x\n", defAction)); 231 LogFlowFunc(("Number of formats: %d\n", lstFormats.size())); 236 232 # ifdef DEBUG 237 for (int i = 0; i < m_lstFormats.size(); i++)238 LogFlowFunc(("\tFormat %d: %s\n", i, m_lstFormats.at(i).toAscii().constData()));233 for (int i = 0; i < lstFormats.size(); i++) 234 LogFlowFunc(("\tFormat %d: %s\n", i, lstFormats.at(i).toAscii().constData())); 239 235 # endif 240 236 … … 244 240 if (!pDropSource) 245 241 return VERR_NO_MEMORY; 246 UIDnDDataObject *pDataObject = new UIDnDDataObject(this, m_lstFormats);242 UIDnDDataObject *pDataObject = new UIDnDDataObject(this, lstFormats); 247 243 if (!pDataObject) 248 244 return VERR_NO_MEMORY; 249 245 250 246 DWORD dwOKEffects = DROPEFFECT_NONE; 251 if ( m_actions)252 { 253 if ( m_actions & Qt::CopyAction)247 if (actions) 248 { 249 if (actions & Qt::CopyAction) 254 250 dwOKEffects |= DROPEFFECT_COPY; 255 if ( m_actions & Qt::MoveAction)251 if (actions & Qt::MoveAction) 256 252 dwOKEffects |= DROPEFFECT_MOVE; 257 if ( m_actions & Qt::LinkAction)253 if (actions & Qt::LinkAction) 258 254 dwOKEffects |= DROPEFFECT_LINK; 259 255 } … … 276 272 277 273 /* Note: pMData is transferred to the QDrag object, so no need for deletion. */ 278 m_pMIMEData = new UIDnDMIMEData(this, m_lstFormats, m_defAction, m_actions);274 m_pMIMEData = new UIDnDMIMEData(this, lstFormats, defAction, actions); 279 275 if (!m_pMIMEData) 280 276 { … … 282 278 return VERR_NO_MEMORY; 283 279 } 280 281 /* Invoke this handler as data needs to be retrieved. */ 282 connect(m_pMIMEData, SIGNAL(getData(QString, QVariant::Type)), 283 this, SLOT(sltGetData(QString, QVariant::Type))); 284 284 285 285 /* Inform the MIME data object of any changes in the current action. */ … … 292 292 */ 293 293 pDrag->setMimeData(m_pMIMEData); 294 Qt::DropAction dropAction = pDrag->exec(m_actions, m_defAction); 294 LogFlowFunc(("Executing modal drag'n drop operation ...\n")); 295 Qt::DropAction dropAction = pDrag->exec(actions, defAction); 295 296 LogRel3(("DnD: Ended with dropAction=%ld\n", UIDnDHandler::toVBoxDnDAction(dropAction))); 296 297 … … 313 314 } 314 315 315 int UIDnDHandler::drag IsPending(ulong screenID)316 int UIDnDHandler::dragCheckPending(ulong screenID) 316 317 { 317 318 int rc; … … 331 332 } 332 333 333 QMutexLocker AutoWriteLock(&m_ ReadLock);334 QMutexLocker AutoWriteLock(&m_WriteLock); 334 335 m_fIsPending = true; 335 336 AutoWriteLock.unlock(); … … 348 349 CGuest guest = m_pSession->guest(); 349 350 350 QVector<QString> vecFmtGuest; 351 QVector<KDnDAction> vecActions; 352 KDnDAction defaultAction = m_dndSource.DragIsPending(screenID, vecFmtGuest, vecActions); 353 LogFlowFunc(("defaultAction=%d, numFormats=%d, numActions=%d\n", defaultAction, 354 vecFmtGuest.size(), vecActions.size())); 355 356 QStringList lstFmtNative; 357 if (defaultAction != KDnDAction_Ignore) 358 { 359 LogRel3(("DnD: Number of supported guest actions: %d\n", vecActions.size())); 360 for (int i = 0; i < vecActions.size(); i++) 361 LogRel3(("\tAction %d: 0x%x\n", i, vecActions.at(i))); 362 363 /** 364 * Do guest -> host format conversion, if needed. 365 * On X11 this already maps to the Xdnd protocol. 366 ** @todo What about the MacOS Carbon Drag Manager? Needs testing. 367 * 368 * See: https://www.iana.org/assignments/media-types/media-types.xhtml 369 */ 370 LogRel3(("DnD: Number of supported guest formats: %d\n", vecFmtGuest.size())); 371 for (int i = 0; i < vecFmtGuest.size(); i++) 351 /* Clear our current data set. */ 352 m_dataSource.lstFormats.clear(); 353 m_dataSource.vecActions.clear(); 354 355 /* Ask the guest if there is a drag and drop operation pending (on the guest). */ 356 QVector<QString> vecFormats; 357 m_dataSource.defaultAction = m_dndSource.DragIsPending(screenID, vecFormats, m_dataSource.vecActions); 358 359 LogRel3(("DnD: Default action is: 0x%x\n", m_dataSource.defaultAction)); 360 LogRel3(("DnD: Number of supported guest actions: %d\n", m_dataSource.vecActions.size())); 361 for (int i = 0; i < m_dataSource.vecActions.size(); i++) 362 LogRel3(("\tAction %d: 0x%x\n", i, m_dataSource.vecActions.at(i))); 363 364 LogRel3(("DnD: Number of supported guest formats: %d\n", vecFormats.size())); 365 for (int i = 0; i < vecFormats.size(); i++) 372 366 { 373 const QString &strFmtGuest = vecF mtGuest.at(i);367 const QString &strFmtGuest = vecFormats.at(i); 374 368 LogRel3(("\tFormat %d: %s\n", i, strFmtGuest.toAscii().constData())); 375 # ifdef RT_OS_WINDOWS376 /* CF_TEXT -> Regular text. */377 if ( strFmtGuest.contains("text/plain", Qt::CaseInsensitive)378 && !lstFmtNative.contains("text/plain"))379 {380 lstFmtNative << "text/plain";381 }382 /* CF_HDROP -> URI list. */383 else if ( strFmtGuest.contains("text/uri-list", Qt::CaseInsensitive)384 && !lstFmtNative.contains("text/uri-list"))385 {386 lstFmtNative << "text/uri-list";387 }388 # else /* RT_OS_WINDOWS */389 390 /* On non-Windows just do a 1:1 mapping. */391 lstFmtNative << strFmtGuest;392 # ifdef RT_OS_MACOS393 /** @todo Does the 1:1 format mapping apply on OS X? Needs testing! */394 # endif395 396 # endif /* !RT_OS_WINDOWS */397 369 } 398 370 399 LogRel3(("DnD: Number of supported host formats: %d\n", lstFmtNative.size())); 400 for (int i = 0; i < lstFmtNative.size(); i++) 401 LogRel3(("\tFormat %d: %s\n", i, lstFmtNative.at(i).toAscii().constData())); 402 } 403 404 if (!lstFmtNative.isEmpty()) 405 { 406 rc = dragStart(lstFmtNative, 407 toQtDnDAction(defaultAction), toQtDnDActions(vecActions)); 371 if ( m_dataSource.defaultAction != KDnDAction_Ignore 372 && vecFormats.size()) 373 { 374 for (int i = 0; i < vecFormats.size(); i++) 375 { 376 const QString &strFormat = vecFormats.at(i); 377 m_dataSource.lstFormats << strFormat; 378 } 379 380 rc = VINF_SUCCESS; /* There's a valid pending drag and drop operation on the guest. */ 408 381 } 409 382 else /* No format data from the guest arrived yet. */ … … 426 399 } 427 400 428 /** 429 * Called by UIDnDMIMEData (Linux, OS X, Solaris) or UIDnDDataObject (Windows) 430 * to start retrieving the actual data from the guest. This function will block 431 * and show a modal progress dialog until the data transfer is complete. 432 * 433 * @return IPRT return code. 434 * @param dropAction Drop action to perform. 435 * @param strMimeType MIME data type. 436 * @param vaType Qt's variant type of the MIME data. 437 * @param vaData The actual MIME data. 438 * @param pParent Pointer to parent widget. 439 */ 440 int UIDnDHandler::retrieveData( Qt::DropAction dropAction, 441 const QString &strMimeType, 442 QVariant::Type vaType, 443 QVariant &vaData) 401 int UIDnDHandler::dragStart(ulong screenID) 402 { 403 int rc; 404 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 405 406 LogFlowFuncEnter(); 407 408 /* Sanity checks. */ 409 if ( !m_dataSource.lstFormats.size() 410 || m_dataSource.defaultAction == KDnDAction_Ignore 411 || !m_dataSource.vecActions.size()) 412 { 413 return VERR_INVALID_PARAMETER; 414 } 415 416 setMode(DNDMODE_GUESTTOHOST); 417 418 rc = dragStartInternal(m_dataSource.lstFormats, 419 toQtDnDAction(m_dataSource.defaultAction), toQtDnDActions(m_dataSource.vecActions)); 420 421 #else /* !VBOX_WITH_DRAG_AND_DROP_GH */ 422 423 NOREF(screenID); 424 425 rc = VERR_NOT_SUPPORTED; 426 427 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 428 429 LogFlowFuncLeaveRC(rc); 430 return rc; 431 } 432 433 int UIDnDHandler::dragStop(ulong screenID) 434 { 435 int rc; 436 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 437 438 m_fIsPending = false; 439 rc = VINF_SUCCESS; 440 441 #else /* !VBOX_WITH_DRAG_AND_DROP_GH */ 442 443 NOREF(screenID); 444 445 rc = VERR_NOT_SUPPORTED; 446 447 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 448 449 LogFlowFuncLeaveRC(rc); 450 return rc; 451 } 452 453 int UIDnDHandler::retrieveDataInternal( Qt::DropAction dropAction, 454 const QString &strMimeType, 455 QVariant::Type vaType, 456 QVariant &vaData) 444 457 { 445 458 LogFlowFunc(("Retrieving data as type=%s (variant type=%ld)\n", … … 518 531 } 519 532 533 setMode(DNDMODE_UNKNOWN); 534 520 535 LogFlowFuncLeaveRC(rc); 521 536 return rc; 537 } 538 539 void UIDnDHandler::setMode(DNDMODE enmMode) 540 { 541 QMutexLocker AutoWriteLock(&m_WriteLock); 542 m_enmMode = enmMode; 543 LogFlowFunc(("Mode is now: %RU32\n", m_enmMode)); 544 } 545 546 /** 547 * Called by UIDnDMIMEData (Linux, OS X, Solaris) to start retrieving the actual data 548 * from the guest. This function will block and show a modal progress dialog until 549 * the data transfer is complete. 550 * 551 * @return QVariant with data retrieved, if any. 552 * @param strMimeType MIME data type. 553 * @param vaType Qt's variant type of the MIME data. 554 */ 555 QVariant UIDnDHandler::sltGetData(const QString &strMimeType, 556 QVariant::Type vaType) 557 { 558 QVariant vaData; 559 int rc = retrieveDataInternal(Qt::CopyAction, strMimeType, vaType, vaData); 560 LogFlowFuncLeaveRC(rc); 561 return vaData; 522 562 } 523 563 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.h
r56321 r56497 62 62 } DNDMODE; 63 63 64 /** 65 * Drag and drop data set from the source. 66 */ 67 typedef struct UIDnDDataSource 68 { 69 /** List of formats supported by the source. */ 70 QStringList lstFormats; 71 /** List of allowed drop actions from the source. */ 72 QVector<KDnDAction> vecActions; 73 /** Default drop action from the source. */ 74 KDnDAction defaultAction; 75 76 } UIDnDDataSource; 77 64 78 /* Frontend -> Target. */ 65 79 Qt::DropAction dragEnter(ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData); … … 69 83 70 84 /* Source -> Frontend. */ 71 int dragIsPending(ulong screenId); 72 int dragStart(const QStringList &lstFormats, Qt::DropAction defAction, Qt::DropActions actions); 85 int dragCheckPending(ulong screenId); 86 int dragStart(ulong screenId); 87 int dragStop(ulong screenID); 73 88 int retrieveData(Qt::DropAction dropAction, const QString &strMimeType, QVariant::Type vaType, QVariant &vaData); 74 89 … … 79 94 static Qt::DropAction toQtDnDAction(KDnDAction action); 80 95 static Qt::DropActions toQtDnDActions(const QVector<KDnDAction> &vecActions); 96 97 public slots: 98 99 QVariant sltGetData(const QString &strMimeType, QVariant::Type vaType); 100 101 protected: 102 103 int dragStartInternal(const QStringList &lstFormats, Qt::DropAction defAction, Qt::DropActions actions); 104 int retrieveDataInternal(Qt::DropAction dropAction, const QString &strMimeType, QVariant::Type vaType, QVariant &vaData); 105 void setMode(DNDMODE enmMode); 81 106 82 107 protected: … … 93 118 /** Current transfer direction. */ 94 119 DNDMODE m_enmMode; 120 /** Current data from the source (if any). 121 * At the momenet we only support one source at a time. */ 122 UIDnDDataSource m_dataSource; 95 123 /** Flag indicating if a drag operation is pending currently. */ 96 124 bool m_fIsPending; 97 125 QMutex m_ReadLock; 98 126 QMutex m_WriteLock; 99 100 /** List of formats supported by the source. */101 QStringList m_lstFormats;102 /** Default drop action from the source. */103 Qt::DropAction m_defAction;104 /** List of allowed drop actions from the source. */105 Qt::DropActions m_actions;106 127 107 128 #ifndef RT_OS_WINDOWS -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp
r56138 r56497 45 45 , m_lstFormats(lstFormats) 46 46 , m_defAction(defAction) 47 , m_curAction(Qt::DropAction::IgnoreAction) 47 48 , m_actions(actions) 48 49 , m_enmState(Dragging) … … 56 57 LogFlowFunc(("\tFormat %d: %s\n", i, lstFormats.at(i).toAscii().constData())); 57 58 #endif 58 59 /**60 * This is unbelievable hacky, but I didn't find another way. Stupid61 * Qt QDrag interface is so less verbose, that we in principle know62 * nothing about what happens when the user drag something around. It63 * is possible that the target on the host requests data64 * (@sa retrieveData) while the mouse button still is pressed. This65 * isn't something we should support, because it would mean transferring66 * the data from the guest while the mouse is still moving (think of67 * transferring a 2GB file from the guest to the host ...). So the idea is68 * to detect the mouse release event and only after this happened, allow69 * data to be retrieved. Unfortunately the QDrag object eats all events70 * while a drag is going on (see QDragManager in the Qt src's).71 *72 * So what we now are going to do is installing an event filter after the73 * QDrag::exec is called, so that this event filter then would be74 * the last in the event filter queue and therefore called before the75 * one installed by the QDrag object (which then in turn would76 * munch all events).77 *78 ** @todo Test this on all supported platforms (X11 works).79 *80 * Note: On Windows the above hack is not needed because as soon as Qt calls81 * OLE's DoDragDrop routine internally (via QtDrag::exec), no mouse82 * events will come through anymore. At this point DoDragDrop is modal83 * and will take care of all the input handling. */84 #ifndef RT_OS_WINDOWS85 /* Install the event filter in a deferred way. */86 QTimer::singleShot(0, this, SLOT(sltInstallEventFilter()));87 #endif88 59 } 89 60 … … 95 66 bool UIDnDMIMEData::hasFormat(const QString &strMIMEType) const 96 67 { 97 bool fRc = m_lstFormats.contains(strMIMEType);98 LogFlowFunc(("%s: %RTbool (QtMimeData: %RTbool )\n",99 strMIMEType.toStdString().c_str(), fRc, QMimeData::hasFormat(strMIMEType) ));68 bool fRc = (m_curAction != Qt::DropAction::IgnoreAction); 69 LogFlowFunc(("%s: %RTbool (QtMimeData: %RTbool, curAction=0x%x)\n", 70 strMIMEType.toStdString().c_str(), fRc, QMimeData::hasFormat(strMIMEType), m_curAction)); 100 71 return fRc; 101 72 } … … 112 83 QVariant UIDnDMIMEData::retrieveData(const QString &strMIMEType, QVariant::Type vaType) const 113 84 { 114 LogFlowFunc(("state=%RU32, mimeType=%s, type=%d (%s)\n", m_enmState, strMIMEType.toStdString().c_str(),115 vaType, QVariant::typeToName(vaType)));85 LogFlowFunc(("state=%RU32, curAction=0x%x, defAction=0x%x, mimeType=%s, type=%d (%s)\n", 86 m_enmState, m_curAction, m_defAction, strMIMEType.toStdString().c_str(), vaType, QVariant::typeToName(vaType))); 116 87 117 88 bool fCanDrop = true; … … 126 97 * (see UIDnDMimeData::eventFilter). This filter will update the current 127 98 * operation state for us (based on the mouse buttons). */ 128 if (m_ enmState != Dropped)129 { 130 LogFlowFunc((" Not yet in 'dropped' state, so can't drop yet\n"));99 if (m_curAction == Qt::DropAction::IgnoreAction) 100 { 101 LogFlowFunc(("Current drop action is 0x%x, so can't drop yet\n", m_curAction)); 131 102 fCanDrop = false; 132 103 } 133 104 #endif 134 105 135 /* Do we support the requested MIME type? */ 136 if ( fCanDrop 137 && !m_lstFormats.contains(strMIMEType)) 138 { 139 LogRel3(("DnD: Unsupported MIME type=%s\n", strMIMEType.toStdString().c_str())); 140 fCanDrop = false; 141 } 142 143 /* Supported types. See below in the switch statement. */ 144 if ( fCanDrop 145 && !( 146 /* Plain text. */ 147 vaType == QVariant::String 148 /* Binary data. */ 149 || vaType == QVariant::ByteArray 150 /* URI list. */ 151 || vaType == QVariant::List)) 152 { 153 LogRel3(("DnD: Unsupported data type=%d (%s)\n", vaType, QVariant::typeToName(vaType))); 154 fCanDrop = false; 155 } 156 157 LogRel3(("DnD: State=%ld, fCanDrop=%RTbool\n", m_enmState, fCanDrop)); 106 if (fCanDrop) 107 { 108 /* Do we support the requested MIME type? */ 109 if (!m_lstFormats.contains(strMIMEType)) 110 { 111 LogRel(("DnD: Unsupported MIME type '%s'\n", strMIMEType.toStdString().c_str())); 112 fCanDrop = false; 113 } 114 115 /* Supported types. See below in the switch statement. */ 116 if (!( 117 /* Plain text. */ 118 vaType == QVariant::String 119 /* Binary data. */ 120 || vaType == QVariant::ByteArray 121 /* URI list. */ 122 || vaType == QVariant::List)) 123 { 124 LogRel(("DnD: Unsupported data type '%s'\n", QVariant::typeToName(vaType))); 125 fCanDrop = false; 126 } 127 } 128 129 LogRel3(("DnD: State=%ld, Action=0x%x, fCanDrop=%RTbool\n", m_enmState, m_curAction, fCanDrop)); 158 130 159 131 if (!fCanDrop) 160 132 { 161 133 LogFlowFunc(("Skipping request, state=%RU32 ...\n", m_enmState)); 162 return QMimeData::retrieveData(strMIMEType, vaType); 163 } 164 165 /* Note: The const_cast is used because this function needs to be const (otherwise 166 * Qt won't call it), but we need the stuff in an unconst'ed way. */ 167 int rc = const_cast<UIDnDMIMEData *>(this)->retrieveDataInternal(strMIMEType, vaType); 168 169 LogFlowFunc(("Returning rc=%Rrc, state=%RU32\n", rc, m_enmState)); 170 return m_vaData; 134 return QVariant(QVariant::Invalid); /* Return a NULL variant. */ 135 } 136 137 QVariant vaData = emit getData(strMIMEType, vaType); 138 139 LogRel3(("DnD: Returning data of type '%s'\n", vaData.typeName())); 140 return vaData; 171 141 } 172 142 … … 180 150 switch (pEvent->type()) 181 151 { 182 case QEvent::MouseMove:183 {184 QMouseEvent *pMouseEvent = (QMouseEvent*)(pEvent);185 AssertPtr(pMouseEvent);186 LogFlowFunc(("MouseMove: x=%d, y=%d\n", pMouseEvent->globalX(), pMouseEvent->globalY()));187 188 break;189 }190 191 152 case QEvent::MouseButtonRelease: 192 153 { … … 223 184 } 224 185 225 /* Do normal processing by Qt. */226 return QObject::eventFilter(pObject, pEvent);186 /* Propagate further. */ 187 return false; 227 188 } 228 189 #endif /* !RT_OS_WINDOWS */ 229 190 191 #if 0 230 192 int UIDnDMIMEData::setData(const QString &mimeType) 231 193 { … … 278 240 return rc; 279 241 } 280 281 int UIDnDMIMEData::retrieveDataInternal(const QString &strMIMEType, QVariant::Type vaType) 282 { 283 LogFlowFunc(("state=%RU32, mimeType=%s, type=%d (%s)\n", m_enmState, 284 strMIMEType.toStdString().c_str(), vaType, QVariant::typeToName(vaType))); 285 286 AssertPtr(m_pDnDHandler); 287 int rc = m_pDnDHandler->retrieveData(m_defAction, strMIMEType, vaType, m_vaData); 288 if (RT_SUCCESS(rc)) 289 { 290 /* Nothing to do here yet. */ 291 } 292 else if (rc == VERR_CANCELLED) 293 m_enmState = Canceled; 294 else 295 m_enmState = Error; 296 297 LogFlowFuncLeaveRC(rc); 298 return rc; 299 } 242 #endif 300 243 301 244 /** … … 307 250 { 308 251 LogFlowFunc(("dropAction=0x%x\n", dropAction)); 309 m_defAction = dropAction; 310 } 311 312 #ifndef RT_OS_WINDOWS 313 /** 314 * Issued by ourselves to install the event filter. 315 */ 316 void UIDnDMIMEData::sltInstallEventFilter(void) 317 { 318 LogFlowFunc(("Installing event filter ...\n")); 319 AssertPtr(qApp); 320 qApp->installEventFilter(this); 321 } 322 #endif 323 252 m_curAction = dropAction; 253 } 254 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.h
r55821 r56497 63 63 UIDnDMIMEData(UIDnDHandler *pDnDHandler, QStringList formats, Qt::DropAction defAction, Qt::DropActions actions); 64 64 65 public:65 signals: 66 66 67 int setData(const QString &mimeType);67 int getData(const QString &strMIMEType, QVariant::Type vaType) const; 68 68 69 69 public slots: … … 78 78 virtual bool hasFormat(const QString &mimeType) const; 79 79 80 virtual QVariant retrieveData(const QString & mimeType, QVariant::Type type) const;80 virtual QVariant retrieveData(const QString &strMIMEType, QVariant::Type vaType) const; 81 81 82 82 #ifndef RT_OS_WINDOWS … … 85 85 /** @} */ 86 86 87 int retrieveDataInternal(const QString &strMIMEType, QVariant::Type vaType);88 89 protected slots:90 91 #ifndef RT_OS_WINDOWS92 void sltInstallEventFilter(void);93 #endif94 95 87 protected: 96 88 … … 98 90 99 91 QStringList m_lstFormats; 92 /** Default action on successful drop operation. */ 100 93 Qt::DropAction m_defAction; 94 /** Current action, based on QDrag's status. */ 95 Qt::DropAction m_curAction; 101 96 Qt::DropActions m_actions; 102 97 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r56217 r56497 545 545 , m_fAccelerate2DVideo(bAccelerate2DVideo) 546 546 #endif /* VBOX_WITH_VIDEOHWACCEL */ 547 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 548 , m_fIsDraggingFromGuest(false) 549 #endif 547 550 { 548 551 /* Load machine view settings: */ … … 1420 1423 1421 1424 #ifdef VBOX_WITH_DRAG_AND_DROP 1425 bool UIMachineView::dragAndDropCanAccept(void) const 1426 { 1427 bool fAccept = m_pDnDHandler 1428 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 1429 && !m_fIsDraggingFromGuest 1430 #endif 1431 && machine().GetDnDMode() != KDnDMode_Disabled; 1432 LogRelFunc(("fAccept=%RTbool\n", fAccept)); 1433 return fAccept; 1434 } 1435 1422 1436 bool UIMachineView::dragAndDropIsActive(void) const 1423 1437 { … … 1430 1444 AssertPtrReturnVoid(pEvent); 1431 1445 1432 if (!dragAndDrop IsActive())1446 if (!dragAndDropCanAccept()) 1433 1447 return; 1434 1448 … … 1453 1467 AssertPtrReturnVoid(pEvent); 1454 1468 1455 if (!dragAndDrop IsActive())1469 if (!dragAndDropCanAccept()) 1456 1470 return; 1457 1471 … … 1476 1490 AssertPtrReturnVoid(pEvent); 1477 1491 1492 if (!dragAndDropCanAccept()) 1493 return; 1494 1495 m_pDnDHandler->dragLeave(screenId()); 1496 1497 pEvent->accept(); 1498 } 1499 1500 int UIMachineView::dragCheckPending(void) 1501 { 1502 int rc; 1503 1478 1504 if (!dragAndDropIsActive()) 1479 return; 1480 1481 m_pDnDHandler->dragLeave(screenId()); 1482 1483 pEvent->accept(); 1484 } 1485 1486 void UIMachineView::dragIsPending(void) 1487 { 1505 rc = VERR_ACCESS_DENIED; 1506 else if (!m_fIsDraggingFromGuest) 1507 { 1508 /** @todo Add guest->guest DnD functionality here by getting 1509 * the source of guest B (when copying from B to A). */ 1510 rc = m_pDnDHandler->dragCheckPending(screenId()); 1511 if (RT_SUCCESS(rc)) 1512 m_fIsDraggingFromGuest = true; 1513 } 1514 else /* Already dragging, so report success. */ 1515 rc = VINF_SUCCESS; 1516 1517 LogRel3(("DnD: dragCheckPending ended with rc=%Rrc\n", rc)); 1518 return rc; 1519 } 1520 1521 int UIMachineView::dragStart(void) 1522 { 1523 int rc; 1524 1488 1525 if (!dragAndDropIsActive()) 1489 return; 1490 1491 /** @todo Add guest->guest DnD functionality here by getting 1492 * the source of guest B (when copying from B to A). */ 1493 m_pDnDHandler->dragIsPending(screenId()); 1526 rc = VERR_ACCESS_DENIED; 1527 else if (!m_fIsDraggingFromGuest) 1528 rc = VERR_WRONG_ORDER; 1529 else 1530 { 1531 /** @todo Add guest->guest DnD functionality here by getting 1532 * the source of guest B (when copying from B to A). */ 1533 rc = m_pDnDHandler->dragStart(screenId()); 1534 1535 m_fIsDraggingFromGuest = false; 1536 } 1537 1538 LogRel3(("DnD: dragStart ended with rc=%Rrc\n", rc)); 1539 return rc; 1540 } 1541 1542 int UIMachineView::dragStop(void) 1543 { 1544 int rc; 1545 1546 if (!dragAndDropIsActive()) 1547 rc = VERR_ACCESS_DENIED; 1548 else if (!m_fIsDraggingFromGuest) 1549 rc = VERR_WRONG_ORDER; 1550 else 1551 rc = m_pDnDHandler->dragStop(screenId()); 1552 1553 LogRel3(("DnD: dragStop ended with rc=%Rrc\n", rc)); 1554 return rc; 1494 1555 } 1495 1556 … … 1498 1559 AssertPtrReturnVoid(pEvent); 1499 1560 1500 if (!dragAndDrop IsActive())1561 if (!dragAndDropCanAccept()) 1501 1562 return; 1502 1563 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
r56443 r56497 263 263 #ifdef VBOX_WITH_DRAG_AND_DROP 264 264 /** 265 * Returns @true if the VM window can accept (start is, start) a drag and drop 266 * operation, @false if not. 267 */ 268 bool dragAndDropCanAccept(void) const; 269 270 /** 265 271 * Returns @true if drag and drop for this machine is active 266 272 * (that is, host->guest, guest->host or bidirectional), @false if not. … … 298 304 * and (optionally) starts a drag and drop operation on the host. 299 305 */ 300 void dragIsPending(void); 306 int dragCheckPending(void); 307 308 /** 309 * Guest -> Host: Starts a drag and drop operation from guest to the host. This 310 * internally either uses Qt's abstract QDrag methods or some other 311 * OS-dependent implementation. 312 */ 313 int dragStart(void); 314 315 /** 316 * Guest -> Host: Aborts (and resets) the current (pending) guest to host 317 * drag and drop operation. 318 */ 319 int dragStop(void); 301 320 302 321 /** … … 358 377 /** Pointer to drag and drop handler instance. */ 359 378 UIDnDHandler *m_pDnDHandler; 379 # ifdef VBOX_WITH_DRAG_AND_DROP_GH 380 /** Flag indicating whether a guest->host drag currently is in 381 * progress or not. */ 382 bool m_fIsDraggingFromGuest; 383 # endif 360 384 #endif 361 385 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
r55724 r56497 957 957 #ifdef VBOX_WITH_DRAG_AND_DROP 958 958 # ifdef VBOX_WITH_DRAG_AND_DROP_GH 959 QPointer<UIMachineView> pView = m_views[uScreenId]; 960 bool fHandleDnDPending = RT_BOOL(mouseButtons.testFlag(Qt::LeftButton)); 961 962 /* Mouse pointer outside VM window? */ 959 963 if ( cpnt.x() < 0 960 964 || cpnt.x() > iCw - 1 … … 962 966 || cpnt.y() > iCh - 1) 963 967 { 964 bool fHandleDnDPending965 = RT_BOOL(mouseButtons.testFlag(Qt::LeftButton));966 968 if (fHandleDnDPending) 967 969 { 968 m_views[uScreenId]->dragIsPending(); 969 return true; 970 } 970 LogRel2(("DnD: Drag and drop operation from guest to host started\n")); 971 972 int rc = pView->dragCheckPending(); 973 if (RT_SUCCESS(rc)) 974 { 975 pView->dragStart(); 976 return true; /* Bail out -- we're done here. */ 977 } 978 } 979 } 980 else /* Inside VM window? */ 981 { 982 if (fHandleDnDPending) 983 pView->dragStop(); 971 984 } 972 985 # endif
Note:
See TracChangeset
for help on using the changeset viewer.