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_WRENCH_MENU_H_
6#define CHROME_BROWSER_UI_VIEWS_WRENCH_MENU_H_
7#pragma once
8
9#include <map>
10#include <utility>
11
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "ui/base/models/menu_model.h"
15#include "views/controls/menu/menu_delegate.h"
16
17class Browser;
18
19namespace views {
20class MenuButton;
21class MenuItemView;
22class View;
23}  // namespace views
24
25// WrenchMenu adapts the WrenchMenuModel to view's menu related classes.
26class WrenchMenu : public base::RefCounted<WrenchMenu>,
27                   public views::MenuDelegate {
28 public:
29  explicit WrenchMenu(Browser* browser);
30
31  void Init(ui::MenuModel* model);
32
33  // Shows the menu relative to the specified view.
34  void RunMenu(views::MenuButton* host);
35
36  // MenuDelegate overrides:
37  virtual bool IsItemChecked(int id) const;
38  virtual bool IsCommandEnabled(int id) const;
39  virtual void ExecuteCommand(int id);
40  virtual bool GetAccelerator(int id, views::Accelerator* accelerator);
41
42 private:
43  friend class base::RefCounted<WrenchMenu>;
44
45  class CutCopyPasteView;
46  class ZoomView;
47
48  typedef std::pair<ui::MenuModel*,int> Entry;
49  typedef std::map<int,Entry> IDToEntry;
50
51  ~WrenchMenu();
52
53  // Populates |parent| with all the child menus in |model|. Recursively invokes
54  // |PopulateMenu| for any submenu. |next_id| is incremented for every menu
55  // that is created.
56  void PopulateMenu(views::MenuItemView* parent,
57                    ui::MenuModel* model,
58                    int* next_id);
59
60  // Adds a new menu to |parent| to represent the MenuModel/index pair passed
61  // in.
62  views::MenuItemView* AppendMenuItem(views::MenuItemView* parent,
63                                      ui::MenuModel* model,
64                                      int index,
65                                      ui::MenuModel::ItemType menu_type,
66                                      int* next_id);
67
68  // Invoked from the cut/copy/paste menus. Cancels the current active menu and
69  // activates the menu item in |model| at |index|.
70  void CancelAndEvaluate(ui::MenuModel* model, int index);
71
72  // The views menu.
73  scoped_ptr<views::MenuItemView> root_;
74
75  // Maps from the ID as understood by MenuItemView to the model/index pair the
76  // item came from.
77  IDToEntry id_to_entry_;
78
79  // Browser the menu is being shown for.
80  Browser* browser_;
81
82  // |CancelAndEvaluate| sets |selected_menu_model_| and |selected_index_|.
83  // If |selected_menu_model_| is non-null after the menu completes
84  // ActivatedAt is invoked. This is done so that ActivatedAt isn't invoked
85  // while the message loop is nested.
86  ui::MenuModel* selected_menu_model_;
87  int selected_index_;
88
89  DISALLOW_COPY_AND_ASSIGN(WrenchMenu);
90};
91
92#endif  // CHROME_BROWSER_UI_VIEWS_WRENCH_MENU_H_
93