]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/menu.cpp
Better fix
[wxWidgets.git] / src / gtk1 / menu.cpp
index 502346ec53d20ba40c576d8cac4d5b6fde1e9bcf..62906a470948f9f76fb09baf0657f46655b6a5d2 100644 (file)
 #include "wx/wxprec.h"
 
 #include "wx/menu.h"
+#include "wx/stockitem.h"
 
 #ifndef WX_PRECOMP
     #include "wx/intl.h"
+    #include "wx/log.h"
+    #include "wx/app.h"
+    #include "wx/bitmap.h"
 #endif
 
-#include "wx/log.h"
-#include "wx/app.h"
-#include "wx/bitmap.h"
-
 #if wxUSE_ACCEL
     #include "wx/accel.h"
 #endif // wxUSE_ACCEL
@@ -91,6 +91,41 @@ static wxString wxReplaceUnderscore( const wxString& title )
     return str;
 }
 
+static wxString wxConvertFromGTKToWXLabel(const wxString& gtkLabel)
+{
+    wxString label;
+    for ( const wxChar *pc = gtkLabel.c_str(); *pc; pc++ )
+    {
+        // '_' is the escape character for GTK+.
+
+        if ( *pc == wxT('_') && *(pc+1) == wxT('_'))
+        {
+            // An underscore was escaped.
+            label += wxT('_');
+            pc++;
+        }
+        else if ( *pc == wxT('_') )
+        {
+            // Convert GTK+ hotkey symbol to wxWidgets/Windows standard
+            label += wxT('&');
+        }
+        else if ( *pc == wxT('&') )
+        {
+            // Double the ampersand to escape it as far as wxWidgets is concerned
+            label += wxT("&&");
+        }
+        else
+        {
+            // don't remove ampersands '&' since if we have them in the menu title
+            // it means that they were doubled to indicate "&" instead of accelerator
+            label += *pc;
+        }
+    }
+
+    return label;
+}
+
+
 //-----------------------------------------------------------------------------
 // activate message from GTK
 //-----------------------------------------------------------------------------
@@ -108,19 +143,19 @@ static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event)
 
     wxWindow *win = menu->GetInvokingWindow();
     if (win)
-        win->GetEventHandler()->ProcessEvent( event );
+        win->HandleWindowEvent( event );
 }
 
 extern "C" {
 
-static void gtk_menu_open_callback( GtkWidget *widget, wxMenu *menu )
+static void gtk_menu_open_callback( GtkWidget *WXUNUSED(widget), wxMenu *menu )
 {
     wxMenuEvent event(wxEVT_MENU_OPEN, -1, menu);
 
     DoCommonMenuCallbackCode(menu, event);
 }
 
-static void gtk_menu_close_callback( GtkWidget *widget, wxMenuBar *menubar )
+static void gtk_menu_close_callback( GtkWidget *WXUNUSED(widget), wxMenuBar *menubar )
 {
     if ( !menubar->GetMenuCount() )
     {
@@ -408,7 +443,7 @@ wxMenu *wxMenuBar::Remove(size_t pos)
 
 static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
 {
-    if (wxMenuItem::GetLabelFromText(menu->GetTitle()) == wxMenuItem::GetLabelFromText(menuString))
+    if (wxMenuItem::GetLabelText(wxConvertFromGTKToWXLabel(menu->GetTitle())) == wxMenuItem::GetLabelText(menuString))
     {
         int res = menu->FindItem( itemString );
         if (res != wxNOT_FOUND)
@@ -493,7 +528,7 @@ void wxMenuBar::EnableTop( size_t pos, bool flag )
         gtk_widget_set_sensitive( menu->m_owner, flag );
 }
 
-wxString wxMenuBar::GetLabelTop( size_t pos ) const
+wxString wxMenuBar::GetMenuLabel( size_t pos ) const
 {
     wxMenuList::compatibility_iterator node = m_menus.Item( pos );
 
@@ -501,26 +536,10 @@ wxString wxMenuBar::GetLabelTop( size_t pos ) const
 
     wxMenu* menu = node->GetData();
 
-    wxString label;
-    wxString text( menu->GetTitle() );
-    for ( const wxChar *pc = text.c_str(); *pc; pc++ )
-    {
-        if ( *pc == wxT('_') )
-        {
-            // '_' is the escape character for GTK+
-            continue;
-        }
-
-        // don't remove ampersands '&' since if we have them in the menu title
-        // it means that they were doubled to indicate "&" instead of accelerator
-
-        label += *pc;
-    }
-
-    return label;
+    return wxConvertFromGTKToWXLabel(menu->GetTitle());
 }
 
-void wxMenuBar::SetLabelTop( size_t pos, const wxString& label )
+void wxMenuBar::SetMenuLabel( size_t pos, const wxString& label )
 {
     wxMenuList::compatibility_iterator node = m_menus.Item( pos );
 
@@ -613,7 +632,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
             commandEvent.SetInt(item->IsChecked());
         commandEvent.SetEventObject(menu);
 
-        frame->GetEventHandler()->ProcessEvent(commandEvent);
+        frame->HandleWindowEvent(commandEvent);
     }
     else
     {
@@ -647,7 +666,7 @@ static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu )
         return;
 
     wxWindow *win = menu->GetInvokingWindow();
-    if (win) win->GetEventHandler()->ProcessEvent( event );
+    if (win) win->HandleWindowEvent( event );
 }
 }
 
@@ -676,7 +695,7 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu )
 
     wxWindow *win = menu->GetInvokingWindow();
     if (win)
-        win->GetEventHandler()->ProcessEvent( event );
+        win->HandleWindowEvent( event );
 }
 }
 
@@ -704,7 +723,7 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu,
                        wxMenu *subMenu)
           : wxMenuItemBase(parentMenu, id, text, help, kind, subMenu)
 {
-    Init(text);
+    Init();
 }
 
 wxMenuItem::wxMenuItem(wxMenu *parentMenu,
@@ -716,15 +735,15 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu,
           : wxMenuItemBase(parentMenu, id, text, help,
                            isCheckable ? wxITEM_CHECK : wxITEM_NORMAL, subMenu)
 {
-    Init(text);
+    Init();
 }
 
-void wxMenuItem::Init(const wxString& text)
+void wxMenuItem::Init()
 {
     m_labelWidget = (GtkWidget *) NULL;
     m_menuItem = (GtkWidget *) NULL;
 
-    DoSetText(text);
+    DoSetText(m_text);
 }
 
 wxMenuItem::~wxMenuItem()
@@ -734,8 +753,14 @@ wxMenuItem::~wxMenuItem()
 
 // return the menu item text without any menu accels
 /* static */
-wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
+wxString wxMenuItemBase::GetLabelText(const wxString& text)
 {
+    // The argument to this function will now always be in wxWidgets standard label
+    // format, not GTK+ format, so we do what the other ports do.
+
+    return wxStripMenuCodes(text);
+
+#if 0
     wxString label;
 
     for ( const wxChar *pc = text.c_str(); *pc; pc++ )
@@ -761,13 +786,30 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
         label += *pc;
     }
 
-    // wxPrintf( wxT("GetLabelFromText(): text %s label %s\n"), text.c_str(), label.c_str() );
+    // wxPrintf( wxT("GetLabelText(): text %s label %s\n"), text.c_str(), label.c_str() );
+
+    return label;
+#endif
+}
 
+wxString wxMenuItem::GetItemLabel() const
+{
+    wxString label = wxConvertFromGTKToWXLabel(m_text);
+    if (!m_hotKey.IsEmpty())
+        label = label + wxT("\t") + m_hotKey;
     return label;
 }
 
-void wxMenuItem::SetText( const wxString& str )
+void wxMenuItem::SetItemLabel( const wxString& string )
 {
+    wxString str = string;
+    if ( str.empty() && !IsSeparator() )
+    {
+        wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
+        str = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR |
+                                       wxSTOCK_WITH_MNEMONIC);
+    }
+
     // Some optimization to avoid flicker
     wxString oldLabel = m_text;
     oldLabel = wxStripMenuCodes(oldLabel);
@@ -826,7 +868,9 @@ void wxMenuItem::SetText( const wxString& str )
 void wxMenuItem::DoSetText( const wxString& str )
 {
     // '\t' is the deliminator indicating a hot key
-    m_text.Empty();
+    wxString text;
+    text.reserve(str.length());
+
     const wxChar *pc = str;
     while ( (*pc != wxT('\0')) && (*pc != wxT('\t')) )
     {
@@ -834,32 +878,32 @@ void wxMenuItem::DoSetText( const wxString& str )
         {
             // "&" is doubled to indicate "&" instead of accelerator
             ++pc;
-            m_text << wxT('&');
+            text << wxT('&');
         }
         else if (*pc == wxT('&'))
         {
-            m_text << wxT('_');
+            text << wxT('_');
         }
         else if ( *pc == wxT('_') )    // escape underscores
         {
-            m_text << wxT("__");
+            text << wxT("__");
         }
         else
         {
-            m_text << *pc;
+            text << *pc;
         }
         ++pc;
     }
 
     m_hotKey = wxEmptyString;
 
-    if(*pc == wxT('\t'))
+    if ( *pc == wxT('\t') )
     {
        pc++;
        m_hotKey = pc;
     }
 
-    // wxPrintf( wxT("DoSetText(): str %s m_text %s hotkey %s\n"), str.c_str(), m_text.c_str(), m_hotKey.c_str() );
+    m_text = text;
 }
 
 #if wxUSE_ACCEL
@@ -872,11 +916,12 @@ wxAcceleratorEntry *wxMenuItem::GetAccel() const
         return (wxAcceleratorEntry *)NULL;
     }
 
-    // as wxGetAccelFromString() looks for TAB, insert a dummy one here
+    // accelerator parsing code looks for them after a TAB, so insert a dummy
+    // one here
     wxString label;
     label << wxT('\t') << GetHotKey();
 
-    return wxGetAccelFromString(label);
+    return wxAcceleratorEntry::Create(label);
 }
 
 #endif // wxUSE_ACCEL
@@ -985,7 +1030,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos)
     }
     else if (mitem->GetBitmap().Ok())
     {
-        text = mitem->GetText();
+        text = mitem->wxMenuItemBase::GetItemLabel();
         const wxBitmap *bitmap = &mitem->GetBitmap();
 
         // TODO
@@ -997,8 +1042,8 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos)
     }
     else // a normal item
     {
-        // text has "_" instead of "&" after mitem->SetText() so don't use it
-        text =  mitem->GetText() ;
+        // text has "_" instead of "&" after mitem->SetItemLabel() so don't use it
+        text =  mitem->wxMenuItemBase::GetItemLabel() ;
 
         switch ( mitem->GetKind() )
         {
@@ -1051,7 +1096,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos)
     GdkModifierType accel_mods;
     wxCharBuffer buf = wxGTK_CONV( GetGtkHotKey(*mitem) );
 
-    // wxPrintf( wxT("item: %s hotkey %s\n"), mitem->GetText().c_str(), GetGtkHotKey(*mitem).c_str() );
+    // wxPrintf( wxT("item: %s hotkey %s\n"), mitem->GetItemLabel().c_str(), GetGtkHotKey(*mitem).c_str() );
     gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods);
     if (accel_key != 0)
     {
@@ -1237,10 +1282,10 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
                 hotkey << wxT("Down" );
                 break;
             case WXK_PAGEUP:
-                hotkey << wxT("PgUp" );
+                hotkey << wxT("Page_Up" );
                 break;
             case WXK_PAGEDOWN:
-                hotkey << wxT("PgDn" );
+                hotkey << wxT("Page_Down" );
                 break;
             case WXK_LEFT:
                 hotkey << wxT("Left" );
@@ -1358,10 +1403,10 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
                 hotkey << wxT("KP_Down" );
                 break;
             case WXK_NUMPAD_PAGEUP:
-                hotkey << wxT("KP_PgUp" );
+                hotkey << wxT("KP_Page_Up" );
                 break;
             case WXK_NUMPAD_PAGEDOWN:
-                hotkey << wxT("KP_PgDn" );
+                hotkey << wxT("KP_Page_Down" );
                 break;
             case WXK_NUMPAD_END:
                 hotkey << wxT("KP_End" );
@@ -1416,14 +1461,14 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
                 hotkey += wxString::Format(wxT("Special%d"), code - WXK_SPECIAL1 + 1);
                 break;
           */
-                // if there are any other keys wxGetAccelFromString() may
+                // if there are any other keys wxAcceleratorEntry::Create() may
                 // return, we should process them here
 
             default:
                 if ( code < 127 )
                 {
                     wxString name = wxGTK_CONV_BACK( gdk_keyval_name((guint)code) );
-                    if ( name )
+                    if ( !name.empty() )
                     {
                         hotkey << name;
                         break;
@@ -1450,7 +1495,7 @@ static wxString GetGtkHotKey( const wxMenuItem& item )
 extern "C" WXDLLIMPEXP_CORE
 void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting  )
 {
-    *is_waiting = FALSE;
+    *is_waiting = false;
 }
 
 WXDLLIMPEXP_CORE void SetInvokingWindow( wxMenu *menu, wxWindow* win )