Fixes for accelerator handling in wxGTK.

See https://github.com/wxWidgets/wxWidgets/pull/1463
This commit is contained in:
Vadim Zeitlin
2019-08-09 23:54:37 +02:00
5 changed files with 375 additions and 151 deletions

View File

@@ -501,6 +501,27 @@ public:
@c Shift+/ do not, so avoid using accelerators of this form in portable
code.
@note In wxGTk, the left/right/up/down arrow keys do not work as
accelerator keys for a menu item unless a modifier key is used.
Additionally, the following keycodes are not supported as menu
accelerator keys:
- WXK_COMMAND/WXK_CONTROL
- WXK_SHIFT
- WXK_ALT
- WXK_SCROLL
- WXK_CAPITAL
- WXK_NUMLOCK
- WXK_NUMPAD_TAB
- WXK_TAB
- WXK_WINDOWS_LEFT
- WXK_WINDOWS_RIGHT
- WXK_ADD
- WXK_SEPARATOR
- WXK_SUBTRACT
- WXK_DECIMAL
- WXK_DIVIDE
- WXK_SNAPSHOT
@see GetItemLabel(), GetItemLabelText()
*/
virtual void SetItemLabel(const wxString& label);

View File

@@ -38,8 +38,6 @@ wxAcceleratorTable wxNullAcceleratorTable;
// wxAcceleratorEntry implementation
// ============================================================================
wxGCC_WARNING_SUPPRESS(missing-field-initializers)
static const struct wxKeyName
{
wxKeyCode code;
@@ -82,6 +80,7 @@ static const struct wxKeyName
{ WXK_SEPARATOR, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Separator") },
{ WXK_SUBTRACT, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Subtract") },
{ WXK_DECIMAL, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Decimal") },
{ WXK_MULTIPLY, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Multiply") },
{ WXK_DIVIDE, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Divide") },
{ WXK_NUMLOCK, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Num_lock"), /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Num Lock") },
{ WXK_SCROLL, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Scroll_lock"), /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Scroll Lock") },
@@ -114,7 +113,6 @@ static const struct wxKeyName
{ WXK_COMMAND, /*TRANSLATORS: Name of keyboard key*/ wxTRANSLATE("Command") },
};
wxGCC_WARNING_RESTORE(missing-field-initializers)
// return true if the 2 strings refer to the same accel
//
@@ -182,7 +180,8 @@ wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)
wxString current;
for ( size_t n = (size_t)posTab; n < label.length(); n++ )
{
if ( (label[n] == '+') || (label[n] == '-') )
bool skip = false;
if ( !skip && ( (label[n] == '+') || (label[n] == '-') ) )
{
if ( CompareAccelString(current, wxTRANSLATE("ctrl")) )
accelFlags |= wxACCEL_CTRL;
@@ -192,6 +191,16 @@ wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)
accelFlags |= wxACCEL_SHIFT;
else if ( CompareAccelString(current, wxTRANSLATE("rawctrl")) )
accelFlags |= wxACCEL_RAW_CTRL;
else if ( CompareAccelString(current, wxTRANSLATE("num ")) )
{
// This isn't really a modifier, but is part of the name of keys
// that have a =/- in them (e.g. num + and num -)
// So we want to skip the processing if we see it
skip = true;
current += label[n];
continue;
}
else // not a recognized modifier name
{
// we may have "Ctrl-+", for example, but we still want to
@@ -216,7 +225,8 @@ wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)
}
else // not special character
{
current += (wxChar) wxTolower(label[n]);
// Preserve case of the key (see comment below)
current += label[n];
}
}
@@ -247,13 +257,14 @@ wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)
default:
keyCode = IsNumberedAccelKey(current, wxTRANSLATE("F"),
WXK_F1, 1, 12);
WXK_F1, 1, 24);
if ( !keyCode )
{
for ( size_t n = 0; n < WXSIZEOF(wxKeyNames); n++ )
{
const wxKeyName& kn = wxKeyNames[n];
if ( CompareAccelString(current, kn.name) )
if ( CompareAccelString(current, kn.name)
|| ( kn.display_name && CompareAccelString(current, kn.display_name) ) )
{
keyCode = kn.code;
break;
@@ -261,6 +272,9 @@ wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)
}
}
if ( !keyCode )
keyCode = IsNumberedAccelKey(current, wxTRANSLATE("KP_F"),
WXK_NUMPAD_F1, 1, 4);
if ( !keyCode )
keyCode = IsNumberedAccelKey(current, wxTRANSLATE("KP_"),
WXK_NUMPAD0, 0, 9);
@@ -340,9 +354,12 @@ wxString wxAcceleratorEntry::AsPossiblyLocalizedString(bool localized) const
const int code = GetKeyCode();
if ( code >= WXK_F1 && code <= WXK_F12 )
if ( code >= WXK_F1 && code <= WXK_F24 )
text << PossiblyLocalize(wxTRANSLATE("F"), localized)
<< code - WXK_F1 + 1;
else if ( code >= WXK_NUMPAD_F1 && code <= WXK_NUMPAD_F4 )
text << PossiblyLocalize(wxTRANSLATE("KP_F"), localized)
<< code - WXK_NUMPAD_F1 + 1;
else if ( code >= WXK_NUMPAD0 && code <= WXK_NUMPAD9 )
text << PossiblyLocalize(wxTRANSLATE("KP_"), localized)
<< code - WXK_NUMPAD0;

View File

@@ -665,12 +665,17 @@ void wxMenuItem::SetGtkLabel()
guint accel_key;
GdkModifierType accel_mods;
wxGetGtkAccel(this, &accel_key, &accel_mods);
if (accel_key)
if ( accel_key && gtk_accelerator_valid( accel_key, accel_mods ) )
{
gtk_widget_add_accelerator(
m_menuItem, "activate", GetRootParentMenu(m_parentMenu)->m_accel,
accel_key, accel_mods, GTK_ACCEL_VISIBLE);
}
else
{
// Remove the accelerator since it couldn't be made or is invalid
m_text = m_text.BeforeFirst( wxS( '\t' ) );
}
#endif // wxUSE_ACCEL
}
@@ -1036,47 +1041,46 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
int code = accel->GetKeyCode();
switch ( code )
{
case WXK_F1:
case WXK_F2:
case WXK_F3:
case WXK_F4:
case WXK_F5:
case WXK_F6:
case WXK_F7:
case WXK_F8:
case WXK_F9:
case WXK_F10:
case WXK_F11:
case WXK_F12:
case WXK_F13:
case WXK_F14:
case WXK_F15:
case WXK_F16:
case WXK_F17:
case WXK_F18:
case WXK_F19:
case WXK_F20:
case WXK_F21:
case WXK_F22:
case WXK_F23:
case WXK_F24:
case WXK_F1: case WXK_F2: case WXK_F3: case WXK_F4: case WXK_F5:
case WXK_F6: case WXK_F7: case WXK_F8: case WXK_F9: case WXK_F10:
case WXK_F11: case WXK_F12: case WXK_F13: case WXK_F14: case WXK_F15:
case WXK_F16: case WXK_F17: case WXK_F18: case WXK_F19: case WXK_F20:
case WXK_F21: case WXK_F22: case WXK_F23: case WXK_F24:
hotkey += wxString::Format(wxT("F%d"), code - WXK_F1 + 1);
break;
// TODO: we should use gdk_keyval_name() (a.k.a.
// XKeysymToString) here as well as hardcoding the keysym
// names this might be not portable
case WXK_INSERT:
case WXK_INSERT:
hotkey << wxT("Insert" );
break;
case WXK_DELETE:
hotkey << wxT("Delete" );
break;
case WXK_UP:
hotkey << wxT("Up" );
if ( flags )
hotkey << wxT("Up" );
else
wxFAIL_MSG( wxT("The Up key must have modifiers to be an accelerator key") );
break;
case WXK_DOWN:
hotkey << wxT("Down" );
if ( flags )
hotkey << wxT("Down" );
else
wxFAIL_MSG( wxT("The Down key must have modifiers to be an accelerator key") );
break;
case WXK_LEFT:
if ( flags )
hotkey << wxT("Left" );
else
wxFAIL_MSG( wxT("The Left key must have modifiers to be an accelerator key") );
break;
case WXK_RIGHT:
if ( flags )
hotkey << wxT("Right" );
else
wxFAIL_MSG( wxT("The Right key must have modifiers to be an accelerator key") );
break;
case WXK_PAGEUP:
hotkey << wxT("Page_Up" );
@@ -1084,12 +1088,6 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
case WXK_PAGEDOWN:
hotkey << wxT("Page_Down" );
break;
case WXK_LEFT:
hotkey << wxT("Left" );
break;
case WXK_RIGHT:
hotkey << wxT("Right" );
break;
case WXK_HOME:
hotkey << wxT("Home" );
break;
@@ -1102,32 +1100,14 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
case WXK_BACK:
hotkey << wxT("BackSpace" );
break;
case WXK_TAB:
hotkey << wxT("Tab" );
break;
case WXK_ESCAPE:
hotkey << wxT("Esc" );
hotkey << wxT("Escape" );
break;
case WXK_SPACE:
hotkey << wxT("space" );
break;
case WXK_MULTIPLY:
hotkey << wxT("Multiply" );
break;
case WXK_ADD:
hotkey << wxT("Add" );
break;
case WXK_SEPARATOR:
hotkey << wxT("Separator" );
break;
case WXK_SUBTRACT:
hotkey << wxT("Subtract" );
break;
case WXK_DECIMAL:
hotkey << wxT("Decimal" );
break;
case WXK_DIVIDE:
hotkey << wxT("Divide" );
hotkey << wxT("multiply" );
break;
case WXK_CANCEL:
hotkey << wxT("Cancel" );
@@ -1141,9 +1121,6 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
case WXK_PAUSE:
hotkey << wxT("Pause" );
break;
case WXK_CAPITAL:
hotkey << wxT("Capital" );
break;
case WXK_SELECT:
hotkey << wxT("Select" );
break;
@@ -1153,18 +1130,9 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
case WXK_EXECUTE:
hotkey << wxT("Execute" );
break;
case WXK_SNAPSHOT:
hotkey << wxT("Snapshot" );
break;
case WXK_HELP:
hotkey << wxT("Help" );
break;
case WXK_NUMLOCK:
hotkey << wxT("Num_Lock" );
break;
case WXK_SCROLL:
hotkey << wxT("Scroll_Lock" );
break;
case WXK_NUMPAD_INSERT:
hotkey << wxT("KP_Insert" );
break;
@@ -1174,9 +1142,6 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
case WXK_NUMPAD_SPACE:
hotkey << wxT("KP_Space" );
break;
case WXK_NUMPAD_TAB:
hotkey << wxT("KP_Tab" );
break;
case WXK_NUMPAD_ENTER:
hotkey << wxT("KP_Enter" );
break;
@@ -1187,17 +1152,29 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
case WXK_NUMPAD_HOME:
hotkey << wxT("KP_Home" );
break;
case WXK_NUMPAD_LEFT:
hotkey << wxT("KP_Left" );
break;
case WXK_NUMPAD_UP:
hotkey << wxT("KP_Up" );
break;
case WXK_NUMPAD_RIGHT:
hotkey << wxT("KP_Right" );
if ( flags )
hotkey << wxT("KP_Up" );
else
wxFAIL_MSG( wxT("The KP_Up key must have modifiers to be an accelerator key") );
break;
case WXK_NUMPAD_DOWN:
hotkey << wxT("KP_Down" );
if ( flags )
hotkey << wxT("KP_Down" );
else
wxFAIL_MSG( wxT("The KP_Down key must have modifiers to be an accelerator key") );
break;
case WXK_NUMPAD_LEFT:
if ( flags )
hotkey << wxT("KP_Left" );
else
wxFAIL_MSG( wxT("The KP_Left key must have modifiers to be an accelerator key") );
break;
case WXK_NUMPAD_RIGHT:
if ( flags )
hotkey << wxT("KP_Right" );
else
wxFAIL_MSG( wxT("The KP_Right key must have modifiers to be an accelerator key") );
break;
case WXK_NUMPAD_PAGEUP:
hotkey << wxT("KP_Page_Up" );
@@ -1234,32 +1211,58 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
break;
case WXK_NUMPAD0: case WXK_NUMPAD1: case WXK_NUMPAD2:
case WXK_NUMPAD3: case WXK_NUMPAD4: case WXK_NUMPAD5:
case WXK_NUMPAD6: case WXK_NUMPAD7: case WXK_NUMPAD8: case WXK_NUMPAD9:
case WXK_NUMPAD6: case WXK_NUMPAD7: case WXK_NUMPAD8:
case WXK_NUMPAD9:
hotkey += wxString::Format(wxT("KP_%d"), code - WXK_NUMPAD0);
break;
case WXK_WINDOWS_LEFT:
hotkey << wxT("Super_L" );
break;
case WXK_WINDOWS_RIGHT:
hotkey << wxT("Super_R" );
break;
case WXK_WINDOWS_MENU:
hotkey << wxT("Menu" );
break;
case WXK_COMMAND:
hotkey << wxT("Command" );
/*
The following keycodes have been shown not to work as accelerator
keys on GTK (see https://trac.wxwidgets.org/ticket/10049)
and are not valid
(see gtkaccelgroup.c inside gtk_accelerator_valid())
*/
case WXK_COMMAND: // Same as WXK_CONTROL
case WXK_SHIFT:
case WXK_ALT:
case WXK_SCROLL: // Scroll lock
case WXK_CAPITAL: // Caps lock
case WXK_NUMLOCK:
case WXK_NUMPAD_TAB:
case WXK_TAB:
case WXK_WINDOWS_LEFT:
case WXK_WINDOWS_RIGHT:
/*
The following keycodes do not map clearly into a GTK keycode,
so they are not included in the accelerator mapping:
*/
case WXK_ADD:
case WXK_SEPARATOR:
case WXK_SUBTRACT:
case WXK_DECIMAL:
case WXK_DIVIDE:
case WXK_SNAPSHOT:
/*
The following special codes do not map into GTK keycodes,
see gdk/keynames.txt
*/
case WXK_SPECIAL1: case WXK_SPECIAL2: case WXK_SPECIAL3:
case WXK_SPECIAL4: case WXK_SPECIAL5: case WXK_SPECIAL6:
case WXK_SPECIAL7: case WXK_SPECIAL8: case WXK_SPECIAL9:
case WXK_SPECIAL10: case WXK_SPECIAL11: case WXK_SPECIAL12:
case WXK_SPECIAL13: case WXK_SPECIAL14: case WXK_SPECIAL15:
case WXK_SPECIAL16: case WXK_SPECIAL17: case WXK_SPECIAL18:
case WXK_SPECIAL19: case WXK_SPECIAL20:
wxFAIL_MSG( wxT("Unsupported keyboard accelerator key") );
break;
/* These probably wouldn't work as there is no SpecialX in gdk/keynames.txt
case WXK_SPECIAL1: case WXK_SPECIAL2: case WXK_SPECIAL3: case WXK_SPECIAL4:
case WXK_SPECIAL5: case WXK_SPECIAL6: case WXK_SPECIAL7: case WXK_SPECIAL8:
case WXK_SPECIAL9: case WXK_SPECIAL10: case WXK_SPECIAL11: case WXK_SPECIAL12:
case WXK_SPECIAL13: case WXK_SPECIAL14: case WXK_SPECIAL15: case WXK_SPECIAL16:
case WXK_SPECIAL17: case WXK_SPECIAL18: case WXK_SPECIAL19: case WXK_SPECIAL20:
hotkey += wxString::Format(wxT("Special%d"), code - WXK_SPECIAL1 + 1);
break;
*/
// if there are any other keys wxAcceleratorEntry::Create() may
// return, we should process them here
// if there are any other keys wxAcceleratorEntry::Create() may
// return, we should process them here
default:
if ( code < 127 )

View File

@@ -20,73 +20,81 @@
#endif // WX_PRECOMP
#include "wx/accel.h"
#include "wx/scopedptr.h"
class AccelEntryTestCase : public CppUnit::TestCase
{
public:
AccelEntryTestCase() {}
private:
CPPUNIT_TEST_SUITE( AccelEntryTestCase );
CPPUNIT_TEST( Create );
CPPUNIT_TEST( ToFromString );
CPPUNIT_TEST_SUITE_END();
void Create();
void ToFromString();
wxDECLARE_NO_COPY_CLASS(AccelEntryTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( AccelEntryTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AccelEntryTestCase, "AccelEntryTestCase" );
namespace
{
void CheckAccelEntry(const wxAcceleratorEntry& accel, int keycode, int flags)
{
CPPUNIT_ASSERT_EQUAL( keycode, accel.GetKeyCode() );
CPPUNIT_ASSERT_EQUAL( flags, accel.GetFlags() );
CHECK( keycode == accel.GetKeyCode() );
CHECK( flags == accel.GetFlags() );
}
} // anonymous namespace
void AccelEntryTestCase::Create()
/*
* Test the creation of accelerator keys using the Create function
*/
TEST_CASE( "wxAcceleratorEntry::Create", "[accelentry]" )
{
wxScopedPtr<wxAcceleratorEntry>
pa(wxAcceleratorEntry::Create("Foo\tCtrl+Z"));
CPPUNIT_ASSERT( pa );
CPPUNIT_ASSERT( pa->IsOk() );
wxAcceleratorEntry* pa;
CheckAccelEntry(*pa, 'Z', wxACCEL_CTRL);
SECTION( "Correct behavior" )
{
pa = wxAcceleratorEntry::Create("Foo\tCtrl+Z");
CHECK( pa );
CHECK( pa->IsOk() );
CheckAccelEntry(*pa, 'Z', wxACCEL_CTRL);
}
// There must be a TAB in the string passed to Create()
pa.reset(wxAcceleratorEntry::Create("Shift-Q"));
CPPUNIT_ASSERT( !pa );
SECTION( "Tab missing" )
{
pa = wxAcceleratorEntry::Create("Shift-Q");
pa.reset(wxAcceleratorEntry::Create("Bar\tShift-Q"));
CPPUNIT_ASSERT( pa );
CPPUNIT_ASSERT( pa->IsOk() );
CheckAccelEntry(*pa, 'Q', wxACCEL_SHIFT);
CHECK( !pa );
}
SECTION( "No accelerator key specified" )
{
pa = wxAcceleratorEntry::Create("bloordyblop");
pa.reset(wxAcceleratorEntry::Create("bloordyblop"));
CPPUNIT_ASSERT( !pa );
CHECK( !pa );
}
SECTION( "Display name parsing" )
{
pa = wxAcceleratorEntry::Create("Test\tBackSpace");
CHECK( pa );
CHECK( pa->IsOk() );
CheckAccelEntry(*pa, WXK_BACK, wxACCEL_NORMAL);
}
}
void AccelEntryTestCase::ToFromString()
/*
* Test the creation of accelerator keys from strings and also the
* creation of strings from an accelerator key
*/
TEST_CASE( "wxAcceleratorEntry::StringTests", "[accelentry]" )
{
wxAcceleratorEntry a(wxACCEL_ALT, 'X');
CPPUNIT_ASSERT_EQUAL( "Alt+X", a.ToString() );
CPPUNIT_ASSERT( a.FromString("Alt+Shift+F1") );
CheckAccelEntry(a, WXK_F1, wxACCEL_ALT | wxACCEL_SHIFT);
SECTION( "Create string from key" )
{
CHECK( "Alt+X" == a.ToString() );
}
CPPUNIT_ASSERT( !a.FromString("bloordyblop") );
SECTION( "Create from valid string" )
{
CHECK( a.FromString("Alt+Shift+F1") );
CheckAccelEntry(a, WXK_F1, wxACCEL_ALT | wxACCEL_SHIFT);
}
SECTION( "Create from invalid string" )
{
CHECK( !a.FromString("bloordyblop") );
}
}

View File

@@ -608,3 +608,178 @@ void MenuTestCase::Events()
src );
#endif // wxUSE_UIACTIONSIMULATOR
}
namespace
{
void VerifyAccelAssigned( wxString labelText, int keycode )
{
wxAcceleratorEntry* entry = wxAcceleratorEntry::Create( labelText );
CHECK( entry );
CHECK( entry->GetKeyCode() == keycode );
}
struct key
{
int keycode;
wxString name;
bool skip;
};
key modKeys[] =
{
{ wxACCEL_NORMAL, "Normal", false },
{ wxACCEL_CTRL, "Ctrl", false },
{ wxACCEL_SHIFT, "Shift", false },
{ wxACCEL_ALT, "Alt", false }
};
/*
The keys marked as skip below are not supported as accelerator
keys on GTK.
*/
key specialKeys[] =
{
{ WXK_F1, "WXK_F1", false },
{ WXK_F2, "WXK_F2", false },
{ WXK_F3, "WXK_F3", false },
{ WXK_F4, "WXK_F4", false },
{ WXK_F5, "WXK_F5", false },
{ WXK_F6, "WXK_F6", false },
{ WXK_F7, "WXK_F7", false },
{ WXK_F8, "WXK_F8", false },
{ WXK_F9, "WXK_F9", false },
{ WXK_F10, "WXK_F10", false },
{ WXK_F11, "WXK_F11", false },
{ WXK_F12, "WXK_F12", false },
{ WXK_F13, "WXK_F13", false },
{ WXK_F14, "WXK_F14", false },
{ WXK_F15, "WXK_F15", false },
{ WXK_F16, "WXK_F16", false },
{ WXK_F17, "WXK_F17", false },
{ WXK_F18, "WXK_F18", false },
{ WXK_F19, "WXK_F19", false },
{ WXK_F20, "WXK_F20", false },
{ WXK_F21, "WXK_F21", false },
{ WXK_F22, "WXK_F22", false },
{ WXK_F23, "WXK_F23", false },
{ WXK_F24, "WXK_F24", false },
{ WXK_INSERT, "WXK_INSERT", false },
{ WXK_DELETE, "WXK_DELETE", false },
{ WXK_UP, "WXK_UP", false },
{ WXK_DOWN, "WXK_DOWN", false },
{ WXK_PAGEUP, "WXK_PAGEUP", false },
{ WXK_PAGEDOWN, "WXK_PAGEDOWN", false },
{ WXK_LEFT, "WXK_LEFT", false },
{ WXK_RIGHT, "WXK_RIGHT", false },
{ WXK_HOME, "WXK_HOME", false },
{ WXK_END, "WXK_END", false },
{ WXK_RETURN, "WXK_RETURN", false },
{ WXK_BACK, "WXK_BACK", false },
{ WXK_TAB, "WXK_TAB", true },
{ WXK_ESCAPE, "WXK_ESCAPE", false },
{ WXK_SPACE, "WXK_SPACE", false },
{ WXK_MULTIPLY, "WXK_MULTIPLY", false },
{ WXK_ADD, "WXK_ADD", true },
{ WXK_SEPARATOR, "WXK_SEPARATOR", true },
{ WXK_SUBTRACT, "WXK_SUBTRACT", true },
{ WXK_DECIMAL, "WXK_DECIMAL", true },
{ WXK_DIVIDE, "WXK_DIVIDE", true },
{ WXK_CANCEL, "WXK_CANCEL", false },
{ WXK_CLEAR, "WXK_CLEAR", false },
{ WXK_MENU, "WXK_MENU", false },
{ WXK_PAUSE, "WXK_PAUSE", false },
{ WXK_CAPITAL, "WXK_CAPITAL", true },
{ WXK_SELECT, "WXK_SELECT", false },
{ WXK_PRINT, "WXK_PRINT", false },
{ WXK_EXECUTE, "WXK_EXECUTE", false },
{ WXK_SNAPSHOT, "WXK_SNAPSHOT", true },
{ WXK_HELP, "WXK_HELP", false },
{ WXK_NUMLOCK, "WXK_NUMLOCK", true },
{ WXK_SCROLL, "WXK_SCROLL", true },
{ WXK_NUMPAD_INSERT, "WXK_NUMPAD_INSERT", false },
{ WXK_NUMPAD_DELETE, "WXK_NUMPAD_DELETE", false },
{ WXK_NUMPAD_SPACE, "WXK_NUMPAD_SPACE", false },
{ WXK_NUMPAD_TAB, "WXK_NUMPAD_TAB", true },
{ WXK_NUMPAD_ENTER, "WXK_NUMPAD_ENTER", false },
{ WXK_NUMPAD_F1, "WXK_NUMPAD_F1", false },
{ WXK_NUMPAD_F2, "WXK_NUMPAD_F2", false },
{ WXK_NUMPAD_F3, "WXK_NUMPAD_F3", false },
{ WXK_NUMPAD_F4, "WXK_NUMPAD_F4", false },
{ WXK_NUMPAD_HOME, "WXK_NUMPAD_HOME", false },
{ WXK_NUMPAD_LEFT, "WXK_NUMPAD_LEFT", false },
{ WXK_NUMPAD_UP, "WXK_NUMPAD_UP", false },
{ WXK_NUMPAD_RIGHT, "WXK_NUMPAD_RIGHT", false },
{ WXK_NUMPAD_DOWN, "WXK_NUMPAD_DOWN", false },
{ WXK_NUMPAD_PAGEUP, "WXK_NUMPAD_PAGEUP", false },
{ WXK_NUMPAD_PAGEDOWN, "WXK_NUMPAD_PAGEDOWN", false },
{ WXK_NUMPAD_END, "WXK_NUMPAD_END", false },
{ WXK_NUMPAD_BEGIN, "WXK_NUMPAD_BEGIN", false },
{ WXK_NUMPAD_EQUAL, "WXK_NUMPAD_EQUAL", false },
{ WXK_NUMPAD_MULTIPLY, "WXK_NUMPAD_MULTIPLY", false },
{ WXK_NUMPAD_ADD, "WXK_NUMPAD_ADD", false },
{ WXK_NUMPAD_SEPARATOR, "WXK_NUMPAD_SEPARATOR", false },
{ WXK_NUMPAD_SUBTRACT, "WXK_NUMPAD_SUBTRACT", false },
{ WXK_NUMPAD_DECIMAL, "WXK_NUMPAD_DECIMAL", false },
{ WXK_NUMPAD_DIVIDE, "WXK_NUMPAD_DIVIDE", false },
{ WXK_NUMPAD0, "WXK_NUMPAD0", false },
{ WXK_NUMPAD1, "WXK_NUMPAD1", false },
{ WXK_NUMPAD2, "WXK_NUMPAD2", false },
{ WXK_NUMPAD3, "WXK_NUMPAD3", false },
{ WXK_NUMPAD4, "WXK_NUMPAD4", false },
{ WXK_NUMPAD5, "WXK_NUMPAD5", false },
{ WXK_NUMPAD6, "WXK_NUMPAD6", false },
{ WXK_NUMPAD7, "WXK_NUMPAD7", false },
{ WXK_NUMPAD8, "WXK_NUMPAD8", false },
{ WXK_NUMPAD9, "WXK_NUMPAD9", false },
{ WXK_WINDOWS_LEFT, "WXK_WINDOWS_LEFT", true },
{ WXK_WINDOWS_RIGHT, "WXK_WINDOWS_RIGHT", true },
{ WXK_WINDOWS_MENU, "WXK_WINDOWS_MENU", false },
{ WXK_COMMAND, "WXK_COMMAND", true }
};
}
TEST_CASE( "wxMenuItemAccelEntry", "[menu][accelentry]" )
{
wxMenu* menu = new wxMenu;
menu->Append( wxID_ANY, "Test" );
wxMenuItem* item = menu->FindItemByPosition( 0 );
SECTION( "Modifier keys" )
{
for ( int i = 0; i < WXSIZEOF(modKeys); i++ )
{
const key& k = modKeys[i];
INFO( wxString::Format( "Modifier: %s", k.name ) );
wxAcceleratorEntry accelEntry( k.keycode, 'A' , wxID_ANY, item );
item->SetAccel( &accelEntry );
wxString labelText = item->GetItemLabel();
INFO( wxString::Format( "Label text: %s", labelText ) );
VerifyAccelAssigned( labelText, 'A' );
}
}
SECTION( "Special keys" )
{
for ( int i = 0; i < WXSIZEOF(specialKeys); i++ )
{
const key& k = specialKeys[i];
if( k.skip )
continue;
INFO( wxString::Format( "Keycode: %s", k.name ) );
wxAcceleratorEntry accelEntry( wxACCEL_CTRL, k.keycode, wxID_ANY, item );
item->SetAccel( &accelEntry );
wxString labelText = item->GetItemLabel();
INFO( wxString::Format( "Label text: %s", labelText ) );
VerifyAccelAssigned( labelText, k.keycode );
}
}
}