Home | History | Annotate | Download | only in extensions
      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 #include "chrome/browser/extensions/extension_context_menu_model.h"
      6 
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/extensions/extension_service.h"
      9 #include "chrome/browser/extensions/extension_tabs_module.h"
     10 #include "chrome/browser/prefs/pref_service.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/common/extensions/extension.h"
     14 #include "chrome/common/extensions/extension_action.h"
     15 #include "chrome/common/extensions/extension_constants.h"
     16 #include "chrome/common/pref_names.h"
     17 #include "chrome/common/url_constants.h"
     18 #include "grit/generated_resources.h"
     19 
     20 enum MenuEntries {
     21   NAME = 0,
     22   CONFIGURE,
     23   HIDE,
     24   DISABLE,
     25   UNINSTALL,
     26   MANAGE,
     27   INSPECT_POPUP
     28 };
     29 
     30 ExtensionContextMenuModel::ExtensionContextMenuModel(
     31     const Extension* extension,
     32     Browser* browser,
     33     PopupDelegate* delegate)
     34     : ALLOW_THIS_IN_INITIALIZER_LIST(SimpleMenuModel(this)),
     35       extension_id_(extension->id()),
     36       browser_(browser),
     37       profile_(browser->profile()),
     38       delegate_(delegate) {
     39   extension_action_ = extension->browser_action();
     40   if (!extension_action_)
     41     extension_action_ = extension->page_action();
     42 
     43   InitCommonCommands();
     44 
     45   if (profile_->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode) &&
     46       delegate_) {
     47     AddSeparator();
     48     AddItemWithStringId(INSPECT_POPUP, IDS_EXTENSION_ACTION_INSPECT_POPUP);
     49   }
     50 }
     51 
     52 ExtensionContextMenuModel::~ExtensionContextMenuModel() {
     53 }
     54 
     55 void ExtensionContextMenuModel::InitCommonCommands() {
     56   const Extension* extension = GetExtension();
     57 
     58   // The extension pointer should only be null if the extension was uninstalled,
     59   // and since the menu just opened, it should still be installed.
     60   DCHECK(extension);
     61 
     62   AddItem(NAME, UTF8ToUTF16(extension->name()));
     63   AddSeparator();
     64   AddItemWithStringId(CONFIGURE, IDS_EXTENSIONS_OPTIONS);
     65   AddItemWithStringId(DISABLE, IDS_EXTENSIONS_DISABLE);
     66   AddItemWithStringId(UNINSTALL, IDS_EXTENSIONS_UNINSTALL);
     67   if (extension->browser_action())
     68     AddItemWithStringId(HIDE, IDS_EXTENSIONS_HIDE_BUTTON);
     69   AddSeparator();
     70   AddItemWithStringId(MANAGE, IDS_MANAGE_EXTENSIONS);
     71 }
     72 
     73 bool ExtensionContextMenuModel::IsCommandIdChecked(int command_id) const {
     74   return false;
     75 }
     76 
     77 bool ExtensionContextMenuModel::IsCommandIdEnabled(int command_id) const {
     78   const Extension* extension = this->GetExtension();
     79   if (!extension)
     80     return false;
     81 
     82   if (command_id == CONFIGURE) {
     83     return extension->options_url().spec().length() > 0;
     84   } else if (command_id == NAME) {
     85     // The NAME links to the Homepage URL. If the extension doesn't have a
     86     // homepage, we just disable this menu item.
     87     return extension->GetHomepageURL().is_valid();
     88   } else if (command_id == INSPECT_POPUP) {
     89     TabContents* contents = browser_->GetSelectedTabContents();
     90     if (!contents)
     91       return false;
     92 
     93     return extension_action_->HasPopup(ExtensionTabUtil::GetTabId(contents));
     94   } else if (command_id == DISABLE || command_id == UNINSTALL) {
     95     // Some extension types can not be disabled or uninstalled.
     96     return Extension::UserMayDisable(extension->location());
     97   }
     98   return true;
     99 }
    100 
    101 bool ExtensionContextMenuModel::GetAcceleratorForCommandId(
    102     int command_id, ui::Accelerator* accelerator) {
    103   return false;
    104 }
    105 
    106 void ExtensionContextMenuModel::ExecuteCommand(int command_id) {
    107   const Extension* extension = GetExtension();
    108   if (!extension)
    109     return;
    110 
    111   switch (command_id) {
    112     case NAME: {
    113       browser_->OpenURL(extension->GetHomepageURL(), GURL(),
    114                         NEW_FOREGROUND_TAB, PageTransition::LINK);
    115       break;
    116     }
    117     case CONFIGURE:
    118       DCHECK(!extension->options_url().is_empty());
    119       profile_->GetExtensionProcessManager()->OpenOptionsPage(extension,
    120                                                               browser_);
    121       break;
    122     case HIDE: {
    123       ExtensionService* extension_service = profile_->GetExtensionService();
    124       extension_service->SetBrowserActionVisibility(extension, false);
    125       break;
    126     }
    127     case DISABLE: {
    128       ExtensionService* extension_service = profile_->GetExtensionService();
    129       extension_service->DisableExtension(extension_id_);
    130       break;
    131     }
    132     case UNINSTALL: {
    133       AddRef();  // Balanced in Accepted() and Canceled()
    134       extension_uninstall_dialog_.reset(new ExtensionUninstallDialog(profile_));
    135       extension_uninstall_dialog_->ConfirmUninstall(this, extension);
    136       break;
    137     }
    138     case MANAGE: {
    139       browser_->OpenURL(GURL(chrome::kChromeUIExtensionsURL), GURL(),
    140                         SINGLETON_TAB, PageTransition::LINK);
    141       break;
    142     }
    143     case INSPECT_POPUP: {
    144       delegate_->InspectPopup(extension_action_);
    145       break;
    146     }
    147     default:
    148      NOTREACHED() << "Unknown option";
    149      break;
    150   }
    151 }
    152 
    153 void ExtensionContextMenuModel::ExtensionDialogAccepted() {
    154   if (GetExtension())
    155     profile_->GetExtensionService()->UninstallExtension(extension_id_, false,
    156                                                         NULL);
    157 
    158   Release();
    159 }
    160 
    161 void ExtensionContextMenuModel::ExtensionDialogCanceled() {
    162   Release();
    163 }
    164 
    165 const Extension* ExtensionContextMenuModel::GetExtension() const {
    166   ExtensionService* extension_service = profile_->GetExtensionService();
    167   return extension_service->GetExtensionById(extension_id_, false);
    168 }
    169