extension_action_view_controller.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 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_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
6#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
7
8#include "chrome/browser/extensions/extension_action_icon_factory.h"
9#include "chrome/browser/extensions/extension_context_menu_model.h"
10#include "chrome/browser/ui/views/extensions/extension_popup.h"
11#include "ui/base/accelerators/accelerator.h"
12#include "ui/gfx/image/image.h"
13#include "ui/views/context_menu_controller.h"
14#include "ui/views/widget/widget_observer.h"
15
16class Browser;
17class ExtensionAction;
18class ExtensionActionViewDelegate;
19
20namespace content {
21class WebContents;
22}
23
24namespace extensions {
25class Command;
26class Extension;
27}
28
29namespace ui {
30class Accelerator;
31}
32
33namespace views {
34class MenuRunner;
35class View;
36class Widget;
37}
38
39// An abstract "View" for an ExtensionAction (either a BrowserAction or a
40// PageAction). This contains the logic for showing the action's popup and
41// the context menu. This class doesn't subclass View directly, as the
42// implementations for page actions/browser actions are different types of
43// views.
44// All common logic for executing extension actions should go in this class;
45// ExtensionActionViewDelegate classes should only have knowledge relating to
46// the views::View wrapper.
47class ExtensionActionViewController
48    : public ExtensionActionIconFactory::Observer,
49      public ExtensionContextMenuModel::PopupDelegate,
50      public ui::AcceleratorTarget,
51      public views::ContextMenuController,
52      public views::WidgetObserver {
53 public:
54  ExtensionActionViewController(const extensions::Extension* extension,
55                                Browser* browser,
56                                ExtensionAction* extension_action,
57                                ExtensionActionViewDelegate* delegate);
58  virtual ~ExtensionActionViewController();
59
60  // ExtensionContextMenuModel::PopupDelegate:
61  virtual void InspectPopup() OVERRIDE;
62
63  // Executes the default extension action (typically showing the popup), and
64  // attributes the action to a user (thus, only use this for actions that
65  // *were* done by the user).
66  void ExecuteActionByUser();
67
68  // Executes the extension action with |show_action|. If
69  // |grant_tab_permissions| is true, this will grant the extension active tab
70  // permissions. Only do this if this was done through a user action (and not
71  // e.g. an API). Returns true if a popup is shown.
72  bool ExecuteAction(ExtensionPopup::ShowAction show_action,
73                     bool grant_tab_permissions);
74
75  // Hides the popup, if one is open.
76  void HidePopup();
77
78  // Returns the icon from the |icon_factory_|.
79  gfx::Image GetIcon(int tab_id);
80
81  // Returns the current tab id.
82  int GetCurrentTabId() const;
83
84  // Registers an accelerator for the extension action's command, if one
85  // exists.
86  void RegisterCommand();
87
88  // Unregisters the accelerator for the extension action's command, if one
89  // exists. If |only_if_removed| is true, then this will only unregister if the
90  // command has been removed.
91  void UnregisterCommand(bool only_if_removed);
92
93  const extensions::Extension* extension() const { return extension_; }
94  Browser* browser() { return browser_; }
95  ExtensionAction* extension_action() { return extension_action_; }
96  const ExtensionAction* extension_action() const { return extension_action_; }
97  ExtensionPopup* popup() { return popup_; }
98  bool is_menu_running() const { return menu_runner_.get() != NULL; }
99
100 private:
101  // ExtensionActionIconFactory::Observer:
102  virtual void OnIconUpdated() OVERRIDE;
103
104  // ui::AcceleratorTarget:
105  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
106  virtual bool CanHandleAccelerators() const OVERRIDE;
107
108  // views::WidgetObserver:
109  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
110
111  // views::ContextMenuController:
112  virtual void ShowContextMenuForView(views::View* source,
113                                      const gfx::Point& point,
114                                      ui::MenuSourceType source_type) OVERRIDE;
115
116  // Shows the context menu for extension action.
117  void DoShowContextMenu(ui::MenuSourceType source_type);
118
119  // Shows the popup for the extension action, given the associated |popup_url|.
120  // |grant_tab_permissions| is true if active tab permissions should be given
121  // to the extension; this is only true if the popup is opened through a user
122  // action.
123  // Returns true if a popup is successfully shown.
124  bool ShowPopupWithUrl(ExtensionPopup::ShowAction show_action,
125                        const GURL& popup_url,
126                        bool grant_tab_permissions);
127
128  // Populates |command| with the command associated with |extension|, if one
129  // exists. Returns true if |command| was populated.
130  bool GetExtensionCommand(extensions::Command* command);
131
132  // Closes the currently-active menu, if needed. This is the case when there
133  // is an active menu that wouldn't close automatically when a new one is
134  // opened.
135  // Returns true if a menu was closed, false otherwise.
136  bool CloseActiveMenuIfNeeded();
137
138  // Cleans up after the popup. If |close_widget| is true, this will call
139  // Widget::Close() on the popup's widget; otherwise it assumes the popup is
140  // already closing.
141  void CleanupPopup(bool close_widget);
142
143  // The extension associated with the action we're displaying.
144  const extensions::Extension* extension_;
145
146  // The corresponding browser.
147  Browser* browser_;
148
149  // The browser action this view represents. The ExtensionAction is not owned
150  // by this class.
151  ExtensionAction* extension_action_;
152
153  // Our delegate.
154  ExtensionActionViewDelegate* delegate_;
155
156  // The object that will be used to get the browser action icon for us.
157  // It may load the icon asynchronously (in which case the initial icon
158  // returned by the factory will be transparent), so we have to observe it for
159  // updates to the icon.
160  ExtensionActionIconFactory icon_factory_;
161
162  // Responsible for running the menu.
163  scoped_ptr<views::MenuRunner> menu_runner_;
164
165  // The browser action's popup, if it is visible; NULL otherwise.
166  ExtensionPopup* popup_;
167
168  // The extension key binding accelerator this extension action is listening
169  // for (to show the popup).
170  scoped_ptr<ui::Accelerator> action_keybinding_;
171
172  // If non-NULL, this is the next ExtensionActionViewController context menu
173  // which wants to run once the current owner (this one) is done.
174  base::Closure followup_context_menu_task_;
175
176  base::WeakPtrFactory<ExtensionActionViewController> weak_factory_;
177
178  DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController);
179};
180
181#endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
182