X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/092f753690cec1f4ee3a7ad2df53afc70caaa2f3..4227afa4f748870bbfce75047db465f024e0ac1d:/src/gtk/menu.cpp diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index e6789d180b..97d7f22a84 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -7,11 +7,14 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "menu.h" -#pragma implementation "menuitem.h" +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) + #pragma implementation "menu.h" + #pragma implementation "menuitem.h" #endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + #include "wx/log.h" #include "wx/intl.h" #include "wx/app.h" @@ -58,12 +61,7 @@ extern bool g_isIdle; // substitute for missing GtkPixmapMenuItem //----------------------------------------------------------------------------- -// FIXME: I can't make this compile with GTK+ 2.0, disabling for now (VZ) #ifndef __WXGTK20__ - #define USE_MENU_BITMAPS -#endif - -#ifdef USE_MENU_BITMAPS #define GTK_TYPE_PIXMAP_MENU_ITEM (gtk_pixmap_menu_item_get_type ()) #define GTK_PIXMAP_MENU_ITEM(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_PIXMAP_MENU_ITEM, GtkPixmapMenuItem)) @@ -96,12 +94,11 @@ struct _GtkPixmapMenuItemClass }; -GtkType gtk_pixmap_menu_item_get_type (void); +GtkType gtk_pixmap_menu_item_get_type (void); GtkWidget* gtk_pixmap_menu_item_new (void); void gtk_pixmap_menu_item_set_pixmap (GtkPixmapMenuItem *menu_item, - GtkWidget *pixmap); - -#endif // USE_MENU_BITMAPS + GtkWidget *pixmap); +#endif // GTK 2.0 //----------------------------------------------------------------------------- // idle system @@ -113,21 +110,39 @@ static wxString wxReplaceUnderscore( const wxString& title ) /* GTK 1.2 wants to have "_" instead of "&" for accelerators */ wxString str; - for ( pc = title; *pc != wxT('\0'); pc++ ) + pc = title; + while (*pc != wxT('\0')) { - if (*pc == wxT('&')) + if ((*pc == wxT('&')) && (*(pc+1) == wxT('&'))) { -#if GTK_CHECK_VERSION(1, 2, 1) + // "&" is doubled to indicate "&" instead of accelerator + ++pc; + str << wxT('&'); + } + else if (*pc == wxT('&')) + { +#if GTK_CHECK_VERSION(1, 2, 0) str << wxT('_'); +#endif + } +#if GTK_CHECK_VERSION(2, 0, 0) + else if (*pc == wxT('/')) + { + str << wxT("\\/"); } + else if (*pc == wxT('\\')) + { + str << wxT("\\\\"); + } +#elif GTK_CHECK_VERSION(1, 2, 0) else if (*pc == wxT('/')) { str << wxT('\\'); -#endif } +#endif else { -#if __WXGTK12__ +#ifdef __WXGTK12__ if ( *pc == wxT('_') ) { // underscores must be doubled to prevent them from being @@ -138,10 +153,30 @@ static wxString wxReplaceUnderscore( const wxString& title ) str << *pc; } + ++pc; } return str; } +//----------------------------------------------------------------------------- +// activate message from GTK +//----------------------------------------------------------------------------- + +static void gtk_menu_open_callback( GtkWidget *widget, wxMenu *menu ) +{ + if (g_isIdle) wxapp_install_idle_handler(); + + wxMenuEvent event( wxEVT_MENU_OPEN, -1, menu ); + event.SetEventObject( menu ); + + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(event)) + return; + + wxWindow *win = menu->GetInvokingWindow(); + if (win) win->GetEventHandler()->ProcessEvent( event ); +} + //----------------------------------------------------------------------------- // wxMenuBar //----------------------------------------------------------------------------- @@ -162,8 +197,6 @@ wxMenuBar::wxMenuBar( long style ) return; } - m_menus.DeleteContents( TRUE ); - /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */ #if GTK_CHECK_VERSION(1, 2, 1) m_accel = gtk_accel_group_new(); @@ -203,8 +236,6 @@ wxMenuBar::wxMenuBar() return; } - m_menus.DeleteContents( TRUE ); - /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */ #if GTK_CHECK_VERSION(1, 2, 1) m_accel = gtk_accel_group_new(); @@ -230,16 +261,14 @@ static void wxMenubarUnsetInvokingWindow( wxMenu *menu, wxWindow *win ) { menu->SetInvokingWindow( (wxWindow*) NULL ); -#if GTK_CHECK_VERSION(1, 2, 0) wxWindow *top_frame = win; while (top_frame->GetParent() && !(top_frame->IsTopLevel())) top_frame = top_frame->GetParent(); - /* support for native hot keys */ + /* support for native hot keys */ gtk_accel_group_detach( menu->m_accel, ACCEL_OBJ_CAST(top_frame->m_widget) ); -#endif - wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst(); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); while (node) { wxMenuItem *menuitem = node->GetData(); @@ -264,7 +293,7 @@ static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win ) gtk_accel_group_attach( menu->m_accel, obj ); #endif // GTK+ 1.2.1+ - wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst(); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); while (node) { wxMenuItem *menuitem = node->GetData(); @@ -288,7 +317,7 @@ void wxMenuBar::SetInvokingWindow( wxWindow *win ) gtk_accel_group_attach( m_accel, obj ); #endif // GTK+ 1.2.1+ - wxMenuList::Node *node = m_menus.GetFirst(); + wxMenuList::compatibility_iterator node = m_menus.GetFirst(); while (node) { wxMenu *menu = node->GetData(); @@ -305,11 +334,11 @@ void wxMenuBar::UnsetInvokingWindow( wxWindow *win ) while (top_frame->GetParent() && !(top_frame->IsTopLevel())) top_frame = top_frame->GetParent(); - /* support for native key accelerators indicated by underscroes */ + // support for native key accelerators indicated by underscroes gtk_accel_group_detach( m_accel, ACCEL_OBJ_CAST(top_frame->m_widget) ); #endif // GTK+ 1.2.1+ - wxMenuList::Node *node = m_menus.GetFirst(); + wxMenuList::compatibility_iterator node = m_menus.GetFirst(); while (node) { wxMenu *menu = node->GetData(); @@ -330,18 +359,18 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) { wxString str( wxReplaceUnderscore( title ) ); - /* this doesn't have much effect right now */ + // This doesn't have much effect right now. menu->SetTitle( str ); - /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */ + // GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. #if GTK_CHECK_VERSION(1, 2, 1) - /* local buffer in multibyte form */ wxString buf; buf << wxT('/') << str.c_str(); - char *cbuf = new char[buf.Length()+1]; - strcpy(cbuf, buf.mbc_str()); + // local buffer in multibyte form + char cbuf[400]; + strcpy(cbuf, wxGTK_CONV(buf) ); GtkItemFactoryEntry entry; entry.path = (gchar *)cbuf; // const_cast @@ -350,8 +379,8 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) entry.callback_action = 0; entry.item_type = (char *)""; - gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */ - /* in order to get the pointer to the item we need the item text _without_ underscores */ + gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); // what is 2 ? + // in order to get the pointer to the item we need the item text _without_ underscores wxString tmp = wxT("
/"); const wxChar *pc; for ( pc = str; *pc != wxT('\0'); pc++ ) @@ -363,12 +392,11 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) pc++; tmp << *pc; } - menu->m_owner = gtk_item_factory_get_item( m_factory, tmp.mb_str() ); + menu->m_owner = gtk_item_factory_get_item( m_factory, wxGTK_CONV( tmp ) ); gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu->m_owner), menu->m_menu ); - delete [] cbuf; #else - menu->m_owner = gtk_menu_item_new_with_label( str.mb_str() ); + menu->m_owner = gtk_menu_item_new_with_label( wxGTK_CONV( str ) ); gtk_widget_show( menu->m_owner ); gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu->m_owner), menu->m_menu ); @@ -376,11 +404,28 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) #endif + gtk_signal_connect( GTK_OBJECT(menu->m_owner), "activate", + GTK_SIGNAL_FUNC(gtk_menu_open_callback), + (gpointer)menu ); + // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables - // adding menu later on. + // addings menu later on. if (m_invokingWindow) + { wxMenubarSetInvokingWindow( menu, m_invokingWindow ); + // OPTIMISE ME: we should probably cache this, or pass it + // directly, but for now this is a minimal + // change to validate the new dynamic sizing. + // see (and refactor :) similar code in Remove + // below. + + wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame ); + + if( frame ) + frame->UpdateMenuBarSize(); + } + return TRUE; } @@ -389,7 +434,6 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) if ( !wxMenuBarBase::Insert(pos, menu, title) ) return FALSE; -#if __WXGTK12__ // GTK+ doesn't have a function to insert a menu using GtkItemFactory (as // of version 1.2.6), so we first append the item and then change its // index @@ -405,14 +449,6 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) menu_shell->children = g_list_insert(menu_shell->children, data, pos); return TRUE; -#else // GTK < 1.2 - // this should be easy to do with GTK 1.0 - can use standard functions for - // this and don't need any hacks like above, but as I don't have GTK 1.0 - // any more I can't do it - wxFAIL_MSG( wxT("TODO") ); - - return FALSE; -#endif // GTK 1.2/1.0 } wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) @@ -428,6 +464,36 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) return menuOld; } +static wxMenu *CopyMenu (wxMenu *menu) +{ + wxMenu *menucopy = new wxMenu (); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); + while (node) + { + wxMenuItem *item = node->GetData(); + int itemid = item->GetId(); + wxString text = item->GetText(); + text.Replace(wxT("_"), wxT("&")); + wxMenu *submenu = item->GetSubMenu(); + if (!submenu) + { + wxMenuItem* itemcopy = new wxMenuItem(menucopy, + itemid, text, + menu->GetHelpString(itemid)); + itemcopy->SetBitmap(item->GetBitmap()); + itemcopy->SetCheckable(item->IsCheckable()); + menucopy->Append(itemcopy); + } + else + menucopy->Append (itemid, text, CopyMenu(submenu), + menu->GetHelpString(itemid)); + + node = node->GetNext(); + } + + return menucopy; +} + wxMenu *wxMenuBar::Remove(size_t pos) { wxMenu *menu = wxMenuBarBase::Remove(pos); @@ -441,18 +507,32 @@ wxMenu *wxMenuBar::Remove(size_t pos) printf( "menu shell entries before %d\n", (int)g_list_length( menu_shell->children ) ); */ + wxMenu *menucopy = CopyMenu( menu ); + // unparent calls unref() and that would delete the widget so we raise // the ref count to 2 artificially before invoking unparent. gtk_widget_ref( menu->m_menu ); gtk_widget_unparent( menu->m_menu ); gtk_widget_destroy( menu->m_owner ); + delete menu; + menu = menucopy; /* printf( "factory entries after %d\n", (int)g_slist_length(m_factory->items) ); printf( "menu shell entries after %d\n", (int)g_list_length( menu_shell->children ) ); */ + if (m_invokingWindow) + { + // OPTIMISE ME: see comment in GtkAppend + + wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame ); + + if( frame ) + frame->UpdateMenuBarSize(); + } + return menu; } @@ -465,7 +545,7 @@ static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString return res; } - wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst(); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); while (node) { wxMenuItem *item = node->GetData(); @@ -480,7 +560,7 @@ static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemString ) const { - wxMenuList::Node *node = m_menus.GetFirst(); + wxMenuList::compatibility_iterator node = m_menus.GetFirst(); while (node) { wxMenu *menu = node->GetData(); @@ -498,7 +578,7 @@ static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id) { wxMenuItem* result = menu->FindChildItem(id); - wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst(); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); while ( node && result == NULL ) { wxMenuItem *item = node->GetData(); @@ -515,7 +595,7 @@ static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id) wxMenuItem* wxMenuBar::FindItem( int id, wxMenu **menuForItem ) const { wxMenuItem* result = 0; - wxMenuList::Node *node = m_menus.GetFirst(); + wxMenuList::compatibility_iterator node = m_menus.GetFirst(); while (node && result == 0) { wxMenu *menu = node->GetData(); @@ -533,7 +613,7 @@ wxMenuItem* wxMenuBar::FindItem( int id, wxMenu **menuForItem ) const void wxMenuBar::EnableTop( size_t pos, bool flag ) { - wxMenuList::Node *node = m_menus.Item( pos ); + wxMenuList::compatibility_iterator node = m_menus.Item( pos ); wxCHECK_RET( node, wxT("menu not found") ); @@ -545,7 +625,7 @@ void wxMenuBar::EnableTop( size_t pos, bool flag ) wxString wxMenuBar::GetLabelTop( size_t pos ) const { - wxMenuList::Node *node = m_menus.Item( pos ); + wxMenuList::compatibility_iterator node = m_menus.Item( pos ); wxCHECK_MSG( node, wxT("invalid"), wxT("menu not found") ); @@ -553,28 +633,26 @@ wxString wxMenuBar::GetLabelTop( size_t pos ) const wxString label; wxString text( menu->GetTitle() ); -#if GTK_CHECK_VERSION(1, 2, 0) for ( const wxChar *pc = text.c_str(); *pc; pc++ ) { - if ( *pc == wxT('_') || *pc == wxT('&') ) + if ( *pc == wxT('_') ) { - // '_' is the escape character for GTK+ and '&' is the one for - // wxWindows - skip both of them + // '_' 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; } -#else // GTK+ 1.0 - label = text; -#endif // GTK+ 1.2/1.0 return label; } void wxMenuBar::SetLabelTop( size_t pos, const wxString& label ) { - wxMenuList::Node *node = m_menus.Item( pos ); + wxMenuList::compatibility_iterator node = m_menus.Item( pos ); wxCHECK_RET( node, wxT("menu not found") ); @@ -589,10 +667,10 @@ void wxMenuBar::SetLabelTop( size_t pos, const wxString& label ) GtkLabel *label = GTK_LABEL( GTK_BIN(menu->m_owner)->child ); /* set new text */ - gtk_label_set( label, str.mb_str()); + gtk_label_set( label, wxGTK_CONV( str ) ); /* reparse key accel */ - (void)gtk_label_parse_uline (GTK_LABEL(label), str.mb_str() ); + (void)gtk_label_parse_uline (GTK_LABEL(label), wxGTK_CONV( str ) ); gtk_accel_label_refetch( GTK_ACCEL_LABEL(label) ); } @@ -621,21 +699,55 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) if (item->IsCheckable()) { - bool isReallyChecked = item->IsChecked(); - if ( item->wxMenuItemBase::IsChecked() == isReallyChecked ) + bool isReallyChecked = item->IsChecked(), + isInternallyChecked = item->wxMenuItemBase::IsChecked(); + + // ensure that the internal state is always consistent with what is + // shown on the screen + item->wxMenuItemBase::Check(isReallyChecked); + + // we must not report the events for the radio button going up nor the + // events resulting from the calls to wxMenuItem::Check() + if ( (item->GetKind() == wxITEM_RADIO && !isReallyChecked) || + (isInternallyChecked == isReallyChecked) ) { - /* the menu item has been checked by calling wxMenuItem->Check() */ return; } - else - { - /* the user pressed on the menu item -> report and make consistent - * again */ - item->wxMenuItemBase::Check(isReallyChecked); - } } - menu->SendEvent(item->GetId(), item->IsCheckable() ? item->IsChecked() : -1); + + // Is this menu on a menubar? (possibly nested) + wxFrame* frame = NULL; + wxMenu* pm = menu; + while ( pm && !frame ) + { + if ( pm->IsAttached() ) + frame = pm->GetMenuBar()->GetFrame(); + pm = pm->GetParent(); + } + + // FIXME: why do we have to call wxFrame::GetEventHandler() directly here? + // normally wxMenu::SendEvent() should be enough, if it doesn't work + // in wxGTK then we have a bug in wxMenu::GetInvokingWindow() which + // should be fixed instead of working around it here... + if (frame) + { + // If it is attached then let the frame send the event. + // Don't call frame->ProcessCommand(id) because it toggles + // checkable items and we've already done that above. + wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id); + commandEvent.SetEventObject(frame); + if (item->IsCheckable()) + commandEvent.SetInt(item->IsChecked()); + commandEvent.SetEventObject(menu); + + frame->GetEventHandler()->ProcessEvent(commandEvent); + } + else + { + // otherwise let the menu have it + menu->SendEvent(id, item->IsCheckable() ? item->IsChecked() : -1); + } } //----------------------------------------------------------------------------- @@ -656,7 +768,8 @@ static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu ) wxMenuEvent event( wxEVT_MENU_HIGHLIGHT, id ); event.SetEventObject( menu ); - if (menu->GetEventHandler()->ProcessEvent(event)) + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(event)) return; wxWindow *win = menu->GetInvokingWindow(); @@ -681,7 +794,8 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu ) wxMenuEvent event( wxEVT_MENU_HIGHLIGHT, -1 ); event.SetEventObject( menu ); - if (menu->GetEventHandler()->ProcessEvent(event)) + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(event)) return; wxWindow *win = menu->GetInvokingWindow(); @@ -749,60 +863,113 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text) for ( const wxChar *pc = text.c_str(); *pc; pc++ ) { - if ( *pc == wxT('_') ) + if ( *pc == wxT('_') ) { - // wxGTK escapes "xxx_xxx" to "xxx__xxx" + // GTK 1.2 escapes "xxx_xxx" to "xxx__xxx" pc++; label += *pc; continue; } - if ( *pc == wxT('&') ) +#if GTK_CHECK_VERSION(2, 0, 0) + if ( *pc == wxT('\\') ) { - // wxMSW escapes & + // GTK 2.0 escapes "xxx/xxx" to "xxx\/xxx" + pc++; + label += *pc; + continue; + } +#endif + + if ( (*pc == wxT('&')) && (*(pc+1) != wxT('&')) ) + { + // wxMSW escapes "&" + // "&" is doubled to indicate "&" instead of accelerator continue; } label += *pc; } + // wxPrintf( L"text %s label %s\n", text.c_str(), label.c_str() ); + return label; } void wxMenuItem::SetText( const wxString& str ) { + // Some optimization to avoid flicker + wxString oldLabel = m_text; + oldLabel = wxStripMenuCodes(oldLabel.BeforeFirst('\t')); + oldLabel.Replace(wxT("_"), wxT("")); + wxString label1 = wxStripMenuCodes(str.BeforeFirst('\t')); + if (oldLabel == label1) + return; + DoSetText(str); if (m_menuItem) { GtkLabel *label; if (m_labelWidget) - label = (GtkLabel*) m_labelWidget; + label = (GtkLabel*) m_labelWidget; else - label = GTK_LABEL( GTK_BIN(m_menuItem)->child ); + label = GTK_LABEL( GTK_BIN(m_menuItem)->child ); - /* set new text */ - gtk_label_set( label, m_text.mb_str()); +#if GTK_CHECK_VERSION(2, 0, 0) + // We have to imitate item_factory_unescape_label here + wxString tmp; + for (size_t n = 0; n < m_text.Len(); n++) + { + if (m_text[n] != wxT('\\')) + tmp += m_text[n]; + } - /* reparse key accel */ - (void)gtk_label_parse_uline (GTK_LABEL(label), m_text.mb_str() ); + gtk_label_set_text_with_mnemonic( GTK_LABEL(label), wxGTK_CONV(tmp) ); +#else + // set new text + gtk_label_set( label, wxGTK_CONV( m_text ) ); + + // reparse key accel + (void)gtk_label_parse_uline (GTK_LABEL(label), wxGTK_CONV(m_text) ); gtk_accel_label_refetch( GTK_ACCEL_LABEL(label) ); +#endif } } // it's valid for this function to be called even if m_menuItem == NULL void wxMenuItem::DoSetText( const wxString& str ) { - /* '\t' is the deliminator indicating a hot key */ + // '\t' is the deliminator indicating a hot key m_text.Empty(); const wxChar *pc = str; - for (; (*pc != wxT('\0')) && (*pc != wxT('\t')); pc++ ) + while ( (*pc != wxT('\0')) && (*pc != wxT('\t')) ) { - if (*pc == wxT('&')) + if ((*pc == wxT('&')) && (*(pc+1) == wxT('&'))) + { + // "&" is doubled to indicate "&" instead of accelerator + ++pc; + m_text << wxT('&'); + } + else if (*pc == wxT('&')) { -#if GTK_CHECK_VERSION(1, 2, 0) m_text << wxT('_'); } +#if GTK_CHECK_VERSION(2, 0, 0) + else if ( *pc == wxT('_') ) // escape underscores + { + // m_text << wxT("__"); doesn't work + m_text << wxT("__"); + } + else if (*pc == wxT('/')) // we have to escape slashes + { + m_text << wxT("\\/"); + } + else if (*pc == wxT('\\')) // we have to double backslashes + { + m_text << wxT("\\\\"); + } +#else else if ( *pc == wxT('_') ) // escape underscores { m_text << wxT("__"); @@ -810,22 +977,23 @@ void wxMenuItem::DoSetText( const wxString& str ) else if (*pc == wxT('/')) /* we have to filter out slashes ... */ { m_text << wxT('\\'); /* ... and replace them with back slashes */ -#endif // GTK+ 1.2.0+ } - else +#endif + else { m_text << *pc; + } + ++pc; } - /* only GTK 1.2 knows about hot keys */ + // wxPrintf( L"str %s m_text %s\n", str.c_str(), m_text.c_str() ); + m_hotKey = wxT(""); -#if GTK_CHECK_VERSION(1, 2, 0) if(*pc == wxT('\t')) { pc++; m_hotKey = pc; } -#endif // GTK+ 1.2.0+ } #if wxUSE_ACCEL @@ -851,17 +1019,20 @@ void wxMenuItem::Check( bool check ) { wxCHECK_RET( m_menuItem, wxT("invalid menu item") ); - wxCHECK_RET( IsCheckable(), wxT("Can't check uncheckable item!") ) - if (check == m_isChecked) return; wxMenuItemBase::Check( check ); - // GTK+ does it itself for the radio item - if ( GetKind() == wxITEM_CHECK ) + switch ( GetKind() ) { - gtk_check_menu_item_set_state( (GtkCheckMenuItem*)m_menuItem, (gint)check ); + case wxITEM_CHECK: + case wxITEM_RADIO: + gtk_check_menu_item_set_state( (GtkCheckMenuItem*)m_menuItem, (gint)check ); + break; + + default: + wxFAIL_MSG( _T("can't check this item") ); } } @@ -885,18 +1056,25 @@ bool wxMenuItem::IsChecked() const wxString wxMenuItem::GetFactoryPath() const { - /* in order to get the pointer to the item we need the item text - _without_ underscores */ + // In order to get the pointer to the item we need the item + // text _without_ underscores in GTK 1.2 wxString path( wxT("
/") ); for ( const wxChar *pc = m_text.c_str(); *pc; pc++ ) { - if ( *pc == wxT('_') || *pc == wxT('&') ) + if ( *pc == wxT('_') ) { - // remove '_' and '&' unconditionally +#ifdef __WXGTK20__ + pc++; +#else + // remove '_' unconditionally continue; +#endif } + // don't remove ampersands '&' since if we have them in the menu item title + // it means that they were doubled to indicate "&" instead of accelerator + path += *pc; } @@ -911,20 +1089,15 @@ IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler) void wxMenu::Init() { -#if GTK_CHECK_VERSION(1, 2, 0) m_accel = gtk_accel_group_new(); m_factory = gtk_item_factory_new( GTK_TYPE_MENU, "
", m_accel ); m_menu = gtk_item_factory_get_widget( m_factory, "
" ); -#else - m_menu = gtk_menu_new(); // Do not show! -#endif m_owner = (GtkWidget*) NULL; -#if GTK_CHECK_VERSION(1, 2, 0) - /* Tearoffs are entries, just like separators. So if we want this - menu to be a tear-off one, we just append a tearoff entry - immediately. */ + // Tearoffs are entries, just like separators. So if we want this + // menu to be a tear-off one, we just append a tearoff entry + // immediately. if(m_style & wxMENU_TEAROFF) { GtkItemFactoryEntry entry; @@ -933,10 +1106,9 @@ void wxMenu::Init() entry.callback_action = 0; entry.item_type = (char *)""; entry.accelerator = (gchar*) NULL; - gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */ + gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); // what is 2 ? //GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "
/tearoff" ); } -#endif // GTK+ 1.2.0+ // append the title as the very first entry if we have it if ( !!m_title ) @@ -948,9 +1120,10 @@ void wxMenu::Init() wxMenu::~wxMenu() { - m_items.Clear(); + WX_CLEAR_LIST(wxMenuItemList, m_items); - gtk_widget_destroy( m_menu ); + if ( GTK_IS_WIDGET( m_menu )) + gtk_widget_destroy( m_menu ); gtk_object_unref( GTK_OBJECT(m_factory) ); } @@ -959,18 +1132,11 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) { GtkWidget *menuItem; -#if defined(USE_MENU_BITMAPS) || !GTK_CHECK_VERSION(1, 2, 0) - bool appended = FALSE; -#endif - -#if GTK_CHECK_VERSION(1, 2, 0) - // is this a radio item? - bool isRadio = FALSE; -#endif // GTK+ >= 1.2 + // does this item terminate the current radio group? + bool endOfRadioGroup = TRUE; if ( mitem->IsSeparator() ) { -#if GTK_CHECK_VERSION(1, 2, 0) GtkItemFactoryEntry entry; entry.path = (char *)"/sep"; entry.callback = (GtkItemFactoryCallback) NULL; @@ -978,24 +1144,23 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) entry.item_type = (char *)""; entry.accelerator = (gchar*) NULL; - gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */ + gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); // what is 2 ? - /* this will be wrong for more than one separator. do we care? */ + // this will be wrong for more than one separator. do we care? menuItem = gtk_item_factory_get_widget( m_factory, "
/sep" ); -#else // GTK+ 1.0 - menuItem = gtk_menu_item_new(); -#endif // GTK 1.2/1.0 + + // we might have a separator inside a radio group + endOfRadioGroup = FALSE; } else if ( mitem->IsSubMenu() ) { -#if GTK_CHECK_VERSION(1, 2, 0) - /* text has "_" instead of "&" after mitem->SetText() */ + // text has "_" instead of "&" after mitem->SetText() wxString text( mitem->GetText() ); - /* local buffer in multibyte form */ + // local buffer in multibyte form char buf[200]; strcpy( buf, "/" ); - strcat( buf, text.mb_str() ); + strcat( buf, wxGTK_CONV( text ) ); GtkItemFactoryEntry entry; entry.path = buf; @@ -1004,13 +1169,10 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) entry.item_type = (char *)""; entry.accelerator = (gchar*) NULL; - gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */ + gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); // what is 2 ? wxString path( mitem->GetFactoryPath() ); - menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() ); -#else // GTK+ 1.0 - menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str()); -#endif // GTK 1.2/1.0 + menuItem = gtk_item_factory_get_item( m_factory, wxGTK_CONV( path ) ); gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), mitem->GetSubMenu()->m_menu ); @@ -1020,26 +1182,48 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) if ( m_invokingWindow ) wxMenubarSetInvokingWindow(mitem->GetSubMenu(), m_invokingWindow); } -#ifdef USE_MENU_BITMAPS - else if (mitem->GetBitmap().Ok()) // An item with bitmap +#ifndef __WXGTK20__ + else if (mitem->GetBitmap().Ok()) { + // Our extra code for Bitmaps in GTK 1.2 wxString text( mitem->GetText() ); const wxBitmap *bitmap = &mitem->GetBitmap(); menuItem = gtk_pixmap_menu_item_new (); - GtkWidget *label = gtk_accel_label_new (text.mb_str()); + GtkWidget *label = gtk_accel_label_new ( wxGTK_CONV( text ) ); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_container_add (GTK_CONTAINER (menuItem), label); - guint accel_key = gtk_label_parse_uline (GTK_LABEL(label), text.mb_str() ); + gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), menuItem); + guint accel_key; + GdkModifierType accel_mods; + + // accelerator for the item, as specified by its label + // (ex. Ctrl+O for open) + gtk_accelerator_parse(GetHotKey(*mitem).c_str(), &accel_key, + &accel_mods); + if (accel_key != GDK_VoidSymbol) + { + gtk_widget_add_accelerator (menuItem, + "activate_item", + gtk_menu_get_accel_group( + GTK_MENU(m_menu)), + accel_key, accel_mods, + GTK_ACCEL_VISIBLE); + } + + // accelerator for the underlined char (ex ALT+F for the File menu) + accel_key = gtk_label_parse_uline (GTK_LABEL(label), wxGTK_CONV( text ) ); if (accel_key != GDK_VoidSymbol) - { + { gtk_widget_add_accelerator (menuItem, - "activate_item", - gtk_menu_ensure_uline_accel_group (GTK_MENU (m_menu)), - accel_key, 0, - GTK_ACCEL_LOCKED); + "activate_item", + gtk_menu_ensure_uline_accel_group ( + GTK_MENU (m_menu)), + accel_key, (GdkModifierType) 0, + GTK_ACCEL_LOCKED); } + gtk_widget_show (label); mitem->SetLabelWidget(label); @@ -1051,26 +1235,26 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) gtk_signal_connect( GTK_OBJECT(menuItem), "activate", GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer)this ); + gtk_menu_append( GTK_MENU(m_menu), menuItem ); gtk_widget_show( menuItem ); - - appended = TRUE; // We've done this, don't do it again } -#endif // USE_MENU_BITMAPS +#endif else // a normal item { -#if GTK_CHECK_VERSION(1, 2, 0) - /* text has "_" instead of "&" after mitem->SetText() */ + // text has "_" instead of "&" after mitem->SetText() so don't use it wxString text( mitem->GetText() ); - /* local buffer in multibyte form */ - char buf[200]; - strcpy( buf, "/" ); - strncat( buf, text.mb_str(), WXSIZEOF(buf) - 2 ); - buf[WXSIZEOF(buf) - 1] = '\0'; + // buffers containing the menu item path and type in multibyte form + char bufPath[256], + bufType[256]; + + strcpy( bufPath, "/" ); + strncat( bufPath, wxGTK_CONV(text), WXSIZEOF(bufPath) - 2 ); + bufPath[WXSIZEOF(bufPath) - 1] = '\0'; GtkItemFactoryEntry entry; - entry.path = buf; + entry.path = bufPath; entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback; entry.callback_action = 0; @@ -1087,19 +1271,23 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) { // start of a new radio group item_type = ""; - m_pathLastRadio = buf + 1; + wxString tmp( wxGTK_CONV_BACK( bufPath ) ); + tmp.Remove(0,1); + m_pathLastRadio = tmp; } else // continue the radio group { pathRadio = m_pathLastRadio; - pathRadio.Replace("_", ""); - pathRadio.Prepend("
/"); - item_type = pathRadio; + pathRadio.Replace(wxT("_"), wxT("")); + pathRadio.Prepend(wxT("
/")); + + strncpy(bufType, wxGTK_CONV(pathRadio), WXSIZEOF(bufType)); + bufType[WXSIZEOF(bufType) - 1] = '\0'; + item_type = bufType; } - // remember that this one was a radio item to avoid resetting - // m_pathLastRadio below - isRadio = TRUE; + // continue the existing radio group, if any + endOfRadioGroup = FALSE; break; default: @@ -1108,6 +1296,63 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) case wxITEM_NORMAL: item_type = ""; +#if defined(__WXGTK20__) && wxUSE_IMAGE + if (mitem->GetBitmap().Ok()) + { + item_type = ""; + // GTK2's image factory know about image items, but they need to + // get a GdkPixbuf structure, which we need to create on the fly. + // This Pixbuf structure needs to be static so we create it and + // just make it a memory leak... + wxImage image( mitem->GetBitmap().ConvertToImage() ); + size_t size = 4 + // magic + 20 + // header + image.GetHeight() * image.GetWidth() * 4; // RGBA + + unsigned char *dest = new unsigned char[size]; + entry.extra_data = dest; + + unsigned char *source = image.GetData(); + bool has_mask = image.HasMask(); + unsigned char mask_r = image.GetMaskRed(); + unsigned char mask_b = image.GetMaskBlue(); + unsigned char mask_g = image.GetMaskGreen(); + wxUint32 tmp; + + // Magic + *dest = 'G'; dest++; *dest = 'd'; dest++; *dest = 'k'; dest++; *dest = 'P'; dest++; + // Data size + tmp = size; + *dest = tmp >> 24; dest++; *dest = tmp >> 16; dest++; *dest = tmp >> 8; dest++; *dest = tmp; dest++; + // Pixdata type + *dest = 1; dest++; *dest = 1; dest++; *dest = 0; dest++; *dest = 2; dest++; + // Rowstride + tmp = image.GetWidth()*4; + *dest = tmp >> 24; dest++; *dest = tmp >> 16; dest++; *dest = tmp >> 8; dest++; *dest = tmp; dest++; + // Width + tmp = image.GetWidth(); + *dest = tmp >> 24; dest++; *dest = tmp >> 16; dest++; *dest = tmp >> 8; dest++; *dest = tmp; dest++; + // Height + tmp = image.GetHeight(); + *dest = tmp >> 24; dest++; *dest = tmp >> 16; dest++; *dest = tmp >> 8; dest++; *dest = tmp; dest++; + + for (int i = 0; i < image.GetWidth()*image.GetHeight(); i++) + { + unsigned char r = *source; source++; + unsigned char g = *source; source++; + unsigned char b = *source; source++; + *dest = r; dest++; + *dest = g; dest++; + *dest = b; dest++; + if (has_mask && (r == mask_r) && (g == mask_g) && (b == mask_b)) + *dest = 0; + else + *dest = 255; + dest++; + } + break; + } +#endif // GTK 2.0+ break; } @@ -1118,9 +1363,10 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) // due to an apparent bug in GTK+, we have to use a static buffer here - // otherwise GTK+ 1.2.2 manages to override the memory we pass to it // somehow! (VZ) - static char s_accel[50]; // must be big enougg + char s_accel[50]; // should be big enough, we check for overruns wxString tmp( GetHotKey(*mitem) ); - strncpy(s_accel, tmp.mb_str(), WXSIZEOF(s_accel)); + strncpy(s_accel, wxGTK_CONV( tmp ), WXSIZEOF(s_accel)); + s_accel[WXSIZEOF(s_accel) - 1] = '\0'; entry.accelerator = s_accel; #else // !wxUSE_ACCEL entry.accelerator = (char*) NULL; @@ -1129,19 +1375,16 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */ wxString path( mitem->GetFactoryPath() ); - menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() ); -#else // GTK+ 1.0 - menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() ) - : gtk_menu_item_new_with_label( mitem->GetText().mb_str() ); + menuItem = gtk_item_factory_get_widget( m_factory, wxGTK_CONV( path ) ); - gtk_signal_connect( GTK_OBJECT(menuItem), "activate", - GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), - (gpointer)this ); -#endif // GTK+ 1.2/1.0 + if (!menuItem) + wxLogError( wxT("Wrong menu path: %s\n"), path.c_str() ); } if ( !mitem->IsSeparator() ) { + wxASSERT_MSG( menuItem, wxT("invalid menuitem") ); + gtk_signal_connect( GTK_OBJECT(menuItem), "select", GTK_SIGNAL_FUNC(gtk_menu_hilight_callback), (gpointer)this ); @@ -1151,42 +1394,33 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) (gpointer)this ); } -#if !GTK_CHECK_VERSION(1, 2, 0) - if (!appended) - { - gtk_menu_append( GTK_MENU(m_menu), menuItem ); - gtk_widget_show( menuItem ); - } -#endif // GTK+ 1.0 - mitem->SetMenuItem(menuItem); -#if GTK_CHECK_VERSION(1, 2, 0) - if ( !isRadio ) + if ( endOfRadioGroup ) { m_pathLastRadio.clear(); } -#endif // GTK+ >= 1.2 return TRUE; } -bool wxMenu::DoAppend(wxMenuItem *mitem) +wxMenuItem* wxMenu::DoAppend(wxMenuItem *mitem) { - return GtkAppend(mitem) && wxMenuBase::DoAppend(mitem); + if (!GtkAppend(mitem)) + return NULL; + return wxMenuBase::DoAppend(mitem); } -bool wxMenu::DoInsert(size_t pos, wxMenuItem *item) +wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item) { if ( !wxMenuBase::DoInsert(pos, item) ) - return FALSE; + return NULL; -#ifdef __WXGTK12__ // GTK+ doesn't have a function to insert a menu using GtkItemFactory (as // of version 1.2.6), so we first append the item and then change its // index if ( !GtkAppend(item) ) - return FALSE; + return NULL; if ( m_style & wxMENU_TEAROFF ) { @@ -1199,13 +1433,7 @@ bool wxMenu::DoInsert(size_t pos, wxMenuItem *item) menu_shell->children = g_list_remove(menu_shell->children, data); menu_shell->children = g_list_insert(menu_shell->children, data, pos); - return TRUE; -#else // GTK < 1.2 - // this should be easy to do... - wxFAIL_MSG( wxT("not implemented") ); - - return FALSE; -#endif // GTK 1.2/1.0 + return item; } wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) @@ -1222,13 +1450,13 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const { - wxNode *node = m_items.First(); + wxMenuItemList::compatibility_iterator node = m_items.GetFirst(); while (node) { - wxMenuItem *item = (wxMenuItem*)node->Data(); + wxMenuItem *item = node->GetData(); if (item->GetMenuItem() == menuItem) return item->GetId(); - node = node->Next(); + node = node->GetNext(); } return wxNOT_FOUND; @@ -1288,6 +1516,35 @@ static wxString GetHotKey( const wxMenuItem& item ) case WXK_DELETE: hotkey << wxT("Delete" ); break; + case WXK_UP: + hotkey << wxT("Up" ); + break; + case WXK_DOWN: + hotkey << wxT("Down" ); + break; + case WXK_PAGEUP: + case WXK_PRIOR: + hotkey << wxT("Prior" ); + break; + case WXK_PAGEDOWN: + case WXK_NEXT: + hotkey << wxT("Next" ); + break; + case WXK_LEFT: + hotkey << wxT("Left" ); + break; + case WXK_RIGHT: + hotkey << wxT("Right" ); + break; + case WXK_HOME: + hotkey << wxT("Home" ); + break; + case WXK_END: + hotkey << wxT("End" ); + break; + case WXK_RETURN: + hotkey << wxT("Return" ); + break; // if there are any other keys wxGetAccelFromString() may // return, we should process them here @@ -1295,7 +1552,7 @@ static wxString GetHotKey( const wxMenuItem& item ) default: if ( code < 127 ) { - gchar *name = gdk_keyval_name((guint)code); + wxString name = wxGTK_CONV_BACK( gdk_keyval_name((guint)code) ); if ( name ) { hotkey << name; @@ -1319,7 +1576,7 @@ static wxString GetHotKey( const wxMenuItem& item ) // substitute for missing GtkPixmapMenuItem //----------------------------------------------------------------------------- -#ifdef USE_MENU_BITMAPS +#ifndef __WXGTK20__ /* * Copyright (C) 1998, 1999, 2000 Free Software Foundation @@ -1360,23 +1617,23 @@ extern "C" static void gtk_pixmap_menu_item_class_init (GtkPixmapMenuItemClass *klass); static void gtk_pixmap_menu_item_init (GtkPixmapMenuItem *menu_item); static void gtk_pixmap_menu_item_draw (GtkWidget *widget, - GdkRectangle *area); + GdkRectangle *area); static gint gtk_pixmap_menu_item_expose (GtkWidget *widget, - GdkEventExpose *event); + GdkEventExpose *event); /* we must override the following functions */ static void gtk_pixmap_menu_item_map (GtkWidget *widget); static void gtk_pixmap_menu_item_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); + GtkAllocation *allocation); static void gtk_pixmap_menu_item_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); static void gtk_pixmap_menu_item_size_request (GtkWidget *widget, - GtkRequisition *requisition); + GtkRequisition *requisition); static void gtk_pixmap_menu_item_remove (GtkContainer *container, - GtkWidget *child); + GtkWidget *child); static void changed_have_pixmap_status (GtkPixmapMenuItem *menu_item); @@ -1407,7 +1664,7 @@ gtk_pixmap_menu_item_get_type (void) }; pixmap_menu_item_type = gtk_type_unique (gtk_menu_item_get_type (), - &pixmap_menu_item_info); + &pixmap_menu_item_info); } return pixmap_menu_item_type; @@ -1469,7 +1726,7 @@ gtk_pixmap_menu_item_init (GtkPixmapMenuItem *menu_item) static void gtk_pixmap_menu_item_draw (GtkWidget *widget, - GdkRectangle *area) + GdkRectangle *area) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_PIXMAP_MENU_ITEM (widget)); @@ -1486,7 +1743,7 @@ gtk_pixmap_menu_item_draw (GtkWidget *widget, static gint gtk_pixmap_menu_item_expose (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_PIXMAP_MENU_ITEM (widget), FALSE); @@ -1514,7 +1771,7 @@ gtk_pixmap_menu_item_expose (GtkWidget *widget, void gtk_pixmap_menu_item_set_pixmap (GtkPixmapMenuItem *menu_item, - GtkWidget *pixmap) + GtkWidget *pixmap) { g_return_if_fail (menu_item != NULL); g_return_if_fail (pixmap != NULL); @@ -1531,7 +1788,7 @@ gtk_pixmap_menu_item_set_pixmap (GtkPixmapMenuItem *menu_item, if (GTK_WIDGET_VISIBLE (pixmap->parent)) { if (GTK_WIDGET_MAPPED (pixmap->parent) && - GTK_WIDGET_VISIBLE(pixmap) && + GTK_WIDGET_VISIBLE(pixmap) && !GTK_WIDGET_MAPPED (pixmap)) gtk_widget_map (pixmap); } @@ -1562,7 +1819,7 @@ gtk_pixmap_menu_item_map (GtkWidget *widget) static void gtk_pixmap_menu_item_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { GtkPixmapMenuItem *pmenu_item; @@ -1579,8 +1836,8 @@ gtk_pixmap_menu_item_size_allocate (GtkWidget *widget, child_allocation.height = pmenu_item->pixmap->requisition.height; child_allocation.x = border_width + BORDER_SPACING; child_allocation.y = (border_width + BORDER_SPACING - + (((allocation->height - child_allocation.height) - child_allocation.x) - / 2)); /* center pixmaps vertically */ + + (((allocation->height - child_allocation.height) - child_allocation.x) + / 2)); /* center pixmaps vertically */ gtk_widget_size_allocate (pmenu_item->pixmap, &child_allocation); } @@ -1590,9 +1847,9 @@ gtk_pixmap_menu_item_size_allocate (GtkWidget *widget, static void gtk_pixmap_menu_item_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { GtkPixmapMenuItem *menu_item; @@ -1606,12 +1863,12 @@ gtk_pixmap_menu_item_forall (GtkContainer *container, (* callback) (menu_item->pixmap, callback_data); GTK_CONTAINER_CLASS(parent_class)->forall(container,include_internals, - callback,callback_data); + callback,callback_data); } static void gtk_pixmap_menu_item_size_request (GtkWidget *widget, - GtkRequisition *requisition) + GtkRequisition *requisition) { GtkPixmapMenuItem *menu_item; GtkRequisition req = {0, 0}; @@ -1633,7 +1890,7 @@ gtk_pixmap_menu_item_size_request (GtkWidget *widget, static void gtk_pixmap_menu_item_remove (GtkContainer *container, - GtkWidget *child) + GtkWidget *child) { GtkBin *bin; gboolean widget_was_visible; @@ -1645,7 +1902,7 @@ gtk_pixmap_menu_item_remove (GtkContainer *container, bin = GTK_BIN (container); g_return_if_fail ((bin->child == child || - (GTK_PIXMAP_MENU_ITEM(container)->pixmap == child))); + (GTK_PIXMAP_MENU_ITEM(container)->pixmap == child))); widget_was_visible = GTK_WIDGET_VISIBLE (child); @@ -1691,5 +1948,5 @@ changed_have_pixmap_status (GtkPixmapMenuItem *menu_item) gtk_widget_queue_resize(GTK_WIDGET(menu_item)); } -#endif // USE_MENU_BITMAPS +#endif