]> git.saurik.com Git - wxWidgets.git/blame - src/mac/menuitem.cpp
several mac fixes (Mark Newsams patches)
[wxWidgets.git] / src / mac / 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
519cb848 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 ;
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
e9576ca5
SC
175// ctor & dtor
176// -----------
177
178wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
e7549107 179 const wxString& text, const wxString& strHelp,
e9576ca5 180 bool bCheckable,
e7549107 181 wxMenu *pSubMenu)
e9576ca5 182{
e7549107 183 wxASSERT( pParentMenu != NULL );
e9576ca5 184
e7549107
SC
185 m_parentMenu = pParentMenu;
186 m_subMenu = pSubMenu;
187 m_isEnabled = TRUE;
188 m_isChecked = FALSE;
189 m_id = id;
190 m_text = text;
191 m_isCheckable = bCheckable;
192 m_help = strHelp;
519cb848 193
e7549107
SC
194
195 if ( m_text == "E&xit" ||m_text == "Exit" )
196 {
197 m_text = "Quit\tCtrl+Q" ;
198 }
e9576ca5
SC
199}
200
201wxMenuItem::~wxMenuItem()
202{
203}
204
51abe921
SC
205bool wxMenuItem::IsChecked() const
206{
207 return wxMenuItemBase::IsChecked() ;
208}
209
210wxString wxMenuItem::GetLabel() const
211{
212 return wxStripMenuCodes(m_text);
213}
214
215// accelerators
216// ------------
217
218#if wxUSE_ACCEL
219
220wxAcceleratorEntry *wxMenuItem::GetAccel() const
221{
222 return wxGetAccelFromString(GetText());
223}
224
225#endif // wxUSE_ACCEL
226
e9576ca5
SC
227// misc
228// ----
229
e7549107
SC
230/*
231
e9576ca5
SC
232// delete the sub menu
233void wxMenuItem::DeleteSubMenu()
234{
e7549107 235 wxASSERT( m_subMenu != NULL );
e9576ca5 236
e7549107
SC
237 delete m_subMenu;
238 m_subMenu = NULL;
e9576ca5
SC
239}
240
e7549107
SC
241*/
242
e9576ca5
SC
243// change item state
244// -----------------
245
246void wxMenuItem::Enable(bool bDoEnable)
247{
e7549107
SC
248 if ( m_isEnabled != bDoEnable ) {
249 if ( m_subMenu == NULL )
519cb848
SC
250 {
251 // normal menu item
e7549107 252 if ( m_parentMenu->GetHMenu() )
519cb848 253 {
e7549107 254 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
519cb848
SC
255 if ( index >= 1 )
256 {
257 if ( bDoEnable )
e7549107 258 UMAEnableMenuItem( m_parentMenu->GetHMenu() , index ) ;
519cb848 259 else
e7549107 260 UMADisableMenuItem( m_parentMenu->GetHMenu() , index ) ;
519cb848
SC
261 }
262 }
e9576ca5 263 }
519cb848 264 else
e9576ca5 265 {
519cb848 266 // submenu
e7549107 267 if ( m_parentMenu->GetHMenu() )
519cb848 268 {
e7549107 269 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
519cb848
SC
270 if ( index >= 1 )
271 {
272 if ( bDoEnable )
e7549107 273 UMAEnableMenuItem( m_parentMenu->GetHMenu() , index ) ;
519cb848 274 else
e7549107 275 UMADisableMenuItem( m_parentMenu->GetHMenu() , index ) ;
519cb848
SC
276 }
277 }
e9576ca5
SC
278 }
279
e7549107 280 m_isEnabled = bDoEnable;
e9576ca5
SC
281 }
282}
283
284void wxMenuItem::Check(bool bDoCheck)
285{
286 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
287
e7549107 288 if ( m_isChecked != bDoCheck )
519cb848 289 {
e7549107
SC
290 m_isChecked = bDoCheck;
291 if ( m_parentMenu->GetHMenu() )
519cb848 292 {
e7549107 293 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
519cb848
SC
294 if ( index >= 1 )
295 {
296 if ( bDoCheck )
e7549107 297 ::SetItemMark( m_parentMenu->GetHMenu() , index , 0x12 ) ; // checkmark
519cb848 298 else
e7549107 299 ::SetItemMark( m_parentMenu->GetHMenu() , index , 0 ) ; // no mark
519cb848
SC
300 }
301 }
e9576ca5 302 }
51abe921
SC
303}
304
305void wxMenuItem::SetText(const wxString& text)
306{
307 // don't do anything if label didn't change
308 if ( m_text == text )
309 return;
310
311 wxMenuItemBase::SetText(text);
312// OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
313
314 wxCHECK_RET( m_parentMenu && m_parentMenu->GetHMenu(), wxT("menuitem without menu") );
315 if ( m_parentMenu->GetHMenu() )
316 {
317 int index = m_parentMenu->MacGetIndexFromItem( this ) ;
318 if ( index >= 1 )
319 {
320 Str255 label;
2f1ae414
SC
321 MacBuildMenuString( label , NULL , NULL , text ,false);
322 UMASetMenuItemText( m_parentMenu->GetHMenu() , index , label ) ; // checkmark
51abe921
SC
323 }
324 }
325
326#if wxUSE_ACCEL
327 m_parentMenu->UpdateAccel(this);
328#endif // wxUSE_ACCEL
329
330}
331void wxMenuItem::SetCheckable(bool checkable)
332{
333 wxMenuItemBase::SetCheckable(checkable);
334 // OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
335}
336
337// ----------------------------------------------------------------------------
338// wxMenuItemBase
339// ----------------------------------------------------------------------------
340
2f1ae414
SC
341/* static */
342wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
343{
344 return wxStripMenuCodes(text);
345}
346
51abe921
SC
347wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
348 int id,
349 const wxString& name,
350 const wxString& help,
351 bool isCheckable,
352 wxMenu *subMenu)
353{
354 return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
355}