Re: RE : new mime detection approach



Anne et Bertrand дµÀ:
From: Alexander Larsson <alexl redhat com>
 >
 >I read the mime detection threads, and considered the opinions and
 >options. It seems that there is no perfect solution to this problem.
 >After some discussion with dave I came up with a solution that seems to
 >work pretty well, although its not perfect.

Great !
Any chance to see this back-ported to nautilus-2.4 or to download the patches somewhere ?

Bertrand Dekoninck


I back ported the patch, but found no effect. Maybe something were wrong :-(

Could you please help me check these patches?

Regards
James Su
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-directory-async.c nautilus-2.4.1/libnautilus-private/nautilus-directory-async.c
--- nautilus-2.4.1.old/libnautilus-private/nautilus-directory-async.c	2003-08-29 20:03:51.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-directory-async.c	2004-01-18 10:53:20.284777176 +0800
@@ -526,6 +526,7 @@
 			      NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES) != FALSE;
 	request->file_info = (file_attributes & 
 			      (NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
+			       NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE |
 			       NAUTILUS_FILE_ATTRIBUTE_IS_DIRECTORY |
 			       NAUTILUS_FILE_ATTRIBUTE_CAPABILITIES |
 			       NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE)) != FALSE;
@@ -564,6 +565,8 @@
 	
 	request->metafile |= (file_attributes & 
 			      NAUTILUS_FILE_ATTRIBUTE_METADATA) != FALSE;
+
+ 	request->slow_mime_type = (file_attributes & NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE) != FALSE;
 }
 
 static void
@@ -581,6 +584,7 @@
 		NAUTILUS_FILE_ATTRIBUTE_CAPABILITIES |
 		NAUTILUS_FILE_ATTRIBUTE_CUSTOM_ICON |
 		NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
+		NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE |
 		NAUTILUS_FILE_ATTRIBUTE_METADATA |
 		NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE |
 		NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES;
@@ -873,7 +877,7 @@
 		if (file != NULL) {
 			/* file already exists, check if it changed */
 			set_file_unconfirmed (file, FALSE);
-			if (nautilus_file_update_info (file, file_info)) {
+			if (nautilus_file_update_info (file, file_info, FALSE)) {
 				/* File changed, notify about the change. */
 				nautilus_file_ref (file);
 				changed_files = g_list_prepend (changed_files, file);
@@ -1256,9 +1260,11 @@
 
 	/* Call the callback. */
 	if (callback->file != NULL) {
-		(* callback->callback.file) (callback->file,
-					     callback->callback_data);
-	} else {
+		if (callback->callback.file) {
+			(* callback->callback.file) (callback->file,
+						     callback->callback_data);
+		}
+	} else if (callback->callback.directory != NULL) {
 		if (directory == NULL || !callback->request.file_list) {
 			file_list = NULL;
 		} else {
@@ -1288,7 +1294,6 @@
 	g_assert (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
 	g_assert (file == NULL || NAUTILUS_IS_FILE (file));
 	g_assert (file != NULL || directory_callback != NULL);
-	g_assert (file == NULL || file_callback != NULL);
 	
 	/* Construct a callback object. */
 	callback.file = file;
@@ -1300,7 +1305,7 @@
 	callback.callback_data = callback_data;
 	nautilus_directory_set_up_request (&callback.request, file_attributes);
 	callback.request.file_list = wait_for_file_list;
-	
+
 	/* Handle the NULL case. */
 	if (directory == NULL) {
 		ready_callback_call (NULL, &callback);
@@ -1311,7 +1316,10 @@
 	if (g_list_find_custom (directory->details->call_when_ready_list,
 				&callback,
 				ready_callback_key_compare) != NULL) {
-		g_warning ("tried to add a new callback while an old one was pending");
+		if (file_callback != NULL && directory_callback != NULL) {
+			g_warning ("tried to add a new callback while an old one was pending");
+		}
+		/* NULL callback means, just read it. Conflicts are ok. */
 		return;
 	}
 
@@ -1649,6 +1657,26 @@
 }
 
 static gboolean
+always_lacks (NautilusFile *file)
+{
+	return TRUE;
+}
+
+static gboolean
+lacks_slow_mime_type (NautilusFile *file)
+{
+	return !file->details->got_slow_mime_type
+		&& !file->details->is_gone;
+}
+
+static gboolean
+wants_slow_mime_type (const Request *request)
+{
+	return request->slow_mime_type;
+}
+
+
+static gboolean
 lacks_deep_count (NautilusFile *file)
 {
 	return file->details->deep_counts_status != NAUTILUS_REQUEST_DONE;
@@ -1786,6 +1814,12 @@
 		}
 	}
 
+	if (request->slow_mime_type) {
+		if (has_problem (directory, file, lacks_slow_mime_type)) {
+			return FALSE;
+		}
+	}
+
 	if (request->top_left_text) {
 		if (has_problem (directory, file, lacks_top_left)) {
 			return FALSE;
@@ -2065,7 +2099,7 @@
 	
 #ifdef DEBUG_LOAD_DIRECTORY
 	g_message ("load_directory called to monitor file list of %s", directory->details->uri);
-#endif	
+#endif
 	gnome_vfs_async_load_directory
 		(&directory->details->directory_load_in_progress, /* handle */
 		 directory->details->uri,                         /* uri */
@@ -2759,6 +2793,7 @@
 	NautilusDirectory *directory;
 	NautilusFile *get_info_file;
 	GnomeVFSGetFileInfoResult *result;
+	gboolean has_slow_mime_type;
 
 	directory = NAUTILUS_DIRECTORY (callback_data);
 	g_assert (handle == NULL || handle == directory->details->get_info_in_progress);
@@ -2767,10 +2802,13 @@
 	g_assert (NAUTILUS_IS_FILE (get_info_file));
 
 	nautilus_directory_ref (directory);
+
+	has_slow_mime_type = directory->details->get_info_has_slow_mime_type;
 	
 	directory->details->get_info_file = NULL;
 	directory->details->get_info_in_progress = NULL;
-
+	directory->details->get_info_has_slow_mime_type = FALSE;
+	
 	/* ref here because we might be removing the last ref when we
 	 * mark the file gone below, but we need to keep a ref at
 	 * least long enough to send the change notification. 
@@ -2796,7 +2834,7 @@
 			}
 		}
 	} else {
-		nautilus_file_update_info (get_info_file, result->file_info);
+		nautilus_file_update_info (get_info_file, result->file_info, has_slow_mime_type);
 	}
 
 	nautilus_file_changed (get_info_file);
@@ -2818,7 +2856,8 @@
 		if (file != NULL) {
 			g_assert (NAUTILUS_IS_FILE (file));
 			g_assert (file->details->directory == directory);
-			if (is_needy (file, lacks_info, wants_info)) {
+			if (is_needy (file, lacks_info, wants_info) ||
+			    is_needy (file, lacks_slow_mime_type, wants_slow_mime_type)) {
 				return;
 			}
 		}
@@ -2835,16 +2874,20 @@
 	char *uri;
 	GnomeVFSURI *vfs_uri;
 	GList fake_list;
-
+	gboolean need_slow_mime;
+	GnomeVFSFileInfoOptions options;
+	
 	file_info_stop (directory);
 
 	if (directory->details->get_info_in_progress != NULL) {
 		return;
 	}
 
-	if (!is_needy (file, lacks_info, wants_info)) {
+	if (!is_needy (file, lacks_info, wants_info) &&
+	    !is_needy (file, lacks_slow_mime_type, wants_slow_mime_type)) {
 		return;
 	}
+	need_slow_mime = is_needy (file, always_lacks, wants_slow_mime_type);
 	
 	uri = nautilus_file_get_uri (file);
 	vfs_uri = gnome_vfs_uri_new (uri);
@@ -2857,6 +2900,7 @@
 		file->details->file_info_is_up_to_date = TRUE;
 		file->details->get_info_failed = TRUE;
 		file->details->get_info_error = GNOME_VFS_ERROR_INVALID_URI;
+		file->details->got_slow_mime_type = need_slow_mime;
 
 		nautilus_directory_async_state_changed (directory);
 		return;
@@ -2870,18 +2914,23 @@
 	fake_list.data = vfs_uri;
 	fake_list.prev = NULL;
 	fake_list.next = NULL;
+
+	options = GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+		| GNOME_VFS_FILE_INFO_FOLLOW_LINKS;
+	if (need_slow_mime) {
+		options |= GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE;
+	}
+	directory->details->get_info_has_slow_mime_type = need_slow_mime;
 	gnome_vfs_async_get_file_info
 		(&directory->details->get_info_in_progress,
 		 &fake_list,
-		 GNOME_VFS_FILE_INFO_GET_MIME_TYPE
-		 | GNOME_VFS_FILE_INFO_FOLLOW_LINKS,
+		 options,
 		 GNOME_VFS_PRIORITY_DEFAULT,
 		 get_info_callback,
 		 directory);
 	gnome_vfs_uri_unref (vfs_uri);
 }
 
-
 static void
 link_info_done (NautilusDirectory *directory,
 		NautilusFile *file,
@@ -3139,6 +3188,7 @@
 
 		if (file_needs_low_priority_work_done (directory, file)) {
 			/* Start getting attributes if possible */
+			file_info_start (directory, file); /* for slow mime type */
 			directory_count_start (directory, file);
 			deep_count_start (directory, file);
 			mime_list_start (directory, file);
@@ -3367,6 +3417,10 @@
 		return TRUE;
 	}
 
+	if (is_needy (file, lacks_slow_mime_type, wants_slow_mime_type)) {
+		return TRUE;
+	}
+
 	if (is_needy (file, lacks_top_left, wants_top_left)) {
 		return TRUE;
 	}
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-directory-private.h nautilus-2.4.1/libnautilus-private/nautilus-directory-private.h
--- nautilus-2.4.1.old/libnautilus-private/nautilus-directory-private.h	2003-08-29 20:03:52.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-directory-private.h	2004-01-18 10:51:59.959988400 +0800
@@ -99,6 +99,10 @@
 
 	NautilusFile *get_info_file;
 	GnomeVFSAsyncHandle *get_info_in_progress;
+	gboolean get_info_has_slow_mime_type;
+
+	NautilusFile *slow_mime_type_file;
+	GnomeVFSAsyncHandle *slow_mime_type_in_progress;
 
 	TopLeftTextReadState *top_left_read_state;
 
@@ -119,6 +123,7 @@
 	gboolean metafile;
 	gboolean mime_list;
 	gboolean top_left_text;
+ 	gboolean slow_mime_type;
 } Request;
 
 NautilusDirectory *nautilus_directory_get_existing                    (const char                *uri);
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-file-attributes.h nautilus-2.4.1/libnautilus-private/nautilus-file-attributes.h
--- nautilus-2.4.1.old/libnautilus-private/nautilus-file-attributes.h	2003-04-02 19:50:53.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-file-attributes.h	2004-01-18 10:55:58.509723328 +0800
@@ -42,6 +42,9 @@
 	NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE = 1 << 9,
 	NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT = 1 << 10,
 	NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME = 1 << 11,
+  	NAUTILUS_FILE_ATTRIBUTE_VOLUMES = 1 << 12,
+  	NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 13,
+ 	NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE = 1 << 14,
 } NautilusFileAttributes;
 
 #endif /* NAUTILUS_FILE_ATTRIBUTES_H */
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-file.c nautilus-2.4.1/libnautilus-private/nautilus-file.c
--- nautilus-2.4.1.old/libnautilus-private/nautilus-file.c	2003-09-19 19:28:07.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-file.c	2004-01-18 11:48:17.126581040 +0800
@@ -96,6 +96,7 @@
 	NautilusFileOperationCallback callback;
 	gpointer callback_data;
 	gboolean is_rename;
+	gboolean use_slow_mime;
 } Operation;
 
 typedef GList * (* ModifyListFunction) (GList *list, NautilusFile *file);
@@ -114,7 +115,8 @@
 							      gboolean          include_real_name);
 static char *   nautilus_file_get_type_as_string             (NautilusFile     *file);
 static gboolean update_info_and_name                         (NautilusFile     *file,
-							      GnomeVFSFileInfo *info);
+							      GnomeVFSFileInfo *info,
+ 							      gboolean info_has_slow_mime);
 static char *   nautilus_file_get_display_name_nocopy        (NautilusFile     *file);
 static char *   nautilus_file_get_display_name_collation_key (NautilusFile     *file);
 
@@ -268,7 +270,7 @@
 	nautilus_directory_ref (directory);
 	file->details->directory = directory;
 
-	update_info_and_name (file, info);
+	update_info_and_name (file, info, FALSE);
 	return file;
 }
 
@@ -951,7 +953,7 @@
 		old_uri = nautilus_file_get_uri (op->file);
 		old_relative_uri = g_strdup (op->file->details->relative_uri);
 
-		update_info_and_name (op->file, new_info);
+		update_info_and_name (op->file, new_info, op->use_slow_mime);
 
 		/* Self-owned files store their metadata under the
 		 * hard-code name "."  so there's no need to rename
@@ -1006,7 +1008,8 @@
 	char *uri, *old_name;
 	gboolean success;
 	gboolean is_local_desktop_file;
-
+	GnomeVFSFileInfoOptions options;
+	
 	g_return_if_fail (NAUTILUS_IS_FILE (file));
 	g_return_if_fail (new_name != NULL);
 	g_return_if_fail (callback != NULL);
@@ -1108,6 +1111,13 @@
 	/* Set up a renaming operation. */
 	op = operation_new (file, callback, callback_data);
 	op->is_rename = TRUE;
+	op->use_slow_mime = file->details->got_slow_mime_type;
+
+	options = GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+		| GNOME_VFS_FILE_INFO_FOLLOW_LINKS;
+	if (op->use_slow_mime) {
+		options |= GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE;
+	}
 
 	/* Do the renaming. */
 	partial_file_info = gnome_vfs_file_info_new ();
@@ -1116,8 +1126,7 @@
 	gnome_vfs_async_set_file_info (&op->handle,
 				       vfs_uri, partial_file_info, 
 				       GNOME_VFS_SET_FILE_INFO_NAME,
-				       (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
-					| GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
+				       options,
 				       GNOME_VFS_PRIORITY_DEFAULT,
 				       rename_callback, op);
 	gnome_vfs_file_info_unref (partial_file_info);
@@ -1280,7 +1289,8 @@
 static gboolean
 update_info_internal (NautilusFile *file,
 		      GnomeVFSFileInfo *info,
-		      gboolean update_name)
+		      gboolean update_name,
+		      gboolean info_has_slow_mime)
 {
 	GList *node;
 	GnomeVFSFileInfo *info_copy;
@@ -1296,12 +1306,13 @@
 	}
 
 	file->details->file_info_is_up_to_date = TRUE;
-
+	file->details->got_slow_mime_type = info_has_slow_mime;
 	if (file->details->info != NULL
 	    && gnome_vfs_file_info_matches (file->details->info, info)) {
 		return FALSE;
 	}
 
+
 	/* FIXME bugzilla.gnome.org 42044: Need to let links that
 	 * point to the old name know that the file has been renamed.
 	 */
@@ -1339,16 +1350,18 @@
 
 static gboolean
 update_info_and_name (NautilusFile *file,
-		      GnomeVFSFileInfo *info)
+		      GnomeVFSFileInfo *info,
+		      gboolean info_has_slow_mime)
 {
-	return update_info_internal (file, info, TRUE);
+	return update_info_internal (file, info, TRUE, info_has_slow_mime);
 }
 
 gboolean
 nautilus_file_update_info (NautilusFile *file,
-			   GnomeVFSFileInfo *info)
+			   GnomeVFSFileInfo *info,
+			   gboolean info_has_slow_mime)
 {
-	return update_info_internal (file, info, FALSE);
+	return update_info_internal (file, info, FALSE, info_has_slow_mime);
 }
 
 static gboolean
@@ -3175,7 +3188,7 @@
 	g_assert (handle == op->handle);
 
 	if (result == GNOME_VFS_OK && new_info != NULL) {
-		nautilus_file_update_info (op->file, new_info);
+		nautilus_file_update_info (op->file, new_info, op->use_slow_mime);
 	}
 	operation_complete (op, result);
 }
@@ -3199,6 +3212,7 @@
 	Operation *op;
 	GnomeVFSURI *vfs_uri;
 	GnomeVFSFileInfo *partial_file_info;
+ 	GnomeVFSFileInfoOptions options;
 
 	if (!nautilus_file_can_set_permissions (file)) {
 		/* Claim that something changed even if the permission change failed.
@@ -3221,7 +3235,13 @@
 
 	/* Set up a permission change operation. */
 	op = operation_new (file, callback, callback_data);
+ 	op->use_slow_mime = file->details->got_slow_mime_type;
 
+ 	options = GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+ 		| GNOME_VFS_FILE_INFO_FOLLOW_LINKS;
+ 	if (op->use_slow_mime) {
+ 		options |= GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE;
+ 	}
 	/* Change the file-on-disk permissions. */
 	partial_file_info = gnome_vfs_file_info_new ();
 	partial_file_info->permissions = new_permissions;
@@ -3229,8 +3249,7 @@
 	gnome_vfs_async_set_file_info (&op->handle,
 				       vfs_uri, partial_file_info, 
 				       GNOME_VFS_SET_FILE_INFO_PERMISSIONS,
-				       (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
-					| GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
+				       options,
 				       GNOME_VFS_PRIORITY_DEFAULT,
 				       set_permissions_callback, op);
 	gnome_vfs_file_info_unref (partial_file_info);
@@ -3473,7 +3492,7 @@
 	g_assert (handle == op->handle);
 
 	if (result == GNOME_VFS_OK && new_info != NULL) {
-		nautilus_file_update_info (op->file, new_info);
+		nautilus_file_update_info (op->file, new_info, op->use_slow_mime);
 	}
 	operation_complete (op, result);
 }
@@ -3488,9 +3507,17 @@
 	Operation *op;
 	GnomeVFSURI *uri;
 	GnomeVFSFileInfo *partial_file_info;
+	GnomeVFSFileInfoOptions options;
 	
 	/* Set up a owner-change operation. */
 	op = operation_new (file, callback, callback_data);
+	op->use_slow_mime = file->details->got_slow_mime_type;
+
+	options = GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+		| GNOME_VFS_FILE_INFO_FOLLOW_LINKS;
+	if (op->use_slow_mime) {
+		options |= GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE;
+	}
 
 	/* Change the file-on-disk owner. */
 	partial_file_info = gnome_vfs_file_info_new ();
@@ -3501,8 +3528,7 @@
 	gnome_vfs_async_set_file_info (&op->handle,
 				       uri, partial_file_info, 
 				       GNOME_VFS_SET_FILE_INFO_OWNER,
-				       (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
-					| GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
+				       options,
 				       GNOME_VFS_PRIORITY_DEFAULT,
 				       set_owner_and_group_callback, op);
 	gnome_vfs_file_info_unref (partial_file_info);
@@ -4469,6 +4495,13 @@
 	return ((NautilusFileClass*)G_OBJECT_GET_CLASS (file))->get_file_type (file);
 }
 
+gboolean
+nautilus_file_needs_slow_mime_type (NautilusFile *file)
+{
+	return !file->details->got_slow_mime_type &&
+		has_local_path (file);
+}
+
 /**
  * nautilus_file_get_mime_type
  * 
@@ -5132,8 +5165,6 @@
 			       gpointer callback_data)
 
 {
-	g_return_if_fail (callback != NULL);
-
 	if (file == NULL) {
 		(* callback) (file, callback_data);
 		return;
@@ -5197,6 +5228,12 @@
 }
 
 static void
+invalidate_slow_mime_type (NautilusFile *file)
+{
+	file->details->file_info_is_up_to_date = FALSE;
+}
+
+static void
 invalidate_link_info (NautilusFile *file)
 {
 	file->details->link_info_is_up_to_date = FALSE;
@@ -5234,6 +5271,9 @@
 	if (request.file_info) {
 		invalidate_file_info (file);
 	}
+	if (request.slow_mime_type) {
+		invalidate_slow_mime_type (file);
+	}
 	if (request.top_left_text) {
 		invalidate_top_left_text (file);
 	}
@@ -5302,7 +5342,8 @@
 		NAUTILUS_FILE_ATTRIBUTE_METADATA |
 		NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
 		NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT |
-		NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME;
+		NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME |
+ 		NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE;
 }
 
 void
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-file.h nautilus-2.4.1/libnautilus-private/nautilus-file.h
--- nautilus-2.4.1.old/libnautilus-private/nautilus-file.h	2003-05-17 02:32:15.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-file.h	2004-01-18 10:50:58.515329408 +0800
@@ -137,6 +137,7 @@
 char *                  nautilus_file_get_mime_type                     (NautilusFile                   *file);
 gboolean                nautilus_file_is_mime_type                      (NautilusFile                   *file,
 									 const char                     *mime_type);
+gboolean                nautilus_file_needs_slow_mime_type              (NautilusFile                   *file);
 gboolean                nautilus_file_is_symbolic_link                  (NautilusFile                   *file);
 char *                  nautilus_file_get_volume_free_space             (NautilusFile                   *file);
 char *                  nautilus_file_get_volume_name                   (NautilusFile                   *file);
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-file-private.h nautilus-2.4.1/libnautilus-private/nautilus-file-private.h
--- nautilus-2.4.1.old/libnautilus-private/nautilus-file-private.h	2003-04-23 17:49:45.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-file-private.h	2004-01-18 10:50:58.506330776 +0800
@@ -106,6 +106,8 @@
 	/* got_info known from info field being non-NULL */
 	eel_boolean_bit get_info_failed               : 1;
 	eel_boolean_bit file_info_is_up_to_date       : 1;
+	
+	eel_boolean_bit got_slow_mime_type            : 1;
 
 	eel_boolean_bit got_directory_count           : 1;
 	eel_boolean_bit directory_count_failed        : 1;
@@ -151,7 +153,8 @@
  * no change, update file and return TRUE if the file info contains
  * new state.  */
 gboolean      nautilus_file_update_info                    (NautilusFile           *file,
-							    GnomeVFSFileInfo       *info);
+							    GnomeVFSFileInfo       *info,
+							    gboolean                info_has_slow_mime);
 gboolean      nautilus_file_update_name                    (NautilusFile           *file,
 							    const char             *name);
 
diff -ur nautilus-2.4.1.old/libnautilus-private/nautilus-mime-actions.c nautilus-2.4.1/libnautilus-private/nautilus-mime-actions.c
--- nautilus-2.4.1.old/libnautilus-private/nautilus-mime-actions.c	2003-06-08 16:45:11.000000000 +0800
+++ nautilus-2.4.1/libnautilus-private/nautilus-mime-actions.c	2004-01-18 10:50:58.518328952 +0800
@@ -97,7 +97,8 @@
 {
 	return NAUTILUS_FILE_ATTRIBUTE_ACTIVATION_URI |
 		NAUTILUS_FILE_ATTRIBUTE_METADATA |
-		NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE;
+		NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
+		NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE;
 }
 
 
diff -ur nautilus-2.4.1.old/src/file-manager/fm-directory-view.c nautilus-2.4.1/src/file-manager/fm-directory-view.c
--- nautilus-2.4.1.old/src/file-manager/fm-directory-view.c	2003-09-29 17:45:30.000000000 +0800
+++ nautilus-2.4.1/src/file-manager/fm-directory-view.c	2004-01-18 11:04:05.090751768 +0800
@@ -2367,8 +2367,8 @@
 		return;
 	}
 
-	*pending_list = g_list_concat (*pending_list,
-				       nautilus_file_list_copy (files));
+	*pending_list = g_list_concat (nautilus_file_list_copy (files),
+				       *pending_list);
 
 	if (! view->details->loading || nautilus_directory_are_all_files_seen (view->details->model)) {
 		schedule_idle_display_of_pending_files (view);
@@ -4998,6 +4998,9 @@
 void
 fm_directory_view_notify_selection_changed (FMDirectoryView *view)
 {
+	NautilusFile *file;
+	GList *selection, *p;
+
 	g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
 	if (!view->details->selection_change_is_due_to_shell) {
@@ -5022,6 +5025,20 @@
 
 		/* Schedule an update of menu item states to match selection */
 		schedule_update_menus (view);
+ 
+ 		selection = fm_directory_view_get_selection (view);
+ 		for (p = selection; p != NULL; p = p->next) {
+ 			file = p->data;
+ 			
+ 			if (nautilus_file_needs_slow_mime_type (file)) {
+ 				nautilus_file_call_when_ready
+ 					(file,
+ 					 NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE,
+ 					 NULL,
+ 					 NULL);
+ 			}
+ 		}
+ 		nautilus_file_list_free (selection);
 	}
 }
 
@@ -5349,7 +5366,6 @@
 		(file, attributes, activate_activation_uri_ready_callback, parameters);
 }
 
-
 /**
  * fm_directory_view_activate_files:
  * 
@@ -5616,6 +5632,9 @@
 static void
 fm_directory_view_merge_menus (FMDirectoryView *view)
 {
+	NautilusFile *file;
+	GList *selection, *p;
+	
 	g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
 	/* Remember that the menus have been merged so that we
diff -ur nautilus-2.4.1.old/src/file-manager/fm-properties-window.c nautilus-2.4.1/src/file-manager/fm-properties-window.c
--- nautilus-2.4.1.old/src/file-manager/fm-properties-window.c	2003-09-29 17:59:35.000000000 +0800
+++ nautilus-2.4.1/src/file-manager/fm-properties-window.c	2004-01-18 10:50:58.919268000 +0800
@@ -974,8 +974,8 @@
 					      G_CALLBACK (properties_window_update),
 					      window);
 
-	nautilus_file_monitor_remove (original_file, window);
-	nautilus_file_monitor_remove (target_file, window);
+	nautilus_file_monitor_remove (original_file, &window->details->original_files);
+	nautilus_file_monitor_remove (target_file, &window->details->target_files);
 
 	nautilus_file_unref (original_file);
 	nautilus_file_unref (target_file);
@@ -3329,10 +3329,11 @@
 		file = NAUTILUS_FILE (l->data);
 
 		attributes = nautilus_icon_factory_get_required_file_attributes ();
-		attributes |= NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME;
+		attributes |= NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME
+			| NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE;
 
 		nautilus_file_monitor_add (NAUTILUS_FILE (l->data),
-					   window, 
+					   &window->details->original_files, 
 					   attributes);	
 	}
 	
@@ -3348,7 +3349,7 @@
 		}
 		
 		attributes |= NAUTILUS_FILE_ATTRIBUTE_METADATA;
-		nautilus_file_monitor_add (file, window, attributes);
+		nautilus_file_monitor_add (file, &window->details->target_files, attributes);
 	}	
 		
 	for (l = window->details->target_files; l != NULL; l = l->next) {
@@ -3649,13 +3650,13 @@
 	remove_window (window);
 
 	for (l = window->details->original_files; l != NULL; l = l->next) {
-		nautilus_file_monitor_remove (NAUTILUS_FILE (l->data), window);
+		nautilus_file_monitor_remove (NAUTILUS_FILE (l->data), &window->details->original_files);
 	}
 	nautilus_file_list_free (window->details->original_files);
 	window->details->original_files = NULL;
 	
 	for (l = window->details->target_files; l != NULL; l = l->next) {
-		nautilus_file_monitor_remove (NAUTILUS_FILE (l->data), window);
+		nautilus_file_monitor_remove (NAUTILUS_FILE (l->data), &window->details->target_files);
 	}
 	nautilus_file_list_free (window->details->target_files);
 	window->details->target_files = NULL;
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime.c gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime.c
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime.c	2003-09-27 23:42:51.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime.c	2004-01-18 13:36:22.076718768 +0800
@@ -515,17 +515,19 @@
 }
 
 const char *
-_gnome_vfs_get_mime_type_internal (GnomeVFSMimeSniffBuffer *buffer, const char *file_name)
+_gnome_vfs_get_mime_type_internal (GnomeVFSMimeSniffBuffer *buffer, const char *file_name, gboolean use_suffix)
 {
 	const char *result;
+	const char *zip_result;
 
 	result = NULL;
 	
 	if (buffer != NULL) {
 		result = _gnome_vfs_mime_get_type_from_magic_table (buffer);
-		
-		if (result != NULL) {
-			if (strcmp (result, "application/x-gzip") == 0) {
+
+		if (result != NULL && result != GNOME_VFS_MIME_TYPE_UNKNOWN) {
+			if ((strcmp (result, "application/x-gzip") == 0) ||
+			    (strcmp (result, "application/zip") == 0)) {
 		
 				/* So many file types come compressed by gzip 
 				 * that extensions are more reliable than magic
@@ -535,18 +537,14 @@
 				 * FIXME bugzilla.gnome.org 46867:
 				 * Allow specific mime types to override 
 				 * magic detection
-			 */
-			if (file_name != NULL) {
-				result = gnome_vfs_mime_type_from_name_or_default (file_name, NULL);
-			}
-			
-			if (result != NULL) {
-				return result;
+				 */
+				if (file_name != NULL) {
+					zip_result = gnome_vfs_mime_type_from_name_or_default (file_name, NULL);
+					if (zip_result != NULL && zip_result != GNOME_VFS_MIME_TYPE_UNKNOWN) {
+						return zip_result;
+					}
+				}
 			}
-				/* Didn't find an extension match,
-				 * assume gzip. */
-			return "application/x-gzip";
-		}
 			return result;
 		}
 		
@@ -572,7 +570,9 @@
 		}
 	}
 	
-	if (result == NULL && file_name != NULL) {
+	if (use_suffix &&
+	    (result == NULL || result == GNOME_VFS_MIME_TYPE_UNKNOWN) &&
+	    file_name != NULL) {
 		/* No type recognized -- fall back on extensions. */
 		result = gnome_vfs_mime_type_from_name_or_default (file_name, NULL);
 	}
@@ -625,7 +625,7 @@
 
 	base_name = gnome_vfs_uri_extract_short_path_name (uri);
 
-	result = _gnome_vfs_get_mime_type_internal (buffer, base_name);
+	result = _gnome_vfs_get_mime_type_internal (buffer, base_name, TRUE);
 	g_free (base_name);
 
 	gnome_vfs_mime_sniff_buffer_free (buffer);
@@ -661,22 +661,9 @@
 	return GNOME_VFS_OK;
 }
 
-/**
- * gnome_vfs_get_file_mime_type:
- * @path: a path of a file.
- * @optional_stat_info: optional stat buffer.
- * @suffix_only: whether or not to do a magic-based lookup.
- *
- * Tries to guess the mime type of the file represented by @path.
- * If @suffix_only is false, uses the mime-magic based lookup first.
- * Handles passing @path of a non-existent file by falling back
- * on returning a type based on the extension.
- *
- * Returns: the mime-type for this path
- */
-const char *
-gnome_vfs_get_file_mime_type (const char *path, const struct stat *optional_stat_info,
-	gboolean suffix_only)
+static const char *
+gnome_vfs_get_file_mime_type_internal (const char *path, const struct stat *optional_stat_info,
+				       gboolean suffix_only, gboolean suffix_first)
 {
 	const char *result;
 	GnomeVFSMimeSniffBuffer *buffer;
@@ -709,6 +696,14 @@
 		}
 	}
 
+	if (suffix_first && !suffix_only) {
+		result = _gnome_vfs_get_mime_type_internal (NULL, path, TRUE);
+		if (result != NULL &&
+		    result != GNOME_VFS_MIME_TYPE_UNKNOWN) {
+			return result;
+		}
+	}
+
 	if (!suffix_only) {
 		file = fopen(path, "r");
 	}
@@ -717,11 +712,11 @@
 		buffer = _gnome_vfs_mime_sniff_buffer_new_generic
 			(file_seek_binder, file_read_binder, file);
 
-		result = _gnome_vfs_get_mime_type_internal (buffer, path);
+		result = _gnome_vfs_get_mime_type_internal (buffer, path, !suffix_first);
 		gnome_vfs_mime_sniff_buffer_free (buffer);
 		fclose (file);
 	} else {
-		result = _gnome_vfs_get_mime_type_internal (NULL, path);
+		result = _gnome_vfs_get_mime_type_internal (NULL, path, !suffix_first);
 	}
 
 	
@@ -729,6 +724,47 @@
 	return result;
 }
 
+
+/**
+ * gnome_vfs_get_file_mime_type_fast:
+ * @path: a path of a file.
+ * @optional_stat_info: optional stat buffer.
+ *
+ * Tries to guess the mime type of the file represented by @path.
+ * If It uses extention/name detection first, and if that fails
+ * it falls back to mime-magic based lookup. This is faster
+ * than always doing mime-magic, but doesn't always produce
+ * the right answer, so for important decisions 
+ * you should use gnome_vfs_get_file_mime_type.
+ *
+ * Returns: the mime-type for this path
+ */
+const char *
+gnome_vfs_get_file_mime_type_fast (const char *path, const struct stat *optional_stat_info)
+{
+	return gnome_vfs_get_file_mime_type_internal (path, optional_stat_info, FALSE, TRUE);
+}
+
+/**
+ * gnome_vfs_get_file_mime_type:
+ * @path: a path of a file.
+ * @optional_stat_info: optional stat buffer.
+ * @suffix_only: whether or not to do a magic-based lookup.
+ *
+ * Tries to guess the mime type of the file represented by @path.
+ * If @suffix_only is false, uses the mime-magic based lookup first.
+ * Handles passing @path of a non-existent file by falling back
+ * on returning a type based on the extension.
+ *
+ * Returns: the mime-type for this path
+ */
+const char *
+gnome_vfs_get_file_mime_type (const char *path, const struct stat *optional_stat_info,
+	gboolean suffix_only)
+{
+	return gnome_vfs_get_file_mime_type_internal (path, optional_stat_info, suffix_only, FALSE);
+}
+
 /**
  * gnome_vfs_get_mime_type_from_uri:
  * @uri: A file uri.
@@ -777,7 +813,7 @@
 	}
 	
 	buffer = _gnome_vfs_mime_sniff_buffer_new_from_handle (handle);
-	result = _gnome_vfs_get_mime_type_internal (buffer, NULL);	
+	result = _gnome_vfs_get_mime_type_internal (buffer, NULL, FALSE);
 	gnome_vfs_mime_sniff_buffer_free (buffer);
 	gnome_vfs_close (handle);
 
@@ -802,7 +838,7 @@
 
 	buffer = gnome_vfs_mime_sniff_buffer_new_from_existing_data
 		(data, data_size);
-	result = _gnome_vfs_get_mime_type_internal (buffer, NULL);	
+	result = _gnome_vfs_get_mime_type_internal (buffer, NULL, FALSE);
 
 	gnome_vfs_mime_sniff_buffer_free (buffer);
 
@@ -1015,3 +1051,27 @@
 
 	return mime_type;
 }
+
+
+/* This is private due to the feature freeze, maybe it should be public */
+char *
+_gnome_vfs_get_slow_mime_type (const char *text_uri)
+{
+	GnomeVFSFileInfo *info;
+	char *mime_type;
+	GnomeVFSResult result;
+
+	info = gnome_vfs_file_info_new ();
+	result = gnome_vfs_get_file_info (text_uri, info,
+					  GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
+					  GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE |
+					  GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+	if (info->mime_type == NULL || result != GNOME_VFS_OK) {
+		mime_type = NULL;
+	} else {
+		mime_type = g_strdup (info->mime_type);
+	}
+	gnome_vfs_file_info_unref (info);
+
+	return mime_type;
+}
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime.h gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime.h
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime.h	2002-12-18 22:05:45.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime.h	2004-01-18 13:35:58.644281040 +0800
@@ -49,6 +49,7 @@
 const char  *gnome_vfs_get_mime_type_from_file_data		(GnomeVFSURI       *uri);
 #endif
 
+const char *gnome_vfs_get_file_mime_type_fast (const char *path, const struct stat *optional_stat_info);
 const char  *gnome_vfs_get_file_mime_type 			(const char        *path, 
 								 const struct stat *optional_stat_info,
 								 gboolean           suffix_only);
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-magic.c gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-magic.c
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-magic.c	2003-09-27 23:42:51.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-magic.c	2004-01-18 13:35:58.788259152 +0800
@@ -709,21 +709,6 @@
 	G_UNLOCK (mime_magic_table_mutex);
 }
 
-/**
- * gnome_vfs_get_mime_type_for_buffer:
- * @buffer: a sniff buffer referencing either a file or data in memory
- *
- * This routine uses a magic database to guess the mime type of the
- * data represented by @buffer.
- *
- * Returns a pointer to an internal copy of the mime-type for @buffer.
- */
-const char *
-gnome_vfs_get_mime_type_for_buffer (GnomeVFSMimeSniffBuffer *buffer)
-{
-	return _gnome_vfs_get_mime_type_internal (buffer, NULL);
-}
-
 enum {
 	GNOME_VFS_TEXT_SNIFF_LENGTH = 256
 };
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-private.h gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-private.h
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-private.h	2002-12-20 01:57:19.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-private.h	2004-01-18 13:35:58.788259152 +0800
@@ -41,6 +41,8 @@
 void             _gnome_vfs_mime_info_mark_user_mime_dir_dirty   (void);
 
 
+char * _gnome_vfs_get_slow_mime_type (const char *text_uri);
+
 G_END_DECLS
 
 #endif /* GNOME_VFS_MIME_PRIVATE_H */
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-sniff-buffer.c gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-sniff-buffer.c
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-sniff-buffer.c	2002-12-20 01:57:19.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-sniff-buffer.c	2004-01-18 13:35:58.789259000 +0800
@@ -179,3 +179,18 @@
 	/* not enough data */
 	return GNOME_VFS_ERROR_EOF;
 }
+
+/*
+ * gnome_vfs_get_mime_type_for_buffer:
+ * @buffer: a sniff buffer referencing either a file or data in memory
+ *
+ * This routine uses a magic database to guess the mime type of the
+ * data represented by @buffer.
+ *
+ * Returns a pointer to an internal copy of the mime-type for @buffer.
+ */
+const char *
+gnome_vfs_get_mime_type_for_buffer (GnomeVFSMimeSniffBuffer *buffer)
+{
+	return _gnome_vfs_get_mime_type_internal (buffer, NULL, FALSE);
+}
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h	2002-12-20 01:57:19.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h	2004-01-18 13:35:58.789259000 +0800
@@ -41,7 +41,8 @@
 };
 
 const char *_gnome_vfs_get_mime_type_internal         (GnomeVFSMimeSniffBuffer *buffer,
-						      const char              *file_name);
+						      const char               *file_name,
+						       gboolean                 use_suffix);
 const char *_gnome_vfs_mime_get_type_from_magic_table (GnomeVFSMimeSniffBuffer *buffer);
 
 #endif
diff -ur gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-utils.c gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-utils.c
--- gnome-vfs-2.4.1.old/libgnomevfs/gnome-vfs-utils.c	2003-09-27 23:42:52.000000000 +0800
+++ gnome-vfs-2.4.1/libgnomevfs/gnome-vfs-utils.c	2004-01-18 13:35:58.864247600 +0800
@@ -36,6 +36,7 @@
 #include "gnome-vfs-private-utils.h"
 #include "gnome-vfs-ops.h"
 #include "gnome-vfs-mime-handlers.h"
+#include "gnome-vfs-mime-private.h"
 #include <glib/gstrfuncs.h>
 #include <glib/gutils.h>
 #include <gconf/gconf-client.h>
@@ -2031,7 +2032,7 @@
 	
 	g_free (scheme);
 
-	type = gnome_vfs_get_mime_type (url);
+	type = _gnome_vfs_get_slow_mime_type (url);
 
 	if (type == NULL) {
 		return GNOME_VFS_ERROR_BAD_PARAMETERS;
diff -ur gnome-vfs-2.4.1.old/modules/file-method.c gnome-vfs-2.4.1/modules/file-method.c
--- gnome-vfs-2.4.1.old/modules/file-method.c	2003-09-27 23:42:52.000000000 +0800
+++ gnome-vfs-2.4.1/modules/file-method.c	2004-01-18 13:35:58.942235744 +0800
@@ -559,8 +559,16 @@
 		 */
 		mime_type = "x-special/symlink";
 	} else {
-		mime_type = gnome_vfs_get_file_mime_type (full_name,
-			stat_buffer, (options & GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE) != 0);
+		if (options & GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE) {
+			mime_type = gnome_vfs_get_file_mime_type (full_name,
+								  stat_buffer, TRUE);
+		} else if (options & GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE) {
+			mime_type = gnome_vfs_get_file_mime_type (full_name,
+								  stat_buffer, FALSE);
+		} else {
+			mime_type = gnome_vfs_get_file_mime_type_fast (full_name,
+								       stat_buffer);
+		}
 	}
 
 	g_assert (mime_type);


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