diff -uNr ../nautilus-2.20.0-orig/libnautilus-private/nautilus-icon-container.h ./libnautilus-private/nautilus-icon-container.h
--- ../nautilus-2.20.0-orig/libnautilus-private/nautilus-icon-container.h	2007-04-03 18:08:46.000000000 +0800
+++ ./libnautilus-private/nautilus-icon-container.h	2008-05-13 21:01:55.000000000 +0800
@@ -138,6 +138,9 @@
 						   NautilusIconData *data,
 						   char **editable_text,
 						   char **additional_text);
+	void         (* get_icon_tooltip)         (NautilusIconContainer *container,
+						   NautilusIconData *data,
+						   char **additional_text);
 	char *       (* get_icon_description)     (NautilusIconContainer *container,
 						   NautilusIconData *data);
 	int          (* compare_icons)            (NautilusIconContainer *container,
diff -uNr ../nautilus-2.20.0-orig/libnautilus-private/nautilus-link-desktop-file.c ./libnautilus-private/nautilus-link-desktop-file.c
--- ../nautilus-2.20.0-orig/libnautilus-private/nautilus-link-desktop-file.c	2007-04-03 18:08:46.000000000 +0800
+++ ./libnautilus-private/nautilus-link-desktop-file.c	2008-05-13 21:01:55.000000000 +0800
@@ -210,8 +210,6 @@
 	 * It just contains a copy of the name. This is probably because the
 	 * panel shows the comment field as a tooltip.
 	 */
-	return NULL;
-#ifdef THIS_IS_NOT_USED_RIGHT_NOW
 	char *type;
 	char *retval;
 
@@ -228,7 +226,6 @@
 	g_free (type);
 
 	return retval;
-#endif
 }
 
 
diff -uNr ../nautilus-2.20.0-orig/libnautilus-private/nautilus-metadata.h ./libnautilus-private/nautilus-metadata.h
--- ../nautilus-2.20.0-orig/libnautilus-private/nautilus-metadata.h	2007-09-10 14:56:45.000000000 +0800
+++ ./libnautilus-private/nautilus-metadata.h	2008-05-13 21:01:55.000000000 +0800
@@ -74,5 +74,6 @@
 /* per link file */
 
 #define NAUTILUS_METADATA_KEY_EXTRA_TEXT		 	"extra_text"
+#define NAUTILUS_METADATA_DISK_SPACE_USED		"disk_space_used"
 
 #endif /* NAUTILUS_METADATA_H */
diff -uNr ../nautilus-2.20.0-orig/po/zh_CN.po ./po/zh_CN.po
--- ../nautilus-2.20.0-orig/po/zh_CN.po	2007-09-10 14:56:45.000000000 +0800
+++ ./po/zh_CN.po	2008-05-13 21:05:58.000000000 +0800
@@ -4112,6 +4112,61 @@
 msgid "Show Tree"
 msgstr "显示树"
 
+#: ../src/file-manager/fm-tooltip.c:107
+msgid "Display drives and hardwares connected to this computer"
+msgstr "显示连接到此计算机的驱动器和硬件"
+
+#: ../src/file-manager/fm-tooltip.c:110
+msgid "Contain current user's files"
+msgstr "包含当前用户的文档"
+
+#: ../src/file-manager/fm-tooltip.c:116 ../src/file-manager/fm-tooltip.c:159
+#, c-format
+msgid ""
+"free space: %s \n"
+"total space: %s"
+msgstr ""
+"可用空间： %s \n"
+"总大小： %s"
+
+#: ../src/file-manager/fm-tooltip.c:122
+msgid "Contain files you have already deleted"
+msgstr "包含您已经删除的文件和文件夹"
+
+#: ../src/file-manager/fm-tooltip.c:125
+msgid "Display websites, network computers and ftp sites"
+msgstr "显示到网站，网络计算机和FTP站点的快捷方式"
+
+#: ../src/file-manager/fm-tooltip.c:165
+msgid "Sorry, something need to be done with directory"
+msgstr "对不起，该项目的Tooltip还未制作"
+
+#: ../src/file-manager/fm-tooltip.c:177
+msgid "Link to root filesystem"
+msgstr "到文件系统的快捷方式"
+
+#: ../src/file-manager/fm-tooltip.c:180
+msgid "Link to network"
+msgstr "显示到网站，网络计算机和FTP站点的快捷方式"
+
+#: ../src/file-manager/fm-tooltip.c:184
+msgid "Sorry, some thing need to be done with service"
+msgstr "对不起，该项目的Tooltip还未制作"
+
+#: ../src/file-manager/fm-tooltip.c:253
+#, c-format
+msgid "More than %s"
+msgstr "大小：大于%s"
+
+#: ../src/file-manager/fm-tooltip.c:256
+msgid "Please wait..."
+msgstr "请稍候"
+
+#: ../src/file-manager/fm-tooltip.c:351
+#, c-format
+msgid "Size: %s"
+msgstr "大小：%s"
+
 #: ../src/nautilus-application.c:282
 #, c-format
 msgid "Nautilus could not create the required folder \"%s\"."
diff -uNr ../nautilus-2.20.0-orig/src/file-manager/fm-icon-container.c ./src/file-manager/fm-icon-container.c
--- ../nautilus-2.20.0-orig/src/file-manager/fm-icon-container.c	2007-04-03 18:08:04.000000000 +0800
+++ ./src/file-manager/fm-icon-container.c	2008-05-13 21:01:55.000000000 +0800
@@ -36,6 +36,7 @@
 #include <libnautilus-private/nautilus-desktop-icon-file.h>
 
 #include "fm-icon-container.h"
+#include "fm-tooltip.h"
 
 #define ICON_TEXT_ATTRIBUTES_NUM_ITEMS		3
 #define ICON_TEXT_ATTRIBUTES_DEFAULT_TOKENS	"size,date_modified,type"
@@ -287,14 +288,6 @@
 	if (nautilus_file_is_nautilus_link (file)) {
 		/* FIXME bugzilla.gnome.org 42531: Does sync. I/O and works only locally. */
  		*additional_text = NULL;
-		if (nautilus_file_is_local (file)) {
-			actual_uri = nautilus_file_get_uri (file);
-			description = nautilus_link_local_get_additional_text (actual_uri);
-			if (description)
-				*additional_text = g_strdup_printf (" \n%s\n ", description);
-			g_free (description);
-			g_free (actual_uri);
-		}
 		/* Don't show the normal extra information for desktop files, it doesn't
 		 * make sense. */
 		return;
@@ -322,6 +315,25 @@
 	}
 }
 
+static void 
+fm_icon_container_get_icon_tooltip (NautilusIconContainer *container,
+				 NautilusIconData      *data,
+				 char                 **tooltip)
+{
+	FMIconView *icon_view;
+	NautilusFile *file;
+
+	file = NAUTILUS_FILE (data);
+
+	g_assert (NAUTILUS_IS_FILE (file));
+	g_assert (tooltip != NULL);
+	icon_view = get_icon_view (container);
+	g_return_if_fail (icon_view != NULL);
+
+	format_tooltip_for_file(file, tooltip);
+
+}
+
 /* Sort as follows:
  *   0) computer link
  *   1) home link
@@ -481,6 +493,7 @@
 	ic_class = &klass->parent_class;
 
 	ic_class->get_icon_text = fm_icon_container_get_icon_text;
+	ic_class->get_icon_tooltip = fm_icon_container_get_icon_tooltip;
 	ic_class->get_icon_images = fm_icon_container_get_icon_images;
 	ic_class->get_icon_description = fm_icon_container_get_icon_description;
 	ic_class->start_monitor_top_left = fm_icon_container_start_monitor_top_left;
diff -uNr ../nautilus-2.20.0-orig/src/file-manager/fm-icon-view.c ./src/file-manager/fm-icon-view.c
--- ../nautilus-2.20.0-orig/src/file-manager/fm-icon-view.c	2007-04-03 18:08:04.000000000 +0800
+++ ./src/file-manager/fm-icon-view.c	2008-05-13 21:01:55.000000000 +0800
@@ -24,6 +24,7 @@
 
 #include <config.h>
 #include "fm-icon-view.h"
+#include "fm-tooltip.h"
 
 #include "fm-actions.h"
 #include "fm-icon-container.h"
@@ -67,6 +68,8 @@
 #include <libnautilus-private/nautilus-icon-container.h>
 #include <libnautilus-private/nautilus-icon-dnd.h>
 #include <libnautilus-private/nautilus-icon-factory.h>
+#include <libnautilus-private/nautilus-icon-canvas-item.h>
+#include <libnautilus-private/nautilus-icon-private.h>
 #include <libnautilus-private/nautilus-link.h>
 #include <libnautilus-private/nautilus-metadata.h>
 #include <libnautilus-private/nautilus-view-factory.h>
@@ -2691,6 +2694,43 @@
 	iface->get_title = NULL;
 }
 
+static gboolean
+icon_view_query_tooltip_cb(GtkWidget *icon_view,
+                        gint    x,
+                        gint    y,
+                        gboolean        keyboard_tip,
+                        GtkTooltip      *tooltip,
+                        FMIconView      *fm_icon_view)
+{
+	NautilusIconCanvasItem *icon_item;
+	NautilusIconContainer *container;
+	NautilusIcon	*icon;
+	EelCanvas    *canvas;
+	EelCanvasItem *item;
+        gchar *additional;
+ 
+	/*FIXME I don't know which one could be NULL, so check them all*/
+	if(!(container = get_icon_container(fm_icon_view)) ||
+		!(canvas = &(container->canvas)) ||
+		!(item = canvas->current_item) ||
+		!(icon_item = NAUTILUS_ICON_CANVAS_ITEM (item)) ||
+		!(icon = icon_item->user_data))
+		return FALSE;	
+
+	EEL_CALL_METHOD (NAUTILUS_ICON_CONTAINER_CLASS,
+			container, get_icon_tooltip, 
+			(container, icon->data, &additional));
+
+	if(additional != NULL){
+		gtk_tooltip_set_text(tooltip, additional);
+		g_free(additional);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+
+}
+
 static void
 fm_icon_view_init (FMIconView *icon_view)
 {
@@ -2704,6 +2744,10 @@
 
 	create_icon_container (icon_view);
 
+	g_object_set(icon_view, "has-tooltip", TRUE, NULL);
+	g_signal_connect(icon_view, "query-tooltip",
+		G_CALLBACK(icon_view_query_tooltip_cb), icon_view);
+
 	if (!setup_sound_preview) {
 		eel_preferences_add_auto_enum (NAUTILUS_PREFERENCES_PREVIEW_SOUND,
 					       &preview_sound_auto_value);
diff -uNr ../nautilus-2.20.0-orig/src/file-manager/fm-list-view.c ./src/file-manager/fm-list-view.c
--- ../nautilus-2.20.0-orig/src/file-manager/fm-list-view.c	2007-08-21 17:37:48.000000000 +0800
+++ ./src/file-manager/fm-list-view.c	2008-05-13 21:01:55.000000000 +0800
@@ -27,6 +27,7 @@
 
 #include <config.h>
 #include "fm-list-view.h"
+#include "fm-tooltip.h"
 
 #include <string.h>
 #include "fm-error-reporting.h"
@@ -1247,6 +1248,43 @@
 	g_free (text);
 }
 
+static gboolean
+tree_view_query_tooltip_cb(GtkWidget *tree_view,
+                        gint    x,
+                        gint    y,
+                        gboolean        keyboard_tip,
+                        GtkTooltip      *tooltip,
+                        FMListView      *fm_list_view)
+{
+        GtkTreePath *tree_path;
+        GtkTreeViewColumn *tree_column;
+        gint c_x, c_y;
+        gint b_x, b_y;
+        NautilusFile *file;
+        char    *file_name;
+        char    *tooltip_format;
+ 
+        gtk_tree_view_convert_widget_to_bin_window_coords(
+					GTK_TREE_VIEW(tree_view),
+					x, y, &b_x, &b_y);
+        gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree_view),
+					b_x, b_y, &tree_path,
+					&tree_column, &c_x, &c_y);
+	if(!tree_path)
+		return FALSE;
+
+        file = fm_list_model_file_for_path(fm_list_view->details->model,
+					tree_path);
+	format_tooltip_for_file(file, &tooltip_format);
+	if(!tooltip_format)
+		return FALSE;
+
+	gtk_tooltip_set_text(tooltip, tooltip_format);
+	gtk_tree_view_set_tooltip_cell(GTK_TREE_VIEW(tree_view), 
+					tooltip, tree_path, NULL, NULL);
+        return TRUE;
+}
+
 static void
 create_and_set_up_tree_view (FMListView *view)
 {
@@ -1256,6 +1294,7 @@
 	AtkObject *atk_obj;
 	GList *nautilus_columns;
 	GList *l;
+	GtkWidget *tree_view;
 	
 	view->details->tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
 	view->details->columns = g_hash_table_new_full (g_str_hash, 
@@ -1264,6 +1303,11 @@
 							(GDestroyNotify) g_object_unref);
 	gtk_tree_view_set_enable_search (view->details->tree_view, TRUE);
 
+	tree_view = GTK_WIDGET(view->details->tree_view);
+	g_object_set(tree_view, "has-tooltip", TRUE, NULL);
+	g_signal_connect(tree_view, "query-tooltip",
+			G_CALLBACK(tree_view_query_tooltip_cb), view);
+
 	/* Don't handle backspace key. It's used to open the parent folder. */
 	binding_set = gtk_binding_set_by_class (GTK_WIDGET_GET_CLASS (view->details->tree_view));
 	gtk_binding_entry_clear (binding_set, GDK_BackSpace, 0);
diff -uNr ../nautilus-2.20.0-orig/src/file-manager/fm-tooltip.c ./src/file-manager/fm-tooltip.c
--- ../nautilus-2.20.0-orig/src/file-manager/fm-tooltip.c	1970-01-01 08:00:00.000000000 +0800
+++ ./src/file-manager/fm-tooltip.c	2008-05-13 21:01:55.000000000 +0800
@@ -0,0 +1,379 @@
+/*
+ * fm-tooltip.c
+ * Copyright (C) Gao Long 2008 <imgaolong@gmail.com>
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
+ */
+ 
+#include "fm-tooltip.h"
+
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#elif HAVE_SYS_MOUNT_H
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/mount.h>
+#endif
+
+#define MAX_ADDITIONAL_TEXT 6
+#define TIME_INTERVAL	500 
+
+static guint update_directory_contents_timeout_id;
+
+/* 
+ * modified from fm-properties-window.c
+ */
+static gboolean
+get_free_space (NautilusFile *file, GnomeVFSFileSize *capacity, GnomeVFSFileSize *free)
+{
+	int statfs_result;
+#if HAVE_STATVFS
+	struct statvfs statfs_buffer;
+#else
+	struct statfs statfs_buffer;
+#endif
+	GnomeVFSFileSize block_size;
+	GnomeVFSURI *vfs_uri;
+	gchar *path;
+	gchar *uri;
+	
+	uri 	= nautilus_file_get_activation_uri (file);
+	vfs_uri = gnome_vfs_uri_new (uri);
+	path 	= g_filename_from_uri (uri,NULL,NULL);
+
+
+	if (path == NULL) {
+		return FALSE;
+	}
+
+	statfs_result = -1;
+	
+#if HAVE_STATVFS
+	statfs_result = statvfs (path, &statfs_buffer);
+	block_size = statfs_buffer.f_frsize; 
+#else
+#if STATFS_ARGS == 2
+	statfs_result = statfs (path, &statfs_buffer);
+#elif STATFS_ARGS == 4
+	statfs_result = statfs (path, &statfs_buffer,
+				sizeof (statfs_buffer), 0);
+#endif
+	block_size = statfs_buffer.f_bsize; 
+#endif  
+
+	if (statfs_result != 0) {
+		return FALSE;
+	}
+	
+	*capacity = statfs_buffer.f_blocks * block_size;
+
+	*free 	 = statfs_buffer.f_bavail * block_size; 
+	
+	return TRUE;
+}
+
+static void
+handle_desktop_icon_file(NautilusFile			*file,
+				 		char	**tooltip)
+{
+	NautilusDesktopLink *link;
+	gchar *uri;
+	GnomeVFSFileSize total, free;
+	gchar *total_str, *free_str;
+
+	*tooltip = NULL;
+	uri = nautilus_file_get_activation_uri (file);
+	link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file));
+
+	if (link != NULL) {
+		switch (nautilus_desktop_link_get_link_type (link)) {
+		case NAUTILUS_DESKTOP_LINK_COMPUTER:
+			*tooltip = g_strdup(_("Display drives and hardwares connected to this computer"));
+			break;
+		case NAUTILUS_DESKTOP_LINK_HOME:
+			*tooltip = g_strdup(_("Contain current user's files"));
+			break;
+		case NAUTILUS_DESKTOP_LINK_VOLUME:
+			if(get_free_space(file, &total, &free)){
+				total_str = gnome_vfs_format_file_size_for_display (total);
+				free_str = gnome_vfs_format_file_size_for_display (free);
+				*tooltip = g_strdup_printf(_("free space: %s \ntotal space: %s"), free_str, total_str);
+				g_free(total_str);
+				g_free(free_str);
+			}
+			break;
+		case NAUTILUS_DESKTOP_LINK_TRASH:
+			*tooltip = g_strdup(_("Contain files you have already deleted"));
+			break;
+		case NAUTILUS_DESKTOP_LINK_NETWORK:
+			*tooltip = g_strdup(_("Display websites, network computers and ftp sites"));
+			break;
+		default:
+			break;
+		}
+		g_free(uri);
+		g_object_unref (link);
+	}
+}
+
+static void
+handle_link(NautilusFile	*file,
+		char		**tooltip)
+{
+	char *uri, *act_uri;
+	gchar *description;
+	GnomeDesktopItem *desktop;
+	GnomeDesktopItemType link_type;
+	GnomeVFSFileSize total, free;
+	gchar *total_str, *free_str;
+	
+	*tooltip = NULL;
+	uri = nautilus_file_get_uri (file);
+	act_uri = nautilus_file_get_activation_uri (file);
+	desktop	= gnome_desktop_item_new_from_uri(uri,
+		GNOME_DESKTOP_ITEM_LOAD_ONLY_IF_EXISTS, NULL);
+
+	if (desktop != NULL) {
+		link_type = gnome_desktop_item_get_entry_type(desktop);
+		switch (link_type) {
+		case GNOME_DESKTOP_ITEM_TYPE_FSDEVICE:
+			if(get_free_space(file, &total, &free)){
+				total_str = gnome_vfs_format_file_size_for_display (total);
+				free_str = gnome_vfs_format_file_size_for_display (free);
+				*tooltip = g_strdup_printf(_("free space: %s \ntotal space: %s"), free_str, total_str);
+				g_free(total_str);
+				g_free(free_str);
+			}
+			break;
+		case GNOME_DESKTOP_ITEM_TYPE_DIRECTORY:
+			gnome_ok_dialog(_("Sorry, something need to be done with directory"));
+			break;
+		case GNOME_DESKTOP_ITEM_TYPE_APPLICATION:
+			if (nautilus_file_is_local (file)) {
+				description = nautilus_link_local_get_additional_text (uri);
+				if (description)
+					*tooltip = g_strdup_printf (" \n%s\n ", description);
+				g_free (description);
+			}
+			break;
+		case GNOME_DESKTOP_ITEM_TYPE_LINK:
+			if(!strcmp(act_uri, "file:///")){
+				*tooltip = g_strdup(_("Link to root filesystem"));
+			}
+			if(!strcmp(act_uri, "network://")){
+				*tooltip = g_strdup(_("Link to network"));
+			}
+			break;
+		case GNOME_DESKTOP_ITEM_TYPE_SERVICE:
+			gnome_ok_dialog(_("Sorry, some thing need to be done with service"));
+			break;				
+		default:
+			break;
+		}
+	}				
+	g_free (uri);
+	g_free (act_uri);
+}
+
+/*
+ * Get the preference for which caption text should appear
+ * beneath icons.
+ * modified from fm-icon-container.c
+ */
+static const EelStringList *
+get_icon_text_attributes_from_preferences (void)
+{
+	static const EelStringList *attributes;
+
+	if (attributes == NULL) {
+		eel_preferences_add_auto_string_list (NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
+						      &attributes);
+	}
+
+	return attributes;
+}
+
+/* 
+ * modified from fm-properties-window.c 
+ */
+static void
+directory_contents_value_field_update (NautilusFile *file, char **tooltip)
+{
+	NautilusRequestStatus status, file_status;
+	gchar *size_str, *disk_space_used;
+	GnomeVFSFileSize file_size;
+
+	status = NAUTILUS_REQUEST_DONE;
+	file_status = NAUTILUS_REQUEST_NOT_STARTED;
+
+	file_status = nautilus_file_get_deep_counts (file, 
+			NULL, NULL, NULL, &file_size, TRUE);
+	size_str = gnome_vfs_format_file_size_for_display (file_size);
+	if(file_status != NAUTILUS_REQUEST_DONE){
+		status = file_status;
+	}
+	
+	if (status == NAUTILUS_REQUEST_DONE) {
+		if(tooltip != NULL)
+			*tooltip = g_strdup(size_str);
+
+		disk_space_used = nautilus_file_get_metadata (file,
+                                      NAUTILUS_METADATA_DISK_SPACE_USED,
+                                      NULL);
+
+		if(disk_space_used == NULL){
+			nautilus_file_set_metadata (file,
+				NAUTILUS_METADATA_DISK_SPACE_USED,
+				NULL, size_str);
+		} else if(strcmp(disk_space_used, size_str) != 0){
+			nautilus_file_set_metadata (file,
+				NAUTILUS_METADATA_DISK_SPACE_USED,
+				NULL, size_str);
+		}
+		g_free(disk_space_used);
+		
+	} else if(status == NAUTILUS_REQUEST_IN_PROGRESS) {
+		if(tooltip != NULL)
+			*tooltip = g_strdup_printf(_("More than %s"), size_str);
+	} else {
+		if(tooltip != NULL)
+			*tooltip = g_strdup(_("Please wait...")); 
+	}
+	g_free(size_str);
+
+}
+
+static gboolean
+update_directory_contents_callback (NautilusFile *file)
+{
+
+	update_directory_contents_timeout_id = 0;
+	directory_contents_value_field_update (file, NULL);
+
+	return FALSE;
+}
+
+static void 
+schedule_directory_contents_update (NautilusFile *file)
+{
+
+	if (update_directory_contents_timeout_id == 0) {
+		update_directory_contents_timeout_id
+			= g_timeout_add (TIME_INTERVAL,
+				update_directory_contents_callback, file);
+	}
+}
+
+static void
+request_recompute(NautilusFile	*file,
+		char		**tooltip)
+{
+	NautilusFileAttributes attributes;
+
+	attributes = 0;
+	attributes |= NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS;		
+	attributes |= NAUTILUS_FILE_ATTRIBUTE_METADATA;
+
+	nautilus_file_monitor_add (file, &file, attributes);
+
+	directory_contents_value_field_update(file, tooltip);
+
+	nautilus_file_recompute_deep_counts(file);
+
+	g_signal_connect_object (file,
+			 "updated_deep_count_in_progress",
+			 G_CALLBACK (schedule_directory_contents_update),
+			 file, G_CONNECT_SWAPPED);
+}
+
+static gboolean
+directory_changed(NautilusFile	*file)
+{
+	static gchar *last_uri=NULL;
+	gchar *current_uri=NULL;
+	gboolean ret;
+
+	current_uri = nautilus_file_get_activation_uri(file);
+	
+	if(last_uri != NULL && current_uri != NULL && 
+		strcmp(current_uri, last_uri) == 0){
+		ret = FALSE;
+	} else {
+		ret = TRUE;
+	}
+
+	g_free(last_uri);
+
+	/* there might be a constant memory usage */
+	/* as small as size_of(char)*/
+	last_uri = g_strdup(current_uri);
+	g_free(current_uri);
+
+	return ret;
+
+}
+
+static void
+handle_others(NautilusFile	*file,
+		char		**tooltip)
+{
+	const EelStringList *attribute_names;
+	const char *attribute;
+	char *text_array[MAX_ADDITIONAL_TEXT];
+	int i, j, num_attributes;
+	gchar *disk_space_used;
+
+	/* Find out what attributes go below each icon. */
+	attribute_names = get_icon_text_attributes_from_preferences ();
+	num_attributes = eel_string_list_get_length (attribute_names);
+	/* Get the attributes. */
+	/* modified from fm-icon-container.c */
+	for (i = 0, j = 0; i < num_attributes; i++)	{
+		attribute = eel_string_list_peek_nth (attribute_names, i);
+		if (eel_strcmp (attribute, "none") == 0) {
+			continue;
+		}
+		text_array[j++] =
+			nautilus_file_get_string_attribute_with_default (file, attribute);
+	}
+	text_array[j] = NULL;
+
+	/* Return them. */
+	*tooltip = g_strjoinv ("\n", text_array);
+
+	for (i = 0; i < j; i++) {
+		g_free(text_array[i]);
+	}
+}
+
+void
+format_tooltip_for_file(NautilusFile	*file,
+			char		**tooltip)
+{
+	
+	*tooltip = NULL;
+	if (NAUTILUS_IS_DESKTOP_ICON_FILE (file)) {
+		handle_desktop_icon_file(file, tooltip);
+	}else	if (nautilus_file_is_nautilus_link (file)) {
+		handle_link(file, tooltip);
+	}else {
+		handle_others(file, tooltip);
+	}
+
+}
diff -uNr ../nautilus-2.20.0-orig/src/file-manager/fm-tooltip.h ./src/file-manager/fm-tooltip.h
--- ../nautilus-2.20.0-orig/src/file-manager/fm-tooltip.h	1970-01-01 08:00:00.000000000 +0800
+++ ./src/file-manager/fm-tooltip.h	2008-05-13 21:01:55.000000000 +0800
@@ -0,0 +1,94 @@
+/*
+ * fm-tooltip.h
+ * Copyright (C) Gao Long 2008 <imgaolong@gmail.com>
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
+ */
+ 
+#ifndef _EXTRA_H
+#define EXTRA_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "fm-list-view.h"
+#include "fm-error-reporting.h"
+#include "fm-list-model.h"
+
+/* included for future usage */
+#include <config.h>
+#include <string.h>
+#include <string.h>
+#include <eel/eel-vfs-extensions.h>
+#include <eel/eel-glib-extensions.h>
+#include <eel/eel-gtk-macros.h>
+#include <gdk/gdkcursor.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkbindings.h>
+#include <gtk/gtkcellrendererpixbuf.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtktreeselection.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkradiomenuitem.h>
+#include <gtk/gtkradioaction.h>
+#include <libgnomevfs/gnome-vfs-mime-handlers.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <eel/eel-string.h>
+#include <libnautilus-private/nautilus-file-attributes.h>
+#include <libnautilus-private/nautilus-thumbnails.h>
+#include <libnautilus-private/nautilus-desktop-icon-file.h>
+
+#include <libegg/eggtreemultidnd.h>
+#include <glib/gi18n.h>
+#include <libgnome/gnome-macros.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libnautilus-extension/nautilus-column-provider.h>
+#include <libnautilus-private/nautilus-column-chooser.h>
+#include <libnautilus-private/nautilus-column-utilities.h>
+#include <libnautilus-private/nautilus-debug-log.h>
+#include <libnautilus-private/nautilus-directory-background.h>
+#include <libnautilus-private/nautilus-directory.h>
+#include <libnautilus-private/nautilus-dnd.h>
+#include <libnautilus-private/nautilus-file-dnd.h>
+#include <libnautilus-private/nautilus-file.h>
+#include <libnautilus-private/nautilus-file-utilities.h>
+#include <libnautilus-private/nautilus-ui-utilities.h>
+#include <libnautilus-private/nautilus-global-preferences.h>
+#include <libnautilus-private/nautilus-icon-dnd.h>
+#include <libnautilus-private/nautilus-icon-factory.h>
+#include <libnautilus-private/nautilus-metadata.h>
+#include <libnautilus-private/nautilus-module.h>
+#include <libnautilus-private/nautilus-tree-view-drag-dest.h>
+#include <libnautilus-private/nautilus-view-factory.h>
+#include <libnautilus-private/nautilus-clipboard.h>
+#include <libnautilus-private/nautilus-cell-renderer-pixbuf-emblem.h>
+#include <libnautilus-private/nautilus-cell-renderer-text-ellipsized.h>
+
+void
+format_tooltip_for_file(NautilusFile	*file,
+			char		**tooltip);
+
+G_END_DECLS
+
+#endif /* EXTRA_H */
+
+ 
diff -uNr ../nautilus-2.20.0-orig/src/file-manager/Makefile.am ./src/file-manager/Makefile.am
--- ../nautilus-2.20.0-orig/src/file-manager/Makefile.am	2007-06-27 15:12:32.000000000 +0800
+++ ./src/file-manager/Makefile.am	2008-05-13 21:01:55.000000000 +0800
@@ -38,6 +38,8 @@
 	fm-tree-model.h			\
 	fm-tree-view.c			\
 	fm-tree-view.h			\
+	fm-tooltip.c			\
+	fm-tooltip.h			\
 	$(NULL)
 
 EMPTY_VIEW_SOURCES = \
