[gtk+/gtk-2-24] recent-manager: Add migration to the new storage file location
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-2-24] recent-manager: Add migration to the new storage file location
- Date: Sun, 31 Oct 2010 14:33:41 +0000 (UTC)
commit 7825f01b2fb65dab94cb931780e958bc00448484
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Sat Oct 30 15:11:23 2010 +0100
recent-manager: Add migration to the new storage file location
The recently-used.xbel file location has been moved from $HOME to
$XDG_DATA_DIR, to be compliant with the desktop bookmark specification
and with other desktop environments following it.
The effective change was done in gtk+-3, but we need a migration path
for gtk+-2.
The possible cases are:
â?¢ the old file is not present, so we just switch to the new one;
â?¢ the old file is present, but the new one is not; in this case
we rename the old file to the new one.
â?¢ both the old file and the new file are present; in this case,
we try a simple merge of the contents and remove the old file.
The merge is the (obviously) more expensive option, but it should only
happen once.
https://bugzilla.gnome.org/show_bug.cgi?id=633242
gtk/gtkrecentmanager.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 135 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkrecentmanager.c b/gtk/gtkrecentmanager.c
index b1b1e25..b343920 100644
--- a/gtk/gtkrecentmanager.c
+++ b/gtk/gtkrecentmanager.c
@@ -42,7 +42,7 @@
#include "gtkalias.h"
/* the file where we store the recently used items */
-#define GTK_RECENTLY_USED_FILE ".recently-used.xbel"
+#define GTK_RECENTLY_USED_FILE "recently-used.xbel"
/* return all items by default */
#define DEFAULT_LIMIT -1
@@ -468,6 +468,139 @@ gtk_recent_manager_monitor_changed (GFileMonitor *monitor,
}
}
+/*
+ * get_default_recent_file:
+ *
+ * Retrieves the default storage file
+ *
+ * The default file is under XDG_DATA_HOME/recently-used.xbel but we also
+ * check if the old $HOME/.recently-used.xbel is still there, and rename it
+ * if needed.
+ *
+ * Return value: a newly allocated string with the new file
+ */
+static char *
+get_default_recent_file (void)
+{
+ char *old_file = g_build_filename (g_get_home_dir (),
+ "." GTK_RECENTLY_USED_FILE,
+ NULL);
+ char *new_file = g_build_filename (g_get_user_data_dir (),
+ GTK_RECENTLY_USED_FILE,
+ NULL);
+ GBookmarkFile *bf_old = NULL, *bf_new = NULL;
+ char **uris;
+ gsize n_uris, i;
+
+ /* simple case: the old file does not exist, so we just use the new one */
+ if (!g_file_test (old_file, G_FILE_TEST_EXISTS))
+ {
+ g_free (old_file);
+ return new_file;
+ }
+
+ /* less simple case: the old file still exists but the new one doesn't,
+ * so we rename the old one to the new one
+ */
+ if (!g_file_test (new_file, G_FILE_TEST_EXISTS))
+ {
+ if (g_rename (old_file, new_file) == -1)
+ filename_warning ("Unable to rename '%s': %s",
+ old_file,
+ g_strerror (errno));
+
+ g_free (old_file);
+ return new_file;
+ }
+
+ /* complex case: both the old file and the new file exist, so we do
+ * a preliminary parse pass and merge the contents, then remove the
+ * old file
+ */
+ bf_old = g_bookmark_file_new ();
+ if (!g_bookmark_file_load_from_file (bf_old, old_file, NULL))
+ goto unlink_and_return;
+
+ bf_new = g_bookmark_file_new ();
+ if (!g_bookmark_file_load_from_file (bf_new, new_file, NULL))
+ goto unlink_and_return;
+
+ uris = g_bookmark_file_get_uris (bf_old, &n_uris);
+ for (i = 0; i < n_uris; i++)
+ {
+ char *mime, *title, *description;
+ gboolean is_private;
+ char **apps;
+ gsize n_apps, j;
+
+ /* the new file always wins */
+ if (g_bookmark_file_has_item (bf_new, uris[i]))
+ continue;
+
+ mime = g_bookmark_file_get_mime_type (bf_old, uris[i], NULL);
+ title = g_bookmark_file_get_title (bf_old, uris[i], NULL);
+ description = g_bookmark_file_get_description (bf_old, uris[i], NULL);
+ is_private = g_bookmark_file_get_is_private (bf_old, uris[i], NULL);
+
+ g_bookmark_file_set_mime_type (bf_new, uris[i], mime);
+
+ if (title != NULL)
+ g_bookmark_file_set_title (bf_new, uris[i], title);
+
+ if (description != NULL)
+ g_bookmark_file_set_description (bf_new, uris[i], description);
+
+ g_free (mime);
+ g_free (title);
+ g_free (description);
+
+ g_bookmark_file_set_is_private (bf_new, uris[i], is_private);
+
+ apps = g_bookmark_file_get_applications (bf_old, uris[i], &n_apps, NULL);
+ for (j = 0; j < n_apps; j++)
+ {
+ char *exec;
+ guint count;
+ time_t stamp;
+
+ g_bookmark_file_get_app_info (bf_old, uris[i], apps[j],
+ &exec,
+ &count,
+ &stamp,
+ NULL);
+
+ g_bookmark_file_set_app_info (bf_new, uris[i], apps[j],
+ exec,
+ count,
+ stamp,
+ NULL);
+
+ g_free (exec);
+ }
+
+ g_strfreev (apps);
+ }
+
+ g_strfreev (uris);
+
+ /* we don't particularly care about errors here; if it fails then
+ * we start with a blank slate anyhow
+ */
+ g_bookmark_file_to_file (bf_new, new_file, NULL);
+
+unlink_and_return:
+ if (bf_old != NULL)
+ g_bookmark_file_free (bf_old);
+
+ if (bf_new != NULL)
+ g_bookmark_file_free (bf_new);
+
+ g_unlink (old_file);
+ g_free (old_file);
+
+ return new_file;
+}
+
static void
gtk_recent_manager_set_filename (GtkRecentManager *manager,
const gchar *filename)
@@ -508,9 +641,7 @@ gtk_recent_manager_set_filename (GtkRecentManager *manager,
else
{
if (!filename || *filename == '\0')
- priv->filename = g_build_filename (g_get_home_dir (),
- GTK_RECENTLY_USED_FILE,
- NULL);
+ priv->filename = get_default_recent_file ();
else
priv->filename = g_strdup (filename);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]