Checking addresses in the composition window



Balsa uses a rudimentary test to decide when a message is ready to 
send, and activates/deactivates various toolbar buttons accordingly. 
Only the `From:' and `To:' entries are checked. This patch introduces a 
test based on parsing all of the address entries (`Cc:' and `Bcc:', in 
addition to `From:' and `To:'), and verifies that there's exactly one 
`From' address, at least one `To:' address, and that if `Cc:' or `Bcc:' 
addresses are entered, they parse into at least one address. (BTW, RFC 
2822 permits more than one `From:' address--should Balsa?)

Perhaps more controversially, the patch also gives some visual feedback 
about which fields are invalid, by coloring the label (`From:', etc.). 
The color for an invalid field is a user preference, defaulting to dark 
red. Feature bloat? Perhaps--but IMHO feedback is useful, so that I 
don't sit there clicking a greyed-out `Send this message' button, with 
no indication as to why it won't work.

Comments, suggestions, or improvements?

Peter
diff -u -r1.17 address.c
--- libbalsa/address.c	2001/12/19 13:16:38	1.17
+++ libbalsa/address.c	2001/12/24 08:07:36
@@ -153,6 +153,35 @@
     return list;
 }
 
+/* libbalsa_address_count_from_string:
+ * return the number of addresses parsed from the_str */
+gint
+libbalsa_address_count_from_string(gchar * the_str)
+{
+    ADDRESS *address = NULL;
+    LibBalsaAddress *addr = NULL;
+    gint count = 0;
+
+    libbalsa_lock_mutt();
+
+    /* FIXME: this is wasteful!
+     * rfc822_parse_adrlist(address, the_str, &count)
+     * would be better, where rfc822_parse_adrlist only counts addresses
+     * when its third argument is nonNULL */
+    address = rfc822_parse_adrlist(address, the_str);
+
+    while (address) {
+        if (address->mailbox && !address->group) { /* *** For now */
+            ++count;
+        }
+        address = address->next;
+    }
+    rfc822_free_address(&address);
+    libbalsa_unlock_mutt();
+
+    return count;
+}
+
 LibBalsaAddress *
 libbalsa_address_new_from_libmutt(ADDRESS * caddr)
 {
Index: libbalsa/address.h
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/address.h,v
retrieving revision 1.12
diff -u -r1.12 address.h
--- libbalsa/address.h	2001/09/26 16:29:13	1.12
+++ libbalsa/address.h	2001/12/24 08:07:36
@@ -86,6 +86,7 @@
 LibBalsaAddress *libbalsa_address_new(void);
 LibBalsaAddress *libbalsa_address_new_from_string(gchar * address);
 GList *libbalsa_address_new_list_from_string(gchar * address);
+gint libbalsa_address_count_from_string(gchar * address);
 
 gchar *libbalsa_address_to_gchar(LibBalsaAddress * addr, gint n);
 
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/24 08:07:36
@@ -77,6 +77,7 @@
 #define DEFAULT_QUOTE_REGEX  "^(([ \tA-Z])\1*[|>:}#])"
 
 #define DEFAULT_URL_COLOR    "rgb:A000/0000/0000"
+#define DEFAULT_BAD_ADDRESS_COLOR    "rgb:BFFF/0000/0000"
 
 #define MAILBOX_MANAGER_WIDTH 350
 #define MAILBOX_MANAGER_HEIGHT 400
@@ -249,6 +250,9 @@
 
     /* text color of URL's */
     GdkColor url_color;
+
+    /* label color of bad addresses */
+    GdkColor bad_address_color;
 
     GtkToolbarStyle toolbar_style;
     GnomeMDIMode mdi_style;
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/24 08:07:37
@@ -120,6 +120,7 @@
     GtkWidget *unread_color;
     GtkWidget *quoted_color[MAX_QUOTED_COLOR];
     GtkWidget *url_color;
+    GtkWidget *bad_address_color;
 
     /* quote regex */
     GtkWidget *quote_pattern;
@@ -486,6 +487,10 @@
 		       GTK_SIGNAL_FUNC(properties_modified_cb),
 		       property_box);
 
+    gtk_signal_connect(GTK_OBJECT(pui->bad_address_color), "released",
+		       GTK_SIGNAL_FUNC(properties_modified_cb),
+		       property_box);
+
     /* Gnome Property Box Signals */
     gtk_signal_connect(GTK_OBJECT(property_box), "destroy",
 		       GTK_SIGNAL_FUNC(destroy_pref_window_cb), pui);
@@ -738,6 +743,15 @@
 			       &(balsa_app.url_color.blue),
 			       0);			       
 
+    /* bad address color */
+    gdk_colormap_free_colors(gdk_window_get_colormap(GTK_WIDGET(pbox)->window),
+			     &balsa_app.bad_address_color, 1);
+    gnome_color_picker_get_i16(GNOME_COLOR_PICKER(pui->bad_address_color),
+			       &(balsa_app.bad_address_color.red),
+			       &(balsa_app.bad_address_color.green),
+			       &(balsa_app.bad_address_color.blue),
+			       0);			       
+
     /* Information dialogs */
     menu_item =
 	gtk_menu_get_active(GTK_MENU(pui->information_message_menu));
@@ -985,6 +999,11 @@
 			       balsa_app.url_color.green,
 			       balsa_app.url_color.blue, 0);
 
+    gnome_color_picker_set_i16(GNOME_COLOR_PICKER(pui->bad_address_color),
+			       balsa_app.bad_address_color.red,
+			       balsa_app.bad_address_color.green,
+			       balsa_app.bad_address_color.blue, 0);
+
     /* Information Message */
     gtk_menu_set_active(GTK_MENU(pui->information_message_menu),
 			balsa_app.information_message);
@@ -1886,6 +1905,16 @@
     vbox9 = vbox_in_container(color_frame);
 
     pui->url_color = color_box(GTK_BOX(vbox9), _("Hyperlink color"));
+    
+    {
+        GtkWidget *frame = gtk_frame_new(_("Composition Window"));
+        GtkWidget *vbox = vbox_in_container(frame);
+        gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+        gtk_box_pack_start(GTK_BOX(vbox8), frame, FALSE, FALSE, 0);
+        pui->bad_address_color =
+            color_box(GTK_BOX(vbox),
+                      _("Invalid or incomplete address label color"));
+    }
 
     /* Fonts Preferences Page */
     vbox9 = gtk_vbox_new(FALSE, 0);
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/24 08:07:38
@@ -570,6 +570,10 @@
     /* URL coloring */
     load_color("UrlColor=" DEFAULT_URL_COLOR, &balsa_app.url_color);
 
+    /* bad address coloring */
+    load_color("BadAddressColor=" DEFAULT_BAD_ADDRESS_COLOR,
+               &balsa_app.bad_address_color);
+
     /* ... font used to display messages */
     g_free(balsa_app.message_font);
     balsa_app.message_font =
@@ -872,6 +876,7 @@
     }
 
     save_color("UrlColor", &balsa_app.url_color);
+    save_color("BadAddressColor", &balsa_app.bad_address_color);
 
     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/24 08:07:39
@@ -594,6 +594,11 @@
 	gdk_font_unref(bsm->font);
 	bsm->font = NULL;
     }
+    if (bsm->bad_address_style) {
+        gtk_style_unref(bsm->bad_address_style);
+        bsm->bad_address_style = NULL;
+    }
+
     g_free(bsm);
 
 
@@ -1471,10 +1476,14 @@
     /* cc: */
     create_email_entry(table, _("Cc:"), 3, GNOME_STOCK_MENU_BOOK_YELLOW,
 		       msg, msg->cc);
+    gtk_signal_connect(GTK_OBJECT(msg->cc[1]), "changed",
+		       GTK_SIGNAL_FUNC(check_readiness), msg);
 
     /* bcc: */
     create_email_entry(table, _("Bcc:"), 4, GNOME_STOCK_MENU_BOOK_GREEN,
 		       msg, msg->bcc);
+    gtk_signal_connect(GTK_OBJECT(msg->bcc[1]), "changed",
+		       GTK_SIGNAL_FUNC(check_readiness), msg);
 
     /* fcc: */
     msg->fcc[0] = gtk_label_new(_("Fcc:"));
@@ -2220,6 +2229,12 @@
     /* create the top portion with the to, from, etc in it */
     gtk_paned_add1(GTK_PANED(paned), create_info_pane(msg, type));
 
+    /* set up the style for flagging bad/incomplete addresses */
+    msg->bad_address_style =
+        gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(msg->from[0])));
+    msg->bad_address_style->fg[GTK_STATE_NORMAL] =
+        balsa_app.bad_address_color;
+
     /* create text area for the message */
     gtk_paned_add2(GTK_PANED(paned), create_text_area(msg));
 
@@ -2522,52 +2537,57 @@
 }
 
 
-/* is_ready_to_send returns TRUE if the message is ready to send or 
-   postpone. It tests currently only the "To" and "From" fields
-*/
+/* is_ready_to_send:
+ * returns TRUE if the message is ready to send or postpone.
+ *
+ * tests:
+ * - `from' has exactly one address (but note: RFC 2822 allows more);
+ * - `to' has at least one address;
+ * - `cc' is empty, or has at least one address;
+ * - `bcc' is empty, or has at least one address.
+ *
+ * sets the label of any address field that fails the test to the
+ * BadAddressColor.
+ */
 static gboolean
 is_ready_to_send(BalsaSendmsg * bsmsg)
 {
-    GList* list = NULL;
-    GList* l;
+    gboolean ready = TRUE;
     gchar *tmp;
-    size_t len;
 
-    list = g_list_append(list, gtk_entry_get_text(GTK_ENTRY(bsmsg->to[1])));
-    l = list =
-        g_list_append(list, gtk_entry_get_text(GTK_ENTRY(bsmsg->from[1])));
-
-    while (list) {
-        tmp = (gchar*) list->data;
-        len = strlen(tmp);
-        
-        if (len < 1) {		/* empty */
-            g_list_free(l);
-            return FALSE;
-        }
-        
+    tmp = gtk_entry_get_text(GTK_ENTRY(bsmsg->from[1]));
+    if (libbalsa_address_count_from_string(tmp) != 1) {
+        ready = FALSE;
+        gtk_widget_set_style(GTK_WIDGET(bsmsg->from[0]),
+                             bsmsg->bad_address_style);
+    } else
+        gtk_widget_set_rc_style(GTK_WIDGET(bsmsg->from[0]));
+
+    tmp = gtk_entry_get_text(GTK_ENTRY(bsmsg->to[1]));
+    if (libbalsa_address_count_from_string(tmp) <= 0) {
+        ready = FALSE;
+        gtk_widget_set_style(GTK_WIDGET(bsmsg->to[0]),
+                             bsmsg->bad_address_style);
+    } else
+        gtk_widget_set_rc_style(GTK_WIDGET(bsmsg->to[0]));
+
+    tmp = gtk_entry_get_text(GTK_ENTRY(bsmsg->cc[1]));
+    if (*tmp && libbalsa_address_count_from_string(tmp) <= 0) {
+        ready = FALSE;
+        gtk_widget_set_style(GTK_WIDGET(bsmsg->cc[0]),
+                             bsmsg->bad_address_style);
+    } else
+        gtk_widget_set_rc_style(GTK_WIDGET(bsmsg->cc[0]));
+
+    tmp = gtk_entry_get_text(GTK_ENTRY(bsmsg->bcc[1]));
+    if (*tmp && libbalsa_address_count_from_string(tmp) <= 0) {
+        ready = FALSE;
+        gtk_widget_set_style(GTK_WIDGET(bsmsg->bcc[0]),
+                             bsmsg->bad_address_style);
+    } else
+        gtk_widget_set_rc_style(GTK_WIDGET(bsmsg->bcc[0]));
 
-        if (tmp[len - 1] == '@') {	/* this shouldn't happen */
-            g_list_free(l);
-            return FALSE;
-        }
-        
-        if (len < 4) {
-            if (strchr(tmp, '@')) {	
-                /* you won't have an @ in an address less than 4
-                   characters */
-                g_list_free(l);
-                return FALSE;
-            }
-            
-            /* assume they are mailing it to someone in their local domain */
-        }
-
-        list = g_list_next(list);
-    }
-    
-    g_list_free(l);
-    return TRUE;
+    return ready;
 }
 
 static void
@@ -2715,17 +2735,6 @@
 	fprintf(stderr, "sending with charset: %s\n", bsmsg->charset);
 
     message = bsmsg2message(bsmsg);
-    if (!LIBBALSA_IS_ADDRESS(message->from)) {
-        gnome_ok_dialog_parented(_("Missing or invalid `From' address"),
-                                 GTK_WINDOW(balsa_app.main_window));
-        return FALSE;
-    }
-    if (message->to_list == NULL
-        || !LIBBALSA_IS_ADDRESS(message->to_list->data)) {
-        gnome_ok_dialog_parented(_("Missing or invalid `To' address"),
-                                 GTK_WINDOW(balsa_app.main_window));
-        return FALSE;
-    }
     fcc = message->fcc_mailbox && *(message->fcc_mailbox)
 	? mblist_find_mbox_by_name(balsa_app.mblist, message->fcc_mailbox)
 	: NULL;
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/24 08:07:39
@@ -68,6 +68,9 @@
 	guint delete_sig_id;
 	gboolean modified;
 	gboolean flow;          /* send format=flowed */ 
+        /* style for changing the color of address labels when the
+         * address isn't valid: */
+        GtkStyle *bad_address_style;  
     };
 
     BalsaSendmsg *sendmsg_window_new(GtkWidget *, LibBalsaMessage *,


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