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

Side by Side Diff: chrome/browser/views/download_tab_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_tab_view.h" 5 #include "chrome/browser/views/download_tab_view.h"
6 6
7 #include <time.h> 7 #include <time.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <functional> 10 #include <functional>
(...skipping 12 matching lines...) Expand all
23 #include "chrome/common/l10n_util.h" 23 #include "chrome/common/l10n_util.h"
24 #include "chrome/common/resource_bundle.h" 24 #include "chrome/common/resource_bundle.h"
25 #include "chrome/common/stl_util-inl.h" 25 #include "chrome/common/stl_util-inl.h"
26 #include "chrome/common/time_format.h" 26 #include "chrome/common/time_format.h"
27 #include "chrome/views/background.h" 27 #include "chrome/views/background.h"
28 #include "googleurl/src/gurl.h" 28 #include "googleurl/src/gurl.h"
29 #include "generated_resources.h" 29 #include "generated_resources.h"
30 30
31 // Approximate spacing, in pixels, taken from initial UI mock up screens 31 // Approximate spacing, in pixels, taken from initial UI mock up screens
32 static const int kVerticalPadding = 5; 32 static const int kVerticalPadding = 5;
33 static const int kHorizontalButtonPadding = 15; 33 static const int kHorizontalLinkPadding = 15;
34 static const int kHorizontalButtonPadding = 8;
34 35
35 // For vertical and horizontal element spacing 36 // For vertical and horizontal element spacing
36 static const int kSpacer = 20; 37 static const int kSpacer = 20;
37 38
38 // Horizontal space between the left edge of the entries and the 39 // Horizontal space between the left edge of the entries and the
39 // left edge of the view. 40 // left edge of the view.
40 static const int kLeftMargin = 38; 41 static const int kLeftMargin = 38;
41 42
42 // x-position of the icon (massage this so it visually matches 43 // x-position of the icon (massage this so it visually matches
43 // kDestinationSearchOffset in native_ui_contents.cc 44 // kDestinationSearchOffset in native_ui_contents.cc
(...skipping 14 matching lines...) Expand all
58 59
59 // Status label color (grey) 60 // Status label color (grey)
60 static const SkColor kStatusColor = SkColorSetRGB(128, 128, 128); 61 static const SkColor kStatusColor = SkColorSetRGB(128, 128, 128);
61 62
62 // URL label color (green) 63 // URL label color (green)
63 static const SkColor kUrlColor = SkColorSetRGB(0, 128, 0); 64 static const SkColor kUrlColor = SkColorSetRGB(0, 128, 0);
64 65
65 // Paused download indicator (red) 66 // Paused download indicator (red)
66 static const SkColor kPauseColor = SkColorSetRGB(128, 0, 0); 67 static const SkColor kPauseColor = SkColorSetRGB(128, 0, 0);
67 68
69 // Warning label color (blue)
70 static const SkColor kWarningColor = SkColorSetRGB(87, 108, 149);
71
68 // Selected item background color 72 // Selected item background color
69 static const SkColor kSelectedItemColor = SkColorSetRGB(215, 232, 255); 73 static const SkColor kSelectedItemColor = SkColorSetRGB(215, 232, 255);
70 74
71 // State key used to identify search text. 75 // State key used to identify search text.
72 static const wchar_t kSearchTextKey[] = L"st"; 76 static const wchar_t kSearchTextKey[] = L"st";
73 77
78 // The maximum number of characters we show in a file name when displaying the
79 // dangerous download message.
80 static const int kFileNameMaxLength = 20;
81
74 // Sorting functor for DownloadItem -------------------------------------------- 82 // Sorting functor for DownloadItem --------------------------------------------
75 83
76 // Sort DownloadItems into ascending order by their start time. 84 // Sort DownloadItems into ascending order by their start time.
77 class DownloadItemSorter : public std::binary_function<DownloadItem*, 85 class DownloadItemSorter : public std::binary_function<DownloadItem*,
78 DownloadItem*, 86 DownloadItem*,
79 bool> { 87 bool> {
80 public: 88 public:
81 bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) { 89 bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) {
82 return lhs->start_time() < rhs->start_time(); 90 return lhs->start_time() < rhs->start_time();
83 } 91 }
84 }; 92 };
85 93
86 94
87 // DownloadItemTabView implementation ------------------------------------------ 95 // DownloadItemTabView implementation ------------------------------------------
88 DownloadItemTabView::DownloadItemTabView() 96 DownloadItemTabView::DownloadItemTabView()
89 : model_(NULL), 97 : model_(NULL),
90 parent_(NULL) { 98 parent_(NULL),
99 is_floating_view_renderer_(false) {
91 // Create our element views using empty strings for now, 100 // Create our element views using empty strings for now,
92 // set them based on the model's state in Layout(). 101 // set them based on the model's state in Layout().
93 since_ = new ChromeViews::Label(L""); 102 since_ = new ChromeViews::Label(L"");
94 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 103 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
95 ChromeFont font = rb.GetFont(ResourceBundle::WebFont); 104 ChromeFont font = rb.GetFont(ResourceBundle::WebFont);
96 since_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT); 105 since_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT);
97 since_->SetFont(font); 106 since_->SetFont(font);
98 AddChildView(since_); 107 AddChildView(since_);
99 108
100 date_ = new ChromeViews::Label(L""); 109 date_ = new ChromeViews::Label(L"");
101 date_->SetColor(kStatusColor); 110 date_->SetColor(kStatusColor);
102 date_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT); 111 date_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT);
103 date_->SetFont(font); 112 date_->SetFont(font);
104 AddChildView(date_); 113 AddChildView(date_);
105 114
106 // file_name_ is enabled once the download has finished and we can open 115 // file_name_ is enabled once the download has finished and we can open
107 // it via ShellExecute. 116 // it via ShellExecute.
108 file_name_ = new ChromeViews::Link(L""); 117 file_name_ = new ChromeViews::Link(L"");
109 file_name_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT); 118 file_name_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT);
110 file_name_->SetController(this); 119 file_name_->SetController(this);
111 file_name_->SetFont(font); 120 file_name_->SetFont(font);
112 AddChildView(file_name_); 121 AddChildView(file_name_);
113 122
123 // dangerous_download_warning_ is enabled when a dangerous download has been
124 // initiated.
125 dangerous_download_warning_ = new ChromeViews::Label();
126 dangerous_download_warning_ ->SetMultiLine(true);
127 dangerous_download_warning_->SetColor(kWarningColor);
128 dangerous_download_warning_->SetHorizontalAlignment(
129 ChromeViews::Label::ALIGN_LEFT);
130 dangerous_download_warning_->SetFont(font);
131 AddChildView(dangerous_download_warning_);
132
133 // The save and discard buttons are shown to prompt the user when a dangerous
134 // download was started.
135 save_button_ = new ChromeViews::NativeButton(
136 l10n_util::GetString(IDS_SAVE_DOWNLOAD));
137 save_button_->set_enforce_dlu_min_size(false);
138 save_button_->SetListener(this);
139 discard_button_ = new ChromeViews::NativeButton(
140 l10n_util::GetString(IDS_DISCARD_DOWNLOAD));
141 discard_button_->SetListener(this);
142 discard_button_->set_enforce_dlu_min_size(false);
143 AddChildView(save_button_);
144 AddChildView(discard_button_);
145
114 // Set our URL name 146 // Set our URL name
115 download_url_ = new ChromeViews::Label(L""); 147 download_url_ = new ChromeViews::Label(L"");
116 download_url_->SetColor(kUrlColor); 148 download_url_->SetColor(kUrlColor);
117 download_url_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT); 149 download_url_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT);
118 download_url_->SetFont(font); 150 download_url_->SetFont(font);
119 AddChildView(download_url_); 151 AddChildView(download_url_);
120 152
121 // Set our time remaining 153 // Set our time remaining
122 time_remaining_ = new ChromeViews::Label(L""); 154 time_remaining_ = new ChromeViews::Label(L"");
123 time_remaining_->SetColor(kStatusColor); 155 time_remaining_->SetColor(kStatusColor);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 void DownloadItemTabView::GetPreferredSize(CSize* out) { 197 void DownloadItemTabView::GetPreferredSize(CSize* out) {
166 CSize pause_size; 198 CSize pause_size;
167 pause_->GetPreferredSize(&pause_size); 199 pause_->GetPreferredSize(&pause_size);
168 CSize cancel_size; 200 CSize cancel_size;
169 cancel_->GetPreferredSize(&cancel_size); 201 cancel_->GetPreferredSize(&cancel_size);
170 CSize show_size; 202 CSize show_size;
171 show_->GetPreferredSize(&show_size); 203 show_->GetPreferredSize(&show_size);
172 204
173 out->cx = download_util::kBigProgressIconSize + 205 out->cx = download_util::kBigProgressIconSize +
174 2 * kSpacer + 206 2 * kSpacer +
175 kHorizontalButtonPadding + 207 kHorizontalLinkPadding +
176 kFilenameSize + 208 kFilenameSize +
177 std::max(pause_size.cx + cancel_size.cx + kHorizontalButtonPadding, 209 std::max(pause_size.cx + cancel_size.cx + kHorizontalLinkPadding,
178 show_size.cx); 210 show_size.cx);
179 211
180 out->cy = download_util::kBigProgressIconSize; 212 out->cy = download_util::kBigProgressIconSize;
181 } 213 }
182 214
183 // Each DownloadItemTabView has reasonably complex layout requirements 215 // Each DownloadItemTabView has reasonably complex layout requirements
184 // that are based on the state of its model. To make the code much simpler 216 // that are based on the state of its model. To make the code much simpler
185 // to read, Layout() is split into state specific code which will result 217 // to read, Layout() is split into state specific code which will result
186 // in some redundant code. 218 // in some redundant code.
187 void DownloadItemTabView::Layout() { 219 void DownloadItemTabView::Layout() {
188 DCHECK(model_); 220 DCHECK(model_);
189 switch (model_->state()) { 221 switch (model_->state()) {
190 case DownloadItem::COMPLETE: 222 case DownloadItem::COMPLETE:
191 LayoutComplete(); 223 if (model_->safety_state() == DownloadItem::DANGEROUS)
224 LayoutPromptDangerousDownload();
225 else
226 LayoutComplete();
192 break; 227 break;
193 case DownloadItem::CANCELLED: 228 case DownloadItem::CANCELLED:
194 LayoutCancelled(); 229 LayoutCancelled();
195 break; 230 break;
196 case DownloadItem::IN_PROGRESS: 231 case DownloadItem::IN_PROGRESS:
197 LayoutInProgress(); 232 if (model_->safety_state() == DownloadItem::DANGEROUS)
233 LayoutPromptDangerousDownload();
234 else
235 LayoutInProgress();
198 break; 236 break;
199 case DownloadItem::REMOVING: 237 case DownloadItem::REMOVING:
200 break; 238 break;
201 default: 239 default:
202 NOTREACHED(); 240 NOTREACHED();
203 } 241 }
204 } 242 }
205 243
206 // Only display the date if the download is the last that occurred 244 // Only display the date if the download is the last that occurred
207 // on a given day. 245 // on a given day.
(...skipping 23 matching lines...) Expand all
231 269
232 // DownloadItem::COMPLETE state layout 270 // DownloadItem::COMPLETE state layout
233 void DownloadItemTabView::LayoutComplete() { 271 void DownloadItemTabView::LayoutComplete() {
234 // Hide unused UI elements 272 // Hide unused UI elements
235 pause_->SetVisible(false); 273 pause_->SetVisible(false);
236 pause_->SetEnabled(false); 274 pause_->SetEnabled(false);
237 cancel_->SetVisible(false); 275 cancel_->SetVisible(false);
238 cancel_->SetEnabled(false); 276 cancel_->SetEnabled(false);
239 time_remaining_->SetVisible(false); 277 time_remaining_->SetVisible(false);
240 download_progress_->SetVisible(false); 278 download_progress_->SetVisible(false);
279 dangerous_download_warning_->SetVisible(false);
280 save_button_->SetVisible(false);
281 save_button_->SetEnabled(false);
282 discard_button_->SetVisible(false);
283 discard_button_->SetEnabled(false);
241 284
242 LayoutDate(); 285 LayoutDate();
243 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset + 286 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset +
244 download_util::kBigProgressIconSize + kInfoPadding; 287 download_util::kBigProgressIconSize + kInfoPadding;
245 288
246 // File name and URL 289 // File name and URL
247 CSize file_name_size; 290 CSize file_name_size;
248 file_name_->SetText(model_->file_name()); 291 file_name_->SetText(model_->file_name());
249 file_name_->GetPreferredSize(&file_name_size); 292 file_name_->GetPreferredSize(&file_name_size);
250 file_name_->SetBounds(dx, download_util::kBigProgressIconOffset, 293 file_name_->SetBounds(dx, download_util::kBigProgressIconOffset,
(...skipping 28 matching lines...) Expand all
279 322
280 // DownloadItem::CANCELLED state layout 323 // DownloadItem::CANCELLED state layout
281 void DownloadItemTabView::LayoutCancelled() { 324 void DownloadItemTabView::LayoutCancelled() {
282 // Hide unused UI elements 325 // Hide unused UI elements
283 show_->SetVisible(false); 326 show_->SetVisible(false);
284 show_->SetEnabled(false); 327 show_->SetEnabled(false);
285 pause_->SetVisible(false); 328 pause_->SetVisible(false);
286 pause_->SetEnabled(false); 329 pause_->SetEnabled(false);
287 cancel_->SetVisible(false); 330 cancel_->SetVisible(false);
288 cancel_->SetEnabled(false); 331 cancel_->SetEnabled(false);
332 dangerous_download_warning_->SetVisible(false);
333 save_button_->SetVisible(false);
334 save_button_->SetEnabled(false);
335 discard_button_->SetVisible(false);
336 discard_button_->SetEnabled(false);
289 337
290 LayoutDate(); 338 LayoutDate();
291 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset + 339 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset +
292 download_util::kBigProgressIconSize + kInfoPadding; 340 download_util::kBigProgressIconSize + kInfoPadding;
293 341
294 // File name and URL, truncated to show cancelled status 342 // File name and URL, truncated to show cancelled status
295 CSize file_name_size; 343 CSize file_name_size;
296 file_name_->SetText(model_->file_name()); 344 file_name_->SetText(model_->file_name());
297 file_name_->GetPreferredSize(&file_name_size); 345 file_name_->GetPreferredSize(&file_name_size);
298 file_name_->SetBounds(dx, download_util::kBigProgressIconOffset, 346 file_name_->SetBounds(dx, download_util::kBigProgressIconOffset,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 kProgressSize, 413 kProgressSize,
366 byte_size.cy); 414 byte_size.cy);
367 download_progress_->SetVisible(true); 415 download_progress_->SetVisible(true);
368 } 416 }
369 417
370 // DownloadItem::IN_PROGRESS state layout 418 // DownloadItem::IN_PROGRESS state layout
371 void DownloadItemTabView::LayoutInProgress() { 419 void DownloadItemTabView::LayoutInProgress() {
372 // Hide unused UI elements 420 // Hide unused UI elements
373 show_->SetVisible(false); 421 show_->SetVisible(false);
374 show_->SetEnabled(false); 422 show_->SetEnabled(false);
423 dangerous_download_warning_->SetVisible(false);
424 save_button_->SetVisible(false);
425 save_button_->SetEnabled(false);
426 discard_button_->SetVisible(false);
427 discard_button_->SetEnabled(false);
375 428
376 LayoutDate(); 429 LayoutDate();
377 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset + 430 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset +
378 download_util::kBigProgressIconSize + 431 download_util::kBigProgressIconSize +
379 kInfoPadding; 432 kInfoPadding;
380 433
381 // File name and URL, truncated to show progress status 434 // File name and URL, truncated to show progress status
382 CSize file_name_size; 435 CSize file_name_size;
383 file_name_->SetText(model_->file_name()); 436 file_name_->SetText(model_->GetFileName());
384 file_name_->GetPreferredSize(&file_name_size); 437 file_name_->GetPreferredSize(&file_name_size);
385 file_name_->SetBounds(dx, download_util::kBigProgressIconOffset, 438 file_name_->SetBounds(dx, download_util::kBigProgressIconOffset,
386 kFilenameSize - kProgressSize - kSpacer, 439 kFilenameSize - kProgressSize - kSpacer,
387 file_name_size.cy); 440 file_name_size.cy);
388 file_name_->SetVisible(true); 441 file_name_->SetVisible(true);
389 file_name_->SetEnabled(false); 442 file_name_->SetEnabled(false);
390 443
391 GURL url(model_->url()); 444 GURL url(model_->url());
392 download_url_->SetURL(url); 445 download_url_->SetURL(url);
393 CSize url_size; 446 CSize url_size;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 pause_->SetText(l10n_util::GetString(IDS_DOWNLOAD_LINK_RESUME)); 560 pause_->SetText(l10n_util::GetString(IDS_DOWNLOAD_LINK_RESUME));
508 else 561 else
509 pause_->SetText(l10n_util::GetString(IDS_DOWNLOAD_LINK_PAUSE)); 562 pause_->SetText(l10n_util::GetString(IDS_DOWNLOAD_LINK_PAUSE));
510 563
511 CSize pause_size; 564 CSize pause_size;
512 pause_->SetVisible(true); 565 pause_->SetVisible(true);
513 pause_->SetEnabled(true); 566 pause_->SetEnabled(true);
514 pause_->GetPreferredSize(&pause_size); 567 pause_->GetPreferredSize(&pause_size);
515 pause_->SetBounds(dx, y_pos, pause_size.cx, pause_size.cy); 568 pause_->SetBounds(dx, y_pos, pause_size.cx, pause_size.cy);
516 569
517 dx += pause_size.cx + kHorizontalButtonPadding; 570 dx += pause_size.cx + kHorizontalLinkPadding;
518 571
519 CSize cancel_size; 572 CSize cancel_size;
520 cancel_->GetPreferredSize(&cancel_size); 573 cancel_->GetPreferredSize(&cancel_size);
521 cancel_->SetBounds(dx, y_pos, cancel_size.cx, cancel_size.cy); 574 cancel_->SetBounds(dx, y_pos, cancel_size.cx, cancel_size.cy);
522 cancel_->SetVisible(true); 575 cancel_->SetVisible(true);
523 cancel_->SetEnabled(true); 576 cancel_->SetEnabled(true);
524 } 577 }
525 578
579 void DownloadItemTabView::LayoutPromptDangerousDownload() {
580 // Hide unused UI elements
581 show_->SetVisible(false);
582 show_->SetEnabled(false);
583 file_name_->SetVisible(false);
584 file_name_->SetEnabled(false);
585 pause_->SetVisible(false);
586 pause_->SetEnabled(false);
587 cancel_->SetVisible(false);
588 cancel_->SetEnabled(false);
589 time_remaining_->SetVisible(false);
590 download_progress_->SetVisible(false);
591
592 LayoutDate();
593 int dx = kDownloadIconOffset - download_util::kBigProgressIconOffset +
594 download_util::kBigProgressIconSize +
595 kInfoPadding;
596
597 // Warning message and URL.
598 CSize warning_size;
599 std::wstring file_name;
600 ElideString(model_->original_name(), kFileNameMaxLength, &file_name);
601 dangerous_download_warning_->SetText(
602 l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, file_name));
603 dangerous_download_warning_->GetPreferredSize(&warning_size);
604 dangerous_download_warning_->SetBounds(dx, 0,
605 kFilenameSize, warning_size.cy);
606 dangerous_download_warning_->SetVisible(true);
607
608 GURL url(model_->url());
609 download_url_->SetURL(url);
610 CSize url_size;
611 download_url_->GetPreferredSize(&url_size);
612 download_url_->SetBounds(dx, height() - url_size.cy,
613 std::min(kFilenameSize - kSpacer,
614 static_cast<int>(width() - dx)),
615 url_size.cy);
616 download_url_->SetVisible(true);
617
618 dx += kFilenameSize + kSpacer;
619
620 // Save/Discard buttons.
621 CSize button_size;
622 save_button_->GetPreferredSize(&button_size);
623 save_button_->SetBounds(dx, (height() - button_size.cy) / 2,
624 button_size.cx, button_size.cy);
625 save_button_->SetVisible(true);
626 save_button_->SetEnabled(true);
627
628 dx += button_size.cx + kHorizontalButtonPadding;
629
630 discard_button_->GetPreferredSize(&button_size);
631 discard_button_->SetBounds(dx, (height() - button_size.cy) / 2,
632 button_size.cx, button_size.cy);
633 discard_button_->SetVisible(true);
634 discard_button_->SetEnabled(true);
635 }
636
526 void DownloadItemTabView::Paint(ChromeCanvas* canvas) { 637 void DownloadItemTabView::Paint(ChromeCanvas* canvas) {
527 PaintBackground(canvas); 638 PaintBackground(canvas);
528 639
529 if (model_->state() == DownloadItem::IN_PROGRESS) { 640 if (model_->state() == DownloadItem::IN_PROGRESS &&
641 model_->safety_state() != DownloadItem::DANGEROUS) {
530 download_util::PaintDownloadProgress(canvas, 642 download_util::PaintDownloadProgress(canvas,
531 this, 643 this,
532 kDownloadIconOffset - 644 kDownloadIconOffset -
533 download_util::kBigProgressIconOffset, 645 download_util::kBigProgressIconOffset,
534 0, 646 0,
535 parent_->start_angle(), 647 parent_->start_angle(),
536 model_->PercentComplete(), 648 model_->PercentComplete(),
537 download_util::BIG); 649 download_util::BIG);
538 } 650 }
539 651
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 download_util::kBigProgressIconSize); 710 download_util::kBigProgressIconSize);
599 711
600 // The position of the highlighted region does not take into account the 712 // The position of the highlighted region does not take into account the
601 // View's UI layout so we have to manually mirror the position if the View is 713 // View's UI layout so we have to manually mirror the position if the View is
602 // using a right-to-left UI layout. 714 // using a right-to-left UI layout.
603 gfx::Rect mirrored_rect(select_rect); 715 gfx::Rect mirrored_rect(select_rect);
604 select_rect.MoveToX(MirroredLeftPointForRect(mirrored_rect)); 716 select_rect.MoveToX(MirroredLeftPointForRect(mirrored_rect));
605 if (select_rect.PtInRect(point)) { 717 if (select_rect.PtInRect(point)) {
606 parent_->ItemBecameSelected(model_); 718 parent_->ItemBecameSelected(model_);
607 719
608 if (event.IsRightMouseButton()) { 720 // Don't show the right-click menu if we are prompting the user for a
721 // dangerous download.
722 if (event.IsRightMouseButton() &&
723 model_->safety_state() != DownloadItem::DANGEROUS) {
609 ChromeViews::View::ConvertPointToScreen(this, &point); 724 ChromeViews::View::ConvertPointToScreen(this, &point);
610 725
611 download_util::DownloadDestinationContextMenu menu( 726 download_util::DownloadDestinationContextMenu menu(
612 model_, GetViewContainer()->GetHWND(), point); 727 model_, GetViewContainer()->GetHWND(), point);
613 } 728 }
614 } else { 729 } else {
615 parent_->ItemBecameSelected(NULL); 730 parent_->ItemBecameSelected(NULL);
616 } 731 }
617 732
618 return true; 733 return true;
619 } 734 }
620 735
621 // Handle drag (file copy) operations. 736 // Handle drag (file copy) operations.
622 bool DownloadItemTabView::OnMouseDragged(const ChromeViews::MouseEvent& event) { 737 bool DownloadItemTabView::OnMouseDragged(const ChromeViews::MouseEvent& event) {
623 if (model_->state() != DownloadItem::COMPLETE) 738 if (model_->state() != DownloadItem::COMPLETE ||
739 model_->safety_state() == DownloadItem::DANGEROUS)
624 return false; 740 return false;
625 741
626 CPoint point(event.x(), event.y()); 742 CPoint point(event.x(), event.y());
627 743
628 // In order to make sure drag and drop works as expected when the UI is 744 // In order to make sure drag and drop works as expected when the UI is
629 // mirrored, we can either flip the mouse X coordinate or flip the X position 745 // mirrored, we can either flip the mouse X coordinate or flip the X position
630 // of the drag rectangle. Flipping the mouse X coordinate is easier. 746 // of the drag rectangle. Flipping the mouse X coordinate is easier.
631 point.x = MirroredXCoordinateInsideView(point.x); 747 point.x = MirroredXCoordinateInsideView(point.x);
632 CRect drag_rect(kDownloadIconOffset - download_util::kBigProgressIconOffset, 748 CRect drag_rect(kDownloadIconOffset - download_util::kBigProgressIconOffset,
633 0, 749 0,
(...skipping 24 matching lines...) Expand all
658 model_->Cancel(true /* update history service */); 774 model_->Cancel(true /* update history service */);
659 } else if (source == show_) { 775 } else if (source == show_) {
660 model_->manager()->ShowDownloadInShell(model_); 776 model_->manager()->ShowDownloadInShell(model_);
661 } else { 777 } else {
662 NOTREACHED(); 778 NOTREACHED();
663 } 779 }
664 780
665 parent_->ItemBecameSelected(model_); 781 parent_->ItemBecameSelected(model_);
666 } 782 }
667 783
784 void DownloadItemTabView::ButtonPressed(ChromeViews::NativeButton* sender) {
785 if (sender == save_button_) {
786 parent_->model()->DangerousDownloadValidated(model_);
787 // Relayout and repaint to display the right mode (complete or in progress).
788 Layout();
789 SchedulePaint();
790 } else if (sender == discard_button_) {
791 model_->Remove(true);
792 } else {
793 NOTREACHED();
794 }
795 }
668 796
669 // DownloadTabView implementation ---------------------------------------------- 797 // DownloadTabView implementation ----------------------------------------------
670 798
671 DownloadTabView::DownloadTabView(DownloadManager* model) 799 DownloadTabView::DownloadTabView(DownloadManager* model)
672 : model_(model), 800 : model_(model),
673 start_angle_(download_util::kStartAngleDegrees), 801 start_angle_(download_util::kStartAngleDegrees),
674 scroll_helper_(kSpacer, download_util::kBigProgressIconSize + kSpacer), 802 scroll_helper_(kSpacer, download_util::kBigProgressIconSize + kSpacer),
675 selected_index_(-1) { 803 selected_index_(-1) {
676 DCHECK(model_); 804 DCHECK(model_);
677 } 805 }
678 806
679 DownloadTabView::~DownloadTabView() { 807 DownloadTabView::~DownloadTabView() {
680 StopDownloadProgress(); 808 StopDownloadProgress();
681 model_->RemoveObserver(this); 809 model_->RemoveObserver(this);
682 810
683 // DownloadManager owns the contents. 811 // DownloadManager owns the contents.
684 downloads_.clear(); 812 downloads_.clear();
685 ClearDownloadInProgress(); 813 ClearDownloadInProgress();
814 ClearDangerousDownloads();
686 815
687 icon_consumer_.CancelAllRequests(); 816 icon_consumer_.CancelAllRequests();
688 } 817 }
689 818
690 void DownloadTabView::Initialize() { 819 void DownloadTabView::Initialize() {
691 model_->AddObserver(this); 820 model_->AddObserver(this);
692 } 821 }
693 822
694 // Start progress animation timers when we get our first (in-progress) download. 823 // Start progress animation timers when we get our first (in-progress) download.
695 void DownloadTabView::StartDownloadProgress() { 824 void DownloadTabView::StartDownloadProgress() {
(...skipping 17 matching lines...) Expand all
713 } 842 }
714 843
715 void DownloadTabView::DidChangeBounds(const CRect& previous, 844 void DownloadTabView::DidChangeBounds(const CRect& previous,
716 const CRect& current) { 845 const CRect& current) {
717 Layout(); 846 Layout();
718 } 847 }
719 848
720 void DownloadTabView::Layout() { 849 void DownloadTabView::Layout() {
721 CRect r; 850 CRect r;
722 DetachAllFloatingViews(); 851 DetachAllFloatingViews();
852 // Dangerous downloads items use NativeButtons, so they need to be attached
853 // as NativeControls are not supported yet in floating views.
854 gfx::Rect visible_bounds = GetVisibleBounds();
855 int row_start = (visible_bounds.y() - kSpacer) /
856 (download_util::kBigProgressIconSize + kSpacer);
857 int row_stop = (visible_bounds.y() - kSpacer + visible_bounds.height()) /
858 (download_util::kBigProgressIconSize + kSpacer);
859 row_stop = std::min(row_stop, static_cast<int>(downloads_.size()) - 1);
860 for (int i = row_start; i <= row_stop; ++i) {
861 // The DownloadManager stores downloads earliest first, but this view
862 // displays latest first, so adjust the index:
863 int index = static_cast<int>(downloads_.size()) - 1 - i;
864 if (downloads_[index]->safety_state() == DownloadItem::DANGEROUS)
865 ValidateFloatingViewForID(index);
866 }
723 View* v = GetParent(); 867 View* v = GetParent();
724 if (v) { 868 if (v) {
725 v->GetLocalBounds(&r, true); 869 v->GetLocalBounds(&r, true);
726 int h = static_cast<int>(downloads_.size()) * 870 int h = static_cast<int>(downloads_.size()) *
727 (download_util::kBigProgressIconSize + kSpacer) + kSpacer; 871 (download_util::kBigProgressIconSize + kSpacer) + kSpacer;
728 SetBounds(x(), y(), v->width(), h); 872 SetBounds(x(), y(), v->width(), h);
729 } 873 }
730 } 874 }
731 875
732 // Paint our scrolled region 876 // Paint our scrolled region
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 } 927 }
784 928
785 ChromeViews::View* DownloadTabView::CreateFloatingViewForIndex(int index) { 929 ChromeViews::View* DownloadTabView::CreateFloatingViewForIndex(int index) {
786 if (index >= static_cast<int>(downloads_.size())) { 930 if (index >= static_cast<int>(downloads_.size())) {
787 // It's possible that the downloads have been cleared via the "Clear 931 // It's possible that the downloads have been cleared via the "Clear
788 // Browsing Data" command, so this index is gone. 932 // Browsing Data" command, so this index is gone.
789 return NULL; 933 return NULL;
790 } 934 }
791 935
792 DownloadItemTabView* dl = new DownloadItemTabView(); 936 DownloadItemTabView* dl = new DownloadItemTabView();
937 // We attach the view before layout as the Save/Discard buttons are native
938 // and need to be in the tree hierarchy to compute their preferred size
939 // correctly.
940 AttachFloatingView(dl, index);
793 dl->SetModel(downloads_[index], this); 941 dl->SetModel(downloads_[index], this);
794 int row = static_cast<int>(downloads_.size()) - 1 - index; 942 int row = static_cast<int>(downloads_.size()) - 1 - index;
795 int y_pos = row * (download_util::kBigProgressIconSize + kSpacer) + kSpacer; 943 int y_pos = row * (download_util::kBigProgressIconSize + kSpacer) + kSpacer;
796 dl->SetBounds(0, y_pos, width(), download_util::kBigProgressIconSize); 944 dl->SetBounds(0, y_pos, width(), download_util::kBigProgressIconSize);
797 dl->Layout(); 945 dl->Layout();
798 AttachFloatingView(dl, index);
799 return dl; 946 return dl;
800 } 947 }
801 948
802 bool DownloadTabView::EnumerateFloatingViews( 949 bool DownloadTabView::EnumerateFloatingViews(
803 ChromeViews::View::FloatingViewPosition position, 950 ChromeViews::View::FloatingViewPosition position,
804 int starting_id, int* id) { 951 int starting_id, int* id) {
805 DCHECK(id); 952 DCHECK(id);
806 return View::EnumerateFloatingViewsForInterval( 953 return View::EnumerateFloatingViewsForInterval(
807 0, static_cast<int>(downloads_.size()), false, position, starting_id, id); 954 0, static_cast<int>(downloads_.size()), false, position, starting_id, id);
808 } 955 }
809 956
810 ChromeViews::View* DownloadTabView::ValidateFloatingViewForID(int id) { 957 ChromeViews::View* DownloadTabView::ValidateFloatingViewForID(int id) {
811 return CreateFloatingViewForIndex(id); 958 return CreateFloatingViewForIndex(id);
812 } 959 }
813 960
814 void DownloadTabView::OnDownloadUpdated(DownloadItem* download) { 961 void DownloadTabView::OnDownloadUpdated(DownloadItem* download) {
815 switch (download->state()) { 962 switch (download->state()) {
816 case DownloadItem::COMPLETE: 963 case DownloadItem::COMPLETE:
817 case DownloadItem::CANCELLED: { 964 case DownloadItem::CANCELLED: {
818 base::hash_set<DownloadItem*>::iterator d = in_progress_.find(download); 965 base::hash_set<DownloadItem*>::iterator d = in_progress_.find(download);
819 if (d != in_progress_.end()) { 966 if (d != in_progress_.end()) {
820 (*d)->RemoveObserver(this); 967 // If this is a dangerous download not yet validated by the user, we
968 // still need to be notified when the validation happens.
969 if (download->safety_state() != DownloadItem::DANGEROUS)
970 (*d)->RemoveObserver(this);
821 in_progress_.erase(d); 971 in_progress_.erase(d);
822 } 972 }
823 if (in_progress_.empty()) 973 if (in_progress_.empty())
824 StopDownloadProgress(); 974 StopDownloadProgress();
825 LoadIcon(download); 975 LoadIcon(download);
826 break; 976 break;
827 } 977 }
828 case DownloadItem::IN_PROGRESS: { 978 case DownloadItem::IN_PROGRESS: {
829 // If all IN_PROGRESS downloads are paused, don't waste CPU issuing any 979 // If all IN_PROGRESS downloads are paused, don't waste CPU issuing any
830 // further progress updates until at least one download is active again. 980 // further progress updates until at least one download is active again.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 } 1020 }
871 } 1021 }
872 } 1022 }
873 1023
874 // A download has started or been deleted. Query our DownloadManager for the 1024 // A download has started or been deleted. Query our DownloadManager for the
875 // current set of downloads, which will call us back in SetDownloads once it 1025 // current set of downloads, which will call us back in SetDownloads once it
876 // has retrieved them. 1026 // has retrieved them.
877 void DownloadTabView::ModelChanged() { 1027 void DownloadTabView::ModelChanged() {
878 downloads_.clear(); 1028 downloads_.clear();
879 ClearDownloadInProgress(); 1029 ClearDownloadInProgress();
1030 ClearDangerousDownloads();
880 DetachAllFloatingViews(); 1031 DetachAllFloatingViews();
881 1032
882 // Issue the query. 1033 // Issue the query.
883 model_->GetDownloads(this, search_text_); 1034 model_->GetDownloads(this, search_text_);
884 } 1035 }
885 1036
886 void DownloadTabView::SetDownloads(std::vector<DownloadItem*>& downloads) { 1037 void DownloadTabView::SetDownloads(std::vector<DownloadItem*>& downloads) {
887 // Stop progress timers. 1038 // Stop progress timers.
888 StopDownloadProgress(); 1039 StopDownloadProgress();
889 1040
890 // Clear out old state and remove self as observer for each download. 1041 // Clear out old state and remove self as observer for each download.
891 downloads_.clear(); 1042 downloads_.clear();
892 ClearDownloadInProgress(); 1043 ClearDownloadInProgress();
1044 ClearDangerousDownloads();
893 1045
894 // Swap new downloads in. 1046 // Swap new downloads in.
895 downloads_.swap(downloads); 1047 downloads_.swap(downloads);
896 sort(downloads_.begin(), downloads_.end(), DownloadItemSorter()); 1048 sort(downloads_.begin(), downloads_.end(), DownloadItemSorter());
897 1049
898 // Scan for any in progress downloads and add ourself to them as an observer. 1050 // Scan for any in progress downloads and add ourself to them as an observer.
899 for (OrderedDownloads::iterator it = downloads_.begin(); 1051 for (OrderedDownloads::iterator it = downloads_.begin();
900 it != downloads_.end(); ++it) { 1052 it != downloads_.end(); ++it) {
901 DownloadItem* download = *it; 1053 DownloadItem* download = *it;
902 if (download->state() == DownloadItem::IN_PROGRESS) { 1054 if (download->state() == DownloadItem::IN_PROGRESS) {
903 download->AddObserver(this); 1055 download->AddObserver(this);
904 in_progress_.insert(download); 1056 in_progress_.insert(download);
1057 } else if (download->safety_state() == DownloadItem::DANGEROUS) {
1058 // We need to be notified when the user validates the dangerous download.
1059 download->AddObserver(this);
1060 dangerous_downloads_.insert(download);
905 } 1061 }
906 } 1062 }
907 1063
908 // Start any progress timers if required. 1064 // Start any progress timers if required.
909 if (!in_progress_.empty()) 1065 if (!in_progress_.empty())
910 StartDownloadProgress(); 1066 StartDownloadProgress();
911 1067
912 // Update the UI. 1068 // Update the UI.
913 selected_index_ = -1; 1069 selected_index_ = -1;
914 GetParent()->GetParent()->Layout(); 1070 GetParent()->GetParent()->Layout();
(...skipping 27 matching lines...) Expand all
942 icon_consumer_.SetClientData(im, h, download); 1098 icon_consumer_.SetClientData(im, h, download);
943 } 1099 }
944 1100
945 void DownloadTabView::ClearDownloadInProgress() { 1101 void DownloadTabView::ClearDownloadInProgress() {
946 for (base::hash_set<DownloadItem*>::iterator it = in_progress_.begin(); 1102 for (base::hash_set<DownloadItem*>::iterator it = in_progress_.begin();
947 it != in_progress_.end(); ++it) 1103 it != in_progress_.end(); ++it)
948 (*it)->RemoveObserver(this); 1104 (*it)->RemoveObserver(this);
949 in_progress_.clear(); 1105 in_progress_.clear();
950 } 1106 }
951 1107
1108 void DownloadTabView::ClearDangerousDownloads() {
1109 base::hash_set<DownloadItem*>::const_iterator it;
1110 for (it = dangerous_downloads_.begin();
1111 it != dangerous_downloads_.end(); ++it)
1112 (*it)->RemoveObserver(this);
1113 dangerous_downloads_.clear();
1114 }
1115
952 // Check to see if the download is the latest download on a given day. 1116 // Check to see if the download is the latest download on a given day.
953 // We use this to determine when to draw the date next to a particular 1117 // We use this to determine when to draw the date next to a particular
954 // download view: if the DownloadItem is the latest download on a given 1118 // download view: if the DownloadItem is the latest download on a given
955 // day, the date gets drawn. 1119 // day, the date gets drawn.
956 bool DownloadTabView::ShouldDrawDateForDownload(DownloadItem* download) { 1120 bool DownloadTabView::ShouldDrawDateForDownload(DownloadItem* download) {
957 DCHECK(download); 1121 DCHECK(download);
958 OrderedDownloads::iterator it = find(downloads_.begin(), 1122 OrderedDownloads::iterator it = find(downloads_.begin(),
959 downloads_.end(), 1123 downloads_.end(),
960 download); 1124 download);
961 DCHECK(it != downloads_.end()); 1125 DCHECK(it != downloads_.end());
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 DCHECK(profile()->HasCreatedDownloadManager()); 1333 DCHECK(profile()->HasCreatedDownloadManager());
1170 contents_->SetIsLoading( 1334 contents_->SetIsLoading(
1171 profile()->GetDownloadManager()->in_progress_count() > 0, 1335 profile()->GetDownloadManager()->in_progress_count() > 0,
1172 NULL); 1336 NULL);
1173 break; 1337 break;
1174 default: 1338 default:
1175 break; 1339 break;
1176 } 1340 }
1177 } 1341 }
1178 1342
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698