| 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 |