manage_password_item_view.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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 "grit/generated_resources.h" 8#include "grit/ui_resources.h" 9#include "ui/base/l10n/l10n_util.h" 10#include "ui/base/resource/resource_bundle.h" 11#include "ui/views/controls/button/button.h" 12#include "ui/views/controls/button/image_button.h" 13#include "ui/views/layout/grid_layout.h" 14#include "ui/views/layout/layout_constants.h" 15 16ManagePasswordItemView::ManagePasswordItemView( 17 ManagePasswordsBubbleModel* manage_passwords_bubble_model, 18 autofill::PasswordForm password_form, 19 int field_1_width, 20 int field_2_width) 21 : manage_passwords_bubble_model_(manage_passwords_bubble_model), 22 password_form_(password_form), 23 delete_password_(false), 24 field_1_width_(field_1_width), 25 field_2_width_(field_2_width) { 26 views::GridLayout* layout = new views::GridLayout(this); 27 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 28 SetLayoutManager(layout); 29 30 // Build the columnset we need for the current state of the model. 31 int column_set_to_build = 32 !manage_passwords_bubble_model_->WaitingToSavePassword() 33 ? COLUMN_SET_MANAGE 34 : COLUMN_SET_SAVE; 35 BuildColumnSet(layout, column_set_to_build); 36 layout->StartRowWithPadding( 37 0, column_set_to_build, 0, views::kRelatedControlVerticalSpacing); 38 39 // Add the username field: fills the first non-padding column of the layout. 40 label_1_ = new views::Label(password_form_.username_value); 41 label_1_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 42 layout->AddView(label_1_); 43 44 // Add the password field: fills the second non-padding column of the layout. 45 label_2_ = 46 new views::Link(GetPasswordDisplayString(password_form_.password_value)); 47 label_2_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 48 label_2_->set_listener(this); 49 label_2_->SetFocusable(false); 50 label_2_->SetEnabled(false); 51 label_2_->SetUnderline(false); 52 layout->AddView(label_2_); 53 54 // If we're managing passwords (that is, we're not currently in the process 55 // of saving a password), construct and add the delete button: fills the 56 // third non-padding column of the layout. 57 if (!manage_passwords_bubble_model_->WaitingToSavePassword()) { 58 delete_button_ = new views::ImageButton(this); 59 delete_button_->SetImage(views::ImageButton::STATE_NORMAL, 60 rb->GetImageNamed(IDR_CLOSE_2).ToImageSkia()); 61 delete_button_->SetImage(views::ImageButton::STATE_HOVERED, 62 rb->GetImageNamed(IDR_CLOSE_2_H).ToImageSkia()); 63 delete_button_->SetImage(views::ImageButton::STATE_PRESSED, 64 rb->GetImageNamed(IDR_CLOSE_2_P).ToImageSkia()); 65 layout->AddView(delete_button_, 1, 1); 66 } 67 68 // Match the padding at the top of the row with padding at the bottom. 69 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 70} 71 72void ManagePasswordItemView::BuildColumnSet(views::GridLayout* layout, 73 int column_set_id) { 74 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); 75 76 // The username field. 77 column_set->AddPaddingColumn(0, views::kItemLabelSpacing); 78 column_set->AddColumn(views::GridLayout::FILL, 79 views::GridLayout::FILL, 80 0, 81 views::GridLayout::FIXED, 82 field_1_width_, 83 field_1_width_); 84 85 // The password field. 86 column_set->AddPaddingColumn(0, views::kItemLabelSpacing); 87 column_set->AddColumn(views::GridLayout::FILL, 88 views::GridLayout::FILL, 89 1, 90 views::GridLayout::USE_PREF, 91 field_2_width_, 92 field_2_width_); 93 94 // If we're in manage-mode, we need another column for the delete button. 95 if (column_set_id == COLUMN_SET_MANAGE) { 96 column_set->AddColumn(views::GridLayout::TRAILING, 97 views::GridLayout::FILL, 98 0, 99 views::GridLayout::USE_PREF, 100 0, 101 0); 102 } 103 column_set->AddPaddingColumn(0, views::kItemLabelSpacing); 104} 105 106// static 107base::string16 ManagePasswordItemView::GetPasswordDisplayString( 108 const base::string16& password) { 109 const wchar_t kPasswordBullet = 0x2022; 110 const size_t kMaxPasswordChar = 22; 111 return base::string16(std::min(password.length(), kMaxPasswordChar), 112 kPasswordBullet); 113} 114 115ManagePasswordItemView::~ManagePasswordItemView() { 116 if (delete_password_) 117 manage_passwords_bubble_model_->DeleteFromBestMatches(password_form_); 118} 119 120void ManagePasswordItemView::Refresh() { 121 // TODO(mkwst): We're currently swaping out values in the same view. We need 122 // to swap out views in order to enable some future work (and to make the undo 123 // button's alignment work correctly). 124 125 if (delete_password_) { 126 // The user clicked the "delete password" button, so: 127 // 128 // Change the username string to "Deleted" 129 label_1_->SetText(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED)); 130 131 // Change the password's text to "Undo", and enable the link. 132 label_2_->SetText(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO)); 133 label_2_->SetHorizontalAlignment(gfx::ALIGN_RIGHT); 134 label_2_->SetEnabled(true); 135 label_2_->SetFocusable(true); 136 137 if (delete_button_) 138 delete_button_->SetVisible(false); 139 } else { 140 // The user clicked the "undo" button after deleting a password, so: 141 142 // Move focus to the parent in order to get the focus ring off the link 143 // that the user just clicked. 144 parent()->RequestFocus(); 145 146 // Change the username string back to the username. 147 label_1_->SetText(password_form_.username_value); 148 149 // Set the password string to the appropriate number of bullets, and 150 // disable the link. 151 label_2_->SetText(GetPasswordDisplayString(password_form_.password_value)); 152 label_2_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 153 label_2_->SetEnabled(false); 154 label_2_->SetFocusable(false); 155 156 if (delete_button_) 157 delete_button_->SetVisible(true); 158 } 159 160 // After the view is consistent, notify the model that the password needs to 161 // be updated (either removed or put back into the store, as appropriate. 162 manage_passwords_bubble_model_->OnPasswordAction( 163 password_form_, 164 delete_password_ ? ManagePasswordsBubbleModel::REMOVE_PASSWORD 165 : ManagePasswordsBubbleModel::ADD_PASSWORD); 166} 167 168void ManagePasswordItemView::ButtonPressed(views::Button* sender, 169 const ui::Event& event) { 170 DCHECK_EQ(delete_button_, sender); 171 delete_password_ = true; 172 Refresh(); 173} 174 175void ManagePasswordItemView::LinkClicked(views::Link* source, 176 int event_flags) { 177 DCHECK_EQ(source, label_2_); 178 delete_password_ = false; 179 Refresh(); 180} 181