]> git.saurik.com Git - wxWidgets.git/blame - src/palmos/menu.cpp
route all Cairo calls in GTK printing code through gs_cairo (is this still needed?)
[wxWidgets.git] / src / palmos / menu.cpp
CommitLineData
ffecfa5a 1/////////////////////////////////////////////////////////////////////////////
e2731512 2// Name: src/palmos/menu.cpp
ffecfa5a 3// Purpose: wxMenu, wxMenuBar, wxMenuItem
e2731512 4// Author: William Osborne - minimal working wxPalmOS port
ffecfa5a
JS
5// Modified by:
6// Created: 10/12/04
e2731512 7// RCS-ID: $Id$
ffecfa5a
JS
8// Copyright: (c) William Osborne
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
ffecfa5a
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_MENUS
28
3b3dc801
WS
29#include "wx/menu.h"
30
ffecfa5a
JS
31#ifndef WX_PRECOMP
32 #include "wx/frame.h"
ffecfa5a
JS
33 #include "wx/utils.h"
34 #include "wx/intl.h"
35 #include "wx/log.h"
36#endif
37
38#if wxUSE_OWNER_DRAWN
39 #include "wx/ownerdrw.h"
40#endif
41
6afc1b46 42#ifdef __WXPALMOS6__
20bc5ad8 43#include <Loader.h>
6afc1b46
VZ
44#else // __WXPALMOS5__
45#include <UIResources.h> // MenuRscType
46#endif
47
20bc5ad8
WS
48#include <Form.h>
49#include <Menu.h>
50
ffecfa5a
JS
51// ----------------------------------------------------------------------------
52// global variables
53// ----------------------------------------------------------------------------
54
55extern wxMenu *wxCurrentPopupMenu;
56
57// ----------------------------------------------------------------------------
58// constants
59// ----------------------------------------------------------------------------
60
61// the (popup) menu title has this special id
62static const int idMenuTitle = -3;
63
64// ----------------------------------------------------------------------------
65// private functions
66// ----------------------------------------------------------------------------
67
68// ============================================================================
69// implementation
70// ============================================================================
71
7ec69821 72#include "wx/listimpl.cpp"
ffecfa5a 73
412e0d47 74WX_DEFINE_LIST( wxMenuInfoList )
ffecfa5a
JS
75
76#if wxUSE_EXTENDED_RTTI
77
78WX_DEFINE_FLAGS( wxMenuStyle )
79
80wxBEGIN_FLAGS( wxMenuStyle )
81 wxFLAGS_MEMBER(wxMENU_TEAROFF)
82wxEND_FLAGS( wxMenuStyle )
83
84IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler,"wx/menu.h")
85
86wxCOLLECTION_TYPE_INFO( wxMenuItem * , wxMenuItemList ) ;
87
88template<> void wxCollectionToVariantArray( wxMenuItemList const &theList, wxxVariantArray &value)
89{
90 wxListCollectionToVariantArray<wxMenuItemList::compatibility_iterator>( theList , value ) ;
91}
92
93wxBEGIN_PROPERTIES_TABLE(wxMenu)
94 wxEVENT_PROPERTY( Select , wxEVT_COMMAND_MENU_SELECTED , wxCommandEvent)
95 wxPROPERTY( Title, wxString , SetTitle, GetTitle, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
96 wxREADONLY_PROPERTY_FLAGS( MenuStyle , wxMenuStyle , long , GetStyle , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
97 wxPROPERTY_COLLECTION( MenuItems , wxMenuItemList , wxMenuItem* , Append , GetMenuItems , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
98wxEND_PROPERTIES_TABLE()
99
100wxBEGIN_HANDLERS_TABLE(wxMenu)
101wxEND_HANDLERS_TABLE()
102
103wxDIRECT_CONSTRUCTOR_2( wxMenu , wxString , Title , long , MenuStyle )
104
105WX_DEFINE_FLAGS( wxMenuBarStyle )
106
107wxBEGIN_FLAGS( wxMenuBarStyle )
108 wxFLAGS_MEMBER(wxMB_DOCKABLE)
109wxEND_FLAGS( wxMenuBarStyle )
110
111// the negative id would lead the window (its superclass !) to vetoe streaming out otherwise
112bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxWriter * , wxPersister * , wxxVariantArray & )
113{
114 return true ;
115}
116
117IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow ,"wx/menu.h",wxMenuBarStreamingCallback)
118
119IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfo, wxObject , "wx/menu.h" )
120
121wxBEGIN_PROPERTIES_TABLE(wxMenuInfo)
122 wxREADONLY_PROPERTY( Menu , wxMenu* , GetMenu , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
123 wxREADONLY_PROPERTY( Title , wxString , GetTitle , wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
124wxEND_PROPERTIES_TABLE()
125
126wxBEGIN_HANDLERS_TABLE(wxMenuInfo)
127wxEND_HANDLERS_TABLE()
128
4055ed82 129wxCONSTRUCTOR_2( wxMenuInfo , wxMenu* , Menu , wxString , Title )
ffecfa5a
JS
130
131wxCOLLECTION_TYPE_INFO( wxMenuInfo * , wxMenuInfoList ) ;
132
133template<> void wxCollectionToVariantArray( wxMenuInfoList const &theList, wxxVariantArray &value)
134{
135 wxListCollectionToVariantArray<wxMenuInfoList::compatibility_iterator>( theList , value ) ;
136}
137
138wxBEGIN_PROPERTIES_TABLE(wxMenuBar)
139 wxPROPERTY_COLLECTION( MenuInfos , wxMenuInfoList , wxMenuInfo* , Append , GetMenuInfos , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
140wxEND_PROPERTIES_TABLE()
141
142wxBEGIN_HANDLERS_TABLE(wxMenuBar)
143wxEND_HANDLERS_TABLE()
144
145wxCONSTRUCTOR_DUMMY( wxMenuBar )
146
147#else
148IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
149IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow)
150IMPLEMENT_DYNAMIC_CLASS(wxMenuInfo, wxObject)
151#endif
152
153const wxMenuInfoList& wxMenuBar::GetMenuInfos() const
154{
155 wxMenuInfoList* list = const_cast< wxMenuInfoList* >( &m_menuInfos ) ;
156 WX_CLEAR_LIST( wxMenuInfoList , *list ) ;
157 for( size_t i = 0 ; i < GetMenuCount() ; ++i )
158 {
159 wxMenuInfo* info = new wxMenuInfo() ;
52af3158 160 info->Create( const_cast<wxMenuBar*>(this)->GetMenu(i) , GetMenuLabel(i) ) ;
ffecfa5a
JS
161 list->Append( info ) ;
162 }
163 return m_menuInfos ;
164}
165
166// ---------------------------------------------------------------------------
167// wxMenu construction, adding and removing menu items
168// ---------------------------------------------------------------------------
169
170// Construct a menu with optional title (then use append)
171void wxMenu::Init()
172{
173}
174
175// The wxWindow destructor will take care of deleting the submenus.
176wxMenu::~wxMenu()
177{
178}
179
180void wxMenu::Break()
181{
182}
183
184void wxMenu::Attach(wxMenuBarBase *menubar)
185{
186 wxMenuBase::Attach(menubar);
187}
188
189#if wxUSE_ACCEL
190
191int wxMenu::FindAccel(int id) const
192{
193 return wxNOT_FOUND;
194}
195
196void wxMenu::UpdateAccel(wxMenuItem *item)
197{
198}
199
200#endif // wxUSE_ACCEL
201
202// append a new item or submenu to the menu
203bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
204{
205 if ( IsAttached() && GetMenuBar()->IsAttached() )
206 {
4055ed82 207 // Regenerate the menu resource
ffecfa5a
JS
208 GetMenuBar()->Refresh();
209 }
4055ed82
WS
210
211 return true;
ffecfa5a
JS
212}
213
214void wxMenu::EndRadioGroup()
215{
216}
217
218wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
219{
220 wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
221
222 if(!wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item))
223 {
224 return NULL;
225 }
226 else if(IsAttached() && GetMenuBar()->IsAttached())
227 {
4055ed82 228 // Regenerate the menu resource
ffecfa5a
JS
229 GetMenuBar()->Refresh();
230 }
4055ed82
WS
231
232 return item;
ffecfa5a
JS
233}
234
235wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
236{
237 if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos))
238 return item;
239 else
4055ed82 240 return NULL;
ffecfa5a
JS
241}
242
243wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
244{
245 // we need to find the items position in the child list
246 size_t pos;
247 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
248 for ( pos = 0; node; pos++ )
249 {
250 if ( node->GetData() == item )
251 break;
252
253 node = node->GetNext();
254 }
255
256 // DoRemove() (unlike Remove) can only be called for existing item!
257 wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
258
259 // remove the item from the menu
260 wxMenuItem *ret=wxMenuBase::DoRemove(item);
4055ed82 261
ffecfa5a
JS
262 if ( IsAttached() && GetMenuBar()->IsAttached() )
263 {
4055ed82 264 // Regenerate the menu resource
ffecfa5a
JS
265 GetMenuBar()->Refresh();
266 }
4055ed82 267
ffecfa5a
JS
268 return ret;
269}
270
271// ---------------------------------------------------------------------------
272// accelerator helpers
273// ---------------------------------------------------------------------------
274
275#if wxUSE_ACCEL
276
277// create the wxAcceleratorEntries for our accels and put them into provided
278// array - return the number of accels we have
279size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
280{
281 size_t count = GetAccelCount();
282 for ( size_t n = 0; n < count; n++ )
283 {
284 *accels++ = *m_accels[n];
285 }
286
287 return count;
288}
289
290#endif // wxUSE_ACCEL
291
292// ---------------------------------------------------------------------------
293// set wxMenu title
294// ---------------------------------------------------------------------------
295
296void wxMenu::SetTitle(const wxString& label)
297{
298 m_title = label;
299
300 if ( IsAttached() && GetMenuBar()->IsAttached() )
301 {
4055ed82 302 // Regenerate the menu resource
ffecfa5a
JS
303 GetMenuBar()->Refresh();
304 }
305}
306
307// ---------------------------------------------------------------------------
308// event processing
309// ---------------------------------------------------------------------------
310
311bool wxMenu::PalmCommand(WXUINT WXUNUSED(param), WXWORD id)
312{
313 return false;
314}
315
316// ---------------------------------------------------------------------------
317// other
318// ---------------------------------------------------------------------------
319
320wxWindow *wxMenu::GetWindow() const
321{
322 return NULL;
323}
324
325// ---------------------------------------------------------------------------
326// Menu Bar
327// ---------------------------------------------------------------------------
328
329void wxMenuBar::Init()
330{
331}
332
333wxMenuBar::wxMenuBar()
334{
335}
336
337wxMenuBar::wxMenuBar( long WXUNUSED(style) )
338{
339}
340
294ea16d 341wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], long WXUNUSED(style))
ffecfa5a
JS
342{
343}
344
345wxMenuBar::~wxMenuBar()
346{
347}
348
349// ---------------------------------------------------------------------------
350// wxMenuBar helpers
351// ---------------------------------------------------------------------------
352
353void wxMenuBar::Refresh()
354{
355 wxCHECK_RET( IsAttached(), wxT("can't refresh unattached menubar") );
356
357 // Regenerate the menu resource
358 LoadMenu();
359}
360
361WXHMENU wxMenuBar::Create()
362{
363 return NULL;
364}
365
366int wxMenuBar::PalmPositionForWxMenu(wxMenu *menu, int wxpos)
367{
368 return -1;
369}
370
371// ---------------------------------------------------------------------------
372// wxMenuBar functions to work with the top level submenus
373// ---------------------------------------------------------------------------
374
375void wxMenuBar::EnableTop(size_t pos, bool enable)
376{
377 // Palm OS does not have support for grayed or disabled items
378}
379
52af3158 380void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
ffecfa5a
JS
381{
382 wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
383
52af3158 384 m_titles[pos] = label;
ffecfa5a
JS
385
386 if ( !IsAttached() )
387 {
388 return;
389 }
390
391 // Regenerate the menu resource
392 Refresh();
393}
394
52af3158 395wxString wxMenuBar::GetMenuLabel(size_t pos) const
ffecfa5a
JS
396{
397 wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
52af3158 398 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
ffecfa5a 399
52af3158 400 return m_titles[pos];
ffecfa5a
JS
401}
402
403// ---------------------------------------------------------------------------
404// wxMenuBar construction
405// ---------------------------------------------------------------------------
406
407wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
408{
409 wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
410 if ( !menuOld )
411 return NULL;
412
52af3158 413 m_titles[pos] = title;
ffecfa5a
JS
414
415 if ( IsAttached() )
416 {
417 // Regenerate the menu resource
418 Refresh();
419 }
420
421 return menuOld;
422}
423
424bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
425{
426 if ( !wxMenuBarBase::Insert(pos, menu, title) )
4055ed82 427 return false;
ffecfa5a 428
52af3158 429 m_titles.Insert(title, pos);
ffecfa5a
JS
430
431 if ( IsAttached() )
432 {
433 // Regenerate the menu resource
434 Refresh();
435 }
436
4055ed82 437 return true;
ffecfa5a
JS
438}
439
440bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
441{
442 if ( !wxMenuBarBase::Append(menu, title) )
4055ed82 443 return false;
ffecfa5a 444
52af3158 445 m_titles.Add(title);
ffecfa5a
JS
446
447 if(IsAttached())
448 {
449 // Regenerate the menu resource
450 Refresh();
451 }
452
4055ed82 453 return true;
ffecfa5a
JS
454}
455
456wxMenu *wxMenuBar::Remove(size_t pos)
457{
458 wxMenu *menu = wxMenuBarBase::Remove(pos);
459 if ( !menu )
460 return NULL;
461
462 m_titles.RemoveAt(pos);
463
464 if (IsAttached())
465 {
466 // Regenerate the menu resource
467 Refresh();
468 }
469
470 return menu;
471}
472
473#if wxUSE_ACCEL
474
475void wxMenuBar::RebuildAccelTable()
476{
477}
478
479#endif // wxUSE_ACCEL
480
481int wxMenuBar::ProcessCommand(int ItemID)
482{
483 if(!IsAttached())
484 return -1;
4055ed82 485
ffecfa5a
JS
486 int MenuNum=(ItemID/1000)-1;
487 int ItemNum=(ItemID-(1000*(MenuNum+1)));
4055ed82 488
ffecfa5a
JS
489 // Should never happen, but it doesn't hurt to check anyway.
490 if(MenuNum>GetMenuCount())
491 return -1;
492
493 // Get the menu
494 wxMenu *ActiveMenu=GetMenu(MenuNum);
4055ed82 495
ffecfa5a
JS
496 // Make sure this is a valid item.
497 if(ItemNum>ActiveMenu->GetMenuItemCount())
498 return -1;
499
500 // Get the item
501 wxMenuItem *ActiveItem=ActiveMenu->FindItemByPosition(ItemNum);
502 int ActiveID=ActiveItem->GetId();
503
504 return ActiveID;
505}
506
4055ed82
WS
507/* Palm OS does not have good dynamic menu support. About all you can do with
508 * the standard API calls is to add new items to an existing drop-down menu and
509 * hide/show items in a drop-down menu. It is impossible to add, hide, or
510 * change the label on a drop-down menu.
511 *
512 * The easiest and simplest way around this limitation is to modify the Palm OS
513 * MenuBarType structure directly. This gives limited ability to change the
514 * label on a drop-down menu. I have not been able to find a safe way to add,
ffecfa5a 515 * delete, or resize drop-down menus in OS 6.
4055ed82 516 *
ffecfa5a 517 * The following routine attempt to work around these limitations present in the
4055ed82 518 * Palm OS API to provide limited dynamic menu support. This solution is far
ffecfa5a
JS
519 * from perfect, but the only other option is to wait for PalmSource to add full
520 * dynamic menu support, or to recreate the Palm OS menu system from scratch.
4055ed82 521 *
ffecfa5a
JS
522 * This system is limited in that no more than 4 drop-down menus are allowed per
523 * menu bar, and the label for each drop-down menu is limited to 8 characters of
524 * text. However, this menu system should work for most applications.
4055ed82
WS
525 *
526 * Basically the menu routines select one of four menu bars, depending on
527 * whether or not the requested menu bar has one, two, three, or four drop-down
ffecfa5a 528 * menus.
4055ed82
WS
529 *
530 * These four "template" menu bars contain one, two, three, or four drop-down
531 * menus. Each menu has a dummy menu item attached to it to allow the Palm OS
ffecfa5a 532 * MenuAddItem function to add the real items.
4055ed82
WS
533 *
534 * The labels on the drop-down menus are then replaced with the labels of the
ffecfa5a 535 * real menus.
4055ed82
WS
536 *
537 * The menu is then attached to the active window and the MenuAddItem API
538 * function is called to add the items to each drop-down menu. Finally,
ffecfa5a
JS
539 * MenuHideItem is called to remove the dummy items from each drop-down menu.
540 */
541void wxMenuBar::LoadMenu()
542{
543 int i=0;
544 int j=0;
6afc1b46 545#ifdef __WXPALMOS6__
ffecfa5a
JS
546 // Handle to the currently running application database
547 DmOpenRef AppDB;
548
549 // Get app database reference - needed for some Palm OS Menu API calls.
550 SysGetModuleDatabase(SysGetRefNum(), NULL, &AppDB);
6afc1b46 551#endif // __WXPALMOS6__
ffecfa5a
JS
552
553 // Get the number of menus
554 int NumMenus=GetMenuCount();
555
556 // Set up the pointers and handles
4055ed82 557 char *PalmOSMenuBarPtr;
ffecfa5a 558 MemHandle PalmOSMenuBar;
4055ed82 559
ffecfa5a
JS
560 // Load the menu template and set up the menu pointers
561 if(NumMenus==1)
562 {
6afc1b46
VZ
563 PalmOSMenuBar = POS_DmGetResource (AppDB, MenuRscType, 1000);
564 PalmOSMenuBarPtr = (char *)MemHandleLock (PalmOSMenuBar);
ffecfa5a 565
6afc1b46 566 PalmOSMenuBarPtr += 74;
ffecfa5a
JS
567 }
568 else if(NumMenus==2)
569 {
6afc1b46
VZ
570 PalmOSMenuBar = POS_DmGetResource (AppDB, MenuRscType, 2000);
571 PalmOSMenuBarPtr = (char *)MemHandleLock (PalmOSMenuBar);
ffecfa5a 572
6afc1b46 573 PalmOSMenuBarPtr += 116;
ffecfa5a
JS
574 }
575 else if(NumMenus==3)
576 {
6afc1b46
VZ
577 PalmOSMenuBar = POS_DmGetResource (AppDB, MenuRscType, 3000);
578 PalmOSMenuBarPtr = (char *)MemHandleLock (PalmOSMenuBar);
ffecfa5a 579
6afc1b46 580 PalmOSMenuBarPtr += 158;
ffecfa5a
JS
581 }
582 else
583 {
4055ed82 584 // We support a maximum of 4 menus, so make sure that do not create
ffecfa5a
JS
585 // more than we can handle.
586 NumMenus=4;
587
6afc1b46
VZ
588 PalmOSMenuBar = POS_DmGetResource (AppDB, MenuRscType, 4000);
589 PalmOSMenuBarPtr = (char *)MemHandleLock (PalmOSMenuBar);
ffecfa5a 590
6afc1b46 591 PalmOSMenuBarPtr += 200;
ffecfa5a 592 }
4055ed82 593
ffecfa5a
JS
594 // Set the proper names for the drop-down triggers.
595 for(i=0;i<NumMenus;i++)
596 {
597 // Clear out the old label
598 char buffer[8]={' ',' ',' ',' ',' ',' ',' ',' '};
599 MemMove(PalmOSMenuBarPtr,buffer,8);
4055ed82 600
ffecfa5a
JS
601 wxString MenuTitle=m_titles.Item(i);
602
603 // Make sure we don't copy more than 8 bytes for the label
6afc1b46
VZ
604 int LengthToCopy = MenuTitle.length();
605 if(LengthToCopy > 8)
606 LengthToCopy = 8;
ffecfa5a 607
6afc1b46 608 MemMove(PalmOSMenuBarPtr,(char*)(&MenuTitle),LengthToCopy);
ffecfa5a
JS
609 PalmOSMenuBarPtr+=11;
610 }
611
612 // We are done with the menu pointer.
4055ed82 613 MemHandleUnlock(PalmOSMenuBar);
ffecfa5a
JS
614 DmReleaseResource(PalmOSMenuBar);
615
4055ed82 616 // We must make the menu active before we can add items to the drop-down
ffecfa5a 617 // triggers.
6afc1b46 618 POS_FrmSetMenu (FrmGetActiveForm(), AppDB, NumMenus * 1000);
ffecfa5a 619
4055ed82
WS
620 /* Add the menu items to the drop-down triggers. This must be done after
621 * setting the triggers, because setting the names of drop-down triggers
622 * that have a variable number of items requires carefull calculation of
ffecfa5a
JS
623 * the offsets in the MenuBarType structure. Setting the triggers first
624 * avoids this.
625 */
626 for(i=0;i<NumMenus;i++)
627 {
628 wxMenu *CurrentMenu=GetMenu(i);
4055ed82 629
ffecfa5a
JS
630 for(j=0;j<CurrentMenu->GetMenuItemCount();j++)
631 {
632 wxMenuItem *CurrentItem=CurrentMenu->FindItemByPosition(j);
633 wxString ItemLabel=CurrentItem->GetLabel();
4055ed82 634
ffecfa5a
JS
635 if(CurrentItem->IsSeparator()==true)
636 {
637 char Separator=MenuSeparatorChar;
638 if(j==0)
639 MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,&Separator);
640 else
641 MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,&Separator);
642 }
643 else
644 {
645 if(j==0)
6afc1b46 646 MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,(char *)(&ItemLabel));
ffecfa5a 647 else
6afc1b46 648 MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,(char *)(&ItemLabel));
ffecfa5a
JS
649 }
650 }
4055ed82 651
ffecfa5a
JS
652 // Hide the dummy menu item, since we don't need it anymore.
653 MenuHideItem(9000+i);
654 }
655}
656
657void wxMenuBar::Attach(wxFrame *frame)
658{
17131ffd
WS
659 // before attaching preprocess menus to not include wxID_EXIT item
660 // as PalmOS guidelines suggest
661
662 wxMenuItem *item;
663 wxMenu *menu;
664 int i;
665
666 while( item = FindItem(wxID_EXIT) )
667 {
668 menu = item->GetMenu();
669 if( !menu ) break; // something broken ?
670
671 size_t count = menu->GetMenuItemCount();
672 if( count == 0 ) break; // something broken ?
673
674 // if EXIT is last item in menu
675 if( menu->FindItemByPosition( count - 1 ) == item )
676 {
677 menu->Destroy( item );
678
679 // was more than one item?
680 // was previous separator ?
681 if( count > 2 )
682 {
683 item = menu->FindItemByPosition( count - 2 );
684 if(item && item->IsSeparator())
685 menu->Destroy( item );
686 }
687 }
688
689 // if EXIT is first item in menu
690 else if( menu->FindItemByPosition( 0 ) == item )
691 {
692 menu->Destroy( item );
693
694 // was more than one item?
695 // was previous separator ?
696 if( count > 2 )
697 {
698 item = menu->FindItemByPosition( 0 );
699 if(item && item->IsSeparator())
700 menu->Destroy( item );
701 }
702 }
703
704 // if EXIT is in the middle but before and after are selectors
705 else
706 {
707 i = 1; // 0 case already done
708 while ( (i < count) && (menu->FindItemByPosition( 0 ) != item) )
709 {
710 i++;
711 }
712
713 if (i >= count) break;
714 if (menu->FindItemByPosition( i ) != item) break;
715 menu->Destroy( item );
716 item = menu->FindItemByPosition( i );
717 if ( item &&
718 item->IsSeparator() &&
719 menu->FindItemByPosition( i-1 )->IsSeparator() )
720 {
721 // noe need for two neighbouring separators
722 menu->Destroy( item );
723 }
724 }
725 }
726
727 // check if we received any empty menu!
728 i = 0;
729 while(i < GetMenuCount())
730 {
731 menu = GetMenu(i);
732
733 if( menu && (menu->GetMenuItemCount()==0) )
734 {
735 menu = Remove( i );
736 delete menu;
737 }
738 else
739 i++;
740 }
741
ffecfa5a 742 wxMenuBarBase::Attach(frame);
ffecfa5a 743
4055ed82 744 LoadMenu();
ffecfa5a 745}
ffecfa5a
JS
746
747void wxMenuBar::Detach()
748{
749 wxMenuBarBase::Detach();
750}
751
752#endif // wxUSE_MENUS