Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / download / download_danger_prompt_views.cc
blob8f01728b6a6e044a1561526e4bae046e3bf635a3
1 // Copyright 2013 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.
5 #include "base/compiler_specific.h"
6 #include "chrome/browser/download/download_danger_prompt.h"
7 #include "chrome/browser/download/download_stats.h"
8 #include "chrome/browser/ui/views/constrained_window_views.h"
9 #include "components/web_modal/web_contents_modal_dialog_host.h"
10 #include "components/web_modal/web_contents_modal_dialog_manager.h"
11 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/download_danger_type.h"
14 #include "content/public/browser/download_item.h"
15 #include "content/public/browser/web_contents.h"
16 #include "grit/chromium_strings.h"
17 #include "grit/generated_resources.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/views/controls/button/label_button.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/grid_layout.h"
22 #include "ui/views/view.h"
23 #include "ui/views/widget/widget.h"
24 #include "ui/views/window/dialog_client_view.h"
25 #include "ui/views/window/dialog_delegate.h"
27 using content::BrowserThread;
28 using web_modal::WebContentsModalDialogManager;
29 using web_modal::WebContentsModalDialogManagerDelegate;
31 namespace {
33 const int kMessageWidth = 320;
34 const int kParagraphPadding = 15;
36 // Views-specific implementation of download danger prompt dialog. We use this
37 // class rather than a TabModalConfirmDialog so that we can use custom
38 // formatting on the text in the body of the dialog.
39 class DownloadDangerPromptViews : public DownloadDangerPrompt,
40 public content::DownloadItem::Observer,
41 public views::DialogDelegate {
42 public:
43 DownloadDangerPromptViews(content::DownloadItem* item,
44 content::WebContents* web_contents,
45 bool show_context,
46 const OnDone& done);
48 // DownloadDangerPrompt methods:
49 virtual void InvokeActionForTesting(Action action) OVERRIDE;
51 // views::DialogDelegate methods:
52 virtual base::string16 GetDialogButtonLabel(
53 ui::DialogButton button) const OVERRIDE;
54 virtual base::string16 GetWindowTitle() const OVERRIDE;
55 virtual void DeleteDelegate() OVERRIDE;
56 virtual ui::ModalType GetModalType() const OVERRIDE;
57 virtual bool Cancel() OVERRIDE;
58 virtual bool Accept() OVERRIDE;
59 virtual bool Close() OVERRIDE;
60 // TODO(wittman): Remove this override once we move to the new style frame
61 // view on all dialogs.
62 virtual views::NonClientFrameView* CreateNonClientFrameView(
63 views::Widget* widget) OVERRIDE;
64 virtual views::View* GetInitiallyFocusedView() OVERRIDE;
65 virtual views::View* GetContentsView() OVERRIDE;
66 virtual views::Widget* GetWidget() OVERRIDE;
67 virtual const views::Widget* GetWidget() const OVERRIDE;
69 // content::DownloadItem::Observer:
70 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
72 private:
73 base::string16 GetAcceptButtonTitle() const;
74 base::string16 GetCancelButtonTitle() const;
75 // The message lead is separated from the main text and is bolded.
76 base::string16 GetMessageLead() const;
77 base::string16 GetMessageBody() const;
78 void RunDone(Action action);
80 content::DownloadItem* download_;
81 content::WebContents* web_contents_;
82 bool show_context_;
83 OnDone done_;
85 views::View* contents_view_;
88 DownloadDangerPromptViews::DownloadDangerPromptViews(
89 content::DownloadItem* item,
90 content::WebContents* web_contents,
91 bool show_context,
92 const OnDone& done)
93 : download_(item),
94 web_contents_(web_contents),
95 show_context_(show_context),
96 done_(done),
97 contents_view_(NULL) {
98 DCHECK(!done_.is_null());
99 download_->AddObserver(this);
101 contents_view_ = new views::View;
103 views::GridLayout* layout = views::GridLayout::CreatePanel(contents_view_);
104 contents_view_->SetLayoutManager(layout);
106 views::ColumnSet* column_set = layout->AddColumnSet(0);
107 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
108 views::GridLayout::FIXED, kMessageWidth, 0);
110 const base::string16 message_lead = GetMessageLead();
112 if (!message_lead.empty()) {
113 views::Label* message_lead_label = new views::Label(message_lead);
114 message_lead_label->SetMultiLine(true);
115 message_lead_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
116 message_lead_label->SetAllowCharacterBreak(true);
118 gfx::FontList font_list(gfx::Font().DeriveFont(0, gfx::Font::BOLD));
119 message_lead_label->SetFontList(font_list);
121 layout->StartRow(0, 0);
122 layout->AddView(message_lead_label);
124 layout->AddPaddingRow(0, kParagraphPadding);
127 views::Label* message_body_label = new views::Label(GetMessageBody());
128 message_body_label->SetMultiLine(true);
129 message_body_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
130 message_body_label->SetAllowCharacterBreak(true);
132 layout->StartRow(0, 0);
133 layout->AddView(message_body_label);
135 RecordOpenedDangerousConfirmDialog(download_->GetDangerType());
138 // DownloadDangerPrompt methods:
139 void DownloadDangerPromptViews::InvokeActionForTesting(Action action) {
140 switch (action) {
141 case ACCEPT:
142 Accept();
143 break;
145 case CANCEL:
146 case DISMISS:
147 Cancel();
148 break;
150 default:
151 NOTREACHED();
152 break;
156 // views::DialogDelegate methods:
157 base::string16 DownloadDangerPromptViews::GetDialogButtonLabel(
158 ui::DialogButton button) const {
159 switch (button) {
160 case ui::DIALOG_BUTTON_OK:
161 return GetAcceptButtonTitle();
163 case ui::DIALOG_BUTTON_CANCEL:
164 return GetCancelButtonTitle();
166 default:
167 return DialogDelegate::GetDialogButtonLabel(button);
171 base::string16 DownloadDangerPromptViews::GetWindowTitle() const {
172 if (show_context_)
173 return l10n_util::GetStringUTF16(IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE);
174 else
175 return l10n_util::GetStringUTF16(IDS_RESTORE_KEEP_DANGEROUS_DOWNLOAD_TITLE);
178 void DownloadDangerPromptViews::DeleteDelegate() {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
181 delete this;
184 ui::ModalType DownloadDangerPromptViews::GetModalType() const {
185 #if defined(USE_ASH)
186 return ui::MODAL_TYPE_CHILD;
187 #else
188 return views::WidgetDelegate::GetModalType();
189 #endif
192 bool DownloadDangerPromptViews::Cancel() {
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 RunDone(CANCEL);
196 return true;
199 bool DownloadDangerPromptViews::Accept() {
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
202 RunDone(ACCEPT);
203 return true;
206 bool DownloadDangerPromptViews::Close() {
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 RunDone(DISMISS);
210 return true;
213 // TODO(wittman): Remove this override once we move to the new style frame
214 // view on all dialogs.
215 views::NonClientFrameView* DownloadDangerPromptViews::CreateNonClientFrameView(
216 views::Widget* widget) {
217 return CreateConstrainedStyleNonClientFrameView(
218 widget, web_contents_->GetBrowserContext());
221 views::View* DownloadDangerPromptViews::GetInitiallyFocusedView() {
222 return GetDialogClientView()->cancel_button();
225 views::View* DownloadDangerPromptViews::GetContentsView() {
226 return contents_view_;
229 views::Widget* DownloadDangerPromptViews::GetWidget() {
230 return contents_view_->GetWidget();
233 const views::Widget* DownloadDangerPromptViews::GetWidget() const {
234 return contents_view_->GetWidget();
237 // content::DownloadItem::Observer:
238 void DownloadDangerPromptViews::OnDownloadUpdated(
239 content::DownloadItem* download) {
240 // If the download is nolonger dangerous (accepted externally) or the download
241 // is in a terminal state, then the download danger prompt is no longer
242 // necessary.
243 if (!download_->IsDangerous() || download_->IsDone()) {
244 RunDone(DISMISS);
245 Cancel();
249 base::string16 DownloadDangerPromptViews::GetAcceptButtonTitle() const {
250 if (show_context_)
251 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD);
252 switch (download_->GetDangerType()) {
253 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
254 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
255 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
256 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD_AGAIN_MALICIOUS);
258 default:
259 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD_AGAIN);
263 base::string16 DownloadDangerPromptViews::GetCancelButtonTitle() const {
264 if (show_context_)
265 return l10n_util::GetStringUTF16(IDS_CANCEL);
266 switch (download_->GetDangerType()) {
267 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
268 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
269 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
270 return l10n_util::GetStringUTF16(IDS_CONFIRM_CANCEL_AGAIN_MALICIOUS);
272 default:
273 return l10n_util::GetStringUTF16(IDS_CANCEL);
277 base::string16 DownloadDangerPromptViews::GetMessageLead() const {
278 if (!show_context_) {
279 switch (download_->GetDangerType()) {
280 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
281 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
282 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
283 return l10n_util::GetStringUTF16(
284 IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_LEAD);
286 default:
287 break;
291 return base::string16();
294 base::string16 DownloadDangerPromptViews::GetMessageBody() const {
295 if (show_context_) {
296 switch (download_->GetDangerType()) {
297 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: {
298 return l10n_util::GetStringFUTF16(
299 IDS_PROMPT_DANGEROUS_DOWNLOAD,
300 download_->GetFileNameToReportUser().LossyDisplayName());
302 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: // Fall through
303 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
304 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
305 return l10n_util::GetStringFUTF16(
306 IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT,
307 download_->GetFileNameToReportUser().LossyDisplayName());
309 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: {
310 return l10n_util::GetStringFUTF16(
311 IDS_PROMPT_UNCOMMON_DOWNLOAD_CONTENT,
312 download_->GetFileNameToReportUser().LossyDisplayName());
314 case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
315 return l10n_util::GetStringFUTF16(
316 IDS_PROMPT_DOWNLOAD_CHANGES_SETTINGS,
317 download_->GetFileNameToReportUser().LossyDisplayName());
319 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
320 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
321 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
322 case content::DOWNLOAD_DANGER_TYPE_MAX: {
323 break;
326 } else {
327 switch (download_->GetDangerType()) {
328 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
329 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
330 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
331 return l10n_util::GetStringUTF16(
332 IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_BODY);
334 default: {
335 return l10n_util::GetStringUTF16(
336 IDS_PROMPT_CONFIRM_KEEP_DANGEROUS_DOWNLOAD);
340 NOTREACHED();
341 return base::string16();
344 void DownloadDangerPromptViews::RunDone(Action action) {
345 // Invoking the callback can cause the download item state to change or cause
346 // the window to close, and |callback| refers to a member variable.
347 OnDone done = done_;
348 done_.Reset();
349 if (download_ != NULL) {
350 download_->RemoveObserver(this);
351 download_ = NULL;
353 if (!done.is_null())
354 done.Run(action);
357 } // namespace
359 DownloadDangerPrompt* DownloadDangerPrompt::Create(
360 content::DownloadItem* item,
361 content::WebContents* web_contents,
362 bool show_context,
363 const OnDone& done) {
364 DownloadDangerPromptViews* download_danger_prompt =
365 new DownloadDangerPromptViews(item, web_contents, show_context, done);
367 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
368 WebContentsModalDialogManager::FromWebContents(web_contents);
369 WebContentsModalDialogManagerDelegate* modal_delegate =
370 web_contents_modal_dialog_manager->delegate();
371 CHECK(modal_delegate);
372 views::Widget* dialog = views::Widget::CreateWindowAsFramelessChild(
373 download_danger_prompt,
374 modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
375 web_contents_modal_dialog_manager->ShowDialog(dialog->GetNativeView());
377 return download_danger_prompt;