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