[Xfce4-commits] <midori:master> Converge private data registration and dialog

Christian Dywan noreply at xfce.org
Thu Nov 22 02:02:02 CET 2012


Updating branch refs/heads/master
         to 06f4542258a2e71f24b054ba4dcf4b29590e9f35 (commit)
       from b8fc0f8d26f38ab3718735bfc3d30f039dd715db (commit)

commit 06f4542258a2e71f24b054ba4dcf4b29590e9f35
Author: Christian Dywan <christian at twotoasts.de>
Date:   Thu Nov 22 01:28:02 2012 +0100

    Converge private data registration and dialog

 extensions/web-cache.c      |    4 +-
 katze/midori-paths.vala     |   16 ++
 midori/main.c               |  170 +------------------
 midori/midori-browser.c     |  179 ++-----------------
 midori/midori-privatedata.c |  403 +++++++++++++++++++++++++++++++++++++++++++
 midori/midori-privatedata.h |   43 +++++
 midori/midori.h             |    1 +
 midori/sokoke.c             |   73 --------
 midori/sokoke.h             |   16 --
 9 files changed, 485 insertions(+), 420 deletions(-)

diff --git a/extensions/web-cache.c b/extensions/web-cache.c
index 53ea445..e95c509 100644
--- a/extensions/web-cache.c
+++ b/extensions/web-cache.c
@@ -447,7 +447,7 @@ web_cache_activate_cb (MidoriExtension* extension,
 static void
 web_cache_clear_cache_cb (void)
 {
-    sokoke_remove_path (web_cache_get_cache_dir (), TRUE);
+    midori_paths_remove_path (web_cache_get_cache_dir ());
 }
 #endif
 
@@ -467,7 +467,7 @@ extension_init (void)
     g_signal_connect (extension, "activate",
         G_CALLBACK (web_cache_activate_cb), NULL);
 
-    sokoke_register_privacy_item ("web-cache", _("Web Cache"),
+    midori_private_data_register_item ("web-cache", _("Web Cache"),
         G_CALLBACK (web_cache_clear_cache_cb));
 
     return extension;
diff --git a/katze/midori-paths.vala b/katze/midori-paths.vala
index 86b3cdd..d85e61b 100644
--- a/katze/midori-paths.vala
+++ b/katze/midori-paths.vala
@@ -123,6 +123,22 @@ namespace Midori {
             while (i != -1);
         }
 
+        public static void remove_path (string path) {
+            try {
+                var dir = Dir.open (path, 0);
+                string? name;
+                while (true) {
+                    name = dir.read_name ();
+                    if (name == null)
+                        break;
+                    remove_path (Path.build_filename (path, name));
+                }
+            }
+            catch (Error error) {
+                FileUtils.remove (path);
+            }
+        }
+
         public static unowned string get_config_dir_for_writing () {
             assert (config_dir != null);
             mkdir_with_parents (config_dir);
diff --git a/midori/main.c b/midori/main.c
index 77d06f0..0e405e5 100644
--- a/midori/main.c
+++ b/midori/main.c
@@ -21,6 +21,7 @@
 #include "midori-panel.h"
 #include "midori-platform.h"
 #include "midori-preferences.h"
+#include "midori-privatedata.h"
 #include "midori-searchaction.h"
 #include <midori/midori-core.h>
 
@@ -1306,19 +1307,6 @@ midori_web_app_browser_new_window_cb (MidoriBrowser* browser,
     return new_browser;
 }
 
-static void
-midori_remove_config_file (gint         clear_prefs,
-                           gint         flag,
-                           const gchar* filename)
-{
-    if ((clear_prefs & flag) == flag)
-    {
-        gchar* config_file = midori_paths_get_config_filename_for_writing (filename);
-        g_unlink (config_file);
-        g_free (config_file);
-    }
-}
-
 static gchar*
 midori_prepare_uri (const gchar *uri)
 {
@@ -1410,24 +1398,9 @@ midori_inactivity_timeout (gpointer data)
         XScreenSaverQueryInfo (xdisplay, RootWindow (xdisplay, 0), mit_info);
         if (mit_info->idle / 1000 > mit->timeout)
         {
-            GList* children;
             GtkWidget* view;
-            KatzeArray* history = katze_object_get_object (mit->browser, "history");
-            KatzeArray* trash = katze_object_get_object (mit->browser, "trash");
-            GList* data_items = sokoke_register_privacy_item (NULL, NULL, NULL);
-
-            children = midori_browser_get_tabs (mit->browser);
-            for (; children; children = g_list_next (children))
-                midori_browser_close_tab (mit->browser, children->data);
-            g_list_free (children);
             midori_browser_set_current_uri (mit->browser, mit->uri);
-            /* Clear all private data */
-            if (history != NULL)
-                katze_array_clear (history);
-            if (trash != NULL)
-                katze_array_clear (trash);
-            for (; data_items != NULL; data_items = g_list_next (data_items))
-                ((SokokePrivacyItem*)(data_items->data))->clear ();
+            midori_private_data_clear_all (mit->browser);
         }
     }
     #else
@@ -1453,111 +1426,6 @@ midori_setup_inactivity_reset (MidoriBrowser* browser,
     }
 }
 
-static void
-midori_clear_web_cookies_cb (void)
-{
-    SoupSession* session = webkit_get_default_session ();
-    MidoriWebSettings* settings = g_object_get_data (G_OBJECT (session), "midori-settings");
-    SoupSessionFeature* jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR);
-    GSList* cookies = soup_cookie_jar_all_cookies (SOUP_COOKIE_JAR (jar));
-    SoupSessionFeature* feature;
-    gchar* cache;
-
-    /* HTTP Cookies/ Web Cookies */
-    for (; cookies != NULL; cookies = g_slist_next (cookies))
-    {
-        const gchar* domain = ((SoupCookie*)cookies->data)->domain;
-        if (midori_web_settings_get_site_data_policy (settings, domain)
-         == MIDORI_SITE_DATA_PRESERVE)
-            continue;
-        soup_cookie_jar_delete_cookie ((SoupCookieJar*)jar, cookies->data);
-    }
-    soup_cookies_free (cookies);
-    /* Removing KatzeHttpCookies makes it save outstanding changes */
-    if ((feature = soup_session_get_feature (session, KATZE_TYPE_HTTP_COOKIES)))
-    {
-        g_object_ref (feature);
-        soup_session_remove_feature (session, feature);
-        soup_session_add_feature (session, feature);
-        g_object_unref (feature);
-    }
-
-    /* Local shared objects/ Flash cookies */
-    if (midori_web_settings_has_plugin_support ())
-    {
-    #ifdef GDK_WINDOWING_X11
-    cache = g_build_filename (g_get_home_dir (), ".macromedia", "Flash_Player", NULL);
-    sokoke_remove_path (cache, TRUE);
-    g_free (cache);
-    #elif defined(GDK_WINDOWING_WIN32)
-    cache = g_build_filename (g_get_user_data_dir (), "Macromedia", "Flash Player", NULL);
-    sokoke_remove_path (cache, TRUE);
-    g_free (cache);
-    #elif defined(GDK_WINDOWING_QUARTZ)
-    cache = g_build_filename (g_get_home_dir (), "Library", "Preferences",
-                              "Macromedia", "Flash Player", NULL);
-    sokoke_remove_path (cache, TRUE);
-    g_free (cache);
-    #endif
-    }
-
-    /* HTML5 databases */
-    webkit_remove_all_web_databases ();
-
-    /* HTML5 offline application caches */
-    #if WEBKIT_CHECK_VERSION (1, 3, 13)
-    /* Changing the size implies clearing the cache */
-    webkit_application_cache_set_maximum_size (
-        webkit_application_cache_get_maximum_size () - 1);
-    #endif
-}
-
-static void
-midori_clear_saved_logins_cb (void)
-{
-    sqlite3* db;
-    gchar* path = g_build_filename (midori_paths_get_config_dir_for_writing (), "logins", NULL);
-    g_unlink (path);
-    /* Form History database, written by the extension */
-    katze_assign (path, g_build_filename (midori_paths_get_config_dir_for_writing (),
-        "extensions", MIDORI_MODULE_PREFIX "formhistory." G_MODULE_SUFFIX, "forms.db", NULL));
-    if (sqlite3_open (path, &db) == SQLITE_OK)
-    {
-        sqlite3_exec (db, "DELETE FROM forms", NULL, NULL, NULL);
-        sqlite3_close (db);
-    }
-    g_free (path);
-}
-
-#if WEBKIT_CHECK_VERSION (1, 3, 11)
-static void
-midori_clear_web_cache_cb (void)
-{
-    SoupSession* session = webkit_get_default_session ();
-    SoupSessionFeature* feature = soup_session_get_feature (session, SOUP_TYPE_CACHE);
-    gchar* cache = g_build_filename (midori_paths_get_cache_dir (), "web", NULL);
-    soup_cache_clear (SOUP_CACHE (feature));
-    soup_cache_flush (SOUP_CACHE (feature));
-    sokoke_remove_path (cache, TRUE);
-    g_free (cache);
-}
-#endif
-
-static void
-midori_clear_page_icons_cb (void)
-{
-    gchar* cache = g_build_filename (midori_paths_get_cache_dir (), "icons", NULL);
-    /* FIXME: Exclude search engine icons */
-    sokoke_remove_path (cache, TRUE);
-    g_free (cache);
-    cache = g_build_filename (midori_paths_get_user_data_dir (), "webkit", "icondatabase", NULL);
-    sokoke_remove_path (cache, TRUE);
-    g_free (cache);
-    #if WEBKIT_CHECK_VERSION (1, 8, 0)
-    webkit_favicon_database_clear (webkit_get_favicon_database ());
-    #endif
-}
-
 int
 main (int    argc,
       char** argv)
@@ -1824,18 +1692,7 @@ main (int    argc,
     #endif
     #endif
 
-    /* i18n: Logins and passwords in websites and web forms */
-    sokoke_register_privacy_item ("formhistory", _("Saved logins and _passwords"),
-        G_CALLBACK (midori_clear_saved_logins_cb));
-    sokoke_register_privacy_item ("web-cookies", _("Cookies and Website data"),
-        G_CALLBACK (midori_clear_web_cookies_cb));
-    #if WEBKIT_CHECK_VERSION (1, 3, 11)
-    /* TODO: Preserve page icons of search engines and merge privacy items */
-    sokoke_register_privacy_item ("web-cache", _("Web Cache"),
-        G_CALLBACK (midori_clear_web_cache_cb));
-    #endif
-    sokoke_register_privacy_item ("page-icons", _("Website icons"),
-        G_CALLBACK (midori_clear_page_icons_cb));
+    midori_private_data_register_built_ins ();
 
     /* Web Application or Private Browsing support */
     if (webapp || private || run)
@@ -2279,26 +2136,7 @@ main (int    argc,
 
     g_object_get (settings, "maximum-history-age", &max_history_age, NULL);
     midori_history_terminate (history, max_history_age);
-
-    /* Clear data on quit, according to the Clear private data dialog */
-    g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
-    if (clear_prefs & MIDORI_CLEAR_ON_QUIT)
-    {
-        GList* data_items = sokoke_register_privacy_item (NULL, NULL, NULL);
-        gchar* clear_data = katze_object_get_string (settings, "clear-data");
-
-        midori_remove_config_file (clear_prefs, MIDORI_CLEAR_SESSION, "session.xbel");
-        midori_remove_config_file (clear_prefs, MIDORI_CLEAR_HISTORY, "history.db");
-        midori_remove_config_file (clear_prefs, MIDORI_CLEAR_HISTORY, "tabtrash.xbel");
-
-        for (; data_items != NULL; data_items = g_list_next (data_items))
-        {
-            SokokePrivacyItem* privacy = data_items->data;
-            if (clear_data && strstr (clear_data, privacy->name))
-                privacy->clear ();
-        }
-        g_free (clear_data);
-    }
+    midori_private_data_on_quit (settings);
 
     /* Removing KatzeHttpCookies makes it save outstanding changes */
     soup_session_remove_feature_by_type (webkit_get_default_session (),
diff --git a/midori/midori-browser.c b/midori/midori-browser.c
index 7277e7f..03dfb9a 100644
--- a/midori/midori-browser.c
+++ b/midori/midori-browser.c
@@ -23,7 +23,9 @@
 #include "midori-findbar.h"
 #include "midori-transferbar.h"
 #include "midori-platform.h"
+#include "midori-privatedata.h"
 #include "midori-core.h"
+#include "midori-privatedata.h"
 
 #include "marshal.h"
 
@@ -92,8 +94,6 @@ struct _MidoriBrowser
     gint last_tab_size;
     guint panel_timeout;
 
-    gint clear_private_data;
-
     MidoriWebSettings* settings;
     KatzeArray* proxy_array;
     KatzeArray* bookmarks;
@@ -280,6 +280,15 @@ _toggle_tabbar_smartly (MidoriBrowser* browser,
 }
 
 static void
+midori_browser_trash_clear_cb (KatzeArray*    trash,
+                               MidoriBrowser* browser)
+{
+    gboolean trash_empty = katze_array_is_empty (browser->trash);
+    _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
+    _action_set_sensitive (browser, "Trash", !trash_empty);
+}
+
+static void
 _midori_browser_update_actions (MidoriBrowser* browser)
 {
     gboolean has_tabs = _toggle_tabbar_smartly (browser, FALSE);
@@ -287,11 +296,7 @@ _midori_browser_update_actions (MidoriBrowser* browser)
     _action_set_sensitive (browser, "TabNext", has_tabs);
 
     if (browser->trash)
-    {
-        gboolean trash_empty = katze_array_is_empty (browser->trash);
-        _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
-        _action_set_sensitive (browser, "Trash", !trash_empty);
-    }
+        midori_browser_trash_clear_cb (browser->trash, browser);
 }
 
 static void
@@ -4575,72 +4580,6 @@ _action_manage_search_engines_activate (GtkAction*     action,
 }
 
 static void
-midori_browser_clear_private_data_response_cb (GtkWidget*     dialog,
-                                               gint           response_id,
-                                               MidoriBrowser* browser)
-{
-    if (response_id == GTK_RESPONSE_ACCEPT)
-    {
-        GtkToggleButton* button;
-        gint clear_prefs = MIDORI_CLEAR_NONE;
-        gint saved_prefs = MIDORI_CLEAR_NONE;
-        GList* data_items = sokoke_register_privacy_item (NULL, NULL, NULL);
-        GString* clear_data = g_string_new (NULL);
-        g_object_get (browser->settings, "clear-private-data", &saved_prefs, NULL);
-
-        button = g_object_get_data (G_OBJECT (dialog), "session");
-        if (gtk_toggle_button_get_active (button))
-        {
-            GList* tabs = gtk_container_get_children (GTK_CONTAINER (browser->notebook));
-            for (; tabs != NULL; tabs = g_list_next (tabs))
-                gtk_widget_destroy (tabs->data);
-            g_list_free (tabs);
-            clear_prefs |= MIDORI_CLEAR_SESSION;
-        }
-        button = g_object_get_data (G_OBJECT (dialog), "history");
-        if (gtk_toggle_button_get_active (button))
-        {
-            katze_array_clear (browser->history);
-            katze_array_clear (browser->trash);
-            _midori_browser_update_actions (browser);
-            clear_prefs |= MIDORI_CLEAR_HISTORY;
-            clear_prefs |= MIDORI_CLEAR_TRASH; /* For backward-compatibility */
-        }
-        if (clear_prefs != saved_prefs)
-        {
-            clear_prefs |= (saved_prefs & MIDORI_CLEAR_ON_QUIT);
-            g_object_set (browser->settings, "clear-private-data", clear_prefs, NULL);
-        }
-        for (; data_items != NULL; data_items = g_list_next (data_items))
-        {
-            SokokePrivacyItem* privacy = data_items->data;
-            button = g_object_get_data (G_OBJECT (dialog), privacy->name);
-            g_return_if_fail (button != NULL && GTK_IS_TOGGLE_BUTTON (button));
-            if (gtk_toggle_button_get_active (button))
-            {
-                privacy->clear ();
-                g_string_append (clear_data, privacy->name);
-                g_string_append_c (clear_data, ',');
-            }
-        }
-        g_object_set (browser->settings, "clear-data", clear_data->str, NULL);
-        g_string_free (clear_data, TRUE);
-    }
-    if (response_id != GTK_RESPONSE_DELETE_EVENT)
-        gtk_widget_destroy (dialog);
-}
-
-static void
-midori_browser_clear_on_quit_toggled_cb (GtkToggleButton*   button,
-                                         MidoriWebSettings* settings)
-{
-    gint clear_prefs = MIDORI_CLEAR_NONE;
-    g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
-    clear_prefs ^= MIDORI_CLEAR_ON_QUIT;
-    g_object_set (settings, "clear-private-data", clear_prefs, NULL);
-}
-
-static void
 _action_clear_private_data_activate (GtkAction*     action,
                                      MidoriBrowser* browser)
 {
@@ -4651,94 +4590,10 @@ _action_clear_private_data_activate (GtkAction*     action,
 
     if (!dialog)
     {
-        GtkWidget* content_area;
-        GdkScreen* screen;
-        GtkSizeGroup* sizegroup;
-        GtkWidget* hbox;
-        GtkWidget* alignment;
-        GtkWidget* vbox;
-        GtkWidget* icon;
-        GtkWidget* label;
-        GtkWidget* button;
-        GList* data_items;
-        gchar* clear_data = katze_object_get_string (browser->settings, "clear-data");
-
-        gint clear_prefs = MIDORI_CLEAR_NONE;
-        g_object_get (browser->settings, "clear-private-data", &clear_prefs, NULL);
-
-        /* i18n: Dialog: Clear Private Data, in the Tools menu */
-        dialog = gtk_dialog_new_with_buttons (_("Clear Private Data"),
-            GTK_WINDOW (browser),
-            GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
-            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-            _("_Clear private data"), GTK_RESPONSE_ACCEPT, NULL);
-        katze_widget_add_class (gtk_dialog_get_widget_for_response (
-            GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT), "noundo");
-        content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
-        gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
-        screen = gtk_widget_get_screen (GTK_WIDGET (browser));
-        if (screen)
-        {
-            gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_CLEAR);
-        }
-        sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-        hbox = gtk_hbox_new (FALSE, 4);
-        icon = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_DIALOG);
-        gtk_size_group_add_widget (sizegroup, icon);
-        gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
-        label = gtk_label_new (_("Clear the following data:"));
-        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
-        gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
-        hbox = gtk_hbox_new (FALSE, 4);
-        icon = gtk_image_new ();
-        gtk_size_group_add_widget (sizegroup, icon);
-        gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
-        vbox = gtk_vbox_new (TRUE, 4);
-        alignment = gtk_alignment_new (0, 0, 1, 1);
-        gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 6, 12, 0);
-        button = gtk_check_button_new_with_mnemonic (_("Last open _tabs"));
-        if ((clear_prefs & MIDORI_CLEAR_SESSION) == MIDORI_CLEAR_SESSION)
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-        g_object_set_data (G_OBJECT (dialog), "session", button);
-        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
-        /* i18n: Browsing history, visited web pages, closed tabs */
-        button = gtk_check_button_new_with_mnemonic (_("_History"));
-        if ((clear_prefs & MIDORI_CLEAR_HISTORY) == MIDORI_CLEAR_HISTORY)
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-        g_object_set_data (G_OBJECT (dialog), "history", button);
-        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
-
-        data_items = sokoke_register_privacy_item (NULL, NULL, NULL);
-        for (; data_items != NULL; data_items = g_list_next (data_items))
-        {
-            SokokePrivacyItem* privacy = data_items->data;
-            button = gtk_check_button_new_with_mnemonic (privacy->label);
-            gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
-            g_object_set_data (G_OBJECT (dialog), privacy->name, button);
-            if (clear_data && strstr (clear_data, privacy->name))
-                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-        }
-        g_free (clear_data);
-        gtk_container_add (GTK_CONTAINER (alignment), vbox);
-        gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
-        gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
-        button = gtk_check_button_new_with_mnemonic (_("Clear private data when _quitting Midori"));
-        if ((clear_prefs & MIDORI_CLEAR_ON_QUIT) == MIDORI_CLEAR_ON_QUIT)
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-        g_signal_connect (button, "toggled",
-            G_CALLBACK (midori_browser_clear_on_quit_toggled_cb), browser->settings);
-        alignment = gtk_alignment_new (0, 0, 1, 1);
-        gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 2, 0);
-        gtk_container_add (GTK_CONTAINER (alignment), button);
-        gtk_box_pack_start (GTK_BOX (content_area), alignment, FALSE, FALSE, 0);
-        gtk_widget_show_all (content_area);
-
-        g_signal_connect (dialog, "response",
-            G_CALLBACK (midori_browser_clear_private_data_response_cb), browser);
+        dialog = midori_private_data_get_dialog (browser);
         g_signal_connect (dialog, "destroy",
             G_CALLBACK (gtk_widget_destroyed), &dialog);
         gtk_widget_show (dialog);
-        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
     }
     else
         gtk_window_present (GTK_WINDOW (dialog));
@@ -5407,10 +5262,7 @@ _action_trash_empty_activate (GtkAction*     action,
                               MidoriBrowser* browser)
 {
     if (browser->trash)
-    {
         katze_array_clear (browser->trash);
-        _midori_browser_update_actions (browser);
-    }
 }
 
 static const GtkActionEntry entries[] =
@@ -7405,8 +7257,9 @@ midori_browser_set_property (GObject*      object,
                       NULL);
         _action_set_visible (browser, "Trash", browser->trash != NULL);
         _action_set_visible (browser, "UndoTabClose", browser->trash != NULL);
-        /* FIXME: Connect to updates */
-        _midori_browser_update_actions (browser);
+        g_signal_connect (browser->trash, "clear",
+            G_CALLBACK (midori_browser_trash_clear_cb), browser);
+        midori_browser_trash_clear_cb (browser->trash, browser);
         break;
     case PROP_SEARCH_ENGINES:
     {
diff --git a/midori/midori-privatedata.c b/midori/midori-privatedata.c
new file mode 100644
index 0000000..40f4f83
--- /dev/null
+++ b/midori/midori-privatedata.c
@@ -0,0 +1,403 @@
+/*
+ Copyright (C) 2008-2012 Christian Dywan <christian at twotoasts.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 "midori-privatedata.h"
+
+#include "marshal.h"
+#include "midori-platform.h"
+#include "midori-core.h"
+
+#include "config.h"
+#include <string.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <sqlite3.h>
+
+#if WEBKIT_CHECK_VERSION (1, 3, 11)
+    #define LIBSOUP_USE_UNSTABLE_REQUEST_API
+    #include <libsoup/soup-cache.h>
+#endif
+
+static void
+midori_private_data_dialog_response_cb (GtkWidget*     dialog,
+                                        gint           response_id,
+                                        MidoriBrowser* browser)
+{
+    if (response_id == GTK_RESPONSE_ACCEPT)
+    {
+        GtkToggleButton* button;
+        gint clear_prefs = MIDORI_CLEAR_NONE;
+        gint saved_prefs = MIDORI_CLEAR_NONE;
+        GList* data_items = midori_private_data_register_item (NULL, NULL, NULL);
+        GString* clear_data = g_string_new (NULL);
+        MidoriWebSettings* settings = midori_browser_get_settings (browser);
+        g_object_get (settings, "clear-private-data", &saved_prefs, NULL);
+
+        button = g_object_get_data (G_OBJECT (dialog), "session");
+        if (gtk_toggle_button_get_active (button))
+        {
+            GList* tabs = midori_browser_get_tabs (browser);
+            for (; tabs != NULL; tabs = g_list_next (tabs))
+                midori_browser_close_tab (browser, tabs->data);
+            g_list_free (tabs);
+            clear_prefs |= MIDORI_CLEAR_SESSION;
+        }
+        button = g_object_get_data (G_OBJECT (dialog), "history");
+        if (gtk_toggle_button_get_active (button))
+        {
+            KatzeArray* history = katze_object_get_object (browser, "history");
+            KatzeArray* trash = katze_object_get_object (browser, "trash");
+            katze_array_clear (history);
+            katze_array_clear (trash);
+            g_object_ref (history);
+            g_object_ref (trash);
+            clear_prefs |= MIDORI_CLEAR_HISTORY;
+            clear_prefs |= MIDORI_CLEAR_TRASH; /* For backward-compatibility */
+        }
+        if (clear_prefs != saved_prefs)
+        {
+            clear_prefs |= (saved_prefs & MIDORI_CLEAR_ON_QUIT);
+            g_object_set (settings, "clear-private-data", clear_prefs, NULL);
+        }
+        for (; data_items != NULL; data_items = g_list_next (data_items))
+        {
+            MidoriPrivateDataItem* privacy = data_items->data;
+            button = g_object_get_data (G_OBJECT (dialog), privacy->name);
+            g_return_if_fail (button != NULL && GTK_IS_TOGGLE_BUTTON (button));
+            if (gtk_toggle_button_get_active (button))
+            {
+                privacy->clear ();
+                g_string_append (clear_data, privacy->name);
+                g_string_append_c (clear_data, ',');
+            }
+        }
+        g_object_set (settings, "clear-data", clear_data->str, NULL);
+        g_string_free (clear_data, TRUE);
+    }
+    if (response_id != GTK_RESPONSE_DELETE_EVENT)
+        gtk_widget_destroy (dialog);
+}
+
+static void
+midori_private_data_clear_on_quit_toggled_cb (GtkToggleButton*   button,
+                                              MidoriWebSettings* settings)
+{
+    gint clear_prefs = MIDORI_CLEAR_NONE;
+    g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
+    clear_prefs ^= MIDORI_CLEAR_ON_QUIT;
+    g_object_set (settings, "clear-private-data", clear_prefs, NULL);
+}
+
+GtkWidget*
+midori_private_data_get_dialog (MidoriBrowser* browser)
+{
+    GtkWidget* dialog;
+    GtkWidget* content_area;
+    GdkScreen* screen;
+    GtkSizeGroup* sizegroup;
+    GtkWidget* hbox;
+    GtkWidget* alignment;
+    GtkWidget* vbox;
+    GtkWidget* icon;
+    GtkWidget* label;
+    GtkWidget* button;
+    GList* data_items;
+    MidoriWebSettings* settings = midori_browser_get_settings (browser);
+    gchar* clear_data = katze_object_get_string (settings, "clear-data");
+    gint clear_prefs = MIDORI_CLEAR_NONE;
+    g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
+
+    /* i18n: Dialog: Clear Private Data, in the Tools menu */
+    dialog = gtk_dialog_new_with_buttons (_("Clear Private Data"),
+        GTK_WINDOW (browser),
+        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+        _("_Clear private data"), GTK_RESPONSE_ACCEPT, NULL);
+    katze_widget_add_class (gtk_dialog_get_widget_for_response (
+        GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT), "noundo");
+    content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+    gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
+    screen = gtk_widget_get_screen (GTK_WIDGET (browser));
+    if (screen)
+        gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_CLEAR);
+    sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+    hbox = gtk_hbox_new (FALSE, 4);
+    icon = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_DIALOG);
+    gtk_size_group_add_widget (sizegroup, icon);
+    gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+    label = gtk_label_new (_("Clear the following data:"));
+    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
+    hbox = gtk_hbox_new (FALSE, 4);
+    icon = gtk_image_new ();
+    gtk_size_group_add_widget (sizegroup, icon);
+    gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+    vbox = gtk_vbox_new (TRUE, 4);
+    alignment = gtk_alignment_new (0, 0, 1, 1);
+    gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 6, 12, 0);
+    button = gtk_check_button_new_with_mnemonic (_("Last open _tabs"));
+    if ((clear_prefs & MIDORI_CLEAR_SESSION) == MIDORI_CLEAR_SESSION)
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+    g_object_set_data (G_OBJECT (dialog), "session", button);
+    gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+    /* i18n: Browsing history, visited web pages, closed tabs */
+    button = gtk_check_button_new_with_mnemonic (_("_History"));
+    if ((clear_prefs & MIDORI_CLEAR_HISTORY) == MIDORI_CLEAR_HISTORY)
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+    g_object_set_data (G_OBJECT (dialog), "history", button);
+    gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+
+    data_items = midori_private_data_register_item (NULL, NULL, NULL);
+    for (; data_items != NULL; data_items = g_list_next (data_items))
+    {
+        MidoriPrivateDataItem* privacy = data_items->data;
+        button = gtk_check_button_new_with_mnemonic (privacy->label);
+        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+        g_object_set_data (G_OBJECT (dialog), privacy->name, button);
+        if (clear_data && strstr (clear_data, privacy->name))
+            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+    }
+    g_free (clear_data);
+    gtk_container_add (GTK_CONTAINER (alignment), vbox);
+    gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
+    button = gtk_check_button_new_with_mnemonic (_("Clear private data when _quitting Midori"));
+    if ((clear_prefs & MIDORI_CLEAR_ON_QUIT) == MIDORI_CLEAR_ON_QUIT)
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+    g_signal_connect (button, "toggled",
+        G_CALLBACK (midori_private_data_clear_on_quit_toggled_cb), settings);
+    alignment = gtk_alignment_new (0, 0, 1, 1);
+    gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 2, 0);
+    gtk_container_add (GTK_CONTAINER (alignment), button);
+    gtk_box_pack_start (GTK_BOX (content_area), alignment, FALSE, FALSE, 0);
+    gtk_widget_show_all (content_area);
+
+    g_signal_connect (dialog, "response",
+        G_CALLBACK (midori_private_data_dialog_response_cb), browser);
+    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+    return dialog;
+}
+
+static void
+midori_remove_config_file (gint         clear_prefs,
+                           gint         flag,
+                           const gchar* filename)
+{
+    if ((clear_prefs & flag) == flag)
+    {
+        gchar* config_file = midori_paths_get_config_filename_for_writing (filename);
+        g_unlink (config_file);
+        g_free (config_file);
+    }
+}
+
+static void
+midori_clear_web_cookies_cb (void)
+{
+    SoupSession* session = webkit_get_default_session ();
+    MidoriWebSettings* settings = g_object_get_data (G_OBJECT (session), "midori-settings");
+    SoupSessionFeature* jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR);
+    GSList* cookies = soup_cookie_jar_all_cookies (SOUP_COOKIE_JAR (jar));
+    SoupSessionFeature* feature;
+    gchar* cache;
+
+    /* HTTP Cookies/ Web Cookies */
+    for (; cookies != NULL; cookies = g_slist_next (cookies))
+    {
+        const gchar* domain = ((SoupCookie*)cookies->data)->domain;
+        if (midori_web_settings_get_site_data_policy (settings, domain)
+         == MIDORI_SITE_DATA_PRESERVE)
+            continue;
+        soup_cookie_jar_delete_cookie ((SoupCookieJar*)jar, cookies->data);
+    }
+    soup_cookies_free (cookies);
+    /* Removing KatzeHttpCookies makes it save outstanding changes */
+    if ((feature = soup_session_get_feature (session, KATZE_TYPE_HTTP_COOKIES)))
+    {
+        g_object_ref (feature);
+        soup_session_remove_feature (session, feature);
+        soup_session_add_feature (session, feature);
+        g_object_unref (feature);
+    }
+
+    /* Local shared objects/ Flash cookies */
+    if (midori_web_settings_has_plugin_support ())
+    {
+    #ifdef GDK_WINDOWING_X11
+    cache = g_build_filename (g_get_home_dir (), ".macromedia", "Flash_Player", NULL);
+    midori_paths_remove_path (cache);
+    g_free (cache);
+    #elif defined(GDK_WINDOWING_WIN32)
+    cache = g_build_filename (g_get_user_data_dir (), "Macromedia", "Flash Player", NULL);
+    midori_paths_remove_path (cache);
+    g_free (cache);
+    #elif defined(GDK_WINDOWING_QUARTZ)
+    cache = g_build_filename (g_get_home_dir (), "Library", "Preferences",
+                              "Macromedia", "Flash Player", NULL);
+    midori_paths_remove_path (cache);
+    g_free (cache);
+    #endif
+    }
+
+    /* HTML5 databases */
+    webkit_remove_all_web_databases ();
+
+    /* HTML5 offline application caches */
+    #if WEBKIT_CHECK_VERSION (1, 3, 13)
+    /* Changing the size implies clearing the cache */
+    webkit_application_cache_set_maximum_size (
+        webkit_application_cache_get_maximum_size () - 1);
+    #endif
+}
+
+static void
+midori_clear_saved_logins_cb (void)
+{
+    sqlite3* db;
+    gchar* path = g_build_filename (midori_paths_get_config_dir_for_writing (), "logins", NULL);
+    g_unlink (path);
+    /* Form History database, written by the extension */
+    katze_assign (path, g_build_filename (midori_paths_get_config_dir_for_writing (),
+        "extensions", MIDORI_MODULE_PREFIX "formhistory." G_MODULE_SUFFIX, "forms.db", NULL));
+    if (sqlite3_open (path, &db) == SQLITE_OK)
+    {
+        sqlite3_exec (db, "DELETE FROM forms", NULL, NULL, NULL);
+        sqlite3_close (db);
+    }
+    g_free (path);
+}
+
+#if WEBKIT_CHECK_VERSION (1, 3, 11)
+static void
+midori_clear_web_cache_cb (void)
+{
+    SoupSession* session = webkit_get_default_session ();
+    SoupSessionFeature* feature = soup_session_get_feature (session, SOUP_TYPE_CACHE);
+    gchar* cache = g_build_filename (midori_paths_get_cache_dir (), "web", NULL);
+    soup_cache_clear (SOUP_CACHE (feature));
+    soup_cache_flush (SOUP_CACHE (feature));
+    midori_paths_remove_path (cache);
+    g_free (cache);
+}
+#endif
+
+static void
+midori_clear_page_icons_cb (void)
+{
+    gchar* cache = g_build_filename (midori_paths_get_cache_dir (), "icons", NULL);
+    /* FIXME: Exclude search engine icons */
+    midori_paths_remove_path (cache);
+    g_free (cache);
+    cache = g_build_filename (midori_paths_get_user_data_dir (), "webkit", "icondatabase", NULL);
+    midori_paths_remove_path (cache);
+    g_free (cache);
+    #if WEBKIT_CHECK_VERSION (1, 8, 0)
+    webkit_favicon_database_clear (webkit_get_favicon_database ());
+    #endif
+}
+
+void
+midori_private_data_register_built_ins ()
+{
+    /* i18n: Logins and passwords in websites and web forms */
+    midori_private_data_register_item ("formhistory", _("Saved logins and _passwords"),
+        G_CALLBACK (midori_clear_saved_logins_cb));
+    midori_private_data_register_item ("web-cookies", _("Cookies and Website data"),
+        G_CALLBACK (midori_clear_web_cookies_cb));
+    #if WEBKIT_CHECK_VERSION (1, 3, 11)
+    /* TODO: Preserve page icons of search engines and merge privacy items */
+    midori_private_data_register_item ("web-cache", _("Web Cache"),
+        G_CALLBACK (midori_clear_web_cache_cb));
+    #endif
+    midori_private_data_register_item ("page-icons", _("Website icons"),
+        G_CALLBACK (midori_clear_page_icons_cb));
+}
+
+void
+midori_private_data_clear_all (MidoriBrowser* browser)
+{
+    KatzeArray* history = katze_object_get_object (browser, "history");
+    KatzeArray* trash = katze_object_get_object (browser, "trash");
+    GList* data_items = midori_private_data_register_item (NULL, NULL, NULL);
+    GList* tabs = midori_browser_get_tabs (browser);
+    for (; tabs; tabs = g_list_next (tabs))
+        midori_browser_close_tab (browser, tabs->data);
+    g_list_free (tabs);
+    if (history != NULL)
+        katze_array_clear (history);
+    if (trash != NULL)
+        katze_array_clear (trash);
+    g_object_unref (history);
+    g_object_unref (trash);
+
+    for (; data_items != NULL; data_items = g_list_next (data_items))
+        ((MidoriPrivateDataItem*)(data_items->data))->clear ();
+}
+
+void
+midori_private_data_on_quit (MidoriWebSettings* settings)
+{
+    gint clear_prefs = MIDORI_CLEAR_NONE;
+    g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
+    if (clear_prefs & MIDORI_CLEAR_ON_QUIT)
+    {
+        GList* data_items = midori_private_data_register_item (NULL, NULL, NULL);
+        gchar* clear_data = katze_object_get_string (settings, "clear-data");
+
+        midori_remove_config_file (clear_prefs, MIDORI_CLEAR_SESSION, "session.xbel");
+        midori_remove_config_file (clear_prefs, MIDORI_CLEAR_HISTORY, "history.db");
+        midori_remove_config_file (clear_prefs, MIDORI_CLEAR_HISTORY, "tabtrash.xbel");
+
+        for (; data_items != NULL; data_items = g_list_next (data_items))
+        {
+            MidoriPrivateDataItem* privacy = data_items->data;
+            if (clear_data && strstr (clear_data, privacy->name))
+                privacy->clear ();
+        }
+        g_free (clear_data);
+    }
+}
+
+/**
+ * midori_private_data_register_item:
+ * @name: the name of the privacy item
+ * @label: a user visible, localized label
+ * @clear: a callback clearing data
+ *
+ * Registers an item to clear data, either via the
+ * Clear Private Data dialogue or when Midori quits.
+ *
+ * Return value: a #GList if all arguments are %NULL
+ **/
+GList*
+midori_private_data_register_item (const gchar* name,
+                                   const gchar* label,
+                                   GCallback    clear)
+{
+    static GList* items = NULL;
+    MidoriPrivateDataItem* item;
+
+    if (name == NULL && label == NULL && clear == NULL)
+        return items;
+
+    g_return_val_if_fail (name != NULL, NULL);
+    g_return_val_if_fail (label != NULL, NULL);
+    g_return_val_if_fail (clear != NULL, NULL);
+
+    item = g_new (MidoriPrivateDataItem, 1);
+    item->name = g_strdup (name);
+    item->label = g_strdup (label);
+    item->clear = clear;
+    items = g_list_append (items, item);
+    return NULL;
+}
+
diff --git a/midori/midori-privatedata.h b/midori/midori-privatedata.h
new file mode 100644
index 0000000..5470ccd
--- /dev/null
+++ b/midori/midori-privatedata.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 2008-2012 Christian Dywan <christian at twotoasts.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.
+*/
+
+#ifndef __PRIVATE_DATA_H__
+#define __PRIVATE_DATA_H__ 1
+
+#include <midori/midori-browser.h>
+#include <webkit/webkit.h>
+
+GtkWidget*
+midori_private_data_get_dialog (MidoriBrowser* browser);
+
+void
+midori_private_data_register_built_ins ();
+
+void
+midori_private_data_clear_all (MidoriBrowser* browser);
+
+void
+midori_private_data_on_quit (MidoriWebSettings* settings);
+
+typedef struct
+{
+    gchar* name;
+    gchar* label;
+    GCallback clear;
+} MidoriPrivateDataItem;
+
+GList*
+midori_private_data_register_item (const gchar* name,
+                                   const gchar* label,
+                                   GCallback    clear);
+
+#endif /* !__SOKOKE_H__ */
+
diff --git a/midori/midori.h b/midori/midori.h
index 2dace3d..7c4e616 100644
--- a/midori/midori.h
+++ b/midori/midori.h
@@ -20,6 +20,7 @@
 #include "midori-locationaction.h"
 #include "midori-panel.h"
 #include "midori-preferences.h"
+#include "midori-privatedata.h"
 #include "midori-searchaction.h"
 #include "midori-view.h"
 #include "midori-websettings.h"
diff --git a/midori/sokoke.c b/midori/sokoke.c
index cffb131..2faf092 100644
--- a/midori/sokoke.c
+++ b/midori/sokoke.c
@@ -824,45 +824,6 @@ sokoke_time_t_to_julian (const time_t* timestamp)
     return julian;
 }
 
-/**
- * sokoke_remove_path:
- * @path: an absolute path
- * @ignore_errors: keep removing even if an error occurred
- *
- * Removes the file at @path or the folder including any
- * child folders and files if @path is a folder.
- *
- * If @ignore_errors is %TRUE and @path is a folder with
- * children, one of which can't be removed, remaining
- * children will be deleted nevertheless
- * If @ignore_errors is %FALSE and @path is a folder, the
- * removal process will cancel immediately.
- *
- * Return value: %TRUE on success, %FALSE if an error occurred
- **/
-gboolean
-sokoke_remove_path (const gchar* path,
-                    gboolean     ignore_errors)
-{
-    GDir* dir = g_dir_open (path, 0, NULL);
-    const gchar* name;
-
-    if (!dir)
-        return g_remove (path) == 0;
-
-    while ((name = g_dir_read_name (dir)))
-    {
-        gchar* sub_path = g_build_filename (path, name, NULL);
-        if (!sokoke_remove_path (sub_path, ignore_errors) && !ignore_errors)
-            return FALSE;
-        g_free (sub_path);
-    }
-
-    g_dir_close (dir);
-    g_rmdir (path);
-    return TRUE;
-}
-
 gchar*
 sokoke_replace_variables (const gchar* template,
                           const gchar* variable_first, ...)
@@ -1051,40 +1012,6 @@ sokoke_recursive_fork_protection (const gchar* uri,
     return g_strcmp0 (fork_uri, uri) == 0 ? FALSE : TRUE;
 }
 
-/**
- * sokoke_register_privacy_item:
- * @name: the name of the privacy item
- * @label: a user visible, localized label
- * @clear: a callback clearing data
- *
- * Registers an item to clear data, either via the
- * Clear Private Data dialogue or when Midori quits.
- *
- * Return value: a #GList if all arguments are %NULL
- **/
-GList*
-sokoke_register_privacy_item (const gchar* name,
-                              const gchar* label,
-                              GCallback    clear)
-{
-    static GList* items = NULL;
-    SokokePrivacyItem* item;
-
-    if (name == NULL && label == NULL && clear == NULL)
-        return items;
-
-    g_return_val_if_fail (name != NULL, NULL);
-    g_return_val_if_fail (label != NULL, NULL);
-    g_return_val_if_fail (clear != NULL, NULL);
-
-    item = g_new (SokokePrivacyItem, 1);
-    item->name = g_strdup (name);
-    item->label = g_strdup (label);
-    item->clear = clear;
-    items = g_list_append (items, item);
-    return NULL;
-}
-
 static void
 sokoke_widget_clipboard_owner_clear_func (GtkClipboard* clipboard,
                                           gpointer      user_data)
diff --git a/midori/sokoke.h b/midori/sokoke.h
index 7d12538..1c86dfc 100644
--- a/midori/sokoke.h
+++ b/midori/sokoke.h
@@ -89,10 +89,6 @@ sokoke_action_create_popup_menu_item    (GtkAction*      action);
 gint64
 sokoke_time_t_to_julian                 (const time_t*   timestamp);
 
-gboolean
-sokoke_remove_path                      (const gchar*    path,
-                                         gboolean        ignore_errors);
-
 gchar*
 sokoke_replace_variables                (const gchar* template,
                                          const gchar* variable_first, ...);
@@ -116,18 +112,6 @@ gboolean
 sokoke_recursive_fork_protection        (const gchar*         uri,
                                          gboolean             set_uri);
 
-typedef struct
-{
-    gchar* name;
-    gchar* label;
-    GCallback clear;
-} SokokePrivacyItem;
-
-GList*
-sokoke_register_privacy_item (const gchar* name,
-                              const gchar* label,
-                              GCallback    clear);
-
 void
 sokoke_widget_copy_clipboard (GtkWidget*          widget,
                               const gchar*        text,


More information about the Xfce4-commits mailing list