GnomeVFS



I was just exploring the wonders of GnomeVFS to be able to resolve various
MIME issues reported to me by internal users, so I thought I might as well
try to hack balsa a bit, too. Here is what I did (see attachment.)

Notes:
1. I don't consider my code to be complete or well-tested in any sense, but
it does improve the functionality quite a bit in my environment.
2. I haven't implemented any configure tests, related macros etc; I've just
hacked src/Makefile.am for now.
3. Unfortunately, gnome-vfs leaves a lot to be desired when it comes to
compatibility with older apps, e.g. it doesn't do anything productive with
"open", "view" and "edit" keys (except for providing an API for returning
their values, i.e. an alternative to gnome_mime_get_value() etc.) I
therefore
kept the old gnome_mime... calls.

-- 
Toralf Lund <toralf@kscanners.com>  +47 66 85 51 22
Kongsberg Scanners AS               +47 66 85 51 00 (switchboard)
http://www.kscanners.no/~toralf     +47 66 85 51 01 (fax)
Index: src/balsa-message.c
===================================================================
RCS file: /cvs/gnome/balsa/src/balsa-message.c,v
retrieving revision 1.176
diff -u -r1.176 balsa-message.c
--- src/balsa-message.c	2001/08/28 09:24:31	1.176
+++ src/balsa-message.c	2001/08/29 13:30:45
@@ -51,6 +51,8 @@
 #include "quote-color.h"
 #include "sendmsg-window.h"
 
+#include <libgnomevfs/gnome-vfs-mime-handlers.h>
+
 #define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
 
 enum {
@@ -154,8 +156,10 @@
 static void part_info_init_html(BalsaMessage * bm, BalsaPartInfo * info,
 				gchar * ptr, size_t len);
 #endif
+static GtkWidget* part_info_mime_button_vfs (BalsaPartInfo* info, const gchar* content_type);
 static GtkWidget* part_info_mime_button (BalsaPartInfo* info, const gchar* content_type, const gchar* key);
 static void part_context_menu_cb(GtkWidget * menu_item, BalsaPartInfo * info);
+static void part_context_menu_vfs_cb(GtkWidget * menu_item, BalsaPartInfo * info);
 static void part_create_menu (BalsaPartInfo* info);
 
 static GtkViewportClass *parent_class = NULL;
@@ -818,7 +822,7 @@
     GtkWidget *vbox;
     GtkWidget *button;
     gchar *msg;
-    const gchar *cmd;
+    const gchar *cmd, *content_desc;
     gchar *content_type;
     
 
@@ -826,7 +830,9 @@
     gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
 
     content_type = libbalsa_message_body_get_content_type(info->body);
-    if ((cmd = gnome_mime_get_value(content_type, "view")) != NULL) {
+    if((button=part_info_mime_button_vfs(info, content_type))) {
+	gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 2);
+    } else if ((cmd = gnome_mime_get_value(content_type, "view")) != NULL) {
         button = part_info_mime_button (info, content_type, "view");
 	gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 2);
     } else if ((cmd = gnome_mime_get_value (content_type, "open")) != NULL) {
@@ -837,8 +843,12 @@
 			   gtk_label_new(_("No open or view action defined in GNOME MIME for this content type")),
 			   FALSE, FALSE, 1);
     }
+    
+    if((content_desc=gnome_vfs_mime_get_description(content_type)))
+	msg = g_strdup_printf(_("Type: %s (%s)"), content_desc, content_type);
+    else
+	msg = g_strdup_printf(_("Content Type: %s"), content_type);
 
-    msg = g_strdup_printf(_("Content Type: %s"), content_type);
     gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(msg), FALSE, FALSE, 1);
     g_free(msg);
 
@@ -888,6 +898,33 @@
 }
 
 
+static GtkWidget*
+part_info_mime_button_vfs (BalsaPartInfo* info, const gchar* content_type)
+{
+    GtkWidget* button=NULL;
+    gchar* msg;
+    const gchar* cmd;
+    GnomeVFSMimeApplication *app=
+	gnome_vfs_mime_get_default_application(content_type);
+
+    if(app) {
+	cmd = app->command;
+	msg = g_strdup_printf(_("View part with %s"), app->name);
+	button = gtk_button_new_with_label(msg);
+	gtk_object_set_data (GTK_OBJECT (button), "mime_action", 
+			     (gpointer) g_strdup(app->id)); /* *** */
+	g_free(msg);
+
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			   (GtkSignalFunc) part_context_menu_vfs_cb,
+			   (gpointer) info);
+
+	gnome_vfs_mime_application_free(app);
+	
+    }
+    return button;
+}
+
 static void
 display_multipart(BalsaMessage * bm, LibBalsaMessageBody * body)
 {
@@ -1885,30 +1922,58 @@
 	display_part(bm, body);
 }
 
+static void add_vfs_menu_item(BalsaPartInfo *info, 
+			      const GnomeVFSMimeApplication *app)
+{
+    gchar *menu_label = g_strdup_printf(_("Open with %s"), app->name);
+    GtkWidget *menu_item = gtk_menu_item_new_with_label (menu_label);
+    
+    gtk_object_set_data (GTK_OBJECT (menu_item), "mime_action", 
+			 g_strdup(app->id));
+    gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+			GTK_SIGNAL_FUNC (part_context_menu_vfs_cb),
+			(gpointer) info);
+    gtk_menu_append (GTK_MENU (info->popup_menu), menu_item);
+    g_free (menu_label);
+}
+
 
 static void
 part_create_menu (BalsaPartInfo* info) 
 {
     GtkWidget* menu_item;
     GList* list;
-    GList* key_list;
+    GList* key_list, *app_list;
     gchar* content_type;
     gchar* key;
     const gchar* cmd;
     gchar* menu_label;
     gchar** split_key;
     gint i;
-    
+    GnomeVFSMimeApplication *app;
+
     info->popup_menu = gtk_menu_new ();
     
     content_type = libbalsa_message_body_get_content_type (info->body);
     key_list = list = gnome_mime_get_keys (content_type);
     
+    /* Add default GnomeVFS application first of all. Not included in 
+       "short list" looped below, I think. */
+    if((app=gnome_vfs_mime_get_default_application(content_type))) {
+	add_vfs_menu_item(info, app);
+	gnome_vfs_mime_application_free(app);
+    }
+
+
     while (list) {
         key = list->data;
 
         if (key && g_strcasecmp (key, "icon-filename") 
-	    && g_strncasecmp (key, "fm-", 3)) {
+	    && g_strncasecmp (key, "fm-", 3)
+	    /* Get rid of additional GnomeVFS entries: */
+	    && (!strstr(key, "_") || strstr(key, "."))
+	    && g_strncasecmp(key, "description", 11)) {
+	    
             if ((cmd = gnome_mime_get_value (content_type, key)) != NULL) {
                 if (g_strcasecmp (key, "open") == 0 || 
                     g_strcasecmp (key, "view") == 0 || 
@@ -1930,19 +1995,31 @@
                     g_strfreev (split_key);
                 }
                 
-                menu_item = gtk_menu_item_new_with_label (menu_label);
-                gtk_object_set_data (GTK_OBJECT (menu_item), "mime_action", 
-                                     key);
-                gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
-                                    GTK_SIGNAL_FUNC (part_context_menu_cb),
-                                    (gpointer) info);
-                gtk_menu_append (GTK_MENU (info->popup_menu), menu_item);
-                g_free (menu_label);
-            }
+		menu_item = gtk_menu_item_new_with_label (menu_label);
+		gtk_object_set_data (GTK_OBJECT (menu_item), "mime_action", 
+					 key);
+		gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+				    GTK_SIGNAL_FUNC (part_context_menu_cb),
+				    (gpointer) info);
+		gtk_menu_append (GTK_MENU (info->popup_menu), menu_item);
+		g_free (menu_label);
+	    }
         }
         list = g_list_next (list);
     }
+    
+    app_list=list=gnome_vfs_mime_get_short_list_applications(content_type);
+
+    while (list) {
+	app=list->data;
+
+	if(app)
+	    add_vfs_menu_item(info, app);
+	
+        list = g_list_next (list);
+    }
 
+
     menu_item = gtk_menu_item_new_with_label (_("Save..."));
     gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
                         GTK_SIGNAL_FUNC (part_context_menu_save),
@@ -1952,6 +2029,7 @@
     gtk_widget_show_all (info->popup_menu);
 
     g_list_free (key_list);
+    gnome_vfs_mime_application_list_free (app_list);
     g_free (content_type);
 }
 
@@ -2029,6 +2107,38 @@
 
     g_free(content_type);
 }
+
+
+static void
+part_context_menu_vfs_cb(GtkWidget * menu_item, BalsaPartInfo * info)
+{
+    gchar *id;
+    
+    if(id = gtk_object_get_data (GTK_OBJECT (menu_item), "mime_action")) {
+	GnomeVFSMimeApplication *app=
+	    gnome_vfs_mime_application_new_from_id(id);
+	if(app) {
+	    if (libbalsa_message_body_save_temporary(info->body, NULL)) {
+		gchar *exe_str=
+		    g_strdup_printf("%s %s%s", app->command,
+				    (app->expects_uris==GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS?"file:":""),
+				    info->body->temp_filename);
+		
+		gnome_execute_shell(NULL, exe_str);
+		fprintf(stderr, "Executed: %s\n", exe_str);
+		g_free (exe_str);
+	    } else {
+		balsa_information(LIBBALSA_INFORMATION_WARNING,
+				  _("could not create temporary file %s"),
+				  info->body->temp_filename);
+	    }
+	    gnome_vfs_mime_application_free(app);    
+	} else {
+	    fprintf(stderr, "lookup for application %s returned NULL\n", id);
+	}
+    }
+}
+
 
 
 void
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/balsa/src/Makefile.am,v
retrieving revision 1.101
diff -u -r1.101 Makefile.am
--- src/Makefile.am	2001/08/24 23:22:42	1.101
+++ src/Makefile.am	2001/08/29 13:30:45
@@ -76,6 +76,7 @@
 	$(top_builddir)/libmutt/imap/libimap.a	\
 	$(top_builddir)/libmutt/libmutt.a	\
 	$(top_builddir)/libinit_balsa/libinit_balsa.a \
+	-lgnomevfs\
 	-lpspell \
 	-lltdl \
 	$(INTLLIBS) \


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