Changeset 50265 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Jan 29, 2014 11:12:44 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91898
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r50191 r50265 5 5 6 6 # 7 # Copyright (C) 2006-201 3Oracle Corporation7 # Copyright (C) 2006-2014 Oracle Corporation 8 8 # 9 9 # This file is part of VirtualBox Open Source Edition (OSE), as … … 176 176 ./src/net 177 177 endif 178 178 179 179 VirtualBox_INCS = \ 180 180 $(VBOX_GUI_INC_DIRS) \ … … 390 390 src/widgets/VBoxOSTypeSelectorButton.h \ 391 391 src/widgets/UINameAndSystemEditor.h \ 392 392 src/widgets/UIWarningPane.h \ 393 393 src/widgets/UIFilmContainer.h \ 394 394 src/widgets/graphics/UIGraphicsButton.h \ … … 433 433 434 434 ifdef VBOX_GUI_WITH_NETWORK_MANAGER 435 VirtualBox_QT_MOCHDRS += \435 VirtualBox_QT_MOCHDRS += \ 436 436 src/net/UINetworkManager.h \ 437 437 src/net/UINetworkManagerDialog.h \ … … 448 448 src/settings/global/UIGlobalSettingsProxy.h \ 449 449 src/settings/global/UIGlobalSettingsUpdate.h 450 endif 451 452 ifdef VBOX_WITH_DRAG_AND_DROP 453 ifdef VBOX_WITH_DRAG_AND_DROP_GH 454 VirtualBox_QT_MOCHDRS += \ 455 src/runtime/UIDnDMIMEData.h 456 endif 450 457 endif 451 458 … … 477 484 478 485 ifdef VBOX_GUI_WITH_NETWORK_MANAGER 479 VirtualBox_QT_MOCSRCS += \486 VirtualBox_QT_MOCSRCS += \ 480 487 src/net/UINetworkReply.cpp \ 481 488 src/net/UIUpdateManager.cpp 489 endif 490 491 ifdef VBOX_WITH_DRAG_AND_DROP 492 ifdef VBOX_WITH_DRAG_AND_DROP_GH 493 VirtualBox_QT_MOCSRCS += \ 494 src/runtime/UIDnDMIMEData.cpp 495 endif 482 496 endif 483 497 … … 763 777 VirtualBox_QT_MOCSRCS += \ 764 778 src/runtime/UIDnDHandler.cpp 779 ifdef VBOX_WITH_DRAG_AND_DROP_GH 780 VirtualBox_SOURCES += \ 781 src/runtime/UIDnDMIMEData.cpp 782 VirtualBox_QT_MOCSRCS += \ 783 src/runtime/UIDnDMIMEData.cpp 784 endif 765 785 endif 766 786 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp
r49891 r50265 7 7 8 8 /* 9 * Copyright (C) 2011-201 3Oracle Corporation9 * Copyright (C) 2011-2014 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 21 21 #include <QApplication> 22 22 #include <QKeyEvent> 23 #include <QMimeData>24 23 #include <QStringList> 25 24 #include <QTimer> … … 33 32 /* GUI includes: */ 34 33 #include "UIDnDHandler.h" 34 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 35 # include "UIDnDMIMEData.h" 36 #endif 35 37 #include "UIMessageCenter.h" 36 38 … … 40 42 #include "CGuest.h" 41 43 42 UIDnDHandler *UIDnDHandler::m_pInstance = 0;43 44 UIDnDHandler::UIDnDHandler( )44 UIDnDHandler *UIDnDHandler::m_pInstance = NULL; 45 46 UIDnDHandler::UIDnDHandler(void) 45 47 { 46 48 } … … 50 52 */ 51 53 52 Qt::DropAction UIDnDHandler::dragHGEnter(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget * /* pParent = 0 */) 54 Qt::DropAction UIDnDHandler::dragHGEnter(CGuest &guest, ulong screenId, int x, int y, 55 Qt::DropAction proposedAction, Qt::DropActions possibleActions, 56 const QMimeData *pMimeData, QWidget * /* pParent = NULL */) 53 57 { 54 58 LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n", … … 66 70 } 67 71 68 Qt::DropAction UIDnDHandler::dragHGMove(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget * /* pParent = 0 */) 72 Qt::DropAction UIDnDHandler::dragHGMove(CGuest &guest, ulong screenId, int x, int y, 73 Qt::DropAction proposedAction, Qt::DropActions possibleActions, 74 const QMimeData *pMimeData, QWidget * /* pParent = NULL */) 69 75 { 70 76 #ifdef DEBUG_andy … … 85 91 } 86 92 87 Qt::DropAction UIDnDHandler::dragHGDrop(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent /* = 0 */) 93 Qt::DropAction UIDnDHandler::dragHGDrop(CGuest &guest, ulong screenId, int x, int y, 94 Qt::DropAction proposedAction, Qt::DropActions possibleActions, 95 const QMimeData *pMimeData, QWidget *pParent /* = NULL */) 88 96 { 89 97 LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n", … … 132 140 } 133 141 134 void UIDnDHandler::dragHGLeave(CGuest &guest, ulong screenId, QWidget * /* pParent = 0*/)142 void UIDnDHandler::dragHGLeave(CGuest &guest, ulong screenId, QWidget * /* pParent = NULL */) 135 143 { 136 144 LogFlowFunc(("screenId=%RU32\n", screenId)); … … 138 146 } 139 147 140 /* 141 * Guest -> Host 142 */ 143 144 class UIDnDMimeData: public QMimeData 145 { 146 Q_OBJECT; 147 148 enum State 149 { 150 Dragging, 151 Dropped, 152 Finished, 153 Canceled 154 }; 155 156 public: 157 UIDnDMimeData(CSession &session, QStringList formats, Qt::DropAction defAction, Qt::DropActions actions, QWidget *pParent) 158 : m_pParent(pParent) 159 , m_session(session) 160 , m_formats(formats) 161 , m_defAction(defAction) 162 , m_actions(actions) 163 , m_fState(Dragging) 164 { 165 /* 166 * This is unbelievable hacky, but I didn't find another way. Stupid 167 * Qt QDrag interface is so less verbose, that we in principle know 168 * nothing about what happens when the user drag something around. It 169 * is possible that the target request data (s. retrieveData) while the 170 * mouse button is still pressed. This isn't something we can support, 171 * cause it would mean transferring the data from the guest while the 172 * mouse is still moving (thing of a 2GB file ...). So the idea is to 173 * detect the mouse release event and only after this happened, allow 174 * data to be retrieved. Unfortunately the QDrag object eats all events 175 * while a drag is going on (see QDragManager in the Qt src's). So what 176 * we do, is installing an event filter after the QDrag::exec is called 177 * to be last in the event filter queue and therefore called before the 178 * one installed by the QDrag object. 179 * 180 ** @todo: Test this on all supported platforms (X11 works). 181 */ 182 QTimer::singleShot(0, this, SLOT(sltInstallEventFilter())); 183 } 184 185 virtual QStringList formats() const { return m_formats; } 186 virtual bool hasFormat(const QString &mimeType) const { return m_formats.contains(mimeType); } 187 188 public slots: 189 void sltActionChanged(Qt::DropAction action) { m_defAction = action; } 190 191 protected: 192 virtual QVariant retrieveData(const QString &mimeType, QVariant::Type type) const 193 { 194 /* Mouse button released? */ 195 if (m_fState != Dropped) 196 return m_data; 197 198 /* Supported types. See below in the switch statement. */ 199 if (!( type == QVariant::String 200 || type == QVariant::ByteArray)) 201 return QVariant(); 202 203 CGuest guest = m_session.GetConsole().GetGuest(); 204 /* No, start getting the data from the guest. First inform the guest we 205 * want the data in the specified mime-type. */ 206 CProgress progress = guest.DragGHDropped(mimeType, UIDnDHandler::toVBoxDnDAction(m_defAction)); 207 if (guest.isOk()) 208 { 209 msgCenter().showModalProgressDialog(progress, tr("Dropping data ..."), ":/progress_dnd_gh_90px.png", m_pParent); 210 if (!progress.GetCanceled()) 211 { 212 if (progress.isOk() && progress.GetResultCode() == 0) 213 { 214 /* After the data is successfully arrived from the guest, we query it from Main. */ 215 QVector<uint8_t> data = guest.DragGHGetData(); 216 if (!data.isEmpty()) 217 { 218 /* Todo: not sure what to add here more: needs more testing. */ 219 switch (type) 220 { 221 case QVariant::String: 222 { 223 m_data = QVariant(QString(reinterpret_cast<const char*>(data.data()))); 224 break; 225 } 226 case QVariant::ByteArray: 227 { 228 QByteArray ba(reinterpret_cast<const char*>(data.constData()), data.size()); 229 m_data = QVariant(ba); 230 break; 231 } 232 default: break; 233 } 234 } 235 m_fState = Finished; 236 } 237 else 238 msgCenter().cannotDropData(progress, m_pParent); 239 } 240 else 241 m_fState = Canceled; 242 } 243 else 244 msgCenter().cannotDropData(guest, m_pParent); 245 return m_data; 246 } 247 248 bool eventFilter(QObject * /* pObject */, QEvent *pEvent) 249 { 250 switch (pEvent->type()) 251 { 252 case QEvent::MouseButtonRelease: m_fState = Dropped; break; 253 case QEvent::KeyPress: 254 { 255 if (static_cast<QKeyEvent*>(pEvent)->key() == Qt::Key_Escape) 256 m_fState = Canceled; 257 break; 258 } 259 } 260 261 /* Propagate the event further. */ 262 return false; 263 } 264 265 private slots: 266 void sltInstallEventFilter() { qApp->installEventFilter(this); } 267 268 private: 269 /* Private members. */ 270 QWidget *m_pParent; 271 CSession m_session; 272 QStringList m_formats; 273 Qt::DropAction m_defAction; 274 Qt::DropActions m_actions; 275 mutable State m_fState; 276 mutable QVariant m_data; 277 }; 278 279 void UIDnDHandler::dragGHPending(CSession &session, ulong screenId, QWidget *pParent /* = 0 */) 280 { 148 int UIDnDHandler::dragGHPending(CSession &session, ulong screenId, QWidget *pParent /* = NULL */) 149 { 150 int rc; 151 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 281 152 /* 282 153 * How this works: Host is asking the guest if there is any DnD … … 289 160 */ 290 161 CGuest guest = session.GetConsole().GetGuest(); 291 QVector<QString> formats; 292 QVector<KDragAndDropAction> actions; 293 KDragAndDropAction defaultAction = guest.DragGHPending(screenId, formats, actions); 162 QVector<QString> vecFmtGuest; 163 QVector<KDragAndDropAction> vecActions; 164 KDragAndDropAction defaultAction = guest.DragGHPending(screenId, vecFmtGuest, vecActions); 165 LogFlowFunc(("defaultAction=%d, numFormats=%d\n", defaultAction, vecFmtGuest.size())); 166 167 /* 168 * Do guest -> host format conversion, if needed. 169 * On X11 this already maps to the Xdnd protocol. 170 ** @todo What about MacOS X Carbon Drag Manager? 171 * 172 * See: https://www.iana.org/assignments/media-types/media-types.xhtml 173 */ 174 LogFlowFunc(("Number of guest formats: %d\n", vecFmtGuest.size())); 175 QStringList lstFmtNative; 176 for (int i = 0; i < vecFmtGuest.size(); i++) 177 { 178 const QString &strFmt = vecFmtGuest.at(i); 179 LogFlowFunc(("\tFormat %d: %s\n", i, 180 strFmt.toAscii().constData())); 181 #ifdef RT_OS_WINDOWS 182 if ( strFmt.contains("text", Qt::CaseInsensitive) 183 && !lstFmtNative.contains("text/plain")) 184 { 185 lstFmtNative << "text/plain"; 186 } 187 #else 188 lstFmtNative << strFmt; 189 #endif 190 } 191 192 LogFlowFunc(("Number of native formats: %d\n", lstFmtNative.size())); 193 #ifdef DEBUG 194 for (int i = 0; i < lstFmtNative.size(); i++) 195 LogFlowFunc(("\tFormat %d: %s\n", i, lstFmtNative.at(i).toAscii().constData())); 196 #endif 294 197 295 198 if ( defaultAction != KDragAndDropAction_Ignore 296 && ! formats.isEmpty())199 && !lstFmtNative.isEmpty()) 297 200 { 298 QDrag *pDrag = new QDrag(pParent); 299 /* pMData is transfered to the QDrag object, so no need for deletion. */ 300 UIDnDMimeData *pMData = new UIDnDMimeData(session, formats.toList(), toQtDnDAction(defaultAction), toQtDnDActions(actions), pParent); 301 /* Inform the mime data object of any changes in the current action. */ 302 connect(pDrag, SIGNAL(actionChanged(Qt::DropAction)), 303 pMData, SLOT(sltActionChanged(Qt::DropAction))); 304 pDrag->setMimeData(pMData); 305 /* Fire it up. */ 306 pDrag->exec(toQtDnDActions(actions), toQtDnDAction(defaultAction)); 201 try 202 { 203 QDrag *pDrag = new QDrag(pParent); 204 205 /* pMData is transfered to the QDrag object, so no need for deletion. */ 206 UIDnDMimeData *pMData = new UIDnDMimeData(session, lstFmtNative, 207 toQtDnDAction(defaultAction), 208 toQtDnDActions(vecActions), pParent); 209 210 /* Inform the MIME data object of any changes in the current action. */ 211 connect(pDrag, SIGNAL(actionChanged(Qt::DropAction)), 212 pMData, SLOT(sltDropActionChanged(Qt::DropAction))); 213 214 /* Fire it up. 215 * 216 * On Windows this will start a modal operation using OLE's 217 * DoDragDrop() method, so this call will block until the DnD operation 218 * is finished. */ 219 pDrag->setMimeData(pMData); 220 pDrag->exec(toQtDnDActions(vecActions), toQtDnDAction(defaultAction)); 221 222 rc = VINF_SUCCESS; 223 } 224 catch (std::bad_alloc) 225 { 226 rc = VERR_NO_MEMORY; 227 } 307 228 } 229 else 230 rc = VINF_SUCCESS; 231 #else 232 rc = VERR_NOT_SUPPORTED; 233 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 234 235 LogFlowFuncLeaveRC(rc); 236 return rc; 308 237 } 309 238 … … 341 270 Qt::DropAction UIDnDHandler::toQtDnDAction(KDragAndDropAction action) 342 271 { 272 Qt::DropAction dropAct = Qt::IgnoreAction; 343 273 if (action == KDragAndDropAction_Copy) 344 returnQt::CopyAction;274 dropAct = Qt::CopyAction; 345 275 if (action == KDragAndDropAction_Move) 346 returnQt::MoveAction;276 dropAct = Qt::MoveAction; 347 277 if (action == KDragAndDropAction_Link) 348 return Qt::LinkAction; 349 350 return Qt::IgnoreAction; 351 } 352 353 Qt::DropActions UIDnDHandler::toQtDnDActions(const QVector<KDragAndDropAction> &actions) 354 { 355 Qt::DropActions a = 0; 356 for (int i = 0; i < actions.size(); ++i) 278 dropAct = Qt::LinkAction; 279 280 LogFlowFunc(("dropAct=0x%x\n", dropAct)); 281 return dropAct; 282 } 283 284 Qt::DropActions UIDnDHandler::toQtDnDActions(const QVector<KDragAndDropAction> &vecActions) 285 { 286 Qt::DropActions dropActs = Qt::IgnoreAction; 287 for (int i = 0; i < vecActions.size(); i++) 357 288 { 358 switch (actions.at(i)) 359 { 360 case KDragAndDropAction_Ignore: a |= Qt::IgnoreAction; break; 361 case KDragAndDropAction_Copy: a |= Qt::CopyAction; break; 362 case KDragAndDropAction_Move: a |= Qt::MoveAction; break; 363 case KDragAndDropAction_Link: a |= Qt::LinkAction; break; 289 switch (vecActions.at(i)) 290 { 291 case KDragAndDropAction_Ignore: 292 dropActs |= Qt::IgnoreAction; 293 break; 294 case KDragAndDropAction_Copy: 295 dropActs |= Qt::CopyAction; 296 break; 297 case KDragAndDropAction_Move: 298 dropActs |= Qt::MoveAction; 299 break; 300 case KDragAndDropAction_Link: 301 dropActs |= Qt::LinkAction; 302 break; 303 default: 304 break; 364 305 } 365 306 } 366 return a; 307 308 LogFlowFunc(("dropActions=0x%x\n", dropActs)); 309 return dropActs; 367 310 } 368 311 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.h
r44529 r50265 1 /* $Id$ */ 1 2 /** @file 2 3 * … … 6 7 7 8 /* 8 * Copyright (C) 2011-201 2Oracle Corporation9 * Copyright (C) 2011-2014 Oracle Corporation 9 10 * 10 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 23 24 #include "COMEnums.h" 24 25 25 /* Forward declarations :*/26 /* Forward declarations. */ 26 27 class QMimeData; 27 28 class CSession; 28 29 class CGuest; 29 30 30 /* Todo: check for making this a full static class when possible. */31 /** @todo Check for making this a full static class when possible. */ 31 32 class UIDnDHandler: public QObject 32 33 { 33 34 public: 34 /* Singleton */35 static UIDnDHandler* instance( )35 /* Singleton factory. */ 36 static UIDnDHandler* instance(void) 36 37 { 37 38 if (!m_pInstance) … … 39 40 return m_pInstance; 40 41 } 41 static void destroy() { delete m_pInstance; m_pInstance = 0; } 42 static void destroy(void) 43 { 44 if (m_pInstance) 45 { 46 delete m_pInstance; 47 m_pInstance = NULL; 48 } 49 } 42 50 43 /* Host -> Guest */44 Qt::DropAction dragHGEnter(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = 0);45 Qt::DropAction dragHGMove (CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = 0);46 Qt::DropAction dragHGDrop (CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = 0);47 void dragHGLeave(CGuest &guest, ulong screenId, QWidget *pParent = 0);51 /* Host -> Guest. */ 52 Qt::DropAction dragHGEnter(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = NULL); 53 Qt::DropAction dragHGMove (CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = NULL); 54 Qt::DropAction dragHGDrop (CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent = NULL); 55 void dragHGLeave(CGuest &guest, ulong screenId, QWidget *pParent = NULL); 48 56 49 /* Guest -> Host */50 void dragGHPending(CSession &session, ulong screenId, QWidget *pParent = 0);57 /* Guest -> Host. */ 58 int dragGHPending(CSession &session, ulong screenId, QWidget *pParent = NULL); 51 59 52 60 private: 53 61 static UIDnDHandler *m_pInstance; 54 62 55 UIDnDHandler( );56 ~UIDnDHandler() {}63 UIDnDHandler(void); 64 virtual ~UIDnDHandler(void) {} 57 65 58 /* Private helpers */66 /* Private helpers. */ 59 67 static KDragAndDropAction toVBoxDnDAction(Qt::DropAction action); 60 68 static QVector<KDragAndDropAction> toVBoxDnDActions(Qt::DropActions actions); 61 69 static Qt::DropAction toQtDnDAction(KDragAndDropAction action); 62 static Qt::DropActions toQtDnDActions(const QVector<KDragAndDropAction> & actions);70 static Qt::DropActions toQtDnDActions(const QVector<KDragAndDropAction> &vecActions); 63 71 64 72 friend class UIDnDMimeData; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r50248 r50265 1169 1169 } 1170 1170 1171 void UIMachineView::handleGHDnd( )1171 void UIMachineView::handleGHDnd(void) 1172 1172 { 1173 1173 /* The guest object to talk to. */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
r48950 r50265 907 907 || cpnt.y() > iCh - 1) 908 908 { 909 if ((mouseButtons.testFlag(Qt::LeftButton))) 909 bool fHandledGHDnD 910 = RT_BOOL(mouseButtons.testFlag(Qt::LeftButton)); 911 if (fHandledGHDnD) 910 912 { 911 913 m_views[uScreenId]->handleGHDnd(); 912 913 return false; 914 return true; 914 915 } 915 916 }
Note:
See TracChangeset
for help on using the changeset viewer.