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

Side by Side Diff: chrome/browser/gtk/options/passwords_page_gtk.cc

Issue 6251001: Move chrome/browser/gtk/ to chrome/browser/ui/gtk/... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 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
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/gtk/options/passwords_page_gtk.h"
6
7 #include <string>
8
9 #include "app/l10n_util.h"
10 #include "base/stl_util-inl.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/gtk/gtk_tree.h"
13 #include "chrome/browser/gtk/gtk_util.h"
14 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/notification_details.h"
17 #include "chrome/common/notification_type.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/common/url_constants.h"
20 #include "gfx/gtk_util.h"
21 #include "grit/app_resources.h"
22 #include "grit/chromium_strings.h"
23 #include "grit/generated_resources.h"
24 #include "net/base/net_util.h"
25
26 namespace {
27
28 // Initial width of the first column.
29 const int kSiteColumnInitialSize = 265;
30
31 // Column ids for |password_list_store_|.
32 enum {
33 COL_SITE,
34 COL_USERNAME,
35 COL_COUNT,
36 };
37
38 } // anonymous namespace
39
40 ///////////////////////////////////////////////////////////////////////////////
41 // PasswordsPageGtk, public:
42
43 PasswordsPageGtk::PasswordsPageGtk(Profile* profile)
44 : populater(this), password_showing_(false), profile_(profile) {
45 allow_show_passwords_.Init(prefs::kPasswordManagerAllowShowPasswords,
46 profile->GetPrefs(),
47 this);
48
49 remove_button_ = gtk_button_new_with_label(
50 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON).c_str());
51 gtk_widget_set_sensitive(remove_button_, FALSE);
52 g_signal_connect(remove_button_, "clicked",
53 G_CALLBACK(OnRemoveButtonClickedThunk), this);
54 remove_all_button_ = gtk_button_new_with_label(l10n_util::GetStringUTF8(
55 IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON).c_str());
56 gtk_widget_set_sensitive(remove_all_button_, FALSE);
57 g_signal_connect(remove_all_button_, "clicked",
58 G_CALLBACK(OnRemoveAllButtonClickedThunk), this);
59
60 // We start with the "hide password" text but change it in the realize event.
61 show_password_button_ = gtk_button_new_with_label(
62 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON).c_str());
63 gtk_widget_set_no_show_all(show_password_button_, true);
64 gtk_widget_set_sensitive(show_password_button_, FALSE);
65 g_signal_connect(show_password_button_, "clicked",
66 G_CALLBACK(OnShowPasswordButtonClickedThunk), this);
67 g_signal_connect(show_password_button_, "realize",
68 G_CALLBACK(OnShowPasswordButtonRealizedThunk), this);
69
70 password_ = gtk_label_new("");
71 gtk_label_set_selectable(GTK_LABEL(password_), TRUE);
72 gtk_widget_set_no_show_all(password_, true);
73
74 GtkWidget* buttons = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
75 gtk_box_pack_start(GTK_BOX(buttons), remove_button_, FALSE, FALSE, 0);
76 gtk_box_pack_start(GTK_BOX(buttons), remove_all_button_, FALSE, FALSE, 0);
77 gtk_box_pack_start(GTK_BOX(buttons), show_password_button_, FALSE, FALSE, 0);
78 gtk_box_pack_start(GTK_BOX(buttons), password_, FALSE, FALSE, 0);
79
80 GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL);
81 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
82 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
83 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window),
84 GTK_SHADOW_ETCHED_IN);
85
86 // Sets password_tree_ among other things.
87 InitPasswordTree();
88 gtk_container_add(GTK_CONTAINER(scroll_window), password_tree_);
89
90 page_ = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
91 gtk_container_set_border_width(GTK_CONTAINER(page_),
92 gtk_util::kContentAreaBorder);
93 gtk_box_pack_end(GTK_BOX(page_), buttons, FALSE, FALSE, 0);
94 gtk_box_pack_end(GTK_BOX(page_), scroll_window, TRUE, TRUE, 0);
95
96 // Initialize UI state based on current preference values.
97 OnPrefChanged(prefs::kPasswordManagerAllowShowPasswords);
98 }
99
100 PasswordsPageGtk::~PasswordsPageGtk() {
101 STLDeleteElements(&password_list_);
102 }
103
104 ///////////////////////////////////////////////////////////////////////////////
105 // PasswordsPageGtk, private:
106
107 void PasswordsPageGtk::InitPasswordTree() {
108 password_list_store_ = gtk_list_store_new(COL_COUNT,
109 G_TYPE_STRING,
110 G_TYPE_STRING);
111 password_list_sort_ = gtk_tree_model_sort_new_with_model(
112 GTK_TREE_MODEL(password_list_store_));
113 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(password_list_sort_),
114 COL_SITE, CompareSite, this, NULL);
115 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(password_list_sort_),
116 COL_USERNAME, CompareUsername, this, NULL);
117 password_tree_ = gtk_tree_view_new_with_model(password_list_sort_);
118 g_object_unref(password_list_store_);
119 g_object_unref(password_list_sort_);
120 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(password_tree_), TRUE);
121
122 password_selection_ = gtk_tree_view_get_selection(
123 GTK_TREE_VIEW(password_tree_));
124 gtk_tree_selection_set_mode(password_selection_,
125 GTK_SELECTION_SINGLE);
126 g_signal_connect(password_selection_, "changed",
127 G_CALLBACK(OnPasswordSelectionChangedThunk), this);
128
129 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes(
130 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN).c_str(),
131 gtk_cell_renderer_text_new(),
132 "text", COL_SITE,
133 NULL);
134 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
135 gtk_tree_view_column_set_resizable(column, TRUE);
136 gtk_tree_view_column_set_fixed_width(column, kSiteColumnInitialSize);
137 gtk_tree_view_column_set_sort_column_id(column, COL_SITE);
138 gtk_tree_view_append_column(GTK_TREE_VIEW(password_tree_), column);
139
140 column = gtk_tree_view_column_new_with_attributes(
141 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN).c_str(),
142 gtk_cell_renderer_text_new(),
143 "text", COL_USERNAME,
144 NULL);
145 gtk_tree_view_column_set_sort_column_id(column, COL_USERNAME);
146 gtk_tree_view_append_column(GTK_TREE_VIEW(password_tree_), column);
147 populater.populate();
148 }
149
150 PasswordStore* PasswordsPageGtk::GetPasswordStore() {
151 return profile_->GetPasswordStore(Profile::EXPLICIT_ACCESS);
152 }
153
154 void PasswordsPageGtk::SetPasswordList(
155 const std::vector<webkit_glue::PasswordForm*>& result) {
156 std::string languages =
157 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
158 gtk_list_store_clear(password_list_store_);
159 STLDeleteElements(&password_list_);
160 password_list_ = result;
161 for (size_t i = 0; i < result.size(); ++i) {
162 GtkTreeIter iter;
163 gtk_list_store_insert_with_values(password_list_store_, &iter, (gint) i,
164 COL_SITE,
165 UTF16ToUTF8(net::FormatUrl(result[i]->origin, languages)).c_str(),
166 COL_USERNAME, UTF16ToUTF8(result[i]->username_value).c_str(), -1);
167 }
168 gtk_widget_set_sensitive(remove_all_button_, result.size() > 0);
169 }
170
171 void PasswordsPageGtk::HidePassword() {
172 password_showing_ = false;
173 gtk_label_set_text(GTK_LABEL(password_), "");
174 gtk_button_set_label(GTK_BUTTON(show_password_button_),
175 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON).c_str());
176 }
177
178 void PasswordsPageGtk::Observe(NotificationType type,
179 const NotificationSource& source,
180 const NotificationDetails& details) {
181 DCHECK_EQ(NotificationType::PREF_CHANGED, type.value);
182 const std::string* pref_name = Details<std::string>(details).ptr();
183 OnPrefChanged(*pref_name);
184 }
185
186 void PasswordsPageGtk::OnPrefChanged(const std::string& pref_name) {
187 if (pref_name == prefs::kPasswordManagerAllowShowPasswords) {
188 if (allow_show_passwords_.GetValue()) {
189 gtk_widget_show(show_password_button_);
190 gtk_widget_show(password_);
191 } else {
192 HidePassword();
193 gtk_widget_hide(show_password_button_);
194 gtk_widget_hide(password_);
195 }
196 } else {
197 NOTREACHED();
198 }
199 }
200
201 void PasswordsPageGtk::OnRemoveButtonClicked(GtkWidget* widget) {
202 GtkTreeIter iter;
203 if (!gtk_tree_selection_get_selected(password_selection_,
204 NULL, &iter)) {
205 NOTREACHED();
206 return;
207 }
208
209 GtkTreePath* path = gtk_tree_model_get_path(
210 GTK_TREE_MODEL(password_list_sort_), &iter);
211 gint index = gtk_tree::GetTreeSortChildRowNumForPath(
212 password_list_sort_, path);
213 gtk_tree_path_free(path);
214
215 GtkTreeIter child_iter;
216 gtk_tree_model_sort_convert_iter_to_child_iter(
217 GTK_TREE_MODEL_SORT(password_list_sort_), &child_iter, &iter);
218
219 // Remove from GTK list, DB, and vector.
220 gtk_list_store_remove(password_list_store_, &child_iter);
221 GetPasswordStore()->RemoveLogin(*password_list_[index]);
222 delete password_list_[index];
223 password_list_.erase(password_list_.begin() + index);
224
225 gtk_widget_set_sensitive(remove_all_button_, password_list_.size() > 0);
226 }
227
228 void PasswordsPageGtk::OnRemoveAllButtonClicked(GtkWidget* widget) {
229 GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(page_));
230 GtkWidget* confirm = gtk_message_dialog_new(
231 window,
232 static_cast<GtkDialogFlags>(
233 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
234 GTK_MESSAGE_QUESTION,
235 GTK_BUTTONS_YES_NO,
236 "%s",
237 l10n_util::GetStringUTF8(
238 IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS).c_str());
239 gtk_util::ApplyMessageDialogQuirks(confirm);
240 gtk_window_set_title(GTK_WINDOW(confirm), l10n_util::GetStringUTF8(
241 IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS).c_str());
242 g_signal_connect(confirm, "response",
243 G_CALLBACK(OnRemoveAllConfirmResponseThunk), this);
244 gtk_widget_show_all(confirm);
245 }
246
247 void PasswordsPageGtk::OnRemoveAllConfirmResponse(GtkWidget* confirm,
248 gint response) {
249 bool confirmed = false;
250 switch (response) {
251 case GTK_RESPONSE_YES:
252 confirmed = true;
253 break;
254 default:
255 break;
256 }
257 gtk_widget_destroy(confirm);
258 if (!confirmed)
259 return;
260
261 // Remove from GTK list, DB, and vector.
262 PasswordStore* store = GetPasswordStore();
263 gtk_list_store_clear(password_list_store_);
264 for (size_t i = 0; i < password_list_.size(); ++i)
265 store->RemoveLogin(*password_list_[i]);
266 STLDeleteElements(&password_list_);
267 gtk_widget_set_sensitive(remove_all_button_, FALSE);
268 }
269
270 void PasswordsPageGtk::OnShowPasswordButtonClicked(GtkWidget* widget) {
271 if (password_showing_ || !allow_show_passwords_.GetValue()) {
272 // Hide the password.
273 HidePassword();
274 return;
275 }
276 // Show the password.
277 password_showing_ = true;
278 GtkTreeIter iter;
279 if (!gtk_tree_selection_get_selected(password_selection_,
280 NULL, &iter)) {
281 NOTREACHED();
282 return;
283 }
284 GtkTreePath* path = gtk_tree_model_get_path(
285 GTK_TREE_MODEL(password_list_sort_), &iter);
286 gint index = gtk_tree::GetTreeSortChildRowNumForPath(
287 password_list_sort_, path);
288 gtk_tree_path_free(path);
289 std::string pass = UTF16ToUTF8(password_list_[index]->password_value);
290 gtk_label_set_text(GTK_LABEL(password_), pass.c_str());
291 gtk_button_set_label(GTK_BUTTON(show_password_button_),
292 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON).c_str());
293 }
294
295 void PasswordsPageGtk::OnShowPasswordButtonRealized(GtkWidget* widget) {
296 // We have just realized the "show password" button, so we can now accurately
297 // find out how big it needs to be in order to accomodate both the "show" and
298 // "hide" labels. (This requires font information to work correctly.) The
299 // button starts with the "hide" label so we only have to change it once.
300 GtkRequisition hide_size, show_size;
301 // Get the size request of the button with the "hide password" text.
302 gtk_widget_size_request(show_password_button_, &hide_size);
303 gtk_button_set_label(GTK_BUTTON(show_password_button_),
304 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON).c_str());
305 // Get the size request of the button with the "show password" text.
306 gtk_widget_size_request(show_password_button_, &show_size);
307 // Determine the maximum width and height.
308 if (hide_size.width > show_size.width)
309 show_size.width = hide_size.width;
310 if (hide_size.height > show_size.height)
311 show_size.height = hide_size.height;
312 // Force the button to be large enough for both labels.
313 gtk_widget_set_size_request(show_password_button_, show_size.width,
314 show_size.height);
315 }
316
317 void PasswordsPageGtk::OnPasswordSelectionChanged(GtkTreeSelection* selection) {
318 // No matter how the selection changed, we want to hide the old password.
319 HidePassword();
320
321 GtkTreeIter iter;
322 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) {
323 gtk_widget_set_sensitive(show_password_button_, FALSE);
324 gtk_widget_set_sensitive(remove_button_, FALSE);
325 return;
326 }
327 gtk_widget_set_sensitive(show_password_button_, TRUE);
328 gtk_widget_set_sensitive(remove_button_, TRUE);
329 }
330
331 // static
332 gint PasswordsPageGtk::CompareSite(GtkTreeModel* model,
333 GtkTreeIter* a, GtkTreeIter* b,
334 gpointer window) {
335 int row1 = gtk_tree::GetRowNumForIter(model, a);
336 int row2 = gtk_tree::GetRowNumForIter(model, b);
337 PasswordsPageGtk* page = reinterpret_cast<PasswordsPageGtk*>(window);
338 return page->password_list_[row1]->origin.spec().compare(
339 page->password_list_[row2]->origin.spec());
340 }
341
342 // static
343 gint PasswordsPageGtk::CompareUsername(GtkTreeModel* model,
344 GtkTreeIter* a, GtkTreeIter* b,
345 gpointer window) {
346 int row1 = gtk_tree::GetRowNumForIter(model, a);
347 int row2 = gtk_tree::GetRowNumForIter(model, b);
348 PasswordsPageGtk* page = reinterpret_cast<PasswordsPageGtk*>(window);
349 return page->password_list_[row1]->username_value.compare(
350 page->password_list_[row2]->username_value);
351 }
352
353 void PasswordsPageGtk::PasswordListPopulater::populate() {
354 DCHECK(!pending_login_query_);
355 PasswordStore* store = page_->GetPasswordStore();
356 if (store != NULL)
357 pending_login_query_ = store->GetAutofillableLogins(this);
358 else
359 LOG(ERROR) << "No password store! Cannot display passwords.";
360 }
361
362 void PasswordsPageGtk::PasswordListPopulater::OnPasswordStoreRequestDone(
363 int handle, const std::vector<webkit_glue::PasswordForm*>& result) {
364 DCHECK_EQ(pending_login_query_, handle);
365 pending_login_query_ = 0;
366 page_->SetPasswordList(result);
367 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/options/passwords_page_gtk.h ('k') | chrome/browser/gtk/options/simple_content_exceptions_window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698