Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / passwords / manage_password_item_view.cc
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 "chrome/browser/ui/views/passwords/manage_password_item_view.h"
6
7 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
8 #include "chrome/grit/generated_resources.h"
9 #include "ui/base/l10n/l10n_util.h"
10 #include "ui/base/resource/resource_bundle.h"
11 #include "ui/resources/grit/ui_resources.h"
12 #include "ui/views/border.h"
13 #include "ui/views/controls/button/button.h"
14 #include "ui/views/controls/button/image_button.h"
15 #include "ui/views/controls/label.h"
16 #include "ui/views/controls/link.h"
17 #include "ui/views/controls/link_listener.h"
18 #include "ui/views/layout/fill_layout.h"
19 #include "ui/views/layout/grid_layout.h"
20 #include "ui/views/layout/layout_constants.h"
21
22 namespace {
23
24 enum ColumnSets {
25   TWO_COLUMN_SET,
26   THREE_COLUMN_SET
27 };
28
29 void BuildColumnSet(views::GridLayout* layout, int column_set_id) {
30   views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
31
32   // The username/"Deleted!" field.
33   column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
34   column_set->AddColumn(views::GridLayout::FILL,
35                         views::GridLayout::FILL,
36                         2,
37                         views::GridLayout::USE_PREF,
38                         0,
39                         0);
40
41   // The password/"Undo!" field.
42   column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
43   column_set->AddColumn(views::GridLayout::FILL,
44                         views::GridLayout::FILL,
45                         1,
46                         views::GridLayout::USE_PREF,
47                         0,
48                         0);
49
50   // If we're in manage-mode, we need another column for the delete button.
51   if (column_set_id == THREE_COLUMN_SET) {
52     column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
53     column_set->AddColumn(views::GridLayout::TRAILING,
54                           views::GridLayout::FILL,
55                           0,
56                           views::GridLayout::USE_PREF,
57                           0,
58                           0);
59   }
60   column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
61 }
62
63 views::Label* GenerateUsernameLabel(const autofill::PasswordForm& form) {
64   views::Label* label = new views::Label(form.username_value);
65   label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
66       ui::ResourceBundle::SmallFont));
67   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
68   return label;
69 }
70
71 views::Label* GeneratePasswordLabel(const autofill::PasswordForm& form) {
72   views::Label* label = new views::Label(form.password_value);
73   label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
74       ui::ResourceBundle::SmallFont));
75   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
76   label->SetObscured(true);
77   return label;
78 }
79
80 }  // namespace
81
82 // Render credentials in two columns: username and password.
83 class ManagePasswordItemView::PendingView : public views::View {
84  public:
85   explicit PendingView(ManagePasswordItemView* parent);
86
87  private:
88   virtual ~PendingView();
89 };
90
91 ManagePasswordItemView::PendingView::PendingView(
92     ManagePasswordItemView* parent) {
93   views::GridLayout* layout = new views::GridLayout(this);
94   SetLayoutManager(layout);
95
96   BuildColumnSet(layout, TWO_COLUMN_SET);
97   layout->StartRowWithPadding(
98       0, TWO_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
99   layout->AddView(GenerateUsernameLabel(parent->password_form_));
100   layout->AddView(GeneratePasswordLabel(parent->password_form_));
101   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
102 }
103
104 ManagePasswordItemView::PendingView::~PendingView() {
105 }
106
107 // Render credentials in three columns: username, password, and delete.
108 class ManagePasswordItemView::ManageView : public views::View,
109                                            public views::ButtonListener {
110  public:
111   explicit ManageView(ManagePasswordItemView* parent);
112
113  private:
114   virtual ~ManageView();
115
116   // views::ButtonListener:
117   virtual void ButtonPressed(views::Button* sender,
118                              const ui::Event& event) OVERRIDE;
119
120   views::ImageButton* delete_button_;
121   ManagePasswordItemView* parent_;
122 };
123
124 ManagePasswordItemView::ManageView::ManageView(ManagePasswordItemView* parent)
125     : parent_(parent) {
126   views::GridLayout* layout = new views::GridLayout(this);
127   SetLayoutManager(layout);
128
129   ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
130   delete_button_ = new views::ImageButton(this);
131   delete_button_->SetImage(views::ImageButton::STATE_NORMAL,
132                            rb->GetImageNamed(IDR_CLOSE_2).ToImageSkia());
133   delete_button_->SetImage(views::ImageButton::STATE_HOVERED,
134                            rb->GetImageNamed(IDR_CLOSE_2_H).ToImageSkia());
135   delete_button_->SetImage(views::ImageButton::STATE_PRESSED,
136                            rb->GetImageNamed(IDR_CLOSE_2_P).ToImageSkia());
137
138   BuildColumnSet(layout, THREE_COLUMN_SET);
139   layout->StartRowWithPadding(
140       0, THREE_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
141   layout->AddView(GenerateUsernameLabel(parent->password_form_));
142   layout->AddView(GeneratePasswordLabel(parent->password_form_));
143   layout->AddView(delete_button_);
144   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
145 }
146
147 ManagePasswordItemView::ManageView::~ManageView() {
148 }
149
150 void ManagePasswordItemView::ManageView::ButtonPressed(views::Button* sender,
151                                                        const ui::Event& event) {
152   DCHECK_EQ(delete_button_, sender);
153   parent_->NotifyClickedDelete();
154 }
155
156 // Render a notification to the user that a password has been removed, and
157 // offer an undo link.
158 class ManagePasswordItemView::UndoView : public views::View,
159                                          public views::LinkListener {
160  public:
161   explicit UndoView(ManagePasswordItemView* parent);
162
163  private:
164   virtual ~UndoView();
165
166   // views::LinkListener:
167   virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
168
169   views::Link* undo_link_;
170   ManagePasswordItemView* parent_;
171 };
172
173 ManagePasswordItemView::UndoView::UndoView(ManagePasswordItemView* parent)
174     : parent_(parent) {
175   views::GridLayout* layout = new views::GridLayout(this);
176   SetLayoutManager(layout);
177
178   views::Label* text =
179       new views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED));
180   text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
181   text->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
182       ui::ResourceBundle::SmallFont));
183
184   undo_link_ =
185       new views::Link(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO));
186   undo_link_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
187   undo_link_->set_listener(this);
188   undo_link_->SetUnderline(false);
189   undo_link_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
190       ui::ResourceBundle::SmallFont));
191
192   BuildColumnSet(layout, TWO_COLUMN_SET);
193   layout->StartRowWithPadding(
194       0, TWO_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
195   layout->AddView(text);
196   layout->AddView(undo_link_);
197   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
198 }
199
200 ManagePasswordItemView::UndoView::~UndoView() {
201 }
202
203 void ManagePasswordItemView::UndoView::LinkClicked(views::Link* sender,
204                                                    int event_flags) {
205   DCHECK_EQ(undo_link_, sender);
206   parent_->NotifyClickedUndo();
207 }
208
209 // ManagePasswordItemView
210 ManagePasswordItemView::ManagePasswordItemView(
211     ManagePasswordsBubbleModel* manage_passwords_bubble_model,
212     const autofill::PasswordForm& password_form,
213     password_manager::ui::PasswordItemPosition position)
214     : model_(manage_passwords_bubble_model),
215       password_form_(password_form),
216       delete_password_(false) {
217   views::FillLayout* layout = new views::FillLayout();
218   SetLayoutManager(layout);
219
220   // When a password is displayed as the first item in a list, it has borders
221   // on both the top and bottom. When it's in the middle of a list, or at the
222   // end, it has a border only on the bottom.
223   SetBorder(views::Border::CreateSolidSidedBorder(
224       position == password_manager::ui::FIRST_ITEM ? 1 : 0,
225       0,
226       1,
227       0,
228       GetNativeTheme()->GetSystemColor(
229           ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor)));
230
231   if (password_manager::ui::IsPendingState(model_->state())) {
232     AddChildView(new PendingView(this));
233   } else {
234     AddChildView(new ManageView(this));
235   }
236   GetLayoutManager()->Layout(this);
237 }
238
239 ManagePasswordItemView::~ManagePasswordItemView() {
240 }
241
242 void ManagePasswordItemView::NotifyClickedDelete() {
243   delete_password_ = true;
244   Refresh();
245 }
246
247 void ManagePasswordItemView::NotifyClickedUndo() {
248   delete_password_ = false;
249   Refresh();
250 }
251
252 void ManagePasswordItemView::Refresh() {
253   DCHECK(!password_manager::ui::IsPendingState(model_->state()));
254
255   RemoveAllChildViews(true);
256   if (delete_password_)
257     AddChildView(new UndoView(this));
258   else
259     AddChildView(new ManageView(this));
260   GetLayoutManager()->Layout(this);
261
262   // After the view is consistent, notify the model that the password needs to
263   // be updated (either removed or put back into the store, as appropriate.
264   model_->OnPasswordAction(password_form_,
265                            delete_password_
266                                ? ManagePasswordsBubbleModel::REMOVE_PASSWORD
267                                : ManagePasswordsBubbleModel::ADD_PASSWORD);
268 }