Re: *Please* make this configurable....



Am 28.08.07 21:39 schrieb(en) Albrecht Dreß:
I am using this patch here, and could re-post it...

... and it seems 2b limited to one single source file. The gui clearly needs some polish, but would this meets your intentions?

Cheers, Albrecht.


--
Albrecht Dreß - Johanna-Kirchner-Straße 13 - D-53123 Bonn (Germany)
       Phone (+49) 228 6199571  -  mailto:albrecht dress arcor de
  GnuPG public key:  http://www.mynetcologne.de/~nc-dreszal/pubkey.asc
Index: src/sendmsg-window.c
===================================================================
--- src/sendmsg-window.c	(Revision 7684)
+++ src/sendmsg-window.c	(Arbeitskopie)
@@ -54,6 +54,7 @@
 #include "libbalsa.h"
 #include "misc.h"
 #include "send.h"
+#include "html.h"
 
 #include "balsa-app.h"
 #include "balsa-message.h"
@@ -2782,7 +2783,6 @@
     g_free(sstr);
 }
 
-
 /* create_info_pane 
    creates upper panel with the message headers: From, To, ... and 
    returns it.
@@ -3277,6 +3277,291 @@
     return subject;
 }
 
+/* --- stuff for collecting parts for a reply --- */
+
+static GList *
+scan_bodies(GList * list, LibBalsaMessageBody * body, gboolean ignore_html,
+	    gboolean container_mp_alt)
+{
+    gchar * mime_type;
+
+    while (body) {
+	switch (libbalsa_message_body_type(body)) {
+	case LIBBALSA_MESSAGE_BODY_TYPE_TEXT:
+	    {
+		gchar *mime_type;
+		LibBalsaHTMLType html_type;
+
+		mime_type = libbalsa_message_body_get_mime_type(body);
+		html_type = libbalsa_html_type(mime_type);
+		g_free(mime_type);
+
+		/* On a multipart/alternative, ignore_html defines if html or
+		 * non-html parts will be added. Eject from the container when
+		 * the first part has been found.
+		 * Otherwise, select all text parts. */
+		if (container_mp_alt) {
+		    if ((ignore_html && html_type == LIBBALSA_HTML_TYPE_NONE) ||
+			(!ignore_html && html_type != LIBBALSA_HTML_TYPE_NONE)) {
+			list = g_list_append(list, body);
+			return list;
+		    }
+		} else
+		    list = g_list_append(list, body);
+		break;
+	    }
+
+	case LIBBALSA_MESSAGE_BODY_TYPE_MULTIPART:
+	case LIBBALSA_MESSAGE_BODY_TYPE_MESSAGE:
+	    mime_type = libbalsa_message_body_get_mime_type(body);
+	    list = scan_bodies(list, body->parts, ignore_html,
+			       !g_ascii_strcasecmp(mime_type, "multipart/alternative"));
+	    g_free(mime_type);
+	    break;
+
+	default:
+	    break;
+	}
+
+	body = body->next;
+    }
+
+    return list;
+}
+
+enum {
+    QUOTE_INCLUDE,
+    QUOTE_MIME_TYPE,
+    QUOTE_DISP_TYPE,
+    QUOTE_FILENAME,
+    QUOTE_BODY,
+    QOUTE_NUM_ELEMS
+};
+
+static void
+list_add_quote_body(LibBalsaMessageBody * body, GtkListStore * store)
+{
+    GtkTreeIter iter;
+    gchar * mime_type = libbalsa_message_body_get_mime_type(body);
+    const gchar * disp_type;
+    static gboolean preselect;
+
+    gtk_list_store_append(store, &iter);
+    if (body->mime_part)
+	disp_type = g_mime_part_get_content_disposition(GMIME_PART(body->mime_part));
+    else
+	disp_type = NULL;
+    preselect = !disp_type || *disp_type == '\0' ||
+	!g_ascii_strcasecmp(disp_type, "inline");
+    gtk_list_store_set(store, &iter,
+		       QUOTE_INCLUDE, preselect,
+		       QUOTE_MIME_TYPE, mime_type,
+		       QUOTE_DISP_TYPE, disp_type,
+		       QUOTE_FILENAME, body->filename,
+		       QUOTE_BODY, body,
+		       -1);
+    g_free(mime_type);
+}
+
+static void
+cell_toggled_cb(GtkCellRendererToggle *cell, gchar *path_str, GtkTreeView *treeview)
+{
+    GtkTreeModel *model = NULL;
+    GtkTreePath *path;
+    GtkTreeIter iter;
+    gboolean active;
+  
+    g_return_if_fail (GTK_IS_TREE_VIEW (treeview));
+    if (!(model = gtk_tree_view_get_model(treeview)))
+	return;
+
+    path = gtk_tree_path_new_from_string(path_str);
+    if (!gtk_tree_model_get_iter(model, &iter, path))
+	return;
+    gtk_tree_path_free(path);
+  
+    gtk_tree_model_get(GTK_TREE_MODEL (model),
+		       &iter,
+		       QUOTE_INCLUDE, &active,
+		       -1);
+    gtk_list_store_set(GTK_LIST_STORE (model),
+		       &iter,
+		       QUOTE_INCLUDE, !active,
+		       -1);
+}
+
+static GList *
+quote_parts_select_dlg(GList * body_list, GtkWindow * parent)
+{
+    GtkWidget *dialog;
+    GtkWidget *label;
+    GtkWidget *image;
+    GtkWidget *hbox;
+    GtkWidget *vbox;
+    GtkListStore *list_store;
+    GtkWidget *list_view;
+    GtkTreeViewColumn *column;
+    GtkCellRenderer *renderer;
+    GList *result = NULL;
+
+    dialog = gtk_dialog_new_with_buttons(_("Select parts for quotation"),
+					 parent,
+					 GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_STOCK_OK, GTK_RESPONSE_OK,
+					 NULL);
+
+    label = gtk_label_new(_("Select the parts of the message which shall be quoted in the reply"));
+    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+    gtk_label_set_selectable(GTK_LABEL(label), TRUE);
+    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+    image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION,
+				     GTK_ICON_SIZE_DIALOG);
+    gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.0);
+
+    /* stolen form gtk/gtkmessagedialog.c */
+    hbox = gtk_hbox_new (FALSE, 12);
+    vbox = gtk_vbox_new (FALSE, 12);
+
+    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
+		       FALSE, 0);
+
+    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+    gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), 14);
+
+    /* add the table */
+    list_store = gtk_list_store_new(QOUTE_NUM_ELEMS,
+				    G_TYPE_BOOLEAN, G_TYPE_STRING,
+				    G_TYPE_STRING, G_TYPE_STRING,
+				    G_TYPE_POINTER);
+    g_list_foreach(body_list, (GFunc) list_add_quote_body, list_store);
+    list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
+    renderer = gtk_cell_renderer_toggle_new();
+    g_signal_connect(renderer, "toggled", G_CALLBACK(cell_toggled_cb),
+		     list_view);
+    column = gtk_tree_view_column_new_with_attributes(_("Add"),
+						      renderer,
+						      "active", QUOTE_INCLUDE,
+                                                      NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
+    column = gtk_tree_view_column_new_with_attributes(_("Type"),
+						      gtk_cell_renderer_text_new(),
+						      "text", QUOTE_MIME_TYPE,
+						      NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
+    column = gtk_tree_view_column_new_with_attributes(_("Mode"),
+						      gtk_cell_renderer_text_new(),
+						      "text", QUOTE_DISP_TYPE,
+                                                      NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
+    column = gtk_tree_view_column_new_with_attributes(_("File name"),
+						      gtk_cell_renderer_text_new(),
+						      "text", QUOTE_FILENAME,
+                                                      NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
+    
+    /* add, show & run */
+    gtk_box_pack_start(GTK_BOX(vbox), list_view, FALSE, FALSE, 0);
+    gtk_widget_show_all(hbox);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
+	GtkTreeIter iter;
+	
+	/* build & return a new list with the selected parts */
+	gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &iter);
+	do {
+	    gboolean use_in_quote;
+	    
+	    gtk_tree_model_get(GTK_TREE_MODEL(list_store),
+			       &iter,
+			       QUOTE_INCLUDE,
+			       &use_in_quote,
+			       -1);
+	    if (use_in_quote) {
+		LibBalsaMessageBody *this_body;
+
+		gtk_tree_model_get(GTK_TREE_MODEL(list_store),
+				   &iter,
+				   QUOTE_BODY,
+				   &this_body,
+				   -1);
+		result = g_list_append(result, this_body);
+	    }
+	} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter));
+    }
+
+    /* clean up */
+    g_object_unref(G_OBJECT(list_store));
+    gtk_widget_destroy(dialog);
+    return result;
+}
+
+static GString *
+collect_for_quote(LibBalsaMessageBody *root, gchar * reply_prefix_str,
+		  gint llen, gboolean ignore_html, gboolean flow,
+		  LibBalsaCharsetFunc charset_cb, gpointer charset_cb_data)
+{
+    GList *body_list;
+    LibBalsaMessage *message = root->message;
+    GString *q_body;
+    GList *quote_list;
+
+    libbalsa_message_body_ref(message, FALSE, FALSE);
+
+    /* scan the message and collect text parts which might be included
+     * in the reply, and if there is only one return this part */
+    if (!(body_list = scan_bodies(NULL, root, ignore_html, FALSE))) {
+	libbalsa_message_body_unref(message);
+	return NULL;
+    } else if (body_list->next == NULL) {
+	q_body = process_mime_part(message,
+				   (LibBalsaMessageBody *) body_list->data,
+				   reply_prefix_str, llen, FALSE, flow,
+				   charset_cb, charset_cb_data);
+	g_list_free(body_list);
+	libbalsa_message_body_unref(message);
+	return q_body;
+    }
+
+    /* if there is more than one part ask the user if all should be added */
+    quote_list = quote_parts_select_dlg(body_list, NULL);
+    g_list_free(body_list);
+
+    /* quote selected parts... */
+    q_body = NULL;
+    for (body_list = quote_list; body_list; body_list = g_list_next(body_list)) {
+	LibBalsaMessageBody *this_body = (LibBalsaMessageBody *) body_list->data;
+	GString * this_part;
+
+	this_part = process_mime_part(message, this_body,
+				      reply_prefix_str, llen, FALSE, flow,
+				      charset_cb, charset_cb_data);
+	if (!q_body)
+	    q_body = this_part;
+	else {
+	    if (q_body->str[q_body->len - 1] != '\n')
+		g_string_append_c(q_body, '\n');
+	    if (this_body->filename)
+		g_string_append_printf(q_body, "\n------%s \"%s\"------\n",
+				       _("quoted attachment"), this_body->filename);
+	    else
+		g_string_append_printf(q_body, "\n------%s------\n",
+				       _("quoted attachment"));
+	    g_string_append(q_body, this_part->str);
+	    g_string_free(this_part, TRUE);
+	}
+    }
+
+    /* clean up */
+    g_list_free(quote_list);
+    libbalsa_message_body_unref(message);
+    return q_body;
+}
+
+
 /* quote_body -----------------------------------------------------------
    quotes properly the body of the message.
    Use GString to optimize memory usage.
@@ -3369,11 +3654,14 @@
 	    str = g_strdup_printf(_("On %s, %s wrote:\n"), date, personStr);
 	else
 	    str = g_strdup_printf(_("%s wrote:\n"), personStr);
-	body = content2reply(root,
-                             qtype == QUOTE_ALL ? balsa_app.quote_str : NULL,
-			     bsmsg->flow ? -1 : balsa_app.wraplength,
-			     balsa_app.reply_strip_html, bsmsg->flow,
-			     sw_charset_cb, bsmsg);
+
+	/* scan the message and collect text parts which might be included
+	 * in the reply */
+	body = collect_for_quote(root,
+				 qtype == QUOTE_ALL ? balsa_app.quote_str : NULL,
+				 bsmsg->flow ? -1 : balsa_app.wraplength,
+				 balsa_app.reply_strip_html, bsmsg->flow,
+				 sw_charset_cb, bsmsg);
 	if (body) {
 	    gchar *buf;
 
@@ -5285,7 +5573,7 @@
     gtk_box_pack_start (GTK_BOX (dialog_vbox), hbox, TRUE, TRUE, 0);
     gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
 
-    image = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_DIALOG);
+    image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
     gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
     gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
 
@@ -5316,7 +5604,7 @@
     dialog_action_area = GTK_DIALOG (no_subj_dialog)->action_area;
     gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area), GTK_BUTTONBOX_END);
 
-    cnclbutton = gtk_button_new_from_stock ("gtk-cancel");
+    cnclbutton = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
     gtk_dialog_add_action_widget (GTK_DIALOG (no_subj_dialog), cnclbutton, GTK_RESPONSE_CANCEL);
     GTK_WIDGET_SET_FLAGS (cnclbutton, GTK_CAN_DEFAULT);
 
@@ -5332,7 +5620,7 @@
     hbox = gtk_hbox_new (FALSE, 2);
     gtk_container_add (GTK_CONTAINER (alignment), hbox);
 
-    image = gtk_image_new_from_stock ("balsa_send", GTK_ICON_SIZE_BUTTON);
+    image = gtk_image_new_from_stock (BALSA_PIXMAP_SEND, GTK_ICON_SIZE_BUTTON);
     gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
 
     label = gtk_label_new_with_mnemonic (_("_Send"));

Attachment: pgpYkieRPcTsH.pgp
Description: PGP signature



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