// return prefixCode+number if the string is of the form "<prefix><number>" and // 0 if it isn't // // first and last parameter specify the valid domain for "number" part static int IsNumberedAccelKey(const wxString& str, const wxChar *prefix, wxKeyCode prefixCode, unsigned first, unsigned last) { const size_t lenPrefix = wxStrlen(prefix); if ( !CompareAccelString(str.Left(lenPrefix), prefix) ) return 0; unsigned long num; if ( !str.Mid(lenPrefix).ToULong(&num) ) return 0; if ( num < first || num > last ) { // this must be a mistake, chances that this is a valid name of another // key are vanishingly small wxLogDebug(_T("Invalid key string \"%s\""), str.c_str()); return 0; } return prefixCode + num - first; }
/* static */ bool wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut) { // the parser won't like trailing spaces wxString label = text; label.Trim(true); // the initial \t must be preserved so don't strip leading whitespaces // check for accelerators: they are given after '\t' int posTab = label.Find(wxT('\t')); if ( posTab == wxNOT_FOUND ) { return false; } // parse the accelerator string int accelFlags = wxACCEL_NORMAL; wxString current; for ( size_t n = (size_t)posTab + 1; n < label.length(); n++ ) { if ( (label[n] == '+') || (label[n] == '-') ) { if ( CompareAccelString(current, wxTRANSLATE("ctrl")) ) accelFlags |= wxACCEL_CTRL; else if ( CompareAccelString(current, wxTRANSLATE("alt")) ) accelFlags |= wxACCEL_ALT; else if ( CompareAccelString(current, wxTRANSLATE("shift")) ) accelFlags |= wxACCEL_SHIFT; else // not a recognized modifier name { // we may have "Ctrl-+", for example, but we still want to // catch typos like "Crtl-A" so only give the warning if we // have something before the current '+' or '-', else take // it as a literal symbol if ( current.empty() ) { current += label[n]; // skip clearing it below continue; } else { wxLogDebug(wxT("Unknown accel modifier: '%s'"), current.c_str()); } } current.clear(); } else // not special character { current += (wxChar) wxTolower(label[n]); } } int keyCode; const size_t len = current.length(); switch ( len ) { case 0: wxLogDebug(wxT("No accel key found, accel string ignored.")); return false; case 1: // it's just a letter keyCode = current[0U]; // if the key is used with any modifiers, make it an uppercase one // because Ctrl-A and Ctrl-a are the same; but keep it as is if it's // used alone as 'a' and 'A' are different if ( accelFlags != wxACCEL_NORMAL ) keyCode = wxToupper(keyCode); break; default: keyCode = IsNumberedAccelKey(current, wxTRANSLATE("F"), WXK_F1, 1, 12); if ( !keyCode ) { for ( size_t n = 0; n < WXSIZEOF(wxKeyNames); n++ ) { const wxKeyName& kn = wxKeyNames[n]; if ( CompareAccelString(current, kn.name) ) { keyCode = kn.code; break; } } } if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("KP_"), WXK_NUMPAD0, 0, 9); if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("SPECIAL"), WXK_SPECIAL1, 1, 20); if ( !keyCode ) { wxLogDebug(wxT("Unrecognized accel key '%s', accel string ignored."), current.c_str()); return false; } } wxASSERT_MSG( keyCode, wxT("logic error: should have key code here") ); if ( flagsOut ) *flagsOut = accelFlags; if ( keyOut ) *keyOut = keyCode; return true; }