]> git.saurik.com Git - wxWidgets.git/blame - src/stubs/menu.cpp
fixed an over-optimisation
[wxWidgets.git] / src / stubs / menu.cpp
CommitLineData
93cf77c0
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: menu.cpp
3// Purpose: wxMenu, wxMenuBar, wxMenuItem
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12
13// ============================================================================
14// headers & declarations
15// ============================================================================
16
17// wxWindows headers
18// -----------------
19
20#ifdef __GNUG__
21#pragma implementation "menu.h"
22#pragma implementation "menuitem.h"
23#endif
24
25#include "wx/menu.h"
26#include "wx/menuitem.h"
27#include "wx/log.h"
34138703 28#include "wx/utils.h"
93cf77c0
JS
29
30// other standard headers
31// ----------------------
32#include <string.h>
33
34#if !USE_SHARED_LIBRARY
35IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
36IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
37#endif
38
39// ============================================================================
40// implementation
41// ============================================================================
42
43// Menus
44
45// Construct a menu with optional title (then use append)
46wxMenu::wxMenu(const wxString& title, const wxFunction func)
47{
48 m_title = title;
49 m_parent = NULL;
50 m_eventHandler = this;
51 m_noItems = 0;
52 m_menuBar = NULL;
3dd4e4e0 53 m_clientData = (void*) NULL;
93cf77c0
JS
54 if (m_title != "")
55 {
56 Append(-2, m_title) ;
57 AppendSeparator() ;
58 }
59
60 Callback(func);
61
62 // TODO create menu
63}
64
65// The wxWindow destructor will take care of deleting the submenus.
66wxMenu::~wxMenu()
67{
68 // TODO destroy menu and children
69
70 wxNode *node = m_menuItems.First();
71 while (node)
72 {
73 wxMenuItem *item = (wxMenuItem *)node->Data();
74
75 // Delete child menus.
76 // Beware: they must not be appended to children list!!!
77 // (because order of delete is significant)
78 if (item->GetSubMenu())
79 item->DeleteSubMenu();
80
81 wxNode *next = node->Next();
82 delete item;
83 delete node;
84 node = next;
85 }
86}
87
88void wxMenu::Break()
89{
90 // TODO
91}
92
93// function appends a new item or submenu to the menu
94void wxMenu::Append(wxMenuItem *pItem)
95{
96 // TODO
97
98 wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
99
100 m_menuItems.Append(pItem);
101
102 m_noItems++;
103}
104
105void wxMenu::AppendSeparator()
106{
107 // TODO
108 Append(new wxMenuItem(this, ID_SEPARATOR));
109}
110
111// Pullright item
112void wxMenu::Append(int Id, const wxString& label, wxMenu *SubMenu,
113 const wxString& helpString)
114{
115 Append(new wxMenuItem(this, Id, label, helpString, FALSE, SubMenu));
116}
117
118// Ordinary menu item
119void wxMenu::Append(int Id, const wxString& label,
120 const wxString& helpString, bool checkable)
121{
122 // 'checkable' parameter is useless for Windows.
123 Append(new wxMenuItem(this, Id, label, helpString, checkable));
124}
125
126void wxMenu::Delete(int id)
127{
128 wxNode *node;
129 wxMenuItem *item;
130 int pos;
131
132 for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) {
133 item = (wxMenuItem *)node->Data();
134 if (item->GetId() == id)
135 break;
136 }
137
138 if (!node)
139 return;
140
141 m_menuItems.DeleteNode(node);
142 delete item;
143
144 // TODO
145}
146
147void wxMenu::Enable(int Id, bool Flag)
148{
149 wxMenuItem *item = FindItemForId(Id);
150 wxCHECK_RET( item != NULL, "can't enable non-existing menu item" );
151
152 item->Enable(Flag);
153}
154
155bool wxMenu::Enabled(int Id) const
156{
157 wxMenuItem *item = FindItemForId(Id);
158 wxCHECK( item != NULL, FALSE );
159
160 return item->IsEnabled();
161}
162
163void wxMenu::Check(int Id, bool Flag)
164{
165 wxMenuItem *item = FindItemForId(Id);
166 wxCHECK_RET( item != NULL, "can't get status of non-existing menu item" );
167
168 item->Check(Flag);
169}
170
171bool wxMenu::Checked(int Id) const
172{
173 wxMenuItem *item = FindItemForId(Id);
174 wxCHECK( item != NULL, FALSE );
175
176 return item->IsChecked();
177}
178
179void wxMenu::SetTitle(const wxString& label)
180{
181 m_title = label ;
182 // TODO
183}
184
f7387de5 185const wxString wxMenu::GetTitle() const
93cf77c0
JS
186{
187 return m_title;
188}
189
190void wxMenu::SetLabel(int id, const wxString& label)
191{
192 wxMenuItem *item = FindItemForId(id) ;
193 if (item==NULL)
194 return;
195
196 if (item->GetSubMenu()==NULL)
197 {
198 // TODO
199 }
200 else
201 {
202 // TODO
203 }
204 item->SetName(label);
205}
206
207wxString wxMenu::GetLabel(int Id) const
208{
209 // TODO
210 return wxString("") ;
211}
212
213// Finds the item id matching the given string, -1 if not found.
214int wxMenu::FindItem (const wxString& itemString) const
215{
216 char buf1[200];
217 char buf2[200];
218 wxStripMenuCodes ((char *)(const char *)itemString, buf1);
219
220 for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
221 {
222 wxMenuItem *item = (wxMenuItem *) node->Data ();
223 if (item->GetSubMenu())
224 {
225 int ans = item->GetSubMenu()->FindItem(itemString);
226 if (ans > -1)
227 return ans;
228 }
229 if ( !item->IsSeparator() )
230 {
231 wxStripMenuCodes((char *)item->GetName().c_str(), buf2);
232 if (strcmp(buf1, buf2) == 0)
233 return item->GetId();
234 }
235 }
236
237 return -1;
238}
239
240wxMenuItem *wxMenu::FindItemForId(int itemId, wxMenu ** itemMenu) const
241{
242 if (itemMenu)
243 *itemMenu = NULL;
244 for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
245 {
246 wxMenuItem *item = (wxMenuItem *) node->Data ();
247
248 if (item->GetId() == itemId)
249 {
250 if (itemMenu)
251 *itemMenu = (wxMenu *) this;
252 return item;
253 }
254
255 if (item->GetSubMenu())
256 {
257 wxMenuItem *ans = item->GetSubMenu()->FindItemForId (itemId, itemMenu);
258 if (ans)
259 return ans;
260 }
261 }
262
263 if (itemMenu)
264 *itemMenu = NULL;
265 return NULL;
266}
267
268void wxMenu::SetHelpString(int itemId, const wxString& helpString)
269{
270 wxMenuItem *item = FindItemForId (itemId);
271 if (item)
272 item->SetHelp(helpString);
273}
274
275wxString wxMenu::GetHelpString (int itemId) const
276{
277 wxMenuItem *item = FindItemForId (itemId);
278 wxString str("");
279 return (item == NULL) ? str : item->GetHelp();
280}
281
282void wxMenu::ProcessCommand(wxCommandEvent & event)
283{
284 bool processed = FALSE;
285
286 // Try a callback
287 if (m_callback)
288 {
289 (void) (*(m_callback)) (*this, event);
290 processed = TRUE;
291 }
292
293 // Try the menu's event handler
294 if ( !processed && GetEventHandler())
295 {
296 processed = GetEventHandler()->ProcessEvent(event);
297 }
34138703 298/* TODO
93cf77c0
JS
299 // Try the window the menu was popped up from (and up
300 // through the hierarchy)
301 if ( !processed && GetInvokingWindow())
302 processed = GetInvokingWindow()->ProcessEvent(event);
34138703 303*/
93cf77c0
JS
304}
305
631f1bfe
JS
306// Update a menu and all submenus recursively.
307// source is the object that has the update event handlers
308// defined for it. If NULL, the menu or associated window
309// will be used.
310void wxMenu::UpdateUI(wxEvtHandler* source)
311{
312 if (!source && GetInvokingWindow())
313 source = GetInvokingWindow()->GetEventHandler();
314 if (!source)
315 source = GetEventHandler();
316 if (!source)
317 source = this;
318
319 wxNode* node = GetItems().First();
320 while (node)
321 {
322 wxMenuItem* item = (wxMenuItem*) node->Data();
323 if ( !item->IsSeparator() )
324 {
325 wxWindowID id = item->GetId();
326 wxUpdateUIEvent event(id);
327 event.SetEventObject( source );
328
329 if (source->ProcessEvent(event))
330 {
331 if (event.GetSetText())
332 SetLabel(id, event.GetText());
333 if (event.GetSetChecked())
334 Check(id, event.GetChecked());
335 if (event.GetSetEnabled())
336 Enable(id, event.GetEnabled());
337 }
338
339 if (item->GetSubMenu())
340 item->GetSubMenu()->UpdateUI(source);
341 }
342 node = node->Next();
343 }
344}
345
93cf77c0
JS
346bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
347{
631f1bfe
JS
348 menu->SetInvokingWindow(this);
349 menu->UpdateUI();
350
93cf77c0
JS
351 // TODO
352 return FALSE;
353}
354
355// Menu Bar
356wxMenuBar::wxMenuBar()
357{
358 m_eventHandler = this;
359 m_menuCount = 0;
360 m_menus = NULL;
361 m_titles = NULL;
362 m_menuBarFrame = NULL;
363
364 // TODO
365}
366
34138703 367wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
93cf77c0
JS
368{
369 m_eventHandler = this;
370 m_menuCount = n;
371 m_menus = menus;
372 m_titles = new wxString[n];
373 int i;
374 for ( i = 0; i < n; i++ )
375 m_titles[i] = titles[i];
376 m_menuBarFrame = NULL;
377
378 // TODO
379}
380
381wxMenuBar::~wxMenuBar()
382{
383 int i;
384 for (i = 0; i < m_menuCount; i++)
385 {
386 delete m_menus[i];
387 }
388 delete[] m_menus;
389 delete[] m_titles;
390
391 // TODO
392}
393
394// Must only be used AFTER menu has been attached to frame,
395// otherwise use individual menus to enable/disable items
396void wxMenuBar::Enable(int id, bool flag)
397{
398 wxMenu *itemMenu = NULL;
399 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
400 if (!item)
401 return;
402
403 // TODO
404}
405
406void wxMenuBar::EnableTop(int pos, bool flag)
407{
408 // TODO
409}
410
411// Must only be used AFTER menu has been attached to frame,
412// otherwise use individual menus
413void wxMenuBar::Check(int id, bool flag)
414{
415 wxMenu *itemMenu = NULL;
416 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
417 if (!item)
418 return;
419
420 if (!item->IsCheckable())
421 return ;
422
423 // TODO
424}
425
426bool wxMenuBar::Checked(int id) const
427{
428 wxMenu *itemMenu = NULL;
429 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
430 if (!item)
431 return FALSE;
432
433 // TODO
434 return FALSE;
435}
436
437bool wxMenuBar::Enabled(int id) const
438{
439 wxMenu *itemMenu = NULL;
440 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
441 if (!item)
442 return FALSE;
443
444 // TODO
445 return FALSE ;
446}
447
448
449void wxMenuBar::SetLabel(int id, const wxString& label)
450{
451 wxMenu *itemMenu = NULL;
452 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
453
454 if (!item)
455 return;
456
457 // TODO
458}
459
460wxString wxMenuBar::GetLabel(int id) const
461{
462 wxMenu *itemMenu = NULL;
463 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
464
465 if (!item)
466 return wxString("");
467
468 // TODO
469 return wxString("") ;
470}
471
472void wxMenuBar::SetLabelTop(int pos, const wxString& label)
473{
474 // TODO
475}
476
477wxString wxMenuBar::GetLabelTop(int pos) const
478{
479 // TODO
480 return wxString("");
481}
482
483bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos)
484{
485 // TODO
486 return FALSE;
487}
488
489bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title)
490{
491 // TODO
492 return FALSE;
493}
494
495void wxMenuBar::Append (wxMenu * menu, const wxString& title)
496{
497 if (!OnAppend(menu, title))
498 return;
499
500 m_menuCount ++;
501 wxMenu **new_menus = new wxMenu *[m_menuCount];
502 wxString *new_titles = new wxString[m_menuCount];
503 int i;
504
505 for (i = 0; i < m_menuCount - 1; i++)
506 {
507 new_menus[i] = m_menus[i];
508 m_menus[i] = NULL;
509 new_titles[i] = m_titles[i];
510 m_titles[i] = "";
511 }
512 if (m_menus)
513 {
514 delete[]m_menus;
515 delete[]m_titles;
516 }
517 m_menus = new_menus;
518 m_titles = new_titles;
519
520 m_menus[m_menuCount - 1] = (wxMenu *)menu;
521 m_titles[m_menuCount - 1] = title;
522
523 // TODO
524}
525
526void wxMenuBar::Delete(wxMenu * menu, int i)
527{
528 int j;
529 int ii = (int) i;
530
531 if (menu != 0)
532 {
533 for (ii = 0; ii < m_menuCount; ii++)
534 {
535 if (m_menus[ii] == menu)
536 break;
537 }
538 if (ii >= m_menuCount)
539 return;
540 } else
541 {
542 if (ii < 0 || ii >= m_menuCount)
543 return;
544 menu = m_menus[ii];
545 }
546
547 if (!OnDelete(menu, ii))
548 return;
549
550 menu->SetParent(NULL);
551
552 -- m_menuCount;
553 for (j = ii; j < m_menuCount; j++)
554 {
555 m_menus[j] = m_menus[j + 1];
556 m_titles[j] = m_titles[j + 1];
557 }
558}
559
560// Find the menu menuString, item itemString, and return the item id.
561// Returns -1 if none found.
562int wxMenuBar::FindMenuItem (const wxString& menuString, const wxString& itemString) const
563{
564 char buf1[200];
565 char buf2[200];
566 wxStripMenuCodes ((char *)(const char *)menuString, buf1);
567 int i;
568 for (i = 0; i < m_menuCount; i++)
569 {
570 wxStripMenuCodes ((char *)(const char *)m_titles[i], buf2);
571 if (strcmp (buf1, buf2) == 0)
572 return m_menus[i]->FindItem (itemString);
573 }
574 return -1;
575}
576
577wxMenuItem *wxMenuBar::FindItemForId (int Id, wxMenu ** itemMenu) const
578{
579 if (itemMenu)
580 *itemMenu = NULL;
581
582 wxMenuItem *item = NULL;
583 int i;
584 for (i = 0; i < m_menuCount; i++)
585 if ((item = m_menus[i]->FindItemForId (Id, itemMenu)))
586 return item;
587 return NULL;
588}
589
590void wxMenuBar::SetHelpString (int Id, const wxString& helpString)
591{
592 int i;
593 for (i = 0; i < m_menuCount; i++)
594 {
595 if (m_menus[i]->FindItemForId (Id))
596 {
597 m_menus[i]->SetHelpString (Id, helpString);
598 return;
599 }
600 }
601}
602
603wxString wxMenuBar::GetHelpString (int Id) const
604{
605 int i;
606 for (i = 0; i < m_menuCount; i++)
607 {
608 if (m_menus[i]->FindItemForId (Id))
34138703 609 return wxString(m_menus[i]->GetHelpString (Id));
93cf77c0
JS
610 }
611 return wxString("");
612}
613
614