]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/menuitem.cpp
switching to safe yields, because we got into loops when handling print document...
[wxWidgets.git] / src / mac / carbon / menuitem.cpp
CommitLineData
e9576ca5
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: menuitem.cpp
3// Purpose: wxMenuItem implementation
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
03e11df5 16#include "wx/app.h"
e9576ca5
SC
17#include "wx/menu.h"
18#include "wx/menuitem.h"
19
d497dca4 20#include "wx/mac/uma.h"
e9576ca5
SC
21// ============================================================================
22// implementation
23// ============================================================================
24
25// ----------------------------------------------------------------------------
26// dynamic classes implementation
27// ----------------------------------------------------------------------------
28
2f1ae414 29#if !USE_SHARED_LIBRARY
e9576ca5 30 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
2f1ae414 31#endif //USE_SHARED_LIBRARY
37e2cb08 32
e9576ca5
SC
33// ----------------------------------------------------------------------------
34// wxMenuItem
35// ----------------------------------------------------------------------------
36
2f1ae414
SC
37//
38// Helper Functions to get Mac Menus the way they should be ;-)
39//
40
41void wxMacCtoPString(const char* theCString, Str255 thePString);
42
43// remove inappropriate characters, if useShortcuts is false, the ampersand will not auto-generate a mac menu-shortcut
44
e437cc53 45int wxMenuItem::MacBuildMenuString(StringPtr outMacItemText, SInt16 *outMacShortcutChar , UInt8 *outMacModifiers , const char *inItemText , bool useShortcuts )
2f1ae414
SC
46{
47 char *p = (char *) &outMacItemText[1] ;
48 short macModifiers = 0 ;
2b5f62a0 49 SInt16 macShortCut = 0 ;
2f1ae414
SC
50 const char *inItemName ;
51 wxString inItemTextMac ;
52
53 if (wxApp::s_macDefaultEncodingIsPC)
54 {
55 inItemTextMac = wxMacMakeMacStringFromPC( inItemText ) ;
56 inItemName = inItemTextMac ;
57 }
58 else
59 {
60 inItemName = inItemText ;
61 }
62
63 if ( useShortcuts && !wxApp::s_macSupportPCMenuShortcuts )
64 useShortcuts = false ;
65
66 // we have problems with a leading hypen - it will be taken as a separator
67
68 while ( *inItemName == '-' )
69 inItemName++ ;
70
71 while( *inItemName )
72 {
73 switch ( *inItemName )
74 {
2f1ae414
SC
75 // shortcuts
76 case '&' :
77 {
78 ++inItemName ;
79 if ( *inItemName )
80 {
81 *p++ = *inItemName ;
82 if ( useShortcuts )
83 macShortCut = *inItemName ;
84 }
85 else
86 --inItemName ;
87 }
88 break ;
89 // win-like accelerators
90 case '\t' :
91 {
92 ++inItemName ;
2b5f62a0
VZ
93 bool skip = false ;
94 bool explicitCommandKey = false ;
95 while( *inItemName && !skip )
2f1ae414 96 {
2b5f62a0 97 if (wxStrnicmp("Ctrl", inItemName, 4) == 0)
2f1ae414
SC
98 {
99 inItemName = inItemName + 5;
2b5f62a0 100 explicitCommandKey = true ;
2f1ae414 101 }
2b5f62a0 102 else if (wxStrnicmp("Cntrl", inItemName, 5) == 0)
2f1ae414
SC
103 {
104 inItemName = inItemName + 6;
2b5f62a0 105 explicitCommandKey = true ;
2f1ae414 106 }
2b5f62a0 107 else if (wxStrnicmp("Alt", inItemName, 3) == 0)
2f1ae414
SC
108 {
109 inItemName = inItemName + 4;
110 macModifiers |= kMenuOptionModifier ;
2f1ae414 111 }
2b5f62a0 112 else if (wxStrnicmp("Shift", inItemName, 5) == 0)
2f1ae414
SC
113 {
114 inItemName = inItemName + 6;
115 macModifiers |= kMenuShiftModifier ;
2f1ae414 116 }
2b5f62a0 117 else
2f1ae414 118 {
2b5f62a0 119 skip = true ;
2f1ae414 120 }
2b5f62a0
VZ
121 }
122 if ( *inItemName )
123 {
124 if ( strlen(inItemName) == 1 )
125 {
126 macShortCut = *inItemName;
127 }
128 else if ( !wxStricmp( inItemName , "Delete" ) || !wxStricmp( inItemName , "Del" ) )
129 {
130 macShortCut = WXK_DELETE ;
131 }
132 else if ( !wxStricmp( inItemName , "Back" ) || !wxStricmp( inItemName , "Backspace" ) )
133 {
134 macShortCut = WXK_BACK ;
135 }
136 else if ( !wxStricmp( inItemName , "Return" ) )
2f1ae414 137 {
2b5f62a0
VZ
138 macShortCut = WXK_RETURN ;
139 }
140 else if ( !wxStricmp( inItemName , "Enter" ) )
141 {
142 macShortCut = kEnterCharCode ;
143 }
144 else if ( *inItemName == 'F' )
145 {
146 int fkey = atol(inItemName+1) ;
147 if (fkey >= 1 && fkey < 15 )
148 {
149 macShortCut = WXK_F1 + fkey - 1 ;
150 }
151 if ( !explicitCommandKey )
152 macModifiers |= kMenuNoCommandModifier ;
2f1ae414
SC
153 }
154 }
2b5f62a0
VZ
155
156 inItemName += strlen( inItemName ) ;
157
2f1ae414
SC
158 if ( *inItemName == 0 )
159 --inItemName ;
160
161 }
162 break ;
163 default :
164 *p++ = *inItemName ;
165 }
166 ++inItemName ;
167 }
168
169 outMacItemText[0] = (p - (char *)outMacItemText) - 1;
170 if ( outMacShortcutChar )
171 *outMacShortcutChar = macShortCut ;
172 if ( outMacModifiers )
173 *outMacModifiers = macModifiers ;
174
175 return 0 ;
176}
177
e9576ca5
SC
178// ctor & dtor
179// -----------
180
d65c269b
VZ
181wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
182 int id,
183 const wxString& text,
184 const wxString& strHelp,
185 wxItemKind kind,
e7549107 186 wxMenu *pSubMenu)
d65c269b 187 : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
e9576ca5 188{
d65c269b 189 // VZ: what about translations?? (FIXME)
f1ba2ee8 190 if ( m_text == "E&xit" ||m_text == "Exit" ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" )
e7549107
SC
191 {
192 m_text = "Quit\tCtrl+Q" ;
193 }
e9576ca5
SC
194}
195
196wxMenuItem::~wxMenuItem()
197{
198}
199
51abe921
SC
200bool wxMenuItem::IsChecked() const
201{
202 return wxMenuItemBase::IsChecked() ;
203}
204
205wxString wxMenuItem::GetLabel() const
206{
207 return wxStripMenuCodes(m_text);
208}
209
210// accelerators
211// ------------
212
213#if wxUSE_ACCEL
214
215wxAcceleratorEntry *wxMenuItem::GetAccel() const
216{
217 return wxGetAccelFromString(GetText());
218}
219
220#endif // wxUSE_ACCEL
221
e9576ca5
SC
222// misc
223// ----
224
e7549107
SC
225/*
226
e9576ca5
SC
227// delete the sub menu
228void wxMenuItem::DeleteSubMenu()
229{
e7549107 230 wxASSERT( m_subMenu != NULL );
e9576ca5 231
e7549107
SC
232 delete m_subMenu;
233 m_subMenu = NULL;
e9576ca5
SC
234}
235
e7549107
SC
236*/
237
e9576ca5
SC
238// change item state
239// -----------------
240
241void wxMenuItem::Enable(bool bDoEnable)
242{
e7549107
SC
243 if ( m_isEnabled != bDoEnable ) {
244 if ( m_subMenu == NULL )
519cb848
SC
245 {
246 // normal menu item
76a5e5d2 247 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
519cb848 248 {
e7549107 249 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
519cb848
SC
250 if ( index >= 1 )
251 {
252 if ( bDoEnable )
76a5e5d2 253 UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
519cb848 254 else
76a5e5d2 255 UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
519cb848
SC
256 }
257 }
e9576ca5 258 }
519cb848 259 else
e9576ca5 260 {
519cb848 261 // submenu
76a5e5d2 262 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
519cb848 263 {
e7549107 264 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
519cb848
SC
265 if ( index >= 1 )
266 {
267 if ( bDoEnable )
76a5e5d2 268 UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
519cb848 269 else
76a5e5d2 270 UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
519cb848
SC
271 }
272 }
e9576ca5
SC
273 }
274
e7549107 275 m_isEnabled = bDoEnable;
e9576ca5
SC
276 }
277}
278
279void wxMenuItem::Check(bool bDoCheck)
280{
281 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
282
e7549107 283 if ( m_isChecked != bDoCheck )
519cb848 284 {
e7549107 285 m_isChecked = bDoCheck;
76a5e5d2 286 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
519cb848 287 {
e7549107 288 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
519cb848
SC
289 if ( index >= 1 )
290 {
291 if ( bDoCheck )
76a5e5d2 292 ::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0x12 ) ; // checkmark
519cb848 293 else
76a5e5d2 294 ::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0 ) ; // no mark
519cb848
SC
295 }
296 }
e9576ca5 297 }
51abe921
SC
298}
299
300void wxMenuItem::SetText(const wxString& text)
301{
302 // don't do anything if label didn't change
303 if ( m_text == text )
304 return;
305
306 wxMenuItemBase::SetText(text);
307// OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
308
309 wxCHECK_RET( m_parentMenu && m_parentMenu->GetHMenu(), wxT("menuitem without menu") );
76a5e5d2 310 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
51abe921
SC
311 {
312 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
313 if ( index >= 1 )
314 {
315 Str255 label;
2f1ae414 316 MacBuildMenuString( label , NULL , NULL , text ,false);
76a5e5d2 317 ::SetMenuItemText( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , label ) ; // checkmark
51abe921
SC
318 }
319 }
320
321#if wxUSE_ACCEL
322 m_parentMenu->UpdateAccel(this);
323#endif // wxUSE_ACCEL
324
325}
326void wxMenuItem::SetCheckable(bool checkable)
327{
328 wxMenuItemBase::SetCheckable(checkable);
329 // OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
330}
331
332// ----------------------------------------------------------------------------
333// wxMenuItemBase
334// ----------------------------------------------------------------------------
335
2f1ae414
SC
336/* static */
337wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
338{
339 return wxStripMenuCodes(text);
340}
341
51abe921
SC
342wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
343 int id,
344 const wxString& name,
345 const wxString& help,
d65c269b 346 wxItemKind kind,
51abe921
SC
347 wxMenu *subMenu)
348{
d65c269b 349 return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
51abe921 350}