diff --git a/interface/wx/uiaction.h b/interface/wx/uiaction.h index 05414003ea..a9415d278a 100644 --- a/interface/wx/uiaction.h +++ b/interface/wx/uiaction.h @@ -171,9 +171,9 @@ public: /** Emulate typing in the keys representing the given string. - Currently only the ASCII letters, digits and characters for the definition - of numbers (i.e. characters @c a-z @c A-Z @c 0-9 @c + @c - @c . @c , @c 'space') - are supported. + Currently only the ASCII letters are universally supported. Digits and + punctuation characters can be used with the standard QWERTY (US) + keyboard layout but may not work with other layouts. @param text The string to type. diff --git a/src/common/uiactioncmn.cpp b/src/common/uiactioncmn.cpp index d97dfac869..a74a0d10ec 100644 --- a/src/common/uiactioncmn.cpp +++ b/src/common/uiactioncmn.cpp @@ -95,12 +95,52 @@ bool wxUIActionSimulator::Char(int keycode, int modifiers) return true; } +// Helper function checking if a key must be entered with Shift pressed. If it +// must, returns true and modifies the key to contain the unshifted version. +// +// This currently works only for the standard US keyboard layout which is +// definitely not ideal, but better than nothing... +static bool MapUnshifted(char& ch) +{ + const char* const unshifted = + "`1234567890-=\\" + "[]" + ";'" + ",./" + ; + + const char* const shifted = + "~!@#$%^&*()_+|" + "{}" + ":\"" + "<>?" + ; + + wxCOMPILE_TIME_ASSERT( sizeof(unshifted) == sizeof(shifted), + ShiftedUnshiftedKeysMismatch ); + + const char* const p = strchr(shifted, ch); + if ( !p ) + return false; + + ch = *(unshifted + (p - shifted)); + + return true; +} + bool wxUIActionSimulator::Text(const char *s) { while ( *s != '\0' ) { - const char ch = *s++; - if ( !Char(ch, isupper(ch) ? wxMOD_SHIFT : 0) ) + char ch = *s++; + + // Map the keys that must be entered with Shift modifier to their + // unshifted counterparts. + int modifiers = 0; + if ( isupper(ch) || MapUnshifted(ch) ) + modifiers |= wxMOD_SHIFT; + + if ( !Char(ch, modifiers) ) return false; }