1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h"
11 #include "chrome/browser/ui/browser.h"
12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
13 #include "components/bookmarks/browser/bookmark_model.h"
14 #import "ui/base/cocoa/menu_controller.h"
16 @interface BookmarkContextMenuCocoaController (Private)
17 - (void)willExecuteCommand:(int)command;
20 class BookmarkContextMenuDelegateBridge :
21 public BookmarkContextMenuControllerDelegate {
23 BookmarkContextMenuDelegateBridge(
24 BookmarkContextMenuCocoaController* controller)
25 : controller_(controller) {
28 virtual ~BookmarkContextMenuDelegateBridge() {
31 virtual void CloseMenu() OVERRIDE {
32 [controller_ cancelTracking];
35 virtual void WillExecuteCommand(
37 const std::vector<const BookmarkNode*>& bookmarks) OVERRIDE {
38 [controller_ willExecuteCommand:command_id];
42 BookmarkContextMenuCocoaController* controller_; // Weak; owns us.
44 DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenuDelegateBridge);
47 @implementation BookmarkContextMenuCocoaController
49 - (id)initWithBookmarkBarController:(BookmarkBarController*)controller {
50 if ((self = [super init])) {
51 bookmarkBarController_ = controller;
52 bridge_.reset(new BookmarkContextMenuDelegateBridge(self));
57 // Re-creates |bookmarkContextMenuController_| and |menuController_| based on
58 // |bookmarkModel| and the current value of |bookmarkNode_|.
59 - (void)createMenuControllers:(BookmarkModel*)bookmarkModel {
60 const BookmarkNode* parent = NULL;
61 std::vector<const BookmarkNode*> nodes;
62 if (bookmarkNode_ == bookmarkModel->other_node()) {
63 nodes.push_back(bookmarkNode_);
64 parent = bookmarkModel->bookmark_bar_node();
65 } else if (bookmarkNode_ == bookmarkModel->bookmark_bar_node()) {
66 parent = bookmarkModel->bookmark_bar_node();
67 nodes.push_back(parent);
68 } else if (bookmarkNode_) {
69 nodes.push_back(bookmarkNode_);
70 parent = bookmarkNode_->parent();
73 Browser* browser = [bookmarkBarController_ browser];
74 bookmarkContextMenuController_.reset(
75 new BookmarkContextMenuController([bookmarkBarController_ browserWindow],
76 bridge_.get(), browser,
77 browser->profile(), browser, parent,
79 ui::SimpleMenuModel* menuModel =
80 bookmarkContextMenuController_->menu_model();
81 menuController_.reset([[MenuController alloc] initWithModel:menuModel
82 useWithPopUpButtonCell:NO]);
85 - (BookmarkModel*)bookmarkModel {
86 // Depending on timing, the model may not yet have been loaded.
87 BookmarkModel* bookmarkModel = [bookmarkBarController_ bookmarkModel];
88 if (!bookmarkModel || !bookmarkModel->loaded())
93 - (NSMenu*)menuForBookmarkNode:(const BookmarkNode*)node {
94 BookmarkModel* bookmarkModel = [self bookmarkModel];
96 // This may be called before the BMB view has been added to the window. In
97 // that case, simply return nil so that BookmarkContextMenuController doesn't
98 // get created with a nil window.
99 if (!bookmarkModel || ![bookmarkBarController_ browserWindow])
102 // Rebuild the menu if it's for a different node than the last request.
103 if (!menuController_ || node != bookmarkNode_) {
104 bookmarkNode_ = node;
105 [self createMenuControllers:bookmarkModel];
107 return [menuController_ menu];
110 - (NSMenu*)menuForBookmarkBar {
111 BookmarkModel* bookmarkModel = [self bookmarkModel];
115 return [self menuForBookmarkNode:bookmarkModel->bookmark_bar_node()];
118 - (void)willExecuteCommand:(int)command {
119 // Some items should not close currently-open sub-folder menus.
124 case IDC_BOOKMARK_BAR_REMOVE:
128 [bookmarkBarController_ closeFolderAndStopTrackingMenus];
130 [bookmarkBarController_ unhighlightBookmark:bookmarkNode_];
133 - (void)cancelTracking {
134 [[menuController_ menu] cancelTracking];