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.
5 #include "chrome/browser/ui/gtk/protocol_dialog_gtk.h"
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"
24 const int kMessageWidth
= 400;
28 ///////////////////////////////////////////////////////////////////////////////
29 // ExternalProtocolHandler
32 void 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 render_process_host_id
,
40 ///////////////////////////////////////////////////////////////////////////////
43 ProtocolDialogGtk::ProtocolDialogGtk(
44 scoped_ptr
<const ProtocolDialogDelegate
> delegate
)
45 : delegate_(delegate
.Pass()),
46 creation_time_(base::TimeTicks::Now()) {
47 DCHECK(base::MessageLoopForUI::IsCurrent());
49 dialog_
= gtk_dialog_new_with_buttons(
50 base::UTF16ToUTF8(delegate_
->GetTitleText()).c_str(),
52 GTK_DIALOG_NO_SEPARATOR
,
55 // Add the response buttons.
56 gtk_util::AddButtonToDialog(dialog_
,
57 l10n_util::GetStringUTF8(
58 IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT
).c_str(),
59 GTK_STOCK_CANCEL
, GTK_RESPONSE_REJECT
);
60 gtk_util::AddButtonToDialog(dialog_
,
61 l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT
).c_str(),
62 GTK_STOCK_OK
, GTK_RESPONSE_ACCEPT
);
64 // Create the content-holding vbox.
65 GtkWidget
* vbox
= gtk_vbox_new(FALSE
, ui::kControlSpacing
);
66 gtk_container_set_border_width(GTK_CONTAINER(vbox
),
67 ui::kContentAreaBorder
);
69 // Add the message text.
70 GtkWidget
* label
= gtk_label_new(
71 base::UTF16ToUTF8(delegate_
->GetMessageText()).c_str());
72 gtk_util::SetLabelWidth(label
, kMessageWidth
);
73 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
76 checkbox_
= gtk_check_button_new_with_label(
77 base::UTF16ToUTF8(delegate_
->GetCheckboxText()).c_str());
78 gtk_box_pack_start(GTK_BOX(vbox
), checkbox_
,
81 // Add our vbox to the dialog.
82 GtkWidget
* content_area
= gtk_dialog_get_content_area(GTK_DIALOG(dialog_
));
83 gtk_box_pack_start(GTK_BOX(content_area
), vbox
, FALSE
, FALSE
, 0);
85 g_signal_connect(dialog_
, "response", G_CALLBACK(OnResponseThunk
), this);
87 gtk_window_set_resizable(GTK_WINDOW(dialog_
), FALSE
);
88 gtk_widget_show_all(dialog_
);
91 ProtocolDialogGtk::~ProtocolDialogGtk() {
94 void ProtocolDialogGtk::OnResponse(GtkWidget
* dialog
, int response_id
) {
95 bool checkbox
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_
));
96 if (response_id
== GTK_RESPONSE_ACCEPT
) {
97 delegate_
->DoAccept(delegate_
->url(), checkbox
);
98 UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url",
99 base::TimeTicks::Now() - creation_time_
);
100 } else if (response_id
== GTK_RESPONSE_REJECT
) {
101 delegate_
->DoCancel(delegate_
->url(), checkbox
);
103 // If the response is GTK_RESPONSE_DELETE, triggered by the user closing
104 // the dialog, do nothing.
106 gtk_widget_destroy(dialog_
);