Silence the warning about lack of [NSApplication +setAppleMenu:]
[wxWidgets.git] / src / cocoa / mbarman.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        cocoa/mbarman.cpp
3 // Purpose:     wxMenuBarManager implementation
4 // Author:      David Elliott
5 // Modified by:
6 // Created:     2003/09/04
7 // RCS-ID:      $Id$
8 // Copyright:   (c) 2003 David Elliott
9 // Licence:     wxWidgets licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13 #if wxUSE_MENUS
14 #ifndef WX_PRECOMP
15     #include "wx/log.h"
16     #include "wx/app.h"
17     #include "wx/menu.h"
18     #include "wx/toplevel.h"
19 #endif // WX_PRECOMP
20
21 #include "wx/cocoa/mbarman.h"
22 #include "wx/cocoa/autorelease.h"
23
24 #import <Foundation/NSString.h>
25 #import <Foundation/NSNotification.h>
26 #import <AppKit/NSMenu.h>
27 #import <AppKit/NSApplication.h>
28 #import <AppKit/NSWindow.h>
29
30 // Declare setAppleMenu: in an NSApplication category since Tiger and later
31 // releases support it but don't declare it as it's considered deprecated.
32 @interface NSApplication(wxDeprecatedMethodsWeWantToUse)
33 - (void)setAppleMenu:(NSMenu *)menu;
34 @end
35
36 // ============================================================================
37 // wxMenuBarManagerObserver
38 // ============================================================================
39 @interface wxMenuBarManagerObserver : NSObject
40 {
41     wxMenuBarManager *m_mbarman;
42 }
43
44 - (id)init;
45 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman;
46 - (void)windowDidBecomeKey: (NSNotification *)notification;
47 #if 0
48 - (void)windowDidResignKey: (NSNotification *)notification;
49 - (void)windowDidBecomeMain: (NSNotification *)notification;
50 - (void)windowDidResignMain: (NSNotification *)notification;
51 - (void)windowWillClose: (NSNotification *)notification;
52 #endif // 0
53 @end // interface wxMenuBarManagerObserver : NSObject
54
55 @implementation wxMenuBarManagerObserver : NSObject
56 - (id)init
57 {
58     wxFAIL_MSG(wxT("[wxMenuBarManagerObserver -init] should never be called!"));
59     m_mbarman = NULL;
60     return self;
61 }
62
63 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman
64 {
65     wxASSERT(mbarman);
66     m_mbarman = mbarman;
67     return [super init];
68 }
69
70 - (void)windowDidBecomeKey: (NSNotification *)notification
71 {
72     wxASSERT(m_mbarman);
73     m_mbarman->WindowDidBecomeKey(notification);
74 }
75
76 #if 0
77 - (void)windowDidResignKey: (NSNotification *)notification
78 {
79     wxASSERT(m_mbarman);
80     m_mbarman->WindowDidResignKey(notification);
81 }
82
83 - (void)windowDidBecomeMain: (NSNotification *)notification
84 {
85     wxASSERT(m_mbarman);
86     m_mbarman->WindowDidBecomeMain(notification);
87 }
88
89 - (void)windowDidResignMain: (NSNotification *)notification
90 {
91     wxASSERT(m_mbarman);
92     m_mbarman->WindowDidResignMain(notification);
93 }
94
95 - (void)windowWillClose: (NSNotification *)notification
96 {
97     wxASSERT(m_mbarman);
98     m_mbarman->WindowWillClose(notification);
99 }
100 #endif // 0
101
102 @end // implementation wxMenuBarManagerObserver : NSObject
103
104 // ============================================================================
105 // wxMenuBarManager
106 // ============================================================================
107 wxMenuBarManager *wxMenuBarManager::sm_mbarmanInstance = NULL;
108
109 wxMenuBarManager::wxMenuBarManager()
110 {
111     m_observer = [[wxMenuBarManagerObserver alloc]
112             initWithWxMenuBarManager:this];
113     [[NSNotificationCenter defaultCenter] addObserver:m_observer
114             selector:@selector(windowDidBecomeKey:)
115             name:NSWindowDidBecomeKeyNotification object:nil];
116 #if 0
117     [[NSNotificationCenter defaultCenter] addObserver:m_observer
118             selector:@selector(windowDidResignKey:)
119             name:NSWindowDidResignKeyNotification object:nil];
120     [[NSNotificationCenter defaultCenter] addObserver:m_observer
121             selector:@selector(windowDidBecomeMain:)
122             name:NSWindowDidBecomeMainNotification object:nil];
123     [[NSNotificationCenter defaultCenter] addObserver:m_observer
124             selector:@selector(windowDidResignMain:)
125             name:NSWindowDidResignMainNotification object:nil];
126     [[NSNotificationCenter defaultCenter] addObserver:m_observer
127             selector:@selector(windowWillClose:)
128             name:NSWindowWillCloseNotification object:nil];
129 #endif // 0
130     m_menuApp = nil;
131     m_menuServices = nil;
132     m_menuWindows = nil;
133     m_menuMain = nil;
134     m_mainMenuBarInstalled = true;
135     m_mainMenuBar = NULL;
136     m_currentNSWindow = nil;
137
138     NSApplication *theNSApplication = wxTheApp->GetNSApplication();
139     // Create the services menu.
140     m_menuServices = [[NSMenu alloc] initWithTitle: @"Services"];
141     [theNSApplication setServicesMenu:m_menuServices];
142
143     NSMenuItem *menuitem;
144     // Create the application (Apple) menu.
145     m_menuApp = [[NSMenu alloc] initWithTitle: @"Apple Menu"];
146
147 /**/[m_menuApp addItemWithTitle:@"Preferences..." action:nil keyEquivalent:@""];
148 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
149 /**/menuitem = [[NSMenuItem alloc] initWithTitle: @"Services" action:nil keyEquivalent:@""];
150     [menuitem setSubmenu:m_menuServices];
151     [m_menuApp addItem: menuitem];
152     [menuitem release];
153 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
154 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@""];
155     [menuitem setTarget: theNSApplication];
156     [m_menuApp addItem: menuitem];
157     [menuitem release];
158 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@""];
159     [menuitem setTarget: theNSApplication];
160     [m_menuApp addItem: menuitem];
161     [menuitem release];
162 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
163     [menuitem setTarget: theNSApplication];
164     [m_menuApp addItem: menuitem];
165     [menuitem release];
166 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
167 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
168     [menuitem setTarget: theNSApplication];
169     [m_menuApp addItem: menuitem];
170     [menuitem release];
171
172     [theNSApplication setAppleMenu:m_menuApp];
173
174     // Create the Windows menu
175     m_menuWindows = [[NSMenu alloc] initWithTitle: @"Window"];
176
177 /**/[m_menuWindows addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@""];
178 /**/[m_menuWindows addItem: [NSMenuItem separatorItem]];
179 /**/[m_menuWindows addItemWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""];
180
181     [theNSApplication setWindowsMenu:m_menuWindows];
182
183     // Create the main menubar
184     m_menuMain = [[NSMenu alloc] initWithTitle: @"wxApp Menu"];
185 /**/NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@"App menu"
186         /* Note: title gets clobbered by app name anyway */
187         action:nil keyEquivalent:@""];
188     [dummyItem setSubmenu:m_menuApp];
189     [m_menuMain addItem:dummyItem];
190     [dummyItem release];
191 /**/dummyItem = [[NSMenuItem alloc] initWithTitle:@"Window"
192         action:nil keyEquivalent:@""];
193     [dummyItem setSubmenu:m_menuWindows];
194     [m_menuMain addItem:dummyItem];
195     [dummyItem release];
196
197     [theNSApplication setMainMenu: m_menuMain];
198
199 }
200
201 wxMenuBarManager::~wxMenuBarManager()
202 {
203     [m_observer release];
204 }
205
206 void wxMenuBarManager::CreateInstance()
207 {
208     sm_mbarmanInstance = new wxMenuBarManager;
209 }
210
211 void wxMenuBarManager::DestroyInstance()
212 {
213     delete sm_mbarmanInstance;
214     sm_mbarmanInstance = NULL;
215 }
216
217 void wxMenuBarManager::SetMenuBar(wxMenuBar* menubar)
218 {
219     m_mainMenuBarInstalled = false;
220     if(menubar)
221     {
222         [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
223         [[menubar->GetNSMenu() itemAtIndex:0] setSubmenu:m_menuApp];
224         [wxTheApp->GetNSApplication() setMainMenu:menubar->GetNSMenu()];
225     }
226     else
227         InstallMainMenu();
228 }
229
230 void wxMenuBarManager::SetMainMenuBar(wxMenuBar* menubar)
231 {
232     m_mainMenuBar = menubar;
233     if(m_mainMenuBarInstalled)
234         InstallMainMenu();
235 }
236
237 void wxMenuBarManager::InstallMainMenu()
238 {
239     if(m_mainMenuBar)
240         SetMenuBar(m_mainMenuBar);
241     else
242     {
243         m_mainMenuBarInstalled = true;
244         [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
245         [[m_menuMain itemAtIndex:0] setSubmenu:m_menuApp];
246         [wxTheApp->GetNSApplication() setMainMenu:m_menuMain];
247     }
248 }
249
250 void wxMenuBarManager::WindowDidBecomeKey(NSNotification *notification)
251 {
252     /* NOTE: m_currentNSWindow might be destroyed but we only ever use it
253        to look it up in the hash table.  Do not send messages to it. */
254     m_currentNSWindow = [notification object];
255     wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
256     if(win)
257         InstallMenuBarForWindow(win);
258     else
259         SetMenuBar(NULL);
260 }
261
262 #if 0
263 void wxMenuBarManager::WindowDidResignKey(NSNotification *notification)
264 {
265 }
266
267 void wxMenuBarManager::WindowDidBecomeMain(NSNotification *notification)
268 {
269 }
270
271 void wxMenuBarManager::WindowDidResignMain(NSNotification *notification)
272 {
273 }
274
275 void wxMenuBarManager::WindowWillClose(NSNotification *notification)
276 {
277 }
278 #endif // 0
279
280 void wxMenuBarManager::InstallMenuBarForWindow(wxCocoaNSWindow *win)
281 {
282     wxASSERT(win);
283     wxMenuBar *menubar = win->GetAppMenuBar(win);
284     wxLogTrace(wxTRACE_COCOA,wxT("Found menubar=%p for window=%p."),menubar,win);
285     SetMenuBar(menubar);
286 }
287
288 void wxMenuBarManager::UpdateMenuBar()
289 {
290     if(m_currentNSWindow)
291     {
292         wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
293         if(win)
294             InstallMenuBarForWindow(win);
295     }
296 }
297
298 #endif // wxUSE_MENUS