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/cocoa/tab_modal_confirm_dialog_mac.h"
6
7#include "base/mac/scoped_nsobject.h"
8#include "chrome/browser/ui/browser_dialogs.h"
9#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h"
10#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
11#import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
12#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
13#include "chrome/common/chrome_switches.h"
14#include "ui/base/cocoa/cocoa_base_utils.h"
15#include "ui/base/l10n/l10n_util_mac.h"
16#include "ui/gfx/image/image.h"
17
18// static
19TabModalConfirmDialog* TabModalConfirmDialog::Create(
20    TabModalConfirmDialogDelegate* delegate,
21    content::WebContents* web_contents) {
22  // Deletes itself when closed.
23  return new TabModalConfirmDialogMac(delegate, web_contents);
24}
25
26@interface TabModalConfirmDialogMacBridge : NSObject {
27  TabModalConfirmDialogDelegate* delegate_;  // weak
28}
29@end
30
31@implementation TabModalConfirmDialogMacBridge
32
33- (id)initWithDelegate:(TabModalConfirmDialogDelegate*)delegate {
34  if ((self = [super init])) {
35    delegate_ = delegate;
36    DCHECK(delegate_);
37  }
38  return self;
39}
40
41- (void)onAcceptButton:(id)sender {
42  delegate_->Accept();
43}
44
45- (void)onCancelButton:(id)sender {
46  delegate_->Cancel();
47}
48
49- (void)onLinkClicked:(id)sender {
50  WindowOpenDisposition disposition =
51      ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
52  delegate_->LinkClicked(disposition);
53}
54
55@end
56
57TabModalConfirmDialogMac::TabModalConfirmDialogMac(
58    TabModalConfirmDialogDelegate* delegate,
59    content::WebContents* web_contents)
60    : closing_(false),
61      delegate_(delegate) {
62  bridge_.reset([[TabModalConfirmDialogMacBridge alloc]
63      initWithDelegate:delegate]);
64
65  alert_.reset([[ConstrainedWindowAlert alloc] init]);
66  [alert_ setMessageText:
67      l10n_util::FixUpWindowsStyleLabel(delegate->GetTitle())];
68  [alert_ setLinkText:l10n_util::FixUpWindowsStyleLabel(
69                          delegate->GetLinkText())
70               target:bridge_
71               action:@selector(onLinkClicked:)];
72  [alert_ setInformativeText:
73      l10n_util::FixUpWindowsStyleLabel(delegate->GetDialogMessage())];
74  [alert_ addButtonWithTitle:
75      l10n_util::FixUpWindowsStyleLabel(delegate->GetAcceptButtonTitle())
76              keyEquivalent:kKeyEquivalentReturn
77                     target:bridge_
78                     action:@selector(onAcceptButton:)];
79  [alert_ addButtonWithTitle:
80      l10n_util::FixUpWindowsStyleLabel(delegate->GetCancelButtonTitle())
81              keyEquivalent:kKeyEquivalentEscape
82                     target:bridge_
83                     action:@selector(onCancelButton:)];
84  [[alert_ closeButton] setTarget:bridge_];
85  [[alert_ closeButton] setAction:@selector(onCancelButton:)];
86  [alert_ layout];
87
88  base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
89      [[CustomConstrainedWindowSheet alloc]
90          initWithCustomWindow:[alert_ window]]);
91  window_.reset(new ConstrainedWindowMac(this, web_contents, sheet));
92  delegate_->set_close_delegate(this);
93}
94
95TabModalConfirmDialogMac::~TabModalConfirmDialogMac() {
96}
97
98void TabModalConfirmDialogMac::AcceptTabModalDialog() {
99  delegate_->Accept();
100}
101
102void TabModalConfirmDialogMac::CancelTabModalDialog() {
103  delegate_->Cancel();
104}
105
106void TabModalConfirmDialogMac::CloseDialog() {
107  if (!closing_) {
108    closing_ = true;
109    window_->CloseWebContentsModalDialog();
110  }
111}
112
113void TabModalConfirmDialogMac::OnConstrainedWindowClosed(
114    ConstrainedWindowMac* window) {
115  // If this method should mistakenly be called during Delegate::Close(),
116  // prevent a double-delete by moving delegate_ to a stack variable.
117  if (!delegate_)
118    return;
119  scoped_ptr<TabModalConfirmDialogDelegate> delegate(delegate_.Pass());
120  // Provide a disposition in case the dialog was closed without accepting or
121  // cancelling.
122  delegate->Close();
123  delete this;
124}
125