172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/html_dialog_gtk.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser_dialogs.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/html_dialog_ui.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/native_web_keyboard_event.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace browser { 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsengfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile, 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HtmlDialogUIDelegate* delegate) { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HtmlDialogGtk* html_dialog = 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HtmlDialogGtk(profile, delegate, parent); 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return html_dialog->InitDialog(); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} // namespace browser 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HtmlDialogGtk, public: 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHtmlDialogGtk::HtmlDialogGtk(Profile* profile, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HtmlDialogUIDelegate* delegate, 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::NativeWindow parent_window) 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : HtmlDialogTabContentsDelegate(profile), 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_(delegate), 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parent_window_(parent_window), 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_(NULL) { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHtmlDialogGtk::~HtmlDialogGtk() { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HtmlDialogUIDelegate implementation: 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HtmlDialogGtk::IsDialogModal() const { 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate_ ? delegate_->IsDialogModal() : false; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring HtmlDialogGtk::GetDialogTitle() const { 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate_ ? delegate_->GetDialogTitle() : L""; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL HtmlDialogGtk::GetDialogContentURL() const { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate_) 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate_->GetDialogContentURL(); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid HtmlDialogGtk::GetWebUIMessageHandlers( 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<WebUIMessageHandler*>* handlers) const { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate_) 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delegate_->GetWebUIMessageHandlers(handlers); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handlers->clear(); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HtmlDialogGtk::GetDialogSize(gfx::Size* size) const { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate_) 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_->GetDialogSize(size); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *size = gfx::Size(); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string HtmlDialogGtk::GetDialogArgs() const { 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate_) 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate_->GetDialogArgs(); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(dialog_); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Detach(); 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (delegate_) { 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HtmlDialogUIDelegate* dialog_delegate = delegate_; 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delegate_ = NULL; // We will not communicate further with the delegate. 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick dialog_delegate->OnDialogClosed(json_retval); 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_destroy(dialog_); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool HtmlDialogGtk::ShouldShowDialogTitle() const { 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TabContentsDelegate implementation: 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HtmlDialogGtk::MoveContents(TabContents* source, const gfx::Rect& pos) { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The contained web page wishes to resize itself. We let it do this because 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // if it's a dialog we know about, we trust it not to be mean to the user. 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A simplified version of BrowserWindowGtk::HandleKeyboardEvent(). 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We don't handle global keyboard shortcuts here, but that's fine since 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// they're all browser-specific. (This may change in the future.) 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HtmlDialogGtk::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventKey* os_event = event.os_event; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!os_event || event.type == WebKit::WebInputEvent::Char) 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To make sure the default key bindings can still work, such as Escape to 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // close the dialog. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_bindings_activate_event(GTK_OBJECT(dialog_), os_event); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HtmlDialogGtk: 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsengfx::NativeWindow HtmlDialogGtk::InitDialog() { 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tab_.reset(new TabContentsWrapper( 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new TabContents(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL))); 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tab_->tab_contents()->set_delegate(this); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This must be done before loading the page; see the comments in 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HtmlDialogUI. 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HtmlDialogUI::GetPropertyAccessor().SetProperty( 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tab_->tab_contents()->property_bag(), this); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tab_->controller().LoadURL(GetDialogContentURL(), 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL(), PageTransition::START_PAGE); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate_->IsDialogModal()) 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_ = gtk_dialog_new_with_buttons( 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WideToUTF8(delegate_->GetDialogTitle()).c_str(), 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parent_window_, 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch flags, 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_container_.reset(new TabContentsContainerGtk(NULL)); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_container_->widget(), TRUE, TRUE, 0); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tab_contents_container_->SetTab(tab_.get()); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size dialog_size; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_->GetDialogSize(&dialog_size); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(GTK_WIDGET(tab_contents_container_->widget()), 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_size.width(), 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_size.height()); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(dialog_); 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return GTK_WINDOW(dialog_); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OnDialogClosed(std::string()); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 172