Re: PATCH: Display (additional) inline parts



On 2001.09.03 15:36 Toralf Lund wrote:
> The attached patch attempts to modify the message preview code so that
> more
> than one part may be visible at at time; in addition to the one selected,
> "inline" parts on the "same level" will be displayed. The idea is mainly
> to
> show the contents of correctly forwarded messages (refer to last week's
> discussion on the list) directly.
Right. I didn't really attach anything, did I? Well, here it is.

- Toralf
Index: src/balsa-message.c
===================================================================
RCS file: /cvs/gnome/balsa/src/balsa-message.c,v
retrieving revision 1.177
diff -u -b -r1.177 balsa-message.c
--- src/balsa-message.c	2001/08/29 11:56:38	1.177
+++ src/balsa-message.c	2001/09/03 13:42:36
@@ -33,6 +33,9 @@
 #include "mime.h"
 #include "misc.h"
 
+#include <libmutt/mutt.h>
+#include <libmutt/mime.h>
+
 #ifdef USE_PIXBUF
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #endif
@@ -230,8 +233,16 @@
 {
     bm->table = gtk_table_new(3, 1, FALSE);
     gtk_container_add(GTK_CONTAINER(bm), bm->table);
+
     gtk_widget_show(bm->table);
 
+    bm->content = gtk_vbox_new(FALSE, 0);
+
+    gtk_table_attach(GTK_TABLE(bm->table), bm->content, 0, 1, 1,
+		     2, GTK_EXPAND | GTK_FILL,
+		     GTK_EXPAND | GTK_FILL, 0, 1);
+    gtk_widget_show(bm->content);
+
     bm->header_text = gtk_text_new(NULL, NULL);
     gtk_signal_connect(GTK_OBJECT(bm->header_text), "key_press_event",
 		       (GtkSignalFunc) balsa_message_key_press_event,
@@ -246,7 +257,7 @@
     bm->part_list = gnome_icon_list_new(100, NULL, FALSE);
 
     gnome_icon_list_set_selection_mode(GNOME_ICON_LIST(bm->part_list),
-				       GTK_SELECTION_SINGLE);
+				       GTK_SELECTION_MULTIPLE);
     gtk_signal_connect(GTK_OBJECT(bm->part_list), "select_icon",
 		       GTK_SIGNAL_FUNC(select_icon_cb), bm);
     gtk_signal_connect(GTK_OBJECT(bm->part_list), "size_request",
@@ -839,6 +850,7 @@
     }
 
     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);
 
@@ -2039,26 +2051,28 @@
     select_part(bmessage, index);
 }
 
-/* 
- * If part == -1 then change to no part
- * must release selection before hiding a text widget.
- */
-static void
-select_part(BalsaMessage * bm, gint part)
+static gboolean part_contains(const LibBalsaMessageBody *part, 
+			      const LibBalsaMessageBody *check_part)
 {
-    BalsaPartInfo *info;
+    if(part==check_part)
+	return TRUE;
+    else if(part->parts) {
+	LibBalsaMessageBody *child_part;
 
-    if (bm->current_part && bm->current_part->widget) {
-	if(GTK_IS_EDITABLE(bm->current_part->widget) && 
-	   GTK_WIDGET_REALIZED(bm->current_part->widget))
-	    gtk_editable_claim_selection(
-		GTK_EDITABLE(bm->current_part->widget), FALSE, 
-		GDK_CURRENT_TIME);
-	gtk_widget_hide(bm->current_part->widget);
-	gtk_container_remove(GTK_CONTAINER(bm->table),
-			     bm->current_part->widget);
+	for(child_part=part->parts; child_part; child_part=child_part->next) {
+	    if(part_contains(child_part, check_part)) {
+		return TRUE;
+	    }
+	}
     }
+    return FALSE;
+}
 
+static BalsaPartInfo *add_part(BalsaMessage *bm, gint part)
+{
+    gchar *content_type;
+    BalsaPartInfo *info=NULL;
+
     if (part != -1) {
 	info = (BalsaPartInfo *) gnome_icon_list_get_icon_data
 	    (GNOME_ICON_LIST(bm->part_list), part);
@@ -2069,29 +2083,76 @@
 	    part_info_init(bm, info);
 
 	if (info->widget) {
+	    gtk_container_add(GTK_CONTAINER(bm->content), info->widget);
 	    gtk_widget_show(info->widget);
-	    gtk_table_attach(GTK_TABLE(bm->table), info->widget, 0, 1, 1,
-			     2, GTK_EXPAND | GTK_FILL,
-			     GTK_EXPAND | GTK_FILL, 0, 1);
-	} else {
-	    /* HACK! This is a spacer, so that the attachment icons
-	     * will stay at the bottom of the window.
-	     */
-	    GtkWidget *box;
+	} 
+	gnome_icon_list_select_icon(GNOME_ICON_LIST(bm->part_list), part);
+
+	/* FIXME: Find ancestor with message type multipart/mixed or similar,
+	          then loop. */
+	if(TRUE /* FIXME: Config: "Display inline parts." */) {
+	    gboolean found=FALSE;
+	    
+	    for(part=part+1; part<bm->part_count && !found; part++) {
+		BalsaPartInfo *part_info=(BalsaPartInfo *) gnome_icon_list_get_icon_data
+		    (GNOME_ICON_LIST(bm->part_list), part);
+		LibBalsaMessageBody *body;
 
-	    box = gtk_hbox_new(FALSE, FALSE);
-	    gtk_widget_show(box);
-	    gtk_table_attach(GTK_TABLE(bm->table), box, 0, 1, 1, 2,
-			     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
-			     0, 0);
+		for(body=info->body->next; body && !found; body=body->next) {
+		    if(body->mutt_body && 
+		       body->mutt_body->disposition==DISPINLINE && 
+		       part_contains(body, part_info->body)) {
+			found=TRUE;
+			add_part(bm, part);
 	}
-	bm->current_part = info;
-	gtk_signal_emit(GTK_OBJECT(bm),
-			balsa_message_signals[SELECT_PART]);
-    } else {
-	bm->current_part = NULL;
     }
+	    }
+	}
+    }
 
+    return info;
+}
+
+static void hide_all_parts(BalsaMessage *bm)
+{
+    if(bm->current_part) {
+	gint part;
+
+	for(part=0; part<bm->part_count; part++) {
+	    BalsaPartInfo *current_part=(BalsaPartInfo *) gnome_icon_list_get_icon_data
+		(GNOME_ICON_LIST(bm->part_list), part);
+	    
+	    if(current_part && current_part->widget && 
+	       GTK_WIDGET_VISIBLE(current_part->widget)) {
+		if(GTK_IS_EDITABLE(current_part->widget) && 
+		   GTK_WIDGET_REALIZED(current_part->widget))
+		    gtk_editable_claim_selection(
+						 GTK_EDITABLE(current_part->widget), FALSE, 
+						 GDK_CURRENT_TIME);
+		gtk_widget_hide(current_part->widget);
+		gtk_container_remove(GTK_CONTAINER(bm->content),
+				     current_part->widget);
+	    }
+	    gnome_icon_list_unselect_icon(GNOME_ICON_LIST(bm->part_list), part);
+	}
+    }
+}
+
+
+/* 
+ * If part == -1 then change to no part
+ * must release selection before hiding a text widget.
+ */
+static void
+select_part(BalsaMessage * bm, gint part)
+{
+    hide_all_parts(bm);
+
+    bm->current_part = add_part(bm, part);
+
+    if(bm->current_part)
+	gtk_signal_emit(GTK_OBJECT(bm),
+			balsa_message_signals[SELECT_PART]);
 
     scroll_set(GTK_VIEWPORT(bm)->hadjustment, 0);
     scroll_set(GTK_VIEWPORT(bm)->vadjustment, 0);


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