Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(391)

Side by Side Diff: chrome/browser/ui/views/extensions/extension_action_view.cc

Issue 431173002: Create ExtensionActionView class (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "chrome/browser/ui/views/extensions/extension_action_view.h"
6
7 #include "base/logging.h"
8 #include "chrome/browser/extensions/api/commands/command_service.h"
9 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_toolbar_model.h"
11 #include "chrome/browser/extensions/location_bar_controller.h"
12 #include "chrome/browser/extensions/tab_helper.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/sessions/session_id.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/extensions/accelerator_priority.h"
17 #include "chrome/common/extensions/api/extension_action/action_info.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/manifest_constants.h"
20 #include "ui/views/controls/menu/menu_runner.h"
21 #include "ui/views/view.h"
22 #include "ui/views/widget/widget.h"
23
24 using extensions::ActionInfo;
25 using extensions::CommandService;
26
27 ExtensionActionView::ExtensionActionView(
28 const extensions::Extension* extension,
29 Browser* browser,
30 ExtensionAction* extension_action,
31 ViewDelegate* delegate)
32 : extension_(extension),
33 browser_(browser),
34 extension_action_(extension_action),
35 delegate_(delegate),
36 icon_factory_(browser->profile(), extension, extension_action, this),
37 popup_(NULL) {
38 DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
39 extension_action->action_type() == ActionInfo::TYPE_BROWSER);
40 DCHECK(extension);
41
42 }
43
44 ExtensionActionView::~ExtensionActionView() {
45 HidePopup();
46 UnregisterCommand(false);
47 }
48
49 void ExtensionActionView::InspectPopup() {
50 ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT, true);
51 }
52
53 void ExtensionActionView::ExecuteActionByUser() {
54 ExecuteAction(ExtensionPopup::SHOW, true);
55 }
56
57 bool ExtensionActionView::ExecuteAction(ExtensionPopup::ShowAction show_action,
58 bool grant_tab_permissions) {
59 GURL popup_url;
60 bool show_popup = false;
61 if (extension_action_->action_type() == ActionInfo::TYPE_BROWSER) {
62 extensions::ExtensionToolbarModel* toolbar_model =
63 extensions::ExtensionToolbarModel::Get(browser_->profile());
64 show_popup = toolbar_model->ExecuteBrowserAction(
65 extension_, browser_, &popup_url, grant_tab_permissions) ==
66 extensions::ExtensionToolbarModel::ACTION_SHOW_POPUP;
67 } else { // PageAction
68 content::WebContents* web_contents = delegate_->GetCurrentWebContents();
69 if (!web_contents)
70 return false;
71 extensions::LocationBarController* controller =
72 extensions::TabHelper::FromWebContents(web_contents)->
73 location_bar_controller();
74 switch (controller->OnClicked(extension_action_)) {
75 case extensions::LocationBarController::ACTION_NONE:
76 break;
77 case extensions::LocationBarController::ACTION_SHOW_POPUP:
78 popup_url = extension_action_->GetPopupUrl(GetCurrentTabId());
79 show_popup = true;
80 break;
81 case extensions::LocationBarController::ACTION_SHOW_CONTEXT_MENU:
82 // We are never passing OnClicked a right-click button, so assume that
83 // we're never going to be asked to show a context menu.
84 // TODO(kalman): if this changes, update this class to pass the real
85 // mouse button through to the LocationBarController.
86 NOTREACHED();
87 break;
88 }
89 }
90
91 if (show_popup && ShowPopupWithUrl(show_action, popup_url)) {
92 delegate_->OnPopupShown(grant_tab_permissions);
93 return true;
94 }
95
96 return false;
97 }
98
99 void ExtensionActionView::HidePopup() {
100 if (popup_)
101 CleanupPopup(true);
102 }
103
104 gfx::Image ExtensionActionView::GetIcon(int tab_id) {
105 return icon_factory_.GetIcon(tab_id);
106 }
107
108 int ExtensionActionView::GetCurrentTabId() const {
109 content::WebContents* web_contents = delegate_->GetCurrentWebContents();
110 return web_contents ? SessionID::IdForTab(web_contents) : -1;
111 }
112
113 void ExtensionActionView::RegisterCommand() {
114 // If we've already registered, do nothing.
115 if (action_keybinding_.get())
116 return;
117
118 extensions::Command extension_command;
119 views::FocusManager* focus_manager =
120 delegate_->GetFocusManagerForAccelerator();
121 if (focus_manager && GetExtensionCommand(&extension_command)) {
122 action_keybinding_.reset(
123 new ui::Accelerator(extension_command.accelerator()));
124 focus_manager->RegisterAccelerator(
125 *action_keybinding_,
126 GetAcceleratorPriority(extension_command.accelerator(), extension_),
127 delegate_->GetAsView());
128 }
129 }
130
131 void ExtensionActionView::UnregisterCommand(bool only_if_removed) {
132 views::FocusManager* focus_manager =
133 delegate_->GetFocusManagerForAccelerator();
134 if (!focus_manager || !action_keybinding_.get())
135 return;
136
137 // If |only_if_removed| is true, it means that we only need to unregister
138 // ourselves as an accelerator if the command was removed. Otherwise, we need
139 // to unregister ourselves no matter what (likely because we are shutting
140 // down).
141 extensions::Command extension_command;
142 if (!only_if_removed || !GetExtensionCommand(&extension_command)) {
143 focus_manager->UnregisterAccelerator(*action_keybinding_,
144 delegate_->GetAsView());
145 action_keybinding_.reset();
146 }
147 }
148
149 bool ExtensionActionView::AcceleratorPressed(
150 const ui::Accelerator& accelerator) {
151 // Normal priority shortcuts must be handled via standard browser commands to
152 // be processed at the proper time.
153 if (GetAcceleratorPriority(accelerator, extension()) ==
154 ui::AcceleratorManager::kNormalPriority)
155 return false;
156
157 ExecuteActionByUser();
158 return true;
159 }
160
161 void ExtensionActionView::OnIconUpdated() {
162 delegate_->OnIconUpdated();
163 }
164
165 void ExtensionActionView::OnWidgetDestroying(views::Widget* widget) {
166 DCHECK(popup_);
167 DCHECK_EQ(popup_->GetWidget(), widget);
168 CleanupPopup(false);
169 }
170
171 void ExtensionActionView::ShowContextMenuForView(
172 views::View* source,
173 const gfx::Point& point,
174 ui::MenuSourceType source_type) {
175 if (!extension_->ShowConfigureContextMenus())
176 return;
177
178 delegate_->OnWillShowContextMenus();
179
180 // Reconstructs the menu every time because the menu's contents are dynamic.
181 scoped_refptr<ExtensionContextMenuModel> context_menu_model(
182 new ExtensionContextMenuModel(extension_, browser_, this));
183
184 gfx::Point screen_loc;
185 views::View::ConvertPointToScreen(delegate_->GetAsView(), &screen_loc);
186
187 int run_types = views::MenuRunner::HAS_MNEMONICS |
188 views::MenuRunner::CONTEXT_MENU;
189 if (delegate_->IsNestedView())
190 run_types |= views::MenuRunner::IS_NESTED;
191
192 views::Widget* parent = delegate_->GetParentForContextMenu();
193
194 menu_runner_.reset(
195 new views::MenuRunner(context_menu_model.get(), run_types));
196
197 if (menu_runner_->RunMenuAt(
198 parent,
199 NULL,
200 gfx::Rect(screen_loc, delegate_->GetAsView()->size()),
201 views::MENU_ANCHOR_TOPLEFT,
202 source_type) == views::MenuRunner::MENU_DELETED) {
203 return;
204 }
205
206 menu_runner_.reset();
207 delegate_->OnContextMenuDone();
208 }
209
210 bool ExtensionActionView::ShowPopupWithUrl(
211 ExtensionPopup::ShowAction show_action, const GURL& popup_url) {
212 // If we're already showing the popup for this browser action, just hide it
213 // and return.
214 bool already_showing = popup_ != NULL;
215
216 // Always hide the current popup, even if it's not the same.
217 // Only one popup should be visible at a time.
218 delegate_->HideActivePopup();
219 if (already_showing)
220 return false;
221
222 views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
223 views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
224
225 views::View* reference_view = delegate_->GetReferenceViewForPopup();
226
227 popup_ = ExtensionPopup::ShowPopup(
228 popup_url, browser_, reference_view, arrow, show_action);
229 popup_->GetWidget()->AddObserver(this);
230
231 return true;
232 }
233
234 bool ExtensionActionView::GetExtensionCommand(extensions::Command* command) {
235 DCHECK(command);
236 CommandService* command_service = CommandService::Get(browser_->profile());
237 if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
238 return command_service->GetPageActionCommand(
239 extension_->id(), CommandService::ACTIVE_ONLY, command, NULL);
240 }
241 return command_service->GetBrowserActionCommand(
242 extension_->id(), CommandService::ACTIVE_ONLY, command, NULL);
243 }
244
245 void ExtensionActionView::CleanupPopup(bool close_widget) {
246 DCHECK(popup_);
247 delegate_->CleanupPopup();
248 popup_->GetWidget()->RemoveObserver(this);
249 if (close_widget)
250 popup_->GetWidget()->Close();
251 popup_ = NULL;
252 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698