extension_uninstall_dialog_view.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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 "chrome/common/extensions/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// TODO(estade): remove this when UseNewStyle() is the default. 39int HorizontalMargin() { 40 return views::DialogDelegate::UseNewStyle() ? views::kButtonHEdgeMarginNew : 41 views::kPanelHorizMargin; 42} 43 44// Returns parent window for extension uninstall dialog. 45gfx::NativeWindow GetParent(Browser* browser) { 46 if (browser && browser->window()) 47 return browser->window()->GetNativeWindow(); 48 return NULL; 49} 50 51// Views implementation of the uninstall dialog. 52class ExtensionUninstallDialogViews : public ExtensionUninstallDialog { 53 public: 54 ExtensionUninstallDialogViews(Profile* profile, 55 Browser* browser, 56 ExtensionUninstallDialog::Delegate* delegate); 57 virtual ~ExtensionUninstallDialogViews(); 58 59 // Forwards the accept and cancels to the delegate. 60 void ExtensionUninstallAccepted(); 61 void ExtensionUninstallCanceled(); 62 63 ExtensionUninstallDialogDelegateView* view() { return view_; } 64 65 private: 66 virtual void Show() OVERRIDE; 67 68 ExtensionUninstallDialogDelegateView* view_; 69 bool show_in_app_list_; 70 71 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogViews); 72}; 73 74// The dialog's view, owned by the views framework. 75class ExtensionUninstallDialogDelegateView : public views::DialogDelegateView { 76 public: 77 ExtensionUninstallDialogDelegateView( 78 ExtensionUninstallDialogViews* dialog_view, 79 const extensions::Extension* extension, 80 gfx::ImageSkia* icon); 81 virtual ~ExtensionUninstallDialogDelegateView(); 82 83 // Called when the ExtensionUninstallDialog has been destroyed to make sure 84 // we invalidate pointers. 85 void DialogDestroyed() { dialog_ = NULL; } 86 87 private: 88 // views::DialogDelegate: 89 virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE; 90 virtual int GetDefaultDialogButton() const OVERRIDE { 91 return ui::DIALOG_BUTTON_CANCEL; 92 } 93 virtual bool Accept() OVERRIDE; 94 virtual bool Cancel() OVERRIDE; 95 96 // views::WidgetDelegate: 97 virtual ui::ModalType GetModalType() const OVERRIDE { 98 return ui::MODAL_TYPE_WINDOW; 99 } 100 virtual string16 GetWindowTitle() const OVERRIDE; 101 102 // views::View: 103 virtual gfx::Size GetPreferredSize() OVERRIDE; 104 105 virtual void Layout() OVERRIDE; 106 107 ExtensionUninstallDialogViews* dialog_; 108 109 views::ImageView* icon_; 110 views::Label* heading_; 111 112 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogDelegateView); 113}; 114 115ExtensionUninstallDialogViews::ExtensionUninstallDialogViews( 116 Profile* profile, 117 Browser* browser, 118 ExtensionUninstallDialog::Delegate* delegate) 119 : ExtensionUninstallDialog(profile, browser, delegate), 120 view_(NULL), 121 show_in_app_list_(!browser) { 122} 123 124ExtensionUninstallDialogViews::~ExtensionUninstallDialogViews() { 125 // Close the widget (the views framework will delete view_). 126 if (view_) { 127 view_->DialogDestroyed(); 128 view_->GetWidget()->CloseNow(); 129 } 130} 131 132void ExtensionUninstallDialogViews::Show() { 133 // TODO(tapted): A true |desktop_type| needs to be passed in at creation time 134 // to remove reliance on GetActiveDesktop(). http://crbug.com/308360 135 gfx::NativeWindow parent = show_in_app_list_ ? 136 AppListService::Get(chrome::GetActiveDesktop())->GetAppListWindow() : 137 GetParent(browser_); 138 if (browser_ && !parent) { 139 delegate_->ExtensionUninstallCanceled(); 140 return; 141 } 142 143 view_ = new ExtensionUninstallDialogDelegateView(this, 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 gfx::ImageSkia* icon) 163 : dialog_(dialog_view) { 164 // Scale down to icon size, but allow smaller icons (don't scale up). 165 gfx::Size size(icon->width(), icon->height()); 166 if (size.width() > kIconSize || size.height() > kIconSize) 167 size = gfx::Size(kIconSize, kIconSize); 168 icon_ = new views::ImageView(); 169 icon_->SetImageSize(size); 170 icon_->SetImage(*icon); 171 AddChildView(icon_); 172 173 heading_ = new views::Label( 174 l10n_util::GetStringFUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_HEADING, 175 UTF8ToUTF16(extension->name()))); 176 heading_->SetMultiLine(true); 177 AddChildView(heading_); 178} 179 180ExtensionUninstallDialogDelegateView::~ExtensionUninstallDialogDelegateView() { 181} 182 183string16 ExtensionUninstallDialogDelegateView::GetDialogButtonLabel( 184 ui::DialogButton button) const { 185 return l10n_util::GetStringUTF16((button == ui::DIALOG_BUTTON_OK) ? 186 IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON : IDS_CANCEL); 187} 188 189bool ExtensionUninstallDialogDelegateView::Accept() { 190 if (dialog_) 191 dialog_->ExtensionUninstallAccepted(); 192 return true; 193} 194 195bool ExtensionUninstallDialogDelegateView::Cancel() { 196 if (dialog_) 197 dialog_->ExtensionUninstallCanceled(); 198 return true; 199} 200 201string16 ExtensionUninstallDialogDelegateView::GetWindowTitle() const { 202 return l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_TITLE); 203} 204 205gfx::Size ExtensionUninstallDialogDelegateView::GetPreferredSize() { 206 int width = kRightColumnWidth; 207 width += kIconSize; 208 width += HorizontalMargin() * 2; 209 width += views::kRelatedControlHorizontalSpacing; 210 211 int height = views::kPanelVertMargin * 2; 212 height += heading_->GetHeightForWidth(kRightColumnWidth); 213 214 return gfx::Size(width, 215 std::max(height, kIconSize + views::kPanelVertMargin * 2)); 216} 217 218void ExtensionUninstallDialogDelegateView::Layout() { 219 int x = HorizontalMargin(); 220 int y = views::kPanelVertMargin; 221 222 heading_->SizeToFit(kRightColumnWidth); 223 224 if (heading_->height() <= kIconSize) { 225 icon_->SetBounds(x, y, kIconSize, kIconSize); 226 x += kIconSize; 227 x += views::kRelatedControlHorizontalSpacing; 228 229 heading_->SetX(x); 230 heading_->SetY(y + (kIconSize - heading_->height()) / 2); 231 } else { 232 icon_->SetBounds(x, 233 y + (heading_->height() - kIconSize) / 2, 234 kIconSize, 235 kIconSize); 236 x += kIconSize; 237 x += views::kRelatedControlHorizontalSpacing; 238 239 heading_->SetX(x); 240 heading_->SetY(y); 241 } 242} 243 244} // namespace 245 246// static 247ExtensionUninstallDialog* ExtensionUninstallDialog::Create( 248 Profile* profile, 249 Browser* browser, 250 Delegate* delegate) { 251 return new ExtensionUninstallDialogViews(profile, browser, delegate); 252} 253