1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/gtk/web_dialog_gtk.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/ui/browser_dialogs.h"
11 #include "chrome/browser/ui/gtk/gtk_util.h"
12 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
13 #include "content/public/browser/native_web_keyboard_event.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/web_contents_view.h"
16 #include "ui/web_dialogs/web_dialog_ui.h"
18 using content::NativeWebKeyboardEvent
;
19 using content::WebContents
;
20 using content::WebUIMessageHandler
;
21 using ui::WebDialogDelegate
;
22 using ui::WebDialogUI
;
23 using ui::WebDialogWebContentsDelegate
;
27 gfx::NativeWindow
ShowWebDialog(gfx::NativeWindow parent
,
28 content::BrowserContext
* context
,
29 WebDialogDelegate
* delegate
) {
30 WebDialogGtk
* web_dialog
= new WebDialogGtk(context
, delegate
, parent
);
31 return web_dialog
->InitDialog();
38 void SetDialogStyle() {
39 static bool style_was_set
= false;
46 "style \"chrome-html-dialog\" {\n"
47 " GtkDialog::action-area-border = 0\n"
48 " GtkDialog::content-area-border = 0\n"
49 " GtkDialog::content-area-spacing = 0\n"
51 "widget \"*chrome-html-dialog\" style \"chrome-html-dialog\"");
56 ////////////////////////////////////////////////////////////////////////////////
57 // WebDialogGtk, public:
59 WebDialogGtk::WebDialogGtk(content::BrowserContext
* context
,
60 WebDialogDelegate
* delegate
,
61 gfx::NativeWindow parent_window
)
62 : WebDialogWebContentsDelegate(context
, new ChromeWebContentsHandler
),
64 parent_window_(parent_window
),
68 WebDialogGtk::~WebDialogGtk() {
71 ////////////////////////////////////////////////////////////////////////////////
72 // WebDialogDelegate implementation:
74 ui::ModalType
WebDialogGtk::GetDialogModalType() const {
75 return delegate_
? delegate_
->GetDialogModalType() : ui::MODAL_TYPE_NONE
;
78 base::string16
WebDialogGtk::GetDialogTitle() const {
79 return delegate_
? delegate_
->GetDialogTitle() : base::string16();
82 GURL
WebDialogGtk::GetDialogContentURL() const {
84 return delegate_
->GetDialogContentURL();
89 void WebDialogGtk::GetWebUIMessageHandlers(
90 std::vector
<WebUIMessageHandler
*>* handlers
) const {
92 delegate_
->GetWebUIMessageHandlers(handlers
);
97 void WebDialogGtk::GetDialogSize(gfx::Size
* size
) const {
99 delegate_
->GetDialogSize(size
);
104 void WebDialogGtk::GetMinimumDialogSize(gfx::Size
* size
) const {
106 delegate_
->GetMinimumDialogSize(size
);
111 std::string
WebDialogGtk::GetDialogArgs() const {
113 return delegate_
->GetDialogArgs();
115 return std::string();
118 void WebDialogGtk::OnDialogClosed(const std::string
& json_retval
) {
123 WebDialogDelegate
* dialog_delegate
= delegate_
;
124 delegate_
= NULL
; // We will not communicate further with the delegate.
126 // Store the dialog bounds.
127 gfx::Rect dialog_bounds
= gtk_util::GetDialogBounds(GTK_WIDGET(dialog_
));
128 dialog_delegate
->StoreDialogSize(dialog_bounds
.size());
130 dialog_delegate
->OnDialogClosed(json_retval
);
133 gtk_widget_destroy(dialog_
);
137 void WebDialogGtk::OnCloseContents(WebContents
* source
,
138 bool* out_close_dialog
) {
140 delegate_
->OnCloseContents(source
, out_close_dialog
);
143 void WebDialogGtk::CloseContents(WebContents
* source
) {
146 bool close_dialog
= false;
147 OnCloseContents(source
, &close_dialog
);
149 OnDialogClosed(std::string());
152 content::WebContents
* WebDialogGtk::OpenURLFromTab(
153 content::WebContents
* source
,
154 const content::OpenURLParams
& params
) {
155 content::WebContents
* new_contents
= NULL
;
157 delegate_
->HandleOpenURLFromTab(source
, params
, &new_contents
)) {
160 return WebDialogWebContentsDelegate::OpenURLFromTab(source
, params
);
163 void WebDialogGtk::AddNewContents(content::WebContents
* source
,
164 content::WebContents
* new_contents
,
165 WindowOpenDisposition disposition
,
166 const gfx::Rect
& initial_pos
,
169 if (delegate_
&& delegate_
->HandleAddNewContents(
170 source
, new_contents
, disposition
, initial_pos
, user_gesture
)) {
173 WebDialogWebContentsDelegate::AddNewContents(
174 source
, new_contents
, disposition
, initial_pos
, user_gesture
,
178 void WebDialogGtk::LoadingStateChanged(content::WebContents
* source
) {
180 delegate_
->OnLoadingStateChanged(source
);
183 bool WebDialogGtk::ShouldShowDialogTitle() const {
187 ////////////////////////////////////////////////////////////////////////////////
188 // content::WebContentsDelegate implementation:
190 // A simplified version of BrowserWindowGtk::HandleKeyboardEvent().
191 // We don't handle global keyboard shortcuts here, but that's fine since
192 // they're all browser-specific. (This may change in the future.)
193 void WebDialogGtk::HandleKeyboardEvent(content::WebContents
* source
,
194 const NativeWebKeyboardEvent
& event
) {
195 GdkEventKey
* os_event
= &event
.os_event
->key
;
196 if (!os_event
|| event
.type
== blink::WebInputEvent::Char
)
199 // To make sure the default key bindings can still work, such as Escape to
201 gtk_bindings_activate_event(GTK_OBJECT(dialog_
), os_event
);
204 ////////////////////////////////////////////////////////////////////////////////
207 gfx::NativeWindow
WebDialogGtk::InitDialog() {
208 web_contents_
.reset(WebContents::Create(
209 WebContents::CreateParams(browser_context())));
210 web_contents_
->SetDelegate(this);
212 // This must be done before loading the page; see the comments in
214 WebDialogUI::SetDelegate(web_contents_
.get(), this);
216 web_contents_
->GetController().LoadURL(
217 GetDialogContentURL(),
219 content::PAGE_TRANSITION_AUTO_TOPLEVEL
,
221 GtkDialogFlags flags
= GTK_DIALOG_NO_SEPARATOR
;
222 if (delegate_
->GetDialogModalType() != ui::MODAL_TYPE_NONE
)
223 flags
= static_cast<GtkDialogFlags
>(flags
| GTK_DIALOG_MODAL
);
225 dialog_
= gtk_dialog_new_with_buttons(
226 base::UTF16ToUTF8(delegate_
->GetDialogTitle()).c_str(),
232 gtk_widget_set_name(dialog_
, "chrome-html-dialog");
233 g_signal_connect(dialog_
, "response", G_CALLBACK(OnResponseThunk
), this);
235 GtkWidget
* content_area
= gtk_dialog_get_content_area(GTK_DIALOG(dialog_
));
236 gfx::NativeView web_contents_widget
=
237 web_contents_
->GetView()->GetNativeView();
238 gtk_box_pack_start(GTK_BOX(content_area
), web_contents_widget
, TRUE
, TRUE
, 0);
240 gfx::Size dialog_size
;
241 delegate_
->GetDialogSize(&dialog_size
);
242 if (!dialog_size
.IsEmpty()) {
243 gtk_window_set_default_size(GTK_WINDOW(dialog_
),
245 dialog_size
.height());
247 gfx::Size minimum_dialog_size
;
248 delegate_
->GetMinimumDialogSize(&minimum_dialog_size
);
249 if (!minimum_dialog_size
.IsEmpty()) {
250 gtk_widget_set_size_request(GTK_WIDGET(web_contents_widget
),
251 minimum_dialog_size
.width(),
252 minimum_dialog_size
.height());
255 gtk_widget_show_all(dialog_
);
257 web_contents_
->GetView()->SetInitialFocus();
259 return GTK_WINDOW(dialog_
);
262 void WebDialogGtk::OnResponse(GtkWidget
* dialog
, int response_id
) {
263 OnDialogClosed(std::string());