Changeset 179 for trunk/src


Ignore:
Timestamp:
Sep 12, 2009, 2:10:36 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Implemented support for entering dead keys from the keyboard (#68).

File:
1 edited

Legend:

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

    r169 r179  
    197197};
    198198
     199// Converts known accent symbols to their Key_Dead_ equivalents.
     200static inline int deadCharToDeadKeyCode(const QChar &ch)
     201{
     202    switch (ch.unicode()) {
     203    case 0x0060: return Qt::Key_Dead_Grave;
     204    case 0x00B4: return Qt::Key_Dead_Acute;
     205    case 0x005E: return Qt::Key_Dead_Circumflex;
     206    case 0x007E: return Qt::Key_Dead_Tilde;
     207    case 0x00AF: return Qt::Key_Dead_Macron;
     208    case 0x02D8: return Qt::Key_Dead_Breve;
     209    case 0x02D9: return Qt::Key_Dead_Abovedot;
     210    case 0x00A8: return Qt::Key_Dead_Diaeresis;
     211    case 0x02DA: return Qt::Key_Dead_Abovering;
     212    case 0x02DD: return Qt::Key_Dead_Doubleacute;
     213    case 0x02C7: return Qt::Key_Dead_Caron;
     214    case 0x00B8: return Qt::Key_Dead_Cedilla;
     215    case 0x02DB: return Qt::Key_Dead_Ogonek;
     216    case 0x1DA5: return Qt::Key_Dead_Iota; // @todo is that correct???
     217    case 0x3099: return Qt::Key_Dead_Voiced_Sound;
     218    case 0x309A: return Qt::Key_Dead_Semivoiced_Sound;
     219    case 0x0323: return Qt::Key_Dead_Belowdot;
     220    case 0x02DE: return Qt::Key_Dead_Hook;
     221    case 0x031B: return Qt::Key_Dead_Horn;
     222    default: break;
     223    }
     224
     225    // otherwise, return unmodified unicode value (similar to charToKeycode())
     226    return ch.unicode();
     227}
     228
    199229// Key translation ---------------------------------------------------[ end ]---
    200230
     
    241271}
    242272
    243 static inline int asciiToKeycode(char a, int state)
    244 {
    245     if (a >= 'a' && a <= 'z')
    246         a = toupper(a);
    247     if ((state & Qt::ControlModifier) != 0) {
    248         if (a >= 0 && a <= 31)              // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
    249             a += '@';                       // to @..A..Z.._
    250     }
    251     return a & 0xff;
     273static inline int charToKeycode(const QChar &ch, int state)
     274{
     275    if (!ch.row()) {
     276        if ((state & Qt::ControlModifier) != 0) {
     277            int ascii = ch.cell();
     278            if (ascii >= 0 && ascii <= 31)  // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
     279                return ascii + '@';         // to @..A..Z.._
     280        }
     281    }
     282
     283    return ch.toUpper().unicode();
    252284}
    253285
     
    383415            QString text;
    384416            if (chm.chr) {
    385                 // Note: We ignore the KC_CHAR flag when generating text for the
    386                 // key in order to get correct (non-null) text even for Alt+Letter
    387                 // combinations (that don't have KC_CHAR set) because processing
    388                 // Alt+Letter shortcuts for non-ASCII letters in widgets (e.g.
    389                 // QPushButton) depends on that.
     417                // Note: We ignore the KC_CHAR flag when deciding whether to
     418                // generate text for the key because we want to get correct
     419                // (non-null) text for Alt+Letter combinations (that don't have
     420                // KC_CHAR set): processing Alt+Letter shortcuts for non-ASCII
     421                // letters in widgets (e.g. QPushButton) depends on that.
    390422                if ((chm.fs & (KC_VIRTUALKEY | KC_CHAR)) == KC_CHAR && (chm.chr & 0xFF00)) {
    391                     // We assime we get a DBCS char if the above condition is met.
     423                    // We assume we get a DBCS char if the above condition is met.
    392424                    // DBCS chars seem to have KC_CHAR set but not KC_VIRTUALKEY; we
    393425                    // use this to prevent keys like ESC (chm=0x011B) with the
     
    396428                } else if (chm.chr & 0xFF) {
    397429                    text = QString::fromLocal8Bit((char*)&chm.chr, 1);
     430                    if (chm.fs & KC_DEADKEY) {
     431                        // convert dead keys to Key_Dead_* codes and set text to
     432                        // null to avoid interpreting them as normal chars
     433                        Q_ASSERT(text.size() == 1);
     434                        code = deadCharToDeadKeyCode(text[0]);
     435                        text = QString();
     436                    } else if (chm.fs & KC_INVALIDCOMP) {
     437                        // if the pressed letter is invalid for the given dead
     438                        // key, we set text to null as well (to meet the PM
     439                        // behavior) and set the code to the value of the char
     440                        // (similar to charToKeycode()) to have it recognized
     441                        Q_ASSERT(text.size() == 1);
     442                        code = text[0].toUpper().unicode();
     443                        text = QString();
     444                    }
    398445                }
    399446
    400447                Q_ASSERT(code || !text.isEmpty()); // we must provide the key code
    401448                if (!code && !text.isEmpty()) {
    402                     if (!text[0].row())
    403                         code = asciiToKeycode(text[0].cell(), state);
    404                     else
    405                         code = text[0].toUpper().unicode();
     449                    code = charToKeycode(text[0], state);
    406450                }
    407451            }
Note: See TracChangeset for help on using the changeset viewer.