mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 22:10:08 +00:00
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
This commit is contained in:
parent
78bb09c5a1
commit
7825f01b2f
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user