| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/gtk/external_protocol_dialog_gtk.h" | |
| 6 | |
| 7 #include <gtk/gtk.h> | |
| 8 | |
| 9 #include <string> | |
| 10 | |
| 11 #include "app/l10n_util.h" | |
| 12 #include "app/text_elider.h" | |
| 13 #include "base/metrics/histogram.h" | |
| 14 #include "base/message_loop.h" | |
| 15 #include "base/string_util.h" | |
| 16 #include "base/utf_string_conversions.h" | |
| 17 #include "chrome/browser/external_protocol_handler.h" | |
| 18 #include "chrome/browser/gtk/gtk_util.h" | |
| 19 #include "chrome/browser/tab_contents/tab_util.h" | |
| 20 #include "grit/chromium_strings.h" | |
| 21 #include "grit/generated_resources.h" | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 const int kMessageWidth = 400; | |
| 26 | |
| 27 } // namespace | |
| 28 | |
| 29 /////////////////////////////////////////////////////////////////////////////// | |
| 30 // ExternalProtocolHandler | |
| 31 | |
| 32 // static | |
| 33 void ExternalProtocolHandler::RunExternalProtocolDialog( | |
| 34 const GURL& url, int render_process_host_id, int routing_id) { | |
| 35 new ExternalProtocolDialogGtk(url); | |
| 36 } | |
| 37 | |
| 38 /////////////////////////////////////////////////////////////////////////////// | |
| 39 // ExternalProtocolDialogGtk | |
| 40 | |
| 41 ExternalProtocolDialogGtk::ExternalProtocolDialogGtk(const GURL& url) | |
| 42 : url_(url), | |
| 43 creation_time_(base::TimeTicks::Now()) { | |
| 44 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); | |
| 45 | |
| 46 dialog_ = gtk_dialog_new_with_buttons( | |
| 47 l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_TITLE).c_str(), | |
| 48 NULL, | |
| 49 GTK_DIALOG_NO_SEPARATOR, | |
| 50 NULL); | |
| 51 | |
| 52 // Add the response buttons. | |
| 53 gtk_util::AddButtonToDialog(dialog_, | |
| 54 l10n_util::GetStringUTF8( | |
| 55 IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT).c_str(), | |
| 56 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT); | |
| 57 gtk_util::AddButtonToDialog(dialog_, | |
| 58 l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT).c_str(), | |
| 59 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); | |
| 60 | |
| 61 // Construct the message text. | |
| 62 const int kMaxUrlWithoutSchemeSize = 256; | |
| 63 const int kMaxCommandSize = 256; | |
| 64 std::wstring elided_url_without_scheme; | |
| 65 std::wstring elided_command; | |
| 66 gfx::ElideString(ASCIIToWide(url.possibly_invalid_spec()), | |
| 67 kMaxUrlWithoutSchemeSize, &elided_url_without_scheme); | |
| 68 gfx::ElideString(ASCIIToWide(std::string("xdg-open ") + url.spec()), | |
| 69 kMaxCommandSize, &elided_command); | |
| 70 | |
| 71 std::string message_text = l10n_util::GetStringFUTF8( | |
| 72 IDS_EXTERNAL_PROTOCOL_INFORMATION, | |
| 73 ASCIIToUTF16(url.scheme() + ":"), | |
| 74 WideToUTF16(elided_url_without_scheme)) + "\n\n"; | |
| 75 | |
| 76 message_text += l10n_util::GetStringFUTF8( | |
| 77 IDS_EXTERNAL_PROTOCOL_APPLICATION_TO_LAUNCH, | |
| 78 WideToUTF16(elided_command)) + "\n\n"; | |
| 79 | |
| 80 message_text += l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_WARNING); | |
| 81 | |
| 82 // Create the content-holding vbox. | |
| 83 GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); | |
| 84 gtk_container_set_border_width(GTK_CONTAINER(vbox), | |
| 85 gtk_util::kContentAreaBorder); | |
| 86 | |
| 87 // Add the message text. | |
| 88 GtkWidget* label = gtk_label_new(message_text.c_str()); | |
| 89 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
| 90 gtk_widget_set_size_request(label, kMessageWidth, -1); | |
| 91 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); | |
| 92 | |
| 93 // Add the checkbox. | |
| 94 checkbox_ = gtk_check_button_new_with_label( | |
| 95 l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_CHECKBOX_TEXT).c_str()); | |
| 96 gtk_box_pack_start(GTK_BOX(vbox), checkbox_, | |
| 97 FALSE, FALSE, 0); | |
| 98 | |
| 99 // Add our vbox to the dialog. | |
| 100 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), vbox, | |
| 101 FALSE, FALSE, 0); | |
| 102 | |
| 103 g_signal_connect(dialog_, "response", | |
| 104 G_CALLBACK(OnDialogResponseThunk), this); | |
| 105 | |
| 106 gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE); | |
| 107 gtk_widget_show_all(dialog_); | |
| 108 } | |
| 109 | |
| 110 void ExternalProtocolDialogGtk::OnDialogResponse(GtkWidget* widget, | |
| 111 int response) { | |
| 112 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_))) { | |
| 113 if (response == GTK_RESPONSE_ACCEPT) { | |
| 114 ExternalProtocolHandler::SetBlockState( | |
| 115 url_.scheme(), ExternalProtocolHandler::DONT_BLOCK); | |
| 116 } else if (response == GTK_RESPONSE_REJECT) { | |
| 117 ExternalProtocolHandler::SetBlockState( | |
| 118 url_.scheme(), ExternalProtocolHandler::BLOCK); | |
| 119 } | |
| 120 // If the response is GTK_RESPONSE_DELETE, triggered by the user closing | |
| 121 // the dialog, do nothing. | |
| 122 } | |
| 123 | |
| 124 if (response == GTK_RESPONSE_ACCEPT) { | |
| 125 UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", | |
| 126 base::TimeTicks::Now() - creation_time_); | |
| 127 | |
| 128 ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_); | |
| 129 } | |
| 130 | |
| 131 gtk_widget_destroy(dialog_); | |
| 132 delete this; | |
| 133 } | |
| OLD | NEW |