]> git.saurik.com Git - wxWidgets.git/blob - src/mac/classic/menuitem.cpp
don't create non-existing groups in HasEntry()
[wxWidgets.git] / src / mac / classic / menuitem.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/classic/menuitem.cpp
3 // Purpose: wxMenuItem implementation
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
15
16 #include "wx/wxprec.h"
17
18 #include "wx/menuitem.h"
19
20 #ifndef WX_PRECOMP
21 #include "wx/app.h"
22 #include "wx/menu.h"
23 #endif
24
25 #include "wx/mac/uma.h"
26 // ============================================================================
27 // implementation
28 // ============================================================================
29
30 // ----------------------------------------------------------------------------
31 // dynamic classes implementation
32 // ----------------------------------------------------------------------------
33
34 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
35
36 // ----------------------------------------------------------------------------
37 // wxMenuItem
38 // ----------------------------------------------------------------------------
39
40 //
41 // ctor & dtor
42 // -----------
43
44 wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
45 int id,
46 const wxString& text,
47 const wxString& strHelp,
48 wxItemKind kind,
49 wxMenu *pSubMenu)
50 : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
51 {
52 // TO DISCUSS on dev : whether we can veto id 0
53 // wxASSERT_MSG( id != 0 || pSubMenu != NULL , wxT("A MenuItem ID of Zero does not work under Mac") ) ;
54
55 // In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines
56 // therefore these item must not be translated
57 if ( wxStripMenuCodes(m_text).Upper() == wxT("EXIT") )
58 {
59 m_text =wxT("Quit\tCtrl+Q") ;
60 }
61
62 m_radioGroup.start = -1;
63 m_isRadioGroupStart = false;
64 }
65
66 wxMenuItem::~wxMenuItem()
67 {
68 }
69
70 // change item state
71 // -----------------
72
73 void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
74 {
75 m_bitmap = bitmap;
76 UpdateItemBitmap() ;
77 }
78
79 void wxMenuItem::UpdateItemBitmap()
80 {
81 if ( !m_parentMenu )
82 return ;
83
84 MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
85 MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
86 if( mhandle == NULL || index == 0)
87 return ;
88
89 if ( m_bitmap.Ok() )
90 {
91 ControlButtonContentInfo info ;
92 wxMacCreateBitmapButton( &info , m_bitmap , kControlContentCIconHandle ) ;
93 if ( info.contentType != kControlNoContent )
94 {
95 if ( info.contentType == kControlContentCIconHandle )
96 SetMenuItemIconHandle( mhandle , index ,
97 kMenuColorIconType , (Handle) info.u.cIconHandle ) ;
98 }
99
100 }
101 }
102
103 void wxMenuItem::UpdateItemStatus()
104 {
105 if ( !m_parentMenu )
106 return ;
107
108 #if TARGET_CARBON
109 if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId)
110 {
111 if ( !IsEnabled() )
112 DisableMenuCommand( NULL , kHICommandPreferences ) ;
113 else
114 EnableMenuCommand( NULL , kHICommandPreferences ) ;
115 }
116 if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId)
117 {
118 if ( !IsEnabled() )
119 DisableMenuCommand( NULL , kHICommandQuit ) ;
120 else
121 EnableMenuCommand( NULL , kHICommandQuit ) ;
122 }
123 #endif
124 {
125 MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
126 MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
127 if( mhandle == NULL || index == 0)
128 return ;
129
130 UMAEnableMenuItem( mhandle , index , m_isEnabled ) ;
131 if ( IsCheckable() && IsChecked() )
132 ::SetItemMark( mhandle , index , 0x12 ) ; // checkmark
133 else
134 ::SetItemMark( mhandle , index , 0 ) ; // no mark
135
136 UMASetMenuItemText( mhandle , index , m_text , wxFont::GetDefaultEncoding() ) ;
137 wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
138 UMASetMenuItemShortcut( mhandle , index , entry ) ;
139 delete entry ;
140 }
141 }
142
143 void wxMenuItem::UpdateItemText()
144 {
145 if ( !m_parentMenu )
146 return ;
147
148 MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
149 MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
150 if( mhandle == NULL || index == 0)
151 return ;
152
153 UMASetMenuItemText( mhandle , index , m_text , wxFont::GetDefaultEncoding() ) ;
154 wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
155 UMASetMenuItemShortcut( mhandle , index , entry ) ;
156 delete entry ;
157 }
158
159
160 void wxMenuItem::Enable(bool bDoEnable)
161 {
162 if ( m_isEnabled != bDoEnable )
163 {
164 wxMenuItemBase::Enable( bDoEnable ) ;
165 UpdateItemStatus() ;
166 }
167 }
168 void wxMenuItem::UncheckRadio()
169 {
170 if ( m_isChecked )
171 {
172 wxMenuItemBase::Check( false ) ;
173 UpdateItemStatus() ;
174 }
175 }
176
177 void wxMenuItem::Check(bool bDoCheck)
178 {
179 wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
180
181 if ( m_isChecked != bDoCheck )
182 {
183 if ( GetKind() == wxITEM_RADIO )
184 {
185 if ( bDoCheck )
186 {
187 wxMenuItemBase::Check( bDoCheck ) ;
188 UpdateItemStatus() ;
189
190 // get the index of this item in the menu
191 const wxMenuItemList& items = m_parentMenu->GetMenuItems();
192 int pos = items.IndexOf(this);
193 wxCHECK_RET( pos != wxNOT_FOUND,
194 _T("menuitem not found in the menu items list?") );
195
196 // get the radio group range
197 int start,
198 end;
199
200 if ( m_isRadioGroupStart )
201 {
202 // we already have all information we need
203 start = pos;
204 end = m_radioGroup.end;
205 }
206 else // next radio group item
207 {
208 // get the radio group end from the start item
209 start = m_radioGroup.start;
210 end = items.Item(start)->GetData()->m_radioGroup.end;
211 }
212
213 // also uncheck all the other items in this radio group
214 wxMenuItemList::Node *node = items.Item(start);
215 for ( int n = start; n <= end && node; n++ )
216 {
217 if ( n != pos )
218 {
219 ((wxMenuItem*)node->GetData())->UncheckRadio();
220 }
221 node = node->GetNext();
222 }
223 }
224 }
225 else
226 {
227 wxMenuItemBase::Check( bDoCheck ) ;
228 UpdateItemStatus() ;
229 }
230 }
231 }
232
233 void wxMenuItem::SetText(const wxString& text)
234 {
235 // don't do anything if label didn't change
236 if ( m_text == text )
237 return;
238
239 wxMenuItemBase::SetText(text);
240
241 UpdateItemText() ;
242 }
243
244 // radio group stuff
245 // -----------------
246
247 void wxMenuItem::SetAsRadioGroupStart()
248 {
249 m_isRadioGroupStart = true;
250 }
251
252 void wxMenuItem::SetRadioGroupStart(int start)
253 {
254 wxASSERT_MSG( !m_isRadioGroupStart,
255 _T("should only be called for the next radio items") );
256
257 m_radioGroup.start = start;
258 }
259
260 void wxMenuItem::SetRadioGroupEnd(int end)
261 {
262 wxASSERT_MSG( m_isRadioGroupStart,
263 _T("should only be called for the first radio item") );
264
265 m_radioGroup.end = end;
266 }
267
268 // ----------------------------------------------------------------------------
269 // wxMenuItemBase
270 // ----------------------------------------------------------------------------
271
272 /* static */
273 wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
274 {
275 return wxStripMenuCodes(text);
276 }
277
278 wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
279 int id,
280 const wxString& name,
281 const wxString& help,
282 wxItemKind kind,
283 wxMenu *subMenu)
284 {
285 return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
286 }