OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |