1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "menu.h" 
  12 #pragma implementation "menuitem.h" 
  23 //----------------------------------------------------------------------------- 
  25 //----------------------------------------------------------------------------- 
  27 extern void wxapp_install_idle_handler(); 
  30 //----------------------------------------------------------------------------- 
  32 //----------------------------------------------------------------------------- 
  34 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
,wxWindow
) 
  36 wxMenuBar::wxMenuBar( long style 
) 
  38     /* the parent window is known after wxFrame::SetMenu() */ 
  41     PreCreation( (wxWindow 
*) NULL
, -1, wxDefaultPosition
, wxDefaultSize
, style
, "menu" ); 
  43     m_menus
.DeleteContents( TRUE 
); 
  45     /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */ 
  46 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0) 
  47     m_accel 
= gtk_accel_group_new(); 
  48     m_factory 
= gtk_item_factory_new( GTK_TYPE_MENU_BAR
, "<main>", m_accel 
); 
  49     m_menubar 
= gtk_item_factory_get_widget( m_factory
, "<main>" ); 
  51     m_menubar 
= gtk_menu_bar_new(); 
  54     if (style 
& wxMB_DOCKABLE
) 
  56         m_widget 
= gtk_handle_box_new(); 
  57         gtk_container_add( GTK_CONTAINER(m_widget
), GTK_WIDGET(m_menubar
) ); 
  58         gtk_widget_show( GTK_WIDGET(m_menubar
) ); 
  62         m_widget 
= GTK_WIDGET(m_menubar
); 
  70 wxMenuBar::wxMenuBar() 
  72     /* the parent window is known after wxFrame::SetMenu() */ 
  75     PreCreation( (wxWindow 
*) NULL
, -1, wxDefaultPosition
, wxDefaultSize
, 0, "menu" ); 
  77     m_menus
.DeleteContents( TRUE 
); 
  79     /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */ 
  80 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0) 
  81     m_accel 
= gtk_accel_group_new(); 
  82     m_factory 
= gtk_item_factory_new( GTK_TYPE_MENU_BAR
, "<main>", m_accel 
); 
  83     m_menubar 
= gtk_item_factory_get_widget( m_factory
, "<main>" ); 
  85     m_menubar 
= gtk_menu_bar_new(); 
  88     m_widget 
= GTK_WIDGET(m_menubar
); 
  95 wxMenuBar::~wxMenuBar() 
  97    // how to destroy a GtkItemFactory ? 
 100 void wxMenuBar::Append( wxMenu 
*menu
, const wxString 
&title 
) 
 102     m_menus
.Append( menu 
); 
 104     /* GTK 1.2 wants to have "_" instead of "&" for accelerators */ 
 106     for ( const wxChar 
*pc 
= title
; *pc 
!= _T('\0'); pc
++ ) 
 110 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0) 
 118     /* this doesn't have much effect right now */ 
 119     menu
->SetTitle( str 
); 
 121     /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */ 
 122 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0) 
 124     /* local buffer in multibyte form */ 
 127     strcat( buf
, str
.mb_str() ); 
 129     GtkItemFactoryEntry entry
; 
 131     entry
.accelerator 
= (gchar
*) NULL
; 
 132     entry
.callback 
= (GtkItemFactoryCallback
) NULL
; 
 133     entry
.callback_action 
= 0; 
 134     entry
.item_type 
= "<Branch>"; 
 136     gtk_item_factory_create_item( m_factory
, &entry
, (gpointer
) this, 2 );  /* what is 2 ? */ 
 138     /* in order to get the pointer to the item we need the item text _without_ underscores */ 
 139     wxString tmp 
= _T("<main>/"); 
 140     for ( const wxChar 
*pc 
= str
; *pc 
!= _T('\0'); pc
++ ) 
 142         if (*pc 
== _T('_')) pc
++; /* skip it */ 
 146     menu
->m_owner 
= gtk_item_factory_get_item( m_factory
, tmp
.mb_str() ); 
 148     gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu
->m_owner
), menu
->m_menu 
); 
 152     menu
->m_owner 
= gtk_menu_item_new_with_label( str
.mb_str() ); 
 153     gtk_widget_show( menu
->m_owner 
); 
 154     gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu
->m_owner
), menu
->m_menu 
); 
 156     gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), menu
->m_owner 
); 
 161 static int FindMenuItemRecursive( const wxMenu 
*menu
, const wxString 
&menuString
, const wxString 
&itemString 
) 
 163     if (menu
->GetTitle() == menuString
) 
 165         int res 
= menu
->FindItem( itemString 
); 
 166         if (res 
!= wxNOT_FOUND
) 
 170     wxNode 
*node 
= ((wxMenu 
*)menu
)->GetItems().First();    // const_cast 
 173         wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 174         if (item
->IsSubMenu()) 
 175             return FindMenuItemRecursive(item
->GetSubMenu(), menuString
, itemString
); 
 183 wxMenuItem 
*wxMenuBar::FindItemForId(int itemId
, wxMenu 
**menuForItem 
) const 
 187         // TODO return the pointer to the menu 
 192     return FindItem(itemId
); 
 195 int wxMenuBar::FindMenuItem( const wxString 
&menuString
, const wxString 
&itemString 
) const 
 197     wxNode 
*node 
= m_menus
.First(); 
 200         wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
 201         int res 
= FindMenuItemRecursive( menu
, menuString
, itemString
); 
 202         if (res 
!= -1) return res
; 
 208 // Find a wxMenuItem using its id. Recurses down into sub-menus 
 209 static wxMenuItem
* FindMenuItemByIdRecursive(const wxMenu
* menu
, int id
) 
 211     wxMenuItem
* result 
= menu
->FindItem(id
); 
 213     wxNode 
*node 
= ((wxMenu 
*)menu
)->GetItems().First(); // const_cast 
 214     while ( node 
&& result 
== NULL 
) 
 216         wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 217         if (item
->IsSubMenu()) 
 219             result 
= FindMenuItemByIdRecursive( item
->GetSubMenu(), id 
); 
 227 wxMenuItem
* wxMenuBar::FindItem( int id 
) const 
 229     wxMenuItem
* result 
= 0; 
 230     wxNode 
*node 
= m_menus
.First(); 
 231     while (node 
&& result 
== 0) 
 233         wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
 234         result 
= FindMenuItemByIdRecursive( menu
, id 
); 
 241 void wxMenuBar::Check( int id
, bool check 
) 
 243     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 245     wxCHECK_RET( item
, _T("wxMenuBar::Check: no such item") ); 
 250 bool wxMenuBar::IsChecked( int id 
) const 
 252     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 254     wxCHECK_MSG( item
, FALSE
, _T("wxMenuBar::IsChecked: no such item") ); 
 256     return item
->IsChecked(); 
 259 void wxMenuBar::Enable( int id
, bool enable 
) 
 261     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 263     wxCHECK_RET( item
, _T("wxMenuBar::Enable: no such item") ); 
 265     item
->Enable(enable
); 
 268 bool wxMenuBar::IsEnabled( int id 
) const 
 270     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 272     wxCHECK_MSG( item
, FALSE
, _T("wxMenuBar::IsEnabled: no such item") ); 
 274     return item
->IsEnabled(); 
 277 wxString 
wxMenuBar::GetLabel( int id 
) const 
 279     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 281     wxCHECK_MSG( item
, _T(""), _T("wxMenuBar::GetLabel: no such item") ); 
 283     return item
->GetText(); 
 286 void wxMenuBar::SetLabel( int id
, const wxString 
&label 
) 
 288     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 290     wxCHECK_RET( item
, _T("wxMenuBar::SetLabel: no such item") ); 
 292     item
->SetText( label 
); 
 295 void wxMenuBar::EnableTop( int pos
, bool flag 
) 
 297     wxNode 
*node 
= m_menus
.Nth( pos 
); 
 299     wxCHECK_RET( node
, _T("menu not found") ); 
 301     wxMenu
* menu 
= (wxMenu
*)node
->Data(); 
 304         gtk_widget_set_sensitive( menu
->m_owner
, flag 
); 
 307 wxString 
wxMenuBar::GetLabelTop( int pos 
) const 
 309     wxNode 
*node 
= m_menus
.Nth( pos 
); 
 311     wxCHECK_MSG( node
, _T("invalid"), _T("menu not found") ); 
 313     wxMenu
* menu 
= (wxMenu
*)node
->Data(); 
 315     return menu
->GetTitle(); 
 318 void wxMenuBar::SetLabelTop( int pos
, const wxString
& label 
) 
 320     wxNode 
*node 
= m_menus
.Nth( pos 
); 
 322     wxCHECK_RET( node
, _T("menu not found") ); 
 324     wxMenu
* menu 
= (wxMenu
*)node
->Data(); 
 326     menu
->SetTitle( label 
); 
 329 void wxMenuBar::SetHelpString( int id
, const wxString
& helpString 
) 
 331     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 333     wxCHECK_RET( item
, _T("wxMenuBar::SetHelpString: no such item") ); 
 335     item
->SetHelp( helpString 
); 
 338 wxString 
wxMenuBar::GetHelpString( int id 
) const 
 340     wxMenuItem
* item 
= FindMenuItemById( id 
); 
 342     wxCHECK_MSG( item
, _T(""), _T("wxMenuBar::GetHelpString: no such item") ); 
 344     return item
->GetHelp(); 
 347 //----------------------------------------------------------------------------- 
 349 //----------------------------------------------------------------------------- 
 351 static void gtk_menu_clicked_callback( GtkWidget 
*widget
, wxMenu 
*menu 
) 
 353     if (g_isIdle
) wxapp_install_idle_handler(); 
 355     int id 
= menu
->FindMenuIdByMenuItem(widget
); 
 357     /* should find it for normal (not popup) menu */ 
 358     wxASSERT( (id 
!= -1) || (menu
->GetInvokingWindow() != NULL
) ); 
 360     if (!menu
->IsEnabled(id
)) 
 363     wxMenuItem
* item 
= menu
->FindItem( id 
); 
 364     wxCHECK_RET( item
, _T("error in menu item callback") ); 
 366     if (item
->IsCheckable()) 
 368         if (item
->GetCheckedFlag() == item
->IsChecked()) 
 370             /* the menu item has been checked by calling wxMenuItem->Check() */ 
 375             /* the user pressed on the menu item -> report */ 
 376             item
->SetCheckedFlag(item
->IsChecked());  /* make consistent again */ 
 380     wxCommandEvent 
event( wxEVT_COMMAND_MENU_SELECTED
, id 
); 
 381     event
.SetEventObject( menu 
); 
 384     if (menu
->GetCallback()) 
 386         (void) (*(menu
->GetCallback())) (*menu
, event
); 
 390     if (menu
->GetEventHandler()->ProcessEvent(event
)) 
 393     wxWindow 
*win 
= menu
->GetInvokingWindow(); 
 395         win
->GetEventHandler()->ProcessEvent( event 
); 
 398 //----------------------------------------------------------------------------- 
 400 //----------------------------------------------------------------------------- 
 402 static void gtk_menu_hilight_callback( GtkWidget 
*widget
, wxMenu 
*menu 
) 
 404     if (g_isIdle
) wxapp_install_idle_handler(); 
 406     int id 
= menu
->FindMenuIdByMenuItem(widget
); 
 408     wxASSERT( id 
!= -1 ); // should find it! 
 410     if (!menu
->IsEnabled(id
)) 
 413     wxMenuEvent 
event( wxEVT_MENU_HIGHLIGHT
, id 
); 
 414     event
.SetEventObject( menu 
); 
 416 /*   wxMSW doesn't call callback here either 
 418      if (menu->m_callback) 
 420         (void) (*(menu->m_callback)) (*menu, event); 
 425     if (menu
->GetEventHandler()->ProcessEvent(event
)) 
 428     wxWindow 
*win 
= menu
->GetInvokingWindow(); 
 429     if (win
) win
->GetEventHandler()->ProcessEvent( event 
); 
 432 //----------------------------------------------------------------------------- 
 434 //----------------------------------------------------------------------------- 
 436 static void gtk_menu_nolight_callback( GtkWidget 
*widget
, wxMenu 
*menu 
) 
 438     if (g_isIdle
) wxapp_install_idle_handler(); 
 440     int id 
= menu
->FindMenuIdByMenuItem(widget
); 
 442     wxASSERT( id 
!= -1 ); // should find it! 
 444     if (!menu
->IsEnabled(id
)) 
 447     wxMenuEvent 
event( wxEVT_MENU_HIGHLIGHT
, -1 ); 
 448     event
.SetEventObject( menu 
); 
 450     if (menu
->GetEventHandler()->ProcessEvent(event
)) 
 453     wxWindow 
*win 
= menu
->GetInvokingWindow(); 
 455         win
->GetEventHandler()->ProcessEvent( event 
); 
 458 //----------------------------------------------------------------------------- 
 460 //----------------------------------------------------------------------------- 
 462 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
) 
 464 wxMenuItem::wxMenuItem() 
 467     m_isCheckMenu 
= FALSE
; 
 470     m_subMenu 
= (wxMenu 
*) NULL
; 
 471     m_menuItem 
= (GtkWidget 
*) NULL
; 
 474 // it's valid for this function to be called even if m_menuItem == NULL 
 475 void wxMenuItem::SetName( const wxString
& str 
) 
 477     /* '\t' is the deliminator indicating a hot key */ 
 479     const wxChar 
*pc 
= str
; 
 480     for (; (*pc 
!= _T('\0')) && (*pc 
!= _T('\t')); pc
++ ) 
 484 #if (GTK_MINOR_VERSION > 0) 
 492     /* only GTK 1.2 know about hot keys */ 
 494 #if (GTK_MINOR_VERSION > 0) 
 501         GtkLabel 
*label 
= GTK_LABEL( GTK_BIN(m_menuItem
)->child 
); 
 502         gtk_label_set( label
, m_text
.mb_str()); 
 506 void wxMenuItem::Check( bool check 
) 
 508     wxCHECK_RET( m_menuItem
, _T("invalid menu item") ); 
 510     wxCHECK_RET( IsCheckable(), _T("Can't check uncheckable item!") ) 
 512     if (check 
== m_isChecked
) return; 
 515     gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check 
); 
 518 void wxMenuItem::Enable( bool enable 
) 
 520     wxCHECK_RET( m_menuItem
, _T("invalid menu item") ); 
 522     gtk_widget_set_sensitive( m_menuItem
, enable 
); 
 523     m_isEnabled 
= enable
; 
 526 bool wxMenuItem::IsChecked() const 
 528     wxCHECK_MSG( m_menuItem
, FALSE
, _T("invalid menu item") ); 
 530     wxCHECK( IsCheckable(), FALSE 
); // can't get state of uncheckable item! 
 532     bool bIsChecked 
= ((GtkCheckMenuItem
*)m_menuItem
)->active 
!= 0; 
 537 //----------------------------------------------------------------------------- 
 539 //----------------------------------------------------------------------------- 
 541 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
) 
 543 wxMenu::wxMenu( const wxString
& title
, const wxFunction func 
) 
 546     m_items
.DeleteContents( TRUE 
); 
 547     m_invokingWindow 
= (wxWindow 
*) NULL
; 
 549 #if (GTK_MINOR_VERSION > 0) 
 550     m_accel 
= gtk_accel_group_new(); 
 551     m_factory 
= gtk_item_factory_new( GTK_TYPE_MENU
, "<main>", m_accel 
); 
 552     m_menu 
= gtk_item_factory_get_widget( m_factory
, "<main>" ); 
 554     m_menu 
= gtk_menu_new();  // Do not show! 
 558     m_eventHandler 
= this; 
 559     m_clientData 
= (void*) NULL
; 
 561     if (m_title
.IsNull()) m_title 
= _T(""); 
 562     if (m_title 
!= _T("")) 
 568     m_owner 
= (GtkWidget
*) NULL
; 
 573     /* how do we delete an item-factory ? */ 
 576 void wxMenu::SetTitle( const wxString
& title 
) 
 578     // TODO Waiting for something better 
 582 const wxString 
wxMenu::GetTitle() const 
 587 void wxMenu::AppendSeparator() 
 589     wxMenuItem 
*mitem 
= new wxMenuItem(); 
 590     mitem
->SetId(ID_SEPARATOR
); 
 592     GtkWidget 
*menuItem 
= gtk_menu_item_new(); 
 593     gtk_menu_append( GTK_MENU(m_menu
), menuItem 
); 
 594     gtk_widget_show( menuItem 
); 
 596     mitem
->SetMenuItem(menuItem
); 
 597     m_items
.Append( mitem 
); 
 600 void wxMenu::Append( int id
, const wxString 
&item
, const wxString 
&helpStr
, bool checkable 
) 
 602     wxMenuItem 
*mitem 
= new wxMenuItem(); 
 604     mitem
->SetText(item
); 
 605     mitem
->SetHelp(helpStr
); 
 606     mitem
->SetCheckable(checkable
); 
 608 #if (GTK_MINOR_VERSION > 0) 
 609     /* text has "_" instead of "&" after mitem->SetText() */  
 610     wxString 
text( mitem
->GetText() ); 
 612     /* local buffer in multibyte form */ 
 615     strcat( buf
, text
.mb_str() ); 
 617     GtkItemFactoryEntry entry
; 
 619     entry
.callback 
= (GtkItemFactoryCallback
) gtk_menu_clicked_callback
; 
 620     entry
.callback_action 
= 0; 
 622         entry
.item_type 
= "<CheckItem>"; 
 624         entry
.item_type 
= "<Item>"; 
 626     entry
.accelerator 
= (gchar
*) NULL
; 
 628     wxString 
hotkey( mitem
->GetHotKey() ); 
 629     if (!hotkey
.IsEmpty()) 
 633             case _T('a'):   /* Alt */ 
 635             case _T('m'):   /* Meta */ 
 638                strcpy( hotbuf
, "<alt>" ); 
 639                wxString last 
= hotkey
.Right(1); 
 640                strcat( hotbuf
, last
.mb_str() ); 
 641                entry
.accelerator 
= hotbuf
; 
 644             case _T('c'):    /* Ctrl */ 
 646             case _T('s'):    /* Strg, yeah man, I'm German */ 
 649                strcpy( hotbuf
, "<control>" ); 
 650                wxString last 
= hotkey
.Right(1); 
 651                strcat( hotbuf
, last
.mb_str() ); 
 652                entry
.accelerator 
= hotbuf
; 
 661     gtk_item_factory_create_item( m_factory
, &entry
, (gpointer
) this, 2 );  /* what is 2 ? */ 
 663     /* in order to get the pointer to the item we need the item text _without_ underscores */ 
 664     wxString s 
= _T("<main>/"); 
 665     for ( const wxChar 
*pc 
= text
; *pc 
!= _T('\0'); pc
++ ) 
 667         if (*pc 
== _T('\t')) break; 
 668         if (*pc 
== _T('_')) pc
++; /* skip it */ 
 672     GtkWidget 
*menuItem 
= gtk_item_factory_get_widget( m_factory
, s
.mb_str() ); 
 676     GtkWidget 
*menuItem 
= checkable 
? gtk_check_menu_item_new_with_label( mitem
->GetText().mb_str() ) 
 677                                     : gtk_menu_item_new_with_label( mitem
->GetText().mb_str() ); 
 679     gtk_signal_connect( GTK_OBJECT(menuItem
), "activate", 
 680                         GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
), 
 683     gtk_menu_append( GTK_MENU(m_menu
), menuItem 
); 
 684     gtk_widget_show( menuItem 
); 
 688     gtk_signal_connect( GTK_OBJECT(menuItem
), "select", 
 689                         GTK_SIGNAL_FUNC(gtk_menu_hilight_callback
), 
 692     gtk_signal_connect( GTK_OBJECT(menuItem
), "deselect", 
 693                         GTK_SIGNAL_FUNC(gtk_menu_nolight_callback
), 
 696     mitem
->SetMenuItem(menuItem
); 
 698     m_items
.Append( mitem 
); 
 701 void wxMenu::Append( int id
, const wxString 
&text
, wxMenu 
*subMenu
, const wxString 
&helpStr 
) 
 703     wxMenuItem 
*mitem 
= new wxMenuItem(); 
 705     mitem
->SetText(text
); 
 706     mitem
->SetHelp(helpStr
); 
 708     GtkWidget 
*menuItem 
= gtk_menu_item_new_with_label(mitem
->GetText().mbc_str()); 
 709     mitem
->SetMenuItem(menuItem
); 
 710     mitem
->SetSubMenu(subMenu
); 
 712     gtk_signal_connect( GTK_OBJECT(menuItem
), "select", 
 713                         GTK_SIGNAL_FUNC(gtk_menu_hilight_callback
), 
 716     gtk_signal_connect( GTK_OBJECT(menuItem
), "deselect", 
 717                         GTK_SIGNAL_FUNC(gtk_menu_nolight_callback
), 
 720     gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem
), subMenu
->m_menu 
); 
 721     gtk_menu_append( GTK_MENU(m_menu
), menuItem 
); 
 722     gtk_widget_show( menuItem 
); 
 723     m_items
.Append( mitem 
); 
 726 void wxMenu::Append( wxMenuItem 
*item 
) 
 728     m_items
.Append( item 
); 
 730     GtkWidget 
*menuItem 
= (GtkWidget
*) NULL
; 
 732     if (item
->IsSeparator()) 
 733         menuItem 
= gtk_menu_item_new(); 
 734     else if (item
->IsSubMenu()) 
 735         menuItem 
= gtk_menu_item_new_with_label(item
->GetText().mbc_str()); 
 737         menuItem 
= item
->IsCheckable() ? gtk_check_menu_item_new_with_label(item
->GetText().mbc_str()) 
 738                                        : gtk_menu_item_new_with_label(item
->GetText().mbc_str()); 
 740     if (!item
->IsSeparator()) 
 742         gtk_signal_connect( GTK_OBJECT(menuItem
), "select", 
 743                             GTK_SIGNAL_FUNC(gtk_menu_hilight_callback
), 
 746         gtk_signal_connect( GTK_OBJECT(menuItem
), "deselect", 
 747                             GTK_SIGNAL_FUNC(gtk_menu_nolight_callback
), 
 750         if (!item
->IsSubMenu()) 
 752             gtk_signal_connect( GTK_OBJECT(menuItem
), "activate", 
 753                                 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
), 
 758     gtk_menu_append( GTK_MENU(m_menu
), menuItem 
); 
 759     gtk_widget_show( menuItem 
); 
 760     item
->SetMenuItem(menuItem
); 
 763 int wxMenu::FindItem( const wxString itemString 
) const 
 766     for ( const wxChar 
*pc 
= itemString
; *pc 
!= _T('\0'); pc
++ ) 
 771 #if (GTK_MINOR_VERSION > 0) 
 778     wxNode 
*node 
= m_items
.First(); 
 781         wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 782         if (item
->GetText() == s
) 
 784             return item
->GetId(); 
 792 void wxMenu::Enable( int id
, bool enable 
) 
 794     wxMenuItem 
*item 
= FindItem(id
); 
 796     wxCHECK_RET( item
, _T("wxMenu::Enable: no such item") ); 
 798     item
->Enable(enable
); 
 801 bool wxMenu::IsEnabled( int id 
) const 
 803     wxMenuItem 
*item 
= FindItem(id
); 
 805     wxCHECK_MSG( item
, FALSE
, _T("wxMenu::IsEnabled: no such item") ); 
 807     return item
->IsEnabled(); 
 810 void wxMenu::Check( int id
, bool enable 
) 
 812     wxMenuItem 
*item 
= FindItem(id
); 
 814     wxCHECK_RET( item
, _T("wxMenu::Check: no such item") ); 
 819 bool wxMenu::IsChecked( int id 
) const 
 821     wxMenuItem 
*item 
= FindItem(id
); 
 823     wxCHECK_MSG( item
, FALSE
, _T("wxMenu::IsChecked: no such item") ); 
 825     return item
->IsChecked(); 
 828 void wxMenu::SetLabel( int id
, const wxString 
&label 
) 
 830     wxMenuItem 
*item 
= FindItem(id
); 
 832     wxCHECK_RET( item
, _T("wxMenu::SetLabel: no such item") ); 
 834     item
->SetText(label
); 
 837 wxString 
wxMenu::GetLabel( int id 
) const 
 839     wxMenuItem 
*item 
= FindItem(id
); 
 841     wxCHECK_MSG( item
, _T(""), _T("wxMenu::GetLabel: no such item") ); 
 843     return item
->GetText(); 
 846 void wxMenu::SetHelpString( int id
, const wxString
& helpString 
) 
 848     wxMenuItem 
*item 
= FindItem(id
); 
 850     wxCHECK_RET( item
, _T("wxMenu::SetHelpString: no such item") ); 
 852     item
->SetHelp( helpString 
); 
 855 wxString 
wxMenu::GetHelpString( int id 
) const 
 857     wxMenuItem 
*item 
= FindItem(id
); 
 859     wxCHECK_MSG( item
, _T(""), _T("wxMenu::GetHelpString: no such item") ); 
 861     return item
->GetHelp(); 
 864 int wxMenu::FindMenuIdByMenuItem( GtkWidget 
*menuItem 
) const 
 866     wxNode 
*node 
= m_items
.First(); 
 869         wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 870         if (item
->GetMenuItem() == menuItem
) 
 871            return item
->GetId(); 
 878 wxMenuItem 
*wxMenu::FindItem(int id
) const 
 880     wxNode 
*node 
= m_items
.First(); 
 883         wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 884         if (item
->GetId() == id
) 
 891     /* Not finding anything here can be correct 
 892      * when search the entire menu system for 
 893      * an entry -> no error message. */ 
 895     return (wxMenuItem 
*) NULL
; 
 898 void wxMenu::SetInvokingWindow( wxWindow 
*win 
) 
 900     m_invokingWindow 
= win
; 
 903 wxWindow 
*wxMenu::GetInvokingWindow() 
 905     return m_invokingWindow
; 
 908 // Update a menu and all submenus recursively. source is the object that has 
 909 // the update event handlers defined for it. If NULL, the menu or associated 
 910 // window will be used. 
 911 void wxMenu::UpdateUI(wxEvtHandler
* source
) 
 913   if (!source 
&& GetInvokingWindow()) 
 914     source 
= GetInvokingWindow()->GetEventHandler(); 
 916     source 
= GetEventHandler(); 
 920   wxNode
* node 
= GetItems().First(); 
 923     wxMenuItem
* item 
= (wxMenuItem
*) node
->Data(); 
 924     if ( !item
->IsSeparator() ) 
 926       wxWindowID id 
= item
->GetId(); 
 927       wxUpdateUIEvent 
event(id
); 
 928       event
.SetEventObject( source 
); 
 930       if (source
->ProcessEvent(event
)) 
 932         if (event
.GetSetText()) 
 933           SetLabel(id
, event
.GetText()); 
 934         if (event
.GetSetChecked()) 
 935           Check(id
, event
.GetChecked()); 
 936         if (event
.GetSetEnabled()) 
 937           Enable(id
, event
.GetEnabled()); 
 940       if (item
->GetSubMenu()) 
 941         item
->GetSubMenu()->UpdateUI(source
);