1// Copyright (c) 2013 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/ui/gtk/protocol_dialog_gtk.h" 6 7#include <gtk/gtk.h> 8 9#include <string> 10 11#include "base/message_loop/message_loop.h" 12#include "base/metrics/histogram.h" 13#include "base/strings/utf_string_conversions.h" 14#include "chrome/browser/external_protocol/external_protocol_handler.h" 15#include "chrome/browser/ui/external_protocol_dialog_delegate.h" 16#include "chrome/browser/ui/gtk/gtk_util.h" 17#include "grit/chromium_strings.h" 18#include "grit/generated_resources.h" 19#include "ui/base/gtk/gtk_hig_constants.h" 20#include "ui/base/l10n/l10n_util.h" 21 22namespace { 23 24const int kMessageWidth = 400; 25 26} // namespace 27 28/////////////////////////////////////////////////////////////////////////////// 29// ExternalProtocolHandler 30 31// static 32void ExternalProtocolHandler::RunExternalProtocolDialog( 33 const GURL& url, int render_process_host_id, int routing_id) { 34 new ProtocolDialogGtk(scoped_ptr<const ProtocolDialogDelegate>( 35 new ExternalProtocolDialogDelegate(url))); 36} 37 38/////////////////////////////////////////////////////////////////////////////// 39// ProtocolDialogGtk 40 41ProtocolDialogGtk::ProtocolDialogGtk( 42 scoped_ptr<const ProtocolDialogDelegate> delegate) 43 : delegate_(delegate.Pass()), 44 creation_time_(base::TimeTicks::Now()) { 45 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); 46 47 dialog_ = gtk_dialog_new_with_buttons( 48 UTF16ToUTF8(delegate_->GetTitleText()).c_str(), 49 NULL, 50 GTK_DIALOG_NO_SEPARATOR, 51 NULL); 52 53 // Add the response buttons. 54 gtk_util::AddButtonToDialog(dialog_, 55 l10n_util::GetStringUTF8( 56 IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT).c_str(), 57 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT); 58 gtk_util::AddButtonToDialog(dialog_, 59 l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT).c_str(), 60 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); 61 62 // Create the content-holding vbox. 63 GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kControlSpacing); 64 gtk_container_set_border_width(GTK_CONTAINER(vbox), 65 ui::kContentAreaBorder); 66 67 // Add the message text. 68 GtkWidget* label = gtk_label_new( 69 UTF16ToUTF8(delegate_->GetMessageText()).c_str()); 70 gtk_util::SetLabelWidth(label, kMessageWidth); 71 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 72 73 // Add the checkbox. 74 checkbox_ = gtk_check_button_new_with_label( 75 UTF16ToUTF8(delegate_->GetCheckboxText()).c_str()); 76 gtk_box_pack_start(GTK_BOX(vbox), checkbox_, 77 FALSE, FALSE, 0); 78 79 // Add our vbox to the dialog. 80 GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog_)); 81 gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0); 82 83 g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); 84 85 gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE); 86 gtk_widget_show_all(dialog_); 87} 88 89ProtocolDialogGtk::~ProtocolDialogGtk() { 90} 91 92void ProtocolDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { 93 bool checkbox = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_)); 94 if (response_id == GTK_RESPONSE_ACCEPT) { 95 delegate_->DoAccept(delegate_->url(), checkbox); 96 UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", 97 base::TimeTicks::Now() - creation_time_); 98 } else if (response_id == GTK_RESPONSE_REJECT) { 99 delegate_->DoCancel(delegate_->url(), checkbox); 100 } 101 // If the response is GTK_RESPONSE_DELETE, triggered by the user closing 102 // the dialog, do nothing. 103 104 gtk_widget_destroy(dialog_); 105 delete this; 106} 107