extension_uninstall_dialog_view.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright (c) 2012 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_uninstall_dialog.h" 6 7#include "base/basictypes.h" 8#include "base/compiler_specific.h" 9#include "base/strings/string_util.h" 10#include "base/strings/utf_string_conversions.h" 11#include "chrome/browser/ui/app_list/app_list_service.h" 12#include "chrome/browser/ui/browser.h" 13#include "chrome/browser/ui/browser_window.h" 14#include "chrome/browser/ui/views/constrained_window_views.h" 15#include "extensions/common/extension.h" 16#include "grit/generated_resources.h" 17#include "ui/base/l10n/l10n_util.h" 18#include "ui/compositor/compositor.h" 19#include "ui/compositor/layer.h" 20#include "ui/views/controls/image_view.h" 21#include "ui/views/controls/label.h" 22#include "ui/views/layout/layout_constants.h" 23#include "ui/views/view.h" 24#include "ui/views/widget/widget.h" 25#include "ui/views/window/dialog_delegate.h" 26 27#if defined(USE_ASH) 28#include "ash/shell.h" 29#endif 30 31namespace { 32 33const int kRightColumnWidth = 210; 34const int kIconSize = 69; 35 36class ExtensionUninstallDialogDelegateView; 37 38// Returns parent window for extension uninstall dialog. 39gfx::NativeWindow GetParent(Browser* browser) { 40 if (browser && browser->window()) 41 return browser->window()->GetNativeWindow(); 42 return NULL; 43} 44 45// Views implementation of the uninstall dialog. 46class ExtensionUninstallDialogViews : public ExtensionUninstallDialog { 47 public: 48 ExtensionUninstallDialogViews(Profile* profile, 49 Browser* browser, 50 ExtensionUninstallDialog::Delegate* delegate); 51 virtual ~ExtensionUninstallDialogViews(); 52 53 // Forwards the accept and cancels to the delegate. 54 void ExtensionUninstallAccepted(); 55 void ExtensionUninstallCanceled(); 56 57 ExtensionUninstallDialogDelegateView* view() { return view_; } 58 59 private: 60 virtual void Show() OVERRIDE; 61 62 ExtensionUninstallDialogDelegateView* view_; 63 bool show_in_app_list_; 64 65 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogViews); 66}; 67 68// The dialog's view, owned by the views framework. 69class ExtensionUninstallDialogDelegateView : public views::DialogDelegateView { 70 public: 71 ExtensionUninstallDialogDelegateView( 72 ExtensionUninstallDialogViews* dialog_view, 73 const extensions::Extension* extension, 74 const extensions::Extension* triggering_extension, 75 gfx::ImageSkia* icon); 76 virtual ~ExtensionUninstallDialogDelegateView(); 77 78 // Called when the ExtensionUninstallDialog has been destroyed to make sure 79 // we invalidate pointers. 80 void DialogDestroyed() { dialog_ = NULL; } 81 82 private: 83 // views::DialogDelegate: 84 virtual base::string16 GetDialogButtonLabel( 85 ui::DialogButton button) const OVERRIDE; 86 virtual int GetDefaultDialogButton() const OVERRIDE { 87 // Default to accept when triggered via chrome://extensions page. 88 return triggered_by_extension_ ? 89 ui::DIALOG_BUTTON_CANCEL : ui::DIALOG_BUTTON_OK; 90 } 91 virtual bool Accept() OVERRIDE; 92 virtual bool Cancel() OVERRIDE; 93 94 // views::WidgetDelegate: 95 virtual ui::ModalType GetModalType() const OVERRIDE { 96 return ui::MODAL_TYPE_WINDOW; 97 } 98 virtual base::string16 GetWindowTitle() const OVERRIDE; 99 100 // views::View: 101 virtual gfx::Size GetPreferredSize() const OVERRIDE; 102 103 virtual void Layout() OVERRIDE; 104 105 ExtensionUninstallDialogViews* dialog_; 106 107 views::ImageView* icon_; 108 views::Label* heading_; 109 bool triggered_by_extension_; 110 111 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogDelegateView); 112}; 113 114ExtensionUninstallDialogViews::ExtensionUninstallDialogViews( 115 Profile* profile, 116 Browser* browser, 117 ExtensionUninstallDialog::Delegate* delegate) 118 : ExtensionUninstallDialog(profile, browser, delegate), 119 view_(NULL), 120 show_in_app_list_(!browser) { 121} 122 123ExtensionUninstallDialogViews::~ExtensionUninstallDialogViews() { 124 // Close the widget (the views framework will delete view_). 125 if (view_) { 126 view_->DialogDestroyed(); 127 view_->GetWidget()->CloseNow(); 128 } 129} 130 131void ExtensionUninstallDialogViews::Show() { 132 // TODO(tapted): A true |desktop_type| needs to be passed in at creation time 133 // to remove reliance on GetActiveDesktop(). http://crbug.com/308360 134 gfx::NativeWindow parent = show_in_app_list_ ? 135 AppListService::Get(chrome::GetActiveDesktop())->GetAppListWindow() : 136 GetParent(browser_); 137 if (browser_ && !parent) { 138 delegate_->ExtensionUninstallCanceled(); 139 return; 140 } 141 142 view_ = new ExtensionUninstallDialogDelegateView( 143 this, extension_, triggering_extension_, &icon_); 144 CreateBrowserModalDialogViews(view_, parent)->Show(); 145} 146 147void ExtensionUninstallDialogViews::ExtensionUninstallAccepted() { 148 // The widget gets destroyed when the dialog is accepted. 149 view_ = NULL; 150 delegate_->ExtensionUninstallAccepted(); 151} 152 153void ExtensionUninstallDialogViews::ExtensionUninstallCanceled() { 154 // The widget gets destroyed when the dialog is canceled. 155 view_ = NULL; 156 delegate_->ExtensionUninstallCanceled(); 157} 158 159ExtensionUninstallDialogDelegateView::ExtensionUninstallDialogDelegateView( 160 ExtensionUninstallDialogViews* dialog_view, 161 const extensions::Extension* extension, 162 const extensions::Extension* triggering_extension, 163 gfx::ImageSkia* icon) 164 : dialog_(dialog_view), 165 triggered_by_extension_(triggering_extension != NULL) { 166 // Scale down to icon size, but allow smaller icons (don't scale up). 167 gfx::Size size(icon->width(), icon->height()); 168 if (size.width() > kIconSize || size.height() > kIconSize) 169 size = gfx::Size(kIconSize, kIconSize); 170 icon_ = new views::ImageView(); 171 icon_->SetImageSize(size); 172 icon_->SetImage(*icon); 173 AddChildView(icon_); 174 175 heading_ = new views::Label(base::UTF8ToUTF16(dialog_->GetHeadingText())); 176 heading_->SetMultiLine(true); 177 heading_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 178 AddChildView(heading_); 179} 180 181ExtensionUninstallDialogDelegateView::~ExtensionUninstallDialogDelegateView() { 182} 183 184base::string16 ExtensionUninstallDialogDelegateView::GetDialogButtonLabel( 185 ui::DialogButton button) const { 186 return l10n_util::GetStringUTF16((button == ui::DIALOG_BUTTON_OK) ? 187 IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON : IDS_CANCEL); 188} 189 190bool ExtensionUninstallDialogDelegateView::Accept() { 191 if (dialog_) 192 dialog_->ExtensionUninstallAccepted(); 193 return true; 194} 195 196bool ExtensionUninstallDialogDelegateView::Cancel() { 197 if (dialog_) 198 dialog_->ExtensionUninstallCanceled(); 199 return true; 200} 201 202base::string16 ExtensionUninstallDialogDelegateView::GetWindowTitle() const { 203 return l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_TITLE); 204} 205 206gfx::Size ExtensionUninstallDialogDelegateView::GetPreferredSize() const { 207 int width = kRightColumnWidth; 208 width += kIconSize; 209 width += views::kButtonHEdgeMarginNew * 2; 210 width += views::kRelatedControlHorizontalSpacing; 211 212 int height = views::kPanelVertMargin * 2; 213 height += heading_->GetHeightForWidth(kRightColumnWidth); 214 215 return gfx::Size(width, 216 std::max(height, kIconSize + views::kPanelVertMargin * 2)); 217} 218 219void ExtensionUninstallDialogDelegateView::Layout() { 220 int x = views::kButtonHEdgeMarginNew; 221 int y = views::kPanelVertMargin; 222 223 heading_->SizeToFit(kRightColumnWidth); 224 225 if (heading_->height() <= kIconSize) { 226 icon_->SetBounds(x, y, kIconSize, kIconSize); 227 x += kIconSize; 228 x += views::kRelatedControlHorizontalSpacing; 229 230 heading_->SetX(x); 231 heading_->SetY(y + (kIconSize - heading_->height()) / 2); 232 } else { 233 icon_->SetBounds(x, 234 y + (heading_->height() - kIconSize) / 2, 235 kIconSize, 236 kIconSize); 237 x += kIconSize; 238 x += views::kRelatedControlHorizontalSpacing; 239 240 heading_->SetX(x); 241 heading_->SetY(y); 242 } 243} 244 245} // namespace 246 247// static 248ExtensionUninstallDialog* ExtensionUninstallDialog::Create( 249 Profile* profile, 250 Browser* browser, 251 Delegate* delegate) { 252 return new ExtensionUninstallDialogViews(profile, browser, delegate); 253} 254