r15776 - gnucash/trunk/src - When an SX is updated, synchronize added/removed variables with new/existing instances.

Josh Sled jsled at cvs.gnucash.org
Mon Apr 2 20:19:05 EDT 2007


Author: jsled
Date: 2007-04-02 20:19:04 -0400 (Mon, 02 Apr 2007)
New Revision: 15776
Trac: http://svn.gnucash.org/trac/changeset/15776

Modified:
   gnucash/trunk/src/app-utils/gnc-sx-instance-model.c
   gnucash/trunk/src/doc/sx.rst
Log:
When an SX is updated, synchronize added/removed variables with new/existing instances.


Modified: gnucash/trunk/src/app-utils/gnc-sx-instance-model.c
===================================================================
--- gnucash/trunk/src/app-utils/gnc-sx-instance-model.c	2007-04-02 22:11:52 UTC (rev 15775)
+++ gnucash/trunk/src/app-utils/gnc-sx-instance-model.c	2007-04-03 00:19:04 UTC (rev 15776)
@@ -257,6 +257,15 @@
                                        | GNC_RND_FLOOR);
 }
 
+static GncSxVariable*
+gnc_sx_variable_new_copy(GncSxVariable *to_copy)
+{
+    GncSxVariable *var = gnc_sx_variable_new(to_copy->name);
+    var->value = to_copy->value;
+    var->editable = to_copy->editable;
+    return var;
+}
+
 void
 gnc_sx_variable_free(GncSxVariable *var)
 {
@@ -275,9 +284,7 @@
 {
     GHashTable *to = (GHashTable*)user_data;
     GncSxVariable *to_copy = (GncSxVariable*)value;
-    GncSxVariable *var = gnc_sx_variable_new(to_copy->name);
-    var->value = to_copy->value;
-    var->editable = to_copy->editable;
+    GncSxVariable *var = gnc_sx_variable_new_copy(to_copy);
     g_hash_table_insert(to, key, var);
 }
 
@@ -689,6 +696,24 @@
     }
 }
 
+typedef struct _HashListPair
+{
+    GHashTable *hash;
+    GList *list;
+} HashListPair;
+
+static void
+_find_unreferenced_vars(gchar *key,
+                        gpointer value,
+                        HashListPair *cb_pair)
+{
+    if (!g_hash_table_lookup_extended(cb_pair->hash, key, NULL, NULL))
+    {
+        g_debug("variable [%s] not found", key);
+        cb_pair->list = g_list_append(cb_pair->list, key);
+    }
+}
+
 void
 gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
 {
@@ -706,7 +731,6 @@
     existing = (GncSxInstances*)link->data;
     new_instances = _gnc_sx_gen_instances((gpointer)sx, &model->range_end);
     existing->sx = new_instances->sx;
-    // @fixme: variable names stuff
     existing->next_instance_date = new_instances->next_instance_date;
     {
         GList *existing_iter, *new_iter;
@@ -754,6 +778,57 @@
             g_list_free(new_iter);
         }
     }
+
+    // handle variables
+    {
+        HashListPair removed_cb_data, added_cb_data;
+        GList *removed_var_names = NULL, *added_var_names = NULL;
+        GList *inst_iter = NULL;
+
+        removed_cb_data.hash = new_instances->variable_names;
+        removed_cb_data.list = NULL;
+        g_hash_table_foreach(existing->variable_names, (GHFunc)_find_unreferenced_vars, &removed_cb_data);
+        removed_var_names = removed_cb_data.list;
+        g_debug("%d removed variables", g_list_length(removed_var_names));
+
+        added_cb_data.hash = existing->variable_names;
+        added_cb_data.list = NULL;
+        g_hash_table_foreach(new_instances->variable_names, (GHFunc)_find_unreferenced_vars, &added_cb_data);
+        added_var_names = added_cb_data.list;
+        g_debug("%d added variables", g_list_length(added_var_names));
+
+        g_hash_table_destroy(existing->variable_names);
+        existing->variable_names = new_instances->variable_names;
+        new_instances->variable_names = NULL;
+
+        for (inst_iter = existing->list; inst_iter != NULL; inst_iter = inst_iter->next)
+        {
+            GList *var_iter;
+            GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
+            
+            for (var_iter = removed_var_names; var_iter != NULL; var_iter = var_iter->next)
+            {
+                gchar *to_remove_key = (gchar*)var_iter->data;
+                g_hash_table_remove(inst->variable_bindings, to_remove_key);
+            }
+
+            for (var_iter = added_var_names; var_iter != NULL; var_iter = var_iter->next)
+            {
+                gchar *to_add_key = (gchar*)var_iter->data;
+                if (!g_hash_table_lookup_extended(
+                        inst->variable_bindings, to_add_key, NULL, NULL))
+                {
+                    GncSxVariable *parent_var
+                        = g_hash_table_lookup(existing->variable_names, to_add_key);
+                    GncSxVariable *var_copy;
+
+                    g_assert(parent_var != NULL);
+                    var_copy = gnc_sx_variable_new_copy(parent_var);
+                    g_hash_table_insert(inst->variable_bindings, to_add_key, var_copy);
+                }
+            }
+        }
+    }
     gnc_sx_instances_free(new_instances);
 }
 

Modified: gnucash/trunk/src/doc/sx.rst
===================================================================
--- gnucash/trunk/src/doc/sx.rst	2007-04-02 22:11:52 UTC (rev 15775)
+++ gnucash/trunk/src/doc/sx.rst	2007-04-03 00:19:04 UTC (rev 15776)
@@ -14,6 +14,8 @@
   - [x] printf -> logging
 
 - core
+! - [ ] @fixme-s
+! - [ ] after updating/merging new instances, ensure sx-instance-state consistency
   - [x] sx list -> qof collection
   - [x] sx engine events
     - [x] sx list collection add/remove -- sx-list GNC_EVENT_ITEM_ADDED, _REMOVED
@@ -22,7 +24,6 @@
 !   - [x] implement sort model
   - [x] rename, re-home gnc-sx-instance-model:sxsl_get_sx_vars
   - [x] rename, re-home gnc-sx-instance-model:parse_vars_from_formula
-! - [ ] after updating/merging new instances, enforce state (+variable) consistency.
 
 - unit testing
   - [ ] model updating in the face of change
@@ -50,7 +51,7 @@
 
 - bugs
 
-! - [ ] with SLR open (with instances), add variables to SX; only newly-created instances will have appropriate variable tables.
+! - [x] with SLR open (with instances), add variables to SX; only newly-created instances will have appropriate variable tables.
 
 ! - [x] parse from 1.8 file doesn't setup start date correctly;
     daily-auto-yes-notify.xac has start date of 2006-09-26, but new TXN is



More information about the gnucash-changes mailing list