OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/download/download_item_view.h" | 5 #include "chrome/browser/ui/views/download/download_item_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 | 84 |
85 DownloadItemView::DownloadItemView(DownloadItem* download, | 85 DownloadItemView::DownloadItemView(DownloadItem* download, |
86 DownloadShelfView* parent, | 86 DownloadShelfView* parent, |
87 BaseDownloadItemModel* model) | 87 BaseDownloadItemModel* model) |
88 : warning_icon_(NULL), | 88 : warning_icon_(NULL), |
89 download_(download), | 89 download_(download), |
90 parent_(parent), | 90 parent_(parent), |
91 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)), | 91 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)), |
92 body_state_(NORMAL), | 92 body_state_(NORMAL), |
93 drop_down_state_(NORMAL), | 93 drop_down_state_(NORMAL), |
| 94 mode_(NORMAL_MODE), |
94 progress_angle_(download_util::kStartAngleDegrees), | 95 progress_angle_(download_util::kStartAngleDegrees), |
95 drop_down_pressed_(false), | 96 drop_down_pressed_(false), |
96 dragging_(false), | 97 dragging_(false), |
97 starting_drag_(false), | 98 starting_drag_(false), |
98 model_(model), | 99 model_(model), |
99 save_button_(NULL), | 100 save_button_(NULL), |
100 discard_button_(NULL), | 101 discard_button_(NULL), |
101 dangerous_download_label_(NULL), | 102 dangerous_download_label_(NULL), |
102 dangerous_download_label_sized_(false), | 103 dangerous_download_label_sized_(false), |
103 disabled_while_opening_(false), | 104 disabled_while_opening_(false), |
104 creation_time_(base::Time::Now()), | 105 creation_time_(base::Time::Now()), |
105 ALLOW_THIS_IN_INITIALIZER_LIST(reenable_method_factory_(this)) { | 106 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
106 DCHECK(download_); | 107 DCHECK(download_); |
107 download_->AddObserver(this); | 108 download_->AddObserver(this); |
108 | 109 |
109 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 110 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
110 | 111 |
111 BodyImageSet normal_body_image_set = { | 112 BodyImageSet normal_body_image_set = { |
112 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), | 113 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), |
113 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), | 114 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), |
114 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), | 115 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), |
115 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), | 116 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), | 175 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), |
175 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), | 176 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), |
176 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE), | 177 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE), |
177 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM), | 178 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM), |
178 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD), | 179 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD), |
179 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD), | 180 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD), |
180 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD) | 181 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD) |
181 }; | 182 }; |
182 dangerous_mode_body_image_set_ = dangerous_mode_body_image_set; | 183 dangerous_mode_body_image_set_ = dangerous_mode_body_image_set; |
183 | 184 |
| 185 malicious_mode_body_image_set_ = normal_body_image_set; |
| 186 |
184 LoadIcon(); | 187 LoadIcon(); |
185 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); | 188 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); |
186 | 189 |
187 font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); | 190 font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); |
188 box_height_ = std::max<int>(2 * kVerticalPadding + font_.GetHeight() + | 191 box_height_ = std::max<int>(2 * kVerticalPadding + font_.GetHeight() + |
189 kVerticalTextPadding + font_.GetHeight(), | 192 kVerticalTextPadding + font_.GetHeight(), |
190 2 * kVerticalPadding + | 193 2 * kVerticalPadding + |
191 normal_body_image_set_.top_left->height() + | 194 normal_body_image_set_.top_left->height() + |
192 normal_body_image_set_.bottom_left->height()); | 195 normal_body_image_set_.bottom_left->height()); |
193 | 196 |
194 if (download_util::kSmallProgressIconSize > box_height_) | 197 if (download_util::kSmallProgressIconSize > box_height_) |
195 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; | 198 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; |
196 else | 199 else |
197 box_y_ = kVerticalPadding; | 200 box_y_ = kVerticalPadding; |
198 | 201 |
199 gfx::Size size = GetPreferredSize(); | |
200 if (base::i18n::IsRTL()) { | |
201 // Drop down button is glued to the left of the download shelf. | |
202 drop_down_x_left_ = 0; | |
203 drop_down_x_right_ = normal_drop_down_image_set_.top->width(); | |
204 } else { | |
205 // Drop down button is glued to the right of the download shelf. | |
206 drop_down_x_left_ = | |
207 size.width() - normal_drop_down_image_set_.top->width(); | |
208 drop_down_x_right_ = size.width(); | |
209 } | |
210 | |
211 body_hover_animation_.reset(new ui::SlideAnimation(this)); | 202 body_hover_animation_.reset(new ui::SlideAnimation(this)); |
212 drop_hover_animation_.reset(new ui::SlideAnimation(this)); | 203 drop_hover_animation_.reset(new ui::SlideAnimation(this)); |
213 | 204 |
| 205 UpdateDropDownButtonPosition(); |
| 206 |
214 if (download->GetSafetyState() == DownloadItem::DANGEROUS) | 207 if (download->GetSafetyState() == DownloadItem::DANGEROUS) |
215 EnterDangerousMode(); | 208 ShowWarningDialog(); |
216 | 209 |
217 UpdateAccessibleName(); | 210 UpdateAccessibleName(); |
218 set_accessibility_focusable(true); | 211 set_accessibility_focusable(true); |
219 | 212 |
220 // Set up our animation. | 213 // Set up our animation. |
221 StartDownloadProgress(); | 214 StartDownloadProgress(); |
222 } | 215 } |
223 | 216 |
224 DownloadItemView::~DownloadItemView() { | 217 DownloadItemView::~DownloadItemView() { |
225 if (context_menu_.get()) | |
226 context_menu_->Stop(); | |
227 icon_consumer_.CancelAllRequests(); | 218 icon_consumer_.CancelAllRequests(); |
228 StopDownloadProgress(); | 219 StopDownloadProgress(); |
229 download_->RemoveObserver(this); | 220 download_->RemoveObserver(this); |
230 } | 221 } |
231 | 222 |
232 // Progress animation handlers. | 223 // Progress animation handlers. |
233 | 224 |
234 void DownloadItemView::UpdateDownloadProgress() { | 225 void DownloadItemView::UpdateDownloadProgress() { |
235 progress_angle_ = (progress_angle_ + | 226 progress_angle_ = (progress_angle_ + |
236 download_util::kUnknownIncrementDegrees) % | 227 download_util::kUnknownIncrementDegrees) % |
(...skipping 19 matching lines...) Expand all Loading... |
256 parent()->SchedulePaint(); | 247 parent()->SchedulePaint(); |
257 } | 248 } |
258 | 249 |
259 // DownloadObserver interface. | 250 // DownloadObserver interface. |
260 | 251 |
261 // Update the progress graphic on the icon and our text status label | 252 // Update the progress graphic on the icon and our text status label |
262 // to reflect our current bytes downloaded, time remaining. | 253 // to reflect our current bytes downloaded, time remaining. |
263 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { | 254 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { |
264 DCHECK(download == download_); | 255 DCHECK(download == download_); |
265 | 256 |
266 if (body_state_ == DANGEROUS && | 257 if (IsShowingWarningDialog() && |
267 download->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED) { | 258 download->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED) { |
268 // We have been approved. | 259 // We have been approved. |
269 ClearDangerousMode(); | 260 ClearWarningDialog(); |
270 } else if (body_state_ != DANGEROUS && | 261 } else if (!IsShowingWarningDialog() && |
271 download->GetSafetyState() == DownloadItem::DANGEROUS) { | 262 download->GetSafetyState() == DownloadItem::DANGEROUS) { |
272 EnterDangerousMode(); | 263 ShowWarningDialog(); |
273 // Force the shelf to layout again as our size has changed. | 264 // Force the shelf to layout again as our size has changed. |
274 parent_->Layout(); | 265 parent_->Layout(); |
275 SchedulePaint(); | 266 SchedulePaint(); |
276 } else { | 267 } else { |
277 string16 status_text = model_->GetStatusText(); | 268 string16 status_text = model_->GetStatusText(); |
278 switch (download_->GetState()) { | 269 switch (download_->GetState()) { |
279 case DownloadItem::IN_PROGRESS: | 270 case DownloadItem::IN_PROGRESS: |
280 download_->IsPaused() ? | 271 download_->IsPaused() ? |
281 StopDownloadProgress() : StartDownloadProgress(); | 272 StopDownloadProgress() : StartDownloadProgress(); |
282 LoadIconIfItemPathChanged(); | 273 LoadIconIfItemPathChanged(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 // for painting. | 313 // for painting. |
323 parent()->SchedulePaint(); | 314 parent()->SchedulePaint(); |
324 } | 315 } |
325 | 316 |
326 void DownloadItemView::OnDownloadOpened(DownloadItem* download) { | 317 void DownloadItemView::OnDownloadOpened(DownloadItem* download) { |
327 disabled_while_opening_ = true; | 318 disabled_while_opening_ = true; |
328 SetEnabled(false); | 319 SetEnabled(false); |
329 MessageLoop::current()->PostDelayedTask( | 320 MessageLoop::current()->PostDelayedTask( |
330 FROM_HERE, | 321 FROM_HERE, |
331 base::Bind(&DownloadItemView::Reenable, | 322 base::Bind(&DownloadItemView::Reenable, |
332 reenable_method_factory_.GetWeakPtr()), | 323 weak_ptr_factory_.GetWeakPtr()), |
333 kDisabledOnOpenDuration); | 324 kDisabledOnOpenDuration); |
334 | 325 |
335 // Notify our parent. | 326 // Notify our parent. |
336 parent_->OpenedDownload(this); | 327 parent_->OpenedDownload(this); |
337 } | 328 } |
338 | 329 |
339 // View overrides | 330 // View overrides |
340 | 331 |
341 // In dangerous mode we have to layout our buttons. | 332 // In dangerous mode we have to layout our buttons. |
342 void DownloadItemView::Layout() { | 333 void DownloadItemView::Layout() { |
343 if (IsDangerousMode()) { | 334 if (IsShowingWarningDialog()) { |
| 335 BodyImageSet* body_image_set = |
| 336 (mode_ == DANGEROUS_MODE) ? &dangerous_mode_body_image_set_ : |
| 337 &malicious_mode_body_image_set_; |
344 dangerous_download_label_->SetEnabledColor( | 338 dangerous_download_label_->SetEnabledColor( |
345 GetThemeProvider()->GetColor(ThemeService::COLOR_BOOKMARK_TEXT)); | 339 GetThemeProvider()->GetColor(ThemeService::COLOR_BOOKMARK_TEXT)); |
346 | 340 |
347 int x = kLeftPadding + dangerous_mode_body_image_set_.top_left->width() + | 341 int x = kLeftPadding + body_image_set->top_left->width() + |
348 warning_icon_->width() + kLabelPadding; | 342 warning_icon_->width() + kLabelPadding; |
349 int y = (height() - dangerous_download_label_->height()) / 2; | 343 int y = (height() - dangerous_download_label_->height()) / 2; |
350 dangerous_download_label_->SetBounds(x, y, | 344 dangerous_download_label_->SetBounds(x, y, |
351 dangerous_download_label_->width(), | 345 dangerous_download_label_->width(), |
352 dangerous_download_label_->height()); | 346 dangerous_download_label_->height()); |
353 gfx::Size button_size = GetButtonSize(); | 347 gfx::Size button_size = GetButtonSize(); |
354 x += dangerous_download_label_->width() + kLabelPadding; | 348 x += dangerous_download_label_->width() + kLabelPadding; |
355 y = (height() - button_size.height()) / 2; | 349 y = (height() - button_size.height()) / 2; |
356 save_button_->SetBounds(x, y, button_size.width(), button_size.height()); | 350 if (save_button_) { |
357 x += button_size.width() + kButtonPadding; | 351 save_button_->SetBounds(x, y, button_size.width(), button_size.height()); |
| 352 x += button_size.width() + kButtonPadding; |
| 353 } |
358 discard_button_->SetBounds(x, y, button_size.width(), button_size.height()); | 354 discard_button_->SetBounds(x, y, button_size.width(), button_size.height()); |
359 } | 355 } |
360 } | 356 } |
361 | 357 |
362 gfx::Size DownloadItemView::GetPreferredSize() { | 358 gfx::Size DownloadItemView::GetPreferredSize() { |
363 int width, height; | 359 int width, height; |
364 | 360 |
365 // First, we set the height to the height of two rows or text plus margins. | 361 // First, we set the height to the height of two rows or text plus margins. |
366 height = 2 * kVerticalPadding + 2 * font_.GetHeight() + kVerticalTextPadding; | 362 height = 2 * kVerticalPadding + 2 * font_.GetHeight() + kVerticalTextPadding; |
367 // Then we increase the size if the progress icon doesn't fit. | 363 // Then we increase the size if the progress icon doesn't fit. |
368 height = std::max<int>(height, download_util::kSmallProgressIconSize); | 364 height = std::max<int>(height, download_util::kSmallProgressIconSize); |
369 | 365 |
370 if (IsDangerousMode()) { | 366 if (IsShowingWarningDialog()) { |
371 width = kLeftPadding + dangerous_mode_body_image_set_.top_left->width(); | 367 BodyImageSet* body_image_set = |
| 368 (mode_ == DANGEROUS_MODE) ? &dangerous_mode_body_image_set_ : |
| 369 &malicious_mode_body_image_set_; |
| 370 width = kLeftPadding + body_image_set->top_left->width(); |
372 width += warning_icon_->width() + kLabelPadding; | 371 width += warning_icon_->width() + kLabelPadding; |
373 width += dangerous_download_label_->width() + kLabelPadding; | 372 width += dangerous_download_label_->width() + kLabelPadding; |
374 gfx::Size button_size = GetButtonSize(); | 373 gfx::Size button_size = GetButtonSize(); |
375 // Make sure the button fits. | 374 // Make sure the button fits. |
376 height = std::max<int>(height, 2 * kVerticalPadding + button_size.height()); | 375 height = std::max<int>(height, 2 * kVerticalPadding + button_size.height()); |
377 // Then we make sure the warning icon fits. | 376 // Then we make sure the warning icon fits. |
378 height = std::max<int>(height, 2 * kVerticalPadding + | 377 height = std::max<int>(height, 2 * kVerticalPadding + |
379 warning_icon_->height()); | 378 warning_icon_->height()); |
380 width += button_size.width() * 2 + kButtonPadding; | 379 if (save_button_) |
381 width += dangerous_mode_body_image_set_.top_right->width(); | 380 width += button_size.width() + kButtonPadding; |
| 381 width += button_size.width(); |
| 382 width += body_image_set->top_right->width(); |
| 383 if (mode_ == MALICIOUS_MODE) |
| 384 width += normal_drop_down_image_set_.top->width(); |
382 } else { | 385 } else { |
383 width = kLeftPadding + normal_body_image_set_.top_left->width(); | 386 width = kLeftPadding + normal_body_image_set_.top_left->width(); |
384 width += download_util::kSmallProgressIconSize; | 387 width += download_util::kSmallProgressIconSize; |
385 width += kTextWidth; | 388 width += kTextWidth; |
386 width += normal_body_image_set_.top_right->width(); | 389 width += normal_body_image_set_.top_right->width(); |
387 width += normal_drop_down_image_set_.top->width(); | 390 width += normal_drop_down_image_set_.top->width(); |
388 } | 391 } |
389 return gfx::Size(width, height); | 392 return gfx::Size(width, height); |
390 } | 393 } |
391 | 394 |
392 // Handle a mouse click and open the context menu if the mouse is | 395 // Handle a mouse click and open the context menu if the mouse is |
393 // over the drop-down region. | 396 // over the drop-down region. |
394 bool DownloadItemView::OnMousePressed(const views::MouseEvent& event) { | 397 bool DownloadItemView::OnMousePressed(const views::MouseEvent& event) { |
395 // Mouse should not activate us in dangerous mode. | 398 // Mouse should not activate us in dangerous mode. |
396 if (IsDangerousMode()) | 399 if (mode_ == DANGEROUS_MODE) |
397 return true; | 400 return true; |
398 | 401 |
399 // Stop any completion animation. | 402 // Stop any completion animation. |
400 if (complete_animation_.get() && complete_animation_->is_animating()) | 403 if (complete_animation_.get() && complete_animation_->is_animating()) |
401 complete_animation_->End(); | 404 complete_animation_->End(); |
402 | 405 |
403 if (event.IsOnlyLeftMouseButton()) { | 406 if (event.IsOnlyLeftMouseButton()) { |
404 if (InDropDownButtonXCoordinateRange(event.x())) { | 407 if (InDropDownButtonXCoordinateRange(event.x())) { |
405 drop_down_pressed_ = true; | 408 drop_down_pressed_ = true; |
406 SetState(NORMAL, PUSHED); | 409 SetState(NORMAL, PUSHED); |
407 // We are setting is_mouse_gesture to false when calling ShowContextMenu | 410 // We are setting is_mouse_gesture to false when calling ShowContextMenu |
408 // so that the positioning of the context menu will be similar to a | 411 // so that the positioning of the context menu will be similar to a |
409 // keyboard invocation. I.e. we want the menu to always be positioned | 412 // keyboard invocation. I.e. we want the menu to always be positioned |
410 // next to the drop down button instead of the next to the pointer. | 413 // next to the drop down button instead of the next to the pointer. |
411 ShowContextMenu(event.location(), false); | 414 ShowContextMenu(event.location(), false); |
412 } else { | 415 // Once called, it is possible that *this was deleted (e.g.: due to |
| 416 // invoking the 'Discard' action.) |
| 417 } else if (!IsShowingWarningDialog()) { |
413 SetState(PUSHED, NORMAL); | 418 SetState(PUSHED, NORMAL); |
414 } | 419 } |
415 } | 420 } |
416 return true; | 421 return true; |
417 } | 422 } |
418 | 423 |
419 // Handle drag (file copy) operations. | 424 // Handle drag (file copy) operations. |
420 bool DownloadItemView::OnMouseDragged(const views::MouseEvent& event) { | 425 bool DownloadItemView::OnMouseDragged(const views::MouseEvent& event) { |
421 // Mouse should not activate us in dangerous mode. | 426 // Mouse should not activate us in dangerous mode. |
422 if (IsDangerousMode()) | 427 if (IsShowingWarningDialog()) |
423 return true; | 428 return true; |
424 | 429 |
425 if (!starting_drag_) { | 430 if (!starting_drag_) { |
426 starting_drag_ = true; | 431 starting_drag_ = true; |
427 drag_start_point_ = event.location(); | 432 drag_start_point_ = event.location(); |
428 } | 433 } |
429 if (dragging_) { | 434 if (dragging_) { |
430 if (download_->IsComplete()) { | 435 if (download_->IsComplete()) { |
431 IconManager* im = g_browser_process->icon_manager(); | 436 IconManager* im = g_browser_process->icon_manager(); |
432 gfx::Image* icon = im->LookupIcon(download_->GetUserVerifiedFilePath(), | 437 gfx::Image* icon = im->LookupIcon(download_->GetUserVerifiedFilePath(), |
433 IconLoader::SMALL); | 438 IconLoader::SMALL); |
434 if (icon) { | 439 if (icon) { |
435 views::Widget* widget = GetWidget(); | 440 views::Widget* widget = GetWidget(); |
436 download_util::DragDownload(download_, icon, | 441 download_util::DragDownload(download_, icon, |
437 widget ? widget->GetNativeView() : NULL); | 442 widget ? widget->GetNativeView() : NULL); |
438 } | 443 } |
439 } | 444 } |
440 } else if (ExceededDragThreshold( | 445 } else if (ExceededDragThreshold( |
441 event.location().x() - drag_start_point_.x(), | 446 event.location().x() - drag_start_point_.x(), |
442 event.location().y() - drag_start_point_.y())) { | 447 event.location().y() - drag_start_point_.y())) { |
443 dragging_ = true; | 448 dragging_ = true; |
444 } | 449 } |
445 return true; | 450 return true; |
446 } | 451 } |
447 | 452 |
448 void DownloadItemView::OnMouseReleased(const views::MouseEvent& event) { | 453 void DownloadItemView::OnMouseReleased(const views::MouseEvent& event) { |
449 // Mouse should not activate us in dangerous mode. | 454 // Mouse should not activate us in dangerous mode. |
450 if (IsDangerousMode()) | 455 if (mode_ == DANGEROUS_MODE) |
451 return; | 456 return; |
452 | 457 |
453 if (event.IsOnlyLeftMouseButton() && | 458 if (event.IsOnlyLeftMouseButton() && |
454 !InDropDownButtonXCoordinateRange(event.x())) { | 459 !InDropDownButtonXCoordinateRange(event.x()) && |
| 460 !IsShowingWarningDialog()) { |
455 OpenDownload(); | 461 OpenDownload(); |
456 } | 462 } |
457 | 463 |
458 SetState(NORMAL, NORMAL); | 464 SetState(NORMAL, NORMAL); |
459 } | 465 } |
460 | 466 |
461 void DownloadItemView::OnMouseCaptureLost() { | 467 void DownloadItemView::OnMouseCaptureLost() { |
462 // Mouse should not activate us in dangerous mode. | 468 // Mouse should not activate us in dangerous mode. |
463 if (IsDangerousMode()) | 469 if (mode_ == DANGEROUS_MODE) |
464 return; | 470 return; |
465 | 471 |
466 if (dragging_) { | 472 if (dragging_) { |
467 // Starting a drag results in a MouseCaptureLost. | 473 // Starting a drag results in a MouseCaptureLost. |
468 dragging_ = false; | 474 dragging_ = false; |
469 starting_drag_ = false; | 475 starting_drag_ = false; |
470 } else { | 476 } else { |
471 SetState(NORMAL, NORMAL); | 477 SetState(NORMAL, NORMAL); |
472 } | 478 } |
473 } | 479 } |
474 | 480 |
475 void DownloadItemView::OnMouseMoved(const views::MouseEvent& event) { | 481 void DownloadItemView::OnMouseMoved(const views::MouseEvent& event) { |
476 // Mouse should not activate us in dangerous mode. | 482 // Mouse should not activate us in dangerous mode. |
477 if (IsDangerousMode()) | 483 if (mode_ == DANGEROUS_MODE) |
478 return; | 484 return; |
479 | 485 |
480 bool on_body = !InDropDownButtonXCoordinateRange(event.x()); | 486 bool on_body = !InDropDownButtonXCoordinateRange(event.x()); |
481 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT); | 487 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT); |
482 if (on_body) { | 488 if (on_body) { |
483 body_hover_animation_->Show(); | 489 if (!IsShowingWarningDialog()) |
| 490 body_hover_animation_->Show(); |
484 drop_hover_animation_->Hide(); | 491 drop_hover_animation_->Hide(); |
485 } else { | 492 } else { |
486 body_hover_animation_->Hide(); | 493 if (!IsShowingWarningDialog()) |
| 494 body_hover_animation_->Hide(); |
487 drop_hover_animation_->Show(); | 495 drop_hover_animation_->Show(); |
488 } | 496 } |
489 } | 497 } |
490 | 498 |
491 void DownloadItemView::OnMouseExited(const views::MouseEvent& event) { | 499 void DownloadItemView::OnMouseExited(const views::MouseEvent& event) { |
492 // Mouse should not activate us in dangerous mode. | 500 // Mouse should not activate us in dangerous mode. |
493 if (IsDangerousMode()) | 501 if (mode_ == DANGEROUS_MODE) |
494 return; | 502 return; |
495 | 503 |
496 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL); | 504 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL); |
497 body_hover_animation_->Hide(); | 505 if (!IsShowingWarningDialog()) |
| 506 body_hover_animation_->Hide(); |
498 drop_hover_animation_->Hide(); | 507 drop_hover_animation_->Hide(); |
499 } | 508 } |
500 | 509 |
501 bool DownloadItemView::OnKeyPressed(const views::KeyEvent& event) { | 510 bool DownloadItemView::OnKeyPressed(const views::KeyEvent& event) { |
502 // Key press should not activate us in dangerous mode. | 511 // Key press should not activate us in dangerous mode. |
503 if (IsDangerousMode()) | 512 if (IsShowingWarningDialog()) |
504 return true; | 513 return true; |
505 | 514 |
506 if (event.key_code() == ui::VKEY_SPACE || | 515 if (event.key_code() == ui::VKEY_SPACE || |
507 event.key_code() == ui::VKEY_RETURN) { | 516 event.key_code() == ui::VKEY_RETURN) { |
508 OpenDownload(); | 517 OpenDownload(); |
509 return true; | 518 return true; |
510 } | 519 } |
511 return false; | 520 return false; |
512 } | 521 } |
513 | 522 |
(...skipping 23 matching lines...) Expand all Loading... |
537 SetMouseHandler(NULL); | 546 SetMouseHandler(NULL); |
538 | 547 |
539 // If |is_mouse_gesture| is false, |p| is ignored. The menu is shown aligned | 548 // If |is_mouse_gesture| is false, |p| is ignored. The menu is shown aligned |
540 // to drop down arrow button. | 549 // to drop down arrow button. |
541 if (!is_mouse_gesture) { | 550 if (!is_mouse_gesture) { |
542 drop_down_pressed_ = true; | 551 drop_down_pressed_ = true; |
543 SetState(NORMAL, PUSHED); | 552 SetState(NORMAL, PUSHED); |
544 point.SetPoint(drop_down_x_left_, box_y_); | 553 point.SetPoint(drop_down_x_left_, box_y_); |
545 size.SetSize(drop_down_x_right_ - drop_down_x_left_, box_height_); | 554 size.SetSize(drop_down_x_right_ - drop_down_x_left_, box_height_); |
546 } | 555 } |
547 | 556 // Post a task to release the button. When we call the Run method on the menu |
| 557 // below, it runs an inner message loop that might cause us to be deleted. |
| 558 // Posting a task with a WeakPtr lets us safely handle the button release. |
| 559 MessageLoop::current()->PostNonNestableTask( |
| 560 FROM_HERE, |
| 561 base::Bind(&DownloadItemView::ReleaseDropDown, |
| 562 weak_ptr_factory_.GetWeakPtr())); |
548 views::View::ConvertPointToScreen(this, &point); | 563 views::View::ConvertPointToScreen(this, &point); |
549 | 564 |
550 if (!context_menu_.get()) | 565 if (!context_menu_.get()) |
551 context_menu_.reset(new DownloadShelfContextMenuView(model_.get())); | 566 context_menu_.reset(new DownloadShelfContextMenuView(model_.get())); |
552 // When we call the Run method on the menu, it runs an inner message loop | 567 context_menu_->Run(GetWidget()->GetTopLevelWidget(), |
553 // that might causes us to be deleted. | 568 gfx::Rect(point, size)); |
554 if (context_menu_->Run(GetWidget()->GetTopLevelWidget(), | 569 // We could be deleted now. |
555 gfx::Rect(point, size))) | |
556 return; // We have been deleted! Don't access 'this'. | |
557 | |
558 // If the menu action was to remove the download, this view will also be | |
559 // invalid so we must not access 'this' in this case. | |
560 if (context_menu_->download_item()) { | |
561 drop_down_pressed_ = false; | |
562 // Showing the menu blocks. Here we revert the state. | |
563 SetState(NORMAL, NORMAL); | |
564 } | |
565 } | 570 } |
566 | 571 |
567 void DownloadItemView::GetAccessibleState(ui::AccessibleViewState* state) { | 572 void DownloadItemView::GetAccessibleState(ui::AccessibleViewState* state) { |
568 state->name = accessible_name_; | 573 state->name = accessible_name_; |
569 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; | 574 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; |
570 if (download_->GetSafetyState() == DownloadItem::DANGEROUS) { | 575 if (download_->GetSafetyState() == DownloadItem::DANGEROUS) { |
571 state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; | 576 state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; |
572 } else { | 577 } else { |
573 state->state = ui::AccessibilityTypes::STATE_HASPOPUP; | 578 state->state = ui::AccessibilityTypes::STATE_HASPOPUP; |
574 } | 579 } |
575 } | 580 } |
576 | 581 |
577 void DownloadItemView::ButtonPressed( | 582 void DownloadItemView::ButtonPressed( |
578 views::Button* sender, const views::Event& event) { | 583 views::Button* sender, const views::Event& event) { |
579 if (sender == discard_button_) { | 584 if (sender == discard_button_) { |
580 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", | 585 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", |
581 base::Time::Now() - creation_time_); | 586 base::Time::Now() - creation_time_); |
582 if (download_->IsPartialDownload()) | 587 if (download_->IsPartialDownload()) |
583 download_->Cancel(true); | 588 download_->Cancel(true); |
584 download_->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | 589 download_->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
585 // WARNING: we are deleted at this point. Don't access 'this'. | 590 // WARNING: we are deleted at this point. Don't access 'this'. |
586 } else if (sender == save_button_) { | 591 } else if (save_button_ && sender == save_button_) { |
587 // The user has confirmed a dangerous download. We'd record how quickly the | 592 // The user has confirmed a dangerous download. We'd record how quickly the |
588 // user did this to detect whether we're being clickjacked. | 593 // user did this to detect whether we're being clickjacked. |
589 UMA_HISTOGRAM_LONG_TIMES("clickjacking.save_download", | 594 UMA_HISTOGRAM_LONG_TIMES("clickjacking.save_download", |
590 base::Time::Now() - creation_time_); | 595 base::Time::Now() - creation_time_); |
591 // This will change the state and notify us. | 596 // This will change the state and notify us. |
592 download_->DangerousDownloadValidated(); | 597 download_->DangerousDownloadValidated(); |
593 } | 598 } |
594 } | 599 } |
595 | 600 |
596 void DownloadItemView::AnimationProgressed(const ui::Animation* animation) { | 601 void DownloadItemView::AnimationProgressed(const ui::Animation* animation) { |
597 // We don't care if what animation (body button/drop button/complete), | 602 // We don't care if what animation (body button/drop button/complete), |
598 // is calling back, as they all have to go through the same paint call. | 603 // is calling back, as they all have to go through the same paint call. |
599 SchedulePaint(); | 604 SchedulePaint(); |
600 } | 605 } |
601 | 606 |
| 607 // The DownloadItemView can be in three major modes (NORMAL_MODE, DANGEROUS_MODE |
| 608 // and MALICIOUS_MODE). |
| 609 // |
| 610 // NORMAL_MODE: We are displaying an in-progress or completed download. |
| 611 // .-------------------------------+-. |
| 612 // | [icon] Filename |v| |
| 613 // | [ ] Status | | |
| 614 // `-------------------------------+-' |
| 615 // | | \_ Drop down button. Invokes menu. Responds |
| 616 // | | to mouse. (NORMAL, HOT or PUSHED). |
| 617 // | \_ Icon is overlaid on top of in-progress animation. |
| 618 // \_ Both the body and the drop down button respond to mouse hover and can be |
| 619 // pushed (NORMAL, HOT or PUSHED). |
| 620 // |
| 621 // DANGEROUS_MODE: The file could be potentially dangerous. |
| 622 // .-------------------------------------------------------. |
| 623 // | [ ! ] [This type of file can ] [ Keep ] [ Discard ] | |
| 624 // | [ ] [destroy your computer..] [ ] [ ] | |
| 625 // `-------------------------------------------------------' |
| 626 // | | | | \_ No drop down button. |
| 627 // | | | \_ Buttons are views::TextButtons. |
| 628 // | | \_ Text is in a label (dangerous_download_label_) |
| 629 // | \_ Warning icon. No progress animation. |
| 630 // \_ Body is static. Doesn't respond to mouse hover or press. (NORMAL only) |
| 631 // |
| 632 // MALICIOUS_MODE: The file is known malware. |
| 633 // .---------------------------------------------+-. |
| 634 // | [ - ] [This file is malicious.] [ Discard ] |v| |
| 635 // | [ ] [ ] [ ] | |-. |
| 636 // `---------------------------------------------+-' | |
| 637 // | | | | Drop down button. Responds to |
| 638 // | | | | mouse.(NORMAL, HOT or PUSHED) |
| 639 // | | | \_ Button is a views::TextButton. |
| 640 // | | \_ Text is in a label (dangerous_download_label_) |
| 641 // | \_ Warning icon. No progress animation. |
| 642 // \_ Body is static. Doesn't respond to mouse hover or press. (NORMAL only) |
| 643 // |
602 void DownloadItemView::OnPaint(gfx::Canvas* canvas) { | 644 void DownloadItemView::OnPaint(gfx::Canvas* canvas) { |
603 BodyImageSet* body_image_set = NULL; | 645 BodyImageSet* body_image_set = NULL; |
604 switch (body_state_) { | 646 switch (mode_) { |
605 case NORMAL: | 647 case NORMAL_MODE: |
606 case HOT: | 648 if (body_state_ == PUSHED) |
607 body_image_set = &normal_body_image_set_; | 649 body_image_set = &pushed_body_image_set_; |
| 650 else // NORMAL or HOT |
| 651 body_image_set = &normal_body_image_set_; |
608 break; | 652 break; |
609 case PUSHED: | 653 case DANGEROUS_MODE: |
610 body_image_set = &pushed_body_image_set_; | 654 body_image_set = &dangerous_mode_body_image_set_; |
611 break; | 655 break; |
612 case DANGEROUS: | 656 case MALICIOUS_MODE: |
613 body_image_set = &dangerous_mode_body_image_set_; | 657 body_image_set = &malicious_mode_body_image_set_; |
614 break; | 658 break; |
615 default: | 659 default: |
616 NOTREACHED(); | 660 NOTREACHED(); |
617 } | 661 } |
| 662 |
618 DropDownImageSet* drop_down_image_set = NULL; | 663 DropDownImageSet* drop_down_image_set = NULL; |
619 switch (drop_down_state_) { | 664 switch (mode_) { |
620 case NORMAL: | 665 case NORMAL_MODE: |
621 case HOT: | 666 case MALICIOUS_MODE: |
622 drop_down_image_set = &normal_drop_down_image_set_; | 667 if (drop_down_state_ == PUSHED) |
| 668 drop_down_image_set = &pushed_drop_down_image_set_; |
| 669 else // NORMAL or HOT |
| 670 drop_down_image_set = &normal_drop_down_image_set_; |
623 break; | 671 break; |
624 case PUSHED: | 672 case DANGEROUS_MODE: |
625 drop_down_image_set = &pushed_drop_down_image_set_; | 673 // We don't use a drop down button for mode_ == DANGEROUS_MODE. So we let |
626 break; | 674 // drop_down_image_set == NULL. |
627 case DANGEROUS: | |
628 drop_down_image_set = NULL; // No drop-down in dangerous mode. | |
629 break; | 675 break; |
630 default: | 676 default: |
631 NOTREACHED(); | 677 NOTREACHED(); |
632 } | 678 } |
633 | 679 |
634 int center_width = width() - kLeftPadding - | 680 int center_width = width() - kLeftPadding - |
635 body_image_set->left->width() - | 681 body_image_set->left->width() - |
636 body_image_set->right->width() - | 682 body_image_set->right->width() - |
637 (drop_down_image_set ? | 683 (drop_down_image_set ? |
638 normal_drop_down_image_set_.center->width() : | 684 normal_drop_down_image_set_.center->width() : |
639 0); | 685 0); |
640 | 686 |
641 // May be caused by animation. | 687 // May be caused by animation. |
642 if (center_width <= 0) | 688 if (center_width <= 0) |
643 return; | 689 return; |
644 | 690 |
645 // Draw status before button image to effectively lighten text. | 691 // Draw status before button image to effectively lighten text. No status for |
646 if (!IsDangerousMode()) { | 692 // warning dialogs. |
| 693 if (!IsShowingWarningDialog()) { |
647 if (!status_text_.empty()) { | 694 if (!status_text_.empty()) { |
648 int mirrored_x = GetMirroredXWithWidthInView( | 695 int mirrored_x = GetMirroredXWithWidthInView( |
649 download_util::kSmallProgressIconSize, kTextWidth); | 696 download_util::kSmallProgressIconSize, kTextWidth); |
650 // Add font_.height() to compensate for title, which is drawn later. | 697 // Add font_.height() to compensate for title, which is drawn later. |
651 int y = box_y_ + kVerticalPadding + font_.GetHeight() + | 698 int y = box_y_ + kVerticalPadding + font_.GetHeight() + |
652 kVerticalTextPadding; | 699 kVerticalTextPadding; |
653 SkColor file_name_color = GetThemeProvider()->GetColor( | 700 SkColor file_name_color = GetThemeProvider()->GetColor( |
654 ThemeService::COLOR_BOOKMARK_TEXT); | 701 ThemeService::COLOR_BOOKMARK_TEXT); |
655 // If text is light-on-dark, lightening it alone will do nothing. | 702 // If text is light-on-dark, lightening it alone will do nothing. |
656 // Therefore we mute luminance a wee bit before drawing in this case. | 703 // Therefore we mute luminance a wee bit before drawing in this case. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 PaintBitmaps(canvas, | 735 PaintBitmaps(canvas, |
689 body_image_set->top, body_image_set->center, | 736 body_image_set->top, body_image_set->center, |
690 body_image_set->bottom, | 737 body_image_set->bottom, |
691 x, box_y_, box_height_, center_width); | 738 x, box_y_, box_height_, center_width); |
692 x += center_width; | 739 x += center_width; |
693 PaintBitmaps(canvas, | 740 PaintBitmaps(canvas, |
694 body_image_set->top_right, body_image_set->right, | 741 body_image_set->top_right, body_image_set->right, |
695 body_image_set->bottom_right, | 742 body_image_set->bottom_right, |
696 x, box_y_, box_height_, body_image_set->top_right->width()); | 743 x, box_y_, box_height_, body_image_set->top_right->width()); |
697 | 744 |
698 // Overlay our body hot state. | 745 // Overlay our body hot state. Warning dialogs don't display body a hot state. |
699 if (body_hover_animation_->GetCurrentValue() > 0) { | 746 if (!IsShowingWarningDialog() && |
| 747 body_hover_animation_->GetCurrentValue() > 0) { |
700 canvas->SaveLayerAlpha( | 748 canvas->SaveLayerAlpha( |
701 static_cast<int>(body_hover_animation_->GetCurrentValue() * 255)); | 749 static_cast<int>(body_hover_animation_->GetCurrentValue() * 255)); |
702 canvas->GetSkCanvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); | 750 canvas->GetSkCanvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); |
703 | 751 |
704 int x = kLeftPadding; | 752 int x = kLeftPadding; |
705 PaintBitmaps(canvas, | 753 PaintBitmaps(canvas, |
706 hot_body_image_set_.top_left, hot_body_image_set_.left, | 754 hot_body_image_set_.top_left, hot_body_image_set_.left, |
707 hot_body_image_set_.bottom_left, | 755 hot_body_image_set_.bottom_left, |
708 x, box_y_, box_height_, hot_body_image_set_.top_left->width()); | 756 x, box_y_, box_height_, hot_body_image_set_.top_left->width()); |
709 x += body_image_set->top_left->width(); | 757 x += body_image_set->top_left->width(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 } | 794 } |
747 | 795 |
748 // Restore the canvas to avoid file name etc. text are drawn flipped. | 796 // Restore the canvas to avoid file name etc. text are drawn flipped. |
749 // Consequently, the x-axis of following canvas->DrawXXX() method should be | 797 // Consequently, the x-axis of following canvas->DrawXXX() method should be |
750 // mirrored so the text and images are down in the right positions. | 798 // mirrored so the text and images are down in the right positions. |
751 canvas->Restore(); | 799 canvas->Restore(); |
752 | 800 |
753 // Print the text, left aligned and always print the file extension. | 801 // Print the text, left aligned and always print the file extension. |
754 // Last value of x was the end of the right image, just before the button. | 802 // Last value of x was the end of the right image, just before the button. |
755 // Note that in dangerous mode we use a label (as the text is multi-line). | 803 // Note that in dangerous mode we use a label (as the text is multi-line). |
756 if (!IsDangerousMode()) { | 804 if (!IsShowingWarningDialog()) { |
757 string16 filename; | 805 string16 filename; |
758 if (!disabled_while_opening_) { | 806 if (!disabled_while_opening_) { |
759 filename = ui::ElideFilename(download_->GetFileNameToReportUser(), | 807 filename = ui::ElideFilename(download_->GetFileNameToReportUser(), |
760 font_, kTextWidth); | 808 font_, kTextWidth); |
761 } else { | 809 } else { |
762 // First, Calculate the download status opening string width. | 810 // First, Calculate the download status opening string width. |
763 string16 status_string = | 811 string16 status_string = |
764 l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, string16()); | 812 l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, string16()); |
765 int status_string_width = font_.GetStringWidth(status_string); | 813 int status_string_width = font_.GetStringWidth(status_string); |
766 // Then, elide the file name. | 814 // Then, elide the file name. |
(...skipping 18 matching lines...) Expand all Loading... |
785 IsEnabled() ? file_name_color : | 833 IsEnabled() ? file_name_color : |
786 kFileNameDisabledColor, | 834 kFileNameDisabledColor, |
787 mirrored_x, y, kTextWidth, font_.GetHeight()); | 835 mirrored_x, y, kTextWidth, font_.GetHeight()); |
788 } | 836 } |
789 | 837 |
790 // Load the icon. | 838 // Load the icon. |
791 IconManager* im = g_browser_process->icon_manager(); | 839 IconManager* im = g_browser_process->icon_manager(); |
792 gfx::Image* image = im->LookupIcon(download_->GetUserVerifiedFilePath(), | 840 gfx::Image* image = im->LookupIcon(download_->GetUserVerifiedFilePath(), |
793 IconLoader::SMALL); | 841 IconLoader::SMALL); |
794 const SkBitmap* icon = NULL; | 842 const SkBitmap* icon = NULL; |
795 if (IsDangerousMode()) | 843 if (IsShowingWarningDialog()) |
796 icon = warning_icon_; | 844 icon = warning_icon_; |
797 else if (image) | 845 else if (image) |
798 icon = *image; | 846 icon = *image; |
799 | 847 |
800 // We count on the fact that the icon manager will cache the icons and if one | 848 // We count on the fact that the icon manager will cache the icons and if one |
801 // is available, it will be cached here. We *don't* want to request the icon | 849 // is available, it will be cached here. We *don't* want to request the icon |
802 // to be loaded here, since this will also get called if the icon can't be | 850 // to be loaded here, since this will also get called if the icon can't be |
803 // loaded, in which case LookupIcon will always be NULL. The loading will be | 851 // loaded, in which case LookupIcon will always be NULL. The loading will be |
804 // triggered only when we think the status might change. | 852 // triggered only when we think the status might change. |
805 if (icon) { | 853 if (icon) { |
806 if (!IsDangerousMode()) { | 854 if (!IsShowingWarningDialog()) { |
807 if (download_->IsInProgress()) { | 855 if (download_->IsInProgress()) { |
808 download_util::PaintDownloadProgress(canvas, this, 0, 0, | 856 download_util::PaintDownloadProgress(canvas, this, 0, 0, |
809 progress_angle_, | 857 progress_angle_, |
810 download_->PercentComplete(), | 858 download_->PercentComplete(), |
811 download_util::SMALL); | 859 download_util::SMALL); |
812 } else if (download_->IsComplete() && | 860 } else if (download_->IsComplete() && |
813 complete_animation_.get() && | 861 complete_animation_.get() && |
814 complete_animation_->is_animating()) { | 862 complete_animation_->is_animating()) { |
815 if (download_->IsInterrupted()) { | 863 if (download_->IsInterrupted()) { |
816 download_util::PaintDownloadInterrupted(canvas, this, 0, 0, | 864 download_util::PaintDownloadInterrupted(canvas, this, 0, 0, |
817 complete_animation_->GetCurrentValue(), | 865 complete_animation_->GetCurrentValue(), |
818 download_util::SMALL); | 866 download_util::SMALL); |
819 } else { | 867 } else { |
820 download_util::PaintDownloadComplete(canvas, this, 0, 0, | 868 download_util::PaintDownloadComplete(canvas, this, 0, 0, |
821 complete_animation_->GetCurrentValue(), | 869 complete_animation_->GetCurrentValue(), |
822 download_util::SMALL); | 870 download_util::SMALL); |
823 } | 871 } |
824 } | 872 } |
825 } | 873 } |
826 | 874 |
827 // Draw the icon image. | 875 // Draw the icon image. |
828 int icon_x, icon_y; | 876 int icon_x, icon_y; |
829 | 877 |
830 if (IsDangerousMode()) { | 878 if (IsShowingWarningDialog()) { |
831 icon_x = kLeftPadding + body_image_set->top_left->width(); | 879 icon_x = kLeftPadding + body_image_set->top_left->width(); |
832 icon_y = (height() - icon->height()) / 2; | 880 icon_y = (height() - icon->height()) / 2; |
833 } else { | 881 } else { |
834 icon_x = download_util::kSmallProgressIconOffset; | 882 icon_x = download_util::kSmallProgressIconOffset; |
835 icon_y = download_util::kSmallProgressIconOffset; | 883 icon_y = download_util::kSmallProgressIconOffset; |
836 } | 884 } |
837 icon_x = GetMirroredXWithWidthInView(icon_x, icon->width()); | 885 icon_x = GetMirroredXWithWidthInView(icon_x, icon->width()); |
838 if (IsEnabled()) { | 886 if (IsEnabled()) { |
839 canvas->DrawBitmapInt(*icon, icon_x, icon_y); | 887 canvas->DrawBitmapInt(*icon, icon_x, icon_y); |
840 } else { | 888 } else { |
841 // Use an alpha to make the image look disabled. | 889 // Use an alpha to make the image look disabled. |
842 SkPaint paint; | 890 SkPaint paint; |
843 paint.setAlpha(120); | 891 paint.setAlpha(120); |
844 canvas->DrawBitmapInt(*icon, icon_x, icon_y, paint); | 892 canvas->DrawBitmapInt(*icon, icon_x, icon_y, paint); |
845 } | 893 } |
846 } | 894 } |
847 } | 895 } |
848 | 896 |
849 void DownloadItemView::OpenDownload() { | 897 void DownloadItemView::OpenDownload() { |
| 898 DCHECK(!IsShowingWarningDialog()); |
850 // We're interested in how long it takes users to open downloads. If they | 899 // We're interested in how long it takes users to open downloads. If they |
851 // open downloads super quickly, we should be concerned about clickjacking. | 900 // open downloads super quickly, we should be concerned about clickjacking. |
852 UMA_HISTOGRAM_LONG_TIMES("clickjacking.open_download", | 901 UMA_HISTOGRAM_LONG_TIMES("clickjacking.open_download", |
853 base::Time::Now() - creation_time_); | 902 base::Time::Now() - creation_time_); |
854 download_->OpenDownload(); | 903 download_->OpenDownload(); |
855 UpdateAccessibleName(); | 904 UpdateAccessibleName(); |
856 } | 905 } |
857 | 906 |
858 void DownloadItemView::LoadIcon() { | 907 void DownloadItemView::LoadIcon() { |
859 IconManager* im = g_browser_process->icon_manager(); | 908 IconManager* im = g_browser_process->icon_manager(); |
(...skipping 30 matching lines...) Expand all Loading... |
890 0, 0, center_bitmap->width(), center_bitmap->height(), | 939 0, 0, center_bitmap->width(), center_bitmap->height(), |
891 x, y, width, middle_height, false); | 940 x, y, width, middle_height, false); |
892 y += middle_height; | 941 y += middle_height; |
893 // Draw the bottom. | 942 // Draw the bottom. |
894 canvas->DrawBitmapInt(*bottom_bitmap, | 943 canvas->DrawBitmapInt(*bottom_bitmap, |
895 0, 0, bottom_bitmap->width(), bottom_bitmap->height(), | 944 0, 0, bottom_bitmap->width(), bottom_bitmap->height(), |
896 x, y, width, bottom_bitmap->height(), false); | 945 x, y, width, bottom_bitmap->height(), false); |
897 } | 946 } |
898 | 947 |
899 void DownloadItemView::SetState(State body_state, State drop_down_state) { | 948 void DownloadItemView::SetState(State body_state, State drop_down_state) { |
| 949 // If we are showing a warning dialog, we don't change body state. |
| 950 if (IsShowingWarningDialog()) { |
| 951 body_state = NORMAL; |
| 952 |
| 953 // Current body_state_ should always be NORMAL for warning dialogs. |
| 954 DCHECK(body_state_ == NORMAL); |
| 955 // We shouldn't be calling SetState if we are in DANGEROUS_MODE. |
| 956 DCHECK(mode_ != DANGEROUS_MODE); |
| 957 } |
| 958 // Avoid extra SchedulePaint()s if the state is going to be the same. |
900 if (body_state_ == body_state && drop_down_state_ == drop_down_state) | 959 if (body_state_ == body_state && drop_down_state_ == drop_down_state) |
901 return; | 960 return; |
902 | 961 |
903 body_state_ = body_state; | 962 body_state_ = body_state; |
904 drop_down_state_ = drop_down_state; | 963 drop_down_state_ = drop_down_state; |
905 SchedulePaint(); | 964 SchedulePaint(); |
906 } | 965 } |
907 | 966 |
908 void DownloadItemView::ClearDangerousMode() { | 967 void DownloadItemView::ClearWarningDialog() { |
909 DCHECK(download_->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED && | 968 DCHECK(download_->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED && |
910 body_state_ == DANGEROUS && drop_down_state_ == DANGEROUS); | 969 (mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE)); |
911 | 970 |
| 971 mode_ = NORMAL_MODE; |
912 body_state_ = NORMAL; | 972 body_state_ = NORMAL; |
913 drop_down_state_ = NORMAL; | 973 drop_down_state_ = NORMAL; |
914 | 974 |
915 // Remove the views used by the dangerous mode. | 975 // Remove the views used by the warning dialog. |
916 RemoveChildView(save_button_); | 976 if (save_button_) { |
917 delete save_button_; | 977 RemoveChildView(save_button_); |
918 save_button_ = NULL; | 978 delete save_button_; |
| 979 save_button_ = NULL; |
| 980 } |
919 RemoveChildView(discard_button_); | 981 RemoveChildView(discard_button_); |
920 delete discard_button_; | 982 delete discard_button_; |
921 discard_button_ = NULL; | 983 discard_button_ = NULL; |
922 RemoveChildView(dangerous_download_label_); | 984 RemoveChildView(dangerous_download_label_); |
923 delete dangerous_download_label_; | 985 delete dangerous_download_label_; |
924 dangerous_download_label_ = NULL; | 986 dangerous_download_label_ = NULL; |
925 dangerous_download_label_sized_ = false; | 987 dangerous_download_label_sized_ = false; |
| 988 cached_button_size_.SetSize(0,0); |
926 | 989 |
927 // Set the accessible name back to the status and filename instead of the | 990 // Set the accessible name back to the status and filename instead of the |
928 // download warning. | 991 // download warning. |
929 UpdateAccessibleName(); | 992 UpdateAccessibleName(); |
| 993 UpdateDropDownButtonPosition(); |
930 | 994 |
931 // We need to load the icon now that the download_ has the real path. | 995 // We need to load the icon now that the download_ has the real path. |
932 LoadIcon(); | 996 LoadIcon(); |
933 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); | 997 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); |
934 | 998 |
935 // Force the shelf to layout again as our size has changed. | 999 // Force the shelf to layout again as our size has changed. |
936 parent_->Layout(); | 1000 parent_->Layout(); |
937 parent_->SchedulePaint(); | 1001 parent_->SchedulePaint(); |
938 } | 1002 } |
939 | 1003 |
940 void DownloadItemView::EnterDangerousMode() { | 1004 void DownloadItemView::ShowWarningDialog() { |
941 DCHECK(body_state_ != DANGEROUS && drop_down_state_ != DANGEROUS); | 1005 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); |
| 1006 if (download_->GetDangerType() == DownloadStateInfo::DANGEROUS_URL || |
| 1007 download_->GetDangerType() == DownloadStateInfo::DANGEROUS_CONTENT) { |
| 1008 mode_ = MALICIOUS_MODE; |
| 1009 } else { |
| 1010 DCHECK(download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE); |
| 1011 mode_ = DANGEROUS_MODE; |
| 1012 } |
| 1013 body_state_ = NORMAL; |
| 1014 drop_down_state_ = NORMAL; |
942 tooltip_text_.clear(); | 1015 tooltip_text_.clear(); |
943 body_state_ = DANGEROUS; | 1016 if (mode_ == DANGEROUS_MODE) { |
944 drop_down_state_ = DANGEROUS; | 1017 save_button_ = new views::NativeTextButton(this, |
945 save_button_ = new views::NativeTextButton(this, | 1018 l10n_util::GetStringUTF16( |
946 l10n_util::GetStringUTF16( | 1019 ChromeDownloadManagerDelegate::IsExtensionDownload(download_) ? |
947 ChromeDownloadManagerDelegate::IsExtensionDownload(download_) ? | 1020 IDS_CONTINUE_EXTENSION_DOWNLOAD : IDS_CONFIRM_DOWNLOAD)); |
948 IDS_CONTINUE_EXTENSION_DOWNLOAD : IDS_CONFIRM_DOWNLOAD)); | 1021 save_button_->set_ignore_minimum_size(true); |
949 save_button_->set_ignore_minimum_size(true); | 1022 AddChildView(save_button_); |
| 1023 } |
950 discard_button_ = new views::NativeTextButton( | 1024 discard_button_ = new views::NativeTextButton( |
951 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); | 1025 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); |
952 discard_button_->set_ignore_minimum_size(true); | 1026 discard_button_->set_ignore_minimum_size(true); |
953 AddChildView(save_button_); | |
954 AddChildView(discard_button_); | 1027 AddChildView(discard_button_); |
955 | 1028 |
956 // Ensure the file name is not too long. | 1029 // Ensure the file name is not too long. |
957 | 1030 |
958 // Extract the file extension (if any). | 1031 // Extract the file extension (if any). |
959 FilePath filename(download_->GetTargetName()); | 1032 FilePath filename(download_->GetTargetName()); |
960 #if defined(OS_POSIX) | 1033 #if defined(OS_POSIX) |
961 string16 extension = WideToUTF16(base::SysNativeMBToWide( | 1034 string16 extension = WideToUTF16(base::SysNativeMBToWide( |
962 filename.Extension())); | 1035 filename.Extension())); |
963 #else | 1036 #else |
(...skipping 11 matching lines...) Expand all Loading... |
975 #endif | 1048 #endif |
976 | 1049 |
977 // Elide giant extensions (this shouldn't currently be hit, but might | 1050 // Elide giant extensions (this shouldn't currently be hit, but might |
978 // in future, should we ever notice unsafe giant extensions). | 1051 // in future, should we ever notice unsafe giant extensions). |
979 if (extension.length() > kFileNameMaxLength / 2) | 1052 if (extension.length() > kFileNameMaxLength / 2) |
980 ui::ElideString(extension, kFileNameMaxLength / 2, &extension); | 1053 ui::ElideString(extension, kFileNameMaxLength / 2, &extension); |
981 | 1054 |
982 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1055 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
983 // The dangerous download label text and icon are different | 1056 // The dangerous download label text and icon are different |
984 // under different cases. | 1057 // under different cases. |
985 if (download_->GetDangerType() == DownloadStateInfo::DANGEROUS_URL || | 1058 if (mode_ == MALICIOUS_MODE) { |
986 download_->GetDangerType() == DownloadStateInfo::DANGEROUS_CONTENT) { | |
987 warning_icon_ = rb.GetBitmapNamed(IDR_SAFEBROWSING_WARNING); | 1059 warning_icon_ = rb.GetBitmapNamed(IDR_SAFEBROWSING_WARNING); |
988 } else { | 1060 } else { |
989 DCHECK(download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE); | 1061 DCHECK(download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE); |
| 1062 // The download file has dangerous file type (e.g.: an executable). |
990 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); | 1063 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); |
991 } | 1064 } |
992 string16 dangerous_label; | 1065 string16 dangerous_label; |
993 if (download_->GetDangerType() == DownloadStateInfo::DANGEROUS_URL) { | 1066 if (download_->GetDangerType() == DownloadStateInfo::DANGEROUS_URL) { |
994 // Safebrowsing shows the download URL or content leads to malicious file. | 1067 // Safebrowsing shows the download URL or content leads to malicious file. |
995 dangerous_label = l10n_util::GetStringUTF16( | 1068 dangerous_label = l10n_util::GetStringUTF16( |
996 IDS_PROMPT_MALICIOUS_DOWNLOAD_URL); | 1069 IDS_PROMPT_MALICIOUS_DOWNLOAD_URL); |
997 } else if (download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE && | 1070 } else if (download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE && |
998 ChromeDownloadManagerDelegate::IsExtensionDownload(download_)) { | 1071 ChromeDownloadManagerDelegate::IsExtensionDownload(download_)) { |
999 dangerous_label = | 1072 dangerous_label = |
(...skipping 10 matching lines...) Expand all Loading... |
1010 filename = base::i18n::GetDisplayStringInLTRDirectionality(filename); | 1083 filename = base::i18n::GetDisplayStringInLTRDirectionality(filename); |
1011 dangerous_label = l10n_util::GetStringFUTF16( | 1084 dangerous_label = l10n_util::GetStringFUTF16( |
1012 download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE ? | 1085 download_->GetDangerType() == DownloadStateInfo::DANGEROUS_FILE ? |
1013 IDS_PROMPT_DANGEROUS_DOWNLOAD : | 1086 IDS_PROMPT_DANGEROUS_DOWNLOAD : |
1014 IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT, | 1087 IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT, |
1015 filename); | 1088 filename); |
1016 } | 1089 } |
1017 | 1090 |
1018 dangerous_download_label_ = new views::Label(dangerous_label); | 1091 dangerous_download_label_ = new views::Label(dangerous_label); |
1019 dangerous_download_label_->SetMultiLine(true); | 1092 dangerous_download_label_->SetMultiLine(true); |
1020 dangerous_download_label_->SetHorizontalAlignment( | 1093 dangerous_download_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
1021 views::Label::ALIGN_LEFT); | |
1022 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); | 1094 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); |
1023 AddChildView(dangerous_download_label_); | 1095 AddChildView(dangerous_download_label_); |
1024 SizeLabelToMinWidth(); | 1096 SizeLabelToMinWidth(); |
| 1097 UpdateDropDownButtonPosition(); |
1025 } | 1098 } |
1026 | 1099 |
1027 gfx::Size DownloadItemView::GetButtonSize() { | 1100 gfx::Size DownloadItemView::GetButtonSize() { |
1028 DCHECK(save_button_ && discard_button_); | 1101 DCHECK(discard_button_ && (mode_ == MALICIOUS_MODE || save_button_)); |
1029 gfx::Size size; | 1102 gfx::Size size; |
1030 | 1103 |
1031 // We cache the size when successfully retrieved, not for performance reasons | 1104 // We cache the size when successfully retrieved, not for performance reasons |
1032 // but because if this DownloadItemView is being animated while the tab is | 1105 // but because if this DownloadItemView is being animated while the tab is |
1033 // not showing, the native buttons are not parented and their preferred size | 1106 // not showing, the native buttons are not parented and their preferred size |
1034 // is 0, messing-up the layout. | 1107 // is 0, messing-up the layout. |
1035 if (cached_button_size_.width() != 0) | 1108 if (cached_button_size_.width() != 0) |
1036 return cached_button_size_; | 1109 return cached_button_size_; |
1037 | 1110 |
1038 size = save_button_->GetMinimumSize(); | 1111 if (save_button_) |
| 1112 size = save_button_->GetMinimumSize(); |
1039 gfx::Size discard_size = discard_button_->GetMinimumSize(); | 1113 gfx::Size discard_size = discard_button_->GetMinimumSize(); |
1040 | 1114 |
1041 size.SetSize(std::max(size.width(), discard_size.width()), | 1115 size.SetSize(std::max(size.width(), discard_size.width()), |
1042 std::max(size.height(), discard_size.height())); | 1116 std::max(size.height(), discard_size.height())); |
1043 | 1117 |
1044 if (size.width() != 0) | 1118 if (size.width() != 0) |
1045 cached_button_size_ = size; | 1119 cached_button_size_ = size; |
1046 | 1120 |
1047 return size; | 1121 return size; |
1048 } | 1122 } |
1049 | 1123 |
1050 // This method computes the minimum width of the label for displaying its text | 1124 // This method computes the minimum width of the label for displaying its text |
1051 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the | 1125 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the |
1052 // configuration with minimum width. | 1126 // configuration with minimum width. |
1053 void DownloadItemView::SizeLabelToMinWidth() { | 1127 void DownloadItemView::SizeLabelToMinWidth() { |
1054 if (dangerous_download_label_sized_) | 1128 if (dangerous_download_label_sized_) |
1055 return; | 1129 return; |
1056 | 1130 |
1057 string16 text = dangerous_download_label_->GetText(); | 1131 string16 text = dangerous_download_label_->GetText(); |
1058 TrimWhitespace(text, TRIM_ALL, &text); | 1132 TrimWhitespace(text, TRIM_ALL, &text); |
1059 DCHECK_EQ(string16::npos, text.find('\n')); | 1133 DCHECK_EQ(string16::npos, text.find('\n')); |
1060 | 1134 |
1061 // Make the label big so that GetPreferredSize() is not constrained by the | 1135 // Make the label big so that GetPreferredSize() is not constrained by the |
1062 // current width. | 1136 // current width. |
1063 dangerous_download_label_->SetBounds(0, 0, 1000, 1000); | 1137 dangerous_download_label_->SetBounds(0, 0, 1000, 1000); |
1064 | 1138 |
1065 gfx::Size size; | |
1066 int min_width = -1; | |
1067 // Using BREAK_WORD can work in most cases, but it can also break | 1139 // Using BREAK_WORD can work in most cases, but it can also break |
1068 // lines where it should not. Using BREAK_LINE is safer although | 1140 // lines where it should not. Using BREAK_LINE is safer although |
1069 // slower for Chinese/Japanese. This is not perf-critical at all, though. | 1141 // slower for Chinese/Japanese. This is not perf-critical at all, though. |
1070 base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_LINE); | 1142 base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_LINE); |
1071 bool status = iter.Init(); | 1143 bool status = iter.Init(); |
1072 DCHECK(status); | 1144 DCHECK(status); |
1073 | 1145 |
1074 string16 current_text = text; | 1146 string16 current_text = text; |
1075 string16 prev_text = text; | 1147 string16 prev_text = text; |
1076 while (iter.Advance()) { | 1148 gfx::Size size = dangerous_download_label_->GetPreferredSize(); |
| 1149 int min_width = size.width(); |
| 1150 |
| 1151 // Go through the string and try each line break (starting with no line break) |
| 1152 // searching for the optimal line break position. Stop if we find one that |
| 1153 // yields one that is less than kDangerousTextWidth wide. This is to prevent |
| 1154 // a short string (e.g.: "This file is malicious") from being broken up |
| 1155 // unnecessarily. |
| 1156 while (iter.Advance() && min_width > kDangerousTextWidth) { |
1077 size_t pos = iter.pos(); | 1157 size_t pos = iter.pos(); |
1078 if (pos >= text.length()) | 1158 if (pos >= text.length()) |
1079 break; | 1159 break; |
1080 // This can be a low surrogate codepoint, but u_isUWhiteSpace will | 1160 // This can be a low surrogate codepoint, but u_isUWhiteSpace will |
1081 // return false and inserting a new line after a surrogate pair | 1161 // return false and inserting a new line after a surrogate pair |
1082 // is perfectly ok. | 1162 // is perfectly ok. |
1083 char16 line_end_char = text[pos - 1]; | 1163 char16 line_end_char = text[pos - 1]; |
1084 if (u_isUWhiteSpace(line_end_char)) | 1164 if (u_isUWhiteSpace(line_end_char)) |
1085 current_text.replace(pos - 1, 1, 1, char16('\n')); | 1165 current_text.replace(pos - 1, 1, 1, char16('\n')); |
1086 else | 1166 else |
1087 current_text.insert(pos, 1, char16('\n')); | 1167 current_text.insert(pos, 1, char16('\n')); |
1088 dangerous_download_label_->SetText(current_text); | 1168 dangerous_download_label_->SetText(current_text); |
1089 size = dangerous_download_label_->GetPreferredSize(); | 1169 size = dangerous_download_label_->GetPreferredSize(); |
1090 | 1170 |
1091 if (min_width == -1) | |
1092 min_width = size.width(); | |
1093 | |
1094 // If the width is growing again, it means we passed the optimal width spot. | 1171 // If the width is growing again, it means we passed the optimal width spot. |
1095 if (size.width() > min_width) { | 1172 if (size.width() > min_width) { |
1096 dangerous_download_label_->SetText(prev_text); | 1173 dangerous_download_label_->SetText(prev_text); |
1097 break; | 1174 break; |
1098 } else { | 1175 } else { |
1099 min_width = size.width(); | 1176 min_width = size.width(); |
1100 } | 1177 } |
1101 | 1178 |
1102 // Restore the string. | 1179 // Restore the string. |
1103 prev_text = current_text; | 1180 prev_text = current_text; |
1104 current_text = text; | 1181 current_text = text; |
1105 } | 1182 } |
1106 | 1183 |
1107 // If we have a line with no line breaking opportunity (which is very | |
1108 // unlikely), we won't cut it. | |
1109 if (min_width == -1) | |
1110 size = dangerous_download_label_->GetPreferredSize(); | |
1111 | |
1112 dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); | 1184 dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); |
1113 dangerous_download_label_sized_ = true; | 1185 dangerous_download_label_sized_ = true; |
1114 } | 1186 } |
1115 | 1187 |
1116 void DownloadItemView::Reenable() { | 1188 void DownloadItemView::Reenable() { |
1117 disabled_while_opening_ = false; | 1189 disabled_while_opening_ = false; |
1118 SetEnabled(true); // Triggers a repaint. | 1190 SetEnabled(true); // Triggers a repaint. |
1119 } | 1191 } |
1120 | 1192 |
| 1193 void DownloadItemView::ReleaseDropDown() { |
| 1194 drop_down_pressed_ = false; |
| 1195 SetState(NORMAL, NORMAL); |
| 1196 } |
| 1197 |
1121 bool DownloadItemView::InDropDownButtonXCoordinateRange(int x) { | 1198 bool DownloadItemView::InDropDownButtonXCoordinateRange(int x) { |
1122 if (x > drop_down_x_left_ && x < drop_down_x_right_) | 1199 if (x > drop_down_x_left_ && x < drop_down_x_right_) |
1123 return true; | 1200 return true; |
1124 return false; | 1201 return false; |
1125 } | 1202 } |
1126 | 1203 |
1127 void DownloadItemView::UpdateAccessibleName() { | 1204 void DownloadItemView::UpdateAccessibleName() { |
1128 string16 new_name; | 1205 string16 new_name; |
1129 if (download_->GetSafetyState() == DownloadItem::DANGEROUS) { | 1206 if (IsShowingWarningDialog()) { |
1130 new_name = dangerous_download_label_->GetText(); | 1207 new_name = dangerous_download_label_->GetText(); |
1131 } else { | 1208 } else { |
1132 new_name = status_text_ + char16(' ') + | 1209 new_name = status_text_ + char16(' ') + |
1133 download_->GetFileNameToReportUser().LossyDisplayName(); | 1210 download_->GetFileNameToReportUser().LossyDisplayName(); |
1134 } | 1211 } |
1135 | 1212 |
1136 // If the name has changed, notify assistive technology that the name | 1213 // If the name has changed, notify assistive technology that the name |
1137 // has changed so they can announce it immediately. | 1214 // has changed so they can announce it immediately. |
1138 if (new_name != accessible_name_) { | 1215 if (new_name != accessible_name_) { |
1139 accessible_name_ = new_name; | 1216 accessible_name_ = new_name; |
1140 if (GetWidget()) { | 1217 if (GetWidget()) { |
1141 GetWidget()->NotifyAccessibilityEvent( | 1218 GetWidget()->NotifyAccessibilityEvent( |
1142 this, ui::AccessibilityTypes::EVENT_NAME_CHANGED, true); | 1219 this, ui::AccessibilityTypes::EVENT_NAME_CHANGED, true); |
1143 } | 1220 } |
1144 } | 1221 } |
1145 } | 1222 } |
| 1223 |
| 1224 void DownloadItemView::UpdateDropDownButtonPosition() { |
| 1225 gfx::Size size = GetPreferredSize(); |
| 1226 if (base::i18n::IsRTL()) { |
| 1227 // Drop down button is glued to the left of the download shelf. |
| 1228 drop_down_x_left_ = 0; |
| 1229 drop_down_x_right_ = normal_drop_down_image_set_.top->width(); |
| 1230 } else { |
| 1231 // Drop down button is glued to the right of the download shelf. |
| 1232 drop_down_x_left_ = |
| 1233 size.width() - normal_drop_down_image_set_.top->width(); |
| 1234 drop_down_x_right_ = size.width(); |
| 1235 } |
| 1236 } |
OLD | NEW |