1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_WRENCH_MENU_H_
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_WRENCH_MENU_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/observer_list.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/base_bookmark_model_observer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/menu_model.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_delegate.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkMenuDelegate;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Browser;
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class WrenchMenuObserver;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NativeTheme;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MenuButton;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MenuConfig;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MenuItemView;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MenuRunner;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class View;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WrenchMenu adapts the WrenchMenuModel to view's menu related classes.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WrenchMenu : public views::MenuDelegate,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   public BaseBookmarkModelObserver,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   public content::NotificationObserver {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  enum RunFlags {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Indicates that the menu was opened for a drag-and-drop operation.
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FOR_DROP = 1 << 0,
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WrenchMenu(Browser* browser, int run_flags);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WrenchMenu();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(ui::MenuModel* model);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shows the menu relative to the specified view.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunMenu(views::MenuButton* host);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Closes the menu if it is open, otherwise does nothing.
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void CloseMenu();
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the menu is currently visible to the user.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsShowing();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool for_drop() const { return (run_flags_ & FOR_DROP) != 0; }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void AddObserver(WrenchMenuObserver* observer);
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void RemoveObserver(WrenchMenuObserver* observer);
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MenuDelegate overrides:
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual const gfx::FontList* GetLabelFontList(int command_id) const OVERRIDE;
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual bool GetShouldUseDisabledEmphasizedForegroundColor(
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      int command_id) const OVERRIDE;
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::string16 GetTooltipText(int command_id,
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                        const gfx::Point& p) const OVERRIDE;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsTriggerableEvent(views::MenuItemView* menu,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ui::Event& e) OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetDropFormats(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::MenuItemView* menu,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int* formats,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool AreDropTypesRequired(views::MenuItemView* menu) OVERRIDE;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanDrop(views::MenuItemView* menu,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const ui::OSExchangeData& data) OVERRIDE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetDropOperation(views::MenuItemView* item,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const ui::DropTargetEvent& event,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               DropPosition* position) OVERRIDE;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int OnPerformDrop(views::MenuItemView* menu,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            DropPosition position,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const ui::DropTargetEvent& event) OVERRIDE;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShowContextMenu(views::MenuItemView* source,
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               int command_id,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Point& p,
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               ui::MenuSourceType source_type) OVERRIDE;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanDrag(views::MenuItemView* menu) OVERRIDE;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteDragData(views::MenuItemView* sender,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ui::OSExchangeData* data) OVERRIDE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetDragOperations(views::MenuItemView* sender) OVERRIDE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetMaxWidthForMenu(views::MenuItemView* menu) OVERRIDE;
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsItemChecked(int command_id) const OVERRIDE;
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsCommandEnabled(int command_id) const OVERRIDE;
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void ExecuteCommand(int command_id, int mouse_event_flags) OVERRIDE;
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool GetAccelerator(int command_id,
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              ui::Accelerator* accelerator) const OVERRIDE;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WillShowMenu(views::MenuItemView* menu) OVERRIDE;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WillHideMenu(views::MenuItemView* menu) OVERRIDE;
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool ShouldCloseOnDragComplete() OVERRIDE;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BaseBookmarkModelObserver overrides:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BookmarkModelChanged() OVERRIDE;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content::NotificationObserver overrides:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class CutCopyPasteView;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class RecentTabsMenuModelDelegate;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ZoomView;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::pair<ui::MenuModel*,int> Entry;
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typedef std::map<int,Entry> CommandIDToEntry;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Populates |parent| with all the child menus in |model|. Recursively invokes
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |PopulateMenu| for any submenu.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PopulateMenu(views::MenuItemView* parent,
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    ui::MenuModel* model);
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Adds a new menu item to |parent| at |menu_index| to represent the item in
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |model| at |model_index|:
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // - |menu_index|: position in |parent| to add the new item.
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // - |model_index|: position in |model| to retrieve information about the
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //   new menu item.
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The returned item's MenuItemView::GetCommand() is the same as that of
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |model|->GetCommandIdAt(|model_index|).
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  views::MenuItemView* AddMenuItem(views::MenuItemView* parent,
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   int menu_index,
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   ui::MenuModel* model,
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   int model_index,
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   ui::MenuModel::ItemType menu_type);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked from the cut/copy/paste menus. Cancels the current active menu and
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // activates the menu item in |model| at |index|.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelAndEvaluate(ui::MenuModel* model, int index);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the bookmark menu if necessary. Does nothing if already created or
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the bookmark model isn't loaded.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateBookmarkMenu();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Returns the index of the MenuModel/index pair representing the |command_id|
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // in |command_id_to_entry_|.
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int ModelIndexFromCommandId(int command_id) const;
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The views menu. Owned by |menu_runner_|.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::MenuItemView* root_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<views::MenuRunner> menu_runner_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Maps from the command ID in model to the model/index pair the item came
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // from.
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandIDToEntry command_id_to_entry_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Browser the menu is being shown for.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |CancelAndEvaluate| sets |selected_menu_model_| and |selected_index_|.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |selected_menu_model_| is non-null after the menu completes
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ActivatedAt is invoked. This is done so that ActivatedAt isn't invoked
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // while the message loop is nested.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MenuModel* selected_menu_model_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int selected_index_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for managing the bookmark menu items.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BookmarkMenuDelegate> bookmark_menu_delegate_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Menu corresponding to IDC_BOOKMARKS_MENU.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::MenuItemView* bookmark_menu_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Menu corresponding to IDC_FEEDBACK.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::MenuItemView* feedback_menu_item_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Used for managing "Recent tabs" menu items.
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<RecentTabsMenuModelDelegate> recent_tabs_menu_model_delegate_;
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The bit mask of RunFlags.
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int run_flags_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ObserverList<WrenchMenuObserver> observer_list_;
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WrenchMenu);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // CHROME_BROWSER_UI_VIEWS_TOOLBAR_WRENCH_MENU_H_
191