Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/apps/app_menu_controller_mac.h" | 5 #import "chrome/browser/ui/cocoa/apps/app_menu_controller_mac.h" |
| 6 | 6 |
| 7 #include "apps/app_shim/extension_app_shim_handler_mac.h" | 7 #include "apps/app_shim/extension_app_shim_handler_mac.h" |
| 8 #include "apps/shell_window.h" | 8 #include "apps/shell_window.h" |
| 9 #include "apps/shell_window_registry.h" | 9 #include "apps/shell_window_registry.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h" | 12 #import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h" |
| 13 #include "chrome/common/extensions/extension.h" | 13 #include "chrome/common/extensions/extension.h" |
| 14 #include "grit/chromium_strings.h" | |
| 14 #include "grit/generated_resources.h" | 15 #include "grit/generated_resources.h" |
| 15 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
| 16 #include "ui/base/l10n/l10n_util_mac.h" | 17 #include "ui/base/l10n/l10n_util_mac.h" |
| 17 | 18 |
| 19 namespace { | |
| 20 | |
| 21 // Iterates through top level items in the main menu and returns the first one | |
| 22 // with the given title. | |
| 23 NSMenuItem* FindItemByTitle(const string16& title_utf16) { | |
|
tapted
2013/08/22 05:16:15
nit: base::string16
jackhou1
2013/08/29 04:25:21
Done.
| |
| 24 NSString* title = base::SysUTF16ToNSString(title_utf16); | |
| 25 for (NSMenuItem* menu in [[NSApp mainMenu] itemArray]) { | |
| 26 NSMenuItem* item = [[menu submenu] itemWithTitle:title]; | |
| 27 if (item) | |
| 28 return item; | |
| 29 } | |
| 30 return nil; | |
| 31 } | |
| 32 | |
| 33 // Creates a new NSMenuItem with the same title, action, and key equivalent as | |
| 34 // |original|. Also creates a submenu |original| had a submenu. | |
| 35 // The returned object is not released. | |
| 36 NSMenuItem* DuplicateItem(NSMenuItem* original) { | |
| 37 NSMenuItem* item = [[NSMenuItem alloc] | |
|
tapted
2013/08/22 05:16:15
should assign to a scoped_nsobject when using allo
jackhou1
2013/08/29 04:25:21
Done.
| |
| 38 initWithTitle:[original title] | |
| 39 action:[original action] | |
| 40 keyEquivalent:[original keyEquivalent]]; | |
| 41 if ([original hasSubmenu]) { | |
| 42 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] | |
| 43 initWithTitle:[[original submenu] title]]); | |
| 44 [item setSubmenu:menu]; | |
| 45 } | |
| 46 return item; | |
| 47 } | |
| 48 | |
| 49 // Finds an item using |message_id| and adds a duplicate of it to the submenu of | |
| 50 // |top_level_item|. | |
| 51 NSMenuItem* AddDuplicateItem(NSMenuItem* top_level_item, int message_id) { | |
| 52 NSMenu* menu = [top_level_item submenu]; | |
| 53 NSMenuItem* original = FindItemByTitle(l10n_util::GetStringUTF16(message_id)); | |
| 54 base::scoped_nsobject<NSMenuItem> item(DuplicateItem(original)); | |
|
tapted
2013/08/22 05:16:15
NSMenuItem implements the NSCopying protocol, so i
jackhou1
2013/08/29 04:25:21
Done.
| |
| 55 [menu addItem:item]; | |
| 56 return item; | |
| 57 } | |
| 58 | |
| 59 } // namespace | |
| 60 | |
| 18 @interface AppMenuController () | 61 @interface AppMenuController () |
| 19 // Construct the NSMenuItems for apps. | 62 // Construct the NSMenuItems for apps. |
| 20 - (void)buildAppMenuItems; | 63 - (void)buildAppMenuItems; |
| 21 // Register for NSWindow notifications. | 64 // Register for NSWindow notifications. |
| 22 - (void)registerEventHandlers; | 65 - (void)registerEventHandlers; |
| 23 // If the window is an app window, add or remove menu items. | 66 // If the window is an app window, add or remove menu items. |
| 24 - (void)windowMainStatusChanged:(NSNotification*)notification; | 67 - (void)windowMainStatusChanged:(NSNotification*)notification; |
| 25 // Add menu items for an app and hide Chrome menu items. | 68 // Add menu items for an app and hide Chrome menu items. |
| 26 - (void)addMenuItems:(const extensions::Extension*)app; | 69 - (void)addMenuItems:(const extensions::Extension*)app; |
| 27 // If the window belongs to the currently focused app, remove the menu items and | 70 // If the window belongs to the currently focused app, remove the menu items and |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 39 } | 82 } |
| 40 return self; | 83 return self; |
| 41 } | 84 } |
| 42 | 85 |
| 43 - (void)dealloc { | 86 - (void)dealloc { |
| 44 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 87 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 45 [super dealloc]; | 88 [super dealloc]; |
| 46 } | 89 } |
| 47 | 90 |
| 48 - (void)buildAppMenuItems { | 91 - (void)buildAppMenuItems { |
| 49 quitChromeItem_ = [[[[[NSApp mainMenu] itemAtIndex:0] submenu] itemArray] | 92 quitChromeItem_ = FindItemByTitle(l10n_util::GetStringFUTF16( |
| 50 lastObject]; | 93 IDS_EXIT_MAC, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
| 94 DCHECK(quitChromeItem_); | |
| 51 | 95 |
| 96 // The app's menu. | |
| 52 appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" | 97 appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" |
| 53 action:nil | 98 action:nil |
| 54 keyEquivalent:@""]); | 99 keyEquivalent:@""]); |
| 55 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); | 100 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); |
| 56 [appMenu setAutoenablesItems:NO]; | 101 [appMenu setAutoenablesItems:NO]; |
| 57 NSMenuItem* appQuitItem = [appMenu addItemWithTitle:@"" | 102 NSMenuItem* appQuitItem = [appMenu addItemWithTitle:@"" |
| 58 action:nil | 103 action:nil |
| 59 keyEquivalent:@""]; | 104 keyEquivalent:@""]; |
| 60 [appQuitItem setTarget:self]; | 105 [appQuitItem setTarget:self]; |
| 61 [appQuitItem setEnabled:YES]; | 106 [appQuitItem setEnabled:YES]; |
| 62 [appMenuItem_ setSubmenu:appMenu]; | 107 [appMenuItem_ setSubmenu:appMenu]; |
| 108 | |
| 109 // File menu. | |
| 110 fileMenuItem_.reset(DuplicateItem([[NSApp mainMenu] | |
| 111 itemWithTitle:l10n_util::GetNSString(IDS_FILE_MENU_MAC)])); | |
| 112 AddDuplicateItem(fileMenuItem_, IDS_CLOSE_WINDOW_MAC); | |
| 113 | |
| 114 // Edit menu. | |
| 115 editMenuItem_.reset(DuplicateItem([[NSApp mainMenu] | |
|
tapted
2013/08/22 05:16:15
NSMenu supports NSCopying as well.. and I'm thinki
jackhou1
2013/08/29 04:25:21
I'd rather keep the items minimal until we decide
| |
| 116 itemWithTitle:l10n_util::GetNSString(IDS_EDIT_MENU_MAC)])); | |
| 117 AddDuplicateItem(editMenuItem_, IDS_EDIT_UNDO_MAC); | |
| 118 AddDuplicateItem(editMenuItem_, IDS_EDIT_REDO_MAC); | |
| 119 [[editMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; | |
| 120 AddDuplicateItem(editMenuItem_, IDS_CUT_MAC); | |
| 121 AddDuplicateItem(editMenuItem_, IDS_COPY_MAC); | |
| 122 AddDuplicateItem(editMenuItem_, IDS_PASTE_MAC); | |
| 123 AddDuplicateItem(editMenuItem_, IDS_EDIT_DELETE_MAC); | |
| 124 AddDuplicateItem(editMenuItem_, IDS_EDIT_SELECT_ALL_MAC); | |
| 125 | |
| 126 // Window menu. | |
| 127 windowMenuItem_.reset(DuplicateItem([[NSApp mainMenu] | |
| 128 itemWithTitle:l10n_util::GetNSString(IDS_WINDOW_MENU_MAC)])); | |
| 129 AddDuplicateItem(windowMenuItem_, IDS_MINIMIZE_WINDOW_MAC); | |
| 130 AddDuplicateItem(windowMenuItem_, IDS_ZOOM_WINDOW_MAC); | |
| 131 [[windowMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; | |
| 132 AddDuplicateItem(windowMenuItem_, IDS_ALL_WINDOWS_FRONT_MAC); | |
| 63 } | 133 } |
| 64 | 134 |
| 65 - (void)registerEventHandlers { | 135 - (void)registerEventHandlers { |
| 66 [[NSNotificationCenter defaultCenter] | 136 [[NSNotificationCenter defaultCenter] |
| 67 addObserver:self | 137 addObserver:self |
| 68 selector:@selector(windowMainStatusChanged:) | 138 selector:@selector(windowMainStatusChanged:) |
| 69 name:NSWindowDidBecomeMainNotification | 139 name:NSWindowDidBecomeMainNotification |
| 70 object:nil]; | 140 object:nil]; |
| 71 | 141 |
| 72 [[NSNotificationCenter defaultCenter] | 142 [[NSNotificationCenter defaultCenter] |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 | 197 |
| 128 NSString* quit_localized_string = | 198 NSString* quit_localized_string = |
| 129 l10n_util::GetNSStringF(IDS_EXIT_MAC, base::UTF8ToUTF16(app->name())); | 199 l10n_util::GetNSStringF(IDS_EXIT_MAC, base::UTF8ToUTF16(app->name())); |
| 130 NSMenuItem* appQuitItem = [[[appMenuItem_ submenu] itemArray] lastObject]; | 200 NSMenuItem* appQuitItem = [[[appMenuItem_ submenu] itemArray] lastObject]; |
| 131 [appQuitItem setTitle:quit_localized_string]; | 201 [appQuitItem setTitle:quit_localized_string]; |
| 132 [appQuitItem setAction:[quitChromeItem_ action]]; | 202 [appQuitItem setAction:[quitChromeItem_ action]]; |
| 133 [appQuitItem setKeyEquivalent:[quitChromeItem_ keyEquivalent]]; | 203 [appQuitItem setKeyEquivalent:[quitChromeItem_ keyEquivalent]]; |
| 134 | 204 |
| 135 [appMenuItem_ setTitle:appId]; | 205 [appMenuItem_ setTitle:appId]; |
| 136 [[appMenuItem_ submenu] setTitle:title]; | 206 [[appMenuItem_ submenu] setTitle:title]; |
| 207 | |
| 137 [mainMenu addItem:appMenuItem_]; | 208 [mainMenu addItem:appMenuItem_]; |
| 209 [mainMenu addItem:fileMenuItem_]; | |
| 210 [mainMenu addItem:editMenuItem_]; | |
| 211 [mainMenu addItem:windowMenuItem_]; | |
| 138 } | 212 } |
| 139 | 213 |
| 140 - (void)removeMenuItems:(NSString*)appId { | 214 - (void)removeMenuItems:(NSString*)appId { |
| 141 if (![appId_ isEqualToString:appId]) | 215 if (![appId_ isEqualToString:appId]) |
| 142 return; | 216 return; |
| 143 | 217 |
| 218 // Remove menu items for packaged app. | |
| 144 appId_.reset(); | 219 appId_.reset(); |
| 145 | 220 |
| 146 NSMenu* mainMenu = [NSApp mainMenu]; | 221 NSMenu* mainMenu = [NSApp mainMenu]; |
| 147 [mainMenu removeItem:appMenuItem_]; | 222 [mainMenu removeItem:appMenuItem_]; |
| 223 [mainMenu removeItem:fileMenuItem_]; | |
| 224 [mainMenu removeItem:editMenuItem_]; | |
| 225 [mainMenu removeItem:windowMenuItem_]; | |
| 148 | 226 |
| 149 // Restore the Chrome main menu bar. | 227 // Restore the Chrome main menu bar. |
| 150 for (NSMenuItem* item in [mainMenu itemArray]) | 228 for (NSMenuItem* item in [mainMenu itemArray]) |
| 151 [item setHidden:NO]; | 229 [item setHidden:NO]; |
| 152 | 230 |
| 153 [quitChromeItem_ setAction:@selector(terminate:)]; | 231 [quitChromeItem_ setAction:@selector(terminate:)]; |
| 154 } | 232 } |
| 155 | 233 |
| 156 // If the currently focused window belongs to a platform app, quit the app. | 234 // If the currently focused window belongs to a platform app, quit the app. |
| 157 - (void)quitCurrentPlatformApp { | 235 - (void)quitCurrentPlatformApp { |
| 158 apps::ShellWindow* shellWindow = | 236 apps::ShellWindow* shellWindow = |
| 159 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile( | 237 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile( |
| 160 [NSApp keyWindow]); | 238 [NSApp keyWindow]); |
| 161 if (shellWindow) | 239 if (shellWindow) |
| 162 apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow); | 240 apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow); |
| 163 } | 241 } |
| 164 | 242 |
| 165 @end | 243 @end |
| OLD | NEW |