Changeset 444 for trunk/src/gui/kernel/qdnd_pm.cpp
- Timestamp:
- Dec 30, 2009, 2:32:09 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qdnd_pm.cpp
r442 r444 57 57 #include "qt_os2.h" 58 58 59 #define QDND_DEBUG // in pair with qmime_pm.cpp59 //#define QDND_DEBUG // in pair with qmime_pm.cpp 60 60 61 61 #ifdef QDND_DEBUG … … 89 89 bool hasFormat_sys(const QString &mimeType); 90 90 QStringList formats_sys(); 91 QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type); 91 QVariant retrieveData_sys(const QString &mimeType, 92 QVariant::Type preferredType); 92 93 93 94 private: … … 209 210 210 211 QVariant QPMDragData::retrieveData_sys(const QString &mimeType, 211 QVariant::Type type)212 QVariant::Type preferredType) 212 213 { 213 214 QVariant result; … … 222 223 foreach (QPMMime::DropWorker *w, workers) { 223 224 if (w->hasFormat(mimeType)) { 224 result = w->retrieveData(mimeType, type);225 result = w->retrieveData(mimeType, preferredType); 225 226 break; 226 227 } … … 270 271 MRESULT qt_dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg) 271 272 { 272 // @todo maybe delete last*Op variables 273 274 static HWND lastDragOverHwnd = 0; // last target window 273 static QWidget *lastDragOverWidget = 0; // last target widget 275 274 static USHORT lastDragOverOp = 0; // last DM_DRAGOVER operation 276 275 277 276 static USHORT supportedOps = 0; // operations supported by all items 277 static bool sourceAllowsOp = false; // does source allow requested operation 278 278 279 279 static USHORT lastDropReply = DOR_NEVERDROP; // last reply to DM_DRAGOVER 280 280 static USHORT lastOpRequest = DO_UNKNOWN; // last op requested in DM_DRAGOVER 281 281 282 static Qt::DropAction lastProposedAction = Qt:: IgnoreAction; // last proposed action282 static Qt::DropAction lastProposedAction = Qt::CopyAction; // last proposed action 283 283 static QRect lastAnswerRect; // last accepted rectangle from the target 284 284 // @todo use lastAnswerRect to compress DM_DRAGOVER events … … 289 289 290 290 BOOL ok = FALSE; 291 292 QDragManager *manager = QDragManager::self(); 291 293 292 294 switch (qmsg.msg) { … … 294 296 DEBUG(("DM_DRAGOVER: hwnd %lX di %p x %d y %d", qmsg.hwnd, qmsg.mp1, 295 297 SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2))); 296 297 bool first = lastDragOverHwnd != qmsg.hwnd;298 if (first) {299 // the first DM_DRAGOVER message300 lastDragOverHwnd = qmsg.hwnd;301 lastDropReply = DOR_NEVERDROP;302 lastOpRequest = DO_UNKNOWN;303 lastProposedAction = Qt::IgnoreAction;304 lastAnswerRect = QRect();305 supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;306 // ensure drag data is reset (just in case of a wrong msg flow...)307 dragData.reset();308 }309 310 Q_ASSERT(first || widget->acceptDrops());311 if (!widget->acceptDrops()) {312 if (!first) {313 // Odin32 apps are dramatically bogus, they continue to send314 // DM_DRAGOVER even if we reply DOR_NEVERDROP. Simulate315 // DM_DRAGLEAVE316 lastDragOverHwnd = 0;317 dragData.reset();318 }319 return MRFROM2SHORT(DOR_NEVERDROP, 0);320 }321 298 322 299 DRAGINFO *info = (DRAGINFO *)qmsg.mp1; … … 325 302 if (!ok || !info) 326 303 return MRFROM2SHORT(DOR_NEVERDROP, 0); 304 305 // flip y coordinate 306 QPoint pnt(info->xDrop, info->yDrop); 307 pnt.setY(QApplication::desktop()->height() - (pnt.y() + 1)); 308 pnt = widget->mapFromGlobal(pnt); 309 310 QWidget *dragOverWidget = widget->childAt(pnt); 311 if (!dragOverWidget) 312 dragOverWidget = widget; 313 314 bool first = lastDragOverWidget != dragOverWidget; 315 if (first) { 316 // the first DM_DRAGOVER message 317 if (lastDragOverWidget != 0) { 318 // send drag leave to the old widget 319 dragData.reset(); 320 QPointer<QWidget> dragOverWidgetGuard(dragOverWidget); 321 QDragLeaveEvent dle; 322 QApplication::sendEvent(lastDragOverWidget, &dle); 323 if (!dragOverWidgetGuard) { 324 dragOverWidget = widget->childAt(pnt); 325 if (!dragOverWidget) 326 dragOverWidget = widget; 327 } 328 } 329 lastDragOverWidget = dragOverWidget; 330 lastDragOverOp = 0; 331 supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE; 332 sourceAllowsOp = false; 333 lastDropReply = DOR_NEVERDROP; 334 lastOpRequest = DO_UNKNOWN; 335 lastProposedAction = manager->defaultAction(toQDragDropActions(supportedOps), 336 Qt::NoModifier); 337 lastAnswerRect = QRect(); 338 // ensure drag data is reset (just in case of a wrong msg flow...) 339 dragData.reset(); 340 } 341 342 if (!dragOverWidget->acceptDrops()) { 343 // We don't reply with DOR_NEVERDROP here because in this 344 // case PM will stop sending DM_DRAGOVER to the given HWND but 345 // we may have another non-native child (that has the same HWND) 346 // at a different position that accepts drops 347 DrgFreeDraginfo(info); 348 return MRFROM2SHORT(DOR_NODROP, 0); 349 } 327 350 328 351 USHORT dropReply = DOR_DROP; … … 352 375 if (dropReply != DOR_NEVERDROP) { 353 376 354 bool sourceAllowsOp = false;355 356 377 if (first || lastDragOverOp != info->usOperation) { 357 378 // the current drop operation was changed by a modifier key … … 373 394 // the drop. Other platforms seem to do the same. 374 395 375 // flip y coordinate376 QPoint pnt(info->xDrop, info->yDrop);377 pnt.setY(QApplication::desktop()->height() - (pnt.y() + 1));378 pnt = widget->mapFromGlobal(pnt);379 380 QDragManager *manager = QDragManager::self();381 396 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData; 382 397 … … 388 403 QApplication::mouseButtons(), 389 404 QApplication::keyboardModifiers()); 390 QApplication::sendEvent( widget, &dee);405 QApplication::sendEvent(dragOverWidget, &dee); 391 406 // if not allowed or not accepted, always reply DOR_NODROP 392 // to have DM_DRAGOVER delivered to us again in any case407 // to have DM_DRAGOVER delivered to us again for a new test 393 408 if (sourceAllowsOp && dee.isAccepted()) { 394 409 dropReply = DOR_DROP; 395 410 action = dee.dropAction(); 411 lastProposedAction = dee.proposedAction(); 396 412 lastAnswerRect = dee.answerRect(); 397 413 } else { … … 410 426 dme.setDropAction(action); 411 427 dme.accept(); 412 QApplication::sendEvent( widget, &dme);428 QApplication::sendEvent(dragOverWidget, &dme); 413 429 if (sourceAllowsOp && dme.isAccepted()) { 414 430 dropReply = DOR_DROP; 415 431 action = dme.dropAction(); 432 lastProposedAction = dme.proposedAction(); 433 lastAnswerRect = dme.answerRect(); 416 434 } else { 417 435 dropReply = DOR_NODROP; … … 431 449 432 450 // Odin32 apps produce incorrect message flow, ignore 433 Q_ASSERT(lastDragOver Hwnd!= 0);434 if (lastDragOver Hwnd== 0)451 Q_ASSERT(lastDragOverWidget != 0); 452 if (lastDragOverWidget == 0) 435 453 return 0; 436 454 437 lastDragOverHwnd = 0; 455 QDragLeaveEvent de; 456 QApplication::sendEvent(lastDragOverWidget, &de); 457 458 lastDragOverWidget = 0; 438 459 dragData.reset(); 439 460 440 if (!widget->acceptDrops())441 return 0;442 443 QDragLeaveEvent de;444 QApplication::sendEvent(widget, &de);445 461 return 0; 446 462 } … … 449 465 450 466 // Odin32 apps produce incorrect message flow, ignore 451 Q_ASSERT(lastDragOver Hwnd!= 0);452 if (lastDragOver Hwnd== 0)467 Q_ASSERT(lastDragOverWidget != 0); 468 if (lastDragOverWidget == 0) 453 469 return 0; 454 470 455 471 // Odin32 apps send DM_DROP even if we replied DOR_NEVERDROP or 456 472 // DOR_NODROP, simulate DM_DRAGLEAVE 457 Q_ASSERT(lastDropReply == DM_DROP); 458 if (lastDropReply != DM_DROP) { 459 WinSendMsg(qmsg.hwnd, DM_DRAGLEAVE, 0, 0); 473 Q_ASSERT(lastDropReply == DOR_DROP); 474 if (lastDropReply != DOR_DROP) { 475 QMSG qmsg2 = qmsg; 476 qmsg2.msg = DM_DRAGLEAVE; 477 qt_dispatchDragAndDrop(widget, qmsg2); 460 478 return 0; 461 479 } 462 463 lastDragOverHwnd = 0;464 465 Q_ASSERT(widget->acceptDrops());466 if (!widget->acceptDrops())467 return 0;468 480 469 481 DRAGINFO *info = (DRAGINFO *)qmsg.mp1; … … 471 483 Q_ASSERT(ok && info); 472 484 if (!ok || !info) 473 return MRFROM2SHORT(DOR_NEVERDROP, 0); 474 475 Q_ASSERT(lastOpRequest == info->usOperation); 485 return 0; 476 486 477 487 // flip y coordinate … … 480 490 pnt = widget->mapFromGlobal(pnt); 481 491 492 Q_ASSERT(lastOpRequest == info->usOperation); 493 494 Q_ASSERT(lastDragOverWidget->acceptDrops()); 495 if (!lastDragOverWidget->acceptDrops()) { 496 DrgDeleteDraginfoStrHandles(info); 497 DrgFreeDraginfo(info); 498 return 0; 499 } 500 482 501 QDragManager *manager = QDragManager::self(); 483 502 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData; … … 492 511 de.setDropAction(action); 493 512 494 QApplication::sendEvent( widget, &de);513 QApplication::sendEvent(lastDragOverWidget, &de); 495 514 496 515 if (lastDropReply == DOR_DROP) 497 516 de.accept(); 498 517 518 lastDragOverWidget = 0; 499 519 dragData.reset(de.isAccepted()); 500 520
Note:
See TracChangeset
for help on using the changeset viewer.