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

Side by Side Diff: chrome/browser/ui/views/download/download_item_view.cc

Issue 2346043002: Delete old (pre-MD) download shelf view code. (Closed)
Patch Set: gotta git add Created 4 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
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/i18n/break_iterator.h" 15 #include "base/i18n/break_iterator.h"
16 #include "base/i18n/rtl.h" 16 #include "base/i18n/rtl.h"
17 #include "base/location.h" 17 #include "base/location.h"
18 #include "base/macros.h"
19 #include "base/memory/ptr_util.h"
18 #include "base/metrics/histogram_macros.h" 20 #include "base/metrics/histogram_macros.h"
19 #include "base/single_thread_task_runner.h" 21 #include "base/single_thread_task_runner.h"
20 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
22 #include "base/strings/sys_string_conversions.h" 24 #include "base/strings/sys_string_conversions.h"
23 #include "base/strings/utf_string_conversions.h" 25 #include "base/strings/utf_string_conversions.h"
24 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
25 #include "chrome/browser/browser_process.h" 27 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/download/chrome_download_manager_delegate.h" 28 #include "chrome/browser/download/chrome_download_manager_delegate.h"
27 #include "chrome/browser/download/download_item_model.h" 29 #include "chrome/browser/download/download_item_model.h"
28 #include "chrome/browser/download/download_stats.h" 30 #include "chrome/browser/download/download_stats.h"
29 #include "chrome/browser/download/drag_download_item.h" 31 #include "chrome/browser/download/drag_download_item.h"
30 #include "chrome/browser/extensions/api/experience_sampling_private/experience_s ampling.h" 32 #include "chrome/browser/extensions/api/experience_sampling_private/experience_s ampling.h"
31 #include "chrome/browser/profiles/profile.h" 33 #include "chrome/browser/profiles/profile.h"
32 #include "chrome/browser/safe_browsing/download_feedback_service.h" 34 #include "chrome/browser/safe_browsing/download_feedback_service.h"
33 #include "chrome/browser/safe_browsing/download_protection_service.h" 35 #include "chrome/browser/safe_browsing/download_protection_service.h"
34 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 36 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
35 #include "chrome/browser/themes/theme_properties.h" 37 #include "chrome/browser/themes/theme_properties.h"
36 #include "chrome/browser/ui/views/download/download_feedback_dialog_view.h" 38 #include "chrome/browser/ui/views/download/download_feedback_dialog_view.h"
37 #include "chrome/browser/ui/views/download/download_shelf_context_menu_view.h" 39 #include "chrome/browser/ui/views/download/download_shelf_context_menu_view.h"
38 #include "chrome/browser/ui/views/download/download_shelf_view.h" 40 #include "chrome/browser/ui/views/download/download_shelf_view.h"
39 #include "chrome/browser/ui/views/frame/browser_view.h" 41 #include "chrome/browser/ui/views/frame/browser_view.h"
40 #include "chrome/common/pref_names.h" 42 #include "chrome/common/pref_names.h"
41 #include "chrome/grit/generated_resources.h" 43 #include "chrome/grit/generated_resources.h"
42 #include "chrome/grit/theme_resources.h"
43 #include "components/prefs/pref_service.h" 44 #include "components/prefs/pref_service.h"
44 #include "content/public/browser/download_danger_type.h" 45 #include "content/public/browser/download_danger_type.h"
45 #include "third_party/icu/source/common/unicode/uchar.h" 46 #include "third_party/icu/source/common/unicode/uchar.h"
46 #include "ui/accessibility/ax_view_state.h" 47 #include "ui/accessibility/ax_view_state.h"
47 #include "ui/base/l10n/l10n_util.h" 48 #include "ui/base/l10n/l10n_util.h"
49 #include "ui/base/material_design/material_design_controller.h"
48 #include "ui/base/resource/resource_bundle.h" 50 #include "ui/base/resource/resource_bundle.h"
49 #include "ui/base/theme_provider.h" 51 #include "ui/base/theme_provider.h"
50 #include "ui/events/event.h" 52 #include "ui/events/event.h"
51 #include "ui/gfx/animation/slide_animation.h" 53 #include "ui/gfx/animation/slide_animation.h"
52 #include "ui/gfx/canvas.h" 54 #include "ui/gfx/canvas.h"
55 #include "ui/gfx/color_palette.h"
53 #include "ui/gfx/color_utils.h" 56 #include "ui/gfx/color_utils.h"
54 #include "ui/gfx/image/image.h" 57 #include "ui/gfx/image/image.h"
55 #include "ui/gfx/scoped_canvas.h" 58 #include "ui/gfx/paint_vector_icon.h"
56 #include "ui/gfx/text_elider.h" 59 #include "ui/gfx/text_elider.h"
57 #include "ui/gfx/text_utils.h" 60 #include "ui/gfx/text_utils.h"
58 #include "ui/views/controls/button/label_button.h" 61 #include "ui/gfx/vector_icons_public.h"
62 #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
63 #include "ui/views/animation/ink_drop_highlight.h"
64 #include "ui/views/border.h"
65 #include "ui/views/controls/button/image_button.h"
66 #include "ui/views/controls/button/md_text_button.h"
67 #include "ui/views/controls/button/vector_icon_button.h"
68 #include "ui/views/controls/focusable_border.h"
59 #include "ui/views/controls/label.h" 69 #include "ui/views/controls/label.h"
60 #include "ui/views/mouse_constants.h" 70 #include "ui/views/mouse_constants.h"
61 #include "ui/views/widget/root_view.h" 71 #include "ui/views/widget/root_view.h"
62 #include "ui/views/widget/widget.h" 72 #include "ui/views/widget/widget.h"
63 73
64 using content::DownloadItem; 74 using content::DownloadItem;
65 using extensions::ExperienceSamplingEvent; 75 using extensions::ExperienceSamplingEvent;
66 76
67 namespace { 77 namespace {
68 78
69 // TODO(paulg): These may need to be adjusted when download progress 79 // All values in dp.
70 // animation is added, and also possibly to take into account 80 const int kTextWidth = 140;
71 // different screen resolutions. 81 const int kDangerousTextWidth = 200;
72 const int kTextWidth = 140; // Pixels
73 const int kDangerousTextWidth = 200; // Pixels
74 const int kVerticalPadding = 3; // Pixels
75 const int kVerticalTextPadding = 2; // Pixels
76 const int kTooltipMaxWidth = 800; // Pixels
77 82
78 // Padding around progress indicator, on all sides. 83 // The normal height of the item which may be exceeded if text is large.
79 const int kProgressPadding = 7; 84 const int kDefaultHeight = 48;
80 85
81 // We add some padding before the left image so that the progress animation icon 86 // The vertical distance between the item's visual upper bound (as delineated by
82 // hides the corners of the left image. 87 // the separator on the right) and the edge of the shelf.
83 const int kLeftPadding = 0; // Pixels. 88 const int kTopBottomPadding = 6;
89
90 // The minimum vertical padding above and below contents of the download item.
91 // This is only used when the text size is large.
92 const int kMinimumVerticalPadding = 2 + kTopBottomPadding;
93
94 // Vertical padding between filename and status text.
95 const int kVerticalTextPadding = 1;
96
97 const int kTooltipMaxWidth = 800;
98
99 // Padding before the icon and at end of the item.
100 const int kStartPadding = 12;
101 const int kEndPadding = 6;
102
103 // Horizontal padding between progress indicator and filename/status text.
104 const int kProgressTextPadding = 8;
84 105
85 // The space between the Save and Discard buttons when prompting for a dangerous 106 // The space between the Save and Discard buttons when prompting for a dangerous
86 // download. 107 // download.
87 const int kButtonPadding = 5; // Pixels. 108 const int kButtonPadding = 5;
88 109
89 // The space on the left and right side of the dangerous download label. 110 // The touchable space around the dropdown button's icon.
90 const int kLabelPadding = 4; // Pixels. 111 const int kDropdownBorderWidth = 10;
91 112
92 const SkColor kFileNameDisabledColor = SkColorSetRGB(171, 192, 212); 113 // The space on the right side of the dangerous download label.
114 const int kLabelPadding = 8;
115
116 // Height/width of the warning icon, also in dp.
117 const int kWarningIconSize = 24;
93 118
94 // How long the 'download complete' animation should last for. 119 // How long the 'download complete' animation should last for.
95 const int kCompleteAnimationDurationMs = 2500; 120 const int kCompleteAnimationDurationMs = 2500;
96 121
97 // How long the 'download interrupted' animation should last for. 122 // How long the 'download interrupted' animation should last for.
98 const int kInterruptedAnimationDurationMs = 2500; 123 const int kInterruptedAnimationDurationMs = 2500;
99 124
100 // How long we keep the item disabled after the user clicked it to open the 125 // How long we keep the item disabled after the user clicked it to open the
101 // downloaded item. 126 // downloaded item.
102 const int kDisabledOnOpenDuration = 3000; 127 const int kDisabledOnOpenDuration = 3000;
103 128
129 // The separator is drawn as a border. It's one dp wide.
130 class SeparatorBorder : public views::FocusableBorder {
131 public:
132 explicit SeparatorBorder(SkColor color) : color_(color) {}
133 ~SeparatorBorder() override {}
134
135 void Paint(const views::View& view, gfx::Canvas* canvas) override {
136 if (view.HasFocus())
137 return FocusableBorder::Paint(view, canvas);
138
139 int end_x = base::i18n::IsRTL() ? 0 : view.width() - 1;
140 canvas->DrawLine(gfx::Point(end_x, kTopBottomPadding),
141 gfx::Point(end_x, view.height() - kTopBottomPadding),
142 color_);
143 }
144
145 gfx::Insets GetInsets() const override { return gfx::Insets(0, 0, 0, 1); }
146
147 gfx::Size GetMinimumSize() const override {
148 return gfx::Size(1, 2 * kTopBottomPadding + 1);
149 }
150
151 private:
152 SkColor color_;
153
154 DISALLOW_COPY_AND_ASSIGN(SeparatorBorder);
155 };
156
104 } // namespace 157 } // namespace
105 158
159 // Allows the DownloadItemView to control the InkDrop on the drop down button.
160 class DownloadItemView::DropDownButton : public views::VectorIconButton {
161 public:
162 explicit DropDownButton(views::VectorIconButtonDelegate* delegate)
163 : views::VectorIconButton(delegate) {}
164 ~DropDownButton() override {}
165
166 // Promoted visibility to public.
167 void AnimateInkDrop(views::InkDropState state) {
168 // TODO(bruthig): Plumb in the proper Event.
169 views::VectorIconButton::AnimateInkDrop(state, nullptr /* event */);
170 }
171
172 private:
173 DISALLOW_COPY_AND_ASSIGN(DropDownButton);
174 };
175
106 DownloadItemView::DownloadItemView(DownloadItem* download_item, 176 DownloadItemView::DownloadItemView(DownloadItem* download_item,
107 DownloadShelfView* parent) 177 DownloadShelfView* parent)
108 : warning_icon_(NULL), 178 : shelf_(parent),
109 shelf_(parent), 179 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)),
110 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)), 180 dropdown_state_(NORMAL),
111 body_state_(NORMAL), 181 mode_(NORMAL_MODE),
112 drop_down_state_(NORMAL), 182 dragging_(false),
113 mode_(NORMAL_MODE), 183 starting_drag_(false),
114 drop_down_pressed_(false), 184 model_(download_item),
115 dragging_(false), 185 save_button_(nullptr),
116 starting_drag_(false), 186 discard_button_(nullptr),
117 model_(download_item), 187 dropdown_button_(new DropDownButton(this)),
118 save_button_(NULL), 188 dangerous_download_label_(nullptr),
119 discard_button_(NULL), 189 dangerous_download_label_sized_(false),
120 dangerous_download_label_(NULL), 190 disabled_while_opening_(false),
121 dangerous_download_label_sized_(false), 191 creation_time_(base::Time::Now()),
122 disabled_while_opening_(false), 192 time_download_warning_shown_(base::Time()),
123 creation_time_(base::Time::Now()), 193 weak_ptr_factory_(this) {
124 time_download_warning_shown_(base::Time()), 194 SetInkDropMode(InkDropMode::ON);
125 weak_ptr_factory_(this) {
126 DCHECK(download()); 195 DCHECK(download());
196 DCHECK(ui::MaterialDesignController::IsModeMaterial());
127 download()->AddObserver(this); 197 download()->AddObserver(this);
128 set_context_menu_controller(this); 198 set_context_menu_controller(this);
129 199
130 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 200 dropdown_button_->SetBorder(
131 201 views::Border::CreateEmptyBorder(gfx::Insets(kDropdownBorderWidth)));
132 BodyImageSet normal_body_image_set = { 202 dropdown_button_->set_ink_drop_size(gfx::Size(32, 32));
133 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), 203 AddChildView(dropdown_button_);
134 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE),
135 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM),
136 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP),
137 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE),
138 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM),
139 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP),
140 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE),
141 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM)
142 };
143 normal_body_image_set_ = normal_body_image_set;
144
145 DropDownImageSet normal_drop_down_image_set = {
146 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP),
147 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE),
148 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM)
149 };
150 normal_drop_down_image_set_ = normal_drop_down_image_set;
151
152 BodyImageSet hot_body_image_set = {
153 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP_H),
154 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_H),
155 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_H),
156 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP_H),
157 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_H),
158 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_H),
159 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_H),
160 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_H),
161 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_H)
162 };
163 hot_body_image_set_ = hot_body_image_set;
164
165 DropDownImageSet hot_drop_down_image_set = {
166 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_H),
167 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_H),
168 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_H)
169 };
170 hot_drop_down_image_set_ = hot_drop_down_image_set;
171
172 BodyImageSet pushed_body_image_set = {
173 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP_P),
174 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_P),
175 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_P),
176 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP_P),
177 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_P),
178 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_P),
179 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_P),
180 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_P),
181 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_P)
182 };
183 pushed_body_image_set_ = pushed_body_image_set;
184
185 DropDownImageSet pushed_drop_down_image_set = {
186 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P),
187 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P),
188 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P)
189 };
190 pushed_drop_down_image_set_ = pushed_drop_down_image_set;
191
192 BodyImageSet dangerous_mode_body_image_set = {
193 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP),
194 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE),
195 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM),
196 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP),
197 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE),
198 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM),
199 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD),
200 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD),
201 rb.GetImageSkiaNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD)
202 };
203 dangerous_mode_body_image_set_ = dangerous_mode_body_image_set;
204
205 malicious_mode_body_image_set_ = normal_body_image_set;
206 204
207 LoadIcon(); 205 LoadIcon();
208 206
209 font_list_ = rb.GetFontList(ui::ResourceBundle::BaseFont); 207 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
210 box_height_ = std::max<int>(2 * kVerticalPadding + font_list_.GetHeight() + 208 font_list_ =
211 kVerticalTextPadding + font_list_.GetHeight(), 209 rb.GetFontList(ui::ResourceBundle::BaseFont).DeriveWithSizeDelta(1);
212 2 * kVerticalPadding + 210 status_font_list_ =
213 normal_body_image_set_.top_left->height() + 211 rb.GetFontList(ui::ResourceBundle::BaseFont).DeriveWithSizeDelta(-2);
214 normal_body_image_set_.bottom_left->height());
215
216 box_y_ = std::max(0, (2 * kProgressPadding +
217 DownloadShelf::kProgressIndicatorSize - box_height_) /
218 2);
219
220 body_hover_animation_.reset(new gfx::SlideAnimation(this));
221 drop_hover_animation_.reset(new gfx::SlideAnimation(this));
222 212
223 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); 213 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
224 214
225 OnDownloadUpdated(download()); 215 OnDownloadUpdated(download());
226 UpdateDropDownButtonPosition(); 216
217 SetDropdownState(NORMAL);
218 UpdateColorsFromTheme();
227 } 219 }
228 220
229 DownloadItemView::~DownloadItemView() { 221 DownloadItemView::~DownloadItemView() {
230 StopDownloadProgress(); 222 StopDownloadProgress();
231 download()->RemoveObserver(this); 223 download()->RemoveObserver(this);
232 224
233 // ExperienceSampling: If the user took no action to remove the warning 225 // ExperienceSampling: If the user took no action to remove the warning
234 // before it disappeared, then the user effectively dismissed the download 226 // before it disappeared, then the user effectively dismissed the download
235 // without keeping it. 227 // without keeping it.
236 if (sampling_event_.get()) 228 if (sampling_event_.get())
(...skipping 13 matching lines...) Expand all
250 } 242 }
251 243
252 void DownloadItemView::StopDownloadProgress() { 244 void DownloadItemView::StopDownloadProgress() {
253 if (!progress_timer_.IsRunning()) 245 if (!progress_timer_.IsRunning())
254 return; 246 return;
255 previous_progress_elapsed_ += base::TimeTicks::Now() - progress_start_time_; 247 previous_progress_elapsed_ += base::TimeTicks::Now() - progress_start_time_;
256 progress_start_time_ = base::TimeTicks(); 248 progress_start_time_ = base::TimeTicks();
257 progress_timer_.Stop(); 249 progress_timer_.Stop();
258 } 250 }
259 251
252 // static
253 SkColor DownloadItemView::GetTextColorForThemeProvider(
254 const ui::ThemeProvider* theme) {
255 return theme ? theme->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)
256 : gfx::kPlaceholderColor;
257 }
258
260 void DownloadItemView::OnExtractIconComplete(gfx::Image* icon_bitmap) { 259 void DownloadItemView::OnExtractIconComplete(gfx::Image* icon_bitmap) {
261 if (icon_bitmap) 260 if (icon_bitmap)
262 shelf_->SchedulePaint(); 261 shelf_->SchedulePaint();
263 } 262 }
264 263
265 // DownloadObserver interface. 264 // DownloadObserver interface.
266 265
267 // Update the progress graphic on the icon and our text status label 266 // Update the progress graphic on the icon and our text status label
268 // to reflect our current bytes downloaded, time remaining. 267 // to reflect our current bytes downloaded, time remaining.
269 void DownloadItemView::OnDownloadUpdated(DownloadItem* download_item) { 268 void DownloadItemView::OnDownloadUpdated(DownloadItem* download_item) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 base::TimeDelta::FromMilliseconds(kDisabledOnOpenDuration)); 337 base::TimeDelta::FromMilliseconds(kDisabledOnOpenDuration));
339 338
340 // Notify our parent. 339 // Notify our parent.
341 shelf_->OpenedDownload(); 340 shelf_->OpenedDownload();
342 } 341 }
343 342
344 // View overrides 343 // View overrides
345 344
346 // In dangerous mode we have to layout our buttons. 345 // In dangerous mode we have to layout our buttons.
347 void DownloadItemView::Layout() { 346 void DownloadItemView::Layout() {
347 UpdateColorsFromTheme();
348
348 if (IsShowingWarningDialog()) { 349 if (IsShowingWarningDialog()) {
349 BodyImageSet* body_image_set = 350 gfx::Point child_origin(
350 (mode_ == DANGEROUS_MODE) ? &dangerous_mode_body_image_set_ : 351 kStartPadding + kWarningIconSize + kStartPadding,
351 &malicious_mode_body_image_set_; 352 (height() - dangerous_download_label_->height()) / 2);
352 int x = kLeftPadding + body_image_set->top_left->width() + 353 dangerous_download_label_->SetPosition(child_origin);
353 warning_icon_->width() + kLabelPadding; 354
354 int y = (height() - dangerous_download_label_->height()) / 2; 355 child_origin.Offset(dangerous_download_label_->width() + kLabelPadding, 0);
355 dangerous_download_label_->SetBounds(x, y,
356 dangerous_download_label_->width(),
357 dangerous_download_label_->height());
358 gfx::Size button_size = GetButtonSize(); 356 gfx::Size button_size = GetButtonSize();
359 x += dangerous_download_label_->width() + kLabelPadding; 357 child_origin.set_y((height() - button_size.height()) / 2);
360 y = (height() - button_size.height()) / 2;
361 if (save_button_) { 358 if (save_button_) {
362 save_button_->SetBounds(x, y, button_size.width(), button_size.height()); 359 save_button_->SetBoundsRect(gfx::Rect(child_origin, button_size));
363 x += button_size.width() + kButtonPadding; 360 child_origin.Offset(button_size.width() + kButtonPadding, 0);
364 } 361 }
365 discard_button_->SetBounds(x, y, button_size.width(), button_size.height()); 362 discard_button_->SetBoundsRect(gfx::Rect(child_origin, button_size));
366 UpdateColorsFromTheme(); 363 }
364
365 if (mode_ != DANGEROUS_MODE) {
366 dropdown_button_->SizeToPreferredSize();
367 dropdown_button_->SetPosition(
368 gfx::Point(width() - dropdown_button_->width() - kEndPadding,
369 (height() - dropdown_button_->height()) / 2));
367 } 370 }
368 } 371 }
369 372
370 gfx::Size DownloadItemView::GetPreferredSize() const { 373 gfx::Size DownloadItemView::GetPreferredSize() const {
371 int width, height; 374 int width = 0;
372 375 // We set the height to the height of two rows or text plus margins.
373 // First, we set the height to the height of two rows or text plus margins. 376 int child_height = font_list_.GetBaseline() + kVerticalTextPadding +
374 height = 2 * kVerticalPadding + 2 * font_list_.GetHeight() + 377 status_font_list_.GetHeight();
375 kVerticalTextPadding;
376 // Then we increase the size if the progress icon doesn't fit.
377 height = std::max<int>(
378 height, DownloadShelf::kProgressIndicatorSize + 2 * kProgressPadding);
379 378
380 if (IsShowingWarningDialog()) { 379 if (IsShowingWarningDialog()) {
381 const BodyImageSet* body_image_set = 380 // Width.
382 (mode_ == DANGEROUS_MODE) ? &dangerous_mode_body_image_set_ : 381 width = kStartPadding + kWarningIconSize + kStartPadding +
383 &malicious_mode_body_image_set_; 382 dangerous_download_label_->width() + kLabelPadding;
384 width = kLeftPadding + body_image_set->top_left->width();
385 width += warning_icon_->width() + kLabelPadding;
386 width += dangerous_download_label_->width() + kLabelPadding;
387 gfx::Size button_size = GetButtonSize(); 383 gfx::Size button_size = GetButtonSize();
388 // Make sure the button fits.
389 height = std::max<int>(height, 2 * kVerticalPadding + button_size.height());
390 // Then we make sure the warning icon fits.
391 height = std::max<int>(height, 2 * kVerticalPadding +
392 warning_icon_->height());
393 if (save_button_) 384 if (save_button_)
394 width += button_size.width() + kButtonPadding; 385 width += button_size.width() + kButtonPadding;
395 width += button_size.width(); 386 width += button_size.width() + kEndPadding;
396 width += body_image_set->top_right->width(); 387
397 if (mode_ == MALICIOUS_MODE) 388 // Height: make sure the button fits and the warning icon fits.
398 width += normal_drop_down_image_set_.top->width(); 389 child_height =
390 std::max({child_height, button_size.height(), kWarningIconSize});
399 } else { 391 } else {
400 width = kLeftPadding + normal_body_image_set_.top_left->width(); 392 width = kStartPadding + DownloadShelf::kProgressIndicatorSize +
401 width += DownloadShelf::kProgressIndicatorSize + 2 * kProgressPadding; 393 kProgressTextPadding + kTextWidth + kEndPadding;
402 width += kTextWidth;
403 width += normal_body_image_set_.top_right->width();
404 width += normal_drop_down_image_set_.top->width();
405 } 394 }
406 return gfx::Size(width, height); 395
396 if (mode_ != DANGEROUS_MODE)
397 width += dropdown_button_->GetPreferredSize().width();
398
399 return gfx::Size(width, std::max(kDefaultHeight,
400 2 * kMinimumVerticalPadding + child_height));
407 } 401 }
408 402
409 // Handle a mouse click and open the context menu if the mouse is
410 // over the drop-down region.
411 bool DownloadItemView::OnMousePressed(const ui::MouseEvent& event) { 403 bool DownloadItemView::OnMousePressed(const ui::MouseEvent& event) {
412 HandlePressEvent(event, event.IsOnlyLeftMouseButton()); 404 HandlePressEvent(event, event.IsOnlyLeftMouseButton());
413 return true; 405 return true;
414 } 406 }
415 407
416 // Handle drag (file copy) operations. 408 // Handle drag (file copy) operations.
417 bool DownloadItemView::OnMouseDragged(const ui::MouseEvent& event) { 409 bool DownloadItemView::OnMouseDragged(const ui::MouseEvent& event) {
418 // Mouse should not activate us in dangerous mode. 410 // Mouse should not activate us in dangerous mode.
419 if (IsShowingWarningDialog()) 411 if (IsShowingWarningDialog())
420 return true; 412 return true;
421 413
422 if (!starting_drag_) { 414 if (!starting_drag_) {
423 starting_drag_ = true; 415 starting_drag_ = true;
424 drag_start_point_ = event.location(); 416 drag_start_point_ = event.location();
417 AnimateInkDrop(views::InkDropState::HIDDEN, &event);
425 } 418 }
426 if (dragging_) { 419 if (dragging_) {
427 if (download()->GetState() == DownloadItem::COMPLETE) { 420 if (download()->GetState() == DownloadItem::COMPLETE) {
428 IconManager* im = g_browser_process->icon_manager(); 421 IconManager* im = g_browser_process->icon_manager();
429 gfx::Image* icon = im->LookupIconFromFilepath( 422 gfx::Image* icon = im->LookupIconFromFilepath(
430 download()->GetTargetFilePath(), IconLoader::SMALL); 423 download()->GetTargetFilePath(), IconLoader::SMALL);
431 views::Widget* widget = GetWidget(); 424 views::Widget* widget = GetWidget();
432 DragDownloadItem( 425 DragDownloadItem(download(), icon,
433 download(), icon, widget ? widget->GetNativeView() : NULL); 426 widget ? widget->GetNativeView() : NULL);
434 } 427 }
435 } else if (ExceededDragThreshold(event.location() - drag_start_point_)) { 428 } else if (ExceededDragThreshold(event.location() - drag_start_point_)) {
436 dragging_ = true; 429 dragging_ = true;
437 } 430 }
438 return true; 431 return true;
439 } 432 }
440 433
441 void DownloadItemView::OnMouseReleased(const ui::MouseEvent& event) { 434 void DownloadItemView::OnMouseReleased(const ui::MouseEvent& event) {
442 HandleClickEvent(event, event.IsOnlyLeftMouseButton()); 435 HandleClickEvent(event, event.IsOnlyLeftMouseButton());
443 } 436 }
444 437
445 void DownloadItemView::OnMouseCaptureLost() { 438 void DownloadItemView::OnMouseCaptureLost() {
446 // Mouse should not activate us in dangerous mode. 439 // Mouse should not activate us in dangerous mode.
447 if (mode_ == DANGEROUS_MODE) 440 if (mode_ != NORMAL_MODE)
448 return; 441 return;
449 442
450 if (dragging_) { 443 if (dragging_) {
451 // Starting a drag results in a MouseCaptureLost. 444 // Starting a drag results in a MouseCaptureLost.
452 dragging_ = false; 445 dragging_ = false;
453 starting_drag_ = false; 446 starting_drag_ = false;
454 } 447 }
455 SetState(NORMAL, NORMAL);
456 }
457
458 void DownloadItemView::OnMouseMoved(const ui::MouseEvent& event) {
459 // Mouse should not activate us in dangerous mode.
460 if (mode_ == DANGEROUS_MODE)
461 return;
462
463 bool on_body = !InDropDownButtonXCoordinateRange(event.x());
464 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT);
465 }
466
467 void DownloadItemView::OnMouseExited(const ui::MouseEvent& event) {
468 // Mouse should not activate us in dangerous mode.
469 if (mode_ == DANGEROUS_MODE)
470 return;
471
472 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL);
473 } 448 }
474 449
475 bool DownloadItemView::OnKeyPressed(const ui::KeyEvent& event) { 450 bool DownloadItemView::OnKeyPressed(const ui::KeyEvent& event) {
476 // Key press should not activate us in dangerous mode. 451 // Key press should not activate us in dangerous mode.
477 if (IsShowingWarningDialog()) 452 if (IsShowingWarningDialog())
478 return true; 453 return true;
479 454
480 if (event.key_code() == ui::VKEY_SPACE || 455 if (event.key_code() == ui::VKEY_SPACE ||
481 event.key_code() == ui::VKEY_RETURN) { 456 event.key_code() == ui::VKEY_RETURN) {
457 AnimateInkDrop(views::InkDropState::ACTION_TRIGGERED, nullptr /* &event */);
482 // OpenDownload may delete this, so don't add any code after this line. 458 // OpenDownload may delete this, so don't add any code after this line.
483 OpenDownload(); 459 OpenDownload();
484 return true; 460 return true;
485 } 461 }
486 return false; 462 return false;
487 } 463 }
488 464
489 bool DownloadItemView::GetTooltipText(const gfx::Point& p, 465 bool DownloadItemView::GetTooltipText(const gfx::Point& p,
490 base::string16* tooltip) const { 466 base::string16* tooltip) const {
491 if (IsShowingWarningDialog()) { 467 if (IsShowingWarningDialog()) {
(...skipping 10 matching lines...) Expand all
502 state->name = accessible_name_; 478 state->name = accessible_name_;
503 state->role = ui::AX_ROLE_BUTTON; 479 state->role = ui::AX_ROLE_BUTTON;
504 if (model_.IsDangerous()) 480 if (model_.IsDangerous())
505 state->AddStateFlag(ui::AX_STATE_DISABLED); 481 state->AddStateFlag(ui::AX_STATE_DISABLED);
506 else 482 else
507 state->AddStateFlag(ui::AX_STATE_HASPOPUP); 483 state->AddStateFlag(ui::AX_STATE_HASPOPUP);
508 } 484 }
509 485
510 void DownloadItemView::OnThemeChanged() { 486 void DownloadItemView::OnThemeChanged() {
511 UpdateColorsFromTheme(); 487 UpdateColorsFromTheme();
488 SchedulePaint();
489 }
490
491 void DownloadItemView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
492 InkDropHostView::AddInkDropLayer(ink_drop_layer);
493 // The layer that's added to host the ink drop layer must mask to bounds
494 // so the hover effect is clipped while animating open.
495 layer()->SetMasksToBounds(true);
496 }
497
498 std::unique_ptr<views::InkDropRipple> DownloadItemView::CreateInkDropRipple()
499 const {
500 return base::MakeUnique<views::FloodFillInkDropRipple>(
501 GetLocalBounds(), GetInkDropCenterBasedOnLastEvent(),
502 color_utils::DeriveDefaultIconColor(GetTextColor()),
503 ink_drop_visible_opacity());
504 }
505
506 std::unique_ptr<views::InkDropHighlight>
507 DownloadItemView::CreateInkDropHighlight() const {
508 if (IsShowingWarningDialog())
509 return nullptr;
510
511 gfx::Size size = GetPreferredSize();
512 return base::MakeUnique<views::InkDropHighlight>(
513 size, kInkDropSmallCornerRadius,
514 gfx::RectF(gfx::SizeF(size)).CenterPoint(),
515 color_utils::DeriveDefaultIconColor(GetTextColor()));
512 } 516 }
513 517
514 void DownloadItemView::OnGestureEvent(ui::GestureEvent* event) { 518 void DownloadItemView::OnGestureEvent(ui::GestureEvent* event) {
515 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { 519 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
516 HandlePressEvent(*event, true); 520 HandlePressEvent(*event, true);
517 event->SetHandled(); 521 event->SetHandled();
518 return; 522 return;
519 } 523 }
520 524
521 if (event->type() == ui::ET_GESTURE_TAP) { 525 if (event->type() == ui::ET_GESTURE_TAP) {
522 HandleClickEvent(*event, true); 526 HandleClickEvent(*event, true);
523 event->SetHandled(); 527 event->SetHandled();
524 return; 528 return;
525 } 529 }
526 530
527 SetState(NORMAL, NORMAL);
528 views::View::OnGestureEvent(event); 531 views::View::OnGestureEvent(event);
529 } 532 }
530 533
531 void DownloadItemView::ShowContextMenuForView(View* source, 534 void DownloadItemView::ShowContextMenuForView(View* source,
532 const gfx::Point& point, 535 const gfx::Point& point,
533 ui::MenuSourceType source_type) { 536 ui::MenuSourceType source_type) {
534 // |point| is in screen coordinates. So convert it to local coordinates first. 537 ShowContextMenuImpl(gfx::Rect(point, gfx::Size()), source_type);
535 gfx::Point local_point = point;
536 ConvertPointFromScreen(this, &local_point);
537 ShowContextMenuImpl(local_point, source_type);
538 } 538 }
539 539
540 void DownloadItemView::ButtonPressed(views::Button* sender, 540 void DownloadItemView::ButtonPressed(views::Button* sender,
541 const ui::Event& event) { 541 const ui::Event& event) {
542 if (sender == dropdown_button_) {
543 // TODO(estade): this is copied from ToolbarActionView but should be shared
544 // one way or another.
545 ui::MenuSourceType type = ui::MENU_SOURCE_NONE;
546 if (event.IsMouseEvent())
547 type = ui::MENU_SOURCE_MOUSE;
548 else if (event.IsKeyEvent())
549 type = ui::MENU_SOURCE_KEYBOARD;
550 else if (event.IsGestureEvent())
551 type = ui::MENU_SOURCE_TOUCH;
552 SetDropdownState(PUSHED);
553 ShowContextMenuImpl(dropdown_button_->GetBoundsInScreen(), type);
554 return;
555 }
556
542 base::TimeDelta warning_duration; 557 base::TimeDelta warning_duration;
543 if (!time_download_warning_shown_.is_null()) 558 if (!time_download_warning_shown_.is_null())
544 warning_duration = base::Time::Now() - time_download_warning_shown_; 559 warning_duration = base::Time::Now() - time_download_warning_shown_;
545 560
546 if (save_button_ && sender == save_button_) { 561 if (save_button_ && sender == save_button_) {
547 // The user has confirmed a dangerous download. We'd record how quickly the 562 // The user has confirmed a dangerous download. We'd record how quickly the
548 // user did this to detect whether we're being clickjacked. 563 // user did this to detect whether we're being clickjacked.
549 UMA_HISTOGRAM_LONG_TIMES("clickjacking.save_download", warning_duration); 564 UMA_HISTOGRAM_LONG_TIMES("clickjacking.save_download", warning_duration);
550 // ExperienceSampling: User chose to proceed with a dangerous download. 565 // ExperienceSampling: User chose to proceed with a dangerous download.
551 if (sampling_event_.get()) { 566 if (sampling_event_.get()) {
552 sampling_event_->CreateUserDecisionEvent( 567 sampling_event_->CreateUserDecisionEvent(
553 ExperienceSamplingEvent::kProceed); 568 ExperienceSamplingEvent::kProceed);
554 sampling_event_.reset(NULL); 569 sampling_event_.reset(NULL);
555 } 570 }
556 // This will change the state and notify us. 571 // This will change the state and notify us.
557 download()->ValidateDangerousDownload(); 572 download()->ValidateDangerousDownload();
558 return; 573 return;
559 } 574 }
560 575
561 // WARNING: all end states after this point delete |this|. 576 // WARNING: all end states after this point delete |this|.
562 DCHECK_EQ(discard_button_, sender); 577 DCHECK_EQ(discard_button_, sender);
563 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", warning_duration); 578 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", warning_duration);
564 if (!model_.IsMalicious() && model_.ShouldAllowDownloadFeedback() && 579 if (!model_.IsMalicious() && model_.ShouldAllowDownloadFeedback() &&
565 !shelf_->browser()->profile()->IsOffTheRecord()) { 580 !shelf_->browser()->profile()->IsOffTheRecord()) {
566 if (!shelf_->browser()->profile()->GetPrefs()->HasPrefPath( 581 if (!shelf_->browser()->profile()->GetPrefs()->HasPrefPath(
567 prefs::kSafeBrowsingExtendedReportingEnabled)) { 582 prefs::kSafeBrowsingExtendedReportingEnabled)) {
568 // Show dialog, because the dialog hasn't been shown before. 583 // Show dialog, because the dialog hasn't been shown before.
569 DownloadFeedbackDialogView::Show( 584 DownloadFeedbackDialogView::Show(
570 shelf_->get_parent()->GetNativeWindow(), 585 shelf_->get_parent()->GetNativeWindow(), shelf_->browser()->profile(),
571 shelf_->browser()->profile(),
572 shelf_->GetNavigator(), 586 shelf_->GetNavigator(),
573 base::Bind( 587 base::Bind(&DownloadItemView::PossiblySubmitDownloadToFeedbackService,
574 &DownloadItemView::PossiblySubmitDownloadToFeedbackService, 588 weak_ptr_factory_.GetWeakPtr()));
575 weak_ptr_factory_.GetWeakPtr()));
576 } else { 589 } else {
577 PossiblySubmitDownloadToFeedbackService( 590 PossiblySubmitDownloadToFeedbackService(
578 shelf_->browser()->profile()->GetPrefs()->GetBoolean( 591 shelf_->browser()->profile()->GetPrefs()->GetBoolean(
579 prefs::kSafeBrowsingExtendedReportingEnabled)); 592 prefs::kSafeBrowsingExtendedReportingEnabled));
580 } 593 }
581 return; 594 return;
582 } 595 }
583 download()->Remove(); 596 download()->Remove();
584 } 597 }
585 598
599 SkColor DownloadItemView::GetVectorIconBaseColor() const {
600 return GetTextColor();
601 }
602
586 void DownloadItemView::AnimationProgressed(const gfx::Animation* animation) { 603 void DownloadItemView::AnimationProgressed(const gfx::Animation* animation) {
587 // We don't care if what animation (body button/drop button/complete), 604 // We don't care if what animation (body button/drop button/complete),
588 // is calling back, as they all have to go through the same paint call. 605 // is calling back, as they all have to go through the same paint call.
589 SchedulePaint(); 606 SchedulePaint();
590 } 607 }
591 608
592 void DownloadItemView::OnPaint(gfx::Canvas* canvas) { 609 void DownloadItemView::OnPaint(gfx::Canvas* canvas) {
593 OnPaintBackground(canvas); 610 // Make sure to draw |this| opaquely. Since the toolbar color can be partially
594 if (HasFocus()) 611 // transparent, start with a black backdrop (which is the default initialized
595 canvas->DrawFocusRect(GetLocalBounds()); 612 // color for opaque canvases).
613 canvas->DrawColor(SK_ColorBLACK);
614 canvas->DrawColor(
615 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR));
616
617 DrawStatusText(canvas);
618 DrawFilename(canvas);
619 DrawIcon(canvas);
620 OnPaintBorder(canvas);
596 } 621 }
597 622
598 // The DownloadItemView can be in three major modes (NORMAL_MODE, DANGEROUS_MODE 623 int DownloadItemView::GetYForFilenameText() const {
599 // and MALICIOUS_MODE). 624 int text_height = font_list_.GetBaseline();
600 // 625 if (!status_text_.empty())
601 // NORMAL_MODE: We are displaying an in-progress or completed download. 626 text_height += kVerticalTextPadding + status_font_list_.GetBaseline();
602 // .-------------------------------+-. 627 return (height() - text_height) / 2;
603 // | [icon] Filename |v| 628 }
604 // | [ ] Status | |
605 // `-------------------------------+-'
606 // | | \_ Drop down button. Invokes menu. Responds
607 // | | to mouse. (NORMAL, HOT or PUSHED).
608 // | \_ Icon is overlaid on top of in-progress animation.
609 // \_ Both the body and the drop down button respond to mouse hover and can be
610 // pushed (NORMAL, HOT or PUSHED).
611 //
612 // DANGEROUS_MODE: The file could be potentially dangerous.
613 // .-------------------------------------------------------.
614 // | [ ! ] [This type of file can ] [ Keep ] [ Discard ] |
615 // | [ ] [destroy your computer..] [ ] [ ] |
616 // `-------------------------------------------------------'
617 // | | | | \_ No drop down button.
618 // | | | \_ Buttons are views::LabelButtons.
619 // | | \_ Text is in a label (dangerous_download_label_)
620 // | \_ Warning icon. No progress animation.
621 // \_ Body is static. Doesn't respond to mouse hover or press. (NORMAL only)
622 //
623 // MALICIOUS_MODE: The file is known malware.
624 // .---------------------------------------------+-.
625 // | [ - ] [This file is malicious.] [ Discard ] |v|
626 // | [ ] [ ] [ ] | |-.
627 // `---------------------------------------------+-' |
628 // | | | | Drop down button. Responds to
629 // | | | | mouse.(NORMAL, HOT or PUSHED)
630 // | | | \_ Button is a views::LabelButton.
631 // | | \_ Text is in a label (dangerous_download_label_)
632 // | \_ Warning icon. No progress animation.
633 // \_ Body is static. Doesn't respond to mouse hover or press. (NORMAL only)
634 //
635 void DownloadItemView::OnPaintBackground(gfx::Canvas* canvas) {
636 BodyImageSet* body_image_set = NULL;
637 switch (mode_) {
638 case NORMAL_MODE:
639 if (body_state_ == PUSHED)
640 body_image_set = &pushed_body_image_set_;
641 else // NORMAL or HOT
642 body_image_set = &normal_body_image_set_;
643 break;
644 case DANGEROUS_MODE:
645 body_image_set = &dangerous_mode_body_image_set_;
646 break;
647 case MALICIOUS_MODE:
648 body_image_set = &malicious_mode_body_image_set_;
649 break;
650 default:
651 NOTREACHED();
652 }
653 629
654 DropDownImageSet* drop_down_image_set = NULL; 630 void DownloadItemView::DrawStatusText(gfx::Canvas* canvas) {
655 switch (mode_) { 631 if (status_text_.empty() || IsShowingWarningDialog())
656 case NORMAL_MODE:
657 case MALICIOUS_MODE:
658 if (drop_down_state_ == PUSHED)
659 drop_down_image_set = &pushed_drop_down_image_set_;
660 else // NORMAL or HOT
661 drop_down_image_set = &normal_drop_down_image_set_;
662 break;
663 case DANGEROUS_MODE:
664 // We don't use a drop down button for mode_ == DANGEROUS_MODE. So we let
665 // drop_down_image_set == NULL.
666 break;
667 default:
668 NOTREACHED();
669 }
670
671 int center_width = width() - kLeftPadding -
672 body_image_set->left->width() -
673 body_image_set->right->width() -
674 (drop_down_image_set ?
675 normal_drop_down_image_set_.center->width() :
676 0);
677
678 // May be caused by animation.
679 if (center_width <= 0)
680 return; 632 return;
681 633
682 // Draw status before button image to effectively lighten text. No status for 634 int mirrored_x = GetMirroredXWithWidthInView(
683 // warning dialogs. 635 kStartPadding + DownloadShelf::kProgressIndicatorSize +
684 if (!IsShowingWarningDialog()) { 636 kProgressTextPadding,
685 if (!status_text_.empty()) { 637 kTextWidth);
686 int mirrored_x = GetMirroredXWithWidthInView( 638 int y =
687 2 * kProgressPadding + DownloadShelf::kProgressIndicatorSize, 639 GetYForFilenameText() + font_list_.GetBaseline() + kVerticalTextPadding;
688 kTextWidth); 640 canvas->DrawStringRect(
689 // Add font_list_.height() to compensate for title, which is drawn later. 641 status_text_, status_font_list_, GetDimmedTextColor(),
690 int y = box_y_ + kVerticalPadding + font_list_.GetHeight() + 642 gfx::Rect(mirrored_x, y, kTextWidth, status_font_list_.GetHeight()));
691 kVerticalTextPadding; 643 }
692 SkColor file_name_color = GetThemeProvider()->GetColor(
693 ThemeProperties::COLOR_BOOKMARK_TEXT);
694 // If text is light-on-dark, lightening it alone will do nothing. In this
695 // case we multiply color components by 80% before drawing.
696 if (!color_utils::IsDark(file_name_color)) {
697 file_name_color =
698 color_utils::AlphaBlend(SK_ColorBLACK, file_name_color, 255 / 5);
699 }
700 canvas->DrawStringRect(status_text_, font_list_, file_name_color,
701 gfx::Rect(mirrored_x, y, kTextWidth,
702 font_list_.GetHeight()));
703 }
704 }
705 644
706 // Paint the background images. 645 void DownloadItemView::DrawFilename(gfx::Canvas* canvas) {
707 { 646 if (IsShowingWarningDialog())
708 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width()); 647 return;
709
710 int x = kLeftPadding;
711 PaintImages(canvas,
712 body_image_set->top_left, body_image_set->left,
713 body_image_set->bottom_left,
714 x, box_y_, box_height_, body_image_set->top_left->width());
715 x += body_image_set->top_left->width();
716 PaintImages(canvas,
717 body_image_set->top, body_image_set->center,
718 body_image_set->bottom,
719 x, box_y_, box_height_, center_width);
720 x += center_width;
721 PaintImages(canvas,
722 body_image_set->top_right, body_image_set->right,
723 body_image_set->bottom_right,
724 x, box_y_, box_height_, body_image_set->top_right->width());
725
726 // Overlay our body hot state. Warning dialogs don't display body a hot
727 // state.
728 if (!IsShowingWarningDialog() &&
729 body_hover_animation_->GetCurrentValue() > 0) {
730 canvas->SaveLayerAlpha(
731 static_cast<int>(body_hover_animation_->GetCurrentValue() * 255));
732
733 int x = kLeftPadding;
734 PaintImages(canvas,
735 hot_body_image_set_.top_left, hot_body_image_set_.left,
736 hot_body_image_set_.bottom_left,
737 x, box_y_, box_height_,
738 hot_body_image_set_.top_left->width());
739 x += body_image_set->top_left->width();
740 PaintImages(canvas,
741 hot_body_image_set_.top, hot_body_image_set_.center,
742 hot_body_image_set_.bottom,
743 x, box_y_, box_height_, center_width);
744 x += center_width;
745 PaintImages(canvas,
746 hot_body_image_set_.top_right, hot_body_image_set_.right,
747 hot_body_image_set_.bottom_right,
748 x, box_y_, box_height_,
749 hot_body_image_set_.top_right->width());
750 canvas->Restore();
751 }
752
753 x += body_image_set->top_right->width();
754
755 // Paint the drop-down.
756 if (drop_down_image_set) {
757 PaintImages(canvas,
758 drop_down_image_set->top, drop_down_image_set->center,
759 drop_down_image_set->bottom,
760 x, box_y_, box_height_, drop_down_image_set->top->width());
761
762 // Overlay our drop-down hot state.
763 if (drop_hover_animation_->GetCurrentValue() > 0) {
764 canvas->SaveLayerAlpha(
765 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255));
766
767 PaintImages(canvas,
768 drop_down_image_set->top, drop_down_image_set->center,
769 drop_down_image_set->bottom,
770 x, box_y_, box_height_, drop_down_image_set->top->width());
771
772 canvas->Restore();
773 }
774 }
775 }
776 648
777 // Print the text, left aligned and always print the file extension. 649 // Print the text, left aligned and always print the file extension.
778 // Last value of x was the end of the right image, just before the button. 650 // Last value of x was the end of the right image, just before the button.
779 // Note that in dangerous mode we use a label (as the text is multi-line). 651 // Note that in dangerous mode we use a label (as the text is multi-line).
780 if (!IsShowingWarningDialog()) { 652 base::string16 filename;
781 base::string16 filename; 653 if (!disabled_while_opening_) {
782 if (!disabled_while_opening_) { 654 filename = gfx::ElideFilename(download()->GetFileNameToReportUser(),
783 filename = gfx::ElideFilename(download()->GetFileNameToReportUser(), 655 font_list_, kTextWidth);
784 font_list_, kTextWidth); 656 } else {
785 } else { 657 // First, Calculate the download status opening string width.
786 // First, Calculate the download status opening string width. 658 base::string16 status_string = l10n_util::GetStringFUTF16(
787 base::string16 status_string = 659 IDS_DOWNLOAD_STATUS_OPENING, base::string16());
788 l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, 660 int status_string_width = gfx::GetStringWidth(status_string, font_list_);
789 base::string16()); 661 // Then, elide the file name.
790 int status_string_width = gfx::GetStringWidth(status_string, font_list_); 662 base::string16 filename_string =
791 // Then, elide the file name. 663 gfx::ElideFilename(download()->GetFileNameToReportUser(), font_list_,
792 base::string16 filename_string = 664 kTextWidth - status_string_width);
793 gfx::ElideFilename(download()->GetFileNameToReportUser(), font_list_, 665 // Last, concat the whole string.
794 kTextWidth - status_string_width); 666 filename = l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING,
795 // Last, concat the whole string. 667 filename_string);
796 filename = l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING,
797 filename_string);
798 }
799
800 int mirrored_x = GetMirroredXWithWidthInView(
801 2 * kProgressPadding + DownloadShelf::kProgressIndicatorSize,
802 kTextWidth);
803 SkColor file_name_color = GetThemeProvider()->GetColor(
804 ThemeProperties::COLOR_BOOKMARK_TEXT);
805 int y =
806 box_y_ + (status_text_.empty() ?
807 ((box_height_ - font_list_.GetHeight()) / 2) : kVerticalPadding);
808
809 // Draw the file's name.
810 canvas->DrawStringRect(
811 filename, font_list_,
812 enabled() ? file_name_color : kFileNameDisabledColor,
813 gfx::Rect(mirrored_x, y, kTextWidth, font_list_.GetHeight()));
814 } 668 }
815 669
816 // Load the icon. 670 int mirrored_x = GetMirroredXWithWidthInView(
817 IconManager* im = g_browser_process->icon_manager(); 671 kStartPadding + DownloadShelf::kProgressIndicatorSize +
818 gfx::Image* image = im->LookupIconFromFilepath( 672 kProgressTextPadding,
819 download()->GetTargetFilePath(), IconLoader::SMALL); 673 kTextWidth);
820 const gfx::ImageSkia* icon = NULL; 674 canvas->DrawStringRect(filename, font_list_,
821 if (IsShowingWarningDialog()) 675 enabled() ? GetTextColor() : GetDimmedTextColor(),
822 icon = warning_icon_; 676 gfx::Rect(mirrored_x, GetYForFilenameText(),
823 else if (image) 677 kTextWidth, font_list_.GetHeight()));
824 icon = image->ToImageSkia(); 678 }
825 679
826 // We count on the fact that the icon manager will cache the icons and if one 680 void DownloadItemView::DrawIcon(gfx::Canvas* canvas) {
827 // is available, it will be cached here. We *don't* want to request the icon 681 if (IsShowingWarningDialog()) {
828 // to be loaded here, since this will also get called if the icon can't be 682 int icon_x = base::i18n::IsRTL()
829 // loaded, in which case LookupIcon will always be NULL. The loading will be 683 ? width() - kWarningIconSize - kStartPadding
830 // triggered only when we think the status might change. 684 : kStartPadding;
831 if (icon) { 685 int icon_y = (height() - kWarningIconSize) / 2;
832 int progress_x = 686 canvas->DrawImageInt(GetWarningIcon(), icon_x, icon_y);
833 base::i18n::IsRTL() 687 return;
834 ? width() - kProgressPadding - DownloadShelf::kProgressIndicatorSize 688 }
835 : kProgressPadding;
836 int progress_y = kProgressPadding;
837 689
838 if (!IsShowingWarningDialog()) { 690 // Paint download progress.
839 canvas->Save(); 691 DownloadItem::DownloadState state = download()->GetState();
840 canvas->Translate(gfx::Vector2d(progress_x, progress_y)); 692 canvas->Save();
693 int progress_x =
694 base::i18n::IsRTL()
695 ? width() - kStartPadding - DownloadShelf::kProgressIndicatorSize
696 : kStartPadding;
697 int progress_y = (height() - DownloadShelf::kProgressIndicatorSize) / 2;
698 canvas->Translate(gfx::Vector2d(progress_x, progress_y));
841 699
842 DownloadItem::DownloadState state = download()->GetState(); 700 if (state == DownloadItem::IN_PROGRESS) {
843 if (state == DownloadItem::IN_PROGRESS) { 701 base::TimeDelta progress_time = previous_progress_elapsed_;
844 base::TimeDelta progress_time = previous_progress_elapsed_; 702 if (!download()->IsPaused())
845 if (!download()->IsPaused()) 703 progress_time += base::TimeTicks::Now() - progress_start_time_;
846 progress_time += base::TimeTicks::Now() - progress_start_time_; 704 DownloadShelf::PaintDownloadProgress(
847 DownloadShelf::PaintDownloadProgress(canvas, *GetThemeProvider(), 705 canvas, *GetThemeProvider(), progress_time, model_.PercentComplete());
848 progress_time, 706 } else if (complete_animation_.get() && complete_animation_->is_animating()) {
849 model_.PercentComplete()); 707 if (state == DownloadItem::INTERRUPTED) {
850 } else if (complete_animation_.get() && 708 DownloadShelf::PaintDownloadInterrupted(
851 complete_animation_->is_animating()) { 709 canvas, *GetThemeProvider(), complete_animation_->GetCurrentValue());
852 if (state == DownloadItem::INTERRUPTED) {
853 DownloadShelf::PaintDownloadInterrupted(
854 canvas, *GetThemeProvider(),
855 complete_animation_->GetCurrentValue());
856 } else {
857 DCHECK_EQ(DownloadItem::COMPLETE, state);
858 DownloadShelf::PaintDownloadComplete(
859 canvas, *GetThemeProvider(),
860 complete_animation_->GetCurrentValue());
861 }
862 }
863 canvas->Restore();
864 }
865
866 // Draw the icon image.
867 int icon_x, icon_y;
868
869 if (IsShowingWarningDialog()) {
870 icon_x = kLeftPadding + body_image_set->top_left->width();
871 icon_x = GetMirroredXWithWidthInView(icon_x, icon->width());
872 icon_y = (height() - icon->height()) / 2;
873 } else { 710 } else {
874 icon_x = progress_x + DownloadShelf::kFiletypeIconOffset; 711 DCHECK_EQ(DownloadItem::COMPLETE, state);
875 icon_y = progress_y + DownloadShelf::kFiletypeIconOffset; 712 DownloadShelf::PaintDownloadComplete(
876 } 713 canvas, *GetThemeProvider(), complete_animation_->GetCurrentValue());
877 if (enabled()) {
878 canvas->DrawImageInt(*icon, icon_x, icon_y);
879 } else {
880 // Use an alpha to make the image look disabled.
881 SkPaint paint;
882 paint.setAlpha(120);
883 canvas->DrawImageInt(*icon, icon_x, icon_y, paint);
884 } 714 }
885 } 715 }
716 canvas->Restore();
717
718 // Fetch the already-loaded icon.
719 IconManager* im = g_browser_process->icon_manager();
720 gfx::Image* icon = im->LookupIconFromFilepath(download()->GetTargetFilePath(),
721 IconLoader::SMALL);
722 if (!icon)
723 return;
724
725 // Draw the icon image.
726 int icon_x = progress_x + DownloadShelf::kFiletypeIconOffset;
727 int icon_y = progress_y + DownloadShelf::kFiletypeIconOffset;
728 SkPaint paint;
729 // Use an alpha to make the image look disabled.
730 if (!enabled())
731 paint.setAlpha(120);
732 canvas->DrawImageInt(*icon->ToImageSkia(), icon_x, icon_y, paint);
886 } 733 }
887 734
888 void DownloadItemView::OnFocus() { 735 void DownloadItemView::OnFocus() {
889 View::OnFocus(); 736 View::OnFocus();
890 // We render differently when focused. 737 // We render differently when focused.
891 SchedulePaint(); 738 SchedulePaint();
892 } 739 }
893 740
894 void DownloadItemView::OnBlur() { 741 void DownloadItemView::OnBlur() {
895 View::OnBlur(); 742 View::OnBlur();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 780
934 void DownloadItemView::PossiblySubmitDownloadToFeedbackService(bool enabled) { 781 void DownloadItemView::PossiblySubmitDownloadToFeedbackService(bool enabled) {
935 if (!enabled || !SubmitDownloadToFeedbackService()) 782 if (!enabled || !SubmitDownloadToFeedbackService())
936 download()->Remove(); 783 download()->Remove();
937 // WARNING: 'this' is deleted at this point. Don't access 'this'. 784 // WARNING: 'this' is deleted at this point. Don't access 'this'.
938 } 785 }
939 786
940 void DownloadItemView::LoadIcon() { 787 void DownloadItemView::LoadIcon() {
941 IconManager* im = g_browser_process->icon_manager(); 788 IconManager* im = g_browser_process->icon_manager();
942 last_download_item_path_ = download()->GetTargetFilePath(); 789 last_download_item_path_ = download()->GetTargetFilePath();
943 im->LoadIcon(last_download_item_path_, 790 im->LoadIcon(last_download_item_path_, IconLoader::SMALL,
944 IconLoader::SMALL,
945 base::Bind(&DownloadItemView::OnExtractIconComplete, 791 base::Bind(&DownloadItemView::OnExtractIconComplete,
946 base::Unretained(this)), 792 base::Unretained(this)),
947 &cancelable_task_tracker_); 793 &cancelable_task_tracker_);
948 } 794 }
949 795
950 void DownloadItemView::LoadIconIfItemPathChanged() { 796 void DownloadItemView::LoadIconIfItemPathChanged() {
951 base::FilePath current_download_path = download()->GetTargetFilePath(); 797 base::FilePath current_download_path = download()->GetTargetFilePath();
952 if (last_download_item_path_ == current_download_path) 798 if (last_download_item_path_ == current_download_path)
953 return; 799 return;
954 800
955 LoadIcon(); 801 LoadIcon();
956 } 802 }
957 803
958 void DownloadItemView::UpdateColorsFromTheme() { 804 void DownloadItemView::UpdateColorsFromTheme() {
959 if (dangerous_download_label_ && GetThemeProvider()) { 805 if (!GetThemeProvider())
960 dangerous_download_label_->SetEnabledColor( 806 return;
961 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)); 807
962 } 808 SetBorder(base::MakeUnique<SeparatorBorder>(GetThemeProvider()->GetColor(
809 ThemeProperties::COLOR_TOOLBAR_VERTICAL_SEPARATOR)));
810
811 SkColor text_color = GetTextColor();
812 if (dangerous_download_label_)
813 dangerous_download_label_->SetEnabledColor(text_color);
814 if (save_button_)
815 save_button_->SetEnabledTextColors(text_color);
816 if (discard_button_)
817 discard_button_->SetEnabledTextColors(text_color);
963 } 818 }
964 819
965 void DownloadItemView::ShowContextMenuImpl(const gfx::Point& p, 820 void DownloadItemView::ShowContextMenuImpl(const gfx::Rect& rect,
966 ui::MenuSourceType source_type) { 821 ui::MenuSourceType source_type) {
967 gfx::Point point = p;
968 gfx::Size size;
969
970 // Similar hack as in MenuButton. 822 // Similar hack as in MenuButton.
971 // We're about to show the menu from a mouse press. By showing from the 823 // We're about to show the menu from a mouse press. By showing from the
972 // mouse press event we block RootView in mouse dispatching. This also 824 // mouse press event we block RootView in mouse dispatching. This also
973 // appears to cause RootView to get a mouse pressed BEFORE the mouse 825 // appears to cause RootView to get a mouse pressed BEFORE the mouse
974 // release is seen, which means RootView sends us another mouse press no 826 // release is seen, which means RootView sends us another mouse press no
975 // matter where the user pressed. To force RootView to recalculate the 827 // matter where the user pressed. To force RootView to recalculate the
976 // mouse target during the mouse press we explicitly set the mouse handler 828 // mouse target during the mouse press we explicitly set the mouse handler
977 // to NULL. 829 // to NULL.
978 static_cast<views::internal::RootView*>(GetWidget()->GetRootView())-> 830 static_cast<views::internal::RootView*>(GetWidget()->GetRootView())
979 SetMouseHandler(NULL); 831 ->SetMouseHandler(NULL);
980
981 // If |is_mouse_gesture| is false, |p| is ignored. The menu is shown aligned
982 // to drop down arrow button.
983 if (source_type != ui::MENU_SOURCE_MOUSE &&
984 source_type != ui::MENU_SOURCE_TOUCH) {
985 drop_down_pressed_ = true;
986 SetState(NORMAL, PUSHED);
987 point.SetPoint(drop_down_x_left_, box_y_);
988 size.SetSize(drop_down_x_right_ - drop_down_x_left_, box_height_);
989 }
990 views::View::ConvertPointToScreen(this, &point);
991 832
992 if (!context_menu_.get()) 833 if (!context_menu_.get())
993 context_menu_.reset(new DownloadShelfContextMenuView(download())); 834 context_menu_.reset(new DownloadShelfContextMenuView(download()));
994 835 context_menu_->Run(GetWidget()->GetTopLevelWidget(), rect, source_type,
995 context_menu_->Run(GetWidget()->GetTopLevelWidget(), gfx::Rect(point, size), 836 base::Bind(&DownloadItemView::ReleaseDropdown,
996 source_type, base::Bind(&DownloadItemView::ReleaseDropDown, 837 weak_ptr_factory_.GetWeakPtr()));
997 weak_ptr_factory_.GetWeakPtr()));
998 } 838 }
999 839
1000 void DownloadItemView::HandlePressEvent(const ui::LocatedEvent& event, 840 void DownloadItemView::HandlePressEvent(const ui::LocatedEvent& event,
1001 bool active_event) { 841 bool active_event) {
1002 // The event should not activate us in dangerous mode. 842 // The event should not activate us in dangerous/malicious mode.
1003 if (mode_ == DANGEROUS_MODE) 843 if (IsShowingWarningDialog())
1004 return; 844 return;
1005 845
1006 // Stop any completion animation. 846 // Stop any completion animation.
1007 if (complete_animation_.get() && complete_animation_->is_animating()) 847 if (complete_animation_.get() && complete_animation_->is_animating())
1008 complete_animation_->End(); 848 complete_animation_->End();
1009 849
1010 if (active_event) { 850 // Don't show the ripple for right clicks.
1011 if (InDropDownButtonXCoordinateRange(event.x())) { 851 if (!active_event)
1012 if (context_menu_.get()) { 852 return;
1013 // Ignore two close clicks. This typically happens when the user clicks 853
1014 // the button to close the menu. 854 AnimateInkDrop(views::InkDropState::ACTION_PENDING, &event);
1015 base::TimeDelta delta =
1016 base::TimeTicks::Now() - context_menu_->close_time();
1017 if (delta.InMilliseconds() < views::kMinimumMsBetweenButtonClicks)
1018 return;
1019 }
1020 drop_down_pressed_ = true;
1021 SetState(NORMAL, PUSHED);
1022 // We are setting is_mouse_gesture to false when calling ShowContextMenu
1023 // so that the positioning of the context menu will be similar to a
1024 // keyboard invocation. I.e. we want the menu to always be positioned
1025 // next to the drop down button instead of the next to the pointer.
1026 ShowContextMenuImpl(event.location(), ui::MENU_SOURCE_KEYBOARD);
1027 // Once called, it is possible that *this was deleted (e.g.: due to
1028 // invoking the 'Discard' action.)
1029 } else if (!IsShowingWarningDialog()) {
1030 SetState(PUSHED, NORMAL);
1031 }
1032 }
1033 } 855 }
1034 856
1035 void DownloadItemView::HandleClickEvent(const ui::LocatedEvent& event, 857 void DownloadItemView::HandleClickEvent(const ui::LocatedEvent& event,
1036 bool active_event) { 858 bool active_event) {
1037 // Mouse should not activate us in dangerous mode. 859 // The event should not activate us in dangerous/malicious mode.
1038 if (mode_ == DANGEROUS_MODE) 860 if (!active_event || IsShowingWarningDialog())
1039 return; 861 return;
1040 862
1041 SetState(NORMAL, NORMAL); 863 AnimateInkDrop(views::InkDropState::ACTION_TRIGGERED, &event);
1042
1043 if (!active_event ||
1044 InDropDownButtonXCoordinateRange(event.x()) ||
1045 IsShowingWarningDialog()) {
1046 return;
1047 }
1048 864
1049 // OpenDownload may delete this, so don't add any code after this line. 865 // OpenDownload may delete this, so don't add any code after this line.
1050 OpenDownload(); 866 OpenDownload();
1051 } 867 }
1052 868
1053 // Load an icon for the file type we're downloading, and animate any in progress 869 void DownloadItemView::SetDropdownState(State new_state) {
1054 // download state. 870 // Avoid extra SchedulePaint()s if the state is going to be the same and
1055 void DownloadItemView::PaintImages(gfx::Canvas* canvas, 871 // |dropdown_button_| has already been initialized.
1056 const gfx::ImageSkia* top_image, 872 if (dropdown_state_ == new_state &&
1057 const gfx::ImageSkia* center_image, 873 !dropdown_button_->GetImage(views::CustomButton::STATE_NORMAL).isNull())
1058 const gfx::ImageSkia* bottom_image,
1059 int x, int y, int height, int width) {
1060 int middle_height = height - top_image->height() - bottom_image->height();
1061 // Draw the top.
1062 canvas->DrawImageInt(*top_image,
1063 0, 0, top_image->width(), top_image->height(),
1064 x, y, width, top_image->height(), false);
1065 y += top_image->height();
1066 // Draw the center.
1067 canvas->DrawImageInt(*center_image,
1068 0, 0, center_image->width(), center_image->height(),
1069 x, y, width, middle_height, false);
1070 y += middle_height;
1071 // Draw the bottom.
1072 canvas->DrawImageInt(*bottom_image,
1073 0, 0, bottom_image->width(), bottom_image->height(),
1074 x, y, width, bottom_image->height(), false);
1075 }
1076
1077 void DownloadItemView::SetState(State new_body_state, State new_drop_state) {
1078 // If we are showing a warning dialog, we don't change body state.
1079 if (IsShowingWarningDialog()) {
1080 new_body_state = NORMAL;
1081
1082 // Current body_state_ should always be NORMAL for warning dialogs.
1083 DCHECK_EQ(NORMAL, body_state_);
1084 // We shouldn't be calling SetState if we are in DANGEROUS_MODE.
1085 DCHECK_NE(DANGEROUS_MODE, mode_);
1086 }
1087 // Avoid extra SchedulePaint()s if the state is going to be the same.
1088 if (body_state_ == new_body_state && drop_down_state_ == new_drop_state)
1089 return; 874 return;
1090 875
1091 AnimateStateTransition(body_state_, new_body_state, 876 dropdown_button_->SetIcon(new_state == PUSHED ? gfx::VectorIconId::FIND_NEXT
1092 body_hover_animation_.get()); 877 : gfx::VectorIconId::FIND_PREV);
1093 AnimateStateTransition(drop_down_state_, new_drop_state, 878 if (new_state != dropdown_state_) {
1094 drop_hover_animation_.get()); 879 dropdown_button_->AnimateInkDrop(new_state == PUSHED
1095 body_state_ = new_body_state; 880 ? views::InkDropState::ACTIVATED
1096 drop_down_state_ = new_drop_state; 881 : views::InkDropState::DEACTIVATED);
882 }
883 dropdown_button_->OnThemeChanged();
884 dropdown_state_ = new_state;
1097 SchedulePaint(); 885 SchedulePaint();
1098 } 886 }
1099 887
1100 void DownloadItemView::ToggleWarningDialog() { 888 void DownloadItemView::ToggleWarningDialog() {
1101 if (model_.IsDangerous()) 889 if (model_.IsDangerous())
1102 ShowWarningDialog(); 890 ShowWarningDialog();
1103 else 891 else
1104 ClearWarningDialog(); 892 ClearWarningDialog();
1105 893
1106 UpdateDropDownButtonPosition(); 894 // We need to load the icon now that the download has the real path.
895 LoadIcon();
1107 896
1108 // Force the shelf to layout again as our size has changed. 897 // Force the shelf to layout again as our size has changed.
1109 shelf_->Layout(); 898 shelf_->Layout();
1110 shelf_->SchedulePaint(); 899 shelf_->SchedulePaint();
1111 } 900 }
1112 901
1113 void DownloadItemView::ClearWarningDialog() { 902 void DownloadItemView::ClearWarningDialog() {
1114 DCHECK(download()->GetDangerType() == 903 DCHECK(download()->GetDangerType() ==
1115 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); 904 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED);
1116 DCHECK(mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE); 905 DCHECK(IsShowingWarningDialog());
1117 906
1118 mode_ = NORMAL_MODE; 907 mode_ = NORMAL_MODE;
1119 body_state_ = NORMAL; 908 dropdown_state_ = NORMAL;
1120 drop_down_state_ = NORMAL;
1121 909
1122 // ExperienceSampling: User proceeded through the warning. 910 // ExperienceSampling: User proceeded through the warning.
1123 if (sampling_event_.get()) { 911 if (sampling_event_.get()) {
1124 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed); 912 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed);
1125 sampling_event_.reset(NULL); 913 sampling_event_.reset(NULL);
1126 } 914 }
1127 // Remove the views used by the warning dialog. 915 // Remove the views used by the warning dialog.
1128 if (save_button_) { 916 if (save_button_) {
1129 RemoveChildView(save_button_); 917 RemoveChildView(save_button_);
1130 delete save_button_; 918 delete save_button_;
1131 save_button_ = NULL; 919 save_button_ = NULL;
1132 } 920 }
1133 RemoveChildView(discard_button_); 921 RemoveChildView(discard_button_);
1134 delete discard_button_; 922 delete discard_button_;
1135 discard_button_ = NULL; 923 discard_button_ = NULL;
1136 RemoveChildView(dangerous_download_label_); 924 RemoveChildView(dangerous_download_label_);
1137 delete dangerous_download_label_; 925 delete dangerous_download_label_;
1138 dangerous_download_label_ = NULL; 926 dangerous_download_label_ = NULL;
1139 dangerous_download_label_sized_ = false; 927 dangerous_download_label_sized_ = false;
1140 928
1141 // We need to load the icon now that the download has the real path. 929 // We need to load the icon now that the download has the real path.
1142 LoadIcon(); 930 LoadIcon();
931
932 dropdown_button_->SetVisible(true);
1143 } 933 }
1144 934
1145 void DownloadItemView::ShowWarningDialog() { 935 void DownloadItemView::ShowWarningDialog() {
1146 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); 936 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE);
1147 time_download_warning_shown_ = base::Time::Now(); 937 time_download_warning_shown_ = base::Time::Now();
1148 content::DownloadDangerType danger_type = download()->GetDangerType(); 938 content::DownloadDangerType danger_type = download()->GetDangerType();
1149 RecordDangerousDownloadWarningShown(danger_type); 939 RecordDangerousDownloadWarningShown(danger_type);
1150 #if defined(FULL_SAFE_BROWSING) 940 #if defined(FULL_SAFE_BROWSING)
1151 if (model_.ShouldAllowDownloadFeedback()) { 941 if (model_.ShouldAllowDownloadFeedback()) {
1152 safe_browsing::DownloadFeedbackService::RecordEligibleDownloadShown( 942 safe_browsing::DownloadFeedbackService::RecordEligibleDownloadShown(
1153 danger_type); 943 danger_type);
1154 } 944 }
1155 #endif 945 #endif
1156 mode_ = model_.MightBeMalicious() ? MALICIOUS_MODE : DANGEROUS_MODE; 946 mode_ = model_.MightBeMalicious() ? MALICIOUS_MODE : DANGEROUS_MODE;
1157 947
1158 // ExperienceSampling: Dangerous or malicious download warning is being shown 948 // ExperienceSampling: Dangerous or malicious download warning is being shown
1159 // to the user, so we start a new SamplingEvent and track it. 949 // to the user, so we start a new SamplingEvent and track it.
1160 std::string event_name = model_.MightBeMalicious() 950 std::string event_name = model_.MightBeMalicious()
1161 ? ExperienceSamplingEvent::kMaliciousDownload 951 ? ExperienceSamplingEvent::kMaliciousDownload
1162 : ExperienceSamplingEvent::kDangerousDownload; 952 : ExperienceSamplingEvent::kDangerousDownload;
1163 sampling_event_.reset( 953 sampling_event_.reset(new ExperienceSamplingEvent(
1164 new ExperienceSamplingEvent(event_name, 954 event_name, download()->GetURL(), download()->GetReferrerUrl(),
1165 download()->GetURL(), 955 download()->GetBrowserContext()));
1166 download()->GetReferrerUrl(),
1167 download()->GetBrowserContext()));
1168 956
1169 body_state_ = NORMAL; 957 dropdown_state_ = NORMAL;
1170 drop_down_state_ = NORMAL;
1171 if (mode_ == DANGEROUS_MODE) { 958 if (mode_ == DANGEROUS_MODE) {
1172 save_button_ = new views::LabelButton( 959 save_button_ =
1173 this, model_.GetWarningConfirmButtonText()); 960 views::MdTextButton::Create(this, model_.GetWarningConfirmButtonText());
1174 save_button_->SetStyle(views::Button::STYLE_BUTTON);
1175 AddChildView(save_button_); 961 AddChildView(save_button_);
1176 } 962 }
1177 discard_button_ = new views::LabelButton( 963 discard_button_ = views::MdTextButton::Create(
1178 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); 964 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD));
1179 discard_button_->SetStyle(views::Button::STYLE_BUTTON);
1180 AddChildView(discard_button_); 965 AddChildView(discard_button_);
1181 966
1182 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1183 switch (danger_type) {
1184 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
1185 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
1186 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
1187 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
1188 case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED:
1189 warning_icon_ = rb.GetImageSkiaNamed(IDR_SAFEBROWSING_WARNING);
1190 break;
1191
1192 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
1193 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
1194 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
1195 case content::DOWNLOAD_DANGER_TYPE_MAX:
1196 NOTREACHED();
1197 // fallthrough
1198
1199 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
1200 warning_icon_ = rb.GetImageSkiaNamed(IDR_WARNING);
1201 }
1202 base::string16 dangerous_label = 967 base::string16 dangerous_label =
1203 model_.GetWarningText(font_list_, kTextWidth); 968 model_.GetWarningText(font_list_, kTextWidth);
1204 dangerous_download_label_ = new views::Label(dangerous_label); 969 dangerous_download_label_ = new views::Label(dangerous_label);
1205 dangerous_download_label_->SetMultiLine(true); 970 dangerous_download_label_->SetMultiLine(true);
1206 dangerous_download_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 971 dangerous_download_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1207 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); 972 dangerous_download_label_->SetAutoColorReadabilityEnabled(false);
1208 AddChildView(dangerous_download_label_); 973 AddChildView(dangerous_download_label_);
1209 SizeLabelToMinWidth(); 974 SizeLabelToMinWidth();
975
976 dropdown_button_->SetVisible(mode_ == MALICIOUS_MODE);
977 }
978
979 gfx::ImageSkia DownloadItemView::GetWarningIcon() {
980 switch (download()->GetDangerType()) {
981 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
982 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
983 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
984 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
985 case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED:
986 return gfx::CreateVectorIcon(gfx::VectorIconId::REMOVE_CIRCLE,
987 kWarningIconSize, gfx::kGoogleRed700);
988
989 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
990 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
991 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
992 case content::DOWNLOAD_DANGER_TYPE_MAX:
993 NOTREACHED();
994 break;
995
996 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
997 return gfx::CreateVectorIcon(gfx::VectorIconId::WARNING, kWarningIconSize,
998 gfx::kGoogleYellow700);
999 }
1000 return gfx::ImageSkia();
1210 } 1001 }
1211 1002
1212 gfx::Size DownloadItemView::GetButtonSize() const { 1003 gfx::Size DownloadItemView::GetButtonSize() const {
1213 DCHECK(discard_button_ && (mode_ == MALICIOUS_MODE || save_button_)); 1004 DCHECK(discard_button_ && (mode_ == MALICIOUS_MODE || save_button_));
1214 gfx::Size size = discard_button_->GetPreferredSize(); 1005 gfx::Size size = discard_button_->GetPreferredSize();
1215 if (save_button_) 1006 if (save_button_)
1216 size.SetToMax(save_button_->GetPreferredSize()); 1007 size.SetToMax(save_button_->GetPreferredSize());
1217 return size; 1008 return size;
1218 } 1009 }
1219 1010
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 // If the width is growing again, it means we passed the optimal width spot. 1062 // If the width is growing again, it means we passed the optimal width spot.
1272 if (size.width() > min_width) { 1063 if (size.width() > min_width) {
1273 dangerous_download_label_->SetText(prev_text); 1064 dangerous_download_label_->SetText(prev_text);
1274 break; 1065 break;
1275 } else { 1066 } else {
1276 min_width = size.width(); 1067 min_width = size.width();
1277 } 1068 }
1278 prev_text = current_text; 1069 prev_text = current_text;
1279 } 1070 }
1280 1071
1281 dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); 1072 dangerous_download_label_->SetSize(size);
1282 dangerous_download_label_sized_ = true; 1073 dangerous_download_label_sized_ = true;
1283 } 1074 }
1284 1075
1285 void DownloadItemView::Reenable() { 1076 void DownloadItemView::Reenable() {
1286 disabled_while_opening_ = false; 1077 disabled_while_opening_ = false;
1287 SetEnabled(true); // Triggers a repaint. 1078 SetEnabled(true); // Triggers a repaint.
1288 } 1079 }
1289 1080
1290 void DownloadItemView::ReleaseDropDown() { 1081 void DownloadItemView::ReleaseDropdown() {
1291 drop_down_pressed_ = false; 1082 SetDropdownState(NORMAL);
1292 SetState(NORMAL, NORMAL);
1293 }
1294
1295 bool DownloadItemView::InDropDownButtonXCoordinateRange(int x) {
1296 if (x > drop_down_x_left_ && x < drop_down_x_right_)
1297 return true;
1298 return false;
1299 } 1083 }
1300 1084
1301 void DownloadItemView::UpdateAccessibleName() { 1085 void DownloadItemView::UpdateAccessibleName() {
1302 base::string16 new_name; 1086 base::string16 new_name;
1303 if (IsShowingWarningDialog()) { 1087 if (IsShowingWarningDialog()) {
1304 new_name = dangerous_download_label_->text(); 1088 new_name = dangerous_download_label_->text();
1305 } else { 1089 } else {
1306 new_name = status_text_ + base::char16(' ') + 1090 new_name = status_text_ + base::char16(' ') +
1307 download()->GetFileNameToReportUser().LossyDisplayName(); 1091 download()->GetFileNameToReportUser().LossyDisplayName();
1308 } 1092 }
1309 1093
1310 // If the name has changed, notify assistive technology that the name 1094 // If the name has changed, notify assistive technology that the name
1311 // has changed so they can announce it immediately. 1095 // has changed so they can announce it immediately.
1312 if (new_name != accessible_name_) { 1096 if (new_name != accessible_name_) {
1313 accessible_name_ = new_name; 1097 accessible_name_ = new_name;
1314 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); 1098 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
1315 } 1099 }
1316 } 1100 }
1317 1101
1318 void DownloadItemView::UpdateDropDownButtonPosition() { 1102 void DownloadItemView::AnimateStateTransition(State from,
1319 gfx::Size size = GetPreferredSize(); 1103 State to,
1320 if (base::i18n::IsRTL()) {
1321 // Drop down button is glued to the left of the download shelf.
1322 drop_down_x_left_ = 0;
1323 drop_down_x_right_ = normal_drop_down_image_set_.top->width();
1324 } else {
1325 // Drop down button is glued to the right of the download shelf.
1326 drop_down_x_left_ =
1327 size.width() - normal_drop_down_image_set_.top->width();
1328 drop_down_x_right_ = size.width();
1329 }
1330 }
1331
1332 void DownloadItemView::AnimateStateTransition(State from, State to,
1333 gfx::SlideAnimation* animation) { 1104 gfx::SlideAnimation* animation) {
1334 if (from == NORMAL && to == HOT) { 1105 if (from == NORMAL && to == HOT) {
1335 animation->Show(); 1106 animation->Show();
1336 } else if (from == HOT && to == NORMAL) { 1107 } else if (from == HOT && to == NORMAL) {
1337 animation->Hide(); 1108 animation->Hide();
1338 } else if (from != to) { 1109 } else if (from != to) {
1339 animation->Reset((to == HOT) ? 1.0 : 0.0); 1110 animation->Reset((to == HOT) ? 1.0 : 0.0);
1340 } 1111 }
1341 } 1112 }
1342 1113
1343 void DownloadItemView::ProgressTimerFired() { 1114 void DownloadItemView::ProgressTimerFired() {
1344 // Only repaint for the indeterminate size case. Otherwise, we'll repaint only 1115 // Only repaint for the indeterminate size case. Otherwise, we'll repaint only
1345 // when there's an update notified via OnDownloadUpdated(). 1116 // when there's an update notified via OnDownloadUpdated().
1346 if (model_.PercentComplete() < 0) 1117 if (model_.PercentComplete() < 0)
1347 SchedulePaint(); 1118 SchedulePaint();
1348 } 1119 }
1120
1121 SkColor DownloadItemView::GetTextColor() const {
1122 return GetTextColorForThemeProvider(GetThemeProvider());
1123 }
1124
1125 SkColor DownloadItemView::GetDimmedTextColor() const {
1126 return SkColorSetA(GetTextColor(), 0xC7);
1127 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/download/download_item_view.h ('k') | chrome/browser/ui/views/download/download_item_view_md.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698