12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/gtk/protocol_dialog_gtk.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/external_protocol/external_protocol_handler.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/external_protocol_dialog_delegate.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_hig_constants.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMessageWidth = 400;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExternalProtocolHandler
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalProtocolHandler::RunExternalProtocolDialog(
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, int render_process_host_id, int routing_id) {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  new ProtocolDialogGtk(scoped_ptr<const ProtocolDialogDelegate>(
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ExternalProtocolDialogDelegate(url)));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ProtocolDialogGtk
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolDialogGtk::ProtocolDialogGtk(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<const ProtocolDialogDelegate> delegate)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : delegate_(delegate.Pass()),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      creation_time_(base::TimeTicks::Now()) {
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type());
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dialog_ = gtk_dialog_new_with_buttons(
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UTF16ToUTF8(delegate_->GetTitleText()).c_str(),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_DIALOG_NO_SEPARATOR,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the response buttons.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::AddButtonToDialog(dialog_,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT).c_str(),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::AddButtonToDialog(dialog_,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT).c_str(),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the content-holding vbox.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kControlSpacing);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_set_border_width(GTK_CONTAINER(vbox),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ui::kContentAreaBorder);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the message text.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GtkWidget* label = gtk_label_new(
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UTF16ToUTF8(delegate_->GetMessageText()).c_str());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::SetLabelWidth(label, kMessageWidth);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the checkbox.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checkbox_ = gtk_check_button_new_with_label(
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UTF16ToUTF8(delegate_->GetCheckboxText()).c_str());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), checkbox_,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     FALSE, FALSE, 0);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add our vbox to the dialog.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog_));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show_all(dialog_);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolDialogGtk::~ProtocolDialogGtk() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProtocolDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool checkbox = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_id == GTK_RESPONSE_ACCEPT) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate_->DoAccept(delegate_->url(), checkbox);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url",
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::TimeTicks::Now() - creation_time_);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (response_id == GTK_RESPONSE_REJECT) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate_->DoCancel(delegate_->url(), checkbox);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the response is GTK_RESPONSE_DELETE, triggered by the user closing
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the dialog, do nothing.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_destroy(dialog_);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107