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

Side by Side Diff: chrome/browser/views/password_manager_view.cc

Issue 67055: Use tab to group "Show saved passwords" and "Exceptions"... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/views/password_manager_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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/views/password_manager_view.h"
6
7 #include "base/string_util.h"
8 #include "chrome/common/l10n_util.h"
9 #include "chrome/browser/profile.h"
10 #include "chrome/browser/views/standard_layout.h"
11 #include "chrome/common/pref_names.h"
12 #include "chrome/common/pref_service.h"
13 #include "chrome/views/background.h"
14 #include "chrome/views/controls/button/native_button.h"
15 #include "chrome/views/grid_layout.h"
16 #include "grit/generated_resources.h"
17
18 using views::ColumnSet;
19 using views::GridLayout;
20
21 PasswordManagerView* PasswordManagerView::instance_ = NULL;
22
23 static const int kDefaultWindowWidth = 530;
24 static const int kDefaultWindowHeight = 240;
25
26 ////////////////////////////////////////////////////////////////////////////////
27 // MultiLabelButtons
28 //
29 MultiLabelButtons::MultiLabelButtons(views::ButtonListener* listener,
30 const std::wstring& label,
31 const std::wstring& alt_label)
32 : NativeButton(listener, label),
33 label_(label),
34 alt_label_(alt_label),
35 pref_size_(-1, -1) {
36 }
37
38 gfx::Size MultiLabelButtons::GetPreferredSize() {
39 if (pref_size_.width() == -1 && pref_size_.height() == -1) {
40 // Let's compute our preferred size.
41 std::wstring current_label = label();
42 SetLabel(label_);
43 pref_size_ = NativeButton::GetPreferredSize();
44 SetLabel(alt_label_);
45 gfx::Size alt_pref_size = NativeButton::GetPreferredSize();
46 // Revert to the original label.
47 SetLabel(current_label);
48 pref_size_.SetSize(std::max(pref_size_.width(), alt_pref_size.width()),
49 std::max(pref_size_.height(), alt_pref_size.height()));
50 }
51 return gfx::Size(pref_size_.width(), pref_size_.height());
52 }
53
54
55 ////////////////////////////////////////////////////////////////////
56 // PasswordManagerTableModel
57 PasswordManagerTableModel::PasswordManagerTableModel(Profile* profile)
58 : observer_(NULL),
59 row_count_observer_(NULL),
60 pending_login_query_(NULL),
61 saved_signons_cleanup_(&saved_signons_),
62 profile_(profile) {
63 DCHECK(profile && profile->GetWebDataService(Profile::EXPLICIT_ACCESS));
64 }
65
66 PasswordManagerTableModel::~PasswordManagerTableModel() {
67 CancelLoginsQuery();
68 }
69
70 int PasswordManagerTableModel::RowCount() {
71 return static_cast<int>(saved_signons_.size());
72 }
73
74 std::wstring PasswordManagerTableModel::GetText(int row,
75 int col_id) {
76 switch (col_id) {
77 case IDS_PASSWORD_MANAGER_VIEW_SITE_COLUMN: { // Site.
78 const std::wstring& url = saved_signons_[row]->display_url.display_url();
79 // Force URL to have LTR directionality.
80 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
81 std::wstring localized_url = url;
82 l10n_util::WrapStringWithLTRFormatting(&localized_url);
83 return localized_url;
84 }
85 return url;
86 }
87 case IDS_PASSWORD_MANAGER_VIEW_USERNAME_COLUMN: { // Username.
88 std::wstring username = GetPasswordFormAt(row)->username_value;
89 l10n_util::AdjustStringForLocaleDirection(username, &username);
90 return username;
91 }
92 default:
93 NOTREACHED() << "Invalid column.";
94 return std::wstring();
95 }
96 }
97
98 int PasswordManagerTableModel::CompareValues(int row1, int row2,
99 int column_id) {
100 if (column_id == IDS_PASSWORD_MANAGER_VIEW_SITE_COLUMN) {
101 return saved_signons_[row1]->display_url.Compare(
102 saved_signons_[row2]->display_url, GetCollator());
103 }
104 return TableModel::CompareValues(row1, row2, column_id);
105 }
106
107 void PasswordManagerTableModel::SetObserver(
108 views::TableModelObserver* observer) {
109 observer_ = observer;
110 }
111
112 void PasswordManagerTableModel::GetAllSavedLoginsForProfile() {
113 DCHECK(!pending_login_query_);
114 pending_login_query_ = web_data_service()->GetAllAutofillableLogins(this);
115 }
116
117 void PasswordManagerTableModel::OnWebDataServiceRequestDone(
118 WebDataService::Handle h,
119 const WDTypedResult* result) {
120 DCHECK_EQ(pending_login_query_, h);
121 pending_login_query_ = NULL;
122
123 if (!result)
124 return;
125
126 DCHECK(result->GetType() == PASSWORD_RESULT);
127
128 // Get the result from the database into a useable form.
129 const WDResult<std::vector<PasswordForm*> >* r =
130 static_cast<const WDResult<std::vector<PasswordForm*> >*>(result);
131 std::vector<PasswordForm*> rows = r->GetValue();
132 STLDeleteElements<PasswordRows>(&saved_signons_);
133 saved_signons_.resize(rows.size(), NULL);
134 std::wstring languages =
135 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
136 for (size_t i = 0; i < rows.size(); ++i) {
137 saved_signons_[i] = new PasswordRow(
138 gfx::SortedDisplayURL(rows[i]->origin, languages), rows[i]);
139 }
140 if (observer_)
141 observer_->OnModelChanged();
142 if (row_count_observer_)
143 row_count_observer_->OnRowCountChanged(RowCount());
144 }
145
146 void PasswordManagerTableModel::CancelLoginsQuery() {
147 if (pending_login_query_) {
148 web_data_service()->CancelRequest(pending_login_query_);
149 pending_login_query_ = NULL;
150 }
151 }
152
153 PasswordForm* PasswordManagerTableModel::GetPasswordFormAt(int row) {
154 DCHECK(row >= 0 && row < RowCount());
155 return saved_signons_[row]->form.get();
156 }
157
158 void PasswordManagerTableModel::ForgetAndRemoveSignon(int row) {
159 DCHECK(row >= 0 && row < RowCount());
160 PasswordRows::iterator target_iter = saved_signons_.begin() + row;
161 // Remove from DB, memory, and vector.
162 PasswordRow* password_row = *target_iter;
163 web_data_service()->RemoveLogin(*(password_row->form.get()));
164 delete password_row;
165 saved_signons_.erase(target_iter);
166 if (observer_)
167 observer_->OnItemsRemoved(row, 1);
168 if (row_count_observer_)
169 row_count_observer_->OnRowCountChanged(RowCount());
170 }
171
172 void PasswordManagerTableModel::ForgetAndRemoveAllSignons() {
173 PasswordRows::iterator iter = saved_signons_.begin();
174 while (iter != saved_signons_.end()) {
175 // Remove from DB, memory, and vector.
176 PasswordRow* row = *iter;
177 web_data_service()->RemoveLogin(*(row->form.get()));
178 delete row;
179 iter = saved_signons_.erase(iter);
180 }
181 if (observer_)
182 observer_->OnModelChanged();
183 if (row_count_observer_)
184 row_count_observer_->OnRowCountChanged(RowCount());
185 }
186
187 //////////////////////////////////////////////////////////////////////
188 // PasswordManagerView
189
190 // static
191 void PasswordManagerView::Show(Profile* profile) {
192 DCHECK(profile);
193 if (!instance_) {
194 instance_ = new PasswordManagerView(profile);
195
196 // manager is owned by the dialog window, so Close() will delete it.
197 views::Window::CreateChromeWindow(NULL, gfx::Rect(), instance_);
198 }
199 if (!instance_->window()->IsVisible()) {
200 instance_->window()->Show();
201 } else {
202 instance_->window()->Activate();
203 }
204 }
205
206 PasswordManagerView::PasswordManagerView(Profile* profile)
207 : show_button_(
208 this,
209 l10n_util::GetString(IDS_PASSWORD_MANAGER_VIEW_SHOW_BUTTON),
210 l10n_util::GetString(IDS_PASSWORD_MANAGER_VIEW_HIDE_BUTTON)),
211 remove_button_(this, l10n_util::GetString(
212 IDS_PASSWORD_MANAGER_VIEW_REMOVE_BUTTON)),
213 remove_all_button_(this, l10n_util::GetString(
214 IDS_PASSWORD_MANAGER_VIEW_REMOVE_ALL_BUTTON)),
215 table_model_(profile) {
216 Init();
217 }
218
219 void PasswordManagerView::SetupTable() {
220 // Tell the table model we are concern about how many rows it has.
221 table_model_.set_row_count_observer(this);
222
223 // Creates the different columns for the table.
224 // The float resize values are the result of much tinkering.
225 std::vector<views::TableColumn> columns;
226 columns.push_back(views::TableColumn(IDS_PASSWORD_MANAGER_VIEW_SITE_COLUMN,
227 views::TableColumn::LEFT, -1, 0.55f));
228 columns.back().sortable = true;
229 columns.push_back(views::TableColumn(
230 IDS_PASSWORD_MANAGER_VIEW_USERNAME_COLUMN, views::TableColumn::RIGHT,
231 -1, 0.37f));
232 columns.back().sortable = true;
233 table_view_ = new views::TableView(&table_model_, columns, views::TEXT_ONLY,
234 true, true, true);
235 // Make the table initially sorted by host.
236 views::TableView::SortDescriptors sort;
237 sort.push_back(views::TableView::SortDescriptor(
238 IDS_PASSWORD_MANAGER_VIEW_SITE_COLUMN, true));
239 table_view_->SetSortDescriptors(sort);
240 table_view_->SetObserver(this);
241 }
242
243 void PasswordManagerView::SetupButtonsAndLabels() {
244 // Tell View not to delete class stack allocated views.
245
246 show_button_.SetParentOwned(false);
247 show_button_.SetEnabled(false);
248
249 remove_button_.SetParentOwned(false);
250 remove_button_.SetEnabled(false);
251
252 remove_all_button_.SetParentOwned(false);
253
254 password_label_.SetParentOwned(false);
255 }
256
257 void PasswordManagerView::Init() {
258 // Configure the background and view elements (buttons, labels, table).
259 SetupButtonsAndLabels();
260 SetupTable();
261
262 // Do the layout thing.
263 const int top_column_set_id = 0;
264 const int lower_column_set_id = 1;
265 GridLayout* layout = CreatePanelGridLayout(this);
266 SetLayoutManager(layout);
267
268 // Design the grid.
269 ColumnSet* column_set = layout->AddColumnSet(top_column_set_id);
270 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
271 GridLayout::FIXED, 300, 0);
272 column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
273 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
274 GridLayout::USE_PREF, 0, 0);
275
276 column_set = layout->AddColumnSet(lower_column_set_id);
277 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
278 GridLayout::USE_PREF, 0, 0);
279 column_set->AddPaddingColumn(1, kRelatedControlHorizontalSpacing);
280 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
281 GridLayout::USE_PREF, 0, 0);
282 column_set->LinkColumnSizes(0, 2, -1);
283
284 // Fill the grid.
285 layout->StartRow(0.05f, top_column_set_id);
286 layout->AddView(table_view_, 1, 3);
287 layout->AddView(&remove_button_);
288 layout->StartRow(0.05f, top_column_set_id);
289 layout->SkipColumns(1);
290 layout->AddView(&show_button_);
291 layout->StartRow(0.80f, top_column_set_id);
292 layout->SkipColumns(1);
293 layout->AddView(&password_label_);
294 layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
295
296 // Ask the database for saved password data.
297 table_model_.GetAllSavedLoginsForProfile();
298 }
299
300 PasswordManagerView::~PasswordManagerView() {
301 }
302
303 void PasswordManagerView::Layout() {
304 GetLayoutManager()->Layout(this);
305
306 // Manually lay out the Remove All button in the same row as
307 // the close button.
308 gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false);
309 gfx::Size prefsize = remove_all_button_.GetPreferredSize();
310 int button_y =
311 parent_bounds.bottom() - prefsize.height() - kButtonVEdgeMargin;
312 remove_all_button_.SetBounds(kPanelHorizMargin, button_y, prefsize.width(),
313 prefsize.height());
314 }
315
316 gfx::Size PasswordManagerView::GetPreferredSize() {
317 return gfx::Size(kDefaultWindowWidth, kDefaultWindowHeight);
318 }
319
320 void PasswordManagerView::ViewHierarchyChanged(bool is_add,
321 views::View* parent,
322 views::View* child) {
323 if (child == this) {
324 // Add and remove the Remove All button from the ClientView's hierarchy.
325 if (is_add) {
326 parent->AddChildView(&remove_all_button_);
327 } else {
328 parent->RemoveChildView(&remove_all_button_);
329 }
330 }
331 }
332
333 void PasswordManagerView::OnSelectionChanged() {
334 bool has_selection = table_view_->SelectedRowCount() > 0;
335 remove_button_.SetEnabled(has_selection);
336 // Reset the password related views.
337 show_button_.SetLabel(
338 l10n_util::GetString(IDS_PASSWORD_MANAGER_VIEW_SHOW_BUTTON));
339 show_button_.SetEnabled(has_selection);
340 password_label_.SetText(std::wstring());
341 }
342
343 int PasswordManagerView::GetDialogButtons() const {
344 return DIALOGBUTTON_CANCEL;
345 }
346
347 bool PasswordManagerView::CanResize() const {
348 return true;
349 }
350
351 bool PasswordManagerView::CanMaximize() const {
352 return false;
353 }
354
355 bool PasswordManagerView::IsAlwaysOnTop() const {
356 return false;
357 }
358
359 bool PasswordManagerView::HasAlwaysOnTopMenu() const {
360 return false;
361 }
362
363 std::wstring PasswordManagerView::GetWindowTitle() const {
364 return l10n_util::GetString(IDS_PASSWORD_MANAGER_VIEW_TITLE);
365 }
366
367 void PasswordManagerView::ButtonPressed(views::Button* sender) {
368 DCHECK(window());
369 // Close will result in our destruction.
370 if (sender == &remove_all_button_) {
371 table_model_.ForgetAndRemoveAllSignons();
372 return;
373 }
374
375 // The following require a selection (and only one, since table is single-
376 // select only).
377 views::TableSelectionIterator iter = table_view_->SelectionBegin();
378 int row = *iter;
379 PasswordForm* selected = table_model_.GetPasswordFormAt(row);
380 DCHECK(++iter == table_view_->SelectionEnd());
381
382 if (sender == &remove_button_) {
383 table_model_.ForgetAndRemoveSignon(row);
384 } else if (sender == &show_button_) {
385 if (password_label_.GetText().length() == 0) {
386 password_label_.SetText(selected->password_value);
387 show_button_.SetLabel(
388 l10n_util::GetString(IDS_PASSWORD_MANAGER_VIEW_HIDE_BUTTON));
389 } else {
390 password_label_.SetText(L"");
391 show_button_.SetLabel(
392 l10n_util::GetString(IDS_PASSWORD_MANAGER_VIEW_SHOW_BUTTON));
393 }
394 } else {
395 NOTREACHED() << "Invalid button.";
396 }
397 }
398
399 void PasswordManagerView::WindowClosing() {
400 // The table model will be deleted before the table view, so detach it.
401 table_view_->SetModel(NULL);
402
403 // Clear the static instance so the next time Show() is called, a new
404 // instance is created.
405 instance_ = NULL;
406 }
407
408 views::View* PasswordManagerView::GetContentsView() {
409 return this;
410 }
411
412 void PasswordManagerView::OnRowCountChanged(size_t rows) {
413 remove_all_button_.SetEnabled(rows > 0);
414 }
OLDNEW
« no previous file with comments | « chrome/browser/views/password_manager_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698