]> git.saurik.com Git - wxWidgets.git/blame - src/osx/menuitem_osx.cpp
fix for GTK assert after r72696, a draw/expose_event signal may also be attached...
[wxWidgets.git] / src / osx / menuitem_osx.cpp
CommitLineData
524c47aa
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/menuitem_osx.cpp
3// Purpose: wxMenuItem implementation
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
b5b208a1 7// RCS-ID: $Id$
524c47aa
SC
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
11fed901
SC
14#if wxUSE_MENUS
15
524c47aa
SC
16#include "wx/menuitem.h"
17#include "wx/stockitem.h"
18
19#ifndef WX_PRECOMP
20 #include "wx/app.h"
21 #include "wx/menu.h"
22#endif // WX_PRECOMP
23
24#include "wx/osx/private.h"
25
26IMPLEMENT_ABSTRACT_CLASS( wxMenuItemImpl , wxObject )
27
28wxMenuItemImpl::~wxMenuItemImpl()
29{
30}
31
524c47aa
SC
32wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
33 int id,
34 const wxString& t,
35 const wxString& strHelp,
36 wxItemKind kind,
37 wxMenu *pSubMenu)
38 :wxMenuItemBase(pParentMenu, id, t, strHelp, kind, pSubMenu)
39{
40 wxASSERT_MSG( id != 0 || pSubMenu != NULL , wxT("A MenuItem ID of Zero does not work under Mac") ) ;
41
42 // In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines
43 // therefore these item must not be translated
32f701b0
SC
44 if (pParentMenu != NULL && !pParentMenu->GetNoEventsMode())
45 if ( wxStripMenuCodes(m_text).Upper() == wxT("EXIT") )
46 m_text = wxT("Quit\tCtrl+Q") ;
524c47aa
SC
47
48 m_radioGroup.start = -1;
49 m_isRadioGroupStart = false;
03647350 50
32f701b0 51 wxString text = wxStripMenuCodes(m_text, (pParentMenu != NULL && pParentMenu->GetNoEventsMode()) ? wxStrip_Accel : wxStrip_All);
524c47aa
SC
52 if (text.IsEmpty() && !IsSeparator())
53 {
54 wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
55 text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC);
56 }
03647350 57
524c47aa 58 wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ;
1ea5ef01
SC
59 // use accessors for ID and Kind because they might have been changed in the base constructor
60 m_peer = wxMenuItemImpl::Create( this, pParentMenu, GetId(), text, entry, strHelp, GetKind(), pSubMenu );
524c47aa
SC
61 delete entry;
62}
63
64wxMenuItem::~wxMenuItem()
65{
66 delete m_peer;
67}
68
69// change item state
70// -----------------
71
72void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
73{
74 m_bitmap = bitmap;
75 UpdateItemBitmap();
76}
77
78void wxMenuItem::Enable(bool bDoEnable)
79{
80 if (( m_isEnabled != bDoEnable
81 // avoid changing menuitem state when menu is disabled
82 // eg. BeginAppModalStateForWindow() will disable menus and ignore this change
83 // which in turn causes m_isEnabled to become out of sync with real menuitem state
84#if wxOSX_USE_CARBON
03647350 85 && !(m_parentMenu && !IsMenuItemEnabled(MAC_WXHMENU(m_parentMenu->GetHMenu()), 0))
524c47aa
SC
86#endif
87 )
88 // always update builtin menuitems
89 || ( GetId() == wxApp::s_macPreferencesMenuItemId
90 || GetId() == wxApp::s_macExitMenuItemId
91 || GetId() == wxApp::s_macAboutMenuItemId
92 ))
93 {
94 wxMenuItemBase::Enable( bDoEnable ) ;
95 UpdateItemStatus() ;
96 }
97}
98
99void wxMenuItem::UncheckRadio()
100{
101 if ( m_isChecked )
102 {
103 wxMenuItemBase::Check( false ) ;
104 UpdateItemStatus() ;
105 }
106}
107
108void wxMenuItem::Check(bool bDoCheck)
109{
110 wxCHECK_RET( IsCheckable() && !IsSeparator(), wxT("only checkable items may be checked") );
111
112 if ( m_isChecked != bDoCheck )
113 {
114 if ( GetKind() == wxITEM_RADIO )
115 {
116 if ( bDoCheck )
117 {
118 wxMenuItemBase::Check( bDoCheck ) ;
119 UpdateItemStatus() ;
120
121 // get the index of this item in the menu
122 const wxMenuItemList& items = m_parentMenu->GetMenuItems();
123 int pos = items.IndexOf(this);
124 wxCHECK_RET( pos != wxNOT_FOUND,
9a83f860 125 wxT("menuitem not found in the menu items list?") );
524c47aa
SC
126
127 // get the radio group range
128 int start, end;
129
130 if ( m_isRadioGroupStart )
131 {
132 // we already have all information we need
133 start = pos;
134 end = m_radioGroup.end;
135 }
136 else // next radio group item
137 {
138 // get the radio group end from the start item
139 start = m_radioGroup.start;
140 end = items.Item(start)->GetData()->m_radioGroup.end;
141 }
142
143 // also uncheck all the other items in this radio group
144 wxMenuItemList::compatibility_iterator node = items.Item(start);
145 for ( int n = start; n <= end && node; n++ )
146 {
147 if ( n != pos )
148 ((wxMenuItem*)node->GetData())->UncheckRadio();
149
150 node = node->GetNext();
151 }
152 }
153 }
154 else
155 {
156 wxMenuItemBase::Check( bDoCheck ) ;
157 UpdateItemStatus() ;
158 }
159 }
160}
161
162void wxMenuItem::SetItemLabel(const wxString& text)
163{
164 // don't do anything if label didn't change
165 if ( m_text == text )
166 return;
167
168 wxMenuItemBase::SetItemLabel(text);
169
170 UpdateItemText() ;
171}
172
173
174void wxMenuItem::UpdateItemBitmap()
175{
176 if ( !m_parentMenu )
177 return;
03647350 178
a1b806b9 179 if ( m_bitmap.IsOk() )
524c47aa 180 {
22756322 181 GetPeer()->SetBitmap( m_bitmap );
524c47aa
SC
182 }
183}
184
185void wxMenuItem::UpdateItemStatus()
186{
187 if ( !m_parentMenu )
188 return ;
189
190 if ( IsSeparator() )
191 return ;
03647350 192
524c47aa 193 if ( IsCheckable() && IsChecked() )
22756322 194 GetPeer()->Check( true );
524c47aa 195 else
22756322 196 GetPeer()->Check( false );
03647350 197
22756322 198 GetPeer()->Enable( IsEnabled() );
524c47aa
SC
199}
200
201void wxMenuItem::UpdateItemText()
202{
203 if ( !m_parentMenu )
204 return ;
205
32f701b0 206 wxString text = wxStripMenuCodes(m_text, m_parentMenu != NULL && m_parentMenu->GetNoEventsMode() ? wxStrip_Accel : wxStrip_All);
524c47aa
SC
207 if (text.IsEmpty() && !IsSeparator())
208 {
209 wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
210 text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC);
211 }
03647350 212
524c47aa 213 wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ;
22756322 214 GetPeer()->SetLabel( text, entry );
524c47aa
SC
215 delete entry ;
216}
217
218// radio group stuff
219// -----------------
220
221void wxMenuItem::SetAsRadioGroupStart()
222{
223 m_isRadioGroupStart = true;
224}
225
226void wxMenuItem::SetRadioGroupStart(int start)
227{
228 wxASSERT_MSG( !m_isRadioGroupStart,
229 wxT("should only be called for the next radio items") );
230
231 m_radioGroup.start = start;
232}
233
234void wxMenuItem::SetRadioGroupEnd(int end)
235{
236 wxASSERT_MSG( m_isRadioGroupStart,
237 wxT("should only be called for the first radio item") );
238
239 m_radioGroup.end = end;
240}
241
242// ----------------------------------------------------------------------------
243// wxMenuItemBase
244// ----------------------------------------------------------------------------
245
246wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
247 int id,
248 const wxString& name,
249 const wxString& help,
250 wxItemKind kind,
251 wxMenu *subMenu)
252{
253 return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
254}
11fed901
SC
255
256#endif