Home | History | Annotate | Download | only in views
      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 "content/public/browser/native_web_keyboard_event.h"
     10 #include "content/public/browser/web_contents.h"
     11 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
     12 #include "ui/views/controls/webview/webview.h"
     13 #include "ui/views/widget/widget.h"
     14 #include "ui/views/window/dialog_delegate.h"
     15 #include "ui/web_dialogs/web_dialog_delegate.h"
     16 #include "ui/web_dialogs/web_dialog_ui.h"
     17 
     18 using ui::WebDialogDelegate;
     19 using ui::WebDialogWebContentsDelegate;
     20 
     21 namespace {
     22 
     23 class ConstrainedWebDialogDelegateViews
     24     : public ConstrainedWebDialogDelegateBase {
     25  public:
     26   ConstrainedWebDialogDelegateViews(content::BrowserContext* context,
     27                                     WebDialogDelegate* delegate,
     28                                     WebDialogWebContentsDelegate* tab_delegate,
     29                                     views::WebView* view)
     30       : ConstrainedWebDialogDelegateBase(context, delegate, tab_delegate),
     31         view_(view) {}
     32 
     33   virtual ~ConstrainedWebDialogDelegateViews() {}
     34 
     35   // WebDialogWebContentsDelegate:
     36   virtual void CloseContents(content::WebContents* source) OVERRIDE {
     37     view_->GetWidget()->Close();
     38   }
     39 
     40   // contents::WebContentsDelegate:
     41   virtual void HandleKeyboardEvent(
     42       content::WebContents* source,
     43       const content::NativeWebKeyboardEvent& event) OVERRIDE {
     44     unhandled_keyboard_event_handler_.HandleKeyboardEvent(
     45         event, view_->GetFocusManager());
     46   }
     47 
     48   // ConstrainedWebDialogDelegate:
     49   virtual web_modal::NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
     50     return view_->GetWidget()->GetNativeView();
     51   }
     52 
     53  private:
     54   // Converts keyboard events on the WebContents to accelerators.
     55   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
     56 
     57   views::WebView* view_;
     58 
     59   DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
     60 };
     61 
     62 class ConstrainedWebDialogDelegateViewViews
     63     : public views::WebView,
     64       public ConstrainedWebDialogDelegate,
     65       public views::WidgetDelegate {
     66  public:
     67   ConstrainedWebDialogDelegateViewViews(
     68       content::BrowserContext* browser_context,
     69       WebDialogDelegate* delegate,
     70       WebDialogWebContentsDelegate* tab_delegate)
     71       : views::WebView(browser_context),
     72         impl_(new ConstrainedWebDialogDelegateViews(browser_context, delegate,
     73                                                     tab_delegate, this)) {
     74     SetWebContents(GetWebContents());
     75     AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
     76   }
     77   virtual ~ConstrainedWebDialogDelegateViewViews() {}
     78 
     79   // ConstrainedWebDialogDelegate:
     80   virtual const WebDialogDelegate* GetWebDialogDelegate() const OVERRIDE {
     81     return impl_->GetWebDialogDelegate();
     82   }
     83   virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
     84     return impl_->GetWebDialogDelegate();
     85   }
     86   virtual void OnDialogCloseFromWebUI() OVERRIDE {
     87     return impl_->OnDialogCloseFromWebUI();
     88   }
     89   virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
     90     return impl_->ReleaseWebContentsOnDialogClose();
     91   }
     92   virtual web_modal::NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
     93     return impl_->GetNativeDialog();
     94   }
     95   virtual content::WebContents* GetWebContents() OVERRIDE {
     96     return impl_->GetWebContents();
     97   }
     98 
     99   // views::WidgetDelegate:
    100   virtual views::View* GetInitiallyFocusedView() OVERRIDE {
    101     return this;
    102   }
    103   virtual void WindowClosing() OVERRIDE {
    104     if (!impl_->closed_via_webui())
    105       GetWebDialogDelegate()->OnDialogClosed(std::string());
    106   }
    107   virtual views::Widget* GetWidget() OVERRIDE {
    108     return View::GetWidget();
    109   }
    110   virtual const views::Widget* GetWidget() const OVERRIDE {
    111     return View::GetWidget();
    112   }
    113   virtual base::string16 GetWindowTitle() const OVERRIDE {
    114     return impl_->closed_via_webui() ? base::string16() :
    115         GetWebDialogDelegate()->GetDialogTitle();
    116   }
    117   virtual views::View* GetContentsView() OVERRIDE {
    118     return this;
    119   }
    120   virtual views::NonClientFrameView* CreateNonClientFrameView(
    121       views::Widget* widget) OVERRIDE {
    122     return views::DialogDelegate::CreateDialogFrameView(widget);
    123   }
    124   virtual bool ShouldShowCloseButton() const OVERRIDE {
    125     // No close button if the dialog doesn't want a title bar.
    126     return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
    127   }
    128   virtual ui::ModalType GetModalType() const OVERRIDE {
    129     return ui::MODAL_TYPE_CHILD;
    130   }
    131 
    132   // views::WebView:
    133   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
    134     // Pressing ESC closes the dialog.
    135     DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
    136     GetWidget()->Close();
    137     return true;
    138   }
    139   virtual gfx::Size GetPreferredSize() const OVERRIDE {
    140     gfx::Size size;
    141     if (!impl_->closed_via_webui())
    142       GetWebDialogDelegate()->GetDialogSize(&size);
    143     return size;
    144   }
    145   virtual gfx::Size GetMinimumSize() const OVERRIDE {
    146     // Return an empty size so that we can be made smaller.
    147     return gfx::Size();
    148   }
    149 
    150  private:
    151   scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
    152 
    153   DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
    154 };
    155 
    156 }  // namespace
    157 
    158 ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
    159     content::BrowserContext* browser_context,
    160     WebDialogDelegate* delegate,
    161     WebDialogWebContentsDelegate* tab_delegate,
    162     content::WebContents* web_contents) {
    163   ConstrainedWebDialogDelegateViewViews* dialog =
    164       new ConstrainedWebDialogDelegateViewViews(
    165           browser_context, delegate, tab_delegate);
    166   ShowWebModalDialogViews(dialog, web_contents);
    167   return dialog;
    168 }
    169