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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_VIEWS_H_
6#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_VIEWS_H_
7#pragma once
8
9#include <map>
10#include <set>
11
12#include "chrome/browser/bookmarks/base_bookmark_model_observer.h"
13#include "chrome/browser/bookmarks/bookmark_node_data.h"
14#include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h"
15#include "ui/gfx/native_widget_types.h"
16#include "views/controls/menu/menu_delegate.h"
17#include "views/controls/menu/menu_item_view.h"
18
19class BookmarkBarView;
20class BookmarkNode;
21class Browser;
22class PageNavigator;
23class Profile;
24
25namespace gfx {
26class Rect;
27}  // namespace gfx
28
29namespace ui {
30class OSExchangeData;
31}  // namespace ui
32
33namespace views {
34class MenuButton;
35}  // namespace views
36
37// BookmarkMenuController is responsible for showing a menu of bookmarks,
38// each item in the menu represents a bookmark.
39// BookmarkMenuController deletes itself as necessary, although the menu can
40// be explicitly hidden by way of the Cancel method.
41class BookmarkMenuController : public BaseBookmarkModelObserver,
42                               public views::MenuDelegate,
43                               public BookmarkContextMenuObserver {
44 public:
45  // The observer is notified prior to the menu being deleted.
46  class Observer {
47   public:
48    virtual void BookmarkMenuDeleted(BookmarkMenuController* controller) = 0;
49
50   protected:
51    virtual ~Observer() {}
52  };
53
54  // Creates a BookmarkMenuController showing the children of |node| starting
55  // at index |start_child_index|.
56  BookmarkMenuController(Browser* browser,
57                         Profile* profile,
58                         PageNavigator* page_navigator,
59                         gfx::NativeWindow parent,
60                         const BookmarkNode* node,
61                         int start_child_index);
62
63  void RunMenuAt(BookmarkBarView* bookmark_bar, bool for_drop);
64
65  // Shows the menu.
66  void RunMenuAt(views::MenuButton* button,
67                 views::MenuItemView::AnchorPosition position,
68                 bool for_drop);
69
70  // Hides the menu.
71  void Cancel();
72
73  // Returns the node the menu is showing for.
74  const BookmarkNode* node() const { return node_; }
75
76  // Returns the menu.
77  views::MenuItemView* menu() const { return menu_; }
78
79  // Returns the context menu, or NULL if the context menu isn't showing.
80  views::MenuItemView* context_menu() const {
81    return context_menu_.get() ? context_menu_->menu() : NULL;
82  }
83
84  void set_observer(Observer* observer) { observer_ = observer; }
85
86  // MenuDelegate methods.
87  virtual std::wstring GetTooltipText(int id, const gfx::Point& p);
88  virtual bool IsTriggerableEvent(const views::MouseEvent& e);
89  virtual void ExecuteCommand(int id, int mouse_event_flags);
90  virtual bool GetDropFormats(
91      views::MenuItemView* menu,
92      int* formats,
93      std::set<ui::OSExchangeData::CustomFormat>* custom_formats);
94  virtual bool AreDropTypesRequired(views::MenuItemView* menu);
95  virtual bool CanDrop(views::MenuItemView* menu,
96                       const ui::OSExchangeData& data);
97  virtual int GetDropOperation(views::MenuItemView* item,
98                               const views::DropTargetEvent& event,
99                               DropPosition* position);
100  virtual int OnPerformDrop(views::MenuItemView* menu,
101                            DropPosition position,
102                            const views::DropTargetEvent& event);
103  virtual bool ShowContextMenu(views::MenuItemView* source,
104                               int id,
105                               const gfx::Point& p,
106                               bool is_mouse_gesture);
107  virtual void DropMenuClosed(views::MenuItemView* menu);
108  virtual bool CanDrag(views::MenuItemView* menu);
109  virtual void WriteDragData(views::MenuItemView* sender,
110                             ui::OSExchangeData* data);
111  virtual int GetDragOperations(views::MenuItemView* sender);
112  virtual views::MenuItemView* GetSiblingMenu(
113      views::MenuItemView* menu,
114      const gfx::Point& screen_point,
115      views::MenuItemView::AnchorPosition* anchor,
116      bool* has_mnemonics,
117      views::MenuButton** button);
118  virtual int GetMaxWidthForMenu();
119
120  // BookmarkModelObserver methods.
121  virtual void BookmarkModelChanged();
122  virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model,
123                                         const BookmarkNode* node);
124
125  // BookmarkContextMenu::Observer methods.
126  virtual void WillRemoveBookmarks(
127      const std::vector<const BookmarkNode*>& bookmarks);
128  virtual void DidRemoveBookmarks();
129
130 private:
131  typedef std::map<const BookmarkNode*, int> NodeToMenuIDMap;
132
133  // BookmarkMenuController deletes itself as necessary.
134  virtual ~BookmarkMenuController();
135
136  // Creates a menu and adds it to node_to_menu_id_map_. This uses
137  // BuildMenu to recursively populate the menu.
138  views::MenuItemView* CreateMenu(const BookmarkNode* parent,
139                                  int start_child_index);
140
141  // Creates an entry in menu for each child node of |parent| starting at
142  // |start_child_index|.
143  void BuildMenu(const BookmarkNode* parent,
144                 int start_child_index,
145                 views::MenuItemView* menu,
146                 int* next_menu_id);
147
148  // Returns the menu whose id is |id|.
149  views::MenuItemView* GetMenuByID(int id);
150
151  // Does the work of processing WillRemoveBookmarks. On exit the set of removed
152  // menus is added to |removed_menus|. It's up to the caller to delete the
153  // the menus added to |removed_menus|.
154  void WillRemoveBookmarksImpl(
155      const std::vector<const BookmarkNode*>& bookmarks,
156      std::set<views::MenuItemView*>* removed_menus);
157
158  Browser* browser_;
159
160  Profile* profile_;
161
162  PageNavigator* page_navigator_;
163
164  // Parent of menus.
165  gfx::NativeWindow parent_;
166
167  // The node we're showing the contents of.
168  const BookmarkNode* node_;
169
170  // Maps from menu id to BookmarkNode.
171  std::map<int, const BookmarkNode*> menu_id_to_node_map_;
172
173  // Mapping from node to menu id. This only contains entries for nodes of type
174  // URL.
175  NodeToMenuIDMap node_to_menu_id_map_;
176
177  // Current menu.
178  views::MenuItemView* menu_;
179
180  // Data for the drop.
181  BookmarkNodeData drop_data_;
182
183  // Used when a context menu is shown.
184  scoped_ptr<BookmarkContextMenu> context_menu_;
185
186  // The observer, may be null.
187  Observer* observer_;
188
189  // Is the menu being shown for a drop?
190  bool for_drop_;
191
192  // The bookmark bar. This is only non-null if we're showing a menu item
193  // for a folder on the bookmark bar and not for drop.
194  BookmarkBarView* bookmark_bar_;
195
196  typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap;
197  NodeToMenuMap node_to_menu_map_;
198
199  // ID of the next menu item.
200  int next_menu_id_;
201
202  DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController);
203};
204
205#endif  // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_VIEWS_H_
206