[nautilus] Only place one x-content-bar at a time



commit dde03f7e18f5ea4c949e920c1e746d948a6e0a94
Author: William Jon McCann <jmccann redhat com>
Date:   Sun May 20 09:59:49 2012 -0400

    Only place one x-content-bar at a time
    
    https://bugzilla.gnome.org/show_bug.cgi?id=676120

 src/nautilus-window-manage-views.c |   28 +-----
 src/nautilus-x-content-bar.c       |  180 ++++++++++++++++++++++++++----------
 src/nautilus-x-content-bar.h       |    4 +-
 3 files changed, 136 insertions(+), 76 deletions(-)
---
diff --git a/src/nautilus-window-manage-views.c b/src/nautilus-window-manage-views.c
index ac84a4e..ad58420 100644
--- a/src/nautilus-window-manage-views.c
+++ b/src/nautilus-window-manage-views.c
@@ -1247,33 +1247,13 @@ slot_add_extension_extra_widgets (NautilusWindowSlot *slot)
 static void
 nautilus_window_slot_show_x_content_bar (NautilusWindowSlot *slot, GMount *mount, const char **x_content_types)
 {
-	unsigned int n;
+	GtkWidget *bar;
 
 	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
 
-	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;
-		}
-
-		/* don't show the cluebar for windows software */
-		if (g_content_type_is_a (x_content_types[n], "x-content/win32-software")) {
-			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_slot_add_extra_location_widget (slot, bar);
-			g_object_unref (default_app);
-		}
-	}
+	bar = nautilus_x_content_bar_new (mount, x_content_types);
+	gtk_widget_show (bar);
+	nautilus_window_slot_add_extra_location_widget (slot, bar);
 }
 
 static void
diff --git a/src/nautilus-x-content-bar.c b/src/nautilus-x-content-bar.c
index 288fc6d..a2ece67 100644
--- a/src/nautilus-x-content-bar.c
+++ b/src/nautilus-x-content-bar.c
@@ -37,16 +37,15 @@
 struct NautilusXContentBarPrivate
 {
 	GtkWidget *label;
-	GtkWidget *button;
 
-	char *x_content_type;
+	char **x_content_types;
 	GMount *mount;
 };
 
 enum {
 	PROP_0,
 	PROP_MOUNT,
-	PROP_X_CONTENT_TYPE,
+	PROP_X_CONTENT_TYPES,
 };
 
 enum {
@@ -63,15 +62,16 @@ content_bar_response_cb (GtkInfoBar *infobar,
 	GAppInfo *default_app;
 	NautilusXContentBar *bar = user_data;
 
-	if (response_id != CONTENT_BAR_RESPONSE_APP) {
+	if (response_id < 0) {
 		return;
 	}
 
-	if (bar->priv->x_content_type == NULL ||
+	if (bar->priv->x_content_types == NULL ||
 	    bar->priv->mount == NULL)
 		return;
 
- 	default_app = g_app_info_get_default_for_type (bar->priv->x_content_type, FALSE);
+	/* FIXME */
+ 	default_app = g_app_info_get_default_for_type (bar->priv->x_content_types[response_id], FALSE);
 	if (default_app != NULL) {
 		nautilus_launch_application_for_mount (default_app, bar->priv->mount,
 						       GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (bar))));
@@ -79,15 +79,11 @@ content_bar_response_cb (GtkInfoBar *infobar,
 	}
 }
 
-static void
-nautilus_x_content_bar_set_x_content_type (NautilusXContentBar *bar, const char *x_content_type)
-{					  
+static char *
+get_message_for_x_content_type (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);
 
@@ -117,20 +113,108 @@ nautilus_x_content_bar_set_x_content_type (NautilusXContentBar *bar, const char
 		message = g_strdup_printf (_("The media has been detected as \"%s\"."), description);
 	}
 
+	g_free (description);
+
+	return message;
+}
+
+static char *
+get_message_for_two_x_content_types (char **x_content_types)
+{
+	char *message;
+
+	g_assert (x_content_types[0] != NULL);
+	g_assert (x_content_types[1] != NULL);
+
+	/* few combinations make sense */
+	if (strcmp (x_content_types[0], "x-content/image-dcf") == 0
+	    || strcmp (x_content_types[1], "x-content/image-dcf") == 0) {
+
+		if (strcmp (x_content_types[0], "x-content/audio-player") == 0) {
+			message = g_strdup (_("The media contains music and photos"));
+		} else if (strcmp (x_content_types[1], "x-content/audio-player") == 0) {
+			message = g_strdup (_("The media contains photos and music"));
+		} else {
+			message = g_strdup (_("The media contains digital photos."));
+		}
+	} else {
+		message = get_message_for_x_content_type (x_content_types[0]);
+	}
+
+	return message;
+}
+
+static void
+nautilus_x_content_bar_set_x_content_types (NautilusXContentBar *bar, const char **x_content_types)
+{
+	char *message = NULL;
+	guint num_types;
+	guint n;
+	GPtrArray *types;
+	GPtrArray *apps;
+	GAppInfo *default_app;
+
+	g_strfreev (bar->priv->x_content_types);
+
+	types = g_ptr_array_new ();
+	apps = g_ptr_array_new ();
+	g_ptr_array_set_free_func (apps, g_object_unref);
+	for (n = 0; x_content_types[n] != NULL; n++) {
+		if (g_str_has_prefix (x_content_types[n], "x-content/blank-"))
+			continue;
+
+		if (g_content_type_is_a (x_content_types[n], "x-content/win32-software"))
+			continue;
+
+		default_app = g_app_info_get_default_for_type (x_content_types[n], FALSE);
+		if (default_app == NULL)
+			continue;
+
+		g_ptr_array_add (types, g_strdup (x_content_types[n]));
+		g_ptr_array_add (apps, default_app);
+	}
+
+	num_types = types->len;
+	g_ptr_array_add (types, NULL);
+
+	bar->priv->x_content_types = (char **) g_ptr_array_free (types, FALSE);
+
+	switch (num_types) {
+	case 0:
+		message = NULL;
+		break;
+	case 1:
+		message = get_message_for_x_content_type (bar->priv->x_content_types[0]);
+		break;
+	case 2:
+		message = get_message_for_two_x_content_types (bar->priv->x_content_types);
+		break;
+	default:
+		message = g_strdup (_("Open with:"));
+		break;
+	}
+
+	if (message == NULL) {
+		g_ptr_array_free (apps, TRUE);
+		gtk_widget_destroy (GTK_WIDGET (bar));
+		return;
+	}
 
 	gtk_label_set_text (GTK_LABEL (bar->priv->label), message);
-	gtk_widget_show (bar->priv->label);
+	g_free (message);
 
-	/* TODO: We really need a GtkBrowserBackButton-ish widget here.. until then, we only
-	 *       show the default application. */
+	gtk_widget_show (bar->priv->label);
 
- 	default_app = g_app_info_get_default_for_type (x_content_type, FALSE);
-	if (default_app != NULL) {
-		char *button_text;
+	for (n = 0; bar->priv->x_content_types[n] != NULL; n++) {
 		const char *name;
 		GIcon *icon;
 		GtkWidget *image;
+		GtkWidget *button;
+
+		/* TODO: We really need a GtkBrowserBackButton-ish widget here.. until then, we only
+		 *       show the default application. */
 
+		default_app = g_ptr_array_index (apps, n);
 		icon = g_app_info_get_icon (default_app);
 		if (icon != NULL) {
 			image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON);
@@ -138,20 +222,17 @@ nautilus_x_content_bar_set_x_content_type (NautilusXContentBar *bar, const char
 			image = NULL;
 		}
 
-		name = g_app_info_get_display_name (default_app);
-		button_text = g_strdup_printf (_("Open %s"), name);
+		name = g_app_info_get_name (default_app);
+		button = gtk_info_bar_add_button (GTK_INFO_BAR (bar),
+						  name,
+						  n);
 
-		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);
+		gtk_button_set_image (GTK_BUTTON (button), image);
+		gtk_button_set_label (GTK_BUTTON (button), name);
+		gtk_widget_show (button);
 	}
 
-	g_free (message);
-	g_free (description);
+	g_ptr_array_free (apps, TRUE);
 }
 
 static void
@@ -178,8 +259,8 @@ nautilus_x_content_bar_set_property (GObject      *object,
 	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));
+	case PROP_X_CONTENT_TYPES:
+		nautilus_x_content_bar_set_x_content_types (bar, g_value_get_boxed (value));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -201,8 +282,8 @@ nautilus_x_content_bar_get_property (GObject    *object,
 	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);
+	case PROP_X_CONTENT_TYPES:
+		g_value_set_boxed (value, &bar->priv->x_content_types);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -215,7 +296,7 @@ nautilus_x_content_bar_finalize (GObject *object)
 {
 	NautilusXContentBar *bar = NAUTILUS_X_CONTENT_BAR (object);
 
-	g_free (bar->priv->x_content_type);
+	g_strfreev (bar->priv->x_content_types);
 	if (bar->priv->mount != NULL)
 		g_object_unref (bar->priv->mount);
 
@@ -244,23 +325,26 @@ nautilus_x_content_bar_class_init (NautilusXContentBarClass *klass)
 						 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));
+					 PROP_X_CONTENT_TYPES,
+					 g_param_spec_boxed ("x-content-types",
+							     "The x-content types for the cluebar",
+							     "The x-content types for the cluebar",
+							     G_TYPE_STRV,
+							     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 }
 
 static void
 nautilus_x_content_bar_init (NautilusXContentBar *bar)
 {
 	GtkWidget *content_area;
+	GtkWidget *action_area;
 	PangoAttrList *attrs;
 
 	bar->priv = NAUTILUS_X_CONTENT_BAR_GET_PRIVATE (bar);
 	content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (bar));
+	action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (bar));
+
+	gtk_orientable_set_orientation (GTK_ORIENTABLE (action_area), GTK_ORIENTATION_HORIZONTAL);
 
 	attrs = pango_attr_list_new ();
 	pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
@@ -271,22 +355,18 @@ nautilus_x_content_bar_init (NautilusXContentBar *bar)
 	gtk_label_set_ellipsize (GTK_LABEL (bar->priv->label), PANGO_ELLIPSIZE_END);
 	gtk_container_add (GTK_CONTAINER (content_area), bar->priv->label);
 
-	bar->priv->button = gtk_info_bar_add_button (GTK_INFO_BAR (bar),
-						     "",
-						     CONTENT_BAR_RESPONSE_APP);
-
 	g_signal_connect (bar, "response",
 			  G_CALLBACK (content_bar_response_cb),
 			  bar);
 }
 
 GtkWidget *
-nautilus_x_content_bar_new (GMount *mount, 
-			    const char *x_content_type)
+nautilus_x_content_bar_new (GMount *mount,
+			    const char **x_content_types)
 {
-	return g_object_new (NAUTILUS_TYPE_X_CONTENT_BAR, 
+	return g_object_new (NAUTILUS_TYPE_X_CONTENT_BAR,
 			     "message-type", GTK_MESSAGE_QUESTION,
 			     "mount", mount,
-			     "x-content-type", x_content_type, 
+			     "x-content-types", x_content_types,
 			     NULL);
 }
diff --git a/src/nautilus-x-content-bar.h b/src/nautilus-x-content-bar.h
index c266de4..0bbfafe 100644
--- a/src/nautilus-x-content-bar.h
+++ b/src/nautilus-x-content-bar.h
@@ -53,8 +53,8 @@ typedef struct
 
 GType		 nautilus_x_content_bar_get_type	(void) G_GNUC_CONST;
 
-GtkWidget	*nautilus_x_content_bar_new		   (GMount              *mount, 
-							    const char          *x_content_type);
+GtkWidget	*nautilus_x_content_bar_new		   (GMount              *mount,
+							    const char         **x_content_types);
 
 G_END_DECLS
 



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