Home | History | Annotate | Download | only in cocoa
      1 // Copyright (c) 2011 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_html_ui.h"
      6 
      7 #import <Cocoa/Cocoa.h>
      8 
      9 #include "base/memory/scoped_nsobject.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/ui/cocoa/constrained_window_mac.h"
     12 #include "chrome/browser/ui/webui/html_dialog_ui.h"
     13 #include "chrome/browser/ui/webui/html_dialog_tab_contents_delegate.h"
     14 #include "content/browser/tab_contents/tab_contents.h"
     15 #include "ui/gfx/size.h"
     16 
     17 class ConstrainedHtmlDelegateMac :
     18     public ConstrainedWindowMacDelegateCustomSheet,
     19     public HtmlDialogTabContentsDelegate,
     20     public ConstrainedHtmlUIDelegate {
     21 
     22  public:
     23   ConstrainedHtmlDelegateMac(Profile* profile,
     24                              HtmlDialogUIDelegate* delegate);
     25   ~ConstrainedHtmlDelegateMac() {}
     26 
     27   // ConstrainedWindowMacDelegateCustomSheet -----------------------------------
     28   virtual void DeleteDelegate() {
     29     // From ConstrainedWindowMacDelegate: "you MUST close the sheet belonging to
     30     // your delegate in this method."
     31     if (is_sheet_open())
     32       [NSApp endSheet:sheet()];
     33     html_delegate_->OnDialogClosed("");
     34     delete this;
     35   }
     36 
     37   // ConstrainedHtmlDelegate ---------------------------------------------------
     38   virtual HtmlDialogUIDelegate* GetHtmlDialogUIDelegate();
     39   virtual void OnDialogClose();
     40 
     41   // HtmlDialogTabContentsDelegate ---------------------------------------------
     42   void MoveContents(TabContents* source, const gfx::Rect& pos) {}
     43   void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {}
     44 
     45   void set_window(ConstrainedWindow* window) {
     46     constrained_window_ = window;
     47   }
     48 
     49  private:
     50   TabContents tab_contents_;  // Holds the HTML to be displayed in the sheet.
     51   HtmlDialogUIDelegate* html_delegate_;  // weak.
     52 
     53   // The constrained window that owns |this|. Saved here because it needs to be
     54   // closed in response to the WebUI OnDialogClose callback.
     55   ConstrainedWindow* constrained_window_;
     56 
     57   DISALLOW_COPY_AND_ASSIGN(ConstrainedHtmlDelegateMac);
     58 };
     59 
     60 // The delegate used to forward events from the sheet to the constrained
     61 // window delegate. This bridge needs to be passed into the customsheet
     62 // to allow the HtmlDialog to know when the sheet closes.
     63 @interface ConstrainedHtmlDialogSheetCocoa : NSObject {
     64   ConstrainedHtmlDelegateMac* constrainedHtmlDelegate_;  // weak
     65 }
     66 - (id)initWithConstrainedHtmlDelegateMac:
     67     (ConstrainedHtmlDelegateMac*)ConstrainedHtmlDelegateMac;
     68 - (void)sheetDidEnd:(NSWindow*)sheet
     69          returnCode:(int)returnCode
     70         contextInfo:(void*)contextInfo;
     71 @end
     72 
     73 ConstrainedHtmlDelegateMac::ConstrainedHtmlDelegateMac(
     74   Profile* profile,
     75   HtmlDialogUIDelegate* delegate)
     76   : HtmlDialogTabContentsDelegate(profile),
     77     tab_contents_(profile, NULL, MSG_ROUTING_NONE, NULL, NULL),
     78     html_delegate_(delegate),
     79     constrained_window_(NULL) {
     80   tab_contents_.set_delegate(this);
     81 
     82   // Set |this| as a property on the tab contents so that the ConstrainedHtmlUI
     83   // can get a reference to |this|.
     84   ConstrainedHtmlUI::GetPropertyAccessor().SetProperty(
     85       tab_contents_.property_bag(), this);
     86 
     87   tab_contents_.controller().LoadURL(delegate->GetDialogContentURL(),
     88                                      GURL(), PageTransition::START_PAGE);
     89 
     90   // Create NSWindow to hold tab_contents in the constrained sheet:
     91   gfx::Size size;
     92   delegate->GetDialogSize(&size);
     93   NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
     94 
     95   // |window| is retained by the ConstrainedWindowMacDelegateCustomSheet when
     96   // the sheet is initialized.
     97   scoped_nsobject<NSWindow> window;
     98   window.reset(
     99       [[NSWindow alloc] initWithContentRect:frame
    100                                   styleMask:NSTitledWindowMask
    101                                     backing:NSBackingStoreBuffered
    102                                       defer:YES]);
    103 
    104   [window.get() setContentView:tab_contents_.GetNativeView()];
    105 
    106   // Set the custom sheet to point to the new window.
    107   ConstrainedWindowMacDelegateCustomSheet::init(
    108       window.get(),
    109       [[[ConstrainedHtmlDialogSheetCocoa alloc]
    110           initWithConstrainedHtmlDelegateMac:this] autorelease],
    111       @selector(sheetDidEnd:returnCode:contextInfo:));
    112 }
    113 
    114 HtmlDialogUIDelegate* ConstrainedHtmlDelegateMac::GetHtmlDialogUIDelegate() {
    115   return html_delegate_;
    116 }
    117 
    118 void ConstrainedHtmlDelegateMac::OnDialogClose() {
    119   DCHECK(constrained_window_);
    120   if (constrained_window_)
    121     constrained_window_->CloseConstrainedWindow();
    122 }
    123 
    124 // static
    125 ConstrainedWindow* ConstrainedHtmlUI::CreateConstrainedHtmlDialog(
    126     Profile* profile,
    127     HtmlDialogUIDelegate* delegate,
    128     TabContents* overshadowed) {
    129   // Deleted when ConstrainedHtmlDelegateMac::DeleteDelegate() runs.
    130   ConstrainedHtmlDelegateMac* constrained_delegate =
    131       new ConstrainedHtmlDelegateMac(profile, delegate);
    132   // Deleted when ConstrainedHtmlDelegateMac::OnDialogClose() runs.
    133   ConstrainedWindow* constrained_window =
    134       overshadowed->CreateConstrainedDialog(constrained_delegate);
    135   constrained_delegate->set_window(constrained_window);
    136   return constrained_window;
    137 }
    138 
    139 @implementation ConstrainedHtmlDialogSheetCocoa
    140 
    141 - (id)initWithConstrainedHtmlDelegateMac:
    142     (ConstrainedHtmlDelegateMac*)ConstrainedHtmlDelegateMac {
    143   if ((self = [super init]))
    144     constrainedHtmlDelegate_ = ConstrainedHtmlDelegateMac;
    145   return self;
    146 }
    147 
    148 - (void)sheetDidEnd:(NSWindow*)sheet
    149          returnCode:(int)returnCode
    150         contextInfo:(void *)contextInfo {
    151   [sheet orderOut:self];
    152 }
    153 
    154 @end
    155