| OLD | NEW |
| (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_exceptions_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/pref_names.h" | |
| 17 #include "chrome/common/url_constants.h" | |
| 18 #include "gfx/gtk_util.h" | |
| 19 #include "grit/app_resources.h" | |
| 20 #include "grit/chromium_strings.h" | |
| 21 #include "grit/generated_resources.h" | |
| 22 #include "net/base/net_util.h" | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // Column ids for |exception_list_store_|. | |
| 27 enum { | |
| 28 COL_SITE, | |
| 29 COL_COUNT, | |
| 30 }; | |
| 31 | |
| 32 } // anonymous namespace | |
| 33 | |
| 34 /////////////////////////////////////////////////////////////////////////////// | |
| 35 // PasswordsExceptionsPageGtk, public: | |
| 36 | |
| 37 PasswordsExceptionsPageGtk::PasswordsExceptionsPageGtk(Profile* profile) | |
| 38 : populater(this), profile_(profile) { | |
| 39 | |
| 40 remove_button_ = gtk_button_new_with_label( | |
| 41 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON).c_str()); | |
| 42 gtk_widget_set_sensitive(remove_button_, FALSE); | |
| 43 g_signal_connect(remove_button_, "clicked", | |
| 44 G_CALLBACK(OnRemoveButtonClickedThunk), this); | |
| 45 remove_all_button_ = gtk_button_new_with_label(l10n_util::GetStringUTF8( | |
| 46 IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON).c_str()); | |
| 47 gtk_widget_set_sensitive(remove_all_button_, FALSE); | |
| 48 g_signal_connect(remove_all_button_, "clicked", | |
| 49 G_CALLBACK(OnRemoveAllButtonClickedThunk), this); | |
| 50 | |
| 51 GtkWidget* buttons = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); | |
| 52 gtk_box_pack_start(GTK_BOX(buttons), remove_button_, FALSE, FALSE, 0); | |
| 53 gtk_box_pack_start(GTK_BOX(buttons), remove_all_button_, FALSE, FALSE, 0); | |
| 54 | |
| 55 GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL); | |
| 56 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), | |
| 57 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
| 58 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window), | |
| 59 GTK_SHADOW_ETCHED_IN); | |
| 60 | |
| 61 // Sets exception_tree_ among other things. | |
| 62 InitExceptionTree(); | |
| 63 gtk_container_add(GTK_CONTAINER(scroll_window), exception_tree_); | |
| 64 | |
| 65 page_ = gtk_hbox_new(FALSE, gtk_util::kControlSpacing); | |
| 66 gtk_container_set_border_width(GTK_CONTAINER(page_), | |
| 67 gtk_util::kContentAreaBorder); | |
| 68 gtk_box_pack_end(GTK_BOX(page_), buttons, FALSE, FALSE, 0); | |
| 69 gtk_box_pack_end(GTK_BOX(page_), scroll_window, TRUE, TRUE, 0); | |
| 70 } | |
| 71 | |
| 72 PasswordsExceptionsPageGtk::~PasswordsExceptionsPageGtk() { | |
| 73 STLDeleteElements(&exception_list_); | |
| 74 } | |
| 75 | |
| 76 /////////////////////////////////////////////////////////////////////////////// | |
| 77 // PasswordsExceptionsPageGtk, private: | |
| 78 | |
| 79 void PasswordsExceptionsPageGtk::InitExceptionTree() { | |
| 80 exception_list_store_ = gtk_list_store_new(COL_COUNT, G_TYPE_STRING); | |
| 81 exception_list_sort_ = gtk_tree_model_sort_new_with_model( | |
| 82 GTK_TREE_MODEL(exception_list_store_)); | |
| 83 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(exception_list_sort_), | |
| 84 COL_SITE, CompareSite, this, NULL); | |
| 85 exception_tree_ = gtk_tree_view_new_with_model(exception_list_sort_); | |
| 86 g_object_unref(exception_list_store_); | |
| 87 g_object_unref(exception_list_sort_); | |
| 88 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(exception_tree_), TRUE); | |
| 89 | |
| 90 exception_selection_ = gtk_tree_view_get_selection( | |
| 91 GTK_TREE_VIEW(exception_tree_)); | |
| 92 gtk_tree_selection_set_mode(exception_selection_, | |
| 93 GTK_SELECTION_SINGLE); | |
| 94 g_signal_connect(exception_selection_, "changed", | |
| 95 G_CALLBACK(OnExceptionSelectionChangedThunk), this); | |
| 96 | |
| 97 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( | |
| 98 l10n_util::GetStringUTF8(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN).c_str(), | |
| 99 gtk_cell_renderer_text_new(), | |
| 100 "text", COL_SITE, | |
| 101 NULL); | |
| 102 gtk_tree_view_column_set_sort_column_id(column, COL_SITE); | |
| 103 gtk_tree_view_append_column(GTK_TREE_VIEW(exception_tree_), column); | |
| 104 | |
| 105 populater.populate(); | |
| 106 } | |
| 107 | |
| 108 PasswordStore* PasswordsExceptionsPageGtk::GetPasswordStore() { | |
| 109 return profile_->GetPasswordStore(Profile::EXPLICIT_ACCESS); | |
| 110 } | |
| 111 | |
| 112 void PasswordsExceptionsPageGtk::SetExceptionList( | |
| 113 const std::vector<webkit_glue::PasswordForm*>& result) { | |
| 114 std::string languages = | |
| 115 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); | |
| 116 gtk_list_store_clear(exception_list_store_); | |
| 117 STLDeleteElements(&exception_list_); | |
| 118 exception_list_ = result; | |
| 119 for (size_t i = 0; i < result.size(); ++i) { | |
| 120 GtkTreeIter iter; | |
| 121 gtk_list_store_insert_with_values(exception_list_store_, &iter, (gint) i, | |
| 122 COL_SITE, | |
| 123 UTF16ToUTF8(net::FormatUrl(result[i]->origin, languages)).c_str(), -1); | |
| 124 } | |
| 125 gtk_widget_set_sensitive(remove_all_button_, result.size() > 0); | |
| 126 } | |
| 127 | |
| 128 void PasswordsExceptionsPageGtk::OnRemoveButtonClicked(GtkWidget* widget) { | |
| 129 GtkTreeIter iter; | |
| 130 if (!gtk_tree_selection_get_selected(exception_selection_, | |
| 131 NULL, &iter)) { | |
| 132 NOTREACHED(); | |
| 133 return; | |
| 134 } | |
| 135 | |
| 136 GtkTreePath* path = gtk_tree_model_get_path( | |
| 137 GTK_TREE_MODEL(exception_list_sort_), &iter); | |
| 138 gint index = gtk_tree::GetTreeSortChildRowNumForPath( | |
| 139 exception_list_sort_, path); | |
| 140 gtk_tree_path_free(path); | |
| 141 | |
| 142 GtkTreeIter child_iter; | |
| 143 gtk_tree_model_sort_convert_iter_to_child_iter( | |
| 144 GTK_TREE_MODEL_SORT(exception_list_sort_), &child_iter, &iter); | |
| 145 | |
| 146 // Remove from GTK list, DB, and vector. | |
| 147 gtk_list_store_remove(exception_list_store_, &child_iter); | |
| 148 GetPasswordStore()->RemoveLogin(*exception_list_[index]); | |
| 149 delete exception_list_[index]; | |
| 150 exception_list_.erase(exception_list_.begin() + index); | |
| 151 | |
| 152 gtk_widget_set_sensitive(remove_all_button_, exception_list_.size() > 0); | |
| 153 } | |
| 154 | |
| 155 void PasswordsExceptionsPageGtk::OnRemoveAllButtonClicked(GtkWidget* widget) { | |
| 156 // Remove from GTK list, DB, and vector. | |
| 157 PasswordStore* store = GetPasswordStore(); | |
| 158 gtk_list_store_clear(exception_list_store_); | |
| 159 for (size_t i = 0; i < exception_list_.size(); ++i) | |
| 160 store->RemoveLogin(*exception_list_[i]); | |
| 161 STLDeleteElements(&exception_list_); | |
| 162 gtk_widget_set_sensitive(remove_all_button_, FALSE); | |
| 163 } | |
| 164 | |
| 165 void PasswordsExceptionsPageGtk::OnExceptionSelectionChanged( | |
| 166 GtkTreeSelection* selection) { | |
| 167 GtkTreeIter iter; | |
| 168 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) { | |
| 169 gtk_widget_set_sensitive(remove_button_, FALSE); | |
| 170 return; | |
| 171 } | |
| 172 gtk_widget_set_sensitive(remove_button_, TRUE); | |
| 173 } | |
| 174 | |
| 175 // static | |
| 176 gint PasswordsExceptionsPageGtk::CompareSite(GtkTreeModel* model, | |
| 177 GtkTreeIter* a, GtkTreeIter* b, | |
| 178 gpointer window) { | |
| 179 int row1 = gtk_tree::GetRowNumForIter(model, a); | |
| 180 int row2 = gtk_tree::GetRowNumForIter(model, b); | |
| 181 PasswordsExceptionsPageGtk* page = | |
| 182 reinterpret_cast<PasswordsExceptionsPageGtk*>(window); | |
| 183 return page->exception_list_[row1]->origin.spec().compare( | |
| 184 page->exception_list_[row2]->origin.spec()); | |
| 185 } | |
| 186 | |
| 187 void PasswordsExceptionsPageGtk::ExceptionListPopulater::populate() { | |
| 188 DCHECK(!pending_login_query_); | |
| 189 PasswordStore* store = page_->GetPasswordStore(); | |
| 190 if (store != NULL) | |
| 191 pending_login_query_ = store->GetBlacklistLogins(this); | |
| 192 else | |
| 193 LOG(ERROR) << "No password store! Cannot display exceptions."; | |
| 194 } | |
| 195 | |
| 196 void | |
| 197 PasswordsExceptionsPageGtk::ExceptionListPopulater::OnPasswordStoreRequestDone( | |
| 198 int handle, const std::vector<webkit_glue::PasswordForm*>& result) { | |
| 199 DCHECK_EQ(pending_login_query_, handle); | |
| 200 pending_login_query_ = 0; | |
| 201 page_->SetExceptionList(result); | |
| 202 } | |
| OLD | NEW |