Re: Attaching and quoting messages



>> Balsa would be greatly enhanced by a capability to attach or quote an
>> arbitrary message. The `File' menu could be expanded to:
>>   Include file...
>>   Include message
>>   Attach file...
>>   Attach message
>>   ...
>> where the `message' versions would refer to the currently selected
>> message.
> I implemented this a while back, but never got around to submitting a
> patch. I will do it in a short while (after I've finished some more
> urgent jobs.)
And here it is! The attached patch (against today's CVS version, as usual)
will insert 3 new menu items; "Include Message(s)" and "Attach Messages(s)
under "File", and "Quote Message(s)" under "Edit", where the "Quote"
version is different from the "Include" one in that reply style quote
characters are inserted. I'm not sure if that's the best way of
structuring it, but the menu items and quote types could be easily changed.

Also, I'm not too happy with the term "attach" (neither here nor in 
"Forward
attached") as the parts included are explicitly marked as "inline" (i.e.
we're explicitly telling the receiver they are NOT attachments - refer to
RFC 2183), but I couldn't think of a better alternative. I guess "Include
Message(s) as Separate Part(s)" would have been more accurate, but it's
somewhat long-winded.

--
- Toralf

Index: src/sendmsg-window.c
===================================================================
RCS file: /cvs/gnome/balsa/src/sendmsg-window.c,v
retrieving revision 1.313
diff -u -b -r1.313 sendmsg-window.c
--- src/sendmsg-window.c	2001/10/05 22:06:42	1.313
+++ src/sendmsg-window.c	2001/10/09 11:03:53
@@ -86,10 +86,13 @@
 static gint save_message_cb(GtkWidget *, BalsaSendmsg *);
 static gint print_message_cb(GtkWidget *, BalsaSendmsg *);
 static gint attach_clicked(GtkWidget *, gpointer);
+static void attach_message(BalsaSendmsg *msg, LibBalsaMessage *message);
+static gint insert_selected_messages(BalsaSendmsg *msg, SendType type);
+static gint attach_message_cb(GtkWidget *, BalsaSendmsg *);
+static gint include_message_cb(GtkWidget *, BalsaSendmsg *);
 static void close_window_cb(GtkWidget *, gpointer);
 static gchar* check_if_regular_file(const gchar *);
 static void balsa_sendmsg_destroy_handler(BalsaSendmsg * bsm);
-
 static void check_readiness(GtkEditable * w, BalsaSendmsg * bsmsg);
 static void init_menus(BalsaSendmsg *);
 static gint toggle_from_cb(GtkWidget *, BalsaSendmsg *);
@@ -118,6 +121,8 @@
 static void update_msg_identity(BalsaSendmsg*, LibBalsaIdentity*);
 
 static void sw_size_alloc_cb(GtkWidget * window, GtkAllocation * alloc);
+static GString *
+quoteBody(BalsaSendmsg * msg, LibBalsaMessage * message, SendType type);
 
 /* Standard DnD types */
 enum {
@@ -143,41 +148,47 @@
 static void reflow_par_cb(GtkWidget * widget, BalsaSendmsg * bsmsg);
 static void reflow_body_cb(GtkWidget * widget, BalsaSendmsg * bsmsg);
 static gint insert_signature_cb(GtkWidget *, BalsaSendmsg *);
+static gint quote_messages_cb(GtkWidget *, BalsaSendmsg *);
 
 static GnomeUIInfo file_menu[] = {
 #define MENU_FILE_INCLUDE_POS 0
     GNOMEUIINFO_ITEM_STOCK(N_("_Include File..."), NULL,
 			   include_file_cb, GNOME_STOCK_MENU_OPEN),
-
 #define MENU_FILE_ATTACH_POS 1
     GNOMEUIINFO_ITEM_STOCK(N_("_Attach File..."), NULL,
 			   attach_clicked, GNOME_STOCK_MENU_ATTACH),
-#define MENU_FILE_SEPARATOR1_POS 2
+#define MENU_MSG_INCLUDE_POS 2
+    GNOMEUIINFO_ITEM_STOCK(N_("_Include Message(s)"), NULL,
+			   include_message_cb, GNOME_STOCK_MENU_MAIL),
+#define MENU_FILE_ATTACH_MSG_POS 3
+    GNOMEUIINFO_ITEM_STOCK(N_("Attach _Message(s)"), NULL,
+			   attach_message_cb, GNOME_STOCK_MENU_MAIL_FWD),
+#define MENU_FILE_SEPARATOR1_POS 4
     GNOMEUIINFO_SEPARATOR,
 
-#define MENU_FILE_SEND_POS 3
+#define MENU_FILE_SEND_POS 5
     { GNOME_APP_UI_ITEM, N_("_Send"), 
       N_("Send this message"),
       send_message_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK,
       GNOME_STOCK_MENU_MAIL_SND, 'S', GDK_CONTROL_MASK, NULL },
-#define MENU_FILE_QUEUE_POS 4
+#define MENU_FILE_QUEUE_POS 6
     { GNOME_APP_UI_ITEM, N_("_Queue"), 
       N_("Queue this message in Outbox for sending"),
       queue_message_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK,
       GNOME_STOCK_MENU_MAIL_SND, 'Q', GDK_CONTROL_MASK, NULL },
-#define MENU_FILE_POSTPONE_POS 5
+#define MENU_FILE_POSTPONE_POS 7
     GNOMEUIINFO_ITEM_STOCK(N_("_Postpone"), NULL,
 			   postpone_message_cb, GNOME_STOCK_MENU_SAVE),
-#define MENU_FILE_SAVE_POS 6
+#define MENU_FILE_SAVE_POS 8
     GNOMEUIINFO_ITEM_STOCK(N_("_Save"), NULL,
 			   save_message_cb, GNOME_STOCK_MENU_SAVE),
-#define MENU_FILE_PRINT_POS 7
+#define MENU_FILE_PRINT_POS 9
     GNOMEUIINFO_ITEM_STOCK(N_("Print..."), N_("Print the edited message"),
 			   print_message_cb, GNOME_STOCK_MENU_PRINT),
-#define MENU_FILE_SEPARATOR2_POS 8
+#define MENU_FILE_SEPARATOR2_POS 10
     GNOMEUIINFO_SEPARATOR,
 
-#define MENU_FILE_CLOSE_POS 9
+#define MENU_FILE_CLOSE_POS 11
     GNOMEUIINFO_MENU_CLOSE_ITEM(close_window_cb, NULL),
 
     GNOMEUIINFO_END
@@ -202,23 +213,27 @@
     {GNOME_APP_UI_ITEM, N_("Insert _Signature"), NULL,
      (gpointer) insert_signature_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
      GDK_z, GDK_CONTROL_MASK, NULL},
+#define EDIT_MENU_QUOTE 8
+    {GNOME_APP_UI_ITEM, N_("_Quote Message(s)"), NULL,
+     (gpointer) quote_messages_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
+     0, 0, NULL},
     GNOMEUIINFO_SEPARATOR,
-#define EDIT_MENU_REFLOW_PARA 9
+#define EDIT_MENU_REFLOW_PARA 10
     {GNOME_APP_UI_ITEM, N_("_Reflow Paragraph"), NULL,
      (gpointer) reflow_par_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
      GDK_r, GDK_CONTROL_MASK, NULL},
-#define EDIT_MENU_REFLOW_MESSAGE 10
+#define EDIT_MENU_REFLOW_MESSAGE 11
     {GNOME_APP_UI_ITEM, N_("R_eflow Message"), NULL,
      (gpointer) reflow_body_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
      GDK_r, GDK_CONTROL_MASK | GDK_SHIFT_MASK, NULL},
     GNOMEUIINFO_SEPARATOR,
-#define EDIT_MENU_SPELL_CHECK 12
+#define EDIT_MENU_SPELL_CHECK 13
     GNOMEUIINFO_ITEM_STOCK(N_("_Check Spelling"), 
                            N_("Check the spelling of the message"),
                            spell_check_cb,
                            GNOME_STOCK_MENU_SPELLCHECK),
     GNOMEUIINFO_SEPARATOR,
-#define EDIT_MENU_SELECT_IDENT 14
+#define EDIT_MENU_SELECT_IDENT 15
     GNOMEUIINFO_ITEM_STOCK(N_("Select _Identity..."), 
                            N_("Select the Identity to use for the message"),
                            change_identity_dialog_cb,
@@ -910,6 +925,93 @@
     return TRUE;
 }
 
+static void attach_message(BalsaSendmsg *msg, LibBalsaMessage *message)
+{
+    gchar *name, tmp_file_name[PATH_MAX + 1];
+	
+    libbalsa_lock_mutt();
+    mutt_mktemp(tmp_file_name);
+    libbalsa_unlock_mutt();
+    mkdir(tmp_file_name, 0700);
+    name = g_strdup_printf("%s/forwarded-message", tmp_file_name);
+    libbalsa_message_save(message, name);
+    add_attachment(GNOME_ICON_LIST(msg->attachments[1]), name,
+		   TRUE, "message/rfc822");
+    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+	    msg->view_checkitems[MENU_TOGGLE_ATTACHMENTS_POS]), TRUE);
+}
+
+static gint insert_selected_messages(BalsaSendmsg *msg, SendType type)
+{
+    GtkWidget *index =
+	balsa_window_find_current_index(balsa_app.main_window);
+    gint pos=gtk_editable_get_position(GTK_EDITABLE(msg->text));
+    GString *text = g_string_new("");
+    
+    if (index) {
+	GList *node;
+	GList *mailbox;
+	GtkCTree *ctree = GTK_CTREE(BALSA_INDEX(index)->ctree);
+    
+	for (node = GTK_CLIST(ctree)->selection; node;
+	     node = g_list_next(node)) {
+	    LibBalsaMessage *message =
+		gtk_ctree_node_get_row_data(ctree, GTK_CTREE_NODE(node->data));
+	    GString *body = quoteBody(msg, message, type);
+	    
+	    g_string_append(text, body->str);
+	    g_string_free(body, TRUE);
+	}
+    }
+    
+    gtk_editable_insert_text(GTK_EDITABLE(msg->text), text->str,
+			     strlen(text->str), &pos);
+    g_string_free(text, TRUE);
+    
+    return TRUE;
+}
+
+static gint include_message_cb(GtkWidget *widget, BalsaSendmsg *msg)
+{
+    return insert_selected_messages(msg, SEND_FORWARD_INLINE);
+}
+
+
+static gint
+attach_message_cb(GtkWidget * widget, BalsaSendmsg *msg) 
+{
+    GtkWidget *index =
+	balsa_window_find_current_index(balsa_app.main_window);
+    gint pos=gtk_editable_get_position(GTK_EDITABLE(msg->text));
+    GString *text = g_string_new("");
+    
+    if (index) {
+	GList *node;
+	GList *mailbox;
+	GtkCTree *ctree = GTK_CTREE(BALSA_INDEX(index)->ctree);
+    
+	for (node = GTK_CLIST(ctree)->selection; node;
+	     node = g_list_next(node)) {
+	    LibBalsaMessage *message =
+		gtk_ctree_node_get_row_data(ctree, GTK_CTREE_NODE(node->data));
+
+	    attach_message(msg, message);
+	}
+    }
+    
+    gtk_editable_insert_text(GTK_EDITABLE(msg->text), text->str,
+			     strlen(text->str), &pos);
+    g_string_free(text, TRUE);
+    
+    return TRUE;
+}
+
+
+static gint include_messages_cb(GtkWidget *widget, BalsaSendmsg *msg)
+{
+    return insert_selected_messages(msg, SEND_FORWARD_INLINE);
+}
+
 /* attachments_add - attachments field D&D callback */
 static void
 attachments_add(GtkWidget * widget,
@@ -1512,6 +1614,13 @@
     return TRUE;
 }
 
+
+static gint quote_messages_cb(GtkWidget *widget, BalsaSendmsg *msg)
+{
+    return insert_selected_messages(msg, SEND_REPLY);
+}
+
+
 /* set_entry_to_subject:
    set subject entry based on given replied/forwarded/continued message
    and the compose type.
@@ -1880,18 +1989,7 @@
 	gtk_widget_grab_focus(msg->text);
 
     if (type == SEND_FORWARD_ATTACH) {
- 	gchar *name, tmp_file_name[PATH_MAX + 1];
-	
- 	libbalsa_lock_mutt();
- 	mutt_mktemp(tmp_file_name);
- 	libbalsa_unlock_mutt();
- 	mkdir(tmp_file_name, 0700);
- 	name = g_strdup_printf("%s/forwarded-message", tmp_file_name);
- 	libbalsa_message_save(message, name);
- 	add_attachment(GNOME_ICON_LIST(msg->attachments[1]), name,
- 		       TRUE, "message/rfc822");
- 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
-	    msg->view_checkitems[MENU_TOGGLE_ATTACHMENTS_POS]), TRUE);
+	attach_message(msg, message);
     }
 
     if (type == SEND_CONTINUE && 


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