// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/gtk/html_dialog_gtk.h"
#include <gtk/gtk.h>
#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/native_web_keyboard_event.h"
namespace browser {
gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
HtmlDialogUIDelegate* delegate) {
HtmlDialogGtk* html_dialog =
new HtmlDialogGtk(profile, delegate, parent);
return html_dialog->InitDialog();
}
} // namespace browser
////////////////////////////////////////////////////////////////////////////////
// HtmlDialogGtk, public:
HtmlDialogGtk::HtmlDialogGtk(Profile* profile,
HtmlDialogUIDelegate* delegate,
gfx::NativeWindow parent_window)
: HtmlDialogTabContentsDelegate(profile),
delegate_(delegate),
parent_window_(parent_window),
dialog_(NULL) {
}
HtmlDialogGtk::~HtmlDialogGtk() {
}
////////////////////////////////////////////////////////////////////////////////
// HtmlDialogUIDelegate implementation:
bool HtmlDialogGtk::IsDialogModal() const {
return delegate_ ? delegate_->IsDialogModal() : false;
}
std::wstring HtmlDialogGtk::GetDialogTitle() const {
return delegate_ ? delegate_->GetDialogTitle() : L"";
}
GURL HtmlDialogGtk::GetDialogContentURL() const {
if (delegate_)
return delegate_->GetDialogContentURL();
else
return GURL();
}
void HtmlDialogGtk::GetWebUIMessageHandlers(
std::vector<WebUIMessageHandler*>* handlers) const {
if (delegate_)
delegate_->GetWebUIMessageHandlers(handlers);
else
handlers->clear();
}
void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const {
if (delegate_)
delegate_->GetDialogSize(size);
else
*size = gfx::Size();
}
std::string HtmlDialogGtk::GetDialogArgs() const {
if (delegate_)
return delegate_->GetDialogArgs();
else
return std::string();
}
void HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) {
DCHECK(dialog_);
Detach();
if (delegate_) {
HtmlDialogUIDelegate* dialog_delegate = delegate_;
delegate_ = NULL; // We will not communicate further with the delegate.
dialog_delegate->OnDialogClosed(json_retval);
}
gtk_widget_destroy(dialog_);
delete this;
}
bool HtmlDialogGtk::ShouldShowDialogTitle() const {
return true;
}
////////////////////////////////////////////////////////////////////////////////
// TabContentsDelegate implementation:
void HtmlDialogGtk::MoveContents(TabContents* source, const gfx::Rect& pos) {
// The contained web page wishes to resize itself. We let it do this because
// if it's a dialog we know about, we trust it not to be mean to the user.
}
// A simplified version of BrowserWindowGtk::HandleKeyboardEvent().
// We don't handle global keyboard shortcuts here, but that's fine since
// they're all browser-specific. (This may change in the future.)
void HtmlDialogGtk::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
GdkEventKey* os_event = event.os_event;
if (!os_event || event.type == WebKit::WebInputEvent::Char)
return;
// To make sure the default key bindings can still work, such as Escape to
// close the dialog.
gtk_bindings_activate_event(GTK_OBJECT(dialog_), os_event);
}
////////////////////////////////////////////////////////////////////////////////
// HtmlDialogGtk:
gfx::NativeWindow HtmlDialogGtk::InitDialog() {
tab_.reset(new TabContentsWrapper(
new TabContents(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
tab_->tab_contents()->set_delegate(this);
// This must be done before loading the page; see the comments in
// HtmlDialogUI.
HtmlDialogUI::GetPropertyAccessor().SetProperty(
tab_->tab_contents()->property_bag(), this);
tab_->controller().LoadURL(GetDialogContentURL(),
GURL(), PageTransition::START_PAGE);
GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR;
if (delegate_->IsDialogModal())
flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL);
dialog_ = gtk_dialog_new_with_buttons(
WideToUTF8(delegate_->GetDialogTitle()).c_str(),
parent_window_,
flags,
NULL);
g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
tab_contents_container_.reset(new TabContentsContainerGtk(NULL));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
tab_contents_container_->widget(), TRUE, TRUE, 0);
tab_contents_container_->SetTab(tab_.get());
gfx::Size dialog_size;
delegate_->GetDialogSize(&dialog_size);
gtk_widget_set_size_request(GTK_WIDGET(tab_contents_container_->widget()),
dialog_size.width(),
dialog_size.height());
gtk_widget_show_all(dialog_);
return GTK_WINDOW(dialog_);
}
void HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
OnDialogClosed(std::string());
}