c3042b08abe9e370f230a2dc79eb5c9bb9e1b71c
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / constrained_web_dialog_delegate_views.cc
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/webui/constrained_web_dialog_delegate_base.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "components/web_modal/web_contents_modal_dialog_host.h"
9 #include "components/web_modal/web_contents_modal_dialog_manager.h"
10 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
11 #include "content/public/browser/native_web_keyboard_event.h"
12 #include "content/public/browser/web_contents.h"
13 #include "ui/gfx/size.h"
14 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
15 #include "ui/views/controls/webview/webview.h"
16 #include "ui/views/view.h"
17 #include "ui/views/widget/widget.h"
18 #include "ui/views/widget/widget_delegate.h"
19 #include "ui/views/window/dialog_delegate.h"
20 #include "ui/web_dialogs/web_dialog_delegate.h"
21 #include "ui/web_dialogs/web_dialog_ui.h"
22
23 using content::WebContents;
24 using ui::WebDialogDelegate;
25 using ui::WebDialogWebContentsDelegate;
26 using web_modal::NativeWebContentsModalDialog;
27 using web_modal::WebContentsModalDialogManager;
28 using web_modal::WebContentsModalDialogManagerDelegate;
29
30 namespace {
31
32 class ConstrainedWebDialogDelegateViews
33     : public ConstrainedWebDialogDelegateBase {
34  public:
35   ConstrainedWebDialogDelegateViews(content::BrowserContext* browser_context,
36                                     WebDialogDelegate* delegate,
37                                     WebDialogWebContentsDelegate* tab_delegate,
38                                     views::WebView* view)
39       : ConstrainedWebDialogDelegateBase(
40             browser_context, delegate, tab_delegate),
41         view_(view),
42         window_(NULL) {}
43
44   virtual ~ConstrainedWebDialogDelegateViews() {}
45
46   // WebDialogWebContentsDelegate interface.
47   virtual void CloseContents(WebContents* source) OVERRIDE {
48     window_->Close();
49   }
50
51   // contents::WebContentsDelegate
52   virtual void HandleKeyboardEvent(
53       content::WebContents* source,
54       const content::NativeWebKeyboardEvent& event) OVERRIDE {
55     unhandled_keyboard_event_handler_.HandleKeyboardEvent(
56         event, view_->GetFocusManager());
57   }
58
59   // ConstrainedWebDialogDelegate
60   virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
61     return window_->GetNativeView();
62   }
63
64   void set_window(views::Widget* window) { window_ = window; }
65   views::Widget* window() const { return window_; }
66
67  private:
68   // Converts keyboard events on the WebContents to accelerators.
69   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
70
71   views::WebView* view_;
72   views::Widget* window_;
73
74   DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
75 };
76
77 }  // namespace
78
79 class ConstrainedWebDialogDelegateViewViews
80     : public views::WebView,
81       public ConstrainedWebDialogDelegate,
82       public views::WidgetDelegate {
83  public:
84   ConstrainedWebDialogDelegateViewViews(
85       content::BrowserContext* browser_context,
86       WebDialogDelegate* delegate,
87       WebDialogWebContentsDelegate* tab_delegate);
88   virtual ~ConstrainedWebDialogDelegateViewViews();
89
90   // ConstrainedWebDialogDelegate interface
91   virtual const WebDialogDelegate* GetWebDialogDelegate() const OVERRIDE {
92     return impl_->GetWebDialogDelegate();
93   }
94   virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
95     return impl_->GetWebDialogDelegate();
96   }
97   virtual void OnDialogCloseFromWebUI() OVERRIDE {
98     return impl_->OnDialogCloseFromWebUI();
99   }
100   virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
101     return impl_->ReleaseWebContentsOnDialogClose();
102   }
103   virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
104     return impl_->window()->GetNativeView();
105   }
106   virtual WebContents* GetWebContents() OVERRIDE {
107     return impl_->GetWebContents();
108   }
109
110   // views::WidgetDelegate interface.
111   virtual views::View* GetInitiallyFocusedView() OVERRIDE {
112     return this;
113   }
114   virtual void WindowClosing() OVERRIDE {
115     if (!impl_->closed_via_webui())
116       GetWebDialogDelegate()->OnDialogClosed(std::string());
117   }
118   virtual views::Widget* GetWidget() OVERRIDE {
119     return View::GetWidget();
120   }
121   virtual const views::Widget* GetWidget() const OVERRIDE {
122     return View::GetWidget();
123   }
124   virtual base::string16 GetWindowTitle() const OVERRIDE {
125     return impl_->closed_via_webui() ? base::string16() :
126         GetWebDialogDelegate()->GetDialogTitle();
127   }
128   virtual views::View* GetContentsView() OVERRIDE {
129     return this;
130   }
131   virtual views::NonClientFrameView* CreateNonClientFrameView(
132       views::Widget* widget) OVERRIDE {
133     return views::DialogDelegate::CreateDialogFrameView(widget);
134   }
135   virtual bool ShouldShowCloseButton() const OVERRIDE {
136     // No close button if the dialog doesn't want a title bar.
137     return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
138   }
139
140   virtual ui::ModalType GetModalType() const OVERRIDE {
141 #if defined(USE_ASH)
142     return ui::MODAL_TYPE_CHILD;
143 #else
144     return views::WidgetDelegate::GetModalType();
145 #endif
146   }
147
148   // views::WebView overrides.
149   virtual bool AcceleratorPressed(
150       const ui::Accelerator& accelerator) OVERRIDE {
151     // Pressing ESC closes the dialog.
152     DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
153     impl_->window()->Close();
154     return true;
155   }
156   virtual gfx::Size GetPreferredSize() OVERRIDE {
157     gfx::Size size;
158     if (!impl_->closed_via_webui())
159       GetWebDialogDelegate()->GetDialogSize(&size);
160     return size;
161   }
162   virtual gfx::Size GetMinimumSize() OVERRIDE {
163     // Return an empty size so that we can be made smaller.
164     return gfx::Size();
165   }
166
167   void SetWindow(views::Widget* window) {
168     impl_->set_window(window);
169   }
170
171   views::Widget* GetWindow() {
172     return impl_->window();
173   }
174
175  private:
176   scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
177
178   DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
179 };
180
181 ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
182     content::BrowserContext* browser_context,
183     WebDialogDelegate* delegate,
184     WebDialogWebContentsDelegate* tab_delegate)
185     : views::WebView(browser_context),
186       impl_(new ConstrainedWebDialogDelegateViews(browser_context,
187                                                   delegate,
188                                                   tab_delegate,
189                                                   this)) {
190   SetWebContents(GetWebContents());
191
192   // Pressing ESC closes the dialog.
193   AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
194 }
195
196 ConstrainedWebDialogDelegateViewViews::
197 ~ConstrainedWebDialogDelegateViewViews() {
198 }
199
200 ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
201     content::BrowserContext* browser_context,
202     WebDialogDelegate* delegate,
203     WebDialogWebContentsDelegate* tab_delegate,
204     content::WebContents* web_contents) {
205   ConstrainedWebDialogDelegateViewViews* constrained_delegate =
206       new ConstrainedWebDialogDelegateViewViews(
207           browser_context, delegate, tab_delegate);
208   WebContentsModalDialogManager* web_contents_modal_dialog_manager =
209       WebContentsModalDialogManager::FromWebContents(web_contents);
210   WebContentsModalDialogManagerDelegate* modal_delegate =
211       web_contents_modal_dialog_manager->delegate();
212   DCHECK(modal_delegate);
213   views::Widget* window = views::Widget::CreateWindowAsFramelessChild(
214       constrained_delegate,
215       modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
216   web_contents_modal_dialog_manager->ShowModalDialog(
217       window->GetNativeView());
218   constrained_delegate->SetWindow(window);
219   return constrained_delegate;
220 }