OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/ui/views/download/download_item_view.h" | 5 #include "chrome/browser/ui/views/download/download_item_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 // TODO(paulg): These may need to be adjusted when download progress | 42 // TODO(paulg): These may need to be adjusted when download progress |
43 // animation is added, and also possibly to take into account | 43 // animation is added, and also possibly to take into account |
44 // different screen resolutions. | 44 // different screen resolutions. |
45 static const int kTextWidth = 140; // Pixels | 45 static const int kTextWidth = 140; // Pixels |
46 static const int kDangerousTextWidth = 200; // Pixels | 46 static const int kDangerousTextWidth = 200; // Pixels |
47 static const int kHorizontalTextPadding = 2; // Pixels | 47 static const int kHorizontalTextPadding = 2; // Pixels |
48 static const int kVerticalPadding = 3; // Pixels | 48 static const int kVerticalPadding = 3; // Pixels |
49 static const int kVerticalTextSpacer = 2; // Pixels | 49 static const int kVerticalTextSpacer = 2; // Pixels |
50 static const int kVerticalTextPadding = 2; // Pixels | 50 static const int kVerticalTextPadding = 2; // Pixels |
51 | 51 |
52 // The maximum number of characters we show in a file name when displaying the | |
53 // dangerous download message. | |
54 static const int kFileNameMaxLength = 20; | |
55 | |
56 // We add some padding before the left image so that the progress animation icon | 52 // We add some padding before the left image so that the progress animation icon |
57 // hides the corners of the left image. | 53 // hides the corners of the left image. |
58 static const int kLeftPadding = 0; // Pixels. | 54 static const int kLeftPadding = 0; // Pixels. |
59 | 55 |
60 // The space between the Save and Discard buttons when prompting for a dangerous | 56 // The space between the Save and Discard buttons when prompting for a dangerous |
61 // download. | 57 // download. |
62 static const int kButtonPadding = 5; // Pixels. | 58 static const int kButtonPadding = 5; // Pixels. |
63 | 59 |
64 // The space on the left and right side of the dangerous download label. | 60 // The space on the left and right side of the dangerous download label. |
65 static const int kLabelPadding = 4; // Pixels. | 61 static const int kLabelPadding = 4; // Pixels. |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 if (download_util::kSmallProgressIconSize > box_height_) | 194 if (download_util::kSmallProgressIconSize > box_height_) |
199 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; | 195 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; |
200 else | 196 else |
201 box_y_ = kVerticalPadding; | 197 box_y_ = kVerticalPadding; |
202 | 198 |
203 body_hover_animation_.reset(new ui::SlideAnimation(this)); | 199 body_hover_animation_.reset(new ui::SlideAnimation(this)); |
204 drop_hover_animation_.reset(new ui::SlideAnimation(this)); | 200 drop_hover_animation_.reset(new ui::SlideAnimation(this)); |
205 | 201 |
206 UpdateDropDownButtonPosition(); | 202 UpdateDropDownButtonPosition(); |
207 | 203 |
208 if (download->GetSafetyState() == DownloadItem::DANGEROUS) | 204 if (model_->IsDangerous()) |
209 ShowWarningDialog(); | 205 ShowWarningDialog(); |
210 | 206 |
211 UpdateAccessibleName(); | 207 UpdateAccessibleName(); |
212 set_accessibility_focusable(true); | 208 set_accessibility_focusable(true); |
213 | 209 |
214 // Set up our animation. | 210 // Set up our animation. |
215 StartDownloadProgress(); | 211 StartDownloadProgress(); |
216 } | 212 } |
217 | 213 |
218 DownloadItemView::~DownloadItemView() { | 214 DownloadItemView::~DownloadItemView() { |
(...skipping 29 matching lines...) Expand all Loading... |
248 parent()->SchedulePaint(); | 244 parent()->SchedulePaint(); |
249 } | 245 } |
250 | 246 |
251 // DownloadObserver interface. | 247 // DownloadObserver interface. |
252 | 248 |
253 // Update the progress graphic on the icon and our text status label | 249 // Update the progress graphic on the icon and our text status label |
254 // to reflect our current bytes downloaded, time remaining. | 250 // to reflect our current bytes downloaded, time remaining. |
255 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { | 251 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { |
256 DCHECK(download == download_); | 252 DCHECK(download == download_); |
257 | 253 |
258 if (IsShowingWarningDialog() && | 254 if (IsShowingWarningDialog() && !model_->IsDangerous()) { |
259 download->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED) { | |
260 // We have been approved. | 255 // We have been approved. |
261 ClearWarningDialog(); | 256 ClearWarningDialog(); |
262 } else if (!IsShowingWarningDialog() && | 257 } else if (!IsShowingWarningDialog() && model_->IsDangerous()) { |
263 download->GetSafetyState() == DownloadItem::DANGEROUS) { | |
264 ShowWarningDialog(); | 258 ShowWarningDialog(); |
265 // Force the shelf to layout again as our size has changed. | 259 // Force the shelf to layout again as our size has changed. |
266 parent_->Layout(); | 260 parent_->Layout(); |
267 SchedulePaint(); | 261 SchedulePaint(); |
268 } else { | 262 } else { |
269 string16 status_text = model_->GetStatusText(); | 263 string16 status_text = model_->GetStatusText(); |
270 switch (download_->GetState()) { | 264 switch (download_->GetState()) { |
271 case DownloadItem::IN_PROGRESS: | 265 case DownloadItem::IN_PROGRESS: |
272 download_->IsPaused() ? | 266 download_->IsPaused() ? |
273 StopDownloadProgress() : StartDownloadProgress(); | 267 StopDownloadProgress() : StartDownloadProgress(); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 if (!context_menu_.get()) | 560 if (!context_menu_.get()) |
567 context_menu_.reset(new DownloadShelfContextMenuView(model_.get())); | 561 context_menu_.reset(new DownloadShelfContextMenuView(model_.get())); |
568 context_menu_->Run(GetWidget()->GetTopLevelWidget(), | 562 context_menu_->Run(GetWidget()->GetTopLevelWidget(), |
569 gfx::Rect(point, size)); | 563 gfx::Rect(point, size)); |
570 // We could be deleted now. | 564 // We could be deleted now. |
571 } | 565 } |
572 | 566 |
573 void DownloadItemView::GetAccessibleState(ui::AccessibleViewState* state) { | 567 void DownloadItemView::GetAccessibleState(ui::AccessibleViewState* state) { |
574 state->name = accessible_name_; | 568 state->name = accessible_name_; |
575 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; | 569 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; |
576 if (download_->GetSafetyState() == DownloadItem::DANGEROUS) { | 570 if (model_->IsDangerous()) { |
577 state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; | 571 state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; |
578 } else { | 572 } else { |
579 state->state = ui::AccessibilityTypes::STATE_HASPOPUP; | 573 state->state = ui::AccessibilityTypes::STATE_HASPOPUP; |
580 } | 574 } |
581 } | 575 } |
582 | 576 |
583 void DownloadItemView::ButtonPressed( | 577 void DownloadItemView::ButtonPressed( |
584 views::Button* sender, const views::Event& event) { | 578 views::Button* sender, const views::Event& event) { |
585 if (sender == discard_button_) { | 579 if (sender == discard_button_) { |
586 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", | 580 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 LoadIcon(); | 991 LoadIcon(); |
998 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); | 992 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); |
999 | 993 |
1000 // Force the shelf to layout again as our size has changed. | 994 // Force the shelf to layout again as our size has changed. |
1001 parent_->Layout(); | 995 parent_->Layout(); |
1002 parent_->SchedulePaint(); | 996 parent_->SchedulePaint(); |
1003 } | 997 } |
1004 | 998 |
1005 void DownloadItemView::ShowWarningDialog() { | 999 void DownloadItemView::ShowWarningDialog() { |
1006 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); | 1000 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); |
1007 if (download_->GetDangerType() == | 1001 mode_ = ((model_->IsMalicious()) ? MALICIOUS_MODE : DANGEROUS_MODE); |
1008 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL || | 1002 |
1009 download_->GetDangerType() == | |
1010 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT) { | |
1011 mode_ = MALICIOUS_MODE; | |
1012 } else { | |
1013 DCHECK(download_->GetDangerType() == | |
1014 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | |
1015 mode_ = DANGEROUS_MODE; | |
1016 } | |
1017 body_state_ = NORMAL; | 1003 body_state_ = NORMAL; |
1018 drop_down_state_ = NORMAL; | 1004 drop_down_state_ = NORMAL; |
1019 tooltip_text_.clear(); | 1005 tooltip_text_.clear(); |
1020 if (mode_ == DANGEROUS_MODE) { | 1006 if (mode_ == DANGEROUS_MODE) { |
1021 save_button_ = new views::NativeTextButton(this, | 1007 save_button_ = new views::NativeTextButton( |
1022 l10n_util::GetStringUTF16( | 1008 this, model_->GetWarningConfirmButtonText()); |
1023 ChromeDownloadManagerDelegate::IsExtensionDownload(download_) ? | |
1024 IDS_CONTINUE_EXTENSION_DOWNLOAD : IDS_CONFIRM_DOWNLOAD)); | |
1025 save_button_->set_ignore_minimum_size(true); | 1009 save_button_->set_ignore_minimum_size(true); |
1026 AddChildView(save_button_); | 1010 AddChildView(save_button_); |
1027 } | 1011 } |
1028 discard_button_ = new views::NativeTextButton( | 1012 discard_button_ = new views::NativeTextButton( |
1029 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); | 1013 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); |
1030 discard_button_->set_ignore_minimum_size(true); | 1014 discard_button_->set_ignore_minimum_size(true); |
1031 AddChildView(discard_button_); | 1015 AddChildView(discard_button_); |
1032 | 1016 |
1033 // Ensure the file name is not too long. | |
1034 | |
1035 // Extract the file extension (if any). | |
1036 FilePath filename(download_->GetTargetName()); | |
1037 #if defined(OS_POSIX) | |
1038 string16 extension = WideToUTF16(base::SysNativeMBToWide( | |
1039 filename.Extension())); | |
1040 #else | |
1041 string16 extension = filename.Extension(); | |
1042 #endif | |
1043 | |
1044 // Remove leading '.' | |
1045 if (extension.length() > 0) | |
1046 extension = extension.substr(1); | |
1047 #if defined(OS_POSIX) | |
1048 string16 rootname = WideToUTF16(base::SysNativeMBToWide( | |
1049 filename.RemoveExtension().value())); | |
1050 #else | |
1051 string16 rootname = filename.RemoveExtension().value(); | |
1052 #endif | |
1053 | |
1054 // Elide giant extensions (this shouldn't currently be hit, but might | |
1055 // in future, should we ever notice unsafe giant extensions). | |
1056 if (extension.length() > kFileNameMaxLength / 2) | |
1057 ui::ElideString(extension, kFileNameMaxLength / 2, &extension); | |
1058 | |
1059 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1017 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
1060 // The dangerous download label text and icon are different | 1018 // The dangerous download label text and icon are different under |
1061 // under different cases. | 1019 // different cases. |
1062 if (mode_ == MALICIOUS_MODE) { | 1020 if (mode_ == MALICIOUS_MODE) { |
1063 warning_icon_ = rb.GetBitmapNamed(IDR_SAFEBROWSING_WARNING); | 1021 warning_icon_ = rb.GetBitmapNamed(IDR_SAFEBROWSING_WARNING); |
1064 } else { | 1022 } else { |
1065 DCHECK(download_->GetDangerType() == | |
1066 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | |
1067 // The download file has dangerous file type (e.g.: an executable). | 1023 // The download file has dangerous file type (e.g.: an executable). |
1068 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); | 1024 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); |
1069 } | 1025 } |
1070 string16 dangerous_label; | 1026 string16 dangerous_label = model_->GetWarningText(font_, kTextWidth); |
1071 if (download_->GetDangerType() == | |
1072 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL) { | |
1073 // Safebrowsing shows the download URL or content leads to malicious file. | |
1074 dangerous_label = l10n_util::GetStringUTF16( | |
1075 IDS_PROMPT_MALICIOUS_DOWNLOAD_URL); | |
1076 } else if (download_->GetDangerType() == | |
1077 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE && | |
1078 ChromeDownloadManagerDelegate::IsExtensionDownload(download_)) { | |
1079 dangerous_label = | |
1080 l10n_util::GetStringUTF16(IDS_PROMPT_DANGEROUS_DOWNLOAD_EXTENSION); | |
1081 } else { | |
1082 // The download file has dangerous file type (e.g.: an executable) or the | |
1083 // file content is known to be malicious. | |
1084 DCHECK(download_->GetDangerType() == | |
1085 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE || | |
1086 download_->GetDangerType() == | |
1087 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); | |
1088 ui::ElideString(rootname, | |
1089 kFileNameMaxLength - extension.length(), | |
1090 &rootname); | |
1091 string16 filename = rootname + ASCIIToUTF16(".") + extension; | |
1092 filename = base::i18n::GetDisplayStringInLTRDirectionality(filename); | |
1093 dangerous_label = l10n_util::GetStringFUTF16( | |
1094 download_->GetDangerType() == | |
1095 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE ? | |
1096 IDS_PROMPT_DANGEROUS_DOWNLOAD : | |
1097 IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT, | |
1098 filename); | |
1099 } | |
1100 | |
1101 dangerous_download_label_ = new views::Label(dangerous_label); | 1027 dangerous_download_label_ = new views::Label(dangerous_label); |
1102 dangerous_download_label_->SetMultiLine(true); | 1028 dangerous_download_label_->SetMultiLine(true); |
1103 dangerous_download_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 1029 dangerous_download_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
1104 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); | 1030 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); |
1105 AddChildView(dangerous_download_label_); | 1031 AddChildView(dangerous_download_label_); |
1106 SizeLabelToMinWidth(); | 1032 SizeLabelToMinWidth(); |
1107 UpdateDropDownButtonPosition(); | 1033 UpdateDropDownButtonPosition(); |
1108 } | 1034 } |
1109 | 1035 |
1110 gfx::Size DownloadItemView::GetButtonSize() { | 1036 gfx::Size DownloadItemView::GetButtonSize() { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 // Drop down button is glued to the left of the download shelf. | 1164 // Drop down button is glued to the left of the download shelf. |
1239 drop_down_x_left_ = 0; | 1165 drop_down_x_left_ = 0; |
1240 drop_down_x_right_ = normal_drop_down_image_set_.top->width(); | 1166 drop_down_x_right_ = normal_drop_down_image_set_.top->width(); |
1241 } else { | 1167 } else { |
1242 // Drop down button is glued to the right of the download shelf. | 1168 // Drop down button is glued to the right of the download shelf. |
1243 drop_down_x_left_ = | 1169 drop_down_x_left_ = |
1244 size.width() - normal_drop_down_image_set_.top->width(); | 1170 size.width() - normal_drop_down_image_set_.top->width(); |
1245 drop_down_x_right_ = size.width(); | 1171 drop_down_x_right_ = size.width(); |
1246 } | 1172 } |
1247 } | 1173 } |
OLD | NEW |