]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/menu.cpp
1. wxWindow::IsTopLevel() added and documented
[wxWidgets.git] / src / msw / menu.cpp
index 097765df9d804a979dd3b2e2d4ecef39af8dee53..59fc836e29ff7331a9b17e7dd45af3fa094cb5e7 100644 (file)
@@ -32,6 +32,7 @@
     #include "wx/frame.h"
     #include "wx/menu.h"
     #include "wx/utils.h"
+    #include "wx/intl.h"
 #endif
 
 #if wxUSE_OWNER_DRAWN
@@ -145,6 +146,67 @@ void wxMenu::Append(wxMenuItem *pItem)
 {
     wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
 
+    // check for accelerators: they are given after '\t'
+    wxString label = pItem->GetName();
+    int posTab = label.Find('\t');
+    if ( posTab != wxNOT_FOUND ) {
+        // parse the accelerator string
+        int keyCode = 0;
+        int accelFlags = wxACCEL_NORMAL;
+        wxString current;
+        for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) {
+            if ( (label[n] == '+') || (label[n] == '-') ) {
+                if ( current == _("ctrl") )
+                    accelFlags |= wxACCEL_CTRL;
+                else if ( current == _("alt") )
+                    accelFlags |= wxACCEL_ALT;
+                else if ( current == _("shift") )
+                    accelFlags |= wxACCEL_SHIFT;
+                else {
+                    wxLogDebug(_T("Unknown accel modifier: '%s'"),
+                               current.c_str());
+                }
+
+                current.Empty();
+            }
+            else {
+                current += wxTolower(label[n]);
+            }
+        }
+
+        if ( current.IsEmpty() ) {
+            wxLogDebug(_T("No accel key found, accel string ignored."));
+        }
+        else {
+            if ( current.Len() == 1 ) {
+                // it's a letter
+                keyCode = wxToupper(current[0U]);
+            }
+            else {
+                // it should be a function key
+                if ( current[0U] == 'f' && isdigit(current[1U]) &&
+                     (current.Len() == 2 ||
+                     (current.Len() == 3 && isdigit(current[2U]))) ) {
+                    int n;
+                    sscanf(current.c_str() + 1, "%d", &n);
+
+                    keyCode = VK_F1 + n - 1;
+                }
+                else {
+                    wxLogDebug(_T("Unrecognized accel key '%s', accel "
+                                  "string ignored."), current.c_str());
+                }
+            }
+        }
+
+        if ( keyCode ) {
+            // do add an entry
+            m_accelKeyCodes.Add(keyCode);
+            m_accelFlags.Add(accelFlags);
+            m_accelIds.Add(pItem->GetId());
+        }
+    }
+
     UINT flags = 0;
 
     // if "Break" has just been called, insert a menu break before this item
@@ -190,13 +252,7 @@ void wxMenu::Append(wxMenuItem *pItem)
     {
         // menu is just a normal string (passed in data parameter)
         flags |= MF_STRING;
-        pData = pItem->GetName();
-    }
-
-    // visually select the menu title
-    if ( id == idMenuTitle )
-    {
-        // TODO use SetMenuItemInfo(MFS_DEFAULT) to put it in bold face
+        pData = label;
     }
 
     if ( !::AppendMenu(GetHMENU(), flags, id, pData) )
@@ -205,6 +261,22 @@ void wxMenu::Append(wxMenuItem *pItem)
     }
     else
     {
+#ifdef __WIN32__
+        if ( id == idMenuTitle )
+        {
+            // visually select the menu title
+            MENUITEMINFO mii;
+            mii.cbSize = sizeof(mii);
+            mii.fMask = MIIM_STATE;
+            mii.fState = MFS_DEFAULT;
+
+            if ( !SetMenuItemInfo(GetHMENU(), (unsigned)id, FALSE, &mii) )
+            {
+                wxLogLastError("SetMenuItemInfo");
+            }
+        }
+#endif // __WIN32__
+
         m_menuItems.Append(pItem);
         m_noItems++;
     }
@@ -272,6 +344,23 @@ void wxMenu::Delete(int id)
     delete item;
 }
 
+// ---------------------------------------------------------------------------
+// accelerator helpers
+// ---------------------------------------------------------------------------
+
+// create the wxAcceleratorEntries for our accels and put them into provided
+// array - return the number of accels we have
+size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
+{
+    size_t count = GetAccelCount();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        (*accels++).Set(m_accelFlags[n], m_accelKeyCodes[n], m_accelIds[n]);
+    }
+
+    return count;
+}
+
 // ---------------------------------------------------------------------------
 // wxMenu functions implemented in wxMenuItem
 // ---------------------------------------------------------------------------
@@ -395,7 +484,7 @@ void wxMenu::SetTitle(const wxString& label)
         }
     }
 
-#ifndef __WIN16__
+#ifdef __WIN32__
     // put the title string in bold face
     if ( !m_title.IsEmpty() )
     {
@@ -438,16 +527,18 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id)
     return TRUE;
 }
 
-void wxMenu::ProcessCommand(wxCommandEvent & event)
+bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
     bool processed = FALSE;
 
+#if WXWIN_COMPATIBILITY
     // Try a callback
     if (m_callback)
     {
         (void)(*(m_callback))(*this, event);
         processed = TRUE;
     }
+#endif // WXWIN_COMPATIBILITY
 
     // Try the menu's event handler
     if ( !processed && GetEventHandler())
@@ -460,6 +551,8 @@ void wxMenu::ProcessCommand(wxCommandEvent & event)
     wxWindow *win = GetInvokingWindow();
     if ( !processed && win )
         processed = win->GetEventHandler()->ProcessEvent(event);
+
+    return processed;
 }
 
 // ---------------------------------------------------------------------------
@@ -915,6 +1008,37 @@ void wxMenuBar::Delete(wxMenu * menu, int i)
     }
 }
 
+void wxMenuBar::Attach(wxFrame *frame)
+{
+    wxASSERT_MSG( !m_menuBarFrame, _T("menubar already attached!") );
+
+    m_menuBarFrame = frame;
+
+    // create the accel table - we consider that the menubar construction is
+    // finished
+    size_t nAccelCount = 0;
+    int i;
+    for ( i = 0; i < m_menuCount; i++ )
+    {
+        nAccelCount += m_menus[i]->GetAccelCount();
+    }
+
+    if ( nAccelCount )
+    {
+        wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount];
+
+        nAccelCount = 0;
+        for ( i = 0; i < m_menuCount; i++ )
+        {
+            nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]);
+        }
+
+        m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries);
+
+        delete [] accelEntries;
+    }
+}
+
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items
 // ---------------------------------------------------------------------------