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

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

Issue 6043: Added dangerous download prompting. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/views/download_item_view.h" 5 #include "chrome/browser/views/download_item_view.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/file_util.h"
10 #include "base/string_util.h"
9 #include "chrome/app/theme/theme_resources.h" 11 #include "chrome/app/theme/theme_resources.h"
10 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/download/download_util.h" 13 #include "chrome/browser/download/download_util.h"
12 #include "chrome/browser/views/download_shelf_view.h" 14 #include "chrome/browser/views/download_shelf_view.h"
13 #include "chrome/common/gfx/chrome_canvas.h" 15 #include "chrome/common/gfx/chrome_canvas.h"
14 #include "chrome/common/resource_bundle.h" 16 #include "chrome/common/resource_bundle.h"
15 #include "chrome/common/win_util.h" 17 #include "chrome/common/win_util.h"
18 #include "chrome/views/native_button.h"
16 #include "chrome/views/root_view.h" 19 #include "chrome/views/root_view.h"
17 #include "chrome/views/view_container.h" 20 #include "chrome/views/view_container.h"
18 21
19 #include "generated_resources.h" 22 #include "generated_resources.h"
20 23
21 // TODO(paulg): These may need to be adjusted when download progress 24 // TODO(paulg): These may need to be adjusted when download progress
22 // animation is added, and also possibly to take into account 25 // animation is added, and also possibly to take into account
23 // different screen resolutions. 26 // different screen resolutions.
24 static const int kTextWidth = 140; // Pixels 27 static const int kTextWidth = 140; // Pixels
28 static const int kDangerousTextWidth = 200; // Pixels
25 static const int kHorizontalTextPadding = 2; // Pixels 29 static const int kHorizontalTextPadding = 2; // Pixels
26 static const int kVerticalPadding = 3; // Pixels 30 static const int kVerticalPadding = 3; // Pixels
27 static const int kVerticalTextSpacer = 2; // Pixels 31 static const int kVerticalTextSpacer = 2; // Pixels
28 static const int kVerticalTextPadding = 2; // Pixels 32 static const int kVerticalTextPadding = 2; // Pixels
29 33
34 // The maximum number of characters we show in a file name when displaying the
35 // dangerous download message.
36 static const int kFileNameMaxLength = 20;
37
30 // We add some padding before the left image so that the progress animation icon 38 // We add some padding before the left image so that the progress animation icon
31 // hides the corners of the left image. 39 // hides the corners of the left image.
32 static const int kLeftPadding = 0; // Pixels. 40 static const int kLeftPadding = 0; // Pixels.
33 41
42 // The space between the Save and Discard buttons when prompting for a dangerous
43 // donwload.
44 static const int kButtonPadding = 5; // Pixels.
45
46 // The space on the left and right side of the dangerous donwload label.
47 static const int kLabelPadding = 4; // Pixels.
48
34 static const SkColor kFileNameColor = SkColorSetRGB(87, 108, 149); 49 static const SkColor kFileNameColor = SkColorSetRGB(87, 108, 149);
35 static const SkColor kStatusColor = SkColorSetRGB(123, 141, 174); 50 static const SkColor kStatusColor = SkColorSetRGB(123, 141, 174);
36 51
37 // How long the 'download complete' animation should last for. 52 // How long the 'download complete' animation should last for.
38 static const int kCompleteAnimationDurationMs = 2500; 53 static const int kCompleteAnimationDurationMs = 2500;
39 54
40 // DownloadItemView ------------------------------------------------------------ 55 // DownloadItemView ------------------------------------------------------------
41 56
42 DownloadItemView::DownloadItemView(DownloadItem* download, 57 DownloadItemView::DownloadItemView(DownloadItem* download,
43 DownloadShelfView* parent, 58 DownloadShelfView* parent,
44 DownloadItemView::BaseDownloadItemModel* model) 59 DownloadItemView::BaseDownloadItemModel* model)
45 : download_(download), 60 : download_(download),
46 parent_(parent), 61 parent_(parent),
47 model_(model), 62 model_(model),
48 progress_angle_(download_util::kStartAngleDegrees), 63 progress_angle_(download_util::kStartAngleDegrees),
49 body_state_(NORMAL), 64 body_state_(NORMAL),
50 drop_down_state_(NORMAL), 65 drop_down_state_(NORMAL),
51 drop_down_pressed_(false), 66 drop_down_pressed_(false),
52 file_name_(download_->file_name()),
53 status_text_(l10n_util::GetString(IDS_DOWNLOAD_STATUS_STARTING)), 67 status_text_(l10n_util::GetString(IDS_DOWNLOAD_STATUS_STARTING)),
54 show_status_text_(true), 68 show_status_text_(true),
55 dragging_(false), 69 dragging_(false),
56 starting_drag_(false) { 70 starting_drag_(false),
71 warning_icon_(NULL),
72 save_button_(NULL),
73 discard_button_(NULL),
74 dangerous_download_label_(NULL),
75 dangerous_download_label_sized_(false),
76 cached_button_size_(0, 0) {
57 // TODO(idana) Bug# 1163334 77 // TODO(idana) Bug# 1163334
58 // 78 //
59 // We currently do not mirror each download item on the download shelf (even 79 // We currently do not mirror each download item on the download shelf (even
60 // though the download shelf itself is mirrored and the items appear from 80 // though the download shelf itself is mirrored and the items appear from
61 // right to left on RTL UIs). 81 // right to left on RTL UIs).
62 // 82 //
63 // We explicitly disable mirroring for the item because the code that draws 83 // We explicitly disable mirroring for the item because the code that draws
64 // the download progress animation relies on the View's UI layout setting 84 // the download progress animation relies on the View's UI layout setting
65 // when positioning the animation so we should make sure that code doesn't 85 // when positioning the animation so we should make sure that code doesn't
66 // treat our View as a mirrored View. 86 // treat our View as a mirrored View.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 }; 143 };
124 pushed_body_image_set_ = pushed_body_image_set; 144 pushed_body_image_set_ = pushed_body_image_set;
125 145
126 DropDownImageSet pushed_drop_down_image_set = { 146 DropDownImageSet pushed_drop_down_image_set = {
127 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P), 147 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P),
128 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P), 148 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P),
129 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P) 149 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P)
130 }; 150 };
131 pushed_drop_down_image_set_ = pushed_drop_down_image_set; 151 pushed_drop_down_image_set_ = pushed_drop_down_image_set;
132 152
153 BodyImageSet dangerous_mode_body_image_set = {
154 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP),
155 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE),
156 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM),
157 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP),
158 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE),
159 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM),
160 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD),
161 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD),
162 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD)
163 };
164 dangerous_mode_body_image_set_ = dangerous_mode_body_image_set;
165
133 LoadIcon(); 166 LoadIcon();
134 167
135 font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); 168 font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
136 box_height_ = std::max<int>(2 * kVerticalPadding + font_.height() + 169 box_height_ = std::max<int>(2 * kVerticalPadding + font_.height() +
137 kVerticalTextPadding + font_.height(), 170 kVerticalTextPadding + font_.height(),
138 2 * kVerticalPadding + 171 2 * kVerticalPadding +
139 normal_body_image_set_.top_left->height() + 172 normal_body_image_set_.top_left->height() +
140 normal_body_image_set_.bottom_left->height()); 173 normal_body_image_set_.bottom_left->height());
141 174
142 if (download_util::kSmallProgressIconSize > box_height_) 175 if (download_util::kSmallProgressIconSize > box_height_)
143 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; 176 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2;
144 else 177 else
145 box_y_ = kVerticalPadding; 178 box_y_ = kVerticalPadding;
146 179
147 CSize size; 180 CSize size;
148 GetPreferredSize(&size); 181 GetPreferredSize(&size);
149 drop_down_x_ = size.cx - normal_drop_down_image_set_.top->width(); 182 drop_down_x_ = size.cx - normal_drop_down_image_set_.top->width();
150 183
151 body_hover_animation_.reset(new SlideAnimation(this)); 184 body_hover_animation_.reset(new SlideAnimation(this));
152 drop_hover_animation_.reset(new SlideAnimation(this)); 185 drop_hover_animation_.reset(new SlideAnimation(this));
153 186
187 if (download->safety_state() == DownloadItem::DANGEROUS) {
188 body_state_ = DANGEROUS;
189 drop_down_state_ = DANGEROUS;
190
191 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING);
192 save_button_ = new ChromeViews::NativeButton(
193 l10n_util::GetString(IDS_SAVE_DOWNLOAD));
194 save_button_->set_enforce_dlu_min_size(false);
195 save_button_->SetListener(this);
196 discard_button_ = new ChromeViews::NativeButton(
197 l10n_util::GetString(IDS_DISCARD_DOWNLOAD));
198 discard_button_->SetListener(this);
199 discard_button_->set_enforce_dlu_min_size(false);
200 AddChildView(save_button_);
201 AddChildView(discard_button_);
202 std::wstring file_name = download->original_name();
203 // Ensure the file name is not too long.
204 ElideString(file_name, kFileNameMaxLength, &file_name);
205 dangerous_download_label_ = new ChromeViews::Label(
206 l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, file_name));
207 dangerous_download_label_->SetMultiLine(true);
208 dangerous_download_label_->SetHorizontalAlignment(
209 ChromeViews::Label::ALIGN_LEFT);
210 dangerous_download_label_->SetColor(kFileNameColor);
211 AddChildView(dangerous_download_label_);
212 }
213
154 // Set up our animation 214 // Set up our animation
155 StartDownloadProgress(); 215 StartDownloadProgress();
156 } 216 }
157 217
158 DownloadItemView::~DownloadItemView() { 218 DownloadItemView::~DownloadItemView() {
159 icon_consumer_.CancelAllRequests(); 219 icon_consumer_.CancelAllRequests();
160 StopDownloadProgress(); 220 StopDownloadProgress();
161 download_->RemoveObserver(this); 221 download_->RemoveObserver(this);
162 } 222 }
163 223
(...skipping 18 matching lines...) Expand all
182 progress_timer_.Stop(); 242 progress_timer_.Stop();
183 } 243 }
184 244
185 // DownloadObserver interface 245 // DownloadObserver interface
186 246
187 // Update the progress graphic on the icon and our text status label 247 // Update the progress graphic on the icon and our text status label
188 // to reflect our current bytes downloaded, time remaining. 248 // to reflect our current bytes downloaded, time remaining.
189 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { 249 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) {
190 DCHECK(download == download_); 250 DCHECK(download == download_);
191 251
252 if (body_state_ == DANGEROUS &&
253 download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
254 // We have been approved.
255 ClearDangerousMode();
256 }
257
192 std::wstring status_text = model_->GetStatusText(); 258 std::wstring status_text = model_->GetStatusText();
193 switch (download_->state()) { 259 switch (download_->state()) {
194 case DownloadItem::IN_PROGRESS: 260 case DownloadItem::IN_PROGRESS:
195 download_->is_paused() ? StopDownloadProgress() : StartDownloadProgress(); 261 download_->is_paused() ? StopDownloadProgress() : StartDownloadProgress();
196 break; 262 break;
197 case DownloadItem::COMPLETE: 263 case DownloadItem::COMPLETE:
198 StopDownloadProgress(); 264 StopDownloadProgress();
199 complete_animation_.reset(new SlideAnimation(this)); 265 complete_animation_.reset(new SlideAnimation(this));
200 complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); 266 complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs);
201 complete_animation_->SetTweenType(SlideAnimation::NONE); 267 complete_animation_->SetTweenType(SlideAnimation::NONE);
(...skipping 17 matching lines...) Expand all
219 status_text_ = status_text; 285 status_text_ = status_text;
220 286
221 // We use the parent's (DownloadShelfView's) SchedulePaint, since there 287 // We use the parent's (DownloadShelfView's) SchedulePaint, since there
222 // are spaces between each DownloadItemView that the parent is responsible 288 // are spaces between each DownloadItemView that the parent is responsible
223 // for painting. 289 // for painting.
224 GetParent()->SchedulePaint(); 290 GetParent()->SchedulePaint();
225 } 291 }
226 292
227 // View overrides 293 // View overrides
228 294
295 // In dangerous mode we have to layout our buttons.
296 void DownloadItemView::Layout() {
297 if (IsDangerousMode()) {
298 SizeLabelToMinWidth();
299 int x = kLeftPadding + dangerous_mode_body_image_set_.top_left->width() +
300 warning_icon_->width() + kLabelPadding;
301 int y = (height() - dangerous_download_label_->height()) / 2;
302 dangerous_download_label_->SetBounds(x, y,
303 dangerous_download_label_->width(),
304 dangerous_download_label_->height());
305 CSize button_size;
306 GetButtonSize(&button_size);
307 x += dangerous_download_label_->width() + kLabelPadding;
308 y = (height() - button_size.cy) / 2;
309 save_button_->SetBounds(x, y, button_size.cx, button_size.cy);
310 x += button_size.cx + kButtonPadding;
311 discard_button_->SetBounds(x, y, button_size.cx, button_size.cy);
312 }
313 }
314
315 void DownloadItemView::DidChangeBounds(const CRect& previous,
316 const CRect& current) {
317 Layout();
318 }
319
320 void DownloadItemView::ButtonPressed(ChromeViews::NativeButton* sender) {
321 if (sender == discard_button_) {
322 if (download_->state() == DownloadItem::IN_PROGRESS)
323 download_->Cancel(true);
324 download_->Remove(true);
325 // WARNING: we are deleted at this point. Don't access 'this'.
326 } else if (sender == save_button_) {
327 // This will change the state and notify us.
328 download_->manager()->DangerousDownloadValidated(download_);
329 }
330 }
331
229 // Load an icon for the file type we're downloading, and animate any in progress 332 // Load an icon for the file type we're downloading, and animate any in progress
230 // download state. 333 // download state.
231 void DownloadItemView::Paint(ChromeCanvas* canvas) { 334 void DownloadItemView::Paint(ChromeCanvas* canvas) {
232 int center_width = width() - kLeftPadding -
233 normal_body_image_set_.left->width() -
234 normal_body_image_set_.right->width() -
235 normal_drop_down_image_set_.center->width();
236
237 // May be caused by animation.
238 if (center_width <= 0)
239 return;
240
241 BodyImageSet* body_image_set; 335 BodyImageSet* body_image_set;
242 switch (body_state_) { 336 switch (body_state_) {
243 case NORMAL: 337 case NORMAL:
244 case HOT: 338 case HOT:
245 body_image_set = &normal_body_image_set_; 339 body_image_set = &normal_body_image_set_;
246 break; 340 break;
247 case PUSHED: 341 case PUSHED:
248 body_image_set = &pushed_body_image_set_; 342 body_image_set = &pushed_body_image_set_;
249 break; 343 break;
344 case DANGEROUS:
345 body_image_set = &dangerous_mode_body_image_set_;
346 break;
250 default: 347 default:
251 NOTREACHED(); 348 NOTREACHED();
252 } 349 }
253 DropDownImageSet* drop_down_image_set; 350 DropDownImageSet* drop_down_image_set;
254 switch (drop_down_state_) { 351 switch (drop_down_state_) {
255 case NORMAL: 352 case NORMAL:
256 case HOT: 353 case HOT:
257 drop_down_image_set = &normal_drop_down_image_set_; 354 drop_down_image_set = &normal_drop_down_image_set_;
258 break; 355 break;
259 case PUSHED: 356 case PUSHED:
260 drop_down_image_set = &pushed_drop_down_image_set_; 357 drop_down_image_set = &pushed_drop_down_image_set_;
261 break; 358 break;
359 case DANGEROUS:
360 drop_down_image_set = NULL; // No drop-down in dangerous mode.
361 break;
262 default: 362 default:
263 NOTREACHED(); 363 NOTREACHED();
264 } 364 }
265 365
366 int center_width = width() - kLeftPadding -
367 body_image_set->left->width() -
368 body_image_set->right->width() -
369 (drop_down_image_set ?
370 normal_drop_down_image_set_.center->width() :
371 0);
372
373 // May be caused by animation.
374 if (center_width <= 0)
375 return;
376
266 // Paint the background images. 377 // Paint the background images.
267 int x = kLeftPadding; 378 int x = kLeftPadding;
268 PaintBitmaps(canvas, 379 PaintBitmaps(canvas,
269 body_image_set->top_left, body_image_set->left, 380 body_image_set->top_left, body_image_set->left,
270 body_image_set->bottom_left, 381 body_image_set->bottom_left,
271 x, box_y_, box_height_, body_image_set->top_left->width()); 382 x, box_y_, box_height_, body_image_set->top_left->width());
272 x += body_image_set->top_left->width(); 383 x += body_image_set->top_left->width();
273 PaintBitmaps(canvas, 384 PaintBitmaps(canvas,
274 body_image_set->top, body_image_set->center, 385 body_image_set->top, body_image_set->center,
275 body_image_set->bottom, 386 body_image_set->bottom,
(...skipping 18 matching lines...) Expand all
294 x, box_y_, box_height_, hot_body_image_set_.top_left->width()); 405 x, box_y_, box_height_, hot_body_image_set_.top_left->width());
295 x += body_image_set->top_left->width(); 406 x += body_image_set->top_left->width();
296 PaintBitmaps(canvas, 407 PaintBitmaps(canvas,
297 hot_body_image_set_.top, hot_body_image_set_.center, 408 hot_body_image_set_.top, hot_body_image_set_.center,
298 hot_body_image_set_.bottom, 409 hot_body_image_set_.bottom,
299 x, box_y_, box_height_, center_width); 410 x, box_y_, box_height_, center_width);
300 x += center_width; 411 x += center_width;
301 PaintBitmaps(canvas, 412 PaintBitmaps(canvas,
302 hot_body_image_set_.top_right, hot_body_image_set_.right, 413 hot_body_image_set_.top_right, hot_body_image_set_.right,
303 hot_body_image_set_.bottom_right, 414 hot_body_image_set_.bottom_right,
304 x, box_y_, box_height_, hot_body_image_set_.top_right->width()) ; 415 x, box_y_, box_height_,
416 hot_body_image_set_.top_right->width());
305 canvas->restore(); 417 canvas->restore();
306 } 418 }
307 419
308 x += body_image_set->top_right->width(); 420 x += body_image_set->top_right->width();
309 PaintBitmaps(canvas,
310 drop_down_image_set->top, drop_down_image_set->center,
311 drop_down_image_set->bottom,
312 x, box_y_, box_height_, drop_down_image_set->top->width());
313 421
314 // Overlay our drop-down hot state. 422 // Paint the drop-down.
315 if (drop_hover_animation_->GetCurrentValue() > 0) { 423 if (drop_down_image_set) {
316 canvas->saveLayerAlpha(NULL,
317 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255),
318 SkCanvas::kARGB_NoClipLayer_SaveFlag);
319 canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode);
320
321 PaintBitmaps(canvas, 424 PaintBitmaps(canvas,
322 drop_down_image_set->top, drop_down_image_set->center, 425 drop_down_image_set->top, drop_down_image_set->center,
323 drop_down_image_set->bottom, 426 drop_down_image_set->bottom,
324 x, box_y_, box_height_, drop_down_image_set->top->width()); 427 x, box_y_, box_height_, drop_down_image_set->top->width());
325 428
326 canvas->restore(); 429 // Overlay our drop-down hot state.
430 if (drop_hover_animation_->GetCurrentValue() > 0) {
431 canvas->saveLayerAlpha(NULL,
432 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255),
433 SkCanvas::kARGB_NoClipLayer_SaveFlag);
434 canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode);
435
436 PaintBitmaps(canvas,
437 drop_down_image_set->top, drop_down_image_set->center,
438 drop_down_image_set->bottom,
439 x, box_y_, box_height_, drop_down_image_set->top->width());
440
441 canvas->restore();
442 }
327 } 443 }
328 444
329 // Print the text, left aligned. 445 // Print the text, left aligned.
330 // Last value of x was the end of the right image, just before the button. 446 // Last value of x was the end of the right image, just before the button.
331 if (show_status_text_) { 447 // Note that in dangerous mode we use a label (as the text is multi-line).
332 int y = box_y_ + kVerticalPadding; 448 if (!IsDangerousMode()) {
333 canvas->DrawStringInt(file_name_, font_, kFileNameColor, 449 if (show_status_text_) {
334 download_util::kSmallProgressIconSize, y, 450 int y = box_y_ + kVerticalPadding;
335 kTextWidth, font_.height()); 451 canvas->DrawStringInt(download_->GetFileName(), font_, kFileNameColor,
336 y += font_.height() + kVerticalTextPadding; 452 download_util::kSmallProgressIconSize, y,
453 kTextWidth, font_.height());
454 y += font_.height() + kVerticalTextPadding;
337 455
338 canvas->DrawStringInt(status_text_, font_, kStatusColor, 456 canvas->DrawStringInt(status_text_, font_, kStatusColor,
339 download_util::kSmallProgressIconSize, y, 457 download_util::kSmallProgressIconSize, y,
340 kTextWidth, font_.height()); 458 kTextWidth, font_.height());
341 } else { 459 } else {
342 int y = box_y_ + (box_height_ - font_.height()) / 2; 460 int y = box_y_ + (box_height_ - font_.height()) / 2;
343 canvas->DrawStringInt(file_name_, font_, kFileNameColor, 461 canvas->DrawStringInt(download_->GetFileName(), font_, kFileNameColor,
344 download_util::kSmallProgressIconSize, y, 462 download_util::kSmallProgressIconSize, y,
345 kTextWidth, font_.height()); 463 kTextWidth, font_.height());
464 }
346 } 465 }
347 466
348 // Paint the icon. 467 // Paint the icon.
349 IconManager* im = g_browser_process->icon_manager(); 468 IconManager* im = g_browser_process->icon_manager();
350 SkBitmap* icon = im->LookupIcon(download_->full_path(), IconLoader::SMALL); 469 SkBitmap* icon = IsDangerousMode() ? warning_icon_ :
470 im->LookupIcon(download_->full_path(), IconLoader::SMALL);
351 471
352 if (icon) { 472 if (icon) {
353 if (download_->state() == DownloadItem::IN_PROGRESS) { 473 if (!IsDangerousMode()) {
354 download_util::PaintDownloadProgress(canvas, this, 0, 0, 474 if (download_->state() == DownloadItem::IN_PROGRESS) {
355 progress_angle_, 475 download_util::PaintDownloadProgress(canvas, this, 0, 0,
356 download_->PercentComplete(), 476 progress_angle_,
357 download_util::SMALL); 477 download_->PercentComplete(),
358 } else if (download_->state() == DownloadItem::COMPLETE && 478 download_util::SMALL);
359 complete_animation_->IsAnimating()) { 479 } else if (download_->state() == DownloadItem::COMPLETE &&
360 download_util::PaintDownloadComplete(canvas, this, 0, 0, 480 complete_animation_->IsAnimating()) {
361 complete_animation_->GetCurrentValue(), 481 download_util::PaintDownloadComplete(canvas, this, 0, 0,
362 download_util::SMALL); 482 complete_animation_->GetCurrentValue(),
483 download_util::SMALL);
484 }
363 } 485 }
364 486
365 // Draw the icon image 487 // Draw the icon image
366 canvas->DrawBitmapInt(*icon, 488 canvas->DrawBitmapInt(*icon,
367 download_util::kSmallProgressIconOffset, 489 download_util::kSmallProgressIconOffset,
368 download_util::kSmallProgressIconOffset); 490 download_util::kSmallProgressIconOffset);
369 } 491 }
370 } 492 }
371 493
372 void DownloadItemView::PaintBitmaps(ChromeCanvas* canvas, 494 void DownloadItemView::PaintBitmaps(ChromeCanvas* canvas,
(...skipping 20 matching lines...) Expand all
393 515
394 void DownloadItemView::SetState(State body_state, State drop_down_state) { 516 void DownloadItemView::SetState(State body_state, State drop_down_state) {
395 if (body_state_ == body_state && drop_down_state_ == drop_down_state) 517 if (body_state_ == body_state && drop_down_state_ == drop_down_state)
396 return; 518 return;
397 519
398 body_state_ = body_state; 520 body_state_ = body_state;
399 drop_down_state_ = drop_down_state; 521 drop_down_state_ = drop_down_state;
400 SchedulePaint(); 522 SchedulePaint();
401 } 523 }
402 524
525 void DownloadItemView::ClearDangerousMode() {
526 DCHECK(download_->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED &&
527 body_state_ == DANGEROUS && drop_down_state_ == DANGEROUS);
528
529 body_state_ = NORMAL;
530 drop_down_state_ = NORMAL;
531
532 // Remove the views used by the dangerours mode.
533 RemoveChildView(save_button_);
534 delete save_button_;
535 save_button_ = NULL;
536 RemoveChildView(discard_button_);
537 delete discard_button_;
538 discard_button_ = NULL;
539 RemoveChildView(dangerous_download_label_);
540 delete dangerous_download_label_;
541 dangerous_download_label_ = NULL;
542
543 // We need to load the icon now that the download_ has the real path.
544 LoadIcon();
545
546 // Force the shelf to layout again as our size has changed.
547 parent_->Layout();
548 parent_->SchedulePaint();
549 }
550
403 void DownloadItemView::GetPreferredSize(CSize* out) { 551 void DownloadItemView::GetPreferredSize(CSize* out) {
404 int width = kLeftPadding + normal_body_image_set_.top_left->width(); 552 int width, height;
405 width += download_util::kSmallProgressIconSize; 553 if (IsDangerousMode()) {
406 width += kTextWidth; 554 width = kLeftPadding + dangerous_mode_body_image_set_.top_left->width();
407 width += normal_body_image_set_.top_right->width(); 555 width += warning_icon_->width() + kLabelPadding;
408 width += normal_drop_down_image_set_.top->width(); 556 width += dangerous_download_label_->width() + kLabelPadding;
409 557 CSize button_size;
558 GetButtonSize(&button_size);
559 width += button_size.cx * 2 + kButtonPadding;
560 width += dangerous_mode_body_image_set_.top_right->width();
561 height = std::max<int>(2 * kVerticalPadding + 2 * font_.height() +
562 kVerticalTextPadding,
563 2 * kVerticalPadding + warning_icon_->height());
564 height = std::max<int>(height, 2 * kVerticalPadding + button_size.cy);
565 } else {
566 width = kLeftPadding + normal_body_image_set_.top_left->width();
567 width += download_util::kSmallProgressIconSize;
568 width += kTextWidth;
569 width += normal_body_image_set_.top_right->width();
570 width += normal_drop_down_image_set_.top->width();
571 height = std::max<int>(2 * kVerticalPadding + 2 * font_.height() +
572 kVerticalTextPadding,
573 download_util::kSmallProgressIconSize);
574 }
410 out->cx = width; 575 out->cx = width;
411 out->cy = std::max<int>( 576 out->cy = height;
412 2 * kVerticalPadding + 2 * font_.height() + kVerticalTextPadding,
413 download_util::kSmallProgressIconSize);
414 } 577 }
415 578
416 void DownloadItemView::OnMouseExited(const ChromeViews::MouseEvent& event) { 579 void DownloadItemView::OnMouseExited(const ChromeViews::MouseEvent& event) {
580 // Mouse should not activate us in dangerous mode.
581 if (IsDangerousMode())
582 return;
583
417 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL); 584 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL);
418 body_hover_animation_->Hide(); 585 body_hover_animation_->Hide();
419 drop_hover_animation_->Hide(); 586 drop_hover_animation_->Hide();
420 } 587 }
421 588
422 // Display the context menu for this item. 589 // Display the context menu for this item.
423 bool DownloadItemView::OnMousePressed(const ChromeViews::MouseEvent& event) { 590 bool DownloadItemView::OnMousePressed(const ChromeViews::MouseEvent& event) {
591 // Mouse should not activate us in dangerous mode.
592 if (IsDangerousMode())
593 return true;
594
424 // Stop any completion animation. 595 // Stop any completion animation.
425 if (complete_animation_.get() && complete_animation_->IsAnimating()) 596 if (complete_animation_.get() && complete_animation_->IsAnimating())
426 complete_animation_->End(); 597 complete_animation_->End();
427 598
428 if (event.IsOnlyLeftMouseButton()) { 599 if (event.IsOnlyLeftMouseButton()) {
429 WTL::CPoint point(event.x(), event.y()); 600 WTL::CPoint point(event.x(), event.y());
430 if (event.x() < drop_down_x_) { 601 if (event.x() < drop_down_x_) {
431 SetState(PUSHED, NORMAL); 602 SetState(PUSHED, NORMAL);
432 return true; 603 return true;
433 } 604 }
(...skipping 30 matching lines...) Expand all
464 model_.get(), 635 model_.get(),
465 point); 636 point);
466 drop_down_pressed_ = false; 637 drop_down_pressed_ = false;
467 // Showing the menu blocks. Here we revert the state. 638 // Showing the menu blocks. Here we revert the state.
468 SetState(NORMAL, NORMAL); 639 SetState(NORMAL, NORMAL);
469 } 640 }
470 return true; 641 return true;
471 } 642 }
472 643
473 void DownloadItemView::OnMouseMoved(const ChromeViews::MouseEvent& event) { 644 void DownloadItemView::OnMouseMoved(const ChromeViews::MouseEvent& event) {
645 // Mouse should not activate us in dangerous mode.
646 if (IsDangerousMode())
647 return;
648
474 bool on_body = event.x() < drop_down_x_; 649 bool on_body = event.x() < drop_down_x_;
475 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT); 650 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT);
476 if (on_body) { 651 if (on_body) {
477 body_hover_animation_->Show(); 652 body_hover_animation_->Show();
478 drop_hover_animation_->Hide(); 653 drop_hover_animation_->Hide();
479 } else { 654 } else {
480 body_hover_animation_->Hide(); 655 body_hover_animation_->Hide();
481 drop_hover_animation_->Show(); 656 drop_hover_animation_->Show();
482 } 657 }
483 } 658 }
484 659
485 void DownloadItemView::OnMouseReleased(const ChromeViews::MouseEvent& event, 660 void DownloadItemView::OnMouseReleased(const ChromeViews::MouseEvent& event,
486 bool canceled) { 661 bool canceled) {
662 // Mouse should not activate us in dangerous mode.
663 if (IsDangerousMode())
664 return;
665
487 if (dragging_) { 666 if (dragging_) {
488 // Starting a drag results in a MouseReleased, we need to ignore it. 667 // Starting a drag results in a MouseReleased, we need to ignore it.
489 dragging_ = false; 668 dragging_ = false;
490 starting_drag_ = false; 669 starting_drag_ = false;
491 return; 670 return;
492 } 671 }
493 if (event.IsOnlyLeftMouseButton() && event.x() < drop_down_x_) 672 if (event.IsOnlyLeftMouseButton() && event.x() < drop_down_x_)
494 OpenDownload(); 673 OpenDownload();
495 674
496 SetState(NORMAL, NORMAL); 675 SetState(NORMAL, NORMAL);
497 } 676 }
498 677
499 // Handle drag (file copy) operations. 678 // Handle drag (file copy) operations.
500 bool DownloadItemView::OnMouseDragged(const ChromeViews::MouseEvent& event) { 679 bool DownloadItemView::OnMouseDragged(const ChromeViews::MouseEvent& event) {
680 // Mouse should not activate us in dangerous mode.
681 if (IsDangerousMode())
682 return true;
683
501 if (!starting_drag_) { 684 if (!starting_drag_) {
502 starting_drag_ = true; 685 starting_drag_ = true;
503 drag_start_point_ = event.location(); 686 drag_start_point_ = event.location();
504 } 687 }
505 if (dragging_) { 688 if (dragging_) {
506 if (download_->state() == DownloadItem::COMPLETE) { 689 if (download_->state() == DownloadItem::COMPLETE) {
507 IconManager* im = g_browser_process->icon_manager(); 690 IconManager* im = g_browser_process->icon_manager();
508 SkBitmap* icon = im->LookupIcon(download_->full_path(), 691 SkBitmap* icon = im->LookupIcon(download_->full_path(),
509 IconLoader::SMALL); 692 IconLoader::SMALL);
510 if (icon) 693 if (icon)
(...skipping 25 matching lines...) Expand all
536 GetParent()->SchedulePaint(); 719 GetParent()->SchedulePaint();
537 } 720 }
538 721
539 void DownloadItemView::LoadIcon() { 722 void DownloadItemView::LoadIcon() {
540 IconManager* im = g_browser_process->icon_manager(); 723 IconManager* im = g_browser_process->icon_manager();
541 im->LoadIcon(download_->full_path(), IconLoader::SMALL, 724 im->LoadIcon(download_->full_path(), IconLoader::SMALL,
542 &icon_consumer_, 725 &icon_consumer_,
543 NewCallback(this, &DownloadItemView::OnExtractIconComplete)); 726 NewCallback(this, &DownloadItemView::OnExtractIconComplete));
544 } 727 }
545 728
729 void DownloadItemView::GetButtonSize(CSize* size) {
730 DCHECK(save_button_ && discard_button_);
731 // We cache the size when successfully retrieved, not for performance reasons
732 // but because if this DownloadItemView is being animated while the tab is
733 // not showing, the native buttons are not parented and their preferred size
734 // is 0, messing-up the layout.
735 if (cached_button_size_.cx != 0) {
736 *size = cached_button_size_;
737 }
738
739 CSize tmp_size;
740 save_button_->GetMinimumSize(size);
741 discard_button_->GetMinimumSize(&tmp_size);
742
743 size->cx = std::max(size->cx, tmp_size.cx);
744 size->cy = std::max(size->cy, tmp_size.cy);
745
746 if (size->cx != 0) {
747 cached_button_size_.cx = size->cx;
748 cached_button_size_.cy = size->cy;
749 }
750 }
751
752 // This method computes the miminum width of the label for diplaying its text
753 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the
754 // configuration with minimum width.
755 void DownloadItemView::SizeLabelToMinWidth() {
756 if (dangerous_download_label_sized_)
757 return;
758
759 std::wstring text = dangerous_download_label_->GetText();
760 TrimWhitespace(text, TRIM_ALL, &text);
761 DCHECK_EQ(std::wstring::npos, text.find(L"\n"));
762
763 // Make the label big so that GetPreferredSize() is not constrained by the
764 // current width.
765 dangerous_download_label_->SetBounds(0, 0, 1000, 1000);
766
767 CSize size(0, 0);
768 int min_width = -1;
769 int sp_index = text.find(L" ");
770 while (sp_index != std::wstring::npos) {
771 text.replace(sp_index, 1, L"\n");
772 dangerous_download_label_->SetText(text);
773 dangerous_download_label_->GetPreferredSize(&size);
774
775 if (min_width == -1)
776 min_width = size.cx;
777
778 // If thw width is growing again, it means we passed the optimal width spot.
779 if (size.cx > min_width)
780 break;
781 else
782 min_width = size.cx;
783
784 // Restore the string.
785 text.replace(sp_index, 1, L" ");
786
787 sp_index = text.find(L" ", sp_index + 1);
788 }
789
790 // If we have a line with no space, we won't cut it.
791 if (min_width == -1)
792 dangerous_download_label_->GetPreferredSize(&size);
793
794 dangerous_download_label_->SetBounds(0, 0, size.cx, size.cy);
795 dangerous_download_label_sized_ = true;
796 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698