]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/menucmn.cpp
disable select root menu command when the root is hidden
[wxWidgets.git] / src / common / menucmn.cpp
index bbee94425072da47e5ad72f3598a71e9067aac50..87969e0411da4450b8d2623b22dabae99dfa0de7 100644 (file)
@@ -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;
 
 // ----------------------------------------------------------------------------