2006-07-31 [wwp] 2.4.0cvs3
[claws.git] / src / addr_compl.c
index e33dde0f1748a7f911276ffd60cf4f2eda881964..f2d3986843574c85a116c063bab60febb4b5ec5b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
  *
- * Copyright (C) 2000-2005 by Alfons Hoogervorst & The Sylpheed Claws Team. 
+ * Copyright (C) 2000-2006 by Alfons Hoogervorst & The Sylpheed Claws Team.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -46,6 +46,7 @@
 #include "addr_compl.h"
 #include "utils.h"
 #include "prefs_common.h"
+#include "sylpheed.h"
 #include <pthread.h>
 
 /*!
@@ -112,6 +113,8 @@ static gchar           *g_completion_prefix;        /* last prefix. (this is cached here
                                                 * because the prefix passed to g_completion
                                                 * is g_strdown()'ed */
 
+static gchar *completion_folder_path = NULL;
+
 /*******************************************************************************/
 
 /*
@@ -131,9 +134,6 @@ struct _CompletionWindow {
 
 static GtkListStore *addr_compl_create_store   (void);
 
-static void addr_compl_list_view_add_address   (GtkWidget *list_view,
-                                                const gchar *address);
-
 static GtkWidget *addr_compl_list_view_create  (CompletionWindow *window);
 
 static void addr_compl_create_list_view_columns        (GtkWidget *list_view);
@@ -213,9 +213,8 @@ static void add_address1(const char *str, address_entry *ae)
 {
        completion_entry *ce1;
        ce1 = g_new0(completion_entry, 1),
-       ce1->string = g_utf8_strdown(str, -1);
        /* GCompletion list is case sensitive */
-       g_strdown(ce1->string);
+       ce1->string = g_utf8_strdown(str, -1);
        ce1->ref = ae;
 
        g_completion_list = g_list_prepend(g_completion_list, ce1);
@@ -262,8 +261,8 @@ static gint add_address(const gchar *name, const gchar *address,
 /**
  * Read address book, creating all entries in the completion index.
  */ 
-static void read_address_book(void) {  
-       addrindex_load_completion( add_address );
+static void read_address_book(gchar *folderpath) {     
+       addrindex_load_completion( add_address, folderpath );
        g_address_list = g_list_reverse(g_address_list);
        g_completion_list = g_list_reverse(g_completion_list);
 }
@@ -285,8 +284,7 @@ static gboolean is_completion_pending(void)
 static void clear_completion_cache(void)
 {
        if (is_completion_pending()) {
-               if (g_completion_prefix)
-                       g_free(g_completion_prefix);
+               g_free(g_completion_prefix);
 
                if (g_completion_addresses) {
                        g_slist_free(g_completion_addresses);
@@ -302,19 +300,42 @@ static void clear_completion_cache(void)
  * address completion.
  * \return The number of addresses in the completion list.
  */
-gint start_address_completion(void)
+gint start_address_completion(gchar *folderpath)
 {
        clear_completion_cache();
+
+       if ((completion_folder_path == NULL && folderpath != NULL) ||
+               (completion_folder_path != NULL && folderpath == NULL) ||
+               (completion_folder_path != NULL && folderpath != NULL &&
+                strcmp(completion_folder_path, folderpath) != 0)) {
+
+               debug_print("start_address_completion: resetting\n");
+
+               /* TODO: wwp: optimize: only reset when the new folderpath is MORE restrictive than the old one
+                 (the most easy case is when folderpath is NULL and completion_folder_path is != NULL */
+               if (g_ref_count) {
+                       free_all();
+                       g_ref_count = 0;
+               }
+       }
+
+       g_free(completion_folder_path);
+       if (folderpath != NULL)
+               completion_folder_path = g_strdup(folderpath);
+       else
+               completion_folder_path = NULL;
+
        if (!g_ref_count) {
                init_all();
                /* open the address book */
-               read_address_book();
+               read_address_book(folderpath);
                /* merge the completion entry list into g_completion */
                if (g_completion_list)
                        g_completion_add_items(g_completion, g_completion_list);
        }
        g_ref_count++;
-       debug_print("start_address_completion ref count %d\n", g_ref_count);
+       debug_print("start_address_completion(%s) ref count %d\n",
+                               folderpath, g_ref_count);
 
        return g_list_length(g_completion_list);
 }
@@ -362,7 +383,7 @@ static gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
                return NULL;
 
 #define IS_VALID_CHAR(x) \
-       (isalnum(x) || (x) == '"' || (x) == '<' || (((unsigned char)(x)) > 0x7f))
+       (g_ascii_isalnum(x) || (x) == '"' || (x) == '<' || (((unsigned char)(x)) > 0x7f))
 
        /* now scan back until we hit a valid character */
        for (; *p && !IS_VALID_CHAR(*p); p = g_utf8_next_char(p))
@@ -406,10 +427,11 @@ static void replace_address_in_edit(GtkEntry *entry, const gchar *newtext,
  */
 guint complete_address(const gchar *str)
 {
-       GList *result;
-       gchar *d;
-       guint  count, cpl;
-       completion_entry *ce;
+       GList *result = NULL;
+       gchar *d = NULL;
+       guint  count = 0;
+       guint  cpl = 0;
+       completion_entry *ce = NULL;
 
        g_return_val_if_fail(str != NULL, 0);
 
@@ -528,7 +550,8 @@ gint invalidate_address_completion(void)
                debug_print("Invalidation request for address completion\n");
                free_all();
                init_all();
-               read_address_book();
+               read_address_book(completion_folder_path);
+               if (g_completion_list)
                g_completion_add_items(g_completion, g_completion_list);
                clear_completion_cache();
        }
@@ -713,37 +736,6 @@ static void completion_window_advance_selection(GtkTreeView *list_view, gboolean
        }
 }
 
-#if 0
-/* completion_window_accept_selection() - accepts the current selection in the
- * clist, and destroys the window */
-static void completion_window_accept_selection(GtkWidget **window,
-                                              GtkCList *clist,
-                                              GtkEntry *entry)
-{
-       gchar *address = NULL, *text = NULL;
-       gint   cursor_pos, row;
-
-       g_return_if_fail(window != NULL);
-       g_return_if_fail(*window != NULL);
-       g_return_if_fail(clist != NULL);
-       g_return_if_fail(entry != NULL);
-       g_return_if_fail(clist->selection != NULL);
-
-       /* FIXME: I believe it's acceptable to access the selection member directly  */
-       row = GPOINTER_TO_INT(clist->selection->data);
-
-       /* we just need the cursor position */
-       address = get_address_from_edit(entry, &cursor_pos);
-       g_free(address);
-       gtk_clist_get_text(clist, row, 0, &text);
-       replace_address_in_edit(entry, text, cursor_pos);
-
-       clear_completion_cache();
-       gtk_widget_destroy(*window);
-       *window = NULL;
-}
-#endif
-
 /**
  * Resize window to accommodate maximum number of address entries.
  * \param cw Completion window.
@@ -829,6 +821,7 @@ static gboolean addrcompl_idle( gpointer data ) {
                _displayQueue_ = NULL;
        }
        pthread_mutex_unlock( & _completionMutex_ );
+       sylpheed_do_idle();
 
        return TRUE;
 }
@@ -983,7 +976,7 @@ static void completion_window_apply_selection(GtkTreeView *list_view, GtkEntry *
  */
 void address_completion_start(GtkWidget *mainwindow)
 {
-       start_address_completion();
+       start_address_completion(NULL);
 
        /* register focus change hook */
        g_signal_connect(G_OBJECT(mainwindow), "set_focus",
@@ -1135,9 +1128,7 @@ static gboolean address_completion_complete_address_in_entry(GtkEntry *entry,
        /* printf( "search for :::%s:::\n", searchTerm ); */
 
        /* Clear any existing search */
-       if( _compWindow_->searchTerm ) {
-               g_free( _compWindow_->searchTerm );
-       }
+       g_free( _compWindow_->searchTerm );
        _compWindow_->searchTerm = g_strdup( searchTerm );
 
        /* Perform search on local completion index */
@@ -1147,6 +1138,7 @@ static gboolean address_completion_complete_address_in_entry(GtkEntry *entry,
                g_free( new );
        }
 
+#ifndef USE_LDAP
        /* Select the address if there is only one match */
        if (ncount == 2) {
                /* Display selected address in entry field */           
@@ -1161,7 +1153,9 @@ static gboolean address_completion_complete_address_in_entry(GtkEntry *entry,
                clear_completion_cache();
        }
        /* Make sure that drop-down appears uniform! */
-       else if( ncount == 0 ) {
+       else 
+#endif
+       if( ncount == 0 ) {
                addrcompl_add_queue( g_strdup( searchTerm ) );
        }
        g_free( searchTerm );
@@ -1326,21 +1320,6 @@ static gboolean completion_window_key_press(GtkWidget *widget,
                return FALSE;
        }               
 
-#if 0  
-       /* also make tab / shift tab go to next previous completion entry. we're
-        * changing the key value */
-       if (event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab) {
-               event->keyval = (event->state & GDK_SHIFT_MASK)
-                       ? GDK_Up : GDK_Down;
-               /* need to reset shift state if going up */
-               if (event->state & GDK_SHIFT_MASK)
-                       event->state &= ~GDK_SHIFT_MASK;
-               completion_window_advance_selection(GTK_CLIST(clist), 
-                       event->keyval == GDK_Down ? TRUE : FALSE);
-               return FALSE;
-       }
-#endif
-
        /* make tab move to next field */
        if( event->keyval == GDK_Tab ) {
                /* Reference to parent */
@@ -1468,19 +1447,6 @@ static GtkListStore *addr_compl_create_store(void)
                                  G_TYPE_STRING,
                                  -1);
 }
-
-static void addr_compl_list_view_add_address(GtkWidget *list_view,
-                                            const gchar *address)
-{
-       GtkTreeIter iter;
-       GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model
-                                       (GTK_TREE_VIEW(list_view)));
-       
-       gtk_list_store_append(store, &iter);
-       gtk_list_store_set(store, &iter,
-                          ADDR_COMPL_ADDRESS, address,
-                          -1);
-}
                                             
 static GtkWidget *addr_compl_list_view_create(CompletionWindow *window)
 {