Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / passwords / manage_credential_item_view_controller.mm
blob62c3ff5d95c5b6014307fa7a45ca2986aff4ac71
1 // Copyright 2015 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.
5 #import "chrome/browser/ui/cocoa/passwords/manage_credential_item_view_controller.h"
7 #include <algorithm>
9 #include "base/i18n/rtl.h"
10 #include "chrome/browser/ui/chrome_style.h"
11 #import "chrome/browser/ui/cocoa/passwords/credential_item_view.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
13 #include "components/password_manager/core/common/password_manager_ui.h"
14 #include "grit/components_strings.h"
15 #include "grit/generated_resources.h"
16 #include "skia/ext/skia_utils_mac.h"
17 #import "ui/base/cocoa/controls/hyperlink_button_cell.h"
18 #import "ui/base/cocoa/hover_image_button.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/image/image.h"
22 #include "ui/resources/grit/ui_resources.h"
24 namespace {
26 // Horizontal space betweeen subviews of a credential item.
27 const CGFloat kItemSubviewsHorizontalSpacing = 20.0f;
29 // Lays out |leftSubview| and |rightSubview| within |item| so that they stick
30 // to the left and right sides of |item|, respectively, and resizes |item| to
31 // hold them. Flipped in RTL.
32 void LayOutItem(NSView* item, NSView* leftSubview, NSView* rightSubview) {
33   const CGFloat width = NSWidth([leftSubview frame]) +
34                         kItemSubviewsHorizontalSpacing +
35                         NSWidth([rightSubview frame]);
36   const CGFloat height =
37       std::max(NSHeight([leftSubview frame]), NSHeight([rightSubview frame]));
38   [item setFrameSize:NSMakeSize(width, height)];
39   [leftSubview
40       setFrameOrigin:NSMakePoint(base::i18n::IsRTL()
41                                      ? width - NSWidth([leftSubview frame])
42                                      : 0,
43                                  0)];
44   [rightSubview
45       setFrameOrigin:NSMakePoint(
46                          base::i18n::IsRTL()
47                              ? 0
48                              : width - NSWidth([rightSubview frame]),
49                          (height - NSHeight([rightSubview frame])) / 2.0f)];
50   [leftSubview setAutoresizingMask:NSViewWidthSizable |
51                                    (base::i18n::IsRTL() ? NSViewMinXMargin
52                                                         : NSViewMaxXMargin)];
53   [rightSubview setAutoresizingMask:(base::i18n::IsRTL() ? NSViewMaxXMargin
54                                                          : NSViewMinXMargin)];
56 }  // namespace
58 @implementation ManageCredentialItemView : NSView
60 - (id)initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
61                   delegate:(id<CredentialItemDelegate>)delegate
62                     target:(id)target
63                     action:(SEL)action {
64   if ((self = [super initWithFrame:NSZeroRect])) {
66     // ----------------------------------------------
67     // |      | John Q. Facebooker            |     |
68     // | icon | john@somewhere.com            |  X  |
69     // |      |                               |     |
70     // ----------------------------------------------
72     // Create the views.
73     credentialItem_.reset([[CredentialItemView alloc]
74         initWithPasswordForm:passwordForm
75               credentialType:password_manager::CredentialType::
76                                  CREDENTIAL_TYPE_PASSWORD
77                        style:password_manager_mac::CredentialItemStyle::
78                                  ACCOUNT_CHOOSER
79                     delegate:delegate]);
80     [self addSubview:credentialItem_];
82     deleteButton_.reset([[HoverImageButton alloc]
83         initWithFrame:NSMakeRect(0, 0, chrome_style::GetCloseButtonSize(),
84                                  chrome_style::GetCloseButtonSize())]);
85     [deleteButton_ setBordered:NO];
86     [[deleteButton_ cell] setHighlightsBy:NSNoCellMask];
87     ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
88     [deleteButton_
89         setDefaultImage:bundle.GetNativeImageNamed(IDR_CLOSE_2).ToNSImage()];
90     [deleteButton_
91         setHoverImage:bundle.GetNativeImageNamed(IDR_CLOSE_2_H).ToNSImage()];
92     [deleteButton_
93         setPressedImage:bundle.GetNativeImageNamed(IDR_CLOSE_2_P).ToNSImage()];
94     [deleteButton_ setTarget:target];
95     [deleteButton_ setAction:action];
96     [self addSubview:deleteButton_];
98     LayOutItem(self, credentialItem_, deleteButton_);
99   }
100   return self;
103 @end
105 @implementation DeletedCredentialItemView : NSView
106 - (id)initWithTarget:(id)target action:(SEL)action {
107   if ((self = [super initWithFrame:NSZeroRect])) {
109     // ----------------------------------------------
110     // | Such-and-such has been deleted.       [Undo]
111     // ----------------------------------------------
113     // Create the views.
114     base::scoped_nsobject<NSTextField> explanationLabel(
115         [[NSTextField alloc] initWithFrame:NSZeroRect]);
116     [explanationLabel
117         setStringValue:l10n_util::GetNSString(IDS_MANAGE_PASSWORDS_DELETED)];
118     NSFont* font = ResourceBundle::GetSharedInstance()
119                        .GetFontList(ResourceBundle::SmallFont)
120                        .GetPrimaryFont()
121                        .GetNativeFont();
122     [explanationLabel setFont:font];
123     [explanationLabel setEditable:NO];
124     [explanationLabel setSelectable:NO];
125     [explanationLabel setDrawsBackground:NO];
126     [explanationLabel setBezeled:NO];
127     [explanationLabel sizeToFit];
128     [self addSubview:explanationLabel];
130     undoButton_.reset([[NSButton alloc] initWithFrame:NSZeroRect]);
131     base::scoped_nsobject<HyperlinkButtonCell> cell([[HyperlinkButtonCell alloc]
132         initTextCell:l10n_util::GetNSString(IDS_MANAGE_PASSWORDS_UNDO)]);
133     [cell setControlSize:NSSmallControlSize];
134     [cell setShouldUnderline:NO];
135     [cell setUnderlineOnHover:NO];
136     [cell setTextColor:gfx::SkColorToCalibratedNSColor(
137           chrome_style::GetLinkColor())];
138     [undoButton_ setCell:cell.get()];
139     [undoButton_ sizeToFit];
140     [undoButton_ setTarget:target];
141     [undoButton_ setAction:action];
142     [self addSubview:undoButton_];
144     LayOutItem(self, explanationLabel, undoButton_);
145   }
146   return self;
149 @end
151 @interface ManageCredentialItemViewController()
152 - (void)deleteCredential:(id)sender;
153 - (void)undoDelete:(id)sender;
154 @end
156 @implementation ManageCredentialItemViewController
157 - (id)initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
158                      model:(ManagePasswordsBubbleModel*)model
159                   delegate:(id<CredentialItemDelegate>)delegate {
160   if ((self = [super initWithNibName:nil bundle:nil])) {
161     passwordForm_ = passwordForm;
162     model_ = model;
163     delegate_ = delegate;
164     [self changeToManageView];
165   }
166   return self;
169 - (void)performLayout {
170   [self view].subviews = @[ contentView_ ];
171   [[self view] setFrameSize:[contentView_ frame].size];
172   [contentView_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
175 - (void)loadView {
176   [self setView:[[[NSView alloc] initWithFrame:NSZeroRect] autorelease]];
177   [self performLayout];
180 - (void)deleteCredential:(id)sender {
181   model_->OnPasswordAction(passwordForm_,
182                            ManagePasswordsBubbleModel::REMOVE_PASSWORD);
183   [self changeToDeletedView];
184   [self performLayout];
187 - (void)undoDelete:(id)sender {
188   model_->OnPasswordAction(passwordForm_,
189                            ManagePasswordsBubbleModel::ADD_PASSWORD);
190   [self changeToManageView];
191   [self performLayout];
194 - (void)changeToManageView {
195   contentView_.reset([[ManageCredentialItemView alloc]
196       initWithPasswordForm:passwordForm_
197                   delegate:delegate_
198                     target:self
199                     action:@selector(deleteCredential:)]);
202 - (void)changeToDeletedView {
203   contentView_.reset([[DeletedCredentialItemView alloc]
204       initWithTarget:self
205               action:@selector(undoDelete:)]);
207 @end
209 @implementation ManageCredentialItemViewController (Testing)
211 - (const autofill::PasswordForm&)passwordForm {
212   return passwordForm_;
215 - (NSView*)contentView {
216   return contentView_.get();
219 @end