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 20namespace browser { 21 22gfx::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 34HtmlDialogGtk::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 43HtmlDialogGtk::~HtmlDialogGtk() { 44} 45 46//////////////////////////////////////////////////////////////////////////////// 47// HtmlDialogUIDelegate implementation: 48 49bool HtmlDialogGtk::IsDialogModal() const { 50 return delegate_ ? delegate_->IsDialogModal() : false; 51} 52 53std::wstring HtmlDialogGtk::GetDialogTitle() const { 54 return delegate_ ? delegate_->GetDialogTitle() : L""; 55} 56 57GURL HtmlDialogGtk::GetDialogContentURL() const { 58 if (delegate_) 59 return delegate_->GetDialogContentURL(); 60 else 61 return GURL(); 62} 63 64void HtmlDialogGtk::GetWebUIMessageHandlers( 65 std::vector<WebUIMessageHandler*>* handlers) const { 66 if (delegate_) 67 delegate_->GetWebUIMessageHandlers(handlers); 68 else 69 handlers->clear(); 70} 71 72void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const { 73 if (delegate_) 74 delegate_->GetDialogSize(size); 75 else 76 *size = gfx::Size(); 77} 78 79std::string HtmlDialogGtk::GetDialogArgs() const { 80 if (delegate_) 81 return delegate_->GetDialogArgs(); 82 else 83 return std::string(); 84} 85 86void 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 99bool HtmlDialogGtk::ShouldShowDialogTitle() const { 100 return true; 101} 102 103//////////////////////////////////////////////////////////////////////////////// 104// TabContentsDelegate implementation: 105 106void 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.) 114void 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 127gfx::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 169void HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { 170 OnDialogClosed(std::string()); 171} 172