Changeset 434

Timestamp:
Dec 22, 2009, 2:34:55 AM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Implemented proper generation of possible key and modifier combinations for a given key event. This in particular enables Ctrl+<letter> shortcuts for non-Latin languages and also makes Ctrl+<letter>, Alt+<letter> and similar shortcuts language-neutral. See #50 for details.

Location:
trunk/src/gui/kernel
Files:
4 edited

Legend:

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

    r432 r434  
    6565#include "qcursor_p.h"
    6666
     67
     68
    6769//#define QT_DEBUGMSGFLOW
    6870
     
    944946
    945947            case WM_CHAR: { // keyboard event
     948
     949
     950
    946951                QWidget *g = QWidget::keyboardGrabber();
    947952                if (g)
     
    966971                        return (MRESULT)TRUE;
    967972                }
     973
     974
     975
     976
     977
    968978                break;
    969979            }
     
    25292539    myCaseEnd()
    25302540
     2541
     2542
     2543
     2544
     2545
    25312546    myCaseBegin(WM_PAINT)
    25322547        break;
  • trunk/src/gui/kernel/qkeymapper.cpp

    r2 r434  
    9191void QKeyMapper::changeKeyboard()
    9292{
     93
     94
     95
     96
    9397    instance()->d_func()->clearMappings();
     98
    9499
    95100    // inform all toplevel widgets of the change
  • trunk/src/gui/kernel/qkeymapper_p.h

    r136 r434  
    166166#elif defined(Q_WS_PM)
    167167
     168
    168169    bool translateKeyEvent(QWidget *receiver, const QMSG &qmsg, bool grab);
    169170
    170171    int extraKeyState;
     172
     173
    171174
    172175#elif defined(Q_WS_X11)
  • trunk/src/gui/kernel/qkeymapper_pm.cpp

    r433 r434  
    4949#include "qt_os2.h"
    5050
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
    5172QT_BEGIN_NAMESPACE
    52 
    53 //#define DEBUG_KEYMAPPER
    5473
    5574// Key recorder ----------------------------------------------------[ start ] --
     
    246265// Keyboard map private --------------------------------------------[ start ]---
    247266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
    248311QKeyMapperPrivate::QKeyMapperPrivate()
    249312{
     
    252315    extraKeyState = 0;
    253316
    254    // @todo implement
     317   
    255318}
    256319
     
    262325void QKeyMapperPrivate::clearMappings()
    263326{
    264     // @todo implement
     327    for (int i = 0; i < KeyLayoutSize; ++i) {
     328        if (keyLayout[i]) {
     329            delete keyLayout[i];
     330            keyLayout[i] = 0;
     331        }
     332    }
    265333}
    266334
     
    269337    QList<int> result;
    270338
    271     // @todo implement; so far do the same as QKeyMapper::possibleKeys()
    272     if (e->key() && (e->key() != Qt::Key_unknown))
    273         result << int(e->key() + e->modifiers());
    274     else if (!e->text().isEmpty())
    275         result << int(e->text().at(0).unicode() + e->modifiers());
     339    KeyboardLayoutItem *kbItem = keyLayout[e->nativeScanCode()];
     340    if(!kbItem) {
     341#ifdef DEBUG_KEYMAPPER
     342        qDebug("QKeyMapperPrivate::possibleKeys: none");
     343#endif
     344        return result;
     345    }
     346
     347    int baseKey0 = kbItem->qtKey[0][0] ? kbItem->qtKey[0][0] :
     348                   e->key() && e->key() != Qt::Key_unknown ? e->key() :
     349                   e->text().at(0).unicode();
     350
     351    int baseKey1 = baseKey0;
     352    if (kbItem->layoutIds[1])
     353        kbItem->qtKey[0][1] ? kbItem->qtKey[0][1] :
     354                   e->key() && e->key() != Qt::Key_unknown ? e->key() :
     355                   e->text().at(0).unicode();
     356
     357    Qt::KeyboardModifiers keyMods = e->modifiers();
     358
     359    // The base key is _always_ valid, of course
     360    result << int(baseKey0 + keyMods);
     361    if (baseKey1 != baseKey0)
     362        result << int(baseKey1 + keyMods);
     363
     364    // go through both keyboard layouts
     365    for (int j = 0; j < 2; ++j) {
     366        // check if we skipped the layout in updateKeyMap() and skip too if so
     367        if (!kbItem->layoutIds[j])
     368            continue;
     369        // go through all modifiers
     370        for(int i = 0; i < KeyboardLayoutItem::QtKeySize; ++i) {
     371            Qt::KeyboardModifiers neededMods = QtModsTbl[i];
     372            int key = kbItem->qtKey[i][j];
     373            if (key && key != baseKey0 && key != baseKey1 &&
     374                ((keyMods & neededMods) == neededMods)) {
     375                int k = int(key + (keyMods & ~neededMods));
     376                if (!result.contains(k))
     377                    result << k;
     378            }
     379        }
     380    }
     381
     382#ifdef DEBUG_KEYMAPPER
     383    qDebug("QKeyMapperPrivate::possibleKeys:");
     384    foreach(int k, result)
     385        qDebug("    0x%x", k);
     386#endif
     387
    276388    return result;
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
     460
     461
     462
    277463}
    278464
     
    334520    // char code in the high byte of chm.chr (probably this is less
    335521    // device-dependent than scancode)
    336     switch (chm.chr) {
    337         case 0xEC00: // LWIN
    338         case 0xED00: // RWIN
    339             code = Qt::Key_Meta;
    340             if (!(chm.fs & KC_KEYUP))
    341                 extraKeyState |= Qt::MetaModifier;
    342             else
    343                 extraKeyState &= ~Qt::MetaModifier;
    344             break;
    345         case 0xEE00: // WINAPP (menu with arrow)
    346             code = Qt::Key_Menu;
    347             break;
    348         case 0x5600: // additional '\' (0x56 is actually its scancode)
    349             chm.chr = state & Qt::ShiftModifier ? '|' : '\\';
    350             break;
    351         case 0xFA00: // Back
    352             code = Qt::Key_Back;
    353             break;
    354         case 0xF900: // Forward
    355             code = Qt::Key_Forward;
    356             break;
    357         case 0x2064: // Volume Mute
    358             code = Qt::Key_VolumeMute;
    359             break;
    360         case 0x2E63: // Volume Down
    361             code = Qt::Key_VolumeDown;
    362             break;
    363         case 0x3062: // Volume Up
    364             code = Qt::Key_VolumeUp;
    365             break;
    366         case 0x2267: // Play/Pause
    367             code = Qt::Key_MediaPlay;
    368             break;
    369         case 0x326D: // Web/Home
    370             code = Qt::Key_HomePage;
    371             break;
    372         case 0xF500: // Search
    373             code = Qt::Key_Search;
    374             break;
    375         case 0xF600: // Favorites
    376             code = Qt::Key_Favorites;
    377             break;
    378         }
     522    if (!code){
     523        switch (chm.chr) {
     524            case 0xEC00: // LWIN
     525            case 0xED00: // RWIN
     526                code = Qt::Key_Meta;
     527                if (!(chm.fs & KC_KEYUP))
     528                    extraKeyState |= Qt::MetaModifier;
     529                else
     530                    extraKeyState &= ~Qt::MetaModifier;
     531                break;
     532            case 0xEE00: // WINAPP (menu with arrow)
     533                code = Qt::Key_Menu;
     534                break;
     535            case 0x5600: // additional '\' (0x56 is actually its scancode)
     536                chm.chr = state & Qt::ShiftModifier ? '|' : '\\';
     537                break;
     538            case 0xFA00: // Back
     539                code = Qt::Key_Back;
     540                break;
     541            case 0xF900: // Forward
     542                code = Qt::Key_Forward;
     543                break;
     544            case 0x2064: // Volume Mute
     545                code = Qt::Key_VolumeMute;
     546                break;
     547            case 0x2E63: // Volume Down
     548                code = Qt::Key_VolumeDown;
     549                break;
     550            case 0x3062: // Volume Up
     551                code = Qt::Key_VolumeUp;
     552                break;
     553            case 0x2267: // Play/Pause
     554                code = Qt::Key_MediaPlay;
     555                break;
     556            case 0x326D: // Web/Home
     557                code = Qt::Key_HomePage;
     558                break;
     559            case 0xF500: // Search
     560                code = Qt::Key_Search;
     561                break;
     562            case 0xF600: // Favorites
     563                code = Qt::Key_Favorites;
     564                break;
     565        }
     566    }
    379567
    380568    // update state after updating extraKeyState
Note: See TracChangeset for help on using the changeset viewer.