Ignore:
Timestamp:
Sep 12, 2009, 3:30:48 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Fixed: Ctrl+A..Z should generate characters with codes 0x01-0x1F.

File:
1 edited

Legend:

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

    r179 r180  
    223223    }
    224224
    225     // otherwise, return unmodified unicode value (similar to charToKeycode())
     225    // otherwise, return unmodified uppercase unicode value (similar to other
     226    // cases)
    226227    return ch.unicode();
    227228}
     
    267268        result << int(e->text().at(0).unicode() + e->modifiers());
    268269    return result;
    269 
    270     return result;
    271 }
    272 
    273 static 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)  // [email protected]+A..CTRL+Z..Ctrl+_
    279                 return ascii + '@';         // to @..A..Z.._
    280         }
    281     }
    282 
    283     return ch.toUpper().unicode();
    284270}
    285271
     
    414400        else {
    415401            QString text;
    416             if (chm.chr) {
    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.
    422                 if ((chm.fs & (KC_VIRTUALKEY | KC_CHAR)) == KC_CHAR && (chm.chr & 0xFF00)) {
     402            // we assume that we have a correct 8-bit character not only when
     403            // KC_CHAR is set but also when there are one or more modifiers
     404            // (in which case KC_CHAR is not present) but no KC_VIRTUALKEY.
     405            // The latter is in particular important for Alt+Letter combos
     406            // processing Alt+Letter shortcuts for non-ASCII letters in widgets
     407            // (e.g. QPushButton) depends on that.
     408            if (((chm.fs & KC_CHAR) ||
     409                 (!(chm.fs & KC_VIRTUALKEY) && (chm.fs & (KC_CTRL | KC_ALT | KC_SHIFT)))) &&
     410                chm.chr) {
     411                if (chm.chr & 0xFF00) {
    423412                    // We assume we get a DBCS char if the above condition is met.
    424                     // DBCS chars seem to have KC_CHAR set but not KC_VIRTUALKEY; we
    425                     // use this to prevent keys like ESC (chm=0x011B) with the
    426                     // non-zero high byte to be mistakenly recognized as DBCS.
    427413                    text = QString::fromLocal8Bit((char *)&chm.chr, 2);
    428                 } else if (chm.chr & 0xFF) {
     414                } else {
    429415                    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                     }
     416                }
     417
     418                if (chm.fs & KC_DEADKEY) {
     419                    // convert dead keys to Key_Dead_* codes and set text to
     420                    // null to avoid interpreting them as normal chars
     421                    Q_ASSERT(text.size() == 1);
     422                    code = deadCharToDeadKeyCode(text[0]);
     423                    text = QString();
     424                } else if (chm.fs & KC_INVALIDCOMP) {
     425                    // if the pressed letter is invalid for the given dead
     426                    // key, we set text to null as well (to meet the PM
     427                    // behavior) and set the code to the uppercase unicode
     428                    // value (similar to other cases) to have it recognized
     429                    Q_ASSERT(text.size() == 1);
     430                    code = text[0].toUpper().unicode();
     431                    text = QString();
    445432                }
    446433
    447434                Q_ASSERT(code || !text.isEmpty()); // we must provide the key code
    448435                if (!code && !text.isEmpty()) {
    449                     code = charToKeycode(text[0], state);
     436                    code = text[0].toUpper().unicode();
     437                }
     438
     439                if ((state & Qt::ControlModifier) &&
     440                    !(state & Qt::KeypadModifier) && !(state & Qt::AltModifier) &&
     441                    !text.isEmpty() && !text[0].row()) {
     442                    // Ctrl + A..Z etc. produce ascii from 0x01 to 0x1F
     443                    int ascii = text[0].toUpper().cell();
     444                    if (ascii >= 0x41 && ascii <= 0x5F)
     445                        ascii -= 0x40;
     446                    // the below emulates OS/2 functionality. It differs from
     447                    // e.g. Win32.
     448                    else if (ascii == 0x36 && !(state & Qt::KeypadModifier))
     449                        ascii = 0x1E;
     450                    else if (ascii == 0x2D)
     451                        ascii = 0x1F;
     452                    else if (ascii >= 0x7B && ascii <= 0x7D)
     453                        ascii -= 0x60;
     454                    text = QChar(ascii);
    450455                }
    451456            }
Note: See TracChangeset for help on using the changeset viewer.