Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(915)

Side by Side Diff: chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc

Issue 7920023: Fix crashes related to the extension uninstall dialog. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/compiler_specific.h" 6 #include "base/compiler_specific.h"
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_uninstall_dialog.h" 9 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
10 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/browser_list.h" 11 #include "chrome/browser/ui/browser_list.h"
12 #include "chrome/browser/ui/browser_window.h" 12 #include "chrome/browser/ui/browser_window.h"
13 #include "chrome/browser/ui/views/window.h" 13 #include "chrome/browser/ui/views/window.h"
14 #include "chrome/common/extensions/extension.h" 14 #include "chrome/common/extensions/extension.h"
15 #include "grit/generated_resources.h" 15 #include "grit/generated_resources.h"
16 #include "ui/base/l10n/l10n_util.h" 16 #include "ui/base/l10n/l10n_util.h"
17 #include "views/controls/image_view.h" 17 #include "views/controls/image_view.h"
18 #include "views/controls/label.h" 18 #include "views/controls/label.h"
19 #include "views/layout/layout_constants.h" 19 #include "views/layout/layout_constants.h"
20 #include "views/view.h" 20 #include "views/view.h"
21 #include "views/widget/widget.h" 21 #include "views/widget/widget.h"
22 #include "views/window/dialog_delegate.h" 22 #include "views/window/dialog_delegate.h"
23 23
24 namespace { 24 namespace {
25 25
26 const int kRightColumnWidth = 210; 26 const int kRightColumnWidth = 210;
27 const int kIconSize = 69; 27 const int kIconSize = 69;
28 28
29 class ExtensionUninstallDialogView : public views::DialogDelegateView { 29 class ExtensionUninstallDialogDelegateView;
30
31 // The ExtensionUninstallDialog implementation for the views framework. This
32 // connects the ExtensionUninstallUI::Delegate to the actual widget, reconciling
33 // the two life cycles.
34 class ExtensionUninstallDialogViews : public ExtensionUninstallDialog {
30 public: 35 public:
31 ExtensionUninstallDialogView(ExtensionUninstallDialog::Delegate* delegate, 36 ExtensionUninstallDialogViews(Profile* profile,
32 const Extension* extension, 37 ExtensionUninstallUI::Delegate* delegate,
33 SkBitmap* icon) 38 const Extension* extension,
34 : delegate_(delegate), 39 SkBitmap* icon);
35 icon_(NULL) { 40 virtual ~ExtensionUninstallDialogViews();
36 // Scale down to icon size, but allow smaller icons (don't scale up). 41
37 gfx::Size size(icon->width(), icon->height()); 42 // Forwards the accept and cancels to the delegate.
38 if (size.width() > kIconSize || size.height() > kIconSize) 43 void ExtensionUninstallAccepted();
39 size = gfx::Size(kIconSize, kIconSize); 44 void ExtensionUninstallCanceled();
40 icon_ = new views::ImageView(); 45
41 icon_->SetImageSize(size); 46 ExtensionUninstallDialogDelegateView* view() { return view_; }
42 icon_->SetImage(*icon);
43 AddChildView(icon_);
44
45 heading_ = new views::Label(UTF16ToWide(
46 l10n_util::GetStringFUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_HEADING,
47 UTF8ToUTF16(extension->name()))));
48 heading_->SetMultiLine(true);
49 heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
50 AddChildView(heading_);
51 }
52 47
53 private: 48 private:
49 ExtensionUninstallUI::Delegate* delegate_;
50 ExtensionUninstallDialogDelegateView* view_;
51
52 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogViews);
53 };
54
55 // This class display the uninstall widget and is owned by the views framework.
56 class ExtensionUninstallDialogDelegateView : public views::DialogDelegateView {
57 public:
58 ExtensionUninstallDialogDelegateView(
59 ExtensionUninstallDialogViews* dialog_view,
60 const Extension* extension,
61 SkBitmap* icon);
62 virtual ~ExtensionUninstallDialogDelegateView();
63
64 // Called when the dialog and delegate have been destroyed to make sure
65 // that we don't callback to an invalid pointer.
66 void DialogDestroyed() { dialog_ = NULL; }
67
68 private:
69 ExtensionUninstallDialogViews* dialog_;
70
54 // views::DialogDelegate: 71 // views::DialogDelegate:
55 virtual std::wstring GetDialogButtonLabel( 72 virtual std::wstring GetDialogButtonLabel(
56 MessageBoxFlags::DialogButton button) const OVERRIDE { 73 MessageBoxFlags::DialogButton button) const OVERRIDE;
57 switch (button) {
58 case MessageBoxFlags::DIALOGBUTTON_OK:
59 return UTF16ToWide(
60 l10n_util::GetStringUTF16(
61 IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON));
62 case MessageBoxFlags::DIALOGBUTTON_CANCEL:
63 return UTF16ToWide(l10n_util::GetStringUTF16(IDS_CANCEL));
64 default:
65 NOTREACHED();
66 return L"";
67 }
68 }
69 74
70 virtual int GetDefaultDialogButton() const OVERRIDE { 75 virtual int GetDefaultDialogButton() const OVERRIDE {
71 return MessageBoxFlags::DIALOGBUTTON_CANCEL; 76 return MessageBoxFlags::DIALOGBUTTON_CANCEL;
72 } 77 }
73 78
74 virtual bool Accept() OVERRIDE { 79 virtual bool Accept() OVERRIDE;
75 delegate_->ExtensionDialogAccepted(); 80 virtual bool Cancel() OVERRIDE;
76 return true;
77 }
78
79 virtual bool Cancel() OVERRIDE {
80 delegate_->ExtensionDialogCanceled();
81 return true;
82 }
83 81
84 // views::WindowDelegate: 82 // views::WindowDelegate:
85 virtual bool IsModal() const OVERRIDE { return true; } 83 virtual bool IsModal() const OVERRIDE { return true; }
86 virtual std::wstring GetWindowTitle() const OVERRIDE {
87 return UTF16ToWide(
88 l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_TITLE));
89 }
90 virtual views::View* GetContentsView() { return this; } 84 virtual views::View* GetContentsView() { return this; }
85 virtual std::wstring GetWindowTitle() const OVERRIDE;
91 86
92 // views::View: 87 // views::View:
93 virtual gfx::Size GetPreferredSize() OVERRIDE { 88 virtual gfx::Size GetPreferredSize() OVERRIDE;
94 int width = kRightColumnWidth; 89
95 width += kIconSize; 90 virtual void Layout() OVERRIDE;
96 width += views::kPanelHorizMargin * 3; 91
97
98 int height = views::kPanelVertMargin * 2;
99 height += heading_->GetHeightForWidth(kRightColumnWidth);
100
101 return gfx::Size(width,
102 std::max(height, kIconSize + views::kPanelVertMargin * 2));
103 }
104
105 virtual void Layout() OVERRIDE {
106 int x = views::kPanelHorizMargin;
107 int y = views::kPanelVertMargin;
108
109 heading_->SizeToFit(kRightColumnWidth);
110
111 if (heading_->height() <= kIconSize) {
112 icon_->SetBounds(x, y, kIconSize, kIconSize);
113 x += kIconSize;
114 x += views::kPanelHorizMargin;
115
116 heading_->SetX(x);
117 heading_->SetY(y + (kIconSize - heading_->height()) / 2);
118 } else {
119 icon_->SetBounds(x,
120 y + (heading_->height() - kIconSize) / 2,
121 kIconSize,
122 kIconSize);
123 x += kIconSize;
124 x += views::kPanelHorizMargin;
125
126 heading_->SetX(x);
127 heading_->SetY(y);
128 }
129 }
130
131 ExtensionUninstallDialog::Delegate* delegate_;
132 views::ImageView* icon_; 92 views::ImageView* icon_;
133 views::Label* heading_; 93 views::Label* heading_;
134 94
135 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogView); 95 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogDelegateView);
136 }; 96 };
137 97
98 ExtensionUninstallDialogViews::ExtensionUninstallDialogViews(
99 Profile* profile,
100 ExtensionUninstallUI::Delegate* delegate,
101 const Extension* extension,
102 SkBitmap* icon)
103 : delegate_(delegate),
104 ExtensionUninstallDialog(profile, delegate, extension, icon) {
105 view_ = new ExtensionUninstallDialogDelegateView(this, extension, icon);
106 }
107
108 ExtensionUninstallDialogViews::~ExtensionUninstallDialogViews() {
109 // Close the widget. The views framework will delete views_.
110 if (view_) {
111 view_->DialogDestroyed();
112 view_->GetWidget()->CloseNow();
113 }
114 }
115
116 void ExtensionUninstallDialogViews::ExtensionUninstallAccepted() {
117 // The widget gets destroyed when the dialog is accepted.
118 view_ = NULL;
119
120 delegate_->ExtensionUninstallAccepted();
121 }
122
123 void ExtensionUninstallDialogViews::ExtensionUninstallCanceled() {
124 // The widget gets destroyed when the dialog is canceled.
125 view_ = NULL;
126
127 delegate_->ExtensionUninstallCanceled();
128 }
129
130 ExtensionUninstallDialogDelegateView::ExtensionUninstallDialogDelegateView(
131 ExtensionUninstallDialogViews* dialog_view,
132 const Extension* extension,
133 SkBitmap* icon)
134 : dialog_(dialog_view) {
135 // Scale down to icon size, but allow smaller icons (don't scale up).
136 gfx::Size size(icon->width(), icon->height());
137 if (size.width() > kIconSize || size.height() > kIconSize)
138 size = gfx::Size(kIconSize, kIconSize);
139 icon_ = new views::ImageView();
140 icon_->SetImageSize(size);
141 icon_->SetImage(*icon);
142 AddChildView(icon_);
143
144 heading_ = new views::Label(UTF16ToWide(
145 l10n_util::GetStringFUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_HEADING,
146 UTF8ToUTF16(extension->name()))));
147 heading_->SetMultiLine(true);
148 AddChildView(heading_);
149 }
150
151 ExtensionUninstallDialogDelegateView::~ExtensionUninstallDialogDelegateView() {
152 }
153
154 std::wstring ExtensionUninstallDialogDelegateView::GetDialogButtonLabel(
155 MessageBoxFlags::DialogButton button) const {
156 switch (button) {
157 case MessageBoxFlags::DIALOGBUTTON_OK:
158 return UTF16ToWide(
159 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON));
160 case MessageBoxFlags::DIALOGBUTTON_CANCEL:
161 return UTF16ToWide(l10n_util::GetStringUTF16(IDS_CANCEL));
162 default:
163 NOTREACHED();
164 return L"";
165 }
166 }
167
168 bool ExtensionUninstallDialogDelegateView::Accept() {
169 if (dialog_)
170 dialog_->ExtensionUninstallAccepted();
171 return true;
172 }
173
174 bool ExtensionUninstallDialogDelegateView::Cancel() {
175 if (dialog_)
176 dialog_->ExtensionUninstallCanceled();
177 return true;
178 }
179
180 std::wstring ExtensionUninstallDialogDelegateView::GetWindowTitle() const {
181 return UTF16ToWide(
182 l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_TITLE));
183 }
184
185
186 gfx::Size ExtensionUninstallDialogDelegateView::GetPreferredSize() {
187 int width = kRightColumnWidth;
188 width += kIconSize;
189 width += views::kPanelHorizMargin * 3;
190
191 int height = views::kPanelVertMargin * 2;
192 height += heading_->GetHeightForWidth(kRightColumnWidth);
193
194 return gfx::Size(width,
195 std::max(height, kIconSize + views::kPanelVertMargin * 2));
196 }
197
198 void ExtensionUninstallDialogDelegateView::Layout() {
199 int x = views::kPanelHorizMargin;
200 int y = views::kPanelVertMargin;
201
202 heading_->SizeToFit(kRightColumnWidth);
203
204 if (heading_->height() <= kIconSize) {
205 icon_->SetBounds(x, y, kIconSize, kIconSize);
206 x += kIconSize;
207 x += views::kPanelHorizMargin;
208
209 heading_->SetX(x);
210 heading_->SetY(y + (kIconSize - heading_->height()) / 2);
211 } else {
212 icon_->SetBounds(x,
213 y + (heading_->height() - kIconSize) / 2,
214 kIconSize,
215 kIconSize);
216 x += kIconSize;
217 x += views::kPanelHorizMargin;
218
219 heading_->SetX(x);
220 heading_->SetY(y);
221 }
222 }
223
138 } // namespace 224 } // namespace
139 225
140 // static 226 // static
141 void ExtensionUninstallDialog::Show( 227 void ExtensionUninstallUI::ShowDialog() {
142 Profile* profile, 228 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
143 ExtensionUninstallDialog::Delegate* delegate,
144 const Extension* extension,
145 SkBitmap* icon) {
146 Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
147 if (!browser) { 229 if (!browser) {
148 delegate->ExtensionDialogCanceled(); 230 delegate_->ExtensionUninstallCanceled();
149 return; 231 return;
150 } 232 }
151 233
152 BrowserWindow* window = browser->window(); 234 BrowserWindow* window = browser->window();
153 if (!window) { 235 if (!window) {
154 delegate->ExtensionDialogCanceled(); 236 delegate_->ExtensionUninstallCanceled();
155 return; 237 return;
156 } 238 }
157 239
158 browser::CreateViewsWindow(window->GetNativeHandle(), 240 ExtensionUninstallDialogViews* dialog = new ExtensionUninstallDialogViews(
159 new ExtensionUninstallDialogView(delegate, extension, icon))->Show(); 241 profile_, delegate_, extension_, &icon_);
160 } 242 browser::CreateViewsWindow(window->GetNativeHandle(), dialog->view())->Show();
243 uninstall_dialog_.reset(dialog);
244 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698