- return 0;
-
- return pos + 1 ;
-}
-
-void wxMenu::MacEnableMenu( bool bDoEnable )
-{
- if ( bDoEnable )
- UMAEnableMenuItem( m_hMenu , 0 ) ;
- else
- UMADisableMenuItem( m_hMenu , 0 ) ;
-
- ::DrawMenuBar() ;
-}
-
-bool wxMenu::MacMenuSelect( wxEvtHandler* handler, long when , int macMenuId, int macMenuItemNum )
-{
- int pos;
- wxNode *node;
-
- if ( m_macMenuId == macMenuId )
- {
- node = GetMenuItems().Nth(macMenuItemNum-1);
- if (node)
- {
- wxMenuItem *pItem = (wxMenuItem*)node->Data();
-
- if (pItem->IsCheckable())
- pItem->Check(! pItem->IsChecked());
-
- wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, pItem->GetId());
- event.m_timeStamp = when;
- event.SetEventObject(handler);
- event.SetInt( pItem->GetId() );
- {
- bool processed = false ;
-
-#if WXWIN_COMPATIBILITY
- // Try a callback
- if (m_callback)
- {
- (void) (*(m_callback)) (*this, event);
- processed = TRUE;
- }
-#endif
- // Try the menu's event handler
- if ( !processed && handler)
- {
- processed = handler->ProcessEvent(event);
- }
-
- // Try the window the menu was popped up from (and up
- // through the hierarchy)
- if ( !processed && GetInvokingWindow())
- processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
- }
- return true ;
- }
- }
-#ifndef __DARWIN__
- else if ( macMenuId == kHMHelpMenuID )
- {
- int menuItem = firstUserHelpMenuItem-1 ;
- for (pos = 0, node = GetMenuItems().First(); node; node = node->Next(), pos++)
- {
- wxMenuItem * pItem = (wxMenuItem *) node->Data() ;
-
- wxMenu *pSubMenu = pItem->GetSubMenu() ;
- if ( pSubMenu != NULL )
- {
- }
- else
- {
- if ( pItem->GetId() != wxApp::s_macAboutMenuItemId )
- ++menuItem ;
-
- if ( menuItem == macMenuItemNum )
- {
- wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, pItem->GetId());
- event.m_timeStamp = when;
- event.SetEventObject(handler);
- event.SetInt( pItem->GetId() );
- {
- bool processed = false ;
-#if WXWIN_COMPATIBILITY
- // Try a callback
- if (m_callback)
- {
- (void) (*(m_callback)) (*this, event);
- processed = TRUE;
- }
-#endif
- // Try the menu's event handler
- if ( !processed && handler)
- {
- processed = handler->ProcessEvent(event);
- }
-
- // Try the window the menu was popped up from (and up
- // through the hierarchy)
- if ( !processed && GetInvokingWindow())
- processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
- }
- return true ;
- }
- }
- }
- }
-#endif // __DARWIN__
-
- for (pos = 0, node = GetMenuItems().First(); node; node = node->Next(), pos++)
- {
- wxMenuItem * pItem = (wxMenuItem *) node->Data() ;
-
- wxMenu *pSubMenu = pItem->GetSubMenu() ;
- if ( pSubMenu != NULL )
- {
- if ( pSubMenu->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
- return true ;
- }
- }
-
- return false ;
+ return 0;
+
+ return pos + 1 ;
+}
+
+void wxMenu::MacEnableMenu( bool bDoEnable )
+{
+ UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
+
+ ::DrawMenuBar() ;
+}
+
+// MacOS needs to know about submenus somewhere within this menu
+// before it can be displayed, also hide special menu items
+// like preferences that are handled by the OS
+void wxMenu::MacBeforeDisplay( bool isSubMenu )
+{
+ wxMenuItem* previousItem = NULL ;
+ size_t pos ;
+ wxMenuItemList::compatibility_iterator node;
+ wxMenuItem *item;
+
+ for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
+ {
+ item = (wxMenuItem *)node->GetData();
+ wxMenu* subMenu = item->GetSubMenu() ;
+ if (subMenu)
+ {
+ subMenu->MacBeforeDisplay( true ) ;
+ }
+ else // normal item
+ {
+#if TARGET_CARBON
+ // what we do here is to hide the special items which are
+ // shown in the application menu anyhow -- it doesn't make
+ // sense to show them in their normal place as well
+ if ( item->GetId() == wxApp::s_macAboutMenuItemId ||
+ ( UMAGetSystemVersion() >= 0x1000 && (
+ item->GetId() == wxApp::s_macPreferencesMenuItemId ||
+ item->GetId() == wxApp::s_macExitMenuItemId ) ) )
+
+ {
+ ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
+ pos + 1, kMenuItemAttrHidden, 0 );
+
+ // also check for a separator which was used just to
+ // separate this item from the others, so don't leave
+ // separator at the menu start or end nor 2 consecutive
+ // separators
+ wxMenuItemList::compatibility_iterator nextNode = node->GetNext();
+ wxMenuItem *next = nextNode ? nextNode->GetData() : NULL;
+
+ size_t posSeptoHide;
+ if ( !previousItem && next && next->IsSeparator() )
+ {
+ // next (i.e. second as we must be first) item is
+ // the separator to hide
+ wxASSERT_MSG( pos == 0, _T("should be the menu start") );
+ posSeptoHide = 2;
+ }
+ else if ( GetMenuItems().GetCount() == pos + 1 &&
+ previousItem != NULL &&
+ previousItem->IsSeparator() )
+ {
+ // prev item is a trailing separator we want to hide
+ posSeptoHide = pos;
+ }
+ else if ( previousItem && previousItem->IsSeparator() &&
+ next && next->IsSeparator() )
+ {
+ // two consecutive separators, this is one too many
+ posSeptoHide = pos;
+ }
+ else // no separators to hide
+ {
+ posSeptoHide = 0;
+ }
+
+ if ( posSeptoHide )
+ {
+ // hide the separator as well
+ ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
+ posSeptoHide,
+ kMenuItemAttrHidden,
+ 0 );
+ }
+ }
+#endif // TARGET_CARBON
+ }
+
+ previousItem = item ;
+ }
+
+ if ( isSubMenu )
+ ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
+}
+
+// undo all changes from the MacBeforeDisplay call
+void wxMenu::MacAfterDisplay( bool isSubMenu )
+{
+ if ( isSubMenu )
+ ::DeleteMenu(MacGetMenuId());
+
+ wxMenuItemList::compatibility_iterator node;
+ wxMenuItem *item;
+
+ for (node = GetMenuItems().GetFirst(); node; node = node->GetNext())
+ {
+ item = (wxMenuItem *)node->GetData();
+ wxMenu* subMenu = item->GetSubMenu() ;
+ if (subMenu)
+ {
+ subMenu->MacAfterDisplay( true ) ;
+ }
+ else
+ {
+ // no need to undo hidings
+ }
+ }