]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/menuitem.cpp
added new implementation for editable and brought selection behaviour in synch
[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 char 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 // special characters for macintosh menus -> use some replacement
76 case ';' :
77 *p++ = ',' ;
78 break ;
79 case '^' :
80 *p++ = ' ' ;
81 break ;
82 case '!' :
83 *p++ = ' ' ;
84 break ;
85 case '<' :
86 *p++ = '[' ;
87 break ;
88 case '>' :
89 *p++ = ']' ;
90 break ;
91 case '/' :
92 *p++ = '|' ;
93 break ;
94 case '(' :
95 *p++ = '[' ;
96 break ;
97 case ')' :
98 *p++ = ']' ;
99 break ;
100 // shortcuts
101 case '&' :
102 {
103 ++inItemName ;
104 if ( *inItemName )
105 {
106 *p++ = *inItemName ;
107 if ( useShortcuts )
108 macShortCut = *inItemName ;
109 }
110 else
111 --inItemName ;
112 }
113 break ;
114 // win-like accelerators
115 case '\t' :
116 {
117 ++inItemName ;
118 while( *inItemName )
119 {
120 if (strncmp("Ctrl", inItemName, 4) == 0)
121 {
122 inItemName = inItemName + 5;
123 macShortCut = *inItemName;
124 }
125 else if (strncmp("Cntrl", inItemName, 5) == 0)
126 {
127 inItemName = inItemName + 6;
128 macShortCut = *inItemName;
129 }
130 else if (strncmp("Alt", inItemName, 3) == 0)
131 {
132 inItemName = inItemName + 4;
133 macModifiers |= kMenuOptionModifier ;
134 macShortCut = *inItemName ;
135 }
136 else if (strncmp("Shift", inItemName, 5) == 0)
137 {
138 inItemName = inItemName + 6;
139 macModifiers |= kMenuShiftModifier ;
140 macShortCut = *inItemName ;
141 }
142 else if (strncmp("F", inItemName, 1) == 0)
143 {
144 inItemName += strlen( inItemName ) ;
145 // no function keys at the moment
146 // macModifiers |= kMenuShiftModifier ;
147 // macShortCut = *inItemName ;
148 }
149 else
150 {
151 break ;
152 }
153 }
154
155 if ( *inItemName == 0 )
156 --inItemName ;
157
158 }
159 break ;
160 default :
161 *p++ = *inItemName ;
162 }
163 ++inItemName ;
164 }
165
166 outMacItemText[0] = (p - (char *)outMacItemText) - 1;
167 if ( outMacShortcutChar )
168 *outMacShortcutChar = macShortCut ;
169 if ( outMacModifiers )
170 *outMacModifiers = macModifiers ;
171
172 return 0 ;
173 }
174
175 // ctor & dtor
176 // -----------
177
178 wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
179 int id,
180 const wxString& text,
181 const wxString& strHelp,
182 wxItemKind kind,
183 wxMenu *pSubMenu)
184 : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
185 {
186 // VZ: what about translations?? (FIXME)
187 if ( m_text == "E&xit" ||m_text == "Exit" ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" )
188 {
189 m_text = "Quit\tCtrl+Q" ;
190 }
191 }
192
193 wxMenuItem::~wxMenuItem()
194 {
195 }
196
197 bool wxMenuItem::IsChecked() const
198 {
199 return wxMenuItemBase::IsChecked() ;
200 }
201
202 wxString wxMenuItem::GetLabel() const
203 {
204 return wxStripMenuCodes(m_text);
205 }
206
207 // accelerators
208 // ------------
209
210 #if wxUSE_ACCEL
211
212 wxAcceleratorEntry *wxMenuItem::GetAccel() const
213 {
214 return wxGetAccelFromString(GetText());
215 }
216
217 #endif // wxUSE_ACCEL
218
219 // misc
220 // ----
221
222 /*
223
224 // delete the sub menu
225 void wxMenuItem::DeleteSubMenu()
226 {
227 wxASSERT( m_subMenu != NULL );
228
229 delete m_subMenu;
230 m_subMenu = NULL;
231 }
232
233 */
234
235 // change item state
236 // -----------------
237
238 void wxMenuItem::Enable(bool bDoEnable)
239 {
240 if ( m_isEnabled != bDoEnable ) {
241 if ( m_subMenu == NULL )
242 {
243 // normal menu item
244 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
245 {
246 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
247 if ( index >= 1 )
248 {
249 if ( bDoEnable )
250 UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
251 else
252 UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
253 }
254 }
255 }
256 else
257 {
258 // submenu
259 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
260 {
261 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
262 if ( index >= 1 )
263 {
264 if ( bDoEnable )
265 UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
266 else
267 UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
268 }
269 }
270 }
271
272 m_isEnabled = bDoEnable;
273 }
274 }
275
276 void wxMenuItem::Check(bool bDoCheck)
277 {
278 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
279
280 if ( m_isChecked != bDoCheck )
281 {
282 m_isChecked = bDoCheck;
283 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
284 {
285 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
286 if ( index >= 1 )
287 {
288 if ( bDoCheck )
289 ::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0x12 ) ; // checkmark
290 else
291 ::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0 ) ; // no mark
292 }
293 }
294 }
295 }
296
297 void wxMenuItem::SetText(const wxString& text)
298 {
299 // don't do anything if label didn't change
300 if ( m_text == text )
301 return;
302
303 wxMenuItemBase::SetText(text);
304 // OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
305
306 wxCHECK_RET( m_parentMenu && m_parentMenu->GetHMenu(), wxT("menuitem without menu") );
307 if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
308 {
309 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
310 if ( index >= 1 )
311 {
312 Str255 label;
313 MacBuildMenuString( label , NULL , NULL , text ,false);
314 ::SetMenuItemText( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , label ) ; // checkmark
315 }
316 }
317
318 #if wxUSE_ACCEL
319 m_parentMenu->UpdateAccel(this);
320 #endif // wxUSE_ACCEL
321
322 }
323 void wxMenuItem::SetCheckable(bool checkable)
324 {
325 wxMenuItemBase::SetCheckable(checkable);
326 // OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
327 }
328
329 // ----------------------------------------------------------------------------
330 // wxMenuItemBase
331 // ----------------------------------------------------------------------------
332
333 /* static */
334 wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
335 {
336 return wxStripMenuCodes(text);
337 }
338
339 wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
340 int id,
341 const wxString& name,
342 const wxString& help,
343 wxItemKind kind,
344 wxMenu *subMenu)
345 {
346 return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
347 }