| 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 |