Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / passwords / manage_passwords_bubble_pending_view_controller.mm
1 // Copyright 2014 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 <algorithm>
6
7 #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_pending_view_controller.h"
8
9 #include "base/strings/sys_string_conversions.h"
10 #import "chrome/browser/ui/cocoa/bubble_combobox.h"
11 #import "chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
13 #include "chrome/browser/ui/passwords/save_password_refusal_combobox_model.h"
14 #include "chrome/grit/generated_resources.h"
15 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/models/combobox_model.h"
18
19 using namespace password_manager::mac::ui;
20
21 @interface ManagePasswordsBubblePendingViewController ()
22 - (void)onSaveClicked:(id)sender;
23 - (void)onNopeClicked:(id)sender;
24 - (void)onNeverForThisSiteClicked:(id)sender;
25 @end
26
27 @implementation ManagePasswordsBubblePendingViewController
28
29 - (id)initWithModel:(ManagePasswordsBubbleModel*)model
30            delegate:(id<ManagePasswordsBubblePendingViewDelegate>)delegate {
31   if ((self = [super initWithNibName:nil bundle:nil])) {
32     model_ = model;
33     delegate_ = delegate;
34   }
35   return self;
36 }
37
38 - (void)bubbleWillDisappear {
39   // The "nope" drop-down won't be dismissed until the user chooses an option,
40   // but if the bubble is dismissed (by cross-platform code) before the user
41   // makes a choice, then the choice won't actually take any effect.
42   [[nopeButton_ menu] cancelTrackingWithoutAnimation];
43 }
44
45 - (void)onSaveClicked:(id)sender {
46   model_->OnSaveClicked();
47   [delegate_ viewShouldDismiss];
48 }
49
50 - (void)onNopeClicked:(id)sender {
51   model_->OnNopeClicked();
52   [delegate_ viewShouldDismiss];
53 }
54
55 - (void)onNeverForThisSiteClicked:(id)sender {
56   if (model_->best_matches().empty()) {
57     // Skip confirmation if there are no existing passwords for this site.
58     model_->OnNeverForThisSiteClicked();
59     [delegate_ viewShouldDismiss];
60   } else {
61     [delegate_ passwordShouldNeverBeSavedOnSiteWithExistingPasswords];
62   }
63 }
64
65 - (void)loadView {
66   self.view = [[[NSView alloc] initWithFrame:NSZeroRect] autorelease];
67
68   // -----------------------------------
69   // |  Title                          |
70   // |  -----------------------------  | (1 px border)
71   // |    username   password          |
72   // |  -----------------------------  | (1 px border)
73   // |                [Save] [Nope v]  |
74   // -----------------------------------
75
76   // The bubble should be wide enough to fit the title row, the username and
77   // password row, and the buttons row on one line each, but not smaller than
78   // kDesiredBubbleWidth.
79
80   // Create the elements and add them to the view.
81
82   // Title.
83   NSTextField* titleLabel =
84       [self addTitleLabel:base::SysUTF16ToNSString(model_->title())];
85
86   // Password item.
87   // It should be at least as wide as the box without the padding.
88   passwordItem_.reset([[ManagePasswordItemViewController alloc]
89       initWithModel:model_
90        passwordForm:model_->pending_credentials()
91            position:password_manager::ui::FIRST_ITEM]);
92   NSView* password = [passwordItem_ view];
93   [self.view addSubview:password];
94
95   // Save button.
96   saveButton_.reset(
97       [[self addButton:l10n_util::GetNSString(IDS_PASSWORD_MANAGER_SAVE_BUTTON)
98                 target:self
99                 action:@selector(onSaveClicked:)] retain]);
100
101   // Nope combobox.
102   SavePasswordRefusalComboboxModel comboboxModel;
103   nopeButton_.reset([[BubbleCombobox alloc] initWithFrame:NSZeroRect
104                                                 pullsDown:YES
105                                                     model:&comboboxModel]);
106   NSMenuItem* nopeItem =
107       [nopeButton_ itemAtIndex:SavePasswordRefusalComboboxModel::INDEX_NOPE];
108   [nopeItem setTarget:self];
109   [nopeItem setAction:@selector(onNopeClicked:)];
110   NSMenuItem* neverItem = [nopeButton_
111       itemAtIndex:SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE];
112   [neverItem setTarget:self];
113   [neverItem setAction:@selector(onNeverForThisSiteClicked:)];
114
115   // Insert a dummy row at the top and set its title to the desired title.
116   // Must be done in two steps to prevent NSPopUpButton from removing
117   // duplicates.
118   [nopeButton_ insertItemWithTitle:@"" atIndex:0];
119   [[nopeButton_ itemAtIndex:0]
120       setTitle:l10n_util::GetNSString(IDS_PASSWORD_MANAGER_CANCEL_BUTTON)];
121
122   [nopeButton_ sizeToFit];
123   [self.view addSubview:nopeButton_.get()];
124
125   // Compute the bubble width using the password item.
126   const CGFloat contentWidth =
127       kFramePadding + NSWidth([password frame]) + kFramePadding;
128   const CGFloat width = std::max(kDesiredBubbleWidth, contentWidth);
129
130   // Layout the elements, starting at the bottom and moving up.
131
132   // Buttons go on the bottom row and are right-aligned.
133   // Start with [Save].
134   CGFloat curX = width - kFramePadding - NSWidth([saveButton_ frame]);
135   CGFloat curY = kFramePadding;
136   [saveButton_ setFrameOrigin:NSMakePoint(curX, curY)];
137
138   // [Save] goes to the left of [Nope].
139   curX -= kRelatedControlHorizontalPadding + NSWidth([nopeButton_ frame]);
140   curY = kFramePadding +
141          (NSHeight([saveButton_ frame]) - NSHeight([nopeButton_ frame])) / 2.0;
142   [nopeButton_ setFrameOrigin:NSMakePoint(curX, curY)];
143
144   // Password item goes on the next row and is shifted right.
145   curX = kFramePadding;
146   curY = NSMaxY([saveButton_ frame]) + kUnrelatedControlVerticalPadding;
147   [password setFrameOrigin:NSMakePoint(curX, curY)];
148
149   // Title goes at the top after some padding.
150   curY = NSMaxY([password frame]) + kUnrelatedControlVerticalPadding;
151   [titleLabel setFrameOrigin:NSMakePoint(curX, curY)];
152
153   // Update the bubble size.
154   const CGFloat height = NSMaxY([titleLabel frame]) + kFramePadding;
155   [self.view setFrame:NSMakeRect(0, 0, width, height)];
156 }
157
158 @end
159
160 @implementation ManagePasswordsBubblePendingViewController (Testing)
161
162 - (NSButton*)saveButton {
163   return saveButton_.get();
164 }
165
166 - (BubbleCombobox*)nopeButton {
167   return nopeButton_.get();
168 }
169
170 @end