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