]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/menuitem.cpp
Corrected accidental pointer arithmetic in ClientToScreen and vice versa
[wxWidgets.git] / src / mac / carbon / menuitem.cpp
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
16 #include "wx/app.h"
17 #include "wx/menu.h"
18 #include "wx/menuitem.h"
19
20 #include "wx/mac/uma.h"
21 // ============================================================================
22 // implementation
23 // ============================================================================
24
25 // ----------------------------------------------------------------------------
26 // dynamic classes implementation
27 // ----------------------------------------------------------------------------
28
29 #if !USE_SHARED_LIBRARY
30 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
31 #endif //USE_SHARED_LIBRARY
32
33 // ----------------------------------------------------------------------------
34 // wxMenuItem
35 // ----------------------------------------------------------------------------
36
37 //
38 // Helper Functions to get Mac Menus the way they should be ;-)
39 //
40
41 void 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
45 int wxMenuItem::MacBuildMenuString(StringPtr outMacItemText, SInt16 *outMacShortcutChar , UInt8 *outMacModifiers , const char *inItemText , bool useShortcuts )
46 {
47 char *p = (char *) &outMacItemText[1] ;
48 short macModifiers = 0 ;
49 SInt16 macShortCut = 0 ;
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 {
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 ;
93 bool skip = false ;
94 bool explicitCommandKey = false ;
95 while( *inItemName && !skip )
96 {
97 if (wxStrnicmp("Ctrl", inItemName, 4) == 0)
98 {
99 inItemName = inItemName + 5;
100 explicitCommandKey = true ;
101 }
102 else if (wxStrnicmp("Cntrl", inItemName, 5) == 0)
103 {
104 inItemName = inItemName + 6;
105 explicitCommandKey = true ;
106 }
107 else if (wxStrnicmp("Alt", inItemName, 3) == 0)
108 {
109 inItemName = inItemName + 4;
110 macModifiers |= kMenuOptionModifier ;
111 }
112 else if (wxStrnicmp("Shift", inItemName, 5) == 0)
113 {
114 inItemName = inItemName + 6;
115 macModifiers |= kMenuShiftModifier ;
116 }
117 else
118 {
119 skip = true ;
120 }
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" ) )
137 {
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 ;
153 }
154 }
155
156 inItemName += strlen( inItemName ) ;
157
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
178 // ctor & dtor
179 // -----------
180
181 wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
182 int id,
183 const wxString& text,
184 const wxString& strHelp,
185 wxItemKind kind,
186 wxMenu *pSubMenu)
187 : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
188 {
189 // VZ: what about translations?? (FIXME)
190 if ( m_text == "E&xit" ||m_text == "Exit" ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" )
191 {
192 m_text = "Quit\tCtrl+Q" ;
193 }
194 }
195
196 wxMenuItem::~wxMenuItem()
197 {
198 }
199
200 bool wxMenuItem::IsChecked() const
201 {
202 return wxMenuItemBase::IsChecked() ;
203 }
204
205 wxString wxMenuItem::GetLabel() const
206 {
207 return wxStripMenuCodes(m_text);
208 }
209
210 // accelerators
211 // ------------
212
213 #if wxUSE_ACCEL
214
215 wxAcceleratorEntry *wxMenuItem::GetAccel() const
216 {
217 return wxGetAccelFromString(GetText());
218 }
219
220 #endif // wxUSE_ACCEL
221
222 // misc
223 // ----
224
225 /*
226
227 // delete the sub menu
228 void wxMenuItem::DeleteSubMenu()
229 {
230 wxASSERT( m_subMenu != NULL );
231
232 delete m_subMenu;
233 m_subMenu = NULL;
234 }
235
236 */
237
238 // change item state
239 // -----------------
240
241 void wxMenuItem::Enable(bool bDoEnable)
242 {
243 if ( m_isEnabled != bDoEnable ) {
244 if ( m_subMenu == NULL )
245 {
246 // normal menu item
247 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
248 {
249 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
250 if ( index >= 1 )
251 {
252 if ( bDoEnable )
253 UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
254 else
255 UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
256 }
257 }
258 }
259 else
260 {
261 // submenu
262 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
263 {
264 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
265 if ( index >= 1 )
266 {
267 if ( bDoEnable )
268 UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
269 else
270 UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
271 }
272 }
273 }
274
275 m_isEnabled = bDoEnable;
276 }
277 }
278
279 void wxMenuItem::Check(bool bDoCheck)
280 {
281 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
282
283 if ( m_isChecked != bDoCheck )
284 {
285 m_isChecked = bDoCheck;
286 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
287 {
288 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
289 if ( index >= 1 )
290 {
291 if ( bDoCheck )
292 ::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0x12 ) ; // checkmark
293 else
294 ::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0 ) ; // no mark
295 }
296 }
297 }
298 }
299
300 void 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") );
310 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
311 {
312 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
313 if ( index >= 1 )
314 {
315 Str255 label;
316 MacBuildMenuString( label , NULL , NULL , text ,false);
317 ::SetMenuItemText( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , label ) ; // checkmark
318 }
319 }
320
321 #if wxUSE_ACCEL
322 m_parentMenu->UpdateAccel(this);
323 #endif // wxUSE_ACCEL
324
325 }
326 void wxMenuItem::SetCheckable(bool checkable)
327 {
328 wxMenuItemBase::SetCheckable(checkable);
329 // OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
330 }
331
332 // ----------------------------------------------------------------------------
333 // wxMenuItemBase
334 // ----------------------------------------------------------------------------
335
336 /* static */
337 wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
338 {
339 return wxStripMenuCodes(text);
340 }
341
342 wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
343 int id,
344 const wxString& name,
345 const wxString& help,
346 wxItemKind kind,
347 wxMenu *subMenu)
348 {
349 return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
350 }