| 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/gtk/download/download_item_gtk.h" | 5 #include "chrome/browser/ui/gtk/download/download_item_gtk.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 G_CALLBACK(OnButtonPressThunk), this); | 118 G_CALLBACK(OnButtonPressThunk), this); |
| 119 GTK_WIDGET_UNSET_FLAGS(body_.get(), GTK_CAN_FOCUS); | 119 GTK_WIDGET_UNSET_FLAGS(body_.get(), GTK_CAN_FOCUS); |
| 120 // Remove internal padding on the button. | 120 // Remove internal padding on the button. |
| 121 GtkRcStyle* no_padding_style = gtk_rc_style_new(); | 121 GtkRcStyle* no_padding_style = gtk_rc_style_new(); |
| 122 no_padding_style->xthickness = 0; | 122 no_padding_style->xthickness = 0; |
| 123 no_padding_style->ythickness = 0; | 123 no_padding_style->ythickness = 0; |
| 124 gtk_widget_modify_style(body_.get(), no_padding_style); | 124 gtk_widget_modify_style(body_.get(), no_padding_style); |
| 125 g_object_unref(no_padding_style); | 125 g_object_unref(no_padding_style); |
| 126 | 126 |
| 127 name_label_ = gtk_label_new(NULL); | 127 name_label_ = gtk_label_new(NULL); |
| 128 // Left align and vertically center the labels. |
| 129 gtk_misc_set_alignment(GTK_MISC(name_label_), 0, 0.5); |
| 130 // Until we switch to vector graphics, force the font size. |
| 131 gtk_util::ForceFontSizePixels(name_label_, kTextSize); |
| 128 | 132 |
| 129 UpdateNameLabel(); | 133 UpdateNameLabel(); |
| 130 | 134 |
| 131 status_label_ = gtk_label_new(NULL); | 135 status_label_ = NULL; |
| 132 g_signal_connect(status_label_, "destroy", | |
| 133 G_CALLBACK(gtk_widget_destroyed), &status_label_); | |
| 134 // Left align and vertically center the labels. | |
| 135 gtk_misc_set_alignment(GTK_MISC(name_label_), 0, 0.5); | |
| 136 gtk_misc_set_alignment(GTK_MISC(status_label_), 0, 0.5); | |
| 137 // Until we switch to vector graphics, force the font size. | |
| 138 gtk_util::ForceFontSizePixels(name_label_, kTextSize); | |
| 139 gtk_util::ForceFontSizePixels(status_label_, kTextSize); | |
| 140 | 136 |
| 141 // Stack the labels on top of one another. | 137 // Stack the labels on top of one another. |
| 142 GtkWidget* text_stack = gtk_vbox_new(FALSE, 0); | 138 text_stack_ = gtk_vbox_new(FALSE, 0); |
| 143 gtk_box_pack_start(GTK_BOX(text_stack), name_label_, TRUE, TRUE, 0); | 139 gtk_box_pack_start(GTK_BOX(text_stack_), name_label_, TRUE, TRUE, 0); |
| 144 gtk_box_pack_start(GTK_BOX(text_stack), status_label_, FALSE, FALSE, 0); | |
| 145 | 140 |
| 146 // We use a GtkFixed because we don't want it to have its own window. | 141 // We use a GtkFixed because we don't want it to have its own window. |
| 147 // This choice of widget is not critically important though. | 142 // This choice of widget is not critically important though. |
| 148 progress_area_.Own(gtk_fixed_new()); | 143 progress_area_.Own(gtk_fixed_new()); |
| 149 gtk_widget_set_size_request(progress_area_.get(), | 144 gtk_widget_set_size_request(progress_area_.get(), |
| 150 download_util::kSmallProgressIconSize, | 145 download_util::kSmallProgressIconSize, |
| 151 download_util::kSmallProgressIconSize); | 146 download_util::kSmallProgressIconSize); |
| 152 gtk_widget_set_app_paintable(progress_area_.get(), TRUE); | 147 gtk_widget_set_app_paintable(progress_area_.get(), TRUE); |
| 153 g_signal_connect(progress_area_.get(), "expose-event", | 148 g_signal_connect(progress_area_.get(), "expose-event", |
| 154 G_CALLBACK(OnProgressAreaExposeThunk), this); | 149 G_CALLBACK(OnProgressAreaExposeThunk), this); |
| 155 | 150 |
| 156 // Put the download progress icon on the left of the labels. | 151 // Put the download progress icon on the left of the labels. |
| 157 GtkWidget* body_hbox = gtk_hbox_new(FALSE, 0); | 152 GtkWidget* body_hbox = gtk_hbox_new(FALSE, 0); |
| 158 gtk_container_add(GTK_CONTAINER(body_.get()), body_hbox); | 153 gtk_container_add(GTK_CONTAINER(body_.get()), body_hbox); |
| 159 gtk_box_pack_start(GTK_BOX(body_hbox), progress_area_.get(), FALSE, FALSE, 0); | 154 gtk_box_pack_start(GTK_BOX(body_hbox), progress_area_.get(), FALSE, FALSE, 0); |
| 160 gtk_box_pack_start(GTK_BOX(body_hbox), text_stack, TRUE, TRUE, 0); | 155 gtk_box_pack_start(GTK_BOX(body_hbox), text_stack_, TRUE, TRUE, 0); |
| 161 | 156 |
| 162 menu_button_ = gtk_button_new(); | 157 menu_button_ = gtk_button_new(); |
| 163 gtk_widget_set_app_paintable(menu_button_, TRUE); | 158 gtk_widget_set_app_paintable(menu_button_, TRUE); |
| 164 GTK_WIDGET_UNSET_FLAGS(menu_button_, GTK_CAN_FOCUS); | 159 GTK_WIDGET_UNSET_FLAGS(menu_button_, GTK_CAN_FOCUS); |
| 165 g_signal_connect(menu_button_, "expose-event", | 160 g_signal_connect(menu_button_, "expose-event", |
| 166 G_CALLBACK(OnExposeThunk), this); | 161 G_CALLBACK(OnExposeThunk), this); |
| 167 g_signal_connect(menu_button_, "button-press-event", | 162 g_signal_connect(menu_button_, "button-press-event", |
| 168 G_CALLBACK(OnMenuButtonPressEventThunk), this); | 163 G_CALLBACK(OnMenuButtonPressEventThunk), this); |
| 169 g_object_set_data(G_OBJECT(menu_button_), "left-align-popup", | 164 g_object_set_data(G_OBJECT(menu_button_), "left-align-popup", |
| 170 reinterpret_cast<void*>(true)); | 165 reinterpret_cast<void*>(true)); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 download_complete_ = true; | 337 download_complete_ = true; |
| 343 break; | 338 break; |
| 344 case DownloadItem::IN_PROGRESS: | 339 case DownloadItem::IN_PROGRESS: |
| 345 get_download()->is_paused() ? | 340 get_download()->is_paused() ? |
| 346 StopDownloadProgress() : StartDownloadProgress(); | 341 StopDownloadProgress() : StartDownloadProgress(); |
| 347 break; | 342 break; |
| 348 default: | 343 default: |
| 349 NOTREACHED(); | 344 NOTREACHED(); |
| 350 } | 345 } |
| 351 | 346 |
| 352 // Now update the status label. We may have already removed it; if so, we | |
| 353 // do nothing. | |
| 354 if (!status_label_) { | |
| 355 return; | |
| 356 } | |
| 357 | |
| 358 status_text_ = UTF16ToUTF8(download_model_->GetStatusText()); | 347 status_text_ = UTF16ToUTF8(download_model_->GetStatusText()); |
| 359 // Remove the status text label. | |
| 360 if (status_text_.empty()) { | |
| 361 gtk_widget_destroy(status_label_); | |
| 362 return; | |
| 363 } | |
| 364 | |
| 365 UpdateStatusLabel(status_text_); | 348 UpdateStatusLabel(status_text_); |
| 366 } | 349 } |
| 367 | 350 |
| 368 void DownloadItemGtk::AnimationProgressed(const ui::Animation* animation) { | 351 void DownloadItemGtk::AnimationProgressed(const ui::Animation* animation) { |
| 369 if (animation == &complete_animation_) { | 352 if (animation == &complete_animation_) { |
| 370 gtk_widget_queue_draw(progress_area_.get()); | 353 gtk_widget_queue_draw(progress_area_.get()); |
| 371 } else { | 354 } else { |
| 372 DCHECK(animation == new_item_animation_.get()); | 355 DCHECK(animation == new_item_animation_.get()); |
| 373 if (IsDangerous()) { | 356 if (IsDangerous()) { |
| 374 int progress = static_cast<int>((dangerous_hbox_full_width_ - | 357 int progress = static_cast<int>((dangerous_hbox_full_width_ - |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 GdkColor color = theme_service_->GetGdkColor( | 474 GdkColor color = theme_service_->GetGdkColor( |
| 492 ThemeService::COLOR_BOOKMARK_TEXT); | 475 ThemeService::COLOR_BOOKMARK_TEXT); |
| 493 gtk_util::SetLabelColor( | 476 gtk_util::SetLabelColor( |
| 494 name_label_, | 477 name_label_, |
| 495 theme_service_->UsingNativeTheme() ? NULL : &color); | 478 theme_service_->UsingNativeTheme() ? NULL : &color); |
| 496 gtk_label_set_text(GTK_LABEL(name_label_), | 479 gtk_label_set_text(GTK_LABEL(name_label_), |
| 497 UTF16ToUTF8(elided_filename).c_str()); | 480 UTF16ToUTF8(elided_filename).c_str()); |
| 498 } | 481 } |
| 499 | 482 |
| 500 void DownloadItemGtk::UpdateStatusLabel(const std::string& status_text) { | 483 void DownloadItemGtk::UpdateStatusLabel(const std::string& status_text) { |
| 501 if (!status_label_) | 484 // If |status_text| is empty, only |name_label_| is displayed at the |
| 485 // vertical center of |text_stack_|. Otherwise, |name_label_| is displayed |
| 486 // on the upper half of |text_stack_| and |status_label_| is displayed |
| 487 // on the lower half of |text_stack_|. |
| 488 if (status_text.empty() && status_label_) { |
| 489 gtk_widget_destroy(status_label_); |
| 502 return; | 490 return; |
| 491 } |
| 492 if (!status_label_) { |
| 493 status_label_ = gtk_label_new(NULL); |
| 494 g_signal_connect(status_label_, "destroy", |
| 495 G_CALLBACK(gtk_widget_destroyed), &status_label_); |
| 496 // Left align and vertically center the labels. |
| 497 gtk_misc_set_alignment(GTK_MISC(status_label_), 0, 0.5); |
| 498 // Until we switch to vector graphics, force the font size. |
| 499 gtk_util::ForceFontSizePixels(status_label_, kTextSize); |
| 500 |
| 501 gtk_box_pack_start(GTK_BOX(text_stack_), status_label_, FALSE, FALSE, 0); |
| 502 gtk_widget_show_all(hbox_.get()); |
| 503 } |
| 503 | 504 |
| 504 GdkColor text_color; | 505 GdkColor text_color; |
| 505 if (!theme_service_->UsingNativeTheme()) { | 506 if (!theme_service_->UsingNativeTheme()) { |
| 506 SkColor color = theme_service_->GetColor( | 507 SkColor color = theme_service_->GetColor( |
| 507 ThemeService::COLOR_BOOKMARK_TEXT); | 508 ThemeService::COLOR_BOOKMARK_TEXT); |
| 508 if (color_utils::RelativeLuminance(color) > 0.5) { | 509 if (color_utils::RelativeLuminance(color) > 0.5) { |
| 509 color = SkColorSetRGB( | 510 color = SkColorSetRGB( |
| 510 static_cast<int>(kDownloadItemLuminanceMod * | 511 static_cast<int>(kDownloadItemLuminanceMod * |
| 511 SkColorGetR(color)), | 512 SkColorGetR(color)), |
| 512 static_cast<int>(kDownloadItemLuminanceMod * | 513 static_cast<int>(kDownloadItemLuminanceMod * |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 get_download()->OpenDownload(); | 779 get_download()->OpenDownload(); |
| 779 parent_shelf_->ItemOpened(); | 780 parent_shelf_->ItemOpened(); |
| 780 } | 781 } |
| 781 | 782 |
| 782 gboolean DownloadItemGtk::OnButtonPress(GtkWidget* button, | 783 gboolean DownloadItemGtk::OnButtonPress(GtkWidget* button, |
| 783 GdkEventButton* event) { | 784 GdkEventButton* event) { |
| 784 if (event->type == GDK_BUTTON_PRESS && event->button == 3) { | 785 if (event->type == GDK_BUTTON_PRESS && event->button == 3) { |
| 785 ShowPopupMenu(NULL, event); | 786 ShowPopupMenu(NULL, event); |
| 786 return TRUE; | 787 return TRUE; |
| 787 } | 788 } |
| 788 | |
| 789 return FALSE; | 789 return FALSE; |
| 790 } | 790 } |
| 791 | 791 |
| 792 gboolean DownloadItemGtk::OnProgressAreaExpose(GtkWidget* widget, | 792 gboolean DownloadItemGtk::OnProgressAreaExpose(GtkWidget* widget, |
| 793 GdkEventExpose* event) { | 793 GdkEventExpose* event) { |
| 794 // Create a transparent canvas. | 794 // Create a transparent canvas. |
| 795 gfx::CanvasSkiaPaint canvas(event, false); | 795 gfx::CanvasSkiaPaint canvas(event, false); |
| 796 if (complete_animation_.is_animating()) { | 796 if (complete_animation_.is_animating()) { |
| 797 if (get_download()->IsInterrupted()) { | 797 if (get_download()->IsInterrupted()) { |
| 798 download_util::PaintDownloadInterrupted(&canvas, | 798 download_util::PaintDownloadInterrupted(&canvas, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 826 } | 826 } |
| 827 | 827 |
| 828 gboolean DownloadItemGtk::OnMenuButtonPressEvent(GtkWidget* button, | 828 gboolean DownloadItemGtk::OnMenuButtonPressEvent(GtkWidget* button, |
| 829 GdkEventButton* event) { | 829 GdkEventButton* event) { |
| 830 if (event->type == GDK_BUTTON_PRESS && event->button == 1) { | 830 if (event->type == GDK_BUTTON_PRESS && event->button == 1) { |
| 831 ShowPopupMenu(button, event); | 831 ShowPopupMenu(button, event); |
| 832 menu_showing_ = true; | 832 menu_showing_ = true; |
| 833 gtk_widget_queue_draw(button); | 833 gtk_widget_queue_draw(button); |
| 834 return TRUE; | 834 return TRUE; |
| 835 } | 835 } |
| 836 | |
| 837 return FALSE; | 836 return FALSE; |
| 838 } | 837 } |
| 839 | 838 |
| 840 void DownloadItemGtk::ShowPopupMenu(GtkWidget* button, | 839 void DownloadItemGtk::ShowPopupMenu(GtkWidget* button, |
| 841 GdkEventButton* event) { | 840 GdkEventButton* event) { |
| 842 // Stop any completion animation. | 841 // Stop any completion animation. |
| 843 if (complete_animation_.is_animating()) | 842 if (complete_animation_.is_animating()) |
| 844 complete_animation_.End(); | 843 complete_animation_.End(); |
| 845 | 844 |
| 846 if (!menu_.get()) | 845 if (!menu_.get()) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 863 get_download()->DangerousDownloadValidated(); | 862 get_download()->DangerousDownloadValidated(); |
| 864 } | 863 } |
| 865 | 864 |
| 866 void DownloadItemGtk::OnDangerousDecline(GtkWidget* button) { | 865 void DownloadItemGtk::OnDangerousDecline(GtkWidget* button) { |
| 867 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", | 866 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", |
| 868 base::Time::Now() - creation_time_); | 867 base::Time::Now() - creation_time_); |
| 869 if (get_download()->IsPartialDownload()) | 868 if (get_download()->IsPartialDownload()) |
| 870 get_download()->Cancel(true); | 869 get_download()->Cancel(true); |
| 871 get_download()->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | 870 get_download()->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
| 872 } | 871 } |
| OLD | NEW |