[nautilus/open-with: 3/6] mime-application-chooser: rewrite to make it use GtkAppChooserWidget



commit 682b67327068c60e5d84b64866bbd3dd668ee6f6
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Nov 23 17:52:44 2010 +0100

    mime-application-chooser: rewrite to make it use GtkAppChooserWidget

 .../nautilus-mime-application-chooser.c            |  848 ++++++++------------
 .../nautilus-mime-application-chooser.h            |    7 +-
 2 files changed, 333 insertions(+), 522 deletions(-)
---
diff --git a/libnautilus-private/nautilus-mime-application-chooser.c b/libnautilus-private/nautilus-mime-application-chooser.c
index 5e00171..4aa4a0e 100644
--- a/libnautilus-private/nautilus-mime-application-chooser.c
+++ b/libnautilus-private/nautilus-mime-application-chooser.c
@@ -1,36 +1,36 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
 /*
-   nautilus-mime-application-chooser.c: an mime-application chooser
- 
-   Copyright (C) 2004 Novell, Inc.
-   Copyright (C) 2007 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 APPLICATIONOUT ANY WARRANTY; applicationout 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 application 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.
-
-   Authors: Dave Camp <dave novell com>
-            Alexander Larsson <alexl redhat com>
-*/
+ *  nautilus-mime-application-chooser.c: an mime-application chooser
+ *
+ *  Copyright (C) 2004 Novell, Inc.
+ *  Copyright (C) 2007, 2010 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 APPLICATIONOUT ANY WARRANTY; applicationout 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 application 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.
+ *
+ *  Authors: Dave Camp <dave novell com>
+ *           Alexander Larsson <alexl redhat com>
+ *           Cosimo Cecchi <ccecchi redhat com>
+ */
 
 #include <config.h>
 #include "nautilus-mime-application-chooser.h"
 
-#include "nautilus-open-with-dialog.h"
-#include "nautilus-signaller.h"
 #include "nautilus-file.h"
+#include "nautilus-signaller.h"
 #include <eel/eel-stock-dialogs.h>
 
 #include <string.h>
@@ -40,258 +40,95 @@
 #include <gio/gio.h>
 
 struct _NautilusMimeApplicationChooserDetails {
+	GList *files;
 	char *uri;
 
 	char *content_type;
-	char *extension;
-	char *type_description;
-	char *orig_mime_type;
-	
-	guint refresh_timeout;
 
 	GtkWidget *label;
 	GtkWidget *entry;
-	GtkWidget *treeview;
 	GtkWidget *remove_button;
-	
-	gboolean for_multiple_files;
-
-	GtkListStore *model;
-	GtkCellRenderer *toggle_renderer;
+	GtkWidget *set_as_default_button;
+	GtkWidget *open_with_widget;
 };
 
 enum {
-	COLUMN_APPINFO,
-	COLUMN_DEFAULT,
-	COLUMN_ICON,
-	COLUMN_NAME,
-	NUM_COLUMNS
+	PROP_CONTENT_TYPE = 1,
+	PROP_URI,
+	PROP_FILES,
+	NUM_PROPERTIES
 };
 
-G_DEFINE_TYPE (NautilusMimeApplicationChooser, nautilus_mime_application_chooser, GTK_TYPE_VBOX);
+static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
-static void refresh_model             (NautilusMimeApplicationChooser *chooser);
-static void refresh_model_soon        (NautilusMimeApplicationChooser *chooser);
-static void mime_type_data_changed_cb (GObject                        *signaller,
-				       gpointer                        user_data);
+G_DEFINE_TYPE (NautilusMimeApplicationChooser, nautilus_mime_application_chooser, GTK_TYPE_BOX);
 
 static void
-nautilus_mime_application_chooser_finalize (GObject *object)
+add_app_dialog_response_cb (GtkDialog *dialog,
+			    gint response_id,
+			    gpointer user_data)
 {
-	NautilusMimeApplicationChooser *chooser;
-
-	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (object);
+	NautilusMimeApplicationChooser *chooser = user_data;
+	GAppInfo *info;
+	gchar *message = NULL;
+	GError *error = NULL;
 
-	if (chooser->details->refresh_timeout) {
-		g_source_remove (chooser->details->refresh_timeout);
+	if (response_id != GTK_RESPONSE_OK) {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		return;
 	}
 
-	g_signal_handlers_disconnect_by_func (nautilus_signaller_get_current (),
-					      G_CALLBACK (mime_type_data_changed_cb),
-					      chooser);
-	
-	
-	g_free (chooser->details->uri);
-	g_free (chooser->details->content_type);
-	g_free (chooser->details->extension);
-	g_free (chooser->details->type_description);
-	g_free (chooser->details->orig_mime_type);
-	
-	g_free (chooser->details);
-
-	G_OBJECT_CLASS (nautilus_mime_application_chooser_parent_class)->finalize (object);
-}
-
-static void
-nautilus_mime_application_chooser_class_init (NautilusMimeApplicationChooserClass *class)
-{
-	GObjectClass *gobject_class;
+	info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
 
-	gobject_class = G_OBJECT_CLASS (class);
-	gobject_class->finalize = nautilus_mime_application_chooser_finalize;
-}
+	g_app_info_add_supports_type (info, chooser->details->content_type,
+				      &error);
 
-static void
-default_toggled_cb (GtkCellRendererToggle *renderer,
-		    const char *path_str,
-		    gpointer user_data)
-{
-	NautilusMimeApplicationChooser *chooser;
-	GtkTreeIter iter;
-	GtkTreePath *path;
-	GError *error;
-	
-	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
-	
-	path = gtk_tree_path_new_from_string (path_str);
-	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (chooser->details->model),
-				     &iter, path)) {
-		gboolean is_default;
-		gboolean success;
-		GAppInfo *info;
-		char *message;
-		
-		gtk_tree_model_get (GTK_TREE_MODEL (chooser->details->model),
-				    &iter,
-				    COLUMN_DEFAULT, &is_default,
-				    COLUMN_APPINFO, &info,
-				    -1);
-		
-		if (!is_default && info != NULL) {
-			error = NULL;
-			if (chooser->details->extension) {
-				success = g_app_info_set_as_default_for_extension (info,
-										   chooser->details->extension,
-										   &error);
-			} else {
-				success = g_app_info_set_as_default_for_type (info,
-									      chooser->details->content_type,
-									      &error);
-			}
-
-			if (!success) {
-				message = g_strdup_printf (_("Could not set application as the default: %s"), error->message);
-				eel_show_error_dialog (_("Could not set as default application"),
-						       message,
-						       GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
-				g_free (message);
-				g_error_free (error);
-			}
-
-			g_signal_emit_by_name (nautilus_signaller_get_current (),
-					       "mime_data_changed");
-		}
-		g_object_unref (info);
+	if (error != NULL) {
+		message = g_strdup_printf (_("Error while adding \"%s\": %s"),
+					   g_app_info_get_display_name (info), error->message);
+		eel_show_error_dialog (_("Could not add application"),
+				       message,
+				       GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
+		g_error_free (error);
 	}
-	gtk_tree_path_free (path);
-}
 
-static GAppInfo *
-get_selected_application (NautilusMimeApplicationChooser *chooser)
-{
-	GtkTreeIter iter;
-	GtkTreeSelection *selection;
-	GAppInfo *info;
-	
-	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->details->treeview));
-
-	info = NULL;
-	if (gtk_tree_selection_get_selected (selection, 
-					     NULL,
-					     &iter)) {
-		gtk_tree_model_get (GTK_TREE_MODEL (chooser->details->model),
-				    &iter,
-				    COLUMN_APPINFO, &info,
-				    -1);
-	}
-	
-	return info;
-}
+	g_object_unref (info);
+	g_free (message);
 
-static void
-selection_changed_cb (GtkTreeSelection *selection, 
-		      gpointer user_data)
-{
-	NautilusMimeApplicationChooser *chooser;
-	GAppInfo *info;
-	
-	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
-	
-	info = get_selected_application (chooser);
-	if (info) {
-		gtk_widget_set_sensitive (chooser->details->remove_button,
-					  g_app_info_can_remove_supports_type (info));
-		
-		g_object_unref (info);
-	} else {
-		gtk_widget_set_sensitive (chooser->details->remove_button,
-					  FALSE);
-	}
-}
+	gtk_app_chooser_refresh (GTK_APP_CHOOSER (chooser->details->open_with_widget));
 
-static GtkWidget *
-create_tree_view (NautilusMimeApplicationChooser *chooser)
-{
-	GtkWidget *treeview;
-	GtkListStore *store;
-	GtkTreeViewColumn *column;
-	GtkCellRenderer *renderer;
-	GtkTreeSelection *selection;
-	
-	treeview = gtk_tree_view_new ();
-	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-
-	store = gtk_list_store_new (NUM_COLUMNS,
-				    G_TYPE_APP_INFO,
-				    G_TYPE_BOOLEAN,
-				    G_TYPE_ICON,
-				    G_TYPE_STRING);
-	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
-					      COLUMN_NAME,
-					      GTK_SORT_ASCENDING);
-	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
-				 GTK_TREE_MODEL (store));
-	chooser->details->model = store;
-	
-	renderer = gtk_cell_renderer_toggle_new ();
-	g_signal_connect (renderer, "toggled", 
-			  G_CALLBACK (default_toggled_cb), 
-			  chooser);
-	gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer),
-					    TRUE);
-	
-	column = gtk_tree_view_column_new_with_attributes (_("Default"),
-							   renderer,
-							   "active",
-							   COLUMN_DEFAULT,
-							   NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-	chooser->details->toggle_renderer = renderer;
-
-	renderer = gtk_cell_renderer_pixbuf_new ();
-        g_object_set (renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
-	column = gtk_tree_view_column_new_with_attributes (_("Icon"),
-							   renderer,
-							   "gicon",
-							   COLUMN_ICON,
-							   NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-
-	renderer = gtk_cell_renderer_text_new ();
-	column = gtk_tree_view_column_new_with_attributes (_("Name"),
-							   renderer,
-							   "markup",
-							   COLUMN_NAME,
-							   NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-
-	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
-	g_signal_connect (selection, "changed", 
-			  G_CALLBACK (selection_changed_cb), 
-			  chooser);	
-
-	return treeview;
+	g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
 }
 
 static void
 add_clicked_cb (GtkButton *button,
 		gpointer user_data)
 {
-	NautilusMimeApplicationChooser *chooser;
-	GtkWidget *dialog;
-	
-	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
-	
-	if (chooser->details->for_multiple_files) {
-		dialog = nautilus_add_application_dialog_new_for_multiple_files (chooser->details->extension,
-										 chooser->details->orig_mime_type);
+	NautilusMimeApplicationChooser *chooser = user_data;
+	GtkWidget *dialog, *widget;
+
+	if (chooser->details->files != NULL) {
+		dialog = gtk_app_chooser_dialog_new_for_content_type (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))),
+								      0, chooser->details->content_type);
 	} else {
-		dialog = nautilus_add_application_dialog_new (chooser->details->uri,
-							      chooser->details->orig_mime_type);
+		GFile *file;
+
+		file = g_file_new_for_uri (chooser->details->uri);
+		dialog = gtk_app_chooser_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))),
+						     0, file);
+
+		g_object_unref (file);
 	}
-	gtk_window_set_screen (GTK_WINDOW (dialog),
-			       gtk_widget_get_screen (GTK_WIDGET (chooser)));
+
+	/* set the dialog in SHOW_ALL mode, as we already list recommended applications here */
+	widget = gtk_app_chooser_dialog_get_widget (GTK_APP_CHOOSER_DIALOG (dialog));
+	gtk_app_chooser_widget_set_show_all (GTK_APP_CHOOSER_WIDGET (widget), TRUE);
+
 	gtk_widget_show (dialog);
+
+	g_signal_connect (dialog, "response",
+			  G_CALLBACK (add_app_dialog_response_cb), chooser);
 }
 
 static void
@@ -304,7 +141,7 @@ remove_clicked_cb (GtkButton *button,
 	
 	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
 	
-	info = get_selected_application (chooser);
+	info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (chooser->details->open_with_widget));
 
 	if (info) {
 		error = NULL;
@@ -317,10 +154,12 @@ remove_clicked_cb (GtkButton *button,
 			g_error_free (error);
 			
 		}
-		g_signal_emit_by_name (nautilus_signaller_get_current (),
-				       "mime_data_changed");
+
+		gtk_app_chooser_refresh (GTK_APP_CHOOSER (chooser->details->open_with_widget));
 		g_object_unref (info);
 	}
+
+	g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
 }
 
 static void
@@ -330,34 +169,144 @@ reset_clicked_cb (GtkButton *button,
 	NautilusMimeApplicationChooser *chooser;
 	
 	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
-	
+
 	g_app_info_reset_type_associations (chooser->details->content_type);
+	gtk_app_chooser_refresh (GTK_APP_CHOOSER (chooser->details->open_with_widget));
 
-	g_signal_emit_by_name (nautilus_signaller_get_current (),
-			       "mime_data_changed");
+	g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
 }
 
 static void
-mime_type_data_changed_cb (GObject *signaller,
+set_as_default_clicked_cb (GtkButton *button,
 			   gpointer user_data)
 {
-	NautilusMimeApplicationChooser *chooser;
+	NautilusMimeApplicationChooser *chooser = user_data;
+	GAppInfo *info;
+	GError *error = NULL;
+	gchar *message = NULL;
 
-	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
+	info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (chooser->details->open_with_widget));
+
+	g_app_info_set_as_default_for_type (info, chooser->details->content_type,
+					    &error);
 
-	refresh_model_soon (chooser);
+	if (error != NULL) {
+		message = g_strdup_printf (_("Error while setting \"%s\" as default application: %s"),
+					   g_app_info_get_display_name (info), error->message);
+		eel_show_error_dialog (_("Could not set as default"),
+				       message,
+				       GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
+	}
+
+	g_object_unref (info);
+
+	gtk_app_chooser_refresh (GTK_APP_CHOOSER (chooser->details->open_with_widget));
+	g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
 }
 
 static void
-nautilus_mime_application_chooser_init (NautilusMimeApplicationChooser *chooser)
+application_selected_cb (GtkAppChooserWidget *widget,
+			 GAppInfo *info,
+			 gpointer user_data)
 {
-	GtkWidget *box;
-	GtkWidget *scrolled;
-	GtkWidget *button;
+	NautilusMimeApplicationChooser *chooser = user_data;
+	GAppInfo *default_app;
+
+	default_app = g_app_info_get_default_for_type (chooser->details->content_type, FALSE);
+	gtk_widget_set_sensitive (chooser->details->set_as_default_button,
+				  !g_app_info_equal (info, default_app));
+
+	g_object_unref (default_app);
+
+	gtk_widget_set_sensitive (chooser->details->remove_button,
+				  g_app_info_can_remove_supports_type (info));
+}
+
+static char *
+get_extension (const char *basename)
+{
+	char *p;
 	
-	chooser->details = g_new0 (NautilusMimeApplicationChooserDetails, 1);
+	p = strrchr (basename, '.');
+	
+	if (p && *(p + 1) != '\0') {
+		return g_strdup (p + 1);
+	} else {
+		return NULL;
+	}
+}
+
+static gchar *
+get_extension_from_file (NautilusFile *nfile)
+{
+	char *name;
+	char *extension;
+
+	name = nautilus_file_get_name (nfile);
+	extension = get_extension (name);
+
+	g_free (name);
+
+	return extension;
+}
+
+static void
+nautilus_mime_application_chooser_apply_labels (NautilusMimeApplicationChooser *chooser)
+{
+	gchar *label, *extension = NULL, *description = NULL;
+
+	if (chooser->details->files != NULL) {
+		/* here we assume all files are of the same content type */
+		if (g_content_type_is_unknown (chooser->details->content_type)) {
+			extension = get_extension_from_file (NAUTILUS_FILE (chooser->details->files->data));
+
+			/* the %s here is a file extension */
+			description = g_strdup_printf (_("%s document"), extension);
+		} else {
+			description = g_content_type_get_description (chooser->details->content_type);
+		}
+
+		label = g_strdup_printf (_("Open all files of type \"%s\" with"),
+					 description);
+	} else {
+		GFile *file;
+		gchar *basename, *emname;
+
+		file = g_file_new_for_uri (chooser->details->uri);
+		basename = g_file_get_basename (file);
+
+		if (g_content_type_is_unknown (chooser->details->content_type)) {
+			extension = get_extension (basename);
+
+			/* the %s here is a file extension */
+			description = g_strdup_printf (_("%s document"), extension);
+		} else {
+			description = g_content_type_get_description (chooser->details->content_type);
+		}
+
+		/* first %s is filename, second %s is mime-type description */
+		emname = g_strdup_printf ("<i>%s</i>", basename);
+		label = g_strdup_printf (_("Select an application to open %s and other files of type \"%s\""),
+					 emname, description);
+
+		g_free (emname);
+		g_free (basename);
+		g_object_unref (file);
+	}
+
+	gtk_label_set_markup (GTK_LABEL (chooser->details->label), label);
+
+	g_free (label);
+	g_free (extension);
+	g_free (description);
+}
+
+static void
+nautilus_mime_application_chooser_build_ui (NautilusMimeApplicationChooser *chooser)
+{
+	GtkWidget *box, *button;
+	GAppInfo *info;
 
-	chooser->details->for_multiple_files = FALSE;
 	gtk_container_set_border_width (GTK_CONTAINER (chooser), 8);
 	gtk_box_set_spacing (GTK_BOX (chooser), 0);
 	gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE);
@@ -372,24 +321,20 @@ nautilus_mime_application_chooser_init (NautilusMimeApplicationChooser *chooser)
 
 	gtk_widget_show (chooser->details->label);
 
-	scrolled = gtk_scrolled_window_new (NULL, NULL);
-	
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
-					GTK_POLICY_AUTOMATIC,
-					GTK_POLICY_AUTOMATIC);
-	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
-					     GTK_SHADOW_IN);
-	
-	gtk_widget_show (scrolled);
-	gtk_box_pack_start (GTK_BOX (chooser), scrolled, TRUE, TRUE, 6);
-
-	chooser->details->treeview = create_tree_view (chooser);
-	gtk_widget_show (chooser->details->treeview);
-	
-	gtk_container_add (GTK_CONTAINER (scrolled), 
-			   chooser->details->treeview);
+	chooser->details->open_with_widget = gtk_app_chooser_widget_new (chooser->details->content_type);
+	gtk_app_chooser_widget_set_show_default (GTK_APP_CHOOSER_WIDGET (chooser->details->open_with_widget),
+						 TRUE);
+	gtk_app_chooser_widget_set_show_fallback (GTK_APP_CHOOSER_WIDGET (chooser->details->open_with_widget),
+						  TRUE);
+	gtk_box_pack_start (GTK_BOX (chooser), chooser->details->open_with_widget,
+			    TRUE, TRUE, 6);
+	gtk_widget_show (chooser->details->open_with_widget);
+
+	g_signal_connect (chooser->details->open_with_widget, "application-selected",
+			  G_CALLBACK (application_selected_cb),
+			  chooser);
 
-	box = gtk_hbutton_box_new ();
+	box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
 	gtk_box_set_spacing (GTK_BOX (box), 6);
 	gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_END);
 	gtk_box_pack_start (GTK_BOX (chooser), box, FALSE, FALSE, 6);
@@ -401,7 +346,7 @@ nautilus_mime_application_chooser_init (NautilusMimeApplicationChooser *chooser)
 			  chooser);
 
 	gtk_widget_show (button);
-	gtk_container_add (GTK_CONTAINER (box), button);
+	gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
 
 	button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
 	g_signal_connect (button, "clicked", 
@@ -409,291 +354,158 @@ nautilus_mime_application_chooser_init (NautilusMimeApplicationChooser *chooser)
 			  chooser);
 	
 	gtk_widget_show (button);
-	gtk_container_add (GTK_CONTAINER (box), button);
-	
+	gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);	
 	chooser->details->remove_button = button;
 
 	button = gtk_button_new_with_label (_("Reset"));
 	g_signal_connect (button, "clicked", 
 			  G_CALLBACK (reset_clicked_cb),
 			  chooser);
-	
-	gtk_widget_show (button);
-	gtk_container_add (GTK_CONTAINER (box), button);
-	
-	g_signal_connect (nautilus_signaller_get_current (),
-			  "mime_data_changed",
-			  G_CALLBACK (mime_type_data_changed_cb),
-			  chooser);
-}
 
-static char *
-get_extension (const char *basename)
-{
-	char *p;
-	
-	p = strrchr (basename, '.');
-	
-	if (p && *(p + 1) != '\0') {
-		return g_strdup (p + 1);
-	} else {
-		return NULL;
-	}
-}
+	gtk_widget_show (button);
+	gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
 
-static gboolean
-refresh_model_timeout (gpointer data)
-{
-	NautilusMimeApplicationChooser *chooser = data;
-	
-	chooser->details->refresh_timeout = 0;
+	button = gtk_button_new_with_label (_("Set as default"));
+	g_signal_connect (button, "clicked",
+			  G_CALLBACK (set_as_default_clicked_cb),
+			  chooser);
+	gtk_widget_show (button);
+	gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
 
-	refresh_model (chooser);
+	chooser->details->set_as_default_button = button;
 
-	return FALSE;
+	/* initialize sensitivity */
+	info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (chooser->details->open_with_widget));
+	if (info != NULL) {
+		application_selected_cb (GTK_APP_CHOOSER_WIDGET (chooser->details->open_with_widget),
+					 info, chooser);
+		g_object_unref (info);
+	}
 }
 
-/* This adds a slight delay so that we're sure the mime data is
-   done writing */
 static void
-refresh_model_soon (NautilusMimeApplicationChooser *chooser)
+nautilus_mime_application_chooser_init (NautilusMimeApplicationChooser *chooser)
 {
-	if (chooser->details->refresh_timeout != 0)
-		return;
+	chooser->details = G_TYPE_INSTANCE_GET_PRIVATE (chooser, NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER,
+							NautilusMimeApplicationChooserDetails);
 
-	chooser->details->refresh_timeout =
-		g_timeout_add (300,
-			       refresh_model_timeout,
-			       chooser);
+	gtk_orientable_set_orientation (GTK_ORIENTABLE (chooser),
+					GTK_ORIENTATION_VERTICAL);
 }
 
 static void
-refresh_model (NautilusMimeApplicationChooser *chooser)
+nautilus_mime_application_chooser_constructed (GObject *object)
 {
-	GList *applications;
-	GAppInfo *default_app;
-	GList *l;
-	GtkTreeSelection *selection;
-	GtkTreeViewColumn *column;
-
-	column = gtk_tree_view_get_column (GTK_TREE_VIEW (chooser->details->treeview), 0);
-	gtk_tree_view_column_set_visible (column, TRUE);
-	
-	gtk_list_store_clear (chooser->details->model);
+	NautilusMimeApplicationChooser *chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (object);
 
-	applications = g_app_info_get_all_for_type (chooser->details->content_type);
-	default_app = g_app_info_get_default_for_type (chooser->details->content_type, FALSE);
-	
-	for (l = applications; l != NULL; l = l->next) {
-		GtkTreeIter iter;
-		gboolean is_default;
-		GAppInfo *application;
-		char *escaped;
-		GIcon *icon;
-
-		application = l->data;
-		
-		is_default = default_app && g_app_info_equal (default_app, application);
-
-		escaped = g_markup_escape_text (g_app_info_get_display_name (application), -1);
-
-		icon = g_app_info_get_icon (application);
-
-		gtk_list_store_append (chooser->details->model, &iter);
-		gtk_list_store_set (chooser->details->model, &iter,
-				    COLUMN_APPINFO, application,
-				    COLUMN_DEFAULT, is_default,
-				    COLUMN_ICON, icon,
-				    COLUMN_NAME, escaped,
-				    -1);
-
-		g_free (escaped);
-	}
+	if (G_OBJECT_CLASS (nautilus_mime_application_chooser_parent_class)->constructed != NULL)
+		G_OBJECT_CLASS (nautilus_mime_application_chooser_parent_class)->constructed (object);
 
-	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->details->treeview));
-	
-	if (applications) {
-		g_object_set (chooser->details->toggle_renderer,
-			      "visible", TRUE, 
-			      NULL);
-		gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-	} else {
-		GtkTreeIter iter;
-		char *name;
-
-		gtk_tree_view_column_set_visible (column, FALSE);
-		gtk_list_store_append (chooser->details->model, &iter);
-		name = g_strdup_printf ("<i>%s</i>", _("No applications selected"));
-		gtk_list_store_set (chooser->details->model, &iter,
-				    COLUMN_NAME, name,
-				    COLUMN_APPINFO, NULL,
-				    -1);
-		g_free (name);
-
-		gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
-	}
-	
-	if (default_app) {
-		g_object_unref (default_app);
-	}
-
-	g_list_free_full (applications, g_object_unref);
+	nautilus_mime_application_chooser_build_ui (chooser);
+	nautilus_mime_application_chooser_apply_labels (chooser);
 }
 
 static void
-set_extension_and_description (NautilusMimeApplicationChooser *chooser,
-			       const char *extension,
-			       const char *mime_type)
-{
-	if (extension != NULL &&
-	    g_content_type_is_unknown (mime_type)) {
-		chooser->details->extension = g_strdup (extension);
-		    chooser->details->content_type = g_strdup_printf ("application/x-extension-%s", extension);
-		    /* the %s here is a file extension */
-		    chooser->details->type_description =
-			    g_strdup_printf (_("%s document"), extension);
-	    } else {
-		    char *description;
-
-		    chooser->details->content_type = g_strdup (mime_type);
-		    description = g_content_type_get_description (mime_type);
-		    if (description == NULL) {
-			    description = g_strdup (_("Unknown"));
-		    }
-		    
-		    chooser->details->type_description = description;
-	    }
-}
-
-static gboolean
-set_uri_and_type (NautilusMimeApplicationChooser *chooser, 
-		  const char *uri,
-		  const char *mime_type)
+nautilus_mime_application_chooser_finalize (GObject *object)
 {
-	char *label;
-	char *name;
-	char *emname;
-	char *extension;
-	GFile *file;
-
-	chooser->details->uri = g_strdup (uri);
-
-	file = g_file_new_for_uri (uri);
-	name = g_file_get_basename (file);
-	g_object_unref (file);
-	
-	chooser->details->orig_mime_type = g_strdup (mime_type);
-
-	extension = get_extension (name);
-	set_extension_and_description (NAUTILUS_MIME_APPLICATION_CHOOSER (chooser),
-				       extension, mime_type);
-	g_free (extension);
-
-	/* first %s is filename, second %s is mime-type description */
-	emname = g_strdup_printf ("<i>%s</i>", name);
-	label = g_strdup_printf (_("Select an application to open %s and other files of type \"%s\""),
-				 emname, chooser->details->type_description);
-	g_free (emname);
-	
-	gtk_label_set_markup (GTK_LABEL (chooser->details->label), label);
+	NautilusMimeApplicationChooser *chooser;
 
-	g_free (label);
-	g_free (name);
+	chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (object);
 
-	refresh_model (chooser);
+	g_free (chooser->details->uri);
+	g_free (chooser->details->content_type);
 
-	return TRUE;
+	G_OBJECT_CLASS (nautilus_mime_application_chooser_parent_class)->finalize (object);
 }
 
-static char *
-get_extension_from_file (NautilusFile *nfile)
+static void
+nautilus_mime_application_chooser_get_property (GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec)
 {
-	char *name;
-	char *extension;
-
-	name = nautilus_file_get_name (nfile);
-	extension = get_extension (name);
-	
-	g_free (name);
-	
-	return extension;
+	NautilusMimeApplicationChooser *chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (object);
+
+	switch (property_id) {
+	case PROP_CONTENT_TYPE:
+		g_value_set_string (value, chooser->details->content_type);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
 }
 
-static gboolean
-set_uri_and_type_for_multiple_files (NautilusMimeApplicationChooser *chooser,
-				     GList *uris,
-				     const char *mime_type)
+static void
+nautilus_mime_application_chooser_set_property (GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec)
 {
-	char *label;
-	char *first_extension;
-	gboolean same_extension;
-	GList *iter;
-	
-	chooser->details->for_multiple_files = TRUE;
-	chooser->details->uri = NULL;
-	chooser->details->orig_mime_type = g_strdup (mime_type);
-	same_extension = TRUE;
-	first_extension = get_extension_from_file (NAUTILUS_FILE (uris->data));
-	iter = uris->next;
-
-	while (iter != NULL) {
-		char *extension_current;
-
-		extension_current = get_extension_from_file (NAUTILUS_FILE (iter->data));
-		if (g_strcmp0 (first_extension, extension_current)) {
-			same_extension = FALSE;
-			g_free (extension_current);
-			break;
-		}
-		iter = iter->next;
-
-		g_free (extension_current);
-	}
-	if (!same_extension) {
-		set_extension_and_description (NAUTILUS_MIME_APPLICATION_CHOOSER (chooser),
-					       NULL, mime_type);
-	} else {
-		set_extension_and_description (NAUTILUS_MIME_APPLICATION_CHOOSER (chooser),
-					       first_extension, mime_type);
+	NautilusMimeApplicationChooser *chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (object);
+
+	switch (property_id) {
+	case PROP_CONTENT_TYPE:
+		chooser->details->content_type = g_value_dup_string (value);
+		break;
+	case PROP_FILES:
+		chooser->details->files = g_value_get_pointer (value);
+		break;
+	case PROP_URI:
+		chooser->details->uri = g_value_dup_string (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
 	}
+}
 
-	g_free (first_extension);
-
-	label = g_strdup_printf (_("Open all files of type \"%s\" with:"),
-				 chooser->details->type_description);
-	gtk_label_set_markup (GTK_LABEL (chooser->details->label), label);
-
-	g_free (label);
-
-	refresh_model (chooser);
+static void
+nautilus_mime_application_chooser_class_init (NautilusMimeApplicationChooserClass *class)
+{
+	GObjectClass *gobject_class;
 
-	return TRUE;		
+	gobject_class = G_OBJECT_CLASS (class);
+	gobject_class->set_property = nautilus_mime_application_chooser_set_property;
+	gobject_class->get_property = nautilus_mime_application_chooser_get_property;
+	gobject_class->finalize = nautilus_mime_application_chooser_finalize;
+	gobject_class->constructed = nautilus_mime_application_chooser_constructed;
+
+	properties[PROP_CONTENT_TYPE] = g_param_spec_string ("content-type",
+							     "Content type",
+							     "Content type for this widget",
+							     NULL,
+							     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+							     G_PARAM_STATIC_STRINGS);
+	properties[PROP_URI] = g_param_spec_string ("uri",
+						    "URI",
+						    "URI for this widget",
+						    NULL,
+						    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+						    G_PARAM_STATIC_STRINGS);
+	properties[PROP_FILES] = g_param_spec_pointer ("files",
+						       "Files",
+						       "Files for this widget",
+						       G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+						       G_PARAM_STATIC_STRINGS);
+
+	g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
+
+	g_type_class_add_private (class, sizeof (NautilusMimeApplicationChooserDetails));
 }
 
 GtkWidget *
 nautilus_mime_application_chooser_new (const char *uri,
-				  const char *mime_type)
+				       GList *files,
+				       const char *mime_type)
 {
 	GtkWidget *chooser;
 
-	chooser = gtk_widget_new (NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER, NULL);
-
-	set_uri_and_type (NAUTILUS_MIME_APPLICATION_CHOOSER (chooser), uri, mime_type);
+	chooser = g_object_new (NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER,
+				"uri", uri,
+				"files", files,
+				"content-type", mime_type,
+				NULL);
 
 	return chooser;
 }
-
-GtkWidget *
-nautilus_mime_application_chooser_new_for_multiple_files (GList *uris,
-							  const char *mime_type)
-{
-	GtkWidget *chooser;
-	
-	chooser = gtk_widget_new (NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER, NULL);
-	
-	set_uri_and_type_for_multiple_files (NAUTILUS_MIME_APPLICATION_CHOOSER (chooser),
-					     uris, mime_type);
-	
-	return chooser;
-}
-
diff --git a/libnautilus-private/nautilus-mime-application-chooser.h b/libnautilus-private/nautilus-mime-application-chooser.h
index 64f4ff8..12630ef 100644
--- a/libnautilus-private/nautilus-mime-application-chooser.h
+++ b/libnautilus-private/nautilus-mime-application-chooser.h
@@ -47,9 +47,8 @@ struct _NautilusMimeApplicationChooserClass {
 };
 
 GType      nautilus_mime_application_chooser_get_type (void);
-GtkWidget* nautilus_mime_application_chooser_new      (const char *uri,
-						       const char *mime_type);
-GtkWidget* nautilus_mime_application_chooser_new_for_multiple_files (GList *uris,
-								     const char *mime_type);
+GtkWidget * nautilus_mime_application_chooser_new (const char *uri,
+						   GList *files,
+						   const char *mime_type);
 
 #endif /* NAUTILUS_MIME_APPLICATION_CHOOSER_H */



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