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