OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <AppKit/AppKit.h> | 5 #import <AppKit/AppKit.h> |
6 | 6 |
7 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h" | |
8 | |
9 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
10 #include "chrome/app/chrome_command_ids.h" | 8 #include "chrome/app/chrome_command_ids.h" |
11 #import "chrome/browser/app_controller_mac.h" | 9 #import "chrome/browser/app_controller_mac.h" |
12 #include "chrome/browser/bookmarks/bookmark_model.h" | 10 #include "chrome/browser/bookmarks/bookmark_model.h" |
13 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/profiles/profile_manager.h" | 12 #include "chrome/browser/profiles/profile_manager.h" |
15 #include "chrome/browser/ui/browser_list.h" | 13 #include "chrome/browser/ui/browser_list.h" |
| 14 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h" |
16 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h" | 15 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h" |
17 #include "grit/generated_resources.h" | 16 #include "grit/generated_resources.h" |
18 #include "grit/theme_resources.h" | 17 #include "grit/theme_resources.h" |
19 #include "skia/ext/skia_utils_mac.h" | 18 #include "skia/ext/skia_utils_mac.h" |
20 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
21 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
22 #include "ui/gfx/image/image.h" | 21 #include "ui/gfx/image/image.h" |
23 #include "ui/gfx/mac/nsimage_cache.h" | 22 #include "ui/gfx/mac/nsimage_cache.h" |
24 | 23 |
25 BookmarkMenuBridge::BookmarkMenuBridge(Profile* profile, | 24 BookmarkMenuBridge::BookmarkMenuBridge(Profile* profile, |
26 NSMenu *menu) | 25 NSMenu *menu) |
27 : menu_is_valid_(false), | 26 : menuIsValid_(false), |
28 root_node_(NULL), | |
29 off_the_side_node_start_index_(0), | |
30 profile_(profile), | 27 profile_(profile), |
31 controller_([[BookmarkMenuCocoaController alloc] initWithBridge:this | 28 controller_([[BookmarkMenuCocoaController alloc] initWithBridge:this |
32 andMenu:menu]) { | 29 andMenu:menu]) { |
33 if (GetBookmarkModel()) | |
34 ObserveBookmarkModel(); | |
35 } | |
36 | |
37 BookmarkMenuBridge::BookmarkMenuBridge(const BookmarkNode* root_node, | |
38 Profile* profile, | |
39 NSMenu* menu) | |
40 : menu_is_valid_(false), | |
41 root_node_(root_node), | |
42 off_the_side_node_start_index_(0), | |
43 profile_(profile), | |
44 controller_([[BookmarkMenuCocoaController alloc] initWithBridge:this | |
45 andMenu:menu]) { | |
46 if (GetBookmarkModel()) | 30 if (GetBookmarkModel()) |
47 ObserveBookmarkModel(); | 31 ObserveBookmarkModel(); |
48 } | 32 } |
49 | 33 |
50 BookmarkMenuBridge::~BookmarkMenuBridge() { | 34 BookmarkMenuBridge::~BookmarkMenuBridge() { |
51 BookmarkModel *model = GetBookmarkModel(); | 35 BookmarkModel *model = GetBookmarkModel(); |
52 if (model) | 36 if (model) |
53 model->RemoveObserver(this); | 37 model->RemoveObserver(this); |
| 38 [controller_ release]; |
54 } | 39 } |
55 | 40 |
56 NSMenu* BookmarkMenuBridge::BookmarkMenu() { | 41 NSMenu* BookmarkMenuBridge::BookmarkMenu() { |
57 return [controller_ menu]; | 42 return [controller_ menu]; |
58 } | 43 } |
59 | 44 |
60 void BookmarkMenuBridge::Loaded(BookmarkModel* model, bool ids_reassigned) { | 45 void BookmarkMenuBridge::Loaded(BookmarkModel* model, bool ids_reassigned) { |
61 InvalidateMenu(); | 46 InvalidateMenu(); |
62 } | 47 } |
63 | 48 |
64 void BookmarkMenuBridge::UpdateMenu(NSMenu* bookmark_menu) { | 49 void BookmarkMenuBridge::UpdateMenu(NSMenu* bookmark_menu) { |
65 UpdateMenuInternal(bookmark_menu, false); | 50 UpdateMenuInternal(bookmark_menu, false); |
66 } | 51 } |
67 | 52 |
68 void BookmarkMenuBridge::UpdateSubMenu(NSMenu* bookmark_menu) { | 53 void BookmarkMenuBridge::UpdateSubMenu(NSMenu* bookmark_menu) { |
69 UpdateMenuInternal(bookmark_menu, true); | 54 UpdateMenuInternal(bookmark_menu, true); |
70 } | 55 } |
71 | 56 |
72 void BookmarkMenuBridge::UpdateMenuInternal(NSMenu* bookmark_menu, | 57 void BookmarkMenuBridge::UpdateMenuInternal(NSMenu* bookmark_menu, |
73 bool is_submenu) { | 58 bool is_submenu) { |
74 DCHECK(bookmark_menu); | 59 DCHECK(bookmark_menu); |
75 if (menu_is_valid_) | 60 if (menuIsValid_) |
76 return; | 61 return; |
77 BookmarkModel* model = GetBookmarkModel(); | 62 BookmarkModel* model = GetBookmarkModel(); |
78 if (!model || !model->IsLoaded()) | 63 if (!model || !model->IsLoaded()) |
79 return; | 64 return; |
80 | 65 |
81 if (!folder_image_) { | 66 if (!folder_image_) { |
82 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 67 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
83 folder_image_.reset( | 68 folder_image_.reset( |
84 [rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER) retain]); | 69 [rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER) retain]); |
85 } | 70 } |
86 | 71 |
87 ClearBookmarkMenu(bookmark_menu); | 72 ClearBookmarkMenu(bookmark_menu); |
88 | 73 |
89 if (!root_node_) { | 74 // Add bookmark bar items, if any. |
90 // Add bookmark bar items, if any. | 75 const BookmarkNode* barNode = model->bookmark_bar_node(); |
91 const BookmarkNode* bar_node = model->bookmark_bar_node(); | 76 CHECK(barNode); |
92 CHECK(bar_node); | 77 if (!barNode->empty()) { |
93 if (!bar_node->empty()) { | 78 [bookmark_menu addItem:[NSMenuItem separatorItem]]; |
94 [bookmark_menu addItem:[NSMenuItem separatorItem]]; | 79 AddNodeToMenu(barNode, bookmark_menu, !is_submenu); |
95 AddNodeToMenu(bar_node, bookmark_menu, !is_submenu); | |
96 } | |
97 | |
98 // If the "Other Bookmarks" folder has any content, make a submenu for it | |
99 // and fill it in. | |
100 if (!model->other_node()->empty()) { | |
101 NSString* other_items_title = | |
102 l10n_util::GetNSString(IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME); | |
103 [bookmark_menu addItem:[NSMenuItem separatorItem]]; | |
104 AddNodeAsSubmenu(bookmark_menu, | |
105 model->other_node(), | |
106 other_items_title, | |
107 !is_submenu); | |
108 } | |
109 } else { | |
110 AddNodeToMenu(root_node_, bookmark_menu, false); | |
111 } | 80 } |
112 | 81 |
113 menu_is_valid_ = true; | 82 // If the "Other Bookmarks" folder has any content, make a submenu for it and |
| 83 // fill it in. |
| 84 if (!model->other_node()->empty()) { |
| 85 NSString* other_items_title = |
| 86 l10n_util::GetNSString(IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME); |
| 87 [bookmark_menu addItem:[NSMenuItem separatorItem]]; |
| 88 AddNodeAsSubmenu(bookmark_menu, |
| 89 model->other_node(), |
| 90 other_items_title, |
| 91 !is_submenu); |
| 92 } |
| 93 |
| 94 menuIsValid_ = true; |
114 } | 95 } |
115 | 96 |
116 void BookmarkMenuBridge::BookmarkModelBeingDeleted(BookmarkModel* model) { | 97 void BookmarkMenuBridge::BookmarkModelBeingDeleted(BookmarkModel* model) { |
117 NSMenu* bookmark_menu = BookmarkMenu(); | 98 NSMenu* bookmark_menu = BookmarkMenu(); |
118 if (bookmark_menu == nil) | 99 if (bookmark_menu == nil) |
119 return; | 100 return; |
120 | 101 |
121 ClearBookmarkMenu(bookmark_menu); | 102 ClearBookmarkMenu(bookmark_menu); |
122 } | 103 } |
123 | 104 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 action:nil | 202 action:nil |
222 keyEquivalent:@""] autorelease]; | 203 keyEquivalent:@""] autorelease]; |
223 [items setImage:folder_image_]; | 204 [items setImage:folder_image_]; |
224 [menu addItem:items]; | 205 [menu addItem:items]; |
225 NSMenu* other_submenu = [[[NSMenu alloc] initWithTitle:title] | 206 NSMenu* other_submenu = [[[NSMenu alloc] initWithTitle:title] |
226 autorelease]; | 207 autorelease]; |
227 [menu setSubmenu:other_submenu forItem:items]; | 208 [menu setSubmenu:other_submenu forItem:items]; |
228 AddNodeToMenu(node, other_submenu, add_extra_items); | 209 AddNodeToMenu(node, other_submenu, add_extra_items); |
229 } | 210 } |
230 | 211 |
231 void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, | 212 // TODO(jrg): limit the number of bookmarks in the menubar? |
232 NSMenu* menu, | 213 void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, NSMenu* menu, |
233 bool add_extra_items) { | 214 bool add_extra_items) { |
234 AddNodeToMenuRecursive(node, menu, add_extra_items, 0); | |
235 } | |
236 | |
237 void BookmarkMenuBridge::AddNodeToMenuRecursive(const BookmarkNode* node, | |
238 NSMenu* menu, | |
239 bool add_extra_items, | |
240 int recursion_depth) { | |
241 int child_count = node->child_count(); | 215 int child_count = node->child_count(); |
242 if (!child_count) { | 216 if (!child_count) { |
243 NSString* empty_string = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU); | 217 NSString* empty_string = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU); |
244 NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:empty_string | 218 NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:empty_string |
245 action:nil | 219 action:nil |
246 keyEquivalent:@""] autorelease]; | 220 keyEquivalent:@""] autorelease]; |
247 [menu addItem:item]; | 221 [menu addItem:item]; |
248 } else { | 222 } else for (int i = 0; i < child_count; i++) { |
249 // If this is the first recursive pass, start adding children from the | 223 const BookmarkNode* child = node->GetChild(i); |
250 // start index, which defaults to 0. | 224 NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child]; |
251 const int start = recursion_depth == 0 ? off_the_side_node_start_index_ : 0; | 225 NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title |
252 for (int i = start; i < child_count; i++) { | 226 action:nil |
253 const BookmarkNode* child = node->GetChild(i); | 227 keyEquivalent:@""] autorelease]; |
254 NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child]; | 228 [menu addItem:item]; |
255 NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title | 229 bookmark_nodes_[child] = item; |
256 action:nil | 230 if (child->is_folder()) { |
257 keyEquivalent:@""] autorelease]; | 231 [item setImage:folder_image_]; |
258 [menu addItem:item]; | 232 NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease]; |
259 bookmark_nodes_[child] = item; | 233 [menu setSubmenu:submenu forItem:item]; |
260 if (child->is_folder()) { | 234 AddNodeToMenu(child, submenu, add_extra_items); // recursive call |
261 [item setImage:folder_image_]; | 235 } else { |
262 NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease]; | 236 ConfigureMenuItem(child, item, false); |
263 [menu setSubmenu:submenu forItem:item]; | |
264 AddNodeToMenuRecursive(child, submenu, add_extra_items, | |
265 recursion_depth + 1); // Recursive call. | |
266 } else { | |
267 ConfigureMenuItem(child, item, false); | |
268 } | |
269 } | 237 } |
270 } | 238 } |
271 | 239 |
272 if (add_extra_items) { | 240 if (add_extra_items) { |
273 // Add menus for 'Open All Bookmarks'. | 241 // Add menus for 'Open All Bookmarks'. |
274 [menu addItem:[NSMenuItem separatorItem]]; | 242 [menu addItem:[NSMenuItem separatorItem]]; |
275 bool enabled = child_count != 0; | 243 bool enabled = child_count != 0; |
276 AddItemToMenu(IDC_BOOKMARK_BAR_OPEN_ALL, | 244 AddItemToMenu(IDC_BOOKMARK_BAR_OPEN_ALL, |
277 IDS_BOOKMARK_BAR_OPEN_ALL, | 245 IDS_BOOKMARK_BAR_OPEN_ALL, |
278 node, menu, enabled); | 246 node, menu, enabled); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 | 307 |
340 NSMenuItem* BookmarkMenuBridge::MenuItemForNode(const BookmarkNode* node) { | 308 NSMenuItem* BookmarkMenuBridge::MenuItemForNode(const BookmarkNode* node) { |
341 if (!node) | 309 if (!node) |
342 return nil; | 310 return nil; |
343 std::map<const BookmarkNode*, NSMenuItem*>::iterator it = | 311 std::map<const BookmarkNode*, NSMenuItem*>::iterator it = |
344 bookmark_nodes_.find(node); | 312 bookmark_nodes_.find(node); |
345 if (it == bookmark_nodes_.end()) | 313 if (it == bookmark_nodes_.end()) |
346 return nil; | 314 return nil; |
347 return it->second; | 315 return it->second; |
348 } | 316 } |
OLD | NEW |