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 17class 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 73ConstrainedHtmlDelegateMac::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 114HtmlDialogUIDelegate* ConstrainedHtmlDelegateMac::GetHtmlDialogUIDelegate() { 115 return html_delegate_; 116} 117 118void ConstrainedHtmlDelegateMac::OnDialogClose() { 119 DCHECK(constrained_window_); 120 if (constrained_window_) 121 constrained_window_->CloseConstrainedWindow(); 122} 123 124// static 125ConstrainedWindow* 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