Re: [PATCH] Move custom icons when copying metadata



On Mo, 2005-12-19 at 10:19 +0100, Alexander Larsson wrote:
> On Sun, 2005-12-18 at 22:45 +0100, Christian Neumair wrote:
> > On Mo, 2005-09-26 at 12:28 +0200, Alexander Larsson wrote:
> > > Its sort of strange that the metafile system special-cases a specific
> > > key entry like this. It would make more sense to e.g. store the custom
> > > icon with a relative filename. That would work for more cases than the
> > > prefix of the uri being identical too. For instance when there are
> > > symlinks etc involved.
> > 
> > Do you prefer the attached patch?
> 
> Yeah that looks better.
> 
>  			if (nautilus_file_is_mime_type (file, "application/x-desktop")) {
> +				icon = g_strdup (icon_path);
> +
> 
> This seems to leak though.

I don't think it leaked, the free/malloc codepath was a bit
undiscoverable, though.
I'm attaching a new patch, which aims to be a a bit more readable. This
one also sets the default path of the image file chooser to the target
directory, ensures that no image preview flickering occurs when opening
the file chooser and calls set_icon in the file chooser result switch
with the selected URI instead of using the filename.

-- 
Christian Neumair <chris gnome-de org>
Index: libnautilus-private/nautilus-file.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file.c,v
retrieving revision 1.377
diff -u -p -r1.377 nautilus-file.c
--- libnautilus-private/nautilus-file.c	12 Dec 2005 16:59:10 -0000	1.377
+++ libnautilus-private/nautilus-file.c	19 Dec 2005 18:29:10 -0000
@@ -2766,19 +2766,35 @@ char *
 nautilus_file_get_custom_icon (NautilusFile *file)
 {
 	char *uri;
+	char *dir_uri;
+	char *custom_icon;
+	char *tmp;
 
-	g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
-	
-	uri = NULL;
+	g_assert (NAUTILUS_IS_FILE (file));
 
 	/* Metadata takes precedence */
 	uri = nautilus_file_get_metadata (file, NAUTILUS_METADATA_KEY_CUSTOM_ICON, NULL);
+	if (uri != NULL && nautilus_file_is_directory (file)) {
+		/* The relative concatenation code will truncate
+		 * the URI basename without a trailing "/".
+		 * */
+		tmp = nautilus_file_get_uri (file);
+		dir_uri = g_strconcat (tmp, "/", NULL);
+		g_free (tmp);
 
-	if (uri == NULL && file->details->got_link_info) {
-		uri = g_strdup (file->details->custom_icon);
-	}
+		custom_icon = gnome_vfs_uri_make_full_from_relative (dir_uri, uri);
 
-	return uri;
+		g_free (dir_uri);
+		g_free (uri);
+	} else {
+		custom_icon = uri;
+	}
+ 
+	if (custom_icon == NULL && file->details->got_link_info) {
+		custom_icon = g_strdup (file->details->custom_icon);
+ 	}
+ 
+	return custom_icon;
 }
 
 
Index: src/file-manager/fm-properties-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-properties-window.c,v
retrieving revision 1.224
diff -u -p -r1.224 fm-properties-window.c
--- src/file-manager/fm-properties-window.c	12 Dec 2005 16:59:11 -0000	1.224
+++ src/file-manager/fm-properties-window.c	19 Dec 2005 18:29:13 -0000
@@ -460,7 +460,6 @@ fm_properties_window_drag_data_received 
 					 guint info, guint time)
 {
 	char **uris;
-	char *path;
 	gboolean exactly_one;
 	GtkImage *image;
  	GtkWindow *window; 
@@ -485,9 +484,7 @@ fm_properties_window_drag_data_received 
 			 window);
 	} else {		
 		if (uri_is_local_image (uris[0])) {			
-			path = gnome_vfs_get_local_path_from_uri (uris[0]);
-			set_icon (path,  FM_PROPERTIES_WINDOW (window));
-			g_free (path);
+			set_icon (uris[0], FM_PROPERTIES_WINDOW (window));
 		} else {	
 			if (eel_is_remote_uri (uris[0])) {
 				eel_show_error_dialog
@@ -3720,26 +3717,64 @@ real_finalize (GObject *object)
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+/* converts
+ *  file://foo/foobar/foofoo/bar
+ * to
+ *  foofoo/bar
+ * if
+ *  file://foo/foobar
+ * is the parent
+ *
+ * It does not resolve any symlinks.
+ * */
+static char *
+make_relative_uri_from_full (const char *uri,
+			     const char *base_uri)
+{
+	g_assert (uri != NULL);
+	g_assert (base_uri != NULL);
+
+	if (g_str_has_prefix (uri, base_uri)) {
+		uri += strlen (base_uri);
+		if (*uri != '/') {
+			return NULL;
+		}
+
+		while (*uri == '/') {
+			uri++;
+		}
+
+		if (*uri != '\0') {
+			return g_strdup (uri);
+		}
+	}
+
+	return NULL;
+}
+
 /* icon selection callback to set the image of the file object to the selected file */
 static void
-set_icon (const char* icon_path, FMPropertiesWindow *properties_window)
+set_icon (const char* icon_uri, FMPropertiesWindow *properties_window)
 {
 	NautilusFile *file;
-	char *icon_uri;
 	GnomeDesktopItem *ditem;
 	char *file_uri;
-	
-	g_return_if_fail (properties_window != NULL);
-	g_return_if_fail (FM_IS_PROPERTIES_WINDOW (properties_window));
+	char *icon_path;
+	char *real_icon_uri;
+
+	g_assert (icon_uri != NULL);
+	g_assert (FM_IS_PROPERTIES_WINDOW (properties_window));
 
+	icon_path = gnome_vfs_get_local_path_from_uri (icon_uri);
+	/* we don't allow remote URIs */
 	if (icon_path != NULL) {
 		GList *l;
-		
-		icon_uri = gnome_vfs_get_uri_from_local_path (icon_path);
+
 		for (l = properties_window->details->original_files; l != NULL; l = l->next) {
 			file = NAUTILUS_FILE (l->data);
+
 			file_uri = nautilus_file_get_uri (file);
-			
+
 			if (nautilus_file_is_mime_type (file, "application/x-desktop")) {
 				ditem = gnome_desktop_item_new_from_uri (file_uri,
 									 0,
@@ -3755,15 +3790,21 @@ set_icon (const char* icon_path, FMPrope
 									     NAUTILUS_FILE_ATTRIBUTE_CUSTOM_ICON);
 				}
 			} else {
+				real_icon_uri = make_relative_uri_from_full (icon_uri, file_uri);
+				if (real_icon_uri == NULL) {
+					real_icon_uri = g_strdup (icon_uri);
+				}
 			
-				nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_CUSTOM_ICON, NULL, icon_uri);
+				nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_CUSTOM_ICON, NULL, real_icon_uri);
 				nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_ICON_SCALE, NULL, NULL);
+
+				g_free (real_icon_uri);
 			}
 
 			g_free (file_uri);
-
 		}
-		g_free (icon_uri);	
+
+		g_free (icon_path);
 	}
 }
 
@@ -3820,6 +3861,7 @@ select_image_button_callback (GtkWidget 
 	GList *l;
 	NautilusFile *file;
 	char *image_path;
+	char *uri;
 	gboolean revert_is_sensitive;
 
 	g_assert (FM_IS_PROPERTIES_WINDOW (window));
@@ -3844,6 +3886,7 @@ select_image_button_callback (GtkWidget 
 		gtk_widget_set_size_request (preview, PREVIEW_IMAGE_WIDTH, -1);
 		gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview);
 		gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (dialog), FALSE);
+		gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (dialog), FALSE);
 
 		g_signal_connect (dialog, "update-preview",
 				  G_CALLBACK (update_preview_callback), window);
@@ -3854,6 +3897,23 @@ select_image_button_callback (GtkWidget 
 					   (gpointer *) &window->details->icon_chooser);
 	}
 
+	/* it's likely that the user wants to pick an icon that is inside a local directory */
+	if (g_list_length (window->details->original_files) == 1) {
+		file = NAUTILUS_FILE (window->details->original_files->data);
+
+		if (nautilus_file_is_directory (file)) {
+			uri = nautilus_file_get_uri (file);
+
+			image_path = gnome_vfs_get_local_path_from_uri (uri);
+			if (image_path != NULL) {
+				gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), image_path);
+				g_free (image_path);
+			}
+
+			g_free (uri);
+		}
+	}
+
 	revert_is_sensitive = FALSE;
 	for (l = window->details->original_files; l != NULL; l = l->next) {
 		file = NAUTILUS_FILE (l->data);
@@ -3873,9 +3933,9 @@ select_image_button_callback (GtkWidget 
 		break;
 
 	case GTK_RESPONSE_OK:
-		image_path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-		set_icon (image_path, window);
-		g_free (image_path);
+		uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+		set_icon (uri, window);
+		g_free (uri);
 		break;
 
 	default:

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]