Esempio n. 1
0
bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
{
    WXHMENU submenu = menu ? menu->GetHMenu() : 0;
        wxCHECK_MSG( submenu, false, wxT("can't append invalid menu to menubar") );

    if ( !wxMenuBarBase::Append(menu, title) )
        return false;

    m_titles.Add(title);

    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;

    if ( IsAttached() )
    {
        if (s_macInstalledMenuBar == this)
        {
            menu->MacBeforeDisplay( false ) ;
            ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
        }

        Refresh();
    }

    // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
    // adding menu later on.
    if (m_invokingWindow)
        wxMenubarSetInvokingWindow( menu, m_invokingWindow );

    return true;
}
Esempio n. 2
0
bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
{
    if ( !wxMenuBarBase::Insert(pos, menu, title) )
        return false;

    m_titles.Insert(title, pos);

    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;

    if ( IsAttached() && s_macInstalledMenuBar == this )
    {
        if (s_macInstalledMenuBar == this)
        {
            menu->MacBeforeDisplay( false ) ;

            if ( pos == (size_t) -1  || pos + 1 == m_menus.GetCount() )
                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
            else
                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos+1)->MacGetMenuId() ) ;
        }

        Refresh();
    }

    if (m_invokingWindow)
        wxMenubarSetInvokingWindow( menu, m_invokingWindow );

    return true;
}
Esempio n. 3
0
wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
{
    wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
    if ( !menuOld )
        return NULL;

    m_titles[pos] = title;

    if ( IsAttached() )
    {
        if (s_macInstalledMenuBar == this)
        {
            menuOld->MacAfterDisplay( false ) ;
            ::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;

            menu->MacBeforeDisplay( false ) ;
            UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
            if ( pos == m_menus.GetCount() - 1)
                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
            else
                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos + 1)->MacGetMenuId() ) ;
        }

        Refresh();
    }

    if (m_invokingWindow)
        wxMenubarSetInvokingWindow( menu, m_invokingWindow );

    return menuOld;
}
Esempio n. 4
0
void wxMenuItem::UpdateItemBitmap()
{
    if ( !m_parentMenu )
        return ;

    MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
    MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
    if ( mhandle == NULL || index == 0)
        return ;

    if ( m_bitmap.Ok() )
    {
#if wxUSE_BMPBUTTON
        ControlButtonContentInfo info ;
        wxMacCreateBitmapButton( &info , m_bitmap ) ;
        if ( info.contentType != kControlNoContent )
        {
            if ( info.contentType == kControlContentIconRef )
                SetMenuItemIconHandle( mhandle , index ,
                    kMenuIconRefType , (Handle) info.u.iconRef ) ;
        }
        wxMacReleaseBitmapButton( &info ) ;
#endif
    }
}
Esempio n. 5
0
// ----------------------------------------------------------------------------
// adding/deleting items to/from the list
// ----------------------------------------------------------------------------
int wxChoice::DoAppend(const wxString& item)
{
#if wxUSE_STL
    wxArrayString::iterator insertPoint;
    size_t index;
    
    if (GetWindowStyle() & wxCB_SORT)
    {
        insertPoint = std::lower_bound( m_strings.begin(), m_strings.end(), item );
        index = insertPoint - m_strings.begin();
    }
    else
    {
        insertPoint = m_strings.end();
        index = m_strings.size();
    }

    m_strings.insert( insertPoint, item );
#else
    size_t index = m_strings.Add( item ) ;
#endif
    m_datas.Insert( NULL , index ) ;
    UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ) , item, m_font.GetEncoding() , index );
    DoSetItemClientData( index , NULL ) ;
    m_peer->SetMaximum( GetCount() ) ;
    return index ;
}
Esempio n. 6
0
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
{
    // we need to find the items position in the child list
    size_t pos;
    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();

    for ( pos = 0; node; pos++ )
    {
        if ( node->GetData() == item )
            break;

        node = node->GetNext();
    }

    // DoRemove() (unlike Remove) can only be called for existing item!
    wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );

    ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);

    if ( IsAttached() && GetMenuBar()->IsAttached() )
        // otherwise, the change won't be visible
        GetMenuBar()->Refresh();

    // and from internal data structures
    return wxMenuBase::DoRemove(item);
}
Esempio n. 7
0
void wxChoice::SetString(unsigned int n, const wxString& s)
{
    wxCHECK_RET( IsValid(n), wxT("wxChoice::SetString(): invalid index") );

    m_strings[n] = s ;

    // apple menu pos is 1-based
    UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ;
}
Esempio n. 8
0
void wxMenuItem::UpdateItemBitmap()
{
    if ( !m_parentMenu )
        return ;

    MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
    MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
    DoUpdateItemBitmap( mhandle, index );
}
Esempio n. 9
0
void wxChoice::Clear()
{
    FreeData();
    for ( int i = 0 ; i < GetCount() ; i++ )
    {
        ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ;
    }
    m_strings.Empty() ;
    m_datas.Empty() ;
    m_peer->SetMaximum( 0 ) ;
}
Esempio n. 10
0
void wxMacSearchFieldControl::SetSearchMenu( wxMenu* menu )
{
    if ( menu )
    {
        verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, MAC_WXHMENU(menu->GetHMenu()) ) );
    }
    else
    {
        verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, 0 ) );
    }
}
Esempio n. 11
0
void wxChoice::Delete(int n)
{
    wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") );
    if ( HasClientObjectData() )
    {
        delete GetClientObject(n);
    }
    ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1) ;
    m_strings.RemoveAt( n ) ;
    m_datas.RemoveAt( n ) ;
    m_peer->SetMaximum( GetCount() ) ;
}
Esempio n. 12
0
void wxChoice::Delete(unsigned int n)
{
    wxCHECK_RET( IsValid(n) , wxT("wxChoice::Delete: invalid index") );

    if ( HasClientObjectData() )
        delete GetClientObject( n );

    ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 ) ;
    m_strings.RemoveAt( n ) ;
    m_datas.RemoveAt( n ) ;
    m_peer->SetMaximum( GetCount() ) ;
}
Esempio n. 13
0
int wxChoice::DoInsert(const wxString& item, int pos)
{
    wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
    wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index"));

    if (pos == GetCount())
        return DoAppend(item);

    UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ) , item, m_font.GetEncoding() , pos );
    m_strings.Insert( item, pos ) ;
    m_datas.Insert( NULL, pos ) ;
    DoSetItemClientData( pos , NULL ) ;
    m_peer->SetMaximum( GetCount() ) ;
    return pos ;
}
Esempio n. 14
0
bool wxTaskBarIcon::RemoveIcon()
{
    if(m_pMenu)
    {
        delete m_pMenu;
        m_pMenu = NULL;
    }
    
    //restore old icon to the dock
	OSStatus err = RestoreApplicationDockTileImage();
	wxASSERT(err == 0);
    
    //restore the old menu to the dock
    SetApplicationDockTileMenu(MAC_WXHMENU(m_theLastMenu));

    return !(m_iconAdded = !(err == noErr));
}
Esempio n. 15
0
void wxMenuItem::UpdateItemStatus()
{
    if ( !m_parentMenu )
        return ;

    if ( IsSeparator() )
        return ;

#if TARGET_CARBON
    if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId)
    {
        if ( !IsEnabled() )
            DisableMenuCommand( NULL , kHICommandPreferences ) ;
        else
            EnableMenuCommand( NULL , kHICommandPreferences ) ;
    }

    if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId)
    {
        if ( !IsEnabled() )
            DisableMenuCommand( NULL , kHICommandQuit ) ;
        else
            EnableMenuCommand( NULL , kHICommandQuit ) ;
    }
#endif

    {
        MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
        MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
        if ( mhandle == NULL || index == 0)
            return ;

        UMAEnableMenuItem( mhandle , index , m_isEnabled ) ;
        if ( IsCheckable() && IsChecked() )
            ::SetItemMark( mhandle , index , 0x12 ) ; // checkmark
        else
            ::SetItemMark( mhandle , index , 0 ) ; // no mark

        UMASetMenuItemText( mhandle , index , wxStripMenuCodes(m_text) , wxFont::GetDefaultEncoding() ) ;
        wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ;
        UMASetMenuItemShortcut( mhandle , index , entry ) ;
        delete entry ;
    }
}
Esempio n. 16
0
void wxMenuItem::Enable(bool bDoEnable)
{
    if (( m_isEnabled != bDoEnable
#if TARGET_CARBON
      // avoid changing menuitem state when menu is disabled
      // eg. BeginAppModalStateForWindow() will disable menus and ignore this change
      // which in turn causes m_isEnabled to become out of sync with real menuitem state
         && !(m_parentMenu && !IsMenuItemEnabled(MAC_WXHMENU(m_parentMenu->GetHMenu()), 0)) )
      // always update builtin menuitems
         || (   GetId() == wxApp::s_macPreferencesMenuItemId
             || GetId() == wxApp::s_macExitMenuItemId
             || GetId() == wxApp::s_macAboutMenuItemId
#endif
         ))
    {
        wxMenuItemBase::Enable( bDoEnable ) ;
        UpdateItemStatus() ;
    }
}
Esempio n. 17
0
void wxMenuItem::UpdateItemText()
{
    if ( !m_parentMenu )
        return ;

    MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
    MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
    if (mhandle == NULL || index == 0)
        return ;

    wxString text = m_text;
    if (text.IsEmpty() && !IsSeparator())
    {
        wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
        text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC);
    }

    UMASetMenuItemText( mhandle , index , wxStripMenuCodes(text) , wxFont::GetDefaultEncoding() ) ;
    wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( text ) ;
    UMASetMenuItemShortcut( mhandle , index , entry ) ;
    delete entry ;
}
Esempio n. 18
0
//-----------------------------------------------------------------------------
// wxDockEventHandler
//
// This is the global Mac/Carbon event handler for the dock.
// We need this for two reasons:
// 1) To handle wxTaskBarIcon menu events (see below for why)
// 2) To handle events from the dock when it requests a menu
//-----------------------------------------------------------------------------
pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef,
                                    EventRef inEvent, void *pData )
{
    // Get the parameters we want from the event
    wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData;
    const UInt32 eventClass = GetEventClass(inEvent);
    const UInt32 eventKind = GetEventKind(inEvent);

    // Handle wxTaskBar menu events (note that this is a global event handler
    // so it will actually get called by all commands/menus)
    if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess))
    {
        // if we have no taskbar menu quickly pass it back to wxApp
        if (pTB->m_pMenu == NULL)
            return eventNotHandledErr;

        // This is the real reason why we need this. Normally menus
        // get handled in wxMacAppEventHandler
        //
        // pascal OSStatus wxMacAppEventHandler(EventHandlerCallRef handler,
        //                                      EventRef event, void *data)
        //
        // However, in the case of a taskbar menu call
        // command.menu.menuRef IS NULL!
        // Which causes the wxApp handler just to skip it.
        MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu());
        OSStatus err;

        // get the HICommand from the event
        HICommand command;
        err = GetEventParameter(
            inEvent, kEventParamDirectObject,
            typeHICommand, NULL,
            sizeof(HICommand), NULL, &command );
        if (err == noErr)
        {
            // Obtain the REAL menuRef and the menuItemIndex in the real menuRef
            //
            // NOTE: menuRef is generally used here for submenus, as
            // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass
            // just the top level wxTaskBar menu
            MenuItemIndex menuItemIndex;
            MenuRef menuRef;

            err = GetIndMenuItemWithCommandID(
                taskbarMenuRef,
                command.commandID,
                1, &menuRef, &menuItemIndex );
            if (err == noErr)
            {
                MenuCommand id = command.commandID;
                wxMenuItem *item = NULL;

                if (id != 0) // get the wxMenuItem reference from the MenuRef
                    GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item );

                if (item)
                {
                    // Handle items that are checkable
                    // FIXME: Doesn't work (at least on 10.2)!
                    if (item->IsCheckable())
                        item->Check( !item->IsChecked() );

                    // send the wxEvent to the wxMenu
                    item->GetMenu()->SendEvent( id, item->IsCheckable() ? item->IsChecked() : -1 );

                    // successfully handled the event
                    err = noErr;
                }
            }
        } //end if noErr on getting HICommand from event

        // return whether we handled the event or not
        return err;
    }

    // We better have a kEventClassApplication/kEventAppGetDockTileMenu combo here,
    // otherwise something is truly funky
    wxASSERT(eventClass == kEventClassApplication &&
             eventKind == kEventAppGetDockTileMenu);

    // process the right click events
    // NB: This may result in double or even triple-creation of the menus
    // We need to do this for 2.4 compat, however
    wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL);
    pTB->m_parent->ProcessEvent(downevt);

    wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL);
    pTB->m_parent->ProcessEvent(upevt);

    // create popup menu
    wxMenu* menu = pTB->DoCreatePopupMenu();

    OSStatus err = eventNotHandledErr;

    if (menu != NULL)
    {
        // note to self - a MenuRef *is* a MenuHandle
        MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu());

        // When SetEventParameter is called it will decrement
        // the reference count of the menu - we need to make
        // sure it stays around in the wxMenu class here
        CFRetain(hMenu);

        // set the actual dock menu
        err = SetEventParameter(
            inEvent, kEventParamMenuRef,
            typeMenuRef, sizeof(MenuRef), &hMenu );
        verify_noerr( err );
    }

    return err;
}
Esempio n. 19
0
void wxChoice::SetString(int n, const wxString& s)
{
    m_strings[n] = s ;
    // apple menu pos is 1-based
    UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ;
}
Esempio n. 20
0
void wxMenu::SetTitle(const wxString& label)
{
    m_title = label ;
    UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;
}
Esempio n. 21
0
void wxMenu::MacEnableMenu( bool bDoEnable )
{
    UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;

    ::DrawMenuBar() ;
}
Esempio n. 22
0
// 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);
}
Esempio n. 23
0
pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef,
                                    EventRef inEvent, void* pData)
{
    wxTaskBarIcon*& pTB = (wxTaskBarIcon*&) pData;

    const UInt32 eventClass = GetEventClass(inEvent);
    const UInt32 eventKind = GetEventKind(inEvent);
            
    if (eventClass == kEventClassCommand && eventKind == kEventCommandProcess) 
    {
        //TODO:	This is a complete copy of 
        //static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )

        if (! pTB->GetCurrentMenu() )
        {
            return eventNotHandledErr;
        }
                
        MenuRef hMenu = MAC_WXHMENU(pTB->GetCurrentMenu()->GetHMenu());
        OSStatus result = eventNotHandledErr ;

        HICommand command ;
        OSErr err;
    
        err =    GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, 	
                            NULL, sizeof(HICommand), NULL, &command);
        wxASSERT(err == noErr);
                
        MenuItemIndex menuItemIndex;
        err = GetIndMenuItemWithCommandID(hMenu, command.commandID, 1, NULL, &menuItemIndex);
        wxASSERT(err == noErr);
                
                    
        MenuCommand id = command.commandID ;
        wxMenuItem* item = NULL;
        
        // for items we don't really control
        if ( id == kHICommandPreferences )
        {
            id = wxApp::s_macPreferencesMenuItemId ;
        
            wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
            
            if ( mbar )
            {
                wxMenu* menu = NULL ;
                item = mbar->FindItem( id , &menu ) ;
            }
        }
        else if (id != 0)
            GetMenuItemRefCon( hMenu , menuItemIndex , (UInt32*) &item ) ;

        if ( item )
        {
            if (item->IsCheckable())
            {
                item->Check( !item->IsChecked() ) ;
            }

            item->GetMenu()->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
            result = noErr ;
        }
    
        return result ;
    }
    
    wxASSERT(eventClass == kEventClassApplication && eventKind == kEventAppGetDockTileMenu);
		    	
	//process the right click events
	wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN,NULL);
	pTB->ProcessEvent(downevt);
		
	wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP,NULL);
	pTB->ProcessEvent(upevt);

    //create popup menu
    wxMenu* menu = pTB->DoCreatePopupMenu();
    
    OSStatus err = noErr;

    if(menu)
    {
        //note to self - a MenuRef IS A MenuHandle
        MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu());

        //When we call SetEventParameter it will decrement
        //the reference count of the menu - we need to make
        //sure it stays around in the wxMenu class here
        RetainMenu(hMenu);

        //set the actual dock menu
        err = SetEventParameter((EventRef) inEvent, kEventParamMenuRef, 
                    typeMenuRef, sizeof(MenuRef), 
                     &hMenu);
        wxASSERT(err == 0);

        return err;
    }
    else
        return eventNotHandledErr;
}
Esempio n. 24
0
wxMenu::~wxMenu()
{
    wxRemoveMacMenuAssociation( this ) ;
    if (MAC_WXHMENU(m_hMenu))
        ::DisposeMenu(MAC_WXHMENU(m_hMenu));
}
Esempio n. 25
0
//-----------------------------------------------------------------------------
// wxDockEventHandler
//
// This is the global Mac/Carbon event handler for the dock.
// We need this for two reasons:
// 1) To handle wxTaskBarIcon menu events (see below for why)
// 2) To handle events from the dock when it requests a menu
//-----------------------------------------------------------------------------
pascal OSStatus
wxDockEventHandler(EventHandlerCallRef WXUNUSED(inHandlerCallRef),
                   EventRef inEvent,
                   void *pData)
{
    // Get the parameters we want from the event
    wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData;
    const UInt32 eventClass = GetEventClass(inEvent);
    const UInt32 eventKind = GetEventKind(inEvent);
    
    OSStatus err = eventNotHandledErr;

    // Handle wxTaskBar menu events (note that this is a global event handler
    // so it will actually get called by all commands/menus)
    if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess || eventKind == kEventCommandUpdateStatus ))
    {
        // if we have no taskbar menu quickly pass it back to wxApp
        if (pTB->m_pMenu != NULL)
        {
            // This is the real reason why we need this. Normally menus
            // get handled in wxMacAppEventHandler
            // However, in the case of a taskbar menu call
            // command.menu.menuRef IS NULL!
            // Which causes the wxApp handler just to skip it.

            // get the HICommand from the event
            HICommand command;
            if (GetEventParameter(inEvent, kEventParamDirectObject,
                typeHICommand, NULL,sizeof(HICommand), NULL, &command ) == noErr)
            {
                // Obtain the REAL menuRef and the menuItemIndex in the real menuRef
                //
                // NOTE: menuRef is generally used here for submenus, as
                // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass
                // just the top level wxTaskBar menu
                MenuItemIndex menuItemIndex;
                MenuRef menuRef;
                MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu());

                // the next command is only successful if it was a command from the taskbar menu
                // otherwise we pass it on
                if (GetIndMenuItemWithCommandID(taskbarMenuRef,command.commandID,
                    1, &menuRef, &menuItemIndex ) == noErr)
                {
                    wxMenu* itemMenu = wxFindMenuFromMacMenu( menuRef ) ;
                    int id = wxMacCommandToId( command.commandID ) ;
                    wxMenuItem *item = NULL;

                    if (id != 0) // get the wxMenuItem reference from the MenuRef
                        GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item );

                    if (item && itemMenu )
                    {
                        if ( eventKind == kEventCommandProcess )
                        {
                            if ( itemMenu->HandleCommandProcess( item ) )
                                err = noErr;
                        }
                        else if ( eventKind == kEventCommandUpdateStatus )
                        {
                            if ( itemMenu->HandleCommandUpdateStatus( item ) )
                                err = noErr;
                        }
                    }
                }
            }
        } //end if noErr on getting HICommand from event
    }
    else if ((eventClass == kEventClassApplication) && (eventKind == kEventAppGetDockTileMenu ))
    {
        // process the right click events
        // NB: This may result in double or even triple-creation of the menus
        // We need to do this for 2.4 compat, however
        wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL);
        pTB->m_parent->ProcessEvent(downevt);

        wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL);
        pTB->m_parent->ProcessEvent(upevt);

        // create popup menu
        wxMenu* menu = pTB->DoCreatePopupMenu();

        if (menu != NULL)
        {
            // note to self - a MenuRef *is* a MenuHandle
            MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu());

            // When SetEventParameter is called it will decrement
            // the reference count of the menu - we need to make
            // sure it stays around in the wxMenu class here
            CFRetain(hMenu);

            // set the actual dock menu
            err = SetEventParameter(
                inEvent, kEventParamMenuRef,
                typeMenuRef, sizeof(MenuRef), &hMenu );
            verify_noerr( err );
        }
    }

    return err;
}
Esempio n. 26
0
void wxMenuBar::MacInstallMenuBar()
{
    if ( s_macInstalledMenuBar == this )
        return ;

    MenuBarHandle menubar = NULL ;

#if TARGET_API_MAC_OSX
    menubar = NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
#else
    menubar = NewHandleClear( 12 ) ;
    (*menubar)[3] = 0x0a ;
#endif

    ::SetMenuBar( menubar ) ;
    DisposeMenuBar( menubar ) ;
    MenuHandle appleMenu = NULL ;

    verify_noerr( CreateNewMenu( kwxMacAppleMenuId , 0 , &appleMenu ) ) ;
    verify_noerr( SetMenuTitleWithCFString( appleMenu , CFSTR( "\x14" ) ) );

    // Add About/Preferences separator only on OS X
    // KH/RN: Separator is always present on 10.3 but not on 10.2
    // However, the change from 10.2 to 10.3 suggests it is preferred
#if TARGET_API_MAC_OSX
    InsertMenuItemTextWithCFString( appleMenu,
                CFSTR(""), 0, kMenuItemAttrSeparator, 0); 
#endif
    InsertMenuItemTextWithCFString( appleMenu,
                CFSTR("About..."), 0, 0, 0); 
    MacInsertMenu( appleMenu , 0 ) ;

    // clean-up the help menu before adding new items
    static MenuHandle mh = NULL ;

    if ( mh != NULL )
    {
        MenuItemIndex firstUserHelpMenuItem ;
        if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) == noErr )
        {
            for ( int i = CountMenuItems( mh ) ; i >= firstUserHelpMenuItem ; --i )
                DeleteMenuItem( mh , i ) ;
        }
        else
        {
            mh = NULL ;
        }
    }

#if TARGET_CARBON
    if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId)
    {
        wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
        if ( item == NULL || !(item->IsEnabled()) )
            DisableMenuCommand( NULL , kHICommandPreferences ) ;
        else
            EnableMenuCommand( NULL , kHICommandPreferences ) ;
    }

    // Unlike preferences which may or may not exist, the Quit item should be always
    // enabled unless it is added by the application and then disabled, otherwise
    // a program would be required to add an item with wxID_EXIT in order to get the
    // Quit menu item to be enabled, which seems a bit burdensome.
    if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macExitMenuItemId)
    {
        wxMenuItem *item = FindItem( wxApp::s_macExitMenuItemId , NULL ) ;
        if ( item != NULL && !(item->IsEnabled()) )
            DisableMenuCommand( NULL , kHICommandQuit ) ;
        else
            EnableMenuCommand( NULL , kHICommandQuit ) ;
    }
#endif

    wxMenuList::compatibility_iterator menuIter = m_menus.GetFirst();
    for (size_t i = 0; i < m_menus.GetCount(); i++, menuIter = menuIter->GetNext())
    {
        wxMenuItemList::compatibility_iterator node;
        wxMenuItem *item;
        wxMenu* menu = menuIter->GetData() , *subMenu = NULL ;

        if ( m_titles[i] == wxT("?") || m_titles[i] == wxT("&?")  || m_titles[i] == wxApp::s_macHelpMenuTitleName )
        {
            for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
            {
                item = (wxMenuItem *)node->GetData();
                subMenu = item->GetSubMenu() ;
                if (subMenu)
                {
                    // we don't support hierarchical menus in the help menu yet
                }
                else
                {
                    if ( item->GetId() != wxApp::s_macAboutMenuItemId )
                    {
                        if ( mh == NULL )
                        {
                            MenuItemIndex firstUserHelpMenuItem ;
                            if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) != noErr )
                            {
                                mh = NULL ;
                                break ;
                            }
                        }
                    }

                    if ( item->IsSeparator() )
                    {
                        if ( mh )
                            AppendMenuItemTextWithCFString( mh,
                                CFSTR(""), kMenuItemAttrSeparator, 0,NULL); 
                    }
                    else
                    {
                        wxAcceleratorEntry*
                            entry = wxAcceleratorEntry::Create( item->GetText() ) ;

                        if ( item->GetId() == wxApp::s_macAboutMenuItemId )
                        {
                            // this will be taken care of below
                        }
                        else
                        {
                            if ( mh )
                            {
                                UMAAppendMenuItem(mh, wxStripMenuCodes(item->GetText()) , wxFont::GetDefaultEncoding(), entry);
                                SetMenuItemCommandID( mh , CountMenuItems(mh) , wxIdToMacCommand ( item->GetId() ) ) ;
                                SetMenuItemRefCon( mh , CountMenuItems(mh) , (URefCon) item ) ;
                            }
                        }

                        delete entry ;
                    }
                }
            }
        }
        else
        {
            UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], m_font.GetEncoding()  ) ;
            menu->MacBeforeDisplay(false) ;
            ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus, i)->GetHMenu()), 0);
        }
    }

    // take care of the about menu item wherever it is
    {
        wxMenu* aboutMenu ;
        wxMenuItem *aboutMenuItem = FindItem(wxApp::s_macAboutMenuItemId , &aboutMenu) ;
        if ( aboutMenuItem )
        {
            wxAcceleratorEntry*
                entry = wxAcceleratorEntry::Create( aboutMenuItem->GetText() ) ;
            UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , wxStripMenuCodes ( aboutMenuItem->GetText() ) , wxFont::GetDefaultEncoding() );
            UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
            SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , kHICommandAbout ) ;
            SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId ) , 1 , (URefCon)aboutMenuItem ) ;
            UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
        }
    }

    if ( GetAutoWindowMenu() )
    {
        if ( MacGetWindowMenuHMenu() == NULL )
            CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;

        InsertMenu( (MenuHandle) MacGetWindowMenuHMenu() , 0 ) ;
    }

    ::DrawMenuBar() ;
    s_macInstalledMenuBar = this;
}
Esempio n. 27
0
void wxMenuBar::MacInstallMenuBar()
{
    if ( s_macInstalledMenuBar == this )
        return ;

    m_rootMenu->GetPeer()->MakeRoot();

    // hide items in the apple menu that don't exist in the wx menubar

    int menuid = 0;
    wxMenuItem* appleItem = NULL;
    wxMenuItem* wxItem = NULL;

    menuid = wxApp::s_macAboutMenuItemId;
    appleItem = m_appleMenu->FindItem(menuid);
    wxItem = FindItem(menuid);
    if ( appleItem != NULL )
    {
        if ( wxItem == NULL )
            appleItem->GetPeer()->Hide();
        else
            appleItem->SetItemLabel(wxItem->GetItemLabel());
    }

    menuid = wxApp::s_macPreferencesMenuItemId;
    appleItem = m_appleMenu->FindItem(menuid);
    wxItem = FindItem(menuid);
    if ( appleItem != NULL )
    {
        if ( wxItem == NULL )
            appleItem->GetPeer()->Hide();
        else
            appleItem->SetItemLabel(wxItem->GetItemLabel());
    }


#if 0

    // if we have a mac help menu, clean it up before adding new items
    MenuHandle helpMenuHandle ;
    MenuItemIndex firstUserHelpMenuItem ;

    if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) == noErr )
    {
        for ( int i = CountMenuItems( helpMenuHandle ) ; i >= firstUserHelpMenuItem ; --i )
            DeleteMenuItem( helpMenuHandle , i ) ;
    }
    else
    {
        helpMenuHandle = NULL ;
    }

    if ( wxApp::s_macPreferencesMenuItemId)
    {
        wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
        if ( item == NULL || !(item->IsEnabled()) )
            DisableMenuCommand( NULL , kHICommandPreferences ) ;
        else
            EnableMenuCommand( NULL , kHICommandPreferences ) ;
    }

    // Unlike preferences which may or may not exist, the Quit item should be always
    // enabled unless it is added by the application and then disabled, otherwise
    // a program would be required to add an item with wxID_EXIT in order to get the
    // Quit menu item to be enabled, which seems a bit burdensome.
    if ( wxApp::s_macExitMenuItemId)
    {
        wxMenuItem *item = FindItem( wxApp::s_macExitMenuItemId , NULL ) ;
        if ( item != NULL && !(item->IsEnabled()) )
            DisableMenuCommand( NULL , kHICommandQuit ) ;
        else
            EnableMenuCommand( NULL , kHICommandQuit ) ;
    }

    wxString strippedHelpMenuTitle = wxStripMenuCodes( wxApp::s_macHelpMenuTitleName ) ;
    wxString strippedTranslatedHelpMenuTitle = wxStripMenuCodes( wxString( _("&Help") ) ) ;
    wxMenuList::compatibility_iterator menuIter = m_menus.GetFirst();
    for (size_t i = 0; i < m_menus.GetCount(); i++, menuIter = menuIter->GetNext())
    {
        wxMenuItemList::compatibility_iterator node;
        wxMenuItem *item;
        wxMenu* menu = menuIter->GetData() , *subMenu = NULL ;
        wxString strippedMenuTitle = wxStripMenuCodes(m_titles[i]);

        if ( strippedMenuTitle == wxT("?") || strippedMenuTitle == strippedHelpMenuTitle || strippedMenuTitle == strippedTranslatedHelpMenuTitle )
        {
            for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
            {
                item = (wxMenuItem *)node->GetData();
                subMenu = item->GetSubMenu() ;
                if (subMenu)
                {
                    UMAAppendMenuItem(mh, wxStripMenuCodes(item->GetText()) , wxFont::GetDefaultEncoding() );
                    MenuItemIndex position = CountMenuItems(mh);
                    ::SetMenuItemHierarchicalMenu(mh, position, MAC_WXHMENU(subMenu->GetHMenu()));
                }
                else
                {
                    if ( item->GetId() != wxApp::s_macAboutMenuItemId )
                    {
                        // we have found a user help menu and an item other than the about item,
                        // so we can create the mac help menu now, if we haven't created it yet
                        if ( helpMenuHandle == NULL )
                        {
                            if ( UMAGetHelpMenu( &helpMenuHandle , &firstUserHelpMenuItem) != noErr )
                            {
                                helpMenuHandle = NULL ;
                                break ;
                            }
                        }
                    }

                    if ( item->IsSeparator() )
                    {
                        if ( helpMenuHandle )
                            AppendMenuItemTextWithCFString( helpMenuHandle,
                                                            CFSTR(""), kMenuItemAttrSeparator, 0,NULL);
                    }
                    else
                    {
                        wxAcceleratorEntry*
                        entry = wxAcceleratorEntry::Create( item->GetItemLabel() ) ;

                        if ( item->GetId() == wxApp::s_macAboutMenuItemId )
                        {
                            // this will be taken care of below
                        }
                        else
                        {
                            if ( helpMenuHandle )
                            {
                                UMAAppendMenuItem(helpMenuHandle, wxStripMenuCodes(item->GetItemLabel()) , wxFont::GetDefaultEncoding(), entry);
                                SetMenuItemCommandID( helpMenuHandle , CountMenuItems(helpMenuHandle) , wxIdToMacCommand ( item->GetId() ) ) ;
                                SetMenuItemRefCon( helpMenuHandle , CountMenuItems(helpMenuHandle) , (URefCon) item ) ;
                            }
                        }

                        delete entry ;
                    }
                }
            }
        }

        else if ( ( m_titles[i] == wxT("Window") || m_titles[i] == wxT("&Window") )
                  && GetAutoWindowMenu() )
        {
            if ( MacGetWindowMenuHMenu() == NULL )
            {
                CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;
            }

            MenuRef wm = (MenuRef)MacGetWindowMenuHMenu();
            if ( wm == NULL )
                break;

            // get the insertion point in the standard menu
            MenuItemIndex winListStart;
            GetIndMenuItemWithCommandID(wm,
                                        kHICommandWindowListSeparator, 1, NULL, &winListStart);

            // add a separator so that the standard items and the custom items
            // aren't mixed together, but only if this is the first run
            OSStatus err = GetIndMenuItemWithCommandID(wm,
                           'WXWM', 1, NULL, NULL);

            if ( err == menuItemNotFoundErr )
            {
                InsertMenuItemTextWithCFString( wm,
                                                CFSTR(""), winListStart-1, kMenuItemAttrSeparator, 'WXWM');
            }

            wxInsertMenuItemsInMenu(menu, wm, winListStart);
        }
        else
        {
            UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], GetFont().GetEncoding()  ) ;
            menu->MacBeforeDisplay(false) ;

            ::InsertMenu(MAC_WXHMENU(GetMenu(i)->GetHMenu()), 0);
        }
    }

    // take care of the about menu item wherever it is
    {
        wxMenu* aboutMenu ;
        wxMenuItem *aboutMenuItem = FindItem(wxApp::s_macAboutMenuItemId , &aboutMenu) ;
        if ( aboutMenuItem )
        {
            wxAcceleratorEntry*
            entry = wxAcceleratorEntry::Create( aboutMenuItem->GetItemLabel() ) ;
            UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , wxStripMenuCodes ( aboutMenuItem->GetItemLabel() ) , wxFont::GetDefaultEncoding() );
            UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
            SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , kHICommandAbout ) ;
            SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId ) , 1 , (URefCon)aboutMenuItem ) ;
            UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
            delete entry;
        }
    }

    if ( GetAutoWindowMenu() )
    {
        if ( MacGetWindowMenuHMenu() == NULL )
            CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;

        InsertMenu( (MenuHandle) MacGetWindowMenuHMenu() , 0 ) ;
    }

    ::DrawMenuBar() ;
#endif

    s_macInstalledMenuBar = this;
}
Esempio n. 28
0
// function appends a new item or submenu to the menu
// append a new item or submenu to the menu
bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
{
    wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );

    if ( pItem->IsSeparator() )
    {
        if ( pos == (size_t)-1 )
            AppendMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu),
                CFSTR(""), kMenuItemAttrSeparator, 0,NULL); 
        else
            InsertMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu),
                CFSTR(""), pos, kMenuItemAttrSeparator, 0); 
    }
    else
    {
        wxMenu *pSubMenu = pItem->GetSubMenu() ;
        if ( pSubMenu != NULL )
        {
            wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added"));
            pSubMenu->m_menuParent = this ;

            if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
                pSubMenu->MacBeforeDisplay( true ) ;

            if ( pos == (size_t)-1 )
                UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetText()), wxFont::GetDefaultEncoding(), pSubMenu->m_macMenuId);
            else
                UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetText()), wxFont::GetDefaultEncoding(), pos, pSubMenu->m_macMenuId);

            pItem->UpdateItemBitmap() ;
            pItem->UpdateItemStatus() ;
        }
        else
        {
            if ( pos == (size_t)-1 )
            {
                UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), wxT("a") , wxFont::GetDefaultEncoding() );
                pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ;
            }
            else
            {
                // MacOS counts menu items from 1 and inserts after, therefore having the
                // same effect as wx 0 based and inserting before, we must correct pos
                // after however for updates to be correct
                UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), wxT("a"), wxFont::GetDefaultEncoding(), pos);
                pos += 1 ;
            }

            SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , wxIdToMacCommand ( pItem->GetId() ) ) ;
            SetMenuItemRefCon( MAC_WXHMENU(m_hMenu) , pos , (URefCon) pItem ) ;
            pItem->UpdateItemText() ;
            pItem->UpdateItemBitmap() ;
            pItem->UpdateItemStatus() ;

            if ( pItem->GetId() == idMenuTitle )
                UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , pos , false ) ;
        }
    }

    // if we're already attached to the menubar, we must update it
    if ( IsAttached() && GetMenuBar()->IsAttached() )
        GetMenuBar()->Refresh();

    return true ;
}