Changeset 447 for trunk/src/gui/kernel
- Timestamp:
- Jan 12, 2010, 12:00:10 PM (16 years ago)
- Location:
- trunk/src/gui/kernel
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qapplication_pm.cpp
r438 r447 64 64 #include "qkeymapper_p.h" 65 65 #include "qcursor_p.h" 66 #include "qdnd_p.h" 66 67 67 68 #define WM_KBDLAYERCHANGED 0x0BD4 // defined in OS2TK45/h/pmbidi.h … … 702 703 #define SV_WORKAREA_XLEFT 54 703 704 704 #ifndef QT_NO_DRAGANDDROP705 extern MRESULT qt_dispatchDragAndDrop(QWidget *, const QMSG &); // qdnd_pm.cpp706 #endif707 708 705 /*! 709 706 \internal … … 921 918 #ifndef QT_NO_DRAGANDDROP 922 919 } else if (msg >= WM_DRAGFIRST && msg <= WM_DRAGLAST) { 923 return qt_dispatchDragAndDrop(widget, qmsg);920 return QDragManager::self()->dispatchDragAndDrop(widget, qmsg); 924 921 #endif 925 922 } else { … … 2142 2139 if (rc == RGN_ERROR) { // The update bounding rect is invalid 2143 2140 GpiDestroyRegion(displayPS, hrgn); 2144 d_func()->hd = NULLHANDLE;2145 2141 setAttribute(Qt::WA_PendingUpdate, false); 2146 2142 return false; … … 2166 2162 if (rcl.xRight <= rcl.xLeft || rcl.yTop <= rcl.yBottom) { 2167 2163 WinEndPaint(d_func()->hd); 2164 d_func()->hd = NULLHANDLE; 2168 2165 GpiDestroyRegion(displayPS, hrgn); 2169 d_func()->hd = NULLHANDLE;2170 2166 setAttribute(Qt::WA_PendingUpdate, false); 2171 2167 return true; … … 2173 2169 2174 2170 // flip y coordinate 2175 rcl.yBottom = height() - (rcl.yBottom + 1);2176 rcl.yTop = height() - (rcl.yTop + 1);2177 2178 2171 // note: right top point is exlusive in rcl 2179 QRect updRect(QPoint(rcl.xLeft, rcl.yTop + 1),2180 QPoint(rcl.xRight - 1, rcl.yBottom));2172 QRect updRect(QPoint(rcl.xLeft, height() - rcl.yTop), 2173 QPoint(rcl.xRight - 1, height() - (rcl.yBottom + 1))); 2181 2174 2182 2175 // Mapping region from system to qt (32 bit) coordinate system. -
trunk/src/gui/kernel/qdnd.cpp
r438 r447 358 358 xdndMimeTransferedPixmapIndex = 0; 359 359 #endif 360 #ifdef Q_WS_PM 361 init_sys(); 362 #endif 360 363 } 361 364 … … 363 366 QDragManager::~QDragManager() 364 367 { 368 #ifdef Q_WS_PM 369 uninit_sys(); 370 #endif 365 371 #ifndef QT_NO_CURSOR 366 372 if (restoreCursor) -
trunk/src/gui/kernel/qdnd_p.h
r438 r447 63 63 #ifdef Q_WS_MAC 64 64 # include "private/qt_mac_p.h" 65 #endif 66 67 #if defined(Q_WS_PM) 68 #include "qt_os2.h" 65 69 #endif 66 70 … … 205 209 LPDATAOBJECT currentDataObject; 206 210 #elif defined(Q_WS_PM) 207 friend class Q PMDragData;211 friend class QDragManager; 208 212 QPMDragData *d; 209 213 #endif … … 267 271 #endif 268 272 273 #ifdef Q_WS_PM 274 void init_sys(); 275 void uninit_sys(); 276 void sendDropEvent(QWidget *receiver, QEvent *event); 277 MRESULT dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg); 278 bool isInDrag() const { return inDrag; } 279 #endif 280 269 281 private: 270 282 QPixmap *pm_cursor; … … 272 284 #ifdef Q_WS_QWS 273 285 Qt::DropAction currentActionForOverrideCursor; 286 #endif 287 #ifdef Q_WS_PM 288 bool inDrag; 274 289 #endif 275 290 -
trunk/src/gui/kernel/qdnd_pm.cpp
r444 r447 93 93 94 94 private: 95 friend class QDragManager; 95 96 96 97 void initWorkers(); … … 102 103 DRAGINFO *di; 103 104 QList<QPMMime::DropWorker*> workers; 105 106 QWidget *lastDragOverWidget; // last target widget 107 USHORT lastDragOverOp; // last DM_DRAGOVER operation 108 109 USHORT supportedOps; // operations supported by all items 110 bool sourceAllowsOp : 1; // does source allow requested operation 111 112 USHORT lastDropReply; // last reply to DM_DRAGOVER 113 USHORT lastOpRequest; // last op requested in DM_DRAGOVER 114 115 Qt::DropAction lastProposedAction; // last proposed action 116 QRect lastAnswerRect; // last accepted rectangle from the target 104 117 }; 105 118 … … 107 120 : initialized(false), dropped(false) 108 121 , gotWorkers(false), di(NULL) 109 { 110 QDragManager *manager = QDragManager::self(); 111 Q_ASSERT(!manager->dropData->d); 112 manager->dropData->d = this; 122 , lastDragOverWidget(0), lastDragOverOp(0) 123 , supportedOps(0), sourceAllowsOp(false) 124 , lastDropReply(DOR_NEVERDROP), lastOpRequest(DO_UNKNOWN) 125 , lastProposedAction(Qt::CopyAction) 126 { 113 127 } 114 128 … … 116 130 { 117 131 reset(); 118 119 QDragManager *manager = QDragManager::self();120 if (manager) {121 Q_ASSERT(manager->dropData->d == this);122 manager->dropData->d = 0;123 }124 132 } 125 133 … … 265 273 } 266 274 275 void QDragManager::init_sys() 276 { 277 inDrag = false; 278 279 Q_ASSERT(dropData); 280 Q_ASSERT(!dropData->d); 281 dropData->d = new QPMDragData(); 282 } 283 284 void QDragManager::uninit_sys() 285 { 286 Q_ASSERT(dropData); 287 Q_ASSERT(dropData->d); 288 delete dropData->d; 289 dropData->d = 0; 290 } 291 292 void QDragManager::sendDropEvent(QWidget *receiver, QEvent *event) 293 { 294 Q_ASSERT(!inDrag); 295 inDrag = true; 296 QApplication::sendEvent(receiver, event); 297 // make sure that all issued update requests are handled before we 298 // return from the DM_DRAGOVER/DM_DRAGLEAVE/DM_DROP message; otherwise 299 // we'll get screen corruption due to unexpected screen updates while 300 // dragging 301 QApplication::sendPostedEvents(0, QEvent::UpdateRequest); 302 inDrag = false; 303 } 304 267 305 /*! 268 306 * \internal 269 307 * Direct manipulation (Drag & Drop) event handler 270 308 */ 271 MRESULT qt_dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg) 272 { 273 static QWidget *lastDragOverWidget = 0; // last target widget 274 static USHORT lastDragOverOp = 0; // last DM_DRAGOVER operation 275 276 static USHORT supportedOps = 0; // operations supported by all items 277 static bool sourceAllowsOp = false; // does source allow requested operation 278 279 static USHORT lastDropReply = DOR_NEVERDROP; // last reply to DM_DRAGOVER 280 static USHORT lastOpRequest = DO_UNKNOWN; // last op requested in DM_DRAGOVER 281 282 static Qt::DropAction lastProposedAction = Qt::CopyAction; // last proposed action 283 static QRect lastAnswerRect; // last accepted rectangle from the target 284 // @todo use lastAnswerRect to compress DM_DRAGOVER events 285 286 static QPMDragData dragData; 287 309 MRESULT QDragManager::dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg) 310 { 288 311 Q_ASSERT(widget); 289 312 … … 291 314 292 315 QDragManager *manager = QDragManager::self(); 316 QPMDragData *dragData = manager->dropData->d; 317 Q_ASSERT(dragData); 318 319 // @todo use dragData->lastAnswerRect to compress DM_DRAGOVER events 293 320 294 321 switch (qmsg.msg) { … … 312 339 dragOverWidget = widget; 313 340 314 bool first = lastDragOverWidget != dragOverWidget;341 bool first = dragData->lastDragOverWidget != dragOverWidget; 315 342 if (first) { 316 343 // the first DM_DRAGOVER message 317 if ( lastDragOverWidget != 0) {344 if (dragData->lastDragOverWidget != 0) { 318 345 // send drag leave to the old widget 319 dragData .reset();346 dragData->reset(); 320 347 QPointer<QWidget> dragOverWidgetGuard(dragOverWidget); 321 348 QDragLeaveEvent dle; 322 QApplication::sendEvent(lastDragOverWidget, &dle);349 sendDropEvent(dragData->lastDragOverWidget, &dle); 323 350 if (!dragOverWidgetGuard) { 324 351 dragOverWidget = widget->childAt(pnt); … … 327 354 } 328 355 } 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(); 356 dragData->lastDragOverWidget = dragOverWidget; 357 dragData->lastDragOverOp = 0; 358 dragData->supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE; 359 dragData->sourceAllowsOp = false; 360 dragData->lastDropReply = DOR_NEVERDROP; 361 dragData->lastOpRequest = DO_UNKNOWN; 362 dragData->lastProposedAction = 363 manager->defaultAction(toQDragDropActions(dragData->supportedOps), 364 Qt::NoModifier); 365 dragData->lastAnswerRect = QRect(); 338 366 // ensure drag data is reset (just in case of a wrong msg flow...) 339 dragData .reset();367 dragData->reset(); 340 368 } 341 369 … … 362 390 break; 363 391 } 364 supportedOps &= item->fsSupportedOps;392 dragData->supportedOps &= item->fsSupportedOps; 365 393 } 366 394 if (dropReply != DOR_NEVERDROP) { 367 395 Q_ASSERT(itemCount); 368 if (!itemCount || ! supportedOps) {396 if (!itemCount || !dragData->supportedOps) { 369 397 // items don't have even a single common operation... 370 398 dropReply = DOR_NEVERDROP; … … 375 403 if (dropReply != DOR_NEVERDROP) { 376 404 377 if (first || lastDragOverOp != info->usOperation) {405 if (first || dragData->lastDragOverOp != info->usOperation) { 378 406 // the current drop operation was changed by a modifier key 379 lastDragOverOp = info->usOperation;407 dragData->lastDragOverOp = info->usOperation; 380 408 USHORT realOp = info->usOperation; 381 409 if (realOp == DO_DEFAULT || realOp == DO_UNKNOWN) { 382 410 // the default operation is requested 383 realOp = toPmDragDropOp( lastProposedAction);411 realOp = toPmDragDropOp(dragData->lastProposedAction); 384 412 } 385 sourceAllowsOp =386 (( supportedOps & DO_MOVEABLE) && realOp == DO_MOVE) ||387 (( supportedOps & DO_COPYABLE) && realOp == DO_COPY) ||388 (( supportedOps & DO_LINKABLE) && realOp == DO_LINK);413 dragData->sourceAllowsOp = 414 ((dragData->supportedOps & DO_MOVEABLE) && realOp == DO_MOVE) || 415 ((dragData->supportedOps & DO_COPYABLE) && realOp == DO_COPY) || 416 ((dragData->supportedOps & DO_LINKABLE) && realOp == DO_LINK); 389 417 } 390 418 … … 396 424 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData; 397 425 398 Qt::DropAction action = toQDragDropAction( lastOpRequest);426 Qt::DropAction action = toQDragDropAction(dragData->lastOpRequest); 399 427 400 428 if (first) { 401 dragData.initialize(info); 402 QDragEnterEvent dee(pnt, toQDragDropActions(supportedOps), data, 403 QApplication::mouseButtons(), 429 dragData->initialize(info); 430 QDragEnterEvent dee(pnt, 431 toQDragDropActions(dragData->supportedOps), 432 data, QApplication::mouseButtons(), 404 433 QApplication::keyboardModifiers()); 405 QApplication::sendEvent(dragOverWidget, &dee);434 sendDropEvent(dragOverWidget, &dee); 406 435 // if not allowed or not accepted, always reply DOR_NODROP 407 436 // to have DM_DRAGOVER delivered to us again for a new test 408 if ( sourceAllowsOp && dee.isAccepted()) {437 if (dragData->sourceAllowsOp && dee.isAccepted()) { 409 438 dropReply = DOR_DROP; 410 439 action = dee.dropAction(); 411 lastProposedAction = dee.proposedAction();412 lastAnswerRect = dee.answerRect();440 dragData->lastProposedAction = dee.proposedAction(); 441 dragData->lastAnswerRect = dee.answerRect(); 413 442 } else { 414 443 dropReply = DOR_NODROP; … … 420 449 // the target accepts it) 421 450 if (!first || dropReply == DOR_DROP) { 422 QDragEnterEvent dme(pnt, toQDragDropActions(supportedOps), data, 423 QApplication::mouseButtons(), 424 QApplication::keyboardModifiers()); 451 QDragMoveEvent dme(pnt, 452 toQDragDropActions(dragData->supportedOps), 453 data, QApplication::mouseButtons(), 454 QApplication::keyboardModifiers()); 425 455 // accept by default, since enter event was accepted. 426 456 dme.setDropAction(action); 427 457 dme.accept(); 428 QApplication::sendEvent(dragOverWidget, &dme);429 if ( sourceAllowsOp && dme.isAccepted()) {458 sendDropEvent(dragOverWidget, &dme); 459 if (dragData->sourceAllowsOp && dme.isAccepted()) { 430 460 dropReply = DOR_DROP; 431 461 action = dme.dropAction(); 432 lastProposedAction = dme.proposedAction();433 lastAnswerRect = dme.answerRect();462 dragData->lastProposedAction = dme.proposedAction(); 463 dragData->lastAnswerRect = dme.answerRect(); 434 464 } else { 435 465 dropReply = DOR_NODROP; … … 437 467 } 438 468 439 lastDropReply = dropReply;440 lastOpRequest = toPmDragDropOp(action);469 dragData->lastDropReply = dropReply; 470 dragData->lastOpRequest = toPmDragDropOp(action); 441 471 } 442 472 443 473 DrgFreeDraginfo(info); 444 474 445 return MRFROM2SHORT(dropReply, lastOpRequest);475 return MRFROM2SHORT(dropReply, dragData->lastOpRequest); 446 476 } 447 477 case DM_DRAGLEAVE: { … … 449 479 450 480 // Odin32 apps produce incorrect message flow, ignore 451 Q_ASSERT( lastDragOverWidget != 0);452 if ( lastDragOverWidget == 0)481 Q_ASSERT(dragData->lastDragOverWidget != 0); 482 if (dragData->lastDragOverWidget == 0) 453 483 return 0; 454 484 455 485 QDragLeaveEvent de; 456 QApplication::sendEvent(lastDragOverWidget, &de);457 458 lastDragOverWidget = 0;459 dragData .reset();486 sendDropEvent(dragData->lastDragOverWidget, &de); 487 488 dragData->lastDragOverWidget = 0; 489 dragData->reset(); 460 490 461 491 return 0; … … 465 495 466 496 // Odin32 apps produce incorrect message flow, ignore 467 Q_ASSERT( lastDragOverWidget != 0);468 if ( lastDragOverWidget == 0)497 Q_ASSERT(dragData->lastDragOverWidget != 0); 498 if (dragData->lastDragOverWidget == 0) 469 499 return 0; 470 500 471 501 // Odin32 apps send DM_DROP even if we replied DOR_NEVERDROP or 472 502 // DOR_NODROP, simulate DM_DRAGLEAVE 473 Q_ASSERT( lastDropReply == DOR_DROP);474 if ( lastDropReply != DOR_DROP) {503 Q_ASSERT(dragData->lastDropReply == DOR_DROP); 504 if (dragData->lastDropReply != DOR_DROP) { 475 505 QMSG qmsg2 = qmsg; 476 506 qmsg2.msg = DM_DRAGLEAVE; 477 qt_dispatchDragAndDrop(widget, qmsg2);507 dispatchDragAndDrop(widget, qmsg2); 478 508 return 0; 479 509 } … … 490 520 pnt = widget->mapFromGlobal(pnt); 491 521 492 Q_ASSERT( lastOpRequest == info->usOperation);493 494 Q_ASSERT( lastDragOverWidget->acceptDrops());495 if (! lastDragOverWidget->acceptDrops()) {522 Q_ASSERT(dragData->lastOpRequest == info->usOperation); 523 524 Q_ASSERT(dragData->lastDragOverWidget->acceptDrops()); 525 if (!dragData->lastDragOverWidget->acceptDrops()) { 496 526 DrgDeleteDraginfoStrHandles(info); 497 527 DrgFreeDraginfo(info); … … 499 529 } 500 530 501 QDragManager *manager = QDragManager::self();502 531 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData; 503 532 504 Qt::DropAction action = toQDragDropAction( lastOpRequest);505 506 dragData .setDropped(true);533 Qt::DropAction action = toQDragDropAction(dragData->lastOpRequest); 534 535 dragData->setDropped(true); 507 536 508 537 QDropEvent de(pnt, action, data, QApplication::mouseButtons(), 509 538 QApplication::keyboardModifiers()); 510 if ( lastDropReply == DOR_DROP)539 if (dragData->lastDropReply == DOR_DROP) 511 540 de.setDropAction(action); 512 541 513 QApplication::sendEvent(lastDragOverWidget, &de);514 515 if ( lastDropReply == DOR_DROP)542 sendDropEvent(dragData->lastDragOverWidget, &de); 543 544 if (dragData->lastDropReply == DOR_DROP) 516 545 de.accept(); 517 546 518 lastDragOverWidget = 0;519 dragData .reset(de.isAccepted());547 dragData->lastDragOverWidget = 0; 548 dragData->reset(de.isAccepted()); 520 549 521 550 ULONG targetReply = de.isAccepted() ? -
trunk/src/gui/kernel/qwidget.cpp
r352 r447 86 86 #if defined (Q_WS_WIN) 87 87 # include <private/qwininputcontext_p.h> 88 #endif 89 90 #if defined (Q_WS_PM) 91 # include "qdnd_p.h" 88 92 #endif 89 93 … … 10411 10415 if (d->hd != NULLHANDLE) 10412 10416 return (HPS) d->hd; 10417 #ifndef QT_NO_DRAGANDDROP 10418 if (QDragManager::self()->isInDrag()) 10419 return DrgGetPS(winId()); 10420 #endif 10413 10421 return WinGetPS(winId()); 10414 10422 } … … 10424 10432 // If there is a widget's own ps, the release operation is ignored because 10425 10433 // it will be released elsewhere. Otherwise, we assume that the given hps 10426 // was acquired by WinGetPS in the getPS() call and release it. 10427 if (d->hd == NULLHANDLE) 10434 // was acquired by DrgGetPS/WinGetPS in the getPS() call and release it. 10435 if (d->hd == NULLHANDLE) { 10436 #ifndef QT_NO_DRAGANDDROP 10437 if (QDragManager::self()->isInDrag()) 10438 DrgReleasePS(hps); 10439 else 10440 #endif 10428 10441 WinReleasePS(hps); 10442 } 10429 10443 } 10430 10444 #else
Note:
See TracChangeset
for help on using the changeset viewer.