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/apps/app_info_dialog/app_info_footer_panel.h" 6 7 #include "ash/shelf/shelf_delegate.h" 8 #include "ash/shell.h" 9 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" 12 #include "chrome/browser/ui/browser_dialogs.h" 13 #include "chrome/browser/ui/host_desktop.h" 14 #include "chrome/common/extensions/extension_constants.h" 15 #include "chrome/grit/generated_resources.h" 16 #include "extensions/browser/extension_system.h" 17 #include "extensions/browser/management_policy.h" 18 #include "extensions/browser/uninstall_reason.h" 19 #include "extensions/common/extension.h" 20 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/events/event.h" 22 #include "ui/views/controls/button/label_button.h" 23 #include "ui/views/layout/box_layout.h" 24 #include "ui/views/layout/layout_constants.h" 25 #include "ui/views/view.h" 26 #include "ui/views/widget/widget.h" 27 28 AppInfoFooterPanel::AppInfoFooterPanel(gfx::NativeWindow parent_window, 29 Profile* profile, 30 const extensions::Extension* app) 31 : AppInfoPanel(profile, app), 32 parent_window_(parent_window), 33 create_shortcuts_button_(NULL), 34 pin_to_shelf_button_(NULL), 35 unpin_from_shelf_button_(NULL), 36 remove_button_(NULL), 37 weak_ptr_factory_(this) { 38 CreateButtons(); 39 40 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 41 views::kButtonHEdgeMargin, 42 views::kButtonVEdgeMargin, 43 views::kRelatedButtonHSpacing)); 44 45 LayoutButtons(); 46 } 47 48 AppInfoFooterPanel::~AppInfoFooterPanel() { 49 } 50 51 void AppInfoFooterPanel::CreateButtons() { 52 if (CanCreateShortcuts()) { 53 create_shortcuts_button_ = new views::LabelButton( 54 this, 55 l10n_util::GetStringUTF16( 56 IDS_APPLICATION_INFO_CREATE_SHORTCUTS_BUTTON_TEXT)); 57 create_shortcuts_button_->SetStyle(views::Button::STYLE_BUTTON); 58 } 59 60 if (CanSetPinnedToShelf()) { 61 pin_to_shelf_button_ = new views::LabelButton( 62 this, l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_PIN)); 63 pin_to_shelf_button_->SetStyle(views::Button::STYLE_BUTTON); 64 unpin_from_shelf_button_ = new views::LabelButton( 65 this, l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_UNPIN)); 66 unpin_from_shelf_button_->SetStyle(views::Button::STYLE_BUTTON); 67 } 68 69 if (CanUninstallApp()) { 70 remove_button_ = new views::LabelButton( 71 this, 72 l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT)); 73 remove_button_->SetStyle(views::Button::STYLE_BUTTON); 74 } 75 } 76 77 void AppInfoFooterPanel::LayoutButtons() { 78 if (create_shortcuts_button_) 79 AddChildView(create_shortcuts_button_); 80 81 if (pin_to_shelf_button_) 82 AddChildView(pin_to_shelf_button_); 83 if (unpin_from_shelf_button_) 84 AddChildView(unpin_from_shelf_button_); 85 UpdatePinButtons(); 86 87 if (remove_button_) 88 AddChildView(remove_button_); 89 } 90 91 void AppInfoFooterPanel::UpdatePinButtons() { 92 if (pin_to_shelf_button_ && unpin_from_shelf_button_) { 93 bool is_pinned = 94 !ash::Shell::GetInstance()->GetShelfDelegate()->IsAppPinned(app_->id()); 95 pin_to_shelf_button_->SetVisible(is_pinned); 96 unpin_from_shelf_button_->SetVisible(!is_pinned); 97 } 98 } 99 100 void AppInfoFooterPanel::ButtonPressed(views::Button* sender, 101 const ui::Event& event) { 102 if (sender == create_shortcuts_button_) { 103 CreateShortcuts(); 104 } else if (sender == pin_to_shelf_button_) { 105 SetPinnedToShelf(true); 106 } else if (sender == unpin_from_shelf_button_) { 107 SetPinnedToShelf(false); 108 } else if (sender == remove_button_) { 109 UninstallApp(); 110 } else { 111 NOTREACHED(); 112 } 113 } 114 115 void AppInfoFooterPanel::ExtensionUninstallAccepted() { 116 ExtensionService* service = 117 extensions::ExtensionSystem::Get(profile_)->extension_service(); 118 service->UninstallExtension(app_->id(), 119 extensions::UNINSTALL_REASON_USER_INITIATED, 120 base::Bind(&base::DoNothing), 121 NULL); 122 123 // Close the App Info dialog as well (which will free the dialog too). 124 GetWidget()->Close(); 125 } 126 127 void AppInfoFooterPanel::ExtensionUninstallCanceled() { 128 extension_uninstall_dialog_.reset(); 129 } 130 131 void AppInfoFooterPanel::CreateShortcuts() { 132 DCHECK(CanCreateShortcuts()); 133 chrome::ShowCreateChromeAppShortcutsDialog(GetWidget()->GetNativeWindow(), 134 profile_, 135 app_, 136 base::Callback<void(bool)>()); 137 } 138 139 bool AppInfoFooterPanel::CanCreateShortcuts() const { 140 // Ash platforms can't create shortcuts. 141 return (chrome::GetHostDesktopTypeForNativeWindow(parent_window_) != 142 chrome::HOST_DESKTOP_TYPE_ASH); 143 } 144 145 void AppInfoFooterPanel::SetPinnedToShelf(bool value) { 146 DCHECK(CanSetPinnedToShelf()); 147 ash::ShelfDelegate* shelf_delegate = 148 ash::Shell::GetInstance()->GetShelfDelegate(); 149 DCHECK(shelf_delegate); 150 if (value) 151 shelf_delegate->PinAppWithID(app_->id()); 152 else 153 shelf_delegate->UnpinAppWithID(app_->id()); 154 155 UpdatePinButtons(); 156 Layout(); 157 } 158 159 bool AppInfoFooterPanel::CanSetPinnedToShelf() const { 160 // Non-Ash platforms don't have a shelf. 161 if (chrome::GetHostDesktopTypeForNativeWindow(parent_window_) != 162 chrome::HOST_DESKTOP_TYPE_ASH) { 163 return false; 164 } 165 166 // The Chrome app can't be unpinned. 167 return app_->id() != extension_misc::kChromeAppId && 168 ash::Shell::GetInstance()->GetShelfDelegate()->CanPin(); 169 } 170 171 void AppInfoFooterPanel::UninstallApp() { 172 DCHECK(CanUninstallApp()); 173 extension_uninstall_dialog_.reset( 174 extensions::ExtensionUninstallDialog::Create( 175 profile_, GetWidget()->GetNativeWindow(), this)); 176 extension_uninstall_dialog_->ConfirmUninstall(app_); 177 } 178 179 bool AppInfoFooterPanel::CanUninstallApp() const { 180 return extensions::ExtensionSystem::Get(profile_) 181 ->management_policy() 182 ->UserMayModifySettings(app_, NULL); 183 } 184