2007-02-23 [colin] 2.7.2cvs67
authorColin Leroy <colin@colino.net>
Fri, 23 Feb 2007 18:04:21 +0000 (18:04 +0000)
committerColin Leroy <colin@colino.net>
Fri, 23 Feb 2007 18:04:21 +0000 (18:04 +0000)
* src/addr_compl.c
Fix refcounting, start and end completion who
behaved as if there couldn't be any other current
user of completion

ChangeLog
PATCHSETS
configure.ac
src/addr_compl.c

index f5cdf51038b9c720012c8841b38ba2b1442b5be7..efd15ffc07c4e8583aa655a27f7a32b0f7a5c1ef 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-02-23 [colin]     2.7.2cvs67
+
+       * src/addr_compl.c
+               Fix refcounting, start and end completion who
+               behaved as if there couldn't be any other current
+               user of completion
+
 2007-02-23 [wwp]       2.7.2cvs66
 
        * src/addressbook.c
index ebd509a5bbc80b15fdcb60d7a9d36579e368a0a6..f7536b6a9cb066744e3a485e87641a5053de1f43 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.2.25 -r 1.1.2.26 src/plugins/pgpcore/passphrase.c;  ) > 2.7.2cvs64.patchset
 ( cvs diff -u -r 1.27.2.28 -r 1.27.2.29 src/addr_compl.c;  ) > 2.7.2cvs65.patchset
 ( cvs diff -u -r 1.60.2.81 -r 1.60.2.82 src/addressbook.c;  cvs diff -u -r 1.28.2.23 -r 1.28.2.24 src/addrindex.c;  ) > 2.7.2cvs66.patchset
+( cvs diff -u -r 1.27.2.29 -r 1.27.2.30 src/addr_compl.c;  ) > 2.7.2cvs67.patchset
index 574625467d2b1974d807321463dcf8b5da2dcfa9..2ac5e94db88640f3b4bac8beaf8736ea915a210d 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=7
 MICRO_VERSION=2
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=66
+EXTRA_VERSION=67
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 63bad19f7e9131d46fc34a25e8643449fb9db5b2..60fce98d0d2d37b1eba81946b748407261e247d6 100644 (file)
@@ -102,8 +102,8 @@ typedef struct
 /*******************************************************************************/
 
 static gint        g_ref_count;        /* list ref count */
-static GList      *g_completion_list;  /* list of strings to be checked */
-static GList      *g_address_list;     /* address storage */
+static GList      *g_completion_list = NULL;   /* list of strings to be checked */
+static GList      *g_address_list = NULL;      /* address storage */
 static GCompletion *g_completion;      /* completion object */
 
 static GHashTable *_groupAddresses_ = NULL;
@@ -181,22 +181,11 @@ static void init_all(void)
        g_return_if_fail(g_completion != NULL);
 }
 
-/**
- * Free up all completion index data.
- */
-static void free_all(void)
+static void free_all_addresses(void)
 {
        GList *walk;
-       
-       walk = g_list_first(g_completion_list);
-       for (; walk != NULL; walk = g_list_next(walk)) {
-               completion_entry *ce = (completion_entry *) walk->data;
-               g_free(ce->string);
-               g_free(walk->data);
-       }
-       g_list_free(g_completion_list);
-       g_completion_list = NULL;
-       
+       if (!g_address_list)
+               return;
        walk = g_address_list;
        for (; walk != NULL; walk = g_list_next(walk)) {
                address_entry *ae = (address_entry *) walk->data;
@@ -207,7 +196,35 @@ static void free_all(void)
        }
        g_list_free(g_address_list);
        g_address_list = NULL;
+}
+
+static void clear_completion_cache(void);
+static void free_completion_list(void)
+{
+       GList *walk;
+       if (!g_completion_list)
+               return;
        
+       clear_completion_cache();
+       if (g_completion)
+               g_completion_clear_items(g_completion);
+
+       walk = g_list_first(g_completion_list);
+       for (; walk != NULL; walk = g_list_next(walk)) {
+               completion_entry *ce = (completion_entry *) walk->data;
+               g_free(ce->string);
+               g_free(walk->data);
+       }
+       g_list_free(g_completion_list);
+       g_completion_list = NULL;
+}
+/**
+ * Free up all completion index data.
+ */
+static void free_all(void)
+{
+       free_completion_list(); 
+       free_all_addresses();   
        g_completion_free(g_completion);
        g_completion = NULL;
        if (_groupAddresses_)
@@ -281,10 +298,21 @@ 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(gchar *folderpath) {     
+static void read_address_book(gchar *folderpath) {
+       free_all_addresses();
+       free_completion_list();
+
        addrindex_load_completion( add_address, folderpath );
        g_address_list = g_list_reverse(g_address_list);
        g_completion_list = g_list_reverse(g_completion_list);
+       /* merge the completion entry list into g_completion */
+       if (g_completion_list) {
+               g_completion_add_items(g_completion, g_completion_list);
+               if (debug_get_mode())
+                       debug_print("read %d items in %s\n", 
+                               g_list_length(g_completion_list),
+                               folderpath?folderpath:"(null)");
+       }
 }
 
 /**
@@ -322,22 +350,11 @@ static void clear_completion_cache(void)
  */
 gint start_address_completion(gchar *folderpath)
 {
+       gboolean different_book = FALSE;
        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;
-               }
-       }
+       if (strcmp2(completion_folder_path,folderpath))
+               different_book = TRUE;
 
        g_free(completion_folder_path);
        if (folderpath != NULL)
@@ -349,10 +366,9 @@ gint start_address_completion(gchar *folderpath)
                init_all();
                /* open the 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);
-       }
+       } else if (different_book)
+               read_address_book(folderpath);
+
        g_ref_count++;
        debug_print("start_address_completion(%s) ref count %d\n",
                                folderpath, g_ref_count);
@@ -607,11 +623,7 @@ gint invalidate_address_completion(void)
        if (g_ref_count) {
                /* simply the same as start_address_completion() */
                debug_print("Invalidation request for address completion\n");
-               free_all();
-               init_all();
                read_address_book(completion_folder_path);
-               if (g_completion_list)
-               g_completion_add_items(g_completion, g_completion_list);
                clear_completion_cache();
        }
 
@@ -625,12 +637,23 @@ gint invalidate_address_completion(void)
  */
 gint end_address_completion(void)
 {
+       gboolean different_folder = FALSE;
        clear_completion_cache();
 
+       /* reset the folderpath to NULL */
+       if (completion_folder_path) {
+               g_free(completion_folder_path);
+               completion_folder_path = NULL;
+               different_folder = TRUE;
+       }
        if (0 == --g_ref_count)
                free_all();
 
        debug_print("end_address_completion ref count %d\n", g_ref_count);
+       if (g_ref_count && different_folder) {
+               debug_print("still ref'd, different folder\n");
+               invalidate_address_completion();
+       }
 
        return g_ref_count; 
 }