1
///////////////////////////////////////////////////////////////////////////////
2
// Name: src/osx/menuitem_osx.cpp
3
// Purpose: wxMenuItem implementation
4
// Author: Stefan Csomor
7
// Copyright: (c) Stefan Csomor
8
// Licence: wxWindows licence
9
///////////////////////////////////////////////////////////////////////////////
11
#include "wx/wxprec.h"
15
#include "wx/menuitem.h"
16
#include "wx/stockitem.h"
23
#include "wx/osx/private.h"
25
IMPLEMENT_ABSTRACT_CLASS( wxMenuItemImpl , wxObject )
27
wxMenuItemImpl::~wxMenuItemImpl()
31
wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
34
const wxString& strHelp,
37
:wxMenuItemBase(pParentMenu, id, t, strHelp, kind, pSubMenu)
39
wxASSERT_MSG( id != 0 || pSubMenu != NULL , wxT("A MenuItem ID of Zero does not work under Mac") ) ;
41
// In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines
42
// therefore these item must not be translated
43
if (pParentMenu != NULL && !pParentMenu->GetNoEventsMode())
44
if ( wxStripMenuCodes(m_text).Upper() == wxT("EXIT") )
45
m_text = wxT("Quit\tCtrl+Q") ;
47
m_radioGroup.start = -1;
48
m_isRadioGroupStart = false;
50
wxString text = wxStripMenuCodes(m_text, (pParentMenu != NULL && pParentMenu->GetNoEventsMode()) ? wxStrip_Accel : wxStrip_All);
51
if (text.IsEmpty() && !IsSeparator())
53
wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
54
text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC);
57
wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ;
58
// use accessors for ID and Kind because they might have been changed in the base constructor
59
m_peer = wxMenuItemImpl::Create( this, pParentMenu, GetId(), text, entry, strHelp, GetKind(), pSubMenu );
63
wxMenuItem::~wxMenuItem()
71
void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
77
void wxMenuItem::Enable(bool bDoEnable)
79
if (( m_isEnabled != bDoEnable
80
// avoid changing menuitem state when menu is disabled
81
// eg. BeginAppModalStateForWindow() will disable menus and ignore this change
82
// which in turn causes m_isEnabled to become out of sync with real menuitem state
84
&& !(m_parentMenu && !IsMenuItemEnabled(MAC_WXHMENU(m_parentMenu->GetHMenu()), 0))
87
// always update builtin menuitems
88
|| ( GetId() == wxApp::s_macPreferencesMenuItemId
89
|| GetId() == wxApp::s_macExitMenuItemId
90
|| GetId() == wxApp::s_macAboutMenuItemId
93
wxMenuItemBase::Enable( bDoEnable ) ;
98
void wxMenuItem::UncheckRadio()
102
wxMenuItemBase::Check( false ) ;
107
void wxMenuItem::Check(bool bDoCheck)
109
wxCHECK_RET( IsCheckable() && !IsSeparator(), wxT("only checkable items may be checked") );
111
if ( m_isChecked != bDoCheck )
113
if ( GetKind() == wxITEM_RADIO )
117
wxMenuItemBase::Check( bDoCheck ) ;
120
// get the index of this item in the menu
121
const wxMenuItemList& items = m_parentMenu->GetMenuItems();
122
int pos = items.IndexOf(this);
123
wxCHECK_RET( pos != wxNOT_FOUND,
124
wxT("menuitem not found in the menu items list?") );
126
// get the radio group range
129
if ( m_isRadioGroupStart )
131
// we already have all information we need
133
end = m_radioGroup.end;
135
else // next radio group item
137
// get the radio group end from the start item
138
start = m_radioGroup.start;
139
end = items.Item(start)->GetData()->m_radioGroup.end;
142
// also uncheck all the other items in this radio group
143
wxMenuItemList::compatibility_iterator node = items.Item(start);
144
for ( int n = start; n <= end && node; n++ )
147
((wxMenuItem*)node->GetData())->UncheckRadio();
149
node = node->GetNext();
155
wxMenuItemBase::Check( bDoCheck ) ;
161
void wxMenuItem::SetItemLabel(const wxString& text)
163
// don't do anything if label didn't change
164
if ( m_text == text )
167
wxMenuItemBase::SetItemLabel(text);
173
void wxMenuItem::UpdateItemBitmap()
178
if ( m_bitmap.IsOk() )
180
GetPeer()->SetBitmap( m_bitmap );
184
void wxMenuItem::UpdateItemStatus()
192
if ( IsCheckable() && IsChecked() )
193
GetPeer()->Check( true );
195
GetPeer()->Check( false );
197
GetPeer()->Enable( IsEnabled() );
200
void wxMenuItem::UpdateItemText()
205
wxString text = wxStripMenuCodes(m_text, m_parentMenu != NULL && m_parentMenu->GetNoEventsMode() ? wxStrip_Accel : wxStrip_All);
206
if (text.IsEmpty() && !IsSeparator())
208
wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
209
text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC);
212
wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ;
213
GetPeer()->SetLabel( text, entry );
220
void wxMenuItem::SetAsRadioGroupStart(bool start)
222
m_isRadioGroupStart = start;
225
void wxMenuItem::SetRadioGroupStart(int start)
227
wxASSERT_MSG( !m_isRadioGroupStart,
228
wxT("should only be called for the next radio items") );
230
m_radioGroup.start = start;
233
void wxMenuItem::SetRadioGroupEnd(int end)
235
wxASSERT_MSG( m_isRadioGroupStart,
236
wxT("should only be called for the first radio item") );
238
m_radioGroup.end = end;
241
bool wxMenuItem::IsRadioGroupStart() const
243
return m_isRadioGroupStart;
246
int wxMenuItem::GetRadioGroupStart() const
248
wxASSERT_MSG( !m_isRadioGroupStart,
249
wxS("shouldn't be called for the first radio item") );
251
return m_radioGroup.start;
254
int wxMenuItem::GetRadioGroupEnd() const
256
wxASSERT_MSG( m_isRadioGroupStart,
257
wxS("shouldn't be called for the first radio item") );
259
return m_radioGroup.end;
262
// ----------------------------------------------------------------------------
264
// ----------------------------------------------------------------------------
266
wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
268
const wxString& name,
269
const wxString& help,
273
return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);