]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/menu.cpp
Fixed doubled-up key effects in wxTextCtrl by resetting m_lastMsg to 0
[wxWidgets.git] / src / gtk1 / menu.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: menu.cpp
3// Purpose:
4// Author: Robert Roebling
96fd301f 5// Id: $Id$
a81258be 6// Copyright: (c) 1998 Robert Roebling
96fd301f 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
c801d85f
KB
10#ifdef __GNUG__
11#pragma implementation "menu.h"
6ca41e57 12#pragma implementation "menuitem.h"
c801d85f
KB
13#endif
14
15#include "wx/menu.h"
96fd301f 16#include "wx/log.h"
30dea054 17#include "wx/intl.h"
06cfab17 18#include "wx/app.h"
c801d85f 19
83624f79
RR
20#include "gdk/gdk.h"
21#include "gtk/gtk.h"
22
c801d85f
KB
23//-----------------------------------------------------------------------------
24// wxMenuBar
25//-----------------------------------------------------------------------------
26
27IMPLEMENT_DYNAMIC_CLASS(wxMenuBar,wxWindow)
28
3502e687
RR
29wxMenuBar::wxMenuBar( long style )
30{
31 m_needParent = FALSE; // hmmm
32
33 PreCreation( (wxWindow *) NULL, -1, wxDefaultPosition, wxDefaultSize, 0, "menu" );
34
35 m_menus.DeleteContents( TRUE );
36
37 m_menubar = gtk_menu_bar_new();
38
39 if (style & wxMB_DOCKABLE)
40 {
41 m_widget = gtk_handle_box_new();
c626a8b7
VZ
42 gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_menubar) );
43 gtk_widget_show( GTK_WIDGET(m_menubar) );
3502e687
RR
44 }
45 else
46 {
47 m_widget = GTK_WIDGET(m_menubar);
48 }
49
50 PostCreation();
51
52 Show( TRUE );
53}
54
96fd301f 55wxMenuBar::wxMenuBar()
c801d85f 56{
83624f79 57 m_needParent = FALSE; // hmmm
96fd301f 58
83624f79 59 PreCreation( (wxWindow *) NULL, -1, wxDefaultPosition, wxDefaultSize, 0, "menu" );
c801d85f 60
83624f79 61 m_menus.DeleteContents( TRUE );
96fd301f 62
83624f79 63 m_menubar = gtk_menu_bar_new();
8bbe427f 64
828f655f 65 m_widget = GTK_WIDGET(m_menubar);
96fd301f 66
83624f79 67 PostCreation();
c801d85f 68
83624f79 69 Show( TRUE );
6de97a3b 70}
c801d85f
KB
71
72void wxMenuBar::Append( wxMenu *menu, const wxString &title )
73{
83624f79 74 m_menus.Append( menu );
c626a8b7 75 wxString title2 = title;
96fd301f 76
83624f79 77 int pos;
c626a8b7 78 do
83624f79 79 {
c626a8b7
VZ
80 pos = title2.First( '&' );
81 if (pos != wxNOT_FOUND)
82 title2.Remove( pos, 1 );
83 } while (pos != wxNOT_FOUND);
84
85 menu->SetTitle(title2);
96fd301f 86
c626a8b7 87 menu->m_owner = gtk_menu_item_new_with_label( WXSTRINGCAST(title2) );
2b1c162e
RR
88 gtk_widget_show( menu->m_owner );
89 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu->m_owner), menu->m_menu );
96fd301f 90
2b1c162e 91 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar), menu->m_owner );
6de97a3b 92}
96fd301f 93
716b7364 94static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
c801d85f 95{
c626a8b7 96 if (menu->GetTitle() == menuString)
83624f79
RR
97 {
98 int res = menu->FindItem( itemString );
c626a8b7
VZ
99 if (res != wxNOT_FOUND)
100 return res;
83624f79 101 }
c626a8b7
VZ
102
103 wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
83624f79
RR
104 while (node)
105 {
106 wxMenuItem *item = (wxMenuItem*)node->Data();
107 if (item->IsSubMenu())
108 return FindMenuItemRecursive(item->GetSubMenu(), menuString, itemString);
2b1c162e 109
83624f79
RR
110 node = node->Next();
111 }
112
c626a8b7
VZ
113 return wxNOT_FOUND;
114}
115
116wxMenuItem *wxMenuBar::FindItemForId(int itemId, wxMenu **menuForItem = NULL) const
117{
118 if ( menuForItem )
119 {
120 // TODO return the pointer to the menu
121
122 *menuForItem = NULL;
123 }
124
125 return FindItem(itemId);
6de97a3b 126}
c801d85f
KB
127
128int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemString ) const
129{
83624f79
RR
130 wxNode *node = m_menus.First();
131 while (node)
132 {
133 wxMenu *menu = (wxMenu*)node->Data();
134 int res = FindMenuItemRecursive( menu, menuString, itemString);
135 if (res != -1) return res;
136 node = node->Next();
137 }
138 return -1;
6de97a3b 139}
c801d85f 140
c626a8b7 141// Find a wxMenuItem using its id. Recurses down into sub-menus
96fd301f 142static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id)
716b7364 143{
83624f79 144 wxMenuItem* result = menu->FindItem(id);
716b7364 145
c626a8b7
VZ
146 wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
147 while ( node && result == NULL )
83624f79
RR
148 {
149 wxMenuItem *item = (wxMenuItem*)node->Data();
150 if (item->IsSubMenu())
c626a8b7 151 {
83624f79 152 result = FindMenuItemByIdRecursive( item->GetSubMenu(), id );
c626a8b7 153 }
83624f79
RR
154 node = node->Next();
155 }
96fd301f 156
83624f79 157 return result;
6de97a3b 158}
716b7364 159
c626a8b7 160wxMenuItem* wxMenuBar::FindItem( int id ) const
716b7364 161{
83624f79
RR
162 wxMenuItem* result = 0;
163 wxNode *node = m_menus.First();
164 while (node && result == 0)
165 {
166 wxMenu *menu = (wxMenu*)node->Data();
167 result = FindMenuItemByIdRecursive( menu, id );
168 node = node->Next();
169 }
c626a8b7 170
83624f79 171 return result;
716b7364
RR
172}
173
54ff4a70
RR
174void wxMenuBar::Check( int id, bool check )
175{
83624f79 176 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
177
178 wxCHECK_RET( item, "wxMenuBar::Check: no such item" );
179
180 item->Check(check);
6de97a3b 181}
54ff4a70 182
c626a8b7 183bool wxMenuBar::IsChecked( int id ) const
716b7364 184{
83624f79 185 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
186
187 wxCHECK_MSG( item, FALSE, "wxMenuBar::IsChecked: no such item" );
188
189 return item->IsChecked();
6de97a3b 190}
716b7364 191
54ff4a70
RR
192void wxMenuBar::Enable( int id, bool enable )
193{
83624f79 194 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
195
196 wxCHECK_RET( item, "wxMenuBar::Enable: no such item" );
197
198 item->Enable(enable);
6de97a3b 199}
54ff4a70 200
c626a8b7 201bool wxMenuBar::IsEnabled( int id ) const
716b7364 202{
83624f79 203 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
204
205 wxCHECK_MSG( item, FALSE, "wxMenuBar::IsEnabled: no such item" );
206
207 return item->IsEnabled();
6de97a3b 208}
716b7364 209
bbe0af5b
RR
210wxString wxMenuBar::GetLabel( int id ) const
211{
212 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
213
214 wxCHECK_MSG( item, "", "wxMenuBar::GetLabel: no such item" );
215
216 return item->GetText();
bbe0af5b
RR
217}
218
219void wxMenuBar::SetLabel( int id, const wxString &label )
220{
221 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
222
223 wxCHECK_RET( item, "wxMenuBar::SetLabel: no such item" );
224
225 item->SetText( label );
bbe0af5b
RR
226}
227
2b1c162e 228void wxMenuBar::EnableTop( int pos, bool flag )
bbe0af5b 229{
2b1c162e 230 wxNode *node = m_menus.Nth( pos );
c626a8b7 231
2b1c162e 232 wxCHECK_RET( node, "menu not found" );
c626a8b7 233
2b1c162e 234 wxMenu* menu = (wxMenu*)node->Data();
c626a8b7
VZ
235
236 if (menu->m_owner)
237 gtk_widget_set_sensitive( menu->m_owner, flag );
bbe0af5b
RR
238}
239
2b1c162e 240wxString wxMenuBar::GetLabelTop( int pos ) const
bbe0af5b 241{
2b1c162e 242 wxNode *node = m_menus.Nth( pos );
c626a8b7 243
2b1c162e 244 wxCHECK_MSG( node, "invalid", "menu not found" );
c626a8b7 245
2b1c162e 246 wxMenu* menu = (wxMenu*)node->Data();
c626a8b7 247
2b1c162e 248 return menu->GetTitle();
bbe0af5b
RR
249}
250
2b1c162e 251void wxMenuBar::SetLabelTop( int pos, const wxString& label )
bbe0af5b 252{
2b1c162e 253 wxNode *node = m_menus.Nth( pos );
c626a8b7 254
2b1c162e 255 wxCHECK_RET( node, "menu not found" );
c626a8b7 256
2b1c162e 257 wxMenu* menu = (wxMenu*)node->Data();
c626a8b7 258
2b1c162e 259 menu->SetTitle( label );
bbe0af5b
RR
260}
261
342b6a2f
RR
262void wxMenuBar::SetHelpString( int id, const wxString& helpString )
263{
264 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
265
266 wxCHECK_RET( item, "wxMenuBar::SetHelpString: no such item" );
267
268 item->SetHelp( helpString );
342b6a2f
RR
269}
270
271wxString wxMenuBar::GetHelpString( int id ) const
272{
273 wxMenuItem* item = FindMenuItemById( id );
c626a8b7
VZ
274
275 wxCHECK_MSG( item, "", "wxMenuBar::GetHelpString: no such item" );
276
277 return item->GetHelp();
342b6a2f
RR
278}
279
c801d85f 280//-----------------------------------------------------------------------------
cf7a7e13 281// "activate"
c801d85f
KB
282//-----------------------------------------------------------------------------
283
6de97a3b 284static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
c801d85f 285{
83624f79 286 int id = menu->FindMenuIdByMenuItem(widget);
96fd301f 287
83624f79 288 /* should find it for normal (not popup) menu */
c626a8b7 289 wxASSERT( (id != -1) || (menu->GetInvokingWindow() != NULL) );
96fd301f 290
c626a8b7
VZ
291 if (!menu->IsEnabled(id))
292 return;
96fd301f 293
2d17d68f
RR
294 wxMenuItem* item = menu->FindItem( id );
295 wxCHECK_RET( item, "error in menu item callback" );
c626a8b7
VZ
296
297 if (item->IsCheckable())
2d17d68f 298 {
c626a8b7 299 if (item->GetCheckedFlag() == item->IsChecked())
2d17d68f 300 {
c626a8b7 301 /* the menu item has been checked by calling wxMenuItem->Check() */
2d17d68f 302 return;
c626a8b7
VZ
303 }
304 else
305 {
306 /* the user pressed on the menu item -> report */
307 item->SetCheckedFlag(item->IsChecked()); /* make consistent again */
308 }
2d17d68f
RR
309 }
310
83624f79
RR
311 wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, id );
312 event.SetEventObject( menu );
313 event.SetInt(id );
8bbe427f 314
c626a8b7 315 if (menu->GetCallback())
83624f79 316 {
c626a8b7 317 (void) (*(menu->GetCallback())) (*menu, event);
83624f79
RR
318 return;
319 }
cf7a7e13 320
c626a8b7
VZ
321 if (menu->GetEventHandler()->ProcessEvent(event))
322 return;
cf7a7e13 323
83624f79 324 wxWindow *win = menu->GetInvokingWindow();
c626a8b7
VZ
325 if (win)
326 win->GetEventHandler()->ProcessEvent( event );
cf7a7e13
RR
327}
328
329//-----------------------------------------------------------------------------
330// "select"
331//-----------------------------------------------------------------------------
332
333static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu )
334{
83624f79
RR
335 int id = menu->FindMenuIdByMenuItem(widget);
336
337 wxASSERT( id != -1 ); // should find it!
cf7a7e13 338
c626a8b7
VZ
339 if (!menu->IsEnabled(id))
340 return;
cf7a7e13 341
342b6a2f 342 wxMenuEvent event( wxEVT_MENU_HIGHLIGHT, id );
83624f79 343 event.SetEventObject( menu );
cf7a7e13 344
83624f79 345/* wxMSW doesn't call callback here either
8bbe427f 346
83624f79
RR
347 if (menu->m_callback)
348 {
349 (void) (*(menu->m_callback)) (*menu, event);
350 return;
351 }
13439807 352*/
6de97a3b 353
c626a8b7
VZ
354 if (menu->GetEventHandler()->ProcessEvent(event))
355 return;
6de97a3b 356
83624f79
RR
357 wxWindow *win = menu->GetInvokingWindow();
358 if (win) win->GetEventHandler()->ProcessEvent( event );
6de97a3b 359}
c801d85f 360
cd743a6f
RR
361//-----------------------------------------------------------------------------
362// "deselect"
363//-----------------------------------------------------------------------------
364
365static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu )
366{
367 int id = menu->FindMenuIdByMenuItem(widget);
368
369 wxASSERT( id != -1 ); // should find it!
370
c626a8b7
VZ
371 if (!menu->IsEnabled(id))
372 return;
cd743a6f
RR
373
374 wxMenuEvent event( wxEVT_MENU_HIGHLIGHT, -1 );
375 event.SetEventObject( menu );
376
c626a8b7
VZ
377 if (menu->GetEventHandler()->ProcessEvent(event))
378 return;
cd743a6f
RR
379
380 wxWindow *win = menu->GetInvokingWindow();
c626a8b7
VZ
381 if (win)
382 win->GetEventHandler()->ProcessEvent( event );
cd743a6f
RR
383}
384
cf7a7e13 385//-----------------------------------------------------------------------------
db1b4961 386// wxMenuItem
cf7a7e13
RR
387//-----------------------------------------------------------------------------
388
c801d85f 389IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
96fd301f
VZ
390
391wxMenuItem::wxMenuItem()
c801d85f 392{
83624f79
RR
393 m_id = ID_SEPARATOR;
394 m_isCheckMenu = FALSE;
395 m_isChecked = FALSE;
396 m_isEnabled = TRUE;
397 m_subMenu = (wxMenu *) NULL;
398 m_menuItem = (GtkWidget *) NULL;
6de97a3b 399}
c801d85f 400
c626a8b7 401// it's valid for this function to be called even if m_menuItem == NULL
83624f79 402void wxMenuItem::SetName( const wxString& str )
716b7364 403{
83624f79
RR
404 m_text = "";
405 for ( const char *pc = str; *pc != '\0'; pc++ )
406 {
407 if (*pc == '&') pc++; /* skip it */
408 m_text << *pc;
409 }
96fd301f 410
83624f79
RR
411 if (m_menuItem)
412 {
413 GtkLabel *label = GTK_LABEL( GTK_BIN(m_menuItem)->child );
414 gtk_label_set( label, m_text.c_str());
415 }
716b7364
RR
416}
417
96fd301f 418void wxMenuItem::Check( bool check )
716b7364 419{
83624f79 420 wxCHECK_RET( m_menuItem, "invalid menu item" );
db1b4961 421
83624f79 422 wxCHECK_RET( IsCheckable(), "Can't check uncheckable item!" )
96fd301f 423
2d17d68f
RR
424 if (check == m_isChecked) return;
425
83624f79
RR
426 m_isChecked = check;
427 gtk_check_menu_item_set_state( (GtkCheckMenuItem*)m_menuItem, (gint)check );
716b7364
RR
428}
429
8bbe427f
VZ
430void wxMenuItem::Enable( bool enable )
431{
83624f79 432 wxCHECK_RET( m_menuItem, "invalid menu item" );
db1b4961 433
83624f79
RR
434 gtk_widget_set_sensitive( m_menuItem, enable );
435 m_isEnabled = enable;
a9c96bcc
RR
436}
437
96fd301f 438bool wxMenuItem::IsChecked() const
716b7364 439{
83624f79 440 wxCHECK_MSG( m_menuItem, FALSE, "invalid menu item" );
db1b4961 441
83624f79 442 wxCHECK( IsCheckable(), FALSE ); // can't get state of uncheckable item!
96fd301f 443
83624f79 444 bool bIsChecked = ((GtkCheckMenuItem*)m_menuItem)->active != 0;
96fd301f 445
83624f79 446 return bIsChecked;
716b7364
RR
447}
448
db1b4961 449//-----------------------------------------------------------------------------
83624f79 450// wxMenu
db1b4961
RR
451//-----------------------------------------------------------------------------
452
c801d85f
KB
453IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
454
6de97a3b 455wxMenu::wxMenu( const wxString& title, const wxFunction func )
c801d85f 456{
83624f79
RR
457 m_title = title;
458 m_items.DeleteContents( TRUE );
459 m_invokingWindow = (wxWindow *) NULL;
460 m_menu = gtk_menu_new(); // Do not show!
8bbe427f 461
83624f79
RR
462 m_callback = func;
463 m_eventHandler = this;
464 m_clientData = (void*) NULL;
8bbe427f 465
83624f79
RR
466 if (m_title.IsNull()) m_title = "";
467 if (m_title != "")
468 {
469 Append(-2, m_title);
470 AppendSeparator();
471 }
c626a8b7 472
2b1c162e 473 m_owner = (GtkWidget*) NULL;
6de97a3b 474}
c801d85f 475
c2dd8380
GL
476void wxMenu::SetTitle( const wxString& title )
477{
c626a8b7 478 // TODO Waiting for something better
83624f79 479 m_title = title;
c2dd8380
GL
480}
481
482const wxString wxMenu::GetTitle() const
483{
83624f79 484 return m_title;
c2dd8380
GL
485}
486
96fd301f 487void wxMenu::AppendSeparator()
c801d85f 488{
83624f79
RR
489 wxMenuItem *mitem = new wxMenuItem();
490 mitem->SetId(ID_SEPARATOR);
96fd301f 491
83624f79
RR
492 GtkWidget *menuItem = gtk_menu_item_new();
493 gtk_menu_append( GTK_MENU(m_menu), menuItem );
494 gtk_widget_show( menuItem );
495 mitem->SetMenuItem(menuItem);
496 m_items.Append( mitem );
6de97a3b 497}
c801d85f 498
debe6624 499void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
c801d85f 500{
83624f79
RR
501 wxMenuItem *mitem = new wxMenuItem();
502 mitem->SetId(id);
503 mitem->SetText(item);
504 mitem->SetHelp(helpStr);
505 mitem->SetCheckable(checkable);
506 const char *text = mitem->GetText();
507 GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label(text)
508 : gtk_menu_item_new_with_label(text);
8bbe427f 509
83624f79 510 mitem->SetMenuItem(menuItem);
96fd301f 511
83624f79
RR
512 gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
513 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
514 (gpointer*)this );
96fd301f 515
83624f79
RR
516 gtk_signal_connect( GTK_OBJECT(menuItem), "select",
517 GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
518 (gpointer*)this );
cf7a7e13 519
cd743a6f
RR
520 gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
521 GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
522 (gpointer*)this );
523
83624f79
RR
524 gtk_menu_append( GTK_MENU(m_menu), menuItem );
525 gtk_widget_show( menuItem );
526 m_items.Append( mitem );
6de97a3b 527}
c801d85f 528
96fd301f 529void wxMenu::Append( int id, const wxString &text, wxMenu *subMenu, const wxString &helpStr )
c801d85f 530{
83624f79
RR
531 wxMenuItem *mitem = new wxMenuItem();
532 mitem->SetId(id);
533 mitem->SetText(text);
828f655f 534 mitem->SetHelp(helpStr);
96fd301f 535
83624f79 536 GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText());
83624f79
RR
537 mitem->SetMenuItem(menuItem);
538 mitem->SetSubMenu(subMenu);
96fd301f 539
cd743a6f
RR
540 gtk_signal_connect( GTK_OBJECT(menuItem), "select",
541 GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
542 (gpointer*)this );
543
544 gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
545 GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
546 (gpointer*)this );
547
83624f79
RR
548 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
549 gtk_menu_append( GTK_MENU(m_menu), menuItem );
550 gtk_widget_show( menuItem );
551 m_items.Append( mitem );
6de97a3b 552}
c801d85f 553
828f655f
RR
554void wxMenu::Append( wxMenuItem *item )
555{
556 m_items.Append( item );
c626a8b7 557
828f655f
RR
558 GtkWidget *menuItem = (GtkWidget*) NULL;
559
c626a8b7 560 if (item->IsSeparator())
828f655f 561 menuItem = gtk_menu_item_new();
c626a8b7 562 else if (item->IsSubMenu())
828f655f 563 menuItem = gtk_menu_item_new_with_label(item->GetText());
c626a8b7 564 else
828f655f
RR
565 menuItem = item->IsCheckable() ? gtk_check_menu_item_new_with_label(item->GetText())
566 : gtk_menu_item_new_with_label(item->GetText());
567
568 if (!item->IsSeparator())
569 {
570 gtk_signal_connect( GTK_OBJECT(menuItem), "select",
571 GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
572 (gpointer*)this );
573
574 gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
575 GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
576 (gpointer*)this );
c626a8b7
VZ
577
578 if (!item->IsSubMenu())
579 {
828f655f
RR
580 gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
581 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
582 (gpointer*)this );
c626a8b7 583 }
828f655f 584 }
c626a8b7 585
828f655f
RR
586 gtk_menu_append( GTK_MENU(m_menu), menuItem );
587 gtk_widget_show( menuItem );
588 item->SetMenuItem(menuItem);
589}
590
c801d85f
KB
591int wxMenu::FindItem( const wxString itemString ) const
592{
83624f79 593 wxString s( itemString );
96fd301f 594
83624f79 595 int pos;
c626a8b7 596 do
83624f79
RR
597 {
598 pos = s.First( '&' );
599 if (pos != -1) s.Remove( pos, 1 );
600 } while (pos != -1);
96fd301f 601
83624f79
RR
602 wxNode *node = m_items.First();
603 while (node)
604 {
605 wxMenuItem *item = (wxMenuItem*)node->Data();
606 if (item->GetText() == s)
c626a8b7 607 {
83624f79 608 return item->GetId();
c626a8b7 609 }
83624f79
RR
610 node = node->Next();
611 }
96fd301f 612
c626a8b7 613 return wxNOT_FOUND;
6de97a3b 614}
c801d85f 615
96fd301f 616void wxMenu::Enable( int id, bool enable )
716b7364 617{
83624f79 618 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
619
620 wxCHECK_RET( item, "wxMenu::Enable: no such item" );
621
622 item->Enable(enable);
6de97a3b 623}
716b7364 624
96fd301f 625bool wxMenu::IsEnabled( int id ) const
e2414cbe 626{
83624f79 627 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
628
629 wxCHECK_MSG( item, FALSE, "wxMenu::IsEnabled: no such item" );
630
631 return item->IsEnabled();
6de97a3b 632}
e2414cbe 633
96fd301f 634void wxMenu::Check( int id, bool enable )
c801d85f 635{
83624f79 636 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
637
638 wxCHECK_RET( item, "wxMenu::Check: no such item" );
639
640 item->Check(enable);
6de97a3b 641}
c801d85f 642
96fd301f 643bool wxMenu::IsChecked( int id ) const
c801d85f 644{
83624f79 645 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
646
647 wxCHECK_MSG( item, FALSE, "wxMenu::IsChecked: no such item" );
648
649 return item->IsChecked();
6de97a3b 650}
c801d85f 651
debe6624 652void wxMenu::SetLabel( int id, const wxString &label )
c801d85f 653{
83624f79 654 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
655
656 wxCHECK_RET( item, "wxMenu::SetLabel: no such item" );
657
658 item->SetText(label);
6de97a3b 659}
96fd301f 660
c33c4050
RR
661wxString wxMenu::GetLabel( int id ) const
662{
83624f79 663 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
664
665 wxCHECK_MSG( item, "", "wxMenu::GetLabel: no such item" );
666
667 return item->GetText();
c33c4050
RR
668}
669
670void wxMenu::SetHelpString( int id, const wxString& helpString )
671{
83624f79 672 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
673
674 wxCHECK_RET( item, "wxMenu::SetHelpString: no such item" );
675
676 item->SetHelp( helpString );
c33c4050
RR
677}
678
679wxString wxMenu::GetHelpString( int id ) const
680{
83624f79 681 wxMenuItem *item = FindItem(id);
c626a8b7
VZ
682
683 wxCHECK_MSG( item, "", "wxMenu::GetHelpString: no such item" );
684
685 return item->GetHelp();
c33c4050
RR
686}
687
96fd301f
VZ
688int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
689{
83624f79
RR
690 wxNode *node = m_items.First();
691 while (node)
692 {
693 wxMenuItem *item = (wxMenuItem*)node->Data();
694 if (item->GetMenuItem() == menuItem)
695 return item->GetId();
696 node = node->Next();
697 }
96fd301f 698
c626a8b7 699 return wxNOT_FOUND;
6de97a3b 700}
c801d85f 701
96fd301f 702wxMenuItem *wxMenu::FindItem(int id) const
c801d85f 703{
83624f79 704 wxNode *node = m_items.First();
c626a8b7 705 while (node)
83624f79
RR
706 {
707 wxMenuItem *item = (wxMenuItem*)node->Data();
708 if (item->GetId() == id)
c626a8b7 709 {
83624f79 710 return item;
c626a8b7 711 }
83624f79
RR
712 node = node->Next();
713 }
96fd301f 714
83624f79
RR
715 /* Not finding anything here can be correct
716 * when search the entire menu system for
717 * an entry -> no error message. */
8bbe427f 718
83624f79 719 return (wxMenuItem *) NULL;
96fd301f 720}
c801d85f
KB
721
722void wxMenu::SetInvokingWindow( wxWindow *win )
723{
83624f79 724 m_invokingWindow = win;
6de97a3b 725}
c801d85f 726
96fd301f 727wxWindow *wxMenu::GetInvokingWindow()
c801d85f 728{
83624f79 729 return m_invokingWindow;
6de97a3b 730}
c801d85f 731
c626a8b7
VZ
732// Update a menu and all submenus recursively. source is the object that has
733// the update event handlers defined for it. If NULL, the menu or associated
734// window will be used.
631f1bfe
JS
735void wxMenu::UpdateUI(wxEvtHandler* source)
736{
737 if (!source && GetInvokingWindow())
738 source = GetInvokingWindow()->GetEventHandler();
739 if (!source)
740 source = GetEventHandler();
741 if (!source)
742 source = this;
743
744 wxNode* node = GetItems().First();
745 while (node)
746 {
747 wxMenuItem* item = (wxMenuItem*) node->Data();
748 if ( !item->IsSeparator() )
749 {
750 wxWindowID id = item->GetId();
751 wxUpdateUIEvent event(id);
752 event.SetEventObject( source );
753
754 if (source->ProcessEvent(event))
755 {
756 if (event.GetSetText())
757 SetLabel(id, event.GetText());
758 if (event.GetSetChecked())
759 Check(id, event.GetChecked());
760 if (event.GetSetEnabled())
761 Enable(id, event.GetEnabled());
762 }
763
764 if (item->GetSubMenu())
765 item->GetSubMenu()->UpdateUI(source);
766 }
767 node = node->Next();
768 }
769}
770