Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: chrome/browser/ui/views/passwords/manage_password_items_view.cc

Issue 2960843002: Edit button makes username editable in the password manager bubble. (Closed)
Patch Set: Merge with ToT Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/passwords/manage_password_items_view.h" 5 #include "chrome/browser/ui/views/passwords/manage_password_items_view.h"
6 6
7 #include <numeric> 7 #include <numeric>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" 12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
13 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" 13 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
14 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" 14 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
15 #include "chrome/browser/ui/views/harmony/chrome_typography.h" 15 #include "chrome/browser/ui/views/harmony/chrome_typography.h"
16 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
vasilii 2017/06/30 15:28:05 Remove
irmakk 2017/07/03 14:56:53 Done.
16 #include "chrome/grit/generated_resources.h" 17 #include "chrome/grit/generated_resources.h"
17 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/resources/grit/ui_resources.h" 20 #include "ui/resources/grit/ui_resources.h"
20 #include "ui/views/controls/button/button.h" 21 #include "ui/views/controls/button/button.h"
21 #include "ui/views/controls/button/image_button.h" 22 #include "ui/views/controls/button/image_button.h"
22 #include "ui/views/controls/label.h" 23 #include "ui/views/controls/label.h"
23 #include "ui/views/controls/link.h" 24 #include "ui/views/controls/link.h"
24 #include "ui/views/controls/link_listener.h" 25 #include "ui/views/controls/link_listener.h"
26 #include "ui/views/controls/textfield/textfield.h"
25 #include "ui/views/layout/fill_layout.h" 27 #include "ui/views/layout/fill_layout.h"
26 #include "ui/views/layout/grid_layout.h" 28 #include "ui/views/layout/grid_layout.h"
27 29
28 namespace { 30 namespace {
29 31
30 enum ColumnSets { 32 enum ColumnSets {
31 ONE_COLUMN_SET, 33 ONE_COLUMN_SET,
32 TWO_COLUMN_SET, 34 TWO_COLUMN_SET,
33 THREE_COLUMN_SET 35 THREE_COLUMN_SET
34 }; 36 };
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 } 73 }
72 74
73 std::unique_ptr<views::Label> GenerateUsernameLabel( 75 std::unique_ptr<views::Label> GenerateUsernameLabel(
74 const autofill::PasswordForm& form) { 76 const autofill::PasswordForm& form) {
75 auto label = base::MakeUnique<views::Label>(GetDisplayUsername(form), 77 auto label = base::MakeUnique<views::Label>(GetDisplayUsername(form),
76 CONTEXT_DEPRECATED_SMALL); 78 CONTEXT_DEPRECATED_SMALL);
77 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 79 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
78 return label; 80 return label;
79 } 81 }
80 82
83 std::unique_ptr<views::Textfield> GenerateUsernameEditable(
84 const ::autofill::PasswordForm& form) {
vasilii 2017/06/30 15:28:06 While it's totally correct, we should be consisten
irmakk 2017/07/03 14:56:54 Done.
85 auto editable = base::MakeUnique<views::Textfield>();
86 editable->SetText(GetDisplayUsername(form));
87 editable->SetHorizontalAlignment(gfx::ALIGN_LEFT);
vasilii 2017/06/30 15:28:05 I'm pretty sure that by default views::Textfield d
irmakk 2017/07/03 14:56:53 Removing. But please see line #79, the username la
vasilii 2017/07/03 17:15:30 Label::SetHorizontalAlignment swaps it for RTL
88 return editable;
89 }
90
81 std::unique_ptr<views::Label> GeneratePasswordLabel( 91 std::unique_ptr<views::Label> GeneratePasswordLabel(
82 const autofill::PasswordForm& form) { 92 const autofill::PasswordForm& form) {
83 base::string16 text = 93 base::string16 text =
84 form.federation_origin.unique() 94 form.federation_origin.unique()
85 ? form.password_value 95 ? form.password_value
86 : l10n_util::GetStringFUTF16( 96 : l10n_util::GetStringFUTF16(
87 IDS_PASSWORDS_VIA_FEDERATION, 97 IDS_PASSWORDS_VIA_FEDERATION,
88 base::UTF8ToUTF16(form.federation_origin.host())); 98 base::UTF8ToUTF16(form.federation_origin.host()));
89 auto label = base::MakeUnique<views::Label>(text, CONTEXT_DEPRECATED_SMALL); 99 auto label = base::MakeUnique<views::Label>(text, CONTEXT_DEPRECATED_SMALL);
90 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 100 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 undo_link->SetUnderline(false); 135 undo_link->SetUnderline(false);
126 undo_link->SetFontList(views::style::GetFont(CONTEXT_DEPRECATED_SMALL, 136 undo_link->SetFontList(views::style::GetFont(CONTEXT_DEPRECATED_SMALL,
127 views::style::STYLE_LINK)); 137 views::style::STYLE_LINK));
128 return undo_link; 138 return undo_link;
129 } 139 }
130 140
131 } // namespace 141 } // namespace
132 142
133 // Manage credentials: stores credentials state and adds proper row to layout 143 // Manage credentials: stores credentials state and adds proper row to layout
134 // based on credential state. 144 // based on credential state.
135 class ManagePasswordItemsView::PasswordFormRow : public views::ButtonListener, 145 class ManagePasswordItemsView::PasswordFormRow
136 public views::LinkListener { 146 : public views::ButtonListener,
147 public views::LinkListener,
148 public views::FocusChangeListener {
137 public: 149 public:
138 PasswordFormRow(ManagePasswordItemsView* host, 150 PasswordFormRow(ManagePasswordItemsView* host,
139 const autofill::PasswordForm* password_form, 151 const autofill::PasswordForm* password_form,
140 int fixed_height); 152 int fixed_height);
141 ~PasswordFormRow() override = default; 153 ~PasswordFormRow() override = default;
142 154
143 void AddRow(views::GridLayout* layout); 155 void AddRow(views::GridLayout* layout);
156 RowStatus row_status_;
vasilii 2017/06/30 15:28:06 Should be private
144 157
145 // Returns the fixed height for a row excluding padding. 0 means no fixed 158 // Returns the fixed height for a row excluding padding. 0 means no fixed
146 // height required. 159 // height required.
147 // In MANAGE_STATE a row may represent a credential or a deleted credential. 160 // In MANAGE_STATE a row may represent a credential or a deleted credential.
148 // To avoid repositioning all the rows should have a fixed height. 161 // To avoid repositioning all the rows should have a fixed height.
149 static int GetFixedHeight(password_manager::ui::State state); 162 static int GetFixedHeight(password_manager::ui::State state);
150 163
151 private: 164 private:
152 void AddCredentialsRow(views::GridLayout* layout); 165 void AddCredentialsRow(views::GridLayout* layout);
153 void AddUndoRow(views::GridLayout* layout); 166 void AddUndoRow(views::GridLayout* layout);
154 167
155 // views::ButtonListener: 168 // views::ButtonListener:
156 void ButtonPressed(views::Button* sender, const ui::Event& event) override; 169 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
157 // views::LinkListener: 170 // views::LinkListener:
158 void LinkClicked(views::Link* source, int event_flags) override; 171 void LinkClicked(views::Link* source, int event_flags) override;
172 // views::FocusChangeListener:
173 void OnWillChangeFocus(View* focused_before, View* focused_now) override;
174 void OnDidChangeFocus(View* focused_before, View* focused_now) override;
159 175
160 void ResetControls(); 176 void ResetControls();
161 177
162 ManagePasswordItemsView* host_; 178 ManagePasswordItemsView* host_;
163 const autofill::PasswordForm* password_form_; 179 const autofill::PasswordForm* password_form_;
164 // The UI elements pointers are weak and owned by their parent. 180 // The UI elements pointers are weak and owned by their parent.
165 views::Link* undo_link_; 181 views::Link* undo_link_;
166 views::ImageButton* delete_button_; 182 views::ImageButton* delete_button_;
167 const int fixed_height_; 183 const int fixed_height_;
168 bool deleted_; 184 views::Textfield* editable_;
169 185
170 DISALLOW_COPY_AND_ASSIGN(PasswordFormRow); 186 DISALLOW_COPY_AND_ASSIGN(PasswordFormRow);
171 }; 187 };
172 188
173 ManagePasswordItemsView::PasswordFormRow::PasswordFormRow( 189 ManagePasswordItemsView::PasswordFormRow::PasswordFormRow(
174 ManagePasswordItemsView* host, 190 ManagePasswordItemsView* host,
175 const autofill::PasswordForm* password_form, 191 const autofill::PasswordForm* password_form,
176 int fixed_height) 192 int fixed_height)
177 : host_(host), 193 : row_status_(RowStatus::DEFAULT),
194 host_(host),
178 password_form_(password_form), 195 password_form_(password_form),
179 undo_link_(nullptr), 196 undo_link_(nullptr),
180 delete_button_(nullptr), 197 delete_button_(nullptr),
181 fixed_height_(fixed_height), 198 fixed_height_(fixed_height),
182 deleted_(false) {} 199 editable_(nullptr) {}
183 200
184 void ManagePasswordItemsView::PasswordFormRow::AddRow( 201 void ManagePasswordItemsView::PasswordFormRow::AddRow(
185 views::GridLayout* layout) { 202 views::GridLayout* layout) {
186 if (deleted_) { 203 if (row_status_ == RowStatus::DELETED) {
187 AddUndoRow(layout); 204 AddUndoRow(layout);
188 } else { 205 } else {
189 AddCredentialsRow(layout); 206 AddCredentialsRow(layout);
190 } 207 }
191 } 208 }
192 209
193 int ManagePasswordItemsView::PasswordFormRow::GetFixedHeight( 210 int ManagePasswordItemsView::PasswordFormRow::GetFixedHeight(
194 password_manager::ui::State state) { 211 password_manager::ui::State state) {
195 if (state != password_manager::ui::MANAGE_STATE) 212 if (state != password_manager::ui::MANAGE_STATE)
196 return 0; 213 return 0;
(...skipping 10 matching lines...) Expand all
207 224
208 void ManagePasswordItemsView::PasswordFormRow::AddCredentialsRow( 225 void ManagePasswordItemsView::PasswordFormRow::AddCredentialsRow(
209 views::GridLayout* layout) { 226 views::GridLayout* layout) {
210 ResetControls(); 227 ResetControls();
211 int column_set_id = 228 int column_set_id =
212 host_->model_->state() == password_manager::ui::MANAGE_STATE 229 host_->model_->state() == password_manager::ui::MANAGE_STATE
213 ? THREE_COLUMN_SET 230 ? THREE_COLUMN_SET
214 : TWO_COLUMN_SET; 231 : TWO_COLUMN_SET;
215 BuildColumnSetIfNeeded(layout, column_set_id); 232 BuildColumnSetIfNeeded(layout, column_set_id);
216 layout->StartRow(0, column_set_id); 233 layout->StartRow(0, column_set_id);
217 layout->AddView(GenerateUsernameLabel(*password_form_).release(), 1, 1, 234 if (row_status_ == RowStatus::DEFAULT) {
218 views::GridLayout::FILL, views::GridLayout::FILL, 235 layout->AddView(GenerateUsernameLabel(*password_form_).release(), 1, 1,
219 0, fixed_height_); 236 views::GridLayout::FILL, views::GridLayout::FILL, 0,
237 fixed_height_);
238 } else {
vasilii 2017/06/30 15:28:05 DCHECK_EQ(EDITING, row_status_)?
irmakk 2017/07/03 14:56:54 Done.
239 editable_ = GenerateUsernameEditable(*password_form_).release();
240 layout->AddView(editable_, 1, 1, views::GridLayout::FILL,
241 views::GridLayout::FILL, 0, fixed_height_);
242 host_->GetFocusManager()->SetFocusedView(editable_);
243 host_->delegate_->FocusedOnEditable();
244 host_->GetFocusManager()->AddFocusChangeListener(this);
245 }
220 layout->AddView(GeneratePasswordLabel(*password_form_).release(), 1, 1, 246 layout->AddView(GeneratePasswordLabel(*password_form_).release(), 1, 1,
221 views::GridLayout::FILL, views::GridLayout::FILL, 247 views::GridLayout::FILL, views::GridLayout::FILL,
222 0, fixed_height_); 248 0, fixed_height_);
223 if (column_set_id == THREE_COLUMN_SET) { 249 if (column_set_id == THREE_COLUMN_SET) {
224 delete_button_ = GenerateDeleteButton(this).release(); 250 delete_button_ = GenerateDeleteButton(this).release();
225 layout->AddView(delete_button_, 1, 1, 251 layout->AddView(delete_button_, 1, 1,
226 views::GridLayout::TRAILING, views::GridLayout::FILL, 252 views::GridLayout::TRAILING, views::GridLayout::FILL,
227 0, fixed_height_); 253 0, fixed_height_);
228 } 254 }
229 } 255 }
(...skipping 10 matching lines...) Expand all
240 views::GridLayout::FILL, views::GridLayout::FILL, 266 views::GridLayout::FILL, views::GridLayout::FILL,
241 0, fixed_height_); 267 0, fixed_height_);
242 layout->AddView(undo_link.release(), 1, 1, 268 layout->AddView(undo_link.release(), 1, 1,
243 views::GridLayout::FILL, views::GridLayout::FILL, 269 views::GridLayout::FILL, views::GridLayout::FILL,
244 0, fixed_height_); 270 0, fixed_height_);
245 } 271 }
246 272
247 void ManagePasswordItemsView::PasswordFormRow::ButtonPressed( 273 void ManagePasswordItemsView::PasswordFormRow::ButtonPressed(
248 views::Button* sender, const ui::Event& event) { 274 views::Button* sender, const ui::Event& event) {
249 DCHECK_EQ(delete_button_, sender); 275 DCHECK_EQ(delete_button_, sender);
250 deleted_ = true; 276 row_status_ = RowStatus::DELETED;
251 host_->NotifyPasswordFormStatusChanged(*password_form_, deleted_); 277 host_->NotifyPasswordFormStatusChanged(*password_form_, true);
252 } 278 }
253 279
254 void ManagePasswordItemsView::PasswordFormRow::LinkClicked(views::Link* sender, 280 void ManagePasswordItemsView::PasswordFormRow::LinkClicked(views::Link* sender,
255 int event_flags) { 281 int event_flags) {
256 DCHECK_EQ(undo_link_, sender); 282 DCHECK_EQ(undo_link_, sender);
257 deleted_ = false; 283 row_status_ = RowStatus::DEFAULT;
258 host_->NotifyPasswordFormStatusChanged(*password_form_, deleted_); 284 host_->NotifyPasswordFormStatusChanged(*password_form_, false);
259 } 285 }
260 286
261 void ManagePasswordItemsView::PasswordFormRow::ResetControls() { 287 void ManagePasswordItemsView::PasswordFormRow::ResetControls() {
262 delete_button_ = nullptr; 288 delete_button_ = nullptr;
263 undo_link_ = nullptr; 289 undo_link_ = nullptr;
vasilii 2017/06/30 15:28:06 editable_ = nullptr;
irmakk 2017/07/03 14:56:53 Done.
264 } 290 }
265 291
292 // FocusChangeListener methods.
293 void ManagePasswordItemsView::PasswordFormRow::OnWillChangeFocus(
vasilii 2017/06/30 15:28:06 The definition order should match the declaration
294 View* focused_before,
295 View* focused_now) {
296 // Nothing to do here.
297 }
298
299 void ManagePasswordItemsView::PasswordFormRow::OnDidChangeFocus(
300 View* focused_before,
301 View* focused_now) {
302 if (focused_before == editable_) {
303 host_->SetRowStatusForPendingViewRow(RowStatus::DEFAULT);
304 }
305 }
306
266 // ManagePasswordItemsView 307 // ManagePasswordItemsView
267 ManagePasswordItemsView::ManagePasswordItemsView( 308 ManagePasswordItemsView::ManagePasswordItemsView(
268 ManagePasswordsBubbleModel* manage_passwords_bubble_model, 309 ManagePasswordsBubbleModel* manage_passwords_bubble_model,
269 const std::vector<autofill::PasswordForm>* password_forms) 310 const std::vector<autofill::PasswordForm>* password_forms)
270 : model_(manage_passwords_bubble_model) { 311 : model_(manage_passwords_bubble_model) {
271 int fixed_height = PasswordFormRow::GetFixedHeight(model_->state()); 312 int fixed_height = PasswordFormRow::GetFixedHeight(model_->state());
272 for (const auto& password_form : *password_forms) { 313 for (const auto& password_form : *password_forms) {
273 password_forms_rows_.push_back(base::MakeUnique<PasswordFormRow>( 314 password_forms_rows_.push_back(base::MakeUnique<PasswordFormRow>(
274 this, &password_form, fixed_height)); 315 this, &password_form, fixed_height));
275 } 316 }
276 AddRows(); 317 AddRows();
277 } 318 }
278 319
279 ManagePasswordItemsView::ManagePasswordItemsView( 320 ManagePasswordItemsView::ManagePasswordItemsView(
280 ManagePasswordsBubbleModel* manage_passwords_bubble_model, 321 ManagePasswordsBubbleModel* manage_passwords_bubble_model,
281 const autofill::PasswordForm* password_form) 322 const autofill::PasswordForm* password_form,
282 : model_(manage_passwords_bubble_model) { 323 ManagePasswordItemsDelegate* manage_password_items_delegate)
324 : model_(manage_passwords_bubble_model),
325 delegate_(manage_password_items_delegate) {
283 password_forms_rows_.push_back( 326 password_forms_rows_.push_back(
284 base::MakeUnique<PasswordFormRow>(this, password_form, 0)); 327 base::MakeUnique<PasswordFormRow>(this, password_form, 0));
285 AddRows(); 328 AddRows();
286 } 329 }
287 330
288 ManagePasswordItemsView::~ManagePasswordItemsView() = default; 331 ManagePasswordItemsView::~ManagePasswordItemsView() = default;
289 332
290 void ManagePasswordItemsView::AddRows() { 333 void ManagePasswordItemsView::AddRows() {
291 const int vertical_padding = ChromeLayoutProvider::Get()->GetDistanceMetric( 334 const int vertical_padding = ChromeLayoutProvider::Get()->GetDistanceMetric(
292 views::DISTANCE_RELATED_CONTROL_VERTICAL); 335 views::DISTANCE_RELATED_CONTROL_VERTICAL);
(...skipping 16 matching lines...) Expand all
309 deleted 352 deleted
310 ? ManagePasswordsBubbleModel::REMOVE_PASSWORD 353 ? ManagePasswordsBubbleModel::REMOVE_PASSWORD
311 : ManagePasswordsBubbleModel::ADD_PASSWORD); 354 : ManagePasswordsBubbleModel::ADD_PASSWORD);
312 } 355 }
313 356
314 void ManagePasswordItemsView::Refresh() { 357 void ManagePasswordItemsView::Refresh() {
315 DCHECK_NE(password_manager::ui::PENDING_PASSWORD_STATE, model_->state()); 358 DCHECK_NE(password_manager::ui::PENDING_PASSWORD_STATE, model_->state());
316 RemoveAllChildViews(true); 359 RemoveAllChildViews(true);
317 AddRows(); 360 AddRows();
318 } 361 }
362
363 bool ManagePasswordItemsView::OnKeyPressed(const ui::KeyEvent& event) {
vasilii 2017/06/30 15:28:05 How does it work? The edit doesn't handle ENTER an
364 // Handle key press if editable field is active, leave it to the parent
365 // otherwise.
366 if (password_manager::ui::PENDING_PASSWORD_STATE == model_->state() &&
367 password_forms_rows_[0]->row_status_ == RowStatus::EDITING &&
368 (event.key_code() == ui::KeyboardCode::VKEY_RETURN ||
369 event.key_code() == ui::KeyboardCode::VKEY_ESCAPE)) {
370 SetRowStatusForPendingViewRow(RowStatus::DEFAULT);
371 return true;
372 }
373 return false;
374 }
375
376 void ManagePasswordItemsView::SetRowStatusForPendingViewRow(
377 RowStatus row_status) {
378 DCHECK_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model_->state());
379 const std::unique_ptr<PasswordFormRow>& row = password_forms_rows_[0];
380 if (row->row_status_ == RowStatus::EDITING &&
381 row_status == RowStatus::DEFAULT) {
382 GetFocusManager()->RemoveFocusChangeListener(row.get());
vasilii 2017/06/30 15:28:06 I feel that it's wrong that it's not PasswordFormR
383 delegate_->FocusLostOnEditable();
384 }
385 row->row_status_ = row_status;
386 RemoveAllChildViews(true);
387 AddRows();
388 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698