OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/ui/gtk/html_dialog_gtk.h" | |
6 | |
7 #include <gtk/gtk.h> | |
8 | |
9 #include "base/property_bag.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "chrome/browser/ui/browser.h" | |
13 #include "chrome/browser/ui/browser_dialogs.h" | |
14 #include "chrome/browser/ui/browser_window.h" | |
15 #include "chrome/browser/ui/gtk/gtk_util.h" | |
16 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" | |
17 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
18 #include "chrome/browser/ui/webui/html_dialog_controller.h" | |
19 #include "chrome/browser/ui/webui/html_dialog_ui.h" | |
20 #include "content/public/browser/web_contents.h" | |
21 #include "content/public/browser/native_web_keyboard_event.h" | |
22 | |
23 using content::WebContents; | |
24 using content::WebUIMessageHandler; | |
25 | |
26 namespace browser { | |
27 | |
28 gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, | |
29 Profile* profile, | |
30 Browser* browser, | |
31 HtmlDialogUIDelegate* delegate, | |
32 DialogStyle style) { | |
33 // Ignore style for now. The style parameter only used in the implementation | |
34 // in html_dialog_view.cc file. | |
35 // TODO (bshe): Add style parameter to HtmlDialogGtk. | |
36 HtmlDialogGtk* html_dialog = | |
37 new HtmlDialogGtk(profile, browser, delegate, parent); | |
38 return html_dialog->InitDialog(); | |
39 } | |
40 | |
41 void CloseHtmlDialog(gfx::NativeWindow window) { | |
42 gtk_dialog_response(GTK_DIALOG(window), GTK_RESPONSE_CLOSE); | |
43 } | |
44 | |
45 } // namespace browser | |
46 | |
47 namespace { | |
48 | |
49 void SetDialogStyle() { | |
50 static bool style_was_set = false; | |
51 | |
52 if (style_was_set) | |
53 return; | |
54 style_was_set = true; | |
55 | |
56 gtk_rc_parse_string( | |
57 "style \"chrome-html-dialog\" {\n" | |
58 " GtkDialog::action-area-border = 0\n" | |
59 " GtkDialog::content-area-border = 0\n" | |
60 " GtkDialog::content-area-spacing = 0\n" | |
61 "}\n" | |
62 "widget \"*chrome-html-dialog\" style \"chrome-html-dialog\""); | |
63 } | |
64 | |
65 } // namespace | |
66 | |
67 //////////////////////////////////////////////////////////////////////////////// | |
68 // HtmlDialogGtk, public: | |
69 | |
70 HtmlDialogGtk::HtmlDialogGtk(Profile* profile, | |
71 Browser* browser, | |
72 HtmlDialogUIDelegate* delegate, | |
73 gfx::NativeWindow parent_window) | |
74 : HtmlDialogTabContentsDelegate(profile), | |
75 delegate_(delegate), | |
76 parent_window_(parent_window), | |
77 dialog_(NULL), | |
78 dialog_controller_(new HtmlDialogController(this, profile, browser)) { | |
79 } | |
80 | |
81 HtmlDialogGtk::~HtmlDialogGtk() { | |
82 } | |
83 | |
84 //////////////////////////////////////////////////////////////////////////////// | |
85 // HtmlDialogUIDelegate implementation: | |
86 | |
87 ui::ModalType HtmlDialogGtk::GetDialogModalType() const { | |
88 return delegate_ ? delegate_->GetDialogModalType() : ui::MODAL_TYPE_NONE; | |
89 } | |
90 | |
91 string16 HtmlDialogGtk::GetDialogTitle() const { | |
92 return delegate_ ? delegate_->GetDialogTitle() : string16(); | |
93 } | |
94 | |
95 GURL HtmlDialogGtk::GetDialogContentURL() const { | |
96 if (delegate_) | |
97 return delegate_->GetDialogContentURL(); | |
98 else | |
99 return GURL(); | |
100 } | |
101 | |
102 void HtmlDialogGtk::GetWebUIMessageHandlers( | |
103 std::vector<WebUIMessageHandler*>* handlers) const { | |
104 if (delegate_) | |
105 delegate_->GetWebUIMessageHandlers(handlers); | |
106 else | |
107 handlers->clear(); | |
108 } | |
109 | |
110 void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const { | |
111 if (delegate_) | |
112 delegate_->GetDialogSize(size); | |
113 else | |
114 *size = gfx::Size(); | |
115 } | |
116 | |
117 void HtmlDialogGtk::GetMinimumDialogSize(gfx::Size* size) const { | |
118 if (delegate_) | |
119 delegate_->GetMinimumDialogSize(size); | |
120 else | |
121 *size = gfx::Size(); | |
122 } | |
123 | |
124 std::string HtmlDialogGtk::GetDialogArgs() const { | |
125 if (delegate_) | |
126 return delegate_->GetDialogArgs(); | |
127 else | |
128 return std::string(); | |
129 } | |
130 | |
131 void HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) { | |
132 DCHECK(dialog_); | |
133 | |
134 Detach(); | |
135 if (delegate_) { | |
136 HtmlDialogUIDelegate* dialog_delegate = delegate_; | |
137 delegate_ = NULL; // We will not communicate further with the delegate. | |
138 | |
139 // Store the dialog bounds. | |
140 gfx::Rect dialog_bounds = gtk_util::GetDialogBounds(GTK_WIDGET(dialog_)); | |
141 dialog_delegate->StoreDialogSize(dialog_bounds.size()); | |
142 | |
143 dialog_delegate->OnDialogClosed(json_retval); | |
144 } | |
145 | |
146 gtk_widget_destroy(dialog_); | |
147 delete this; | |
148 } | |
149 | |
150 void HtmlDialogGtk::OnCloseContents(WebContents* source, | |
151 bool* out_close_dialog) { | |
152 if (delegate_) | |
153 delegate_->OnCloseContents(source, out_close_dialog); | |
154 } | |
155 | |
156 void HtmlDialogGtk::CloseContents(WebContents* source) { | |
157 DCHECK(dialog_); | |
158 | |
159 bool close_dialog = false; | |
160 OnCloseContents(source, &close_dialog); | |
161 if (close_dialog) | |
162 OnDialogClosed(std::string()); | |
163 } | |
164 | |
165 content::WebContents* HtmlDialogGtk::OpenURLFromTab( | |
166 content::WebContents* source, | |
167 const content::OpenURLParams& params) { | |
168 content::WebContents* new_contents = NULL; | |
169 if (delegate_ && | |
170 delegate_->HandleOpenURLFromTab(source, params, &new_contents)) { | |
171 return new_contents; | |
172 } | |
173 return HtmlDialogTabContentsDelegate::OpenURLFromTab(source, params); | |
174 } | |
175 | |
176 void HtmlDialogGtk::AddNewContents(content::WebContents* source, | |
177 content::WebContents* new_contents, | |
178 WindowOpenDisposition disposition, | |
179 const gfx::Rect& initial_pos, | |
180 bool user_gesture) { | |
181 if (delegate_ && delegate_->HandleAddNewContents( | |
182 source, new_contents, disposition, initial_pos, user_gesture)) { | |
183 return; | |
184 } | |
185 HtmlDialogTabContentsDelegate::AddNewContents( | |
186 source, new_contents, disposition, initial_pos, user_gesture); | |
187 } | |
188 | |
189 void HtmlDialogGtk::LoadingStateChanged(content::WebContents* source) { | |
190 if (delegate_) | |
191 delegate_->OnLoadingStateChanged(source); | |
192 } | |
193 | |
194 bool HtmlDialogGtk::ShouldShowDialogTitle() const { | |
195 return true; | |
196 } | |
197 | |
198 //////////////////////////////////////////////////////////////////////////////// | |
199 // content::WebContentsDelegate implementation: | |
200 | |
201 // A simplified version of BrowserWindowGtk::HandleKeyboardEvent(). | |
202 // We don't handle global keyboard shortcuts here, but that's fine since | |
203 // they're all browser-specific. (This may change in the future.) | |
204 void HtmlDialogGtk::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { | |
205 GdkEventKey* os_event = &event.os_event->key; | |
206 if (!os_event || event.type == WebKit::WebInputEvent::Char) | |
207 return; | |
208 | |
209 // To make sure the default key bindings can still work, such as Escape to | |
210 // close the dialog. | |
211 gtk_bindings_activate_event(GTK_OBJECT(dialog_), os_event); | |
212 } | |
213 | |
214 //////////////////////////////////////////////////////////////////////////////// | |
215 // HtmlDialogGtk: | |
216 | |
217 gfx::NativeWindow HtmlDialogGtk::InitDialog() { | |
218 tab_.reset(new TabContentsWrapper( | |
219 WebContents::Create(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL))); | |
220 tab_->web_contents()->SetDelegate(this); | |
221 | |
222 // This must be done before loading the page; see the comments in | |
223 // HtmlDialogUI. | |
224 HtmlDialogUI::GetPropertyAccessor().SetProperty( | |
225 tab_->web_contents()->GetPropertyBag(), this); | |
226 | |
227 tab_->web_contents()->GetController().LoadURL( | |
228 GetDialogContentURL(), | |
229 content::Referrer(), | |
230 content::PAGE_TRANSITION_START_PAGE, | |
231 std::string()); | |
232 GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR; | |
233 if (delegate_->GetDialogModalType() != ui::MODAL_TYPE_NONE) | |
234 flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL); | |
235 | |
236 dialog_ = gtk_dialog_new_with_buttons( | |
237 UTF16ToUTF8(delegate_->GetDialogTitle()).c_str(), | |
238 parent_window_, | |
239 flags, | |
240 NULL); | |
241 | |
242 SetDialogStyle(); | |
243 gtk_widget_set_name(dialog_, "chrome-html-dialog"); | |
244 g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); | |
245 | |
246 tab_contents_container_.reset(new TabContentsContainerGtk(NULL)); | |
247 GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog_)); | |
248 gtk_box_pack_start(GTK_BOX(content_area), | |
249 tab_contents_container_->widget(), TRUE, TRUE, 0); | |
250 | |
251 tab_contents_container_->SetTab(tab_.get()); | |
252 | |
253 gfx::Size dialog_size; | |
254 delegate_->GetDialogSize(&dialog_size); | |
255 if (!dialog_size.IsEmpty()) { | |
256 gtk_window_set_default_size(GTK_WINDOW(dialog_), | |
257 dialog_size.width(), | |
258 dialog_size.height()); | |
259 } | |
260 gfx::Size minimum_dialog_size; | |
261 delegate_->GetMinimumDialogSize(&minimum_dialog_size); | |
262 if (!minimum_dialog_size.IsEmpty()) { | |
263 gtk_widget_set_size_request(GTK_WIDGET(tab_contents_container_->widget()), | |
264 minimum_dialog_size.width(), | |
265 minimum_dialog_size.height()); | |
266 } | |
267 | |
268 gtk_widget_show_all(dialog_); | |
269 | |
270 return GTK_WINDOW(dialog_); | |
271 } | |
272 | |
273 void HtmlDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { | |
274 OnDialogClosed(std::string()); | |
275 } | |
OLD | NEW |