Index: trunk/src/kernel/qapplication_pm.cpp
===================================================================
--- trunk/src/kernel/qapplication_pm.cpp	(revision 105)
+++ trunk/src/kernel/qapplication_pm.cpp	(revision 106)
@@ -1201,6 +1201,7 @@
 
         case WM_CHAR: {			// keyboard event
-//@@TODO (dmik): remove
-//qDebug("WM_CHAR:  [%s]", widget->name());
+#if 0
+            qDebug( "WM_CHAR:  [%s]", widget->name() );
+#endif            
             QWidget *g = QWidget::keyboardGrabber();
             if ( g )
@@ -1209,10 +1210,10 @@
                 widget = (QETWidget*)qApp->focusWidget();
             else if ( !widget )
-//@@TODO (dmik): currently we don't use WinSetFocus(). what for? Qt seems
+/// @todo (dmik) currently we don't use WinSetFocus(). what for? Qt seems
 //  to completely handle focus traversal itself.
 //                    || widget->winId() == WinQueryFocus( HWND_DESKTOP ) ) // We faked the message to go to exactly that widget.
                 widget = (QETWidget*)widget->topLevelWidget();
             if ( widget->isEnabled() ) {
-//@@TODO (dmik): we should not pass WM_CHAR to the default window proc,
+/// @todo (dmik) we should not pass WM_CHAR to the default window proc,
 //  otherwise it will come to us again through the widget parent (owner in PM)
 //  if the widget is not top-level, and will be treated by translateKeyEvent()
@@ -1228,5 +1229,5 @@
         }
 
-//@@TODO (dmik): later
+/// @todo (dmik) later
 //	case WM_APPCOMMAND:
 //	    {
@@ -2663,5 +2664,5 @@
 
 // when the compatibility mode is FALSE Qt/OS2 uses the following rule
-// to calculate QKeyEvent::key() codes when the the alpha-numeric key is
+// to calculate QKeyEvent::key() codes when an alpha-numeric key is
 // pressed: key code is the ASCII (Latin 1) character code of that key as if
 // there were no any keyboard modifiers (CTRL, SHIFT, ALT) pressed, with the
@@ -2669,7 +2670,17 @@
 // when the compatibility mode is TRUE Qt/OS2 behaves mostly like Qt/Win32.
 Q_EXPORT bool qt_kbd_compatibility = TRUE;
-//@@TODO (dmik): currentlly, qt_kbd_compatibility is TRUE because
+
+/// @todo (dmik) currentlly, qt_kbd_compatibility is TRUE because
 //  qt_scan2Ascii function below is not well implemented yet (in particular,
-//  it uses the 850 code page that can be not available on some systems...)
+//  it uses the 850 code page that may not be available on some systems...).
+//  Once we find a way to translate scans to US ASCII regardless of the current
+//  code page and/or NLS state (keyboard layout), qt_kbd_compatibility may be
+//  set to FALSE. This, in particular, will enable more correct handling of
+//  Alt+letter combinations when the keyboard is in the NLS state:
+//  QKeyEvent::key() will return a non-null Qt::Key_XXX code corresponding to
+//  the ASCII code of a pressed key, which in turn will let Qt process latin
+//  Alt+letter shortcuts in the NLS keyboard mode together with Alt+NLS_letter
+//  shortcuts  (nice feature imho). Note that Alt+NLS_letter shortcuts are
+//  correctly processed in any case. 
 
 // cache table to store Qt::Key_... values for 256 hardware scancodes
@@ -2713,7 +2724,7 @@
 
 // translates WM_CHAR to Qt::Key_..., ascii, state and text
-void translateKeyCode(
-    CHRMSG &chm, int &code, int &ascii, int &state, QString &text
-) {
+static void translateKeyCode( CHRMSG &chm, int &code, int &ascii, int &state,
+                              QString &text )
+{
     if ( chm.fs & KC_SHIFT )
 	state |= Qt::ShiftButton;
@@ -2793,4 +2804,6 @@
                     break;
                 default:
+                    // break if qt_kbd_compatibility = TRUE to avoid using
+                    // qt_scan2Ascii(), see comments to qt_kbd_compatibility
                     if ( qt_kbd_compatibility ) break;
                     // deduce Qt::Key... from scancode
@@ -2874,14 +2887,6 @@
     if ( ascii > 0x7F ) ascii = 0;
     if ( ch )
-//@@TODO (dmik): later: optimize by using UniUconvToUcs directly
         text = QString::fromLocal8Bit( (char*)&ch, 1 );
 }
-
-//@@TODO (dmik): do we need to export this also? I don't see that it is used
-//  anywhere in Qt/Win32...
-//Q_EXPORT int qt_translateKeyCode(int key)
-//{
-//    return translateKeyCode(key);
-//}
 
 struct KeyRec {
@@ -2944,7 +2949,7 @@
 }
 
-static void store_key_rec(
-    unsigned char scan, int code, int ascii, const QString& text
-) {
+static void store_key_rec( unsigned char scan, int code, int ascii,
+                           const QString& text )
+{
     if ( nrecs == maxrecs ) {
 #if defined(QT_CHECK_RANGE)
@@ -2997,9 +3002,15 @@
                         // remove the Key_Alt from the buffer (otherwise we will
                         // not get the next "Alt pressed" event because the
-                        // "Alt depressed" event, that must preceed it, well be
+                        // "Alt depressed" event, that must preceed it, will be
                         // eaten by the system)
-//@@TODO (dmik): do the same for other global keys (ALT+TAB, ALT+ESC, CTRL+ESC)
+                        find_key_rec( Qt::Key_Alt, TRUE ); 
+/// @todo (dmik) do the same for other global keys (ALT+TAB, ALT+ESC, CTRL+ESC)
 //  by handling this situation when we obtain/loose focus)
-                        find_key_rec( Qt::Key_Alt, TRUE );
+/// @todo (dmik) update: I don't actually think the above should be done, because
+//  it will not solve the problem of stuck modifier keys in general (there may be
+//  other combinations stolen by the system or other apps). More over, I guess
+//  that find_key_rec() above should also be removed to get identical behavior for
+//  all stolen keys. This will allow to solve the problem on the Qt application
+//  level if needed (and even in a platform-independent manner). 
                     }
                     return TRUE;
@@ -3020,7 +3031,7 @@
             if ( rec->code < Key_Shift || rec->code > Key_ScrollLock ) {
                 k0 = sendKeyEvent( QEvent::KeyRelease, rec->code, rec->ascii,
-                                   state, grab, rec->text, TRUE);
+                                   state, grab, rec->text, TRUE );
                 k1 = sendKeyEvent( QEvent::KeyPress, rec->code, rec->ascii,
-                                   state, grab, rec->text, TRUE);
+                                   state, grab, rec->text, TRUE );
             }
         } else {
@@ -3040,5 +3051,5 @@
         } else {
             k0 = sendKeyEvent( QEvent::KeyRelease, rec->code, rec->ascii,
-                                state, grab, rec->text);
+                                state, grab, rec->text );
 
             // keyboard context menu event
@@ -3048,6 +3059,7 @@
     }
 
-//@@TODO (dmik): remove
-//    qDebug("WM_CHAR: RESULT = %d", (k0 || k1));
+#if 0    
+    qDebug("WM_CHAR: RESULT = %d", (k0 || k1));
+#endif    
     return k0 || k1;
 }
Index: trunk/src/widgets/qtextedit.cpp
===================================================================
--- trunk/src/widgets/qtextedit.cpp	(revision 105)
+++ trunk/src/widgets/qtextedit.cpp	(revision 106)
@@ -1376,8 +1376,16 @@
 	    if ( e->text().length() &&
 		( !( e->state() & ControlButton ) &&
-#ifndef Q_OS_MACX
+#if !defined(Q_OS_MACX) && !defined(Q_OS_OS2)
+		  // AltGr+key can produce valid characters in some kbd layouts
+		  // (i.e. the German one) which we must not ignore
 		  !( e->state() & AltButton ) &&
 #endif
 		  !( e->state() & MetaButton ) ||
+		  // Note (dmik): the below line is possibly a typo because it's
+		  // equivalent to just (e->state() & ControlButton) which obviously
+		  // contradicts !( e->state() & ControlButton ) above. Anyway,
+		  // as a result, Ctrl+key are successfully handled by QTextEdit on
+		  // all platforms (because of the || operator), unless assigned 
+		  // as hot keys (shortcuts). 
 		 ( ( (e->state()&ControlButton) | AltButton ) == (ControlButton|AltButton) ) ) &&
 		 ( !e->ascii() || e->ascii() >= 32 || e->text() == "\t" ) ) {
