Changeset 451 for trunk/src/gui/kernel


Ignore:
Timestamp:
Jan 20, 2010, 12:56:59 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: DnD: Support changing the DnD operation (Copy, Move, Link) on the fly, e.g. after the DnD session was started.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/kernel/qdnd_pm.cpp

    r450 r451  
    292292}
    293293
     294// Equivalent of QApplication::mouseButtons() (mouse events aren't delivered
     295// to the window during DnD in PM so this metnod returns an incorrect value).
     296static Qt::MouseButtons mouseButtons()
     297{
     298    Qt::MouseButtons buttons = Qt::NoButton;
     299
     300    if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
     301        buttons |= Qt::LeftButton;
     302    if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
     303        buttons |= Qt::RightButton;
     304    if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
     305        buttons |= Qt::MidButton;
     306
     307    return buttons;
     308}
     309
     310// Equivalent of QApplication::keyboardModifiers() (keyboard events aren't delivered
     311// to the window during DnD in PM so this metnod returns an incorrect value).
     312static Qt::KeyboardModifiers keyboardModifiers()
     313{
     314    Qt::KeyboardModifiers mods = Qt::NoModifier;
     315
     316    if (WinGetKeyState(HWND_DESKTOP, VK_SHIFT ) & 0x8000)
     317        mods |= Qt::ShiftModifier;
     318    if ((WinGetKeyState(HWND_DESKTOP, VK_ALT) & 0x8000) ||
     319        (WinGetKeyState(HWND_DESKTOP, VK_ALTGRAF) & 0x8000))
     320        mods |= Qt::AltModifier;
     321    if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000)
     322        mods |= Qt::ControlModifier;
     323
     324    // Note: we cannot properly detect LWIN/RWIN (Meta) key state here as it
     325    // doesn't have a corresponding VK_ value. The best we can do is to check
     326    // the physical keyboard state using the hardware scancode but it has the
     327    // following problems:
     328    //
     329    //   1. The physical keyboard state may be out of sync with the current
     330    //      input message we are processing.
     331    //   2. The scancode may be hardware dependent
     332    //
     333    // 0x7E is what I get as a scancode value for LWIN from PM here.
     334    // Unfortunately, I have no keyboard with RWIN around so I can't get its
     335    // scan code.
     336
     337    if (WinGetPhysKeyState(HWND_DESKTOP, 0x7E) & 0x8000)
     338        mods |= Qt::MetaModifier;
     339
     340    return mods;
     341}
     342
    294343void QDragManager::init_sys()
    295344{
     
    448497                    QDragEnterEvent dee(pnt,
    449498                                        toQDragDropActions(dragData->supportedOps),
    450                                         data, QApplication::mouseButtons(),
    451                                         QApplication::keyboardModifiers());
     499                                        data, mouseButtons(), keyboardModifiers());
    452500                    dee.setDropAction(dragData->lastAction);
    453501                    sendDropEvent(dragOverWidget, &dee);
     
    469517                    QDragMoveEvent dme(pnt,
    470518                                       toQDragDropActions(dragData->supportedOps),
    471                                        data, QApplication::mouseButtons(),
    472                                        QApplication::keyboardModifiers());
     519                                       data, mouseButtons(), keyboardModifiers());
    473520                    // accept by default, since enter event was accepted.
    474521                    dme.setDropAction(dragData->lastAction);
     
    549596            dragData->setDropped(true);
    550597
    551             QDropEvent de(pnt, dragData->lastAction, data, QApplication::mouseButtons(),
    552                           QApplication::keyboardModifiers());
     598            QDropEvent de(pnt, dragData->lastAction, data, mouseButtons(),
     599                          keyboardModifiers());
    553600            if (dragData->lastDropReply == DOR_DROP)
    554601                de.setDropAction(dragData->lastAction);
     
    651698    // QPMObjectWindow interface
    652699    MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2);
    653    
     700
    654701private:
    655702    QList<DragWorker*> workers;
     
    667714    bool gotExcl = false; // got isExclusive() worker?
    668715    bool skipExcl = false; // skip isExclusive() or itemCount() > 1 workers?
    669     ULONG coopLevel = 0; // itemCount() level for !isExclusive() workers 
     716    ULONG coopLevel = 0; // itemCount() level for !isExclusive() workers
    670717
    671718    bool gotExclForMime = false;
     
    734781            // target's side (where the first encountered drop worker
    735782            // for the given RMF would be used for actual data transfer
    736             // anyway). See also QClipboard::setData(). 
     783            // anyway). See also QClipboard::setData().
    737784            break;
    738785        }
     
    755802
    756803    // remove either all exclusive workers or all their fall-back workers
    757     // (depending on skipExcl) and remove duplicates 
     804    // (depending on skipExcl) and remove duplicates
    758805    for (QList<DragWorker*>::iterator it = workers.begin();
    759806         it < workers.end();) {
     
    767814    }
    768815
    769 #if defined(QDND_DEBUG)           
     816#if defined(QDND_DEBUG)
    770817    foreach (DragWorker *wrk, workers) {
    771818        DEBUG(() << "QPMCoopDragWorker: Will use worker" << wrk
    772819                 << "( isExclusive" << wrk->isExclusive()
    773                  << "itemCount" << wrk->itemCount() << ")"); 
     820                 << "itemCount" << wrk->itemCount() << ")");
    774821    }
    775822#endif
     
    785832    if (!firstWorker)
    786833        return 0;
    787    
     834
    788835    if (firstWorker->isExclusive() && firstWorker->itemCount() == 0) {
    789836        // this is a super exclusive worker that will do everything on its own
    790837        return firstWorker->hwnd();
    791838    }
    792    
     839
    793840    return QPMObjectWindow::hwnd();
    794841}
     
    806853{
    807854    bool moveDisallowed = false;
    808    
     855
    809856    foreach(DragWorker *wrk, workers) {
    810857        // disallow the Move operation if at least one worker asked so
     
    837884        return firstWorker->createDragInfo(targetName, supportedOps);
    838885    }
    839    
     886
    840887    // note that all workers at this place require the same amount of items
    841888    // (guaranteed by collectWorkers())
    842    
     889
    843890    DEBUG(() << "QPMCoopDragWorker: itemCnt" << itemCnt);
    844891
     
    847894    if (!info)
    848895        return 0;
    849    
     896
    850897    // collect all mechanism/format pairs
    851898    QByteArray allFormats;
     
    866913
    867914    static ULONG itemID = 0;
    868    
     915
    869916    const char *type = 0;
    870917    const char *ext = 0;
     
    885932        else
    886933            name = QString(QLatin1String("%1 %2")).arg(targetName).arg(i + 1);
    887        
     934
    888935        if (ext) {
    889936            name += QLatin1Char('.');
     
    896943        // Note 1: DRAGITEM::hstrType is actually ignored by WPS,
    897944        // only the target extension matters.
    898        
     945
    899946        // Note 2: We're not required to fill in the hwndItem field because we
    900947        // use the DC_PREPARE flag (to indicate it will be filled later, after
    901948        // DM_RENDERPREPARE); however, Mozilla refuses to render if hwndItem
    902949        // is initially 0. Set it to our HWND instead (we'll issue a warning if
    903         // DM_RENDER or DM_ENDCONVERSATION is erroneously sent to us) 
     950        // DM_RENDER or DM_ENDCONVERSATION is erroneously sent to us)
    904951
    905952        item->hwndItem = hwnd();
     
    915962        item->fsSupportedOps = supportedOps;
    916963    }
    917    
     964
    918965    if (!ok) {
    919966        DrgFreeDraginfo(info);
    920967        info = 0;
    921968    }
    922    
     969
    923970    return info;
    924971}
     
    930977            DEBUG(() << "Drop target sent DM_RENDERPREPARE after the DnD "
    931978                        "session is over!");
    932             // free the given DRAGTRANSFER structure to avoud memory leak 
     979            // free the given DRAGTRANSFER structure to avoud memory leak
    933980            DRAGTRANSFER *xfer = (DRAGTRANSFER *)mp1;
    934981            if (xfer)
     
    936983            return (MRESULT)FALSE;
    937984        }
    938    
     985
    939986        DRAGTRANSFER *xfer = (DRAGTRANSFER *)mp1;
    940987        Q_ASSERT(xfer && xfer->pditem);
    941988        if (!xfer || !xfer->pditem)
    942989            return (MRESULT)FALSE;
    943        
     990
    944991        // find the item's index (ordinal number)
    945992        ULONG itemCnt = DrgQueryDragitemCount(info);
     
    948995            if (DrgQueryDragitemPtr(info, index) == xfer->pditem)
    949996                break;
    950        
     997
    951998        Q_ASSERT(index < itemCnt);
    952999        if (index >= itemCnt)
     
    9561003                 << QPMMime::queryHSTR(xfer->hstrSelectedRMF) << "for item"
    9571004                 << index << "( id" << xfer->pditem->ulItemID << ")");
    958        
     1005
    9591006        QByteArray drm, drf;
    9601007        if (!QPMMime::parseRMF(xfer->hstrSelectedRMF, drm, drf)) {
     
    9761023        return (MRESULT)(xfer->pditem->hwndItem ? TRUE : FALSE);
    9771024    }
    978    
     1025
    9791026    if (msg == DM_RENDER || msg == DM_ENDCONVERSATION) {
    9801027        DEBUG(() << "Drop target sent DM_RENDER or DM_ENDCONVERSATION to the "
    9811028                    "drag source window instead of the drag item window!");
    9821029        if (msg == DM_RENDER) {
    983             // free the given DRAGTRANSFER structure to avoud memory leak 
     1030            // free the given DRAGTRANSFER structure to avoud memory leak
    9841031            DRAGTRANSFER *xfer = (DRAGTRANSFER *)mp1;
    9851032            if (xfer)
     
    9871034        }
    9881035    }
    989    
     1036
    9901037    return (MRESULT)FALSE;
    9911038}
     
    10141061        ULONG msg = WinQuerySysValue(HWND_DESKTOP, SV_BEGINDRAG) & 0xFFFF;
    10151062        switch(msg) {
    1016             case WM_BUTTON1MOTIONSTART: vkTerminate = VK_BUTTON1; break; 
    1017             case WM_BUTTON2MOTIONSTART: vkTerminate = VK_BUTTON2; break; 
    1018             case WM_BUTTON3MOTIONSTART: vkTerminate = VK_BUTTON3; break; 
     1063            case WM_BUTTON1MOTIONSTART: vkTerminate = VK_BUTTON1; break;
     1064            case WM_BUTTON2MOTIONSTART: vkTerminate = VK_BUTTON2; break;
     1065            case WM_BUTTON3MOTIONSTART: vkTerminate = VK_BUTTON3; break;
    10191066        }
    10201067
     
    10421089
    10431090    static QPMCoopDragWorker dragWorker;
    1044    
     1091
    10451092    bool ok = dragWorker.collectWorkers(o);
    10461093    Q_ASSERT(ok);
     
    10981145    bool moveDisallowed = dragWorker.cleanup(beingCancelled || target == 0);
    10991146    dragWorker.src = 0;
    1100    
     1147
    11011148    moveDisallowed |= beingCancelled || target == 0 ||
    11021149                      info->usOperation != DO_MOVE;
     
    11391186    if (!object || beingCancelled)
    11401187        return;
    1141    
     1188
    11421189    beingCancelled = true;
    11431190
Note: See TracChangeset for help on using the changeset viewer.