X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/eeee4050cf0d267cf8a99ef07b452a590215ac7b..c6a6bbbf637a5a580b7ab182483d27522f5e3189:/src/common/menucmn.cpp?ds=sidebyside diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index bbee944250..87969e0411 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -34,6 +34,8 @@ #include "wx/menu.h" #endif +#include "wx/stockitem.h" + // ---------------------------------------------------------------------------- // template lists // ---------------------------------------------------------------------------- @@ -48,36 +50,9 @@ WX_DEFINE_LIST(wxMenuItemList) // ============================================================================ // ---------------------------------------------------------------------------- -// wxMenuItem +// wxAcceleratorEntry // ---------------------------------------------------------------------------- -wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, - int id, - const wxString& text, - const wxString& help, - wxItemKind kind, - wxMenu *subMenu) - : m_text(text), - m_help(help) -{ - wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") ); - - m_parentMenu = parentMenu; - m_subMenu = subMenu; - m_isEnabled = true; - m_isChecked = false; - m_id = id; - m_kind = kind; - if (m_id == wxID_ANY) - m_id = wxNewId(); - if (m_id == wxID_SEPARATOR) - m_kind = wxITEM_SEPARATOR; -} - -wxMenuItemBase::~wxMenuItemBase() -{ - delete m_subMenu; -} #if wxUSE_ACCEL @@ -172,11 +147,11 @@ static inline bool CompareAccelString(const wxString& str, const wxChar *accel) // // 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) + 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) ) @@ -197,13 +172,20 @@ IsNumberedAccelKey(const wxString& str, return prefixCode + num - first; } -// return wxAcceleratorEntry for the given menu string or NULL if none -wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) +/* 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 NULL; + { + return false; + } // parse the accelerator string int accelFlags = wxACCEL_NORMAL; @@ -252,7 +234,7 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) { case 0: wxLogDebug(wxT("No accel key found, accel string ignored.")); - return NULL; + return false; case 1: // it's just a letter @@ -267,7 +249,7 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) default: keyCode = IsNumberedAccelKey(current, wxTRANSLATE("F"), - WXK_F1, 1, 12); + WXK_F1, 1, 12); if ( !keyCode ) { for ( size_t n = 0; n < WXSIZEOF(wxKeyNames); n++ ) @@ -283,78 +265,186 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("KP_"), - WXK_NUMPAD0, 0, 9); + WXK_NUMPAD0, 0, 9); if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("SPECIAL"), - WXK_SPECIAL1, 1, 20); + WXK_SPECIAL1, 1, 20); if ( !keyCode ) { wxLogDebug(wxT("Unrecognized accel key '%s', accel string ignored."), current.c_str()); - return NULL; + return false; } } wxASSERT_MSG( keyCode, _T("logic error: should have key code here") ); - return new wxAcceleratorEntry(accelFlags, keyCode); + if ( flagsOut ) + *flagsOut = accelFlags; + if ( keyOut ) + *keyOut = keyCode; + + return true; } -wxAcceleratorEntry *wxMenuItemBase::GetAccel() const +/* static */ +wxAcceleratorEntry *wxAcceleratorEntry::Create(const wxString& str) { - return wxGetAccelFromString(GetText()); + int flags, + keyCode; + if ( !ParseAccel(str, &flags, &keyCode) ) + return NULL; + + return new wxAcceleratorEntry(flags, keyCode); } -void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel) +bool wxAcceleratorEntry::FromString(const wxString& str) { - wxString text = m_text.BeforeFirst(wxT('\t')); - if ( accel ) - { - text += wxT('\t'); + return ParseAccel(str, &m_flags, &m_keyCode); +} - int flags = accel->GetFlags(); - if ( flags & wxACCEL_ALT ) - text += _("Alt-"); - if ( flags & wxACCEL_CTRL ) - text += _("Ctrl-"); - if ( flags & wxACCEL_SHIFT ) - text += _("Shift-"); - - const int code = accel->GetKeyCode(); - - if ( wxIsalnum(code) ) - text << (wxChar)code; - else if ( code >= WXK_F1 && code <= WXK_F12 ) - text << _("F") << code - WXK_F1 + 1; - else if ( code >= WXK_NUMPAD0 && code <= WXK_NUMPAD9 ) - text << _("KP_") << code - WXK_NUMPAD0; - else if ( code >= WXK_SPECIAL1 && code <= WXK_SPECIAL20 ) - text << _("SPECIAL") << code - WXK_SPECIAL1 + 1; - else // check the named keys +wxString wxAcceleratorEntry::ToString() const +{ + wxString text; + + int flags = GetFlags(); + if ( flags & wxACCEL_ALT ) + text += _("Alt-"); + if ( flags & wxACCEL_CTRL ) + text += _("Ctrl-"); + if ( flags & wxACCEL_SHIFT ) + text += _("Shift-"); + + const int code = GetKeyCode(); + + if ( code >= WXK_F1 && code <= WXK_F12 ) + text << _("F") << code - WXK_F1 + 1; + else if ( code >= WXK_NUMPAD0 && code <= WXK_NUMPAD9 ) + text << _("KP_") << code - WXK_NUMPAD0; + else if ( code >= WXK_SPECIAL1 && code <= WXK_SPECIAL20 ) + text << _("SPECIAL") << code - WXK_SPECIAL1 + 1; + else // check the named keys + { + size_t n; + for ( n = 0; n < WXSIZEOF(wxKeyNames); n++ ) { - size_t n; - for ( n = 0; n < WXSIZEOF(wxKeyNames); n++ ) + const wxKeyName& kn = wxKeyNames[n]; + if ( code == kn.code ) { - const wxKeyName& kn = wxKeyNames[n]; - if ( code == kn.code ) - { - text << wxGetTranslation(kn.name); - break; - } + text << wxGetTranslation(kn.name); + break; } + } - wxASSERT_MSG( n != WXSIZEOF(wxKeyNames), - wxT("unknown keyboard accelerator code") ); + if ( n == WXSIZEOF(wxKeyNames) ) + { + // must be a simple key + if ( +#if !wxUSE_UNICODE + isascii(code) && +#endif // ANSI + wxIsalnum(code) ) + { + text << (wxChar)code; + } + else + { + wxFAIL_MSG( wxT("unknown keyboard accelerator code") ); + } } } + return text; +} + +wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) +{ + return wxAcceleratorEntry::Create(label); +} + +#endif // wxUSE_ACCEL + + +// ---------------------------------------------------------------------------- +// wxMenuItem +// ---------------------------------------------------------------------------- + +wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, + int id, + const wxString& text, + const wxString& help, + wxItemKind kind, + wxMenu *subMenu) +{ + wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") ); + + m_parentMenu = parentMenu; + m_subMenu = subMenu; + m_isEnabled = true; + m_isChecked = false; + m_id = id; + m_kind = kind; + if (m_id == wxID_ANY) + m_id = wxNewId(); + if (m_id == wxID_SEPARATOR) + m_kind = wxITEM_SEPARATOR; + + SetText(text); + SetHelp(help); +} + +wxMenuItemBase::~wxMenuItemBase() +{ + delete m_subMenu; +} + +#if wxUSE_ACCEL + +wxAcceleratorEntry *wxMenuItemBase::GetAccel() const +{ + return wxAcceleratorEntry::Create(GetText()); +} + +void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel) +{ + wxString text = m_text.BeforeFirst(wxT('\t')); + if ( accel ) + { + text += wxT('\t'); + text += accel->ToString(); + } + SetText(text); } #endif // wxUSE_ACCEL +void wxMenuItemBase::SetText(const wxString& str) +{ + m_text = str; + + if ( m_text.empty() && !IsSeparator() ) + { + wxASSERT_MSG( wxIsStockID(GetId()), + wxT("A non-stock menu item with an empty label?") ); + m_text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR | + wxSTOCK_WITH_MNEMONIC); + } +} + +void wxMenuItemBase::SetHelp(const wxString& str) +{ + m_help = str; + + if ( m_help.empty() && !IsSeparator() && wxIsStockID(GetId()) ) + { + // get a stock help string + m_help = wxGetStockHelpString(GetId()); + } +} + bool wxMenuBase::ms_locked = true; // ----------------------------------------------------------------------------