summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/content_exceptions_table_model.cc (renamed from chrome/browser/views/options/content_exceptions_table_model.cc)2
-rw-r--r--chrome/browser/content_exceptions_table_model.h (renamed from chrome/browser/views/options/content_exceptions_table_model.h)6
-rw-r--r--chrome/browser/gtk/options/content_exception_editor.cc168
-rw-r--r--chrome/browser/gtk/options/content_exception_editor.h80
-rw-r--r--chrome/browser/gtk/options/content_exceptions_window_gtk.cc270
-rw-r--r--chrome/browser/gtk/options/content_exceptions_window_gtk.h101
-rw-r--r--chrome/browser/gtk/options/content_filter_page_gtk.cc9
-rw-r--r--chrome/browser/gtk/options/cookie_filter_page_gtk.cc11
-rw-r--r--chrome/browser/gtk/options/cookie_filter_page_gtk.h2
-rw-r--r--chrome/browser/gtk/options/languages_page_gtk.cc11
-rw-r--r--chrome/browser/views/options/exception_editor_view.cc2
-rw-r--r--chrome/browser/views/options/exceptions_view.h2
-rwxr-xr-xchrome/chrome_browser.gypi8
-rw-r--r--chrome/common/gtk_tree.cc12
-rw-r--r--chrome/common/gtk_tree.h4
15 files changed, 663 insertions, 25 deletions
diff --git a/chrome/browser/views/options/content_exceptions_table_model.cc b/chrome/browser/content_exceptions_table_model.cc
index a733747..530fc10 100644
--- a/chrome/browser/views/options/content_exceptions_table_model.cc
+++ b/chrome/browser/content_exceptions_table_model.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/views/options/content_exceptions_table_model.h"
+#include "chrome/browser/content_exceptions_table_model.h"
#include "app/l10n_util.h"
#include "app/table_model_observer.h"
diff --git a/chrome/browser/views/options/content_exceptions_table_model.h b/chrome/browser/content_exceptions_table_model.h
index 8016eb0..9ade4d8 100644
--- a/chrome/browser/views/options/content_exceptions_table_model.h
+++ b/chrome/browser/content_exceptions_table_model.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_EXCEPTIONS_TABLE_MODEL_H_
-#define CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_EXCEPTIONS_TABLE_MODEL_H_
+#ifndef CHROME_BROWSER_CONTENT_EXCEPTIONS_TABLE_MODEL_H_
+#define CHROME_BROWSER_CONTENT_EXCEPTIONS_TABLE_MODEL_H_
#include <string>
@@ -51,4 +51,4 @@ class ContentExceptionsTableModel : public TableModel {
DISALLOW_COPY_AND_ASSIGN(ContentExceptionsTableModel);
};
-#endif // CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_EXCEPTIONS_TABLE_MODEL_H_
+#endif // CHROME_BROWSER_CONTENT_EXCEPTIONS_TABLE_MODEL_H_
diff --git a/chrome/browser/gtk/options/content_exception_editor.cc b/chrome/browser/gtk/options/content_exception_editor.cc
new file mode 100644
index 0000000..809a31b
--- /dev/null
+++ b/chrome/browser/gtk/options/content_exception_editor.cc
@@ -0,0 +1,168 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/options/content_exception_editor.h"
+
+#include "app/l10n_util.h"
+#include "base/message_loop.h"
+#include "chrome/browser/content_exceptions_table_model.h"
+#include "chrome/browser/host_content_settings_map.h"
+#include "chrome/common/gtk_util.h"
+#include "googleurl/src/url_canon.h"
+#include "googleurl/src/url_parse.h"
+#include "grit/generated_resources.h"
+#include "net/base/net_util.h"
+
+namespace {
+
+// The settings shown in the combobox if show_ask_ is false;
+static const ContentSetting kNoAskSettings[] = { CONTENT_SETTING_ALLOW,
+ CONTENT_SETTING_BLOCK };
+
+// The settings shown in the combobox if show_ask_ is true;
+static const ContentSetting kAskSettings[] = { CONTENT_SETTING_ALLOW,
+ CONTENT_SETTING_ASK,
+ CONTENT_SETTING_BLOCK };
+
+// Returns true if the host name is valid.
+bool ValidHost(const std::string& host) {
+ if (host.empty())
+ return false;
+
+ url_canon::CanonHostInfo host_info;
+ return !net::CanonicalizeHost(host, &host_info).empty();
+}
+
+} // namespace
+
+ContentExceptionEditor::ContentExceptionEditor(
+ GtkWindow* parent,
+ ContentExceptionEditor::Delegate* delegate,
+ ContentExceptionsTableModel* model,
+ int index,
+ const std::string& host,
+ ContentSetting setting)
+ : delegate_(delegate),
+ model_(model),
+ show_ask_(model->content_type() == CONTENT_SETTINGS_TYPE_COOKIES),
+ index_(index),
+ host_(host),
+ setting_(setting) {
+ dialog_ = gtk_dialog_new_with_buttons(
+ l10n_util::GetStringUTF8(is_new() ?
+ IDS_EXCEPTION_EDITOR_NEW_TITLE :
+ IDS_EXCEPTION_EDITOR_TITLE).c_str(),
+ parent,
+ // Non-modal.
+ static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_OK);
+
+ entry_ = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(entry_), host_.c_str());
+ g_signal_connect(entry_, "changed", G_CALLBACK(OnEntryChanged), this);
+ gtk_entry_set_activates_default(GTK_ENTRY(entry_), TRUE);
+
+ action_combo_ = gtk_combo_box_new_text();
+ for (int i = 0; i < GetItemCount(); ++i) {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(action_combo_),
+ GetTitleFor(i).c_str());
+ }
+ gtk_combo_box_set_active(GTK_COMBO_BOX(action_combo_),
+ IndexForSetting(setting_));
+
+ GtkWidget* table = gtk_util::CreateLabeledControlsGroup(
+ NULL,
+ l10n_util::GetStringUTF8(IDS_EXCEPTION_EDITOR_HOST_TITLE).c_str(),
+ entry_,
+ l10n_util::GetStringUTF8(IDS_EXCEPTION_EDITOR_ACTION_TITLE).c_str(),
+ action_combo_,
+ NULL);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), table);
+
+ // Prime the state of the buttons.
+ OnEntryChanged(GTK_EDITABLE(entry_), this);
+
+ gtk_widget_show_all(dialog_);
+
+ g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this);
+ g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this);
+}
+
+int ContentExceptionEditor::GetItemCount() {
+ return show_ask_ ? arraysize(kAskSettings) : arraysize(kNoAskSettings);
+}
+
+std::string ContentExceptionEditor::GetTitleFor(int index) {
+ switch (SettingForIndex(index)) {
+ case CONTENT_SETTING_ALLOW:
+ return l10n_util::GetStringUTF8(IDS_EXCEPTIONS_ALLOW_BUTTON);
+ case CONTENT_SETTING_BLOCK:
+ return l10n_util::GetStringUTF8(IDS_EXCEPTIONS_BLOCK_BUTTON);
+ case CONTENT_SETTING_ASK:
+ return l10n_util::GetStringUTF8(IDS_EXCEPTIONS_ASK_BUTTON);
+ default:
+ NOTREACHED();
+ }
+ return std::string();
+}
+
+ContentSetting ContentExceptionEditor::SettingForIndex(int index) {
+ return show_ask_ ? kAskSettings[index] : kNoAskSettings[index];
+}
+
+int ContentExceptionEditor::IndexForSetting(ContentSetting setting) {
+ for (int i = 0; i < GetItemCount(); ++i)
+ if (SettingForIndex(i) == setting)
+ return i;
+ NOTREACHED();
+ return 0;
+}
+
+// static
+void ContentExceptionEditor::OnEntryChanged(GtkEditable* entry,
+ ContentExceptionEditor* window) {
+ bool can_accept = false;
+ std::string new_host = gtk_entry_get_text(GTK_ENTRY(window->entry_));
+ if (window->is_new()) {
+ can_accept = ValidHost(new_host) &&
+ (window->model_->IndexOfExceptionByHost(new_host) == -1);
+ } else {
+ can_accept = !new_host.empty() &&
+ (window->host_ == new_host ||
+ (ValidHost(new_host) &&
+ window->model_->IndexOfExceptionByHost(new_host) == -1));
+ }
+
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(window->dialog_),
+ GTK_RESPONSE_OK, can_accept);
+}
+
+// static
+void ContentExceptionEditor::OnResponse(
+ GtkWidget* sender,
+ int response_id,
+ ContentExceptionEditor* window) {
+ if (response_id == GTK_RESPONSE_OK) {
+ // Notify our delegate to update everything.
+ std::string new_host = gtk_entry_get_text(GTK_ENTRY(window->entry_));
+ ContentSetting setting = window->SettingForIndex(gtk_combo_box_get_active(
+ GTK_COMBO_BOX(window->action_combo_)));
+ window->delegate_->AcceptExceptionEdit(new_host, setting, window->index_,
+ window->is_new());
+ }
+
+ gtk_widget_destroy(window->dialog_);
+}
+
+// static
+void ContentExceptionEditor::OnWindowDestroy(
+ GtkWidget* widget,
+ ContentExceptionEditor* editor) {
+ MessageLoop::current()->DeleteSoon(FROM_HERE, editor);
+}
diff --git a/chrome/browser/gtk/options/content_exception_editor.h b/chrome/browser/gtk/options/content_exception_editor.h
new file mode 100644
index 0000000..c71e693
--- /dev/null
+++ b/chrome/browser/gtk/options/content_exception_editor.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_GTK_OPTIONS_CONTENT_EXCEPTION_EDITOR_H_
+#define CHROME_BROWSER_GTK_OPTIONS_CONTENT_EXCEPTION_EDITOR_H_
+
+#include <gtk/gtk.h>
+
+#include <string>
+
+#include "chrome/browser/content_exceptions_table_model.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/content_settings_types.h"
+
+// An editor which lets the user create or edit an individual exception to the
+// current content setting policy. (i.e. let www.google.com always show
+// images). Modal to parent.
+class ContentExceptionEditor {
+ public:
+ class Delegate {
+ public:
+ // Invoked when the user accepts the edit.
+ virtual void AcceptExceptionEdit(const std::string& host,
+ ContentSetting setting,
+ int index,
+ bool is_new) = 0;
+
+ protected:
+ virtual ~Delegate() {}
+ };
+
+ ContentExceptionEditor(GtkWindow* parent,
+ Delegate* delegate,
+ ContentExceptionsTableModel* model,
+ int index,
+ const std::string& host,
+ ContentSetting setting);
+
+ private:
+ // Returns true if we're adding a new item.
+ bool is_new() const { return index_ == -1; }
+
+ // Returns the number of items in the |action_combo_|.
+ int GetItemCount();
+
+ // Returns the string representation for an item in |action_combo_|.
+ std::string GetTitleFor(int index);
+
+ // Changes an index from |action_combo_| into a ContentSetting and vice versa.
+ ContentSetting SettingForIndex(int index);
+ int IndexForSetting(ContentSetting setting);
+
+ // GTK callbacks
+ static void OnEntryChanged(GtkEditable* entry,
+ ContentExceptionEditor* window);
+ static void OnResponse(GtkWidget* sender,
+ int response_id,
+ ContentExceptionEditor* window);
+ static void OnWindowDestroy(GtkWidget* widget,
+ ContentExceptionEditor* editor);
+
+ Delegate* delegate_;
+ ContentExceptionsTableModel* model_;
+ bool show_ask_;
+
+ // Index of the item being edited. If -1, indicates this is a new entry.
+ const int index_;
+ const std::string host_;
+ const ContentSetting setting_;
+
+ // UI widgets.
+ GtkWidget* dialog_;
+ GtkWidget* entry_;
+ GtkWidget* action_combo_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentExceptionEditor);
+};
+
+#endif // CHROME_BROWSER_GTK_OPTIONS_CONTENT_EXCEPTION_EDITOR_H_
diff --git a/chrome/browser/gtk/options/content_exceptions_window_gtk.cc b/chrome/browser/gtk/options/content_exceptions_window_gtk.cc
new file mode 100644
index 0000000..eea927f
--- /dev/null
+++ b/chrome/browser/gtk/options/content_exceptions_window_gtk.cc
@@ -0,0 +1,270 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/options/content_exceptions_window_gtk.h"
+
+#include "app/gfx/gtk_util.h"
+#include "app/l10n_util.h"
+#include "base/message_loop.h"
+#include "chrome/browser/gtk/options/content_exception_editor.h"
+#include "chrome/common/gtk_util.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+
+namespace {
+
+// Singletons for each possible exception window.
+ContentExceptionsWindowGtk* instances[CONTENT_SETTINGS_NUM_TYPES] = { NULL };
+
+// Response ids for our custom buttons.
+enum {
+ RESPONSE_ADD = 1,
+ RESPONSE_EDIT,
+ RESPONSE_REMOVE,
+ RESPONSE_REMOVE_ALL
+};
+
+GtkWidget* BuildDialogButton(GtkWidget* dialog, int ids_id,
+ const gchar* stock_id, gint response_id) {
+ GtkWidget* widget = gtk_util::AddButtonToDialog(
+ dialog,
+ gtk_util::ConvertAcceleratorsFromWindowsStyle(
+ l10n_util::GetStringUTF8(ids_id)).c_str(),
+ stock_id,
+ response_id);
+ gtk_button_set_use_underline(GTK_BUTTON(widget), TRUE);
+ gtk_button_box_set_child_secondary(
+ GTK_BUTTON_BOX(GTK_DIALOG(dialog)->action_area),
+ widget,
+ TRUE);
+
+ return widget;
+}
+
+} // namespace
+
+// static
+void ContentExceptionsWindowGtk::ShowExceptionsWindow(
+ GtkWindow* parent,
+ HostContentSettingsMap* map,
+ ContentSettingsType type) {
+ DCHECK(map);
+ DCHECK(type < CONTENT_SETTINGS_NUM_TYPES);
+
+ if (!instances[type]) {
+ // Create the options window.
+ instances[type] = new ContentExceptionsWindowGtk(parent, map, type);
+ }
+}
+
+ContentExceptionsWindowGtk::~ContentExceptionsWindowGtk() {
+}
+
+ContentExceptionsWindowGtk::ContentExceptionsWindowGtk(
+ GtkWindow* parent,
+ HostContentSettingsMap* map,
+ ContentSettingsType type) {
+ // Build the model adapters that translate views and TableModels into
+ // something GTK can use.
+ list_store_ = gtk_list_store_new(COL_COUNT, G_TYPE_STRING, G_TYPE_STRING);
+ treeview_ = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store_));
+ g_object_unref(list_store_);
+
+ // Set up the properties of the treeview
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview_), TRUE);
+
+ GtkTreeViewColumn* hostname_column = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(IDS_EXCEPTIONS_HOSTNAME_HEADER).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", COL_HOSTNAME,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_), hostname_column);
+
+ GtkTreeViewColumn* action_column = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(IDS_EXCEPTIONS_ACTION_HEADER).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", COL_ACTION,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_), action_column);
+
+ treeview_selection_ = gtk_tree_view_get_selection(
+ GTK_TREE_VIEW(treeview_));
+ gtk_tree_selection_set_mode(treeview_selection_, GTK_SELECTION_MULTIPLE);
+ g_signal_connect(treeview_selection_, "changed",
+ G_CALLBACK(OnSelectionChanged), this);
+
+ // Bind |list_store_| to our C++ model.
+ model_.reset(new ContentExceptionsTableModel(map, type));
+ model_adapter_.reset(new gtk_tree::TableAdapter(this, list_store_,
+ model_.get()));
+ // Force a reload of everything to copy data into |list_store_|.
+ model_adapter_->OnModelChanged();
+
+ dialog_ = gtk_dialog_new_with_buttons(
+ GetWindowTitle().c_str(),
+ parent,
+ static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL);
+ // Allow browser windows to go in front of the options dialog in metacity.
+ gtk_window_set_type_hint(GTK_WINDOW(dialog_), GDK_WINDOW_TYPE_HINT_NORMAL);
+ gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
+ gtk_util::kContentAreaSpacing);
+
+ // Create a scrolled window to wrap the treeview widget in order to have a
+ // frame.
+ GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled),
+ GTK_SHADOW_ETCHED_IN);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), scrolled);
+
+ // Add the main tree view to the scrolled window.
+ gtk_container_add(GTK_CONTAINER(scrolled), treeview_);
+
+ BuildDialogButton(dialog_, IDS_EXCEPTIONS_ADD_BUTTON,
+ GTK_STOCK_ADD, RESPONSE_ADD);
+ edit_button_ = BuildDialogButton(dialog_, IDS_EXCEPTIONS_EDIT_BUTTON,
+ GTK_STOCK_EDIT, RESPONSE_EDIT);
+ remove_button_ = BuildDialogButton(dialog_, IDS_EXCEPTIONS_REMOVE_BUTTON,
+ GTK_STOCK_REMOVE, RESPONSE_REMOVE);
+ remove_all_button_ = BuildDialogButton(
+ dialog_, IDS_EXCEPTIONS_REMOVEALL_BUTTON,
+ GTK_STOCK_CLEAR, RESPONSE_REMOVE_ALL);
+
+ UpdateButtonState();
+
+ gtk_widget_show_all(dialog_);
+
+ g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this);
+ g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this);
+}
+
+void ContentExceptionsWindowGtk::SetColumnValues(int row, GtkTreeIter* iter) {
+ std::wstring hostname = model_->GetText(row, IDS_EXCEPTIONS_HOSTNAME_HEADER);
+ gtk_list_store_set(list_store_, iter, COL_HOSTNAME,
+ WideToUTF8(hostname).c_str(), -1);
+
+ std::wstring action = model_->GetText(row, IDS_EXCEPTIONS_ACTION_HEADER);
+ gtk_list_store_set(list_store_, iter, COL_ACTION,
+ WideToUTF8(action).c_str(), -1);
+}
+
+void ContentExceptionsWindowGtk::AcceptExceptionEdit(const std::string& host,
+ ContentSetting setting,
+ int index,
+ bool is_new) {
+ if (!is_new)
+ model_->RemoveException(index);
+ model_->AddException(host, setting);
+
+ int new_index = model_->IndexOfExceptionByHost(host);
+ DCHECK(new_index != -1);
+
+ GtkTreePath* path = gtk_tree_path_new_from_indices(new_index, -1);
+ gtk_tree_selection_select_path(treeview_selection_, path);
+ gtk_tree_path_free(path);
+
+ UpdateButtonState();
+}
+
+void ContentExceptionsWindowGtk::UpdateButtonState() {
+ int num_selected = gtk_tree_selection_count_selected_rows(
+ treeview_selection_);
+ int row_count = gtk_tree_model_iter_n_children(
+ GTK_TREE_MODEL(list_store_), NULL);
+
+ // TODO(erg): http://crbug.com/34177 , support editing of more than one entry
+ // at a time.
+ gtk_widget_set_sensitive(edit_button_, num_selected == 1);
+ gtk_widget_set_sensitive(remove_button_, num_selected >= 1);
+ gtk_widget_set_sensitive(remove_all_button_, row_count > 0);
+}
+
+void ContentExceptionsWindowGtk::Add() {
+ new ContentExceptionEditor(GTK_WINDOW(dialog_),
+ this, model_.get(), -1, std::string(),
+ CONTENT_SETTING_BLOCK);
+}
+
+void ContentExceptionsWindowGtk::Edit() {
+ std::set<int> indices;
+ gtk_tree::GetSelectedIndicies(treeview_selection_, &indices);
+ DCHECK_GT(indices.size(), 0u);
+ int index = *indices.begin();
+ const HostContentSettingsMap::HostSettingPair& entry =
+ model_->entry_at(index);
+ new ContentExceptionEditor(GTK_WINDOW(dialog_), this, model_.get(), index,
+ entry.first, entry.second);
+}
+
+void ContentExceptionsWindowGtk::Remove() {
+ std::set<int> indices;
+ gtk_tree::GetSelectedIndicies(treeview_selection_, &indices);
+
+ for (std::set<int>::reverse_iterator i = indices.rbegin();
+ i != indices.rend(); ++i) {
+ model_->RemoveException(*i);
+ }
+
+ UpdateButtonState();
+}
+
+void ContentExceptionsWindowGtk::RemoveAll() {
+ model_->RemoveAll();
+ UpdateButtonState();
+}
+
+std::string ContentExceptionsWindowGtk::GetWindowTitle() const {
+ switch (model_->content_type()) {
+ case CONTENT_SETTINGS_TYPE_COOKIES:
+ return l10n_util::GetStringUTF8(IDS_COOKIE_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_IMAGES:
+ return l10n_util::GetStringUTF8(IDS_IMAGES_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
+ return l10n_util::GetStringUTF8(IDS_JS_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_PLUGINS:
+ return l10n_util::GetStringUTF8(IDS_PLUGINS_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_POPUPS:
+ return l10n_util::GetStringUTF8(IDS_POPUP_EXCEPTION_TITLE);
+ default:
+ NOTREACHED();
+ }
+ return std::string();
+}
+
+// static
+void ContentExceptionsWindowGtk::OnResponse(
+ GtkDialog* dialog,
+ int response_id,
+ ContentExceptionsWindowGtk* window) {
+ if (response_id == RESPONSE_ADD) {
+ window->Add();
+ } else if (response_id == RESPONSE_EDIT) {
+ window->Edit();
+ } else if (response_id == RESPONSE_REMOVE) {
+ window->Remove();
+ } else if (response_id == RESPONSE_REMOVE_ALL) {
+ window->RemoveAll();
+ } else {
+ gtk_widget_destroy(window->dialog_);
+ }
+}
+
+// static
+void ContentExceptionsWindowGtk::OnWindowDestroy(
+ GtkWidget* widget,
+ ContentExceptionsWindowGtk* window) {
+ instances[window->model_->content_type()] = NULL;
+ MessageLoop::current()->DeleteSoon(FROM_HERE, window);
+}
+
+// static
+void ContentExceptionsWindowGtk::OnSelectionChanged(
+ GtkTreeSelection *selection,
+ ContentExceptionsWindowGtk* languages_page) {
+ languages_page->UpdateButtonState();
+}
diff --git a/chrome/browser/gtk/options/content_exceptions_window_gtk.h b/chrome/browser/gtk/options/content_exceptions_window_gtk.h
new file mode 100644
index 0000000..d2dae62
--- /dev/null
+++ b/chrome/browser/gtk/options/content_exceptions_window_gtk.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_GTK_OPTIONS_CONTENT_EXCEPTIONS_WINDOW_GTK_H_
+#define CHROME_BROWSER_GTK_OPTIONS_CONTENT_EXCEPTIONS_WINDOW_GTK_H_
+
+#include <gtk/gtk.h>
+
+#include <string>
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/content_exceptions_table_model.h"
+#include "chrome/browser/gtk/options/content_exception_editor.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/content_settings_types.h"
+#include "chrome/common/gtk_tree.h"
+
+class HostContentSettingsMap;
+
+// Dialog that lists each of the exceptions to the current content policy, and
+// has options for adding/editing/removing entries. Modal to parrent.
+class ContentExceptionsWindowGtk : public gtk_tree::TableAdapter::Delegate,
+ public ContentExceptionEditor::Delegate {
+ public:
+ static void ShowExceptionsWindow(GtkWindow* window,
+ HostContentSettingsMap* map,
+ ContentSettingsType content_type);
+
+ ~ContentExceptionsWindowGtk();
+
+ // gtk_tree::TableAdapter::Delegate implementation:
+ virtual void SetColumnValues(int row, GtkTreeIter* iter);
+
+ // ContentExceptionEditor::Delegate implementation:
+ virtual void AcceptExceptionEdit(const std::string& host,
+ ContentSetting setting,
+ int index,
+ bool is_new);
+
+ private:
+ // Column ids for |list_store_|.
+ enum {
+ COL_HOSTNAME,
+ COL_ACTION,
+ COL_COUNT
+ };
+
+ ContentExceptionsWindowGtk(GtkWindow* parent,
+ HostContentSettingsMap* map,
+ ContentSettingsType type);
+
+ // Updates which buttons are enabled.
+ void UpdateButtonState();
+
+ // Callbacks for the buttons.
+ void Add();
+ void Edit();
+ void Remove();
+ void RemoveAll();
+
+ // Returns the title of the window (changes based on what ContentSettingsType
+ // was set to in the constructor).
+ std::string GetWindowTitle() const;
+
+ // GTK Callbacks
+ static void OnResponse(GtkDialog* dialog,
+ int response_id,
+ ContentExceptionsWindowGtk* window);
+ static void OnWindowDestroy(GtkWidget* widget,
+ ContentExceptionsWindowGtk* window);
+ static void OnSelectionChanged(GtkTreeSelection *selection,
+ ContentExceptionsWindowGtk* languages_page);
+
+ // The list presented in |treeview_|; a gobject instead of a C++ object.
+ GtkListStore* list_store_;
+
+ // The C++, views-ish, cross-platform model class that actually contains the
+ // gold standard data.
+ scoped_ptr<ContentExceptionsTableModel> model_;
+
+ // The adapter that ferries data back and forth between |model_| and
+ // |list_store_| whenever either of them change.
+ scoped_ptr<gtk_tree::TableAdapter> model_adapter_;
+
+ // The exception window.
+ GtkWidget* dialog_;
+
+ // The treeview that presents the site/action pairs.
+ GtkWidget* treeview_;
+
+ // The current user selection from |treeview_|.
+ GtkTreeSelection* treeview_selection_;
+
+ // Buttons.
+ GtkWidget* edit_button_;
+ GtkWidget* remove_button_;
+ GtkWidget* remove_all_button_;
+};
+
+#endif // CHROME_BROWSER_GTK_OPTIONS_CONTENT_EXCEPTIONS_WINDOW_GTK_H_
diff --git a/chrome/browser/gtk/options/content_filter_page_gtk.cc b/chrome/browser/gtk/options/content_filter_page_gtk.cc
index 5bab461..b575325 100644
--- a/chrome/browser/gtk/options/content_filter_page_gtk.cc
+++ b/chrome/browser/gtk/options/content_filter_page_gtk.cc
@@ -7,6 +7,7 @@
#include "app/l10n_util.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/profile.h"
+#include "chrome/browser/gtk/options/content_exceptions_window_gtk.h"
#include "chrome/browser/gtk/options/options_layout_gtk.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/pref_names.h"
@@ -88,8 +89,6 @@ GtkWidget* ContentFilterPageGtk::InitGroup() {
GtkWidget* exceptions_button = gtk_button_new_with_label(
l10n_util::GetStringUTF8(IDS_COOKIES_EXCEPTIONS_BUTTON).c_str());
- // TODO(erg): Disable the exceptions button until that is implemented.
- gtk_widget_set_sensitive(exceptions_button, FALSE);
g_signal_connect(G_OBJECT(exceptions_button), "clicked",
G_CALLBACK(OnExceptionsClicked), this);
@@ -117,5 +116,9 @@ void ContentFilterPageGtk::OnAllowToggled(
void ContentFilterPageGtk::OnExceptionsClicked(
GtkWidget* button,
ContentFilterPageGtk* content_page) {
- // TODO(erg): Implement a GTK equivalent of ExceptionsView.
+ HostContentSettingsMap* settings_map =
+ content_page->profile()->GetHostContentSettingsMap();
+ ContentExceptionsWindowGtk::ShowExceptionsWindow(
+ GTK_WINDOW(gtk_widget_get_toplevel(button)),
+ settings_map, content_page->content_type_);
}
diff --git a/chrome/browser/gtk/options/cookie_filter_page_gtk.cc b/chrome/browser/gtk/options/cookie_filter_page_gtk.cc
index a1b4108..97ce956 100644
--- a/chrome/browser/gtk/options/cookie_filter_page_gtk.cc
+++ b/chrome/browser/gtk/options/cookie_filter_page_gtk.cc
@@ -9,6 +9,7 @@
#include "chrome/browser/browsing_data_local_storage_helper.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
+#include "chrome/browser/gtk/options/content_exceptions_window_gtk.h"
#include "chrome/browser/gtk/options/cookies_view.h"
#include "chrome/browser/gtk/options/options_layout_gtk.h"
#include "chrome/browser/host_content_settings_map.h"
@@ -107,8 +108,6 @@ GtkWidget* CookieFilterPageGtk::InitCookieStoringGroup() {
// Exception button.
GtkWidget* exceptions_button = gtk_button_new_with_label(
l10n_util::GetStringUTF8(IDS_COOKIES_EXCEPTIONS_BUTTON).c_str());
- // TODO(erg): Disable the exceptions button until that is implemented.
- gtk_widget_set_sensitive(exceptions_button, FALSE);
g_signal_connect(G_OBJECT(exceptions_button), "clicked",
G_CALLBACK(OnExceptionsClicked), this);
gtk_box_pack_start(GTK_BOX(vbox), WrapInHBox(exceptions_button),
@@ -171,9 +170,13 @@ void CookieFilterPageGtk::OnCookiesAllowToggled(
}
void CookieFilterPageGtk::OnExceptionsClicked(
- GtkToggleButton* toggle_button,
+ GtkWidget* button,
CookieFilterPageGtk* cookie_page) {
- // TODO(erg): Implement the exceptions button.
+ HostContentSettingsMap* settings_map =
+ cookie_page->profile()->GetHostContentSettingsMap();
+ ContentExceptionsWindowGtk::ShowExceptionsWindow(
+ GTK_WINDOW(gtk_widget_get_toplevel(button)),
+ settings_map, CONTENT_SETTINGS_TYPE_COOKIES);
}
void CookieFilterPageGtk::OnBlock3rdpartyToggled(
diff --git a/chrome/browser/gtk/options/cookie_filter_page_gtk.h b/chrome/browser/gtk/options/cookie_filter_page_gtk.h
index 7d805ca..6c554c2 100644
--- a/chrome/browser/gtk/options/cookie_filter_page_gtk.h
+++ b/chrome/browser/gtk/options/cookie_filter_page_gtk.h
@@ -34,7 +34,7 @@ class CookieFilterPageGtk : public OptionsPageBase {
// GTK callbacks
static void OnCookiesAllowToggled(GtkWidget* toggle_button,
CookieFilterPageGtk* cookie_page);
- static void OnExceptionsClicked(GtkToggleButton* toggle_button,
+ static void OnExceptionsClicked(GtkWidget* toggle_button,
CookieFilterPageGtk* cookie_page);
static void OnBlock3rdpartyToggled(GtkToggleButton* toggle_button,
CookieFilterPageGtk* cookie_page);
diff --git a/chrome/browser/gtk/options/languages_page_gtk.cc b/chrome/browser/gtk/options/languages_page_gtk.cc
index 8ac6a3e..2f17c9c 100644
--- a/chrome/browser/gtk/options/languages_page_gtk.cc
+++ b/chrome/browser/gtk/options/languages_page_gtk.cc
@@ -374,16 +374,9 @@ void LanguagesPageGtk::OnAddButtonClicked(GtkButton* button,
// static
void LanguagesPageGtk::OnRemoveButtonClicked(GtkButton* button,
LanguagesPageGtk* languages_page) {
- GList* list = gtk_tree_selection_get_selected_rows(
- languages_page->language_order_selection_, NULL);
std::set<int> selected_rows;
- GList* node;
- for (node = list; node != NULL; node = node->next) {
- selected_rows.insert(
- gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(node->data)));
- }
- g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
- g_list_free(list);
+ gtk_tree::GetSelectedIndicies(languages_page->language_order_selection_,
+ &selected_rows);
int selected_row = 0;
for (std::set<int>::reverse_iterator selected = selected_rows.rbegin();
diff --git a/chrome/browser/views/options/exception_editor_view.cc b/chrome/browser/views/options/exception_editor_view.cc
index 63265781..32a772b 100644
--- a/chrome/browser/views/options/exception_editor_view.cc
+++ b/chrome/browser/views/options/exception_editor_view.cc
@@ -5,8 +5,8 @@
#include "chrome/browser/views/options/exception_editor_view.h"
#include "app/l10n_util.h"
+#include "chrome/browser/content_exceptions_table_model.h"
#include "chrome/browser/host_content_settings_map.h"
-#include "chrome/browser/views/options/content_exceptions_table_model.h"
#include "googleurl/src/url_canon.h"
#include "googleurl/src/url_parse.h"
#include "grit/generated_resources.h"
diff --git a/chrome/browser/views/options/exceptions_view.h b/chrome/browser/views/options/exceptions_view.h
index ca3b110..bc33564 100644
--- a/chrome/browser/views/options/exceptions_view.h
+++ b/chrome/browser/views/options/exceptions_view.h
@@ -7,7 +7,7 @@
#include <string>
-#include "chrome/browser/views/options/content_exceptions_table_model.h"
+#include "chrome/browser/content_exceptions_table_model.h"
#include "chrome/browser/views/options/exception_editor_view.h"
#include "chrome/common/content_settings.h"
#include "chrome/common/content_settings_types.h"
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index aafafd3..1cecec6 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -688,6 +688,8 @@
'browser/cocoa/window_size_autosaver.mm',
'browser/command_updater.cc',
'browser/command_updater.h',
+ 'browser/content_exceptions_table_model.cc',
+ 'browser/content_exceptions_table_model.h',
'browser/cookie_modal_dialog.cc',
'browser/cookie_modal_dialog.h',
'browser/cookie_modal_dialog_views.cc',
@@ -1100,6 +1102,10 @@
'browser/gtk/options/advanced_contents_gtk.h',
'browser/gtk/options/advanced_page_gtk.cc',
'browser/gtk/options/advanced_page_gtk.h',
+ 'browser/gtk/options/content_exception_editor.cc',
+ 'browser/gtk/options/content_exception_editor.h',
+ 'browser/gtk/options/content_exceptions_window_gtk.cc',
+ 'browser/gtk/options/content_exceptions_window_gtk.h',
'browser/gtk/options/content_filter_page_gtk.cc',
'browser/gtk/options/content_filter_page_gtk.h',
'browser/gtk/options/content_page_gtk.cc',
@@ -2018,8 +2024,6 @@
'browser/views/options/advanced_contents_view.h',
'browser/views/options/advanced_page_view.cc',
'browser/views/options/advanced_page_view.h',
- 'browser/views/options/content_exceptions_table_model.cc',
- 'browser/views/options/content_exceptions_table_model.h',
'browser/views/options/content_page_view.cc',
'browser/views/options/content_page_view.h',
'browser/views/options/content_filter_page_view.cc',
diff --git a/chrome/common/gtk_tree.cc b/chrome/common/gtk_tree.cc
index 625c248..a1ff19f 100644
--- a/chrome/common/gtk_tree.cc
+++ b/chrome/common/gtk_tree.cc
@@ -65,6 +65,18 @@ bool RemoveRecursively(GtkTreeStore* tree_store, GtkTreeIter* iter) {
return gtk_tree_store_remove(tree_store, iter);
}
+void GetSelectedIndicies(GtkTreeSelection* selection, std::set<int>* out) {
+ GList* list = gtk_tree_selection_get_selected_rows(
+ selection, NULL);
+ GList* node;
+ for (node = list; node != NULL; node = node->next) {
+ out->insert(
+ gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(node->data)));
+ }
+ g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free(list);
+}
+
////////////////////////////////////////////////////////////////////////////////
// TableAdapter
diff --git a/chrome/common/gtk_tree.h b/chrome/common/gtk_tree.h
index 2b2f893..4c2f38e 100644
--- a/chrome/common/gtk_tree.h
+++ b/chrome/common/gtk_tree.h
@@ -6,6 +6,7 @@
#define CHROME_COMMON_GTK_TREE_H_
#include <gtk/gtk.h>
+#include <set>
#include <vector>
#include "app/table_model_observer.h"
@@ -36,6 +37,9 @@ void SelectAndFocusRowNum(int row, GtkTreeView* tree_view);
// valid.
bool RemoveRecursively(GtkTreeStore* tree_store, GtkTreeIter* iter);
+// Writes all the indexes of selected rows into |out|.
+void GetSelectedIndicies(GtkTreeSelection* selection, std::set<int>* out);
+
// A helper class for populating a GtkListStore from a TableModel.
class TableAdapter : public TableModelObserver {
public: