Re: pluggable context menus ...



On Sat, 2002-10-26 at 08:56, Michael Meeks wrote:
> Hi James,
> 
> On Sat, 2002-10-26 at 08:48, James Willcox wrote:
> > Um, that last patch was brain damaged.  This one is better, I promise :)
> 
> 	Ok - it looks nice; there are a few bits that need cleaning up, but the
> feature looks great to me :-)
<snip>

Ok, I understand what you meant now about the duplicating verb thing. 
I've attached a patch that does what you suggested.  The only thing left
now is to figure out how i18n will work.  If there is no other way than
the b-a-s hack, then I think I may need some hand holding.....unless
someone else does it for me :)  Also, this patch fixes a stupid query
problem that was caused by my properties tab patch...

Thanks,
James
? nautilus_jwillcox_context_menus_v1.diff
? nautilus_jwillcox_context_menus_v2.diff
? nautilus_jwillcox_context_menus_v3.diff
? components/emblem/Makefile
? components/emblem/Makefile.in
? components/emblem/Nautilus_View_emblem.server
? components/emblem/Nautilus_View_emblem.server.in
? components/image_properties/nautilus-image-properties-view.xml
? components/notes/nautilus-notes-view.xml
Index: components/image_properties/Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus/components/image_properties/Makefile.am,v
retrieving revision 1.1
diff -u -r1.1 Makefile.am
--- components/image_properties/Makefile.am	24 Oct 2002 15:54:32 -0000	1.1
+++ components/image_properties/Makefile.am	27 Oct 2002 07:14:53 -0000
@@ -32,8 +32,11 @@
 serverdir = $(libdir)/bonobo/servers
 server_DATA = $(server_in_files:.server.in.in=.server)
 $(server_in_files:.server.in.in=.server.in): $(server_in_files)
-	sed -e "s|\ BONOBODIR\@|$(bonobodir)|" $< > $@
+	sed -e "s|\ BONOBODIR\@|$(bonobodir)|" -e "s|\ UIDIR\@|$(datadir)/gnome-2.0/ui|" $< > $@
 @INTLTOOL_SERVER_RULE@
+
+uidir = $(datadir)/gnome-2.0/ui
+ui_DATA = nautilus-image-properties-view.xml
 
 EXTRA_DIST = $(server_in_files)
 CLEANFILES = $(server_DATA) $(server_DATA).in
Index: components/image_properties/Nautilus_View_image_properties.server.in.in
===================================================================
RCS file: /cvs/gnome/nautilus/components/image_properties/Nautilus_View_image_properties.server.in.in,v
retrieving revision 1.1
diff -u -r1.1 Nautilus_View_image_properties.server.in.in
--- components/image_properties/Nautilus_View_image_properties.server.in.in	24 Oct 2002 15:54:32 -0000	1.1
+++ components/image_properties/Nautilus_View_image_properties.server.in.in	27 Oct 2002 07:14:53 -0000
@@ -5,6 +5,7 @@
 	<oaf_attribute name="repo_ids" type="stringv">
 		<item value="IDL:Bonobo/Unknown:1.0"/>
 		<item value="IDL:Bonobo/Control:1.0"/>
+		<item value="IDL:Bonobo/Listener:1.0"/>
 		<item value="IDL:Nautilus/View:1.0"/>
 	</oaf_attribute>
 	<oaf_attribute name="name" type="string" _value="Nautilus Image Properties view"/>
@@ -25,6 +26,7 @@
 	</oaf_attribute>
 	<oaf_attribute name="nautilus:view_as_name" type="string" _value="Image"/>
 	<oaf_attribute name="nautilus:property_page_name" type="string" _value="Image"/>
+	<oaf_attribute name="nautilus:context_menu_ui" type="string" value="@UIDIR@/nautilus-image-properties-view.xml"/>
 </oaf_server>
 
 </oaf_info>
Index: components/image_properties/nautilus-image-properties-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/components/image_properties/nautilus-image-properties-view.c,v
retrieving revision 1.1
diff -u -r1.1 nautilus-image-properties-view.c
--- components/image_properties/nautilus-image-properties-view.c	24 Oct 2002 15:54:32 -0000	1.1
+++ components/image_properties/nautilus-image-properties-view.c	27 Oct 2002 07:14:53 -0000
@@ -26,6 +26,7 @@
 
 #include <gtk/gtkvbox.h>
 #include <gtk/gtklabel.h>
+#include <gtk/gtkmessagedialog.h>
 #include <libgnome/gnome-macros.h>
 #include <libgnome/gnome-i18n.h>
 #include <libgnomevfs/gnome-vfs-async-ops.h>
@@ -220,6 +221,39 @@
 }
 
 static void
+listener_callback (BonoboListener *listener,
+		   const char *event_name,
+		   const CORBA_any *any,
+		   CORBA_Environment *ev,
+		   gpointer user_data)
+{
+	GtkWidget *dialog;
+	const BonoboArg *arg;
+	char *str;
+
+	arg = any;
+	
+	str = BONOBO_ARG_GET_STRING (arg);
+	dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO,
+					 GTK_BUTTONS_OK,
+					 "Got event %s for %s", event_name,
+					 str);
+	g_signal_connect (dialog, "response",
+			  G_CALLBACK (gtk_widget_destroy), NULL);
+	gtk_widget_show (dialog);
+}
+
+static void
+setup_listener (NautilusImagePropertiesView *view)
+{
+	BonoboListener *listener;
+
+	listener = bonobo_listener_new (listener_callback, view);
+	bonobo_object_add_interface (BONOBO_OBJECT (view),
+				     BONOBO_OBJECT (listener));
+}
+
+static void
 nautilus_image_properties_view_instance_init (NautilusImagePropertiesView *view)
 {
 	view->details = g_new0 (NautilusImagePropertiesViewDetails, 1);
@@ -234,6 +268,7 @@
 	gtk_widget_show_all (view->details->vbox);
 	
 	nautilus_view_construct (NAUTILUS_VIEW (view), view->details->vbox);
+	setup_listener (view);
 	
 	g_signal_connect (view, "load_location",
 			  G_CALLBACK (image_load_location_callback), NULL);
Index: components/notes/Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus/components/notes/Makefile.am,v
retrieving revision 1.30
diff -u -r1.30 Makefile.am
--- components/notes/Makefile.am	20 Sep 2002 08:01:12 -0000	1.30
+++ components/notes/Makefile.am	27 Oct 2002 07:14:58 -0000
@@ -26,8 +26,11 @@
 serverdir = $(libdir)/bonobo/servers
 server_DATA = $(server_in_files:.server.in.in=.server)
 $(server_in_files:.server.in.in=.server.in): $(server_in_files)
-	sed -e "s|\ BONOBODIR\@|$(bonobodir)|" $< > $@
+	sed -e "s|\ BONOBODIR\@|$(bonobodir)|" -e "s|\ UIDIR\@|$(datadir)/gnome-2.0/ui|" $< > $@
 @INTLTOOL_SERVER_RULE@
+
+uidir = $(datadir)/gnome-2.0/ui
+ui_DATA = nautilus-notes-view.xml
 
 EXTRA_DIST= $(server_in_files)
 CLEANFILES = $(server_DATA) $(server_DATA).in
Index: components/notes/Nautilus_View_notes.server.in.in
===================================================================
RCS file: /cvs/gnome/nautilus/components/notes/Nautilus_View_notes.server.in.in,v
retrieving revision 1.13
diff -u -r1.13 Nautilus_View_notes.server.in.in
--- components/notes/Nautilus_View_notes.server.in.in	25 Oct 2002 17:38:32 -0000	1.13
+++ components/notes/Nautilus_View_notes.server.in.in	27 Oct 2002 07:14:58 -0000
@@ -18,6 +18,7 @@
 	</oaf_attribute>
 	<oaf_attribute name="nautilus:view_as_name" type="string" _value="Notes"/>
 	<oaf_attribute name="nautilus:property_page_name" type="string" _value="Notes"/>
+	<oaf_attribute name="nautilus:context_menu_ui" type="string" value="@UIDIR@/nautilus-notes-view.xml"/>
 </oaf_server>
 
 </oaf_info>
Index: components/notes/nautilus-notes.c
===================================================================
RCS file: /cvs/gnome/nautilus/components/notes/nautilus-notes.c,v
retrieving revision 1.86
diff -u -r1.86 nautilus-notes.c
--- components/notes/nautilus-notes.c	19 Jul 2002 20:27:27 -0000	1.86
+++ components/notes/nautilus-notes.c	27 Oct 2002 07:14:59 -0000
@@ -37,6 +37,7 @@
 #include <gtk/gtktextbuffer.h>
 #include <gtk/gtktextview.h>
 #include <gtk/gtkvbox.h>
+#include <gtk/gtkmessagedialog.h>
 #include <bonobo/bonobo-property-bag.h>
 #include <libnautilus-private/nautilus-file-attributes.h>
 #include <libnautilus-private/nautilus-file.h>
@@ -350,6 +351,39 @@
 	return NULL;
 }
 
+static void
+listener_callback (BonoboListener *listener,
+		   const char *event_name,
+		   const CORBA_any *any,
+		   CORBA_Environment *ev,
+		   gpointer user_data)
+{
+	GtkWidget *dialog;
+	const BonoboArg *arg;
+	char *str;
+
+	arg = any;
+	
+	str = BONOBO_ARG_GET_STRING (arg);
+
+	dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO,
+					 GTK_BUTTONS_OK,
+					 "Got event %s for %s", event_name,
+					 str);
+	g_signal_connect (dialog, "response",
+			  G_CALLBACK (gtk_widget_destroy), NULL);
+	gtk_widget_show (dialog);
+}
+
+static void
+setup_listener (BonoboObject *obj)
+{
+	BonoboListener *listener;
+
+	listener = bonobo_listener_new (listener_callback, obj);
+	bonobo_object_add_interface (obj, BONOBO_OBJECT (listener));
+}
+
 static BonoboObject *
 make_notes_view ()
 {
@@ -385,6 +419,7 @@
 	/* Create CORBA object. */
         notes->view = nautilus_view_new (vbox);
         g_signal_connect (notes->view, "destroy", G_CALLBACK (do_destroy), notes);
+	setup_listener (BONOBO_OBJECT (notes->view));
 
 	/* allocate a property bag to reflect the TAB_IMAGE property */
 	notes->property_bag = bonobo_property_bag_new (get_bonobo_properties,  set_bonobo_properties, notes);
Index: libnautilus-private/nautilus-mime-actions.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-mime-actions.c,v
retrieving revision 1.102
diff -u -r1.102 nautilus-mime-actions.c
--- libnautilus-private/nautilus-mime-actions.c	25 Oct 2002 17:38:32 -0000	1.102
+++ libnautilus-private/nautilus-mime-actions.c	27 Oct 2002 07:22:12 -0000
@@ -54,7 +54,8 @@
 								  gboolean                  ignore_content_mime_types,
 								  GList                    *explicit_iids,
 								  char                    **extra_sort_criteria,
-								  char                     *extra_requirements);
+								  char                     *extra_requirements,
+								  gboolean                  must_be_view);
 static GList      *str_list_difference                           (GList                    *a,
 								  GList                    *b);
 static char      **strv_concat                                   (char                    **a,
@@ -393,13 +394,13 @@
 	if (metadata_default) {
 		extra_requirements = g_strconcat ("iid == '", default_component_string, "'", NULL);
 		info_list = nautilus_do_component_query (mime_type, uri_scheme, item_mime_types, TRUE,
-							 explicit_iids, sort_conditions, extra_requirements);
+							 explicit_iids, sort_conditions, extra_requirements, TRUE);
 		g_free (extra_requirements);
 	}
 
 	if (info_list == NULL) {
 		info_list = nautilus_do_component_query (mime_type, uri_scheme, item_mime_types, FALSE, 
-							 explicit_iids, sort_conditions, NULL);
+							 explicit_iids, sort_conditions, NULL, TRUE);
 	}
 
 	if (info_list != NULL) {
@@ -624,7 +625,7 @@
 		extra_sort_conditions[1] = NULL;
 		extra_requirements = build_joined_string (iids, "has (['", "','", "'], iid)");
 		result = nautilus_do_component_query (mime_type, uri_scheme, item_mime_types, FALSE,
-						      explicit_iids, extra_sort_conditions, extra_requirements);
+						      explicit_iids, extra_sort_conditions, extra_requirements, TRUE);
 		g_free (extra_requirements);
 		g_free (extra_sort_conditions[0]);
 	}
@@ -749,7 +750,7 @@
 	explicit_iids = get_explicit_content_view_iids_from_metafile (file); 
 
 	info_list = nautilus_do_component_query (mime_type, uri_scheme, NULL, TRUE,
-						 explicit_iids, NULL, NULL);
+						 explicit_iids, NULL, NULL, TRUE);
 	
 	needs_full_attributes = FALSE;
 
@@ -793,7 +794,7 @@
 	info_list = nautilus_do_component_query (mime_type, uri_scheme,
 						 item_mime_types, FALSE,
 						 explicit_iids, NULL,
-						 extra_reqs);
+						 extra_reqs, TRUE);
 	
 	eel_g_list_free_deep (explicit_iids);
 	eel_g_list_free_deep (item_mime_types);
@@ -805,6 +806,43 @@
 }
 
 GList *
+nautilus_mime_get_popup_components_for_file (NautilusFile *file)
+{
+	char *mime_type;
+	char *uri_scheme;
+	char *extra_reqs;
+	GList *item_mime_types;
+	GList *info_list;
+
+	if (!nautilus_mime_actions_check_if_minimum_attributes_ready (file)) {
+		return NULL;
+	}
+
+	uri_scheme = nautilus_file_get_uri_scheme (file);
+
+	mime_type = nautilus_file_get_mime_type (file);
+
+	if (!nautilus_mime_actions_check_if_full_attributes_ready (file) || 
+	    !nautilus_file_get_directory_item_mime_types (file, &item_mime_types)) {
+		item_mime_types = NULL;
+	}
+
+	extra_reqs = "nautilus:context_menu_ui.defined() AND "
+		     "repo_ids.has ('IDL:Bonobo/Listener:1.0')";
+	info_list = nautilus_do_component_query (mime_type, uri_scheme,
+						 item_mime_types, FALSE,
+						 NULL, NULL,
+						 extra_reqs, FALSE);
+	
+	eel_g_list_free_deep (item_mime_types);
+
+	g_free (uri_scheme);
+	g_free (mime_type);
+
+	return info_list;
+}
+
+GList *
 nautilus_mime_get_all_components_for_file (NautilusFile *file)
 {
 	return nautilus_mime_get_all_components_for_file_extended (file, NULL);
@@ -838,7 +876,7 @@
 
 	return nautilus_do_component_query
 		(NULL, uri_scheme, NULL, TRUE,
-		 NULL, NULL, NULL);
+		 NULL, NULL, NULL, TRUE);
 }
 
 gboolean
@@ -1312,32 +1350,28 @@
 make_bonobo_activation_query_with_known_mime_type (const char *mime_type, 
 				     const char *uri_scheme, 
 				     GList      *explicit_iids, 
-				     const char *extra_requirements)
+				     const char *extra_requirements,
+				     gboolean    must_be_view)
 {
         char *mime_supertype;
         char *result;
         char *explicit_iid_query;
+	const char *view_as_name_logic;
 
         mime_supertype = mime_type_get_supertype (mime_type);
 
         explicit_iid_query = make_bonobo_activation_query_for_explicit_content_view_iids (explicit_iids);
 
+	if (must_be_view) {
+		view_as_name_logic = "nautilus:view_as_name.defined ()";
+	} else {
+		view_as_name_logic = "true";
+	}
+
         result = g_strdup_printf 
                 (
-                 /* Check if the component has the interfaces we need.
-                  * We can work with either a Nautilus View, or
-                  * with a Bonobo Control or Embeddable that supports
-                  * one of the three persistence interfaces:
-                  * PersistStream, ProgressiveDataSink, or
-                  * PersistFile.
-                  */
-                 "(((repo_ids.has_all (['IDL:Bonobo/Control:1.0',"
-                                      "'IDL:Nautilus/View:1.0'])"
-                  "OR (repo_ids.has_one (['IDL:Bonobo/Control:1.0',"
-                                         "'IDL:Bonobo/Embeddable:1.0'])"
-                      "AND repo_ids.has_one (['IDL:Bonobo/PersistStream:1.0',"
-                                             "'IDL:Bonobo/ProgressiveDataSink:1.0',"
-                                             "'IDL:Bonobo/PersistFile:1.0'])))"
+
+                 
                  
                  /* Check that the component either has a specific
                   * MIME type or URI scheme. If neither is specified,
@@ -1345,7 +1379,7 @@
                   * and all schemes". For that, you have to do a
                   * wildcard for the MIME type or for the scheme.
                   */
-                 "AND (bonobo:supported_mime_types.defined ()"
+                 "(bonobo:supported_mime_types.defined ()"
                       "OR bonobo:supported_uri_schemes.defined ()"
 		      "OR bonobo:additional_uri_schemes.defined ())"
 
@@ -1379,12 +1413,13 @@
 		 "OR (bonobo:additional_uri_schemes.has ('%s')"
                       "OR bonobo:additional_uri_schemes.has ('*')))"
 
-                  /* Check that the component makes it clear that it's
+		 /* Check that the component makes it clear that it's
                    * intended for Nautilus by providing a "view_as"
                    * name. We could instead support a default, but
                    * that would make components that are untested with
                    * Nautilus appear.  */
-                 "AND nautilus:view_as_name.defined ())"
+		  "AND %s)"
+                  
 
                   /* Also select iids that were specifically requested
                      for this location, even if they do not otherwise
@@ -1397,14 +1432,42 @@
                  /* The MIME type, MIME supertype, and URI scheme for
                   * the %s above.
                   */
-                 , mime_type, mime_supertype, uri_scheme, uri_scheme
+                 , mime_type, mime_supertype, uri_scheme, uri_scheme,
 
                  /* The explicit metafile iid query for the %s above. */
-                 , explicit_iid_query
+                 view_as_name_logic, explicit_iid_query
 
 		 /* extra requirements */
 		 , extra_requirements != NULL ? extra_requirements : "true");
 
+	if (must_be_view) {
+		char *str;
+
+
+                 /* Check if the component has the interfaces we need.
+                  * We can work with either a Nautilus View, or
+                  * with a Bonobo Control or Embeddable that supports
+                  * one of the three persistence interfaces:
+                  * PersistStream, ProgressiveDataSink, or
+                  * PersistFile.
+                  */
+		str = g_strdup_printf ("(((repo_ids.has_all (['IDL:Bonobo/Control:1.0',"
+                                      "'IDL:Nautilus/View:1.0'])"
+                  "OR (repo_ids.has_one (['IDL:Bonobo/Control:1.0',"
+                                         "'IDL:Bonobo/Embeddable:1.0'])"
+                      "AND repo_ids.has_one (['IDL:Bonobo/PersistStream:1.0',"
+                                             "'IDL:Bonobo/ProgressiveDataSink:1.0',"
+                                          "'IDL:Bonobo/PersistFile:1.0']))) "
+					  "AND %s", result);
+		g_free (result);
+		result = str;
+	} else {
+		char *str;
+		str = g_strdup_printf ("((true AND %s", result);
+		g_free (result);
+		result = str;
+	}
+
         g_free (mime_supertype);
         g_free (explicit_iid_query);
         return result;
@@ -1413,31 +1476,28 @@
 static char *
 make_bonobo_activation_query_with_uri_scheme_only (const char *uri_scheme, 
 				     GList      *explicit_iids, 
-				     const char *extra_requirements)
+				     const char *extra_requirements,
+				     gboolean    must_be_view)
 {
         char *result;
         char *explicit_iid_query;
+	const char *view_as_name_logic;
         
         explicit_iid_query = make_bonobo_activation_query_for_explicit_content_view_iids (explicit_iids);
 
+	if (must_be_view) {
+		view_as_name_logic = "nautilus:view_as_name.defined ()";
+	} else {
+		view_as_name_logic = "true";
+	}
+
         result = g_strdup_printf 
                 (
-                 /* Check if the component has the interfaces we need.
-                  * We can work with either a Nautilus tView, or
-                  * with a Bonobo Control or Embeddable that works on
-                  * a file, which is indicated by Bonobo PersistFile.
-                  */
-                  "(((repo_ids.has_all(['IDL:Bonobo/Control:1.0',"
-                                      "'IDL:Nautilus/View:1.0'])"
-                   "OR (repo_ids.has_one(['IDL:Bonobo/Control:1.0',"
-                                         "'IDL:Bonobo/Embeddable:1.0'])"
-                       "AND repo_ids.has('IDL:Bonobo/PersistFile:1.0')))"
-
 
                   /* Check if the component supports this particular
                    * URI scheme.
                    */
-                  "AND (((bonobo:supported_uri_schemes.has ('%s')"
+                  "(((bonobo:supported_uri_schemes.has ('%s')"
                          "OR bonobo:supported_uri_schemes.has ('*'))"
 
                   /* Check that the component doesn't require
@@ -1452,13 +1512,12 @@
 		  "OR (bonobo:additional_uri_schemes.has ('%s')"
 		      "OR bonobo:additional_uri_schemes.has ('*')))"
 
-
-                  /* Check that the component makes it clear that it's
+		 /* Check that the component makes it clear that it's
                    * intended for Nautilus by providing a "view_as"
                    * name. We could instead support a default, but
                    * that would make components that are untested with
                    * Nautilus appear.  */
-                  "AND nautilus:view_as_name.defined ())"
+		  "AND %s)"
 
                  /* Also select iids that were specifically requested
                      for this location, even if they do not otherwise
@@ -1470,11 +1529,41 @@
 		  " AND (%s)"
 
                   /* The URI scheme for the %s above. */
-                  , uri_scheme, uri_scheme
+                  , uri_scheme, uri_scheme, view_as_name_logic
 
                   /* The explicit metafile iid query for the %s above. */
                   , explicit_iid_query,
 		  extra_requirements != NULL ? extra_requirements : "true");
+	
+
+	if (must_be_view) {
+		char *str;
+
+
+                 /* Check if the component has the interfaces we need.
+                  * We can work with either a Nautilus View, or
+                  * with a Bonobo Control or Embeddable that supports
+                  * one of the three persistence interfaces:
+                  * PersistStream, ProgressiveDataSink, or
+                  * PersistFile.
+                  */
+		str = g_strdup_printf ("(((repo_ids.has_all (['IDL:Bonobo/Control:1.0',"
+                                      "'IDL:Nautilus/View:1.0'])"
+                  "OR (repo_ids.has_one (['IDL:Bonobo/Control:1.0',"
+                                         "'IDL:Bonobo/Embeddable:1.0'])"
+                      "AND repo_ids.has_one (['IDL:Bonobo/PersistStream:1.0',"
+                                             "'IDL:Bonobo/ProgressiveDataSink:1.0',"
+                                          "'IDL:Bonobo/PersistFile:1.0']))) "
+					  "AND %s", result);
+		g_free (result);
+		result = str;
+	} else {
+		char *str;
+		str = g_strdup_printf ("((true AND %s", result);
+		g_free (result);
+		result = str;
+	}
+		  
 
 	g_free (explicit_iid_query);
 	
@@ -1591,7 +1680,8 @@
 			     gboolean           ignore_content_mime_types,
 			     GList             *explicit_iids,
 			     char             **extra_sort_criteria,
-			     char              *extra_requirements)
+			     char              *extra_requirements,
+			     gboolean           must_be_view)
 { 
 	Bonobo_ServerInfoList *bonobo_activation_result;
 	char *query;
@@ -1603,9 +1693,9 @@
         query = NULL;
 
         if (is_known_mime_type (mime_type)) {
-                query = make_bonobo_activation_query_with_known_mime_type (mime_type, uri_scheme, explicit_iids, extra_requirements);
+                query = make_bonobo_activation_query_with_known_mime_type (mime_type, uri_scheme, explicit_iids, extra_requirements, must_be_view);
         } else {
-                query = make_bonobo_activation_query_with_uri_scheme_only (uri_scheme, explicit_iids, extra_requirements);
+                query = make_bonobo_activation_query_with_uri_scheme_only (uri_scheme, explicit_iids, extra_requirements, must_be_view);
         }
 
 	all_sort_criteria = strv_concat (extra_sort_criteria, nautilus_sort_criteria);
Index: libnautilus-private/nautilus-mime-actions.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-mime-actions.h,v
retrieving revision 1.25
diff -u -r1.25 nautilus-mime-actions.h
--- libnautilus-private/nautilus-mime-actions.h	25 Oct 2002 17:38:33 -0000	1.25
+++ libnautilus-private/nautilus-mime-actions.h	27 Oct 2002 07:22:12 -0000
@@ -44,6 +44,7 @@
 GList *                  nautilus_mime_get_all_applications_for_file               (NautilusFile           *file);
 GList *                  nautilus_mime_get_all_components_for_file                 (NautilusFile           *file);
 GList *                  nautilus_mime_get_all_components_for_file_extended        (NautilusFile           *file, char *extra_requirements);
+GList *                  nautilus_mime_get_popup_components_for_file               (NautilusFile           *file);
  gboolean                 nautilus_mime_has_any_components_for_file                 (NautilusFile           *file);
  gboolean                 nautilus_mime_has_any_components_for_file_extended        (NautilusFile           *file, char *extra_requirements);
 gboolean                 nautilus_mime_has_any_applications_for_file               (NautilusFile           *file);
Index: libnautilus-private/nautilus-program-chooser.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-program-chooser.c,v
retrieving revision 1.78
diff -u -r1.78 nautilus-program-chooser.c
--- libnautilus-private/nautilus-program-chooser.c	25 Oct 2002 17:38:33 -0000	1.78
+++ libnautilus-private/nautilus-program-chooser.c	27 Oct 2002 07:22:13 -0000
@@ -441,7 +441,7 @@
 	
 
 	programs = type == GNOME_VFS_MIME_ACTION_TYPE_COMPONENT
-		? nautilus_mime_get_all_components_for_file_extended (program_chooser->details->file, "(NOT nautilus:property_page_name.defined)")
+		? nautilus_mime_get_all_components_for_file_extended (program_chooser->details->file, "NOT nautilus:property_page_name.defined()")
 		: nautilus_mime_get_all_applications_for_file (program_chooser->details->file);
 
 	list_store = program_chooser->details->list_store;
Index: libnautilus-private/nautilus-program-choosing.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-program-choosing.c,v
retrieving revision 1.62
diff -u -r1.62 nautilus-program-choosing.c
--- libnautilus-private/nautilus-program-choosing.c	25 Oct 2002 17:38:33 -0000	1.62
+++ libnautilus-private/nautilus-program-choosing.c	27 Oct 2002 07:22:14 -0000
@@ -194,7 +194,7 @@
 	identifier = NULL;
 	dialog = NULL;
 	if (nautilus_mime_has_any_components_for_file_extended (file,
-	    "(NOT nautilus:property_page_name.defined()")) {
+	    "NOT nautilus:property_page_name.defined()")) {
 		dialog = set_up_program_chooser (file, GNOME_VFS_MIME_ACTION_TYPE_COMPONENT,
 						 choose_data->parent_window);
 		if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.554
diff -u -r1.554 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	11 Oct 2002 22:22:46 -0000	1.554
+++ src/file-manager/fm-directory-view.c	27 Oct 2002 07:24:41 -0000
@@ -38,6 +38,8 @@
 #include <bonobo/bonobo-control.h>
 #include <bonobo/bonobo-window.h>
 #include <bonobo/bonobo-zoomable.h>
+#include <bonobo/bonobo-ui-util.h>
+#include <bonobo/bonobo-exception.h>
 #include <eel/eel-background.h>
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-gnome-extensions.h>
@@ -53,6 +55,7 @@
 #include <gtk/gtkselection.h>
 #include <gtk/gtksignal.h>
 #include <gtk/gtkstock.h>
+#include <gtk/gtkmessagedialog.h>
 #include <libgnome/gnome-i18n.h>
 #include <libgnome/gnome-util.h>
 #include <libgnomeui/gnome-uidefs.h>
@@ -154,6 +157,7 @@
 #define FM_DIRECTORY_VIEW_POPUP_PATH_SCRIPTS_SEPARATOR    		"/popups/selection/Open Placeholder/Scripts/After Scripts"
 #define FM_DIRECTORY_VIEW_POPUP_PATH_OPEN_WITH				"/popups/selection/Open Placeholder/Open With"
 #define FM_DIRECTORY_VIEW_POPUP_PATH_SCRIPTS				"/popups/selection/Open Placeholder/Scripts"
+#define FM_DIRECTORY_VIEW_POPUP_PATH_MIME_ACTIONS			"/popups/selection/Mime Actions"
 
 #define MAX_MENU_LEVELS 5
 
@@ -260,6 +264,12 @@
 	WindowChoice choice;
 } ActivateParameters;
 
+typedef struct {
+	char *id;
+	char *verb;
+	char *uri;
+} BonoboMimeActionData;
+
 enum {
 	GNOME_COPIED_FILES
 };
@@ -3491,6 +3501,218 @@
 				       FM_DIRECTORY_VIEW_POPUP_PATH_OPEN_WITH,
 				       sensitive);
 }
+/*
+static GList *
+get_bonobo_verb_names (Bonobo_ServerInfo *info)
+{
+	Bonobo_ActivationProperty *prop;
+	Bonobo_StringList strings;
+	GList *list;
+	unsigned int i;
+
+	prop = bonobo_server_info_prop_find (info,
+				"nautilus:context_menu_verbs");
+
+	g_return_val_if_fail (prop != NULL, NULL);
+
+	strings = prop->v._u.value_stringv;
+	list = NULL;
+
+	for (i=0; i < strings._length; i++) {
+		list = g_list_prepend (list, g_strdup (strings._buffer[i]));
+	}
+	
+	return list;
+}
+*/
+
+static BonoboMimeActionData *
+bonobo_mime_action_data_new (const char *id, const char *verb, const char *uri)
+{
+	BonoboMimeActionData *data;
+
+	data = g_new (BonoboMimeActionData, 1);
+	data->id = g_strdup (id);
+	data->verb = g_strdup (verb);
+	data->uri = g_strdup (uri);
+
+	return data;
+}
+
+static void
+bonobo_mime_action_data_free (BonoboMimeActionData *data)
+{
+	g_free (data->id);
+	g_free (data->verb);
+	g_free (data->uri);
+	g_free (data);
+}
+
+
+static void
+bonobo_mime_action_activate_callback (CORBA_Object obj,
+				      const char *error_reason,
+				      gpointer user_data)
+{
+	Bonobo_Listener listener;
+	CORBA_Environment ev;
+	BonoboMimeActionData *data;
+
+	data = user_data;
+
+	if (obj == CORBA_OBJECT_NIL) {
+		GtkWidget *dialog;
+
+		/* FIXME: make an error message that is not so lame */
+		dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
+						 GTK_BUTTONS_OK,
+						 _("Could not complete specified action:  %s"), error_reason);
+		g_signal_connect (dialog, "response",
+				  G_CALLBACK (gtk_widget_destroy), NULL);
+		gtk_widget_show (dialog);
+		return;
+	}
+
+	CORBA_exception_init (&ev);
+
+	listener = Bonobo_Unknown_queryInterface (obj,
+						  "IDL:Bonobo/Listener:1.0",
+						  &ev);
+
+	if (!BONOBO_EX (&ev)) {
+		BonoboArg *arg;
+
+		arg = bonobo_arg_new (BONOBO_ARG_STRING);
+		BONOBO_ARG_SET_STRING (arg, data->uri);
+		Bonobo_Listener_event (listener, data->verb, arg, &ev);
+		bonobo_arg_release (arg);
+		bonobo_object_release_unref (listener, &ev);
+	} else {
+		GtkWidget *dialog;
+
+		/* FIXME: make an error message that is not so lame */
+		dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
+				GTK_BUTTONS_OK,
+				_("Could not complete specified action."));
+		g_signal_connect (dialog, "response",
+				  G_CALLBACK (gtk_widget_destroy), NULL);
+		gtk_widget_show (dialog);
+	}
+
+}
+
+
+static void
+bonobo_mime_action_callback (BonoboUIComponent *component,
+			     gpointer callback_data, const char *path)
+{
+	BonoboMimeActionData *data;
+
+	data = callback_data;
+
+	bonobo_activation_activate_from_id_async (data->id, 0,
+				bonobo_mime_action_activate_callback,
+				data, NULL);
+	
+}
+
+static void
+bonobo_mime_action_menu_data_destroy_callback (gpointer data, GClosure *closure)
+{
+	bonobo_mime_action_data_free ((BonoboMimeActionData *)data);
+}
+
+static void
+add_bonobo_verbs (FMDirectoryView *view, NautilusFile *file,
+		  Bonobo_ServerInfo *info, BonoboUINode *node)
+{
+	BonoboUINode *n;
+
+	for (n = bonobo_ui_node_children (node); n;
+	     n = bonobo_ui_node_next (n)) {
+		const char *verb;
+		BonoboMimeActionData *data;
+		GClosure *closure;
+		char *uri;
+
+		verb = bonobo_ui_node_get_attr (n, "name");
+		
+		uri = nautilus_file_get_uri (file);
+		data = bonobo_mime_action_data_new (info->iid,
+						    verb, uri);
+		closure = g_cclosure_new
+				(G_CALLBACK (bonobo_mime_action_callback),
+				 data,
+				 bonobo_mime_action_menu_data_destroy_callback);	
+		bonobo_ui_component_add_verb_full
+					(view->details->ui,
+					 data->verb,
+					 closure); 
+	}
+
+}
+
+static void
+reset_bonobo_mime_actions_menu (FMDirectoryView *view, GList *selection)
+{
+	NautilusFile *file;
+	gboolean sensitive;
+
+	/* Clear any previous inserted items in the mime actions placeholder */
+	nautilus_bonobo_remove_menu_items_and_commands
+		(view->details->ui, FM_DIRECTORY_VIEW_POPUP_PATH_MIME_ACTIONS);
+
+	/* This menu is only displayed when there's one selected item. */
+	if (!eel_g_list_exactly_one_item (selection)) {
+		sensitive = FALSE;
+	} else {
+		GList *components, *l;
+		sensitive = TRUE;
+		
+		file = NAUTILUS_FILE (selection->data);
+		
+		components = nautilus_mime_get_popup_components_for_file (file);
+		l = components;
+		while (l != NULL) {
+			Bonobo_ServerInfo *info;
+			const char *ui_file;
+			BonoboUINode *node, *n, *children;
+
+			info = l->data;
+
+			ui_file = bonobo_server_info_prop_lookup (info,
+						"nautilus:context_menu_ui",
+						NULL);
+
+			bonobo_ui_util_set_ui (view->details->ui, NULL,
+					       ui_file, "nautilus", NULL);
+
+			node = bonobo_ui_util_new_ui (view->details->ui,
+						      ui_file, NULL,
+						      "nautilus");
+
+			children = NULL;
+			if (node != NULL) {
+				children = bonobo_ui_node_children (node);
+			}
+			
+			for (n = children; n;
+			     n = bonobo_ui_node_next (n)) {
+				
+				if (bonobo_ui_node_has_name (n, "commands")) {
+					add_bonobo_verbs (view, file, info, n);
+				}
+			}
+
+			l = l->next;
+		}
+		gnome_vfs_mime_component_list_free (components);
+	}
+
+	nautilus_bonobo_set_sensitive (view->details->ui,
+				       FM_DIRECTORY_VIEW_POPUP_PATH_MIME_ACTIONS,
+				       sensitive);
+}
 
 static char *
 change_to_view_directory (FMDirectoryView *view)
@@ -4323,6 +4545,7 @@
 
 	/* Broken into its own function just for convenience */
 	reset_bonobo_open_with_menu (view, selection);
+	reset_bonobo_mime_actions_menu (view, selection);
 
 	if (all_selected_items_in_trash (view)) {
 		label = _("_Delete from Trash");
Index: src/file-manager/nautilus-directory-view-ui.xml
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/nautilus-directory-view-ui.xml,v
retrieving revision 1.49
diff -u -r1.49 nautilus-directory-view-ui.xml
--- src/file-manager/nautilus-directory-view-ui.xml	30 Sep 2002 15:43:09 -0000	1.49
+++ src/file-manager/nautilus-directory-view-ui.xml	27 Oct 2002 07:24:44 -0000
@@ -249,6 +249,7 @@
 			 pixtype="stock" pixname="gtk-paste"
 			 verb="Paste Files"/>
 		</placeholder>
+		<placeholder name="Mime Actions" delimit="top"/>
 		<placeholder name="File Actions" delimit="top">
 			<menuitem name="Duplicate" verb="Duplicate"/>
 			<menuitem name="Create Link" verb="Create Link"/>


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