GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Macros | Typedefs | Enumerations | Functions
gnc-sx-instance-model.h File Reference
#include "config.h"
#include <glib.h>
#include <glib-object.h>
#include "gnc-numeric.h"
#include "SchedXaction.h"

Go to the source code of this file.

Data Structures

struct  _GncSxInstanceModel
 
struct  _GncSxInstanceModelClass
 
struct  _GncSxInstances
 
struct  _GncSxVariable
 
struct  _GncSxInstance
 
struct  _GncSxVariableNeeded
 
struct  _GncSxSummary
 

Macros

#define GNC_TYPE_SX_INSTANCE_MODEL   (gnc_sx_instance_model_get_type ())
 
#define GNC_SX_INSTANCE_MODEL(obj)   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModel))
 
#define GNC_SX_INSTANCE_MODEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModelClass))
 
#define GNC_IS_SX_INSTANCE_MODEL(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_INSTANCE_MODEL))
 
#define GNC_IS_SX_INSTANCE_MODEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_INSTANCE_MODEL))
 
#define GNC_SX_INSTANCE_MODEL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModelClass))
 

Typedefs

typedef struct _GncSxInstanceModel GncSxInstanceModel
 
typedef struct
_GncSxInstanceModelClass 
GncSxInstanceModelClass
 
typedef struct _GncSxInstances GncSxInstances
 
typedef struct _GncSxVariable GncSxVariable
 
typedef struct _GncSxInstance GncSxInstance
 
typedef struct _GncSxVariableNeeded GncSxVariableNeeded
 
typedef struct _GncSxSummary GncSxSummary
 

Enumerations

enum  GncSxInstanceState {
  SX_INSTANCE_STATE_IGNORED, SX_INSTANCE_STATE_POSTPONED, SX_INSTANCE_STATE_TO_CREATE, SX_INSTANCE_STATE_REMINDER,
  SX_INSTANCE_STATE_CREATED, SX_INSTANCE_STATE_MAX_STATE
}
 

Functions

GType gnc_sx_instance_model_get_type (void)
 
GncSxInstanceModelgnc_sx_get_current_instances (void)
 
GncSxInstanceModelgnc_sx_get_instances (const GDate *range_end, gboolean include_disabled)
 
void gnc_sx_instance_model_update_sx_instances (GncSxInstanceModel *model, SchedXaction *sx)
 
void gnc_sx_instance_model_remove_sx_instances (GncSxInstanceModel *model, SchedXaction *sx)
 
GList * gnc_sx_instance_get_variables (GncSxInstance *inst)
 
Accountgnc_sx_get_template_transaction_account (const SchedXaction *sx)
 
GHashTable * gnc_sx_instance_get_variables_for_parser (GHashTable *instance_var_hash)
 
GncSxVariablegnc_sx_variable_new_full (gchar *name, gnc_numeric value, gboolean editable)
 
void gnc_sx_variable_free (GncSxVariable *var)
 
void gnc_sx_instance_model_change_instance_state (GncSxInstanceModel *model, GncSxInstance *instance, GncSxInstanceState new_state)
 
void gnc_sx_instance_model_set_variable (GncSxInstanceModel *model, GncSxInstance *instance, GncSxVariable *variable, gnc_numeric *new_value)
 
GList * gnc_sx_instance_model_check_variables (GncSxInstanceModel *model)
 
void gnc_sx_instance_model_effect_change (GncSxInstanceModel *model, gboolean auto_create_only, GList **created_transaction_guids, GList **creation_errors)
 
void gnc_sx_instance_model_summarize (GncSxInstanceModel *model, GncSxSummary *summary)
 
void gnc_sx_summary_print (const GncSxSummary *summary)
 
void gnc_sx_get_variables (SchedXaction *sx, GHashTable *var_hash)
 
int gnc_sx_parse_vars_from_formula (const char *formula, GHashTable *var_hash, gnc_numeric *result)
 
void gnc_sx_randomize_variables (GHashTable *vars)
 
GHashTable * gnc_g_hash_new_guid_numeric (void)
 
void gnc_sx_all_instantiate_cashflow (GList *all_sxes, const GDate *range_start, const GDate *range_end, GHashTable *map, GList **creation_errors)
 
GHashTable * gnc_sx_all_instantiate_cashflow_all (GDate range_start, GDate range_end)
 

Function Documentation

GHashTable* gnc_g_hash_new_guid_numeric ( void  )

Returns a GHashTable<GUID*, gnc_numeric*> with no destructor for the key, but a destructor for the value set.

The returned value must be free'd with g_hash_table_destroy or g_hash_table_unref.

Definition at line 1474 of file gnc-sx-instance-model.c.

1475 {
1476  return g_hash_table_new_full (guid_hash_to_guint, guid_g_hash_table_equal,
1477  NULL, gnc_numeric_free);
1478 }
guint guid_hash_to_guint(gconstpointer ptr)
gint guid_g_hash_table_equal(gconstpointer guid_a, gconstpointer guid_b)
void gnc_sx_all_instantiate_cashflow ( GList *  all_sxes,
const GDate *  range_start,
const GDate *  range_end,
GHashTable *  map,
GList **  creation_errors 
)

Instantiates the cash flow of all given SXs (in the given GList<SchedXAction*>) into the GHashTable<GUID*, gnc_numeric*> for the given date range. Each SX is counted with multiplicity as it has occurrences in the given date range.

The creation_errors list, if non-NULL, receive any errors that occurred during creation, similar as in gnc_sx_instance_model_effect_change().

Definition at line 1720 of file gnc-sx-instance-model.c.

1723 {
1724  SxAllCashflow userdata;
1725  userdata.hash = map;
1726  userdata.creation_errors = creation_errors;
1727  userdata.range_start = range_start;
1728  userdata.range_end = range_end;
1729 
1730  /* The work is done in the callback for each SX */
1731  g_list_foreach(all_sxes, instantiate_cashflow_cb, &userdata);
1732 }
GHashTable* gnc_sx_all_instantiate_cashflow_all ( GDate  range_start,
GDate  range_end 
)

Simplified wrapper around gnc_sx_all_instantiate_cashflow(): Run that function on all SX of the current book for the given date range. Ignore any potential error messages. Returns a newly allocated GHashTable with the result, which is a GHashTable<GUID*, gnc_numeric*>, identical to what gnc_g_hash_new_guid_numeric() would return. The returned value must be free'd with g_hash_table_destroy.

Definition at line 1735 of file gnc-sx-instance-model.c.

1736 {
1737  GHashTable *result_map = gnc_g_hash_new_guid_numeric();
1738  GList *all_sxes = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
1740  &range_start, &range_end,
1741  result_map, NULL);
1742  return result_map;
1743 }
GHashTable * gnc_g_hash_new_guid_numeric(void)
void gnc_sx_all_instantiate_cashflow(GList *all_sxes, const GDate *range_start, const GDate *range_end, GHashTable *map, GList **creation_errors)
GncSxInstanceModel* gnc_sx_get_current_instances ( void  )

Shorthand for get_instances(now, FALSE);

Definition at line 410 of file gnc-sx-instance-model.c.

411 {
412  GDate now;
413  g_date_clear(&now, 1);
414  gnc_gdate_set_time64 (&now, gnc_time (NULL));
415  return gnc_sx_get_instances(&now, FALSE);
416 }
GncSxInstanceModel * gnc_sx_get_instances(const GDate *range_end, gboolean include_disabled)
time64 gnc_time(time64 *tbuf)
get the current local time
void gnc_gdate_set_time64(GDate *gd, time64 time)
GncSxInstanceModel* gnc_sx_get_instances ( const GDate *  range_end,
gboolean  include_disabled 
)

Allocates a new SxInstanceModel and fills it with generated instances for all scheduled transactions up to the given range_end date.

The caller must unref the returned object by g_object_unref(G_OBJECT(inst_model)); when no longer in use.

Definition at line 419 of file gnc-sx-instance-model.c.

420 {
421  GList *all_sxes = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
422  GncSxInstanceModel *instances;
423 
424  g_assert(range_end != NULL);
425  g_assert(g_date_valid(range_end));
426 
427  instances = gnc_sx_instance_model_new();
428  instances->include_disabled = include_disabled;
429  instances->range_end = *range_end;
430 
431  if (include_disabled)
432  {
433  instances->sx_instance_list = gnc_g_list_map(all_sxes, (GncGMapFunc)_gnc_sx_gen_instances, (gpointer)range_end);
434  }
435  else
436  {
437  GList *sx_iter = g_list_first(all_sxes);
438  GList *enabled_sxes = NULL;
439 
440  for (; sx_iter != NULL; sx_iter = sx_iter->next)
441  {
442  SchedXaction *sx = (SchedXaction*)sx_iter->data;
443  if (xaccSchedXactionGetEnabled(sx))
444  {
445  enabled_sxes = g_list_append(enabled_sxes, sx);
446  }
447  }
448  instances->sx_instance_list = gnc_g_list_map(enabled_sxes, (GncGMapFunc)_gnc_sx_gen_instances, (gpointer)range_end);
449  g_list_free(enabled_sxes);
450  }
451 
452  return instances;
453 }
GList * gnc_g_list_map(GList *list, GncGMapFunc fn, gpointer user_data)
GList* gnc_sx_instance_get_variables ( GncSxInstance inst)
Returns
GList<GncSxVariable*>. Caller owns the list, but not the items.

Definition at line 337 of file gnc-sx-instance-model.c.

338 {
339  GList *vars = NULL;
340  g_hash_table_foreach(inst->variable_bindings, _build_list_from_hash_elts, &vars);
341  return vars;
342 }
GHashTable * variable_bindings
GHashTable* gnc_sx_instance_get_variables_for_parser ( GHashTable *  instance_var_hash)
Returns
caller-owned data struct.
caller-owned.

Definition at line 100 of file gnc-sx-instance-model.c.

101 {
102  GHashTable *parser_vars;
103  parser_vars = g_hash_table_new(g_str_hash, g_str_equal);
104  g_hash_table_foreach(instance_var_hash, (GHFunc)_sx_var_to_raw_numeric, parser_vars);
105  return parser_vars;
106 }
void gnc_sx_instance_model_change_instance_state ( GncSxInstanceModel model,
GncSxInstance instance,
GncSxInstanceState  new_state 
)

There is a constraint around a sequence of upcoming instance states. In short: the last-created state and a list of postponed instances are modeled, but upcoming reminders are not. As such, a reminder can never be before any other (modeled) instance type. For instance, the following sequences are disallowed:

[...] remind <- will be lost/skipped over; must be converted to postponed. to-create <- this will be the last-recorded state. [...]

[...] remind <- same as previous; will be lost/skipped; must be postponed. postponed [...]

remind <- same... ignore [...]

As such, the SinceLastRun model will enforce that there are no previous remind instances at every state change. They will be silently converted to postponed-state transactions.

Definition at line 1311 of file gnc-sx-instance-model.c.

1314 {
1315  if (instance->state == new_state)
1316  return;
1317 
1318  instance->state = new_state;
1319 
1320  // ensure 'remind' constraints are met:
1321  {
1322  GList *inst_iter;
1323  inst_iter = g_list_find(instance->parent->instance_list, instance);
1324  g_assert(inst_iter != NULL);
1325  if (instance->state != SX_INSTANCE_STATE_REMINDER)
1326  {
1327  // iterate backwards, making sure reminders are changed to 'postponed'
1328  for (inst_iter = inst_iter->prev; inst_iter != NULL; inst_iter = inst_iter->prev)
1329  {
1330  GncSxInstance *prev_inst = (GncSxInstance*)inst_iter->data;
1331  if (prev_inst->state != SX_INSTANCE_STATE_REMINDER)
1332  continue;
1333  prev_inst->state = SX_INSTANCE_STATE_POSTPONED;
1334  }
1335  }
1336  else
1337  {
1338  // iterate forward, make sure transactions are set to 'remind'
1339  for (inst_iter = inst_iter->next; inst_iter != NULL; inst_iter = inst_iter->next)
1340  {
1341  GncSxInstance *next_inst = (GncSxInstance*)inst_iter->data;
1342  if (next_inst->state == SX_INSTANCE_STATE_REMINDER)
1343  continue;
1344  next_inst->state = SX_INSTANCE_STATE_REMINDER;
1345  }
1346  }
1347  }
1348 
1349  g_signal_emit_by_name(model, "updated", (gpointer)instance->parent->sx);
1350 }
GncSxInstances * parent
GncSxInstanceState state
GList* gnc_sx_instance_model_check_variables ( GncSxInstanceModel model)
Returns
List<GncSxVariableNeeded> of unbound {instance,variable} pairs; the caller owns the list and the items.

Definition at line 1372 of file gnc-sx-instance-model.c.

1373 {
1374  GList *rtn = NULL;
1375  GList *sx_iter, *inst_iter, *var_list = NULL, *var_iter;
1376 
1377  for (sx_iter = model->sx_instance_list; sx_iter != NULL; sx_iter = sx_iter->next)
1378  {
1379  GncSxInstances *instances = (GncSxInstances*)sx_iter->data;
1380  for (inst_iter = instances->instance_list; inst_iter != NULL; inst_iter = inst_iter->next)
1381  {
1382  GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
1383 
1384  if (inst->state != SX_INSTANCE_STATE_TO_CREATE)
1385  continue;
1386 
1387  g_hash_table_foreach(inst->variable_bindings, (GHFunc)_list_from_hash_elts, &var_list);
1388  for (var_iter = var_list; var_iter != NULL; var_iter = var_iter->next)
1389  {
1390  GncSxVariable *var = (GncSxVariable*)var_iter->data;
1391  if (gnc_numeric_check(var->value) != GNC_ERROR_OK)
1392  {
1393  GncSxVariableNeeded *need = g_new0(GncSxVariableNeeded, 1);
1394  need->instance = inst;
1395  need->variable = var;
1396  rtn = g_list_append(rtn, need);
1397  }
1398  }
1399  g_list_free(var_list);
1400  var_list = NULL;
1401  }
1402  }
1403  return rtn;
1404 }
GHashTable * variable_bindings
GncSxInstanceState state
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
void gnc_sx_instance_model_effect_change ( GncSxInstanceModel model,
gboolean  auto_create_only,
GList **  created_transaction_guids,
GList **  creation_errors 
)

Really ("effectively") create the transactions from the SX instances in the given model.

Definition at line 1219 of file gnc-sx-instance-model.c.

1223 {
1224  GList *iter;
1225 
1226  if (qof_book_is_readonly(gnc_get_current_book()))
1227  {
1228  /* Is the book read-only? Then don't change anything here. */
1229  return;
1230  }
1231 
1232  for (iter = model->sx_instance_list; iter != NULL; iter = iter->next)
1233  {
1234  GList *instance_iter;
1235  GncSxInstances *instances = (GncSxInstances*)iter->data;
1236  GDate *last_occur_date;
1237  gint instance_count = 0;
1238  gint remain_occur_count = 0;
1239 
1240  // If there are no instances, then skip; specifically, skip
1241  // re-setting SchedXaction fields, which will dirty the book
1242  // spuriously.
1243  if (g_list_length(instances->instance_list) == 0)
1244  continue;
1245 
1246  last_occur_date = (GDate*) xaccSchedXactionGetLastOccurDate(instances->sx);
1247  instance_count = gnc_sx_get_instance_count(instances->sx, NULL);
1248  remain_occur_count = xaccSchedXactionGetRemOccur(instances->sx);
1249 
1250  for (instance_iter = instances->instance_list; instance_iter != NULL; instance_iter = instance_iter->next)
1251  {
1252  GncSxInstance *inst = (GncSxInstance*)instance_iter->data;
1253  gboolean sx_is_auto_create;
1254 
1255  xaccSchedXactionGetAutoCreate(inst->parent->sx, &sx_is_auto_create, NULL);
1256  if (auto_create_only && !sx_is_auto_create)
1257  {
1258  if (inst->state != SX_INSTANCE_STATE_TO_CREATE)
1259  {
1260  break;
1261  }
1262  continue;
1263  }
1264 
1265  if (inst->orig_state == SX_INSTANCE_STATE_POSTPONED
1266  && inst->state != SX_INSTANCE_STATE_POSTPONED)
1267  {
1268  // remove from postponed list
1269  g_assert(inst->temporal_state != NULL);
1271  }
1272 
1273  switch (inst->state)
1274  {
1275  case SX_INSTANCE_STATE_CREATED:
1276  // nop: we've already processed this.
1277  break;
1278  case SX_INSTANCE_STATE_IGNORED:
1279  increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
1280  break;
1281  case SX_INSTANCE_STATE_POSTPONED:
1282  if (inst->orig_state != SX_INSTANCE_STATE_POSTPONED)
1283  {
1284  gnc_sx_add_defer_instance(instances->sx,
1286  }
1287  increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
1288  break;
1289  case SX_INSTANCE_STATE_TO_CREATE:
1290  create_transactions_for_instance(inst, created_transaction_guids, creation_errors);
1291  increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
1292  gnc_sx_instance_model_change_instance_state(model, inst, SX_INSTANCE_STATE_CREATED);
1293  break;
1294  case SX_INSTANCE_STATE_REMINDER:
1295  // do nothing
1296  // assert no non-remind instances after this?
1297  break;
1298  default:
1299  g_assert_not_reached();
1300  break;
1301  }
1302  }
1303 
1304  xaccSchedXactionSetLastOccurDate(instances->sx, last_occur_date);
1305  gnc_sx_set_instance_count(instances->sx, instance_count);
1306  xaccSchedXactionSetRemOccur(instances->sx, remain_occur_count);
1307  }
1308 }
void gnc_sx_set_instance_count(SchedXaction *sx, gint instance_num)
void gnc_sx_instance_model_change_instance_state(GncSxInstanceModel *model, GncSxInstance *instance, GncSxInstanceState new_state)
GncSxInstanceState orig_state
GncSxInstances * parent
void gnc_sx_add_defer_instance(SchedXaction *sx, void *deferStateData)
Adds an instance to the deferred list of the SX.
SXTmpStateData * gnc_sx_clone_temporal_state(SXTmpStateData *stateData)
Allocates and returns a one-by-one copy of the given temporal state.
gboolean qof_book_is_readonly(const QofBook *book)
GncSxInstanceState state
void gnc_sx_remove_defer_instance(SchedXaction *sx, void *deferStateData)
Removes an instance from the deferred list.
gint gnc_sx_get_instance_count(const SchedXaction *sx, SXTmpStateData *stateData)
Get the instance count.
void gnc_sx_instance_model_summarize ( GncSxInstanceModel model,
GncSxSummary summary 
)
Parameters
summaryCaller-provided, populated with a summarization of the state of the model. Specifically, used to determine if there are SLR SXes that need either auto-creation or user-interaction.

Definition at line 1407 of file gnc-sx-instance-model.c.

1408 {
1409  GList *sx_iter, *inst_iter;
1410 
1411  g_return_if_fail(model != NULL);
1412  g_return_if_fail(summary != NULL);
1413 
1414  summary->need_dialog = FALSE;
1415  summary->num_instances = 0;
1416  summary->num_to_create_instances = 0;
1417  summary->num_auto_create_instances = 0;
1419 
1420  for (sx_iter = model->sx_instance_list; sx_iter != NULL; sx_iter = sx_iter->next)
1421  {
1422  GncSxInstances *instances = (GncSxInstances*)sx_iter->data;
1423  gboolean sx_is_auto_create = FALSE, sx_notify = FALSE;
1424  xaccSchedXactionGetAutoCreate(instances->sx, &sx_is_auto_create, &sx_notify);
1425  for (inst_iter = instances->instance_list; inst_iter != NULL; inst_iter = inst_iter->next)
1426  {
1427  GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
1428  summary->num_instances++;
1429 
1430  if (inst->state == SX_INSTANCE_STATE_TO_CREATE)
1431  {
1432  if (sx_is_auto_create)
1433  {
1434  if (!sx_notify)
1435  {
1437  }
1438  else
1439  {
1440  summary->num_auto_create_instances++;
1441  }
1442  }
1443  else
1444  {
1445  summary->num_to_create_instances++;
1446  }
1447  }
1448  }
1449  }
1450 
1451  // if all the instances are 'auto-create, no-notify', then we don't need
1452  // the dialog.
1453  summary->need_dialog
1454  = (summary->num_instances != 0
1455  && summary->num_auto_create_no_notify_instances != summary->num_instances);
1456 }
gint num_auto_create_no_notify_instances
GncSxInstanceState state
void gnc_sx_instance_model_update_sx_instances ( GncSxInstanceModel model,
SchedXaction sx 
)

Regenerates and updates the GncSxInstances* for the given SX. Model consumers are probably going to call this in response to seeing the "update" signal, unless they need to be doing something else like finishing an iteration over an existing GncSxInstances*.

Definition at line 725 of file gnc-sx-instance-model.c.

726 {
727  GncSxInstances *existing, *new_instances;
728  GList *link;
729 
730  link = g_list_find_custom(model->sx_instance_list, sx, (GCompareFunc)_gnc_sx_instance_find_by_sx);
731  if (link == NULL)
732  {
733  g_critical("couldn't find sx [%p]\n", sx);
734  return;
735  }
736 
737  // merge the new instance data into the existing structure, mutating as little as possible.
738  existing = (GncSxInstances*)link->data;
739  new_instances = _gnc_sx_gen_instances((gpointer)sx, &model->range_end);
740  existing->sx = new_instances->sx;
741  existing->next_instance_date = new_instances->next_instance_date;
742  {
743  GList *existing_iter, *new_iter;
744  gboolean existing_remain, new_remain;
745 
746  // step through the lists pairwise, and retain the existing
747  // instance if the dates align, as soon as they don't stop and
748  // cleanup.
749  existing_iter = existing->instance_list;
750  new_iter = new_instances->instance_list;
751  for (; existing_iter != NULL && new_iter != NULL; existing_iter = existing_iter->next, new_iter = new_iter->next)
752  {
753  GncSxInstance *existing_inst, *new_inst;
754  gboolean same_instance_date;
755  existing_inst = (GncSxInstance*)existing_iter->data;
756  new_inst = (GncSxInstance*)new_iter->data;
757 
758  same_instance_date = g_date_compare(&existing_inst->date, &new_inst->date) == 0;
759  if (!same_instance_date)
760  break;
761  }
762 
763  existing_remain = (existing_iter != NULL);
764  new_remain = (new_iter != NULL);
765 
766  if (existing_remain)
767  {
768  // delete excess
769  gnc_g_list_cut(&existing->instance_list, existing_iter);
770  g_list_foreach(existing_iter, (GFunc)gnc_sx_instance_free, NULL);
771  }
772 
773  if (new_remain)
774  {
775  // append new
776  GList *new_iter_iter;
777  gnc_g_list_cut(&new_instances->instance_list, new_iter);
778 
779  for (new_iter_iter = new_iter; new_iter_iter != NULL; new_iter_iter = new_iter_iter->next)
780  {
781  GncSxInstance *inst = (GncSxInstance*)new_iter_iter->data;
782  inst->parent = existing;
783  existing->instance_list = g_list_append(existing->instance_list, new_iter_iter->data);
784  }
785  g_list_free(new_iter);
786  }
787  }
788 
789  // handle variables
790  {
791  HashListPair removed_cb_data, added_cb_data;
792  GList *removed_var_names = NULL, *added_var_names = NULL;
793  GList *inst_iter = NULL;
794 
795  removed_cb_data.hash = new_instances->variable_names;
796  removed_cb_data.list = NULL;
797  g_hash_table_foreach(existing->variable_names, (GHFunc)_find_unreferenced_vars, &removed_cb_data);
798  removed_var_names = removed_cb_data.list;
799  g_debug("%d removed variables", g_list_length(removed_var_names));
800 
801  added_cb_data.hash = existing->variable_names;
802  added_cb_data.list = NULL;
803  g_hash_table_foreach(new_instances->variable_names, (GHFunc)_find_unreferenced_vars, &added_cb_data);
804  added_var_names = added_cb_data.list;
805  g_debug("%d added variables", g_list_length(added_var_names));
806 
807  if (existing->variable_names != NULL)
808  {
809  g_hash_table_destroy(existing->variable_names);
810  }
811  existing->variable_names = new_instances->variable_names;
812  new_instances->variable_names = NULL;
813 
814  for (inst_iter = existing->instance_list; inst_iter != NULL; inst_iter = inst_iter->next)
815  {
816  GList *var_iter;
817  GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
818 
819  for (var_iter = removed_var_names; var_iter != NULL; var_iter = var_iter->next)
820  {
821  gchar *to_remove_key = (gchar*)var_iter->data;
822  g_hash_table_remove(inst->variable_bindings, to_remove_key);
823  }
824 
825  for (var_iter = added_var_names; var_iter != NULL; var_iter = var_iter->next)
826  {
827  gchar *to_add_key = (gchar*)var_iter->data;
828  if (!g_hash_table_lookup_extended(
829  inst->variable_bindings, to_add_key, NULL, NULL))
830  {
831  GncSxVariable *parent_var
832  = g_hash_table_lookup(existing->variable_names, to_add_key);
833  GncSxVariable *var_copy;
834 
835  g_assert(parent_var != NULL);
836  var_copy = gnc_sx_variable_new_copy(parent_var);
837  g_hash_table_insert(inst->variable_bindings, g_strdup(to_add_key), var_copy);
838  }
839  }
840  }
841  }
842  gnc_sx_instances_free(new_instances);
843 }
GncSxInstances * parent
void gnc_g_list_cut(GList **list, GList *cut_point)
GHashTable * variable_bindings
GHashTable * variable_names
void gnc_sx_summary_print ( const GncSxSummary summary)

Debug output to trace file

Definition at line 1459 of file gnc-sx-instance-model.c.

1460 {
1461  g_message("num_instances: %d", summary->num_instances);
1462  g_message("num_to_create: %d", summary->num_to_create_instances);
1463  g_message("num_auto_create_instances: %d", summary->num_auto_create_instances);
1464  g_message("num_auto_create_no_notify_instances: %d", summary->num_auto_create_no_notify_instances);
1465  g_message("need dialog? %s", summary->need_dialog ? "true" : "false");
1466 }
gint num_auto_create_no_notify_instances