match Nickname on auto-address completion
[claws.git] / src / addr_compl.c
index a028d4b8d3e9b115eb6cf53501da9af6118fb94b..ee1b6219def2ddbbda1ae0941744d7520c90088c 100644 (file)
@@ -144,38 +144,42 @@ static void free_all(void)
        g_completion = NULL;
 }
 
+static gint add_address1(const char *str, address_entry *ae)
+{
+       completion_entry *ce1;
+       ce1 = g_new0(completion_entry, 1),
+       ce1->string = g_strdup(str);
+       /* GCompletion list is case sensitive */
+       g_strdown(ce1->string);
+       ce1->ref = ae;
+
+       g_completion_list = g_list_append(g_completion_list, ce1);
+}
+
 /* add_address() - adds address to the completion list. this function looks
  * complicated, but it's only allocation checks.
  */
-static gint add_address(const gchar *name, const gchar *address)
+static gint add_address(const gchar *name, const gchar *address, const gchar *alias)
 {
        address_entry    *ae;
-       completion_entry *ce1;
-       completion_entry *ce2;
 
        if (!name || !address) return -1;
 
+       debug_print( "completion: add_address: %s - %s\n", name, address );
+
        ae = g_new0(address_entry, 1);
-       ce1 = g_new0(completion_entry, 1),
-       ce2 = g_new0(completion_entry, 1);
 
        g_return_val_if_fail(ae != NULL, -1);
-       g_return_val_if_fail(ce1 != NULL && ce2 != NULL, -1);   
 
        ae->name    = g_strdup(name);
        ae->address = g_strdup(address);                
-       ce1->string = g_strdup(name);
-       ce2->string = g_strdup(address);
 
-       /* GCompletion list is case sensitive */
-       g_strdown(ce2->string);
-       g_strdown(ce1->string);
-       ce1->ref = ce2->ref = ae;
-
-       g_completion_list = g_list_append(g_completion_list, ce1);
-       g_completion_list = g_list_append(g_completion_list, ce2);
        g_address_list    = g_list_append(g_address_list,    ae);
 
+       add_address1(name, ae);
+       add_address1(address, ae);
+       add_address1(alias, ae);
+
        return 0;
 }
 
@@ -217,8 +221,15 @@ gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
        wchar_t *wtext;
        wchar_t *wp;
        wchar_t rfc_mail_sep;
+       wchar_t quote;
+       wchar_t lt;
+       gboolean in_quote = FALSE;
        gchar *str;
 
+       if (mbtowc(&rfc_mail_sep, ",", 1) < 0) return NULL;
+       if (mbtowc(&quote, "\"", 1) < 0) return NULL;
+       if (mbtowc(&lt, "<", 1) < 0) return NULL;
+
        edit_text = gtk_entry_get_text(entry);
        if (edit_text == NULL) return NULL;
 
@@ -227,14 +238,13 @@ gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
 
        cur_pos = gtk_editable_get_position(GTK_EDITABLE(entry));
 
-       if (mbtowc(&rfc_mail_sep, ",", 1) < 0) {
-               g_free(wtext);
-               return NULL;
-       }
-
        /* scan for a separator. doesn't matter if walk points at null byte. */
-       for (wp = wtext + cur_pos; wp > wtext && *wp != rfc_mail_sep; wp--)
-               ;
+       for (wp = wtext + cur_pos; wp > wtext; wp--) {
+               if (!in_quote && *wp == rfc_mail_sep)
+                       break;
+               if (*wp == quote)
+                       in_quote ^= TRUE;
+       }
 
        /* have something valid */
        if (wcslen(wp) == 0) {
@@ -242,7 +252,8 @@ gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
                return NULL;
        }
 
-#define IS_VALID_CHAR(x)       (iswalnum(x) || ((x) > 0x7f))
+#define IS_VALID_CHAR(x) \
+       (iswalnum(x) || (x) == quote || (x) == lt || ((x) > 0x7f))
 
        /* now scan back until we hit a valid character */
        for (; *wp && !IS_VALID_CHAR(*wp); wp++)
@@ -329,22 +340,29 @@ guint complete_address(const gchar *str)
 gchar *get_complete_address(gint index)
 {
        const address_entry *p;
-       
+       gchar *address = NULL;
+
        if (index < g_completion_count) {
                if (index == 0)
-                       return g_strdup(g_completion_prefix);
+                       address = g_strdup(g_completion_prefix);
                else {
                        /* get something from the unique addresses */
                        p = (address_entry *)g_slist_nth_data
                                (g_completion_addresses, index - 1);
-                       if (p == NULL)
-                               return NULL;
-                       else
-                               return g_strdup_printf
-                                       ("%s <%s>", p->name, p->address);
+                       if (p != NULL) {
+                               if (!p->name || p->name[0] == '\0')
+                                       address = g_strdup_printf(p->address);
+                               else if (strchr_with_skip_quote(p->name, '"', ','))
+                                       address = g_strdup_printf
+                                               ("\"%s\" <%s>", p->name, p->address);
+                               else
+                                       address = g_strdup_printf
+                                               ("%s <%s>", p->name, p->address);
+                       }
                }
-       } else
-               return NULL;
+       }
+
+       return address;
 }
 
 gchar *get_next_complete_address(void)