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