External-editor support, better maildir guessing
- From: Jelmer Vernooij <jelmer lintux cx>
- To: balsa-list gnome org
- Subject: External-editor support, better maildir guessing
- Date: Tue, 25 Dec 2001 17:13:08 +0100
Hi!
Here's my next patch, features:
- External editor support
- Mutt-like external editor support (edit the headers with the
external editor too). (Checkbox)
- Try whether $HOME/mail, $HOME/Mail or $HOME/nsmail exist and default
to $HOME/mail if none of them exists. (The balsa startup wizard now
guesses all my settings correctly :)
Notes:
- The external editor support is not very heavily tested, might have
bugs..
- I have used the identity icon for 'edit with external editor'.
We need a more appropriate icon.
Time to shut down my computer :) Merry christmas to all!
Jelmer
--
Jelmer Vernooij <jelmer@nl.linux.org> - http://nl.linux.org/~jelmer/
Development And Underdevelopment: http://library.thinkquest.org/C0110231/
Listening to Garbage: Cherry Lips
16:58:15 up 8 days, 41 min, 11 users, load average: 0.60, 0.50, 0.33
Index: src/balsa-app.h
===================================================================
RCS file: /cvs/gnome/balsa/src/balsa-app.h,v
retrieving revision 1.163
diff -u -r1.163 balsa-app.h
--- src/balsa-app.h 2001/12/05 22:49:11 1.163
+++ src/balsa-app.h 2001/12/25 16:08:23
@@ -272,6 +272,10 @@
gboolean previewpane;
gboolean debug;
+ /* external editor */
+ gchar *extern_editor_command;
+ gboolean extern_editor_mutt_like;
+
/* arp --- string to prefix "replied to" messages. */
gchar *quote_str;
Index: src/pref-manager.c
===================================================================
RCS file: /cvs/gnome/balsa/src/pref-manager.c,v
retrieving revision 1.185
diff -u -r1.185 pref-manager.c
--- src/pref-manager.c 2001/12/08 15:04:20 1.185
+++ src/pref-manager.c 2001/12/25 16:08:29
@@ -103,6 +103,10 @@
GtkWidget *debug_message_menu;
GtkWidget *fatal_message_menu;
+ /* External editor preferences */
+ GtkWidget *extern_editor_command;
+ GtkWidget *extern_editor_mutt_like;
+
/* arp */
GtkWidget *quote_str;
@@ -408,6 +412,14 @@
gtk_signal_connect(GTK_OBJECT(pui->forward_attached), "toggled",
GTK_SIGNAL_FUNC(properties_modified_cb), property_box);
+ /* external editor */
+ gtk_signal_connect(GTK_OBJECT(pui->extern_editor_command), "changed",
+ GTK_SIGNAL_FUNC(properties_modified_cb),
+ property_box);
+ gtk_signal_connect(GTK_OBJECT(pui->extern_editor_mutt_like), "toggled",
+ GTK_SIGNAL_FUNC(properties_modified_cb),
+ property_box);
+
/* arp */
gtk_signal_connect(GTK_OBJECT(pui->quote_str), "changed",
GTK_SIGNAL_FUNC(properties_modified_cb),
@@ -649,6 +661,13 @@
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
(pui->close_mailbox_minutes));
+ /* external editor */
+ g_free(balsa_app.extern_editor_command);
+ balsa_app.extern_editor_command =
+ g_strdup(gtk_entry_get_text(GTK_ENTRY(pui->extern_editor_command)));
+
+ balsa_app.extern_editor_mutt_like = GTK_TOGGLE_BUTTON(pui->extern_editor_mutt_like)->active;
+
/* arp */
g_free(balsa_app.quote_str);
balsa_app.quote_str =
@@ -901,6 +920,11 @@
gtk_widget_set_sensitive(pui->send_rfc2646_format_flowed,
GTK_TOGGLE_BUTTON(pui->wordwrap)->active);
+ /* external editor */
+ gtk_entry_set_text(GTK_ENTRY(pui->extern_editor_command), balsa_app.extern_editor_command);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pui->extern_editor_mutt_like),
+ balsa_app.extern_editor_mutt_like);
+
/* arp */
gtk_entry_set_text(GTK_ENTRY(pui->quote_str), balsa_app.quote_str);
entry_widget = gnome_entry_gtk_entry(GNOME_ENTRY(pui->quote_pattern));
@@ -1627,10 +1651,14 @@
vbox2 = vbox_in_container(frame2);
- table2 = GTK_TABLE(gtk_table_new(3, 2, FALSE));
+ table2 = GTK_TABLE(gtk_table_new(5, 2, FALSE));
gtk_container_add(GTK_CONTAINER(vbox2), GTK_WIDGET(table2));
gtk_container_set_border_width(GTK_CONTAINER(table2), 2);
- pui->quote_str = attach_entry(_("Reply prefix:"), 4, table2);
+ pui->extern_editor_command = attach_entry(_("External editor command:"), 4, table2);
+ pui->extern_editor_mutt_like =
+ gtk_check_button_new_with_label(_("External editor mutt-like"));
+ gtk_box_pack_start(GTK_BOX(vbox2), pui->extern_editor_mutt_like, FALSE, TRUE, 0);
+ pui->quote_str = attach_entry(_("Reply prefix:"), 5, table2);
pui->autoquote =
gtk_check_button_new_with_label(_("Automatically quote original "
Index: src/save-restore.c
===================================================================
RCS file: /cvs/gnome/balsa/src/save-restore.c,v
retrieving revision 1.223
diff -u -r1.223 save-restore.c
--- src/save-restore.c 2001/12/05 22:49:12 1.223
+++ src/save-restore.c 2001/12/25 16:08:30
@@ -731,6 +731,10 @@
/* Compose window ... */
gnome_config_push_prefix(BALSA_CONFIG_PREFIX "Compose/");
+ g_free(balsa_app.extern_editor_command);
+ balsa_app.extern_editor_command = gnome_config_get_string("ExternEditorCommand=gnome-edit %s");
+ balsa_app.extern_editor_mutt_like = gnome_config_get_bool("ExternEditorMuttLike=false");
+
g_free(balsa_app.quote_str);
balsa_app.quote_str = gnome_config_get_string("QuoteString=> ");
g_free(balsa_app.compose_headers);
@@ -974,6 +978,8 @@
gnome_config_set_string("ComposeHeaders", balsa_app.compose_headers);
gnome_config_set_bool("RequestDispositionNotification", balsa_app.req_dispnotify);
+ gnome_config_set_string("ExternEditorCommand", balsa_app.extern_editor_command);
+ gnome_config_set_bool("ExternEditorMuttLike", balsa_app.extern_editor_mutt_like);
gnome_config_set_string("QuoteString", balsa_app.quote_str);
gnome_config_pop_prefix();
Index: src/sendmsg-window.c
===================================================================
RCS file: /cvs/gnome/balsa/src/sendmsg-window.c,v
retrieving revision 1.330
diff -u -r1.330 sendmsg-window.c
--- src/sendmsg-window.c 2001/12/19 13:16:37 1.330
+++ src/sendmsg-window.c 2001/12/25 16:08:34
@@ -48,6 +48,7 @@
#endif
#include <sys/stat.h> /* for check_if_regular_file() */
+#include <sys/wait.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -75,6 +76,12 @@
#define GNOME_MIME_BUG_WORKAROUND 1
+typedef struct {
+ pid_t pid_editor;
+ gchar *filename;
+ BalsaSendmsg *msg;
+}balsa_edit_with_gnome_data ;
+
static gchar *read_signature(BalsaSendmsg *msg);
static gint include_file_cb(GtkWidget *, BalsaSendmsg *);
static gint send_message_cb(GtkWidget *, BalsaSendmsg *);
@@ -246,6 +253,12 @@
N_("Select the Identity to use for the message"),
change_identity_dialog_cb,
BALSA_PIXMAP_MENU_IDENTITY),
+ GNOMEUIINFO_SEPARATOR,
+#define EDIT_MENU_EDIT_GNOME 17
+ GNOMEUIINFO_ITEM_STOCK(N_("_Edit with Gnome-Editor"),
+ N_("Edit the current message with the default Gnome editor"),
+ edit_with_gnome,
+ BALSA_PIXMAP_MENU_IDENTITY), /*FIXME: Other icon */
GNOMEUIINFO_END
};
@@ -663,136 +676,247 @@
update_msg_identity(msg, ident);
}
-/*
- Drop down list identity update
-*/
+/* Edit the current file with an external editor.
+ *
+ * We fork the twice current process, so we get:
+ *
+ * - Old (parent )process (this needs to continue because we don't want
+ * balsa to 'hang' until the editor exits
+ * - New (child) process (forks and waits for child to finish)
+ * - New (grandchild) process (executes editor)
+ */
+void
+edit_with_gnome(GtkWidget* widget, BalsaSendmsg* msg)
+{
+ gchar *filename = tmpnam(NULL);
+ gchar *command;
+ gchar **cmdline;
+ balsa_edit_with_gnome_data *data = g_malloc(sizeof(balsa_edit_with_gnome_data));
+ pid_t pid, pid_ext;
+ FILE *tmp = fopen(filename, "w+");
+
+ if(balsa_app.extern_editor_mutt_like){
+ gchar *from = gtk_entry_get_text(GTK_ENTRY(msg->from[1])),
+ *to = gtk_entry_get_text(GTK_ENTRY(msg->to[1])),
+ *reply_to =
+ gtk_entry_get_text(GTK_ENTRY(msg->reply_to[1])), *cc =
+ gtk_entry_get_text(GTK_ENTRY(msg->cc[1])),
+ *bcc = gtk_entry_get_text(GTK_ENTRY(msg->bcc[1])),
+ *subject = gtk_entry_get_text(GTK_ENTRY(msg->subject[1])),
+ *comments = gtk_entry_get_text(GTK_ENTRY(msg->comments[1]));
+
+ /* Write all the headers */
+ fprintf(tmp, "From: %s\n"
+ "To: %s\n"
+ "Cc: %s\n"
+ "Bcc: %s\n"
+ "Subject: %s\n"
+ "Reply-To: %s\n"
+ "Comments: %s\n\n\n",
+ from,to,cc,bcc,subject,reply_to,comments);
+ }
+ gtk_widget_set_sensitive(msg->text, FALSE);
+ fputs(gtk_editable_get_chars(GTK_EDITABLE(msg->text), 0,
+ gtk_text_get_length(GTK_TEXT
+ (msg->text))),tmp);
+ fclose(tmp);
+ if ((pid = fork()) < 0) {
+ perror ("fork");
+ return;
+ }
+ if (pid == 0) {
+ setpgrp();
+ command = g_malloc(strlen(filename) + 30);
+ g_snprintf(command, strlen(filename)+30, balsa_app.extern_editor_command, filename);
+ cmdline = g_strsplit (command, " ", 1024);
+ execvp (cmdline[0], cmdline);
+ perror ("execvp");
+ g_strfreev (cmdline);
+ g_free(command);
+ exit(127);
+ }
+ /* Return immediately. We don't want balsa to 'hang' */
+ data->pid_editor = pid;
+ data->filename = g_strdup(filename);
+ data->msg = msg;
+ gtk_idle_add((GtkFunction) edit_with_gnome_check, data);
+}
+
+static gboolean edit_with_gnome_check(gpointer data){
+ FILE *tmp;
+ balsa_edit_with_gnome_data *data_real = (balsa_edit_with_gnome_data *)data;
+ pid_t pid;
+ gint curposition;
+ gchar line[81]; /* FIXME:All lines should wrap at this line */
+ /* Editor not ready */
+ pid = waitpid (data_real->pid_editor, NULL, WNOHANG);
+ if(pid == -1){
+ perror("waitpid");
+ return TRUE;
+ }else if(pid == 0)return TRUE;
+ tmp = fopen(data_real->filename, "r");
+ if(tmp == NULL){
+ perror("fopen");
+ return TRUE;
+ }
+ if(balsa_app.extern_editor_mutt_like){
+ while(!feof(tmp)){
+ fgets(line, 80, tmp);
+ if(line[strlen(line)-1] == '\n')line[strlen(line)-1] = '\0';
+ if(!strncmp(line, "To: ", 4))gtk_entry_set_text(GTK_ENTRY(data_real->msg->to[1]), line+4);
+ else if(!strncmp(line, "From: ", 6))gtk_entry_set_text(GTK_ENTRY(data_real->msg->from[1]), line+6);
+ else if(!strncmp(line, "Reply-To: ", 10))gtk_entry_set_text(GTK_ENTRY(data_real->msg->reply_to[1]), line+10);
+ else if(!strncmp(line, "Bcc: ", 5))gtk_entry_set_text(GTK_ENTRY(data_real->msg->bcc[1]), line+5);
+ else if(!strncmp(line, "Cc: ", 4))gtk_entry_set_text(GTK_ENTRY(data_real->msg->cc[1]), line+4);
+ else if(!strncmp(line, "Comments: ", 10))gtk_entry_set_text(GTK_ENTRY(data_real->msg->comments[1]), line+10);
+ else if(!strncmp(line, "Subject: ", 9))gtk_entry_set_text(GTK_ENTRY(data_real->msg->subject[1]), line+9);
+ else break;
+ }
+ }
+ gtk_editable_delete_text(GTK_EDITABLE(data_real->msg->text),0,-1);
+ curposition = 0;
+ while(!feof(tmp)){
+ fgets(line, 80, tmp);
+ gtk_editable_insert_text(GTK_EDITABLE(data_real->msg->text),line, strlen(line), &curposition);
+ }
+ g_free(data_real->filename);
+ fclose(tmp);
+ unlink(data_real->filename);
+ gtk_widget_set_sensitive(data_real->msg->text, TRUE);
+ g_free(data);
+ return FALSE;
+}
+/*
+ Drop down list identity update
+ */
-static void
+ static void
update_msg_identity(BalsaSendmsg* msg, LibBalsaIdentity* ident)
{
- gchar* tmpstr=libbalsa_address_to_gchar(ident->address, 0);
-
- /* change entries to reflect new identity */
- gtk_entry_set_text(GTK_ENTRY(msg->from[1]), tmpstr);
- g_free(tmpstr);
+ gchar* tmpstr=libbalsa_address_to_gchar(ident->address, 0);
- gtk_entry_set_text(GTK_ENTRY(msg->reply_to[1]), ident->replyto);
-
- gtk_entry_set_text(GTK_ENTRY(msg->bcc[1]), ident->bcc);
-
- /* change the subject to use the reply/forward strings */
+ /* change entries to reflect new identity */
+ gtk_entry_set_text(GTK_ENTRY(msg->from[1]), tmpstr);
+ g_free(tmpstr);
+
+ gtk_entry_set_text(GTK_ENTRY(msg->reply_to[1]), ident->replyto);
- /* remove/add the signature depending on the new settings, change
- * the signature if path changed */
+ gtk_entry_set_text(GTK_ENTRY(msg->bcc[1]), ident->bcc);
- /* update the current messages identity */
+ /* change the subject to use the reply/forward strings */
+
+ /* remove/add the signature depending on the new settings, change
+ * the signature if path changed */
+
+ /* update the current messages identity */
msg->ident=ident;
}
-static void
+ static void
sw_size_alloc_cb(GtkWidget * window, GtkAllocation * alloc)
{
- balsa_app.sw_height = alloc->height;
- balsa_app.sw_width = alloc->width;
+ balsa_app.sw_height = alloc->height;
+ balsa_app.sw_width = alloc->width;
}
/* remove_attachment - right mouse button callback */
-static void
+ static void
remove_attachment(GtkWidget * widget, GnomeIconList * ilist)
{
- gint num = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(ilist),
- "selectednumbertoremove"));
- gnome_icon_list_remove(ilist, num);
- gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoremove");
+ gint num = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(ilist),
+ "selectednumbertoremove"));
+ gnome_icon_list_remove(ilist, num);
+ gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoremove");
}
/* ask if an attachment shall be message/external-body */
static void
extbody_dialog_delete(GtkWidget *dialog, GdkEvent *event,
- gpointer user_data)
+ gpointer user_data)
{
- GnomeIconList *ilist =
- GNOME_ICON_LIST(gtk_object_get_user_data (GTK_OBJECT (dialog)));
- gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoextbody");
- gtk_widget_hide (dialog);
- gtk_object_destroy(GTK_OBJECT(dialog));
+ GnomeIconList *ilist =
+ GNOME_ICON_LIST(gtk_object_get_user_data (GTK_OBJECT (dialog)));
+ gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoextbody");
+ gtk_widget_hide (dialog);
+ gtk_object_destroy(GTK_OBJECT(dialog));
}
-static void
+ static void
no_change_to_extbody(GtkWidget *widget, gpointer user_data)
{
- GtkWidget *dialog = GTK_WIDGET(user_data);
- GnomeIconList *ilist;
+ GtkWidget *dialog = GTK_WIDGET(user_data);
+ GnomeIconList *ilist;
- ilist =
- GNOME_ICON_LIST(gtk_object_get_user_data (GTK_OBJECT (dialog)));
- gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoextbody");
- gtk_widget_hide (dialog);
- gtk_object_destroy(GTK_OBJECT(dialog));
+ ilist =
+ GNOME_ICON_LIST(gtk_object_get_user_data (GTK_OBJECT (dialog)));
+ gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoextbody");
+ gtk_widget_hide (dialog);
+ gtk_object_destroy(GTK_OBJECT(dialog));
}
static void
add_extbody_attachment(GnomeIconList *ilist,
- const gchar *name, const gchar *mime_type,
- gboolean delete_on_destroy, gboolean is_url) {
- gchar *pix;
- gchar *label;
- attachment_t *attach;
- gint pos;
+ const gchar *name, const gchar *mime_type,
+ gboolean delete_on_destroy, gboolean is_url) {
+ gchar *pix;
+ gchar *label;
+ attachment_t *attach;
+ gint pos;
- g_return_if_fail(name != NULL);
-
- attach = g_malloc(sizeof(attachment_t));
- if (is_url)
- attach->filename = g_strdup_printf("URL %s", name);
- else
- attach->filename = g_strdup(name);
- attach->force_mime_type = mime_type != NULL ? g_strdup(mime_type) : NULL;
- attach->delete_on_destroy = delete_on_destroy;
- attach->as_extbody = TRUE;
-
- pix = libbalsa_icon_finder("message/external-body", attach->filename);
- label = g_strdup_printf ("%s (%s)", attach->filename,
- "message/external-body");
- pos = gnome_icon_list_append(ilist, pix, label);
- gnome_icon_list_set_icon_data_full(ilist, pos, attach, destroy_attachment);
- g_free(pix);
- g_free(label);
+ g_return_if_fail(name != NULL);
+
+ attach = g_malloc(sizeof(attachment_t));
+ if (is_url)
+ attach->filename = g_strdup_printf("URL %s", name);
+ else
+ attach->filename = g_strdup(name);
+ attach->force_mime_type = mime_type != NULL ? g_strdup(mime_type) : NULL;
+ attach->delete_on_destroy = delete_on_destroy;
+ attach->as_extbody = TRUE;
+
+ pix = libbalsa_icon_finder("message/external-body", attach->filename);
+ label = g_strdup_printf ("%s (%s)", attach->filename,
+ "message/external-body");
+ pos = gnome_icon_list_append(ilist, pix, label);
+ gnome_icon_list_set_icon_data_full(ilist, pos, attach, destroy_attachment);
+ g_free(pix);
+ g_free(label);
}
/* send attachment as external body - right mouse button callback */
-static void
+ static void
extbody_attachment(GtkWidget * widget, gpointer user_data)
{
- GtkWidget *dialog = GTK_WIDGET(user_data);
- GnomeIconList *ilist;
- gint num;
- attachment_t *oldattach;
-
- ilist =
- GNOME_ICON_LIST(gtk_object_get_user_data (GTK_OBJECT (dialog)));
- num = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(ilist),
- "selectednumbertoextbody"));
- oldattach =
- (attachment_t *)gnome_icon_list_get_icon_data(ilist, num);
- g_return_if_fail(oldattach);
- gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoextbody");
- gtk_widget_hide (dialog);
- gtk_object_destroy(GTK_OBJECT(dialog));
-
- /* remove the selected element and replace it */
- gnome_icon_list_freeze(ilist);
- add_extbody_attachment(ilist, oldattach->filename,
- oldattach->force_mime_type,
- oldattach->delete_on_destroy, FALSE);
+ GtkWidget *dialog = GTK_WIDGET(user_data);
+ GnomeIconList *ilist;
+ gint num;
+ attachment_t *oldattach;
+
+ ilist =
+ GNOME_ICON_LIST(gtk_object_get_user_data (GTK_OBJECT (dialog)));
+ num = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(ilist),
+ "selectednumbertoextbody"));
+ oldattach =
+ (attachment_t *)gnome_icon_list_get_icon_data(ilist, num);
+ g_return_if_fail(oldattach);
+ gtk_object_remove_data(GTK_OBJECT(ilist), "selectednumbertoextbody");
+ gtk_widget_hide (dialog);
+ gtk_object_destroy(GTK_OBJECT(dialog));
+
+ /* remove the selected element and replace it */
+ gnome_icon_list_freeze(ilist);
+ add_extbody_attachment(ilist, oldattach->filename,
+ oldattach->force_mime_type,
+ oldattach->delete_on_destroy, FALSE);
gnome_icon_list_remove(ilist, num);
gnome_icon_list_thaw(ilist);
@@ -1571,12 +1695,12 @@
/* add the spell check widget to the notebook last */
gtk_notebook_append_page(GTK_NOTEBOOK(nb), GTK_WIDGET(sc),
- gtk_label_new("Spell Check"));
+ gtk_label_new(_("Spell Check")));
spell_check_page = gtk_notebook_page_num(GTK_NOTEBOOK(nb), sc);
/* add the mail headers table to the notebook first */
gtk_notebook_append_page(GTK_NOTEBOOK(nb), GTK_WIDGET(table),
- gtk_label_new("Mail Headers"));
+ gtk_label_new(_("Mail Headers")));
mail_headers_page = gtk_notebook_page_num(GTK_NOTEBOOK(nb), table);
gtk_notebook_set_page(GTK_NOTEBOOK(nb), mail_headers_page);
Index: src/sendmsg-window.h
===================================================================
RCS file: /cvs/gnome/balsa/src/sendmsg-window.h,v
retrieving revision 1.44
diff -u -r1.44 sendmsg-window.h
--- src/sendmsg-window.h 2001/11/12 22:15:12 1.44
+++ src/sendmsg-window.h 2001/12/25 16:08:35
@@ -79,7 +79,8 @@
gchar *forced_mime_type);
typedef void (*field_setter)(BalsaSendmsg *d, const gchar*, const gchar*);
-
+ void edit_with_gnome(GtkWidget *, BalsaSendmsg *);
+ static gboolean edit_with_gnome_check(gpointer);
void sendmsg_window_process_url(const char *url, field_setter func,
void *data);
BalsaSendmsg *sendmsg_window_new_from_list(GtkWidget * w,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]