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

Unified Diff: chrome/browser/gtk/download_item_gtk.cc

Issue 113920: Dangerous download dialog for linux.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: mac uses DownloadManager? Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/gtk/download_item_gtk.h ('k') | chrome/browser/gtk/download_shelf_gtk.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/gtk/download_item_gtk.cc
===================================================================
--- chrome/browser/gtk/download_item_gtk.cc (revision 17020)
+++ chrome/browser/gtk/download_item_gtk.cc (working copy)
@@ -4,9 +4,11 @@
#include "chrome/browser/gtk/download_item_gtk.h"
+#include "app/l10n_util.h"
#include "app/gfx/canvas.h"
#include "app/gfx/font.h"
#include "app/gfx/text_elider.h"
+#include "app/resource_bundle.h"
#include "app/slide_animation.h"
#include "base/basictypes.h"
#include "base/string_util.h"
@@ -30,6 +32,9 @@
// bitmap that we use to draw it, i.e. 16, but can be more.
const int kMenuButtonWidth = 16;
+// Padding on left and right of items in dangerous download prompt.
+const int kDangerousElementPadding = 3;
+
// Amount of space we allot to showing the filename. If the filename is too wide
// it will be elided.
const int kTextWidth = 140;
@@ -39,6 +44,9 @@
// make the download item.
const int kMinDownloadItemWidth = 13 + download_util::kSmallProgressIconSize;
+// As above, but for the dangerous download prompt.
+const int kMinDangerousDownloadWidth = 16;
+
const char* kLabelColorMarkup = "<span color='#%s'>%s</span>";
const char* kFilenameColor = "576C95"; // 87, 108, 149
const char* kStatusColor = "7B8DAE"; // 123, 141, 174
@@ -155,6 +163,8 @@
NineBox* DownloadItemGtk::menu_nine_box_prelight_ = NULL;
NineBox* DownloadItemGtk::menu_nine_box_active_ = NULL;
+NineBox* DownloadItemGtk::dangerous_nine_box_ = NULL;
+
DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
BaseDownloadItemModel* download_model)
: parent_shelf_(parent_shelf),
@@ -162,6 +172,7 @@
progress_angle_(download_util::kStartAngleDegrees),
download_model_(download_model),
bounding_widget_(parent_shelf->GetRightBoundingWidget()),
+ dangerous_prompt_(NULL),
icon_(NULL) {
InitNineBoxes();
LoadIcon();
@@ -185,7 +196,7 @@
// much padding when we set the size request. We need to either use gfx::Font
// or somehow extend TextElider.
std::wstring elided_filename = gfx::ElideFilename(
- download_model_->download()->GetFileName(),
+ get_download()->GetFileName(),
gfx::Font(), kTextWidth);
gchar* label_markup =
g_markup_printf_escaped(kLabelColorMarkup, kFilenameColor,
@@ -198,8 +209,8 @@
gtk_misc_set_alignment(GTK_MISC(name_label_), 0, 0.5);
gtk_misc_set_alignment(GTK_MISC(status_label_), 0, 0.5);
// Until we switch to vector graphics, force the font size.
- gtk_util::ForceFontSizePixels(name_label_, 13.4); // 13.4px == 10pt @ 96dpi
- gtk_util::ForceFontSizePixels(status_label_, 13.4); // 13.4px == 10pt @ 96dpi
+ gtk_util::ForceFontSizePixels(name_label_, 13.4); // 13.4px == 10pt @ 96dpi
+ gtk_util::ForceFontSizePixels(status_label_, 13.4); // 13.4px == 10pt @ 96dpi
// Stack the labels on top of one another.
GtkWidget* text_stack = gtk_vbox_new(FALSE, 0);
@@ -244,11 +255,92 @@
resize_handler_id_ = g_signal_connect(G_OBJECT(shelf_hbox), "size-allocate",
G_CALLBACK(OnShelfResized), this);
- download_model_->download()->AddObserver(this);
+ get_download()->AddObserver(this);
new_item_animation_.reset(new SlideAnimation(this));
new_item_animation_->SetSlideDuration(kNewItemAnimationDurationMs);
gtk_widget_show_all(hbox_);
+
+ if (IsDangerous()) {
+ // Hide the download item components for now.
+ gtk_widget_hide(body_);
+ gtk_widget_hide(menu_button_);
+
+ // Create an hbox to hold it all.
+ dangerous_hbox_ = gtk_hbox_new(FALSE, kDangerousElementPadding);
+
+ // Add padding at the beginning and end. The hbox will add padding between
+ // the empty labels and the other elements.
+ GtkWidget* empty_label_a = gtk_label_new(NULL);
+ GtkWidget* empty_label_b = gtk_label_new(NULL);
+ gtk_box_pack_start(GTK_BOX(dangerous_hbox_), empty_label_a,
+ FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(dangerous_hbox_), empty_label_b,
+ FALSE, FALSE, 0);
+
+ // Create the warning icon.
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ GdkPixbuf* download_pixbuf = rb.GetPixbufNamed(IDR_WARNING);
+ GtkWidget* dangerous_image = gtk_image_new_from_pixbuf(download_pixbuf);
+ gtk_box_pack_start(GTK_BOX(dangerous_hbox_), dangerous_image,
+ FALSE, FALSE, 0);
+
+ // Create the warning text.
+ // TODO(estade): the encoding might not be UTF8.
+ std::string dangerous_warning =
+ l10n_util::GetStringFUTF8(IDS_PROMPT_DANGEROUS_DOWNLOAD,
+ UTF8ToUTF16(get_download()->original_name().value()));
+ gchar* label_markup =
+ g_markup_printf_escaped(kLabelColorMarkup, kFilenameColor,
+ dangerous_warning.c_str());
+ GtkWidget* dangerous_label = gtk_label_new(NULL);
+ // Until we switch to vector graphics, force the font size.
+ // 13.4px == 10pt @ 96dpi
+ gtk_util::ForceFontSizePixels(dangerous_label, 13.4);
+ gtk_label_set_markup(GTK_LABEL(dangerous_label), label_markup);
+ gtk_label_set_line_wrap(GTK_LABEL(dangerous_label), TRUE);
+ gtk_box_pack_start(GTK_BOX(dangerous_hbox_), dangerous_label,
+ FALSE, FALSE, 0);
+ g_free(label_markup);
+
+ // Create the ok button.
+ GtkWidget* dangerous_accept = gtk_button_new_with_label(
+ l10n_util::GetStringUTF8(IDS_SAVE_DOWNLOAD).c_str());
+ g_signal_connect(dangerous_accept, "clicked",
+ G_CALLBACK(OnDangerousAccept), this);
+ GtkWidget* dangerous_accept_vbox = gtk_vbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(dangerous_accept_vbox), dangerous_accept,
+ TRUE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(dangerous_hbox_), dangerous_accept_vbox,
+ FALSE, FALSE, 0);
+
+ // Create the nevermind button.
+ GtkWidget* dangerous_decline = gtk_button_new_with_label(
+ l10n_util::GetStringUTF8(IDS_DISCARD_DOWNLOAD).c_str());
+ g_signal_connect(dangerous_decline, "clicked",
+ G_CALLBACK(OnDangerousDecline), this);
+ GtkWidget* dangerous_decline_vbox = gtk_vbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(dangerous_decline_vbox), dangerous_decline,
+ TRUE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(dangerous_hbox_), dangerous_decline_vbox,
+ FALSE, FALSE, 0);
+
+ // Put it in an alignment so that padding will be added on the left and
+ // right, and an event box so that drawing will be clipped correctly.
+ dangerous_prompt_ = gtk_util::CreateGtkBorderBin(dangerous_hbox_, NULL,
+ 0, 0, kDangerousElementPadding, kDangerousElementPadding);
+ gtk_box_pack_start(GTK_BOX(hbox_), dangerous_prompt_, FALSE, FALSE, 0);
+ gtk_widget_set_app_paintable(dangerous_prompt_, TRUE);
+ g_signal_connect(dangerous_prompt_, "expose-event",
+ G_CALLBACK(OnDangerousPromptExpose), this);
+ gtk_widget_show_all(dangerous_prompt_);
+
+ // The full width will depend on the text.
+ GtkRequisition req;
+ gtk_widget_size_request(dangerous_hbox_, &req);
+ dangerous_hbox_full_width_ = req.width;
+ }
+
new_item_animation_->Show();
}
@@ -256,12 +348,20 @@
StopDownloadProgress();
g_signal_handler_disconnect(parent_shelf_->GetHBox(), resize_handler_id_);
gtk_widget_destroy(hbox_);
- download_model_->download()->RemoveObserver(this);
+ get_download()->RemoveObserver(this);
}
void DownloadItemGtk::OnDownloadUpdated(DownloadItem* download) {
- DCHECK_EQ(download, download_model_->download());
+ DCHECK_EQ(download, get_download());
+ if (dangerous_prompt_ != NULL &&
+ download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
+ // We have been approved.
+ gtk_widget_show_all(hbox_);
+ gtk_widget_destroy(dangerous_prompt_);
+ dangerous_prompt_ = NULL;
+ }
+
switch (download->state()) {
case DownloadItem::REMOVING:
parent_shelf_->RemoveDownloadItem(this); // This will delete us!
@@ -277,7 +377,7 @@
complete_animation_->Show();
break;
case DownloadItem::IN_PROGRESS:
- download_model_->download()->is_paused() ?
+ get_download()->is_paused() ?
StopDownloadProgress() : StartDownloadProgress();
break;
default:
@@ -309,17 +409,32 @@
if (animation == complete_animation_.get()) {
gtk_widget_queue_draw(progress_area_);
} else {
- DCHECK(animation == new_item_animation_.get());
- // See above TODO for explanation of the extra 50.
- int showing_width = std::max(kMinDownloadItemWidth,
- static_cast<int>((kTextWidth + 50 +
- download_util::kSmallProgressIconSize) *
- new_item_animation_->GetCurrentValue()));
- showing_width = std::max(showing_width, kMinDownloadItemWidth);
- gtk_widget_set_size_request(body_, showing_width, -1);
+ if (IsDangerous()) {
+ int showing_width = std::max(kMinDangerousDownloadWidth,
+ static_cast<int>(dangerous_hbox_full_width_ *
+ new_item_animation_->GetCurrentValue()));
+ gtk_widget_set_size_request(dangerous_hbox_, showing_width, -1);
+ } else {
+ DCHECK(animation == new_item_animation_.get());
+ // See above TODO for explanation of the extra 50.
+ int showing_width = std::max(kMinDownloadItemWidth,
+ static_cast<int>((kTextWidth + 50 +
+ download_util::kSmallProgressIconSize) *
+ new_item_animation_->GetCurrentValue()));
+ showing_width = std::max(showing_width, kMinDownloadItemWidth);
+ gtk_widget_set_size_request(body_, showing_width, -1);
+ }
}
}
+DownloadItem* DownloadItemGtk::get_download() {
+ return download_model_->download();
+}
+
+bool DownloadItemGtk::IsDangerous() {
+ return get_download()->safety_state() == DownloadItem::DANGEROUS;
+}
+
// Download progress animation functions.
void DownloadItemGtk::UpdateDownloadProgress() {
@@ -351,7 +466,7 @@
void DownloadItemGtk::LoadIcon() {
IconManager* im = g_browser_process->icon_manager();
- im->LoadIcon(download_model_->download()->full_path(),
+ im->LoadIcon(get_download()->full_path(),
IconLoader::SMALL, &icon_consumer_,
NewCallback(this, &DownloadItemGtk::OnLoadIconComplete));
}
@@ -408,6 +523,17 @@
IDR_DOWNLOAD_BUTTON_MENU_TOP_P, 0, 0,
IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P, 0, 0,
IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P, 0, 0);
+
+ dangerous_nine_box_ = new NineBox(
+ IDR_DOWNLOAD_BUTTON_LEFT_TOP,
+ IDR_DOWNLOAD_BUTTON_CENTER_TOP,
+ IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD,
+ IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE,
+ IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE,
+ IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD,
+ IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM,
+ IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM,
+ IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD);
}
// static
@@ -454,7 +580,7 @@
download_util::PaintDownloadProgress(&canvas,
widget->allocation.x, widget->allocation.y,
download_item->progress_angle_,
- download_item->download_model_->download()->PercentComplete(),
+ download_item->get_download()->PercentComplete(),
download_util::SMALL);
}
@@ -508,3 +634,26 @@
else
gtk_widget_show(item->hbox_);
}
+
+// static
+gboolean DownloadItemGtk::OnDangerousPromptExpose(GtkWidget* widget,
+ GdkEventExpose* event, DownloadItemGtk* item) {
+ dangerous_nine_box_->RenderToWidget(widget);
+ return FALSE; // Continue propagation.
+}
+
+// static
+// TODO(estade): here and below, add clickjacking histogram code.
+void DownloadItemGtk::OnDangerousAccept(GtkWidget* button,
+ DownloadItemGtk* item) {
+ item->get_download()->manager()->DangerousDownloadValidated(
+ item->get_download());
+}
+
+// static
+void DownloadItemGtk::OnDangerousDecline(GtkWidget* button,
+ DownloadItemGtk* item) {
+ if (item->get_download()->state() == DownloadItem::IN_PROGRESS)
+ item->get_download()->Cancel(true);
+ item->get_download()->Remove(true);
+}
« no previous file with comments | « chrome/browser/gtk/download_item_gtk.h ('k') | chrome/browser/gtk/download_shelf_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698