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)
122 /* this doesn't have much effect right now */
123 menu
->SetTitle( str
);
125 /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */
126 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
128 /* local buffer in multibyte form */
131 strcat( buf
, str
.mb_str() );
133 GtkItemFactoryEntry entry
;
135 entry
.accelerator
= (gchar
*) NULL
;
136 entry
.callback
= (GtkItemFactoryCallback
) NULL
;
137 entry
.callback_action
= 0;
138 entry
.item_type
= "<Branch>";
140 gtk_item_factory_create_item( m_factory
, &entry
, (gpointer
) this, 2 ); /* what is 2 ? */
142 /* in order to get the pointer to the item we need the item text _without_ underscores */
143 wxString tmp
= _T("<main>/");
144 for ( const wxChar
*pc
= str
; *pc
!= _T('\0'); pc
++ )
146 if (*pc
== _T('_')) pc
++; /* skip it */
150 menu
->m_owner
= gtk_item_factory_get_item( m_factory
, tmp
.mb_str() );
152 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu
->m_owner
), menu
->m_menu
);
156 menu
->m_owner
= gtk_menu_item_new_with_label( str
.mb_str() );
157 gtk_widget_show( menu
->m_owner
);
158 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu
->m_owner
), menu
->m_menu
);
160 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), menu
->m_owner
);
165 static int FindMenuItemRecursive( const wxMenu
*menu
, const wxString
&menuString
, const wxString
&itemString
)
167 if (menu
->GetTitle() == menuString
)
169 int res
= menu
->FindItem( itemString
);
170 if (res
!= wxNOT_FOUND
)
174 wxNode
*node
= ((wxMenu
*)menu
)->GetItems().First(); // const_cast
177 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
178 if (item
->IsSubMenu())
179 return FindMenuItemRecursive(item
->GetSubMenu(), menuString
, itemString
);
187 wxMenuItem
*wxMenuBar::FindItemForId(int itemId
, wxMenu
**menuForItem
) const
191 // TODO return the pointer to the menu
196 return FindItem(itemId
);
199 int wxMenuBar::FindMenuItem( const wxString
&menuString
, const wxString
&itemString
) const
201 wxNode
*node
= m_menus
.First();
204 wxMenu
*menu
= (wxMenu
*)node
->Data();
205 int res
= FindMenuItemRecursive( menu
, menuString
, itemString
);
206 if (res
!= -1) return res
;
212 // Find a wxMenuItem using its id. Recurses down into sub-menus
213 static wxMenuItem
* FindMenuItemByIdRecursive(const wxMenu
* menu
, int id
)
215 wxMenuItem
* result
= menu
->FindItem(id
);
217 wxNode
*node
= ((wxMenu
*)menu
)->GetItems().First(); // const_cast
218 while ( node
&& result
== NULL
)
220 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
221 if (item
->IsSubMenu())
223 result
= FindMenuItemByIdRecursive( item
->GetSubMenu(), id
);
231 wxMenuItem
* wxMenuBar::FindItem( int id
) const
233 wxMenuItem
* result
= 0;
234 wxNode
*node
= m_menus
.First();
235 while (node
&& result
== 0)
237 wxMenu
*menu
= (wxMenu
*)node
->Data();
238 result
= FindMenuItemByIdRecursive( menu
, id
);
245 void wxMenuBar::Check( int id
, bool check
)
247 wxMenuItem
* item
= FindMenuItemById( id
);
249 wxCHECK_RET( item
, _T("wxMenuBar::Check: no such item") );
254 bool wxMenuBar::IsChecked( int id
) const
256 wxMenuItem
* item
= FindMenuItemById( id
);
258 wxCHECK_MSG( item
, FALSE
, _T("wxMenuBar::IsChecked: no such item") );
260 return item
->IsChecked();
263 void wxMenuBar::Enable( int id
, bool enable
)
265 wxMenuItem
* item
= FindMenuItemById( id
);
267 wxCHECK_RET( item
, _T("wxMenuBar::Enable: no such item") );
269 item
->Enable(enable
);
272 bool wxMenuBar::IsEnabled( int id
) const
274 wxMenuItem
* item
= FindMenuItemById( id
);
276 wxCHECK_MSG( item
, FALSE
, _T("wxMenuBar::IsEnabled: no such item") );
278 return item
->IsEnabled();
281 wxString
wxMenuBar::GetLabel( int id
) const
283 wxMenuItem
* item
= FindMenuItemById( id
);
285 wxCHECK_MSG( item
, _T(""), _T("wxMenuBar::GetLabel: no such item") );
287 return item
->GetText();
290 void wxMenuBar::SetLabel( int id
, const wxString
&label
)
292 wxMenuItem
* item
= FindMenuItemById( id
);
294 wxCHECK_RET( item
, _T("wxMenuBar::SetLabel: no such item") );
296 item
->SetText( label
);
299 void wxMenuBar::EnableTop( int pos
, bool flag
)
301 wxNode
*node
= m_menus
.Nth( pos
);
303 wxCHECK_RET( node
, _T("menu not found") );
305 wxMenu
* menu
= (wxMenu
*)node
->Data();
308 gtk_widget_set_sensitive( menu
->m_owner
, flag
);
311 wxString
wxMenuBar::GetLabelTop( int pos
) const
313 wxNode
*node
= m_menus
.Nth( pos
);
315 wxCHECK_MSG( node
, _T("invalid"), _T("menu not found") );
317 wxMenu
* menu
= (wxMenu
*)node
->Data();
319 return menu
->GetTitle();
322 void wxMenuBar::SetLabelTop( int pos
, const wxString
& label
)
324 wxNode
*node
= m_menus
.Nth( pos
);
326 wxCHECK_RET( node
, _T("menu not found") );
328 wxMenu
* menu
= (wxMenu
*)node
->Data();
330 menu
->SetTitle( label
);
333 void wxMenuBar::SetHelpString( int id
, const wxString
& helpString
)
335 wxMenuItem
* item
= FindMenuItemById( id
);
337 wxCHECK_RET( item
, _T("wxMenuBar::SetHelpString: no such item") );
339 item
->SetHelp( helpString
);
342 wxString
wxMenuBar::GetHelpString( int id
) const
344 wxMenuItem
* item
= FindMenuItemById( id
);
346 wxCHECK_MSG( item
, _T(""), _T("wxMenuBar::GetHelpString: no such item") );
348 return item
->GetHelp();
351 //-----------------------------------------------------------------------------
353 //-----------------------------------------------------------------------------
355 static void gtk_menu_clicked_callback( GtkWidget
*widget
, wxMenu
*menu
)
357 if (g_isIdle
) wxapp_install_idle_handler();
359 int id
= menu
->FindMenuIdByMenuItem(widget
);
361 /* should find it for normal (not popup) menu */
362 wxASSERT( (id
!= -1) || (menu
->GetInvokingWindow() != NULL
) );
364 if (!menu
->IsEnabled(id
))
367 wxMenuItem
* item
= menu
->FindItem( id
);
368 wxCHECK_RET( item
, _T("error in menu item callback") );
370 if (item
->IsCheckable())
372 if (item
->GetCheckedFlag() == item
->IsChecked())
374 /* the menu item has been checked by calling wxMenuItem->Check() */
379 /* the user pressed on the menu item -> report */
380 item
->SetCheckedFlag(item
->IsChecked()); /* make consistent again */
384 wxCommandEvent
event( wxEVT_COMMAND_MENU_SELECTED
, id
);
385 event
.SetEventObject( menu
);
388 if (menu
->GetCallback())
390 (void) (*(menu
->GetCallback())) (*menu
, event
);
394 if (menu
->GetEventHandler()->ProcessEvent(event
))
397 wxWindow
*win
= menu
->GetInvokingWindow();
399 win
->GetEventHandler()->ProcessEvent( event
);
402 //-----------------------------------------------------------------------------
404 //-----------------------------------------------------------------------------
406 static void gtk_menu_hilight_callback( GtkWidget
*widget
, wxMenu
*menu
)
408 if (g_isIdle
) wxapp_install_idle_handler();
410 int id
= menu
->FindMenuIdByMenuItem(widget
);
412 wxASSERT( id
!= -1 ); // should find it!
414 if (!menu
->IsEnabled(id
))
417 wxMenuEvent
event( wxEVT_MENU_HIGHLIGHT
, id
);
418 event
.SetEventObject( menu
);
420 /* wxMSW doesn't call callback here either
422 if (menu->m_callback)
424 (void) (*(menu->m_callback)) (*menu, event);
429 if (menu
->GetEventHandler()->ProcessEvent(event
))
432 wxWindow
*win
= menu
->GetInvokingWindow();
433 if (win
) win
->GetEventHandler()->ProcessEvent( event
);
436 //-----------------------------------------------------------------------------
438 //-----------------------------------------------------------------------------
440 static void gtk_menu_nolight_callback( GtkWidget
*widget
, wxMenu
*menu
)
442 if (g_isIdle
) wxapp_install_idle_handler();
444 int id
= menu
->FindMenuIdByMenuItem(widget
);
446 wxASSERT( id
!= -1 ); // should find it!
448 if (!menu
->IsEnabled(id
))
451 wxMenuEvent
event( wxEVT_MENU_HIGHLIGHT
, -1 );
452 event
.SetEventObject( menu
);
454 if (menu
->GetEventHandler()->ProcessEvent(event
))
457 wxWindow
*win
= menu
->GetInvokingWindow();
459 win
->GetEventHandler()->ProcessEvent( event
);
462 //-----------------------------------------------------------------------------
464 //-----------------------------------------------------------------------------
466 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
)
468 wxMenuItem::wxMenuItem()
471 m_isCheckMenu
= FALSE
;
474 m_subMenu
= (wxMenu
*) NULL
;
475 m_menuItem
= (GtkWidget
*) NULL
;
478 // it's valid for this function to be called even if m_menuItem == NULL
479 void wxMenuItem::SetName( const wxString
& str
)
481 /* '\t' is the deliminator indicating a hot key */
483 const wxChar
*pc
= str
;
484 for (; (*pc
!= _T('\0')) && (*pc
!= _T('\t')); pc
++ )
488 #if (GTK_MINOR_VERSION > 0)
491 if (*pc
== _T('/')) /* we have to filter out slashes ... */
493 m_text
<< _T('\\'); /* ... and replace them with back slashes */
500 /* only GTK 1.2 know about hot keys */
502 #if (GTK_MINOR_VERSION > 0)
512 GtkLabel
*label
= GTK_LABEL( GTK_BIN(m_menuItem
)->child
);
513 gtk_label_set( label
, m_text
.mb_str());
517 void wxMenuItem::Check( bool check
)
519 wxCHECK_RET( m_menuItem
, _T("invalid menu item") );
521 wxCHECK_RET( IsCheckable(), _T("Can't check uncheckable item!") )
523 if (check
== m_isChecked
) return;
526 gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check
);
529 void wxMenuItem::Enable( bool enable
)
531 wxCHECK_RET( m_menuItem
, _T("invalid menu item") );
533 gtk_widget_set_sensitive( m_menuItem
, enable
);
534 m_isEnabled
= enable
;
537 bool wxMenuItem::IsChecked() const
539 wxCHECK_MSG( m_menuItem
, FALSE
, _T("invalid menu item") );
541 wxCHECK( IsCheckable(), FALSE
); // can't get state of uncheckable item!
543 bool bIsChecked
= ((GtkCheckMenuItem
*)m_menuItem
)->active
!= 0;
548 //-----------------------------------------------------------------------------
550 //-----------------------------------------------------------------------------
552 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
)
554 wxMenu::wxMenu( const wxString
& title
, const wxFunction func
)
557 m_items
.DeleteContents( TRUE
);
558 m_invokingWindow
= (wxWindow
*) NULL
;
560 #if (GTK_MINOR_VERSION > 0)
561 m_accel
= gtk_accel_group_new();
562 m_factory
= gtk_item_factory_new( GTK_TYPE_MENU
, "<main>", m_accel
);
563 m_menu
= gtk_item_factory_get_widget( m_factory
, "<main>" );
565 m_menu
= gtk_menu_new(); // Do not show!
569 m_eventHandler
= this;
570 m_clientData
= (void*) NULL
;
572 if (m_title
.IsNull()) m_title
= _T("");
573 if (m_title
!= _T(""))
579 m_owner
= (GtkWidget
*) NULL
;
584 /* how do we delete an item-factory ? */
587 void wxMenu::SetTitle( const wxString
& title
)
589 // TODO Waiting for something better
593 const wxString
wxMenu::GetTitle() const
598 void wxMenu::AppendSeparator()
600 wxMenuItem
*mitem
= new wxMenuItem();
601 mitem
->SetId(ID_SEPARATOR
);
603 #if (GTK_MINOR_VERSION > 0)
604 GtkItemFactoryEntry entry
;
606 entry
.callback
= (GtkItemFactoryCallback
) NULL
;
607 entry
.callback_action
= 0;
608 entry
.item_type
= "<Separator>";
609 entry
.accelerator
= (gchar
*) NULL
;
611 gtk_item_factory_create_item( m_factory
, &entry
, (gpointer
) this, 2 ); /* what is 2 ? */
613 /* this will be wrong for more than one separator. do we care? */
614 GtkWidget
*menuItem
= gtk_item_factory_get_widget( m_factory
, "<main>/sep" );
616 GtkWidget
*menuItem
= gtk_menu_item_new();
617 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
618 gtk_widget_show( menuItem
);
621 mitem
->SetMenuItem(menuItem
);
622 m_items
.Append( mitem
);
625 void wxMenu::Append( int id
, const wxString
&item
, const wxString
&helpStr
, bool checkable
)
627 wxMenuItem
*mitem
= new wxMenuItem();
629 mitem
->SetText(item
);
630 mitem
->SetHelp(helpStr
);
631 mitem
->SetCheckable(checkable
);
633 #if (GTK_MINOR_VERSION > 0)
634 /* text has "_" instead of "&" after mitem->SetText() */
635 wxString
text( mitem
->GetText() );
637 /* local buffer in multibyte form */
640 strcat( buf
, text
.mb_str() );
642 GtkItemFactoryEntry entry
;
644 entry
.callback
= (GtkItemFactoryCallback
) gtk_menu_clicked_callback
;
645 entry
.callback_action
= 0;
647 entry
.item_type
= "<CheckItem>";
649 entry
.item_type
= "<Item>";
651 entry
.accelerator
= (gchar
*) NULL
;
653 wxString
hotkey( mitem
->GetHotKey() );
654 if (!hotkey
.IsEmpty())
658 case _T('a'): /* Alt */
660 case _T('m'): /* Meta */
663 strcpy( hotbuf
, "<alt>" );
664 wxString last
= hotkey
.Right(1);
665 strcat( hotbuf
, last
.mb_str() );
666 entry
.accelerator
= hotbuf
;
669 case _T('c'): /* Ctrl */
671 case _T('s'): /* Strg, yeah man, I'm German */
674 strcpy( hotbuf
, "<control>" );
675 wxString last
= hotkey
.Right(1);
676 strcat( hotbuf
, last
.mb_str() );
677 entry
.accelerator
= hotbuf
;
680 case _T('F'): /* function keys */
682 strcpy( hotbuf
, hotkey
.mb_str() );
683 entry
.accelerator
= hotbuf
;
692 gtk_item_factory_create_item( m_factory
, &entry
, (gpointer
) this, 2 ); /* what is 2 ? */
694 /* in order to get the pointer to the item we need the item text _without_ underscores */
695 wxString s
= _T("<main>/");
696 for ( const wxChar
*pc
= text
; *pc
!= _T('\0'); pc
++ )
698 if (*pc
== _T('_')) pc
++; /* skip it */
702 GtkWidget
*menuItem
= gtk_item_factory_get_widget( m_factory
, s
.mb_str() );
706 GtkWidget
*menuItem
= checkable
? gtk_check_menu_item_new_with_label( mitem
->GetText().mb_str() )
707 : gtk_menu_item_new_with_label( mitem
->GetText().mb_str() );
709 gtk_signal_connect( GTK_OBJECT(menuItem
), "activate",
710 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
),
713 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
714 gtk_widget_show( menuItem
);
718 gtk_signal_connect( GTK_OBJECT(menuItem
), "select",
719 GTK_SIGNAL_FUNC(gtk_menu_hilight_callback
),
722 gtk_signal_connect( GTK_OBJECT(menuItem
), "deselect",
723 GTK_SIGNAL_FUNC(gtk_menu_nolight_callback
),
726 mitem
->SetMenuItem(menuItem
);
728 m_items
.Append( mitem
);
731 void wxMenu::Append( int id
, const wxString
&text
, wxMenu
*subMenu
, const wxString
&helpStr
)
733 wxMenuItem
*mitem
= new wxMenuItem();
735 mitem
->SetText(text
);
736 mitem
->SetHelp(helpStr
);
738 GtkWidget
*menuItem
= gtk_menu_item_new_with_label(mitem
->GetText().mbc_str());
739 mitem
->SetMenuItem(menuItem
);
740 mitem
->SetSubMenu(subMenu
);
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 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem
), subMenu
->m_menu
);
751 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
752 gtk_widget_show( menuItem
);
753 m_items
.Append( mitem
);
756 void wxMenu::Append( wxMenuItem
*item
)
758 m_items
.Append( item
);
760 GtkWidget
*menuItem
= (GtkWidget
*) NULL
;
762 if (item
->IsSeparator())
763 menuItem
= gtk_menu_item_new();
764 else if (item
->IsSubMenu())
765 menuItem
= gtk_menu_item_new_with_label(item
->GetText().mbc_str());
767 menuItem
= item
->IsCheckable() ? gtk_check_menu_item_new_with_label(item
->GetText().mbc_str())
768 : gtk_menu_item_new_with_label(item
->GetText().mbc_str());
770 if (!item
->IsSeparator())
772 gtk_signal_connect( GTK_OBJECT(menuItem
), "select",
773 GTK_SIGNAL_FUNC(gtk_menu_hilight_callback
),
776 gtk_signal_connect( GTK_OBJECT(menuItem
), "deselect",
777 GTK_SIGNAL_FUNC(gtk_menu_nolight_callback
),
780 if (!item
->IsSubMenu())
782 gtk_signal_connect( GTK_OBJECT(menuItem
), "activate",
783 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
),
788 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
789 gtk_widget_show( menuItem
);
790 item
->SetMenuItem(menuItem
);
793 int wxMenu::FindItem( const wxString itemString
) const
796 for ( const wxChar
*pc
= itemString
; *pc
!= _T('\0'); pc
++ )
801 #if (GTK_MINOR_VERSION > 0)
808 wxNode
*node
= m_items
.First();
811 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
812 if (item
->GetText() == s
)
814 return item
->GetId();
822 void wxMenu::Enable( int id
, bool enable
)
824 wxMenuItem
*item
= FindItem(id
);
826 wxCHECK_RET( item
, _T("wxMenu::Enable: no such item") );
828 item
->Enable(enable
);
831 bool wxMenu::IsEnabled( int id
) const
833 wxMenuItem
*item
= FindItem(id
);
835 wxCHECK_MSG( item
, FALSE
, _T("wxMenu::IsEnabled: no such item") );
837 return item
->IsEnabled();
840 void wxMenu::Check( int id
, bool enable
)
842 wxMenuItem
*item
= FindItem(id
);
844 wxCHECK_RET( item
, _T("wxMenu::Check: no such item") );
849 bool wxMenu::IsChecked( int id
) const
851 wxMenuItem
*item
= FindItem(id
);
853 wxCHECK_MSG( item
, FALSE
, _T("wxMenu::IsChecked: no such item") );
855 return item
->IsChecked();
858 void wxMenu::SetLabel( int id
, const wxString
&label
)
860 wxMenuItem
*item
= FindItem(id
);
862 wxCHECK_RET( item
, _T("wxMenu::SetLabel: no such item") );
864 item
->SetText(label
);
867 wxString
wxMenu::GetLabel( int id
) const
869 wxMenuItem
*item
= FindItem(id
);
871 wxCHECK_MSG( item
, _T(""), _T("wxMenu::GetLabel: no such item") );
873 return item
->GetText();
876 void wxMenu::SetHelpString( int id
, const wxString
& helpString
)
878 wxMenuItem
*item
= FindItem(id
);
880 wxCHECK_RET( item
, _T("wxMenu::SetHelpString: no such item") );
882 item
->SetHelp( helpString
);
885 wxString
wxMenu::GetHelpString( int id
) const
887 wxMenuItem
*item
= FindItem(id
);
889 wxCHECK_MSG( item
, _T(""), _T("wxMenu::GetHelpString: no such item") );
891 return item
->GetHelp();
894 int wxMenu::FindMenuIdByMenuItem( GtkWidget
*menuItem
) const
896 wxNode
*node
= m_items
.First();
899 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
900 if (item
->GetMenuItem() == menuItem
)
901 return item
->GetId();
908 wxMenuItem
*wxMenu::FindItem(int id
) const
910 wxNode
*node
= m_items
.First();
913 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
914 if (item
->GetId() == id
)
921 /* Not finding anything here can be correct
922 * when search the entire menu system for
923 * an entry -> no error message. */
925 return (wxMenuItem
*) NULL
;
928 void wxMenu::SetInvokingWindow( wxWindow
*win
)
930 m_invokingWindow
= win
;
933 wxWindow
*wxMenu::GetInvokingWindow()
935 return m_invokingWindow
;
938 // Update a menu and all submenus recursively. source is the object that has
939 // the update event handlers defined for it. If NULL, the menu or associated
940 // window will be used.
941 void wxMenu::UpdateUI(wxEvtHandler
* source
)
943 if (!source
&& GetInvokingWindow())
944 source
= GetInvokingWindow()->GetEventHandler();
946 source
= GetEventHandler();
950 wxNode
* node
= GetItems().First();
953 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
954 if ( !item
->IsSeparator() )
956 wxWindowID id
= item
->GetId();
957 wxUpdateUIEvent
event(id
);
958 event
.SetEventObject( source
);
960 if (source
->ProcessEvent(event
))
962 if (event
.GetSetText())
963 SetLabel(id
, event
.GetText());
964 if (event
.GetSetChecked())
965 Check(id
, event
.GetChecked());
966 if (event
.GetSetEnabled())
967 Enable(id
, event
.GetEnabled());
970 if (item
->GetSubMenu())
971 item
->GetSubMenu()->UpdateUI(source
);