summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-30 22:41:36 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-30 22:41:36 +0000
commit33964ca57ee7192ca32aea0e63dca8e825305206 (patch)
tree7029f512a3ac730261c4ed54aed935b6b9defbae /chrome/browser/gtk
parent52c27fbc951fb7b98ae912944419bc5873e5721f (diff)
downloadchromium_src-33964ca57ee7192ca32aea0e63dca8e825305206.zip
chromium_src-33964ca57ee7192ca32aea0e63dca8e825305206.tar.gz
chromium_src-33964ca57ee7192ca32aea0e63dca8e825305206.tar.bz2
Linux: Adds back the ability to filter cookies by origin in the cookies options view
BUG=27657 TEST=unittest passes, manually testing typing "google" in the search field pulls up origins containing "google" in their name Review URL: http://codereview.chromium.org/437075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33359 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/options/cookies_view.cc75
-rw-r--r--chrome/browser/gtk/options/cookies_view.h21
-rw-r--r--chrome/browser/gtk/options/cookies_view_unittest.cc183
3 files changed, 273 insertions, 6 deletions
diff --git a/chrome/browser/gtk/options/cookies_view.cc b/chrome/browser/gtk/options/cookies_view.cc
index 02b61e6..b591cf0b 100644
--- a/chrome/browser/gtk/options/cookies_view.cc
+++ b/chrome/browser/gtk/options/cookies_view.cc
@@ -23,6 +23,9 @@ namespace {
const int kDialogDefaultWidth = 550;
const int kDialogDefaultHeight = 550;
+// Delay after entering filter text before filtering occurs.
+const int kSearchFilterDelayMs = 500;
+
// Response ids for our custom buttons.
enum {
RESPONSE_REMOVE = 1,
@@ -67,7 +70,8 @@ void CookiesView::Show(Profile* profile) {
}
CookiesView::CookiesView(Profile* profile)
- : profile_(profile) {
+ : profile_(profile),
+ filter_update_factory_(this) {
Init();
}
@@ -113,6 +117,29 @@ void CookiesView::Init() {
g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this);
g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this);
+ // Filtering controls.
+ GtkWidget* filter_hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
+ filter_entry_ = gtk_entry_new();
+ g_signal_connect(G_OBJECT(filter_entry_), "activate",
+ G_CALLBACK(OnFilterEntryActivated), this);
+ g_signal_connect(G_OBJECT(filter_entry_), "changed",
+ G_CALLBACK(OnFilterEntryChanged), this);
+ gtk_box_pack_start(GTK_BOX(filter_hbox), filter_entry_,
+ TRUE, TRUE, 0);
+ filter_clear_button_ = gtk_button_new_with_mnemonic(
+ gtk_util::ConvertAcceleratorsFromWindowsStyle(
+ l10n_util::GetStringUTF8(IDS_COOKIES_CLEAR_SEARCH_LABEL)).c_str());
+ g_signal_connect(G_OBJECT(filter_clear_button_), "clicked",
+ G_CALLBACK(OnFilterClearButtonClicked), this);
+ gtk_box_pack_start(GTK_BOX(filter_hbox), filter_clear_button_,
+ FALSE, FALSE, 0);
+
+ GtkWidget* filter_controls = gtk_util::CreateLabeledControlsGroup(NULL,
+ l10n_util::GetStringUTF8(IDS_COOKIES_SEARCH_LABEL).c_str(), filter_hbox,
+ NULL);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), filter_controls,
+ FALSE, FALSE, 0);
+
// Cookie list.
GtkWidget* cookie_list_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), cookie_list_vbox,
@@ -189,11 +216,8 @@ void CookiesView::Init() {
// Populate the view.
cookies_tree_adapter_->Init();
- gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_));
+ SetInitialTreeState();
EnableControls();
-
- if (cookies_tree_model_->GetChildCount(cookies_tree_model_->GetRoot()))
- gtk_tree::SelectAndFocusRowNum(0, GTK_TREE_VIEW(tree_));
}
void CookiesView::InitStylesAndShow() {
@@ -230,6 +254,12 @@ void CookiesView::InitCookieDetailRow(int row, int label_id,
1, 2, row, row + 1);
}
+void CookiesView::SetInitialTreeState() {
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_));
+ if (cookies_tree_model_->GetChildCount(cookies_tree_model_->GetRoot()))
+ gtk_tree::SelectAndFocusRowNum(0, GTK_TREE_VIEW(tree_));
+}
+
void CookiesView::EnableControls() {
GtkTreeIter iter;
bool selected = gtk_tree_selection_get_selected(selection_, NULL, &iter);
@@ -238,6 +268,9 @@ void CookiesView::EnableControls() {
remove_all_button_,
cookies_tree_model_->GetChildCount(cookies_tree_model_->GetRoot()));
+ const gchar* filter_text = gtk_entry_get_text(GTK_ENTRY(filter_entry_));
+ gtk_widget_set_sensitive(filter_clear_button_, filter_text && *filter_text);
+
if (selected) {
CookieTreeNode::DetailedInfo detailed_info =
static_cast<CookieTreeNode*>(
@@ -377,3 +410,35 @@ gboolean CookiesView::OnTreeViewKeyPress(
}
return FALSE;
}
+
+void CookiesView::UpdateFilterResults() {
+ const gchar* text = gtk_entry_get_text(GTK_ENTRY(filter_entry_));
+ if (text) {
+ cookies_tree_model_->UpdateSearchResults(UTF8ToWide(text));
+ SetInitialTreeState();
+ }
+}
+
+// static
+void CookiesView::OnFilterEntryActivated(GtkEntry* entry, CookiesView* window) {
+ window->filter_update_factory_.RevokeAll();
+ window->UpdateFilterResults();
+}
+
+// static
+void CookiesView::OnFilterEntryChanged(GtkEditable* editable,
+ CookiesView* window) {
+ window->filter_update_factory_.RevokeAll();
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ window->filter_update_factory_.NewRunnableMethod(
+ &CookiesView::UpdateFilterResults), kSearchFilterDelayMs);
+ window->EnableControls();
+}
+
+// static
+void CookiesView::OnFilterClearButtonClicked(GtkButton* button,
+ CookiesView* window) {
+ gtk_entry_set_text(GTK_ENTRY(window->filter_entry_), "");
+ window->filter_update_factory_.RevokeAll();
+ window->UpdateFilterResults();
+}
diff --git a/chrome/browser/gtk/options/cookies_view.h b/chrome/browser/gtk/options/cookies_view.h
index dea3da2..1d63c48 100644
--- a/chrome/browser/gtk/options/cookies_view.h
+++ b/chrome/browser/gtk/options/cookies_view.h
@@ -49,6 +49,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
// Helper for initializing cookie details table.
void InitCookieDetailRow(int row, int label_id, GtkWidget** display_label);
+ // Set the initial selection and tree expanded state.
+ void SetInitialTreeState();
+
// Set sensitivity of buttons based on selection and filter state.
void EnableControls();
@@ -80,11 +83,22 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
static gboolean OnTreeViewKeyPress(GtkWidget* tree_view, GdkEventKey* key,
CookiesView* window);
+ // Filter the list against the text in |filter_entry_|.
+ void UpdateFilterResults();
+
+ // Callbacks for user actions filtering the list.
+ static void OnFilterEntryActivated(GtkEntry* entry, CookiesView* window);
+ static void OnFilterEntryChanged(GtkEditable* editable, CookiesView* window);
+ static void OnFilterClearButtonClicked(GtkButton* button,
+ CookiesView* window);
+
// The parent widget.
GtkWidget* dialog_;
// Widgets of the dialog.
GtkWidget* description_label_;
+ GtkWidget* filter_entry_;
+ GtkWidget* filter_clear_button_;
GtkWidget* remove_button_;
GtkWidget* remove_all_button_;
@@ -105,6 +119,10 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
// The profile.
Profile* profile_;
+ // A factory to construct Runnable Methods so that we can be called back to
+ // re-evaluate the model after the search query string changes.
+ ScopedRunnableMethodFactory<CookiesView> filter_update_factory_;
+
// The Cookies Table model.
scoped_ptr<CookiesTreeModel> cookies_tree_model_;
scoped_ptr<gtk_tree::TreeAdapter> cookies_tree_adapter_;
@@ -118,6 +136,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
FRIEND_TEST(CookiesViewTest, RemoveCookiesByDomain);
FRIEND_TEST(CookiesViewTest, RemoveByDomain);
FRIEND_TEST(CookiesViewTest, RemoveDefaultSelection);
+ FRIEND_TEST(CookiesViewTest, Filter);
+ FRIEND_TEST(CookiesViewTest, FilterRemoveAll);
+ FRIEND_TEST(CookiesViewTest, FilterRemove);
DISALLOW_COPY_AND_ASSIGN(CookiesView);
};
diff --git a/chrome/browser/gtk/options/cookies_view_unittest.cc b/chrome/browser/gtk/options/cookies_view_unittest.cc
index 2160bfa..a81e11a 100644
--- a/chrome/browser/gtk/options/cookies_view_unittest.cc
+++ b/chrome/browser/gtk/options/cookies_view_unittest.cc
@@ -137,8 +137,10 @@ class CookiesViewTest : public testing::Test {
if (!path)
return false;
gtk_tree_selection_select_path(cookies_view.selection_, path);
+ bool rv = gtk_tree_selection_path_is_selected(cookies_view.selection_,
+ path);
gtk_tree_path_free(path);
- return true;
+ return rv;
}
std::string GetSelectedPath(const CookiesView& cookies_view) {
@@ -463,3 +465,182 @@ TEST_F(CookiesViewTest, RemoveDefaultSelection) {
EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_));
}
+
+TEST_F(CookiesViewTest, Filter) {
+ net::CookieMonster* monster = profile_->GetCookieMonster();
+ monster->SetCookie(GURL("http://foo0"), "C=1");
+ monster->SetCookie(GURL("http://bar0"), "D=1");
+ monster->SetCookie(GURL("http://foo1"), "B=1");
+ monster->SetCookie(GURL("http://bar1"), "A=1");
+ CookiesView cookies_view(profile_.get());
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+
+ gtk_entry_set_text(GTK_ENTRY(cookies_view.filter_entry_), "bar");
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+ // Entering text doesn't immediately filter the results.
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ // Results are filtered immediately if you activate (hit enter in the entry).
+ gtk_widget_activate(cookies_view.filter_entry_);
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ gtk_button_clicked(GTK_BUTTON(cookies_view.filter_clear_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+ EXPECT_STREQ("", gtk_entry_get_text(GTK_ENTRY(cookies_view.filter_entry_)));
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+}
+
+TEST_F(CookiesViewTest, FilterRemoveAll) {
+ net::CookieMonster* monster = profile_->GetCookieMonster();
+ monster->SetCookie(GURL("http://foo0"), "C=1");
+ monster->SetCookie(GURL("http://bar0"), "D=1");
+ monster->SetCookie(GURL("http://foo1"), "B=1");
+ monster->SetCookie(GURL("http://bar1"), "A=1");
+ CookiesView cookies_view(profile_.get());
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+
+ gtk_entry_set_text(GTK_ENTRY(cookies_view.filter_entry_), "bar");
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+ // Entering text doesn't immediately filter the results.
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ // Results are filtered immediately if you activate (hit enter in the entry).
+ gtk_widget_activate(cookies_view.filter_entry_);
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A",
+ GetDisplayedCookies(cookies_view).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
+
+ gtk_button_clicked(GTK_BUTTON(cookies_view.remove_all_button_));
+
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
+ EXPECT_STREQ("",
+ GetDisplayedCookies(cookies_view).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+
+ gtk_button_clicked(GTK_BUTTON(cookies_view.filter_clear_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+ EXPECT_STREQ("", gtk_entry_get_text(GTK_ENTRY(cookies_view.filter_entry_)));
+ EXPECT_STREQ("foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+}
+
+TEST_F(CookiesViewTest, FilterRemove) {
+ net::CookieMonster* monster = profile_->GetCookieMonster();
+ monster->SetCookie(GURL("http://foo0"), "C=1");
+ monster->SetCookie(GURL("http://bar0"), "D=1");
+ monster->SetCookie(GURL("http://foo1"), "B=1");
+ monster->SetCookie(GURL("http://bar1"), "A=1");
+ monster->SetCookie(GURL("http://bar1"), "E=1");
+ CookiesView cookies_view(profile_.get());
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,__E,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+ EXPECT_STREQ("D,A,E,C,B", GetMonsterCookies(monster).c_str());
+
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+
+ gtk_entry_set_text(GTK_ENTRY(cookies_view.filter_entry_), "bar");
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+ // Entering text doesn't immediately filter the results.
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,__E,"
+ "foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ // Results are filtered immediately if you activate (hit enter in the entry).
+ gtk_widget_activate(cookies_view.filter_entry_);
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__A,__E",
+ GetDisplayedCookies(cookies_view).c_str());
+
+ ASSERT_TRUE(SelectByPath(cookies_view, "1:0:0"));
+
+ {
+ SCOPED_TRACE("First selection");
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_));
+ CheckDetailsSensitivity(TRUE, cookies_view);
+ }
+
+ gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_));
+
+ {
+ SCOPED_TRACE("First selection removed");
+ EXPECT_STREQ("D,E,C,B", GetMonsterCookies(monster).c_str());
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies,__E",
+ GetDisplayedCookies(cookies_view).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_));
+ EXPECT_STREQ("1:0:0", GetSelectedPath(cookies_view).c_str());
+ CheckDetailsSensitivity(TRUE, cookies_view);
+ }
+
+ gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_));
+
+ {
+ SCOPED_TRACE("Second selection");
+ EXPECT_STREQ("D,C,B", GetMonsterCookies(monster).c_str());
+ EXPECT_STREQ("bar0,_Cookies,__D,"
+ "bar1,_Cookies",
+ GetDisplayedCookies(cookies_view).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_));
+ EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str());
+ CheckDetailsSensitivity(FALSE, cookies_view);
+ }
+
+ ASSERT_TRUE(SelectByPath(cookies_view, "0:0:0"));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_));
+ gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_));
+
+ {
+ SCOPED_TRACE("Second selection removed");
+ EXPECT_STREQ("C,B", GetMonsterCookies(monster).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_));
+ EXPECT_STREQ("0:0", GetSelectedPath(cookies_view).c_str());
+ CheckDetailsSensitivity(FALSE, cookies_view);
+ EXPECT_STREQ("bar0,_Cookies,"
+ "bar1,_Cookies",
+ GetDisplayedCookies(cookies_view).c_str());
+ }
+
+ gtk_button_clicked(GTK_BUTTON(cookies_view.filter_clear_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.filter_clear_button_));
+ EXPECT_STREQ("", gtk_entry_get_text(GTK_ENTRY(cookies_view.filter_entry_)));
+ EXPECT_STREQ("foo0,_Cookies,__C,"
+ "foo1,_Cookies,__B",
+ GetDisplayedCookies(cookies_view).c_str());
+}