1// Copyright 2013 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 "content/shell/browser/shell_login_dialog.h" 6 7#import <Cocoa/Cocoa.h> 8 9#include "base/logging.h" 10#include "base/mac/bundle_locations.h" 11#import "base/mac/scoped_nsobject.h" 12#include "base/strings/sys_string_conversions.h" 13#include "content/public/browser/browser_thread.h" 14#import "ui/base/cocoa/nib_loading.h" 15 16namespace { 17 18const int kUsernameFieldTag = 1; 19const int kPasswordFieldTag = 2; 20 21} // namespace 22 23// Helper object that receives the notification that the dialog/sheet is 24// going away. 25@interface ShellLoginDialogHelper : NSObject<NSAlertDelegate> { 26 @private 27 base::scoped_nsobject<NSAlert> alert_; 28 NSTextField* usernameField_; // WEAK; owned by alert_ 29 NSSecureTextField* passwordField_; // WEAK; owned by alert_ 30} 31 32- (NSAlert*)alert; 33- (NSView*)accessoryView; 34- (void)focus; 35- (void)alertDidEnd:(NSAlert*)alert 36 returnCode:(int)returnCode 37 contextInfo:(void*)contextInfo; 38- (void)cancel; 39 40@end 41 42@implementation ShellLoginDialogHelper 43 44- (NSAlert*)alert { 45 alert_.reset([[NSAlert alloc] init]); 46 [alert_ setAccessoryView:[self accessoryView]]; 47 return alert_; 48} 49 50- (NSView*)accessoryView { 51 NSView* accessory_view = ui::GetViewFromNib(@"HttpAuth"); 52 if (!accessory_view) 53 return nil; 54 55 usernameField_ = [accessory_view viewWithTag:kUsernameFieldTag]; 56 passwordField_ = [accessory_view viewWithTag:kPasswordFieldTag]; 57 return accessory_view; 58} 59 60- (void)focus { 61 [[alert_ window] makeFirstResponder:usernameField_]; 62} 63 64- (void)alertDidEnd:(NSAlert*)alert 65 returnCode:(int)returnCode 66 contextInfo:(void*)contextInfo { 67 if (returnCode == NSRunStoppedResponse) 68 return; 69 70 content::ShellLoginDialog* this_dialog = 71 reinterpret_cast<content::ShellLoginDialog*>(contextInfo); 72 if (returnCode == NSAlertFirstButtonReturn) { 73 this_dialog->UserAcceptedAuth( 74 base::SysNSStringToUTF16([usernameField_ stringValue]), 75 base::SysNSStringToUTF16([passwordField_ stringValue])); 76 } else { 77 this_dialog->UserCancelledAuth(); 78 } 79} 80 81- (void)cancel { 82 [NSApp endSheet:[alert_ window]]; 83 alert_.reset(); 84} 85 86@end 87 88namespace content { 89 90void ShellLoginDialog::PlatformCreateDialog(const base::string16& message) { 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 92 helper_ = [[ShellLoginDialogHelper alloc] init]; 93 94 // Show the modal dialog. 95 NSAlert* alert = [helper_ alert]; 96 [alert setDelegate:helper_]; 97 [alert setInformativeText:base::SysUTF16ToNSString(message)]; 98 [alert setMessageText:@"Please log in."]; 99 [alert addButtonWithTitle:@"OK"]; 100 NSButton* other = [alert addButtonWithTitle:@"Cancel"]; 101 [other setKeyEquivalent:@"\e"]; 102 [alert 103 beginSheetModalForWindow:nil // nil here makes it app-modal 104 modalDelegate:helper_ 105 didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) 106 contextInfo:this]; 107 108 [helper_ focus]; 109} 110 111void ShellLoginDialog::PlatformCleanUp() { 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 113 [helper_ release]; 114 helper_ = nil; 115} 116 117void ShellLoginDialog::PlatformRequestCancelled() { 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 119 [helper_ cancel]; 120} 121 122} // namespace content 123