Open with first patch



Hi guys!

After reading a lot of documentation, code and getting ideas from
nautilus and gThumb, i finish a first approach to implement this
function. 

In few words, the code add a open with menu under 'File' and a context
menu with the applications installed in the system that can handle the
myme type of the current image. 

Anyway, i have a doubt passing more than one image to an external
program. What if the user select a jpg and a svg image?. The program
have to add to the menu only the applications that support both myme
types?.

So, i'm looking for your feedback in any modification, suggestion, code
cleanup or change in my patch to get this part of the next version of
eog and finish my first collaboration in gnome.

Cheers 

Rodrigo  
? 319859.patch
Index: data/eog-ui.xml
===================================================================
RCS file: /cvs/gnome/eog/data/Attic/eog-ui.xml,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 eog-ui.xml
--- data/eog-ui.xml	16 Dec 2006 18:35:48 -0000	1.1.2.8
+++ data/eog-ui.xml	20 Dec 2006 14:14:41 -0000
@@ -2,6 +2,9 @@
   <menubar name="MainMenu">
     <menu action="File">
       <menuitem action="FileOpen"/>
+      <menu action='FileOpenWith'>
+         <placeholder name="Applications Placeholder"/>
+      </menu>
       <separator/>
       <menuitem action="FileSave"/>
       <menuitem action="FileSaveAs"/>
@@ -82,6 +85,10 @@
   </toolbar>
 
   <popup name="ThumbnailPopup">
+    <menu action='FileOpenWith'>
+       <placeholder name="Applications Placeholder"/>
+    </menu>
+    <separator/>
     <menuitem action="FileSave"/>
     <menuitem action="FileSaveAs"/>
     <separator/>
Index: shell/eog-window.c
===================================================================
RCS file: /cvs/gnome/eog/shell/eog-window.c,v
retrieving revision 1.189.2.38
diff -u -p -r1.189.2.38 eog-window.c
--- shell/eog-window.c	18 Dec 2006 22:38:05 -0000	1.189.2.38
+++ shell/eog-window.c	20 Dec 2006 14:14:45 -0000
@@ -54,6 +54,7 @@
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #include <libgnomevfs/gnome-vfs-mime.h>
+#include <libgnomevfs/gnome-vfs-mime-handlers.h>
 #include <gtk/gtkprintunixdialog.h>
 
 #define EOG_WINDOW_GET_PRIVATE(object) \
@@ -116,6 +117,8 @@ struct _EogWindowPrivate {
 
         guint image_info_message_cid;
         guint tip_message_cid;
+
+	GList*  open_with_menu_ids;
 };
 
 static void eog_window_cmd_fullscreen (GtkAction *action, gpointer user_data);
@@ -126,6 +129,9 @@ static void eog_job_load_progress_cb (Eo
 static void eog_job_transform_cb (EogJobTransform *job, gpointer data);
 static void fullscreen_set_timeout (EogWindow *window);
 static void fullscreen_clear_timeout (EogWindow *window);
+static void open_with_launch_application_callback (GtkAction *action, gpointer callback_data);
+static void eog_update_openwith_menu (EogWindow *window, EogImage *image);
+static void eog_delete_openwith_menu (EogWindow *window);
 
 static void
 eog_window_interp_type_changed_cb (GConfClient *client,
@@ -367,6 +373,8 @@ eog_window_display_image (EogWindow *win
 
 	g_assert (eog_image_has_data (image, EOG_IMAGE_DATA_ALL));
 
+	eog_delete_openwith_menu (window);
+
 	priv = window->priv;
 
 	eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), image);
@@ -390,6 +398,112 @@ eog_window_display_image (EogWindow *win
 	update_status_bar (window);
 
 	add_uri_to_recent_files (window, eog_image_get_uri (image));
+
+	eog_update_openwith_menu (window, image);
+}
+
+static void
+open_with_launch_application_callback (GtkAction *action, gpointer callback_data)
+{
+	GnomeVFSMimeApplication *app;
+	GnomeVFSURI *uri;
+	GList *uris;
+	
+	uri = (GnomeVFSURI *) callback_data;
+	uris = g_list_prepend (NULL, gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE));
+	app = g_object_get_data (G_OBJECT (action), "app");
+	gnome_vfs_mime_application_launch (app, uris);
+	g_list_free (uris);
+	gnome_vfs_uri_unref (uri);
+}
+
+static void
+eog_delete_openwith_menu(EogWindow *window)
+{
+	EogWindowPrivate *priv;
+	GList *scan;
+	guint merge_id;
+
+	priv = window->priv;
+	
+	if (priv->open_with_menu_ids != NULL)
+		for (scan = priv->open_with_menu_ids; scan; scan = scan->next) {
+			merge_id = GPOINTER_TO_UINT (scan->data);
+			gtk_ui_manager_remove_ui (priv->ui_mgr, merge_id);
+		}
+
+	g_list_free (scan);
+	g_list_free (priv->open_with_menu_ids);
+}
+
+static void
+eog_update_openwith_menu(EogWindow *window, EogImage *image)
+{
+	GnomeVFSURI *uri;
+	char *mime_type;
+	GList *apps, *scan;
+	GnomeVFSMimeApplication *app;
+	char *label, *tip;
+	GtkAction *action;
+	EogWindowPrivate *priv;
+	guint merge_id;
+	
+	uri = eog_image_get_uri (image);
+	mime_type = gnome_vfs_get_mime_type (gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE));
+	
+	if (mime_type != NULL) {
+		apps = gnome_vfs_mime_get_all_applications (mime_type);
+		g_free (mime_type);
+
+		priv = window->priv;
+		priv->open_with_menu_ids = NULL;
+
+		for (scan = apps; scan; scan = scan->next) {
+			app = scan->data;
+			
+			/* do not include eog itself */
+			if (g_ascii_strncasecmp (gnome_vfs_mime_application_get_exec (app), "eog", 3) == 0)
+				continue;
+
+			label = g_strdup_printf (_("Open with \"%s\""), app->name);
+			tip = g_strdup_printf (_("Use \"%s\" to open the selected item"), app->name);
+			action = gtk_action_new (app->name, label, tip, NULL);
+			g_free (label);
+			g_free (tip);
+			
+			g_object_set_data (G_OBJECT (action), "app", 
+					app);
+
+			g_signal_connect (G_OBJECT (action),
+					  "activate",
+					  G_CALLBACK (open_with_launch_application_callback),
+					  uri);
+			
+			gtk_action_group_add_action (priv->actions_image, action);
+			
+			merge_id = gtk_ui_manager_new_merge_id (priv->ui_mgr);
+			priv->open_with_menu_ids = g_list_append (priv->open_with_menu_ids, GUINT_TO_POINTER (merge_id));
+
+			gtk_ui_manager_add_ui (priv->ui_mgr,
+			       		merge_id,
+			       		"/MainMenu/File/FileOpenWith/Applications Placeholder",
+			       		app->name,
+			       		app->name,
+			       		GTK_UI_MANAGER_MENUITEM,
+			       		FALSE);
+
+			gtk_ui_manager_add_ui (priv->ui_mgr,
+			       		merge_id,
+			       		"/ThumbnailPopup/FileOpenWith/Applications Placeholder",
+			       		app->name,
+			       		app->name,
+			       		GTK_UI_MANAGER_MENUITEM,
+			       		FALSE);
+		}
+		gnome_vfs_uri_unref (uri);
+		g_list_free (scan);
+		g_list_free (apps);
+	}
 }
 
 static void
@@ -1817,6 +1931,9 @@ static const GtkActionEntry action_entri
 	{ "FileSave", GTK_STOCK_SAVE, N_("_Save"), "<control>s", 
 	  NULL, 
 	  G_CALLBACK (eog_window_cmd_save) },
+	{ "FileOpenWith", NULL, N_("Open _with"), NULL,
+	  N_("Choose a program with which to open the selected item"),
+	  NULL},
 	{ "FileSaveAs", GTK_STOCK_SAVE_AS, N_("Save _As..."), "<control><shift>s", 
 	  NULL, 
 	  G_CALLBACK (eog_window_cmd_save_as) },
@@ -2365,6 +2482,8 @@ eog_window_init (EogWindow *window)
 		gtk_recent_manager_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
 
 	window->priv->recent_menu_id = 0;
+
+	window->priv->open_with_menu_ids = NULL;
 	
 	eog_window_construct_ui (window);
 }
@@ -2428,6 +2547,8 @@ eog_window_dispose (GObject *object)
 	}
 	
 	priv->recent_menu_id = 0;
+
+	priv->open_with_menu_ids = NULL;
 		
 	eog_window_clear_load_job (window);
 


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