Chromium Code Reviews| Index: chrome/browser/ui/views/extensions/extension_action_view_controller.cc |
| diff --git a/chrome/browser/ui/views/extensions/extension_action_view_controller.cc b/chrome/browser/ui/views/extensions/extension_action_view_controller.cc |
| index e17e5ce7742991411fdbf8a912712b341357013d..037e8dedf8a08e75eb411b2030403cdd7a1badbe 100644 |
| --- a/chrome/browser/ui/views/extensions/extension_action_view_controller.cc |
| +++ b/chrome/browser/ui/views/extensions/extension_action_view_controller.cc |
| @@ -5,6 +5,7 @@ |
| #include "chrome/browser/ui/views/extensions/extension_action_view_controller.h" |
| #include "base/logging.h" |
| +#include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/extensions/api/commands/command_service.h" |
| #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
| #include "chrome/browser/extensions/extension_action.h" |
| @@ -12,9 +13,16 @@ |
| #include "chrome/browser/sessions/session_tab_helper.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/extensions/accelerator_priority.h" |
| -#include "chrome/browser/ui/views/extensions/extension_action_view_delegate.h" |
| +#include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h" |
| +#include "chrome/browser/ui/views/toolbar/toolbar_view.h" |
| #include "chrome/common/extensions/api/extension_action/action_info.h" |
| +#include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_source.h" |
| +#include "extensions/browser/notification_types.h" |
| #include "extensions/common/extension.h" |
| +#include "extensions/common/manifest_constants.h" |
| +#include "ui/gfx/image/image_skia.h" |
| +#include "ui/gfx/image/image_skia_operations.h" |
| #include "ui/views/controls/menu/menu_controller.h" |
| #include "ui/views/controls/menu/menu_runner.h" |
| #include "ui/views/view.h" |
| @@ -36,19 +44,28 @@ ExtensionActionViewController* context_menu_owner = NULL; |
| ExtensionActionViewController::ExtensionActionViewController( |
| const extensions::Extension* extension, |
| Browser* browser, |
| - ExtensionAction* extension_action, |
| - ExtensionActionViewDelegate* delegate) |
| + ExtensionAction* extension_action) |
| : extension_(extension), |
| browser_(browser), |
| extension_action_(extension_action), |
| - delegate_(delegate), |
| + delegate_(NULL), |
|
Finnur
2014/10/17 09:57:02
nit: nullptr, same on line 53 and 54.
Devlin
2014/10/17 16:33:33
Ah, right. Old habits and all. :)
|
| icon_factory_(browser->profile(), extension, extension_action, this), |
| + icon_observer_(NULL), |
| popup_(NULL), |
| weak_factory_(this) { |
| DCHECK(extension_action); |
| DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE || |
| extension_action->action_type() == ActionInfo::TYPE_BROWSER); |
| DCHECK(extension); |
| + |
| + content::NotificationSource notification_source = |
| + content::Source<Profile>(browser->profile()->GetOriginalProfile()); |
| + registrar_.Add(this, |
| + extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED, |
| + notification_source); |
| + registrar_.Add(this, |
| + extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED, |
| + notification_source); |
| } |
| ExtensionActionViewController::~ExtensionActionViewController() { |
| @@ -58,24 +75,44 @@ ExtensionActionViewController::~ExtensionActionViewController() { |
| UnregisterCommand(false); |
| } |
| -void ExtensionActionViewController::InspectPopup() { |
| - ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT, true); |
| +ToolbarActionViewController::Type ExtensionActionViewController::GetType() |
| + const { |
| + return TYPE_EXTENSION_ACTION; |
| } |
| -void ExtensionActionViewController::ExecuteActionByUser() { |
| - ExecuteAction(ExtensionPopup::SHOW, true); |
| +void ExtensionActionViewController::SetDelegate( |
| + ToolbarActionViewDelegate* delegate) { |
| + delegate_ = delegate; |
| + delegate_->GetAsView()->set_context_menu_controller(this); |
| } |
| -bool ExtensionActionViewController::ExecuteAction( |
| - ExtensionPopup::ShowAction show_action, bool grant_tab_permissions) { |
| - if (extensions::ExtensionActionAPI::Get(browser_->profile())-> |
| - ExecuteExtensionAction(extension_, browser_, grant_tab_permissions) == |
| - ExtensionAction::ACTION_SHOW_POPUP) { |
| - GURL popup_url = extension_action_->GetPopupUrl(GetCurrentTabId()); |
| - return delegate_->GetPreferredPopupViewController()->ShowPopupWithUrl( |
| - show_action, popup_url, grant_tab_permissions); |
| - } |
| - return false; |
| +gfx::Image ExtensionActionViewController::GetIcon( |
| + content::WebContents* web_contents) { |
| + return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents)); |
| +} |
| + |
| +base::string16 ExtensionActionViewController::GetAccessibleName( |
| + content::WebContents* web_contents) const { |
| + std::string title = |
| + extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents)); |
| + return base::UTF8ToUTF16(title.empty() ? extension()->name() : title); |
| +} |
| + |
| +base::string16 ExtensionActionViewController::GetTooltip( |
| + content::WebContents* web_contents) const { |
| + return GetAccessibleName(web_contents); |
| +} |
| + |
| +bool ExtensionActionViewController::IsEnabled( |
| + content::WebContents* web_contents) const { |
| + return extension_action_->GetIsVisible( |
| + SessionTabHelper::IdForTab(web_contents)); |
| +} |
| + |
| +bool ExtensionActionViewController::HasPopup( |
| + content::WebContents* web_contents) const { |
| + int tab_id = SessionTabHelper::IdForTab(web_contents); |
| + return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id); |
| } |
| void ExtensionActionViewController::HidePopup() { |
| @@ -83,13 +120,21 @@ void ExtensionActionViewController::HidePopup() { |
| CleanupPopup(true); |
| } |
| -gfx::Image ExtensionActionViewController::GetIcon(int tab_id) { |
| - return icon_factory_.GetIcon(tab_id); |
| +bool ExtensionActionViewController::IsMenuRunning() const { |
| + return menu_runner_.get() != NULL; |
| } |
| -int ExtensionActionViewController::GetCurrentTabId() const { |
| - content::WebContents* web_contents = delegate_->GetCurrentWebContents(); |
| - return web_contents ? SessionTabHelper::IdForTab(web_contents) : -1; |
| +void ExtensionActionViewController::ExecuteActionByUser() { |
| + ExecuteAction(ExtensionPopup::SHOW, true); |
| +} |
| + |
| +void ExtensionActionViewController::PaintExtra( |
| + gfx::Canvas* canvas, |
| + const gfx::Rect& bounds, |
| + content::WebContents* web_contents) const { |
| + int tab_id = SessionTabHelper::IdForTab(web_contents); |
| + if (tab_id >= 0) |
| + extension_action_->PaintBadge(canvas, bounds, tab_id); |
| } |
| void ExtensionActionViewController::RegisterCommand() { |
| @@ -110,25 +155,38 @@ void ExtensionActionViewController::RegisterCommand() { |
| } |
| } |
| -void ExtensionActionViewController::UnregisterCommand(bool only_if_removed) { |
| - views::FocusManager* focus_manager = |
| - delegate_->GetFocusManagerForAccelerator(); |
| - if (!focus_manager || !action_keybinding_.get()) |
| - return; |
| +void ExtensionActionViewController::InspectPopup() { |
| + ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT, true); |
| +} |
| - // If |only_if_removed| is true, it means that we only need to unregister |
| - // ourselves as an accelerator if the command was removed. Otherwise, we need |
| - // to unregister ourselves no matter what (likely because we are shutting |
| - // down). |
| - extensions::Command extension_command; |
| - if (!only_if_removed || !GetExtensionCommand(&extension_command)) { |
| - focus_manager->UnregisterAccelerator(*action_keybinding_, this); |
| - action_keybinding_.reset(); |
| +bool ExtensionActionViewController::ExecuteAction( |
| + ExtensionPopup::ShowAction show_action, bool grant_tab_permissions) { |
| + if (extensions::ExtensionActionAPI::Get(browser_->profile())-> |
| + ExecuteExtensionAction(extension_, browser_, grant_tab_permissions) == |
| + ExtensionAction::ACTION_SHOW_POPUP) { |
| + GURL popup_url = extension_action_->GetPopupUrl( |
| + SessionTabHelper::IdForTab(delegate_->GetCurrentWebContents())); |
| + return static_cast<ExtensionActionViewController*>( |
| + delegate_->GetPreferredPopupViewController())->ShowPopupWithUrl( |
| + show_action, popup_url, grant_tab_permissions); |
| } |
| + return false; |
| +} |
| + |
| +gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() { |
| + content::WebContents* web_contents = delegate_->GetCurrentWebContents(); |
| + gfx::Size spacing(0, ToolbarView::kVertSpacing); |
| + gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia(); |
| + if (!IsEnabled(web_contents)) |
| + icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25); |
| + return extension_action_->GetIconWithBadge( |
| + icon, SessionTabHelper::IdForTab(web_contents), spacing); |
| } |
| void ExtensionActionViewController::OnIconUpdated() { |
| delegate_->OnIconUpdated(); |
| + if (icon_observer_) |
| + icon_observer_->OnIconUpdated(); |
| } |
| bool ExtensionActionViewController::AcceleratorPressed( |
| @@ -166,7 +224,6 @@ void ExtensionActionViewController::ShowContextMenuForView( |
| views::View* source, |
| const gfx::Point& point, |
| ui::MenuSourceType source_type) { |
| - |
| // If there's another active menu that won't be dismissed by opening this one, |
| // then we can't show this one right away, since we can only show one nested |
| // menu at a time. |
| @@ -189,6 +246,25 @@ void ExtensionActionViewController::ShowContextMenuForView( |
| DoShowContextMenu(source_type); |
| } |
| +void ExtensionActionViewController::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + DCHECK(type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED || |
| + type == extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED); |
| + std::pair<const std::string, const std::string>* payload = |
| + content::Details<std::pair<const std::string, const std::string> >( |
| + details).ptr(); |
| + if (extension_->id() == payload->first && |
| + payload->second == |
| + extensions::manifest_values::kBrowserActionCommandEvent) { |
| + if (type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED) |
| + RegisterCommand(); |
| + else |
| + UnregisterCommand(true); |
| + } |
| +} |
| + |
| void ExtensionActionViewController::DoShowContextMenu( |
| ui::MenuSourceType source_type) { |
| if (!extension_->ShowConfigureContextMenus()) |
| @@ -282,6 +358,23 @@ bool ExtensionActionViewController::GetExtensionCommand( |
| extension_->id(), CommandService::ACTIVE_ONLY, command, NULL); |
| } |
| +void ExtensionActionViewController::UnregisterCommand(bool only_if_removed) { |
| + views::FocusManager* focus_manager = |
| + delegate_->GetFocusManagerForAccelerator(); |
| + if (!focus_manager || !action_keybinding_.get()) |
| + return; |
| + |
| + // If |only_if_removed| is true, it means that we only need to unregister |
| + // ourselves as an accelerator if the command was removed. Otherwise, we need |
| + // to unregister ourselves no matter what (likely because we are shutting |
| + // down). |
| + extensions::Command extension_command; |
| + if (!only_if_removed || !GetExtensionCommand(&extension_command)) { |
| + focus_manager->UnregisterAccelerator(*action_keybinding_, this); |
| + action_keybinding_.reset(); |
| + } |
| +} |
| + |
| bool ExtensionActionViewController::CloseActiveMenuIfNeeded() { |
| // If this view is shown inside another menu, there's a possibility that there |
| // is another context menu showing that we have to close before we can |