Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2011 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/html_dialog_gtk.h"
      6 
      7 #include <gtk/gtk.h>
      8 
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/ui/browser.h"
     11 #include "chrome/browser/ui/browser_dialogs.h"
     12 #include "chrome/browser/ui/browser_window.h"
     13 #include "chrome/browser/ui/gtk/gtk_util.h"
     14 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
     15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
     16 #include "chrome/browser/ui/webui/html_dialog_ui.h"
     17 #include "content/browser/tab_contents/tab_contents.h"
     18 #include "content/common/native_web_keyboard_event.h"
     19 
     20 namespace browser {
     21 
     22 gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
     23                                  HtmlDialogUIDelegate* delegate) {
     24   HtmlDialogGtk* html_dialog =
     25       new HtmlDialogGtk(profile, delegate, parent);
     26   return html_dialog->InitDialog();
     27 }
     28 
     29 } // namespace browser
     30 
     31 ////////////////////////////////////////////////////////////////////////////////
     32 // HtmlDialogGtk, public:
     33 
     34 HtmlDialogGtk::HtmlDialogGtk(Profile* profile,
     35                              HtmlDialogUIDelegate* delegate,
     36                              gfx::NativeWindow parent_window)
     37     : HtmlDialogTabContentsDelegate(profile),
     38       delegate_(delegate),
     39       parent_window_(parent_window),
     40       dialog_(NULL) {
     41 }
     42 
     43 HtmlDialogGtk::~HtmlDialogGtk() {
     44 }
     45 
     46 ////////////////////////////////////////////////////////////////////////////////
     47 // HtmlDialogUIDelegate implementation:
     48 
     49 bool HtmlDialogGtk::IsDialogModal() const {
     50   return delegate_ ? delegate_->IsDialogModal() : false;
     51 }
     52 
     53 std::wstring HtmlDialogGtk::GetDialogTitle() const {
     54   return delegate_ ? delegate_->GetDialogTitle() : L"";
     55 }
     56 
     57 GURL HtmlDialogGtk::GetDialogContentURL() const {
     58   if (delegate_)
     59     return delegate_->GetDialogContentURL();
     60   else
     61     return GURL();
     62 }
     63 
     64 void HtmlDialogGtk::GetWebUIMessageHandlers(
     65     std::vector<WebUIMessageHandler*>* handlers) const {
     66   if (delegate_)
     67     delegate_->GetWebUIMessageHandlers(handlers);
     68   else
     69     handlers->clear();
     70 }
     71 
     72 void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const {
     73   if (delegate_)
     74     delegate_->GetDialogSize(size);
     75   else
     76     *size = gfx::Size();
     77 }
     78 
     79 std::string HtmlDialogGtk::GetDialogArgs() const {
     80   if (delegate_)
     81     return delegate_->GetDialogArgs();
     82   else
     83     return std::string();
     84 }
     85 
     86 void HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) {
     87   DCHECK(dialog_);
     88 
     89   Detach();
     90   if (delegate_) {
     91     HtmlDialogUIDelegate* dialog_delegate = delegate_;
     92     delegate_ = NULL;  // We will not communicate further with the delegate.
     93     dialog_delegate->OnDialogClosed(json_retval);
     94   }
     95   gtk_widget_destroy(dialog_);
     96   delete this;
     97 }
     98 
     99 bool HtmlDialogGtk::ShouldShowDialogTitle() const {
    100   return true;
    101 }
    102 
    103 ////////////////////////////////////////////////////////////////////////////////
    104 // TabContentsDelegate implementation:
    105 
    106 void HtmlDialogGtk::MoveContents(TabContents* source, const gfx::Rect& pos) {
    107   // The contained web page wishes to resize itself. We let it do this because
    108   // if it's a dialog we know about, we trust it not to be mean to the user.
    109 }
    110 
    111 // A simplified version of BrowserWindowGtk::HandleKeyboardEvent().
    112 // We don't handle global keyboard shortcuts here, but that's fine since
    113 // they're all browser-specific. (This may change in the future.)
    114 void HtmlDialogGtk::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
    115   GdkEventKey* os_event = event.os_event;
    116   if (!os_event || event.type == WebKit::WebInputEvent::Char)
    117     return;
    118 
    119   // To make sure the default key bindings can still work, such as Escape to
    120   // close the dialog.
    121   gtk_bindings_activate_event(GTK_OBJECT(dialog_), os_event);
    122 }
    123 
    124 ////////////////////////////////////////////////////////////////////////////////
    125 // HtmlDialogGtk:
    126 
    127 gfx::NativeWindow HtmlDialogGtk::InitDialog() {
    128   tab_.reset(new TabContentsWrapper(
    129       new TabContents(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
    130   tab_->tab_contents()->set_delegate(this);
    131 
    132   // This must be done before loading the page; see the comments in
    133   // HtmlDialogUI.
    134   HtmlDialogUI::GetPropertyAccessor().SetProperty(
    135       tab_->tab_contents()->property_bag(), this);
    136 
    137   tab_->controller().LoadURL(GetDialogContentURL(),
    138                              GURL(), PageTransition::START_PAGE);
    139   GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR;
    140   if (delegate_->IsDialogModal())
    141     flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL);
    142 
    143   dialog_ = gtk_dialog_new_with_buttons(
    144       WideToUTF8(delegate_->GetDialogTitle()).c_str(),
    145       parent_window_,
    146       flags,
    147       NULL);
    148 
    149   g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
    150 
    151   tab_contents_container_.reset(new TabContentsContainerGtk(NULL));
    152   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
    153                      tab_contents_container_->widget(), TRUE, TRUE, 0);
    154 
    155   tab_contents_container_->SetTab(tab_.get());
    156 
    157   gfx::Size dialog_size;
    158   delegate_->GetDialogSize(&dialog_size);
    159 
    160   gtk_widget_set_size_request(GTK_WIDGET(tab_contents_container_->widget()),
    161                               dialog_size.width(),
    162                               dialog_size.height());
    163 
    164   gtk_widget_show_all(dialog_);
    165 
    166   return GTK_WINDOW(dialog_);
    167 }
    168 
    169 void HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
    170   OnDialogClosed(std::string());
    171 }
    172