1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/menuitem.cpp 
   3 // Purpose:     wxMenuItem implementation 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  14 #include "wx/menuitem.h" 
  15 #include "wx/stockitem.h" 
  22 #include "wx/mac/uma.h" 
  24 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
) 
  27 wxMenuItem::wxMenuItem(wxMenu 
*pParentMenu
, 
  30                        const wxString
& strHelp
, 
  33            :wxMenuItemBase(pParentMenu
, id
, text
, strHelp
, kind
, pSubMenu
) 
  35     wxASSERT_MSG( id 
!= 0 || pSubMenu 
!= NULL 
, wxT("A MenuItem ID of Zero does not work under Mac") ) ; 
  37     // In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines 
  38     // therefore these item must not be translated 
  39     if ( wxStripMenuCodes(m_text
).Upper() == wxT("EXIT") ) 
  40         m_text 
= wxT("Quit\tCtrl+Q") ; 
  42     m_radioGroup
.start 
= -1; 
  43     m_isRadioGroupStart 
= false; 
  46 wxMenuItem::~wxMenuItem() 
  53 void wxMenuItem::SetBitmap(const wxBitmap
& bitmap
) 
  59 void wxMenuItem::UpdateItemBitmap() 
  64     MenuHandle mhandle 
= MAC_WXHMENU(m_parentMenu
->GetHMenu()) ; 
  65     MenuItemIndex index 
= m_parentMenu
->MacGetIndexFromItem( this ) ; 
  66     if ( mhandle 
== NULL 
|| index 
== 0) 
  72         ControlButtonContentInfo info 
; 
  73         wxMacCreateBitmapButton( &info 
, m_bitmap 
) ; 
  74         if ( info
.contentType 
!= kControlNoContent 
) 
  76             if ( info
.contentType 
== kControlContentIconRef 
) 
  77                 SetMenuItemIconHandle( mhandle 
, index 
, 
  78                     kMenuIconRefType 
, (Handle
) info
.u
.iconRef 
) ; 
  80         wxMacReleaseBitmapButton( &info 
) ; 
  85 void wxMenuItem::UpdateItemStatus() 
  94     if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId
) 
  97             DisableMenuCommand( NULL 
, kHICommandPreferences 
) ; 
  99             EnableMenuCommand( NULL 
, kHICommandPreferences 
) ; 
 102     if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId
) 
 105             DisableMenuCommand( NULL 
, kHICommandQuit 
) ; 
 107             EnableMenuCommand( NULL 
, kHICommandQuit 
) ; 
 112         MenuHandle mhandle 
= MAC_WXHMENU(m_parentMenu
->GetHMenu()) ; 
 113         MenuItemIndex index 
= m_parentMenu
->MacGetIndexFromItem( this ) ; 
 114         if ( mhandle 
== NULL 
|| index 
== 0) 
 117         UMAEnableMenuItem( mhandle 
, index 
, m_isEnabled 
) ; 
 118         if ( IsCheckable() && IsChecked() ) 
 119             ::SetItemMark( mhandle 
, index 
, 0x12 ) ; // checkmark 
 121             ::SetItemMark( mhandle 
, index 
, 0 ) ; // no mark 
 123         UMASetMenuItemText( mhandle 
, index 
, wxStripMenuCodes(m_text
) , wxFont::GetDefaultEncoding() ) ; 
 124         wxAcceleratorEntry 
*entry 
= wxAcceleratorEntry::Create( m_text 
) ; 
 125         UMASetMenuItemShortcut( mhandle 
, index 
, entry 
) ; 
 130 void wxMenuItem::UpdateItemText() 
 135     MenuHandle mhandle 
= MAC_WXHMENU(m_parentMenu
->GetHMenu()) ; 
 136     MenuItemIndex index 
= m_parentMenu
->MacGetIndexFromItem( this ) ; 
 137     if (mhandle 
== NULL 
|| index 
== 0) 
 140     wxString text 
= m_text
; 
 141     if (text
.IsEmpty() && !IsSeparator()) 
 143         wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?")); 
 144         text 
= wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR
|wxSTOCK_WITH_MNEMONIC
); 
 147     UMASetMenuItemText( mhandle 
, index 
, wxStripMenuCodes(text
) , wxFont::GetDefaultEncoding() ) ; 
 148     wxAcceleratorEntry 
*entry 
= wxAcceleratorEntry::Create( text 
) ; 
 149     UMASetMenuItemShortcut( mhandle 
, index 
, entry 
) ; 
 153 void wxMenuItem::Enable(bool bDoEnable
) 
 155     if (( m_isEnabled 
!= bDoEnable
 
 157       // avoid changing menuitem state when menu is disabled 
 158       // eg. BeginAppModalStateForWindow() will disable menus and ignore this change 
 159       // which in turn causes m_isEnabled to become out of sync with real menuitem state 
 160          && !(m_parentMenu 
&& !IsMenuItemEnabled(MAC_WXHMENU(m_parentMenu
->GetHMenu()), 0)) ) 
 161       // always update builtin menuitems 
 162          || (   GetId() == wxApp::s_macPreferencesMenuItemId
 
 163              || GetId() == wxApp::s_macExitMenuItemId
 
 164              || GetId() == wxApp::s_macAboutMenuItemId
 
 168         wxMenuItemBase::Enable( bDoEnable 
) ; 
 173 void wxMenuItem::UncheckRadio() 
 177         wxMenuItemBase::Check( false ) ; 
 182 void wxMenuItem::Check(bool bDoCheck
) 
 184     wxCHECK_RET( IsCheckable() && !IsSeparator(), wxT("only checkable items may be checked") ); 
 186     if ( m_isChecked 
!= bDoCheck 
) 
 188         if ( GetKind() == wxITEM_RADIO 
) 
 192                 wxMenuItemBase::Check( bDoCheck 
) ; 
 195                 // get the index of this item in the menu 
 196                 const wxMenuItemList
& items 
= m_parentMenu
->GetMenuItems(); 
 197                 int pos 
= items
.IndexOf(this); 
 198                 wxCHECK_RET( pos 
!= wxNOT_FOUND
, 
 199                              _T("menuitem not found in the menu items list?") ); 
 201                 // get the radio group range 
 204                 if ( m_isRadioGroupStart 
) 
 206                     // we already have all information we need 
 208                     end 
= m_radioGroup
.end
; 
 210                 else // next radio group item 
 212                     // get the radio group end from the start item 
 213                     start 
= m_radioGroup
.start
; 
 214                     end 
= items
.Item(start
)->GetData()->m_radioGroup
.end
; 
 217                 // also uncheck all the other items in this radio group 
 218                 wxMenuItemList::compatibility_iterator node 
= items
.Item(start
); 
 219                 for ( int n 
= start
; n 
<= end 
&& node
; n
++ ) 
 222                         ((wxMenuItem
*)node
->GetData())->UncheckRadio(); 
 224                     node 
= node
->GetNext(); 
 230             wxMenuItemBase::Check( bDoCheck 
) ; 
 236 void wxMenuItem::SetText(const wxString
& text
) 
 238     // don't do anything if label didn't change 
 239     if ( m_text 
== text 
) 
 242     wxMenuItemBase::SetText(text
); 
 250 void wxMenuItem::SetAsRadioGroupStart() 
 252     m_isRadioGroupStart 
= true; 
 255 void wxMenuItem::SetRadioGroupStart(int start
) 
 257     wxASSERT_MSG( !m_isRadioGroupStart
, 
 258                   wxT("should only be called for the next radio items") ); 
 260     m_radioGroup
.start 
= start
; 
 263 void wxMenuItem::SetRadioGroupEnd(int end
) 
 265     wxASSERT_MSG( m_isRadioGroupStart
, 
 266                   wxT("should only be called for the first radio item") ); 
 268     m_radioGroup
.end 
= end
; 
 271 // ---------------------------------------------------------------------------- 
 273 // ---------------------------------------------------------------------------- 
 276 wxString 
wxMenuItemBase::GetLabelFromText(const wxString
& text
) 
 278     return wxStripMenuCodes(text
); 
 281 wxMenuItem 
*wxMenuItemBase::New(wxMenu 
*parentMenu
, 
 283                                 const wxString
& name
, 
 284                                 const wxString
& help
, 
 288     return new wxMenuItem(parentMenu
, id
, name
, help
, kind
, subMenu
);