nautilus r13616 - in trunk: . data libnautilus-private src src/file-manager



Author: alexl
Date: Thu Jan 17 13:45:27 2008
New Revision: 13616
URL: http://svn.gnome.org/viewvc/nautilus?rev=13616&view=rev

Log:
2008-01-17  Alexander Larsson  <alexl redhat com>

        * libnautilus-private/nautilus-file.[ch]:
        * libnautilus-private/nautilus-file-attributes.h:
        * libnautilus-private/nautilus-file-private.h:
	Add GMount attribute to NautilusFile.
	(not implemented yet)
	
        * Makefile.am:
        * configure.in:
        * data/nautilus.xml.in:
        * libnautilus-private/apps_nautilus_preferences.schemas.in:
        * libnautilus-private/nautilus-autorun.[ch]:
        * libnautilus-private/nautilus-global-preferences.c:
        * libnautilus-private/nautilus-global-preferences.h:
        * libnautilus-private/nautilus-program-choosing.c:
        * src/Makefile.am:
        * src/file-manager/fm-directory-view.c:
        * src/nautilus-application.c:
        * src/nautilus-autorun-software.c: Added.
        * src/nautilus-file-management-properties.c:
        * src/nautilus-file-management-properties.glade:
        * src/nautilus-window-manage-views.c:
        * src/nautilus-x-content-bar.[ch]: Added.
	More work on autorun and x-content types from David Zeuthen



Added:
   trunk/nautilus-autorun-software.desktop.in.in
   trunk/src/nautilus-autorun-software.c
   trunk/src/nautilus-x-content-bar.c
   trunk/src/nautilus-x-content-bar.h
Modified:
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/configure.in
   trunk/data/nautilus.xml.in
   trunk/libnautilus-private/apps_nautilus_preferences.schemas.in
   trunk/libnautilus-private/nautilus-autorun.c
   trunk/libnautilus-private/nautilus-autorun.h
   trunk/libnautilus-private/nautilus-file-attributes.h
   trunk/libnautilus-private/nautilus-file-private.h
   trunk/libnautilus-private/nautilus-file.c
   trunk/libnautilus-private/nautilus-file.h
   trunk/libnautilus-private/nautilus-global-preferences.c
   trunk/libnautilus-private/nautilus-global-preferences.h
   trunk/libnautilus-private/nautilus-program-choosing.c
   trunk/src/Makefile.am
   trunk/src/file-manager/fm-directory-view.c
   trunk/src/nautilus-application.c
   trunk/src/nautilus-file-management-properties.c
   trunk/src/nautilus-file-management-properties.glade
   trunk/src/nautilus-window-manage-views.c

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Thu Jan 17 13:45:27 2008
@@ -9,7 +9,8 @@
 	nautilus-home.desktop.in			\
 	nautilus-computer.desktop.in			\
 	nautilus-folder-handler.desktop.in		\
-	nautilus-file-management-properties.desktop.in
+	nautilus-file-management-properties.desktop.in  \
+	nautilus-autorun-software.desktop.in
 
 SUBDIRS =			\
 	libnautilus-extension	\

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Thu Jan 17 13:45:27 2008
@@ -484,6 +484,7 @@
 nautilus-home.desktop.in
 nautilus.desktop.in
 nautilus-folder-handler.desktop.in
+nautilus-autorun-software.desktop.in
 po/Makefile.in
 src/Makefile
 src/file-manager/Makefile

Modified: trunk/data/nautilus.xml.in
==============================================================================
--- trunk/data/nautilus.xml.in	(original)
+++ trunk/data/nautilus.xml.in	Thu Jan 17 13:45:27 2008
@@ -13,11 +13,11 @@
 
    <mime-type type="x-content/video-vcd">
      <!-- http://en.wikipedia.org/wiki/Video_CD -->
-     <_comment>VCD Video</_comment>
+     <_comment>Video CD</_comment>
    </mime-type>
    <mime-type type="x-content/video-svcd">
      <!-- http://en.wikipedia.org/wiki/Super_Video_CD -->
-     <_comment>SVCD Video</_comment>
+     <_comment>Super Video CD</_comment>
    </mime-type>
    <mime-type type="x-content/video-dvd">
      <!-- http://en.wikipedia.org/wiki/DVD-Video -->
@@ -34,26 +34,57 @@
      <_comment>Compact Disc Audio</_comment>
    </mime-type>
 
-   <mime-type type="x-content/blank-media">
+   <mime-type type="x-content/blank-cd">
      <!-- http://en.wikipedia.org/wiki/Compact_Disc -->
+     <_comment>Blank CD Disc</_comment>
+   </mime-type>
+
+   <mime-type type="x-content/blank-dvd">
      <!-- http://en.wikipedia.org/wiki/DVD -->
-     <_comment>Blank Media</_comment>
+     <_comment>Blank DVD Disc</_comment>
    </mime-type>
 
-   <mime-type type="x-content/software-autostart">
-     <!-- http://www.freedesktop.org/wiki/Specifications/autostart-spec -->
-     <_comment>Software</_comment>
+   <mime-type type="x-content/blank-bd">
+     <!-- http://en.wikipedia.org/wiki/Blu-ray_Disc -->
+     <_comment>Blank Blu-Ray Disc</_comment>
    </mime-type>
 
-   <!-- TODO:
+   <mime-type type="x-content/blank-hddvd">
+     <!-- http://en.wikipedia.org/wiki/HD_DVD -->
+     <_comment>Blank HD DVD Disc</_comment>
+   </mime-type>
+
+   <mime-type type="x-content/audio-dvd">
+     <!-- http://en.wikipedia.org/wiki/DVD-Audio -->
+     <_comment>DVD Audio</_comment>
+   </mime-type>
+
+   <mime-type type="x-content/video-bluray">
+     <!-- http://en.wikipedia.org/wiki/Blu-ray_Disc -->
+     <_comment>Blu-Ray Video</_comment>
+   </mime-type>
 
-         - Blu-Ray video  : http://en.wikipedia.org/wiki/Blu-ray_Disc
-         - HD-DVD video   : http://en.wikipedia.org/wiki/HD_DVD
-         - DVD-Audio      : http://en.wikipedia.org/wiki/DVD-Audio
+   <mime-type type="x-content/video-hddvd">
+     <!-- http://en.wikipedia.org/wiki/HD_DVD -->
+     <_comment>HD DVD Video</_comment>
+   </mime-type>
 
-         - Photo CD       : http://en.wikipedia.org/wiki/Photo_CD
-         - Picture CD     : http://en.wikipedia.org/wiki/Picture_CD
+   <mime-type type="x-content/image-picturecd">
+     <!-- http://en.wikipedia.org/wiki/Picture_CD -->
+     <_comment>Picture CD</_comment>
+   </mime-type>
 
+   <mime-type type="x-content/audio-player">
+     <!-- see fd.o hal spec -->
+     <_comment>Portable Audio Player</_comment>
+   </mime-type>
+
+   <mime-type type="x-content/software">
+     <!-- http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html -->
+     <_comment>Software</_comment>
+   </mime-type>
+
+   <!-- TODO:
          - SACD           : http://en.wikipedia.org/wiki/Super_Audio_CD
            - This might be dead and appear to be totally unsupported anyway
 
@@ -62,8 +93,6 @@
          - Enhanced DVD Movie (see link 1. below)
           - ??
 
-          - music player (x-content/music-player)
-
          - picture files
          - audio files
          - video files

Modified: trunk/libnautilus-private/apps_nautilus_preferences.schemas.in
==============================================================================
--- trunk/libnautilus-private/apps_nautilus_preferences.schemas.in	(original)
+++ trunk/libnautilus-private/apps_nautilus_preferences.schemas.in	Thu Jan 17 13:45:27 2008
@@ -102,6 +102,21 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/nautilus/preferences/media_autorun_never_</key>
+      <applyto>/apps/nautilus/preferences/media_autorun_never</applyto>
+      <owner>nautilus</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+         <short>Never prompt or autorun/autostart programs when media is inserted</short>
+         <long>
+           If set to true, then Nautilus will never prompt nor autorun/autostart
+           programs when media is inserted.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/nautilus/preferences/media_autorun_x_content_ask</key>
       <applyto>/apps/nautilus/preferences/media_autorun_x_content_ask</applyto>
       <owner>nautilus</owner>
@@ -109,9 +124,9 @@
       <list_type>string</list_type>
       <default>[]</default>
       <locale name="C">
-         <short>list of x-content/* types to ask the user what to do on insertion</short>
+         <short>List of x-content/* types to ask the user what to do on insertion</short>
          <long>
-           list of x-content/* types to ask the user what to do on insertion
+           List of x-content/* types to ask the user what to do on insertion.
          </long>
       </locale>
     </schema>
@@ -124,9 +139,25 @@
       <list_type>string</list_type>
       <default>[]</default>
       <locale name="C">
-         <short>list of x-content/* types to ignore on insertion</short>
+         <short>List of x-content/* where to prompt the user on insertion</short>
+         <long>
+           List of x-content/* types to ask the user what to do on insertion.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/nautilus/preferences/media_autorun_x_content_open_folder</key>
+      <applyto>/apps/nautilus/preferences/media_autorun_x_content_open_folder</applyto>
+      <owner>nautilus</owner>
+      <type>list</type>
+      <list_type>string</list_type>
+      <default>[]</default>
+      <locale name="C">
+         <short>List of x-content/* types where a folder window should be opened</short>
          <long>
-           list of x-content/* types to ask the user what to do on insertion
+           List of x-content/* types where a folder window should be opened
+           on insertion.
          </long>
       </locale>
     </schema>

Modified: trunk/libnautilus-private/nautilus-autorun.c
==============================================================================
--- trunk/libnautilus-private/nautilus-autorun.c	(original)
+++ trunk/libnautilus-private/nautilus-autorun.c	Thu Jan 17 13:45:27 2008
@@ -29,6 +29,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <gio/gdesktopappinfo.h>
+#include <X11/XKBlib.h>
 
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-stock-dialogs.h>
@@ -38,12 +39,15 @@
 #include "nautilus-file-operations.h"
 #include "nautilus-autorun.h"
 #include "nautilus-program-choosing.h"
+#include "nautilus-open-with-dialog.h"
+#include "nautilus-desktop-icon-file.h"
 
 enum
 {
 	AUTORUN_ASK,
 	AUTORUN_IGNORE,
 	AUTORUN_APP,
+	AUTORUN_OPEN_FOLDER,
 	AUTORUN_SEP,
 };
 enum
@@ -56,24 +60,34 @@
 };
 
 void
-nautilus_autorun_get_preferences (const char *x_content_type, gboolean *pref_ask, gboolean *pref_ignore)
+nautilus_autorun_get_preferences (const char *x_content_type, 
+				  gboolean *pref_ask, 
+				  gboolean *pref_ignore, 
+				  gboolean *pref_open_folder)
 {
 	char **x_content_ask;
 	char **x_content_ignore;
+	char **x_content_open_folder;
 
 	g_return_if_fail (pref_ask != NULL);
 	g_return_if_fail (pref_ignore != NULL);
+	g_return_if_fail (pref_open_folder != NULL);
 
 	*pref_ask = FALSE;
 	*pref_ignore = FALSE;
+	*pref_open_folder = FALSE;
 	x_content_ask = eel_preferences_get_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_ASK);
 	x_content_ignore = eel_preferences_get_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_IGNORE);
+	x_content_open_folder = eel_preferences_get_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_OPEN_FOLDER);
 	if (x_content_ask != NULL) {
 		*pref_ask = eel_g_strv_find (x_content_ask, x_content_type) != -1;
 	}
 	if (x_content_ignore != NULL) {
 		*pref_ignore = eel_g_strv_find (x_content_ignore, x_content_type) != -1;
 	}
+	if (x_content_open_folder != NULL) {
+		*pref_open_folder = eel_g_strv_find (x_content_open_folder, x_content_type) != -1;
+	}
 	g_strfreev (x_content_ignore);
 	g_strfreev (x_content_ask);
 
@@ -112,13 +126,15 @@
 
 
 void
-nautilus_autorun_set_preferences (const char *x_content_type, gboolean pref_ask, gboolean pref_ignore)
+nautilus_autorun_set_preferences (const char *x_content_type, gboolean pref_ask, gboolean pref_ignore, gboolean pref_open_folder)
 {
 	char **x_content_ask;
 	char **x_content_ignore;
+	char **x_content_open_folder;
 
 	x_content_ask = eel_preferences_get_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_ASK);
 	x_content_ignore = eel_preferences_get_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_IGNORE);
+	x_content_open_folder = eel_preferences_get_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_OPEN_FOLDER);
 
 	remove_elem_from_str_array (x_content_ask, x_content_type);
 	if (pref_ask) {
@@ -132,6 +148,13 @@
 	}
 	eel_preferences_set_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_IGNORE, x_content_ignore);
 
+	remove_elem_from_str_array (x_content_open_folder, x_content_type);
+	if (pref_open_folder) {
+		x_content_open_folder = add_elem_to_str_array (x_content_open_folder, x_content_type);
+	}
+	eel_preferences_set_string_array (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_OPEN_FOLDER, x_content_open_folder);
+
+	g_strfreev (x_content_open_folder);
 	g_strfreev (x_content_ignore);
 	g_strfreev (x_content_ask);
 
@@ -156,12 +179,24 @@
 
 typedef struct
 {
+	guint changed_signal_id;
+	GtkWidget *combo_box;
+
 	gboolean update_settings;
 	NautilusAutorunComboBoxChanged changed_cb;
 	gpointer user_data;
 } NautilusAutorunComboBoxData;
 
 static void 
+nautilus_autorun_combobox_data_destroy (NautilusAutorunComboBoxData *data)
+{
+	/* signal handler may be automatically disconnected by destroying the widget */
+	if (g_signal_handler_is_connected (G_OBJECT (data->combo_box), data->changed_signal_id))
+		g_signal_handler_disconnect (G_OBJECT (data->combo_box), data->changed_signal_id);
+	g_free (data);
+}
+
+static void 
 combo_box_changed (GtkComboBox *combo_box,
                    NautilusAutorunComboBoxData *data)
 {
@@ -193,26 +228,34 @@
 	switch (type) {
 	case AUTORUN_ASK:
 		if (data->changed_cb != NULL) {
-			data->changed_cb (TRUE, FALSE, NULL, data->user_data);
+			data->changed_cb (TRUE, FALSE, FALSE, NULL, data->user_data);
 		}
 		if (data->update_settings) {
-			nautilus_autorun_set_preferences (x_content_type, TRUE, FALSE);
+			nautilus_autorun_set_preferences (x_content_type, TRUE, FALSE, FALSE);
 		}
 		break;
 	case AUTORUN_IGNORE:
 		if (data->changed_cb != NULL) {
-			data->changed_cb (FALSE, TRUE, NULL, data->user_data);
+			data->changed_cb (FALSE, TRUE, FALSE, NULL, data->user_data);
 		}
 		if (data->update_settings) {
-			nautilus_autorun_set_preferences (x_content_type, FALSE, TRUE);
+			nautilus_autorun_set_preferences (x_content_type, FALSE, TRUE, FALSE);
+		}
+		break;
+	case AUTORUN_OPEN_FOLDER:
+		if (data->changed_cb != NULL) {
+			data->changed_cb (FALSE, FALSE, TRUE, NULL, data->user_data);
+		}
+		if (data->update_settings) {
+			nautilus_autorun_set_preferences (x_content_type, FALSE, FALSE, TRUE);
 		}
 		break;
 	case AUTORUN_APP:
 		if (data->changed_cb != NULL) {
-			data->changed_cb (FALSE, FALSE, app_info, data->user_data);
+			data->changed_cb (FALSE, FALSE, FALSE, app_info, data->user_data);
 		}
 		if (data->update_settings) {
-			nautilus_autorun_set_preferences (x_content_type, FALSE, FALSE);
+			nautilus_autorun_set_preferences (x_content_type, FALSE, FALSE, FALSE);
 			g_app_info_set_as_default_for_type (app_info,
 							    x_content_type,
 							    NULL);
@@ -230,7 +273,6 @@
 	g_free (x_content_type);
 }
 
-
 void
 nautilus_autorun_prepare_combo_box (GtkWidget *combo_box, 
 				    const char *x_content_type,
@@ -251,14 +293,16 @@
 	int num_apps;
 	gboolean pref_ask;
 	gboolean pref_ignore;
+	gboolean pref_open_folder;
 	NautilusAutorunComboBoxData *data;
 	GtkCellRenderer *renderer;
 
-	nautilus_autorun_get_preferences (x_content_type, &pref_ask, &pref_ignore);
+	nautilus_autorun_get_preferences (x_content_type, &pref_ask, &pref_ignore, &pref_open_folder);
 
 	icon_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
 
 	set_active = -1;
+	data = NULL;
 
 	app_info_list = g_app_info_get_all_for_type (x_content_type);
 	default_app_info = g_app_info_get_default_for_type (x_content_type, FALSE);
@@ -310,7 +354,7 @@
 		
 		gtk_list_store_append (list_store, &iter);
 		pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-						   GTK_STOCK_CANCEL,
+						   GTK_STOCK_CLOSE,
 						   icon_size,
 						   0,
 						   NULL);
@@ -321,8 +365,23 @@
 				    COLUMN_AUTORUN_X_CONTENT_TYPE, x_content_type,
 				    COLUMN_AUTORUN_ITEM_TYPE, AUTORUN_IGNORE,
 				    -1);
-		g_object_unref (pixbuf);
-		
+		g_object_unref (pixbuf);		
+
+		gtk_list_store_append (list_store, &iter);
+		pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+						   "nautilus",
+						   icon_size,
+						   0,
+						   NULL);
+		gtk_list_store_set (list_store, &iter, 
+				    COLUMN_AUTORUN_PIXBUF, pixbuf, 
+				    COLUMN_AUTORUN_NAME, _("Open Folder"), 
+				    COLUMN_AUTORUN_APP_INFO, NULL, 
+				    COLUMN_AUTORUN_X_CONTENT_TYPE, x_content_type,
+				    COLUMN_AUTORUN_ITEM_TYPE, AUTORUN_OPEN_FOLDER,
+				    -1);
+		g_object_unref (pixbuf);		
+
 		gtk_list_store_append (list_store, &iter);
 		gtk_list_store_set (list_store, &iter, 
 				    COLUMN_AUTORUN_PIXBUF, NULL, 
@@ -332,7 +391,7 @@
 				    COLUMN_AUTORUN_ITEM_TYPE, AUTORUN_SEP,
 				    -1);
 
-		for (l = app_info_list, n = include_ask ? 3 : 2; l != NULL; l = l->next, n++) {
+		for (l = app_info_list, n = include_ask ? 4 : 3; l != NULL; l = l->next, n++) {
 			GIcon *icon;
 			NautilusIconInfo *icon_info;
 			char *open_string;
@@ -349,7 +408,7 @@
 			g_object_unref (icon_info);
 			
 			open_string = g_strdup_printf (_("Open %s"), g_app_info_get_name (app_info));
-			
+
 			gtk_list_store_append (list_store, &iter);
 			gtk_list_store_set (list_store, &iter, 
 					    COLUMN_AUTORUN_PIXBUF, pixbuf, 
@@ -376,15 +435,17 @@
 
 	gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (list_store));
 
+	gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo_box));
+
 	renderer = gtk_cell_renderer_pixbuf_new ();
 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
-					"pixbuf", 0,
+					"pixbuf", COLUMN_AUTORUN_PIXBUF,
 					NULL);
 	renderer = gtk_cell_renderer_text_new ();
 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
-					"text", 1,
+					"text", COLUMN_AUTORUN_NAME,
 					NULL);
 	gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo_box), combo_box_separator_func, NULL, NULL);
 
@@ -392,10 +453,13 @@
 		gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
 		gtk_widget_set_sensitive (combo_box, FALSE);
 	} else {
+		gtk_widget_set_sensitive (combo_box, TRUE);
 		if (pref_ask && include_ask) {
 			gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
 		} else if (pref_ignore) {
 			gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), include_ask ? 1 : 0);
+		} else if (pref_open_folder) {
+			gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), include_ask ? 2 : 1);
 		} else if (set_active != -1) {
 			gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), set_active);
 		} else {
@@ -406,17 +470,18 @@
 		data->update_settings = update_settings;
 		data->changed_cb = changed_cb;
 		data->user_data = user_data;
-
-		g_signal_connect (G_OBJECT (combo_box),
-				  "changed",
-				  G_CALLBACK (combo_box_changed),
-				  data);
-
-		/* TODO: unref 'data' when combo box goes bye-bye */
+		data->combo_box = combo_box;
+		data->changed_signal_id = g_signal_connect (G_OBJECT (combo_box),
+							    "changed",
+							    G_CALLBACK (combo_box_changed),
+							    data);
 	}
-}
 
-#include <X11/XKBlib.h>
+	g_object_set_data_full (G_OBJECT (combo_box),
+				"nautilus_autorun_combobox_data",
+				data,
+				(GDestroyNotify) nautilus_autorun_combobox_data_destroy);
+}
 
 static gboolean
 is_shift_pressed (void)
@@ -441,51 +506,217 @@
 /*-- BEGIN MOVE TO GIO --*/
 
 static gboolean
-_dir_exists (GFile *mount_root, const char *dirname)
+_check_nonempty_dir (GFile *mount_root, const char *dirname)
 {
 	GFile *file;
 	GFileInfo *file_info;
-	
+	GFileEnumerator *file_enum;
+	gboolean ret;
+
+	ret = FALSE;
+
 	file = g_file_get_child (mount_root, dirname);
+	file_enum = g_file_enumerate_children (file,
+					       G_FILE_ATTRIBUTE_STANDARD_NAME,
+					       G_FILE_QUERY_INFO_NONE,
+					       NULL,
+					       NULL);
+	if (file_enum != NULL) {
+		file_info = g_file_enumerator_next_file (file_enum, NULL, NULL);
+		if (file_info != NULL) {
+			ret = TRUE;
+			g_object_unref (file_info);
+		}
+		g_object_unref (file_enum);
+	}
+	g_object_unref (file);
+
+	return ret;
+}
+
+static gboolean
+_check_file (GFile *mount_root, const char *file_path, gboolean must_be_executable)
+{
+	GFile *file;
+	GFileInfo *file_info;
+	gboolean ret;
+
+	ret = FALSE;
+
+	file = g_file_get_child (mount_root, file_path);
 	file_info = g_file_query_info (file,
-				       G_FILE_ATTRIBUTE_STANDARD_NAME,
+				       G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
 				       G_FILE_QUERY_INFO_NONE,
 				       NULL,
 				       NULL);
 	if (file_info != NULL) {
+		if (must_be_executable) {
+			if (g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE))
+				ret = TRUE;
+		} else {
+			ret = TRUE;
+		}
 		g_object_unref (file_info);
 	}
 	g_object_unref (file);
 
-	return file_info != NULL;
+	return ret;
 }
 
-static char **
-_g_mount_guess_content_type_for_mount_root (GFile               *mount_root,
-					    GError             **error)
+/**
+ * _g_mount_guess_content_type:
+ * @mount: a #GMount.
+ * @force_rescan: Whether to force a rescan of the content. Otherwise a cached result will be used if available.
+ * @error: return location for error or %NULL to ignore.
+ *
+ * Tries to guess the type of content stored on @mount. Returns one or
+ * more textual identifiers of well-known content types (typically
+ * prefixed with "x-content/"). TODO: link to fd.o spec about this.
+ *
+ * This function may do I/O and thus may take a long time to
+ * complete. For the async version, see
+ * _g_mount_guess_content_type_async().
+ *
+ * Returns: a %NULL terminated array of content types or %NULL on
+ * error. Caller should free this array with g_strfreev() when done
+ * with it.
+ **/
+char **
+_g_mount_guess_content_type (GMount              *mount,
+			     gboolean             force_rescan,
+			     GError             **error)
 {
+	unsigned int n;
 	char **ret;
 	GPtrArray *types;
-	
+	GFile *root;
+	GVolume *volume;
+	char *disc_type = NULL;
+
+	/* TODO: We can't really sensibly cache anything right now..
+	 *       But when moved to gio this can be done.
+	 */
+
 	types = g_ptr_array_new ();
-	
-	/* TODO: analyze mount_root and add more content types as needed */
 
-	if (g_file_has_uri_scheme (mount_root, "cdda")) {
+	root = g_mount_get_root (mount);
+	volume = g_mount_get_volume (mount);
+
+	/* Take advantage of information from HAL's quirk lists that maps a given 
+	 * make/model of (what appears to be just) a storage device to it's intended
+	 * use.
+	 *
+	 * E.g. a mapping saying that a storage device is a music player, a digital
+	 * camera, a videocam, a video play back device, a gps reader.. and so on...
+	 */
+	if (volume != NULL) {
+		char **stor_device_caps;
+
+		/* See gvfs/hal/ghalvolume.c:do_update_from_hal()...
+		 *
+		 * This hack, using g_object_set|get_data() can be
+		 * removed once g_mount_guess_content_type() is in gio
+		 * and the actual code for probing media is in the
+		 * gvfs hal backend.
+		 */
+		stor_device_caps = (char **) g_object_get_data (G_OBJECT (volume), "hal-storage-device-capabilities");
+		if (stor_device_caps != NULL) {
+			for (n = 0; stor_device_caps[n] != NULL; n++) {
+				if (strcmp (stor_device_caps[n], "portable_audio_player") == 0) {
+					g_ptr_array_add (types, g_strdup ("x-content/audio-player"));
+				}
+				/* TODO: map other hal capabilities to x-content/ types */
+			}
+		}
+
+		disc_type = (char *) g_object_get_data (G_OBJECT (volume), "hal-volume.disc.type");
+	}
+	
+	if (g_file_has_uri_scheme (root, "cdda")) {
 		g_ptr_array_add (types, g_strdup ("x-content/audio-cdda"));
 		goto no_sniff;
 	}
+
+	if (g_file_has_uri_scheme (root, "burn")) {
+		if (disc_type != NULL) {
+			if (g_str_has_prefix (disc_type, "dvd")) {
+				g_ptr_array_add (types, g_strdup ("x-content/blank-dvd"));
+			} else if (g_str_has_prefix (disc_type, "hddvd")) {
+				g_ptr_array_add (types, g_strdup ("x-content/blank-hddvd"));
+			} else if (g_str_has_prefix (disc_type, "bd")) {
+				g_ptr_array_add (types, g_strdup ("x-content/blank-bd"));
+			} else {
+				/* assume CD */
+				g_ptr_array_add (types, g_strdup ("x-content/blank-cd"));
+			}
+		}
+		goto no_sniff;
+	}
 	
-	if (_dir_exists (mount_root, "DCIM") ||
-	    _dir_exists (mount_root, "dcim")) {
+	if (_check_nonempty_dir (root, "DCIM") ||
+	    _check_nonempty_dir (root, "dcim")) {
 		g_ptr_array_add (types, g_strdup ("x-content/image-dcf"));
 	}
 	
-	if (_dir_exists (mount_root, "VIDEO_TS") ||
-	    _dir_exists (mount_root, "video_ts")) {
+	if (_check_nonempty_dir (root, "VIDEO_TS") && 
+	    disc_type != NULL) {
 		g_ptr_array_add (types, g_strdup ("x-content/video-dvd"));
 	}
 
+	if (_check_nonempty_dir (root, "AUDIO_TS") && 
+	    disc_type != NULL) {
+		g_ptr_array_add (types, g_strdup ("x-content/audio-dvd"));
+	}
+
+
+	/* see http://www.ccs.neu.edu/home/bchafy/cdb/info/info.html for various docs */
+
+	if (_check_nonempty_dir (root, "SVCD") && 
+	    _check_nonempty_dir (root, "EXT") &&
+	    _check_nonempty_dir (root, "MPEG-2") && 
+	    disc_type != NULL) {
+		/* http://everything2.com/index.pl?node_id=1009222 */
+		g_ptr_array_add (types, g_strdup ("x-content/video-svcd"));
+	}
+
+	if (_check_nonempty_dir (root, "VCD") && 
+	    _check_nonempty_dir (root, "MPEGAV") && 
+	    disc_type != NULL) {
+		/* http://www.herongyang.com/CD-DVD/VCD-Movie-File-Directory-Structure.html */
+		g_ptr_array_add (types, g_strdup ("x-content/video-vcd"));
+	}
+
+	if (_check_nonempty_dir (root, "BDAV") && 
+	    _check_nonempty_dir (root, "BDMV") && 
+	    disc_type != NULL) {
+		/* http://www.blu-raydisc.com/Section-13470/Section-13890/Index.html */
+		g_ptr_array_add (types, g_strdup ("x-content/video-bluray"));
+	}
+
+	if (_check_nonempty_dir (root, "HVDVD_TS") && /* not a typo; should really spell HVDVD_TS */
+	    disc_type != NULL) {
+		/* http://www.cdfreaks.com/reviews/CDFreaks--CES-2006/Page-5.html */
+		g_ptr_array_add (types, g_strdup ("x-content/video-hddvd"));
+	}
+
+	if (_check_nonempty_dir (root, "PICTURES") &&
+	    disc_type != NULL) {
+		/* http://www.re.org/kristin/picturecd.html */
+		g_ptr_array_add (types, g_strdup ("x-content/image-picturecd"));
+	}
+
+	if (_check_file (root, ".autorun", TRUE) ||
+	    _check_file (root, "autorun", TRUE) ||
+	    _check_file (root, "autorun.sh", TRUE) ||
+	    _check_file (root, "autorun.exe", TRUE) || _check_file (root, "AUTORUN.EXE", TRUE) ||
+	    _check_file (root, "autorun.inf", FALSE) || _check_file (root, "AUTORUN.INF", FALSE)) {
+		/* http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html */
+
+		/* http://bugzilla.gnome.org/show_bug.cgi?id=509823#c3 for the autorun.exe and autorun.inf stuff */
+		g_ptr_array_add (types, g_strdup ("x-content/software"));
+	}
+
+
 no_sniff:
 	
 	if (types->len == 0) {
@@ -495,12 +726,16 @@
 		g_ptr_array_add (types, NULL);
 		ret = (char **) g_ptr_array_free (types, FALSE);
 	}
-	
+
+	if (volume != NULL)
+		g_object_unref (volume);
+	g_object_unref (root);
 	return ret;
 }
 
 typedef struct {
 	char **guessed_content_type;
+	gboolean force_rescan;
 } GuessContentData;
 
 static void
@@ -512,8 +747,8 @@
 	GError *error = NULL;
 	
 	op = g_simple_async_result_get_op_res_gpointer (res);
-	
-	op->guessed_content_type = _g_mount_guess_content_type_for_mount_root (G_FILE (object), &error);
+
+	op->guessed_content_type = _g_mount_guess_content_type (G_MOUNT (object), op->force_rescan, &error);
 	
 	if (error != NULL) {
 		g_simple_async_result_set_from_error (res, error);
@@ -523,28 +758,32 @@
 
 /**
  * _g_mount_guess_content_type_async:
- * @mount_root: a #GFile.
+ * @mount: a #GMount.
+ * @force_rescan: Whether to force a rescan of the content. Otherwise a cached result will be used if available.
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @callback: a #GAsyncReadyCallback.
  * @user_data: user data passed to @callback.
  *
- * Like _g_mount_guess_content_type_async() but analyzes a given sub
- * directory instead.
+ * This is an asynchronous version of _g_mount_guess_content_type(),
+ * and is finished by calling _g_mount_guess_content_type_finish() with
+ * the @mount and #GAsyncResults data returned in the @callback.
  */
-static void
-_g_mount_guess_content_type_for_mount_root_async (GFile               *mount_root,
-						  GCancellable        *cancellable,
-						  GAsyncReadyCallback  callback,
-						  gpointer             user_data)
+void
+_g_mount_guess_content_type_async (GMount              *mount,
+				   gboolean             force_rescan,
+				   GCancellable        *cancellable,
+				   GAsyncReadyCallback  callback,
+				   gpointer             user_data)
 {
 	GSimpleAsyncResult *res;
 	GuessContentData *op;
 	
 	op = g_new0 (GuessContentData, 1);
-	res = g_simple_async_result_new (G_OBJECT (mount_root), 
+	op->force_rescan = force_rescan;
+	res = g_simple_async_result_new (G_OBJECT (mount), 
 					 callback, 
 					 user_data, 
-					 _g_mount_guess_content_type_for_mount_root_async);
+					 _g_mount_guess_content_type_async);
 	g_simple_async_result_set_op_res_gpointer (res, op, g_free);
 	
 	g_simple_async_result_run_in_thread (res, guess_content_thread, G_PRIORITY_DEFAULT, cancellable);
@@ -552,28 +791,29 @@
 }
 
 /**
- * _g_mount_guess_content_type_for_mount_root_finish:
- * @mount_root: a #GFile.
+ * _g_mount_guess_content_type_finish:
+ * @mount: a #GMount.
  * @result: a #GAsyncResult.
  * @error: a #GError location to store the error occuring, or %NULL to 
  * ignore.
  * 
- * Like _g_mount_guess_content_type_finish() but analyzes a given sub
- * directory instead.
+ * Finishes guessing content types of @mount. If any errors occured
+ * during the operation, @error will be set to contain the errors and
+ * %FALSE will be returned.
  * 
  * Returns: a %NULL terminated array of content types or %NULL on
  * error. Caller should free this array with g_strfreev() when done
  * with it.
  **/
-static char **
-_g_mount_guess_content_type_for_mount_root_finish (GFile               *mount_root,
-						   GAsyncResult        *result,
-						   GError             **error)
+char **
+_g_mount_guess_content_type_finish (GMount              *mount,
+				    GAsyncResult        *result,
+				    GError             **error)
 {
 	GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
 	GuessContentData *op;
 	
-	g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == _g_mount_guess_content_type_for_mount_root_async);
+	g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == _g_mount_guess_content_type_async);
 	
 	op = g_simple_async_result_get_op_res_gpointer (simple);
 	return op->guessed_content_type;
@@ -584,19 +824,26 @@
 
 typedef struct
 {
+	GtkWidget *dialog;
+
 	GMount *mount;
 	gboolean should_eject;
 
 	gboolean selected_ignore;
+	gboolean selected_open_folder;
 	GAppInfo *selected_app;
 
 	gboolean remember;
 
 	char *x_content_type;
+
+	NautilusAutorunOpenWindow open_window_func;
+	gpointer user_data;
 } AutorunDialogData;
 
-static void
-autorun_launch_for_mount (GMount *mount, GAppInfo *app_info)
+
+void
+nautilus_autorun_launch_for_mount (GMount *mount, GAppInfo *app_info)
 {
 	GFile *root;
 	NautilusFile *file;
@@ -613,6 +860,31 @@
 	g_list_free (files);
 }
 
+static void autorun_dialog_mount_unmounted (GMount *mount, AutorunDialogData *data);
+
+static void
+autorun_dialog_destroy (AutorunDialogData *data)
+{
+	g_signal_handlers_disconnect_by_func (G_OBJECT (data->mount),
+					      G_CALLBACK (autorun_dialog_mount_unmounted),
+					      data);
+
+	gtk_widget_destroy (GTK_WIDGET (data->dialog));
+	if (data->selected_app != NULL) {
+		g_object_unref (data->selected_app);
+	}
+	g_object_unref (data->mount);
+	g_free (data->x_content_type);
+	g_free (data);
+}
+
+static void 
+autorun_dialog_mount_unmounted (GMount *mount, AutorunDialogData *data)
+{
+	/* remove the dialog if the media is unmounted */
+	autorun_dialog_destroy (data);
+}
+
 static void 
 autorun_dialog_response (GtkDialog *dialog, gint response, AutorunDialogData *data)
 {
@@ -620,13 +892,6 @@
 	case GTK_RESPONSE_NONE:
 		/* window was closed */
 		break;
-	case 0:
-		/* eject/unmount */
-		nautilus_file_operations_unmount_mount (NULL,
-							data->mount,
-							data->should_eject,
-							FALSE);
-		break;
 	case GTK_RESPONSE_CANCEL:
 		break;
 	case GTK_RESPONSE_OK:
@@ -634,35 +899,33 @@
 
 		if (data->remember) {
 			/* make sure we don't ask again */
-			nautilus_autorun_set_preferences (data->x_content_type, FALSE, data->selected_ignore);
-			if (!data->selected_ignore && data->selected_app != NULL) {
+			nautilus_autorun_set_preferences (data->x_content_type, FALSE, data->selected_ignore, data->selected_open_folder);
+			if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) {
 				g_app_info_set_as_default_for_type (data->selected_app,
 								    data->x_content_type,
 								    NULL);
 			}
 		} else {
 			/* make sure we do ask again */
-			nautilus_autorun_set_preferences (data->x_content_type, TRUE, FALSE);
+			nautilus_autorun_set_preferences (data->x_content_type, TRUE, FALSE, FALSE);
 		}
 
-		if (!data->selected_ignore && data->selected_app != NULL) {
-			autorun_launch_for_mount (data->mount, data->selected_app);
+		if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) {
+			nautilus_autorun_launch_for_mount (data->mount, data->selected_app);
+		} else if (!data->selected_ignore && data->selected_open_folder) {
+			if (data->open_window_func != NULL)
+				data->open_window_func (data->mount, data->user_data);
 		}
 		break;
 	}
 
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-	if (data->selected_app != NULL) {
-		g_object_unref (data->selected_app);
-	}
-	g_object_unref (data->mount);
-	g_free (data->x_content_type);
-	g_free (data);
+	autorun_dialog_destroy (data);
 }
 
 static void
 autorun_combo_changed (gboolean selected_ask,
 		       gboolean selected_ignore,
+		       gboolean selected_open_folder,
 		       GAppInfo *selected_app,
 		       gpointer user_data)
 {
@@ -673,6 +936,7 @@
 	}
 	data->selected_app = selected_app != NULL ? g_object_ref (selected_app) : NULL;
 	data->selected_ignore = selected_ignore;
+	data->selected_open_folder = selected_open_folder;
 }
 
 
@@ -683,8 +947,9 @@
 }
 
 
-static void
-do_autorun_for_content_type (GMount *mount, const char *x_content_type)
+/* returns TRUE if a folder window should be opened */
+static gboolean
+do_autorun_for_content_type (GMount *mount, const char *x_content_type, NautilusAutorunOpenWindow open_window_func, gpointer user_data)
 {
 	AutorunDialogData *data;
 	GtkWidget *dialog;
@@ -705,27 +970,35 @@
 	gboolean user_forced_dialog;
 	gboolean pref_ask;
 	gboolean pref_ignore;
+	gboolean pref_open_folder;
 	char *media_greeting;
+	gboolean ret;
 
+	ret = FALSE;
 	mount_name = NULL;
 
 	user_forced_dialog = is_shift_pressed ();
 
-	nautilus_autorun_get_preferences (x_content_type, &pref_ask, &pref_ignore);
+	nautilus_autorun_get_preferences (x_content_type, &pref_ask, &pref_ignore, &pref_open_folder);
 
 	if (user_forced_dialog) {
 		goto show_dialog;
 	}
 
-	if (!pref_ask && !pref_ignore) {
+	if (!pref_ask && !pref_ignore && !pref_open_folder) {
 		GAppInfo *app_info;
 		app_info = g_app_info_get_default_for_type (x_content_type, FALSE);
 		if (app_info != NULL) {
-			autorun_launch_for_mount (mount, app_info);
+			nautilus_autorun_launch_for_mount (mount, app_info);
 		}
 		goto out;
 	}
 
+	if (pref_open_folder) {
+		ret = TRUE;
+		goto out;
+	}
+
 	if (pref_ignore) {
 		goto out;
 	}
@@ -746,6 +1019,7 @@
 	icon_info = nautilus_icon_info_lookup (icon, icon_size);
 	pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
 	g_object_unref (icon_info);
+	g_object_unref (icon);
 	image = gtk_image_new_from_pixbuf (pixbuf);
 	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
 	gtk_box_pack_start_defaults (GTK_BOX (hbox), image);
@@ -760,22 +1034,40 @@
 	label = gtk_label_new (NULL);
 
 
+	/* Customize greeting for well-known x-content types */
 	if (strcmp (x_content_type, "x-content/audio-cdda") == 0) {
-		media_greeting = _("You have just inserted an Audio CD");
+		media_greeting = _("You have just inserted an Audio CD.");
+	} else if (strcmp (x_content_type, "x-content/audio-dvd") == 0) {
+		media_greeting = _("You have just inserted an Audio DVD.");
 	} else if (strcmp (x_content_type, "x-content/video-dvd") == 0) {
-		media_greeting = _("You have just inserted a Video DVD");
+		media_greeting = _("You have just inserted a Video DVD.");
 	} else if (strcmp (x_content_type, "x-content/video-vcd") == 0) {
-		media_greeting = _("You have just inserted a Video CD");
+		media_greeting = _("You have just inserted a Video CD.");
 	} else if (strcmp (x_content_type, "x-content/video-svcd") == 0) {
-		media_greeting = _("You have just inserted a Super Video CD");
+		media_greeting = _("You have just inserted a Super Video CD.");
+	} else if (strcmp (x_content_type, "x-content/blank-cd") == 0) {
+		media_greeting = _("You have just inserted a blank CD.");
+	} else if (strcmp (x_content_type, "x-content/blank-dvd") == 0) {
+		media_greeting = _("You have just inserted a blank DVD.");
+	} else if (strcmp (x_content_type, "x-content/blank-cd") == 0) {
+		media_greeting = _("You have just inserted a blank Blu-Ray disc.");
+	} else if (strcmp (x_content_type, "x-content/blank-cd") == 0) {
+		media_greeting = _("You have just inserted a blank HD DVD.");
+	} else if (strcmp (x_content_type, "x-content/image-photocd") == 0) {
+		media_greeting = _("You have just inserted a Photo CD.");
+	} else if (strcmp (x_content_type, "x-content/image-picturecd") == 0) {
+		media_greeting = _("You have just inserted a Picture CD.");
 	} else if (strcmp (x_content_type, "x-content/image-dcf") == 0) {
-		media_greeting = _("You have just inserted media with digital photos");
-	} else if (strcmp (x_content_type, "x-content/blank-media") == 0) {
-		media_greeting = _("You have just inserted blank media");
+		media_greeting = _("You have just inserted media with digital photos.");
+	} else if (strcmp (x_content_type, "x-content/audio-player") == 0) {
+		media_greeting = _("You have just inserted a digital audio player.");
+	} else if (strcmp (x_content_type, "x-content/software") == 0) {
+		media_greeting = _("You have just inserted media with software intended to be automatically started.");
 	} else {
-		media_greeting = _("You have just inserted media");
+		/* fallback to generic greeting */
+		media_greeting = _("You have just inserted media.");
 	}
-	markup = g_strdup_printf ("<big><b>%s. %s</b></big>", media_greeting, _("Choose what application to launch."));
+	markup = g_strdup_printf ("<big><b>%s %s</b></big>", media_greeting, _("Choose what application to launch."));
 	gtk_label_set_markup (GTK_LABEL (label), markup);
 	g_free (markup);
 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
@@ -793,11 +1085,14 @@
 	gtk_box_pack_start_defaults (GTK_BOX (vbox), label);
 	
 	data = g_new0 (AutorunDialogData, 1);
+	data->dialog = dialog;
 	data->mount = g_object_ref (mount);
 	data->remember = !pref_ask;
 	data->selected_ignore = pref_ignore;
 	data->x_content_type = g_strdup (x_content_type);
 	data->selected_app = g_app_info_get_default_for_type (x_content_type, FALSE);
+	data->open_window_func = open_window_func;
+	data->user_data = user_data;
 
 	combo_box = gtk_combo_box_new ();
 	nautilus_autorun_prepare_combo_box (combo_box, x_content_type, FALSE, FALSE, autorun_combo_changed, data);
@@ -844,8 +1139,29 @@
 			  G_CALLBACK (autorun_dialog_response),
 			  data);
 
+	g_signal_connect (G_OBJECT (data->mount),
+			  "unmounted",
+			  G_CALLBACK (autorun_dialog_mount_unmounted),
+			  data);
+
 out:
 	g_free (mount_name);
+	return ret;
+}
+
+typedef struct {
+	GMount *mount;
+	NautilusAutorunOpenWindow open_window_func;
+	gpointer user_data;
+} AutorunData;
+
+
+static void
+autorun_open_folder_for_mount (AutorunData *data)
+{
+	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT_OPEN) && 
+	    data->open_window_func != NULL)
+		data->open_window_func (data->mount, data->user_data);
 }
 
 static void
@@ -855,30 +1171,46 @@
 {
 	GError *error;
 	char **guessed_content_type;
-	GMount *mount = G_MOUNT (user_data);
-	
+	AutorunData *data = user_data;
+	gboolean open_folder;
+
+	open_folder = FALSE;
+
 	error = NULL;
-	guessed_content_type = _g_mount_guess_content_type_for_mount_root_finish (G_FILE (source_object), res, &error);
+	guessed_content_type = _g_mount_guess_content_type_finish (G_MOUNT (source_object), res, &error);
 	if (error != NULL) {
 		g_warning ("Unabled to guess content type for mount: %s", error->message);
 		g_error_free (error);
 	} else {
-		if (guessed_content_type != NULL) {
+		if (guessed_content_type != NULL && g_strv_length (guessed_content_type) > 0) {
 			int n;
 			for (n = 0; guessed_content_type[n] != NULL; n++) {
-				do_autorun_for_content_type (mount, guessed_content_type[n]);
+				if (do_autorun_for_content_type (data->mount, guessed_content_type[n], 
+								 data->open_window_func, data->user_data)) {
+					open_folder = TRUE;
+				}
 			}
 			g_strfreev (guessed_content_type);
+		} else {
+			open_folder = TRUE;
 		}
 	}
 
-	g_object_unref (mount);
+	/* only open the folder once.. */
+	if (open_folder)
+		autorun_open_folder_for_mount (data);
+
+	g_object_unref (data->mount);
+	g_free (data);
 }
 
 void
-nautilus_autorun (GMount *mount)
+nautilus_autorun (GMount *mount, NautilusAutorunOpenWindow open_window_func, gpointer user_data)
 {
-	GFile *root;
+	AutorunData *data;
+
+	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER))
+		return;
 		
 	/* TODO: only do this for local mounts */
 
@@ -886,10 +1218,81 @@
 	 * we do this asynchronously (in another thread) since it
 	 * requires doing I/O.
 	 */
-	root = g_mount_get_root (mount);
-	_g_mount_guess_content_type_for_mount_root_async (root,
-							  NULL,
-							  autorun_guessed_content_type_callback,
-							  g_object_ref (mount));
-	g_object_unref (root);
+
+	data = g_new0 (AutorunData, 1);
+	data->mount = g_object_ref (mount);
+	data->open_window_func = open_window_func;
+	data->user_data = user_data;
+
+	_g_mount_guess_content_type_async (mount,
+					   TRUE,
+					   NULL,
+					   autorun_guessed_content_type_callback,
+					   data);
+}
+
+char **
+nautilus_autorun_get_x_content_types_for_file (NautilusFile *nautilus_file, 
+					       GMount      **out_mount,
+					       gboolean      force_rescan,
+					       gboolean      include_child_dirs)
+{
+	GMount *mount;
+	char **x_content_types;
+
+	x_content_types = NULL;
+
+	g_return_val_if_fail (nautilus_file != NULL, NULL);
+
+	mount = NULL;
+	if (g_type_is_a (G_OBJECT_TYPE (nautilus_file), NAUTILUS_TYPE_DESKTOP_ICON_FILE)) {
+		NautilusDesktopIconFile *desktop_icon_file = NAUTILUS_DESKTOP_ICON_FILE (nautilus_file);
+		NautilusDesktopLink *desktop_link;
+		
+		desktop_link = nautilus_desktop_icon_file_get_link (desktop_icon_file);
+		if (desktop_link != NULL) {
+			if (nautilus_desktop_link_get_link_type (desktop_link) == NAUTILUS_DESKTOP_LINK_MOUNT) {
+				mount = nautilus_desktop_link_get_mount (desktop_link);
+			}
+			g_object_unref (desktop_link);
+		}		
+	} else {
+		GFile *file;
+		file = nautilus_file_get_location (nautilus_file);
+		if (file != NULL) {
+			mount = g_file_find_enclosing_mount (file, NULL, NULL);
+			if (mount != NULL) {
+				GFile *mount_root;
+				mount_root = g_mount_get_root (mount);
+				if (!include_child_dirs) {
+					if (!g_file_equal (mount_root, file)) {
+						g_object_unref (mount);
+						mount = NULL;
+					}
+				}
+				g_object_unref (mount_root);
+			}
+			g_object_unref (file);
+		}
+	}
+
+
+	/* TODO: handle files in computer:///. 
+	 *
+	 * Also need to handle those in libnautilus-private/nautilus-program-choosing.c:nautilus_launch_application()
+	 *
+	 * These NautilusFile instances are of class NautilusVFSFile.. URI is 'computer:///CompactFlash%20Drive.drive'
+	 */
+
+	if (mount != NULL) {
+		/* since we always guess the content type at mount type, we're guaranteed
+		 * to get the cached results
+		 */
+		x_content_types = _g_mount_guess_content_type (mount, force_rescan, NULL);
+		if (out_mount != NULL)
+			*out_mount = g_object_ref (mount);
+		g_object_unref (mount);
+	}
+
+	return x_content_types;
 }

Modified: trunk/libnautilus-private/nautilus-autorun.h
==============================================================================
--- trunk/libnautilus-private/nautilus-autorun.h	(original)
+++ trunk/libnautilus-private/nautilus-autorun.h	Thu Jan 17 13:45:27 2008
@@ -44,11 +44,29 @@
 #include <eel/eel-background.h>
 #include <libnautilus-private/nautilus-file.h>
 
+void _g_mount_guess_content_type_async (GMount              *mount,
+					gboolean             force_rescan,
+					GCancellable        *cancellable,
+					GAsyncReadyCallback  callback,
+					gpointer             user_data);
+
+char ** _g_mount_guess_content_type_finish (GMount              *mount,
+					    GAsyncResult        *result,
+					    GError             **error);
+
+char ** _g_mount_guess_content_type (GMount              *mount,
+				     gboolean             force_rescan,
+				     GError             **error);
+
+
 typedef void (*NautilusAutorunComboBoxChanged) (gboolean selected_ask,
 						gboolean selected_ignore,
+						gboolean selected_open_folder,
 						GAppInfo *selected_app,
 						gpointer user_data);
 
+typedef void (*NautilusAutorunOpenWindow) (GMount *mount, gpointer user_data);
+
 void nautilus_autorun_prepare_combo_box (GtkWidget *combo_box, 
 					 const char *x_content_type, 
 					 gboolean include_ask,
@@ -56,10 +74,16 @@
 					 NautilusAutorunComboBoxChanged changed_cb,
 					 gpointer user_data);
 
-void nautilus_autorun_set_preferences (const char *x_content_type, gboolean pref_ask, gboolean pref_ignore);
-void nautilus_autorun_get_preferences (const char *x_content_type, gboolean *pref_ask, gboolean *pref_ignore);
+void nautilus_autorun_set_preferences (const char *x_content_type, gboolean pref_ask, gboolean pref_ignore, gboolean pref_open_folder);
+void nautilus_autorun_get_preferences (const char *x_content_type, gboolean *pref_ask, gboolean *pref_ignore, gboolean *pref_open_folder);
+
+void nautilus_autorun (GMount *mount, NautilusAutorunOpenWindow open_window_func, gpointer user_data);
 
-void nautilus_autorun (GMount *mount);
+char **nautilus_autorun_get_x_content_types_for_file (NautilusFile   *file, 
+						      GMount       **out_mount,
+						      gboolean       force_rescan, 
+						      gboolean       include_child_dirs);
 
+void nautilus_autorun_launch_for_mount (GMount *mount, GAppInfo *app_info);
 
 #endif /* NAUTILUS_AUTORUN_H */

Modified: trunk/libnautilus-private/nautilus-file-attributes.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file-attributes.h	(original)
+++ trunk/libnautilus-private/nautilus-file-attributes.h	Thu Jan 17 13:45:27 2008
@@ -40,6 +40,7 @@
 	NAUTILUS_FILE_ATTRIBUTE_LARGE_TOP_LEFT_TEXT = 1 << 7,
 	NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 8,
 	NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL = 1 << 9,
+	NAUTILUS_FILE_ATTRIBUTE_MOUNT = 1 << 10,
 } NautilusFileAttributes;
 
 #endif /* NAUTILUS_FILE_ATTRIBUTES_H */

Modified: trunk/libnautilus-private/nautilus-file-private.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file-private.h	(original)
+++ trunk/libnautilus-private/nautilus-file-private.h	Thu Jan 17 13:45:27 2008
@@ -137,6 +137,9 @@
 	GHashTable *extension_attributes;
 	GHashTable *pending_extension_attributes;
 
+	/* Mount for mountpoint or the references GMount for a "mountable" */
+	GMount *mount;
+	
 	/* boolean fields: bitfield to save space, since there can be
            many NautilusFile objects. */
 
@@ -166,6 +169,8 @@
 	eel_boolean_bit mime_list_failed              : 1;
 	eel_boolean_bit mime_list_is_up_to_date       : 1;
 
+	eel_boolean_bit mount_is_up_to_date           : 1;
+	
 	eel_boolean_bit got_top_left_text             : 1;
 	eel_boolean_bit got_large_top_left_text       : 1;
 	eel_boolean_bit top_left_text_is_up_to_date   : 1;

Modified: trunk/libnautilus-private/nautilus-file.c
==============================================================================
--- trunk/libnautilus-private/nautilus-file.c	(original)
+++ trunk/libnautilus-private/nautilus-file.c	Thu Jan 17 13:45:27 2008
@@ -5606,6 +5606,14 @@
 	return file->details->is_mountpoint;
 }
 
+GMount *
+nautilus_file_get_mount (NautilusFile *file)
+{
+	if (file->details->mount) {
+		return g_object_ref (file->details->mount);
+	}
+	return NULL;
+}
 
 /**
  * nautilus_file_is_broken_symbolic_link

Modified: trunk/libnautilus-private/nautilus-file.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file.h	(original)
+++ trunk/libnautilus-private/nautilus-file.h	Thu Jan 17 13:45:27 2008
@@ -171,6 +171,7 @@
 gboolean                nautilus_file_is_launchable                     (NautilusFile                   *file);
 gboolean                nautilus_file_is_symbolic_link                  (NautilusFile                   *file);
 gboolean                nautilus_file_is_mountpoint                     (NautilusFile                   *file);
+GMount *                nautilus_file_get_mount                         (NautilusFile                   *file);
 char *                  nautilus_file_get_volume_free_space             (NautilusFile                   *file);
 char *                  nautilus_file_get_volume_name                   (NautilusFile                   *file);
 char *                  nautilus_file_get_symbolic_link_target_path     (NautilusFile                   *file);

Modified: trunk/libnautilus-private/nautilus-global-preferences.c
==============================================================================
--- trunk/libnautilus-private/nautilus-global-preferences.c	(original)
+++ trunk/libnautilus-private/nautilus-global-preferences.c	Thu Jan 17 13:45:27 2008
@@ -492,6 +492,10 @@
 	  PREFERENCE_BOOLEAN,
 	  GINT_TO_POINTER (TRUE)
 	},
+	{ NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER,
+	  PREFERENCE_BOOLEAN,
+	  GINT_TO_POINTER (FALSE)
+	},
 	{ NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_ASK,
 	  PREFERENCE_STRING_ARRAY,
 	  "", NULL, NULL, NULL
@@ -500,6 +504,10 @@
 	  PREFERENCE_STRING_ARRAY,
 	  "", NULL, NULL, NULL
 	},	
+	{ NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_OPEN_FOLDER,
+	  PREFERENCE_STRING_ARRAY,
+	  "", NULL, NULL, NULL
+	},	
 	{ NULL }
 };
 

Modified: trunk/libnautilus-private/nautilus-global-preferences.h
==============================================================================
--- trunk/libnautilus-private/nautilus-global-preferences.h	(original)
+++ trunk/libnautilus-private/nautilus-global-preferences.h	Thu Jan 17 13:45:27 2008
@@ -51,8 +51,10 @@
 #define NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT_OPEN		"preferences/media_automount_open"
 
 /* Autorun options */
+#define NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER                "preferences/media_autorun_never"
 #define NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_ASK        "preferences/media_autorun_x_content_ask"
 #define NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_IGNORE     "preferences/media_autorun_x_content_ignore"
+#define NAUTILUS_PREFERENCES_MEDIA_AUTORUN_X_CONTENT_OPEN_FOLDER "preferences/media_autorun_x_content_open_folder"
 
 /* Trash options */
 #define NAUTILUS_PREFERENCES_CONFIRM_TRASH			"preferences/confirm_trash"

Modified: trunk/libnautilus-private/nautilus-program-choosing.c
==============================================================================
--- trunk/libnautilus-private/nautilus-program-choosing.c	(original)
+++ trunk/libnautilus-private/nautilus-program-choosing.c	Thu Jan 17 13:45:27 2008
@@ -49,6 +49,8 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 
+#include "nautilus-desktop-icon-file.h"
+
 extern char **environ;
 
 /* Cut and paste from gdkspawn-x11.c */
@@ -261,10 +263,30 @@
 		
 		location = NULL;
 
-		if (nautilus_file_is_nautilus_link (file)) {
-			uri = nautilus_file_get_activation_uri (file);
-			location = g_file_new_for_uri (uri);
-			g_free (uri);
+		if (g_type_is_a (G_OBJECT_TYPE (file), NAUTILUS_TYPE_DESKTOP_ICON_FILE)) {
+			NautilusDesktopIconFile *desktop_icon_file = NAUTILUS_DESKTOP_ICON_FILE (file);
+			NautilusDesktopLink *desktop_link;
+		
+			desktop_link = nautilus_desktop_icon_file_get_link (desktop_icon_file);
+			if (desktop_link != NULL) {
+				if (nautilus_desktop_link_get_link_type (desktop_link) == NAUTILUS_DESKTOP_LINK_MOUNT) {
+					GMount *mount;
+					mount = nautilus_desktop_link_get_mount (desktop_link);
+					if (mount != NULL) {
+						location = g_mount_get_root (mount);
+						g_object_unref (mount);
+					}
+				}
+				g_object_unref (desktop_link);
+			}		
+		}
+		
+		if (location == NULL) {
+			if (nautilus_file_is_nautilus_link (file)) {
+				uri = nautilus_file_get_activation_uri (file);
+				location = g_file_new_for_uri (uri);
+				g_free (uri);
+			}
 		}
 		
 		if (location == NULL) {

Added: trunk/nautilus-autorun-software.desktop.in.in
==============================================================================
--- (empty file)
+++ trunk/nautilus-autorun-software.desktop.in.in	Thu Jan 17 13:45:27 2008
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Encoding=UTF-8
+_Name=Autorun Prompt
+TryExec=nautilus-autorun-software
+Exec=nautilus-autorun-software %u
+Icon=application-x-executable
+NoDisplay=true
+Terminal=false
+StartupNotify=true
+Type=Application
+MimeType=x-content/software;
+X-GNOME-Bugzilla-Bugzilla=GNOME
+X-GNOME-Bugzilla-Product=nautilus
+X-GNOME-Bugzilla-Component=general
+X-GNOME-Bugzilla-Version= VERSION@

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Thu Jan 17 13:45:27 2008
@@ -5,6 +5,7 @@
 bin_PROGRAMS=					\
 	nautilus				\
 	nautilus-file-management-properties	\
+	nautilus-autorun-software		\
 	$(NULL)
 
 #	nautilus-connect-server			
@@ -130,6 +131,8 @@
 	nautilus-window-toolbars.c              \
 	nautilus-window.c			\
 	nautilus-window.h			\
+	nautilus-x-content-bar.c		\
+	nautilus-x-content-bar.h		\
 	nautilus-zoom-control.c			\
 	nautilus-zoom-control.h			\
 	$(NULL)
@@ -140,6 +143,10 @@
 	nautilus-file-management-properties-main.c	\
 	$(NULL)
 
+nautilus_autorun_software_SOURCES= 			\
+	nautilus-autorun-software.c			\
+	$(NULL)
+
 # Disabled for now in the gio world
 #nautilus_connect_server_SOURCES= \
 #	nautilus-connect-server-dialog.c	\

Modified: trunk/src/file-manager/fm-directory-view.c
==============================================================================
--- trunk/src/file-manager/fm-directory-view.c	(original)
+++ trunk/src/file-manager/fm-directory-view.c	Thu Jan 17 13:45:27 2008
@@ -95,6 +95,7 @@
 #include <libnautilus-private/nautilus-trash-monitor.h>
 #include <libnautilus-private/nautilus-ui-utilities.h>
 #include <libnautilus-private/nautilus-signaller.h>
+#include <libnautilus-private/nautilus-autorun.h>
 #include <unistd.h>
 
 /* Minimum starting update inverval */
@@ -4158,6 +4159,27 @@
 	g_free (tip);
 }
 
+static void
+add_x_content_apps (NautilusFile *file, GList **applications)
+{
+	char **x_content_types;
+
+	g_return_if_fail (applications != NULL);
+
+	x_content_types = nautilus_autorun_get_x_content_types_for_file (file, NULL, FALSE, FALSE);
+		
+	if (x_content_types != NULL) {
+		unsigned int n;
+		for (n = 0; x_content_types[n] != NULL; n++) {
+			char *x_content_type = x_content_types[n];
+			GList *app_info_for_x_content_type;
+			
+			app_info_for_x_content_type = g_app_info_get_all_for_type (x_content_type);
+			*applications = g_list_concat (*applications, app_info_for_x_content_type);
+		}
+		g_strfreev (x_content_types);
+	}
+}
 
 static void
 reset_open_with_menu (FMDirectoryView *view, GList *selection)
@@ -4191,6 +4213,7 @@
 	filter_default = (selection != NULL);
 
 	for (node = selection; node != NULL; node = node->next) {
+
 		file = NAUTILUS_FILE (node->data);
 
 		other_applications_visible &=
@@ -4208,6 +4231,11 @@
 		applications = nautilus_mime_get_applications_for_files (selection);
 	}
 
+	if (g_list_length (selection) == 1) {
+		add_x_content_apps (NAUTILUS_FILE (selection->data), &applications);
+	}
+
+
 	num_applications = g_list_length (applications);
 	
 	for (node = applications, index = 0; node != NULL; node = node->next, index++) {

Modified: trunk/src/nautilus-application.c
==============================================================================
--- trunk/src/nautilus-application.c	(original)
+++ trunk/src/nautilus-application.c	Thu Jan 17 13:45:27 2008
@@ -118,6 +118,11 @@
 static void     volume_added_callback              (GVolumeMonitor           *monitor,
 						    GVolume                  *volume,
 						    NautilusApplication      *application);
+static void     drive_connected_callback           (GVolumeMonitor           *monitor,
+						    GDrive                   *drive,
+						    NautilusApplication      *application);
+static void     drive_listen_for_eject_button      (GDrive *drive, 
+						    NautilusApplication *application);
 static void     update_session                    (gpointer                  callback_data);
 static void     init_session                      (void);
 static gboolean is_kdesktop_present               (void);
@@ -165,6 +170,55 @@
 }
 
 static void
+startup_volume_mount_cb (GObject *source_object,
+			 GAsyncResult *res,
+			 gpointer user_data)
+{
+	if (!g_volume_mount_finish (G_VOLUME (source_object), res, NULL)) {
+		/* There was an error mounting the volume, so we
+		   clear the automount part. This is otherwise done
+		   when the mount is added to the volume monitor */
+		g_object_set_data (source_object, "nautilus-automounted", GINT_TO_POINTER (0));
+	}
+}
+
+static void
+automount_all_volumes (NautilusApplication *application)
+{
+	GList *volumes, *l;
+	GMount *mount;
+	GVolume *volume;
+		
+	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT)) {
+		/* automount all mountable volumes at start-up */
+		volumes = g_volume_monitor_get_volumes (application->volume_monitor);
+		for (l = volumes; l != NULL; l = l->next) {
+			volume = l->data;
+			
+			/* TODO: only do this for local volumes */
+			
+			if (!g_volume_can_mount (volume)) {
+				continue;
+			}
+			
+			mount = g_volume_get_mount (volume);
+			if (mount != NULL) {
+				g_object_unref (mount);
+				continue;
+			}
+			
+			/* Set this so we don't autorun stuff from it */
+			g_object_set_data (G_OBJECT (volume), "nautilus-automounted", GINT_TO_POINTER (1));
+
+			/* pass NULL as GMountOperation to avoid user interaction */
+			g_volume_mount (volume, NULL, NULL, startup_volume_mount_cb, NULL);
+		}
+		eel_g_object_list_free (volumes);
+	}
+	
+}
+
+static void
 nautilus_application_instance_init (NautilusApplication *application)
 {
 	/* Create an undo manager */
@@ -172,22 +226,6 @@
 
 	application->shell = nautilus_shell_new (application);
 	
-	/* Watch for mounts so we can restore open windows This used
-	 * to be for showing new window on mount, but is not used
-	 * anymore */
-
-	/* Watch for unmounts so we can close open windows */
-	/* TODO-gio: This should be using the UNMOUNTED feature of GFileMonitor instead */
-	application->volume_monitor = g_volume_monitor_get ();
-	g_signal_connect_object (application->volume_monitor, "mount_removed",
-				 G_CALLBACK (mount_removed_callback), application, 0);
-	g_signal_connect_object (application->volume_monitor, "mount_pre_unmount",
-				 G_CALLBACK (mount_removed_callback), application, 0);
-	g_signal_connect_object (application->volume_monitor, "mount_added",
-				 G_CALLBACK (mount_added_callback), application, 0);
-	g_signal_connect_object (application->volume_monitor, "volume_added",
-				 G_CALLBACK (volume_added_callback), application, 0);
-
 	/* register views */
 	fm_icon_view_register ();
 	fm_desktop_icon_view_register ();
@@ -343,49 +381,6 @@
 }
 
 static void
-migrate_old_nautilus_files (void)
-{
-	char *new_desktop_dir;
-	char *old_desktop_dir;
-	char *migrated_file;
-	char *link_name;
-	char *link_path;
-	int fd;
-	
-	old_desktop_dir = nautilus_get_gmc_desktop_directory ();
-	if (!g_file_test (old_desktop_dir, G_FILE_TEST_IS_DIR) ||
-	    g_file_test (old_desktop_dir, G_FILE_TEST_IS_SYMLINK)) {
-		g_free (old_desktop_dir);
-		return;
-	}
-	migrated_file = g_build_filename (old_desktop_dir, ".migrated", NULL);
-	if (!g_file_test (migrated_file, G_FILE_TEST_EXISTS)) {
-		link_name = g_filename_from_utf8 (_("Link To Old Desktop"), -1, NULL, NULL, NULL);
-		new_desktop_dir = nautilus_get_desktop_directory ();
-		link_path = g_build_filename (new_desktop_dir, link_name, NULL);
-	
-		
-		symlink ("../.gnome-desktop", link_path);
-		
-		g_free (link_name);
-		g_free (new_desktop_dir);
-		g_free (link_path);
-
-		fd = creat (migrated_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-		if (fd >= 0) {
-			close (fd);
-		}
-		
-		eel_show_info_dialog (_("A link called \"Link To Old Desktop\" has been created on the desktop."),
-				      _("The location of the desktop directory has changed in GNOME 2.4. "
-					"You can open the link and move over the files you want, then delete the link."),
-				      NULL);
-	}
-	g_free (old_desktop_dir);
-	g_free (migrated_file);
-}
-
-static void
 menu_provider_items_updated_handler (NautilusMenuProvider *provider, GtkWidget* parent_window, gpointer data)
 {
 
@@ -417,6 +412,8 @@
 static void
 finish_startup (NautilusApplication *application)
 {
+	GList *drives;
+
 	/* initialize nautilus modules */
 	nautilus_module_init ();
 
@@ -425,14 +422,34 @@
 	/* attach menu-provider module callback */
 	menu_provider_init_callback ();
 	
-	/* initialize URI authentication manager */
-	gnome_authentication_manager_init ();
-
-	/* Make the desktop work with old Nautilus. */
-	migrate_old_nautilus_files ();
-
 	/* Initialize the desktop link monitor singleton */
 	nautilus_desktop_link_monitor_get ();
+
+	/* Watch for mounts so we can restore open windows This used
+	 * to be for showing new window on mount, but is not used
+	 * anymore */
+
+	/* Watch for unmounts so we can close open windows */
+	/* TODO-gio: This should be using the UNMOUNTED feature of GFileMonitor instead */
+	application->volume_monitor = g_volume_monitor_get ();
+	g_signal_connect_object (application->volume_monitor, "mount_removed",
+				 G_CALLBACK (mount_removed_callback), application, 0);
+	g_signal_connect_object (application->volume_monitor, "mount_pre_unmount",
+				 G_CALLBACK (mount_removed_callback), application, 0);
+	g_signal_connect_object (application->volume_monitor, "mount_added",
+				 G_CALLBACK (mount_added_callback), application, 0);
+	g_signal_connect_object (application->volume_monitor, "volume_added",
+				 G_CALLBACK (volume_added_callback), application, 0);
+	g_signal_connect_object (application->volume_monitor, "drive_connected",
+				 G_CALLBACK (drive_connected_callback), application, 0);
+
+	/* listen for eject button presses */
+	drives = g_volume_monitor_get_connected_drives (application->volume_monitor);
+	g_list_foreach (drives, (GFunc) drive_listen_for_eject_button, application);
+	g_list_foreach (drives, (GFunc) g_object_unref, NULL);
+	g_list_free (drives);
+
+	automount_all_volumes (application);
 }
 
 static void
@@ -1315,18 +1332,94 @@
 		       GVolume *volume,
 		       NautilusApplication *application)
 {
-	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT)) {
+	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT) &&
+	    g_volume_can_mount (volume)) {
 		nautilus_file_operations_mount_volume (NULL, volume);
 	}
 }
 
 static void
+drive_eject_cb (GObject *source_object,
+		GAsyncResult *res,
+		gpointer user_data)
+{
+	GError *error;
+	char *primary;
+	char *name;
+	error = NULL;
+	if (!g_drive_eject_finish (G_DRIVE (source_object), res, &error)) {
+		if (error->code != G_IO_ERROR_FAILED_HANDLED) {
+			name = g_drive_get_name (G_DRIVE (source_object));
+			primary = g_strdup_printf (_("Unable to eject %s"), name);
+			g_free (name);
+			eel_show_error_dialog (primary,
+					       error->message,
+				       NULL);
+			g_free (primary);
+		}
+		g_error_free (error);
+	}
+}
+
+static void
+drive_eject_button_pressed (GDrive *drive,
+			    NautilusApplication *application)
+{
+	g_drive_eject (drive, 0, NULL, drive_eject_cb, NULL);
+}
+
+static void
+drive_listen_for_eject_button (GDrive *drive, NautilusApplication *application)
+{
+	g_signal_connect (drive,
+			  "eject-button",
+			  G_CALLBACK (drive_eject_button_pressed),
+			  application);
+}
+
+static void
+drive_connected_callback (GVolumeMonitor *monitor,
+			  GDrive *drive,
+			  NautilusApplication *application)
+{
+	drive_listen_for_eject_button (drive, application);
+}
+
+static void
+autorun_show_window (GMount *mount, gpointer user_data)
+{
+	GFile *location;
+	NautilusApplication *application = user_data;
+	
+	location = g_mount_get_root (mount);
+	
+	/* Ther should probably be an easier way to do this */
+	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
+		NautilusWindow *window;
+		window = nautilus_application_create_navigation_window (application, 
+									NULL, 
+									gdk_screen_get_default ());
+		nautilus_window_go_to (window, location);
+
+	} else {
+		nautilus_application_present_spatial_window (application, 
+							     NULL, 
+							     NULL, 
+							     location, 
+							     gdk_screen_get_default ());
+	}
+	g_object_unref (location);
+}
+
+static void
 mount_added_callback (GVolumeMonitor *monitor,
 		      GMount *mount,
 		      NautilusApplication *application)
 {
 	NautilusDirectory *directory;
 	GFile *root;
+	GVolume *enclosing_volume;
+	gboolean ignore_autorun;
 		
 	root = g_mount_get_root (mount);
 	directory = nautilus_directory_get_existing (root);
@@ -1336,7 +1429,21 @@
 		nautilus_directory_unref (directory);
 	}
 
-	nautilus_autorun (mount);
+	ignore_autorun = FALSE;
+
+	enclosing_volume = g_mount_get_volume (mount);
+	if (enclosing_volume != NULL) {
+		if (g_object_get_data (G_OBJECT (enclosing_volume), "nautilus-automounted") != NULL) {
+			ignore_autorun = TRUE;
+			/* Autorun if the user unmounts and then mounts */
+			g_object_set_data (G_OBJECT (enclosing_volume), "nautilus-automounted", NULL);
+		}
+		g_object_unref (enclosing_volume);
+	}
+
+	if (!ignore_autorun) {
+		nautilus_autorun (mount, autorun_show_window, application);
+	}
 }
 
 /* Called whenever a mount is unmounted. Check and see if there are

Added: trunk/src/nautilus-autorun-software.c
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-autorun-software.c	Thu Jan 17 13:45:27 2008
@@ -0,0 +1,254 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* Nautilus
+
+   Copyright (C) 2008 Red Hat, Inc.
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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 Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: David Zeuthen <davidz redhat com>
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#include <glib/gi18n.h>
+
+#include <libgnome/gnome-program.h>
+#include <libgnomeui/gnome-ui-init.h>
+#include <libnautilus-private/nautilus-module.h>
+#include <libnautilus-private/nautilus-icon-info.h>
+
+typedef struct
+{
+	GtkWidget *dialog;
+	GMount *mount;
+} AutorunSoftwareDialogData;
+
+static void autorun_software_dialog_mount_unmounted (GMount *mount, AutorunSoftwareDialogData *data);
+
+static void
+autorun_software_dialog_destroy (AutorunSoftwareDialogData *data)
+{
+	g_signal_handlers_disconnect_by_func (G_OBJECT (data->mount),
+					      G_CALLBACK (autorun_software_dialog_mount_unmounted),
+					      data);
+
+	gtk_widget_destroy (GTK_WIDGET (data->dialog));
+	g_object_unref (data->mount);
+	g_free (data);
+}
+
+static void 
+autorun_software_dialog_mount_unmounted (GMount *mount, AutorunSoftwareDialogData *data)
+{
+	autorun_software_dialog_destroy (data);
+}
+
+static gboolean
+_check_file (GFile *mount_root, const char *file_path, gboolean must_be_executable)
+{
+	GFile *file;
+	GFileInfo *file_info;
+	gboolean ret;
+
+	ret = FALSE;
+
+	file = g_file_get_child (mount_root, file_path);
+	file_info = g_file_query_info (file,
+				       G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
+				       G_FILE_QUERY_INFO_NONE,
+				       NULL,
+				       NULL);
+	if (file_info != NULL) {
+		if (must_be_executable) {
+			if (g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE))
+				ret = TRUE;
+		} else {
+			ret = TRUE;
+		}
+		g_object_unref (file_info);
+	}
+	g_object_unref (file);
+
+	return ret;
+}
+
+static void
+autorun (GMount *mount)
+{
+        GFile *root;
+        GFile *program_to_spawn;
+        char *path_to_spawn;
+        char *cwd_for_program;
+
+        root = g_mount_get_root (mount);
+
+        /* Careful here, according to 
+         *
+         *  http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+         *
+         * the ordering does matter.
+         */
+
+        program_to_spawn = NULL;
+        path_to_spawn = NULL;
+
+	if (_check_file (root, ".autorun", TRUE)) {
+                program_to_spawn = g_file_get_child (root, ".autorun");
+        } else if (_check_file (root, "autorun", TRUE)) {
+                program_to_spawn = g_file_get_child (root, "autorun");
+        } else if (_check_file (root, "autorun.sh", TRUE)) {
+                program_to_spawn = g_file_get_child (root, "autorun.sh");
+        } else if (_check_file (root, "autorun.exe", TRUE)) {
+		/* TODO */
+        } else if (_check_file (root, "AUTORUN.EXE", TRUE)) {
+		/* TODO */
+        } else if (_check_file (root, "autorun.inf", FALSE)) {
+                /* TODO */
+        } else if (_check_file (root, "AUTORUN.INF", FALSE)) {
+                /* TODO */
+        }
+
+        if (program_to_spawn != NULL)
+                path_to_spawn = g_file_get_path (program_to_spawn);
+
+        cwd_for_program = g_file_get_path (root);
+
+        if (path_to_spawn != NULL && cwd_for_program != NULL) {
+                if (chdir (cwd_for_program) == 0)  {
+                        execl (path_to_spawn, path_to_spawn, NULL);
+                        g_warning ("Error execing program: %m");
+                }
+                g_warning ("Error chdir to '%s': %m", cwd_for_program);
+        }
+        g_warning ("Cannot find path for program to spawn");
+
+        if (program_to_spawn != NULL)
+                g_object_unref (program_to_spawn);
+        g_free (path_to_spawn);
+        g_free (cwd_for_program);
+}
+
+static void
+present_autorun_for_software_dialog (GMount *mount)
+{
+	GIcon *icon;
+	int icon_size;
+	NautilusIconInfo *icon_info;
+	GdkPixbuf *pixbuf;
+	GtkWidget *image;
+	char *mount_name;
+	GtkWidget *dialog;
+	AutorunSoftwareDialogData *data;
+
+	mount_name = g_mount_get_name (mount);
+
+	dialog = gtk_message_dialog_new_with_markup (NULL, /* TODO: parent window? */
+						     0,
+						     GTK_MESSAGE_OTHER,
+						     GTK_BUTTONS_CANCEL,
+						     _("<big><b>This media contains software intended to be automatically started. Would you like to run it?</b></big>"));
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+						  _("The software will run directly from the media \"%s\". "
+						    "You should never run software that you don't trust.\n"
+						    "\n"
+						    "If in doubt, press Cancel."),
+                                                  mount_name);
+
+	/* TODO: in a star trek future add support for verifying
+	 * software on media (e.g. if it has a certificate, check it
+	 * etc.)
+	 */
+
+
+	icon = g_mount_get_icon (mount);
+	icon_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_DIALOG);
+	icon_info = nautilus_icon_info_lookup (icon, icon_size);
+	pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
+	image = gtk_image_new_from_pixbuf (pixbuf);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+
+	gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
+
+	gtk_window_set_title (GTK_WINDOW (dialog), mount_name);
+	gtk_window_set_icon (GTK_WINDOW (dialog), pixbuf);
+
+	data = g_new0 (AutorunSoftwareDialogData, 1);
+	data->dialog = dialog;
+	data->mount = g_object_ref (mount);
+
+	g_signal_connect (G_OBJECT (mount),
+			  "unmounted",
+			  G_CALLBACK (autorun_software_dialog_mount_unmounted),
+			  data);
+
+	gtk_dialog_add_button (GTK_DIALOG (dialog),
+			       _("_Run"),
+			       GTK_RESPONSE_OK);
+
+        gtk_widget_show_all (dialog);
+
+        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+                autorun (mount);
+        }
+
+	g_object_unref (icon_info);
+	g_object_unref (pixbuf);
+	g_free (mount_name);
+}
+
+int
+main (int argc, char *argv[])
+{
+        GVolumeMonitor *monitor;
+        GFile *file;
+        GMount *mount;
+
+	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	gnome_program_init ("nautilus-autorun-software", VERSION,
+			    LIBGNOMEUI_MODULE, argc, argv,
+			    NULL, NULL);
+
+        if (argc != 2)
+                goto out;
+
+        /* instantiate monitor so we get the "unmounted" signal properly */
+        monitor = g_volume_monitor_get ();
+        if (monitor == NULL)
+                goto out;
+
+        file = g_file_new_for_commandline_arg (argv[1]);
+        if (file == NULL)
+                goto out;
+
+        mount = g_file_find_enclosing_mount (file, NULL, NULL);
+        if (mount == NULL)
+                goto out;
+
+        present_autorun_for_software_dialog (mount);
+
+out:	
+	return 0;
+}

Modified: trunk/src/nautilus-file-management-properties.c
==============================================================================
--- trunk/src/nautilus-file-management-properties.c	(original)
+++ trunk/src/nautilus-file-management-properties.c	Thu Jan 17 13:45:27 2008
@@ -28,13 +28,8 @@
 
 #include <string.h>
 #include <time.h>
-#include <gtk/gtkdialog.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkmenuitem.h>
-#include <gtk/gtkmessagedialog.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtkcombobox.h>
-#include <gtk/gtksizegroup.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
 
 #include <libgnome/gnome-help.h>
 #include <glib/gi18n.h>
@@ -74,8 +69,8 @@
 #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_OPEN_NEW_WINDOW_WIDGET "new_window_checkbutton"
 #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_SHOW_HIDDEN_WIDGET "hidden_files_checkbutton"
 #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_TREE_VIEW_FOLDERS_WIDGET "treeview_folders_checkbutton"
-#define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_MEDIA_AUTOMOUNT "media_automount_checkbutton"
 #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_MEDIA_AUTOMOUNT_OPEN "media_automount_open_checkbutton"
+#define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_MEDIA_AUTORUN_NEVER "media_autorun_never_checkbutton"
 
 /* int enums */
 #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_THUMBNAIL_LIMIT_WIDGET "preview_image_size_combobox"
@@ -515,24 +510,145 @@
 	gtk_box_pack_start (GTK_BOX (box), chooser, TRUE, TRUE, 0);
 }
 
+static void
+nautilus_file_management_properties_dialog_update_media_sensitivity (GladeXML *xml_dialog)
+{
+	gtk_widget_set_sensitive (glade_xml_get_widget (xml_dialog, "media_handling_vbox"), 
+				  ! eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER));
+}
+
+static void 
+other_type_combo_box_changed (GtkComboBox *combo_box, GtkComboBox *action_combo_box)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	char *x_content_type;
+
+	x_content_type = NULL;
+
+	if (!gtk_combo_box_get_active_iter (combo_box, &iter)) {
+		goto out;
+	}
+
+	model = gtk_combo_box_get_model (combo_box);
+	if (model == NULL) {
+		goto out;
+	}
+
+	gtk_tree_model_get (model, &iter, 
+			    2, &x_content_type,
+			    -1);
+
+	nautilus_autorun_prepare_combo_box (GTK_WIDGET (action_combo_box),
+					    x_content_type,
+					    TRUE,
+					    TRUE,
+					    NULL, NULL);
+out:
+	g_free (x_content_type);
+}
+
 
 static void
 nautilus_file_management_properties_dialog_setup_media_page (GladeXML *xml_dialog)
 {
 	unsigned int n;
+	GList *l;
+	GList *content_types;
+	GtkWidget *other_type_combo_box;
+	GtkListStore *other_type_list_store;
+	GtkCellRenderer *renderer;
+	GtkTreeIter iter;
 	const char *s[] = {"media_audio_cdda_combobox",   "x-content/audio-cdda",
 			   "media_video_dvd_combobox",    "x-content/video-dvd",
-			   "media_video_vcd_combobox",    "x-content/video-vcd",
-			   "media_video_svcd_combobox",   "x-content/video-svcd",
-			   "media_blank_combobox",        "x-content/blank-media",
-			   "media_music_player_combobox", "x-content/music-player",
+			   "media_music_player_combobox", "x-content/audio-player",
 			   "media_dcf_combobox",          "x-content/image-dcf",
+			   "media_software_combobox",     "x-content/software",
 			   NULL};
 
 	for (n = 0; s[n*2] != NULL; n++) {
 		nautilus_autorun_prepare_combo_box (glade_xml_get_widget (xml_dialog, s[n*2]), s[n*2 + 1],
 						    TRUE, TRUE, NULL, NULL); 
 	}
+
+	other_type_combo_box = glade_xml_get_widget (xml_dialog, "media_other_type_combobox");
+
+	other_type_list_store = gtk_list_store_new (3, 
+						    GDK_TYPE_PIXBUF, 
+						    G_TYPE_STRING, 
+						    G_TYPE_STRING);
+
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (other_type_list_store),
+					      1, GTK_SORT_ASCENDING);
+
+
+	content_types = g_content_types_get_registered ();
+
+	for (l = content_types; l != NULL; l = l->next) {
+		char *content_type = l->data;
+		char *description;
+		GIcon *icon;
+		NautilusIconInfo *icon_info;
+		GdkPixbuf *pixbuf;
+		int icon_size;
+
+		if (!g_str_has_prefix (content_type, "x-content/"))
+			continue;
+		for (n = 0; s[n*2] != NULL; n++) {
+			if (strcmp (content_type, s[n*2 + 1]) == 0) {
+				goto skip;
+			}
+		}
+
+		icon_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
+
+		description = g_content_type_get_description (content_type);
+		gtk_list_store_append (other_type_list_store, &iter);
+		icon = g_content_type_get_icon (content_type);
+		if (icon != NULL) {
+			icon_info = nautilus_icon_info_lookup (icon, icon_size);
+			g_object_unref (icon);
+			pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
+			g_object_unref (icon_info);
+		} else {
+			pixbuf = NULL;
+		}
+
+		gtk_list_store_set (other_type_list_store, &iter, 
+				    0, pixbuf, 
+				    1, description, 
+				    2, content_type, 
+				    -1);
+		if (pixbuf != NULL)
+			g_object_unref (pixbuf);
+		g_free (description);
+	skip:
+		;
+	}
+	g_list_foreach (content_types, (GFunc) g_free, NULL);
+	g_list_free (content_types);
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX (other_type_combo_box), GTK_TREE_MODEL (other_type_list_store));
+	
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (other_type_combo_box), renderer, FALSE);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (other_type_combo_box), renderer,
+					"pixbuf", 0,
+					NULL);
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (other_type_combo_box), renderer, TRUE);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (other_type_combo_box), renderer,
+					"text", 1,
+					NULL);
+
+	g_signal_connect (G_OBJECT (other_type_combo_box),
+			  "changed",
+			  G_CALLBACK (other_type_combo_box_changed),
+			  glade_xml_get_widget (xml_dialog, "media_other_action_combobox"));
+
+	gtk_combo_box_set_active (GTK_COMBO_BOX (other_type_combo_box), 0);
+
+	nautilus_file_management_properties_dialog_update_media_sensitivity (xml_dialog);
 }
 
 static  void
@@ -577,11 +693,11 @@
 					    NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER);
 
 	eel_preferences_glade_connect_bool (xml_dialog,
-					    NAUTILUS_FILE_MANAGEMENT_PROPERTIES_MEDIA_AUTOMOUNT,
-					    NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT);
-	eel_preferences_glade_connect_bool (xml_dialog,
 					    NAUTILUS_FILE_MANAGEMENT_PROPERTIES_MEDIA_AUTOMOUNT_OPEN,
 					    NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT_OPEN);
+	eel_preferences_glade_connect_bool (xml_dialog,
+					    NAUTILUS_FILE_MANAGEMENT_PROPERTIES_MEDIA_AUTORUN_NEVER,
+					    NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER);
 
 	eel_preferences_glade_connect_bool (xml_dialog,
 					    NAUTILUS_FILE_MANAGEMENT_PROPERTIES_TRASH_CONFIRM_WIDGET,
@@ -656,8 +772,12 @@
 
 	nautilus_file_management_properties_dialog_setup_icon_caption_page (xml_dialog);
 	nautilus_file_management_properties_dialog_setup_list_column_page (xml_dialog);
-
 	nautilus_file_management_properties_dialog_setup_media_page (xml_dialog);
+
+	eel_preferences_add_callback (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER,
+				      (EelPreferencesCallback ) nautilus_file_management_properties_dialog_update_media_sensitivity,
+				      g_object_ref (xml_dialog));
+
 	
 	/* UI callbacks */
 	dialog = glade_xml_get_widget (xml_dialog, "file_management_dialog");

Modified: trunk/src/nautilus-file-management-properties.glade
==============================================================================
--- trunk/src/nautilus-file-management-properties.glade	(original)
+++ trunk/src/nautilus-file-management-properties.glade	Thu Jan 17 13:45:27 2008
@@ -2204,569 +2204,530 @@
 	      <property name="border_width">12</property>
 	      <property name="visible">True</property>
 	      <property name="homogeneous">False</property>
-	      <property name="spacing">18</property>
+	      <property name="spacing">6</property>
 
 	      <child>
-		<widget class="GtkVBox" id="vbox42">
+		<widget class="GtkVBox" id="media_handling_vbox">
 		  <property name="visible">True</property>
 		  <property name="homogeneous">False</property>
 		  <property name="spacing">6</property>
 
 		  <child>
-		    <widget class="GtkLabel" id="label41">
+		    <widget class="GtkVBox" id="vbox44">
 		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Automatic Mounting&lt;/span&gt;</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkAlignment" id="alignment19">
-		      <property name="visible">True</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xscale">1</property>
-		      <property name="yscale">1</property>
-		      <property name="top_padding">0</property>
-		      <property name="bottom_padding">0</property>
-		      <property name="left_padding">12</property>
-		      <property name="right_padding">0</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
 
 		      <child>
-			<widget class="GtkVBox" id="vbox46">
+			<widget class="GtkLabel" id="label42">
 			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkCheckButton" id="media_automount_checkbutton">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">Automatically _mount media</property>
-			      <property name="use_underline">True</property>
-			      <property name="relief">GTK_RELIEF_NORMAL</property>
-			      <property name="focus_on_click">True</property>
-			      <property name="active">False</property>
-			      <property name="inconsistent">False</property>
-			      <property name="draw_indicator">True</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkCheckButton" id="media_automount_open_checkbutton">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">Open _folder when automounted</property>
-			      <property name="use_underline">True</property>
-			      <property name="relief">GTK_RELIEF_NORMAL</property>
-			      <property name="focus_on_click">True</property>
-			      <property name="active">False</property>
-			      <property name="inconsistent">False</property>
-			      <property name="draw_indicator">True</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
+			  <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Media Handling&lt;/span&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
 			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
 		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkVBox" id="vbox44">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">6</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label42">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Autorun&lt;/span&gt;</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkAlignment" id="alignment18">
-		      <property name="visible">True</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xscale">1</property>
-		      <property name="yscale">1</property>
-		      <property name="top_padding">0</property>
-		      <property name="bottom_padding">0</property>
-		      <property name="left_padding">12</property>
-		      <property name="right_padding">0</property>
 
 		      <child>
-			<widget class="GtkVBox" id="vbox49">
+			<widget class="GtkAlignment" id="alignment18">
 			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label60">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Choose what happens when inserting media or connecting devices to the system</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">True</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">True</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xscale">1</property>
+			  <property name="yscale">1</property>
+			  <property name="top_padding">0</property>
+			  <property name="bottom_padding">0</property>
+			  <property name="left_padding">12</property>
+			  <property name="right_padding">0</property>
 
 			  <child>
-			    <widget class="GtkTable" id="table4">
+			    <widget class="GtkVBox" id="vbox52">
 			      <property name="visible">True</property>
-			      <property name="n_rows">7</property>
-			      <property name="n_columns">2</property>
 			      <property name="homogeneous">False</property>
-			      <property name="row_spacing">6</property>
-			      <property name="column_spacing">6</property>
+			      <property name="spacing">6</property>
 
 			      <child>
-				<widget class="GtkLabel" id="label44">
+				<widget class="GtkLabel" id="label60">
 				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">CD _Audio:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
+				  <property name="label" translatable="yes">Choose what happens when inserting media or connecting devices to the system</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">True</property>
 				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
+				  <property name="wrap">True</property>
 				  <property name="selectable">False</property>
 				  <property name="xalign">0</property>
 				  <property name="yalign">0.5</property>
 				  <property name="xpad">0</property>
 				  <property name="ypad">0</property>
-				  <property name="mnemonic_widget">media_audio_cdda_combobox</property>
 				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 				  <property name="width_chars">-1</property>
 				  <property name="single_line_mode">False</property>
 				  <property name="angle">0</property>
 				</widget>
 				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">0</property>
-				  <property name="bottom_attach">1</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
 				</packing>
 			      </child>
 
 			      <child>
-				<widget class="GtkLabel" id="label50">
+				<widget class="GtkTable" id="table4">
 				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">_DVD Video:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				  <property name="mnemonic_widget">media_video_dvd_combobox</property>
-				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				  <property name="width_chars">-1</property>
-				  <property name="single_line_mode">False</property>
-				  <property name="angle">0</property>
+				  <property name="n_rows">5</property>
+				  <property name="n_columns">2</property>
+				  <property name="homogeneous">False</property>
+				  <property name="row_spacing">6</property>
+				  <property name="column_spacing">6</property>
+
+				  <child>
+				    <widget class="GtkLabel" id="label44">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">CD _Audio:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_audio_cdda_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">0</property>
+				      <property name="bottom_attach">1</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label50">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">_DVD Video:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_video_dvd_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">1</property>
+				      <property name="bottom_attach">2</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_audio_cdda_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">0</property>
+				      <property name="bottom_attach">1</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_video_dvd_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">1</property>
+				      <property name="bottom_attach">2</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label54">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">_Music Player:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_music_player_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">2</property>
+				      <property name="bottom_attach">3</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_music_player_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">2</property>
+				      <property name="bottom_attach">3</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label59">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">_Photos:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_dcf_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">3</property>
+				      <property name="bottom_attach">4</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_dcf_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">3</property>
+				      <property name="bottom_attach">4</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label57">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">_Software:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_software_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">4</property>
+				      <property name="bottom_attach">5</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_software_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">4</property>
+				      <property name="bottom_attach">5</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
 				</widget>
 				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">1</property>
-				  <property name="bottom_attach">2</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
 				</packing>
 			      </child>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
 
-			      <child>
-				<widget class="GtkLabel" id="label51">
-				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">_Video CD:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				  <property name="mnemonic_widget">media_video_vcd_combobox</property>
-				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				  <property name="width_chars">-1</property>
-				  <property name="single_line_mode">False</property>
-				  <property name="angle">0</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">2</property>
-				  <property name="bottom_attach">3</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
-				</packing>
-			      </child>
+		  <child>
+		    <widget class="GtkVBox" id="vbox50">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
 
-			      <child>
-				<widget class="GtkLabel" id="label52">
-				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">_Super Video CD:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				  <property name="mnemonic_widget">media_video_svcd_combobox</property>
-				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				  <property name="width_chars">-1</property>
-				  <property name="single_line_mode">False</property>
-				  <property name="angle">0</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">3</property>
-				  <property name="bottom_attach">4</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
-				</packing>
-			      </child>
+		      <child>
+			<widget class="GtkLabel" id="label61">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Other Media&lt;/span&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
 
-			      <child>
-				<widget class="GtkLabel" id="label57">
-				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">_Blank Disc:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				  <property name="mnemonic_widget">media_blank_combobox</property>
-				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				  <property name="width_chars">-1</property>
-				  <property name="single_line_mode">False</property>
-				  <property name="angle">0</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">4</property>
-				  <property name="bottom_attach">5</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
-				</packing>
-			      </child>
+		      <child>
+			<widget class="GtkAlignment" id="alignment20">
+			  <property name="visible">True</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xscale">1</property>
+			  <property name="yscale">1</property>
+			  <property name="top_padding">0</property>
+			  <property name="bottom_padding">0</property>
+			  <property name="left_padding">12</property>
+			  <property name="right_padding">0</property>
 
-			      <child>
-				<widget class="GtkLabel" id="label54">
-				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">M_usic Player:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				  <property name="width_chars">-1</property>
-				  <property name="single_line_mode">False</property>
-				  <property name="angle">0</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">5</property>
-				  <property name="bottom_attach">6</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
-				</packing>
-			      </child>
+			  <child>
+			    <widget class="GtkVBox" id="vbox51">
+			      <property name="visible">True</property>
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">6</property>
 
 			      <child>
-				<widget class="GtkLabel" id="label59">
+				<widget class="GtkLabel" id="label65">
 				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">_Photo Flash Card:</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
+				  <property name="label" translatable="yes">Less common media formats can be configured here</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">True</property>
 				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
+				  <property name="wrap">True</property>
 				  <property name="selectable">False</property>
 				  <property name="xalign">0</property>
 				  <property name="yalign">0.5</property>
 				  <property name="xpad">0</property>
 				  <property name="ypad">0</property>
-				  <property name="mnemonic_widget">media_dcf_combobox</property>
 				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 				  <property name="width_chars">-1</property>
 				  <property name="single_line_mode">False</property>
 				  <property name="angle">0</property>
 				</widget>
 				<packing>
-				  <property name="left_attach">0</property>
-				  <property name="right_attach">1</property>
-				  <property name="top_attach">6</property>
-				  <property name="bottom_attach">7</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options"></property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_audio_cdda_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">0</property>
-				  <property name="bottom_attach">1</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_video_dvd_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">1</property>
-				  <property name="bottom_attach">2</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_video_vcd_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">2</property>
-				  <property name="bottom_attach">3</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_video_svcd_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">3</property>
-				  <property name="bottom_attach">4</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_blank_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">4</property>
-				  <property name="bottom_attach">5</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_music_player_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">5</property>
-				  <property name="bottom_attach">6</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkComboBox" id="media_dcf_combobox">
-				  <property name="visible">True</property>
-				  <property name="add_tearoffs">False</property>
-				  <property name="focus_on_click">True</property>
-				</widget>
-				<packing>
-				  <property name="left_attach">1</property>
-				  <property name="right_attach">2</property>
-				  <property name="top_attach">6</property>
-				  <property name="bottom_attach">7</property>
-				  <property name="x_options">fill</property>
-				  <property name="y_options">fill</property>
-				</packing>
-			      </child>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkHBox" id="hbox37">
-			      <property name="visible">True</property>
-			      <property name="homogeneous">False</property>
-			      <property name="spacing">0</property>
-
-			      <child>
-				<widget class="GtkImage" id="image1">
-				  <property name="visible">True</property>
-				  <property name="stock">gtk-dialog-info</property>
-				  <property name="icon_size">4</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">8</property>
-				  <property name="ypad">0</property>
-				</widget>
-				<packing>
 				  <property name="padding">0</property>
 				  <property name="expand">False</property>
-				  <property name="fill">True</property>
+				  <property name="fill">False</property>
 				</packing>
 			      </child>
 
 			      <child>
-				<widget class="GtkLabel" id="label58">
+				<widget class="GtkTable" id="table5">
 				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">&lt;i&gt;You can configure applications for other kinds of media and devices by holding down the Shift key while inserting the media or device.&lt;/i&gt;</property>
-				  <property name="use_underline">False</property>
-				  <property name="use_markup">True</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">True</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				  <property name="width_chars">-1</property>
-				  <property name="single_line_mode">False</property>
-				  <property name="angle">0</property>
+				  <property name="n_rows">2</property>
+				  <property name="n_columns">2</property>
+				  <property name="homogeneous">False</property>
+				  <property name="row_spacing">6</property>
+				  <property name="column_spacing">6</property>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_other_type_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">0</property>
+				      <property name="bottom_attach">1</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label64">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">Acti_on:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_other_action_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">1</property>
+				      <property name="bottom_attach">2</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkComboBox" id="media_other_action_combobox">
+				      <property name="visible">True</property>
+				      <property name="add_tearoffs">False</property>
+				      <property name="focus_on_click">True</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">1</property>
+				      <property name="right_attach">2</property>
+				      <property name="top_attach">1</property>
+				      <property name="bottom_attach">2</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options">fill</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label63">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">_Type:</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="mnemonic_widget">media_other_type_combobox</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="left_attach">0</property>
+				      <property name="right_attach">1</property>
+				      <property name="top_attach">0</property>
+				      <property name="bottom_attach">1</property>
+				      <property name="x_options">fill</property>
+				      <property name="y_options"></property>
+				    </packing>
+				  </child>
 				</widget>
 				<packing>
 				  <property name="padding">0</property>
-				  <property name="expand">False</property>
-				  <property name="fill">False</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
 				</packing>
 			      </child>
 			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
 			  </child>
 			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
 		      </child>
 		    </widget>
 		    <packing>
@@ -2778,8 +2739,46 @@
 		</widget>
 		<packing>
 		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkCheckButton" id="media_autorun_never_checkbutton">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">_Never prompt or start programs on media insertion</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkCheckButton" id="media_automount_open_checkbutton">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">B_rowse media when inserted</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
 		</packing>
 	      </child>
 	    </widget>

Modified: trunk/src/nautilus-window-manage-views.c
==============================================================================
--- trunk/src/nautilus-window-manage-views.c	(original)
+++ trunk/src/nautilus-window-manage-views.c	Thu Jan 17 13:45:27 2008
@@ -36,6 +36,7 @@
 #include "nautilus-main.h"
 #include "nautilus-window-private.h"
 #include "nautilus-trash-bar.h"
+#include "nautilus-x-content-bar.h"
 #include "nautilus-zoom-control.h"
 #include <eel/eel-accessibility.h>
 #include <eel/eel-debug.h>
@@ -63,6 +64,7 @@
 #include <libnautilus-private/nautilus-search-directory.h>
 #include <libnautilus-private/nautilus-view-factory.h>
 #include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-autorun.h>
 
 /* FIXME bugzilla.gnome.org 41243: 
  * We should use inheritance instead of these special cases
@@ -1291,6 +1293,32 @@
 }
 
 static void
+nautilus_window_show_x_content_bar (NautilusWindow *window, GMount *mount, char **x_content_types)
+{
+	unsigned int n;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	for (n = 0; x_content_types[n] != NULL; n++) {
+		GAppInfo *default_app;
+
+		/* skip blank media; the burn:/// location will provide it's own cluebar */
+		if (g_str_has_prefix (x_content_types[n], "x-content/blank-"))
+			continue;
+
+		/* only show the cluebar if a default app is available */
+		default_app = g_app_info_get_default_for_type (x_content_types[n], FALSE);
+		if (default_app != NULL)  {
+			GtkWidget *bar;
+			bar = nautilus_x_content_bar_new (mount, x_content_types[n]);
+			gtk_widget_show (bar);
+			nautilus_window_add_extra_location_widget (window, bar);
+			g_object_unref (default_app);
+		}
+	}
+}
+
+static void
 nautilus_window_show_trash_bar (NautilusWindow *window)
 {
 	GtkWidget *bar;
@@ -1312,6 +1340,8 @@
 	NautilusDirectory *directory;
 	gboolean location_really_changed;
 	char *uri;
+	char **x_content_types;
+	GMount *mount;
         
         new_location = window->details->pending_location;
         window->details->pending_location = NULL;
@@ -1370,6 +1400,13 @@
 			nautilus_window_show_trash_bar (window);
 		}
 
+		x_content_types = nautilus_autorun_get_x_content_types_for_file (file, &mount, FALSE, TRUE);
+		if (x_content_types != NULL) {
+			nautilus_window_show_x_content_bar (window, mount, x_content_types);
+			g_strfreev (x_content_types);
+			g_object_unref (mount);
+		}
+
 		nautilus_directory_unref (directory);
 
 		add_extension_extra_widgets (window, window->details->location);

Added: trunk/src/nautilus-x-content-bar.c
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-x-content-bar.c	Thu Jan 17 13:45:27 2008
@@ -0,0 +1,297 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2006 Paolo Borelli <pborelli katamail 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: David Zeuthen <davidz redhat com>
+ *          Paolo Borelli <pborelli katamail com>
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "nautilus-x-content-bar.h"
+#include <libnautilus-private/nautilus-autorun.h>
+#include <libnautilus-private/nautilus-icon-info.h>
+
+#define NAUTILUS_X_CONTENT_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NAUTILUS_TYPE_X_CONTENT_BAR, NautilusXContentBarPrivate))
+
+struct NautilusXContentBarPrivate
+{
+	GtkWidget *label;
+	GtkWidget *button;
+
+	char *x_content_type;
+	GMount *mount;
+};
+
+enum {
+	PROP_0,
+	PROP_MOUNT,
+	PROP_X_CONTENT_TYPE,
+};
+
+G_DEFINE_TYPE (NautilusXContentBar, nautilus_x_content_bar, GTK_TYPE_HBOX)
+
+void
+nautilus_x_content_bar_set_x_content_type (NautilusXContentBar *bar, const char *x_content_type)
+{					  
+	char *message;
+	char *description;
+	GAppInfo *default_app;
+
+	g_free (bar->priv->x_content_type);
+	bar->priv->x_content_type = g_strdup (x_content_type);
+
+	description = g_content_type_get_description (x_content_type);
+
+	/* Customize greeting for well-known x-content types */
+	if (strcmp (x_content_type, "x-content/audio-cdda") == 0) {
+		message = g_strdup (_("These files are on an Audio CD."));
+	} else if (strcmp (x_content_type, "x-content/audio-dvd") == 0) {
+		message = g_strdup (_("These files are on an Audio DVD."));
+	} else if (strcmp (x_content_type, "x-content/video-dvd") == 0) {
+		message = g_strdup (_("These files are on a Video DVD."));
+	} else if (strcmp (x_content_type, "x-content/video-vcd") == 0) {
+		message = g_strdup (_("These files are on a Video CD."));
+	} else if (strcmp (x_content_type, "x-content/video-svcd") == 0) {
+		message = g_strdup (_("These files are on a Super Video CD."));
+	} else if (strcmp (x_content_type, "x-content/image-photocd") == 0) {
+		message = g_strdup (_("These files are on a Photo CD."));
+	} else if (strcmp (x_content_type, "x-content/image-picturecd") == 0) {
+		message = g_strdup (_("These files are on a Picture CD."));
+	} else if (strcmp (x_content_type, "x-content/image-dcf") == 0) {
+		message = g_strdup (_("The media contains digital photos."));
+	} else if (strcmp (x_content_type, "x-content/audio-player") == 0) {
+		message = g_strdup (_("These files are on a digital audio player."));
+	} else if (strcmp (x_content_type, "x-content/software") == 0) {
+		message = g_strdup (_("The media contains software."));
+	} else {
+		/* fallback to generic greeting */
+		message = g_strdup_printf (_("The media has been detected as \"%s\"."), description);
+	}
+
+
+	gtk_label_set_text (GTK_LABEL (bar->priv->label), message);
+	gtk_widget_show (bar->priv->label);
+
+	/* TODO: We really need a GtkBrowserBackButton-ish widget here.. until then, we only
+	 *       show the default application. */
+
+ 	default_app = g_app_info_get_default_for_type (x_content_type, FALSE);
+	if (default_app != NULL) {
+		char *button_text;
+		const char *name;
+		GIcon *icon;
+		GtkWidget *image;
+
+		icon = g_app_info_get_icon (default_app);
+		if (icon != NULL) {
+			GdkPixbuf *pixbuf;
+			int icon_size;
+			NautilusIconInfo *icon_info;
+			icon_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_BUTTON);
+			icon_info = nautilus_icon_info_lookup (icon, icon_size);
+			pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
+			image = gtk_image_new_from_pixbuf (pixbuf);
+			g_object_unref (pixbuf);
+			g_object_unref (icon_info);
+			g_object_unref (icon);
+		} else {
+			image = NULL;
+		}
+
+		name = g_app_info_get_name (default_app);
+		button_text = g_strdup_printf (_("Open %s"), name);
+
+		gtk_button_set_image (GTK_BUTTON (bar->priv->button), image);
+		gtk_button_set_label (GTK_BUTTON (bar->priv->button), button_text);
+		gtk_widget_show (bar->priv->button);
+		g_free (button_text);
+		g_object_unref (default_app);
+	} else {
+		gtk_widget_hide (bar->priv->button);
+	}
+
+	g_free (message);
+	g_free (description);
+}
+
+const char *
+nautilus_x_content_bar_get_x_content_type (NautilusXContentBar *bar)
+{
+	return bar->priv->x_content_type;
+}
+
+GMount *
+nautilus_x_content_bar_get_mount (NautilusXContentBar *bar)
+{
+	return bar->priv->mount != NULL ? g_object_ref (bar->priv->mount) : NULL;
+}
+
+void
+nautilus_x_content_bar_set_mount (NautilusXContentBar *bar, GMount *mount)
+{
+	if (bar->priv->mount != NULL)
+		g_object_unref (bar->priv->mount);
+	bar->priv->mount = mount != NULL ? g_object_ref (mount) : NULL;
+}
+
+
+static void
+nautilus_x_content_bar_set_property (GObject      *object,
+				     guint         prop_id,
+				     const GValue *value,
+				     GParamSpec   *pspec)
+{
+	NautilusXContentBar *bar;
+
+	bar = NAUTILUS_X_CONTENT_BAR (object);
+
+	switch (prop_id) {
+	case PROP_MOUNT:
+		nautilus_x_content_bar_set_mount (bar, G_MOUNT (g_value_get_object (value)));
+		break;
+	case PROP_X_CONTENT_TYPE:
+		nautilus_x_content_bar_set_x_content_type (bar, g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+nautilus_x_content_bar_get_property (GObject    *object,
+				     guint       prop_id,
+				     GValue     *value,
+				     GParamSpec *pspec)
+{
+	NautilusXContentBar *bar;
+
+	bar = NAUTILUS_X_CONTENT_BAR (object);
+
+	switch (prop_id) {
+	case PROP_MOUNT:
+                g_value_set_object (value, bar->priv->mount);
+		break;
+	case PROP_X_CONTENT_TYPE:
+                g_value_set_string (value, bar->priv->x_content_type);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+nautilus_x_content_bar_finalize (GObject *object)
+{
+	NautilusXContentBar *bar = NAUTILUS_X_CONTENT_BAR (object);
+
+	g_free (bar->priv->x_content_type);
+	if (bar->priv->mount != NULL)
+		g_object_unref (bar->priv->mount);
+
+        G_OBJECT_CLASS (nautilus_x_content_bar_parent_class)->finalize (object);
+}
+
+static void
+nautilus_x_content_bar_class_init (NautilusXContentBarClass *klass)
+{
+	GObjectClass *object_class;
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->get_property = nautilus_x_content_bar_get_property;
+	object_class->set_property = nautilus_x_content_bar_set_property;
+	object_class->finalize = nautilus_x_content_bar_finalize;
+
+	g_type_class_add_private (klass, sizeof (NautilusXContentBarPrivate));
+
+        g_object_class_install_property (object_class,
+					 PROP_MOUNT,
+					 g_param_spec_object (
+						 "mount",
+						 "The GMount to run programs for",
+						 "The GMount to run programs for",
+						 G_TYPE_MOUNT,
+						 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+        g_object_class_install_property (object_class,
+					 PROP_X_CONTENT_TYPE,
+					 g_param_spec_string (
+						 "x-content-type",
+						 "The x-content type for the cluebar",
+						 "The x-content type for the cluebar",
+						 NULL,
+						 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+button_clicked_callback (GtkWidget *button, NautilusXContentBar *bar)
+{
+	GAppInfo *default_app;
+
+	if (bar->priv->x_content_type == NULL ||
+	    bar->priv->mount == NULL)
+		return;
+
+ 	default_app = g_app_info_get_default_for_type (bar->priv->x_content_type, FALSE);
+	if (default_app != NULL) {
+		nautilus_autorun_launch_for_mount (bar->priv->mount, default_app);
+		g_object_unref (default_app);
+	}
+}
+
+static void
+nautilus_x_content_bar_init (NautilusXContentBar *bar)
+{
+	GtkWidget *hbox;
+
+	bar->priv = NAUTILUS_X_CONTENT_BAR_GET_PRIVATE (bar);
+
+	hbox = GTK_WIDGET (bar);
+
+	bar->priv->label = gtk_label_new (NULL);
+	gtk_box_pack_start (GTK_BOX (bar), bar->priv->label, FALSE, FALSE, 0);
+
+	bar->priv->button = gtk_button_new ();
+	gtk_box_pack_end (GTK_BOX (hbox), bar->priv->button, FALSE, FALSE, 0);
+
+	g_signal_connect (bar->priv->button,
+			  "clicked",
+			  G_CALLBACK (button_clicked_callback),
+			  bar);
+}
+
+GtkWidget *
+nautilus_x_content_bar_new (GMount *mount, 
+			    const char *x_content_type)
+{
+	GObject *bar;
+
+	bar = g_object_new (NAUTILUS_TYPE_X_CONTENT_BAR, 
+			    "mount", mount,
+			    "x-content-type", x_content_type, 
+			    NULL);
+
+	return GTK_WIDGET (bar);
+}

Added: trunk/src/nautilus-x-content-bar.h
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-x-content-bar.h	Thu Jan 17 13:45:27 2008
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2006 Paolo Borelli <pborelli katamail 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: David Zeuthen <davidz redhat com>
+ *          Paolo Borelli <pborelli katamail com>
+ *
+ */
+
+#ifndef __NAUTILUS_X_CONTENT_BAR_H
+#define __NAUTILUS_X_CONTENT_BAR_H
+
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_X_CONTENT_BAR         (nautilus_x_content_bar_get_type ())
+#define NAUTILUS_X_CONTENT_BAR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_X_CONTENT_BAR, NautilusXContentBar))
+#define NAUTILUS_X_CONTENT_BAR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_X_CONTENT_BAR, NautilusXContentBarClass))
+#define NAUTILUS_IS_X_CONTENT_BAR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_X_CONTENT_BAR))
+#define NAUTILUS_IS_X_CONTENT_BAR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_X_CONTENT_BAR))
+#define NAUTILUS_X_CONTENT_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_X_CONTENT_BAR, NautilusXContentBarClass))
+
+typedef struct NautilusXContentBarPrivate NautilusXContentBarPrivate;
+
+typedef struct
+{
+	GtkHBox	box;
+
+	NautilusXContentBarPrivate *priv;
+} NautilusXContentBar;
+
+typedef struct
+{
+	GtkHBoxClass	    parent_class;
+} NautilusXContentBarClass;
+
+GType		 nautilus_x_content_bar_get_type	(void) G_GNUC_CONST;
+
+GtkWidget	*nautilus_x_content_bar_new		   (GMount              *mount, 
+							    const char          *x_content_type);
+const char      *nautilus_x_content_bar_get_x_content_type (NautilusXContentBar *bar);
+void             nautilus_x_content_bar_set_x_content_type (NautilusXContentBar *bar, 
+							    const char          *x_content_type);
+void             nautilus_x_content_bar_set_mount          (NautilusXContentBar *bar, 
+							    GMount              *mount);
+GMount          *nautilus_x_content_bar_get_mount          (NautilusXContentBar *bar);
+
+G_END_DECLS
+
+#endif /* __NAUTILUS_X_CONTENT_BAR_H */



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