806 lines
28 KiB
C
806 lines
28 KiB
C
|
/*
|
||
|
Copyright (C) 2013 Stephan Haller <nomad@froevel.de>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
See the file COPYING for the full license text.
|
||
|
*/
|
||
|
|
||
|
#include "cookie-permission-manager-preferences-window.h"
|
||
|
|
||
|
/* Define this class in GObject system */
|
||
|
G_DEFINE_TYPE(CookiePermissionManagerPreferencesWindow,
|
||
|
cookie_permission_manager_preferences_window,
|
||
|
GTK_TYPE_DIALOG)
|
||
|
|
||
|
/* Properties */
|
||
|
enum
|
||
|
{
|
||
|
PROP_0,
|
||
|
|
||
|
PROP_MANAGER,
|
||
|
|
||
|
PROP_LAST
|
||
|
};
|
||
|
|
||
|
static GParamSpec* CookiePermissionManagerPreferencesWindowProperties[PROP_LAST]={ 0, };
|
||
|
|
||
|
/* Private structure - access only by public API if needed */
|
||
|
#define COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW_GET_PRIVATE(obj) \
|
||
|
(G_TYPE_INSTANCE_GET_PRIVATE((obj), TYPE_COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW, CookiePermissionManagerPreferencesWindowPrivate))
|
||
|
|
||
|
struct _CookiePermissionManagerPreferencesWindowPrivate
|
||
|
{
|
||
|
/* Extension related */
|
||
|
CookiePermissionManager *manager;
|
||
|
sqlite3 *database;
|
||
|
|
||
|
/* Dialog related */
|
||
|
GtkWidget *contentArea;
|
||
|
GtkListStore *listStore;
|
||
|
GtkWidget *list;
|
||
|
GtkTreeSelection *listSelection;
|
||
|
GtkWidget *deleteButton;
|
||
|
GtkWidget *deleteAllButton;
|
||
|
GtkWidget *askForUnknownPolicyCheckbox;
|
||
|
GtkWidget *addDomainEntry;
|
||
|
GtkWidget *addDomainPolicyCombo;
|
||
|
GtkWidget *addDomainButton;
|
||
|
|
||
|
gint signalManagerChangedDatabaseID;
|
||
|
gint signalManagerAskForUnknownPolicyID;
|
||
|
gint signalAskForUnknownPolicyID;
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
DOMAIN_COLUMN,
|
||
|
POLICY_COLUMN,
|
||
|
N_COLUMN
|
||
|
};
|
||
|
|
||
|
|
||
|
/* IMPLEMENTATION: Private variables and methods */
|
||
|
|
||
|
/* "Add domain"-button was pressed */
|
||
|
static void _cookie_permission_manager_preferences_on_add_domain_clicked(CookiePermissionManagerPreferencesWindow *self,
|
||
|
gpointer *inUserData)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
gchar *domain;
|
||
|
const gchar *domainStart, *domainEnd;
|
||
|
gchar *realDomain;
|
||
|
GtkTreeIter policyIter;
|
||
|
|
||
|
g_return_if_fail(priv->database);
|
||
|
|
||
|
/* Get domain name entered */
|
||
|
domain=g_hostname_to_ascii(gtk_entry_get_text(GTK_ENTRY(priv->addDomainEntry)));
|
||
|
|
||
|
/* Trim whitespaces from start and end of entered domain name */
|
||
|
domainStart=domain;
|
||
|
while(*domainStart && g_ascii_isspace(*domainStart)) domainStart++;
|
||
|
|
||
|
domainEnd=domain+strlen(domain)-1;
|
||
|
while(*domainEnd && g_ascii_isspace(*domainEnd)) domainEnd--;
|
||
|
if(domainEnd<=domainStart) return;
|
||
|
|
||
|
/* Seperate domain name from whitespaces */
|
||
|
realDomain=g_strndup(domain, domainEnd-domainStart+1);
|
||
|
if(!realDomain) return;
|
||
|
|
||
|
/* Get policy from combo box */
|
||
|
if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(priv->addDomainPolicyCombo), &policyIter))
|
||
|
{
|
||
|
gchar *sql;
|
||
|
gchar *error=NULL;
|
||
|
gint success;
|
||
|
gint policy;
|
||
|
gchar *policyName;
|
||
|
|
||
|
/* Get policy value to set for domain */
|
||
|
gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(priv->addDomainPolicyCombo)),
|
||
|
&policyIter,
|
||
|
0, &policy,
|
||
|
1, &policyName,
|
||
|
-1);
|
||
|
|
||
|
/* Add domain name and the selected policy to database */
|
||
|
sql=sqlite3_mprintf("INSERT OR REPLACE INTO policies (domain, value) VALUES ('%q', %d);",
|
||
|
realDomain,
|
||
|
policy);
|
||
|
success=sqlite3_exec(priv->database, sql, NULL, NULL, &error);
|
||
|
|
||
|
/* Show error message if any */
|
||
|
if(success==SQLITE_OK)
|
||
|
{
|
||
|
gtk_list_store_append(priv->listStore, &policyIter);
|
||
|
gtk_list_store_set(priv->listStore,
|
||
|
&policyIter,
|
||
|
DOMAIN_COLUMN, realDomain,
|
||
|
POLICY_COLUMN, policyName,
|
||
|
-1);
|
||
|
}
|
||
|
else g_warning(_("SQL fails: %s"), error);
|
||
|
|
||
|
|
||
|
if(error) sqlite3_free(error);
|
||
|
|
||
|
/* Free allocated resources */
|
||
|
sqlite3_free(sql);
|
||
|
}
|
||
|
|
||
|
/* Free allocated resources */
|
||
|
g_free(realDomain);
|
||
|
g_free(domain);
|
||
|
}
|
||
|
|
||
|
/* Entry containing domain name which may be added to list has changed */
|
||
|
static void _cookie_permission_manager_preferences_on_add_domain_entry_changed(CookiePermissionManagerPreferencesWindow *self,
|
||
|
GtkEditable *inEditable)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
gchar *asciiDomain, *checkAsciiDomain;
|
||
|
gchar *asciiDomainStart, *asciiDomainEnd;
|
||
|
gint dots;
|
||
|
gboolean isValid=FALSE;
|
||
|
|
||
|
/* Get ASCII representation of domain name entered */
|
||
|
asciiDomain=g_hostname_to_ascii(gtk_entry_get_text(GTK_ENTRY(priv->addDomainEntry)));
|
||
|
|
||
|
/* Trim whitespaces from start and end of entered domain name */
|
||
|
asciiDomainStart=asciiDomain;
|
||
|
while(*asciiDomainStart && g_ascii_isspace(*asciiDomainStart)) asciiDomainStart++;
|
||
|
|
||
|
asciiDomainEnd=asciiDomain+strlen(asciiDomain)-1;
|
||
|
while(*asciiDomainEnd && g_ascii_isspace(*asciiDomainEnd)) asciiDomainEnd--;
|
||
|
|
||
|
/* We allow only domain names and not cookie domain name so entered name
|
||
|
* must not start with a dot
|
||
|
*/
|
||
|
checkAsciiDomain=asciiDomainStart;
|
||
|
isValid=(*asciiDomainStart!='.' && *asciiDomainEnd!='.');
|
||
|
|
||
|
/* Now check if ASCII domain name is valid (very very simple check)
|
||
|
* and contains a hostname besides TLD
|
||
|
*/
|
||
|
dots=0;
|
||
|
|
||
|
while(*checkAsciiDomain &&
|
||
|
checkAsciiDomain<=asciiDomainEnd &&
|
||
|
isValid)
|
||
|
{
|
||
|
/* Check for dot as (at least the first one) seperates hostname from TLD */
|
||
|
if(*checkAsciiDomain=='.') dots++;
|
||
|
else
|
||
|
{
|
||
|
/* Check for valid characters in domain name.
|
||
|
* Valid domain name can only contain ASCII alphabetic letters,
|
||
|
* digits (0-9) and hyphens ('-')
|
||
|
*/
|
||
|
isValid=(g_ascii_isalpha(*checkAsciiDomain) ||
|
||
|
g_ascii_isdigit(*checkAsciiDomain) ||
|
||
|
*checkAsciiDomain=='-');
|
||
|
}
|
||
|
|
||
|
checkAsciiDomain++;
|
||
|
}
|
||
|
|
||
|
/* If we have not reached the trimmed end of string something must have gone wrong
|
||
|
* and domain entered is invalid. If domain name entered excluding dots is longer
|
||
|
* than 255 character it is also invalid.
|
||
|
*/
|
||
|
if(checkAsciiDomain<asciiDomainEnd) isValid=FALSE;
|
||
|
else if((checkAsciiDomain-asciiDomainStart-dots)>255) isValid=FALSE;
|
||
|
|
||
|
/* We need at least one dot in domain name (minimum number of dots to seperate
|
||
|
* hostname from TLD)
|
||
|
*/
|
||
|
isValid=(isValid && dots>0);
|
||
|
|
||
|
/* Activate "add" button if hostname (equal to domain name here) is valid */
|
||
|
gtk_widget_set_sensitive(priv->addDomainButton, isValid);
|
||
|
|
||
|
/* Free allocated resources */
|
||
|
g_free(asciiDomain);
|
||
|
}
|
||
|
|
||
|
/* Fill domain list with stored policies */
|
||
|
static void _cookie_permission_manager_preferences_window_fill(CookiePermissionManagerPreferencesWindow *self)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
gint success;
|
||
|
sqlite3_stmt *statement=NULL;
|
||
|
|
||
|
/* Clear tree/list view */
|
||
|
gtk_list_store_clear(priv->listStore);
|
||
|
|
||
|
/* If no database is present return here */
|
||
|
if(!priv->database) return;
|
||
|
|
||
|
/* Fill list store with policies from database */
|
||
|
success=sqlite3_prepare_v2(priv->database,
|
||
|
"SELECT domain, value FROM policies;",
|
||
|
-1,
|
||
|
&statement,
|
||
|
NULL);
|
||
|
if(statement && success==SQLITE_OK)
|
||
|
{
|
||
|
gchar *domain;
|
||
|
gint policy;
|
||
|
gchar *policyName;
|
||
|
GtkTreeIter iter;
|
||
|
|
||
|
while(sqlite3_step(statement)==SQLITE_ROW)
|
||
|
{
|
||
|
/* Get values */
|
||
|
domain=(gchar*)sqlite3_column_text(statement, 0);
|
||
|
policy=sqlite3_column_int(statement, 1);
|
||
|
|
||
|
switch(policy)
|
||
|
{
|
||
|
case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT:
|
||
|
policyName=_("Accept");
|
||
|
break;
|
||
|
|
||
|
case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION:
|
||
|
policyName=_("Accept for session");
|
||
|
break;
|
||
|
|
||
|
case COOKIE_PERMISSION_MANAGER_POLICY_BLOCK:
|
||
|
policyName=_("Block");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
policyName=NULL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(policyName)
|
||
|
{
|
||
|
gtk_list_store_append(priv->listStore, &iter);
|
||
|
gtk_list_store_set(priv->listStore,
|
||
|
&iter,
|
||
|
DOMAIN_COLUMN, domain,
|
||
|
POLICY_COLUMN, policyName,
|
||
|
-1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else g_warning(_("SQL fails: %s"), sqlite3_errmsg(priv->database));
|
||
|
|
||
|
sqlite3_finalize(statement);
|
||
|
}
|
||
|
|
||
|
/* Database instance in manager changed */
|
||
|
static void _cookie_permission_manager_preferences_window_manager_database_changed(CookiePermissionManagerPreferencesWindow *self,
|
||
|
GParamSpec *inSpec,
|
||
|
gpointer inUserData)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
CookiePermissionManager *manager=COOKIE_PERMISSION_MANAGER(inUserData);
|
||
|
const gchar *databaseFilename;
|
||
|
|
||
|
/* Close connection to any open database */
|
||
|
if(priv->database) sqlite3_close(priv->database);
|
||
|
priv->database=NULL;
|
||
|
|
||
|
/* Get pointer to new database and open database */
|
||
|
g_object_get(manager, "database-filename", &databaseFilename, NULL);
|
||
|
if(databaseFilename)
|
||
|
{
|
||
|
gint success;
|
||
|
|
||
|
success=sqlite3_open(databaseFilename, &priv->database);
|
||
|
if(success!=SQLITE_OK)
|
||
|
{
|
||
|
g_warning(_("Could not open database of extenstion: %s"), sqlite3_errmsg(priv->database));
|
||
|
|
||
|
if(priv->database) sqlite3_close(priv->database);
|
||
|
priv->database=NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Fill list with new database */
|
||
|
_cookie_permission_manager_preferences_window_fill(self);
|
||
|
|
||
|
/* Set up availability of management buttons */
|
||
|
gtk_widget_set_sensitive(priv->deleteAllButton, priv->database!=NULL);
|
||
|
gtk_widget_set_sensitive(priv->list, priv->database!=NULL);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Ask-for-unknown-policy in manager changed or check-box changed */
|
||
|
static void _cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed(CookiePermissionManagerPreferencesWindow *self,
|
||
|
GParamSpec *inSpec,
|
||
|
gpointer inUserData)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
CookiePermissionManager *manager=COOKIE_PERMISSION_MANAGER(inUserData);
|
||
|
gboolean doAsk;
|
||
|
|
||
|
/* Get new ask-for-unknown-policy value */
|
||
|
g_object_get(manager, "ask-for-unknown-policy", &doAsk, NULL);
|
||
|
|
||
|
/* Set toogle in widget (but block signal for toggle) */
|
||
|
g_signal_handler_block(priv->askForUnknownPolicyCheckbox, priv->signalAskForUnknownPolicyID);
|
||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->askForUnknownPolicyCheckbox), doAsk);
|
||
|
g_signal_handler_unblock(priv->askForUnknownPolicyCheckbox, priv->signalAskForUnknownPolicyID);
|
||
|
}
|
||
|
|
||
|
static void _cookie_permission_manager_preferences_window_ask_for_unknown_policy_changed(CookiePermissionManagerPreferencesWindow *self,
|
||
|
gpointer *inUserData)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
gboolean doAsk;
|
||
|
|
||
|
/* Get toogle state of widget (but block signal for manager) and set in manager */
|
||
|
g_signal_handler_block(priv->manager, priv->signalManagerAskForUnknownPolicyID);
|
||
|
doAsk=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->askForUnknownPolicyCheckbox));
|
||
|
g_object_set(priv->manager, "ask-for-unknown-policy", doAsk, NULL);
|
||
|
g_signal_handler_unblock(priv->manager, priv->signalManagerAskForUnknownPolicyID);
|
||
|
}
|
||
|
|
||
|
/* Selection in list changed */
|
||
|
void _cookie_permission_manager_preferences_changed_selection(CookiePermissionManagerPreferencesWindow *self,
|
||
|
GtkTreeSelection *inSelection)
|
||
|
{
|
||
|
gboolean selected=(gtk_tree_selection_count_selected_rows(inSelection)>0 ? TRUE: FALSE);
|
||
|
|
||
|
gtk_widget_set_sensitive(self->priv->deleteButton, selected);
|
||
|
}
|
||
|
|
||
|
/* Delete button was clicked on selection */
|
||
|
void _cookie_permission_manager_preferences_on_delete_selection(CookiePermissionManagerPreferencesWindow *self,
|
||
|
GtkButton *inButton)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
GList *rows, *row, *refs=NULL;
|
||
|
GtkTreeRowReference *ref;
|
||
|
GtkTreeModel *model=GTK_TREE_MODEL(priv->listStore);
|
||
|
GtkTreeIter iter;
|
||
|
GtkTreePath *path;
|
||
|
gchar *domain;
|
||
|
gchar *sql;
|
||
|
gint success;
|
||
|
gchar *error;
|
||
|
|
||
|
/* Get selected rows in list and create a row reference because
|
||
|
* we will modify the model while iterating through selected rows
|
||
|
*/
|
||
|
rows=gtk_tree_selection_get_selected_rows(priv->listSelection, &model);
|
||
|
for(row=rows; row; row=row->next)
|
||
|
{
|
||
|
ref=gtk_tree_row_reference_new(model, (GtkTreePath*)row->data);
|
||
|
refs=g_list_prepend(refs, ref);
|
||
|
}
|
||
|
g_list_foreach(rows,(GFunc)gtk_tree_path_free, NULL);
|
||
|
g_list_free(rows);
|
||
|
|
||
|
/* Delete each selected row by its reference */
|
||
|
for(row=refs; row; row=row->next)
|
||
|
{
|
||
|
/* Get domain from selected row */
|
||
|
path=gtk_tree_row_reference_get_path((GtkTreeRowReference*)row->data);
|
||
|
gtk_tree_model_get_iter(model, &iter, path);
|
||
|
gtk_tree_model_get(model, &iter, DOMAIN_COLUMN, &domain, -1);
|
||
|
|
||
|
/* Delete domain from database */
|
||
|
sql=sqlite3_mprintf("DELETE FROM policies WHERE domain='%q';", domain);
|
||
|
success=sqlite3_exec(priv->database,
|
||
|
sql,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&error);
|
||
|
if(success!=SQLITE_OK || error)
|
||
|
{
|
||
|
if(error)
|
||
|
{
|
||
|
g_critical(_("Failed to execute database statement: %s"), error);
|
||
|
sqlite3_free(error);
|
||
|
}
|
||
|
else g_critical(_("Failed to execute database statement: %s"), sqlite3_errmsg(priv->database));
|
||
|
}
|
||
|
sqlite3_free(sql);
|
||
|
|
||
|
/* Delete row from model */
|
||
|
gtk_list_store_remove(priv->listStore, &iter);
|
||
|
}
|
||
|
g_list_foreach(refs,(GFunc)gtk_tree_row_reference_free, NULL);
|
||
|
g_list_free(refs);
|
||
|
}
|
||
|
|
||
|
/* Delete all button was clicked */
|
||
|
void _cookie_permission_manager_preferences_on_delete_all(CookiePermissionManagerPreferencesWindow *self,
|
||
|
GtkButton *inButton)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
gint success;
|
||
|
gchar *error=NULL;
|
||
|
GtkWidget *dialog;
|
||
|
gint dialogResponse;
|
||
|
|
||
|
/* Ask user if he really wants to delete all permissions */
|
||
|
dialog=gtk_message_dialog_new(GTK_WINDOW(self),
|
||
|
GTK_DIALOG_MODAL,
|
||
|
GTK_MESSAGE_QUESTION,
|
||
|
GTK_BUTTONS_YES_NO,
|
||
|
_("Do you really want to delete all cookie permissions?"));
|
||
|
|
||
|
gtk_window_set_title(GTK_WINDOW(dialog), _("Delete all cookie permissions?"));
|
||
|
gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
|
||
|
|
||
|
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
|
||
|
_("This action will delete all cookie permissions. "
|
||
|
"You will be asked for permissions again for each web site visited."));
|
||
|
|
||
|
dialogResponse=gtk_dialog_run(GTK_DIALOG(dialog));
|
||
|
gtk_widget_destroy(dialog);
|
||
|
|
||
|
if(dialogResponse==GTK_RESPONSE_NO) return;
|
||
|
|
||
|
/* Delete all permission */
|
||
|
success=sqlite3_exec(priv->database,
|
||
|
"DELETE FROM policies;",
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&error);
|
||
|
|
||
|
if(success!=SQLITE_OK || error)
|
||
|
{
|
||
|
if(error)
|
||
|
{
|
||
|
g_critical(_("Failed to execute database statement: %s"), error);
|
||
|
sqlite3_free(error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Re-setup list */
|
||
|
_cookie_permission_manager_preferences_window_fill(self);
|
||
|
}
|
||
|
|
||
|
/* Sorting callbacks */
|
||
|
static gint _cookie_permission_manager_preferences_sort_string_callback(GtkTreeModel *inModel,
|
||
|
GtkTreeIter *inLeft,
|
||
|
GtkTreeIter *inRight,
|
||
|
gpointer inUserData)
|
||
|
{
|
||
|
gchar *left, *right;
|
||
|
gint column=GPOINTER_TO_INT(inUserData);
|
||
|
gint result;
|
||
|
|
||
|
gtk_tree_model_get(inModel, inLeft, column, &left, -1);
|
||
|
gtk_tree_model_get(inModel, inRight, column, &right, -1);
|
||
|
|
||
|
result=g_strcmp0(left, right);
|
||
|
|
||
|
g_free(left);
|
||
|
g_free(right);
|
||
|
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
/* IMPLEMENTATION: GObject */
|
||
|
|
||
|
/* Finalize this object */
|
||
|
static void cookie_permission_manager_preferences_window_finalize(GObject *inObject)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW(inObject)->priv;
|
||
|
|
||
|
/* Dispose allocated resources */
|
||
|
if(priv->database) sqlite3_close(priv->database);
|
||
|
priv->database=NULL;
|
||
|
|
||
|
if(priv->manager)
|
||
|
{
|
||
|
if(priv->signalManagerChangedDatabaseID) g_signal_handler_disconnect(priv->manager, priv->signalManagerChangedDatabaseID);
|
||
|
priv->signalManagerChangedDatabaseID=0;
|
||
|
|
||
|
if(priv->signalManagerAskForUnknownPolicyID) g_signal_handler_disconnect(priv->manager, priv->signalManagerAskForUnknownPolicyID);
|
||
|
priv->signalManagerAskForUnknownPolicyID=0;
|
||
|
|
||
|
g_object_unref(priv->manager);
|
||
|
priv->manager=NULL;
|
||
|
}
|
||
|
|
||
|
/* Call parent's class finalize method */
|
||
|
G_OBJECT_CLASS(cookie_permission_manager_preferences_window_parent_class)->finalize(inObject);
|
||
|
}
|
||
|
|
||
|
/* Set/get properties */
|
||
|
static void cookie_permission_manager_preferences_window_set_property(GObject *inObject,
|
||
|
guint inPropID,
|
||
|
const GValue *inValue,
|
||
|
GParamSpec *inSpec)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindow *self=COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW(inObject);
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
|
||
|
GObject *manager;
|
||
|
|
||
|
switch(inPropID)
|
||
|
{
|
||
|
/* Construct-only properties */
|
||
|
case PROP_MANAGER:
|
||
|
/* Release old manager if available and disconnect signals */
|
||
|
if(priv->manager)
|
||
|
{
|
||
|
if(priv->signalManagerChangedDatabaseID) g_signal_handler_disconnect(priv->manager, priv->signalManagerChangedDatabaseID);
|
||
|
priv->signalManagerChangedDatabaseID=0;
|
||
|
|
||
|
if(priv->signalManagerAskForUnknownPolicyID) g_signal_handler_disconnect(priv->manager, priv->signalManagerAskForUnknownPolicyID);
|
||
|
priv->signalManagerAskForUnknownPolicyID=0;
|
||
|
|
||
|
g_object_unref(priv->manager);
|
||
|
priv->manager=NULL;
|
||
|
}
|
||
|
|
||
|
/* Set new cookie permission manager and
|
||
|
* listen to changes in database property
|
||
|
*/
|
||
|
manager=g_value_get_object(inValue);
|
||
|
if(manager)
|
||
|
{
|
||
|
priv->manager=g_object_ref(manager);
|
||
|
|
||
|
priv->signalManagerChangedDatabaseID=
|
||
|
g_signal_connect_swapped(priv->manager,
|
||
|
"notify::database-filename",
|
||
|
G_CALLBACK(_cookie_permission_manager_preferences_window_manager_database_changed),
|
||
|
self);
|
||
|
_cookie_permission_manager_preferences_window_manager_database_changed(self, NULL, priv->manager);
|
||
|
|
||
|
priv->signalManagerAskForUnknownPolicyID=
|
||
|
g_signal_connect_swapped(priv->manager,
|
||
|
"notify::ask-for-unknown-policy",
|
||
|
G_CALLBACK(_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed),
|
||
|
self);
|
||
|
_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed(self, NULL, priv->manager);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void cookie_permission_manager_preferences_window_get_property(GObject *inObject,
|
||
|
guint inPropID,
|
||
|
GValue *outValue,
|
||
|
GParamSpec *inSpec)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindow *self=COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW(inObject);
|
||
|
|
||
|
switch(inPropID)
|
||
|
{
|
||
|
case PROP_MANAGER:
|
||
|
g_value_set_object(outValue, self->priv->manager);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Class initialization
|
||
|
* Override functions in parent classes and define properties and signals
|
||
|
*/
|
||
|
static void cookie_permission_manager_preferences_window_class_init(CookiePermissionManagerPreferencesWindowClass *klass)
|
||
|
{
|
||
|
GObjectClass *gobjectClass=G_OBJECT_CLASS(klass);
|
||
|
|
||
|
/* Override functions */
|
||
|
gobjectClass->finalize=cookie_permission_manager_preferences_window_finalize;
|
||
|
gobjectClass->set_property=cookie_permission_manager_preferences_window_set_property;
|
||
|
gobjectClass->get_property=cookie_permission_manager_preferences_window_get_property;
|
||
|
|
||
|
/* Set up private structure */
|
||
|
g_type_class_add_private(klass, sizeof(CookiePermissionManagerPreferencesWindowPrivate));
|
||
|
|
||
|
/* Define properties */
|
||
|
CookiePermissionManagerPreferencesWindowProperties[PROP_MANAGER]=
|
||
|
g_param_spec_object("manager",
|
||
|
_("Cookie permission manager"),
|
||
|
_("Instance of current cookie permission manager"),
|
||
|
TYPE_COOKIE_PERMISSION_MANAGER,
|
||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||
|
|
||
|
g_object_class_install_properties(gobjectClass, PROP_LAST, CookiePermissionManagerPreferencesWindowProperties);
|
||
|
}
|
||
|
|
||
|
/* Object initialization
|
||
|
* Create private structure and set up default values
|
||
|
*/
|
||
|
static void cookie_permission_manager_preferences_window_init(CookiePermissionManagerPreferencesWindow *self)
|
||
|
{
|
||
|
CookiePermissionManagerPreferencesWindowPrivate *priv;
|
||
|
GtkTreeSortable *sortableList;
|
||
|
GtkCellRenderer *renderer;
|
||
|
GtkTreeViewColumn *column;
|
||
|
GtkWidget *widget;
|
||
|
gchar *text;
|
||
|
gchar *dialogTitle;
|
||
|
GtkWidget *scrolled;
|
||
|
GtkWidget *vbox;
|
||
|
GtkWidget *hbox;
|
||
|
gint width, height;
|
||
|
GtkListStore *list;
|
||
|
GtkTreeIter listIter;
|
||
|
|
||
|
priv=self->priv=COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW_GET_PRIVATE(self);
|
||
|
|
||
|
/* Set up default values */
|
||
|
priv->manager=NULL;
|
||
|
|
||
|
/* Get content area to add gui controls to */
|
||
|
priv->contentArea=gtk_dialog_get_content_area(GTK_DIALOG(self));
|
||
|
#ifdef HAVE_GTK3
|
||
|
vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||
|
gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
|
||
|
#else
|
||
|
vbox=gtk_vbox_new(FALSE, 0);
|
||
|
#endif
|
||
|
|
||
|
/* Set up dialog */
|
||
|
dialogTitle=_("Configure cookie permission");
|
||
|
|
||
|
gtk_window_set_title(GTK_WINDOW(self), dialogTitle);
|
||
|
gtk_window_set_icon_name(GTK_WINDOW(self), GTK_STOCK_PROPERTIES);
|
||
|
|
||
|
sokoke_widget_get_text_size(GTK_WIDGET(self), "M", &width, &height);
|
||
|
gtk_window_set_default_size(GTK_WINDOW(self), width*52, -1);
|
||
|
|
||
|
widget=sokoke_xfce_header_new(gtk_window_get_icon_name(GTK_WINDOW(self)), dialogTitle);
|
||
|
if(widget) gtk_box_pack_start(GTK_BOX(priv->contentArea), widget, FALSE, FALSE, 0);
|
||
|
|
||
|
gtk_dialog_add_button(GTK_DIALOG(self), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
|
||
|
|
||
|
/* Set up description */
|
||
|
widget=gtk_label_new(NULL);
|
||
|
text=g_strdup_printf(_("Below is a list of all web sites and the policy set for them. "
|
||
|
"You can delete policies by marking the entries and clicking on <i>Delete</i>."
|
||
|
"You can also add a policy for a domain manually by entering the domain below, "
|
||
|
"choosing the policy and clicking on <i>Add</i>."));
|
||
|
gtk_label_set_markup(GTK_LABEL(widget), text);
|
||
|
g_free(text);
|
||
|
gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 4);
|
||
|
|
||
|
/* Set up model for cookie domain list */
|
||
|
priv->listStore=gtk_list_store_new(N_COLUMN,
|
||
|
G_TYPE_STRING, /* DOMAIN_COLUMN */
|
||
|
G_TYPE_STRING /* POLICY_COLUMN */);
|
||
|
|
||
|
sortableList=GTK_TREE_SORTABLE(priv->listStore);
|
||
|
gtk_tree_sortable_set_sort_func(sortableList,
|
||
|
DOMAIN_COLUMN,
|
||
|
(GtkTreeIterCompareFunc)_cookie_permission_manager_preferences_sort_string_callback,
|
||
|
GINT_TO_POINTER(DOMAIN_COLUMN),
|
||
|
NULL);
|
||
|
gtk_tree_sortable_set_sort_func(sortableList,
|
||
|
POLICY_COLUMN,
|
||
|
(GtkTreeIterCompareFunc)_cookie_permission_manager_preferences_sort_string_callback,
|
||
|
GINT_TO_POINTER(POLICY_COLUMN),
|
||
|
NULL);
|
||
|
gtk_tree_sortable_set_sort_column_id(sortableList, DOMAIN_COLUMN, GTK_SORT_ASCENDING);
|
||
|
|
||
|
/* Set up domain addition widgets */
|
||
|
#ifdef HAVE_GTK3
|
||
|
hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||
|
gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
|
||
|
#else
|
||
|
hbox=gtk_hbox_new(FALSE, 0);
|
||
|
#endif
|
||
|
|
||
|
priv->addDomainEntry=gtk_entry_new();
|
||
|
gtk_entry_set_max_length(GTK_ENTRY(priv->addDomainEntry), 64);
|
||
|
gtk_container_add(GTK_CONTAINER(hbox), priv->addDomainEntry);
|
||
|
g_signal_connect_swapped(priv->addDomainEntry, "changed", G_CALLBACK(_cookie_permission_manager_preferences_on_add_domain_entry_changed), self);
|
||
|
|
||
|
list=gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
|
||
|
gtk_list_store_append(list, &listIter);
|
||
|
gtk_list_store_set(list, &listIter, 0, COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT, 1, _("Accept"), -1);
|
||
|
gtk_list_store_append(list, &listIter);
|
||
|
gtk_list_store_set(list, &listIter, 0, COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION, 1, _("Accept for session"), -1);
|
||
|
gtk_list_store_append(list, &listIter);
|
||
|
gtk_list_store_set(list, &listIter, 0, COOKIE_PERMISSION_MANAGER_POLICY_BLOCK, 1, _("Block"), -1);
|
||
|
|
||
|
priv->addDomainPolicyCombo=gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
|
||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(priv->addDomainPolicyCombo), 0);
|
||
|
gtk_container_add(GTK_CONTAINER(hbox), priv->addDomainPolicyCombo);
|
||
|
|
||
|
renderer=gtk_cell_renderer_text_new();
|
||
|
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(priv->addDomainPolicyCombo), renderer, TRUE);
|
||
|
gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(priv->addDomainPolicyCombo), renderer, "text", 1);
|
||
|
|
||
|
priv->addDomainButton=gtk_button_new_from_stock(GTK_STOCK_ADD);
|
||
|
gtk_widget_set_sensitive(priv->addDomainButton, FALSE);
|
||
|
gtk_container_add(GTK_CONTAINER(hbox), priv->addDomainButton);
|
||
|
g_signal_connect_swapped(priv->addDomainButton, "clicked", G_CALLBACK(_cookie_permission_manager_preferences_on_add_domain_clicked), self);
|
||
|
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
|
||
|
|
||
|
/* Set up cookie domain list */
|
||
|
priv->list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(priv->listStore));
|
||
|
|
||
|
#ifndef HAVE_GTK3
|
||
|
gtk_widget_set_size_request(priv->list, -1, 300);
|
||
|
#endif
|
||
|
|
||
|
priv->listSelection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->list));
|
||
|
gtk_tree_selection_set_mode(priv->listSelection, GTK_SELECTION_MULTIPLE);
|
||
|
g_signal_connect_swapped(priv->listSelection, "changed", G_CALLBACK(_cookie_permission_manager_preferences_changed_selection), self);
|
||
|
|
||
|
renderer=gtk_cell_renderer_text_new();
|
||
|
column=gtk_tree_view_column_new_with_attributes(_("Domain"),
|
||
|
renderer,
|
||
|
"text", DOMAIN_COLUMN,
|
||
|
NULL);
|
||
|
gtk_tree_view_column_set_sort_column_id(column, DOMAIN_COLUMN);
|
||
|
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
|
||
|
|
||
|
renderer=gtk_cell_renderer_text_new();
|
||
|
column=gtk_tree_view_column_new_with_attributes(_("Policy"),
|
||
|
renderer,
|
||
|
"text", POLICY_COLUMN,
|
||
|
NULL);
|
||
|
gtk_tree_view_column_set_sort_column_id(column, POLICY_COLUMN);
|
||
|
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
|
||
|
|
||
|
scrolled=gtk_scrolled_window_new(NULL, NULL);
|
||
|
#ifdef HAVE_GTK3
|
||
|
gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled), height*10);
|
||
|
#endif
|
||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||
|
gtk_container_add(GTK_CONTAINER(scrolled), priv->list);
|
||
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 5);
|
||
|
|
||
|
/* Set up cookie domain list management buttons */
|
||
|
#ifdef HAVE_GTK3
|
||
|
hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||
|
gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
|
||
|
#else
|
||
|
hbox=gtk_hbox_new(FALSE, 0);
|
||
|
#endif
|
||
|
|
||
|
priv->deleteButton=gtk_button_new_from_stock(GTK_STOCK_DELETE);
|
||
|
gtk_widget_set_sensitive(priv->deleteButton, FALSE);
|
||
|
gtk_container_add(GTK_CONTAINER(hbox), priv->deleteButton);
|
||
|
g_signal_connect_swapped(priv->deleteButton, "clicked", G_CALLBACK(_cookie_permission_manager_preferences_on_delete_selection), self);
|
||
|
|
||
|
priv->deleteAllButton=gtk_button_new_with_mnemonic(_("Delete _all"));
|
||
|
gtk_button_set_image(GTK_BUTTON(priv->deleteAllButton), gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
|
||
|
gtk_widget_set_sensitive(priv->deleteAllButton, FALSE);
|
||
|
gtk_container_add(GTK_CONTAINER(hbox), priv->deleteAllButton);
|
||
|
g_signal_connect_swapped(priv->deleteAllButton, "clicked", G_CALLBACK(_cookie_permission_manager_preferences_on_delete_all), self);
|
||
|
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
|
||
|
|
||
|
/* Add "ask-for-unknown-policy" checkbox */
|
||
|
priv->askForUnknownPolicyCheckbox=gtk_check_button_new_with_mnemonic(_("A_sk for policy if unknown for a domain"));
|
||
|
priv->signalAskForUnknownPolicyID=g_signal_connect_swapped(priv->askForUnknownPolicyCheckbox,
|
||
|
"toggled",
|
||
|
G_CALLBACK(_cookie_permission_manager_preferences_window_ask_for_unknown_policy_changed),
|
||
|
self);
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), priv->askForUnknownPolicyCheckbox, TRUE, TRUE, 5);
|
||
|
|
||
|
/* Finalize setup of content area */
|
||
|
gtk_container_add(GTK_CONTAINER(priv->contentArea), vbox);
|
||
|
}
|
||
|
|
||
|
/* Implementation: Public API */
|
||
|
|
||
|
/* Create new object */
|
||
|
GtkWidget* cookie_permission_manager_preferences_window_new(CookiePermissionManager *inManager)
|
||
|
{
|
||
|
return(g_object_new(TYPE_COOKIE_PERMISSION_MANAGER_PREFERENCES_WINDOW,
|
||
|
"manager", inManager,
|
||
|
NULL));
|
||
|
}
|