- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / bookmarks / bookmark_context_menu_cocoa_controller.mm
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.
4
5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h"
6
7 #include <vector>
8
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/bookmarks/bookmark_model.h"
11 #include "chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h"
12 #include "chrome/browser/ui/browser.h"
13 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
14 #import "ui/base/cocoa/menu_controller.h"
15
16 @interface BookmarkContextMenuCocoaController (Private)
17 - (void)willExecuteCommand:(int)command;
18 @end
19
20 class BookmarkContextMenuDelegateBridge :
21     public BookmarkContextMenuControllerDelegate {
22  public:
23   BookmarkContextMenuDelegateBridge(
24       BookmarkContextMenuCocoaController* controller)
25       : controller_(controller) {
26   }
27
28   virtual ~BookmarkContextMenuDelegateBridge() {
29   }
30
31   virtual void CloseMenu() OVERRIDE {
32     [controller_ cancelTracking];
33   }
34
35   virtual void WillExecuteCommand(
36       int command_id,
37       const std::vector<const BookmarkNode*>& bookmarks) OVERRIDE {
38     [controller_ willExecuteCommand:command_id];
39   }
40
41  private:
42   BookmarkContextMenuCocoaController* controller_;  // Weak; owns us.
43
44   DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenuDelegateBridge);
45 };
46
47 @implementation BookmarkContextMenuCocoaController
48
49 - (id)initWithBookmarkBarController:(BookmarkBarController*)controller {
50   if ((self = [super init])) {
51     bookmarkBarController_ = controller;
52     bridge_.reset(new BookmarkContextMenuDelegateBridge(self));
53   }
54   return self;
55 }
56
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();
71   }
72
73   Browser* browser = [bookmarkBarController_ browser];
74   bookmarkContextMenuController_.reset(
75       new BookmarkContextMenuController([bookmarkBarController_ browserWindow],
76                                         bridge_.get(), browser,
77                                         browser->profile(), browser, parent,
78                                         nodes));
79   ui::SimpleMenuModel* menuModel =
80       bookmarkContextMenuController_->menu_model();
81   menuController_.reset([[MenuController alloc] initWithModel:menuModel
82                                        useWithPopUpButtonCell:NO]);
83 }
84
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())
89     return nil;
90   return bookmarkModel;
91 }
92
93 - (NSMenu*)menuForBookmarkNode:(const BookmarkNode*)node {
94   BookmarkModel* bookmarkModel = [self bookmarkModel];
95
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])
100     return nil;
101
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];
106   }
107   return [menuController_ menu];
108 }
109
110 - (NSMenu*)menuForBookmarkBar {
111   BookmarkModel* bookmarkModel = [self bookmarkModel];
112   if (!bookmarkModel)
113     return nil;
114
115   return [self menuForBookmarkNode:bookmarkModel->bookmark_bar_node()];
116 }
117
118 - (void)willExecuteCommand:(int)command {
119   // Some items should not close currently-open sub-folder menus.
120   switch (command) {
121     case IDC_CUT:
122     case IDC_COPY:
123     case IDC_PASTE:
124     case IDC_BOOKMARK_BAR_REMOVE:
125       return;
126   }
127
128   [bookmarkBarController_ closeFolderAndStopTrackingMenus];
129   if (bookmarkNode_)
130     [bookmarkBarController_ unhighlightBookmark:bookmarkNode_];
131 }
132
133 - (void)cancelTracking {
134   [[menuController_ menu] cancelTracking];
135 }
136
137 @end