[GNOME] GNOME et xdg-user-dirs

Xorg, Compiz, KDE / Gnome / Xfce / Fluxbox / e17 / fvwm ... GDM/KDM/XDM...
Nah
newbie
Messages : 2
Inscription : sam. 30 juin 2007, 12:23

[GNOME] GNOME et xdg-user-dirs

Message par Nah »

Bonjour,
je souhaiterai savoir si il est possible d'utiliser xdg-user-dirs pour qu'il crée les répertoires par défaut et en Français, comme par exemple sous Fedora 7 ?

Merci d'avance pour votre aide ! :D

-> xdg-user-dirs
Avatar de l’utilisateur
atlas95
Hankyu
Messages : 16
Inscription : dim. 11 févr. 2007, 21:58

Message par atlas95 »

+1
Nah
newbie
Messages : 2
Inscription : sam. 30 juin 2007, 12:23

Message par Nah »

Après une petite recherche, c'est vraiment simple à mettre en place, il suffit d'installer xdg-user-dirs ains que xdg-user-dirs-gtk, par contre il faut pas oublier de patcher Nautilus, sinon ça passe pas avec le dossier "Desktop", il sera pas pris en compte.

Il faut aussi ajouter "xdg-user-dirs-gtk-update" a votre session, comme ça tout les changements (si vous déplacez/renomez un dossier..) sont pris en compte...

Voici le patch pour Nautilus: (proviens de Fedora)

Code : Tout sélectionner

Index: src/file-manager/fm-directory-view.c
===================================================================
--- src/file-manager/fm-directory-view.c	(revision 12790)
+++ src/file-manager/fm-directory-view.c	(working copy)
@@ -151,6 +151,7 @@
 #define FM_DIRECTORY_VIEW_POPUP_PATH_LOCATION				"/location"
 
 #define MAX_MENU_LEVELS 5
+#define TEMPLATE_LIMIT 30
 
 enum {
 	ADD_FILE,
@@ -187,9 +188,6 @@ static gboolean confirm_trash_auto_value
 static char *scripts_directory_uri;
 static int scripts_directory_uri_length;
 
-static char *templates_directory_uri;
-static int templates_directory_uri_length;
-
 struct FMDirectoryViewDetails
 {
 	NautilusWindowInfo *window;
@@ -389,6 +387,8 @@ static gboolean activate_check_mime_type
 								NautilusFile *file,
 								gboolean warn_on_mismatch);
 static GdkDragAction ask_link_action                           (FMDirectoryView      *view);
+static void     update_templates_directory                     (FMDirectoryView *view);
+static void     user_dirs_changed                              (FMDirectoryView *view);
 
 static void file_get_volume_and_drive (NautilusFile    *file,
 				       GnomeVFSVolume **volume,
@@ -1619,17 +1619,6 @@ set_up_scripts_directory_global (void)
 }
 
 static void
-set_up_templates_directory_global (void)
-{
-	if (templates_directory_uri != NULL) {
-		return;
-	}
-	
-	templates_directory_uri = nautilus_get_templates_directory_uri ();
-	templates_directory_uri_length = strlen (templates_directory_uri);
-}
-
-static void
 create_scripts_directory (void)
 {
 	char *gnome1_path, *gnome1_uri_str;
@@ -1912,6 +1901,7 @@ fm_directory_view_init (FMDirectoryView 
 	static gboolean setup_autos = FALSE;
 	NautilusDirectory *scripts_directory;
 	NautilusDirectory *templates_directory;
+	char *templates_uri;
 
 	if (!setup_autos) {
 		setup_autos = TRUE;
@@ -1940,10 +1930,18 @@ fm_directory_view_init (FMDirectoryView 
 	add_directory_to_scripts_directory_list (view, scripts_directory);
 	nautilus_directory_unref (scripts_directory);
 
-	set_up_templates_directory_global ();
-	templates_directory = nautilus_directory_get (templates_directory_uri);
-	add_directory_to_templates_directory_list (view, templates_directory);
-	nautilus_directory_unref (templates_directory);
+	if (nautilus_should_use_templates_directory ()) {
+		templates_uri = nautilus_get_templates_directory_uri ();
+		templates_directory = nautilus_directory_get (templates_uri);
+		g_free (templates_uri);
+		add_directory_to_templates_directory_list (view, templates_directory);
+		nautilus_directory_unref (templates_directory);
+	}
+	update_templates_directory (view);
+	g_signal_connect_object (nautilus_signaller_get_current (),
+				 "user_dirs_changed",
+				 G_CALLBACK (user_dirs_changed),
+				 view, G_CONNECT_SWAPPED);
 
 	view->details->sort_directories_first = 
 		eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
@@ -5712,19 +5710,52 @@ add_template_to_templates_menus (FMDirec
 	g_free (action_name);
 }
 
+static void
+update_templates_directory (FMDirectoryView *view)
+{
+	NautilusDirectory *templates_directory;
+	GList *node, *next;
+	char *templates_uri;
+
+	for (node = view->details->templates_directory_list; node != NULL; node = next) {
+		next = node->next;
+		remove_directory_from_templates_directory_list (view, node->data);
+	}
+	
+	if (nautilus_should_use_templates_directory ()) {
+		templates_uri = nautilus_get_templates_directory_uri ();
+		templates_directory = nautilus_directory_get (templates_uri);
+		g_free (templates_uri);
+		add_directory_to_templates_directory_list (view, templates_directory);
+		nautilus_directory_unref (templates_directory);
+	}
+}
+
+static void
+user_dirs_changed (FMDirectoryView *view)
+{
+	update_templates_directory (view);
+	view->details->templates_invalid = TRUE;
+	schedule_update_menus (view);
+}
 
 static gboolean
-directory_belongs_in_templates_menu (const char *uri)
+directory_belongs_in_templates_menu (const char *templates_directory_uri,
+				     const char *uri)
 {
 	int num_levels;
 	int i;
 
-	if (!eel_str_has_prefix (uri, templates_directory_uri)) {
+	if (templates_directory_uri == NULL) {
+		return FALSE;
+	}
+	
+	if (!g_str_has_prefix (uri, templates_directory_uri)) {
 		return FALSE;
 	}
 
 	num_levels = 0;
-	for (i = templates_directory_uri_length; uri[i] != '\0'; i++) {
+	for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) {
 		if (uri[i] == '/') {
 			num_levels++;
 		}
@@ -5738,7 +5769,9 @@ directory_belongs_in_templates_menu (con
 }
 
 static gboolean
-update_directory_in_templates_menu (FMDirectoryView *view, NautilusDirectory *directory)
+update_directory_in_templates_menu (FMDirectoryView *view,
+				    const char *templates_directory_uri,
+				    NautilusDirectory *directory)
 {
 	char *menu_path, *popup_bg_path;
 	GList *file_list, *filtered, *node;
@@ -5747,9 +5780,13 @@ update_directory_in_templates_menu (FMDi
 	NautilusDirectory *dir;
 	char *escaped_path;
 	char *uri;
+	int num;
+
+	/* We know this directory belongs to the template dir, so it must exist */
+	g_assert (templates_directory_uri);
 	
 	uri = nautilus_directory_get_uri (directory);
-	escaped_path = escape_action_path (uri + templates_directory_uri_length);
+	escaped_path = escape_action_path (uri + strlen (templates_directory_uri));
 	g_free (uri);
 	menu_path = g_strconcat (FM_DIRECTORY_VIEW_MENU_PATH_NEW_DOCUMENTS_PLACEHOLDER,
 				 escaped_path,
@@ -5765,13 +5802,14 @@ update_directory_in_templates_menu (FMDi
 
 	file_list = nautilus_file_list_sort_by_display_name (filtered);
 
+	num = 0;
 	any_templates = FALSE;
-	for (node = file_list; node != NULL; node = node->next) {
+	for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
 		file = node->data;
 
 		if (nautilus_file_is_directory (file)) {
 			uri = nautilus_file_get_uri (file);
-			if (directory_belongs_in_templates_menu (uri)) {
+			if (directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
 				dir = nautilus_directory_get (uri);
 				add_directory_to_templates_directory_list (view, dir);
 				nautilus_directory_unref (dir);
@@ -5809,6 +5847,13 @@ update_templates_menu (FMDirectoryView *
 	GtkUIManager *ui_manager;
 	char *uri;
 	GtkAction *action;
+	char *templates_directory_uri;
+
+	if (nautilus_should_use_templates_directory ()) {
+		templates_directory_uri = nautilus_get_templates_directory_uri ();
+	} else {
+		templates_directory_uri = NULL;
+	}
 
 	/* There is a race condition here.  If we don't mark the scripts menu as
 	   valid before we begin our task then we can lose template menu updates that
@@ -5833,9 +5878,11 @@ update_templates_menu (FMDirectoryView *
 		directory = node->data;
 
 		uri = nautilus_directory_get_uri (directory);
-		if (!directory_belongs_in_templates_menu (uri)) {
+		if (!directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
 			remove_directory_from_templates_directory_list (view, directory);
-		} else if (update_directory_in_templates_menu (view, directory)) {
+		} else if (update_directory_in_templates_menu (view,
+							       templates_directory_uri,
+							       directory)) {
 			any_templates = TRUE;
 		}
 		g_free (uri);
@@ -5844,6 +5891,8 @@ update_templates_menu (FMDirectoryView *
 
 	action = gtk_action_group_get_action (view->details->dir_action_group, FM_ACTION_NO_TEMPLATES);
 	gtk_action_set_visible (action, !any_templates);
+
+	g_free (templates_directory_uri);
 }
 
 
Index: libnautilus-private/nautilus-file.c
===================================================================
--- libnautilus-private/nautilus-file.c	(revision 12790)
+++ libnautilus-private/nautilus-file.c	(working copy)
@@ -839,7 +839,6 @@ nautilus_file_can_rename (NautilusFile *
 	}
 
 	if ((is_desktop_file (file) && !can_rename_desktop_file (file)) ||
-	     nautilus_file_is_desktop_directory (file) ||
 	     nautilus_file_is_home (file)) {
 		return FALSE;
 	}
Index: libnautilus-private/nautilus-file-utilities.c
===================================================================
--- libnautilus-private/nautilus-file-utilities.c	(revision 12790)
+++ libnautilus-private/nautilus-file-utilities.c	(working copy)
@@ -31,6 +31,7 @@
 #include "nautilus-metafile.h"
 #include "nautilus-file.h"
 #include "nautilus-search-directory.h"
+#include "nautilus-signaller.h"
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-string.h>
 #include <eel/eel-vfs-extensions.h>
@@ -49,6 +50,10 @@
 #define LEGACY_DESKTOP_DIRECTORY_NAME ".gnome-desktop"
 #define DEFAULT_DESKTOP_DIRECTORY_MODE (0755)
 
+static void update_xdg_dir_cache (void);
+static void schedule_user_dirs_changed (void);
+static void desktop_dir_changed (void);
+
 
 char *
 nautilus_compute_title_for_uri (const char *text_uri)
@@ -148,15 +153,280 @@ nautilus_get_user_directory (void)
 	return user_directory;
 }
 
+typedef struct {
+	char *type;
+	char *path;
+	NautilusFile *file;
+} XdgDirEntry;
+
+
+static XdgDirEntry *
+parse_xdg_dirs (const char *config_file)
+{
+  GArray *array;
+  char *config_file_free = NULL;
+  XdgDirEntry dir;
+  char *data;
+  char **lines;
+  char *p, *d;
+  int i;
+  char *type_start, *type_end;
+  char *value, *unescaped;
+  gboolean relative;
+
+  array = g_array_new (TRUE, TRUE, sizeof (XdgDirEntry));
+  
+  if (config_file == NULL)
+    {
+      config_file_free = g_build_filename (g_get_user_config_dir (),
+					   "user-dirs.dirs", NULL);
+      config_file = (const char *)config_file_free;
+    }
+
+  if (g_file_get_contents (config_file, &data, NULL, NULL))
+    {
+      lines = g_strsplit (data, "\n", 0);
+      g_free (data);
+      for (i = 0; lines[i] != NULL; i++)
+	{
+	  p = lines[i];
+	  while (g_ascii_isspace (*p))
+	    p++;
+      
+	  if (*p == '#')
+	    continue;
+      
+	  value = strchr (p, '=');
+	  if (value == NULL)
+	    continue;
+	  *value++ = 0;
+      
+	  g_strchug (g_strchomp (p));
+	  if (!g_str_has_prefix (p, "XDG_"))
+	    continue;
+	  if (!g_str_has_suffix (p, "_DIR"))
+	    continue;
+	  type_start = p + 4;
+	  type_end = p + strlen (p) - 4;
+      
+	  while (g_ascii_isspace (*value))
+	    value++;
+      
+	  if (*value != '"')
+	    continue;
+	  value++;
+      
+	  relative = FALSE;
+	  if (g_str_has_prefix (value, "$HOME"))
+	    {
+	      relative = TRUE;
+	      value += 5;
+	      while (*value == '/')
+		      value++;
+	    }
+	  else if (*value != '/')
+	    continue;
+	  
+	  d = unescaped = g_malloc (strlen (value) + 1);
+	  while (*value && *value != '"')
+	    {
+	      if ((*value == '\\') && (*(value + 1) != 0))
+		value++;
+	      *d++ = *value++;
+	    }
+	  *d = 0;
+      
+	  *type_end = 0;
+	  dir.type = g_strdup (type_start);
+	  if (relative)
+	    {
+	      dir.path = g_build_filename (g_get_home_dir (), unescaped, NULL);
+	      g_free (unescaped);
+	    }
+	  else 
+	    dir.path = unescaped;
+      
+	  g_array_append_val (array, dir);
+	}
+      
+      g_strfreev (lines);
+    }
+  
+  g_free (config_file_free);
+  
+  return (XdgDirEntry *)g_array_free (array, FALSE);
+}
+
+static XdgDirEntry *cached_xdg_dirs = NULL;
+static GnomeVFSMonitorHandle *cached_xdg_dirs_handle = NULL;
+
+static void
+xdg_dir_changed (NautilusFile *file,
+		 XdgDirEntry *dir)
+{
+	char *file_uri;
+	char *dir_uri;
+	char *path;
+	
+	file_uri = nautilus_file_get_uri (file);
+	dir_uri = gnome_vfs_get_uri_from_local_path (dir->path);
+	if (file_uri && dir_uri &&
+	    !gnome_vfs_uris_match (dir_uri, file_uri)) {
+		path = gnome_vfs_get_local_path_from_uri (file_uri);
+
+		if (path) {
+			char *argv[5];
+			int i;
+			
+			g_free (dir->path);
+			dir->path = path;
+
+			i = 0;
+			argv[i++] = "xdg-user-dirs-update";
+			argv[i++] = "--set";
+			argv[i++] = dir->type;
+			argv[i++] = dir->path;
+			argv[i++] = NULL;
+
+			/* We do this sync, to avoid possible race-conditions
+			   if multiple dirs change at the same time. Its
+			   blocking the main thread, but these updates should
+			   be very rare and very fast. */
+			g_spawn_sync (NULL, 
+				      argv, NULL,
+				      G_SPAWN_SEARCH_PATH |
+				      G_SPAWN_STDOUT_TO_DEV_NULL |
+				      G_SPAWN_STDERR_TO_DEV_NULL,
+				      NULL, NULL,
+				      NULL, NULL, NULL, NULL);
+			schedule_user_dirs_changed ();
+			desktop_dir_changed ();
+		}
+	}
+	g_free (file_uri);
+	g_free (dir_uri);
+}
+
+static void 
+xdg_dir_cache_changed_cb (GnomeVFSMonitorHandle    *handle,
+			  const gchar              *monitor_uri,
+			  const gchar              *info_uri,
+			  GnomeVFSMonitorEventType  event_type,
+			  gpointer                  user_data)
+{
+	if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ||
+	    event_type == GNOME_VFS_MONITOR_EVENT_CREATED) {
+		update_xdg_dir_cache ();
+	}
+}
+
+static int user_dirs_changed_tag = 0;
+
+static gboolean
+emit_user_dirs_changed_idle (gpointer data)
+{
+	g_signal_emit_by_name (nautilus_signaller_get_current (),
+			       "user_dirs_changed");
+	user_dirs_changed_tag = 0;
+	return FALSE;
+}
+
+static void
+schedule_user_dirs_changed (void)
+{
+	if (user_dirs_changed_tag == 0) {
+		user_dirs_changed_tag = g_idle_add (emit_user_dirs_changed_idle, NULL);
+	}
+}
+
+static void
+update_xdg_dir_cache (void)
+{
+	static gboolean started_monitor = FALSE;
+	char *config_file, *uri;
+	int i;
+
+	if (cached_xdg_dirs) {
+		for (i = 0 ; cached_xdg_dirs[i].type != NULL; i++) {
+			if (cached_xdg_dirs[i].file != NULL) {
+				nautilus_file_monitor_remove (cached_xdg_dirs[i].file,
+							      &cached_xdg_dirs[i]);
+				g_signal_handlers_disconnect_by_func (cached_xdg_dirs[i].file,
+								      G_CALLBACK (xdg_dir_changed),
+								      &cached_xdg_dirs[i]);
+				nautilus_file_unref (cached_xdg_dirs[i].file);
+			}
+			g_free (cached_xdg_dirs[i].type);
+			g_free (cached_xdg_dirs[i].path);
+		}
+		g_free (cached_xdg_dirs);
+
+		schedule_user_dirs_changed ();
+		desktop_dir_changed ();
+	}
+
+	if (!started_monitor) {
+		config_file = g_build_filename (g_get_user_config_dir (),
+						     "user-dirs.dirs", NULL);
+		uri = gnome_vfs_get_uri_from_local_path (config_file);
+		gnome_vfs_monitor_add (&cached_xdg_dirs_handle,
+				       uri,
+				       GNOME_VFS_MONITOR_FILE,
+				       xdg_dir_cache_changed_cb,
+				       NULL);
+		g_free (uri);
+		g_free (config_file);
+	}
+	
+	cached_xdg_dirs = parse_xdg_dirs (NULL);
+	
+	for (i = 0 ; cached_xdg_dirs[i].type != NULL; i++) {
+		cached_xdg_dirs[i].file = NULL;
+		if (strcmp (cached_xdg_dirs[i].path, g_get_home_dir ()) != 0) {
+			uri = gnome_vfs_get_uri_from_local_path (cached_xdg_dirs[i].path);
+			cached_xdg_dirs[i].file = nautilus_file_get (uri);
+			nautilus_file_monitor_add (cached_xdg_dirs[i].file,
+						   &cached_xdg_dirs[i],
+						   NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE);
+			g_signal_connect (cached_xdg_dirs[i].file,
+					  "changed", G_CALLBACK (xdg_dir_changed), &cached_xdg_dirs[i]);
+			g_free (uri);
+		}
+	}
+}
+
+char *
+nautilus_get_xdg_dir (const char *type)
+{
+	int i;
+
+	if (cached_xdg_dirs == NULL) {
+		update_xdg_dir_cache ();
+	}
+
+	for (i = 0 ; cached_xdg_dirs != NULL && cached_xdg_dirs[i].type != NULL; i++) {
+		if (strcmp (cached_xdg_dirs[i].type, type) == 0) {
+			return g_strdup (cached_xdg_dirs[i].path);
+		}
+	}
+	if (strcmp ("DESKTOP", type) == 0) {
+		return g_build_filename (g_get_home_dir (), DESKTOP_DIRECTORY_NAME, NULL);
+	}
+	if (strcmp ("TEMPLATES", type) == 0) {
+		return g_build_filename (g_get_home_dir (), "Templates", NULL);
+	}
+	
+	return g_strdup (g_get_home_dir ());
+}
+
 static char *
 get_desktop_path (void)
 {
 	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR)) {
 		return g_strdup (g_get_home_dir());
 	} else {
-		return g_build_filename (g_get_home_dir (), DESKTOP_DIRECTORY_NAME, NULL);
+		return nautilus_get_xdg_dir ("DESKTOP");
 	}
-	
 }
 
 /**
@@ -231,11 +501,22 @@ nautilus_get_home_directory_uri (void)
 }
 
 
+gboolean
+nautilus_should_use_templates_directory (void)
+{
+	char *dir;
+	gboolean res;
+	
+	dir = nautilus_get_xdg_dir ("TEMPLATES");
+	res = strcmp (dir, g_get_home_dir ()) != 0;
+	g_free (dir);
+	return res;
+}
+
 char *
 nautilus_get_templates_directory (void)
 {
-	return  g_build_filename (g_get_home_dir(),
-				  "Templates", NULL);
+	return nautilus_get_xdg_dir ("TEMPLATES");
 }
 
 void
@@ -283,8 +564,9 @@ static char *escaped_desktop_dir_dirname
 static char *escaped_desktop_dir_filename = NULL;
 static gboolean desktop_dir_changed_callback_installed = FALSE;
 
+
 static void
-desktop_dir_changed_callback (gpointer callback_data)
+desktop_dir_changed (void)
 {
 	g_free (escaped_desktop_dir);
 	g_free (escaped_desktop_dir_filename);
@@ -295,6 +577,12 @@ desktop_dir_changed_callback (gpointer c
 }
 
 static void
+desktop_dir_changed_callback (gpointer callback_data)
+{
+	desktop_dir_changed ();
+}
+
+static void
 update_desktop_dir (void)
 {
 	char *uri, *path;
Index: libnautilus-private/nautilus-file-utilities.h
===================================================================
--- libnautilus-private/nautilus-file-utilities.h	(revision 12790)
+++ libnautilus-private/nautilus-file-utilities.h	(working copy)
@@ -37,6 +37,7 @@ gboolean nautilus_file_name_matches_back
 /* These functions all return something something that needs to be
  * freed with g_free, is not NULL, and is guaranteed to exist.
  */
+char *   nautilus_get_xdg_dir                        (const char *type);
 char *   nautilus_get_user_directory                 (void);
 char *   nautilus_get_desktop_directory              (void);
 char *   nautilus_get_desktop_directory_uri          (void);
@@ -49,6 +50,7 @@ gboolean nautilus_is_home_directory_file
 char *   nautilus_get_gmc_desktop_directory          (void);
 char *   nautilus_get_pixmap_directory               (void);
 
+gboolean nautilus_should_use_templates_directory     (void);
 char *   nautilus_get_templates_directory            (void);
 char *   nautilus_get_templates_directory_uri        (void);
 void     nautilus_create_templates_directory         (void);
Index: libnautilus-private/nautilus-signaller.c
===================================================================
--- libnautilus-private/nautilus-signaller.c	(revision 12790)
+++ libnautilus-private/nautilus-signaller.c	(working copy)
@@ -39,6 +39,7 @@ enum {
 	HISTORY_LIST_CHANGED,
 	EMBLEMS_CHANGED,
 	POPUP_MENU_CHANGED,
+	USER_DIRS_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -94,4 +95,12 @@ nautilus_signaller_class_init (NautilusS
 		              NULL, NULL,
 		              g_cclosure_marshal_VOID__VOID,
 		              G_TYPE_NONE, 0);
+	signals[USER_DIRS_CHANGED] =
+		g_signal_new ("user_dirs_changed",
+		              G_TYPE_FROM_CLASS (class),
+		              G_SIGNAL_RUN_LAST,
+		              0,
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
 }
Répondre