GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dialog-sx-since-last-run.c
1 /********************************************************************\
2  * dialog-sx-since-last-run.c : dialog for scheduled transaction *
3  * since-last-run processing. *
4  * Copyright (C) 2006 Joshua Sled <[email protected]> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of version 2 and/or version 3 of the *
8  * GNU General Public License as published by the Free Software *
9  * Foundation. *
10  * *
11  * As a special exception, permission is granted to link the binary *
12  * module resultant from this code with the OpenSSL project's *
13  * "OpenSSL" library (or modified versions of it that use the same *
14  * license as the "OpenSSL" library), and distribute the linked *
15  * executable. You must obey the GNU General Public License in all *
16  * respects for all of the code used other than "OpenSSL". If you *
17  * modify this file, you may extend this exception to your version *
18  * of the file, but you are not obligated to do so. If you do not *
19  * wish to do so, delete this exception statement from your version *
20  * of this file. *
21  * *
22  * This program is distributed in the hope that it will be useful, *
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25  * GNU General Public License for more details. *
26  * *
27  * You should have received a copy of the GNU General Public License*
28  * along with this program; if not, contact: *
29  * *
30  * Free Software Foundation Voice: +1-617-542-5942 *
31  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
32  * Boston, MA 02110-1301, USA [email protected] *
33 \********************************************************************/
34 
35 #include "config.h"
36 #include <glib.h>
37 #include <gtk/gtk.h>
38 
39 #include "dialog-utils.h"
40 #include "gnc-sx-instance-model.h"
41 #include "dialog-sx-since-last-run.h"
42 
43 #include "gnc-prefs.h"
44 #include "gnc-ui-util.h"
45 #include "Query.h"
46 #include "qof.h"
47 #include "gnc-ledger-display.h"
49 /*################## Added for Reg2 #################*/
50 #include "gnc-ledger-display2.h"
51 #include "gnc-plugin-page-register2.h"
52 /*################## Added for Reg2 #################*/
53 #include "gnc-main-window.h"
54 #include "gnc-component-manager.h"
55 #include "gnc-gui-query.h"
56 #include "gnc-session.h"
57 
58 #undef G_LOG_DOMAIN
59 #define G_LOG_DOMAIN "gnc.gui.sx.slr"
60 
61 G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI_SX;
62 
63 #define DIALOG_SX_SINCE_LAST_RUN_CM_CLASS "dialog-sx-since-last-run"
64 
66 {
67  GtkWidget *dialog;
68  gint component_id;
69  GncSxSlrTreeModelAdapter *editing_model;
70  GtkTreeView *instance_view;
71  GtkToggleButton *review_created_txns_toggle;
72  GList *created_txns;
73 };
74 
75 /* ------------------------------------------------------------ */
76 
77 static GObjectClass *parent_class = NULL;
78 
80 {
81  GObject parent;
82 
83  /* protected: */
84  gulong updated_cb_id;
85  gboolean disposed;
86 
87  GncSxInstanceModel *instances;
88  GtkTreeStore *real;
89 };
90 
92 {
93  GObjectClass parent;
95 
96 GType gnc_sx_slr_tree_model_adapter_get_type(void);
97 static void gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass);
98 static void gnc_sx_slr_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data);
99 static void gnc_sx_slr_tree_model_adapter_init(GTypeInstance *instance, gpointer klass);
100 GncSxSlrTreeModelAdapter* gnc_sx_slr_tree_model_adapter_new(GncSxInstanceModel *instances);
101 static void gnc_sx_slr_tree_model_adapter_dispose(GObject *obj);
102 static void gnc_sx_slr_tree_model_adapter_finalize(GObject *obj);
103 
104 GncSxInstanceModel* gnc_sx_slr_tree_model_adapter_get_instance_model(GncSxSlrTreeModelAdapter *slr_model);
105 GncSxInstances* gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
106 static GncSxInstances* _gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth);
108 GncSxInstance* gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
109 static GncSxInstance* _gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth);
111 gboolean gnc_sx_slr_model_get_instance_and_variable(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, GncSxInstance **instance_loc, GncSxVariable **var_loc);
112 
113 void gnc_sx_slr_model_effect_change(GncSxSlrTreeModelAdapter *model, gboolean auto_create_only, GList **created_transaction_guids, GList **creation_errors);
114 
115 GtkTreeModel* gnc_sx_get_slr_state_model(void);
116 
117 #define GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER (gnc_sx_slr_tree_model_adapter_get_type ())
118 #define GNC_SX_SLR_TREE_MODEL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapter))
119 #define GNC_SX_SLR_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapterClass))
120 #define GNC_IS_SX_SLR_TREE_MODEL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER))
121 #define GNC_IS_SX_SLR_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER))
122 #define GNC_SX_SLR_TREE_MODEL_ADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapterClass))
123 
124 /* ------------------------------------------------------------ */
125 
126 static void _show_created_transactions(GncSxSinceLastRunDialog *app_dialog, GList *created_txn_guids);
127 
128 static void close_handler(gpointer user_data);
129 static void dialog_destroy_cb(GtkObject *object, GncSxSinceLastRunDialog *app_dialog);
130 static void dialog_response_cb(GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog *app_dialog);
131 
132 /* ------------------------------------------------------------ */
133 
134 static void
135 _var_numeric_to_string(gnc_numeric *value, GString **str)
136 {
137  *str = g_string_sized_new(5);
138  g_string_printf(*str, "%0.2f", gnc_numeric_to_double(*value));
139 }
140 
141 /* ------------------------------------------------------------ */
142 
143 GType
144 gnc_sx_slr_tree_model_adapter_get_type(void)
145 {
146  static GType gsstma_type = 0;
147  if (gsstma_type == 0)
148  {
149  static const GTypeInfo info =
150  {
152  NULL, /* base_init */
153  NULL, /* base_finalize */
154  (GClassInitFunc)gnc_sx_slr_tree_model_adapter_class_init, /* class_init */
155  NULL, /* class_finalize */
156  NULL, /* class_data */
157  sizeof (GncSxSlrTreeModelAdapter),
158  0, /* n_preallocs */
159  (GInstanceInitFunc)gnc_sx_slr_tree_model_adapter_init /* instance_init */
160  };
161  static const GInterfaceInfo itreeModel_info =
162  {
163  (GInterfaceInitFunc) gnc_sx_slr_tree_model_adapter_interface_init, /* interface_init */
164  NULL, /* interface_finalize */
165  NULL /* interface_data */
166  };
167 
168  gsstma_type = g_type_register_static (G_TYPE_OBJECT,
169  "GncSxSlrTreeModelAdapterType",
170  &info, 0);
171  g_type_add_interface_static(gsstma_type,
172  GTK_TYPE_TREE_MODEL,
173  &itreeModel_info);
174  }
175  return gsstma_type;
176 }
177 
178 static void
179 gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass)
180 {
181  GObjectClass *obj_class;
182 
183  parent_class = g_type_class_peek_parent(klass);
184 
185  obj_class = G_OBJECT_CLASS(klass);
186 
187  obj_class->dispose = gnc_sx_slr_tree_model_adapter_dispose;
188  obj_class->finalize = gnc_sx_slr_tree_model_adapter_finalize;
189 }
190 
191 static GtkTreeModelFlags
192 gsslrtma_get_flags(GtkTreeModel *tree_model)
193 {
194  return gtk_tree_model_get_flags(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real));
195 }
196 
197 static gint
198 gsslrtma_get_n_columns(GtkTreeModel *tree_model)
199 {
200  return gtk_tree_model_get_n_columns(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real));
201 }
202 
203 static GType
204 gsslrtma_get_column_type(GtkTreeModel *tree_model, gint index)
205 {
206  return gtk_tree_model_get_column_type(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), index);
207 }
208 
209 static gboolean
210 gsslrtma_get_iter(GtkTreeModel *tree_model,
211  GtkTreeIter *iter,
212  GtkTreePath *path)
213 {
214  return gtk_tree_model_get_iter(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, path);
215 }
216 
217 static GtkTreePath*
218 gsslrtma_get_path(GtkTreeModel *tree_model,
219  GtkTreeIter *iter)
220 {
221  return gtk_tree_model_get_path(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
222 }
223 
224 static void
225 gsslrtma_get_value(GtkTreeModel *tree_model,
226  GtkTreeIter *iter,
227  gint column,
228  GValue *value)
229 {
230  gtk_tree_model_get_value(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, column, value);
231 }
232 
233 static gboolean
234 gsslrtma_iter_next(GtkTreeModel *tree_model,
235  GtkTreeIter *iter)
236 {
237  return gtk_tree_model_iter_next(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
238 }
239 
240 static gboolean
241 gsslrtma_iter_children(GtkTreeModel *tree_model,
242  GtkTreeIter *iter,
243  GtkTreeIter *parent)
244 {
245  return gtk_tree_model_iter_children(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent);
246 }
247 
248 static gboolean
249 gsslrtma_iter_has_child(GtkTreeModel *tree_model,
250  GtkTreeIter *iter)
251 {
252  return gtk_tree_model_iter_has_child(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
253 }
254 
255 static gint
256 gsslrtma_iter_n_children(GtkTreeModel *tree_model,
257  GtkTreeIter *iter)
258 {
259  return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
260 }
261 
262 static gboolean
263 gsslrtma_iter_nth_child(GtkTreeModel *tree_model,
264  GtkTreeIter *iter,
265  GtkTreeIter *parent,
266  gint n)
267 {
268  return gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent, n);
269 }
270 
271 static gboolean
272 gsslrtma_iter_parent(GtkTreeModel *tree_model,
273  GtkTreeIter *iter,
274  GtkTreeIter *child)
275 {
276  return gtk_tree_model_iter_parent(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, child);
277 }
278 
279 static void
280 gsslrtma_ref_node(GtkTreeModel *tree_model,
281  GtkTreeIter *iter)
282 {
283  gtk_tree_model_ref_node(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
284 }
285 
286 static void
287 gsslrtma_unref_node(GtkTreeModel *tree_model,
288  GtkTreeIter *iter)
289 {
290  gtk_tree_model_unref_node(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
291 }
292 
293 static void
294 gnc_sx_slr_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data)
295 {
296  GtkTreeModelIface *tree_model = (GtkTreeModelIface*)g_iface;
297  tree_model->get_flags = gsslrtma_get_flags;
298  tree_model->get_n_columns = gsslrtma_get_n_columns;
299  tree_model->get_column_type = gsslrtma_get_column_type;
300  tree_model->get_iter = gsslrtma_get_iter;
301  tree_model->get_path = gsslrtma_get_path;
302  tree_model->get_value = gsslrtma_get_value;
303  tree_model->iter_next = gsslrtma_iter_next;
304  tree_model->iter_children = gsslrtma_iter_children;
305  tree_model->iter_has_child = gsslrtma_iter_has_child;
306  tree_model->iter_n_children = gsslrtma_iter_n_children;
307  tree_model->iter_nth_child = gsslrtma_iter_nth_child;
308  tree_model->iter_parent = gsslrtma_iter_parent;
309  tree_model->ref_node = gsslrtma_ref_node;
310  tree_model->unref_node = gsslrtma_unref_node;
311 }
312 
313 static void
314 gsslrtma_proxy_row_changed(GtkTreeModel *treemodel,
315  GtkTreePath *arg1,
316  GtkTreeIter *arg2,
317  gpointer user_data)
318 {
319  g_signal_emit_by_name(user_data, "row-changed", arg1, arg2);
320 }
321 
322 static void
323 gsslrtma_proxy_row_deleted(GtkTreeModel *treemodel,
324  GtkTreePath *arg1,
325  gpointer user_data)
326 {
327  g_signal_emit_by_name(user_data, "row-deleted", arg1);
328 }
329 
330 static void
331 gsslrtma_proxy_row_has_child_toggled(GtkTreeModel *treemodel,
332  GtkTreePath *arg1,
333  GtkTreeIter *arg2,
334  gpointer user_data)
335 {
336  g_signal_emit_by_name(user_data, "row-has-child-toggled", arg1, arg2);
337 }
338 
339 static void
340 gsslrtma_proxy_row_inserted(GtkTreeModel *treemodel,
341  GtkTreePath *arg1,
342  GtkTreeIter *arg2,
343  gpointer user_data)
344 {
345  g_signal_emit_by_name(user_data, "row-inserted", arg1, arg2);
346 }
347 
348 static void
349 gsslrtma_proxy_rows_reordered(GtkTreeModel *treemodel,
350  GtkTreePath *arg1,
351  GtkTreeIter *arg2,
352  gpointer arg3,
353  gpointer user_data)
354 {
355  g_signal_emit_by_name(user_data, "rows-reordered", arg1, arg2, arg3);
356 }
357 
358 // model columns
359 enum
360 {
361  SLR_MODEL_COL_NAME = 0,
362  SLR_MODEL_COL_INSTANCE_STATE,
363  SLR_MODEL_COL_VARAIBLE_VALUE,
364  SLR_MODEL_COL_INSTANCE_VISIBILITY,
365  SLR_MODEL_COL_VARIABLE_VISIBILITY,
366  SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
367 };
368 
369 static void
370 gnc_sx_slr_tree_model_adapter_init(GTypeInstance *instance, gpointer klass)
371 {
372  GncSxSlrTreeModelAdapter *adapter = GNC_SX_SLR_TREE_MODEL_ADAPTER(instance);
373  // columns: thing-name, instance-state, variable-value, instance-visible, variable-visible, instance_state_sensitivity
374  // at depth=0: <sx>, N/A, N/A, N/A N/A, N/A
375  // at depth=1: <instance>, <state>, N/A, <valid>, N/A, <valid>
376  // at depth=2: <variable>, N/A, <value>, N/A, <valid>, N/A
377  adapter->real = gtk_tree_store_new(6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
378 
379  g_signal_connect(adapter->real, "row-changed", G_CALLBACK(gsslrtma_proxy_row_changed), adapter);
380  g_signal_connect(adapter->real, "row-deleted", G_CALLBACK(gsslrtma_proxy_row_deleted), adapter);
381  g_signal_connect(adapter->real, "row-has-child-toggled", G_CALLBACK(gsslrtma_proxy_row_has_child_toggled), adapter);
382  g_signal_connect(adapter->real, "row-inserted", G_CALLBACK(gsslrtma_proxy_row_inserted), adapter);
383  g_signal_connect(adapter->real, "rows-reordered", G_CALLBACK(gsslrtma_proxy_rows_reordered), adapter);
384 }
385 
386 static char* gnc_sx_instance_state_names[] =
387 {
388  N_("Ignored"),
389  N_("Postponed"),
390  N_("To-Create"),
391  N_("Reminder"),
392  N_("Created"),
393  NULL
394 };
395 
396 static GtkTreeModel* _singleton_slr_state_model = NULL;
397 
398 GtkTreeModel*
399 gnc_sx_get_slr_state_model(void)
400 {
401  if (_singleton_slr_state_model == NULL)
402  {
403  int i;
404  GtkTreeIter iter;
405 
406  _singleton_slr_state_model = GTK_TREE_MODEL(gtk_list_store_new(1, G_TYPE_STRING));
407  for (i = 0; i != SX_INSTANCE_STATE_CREATED; i++)
408  {
409  gtk_list_store_insert_with_values(GTK_LIST_STORE(_singleton_slr_state_model),
410  &iter,
411  SX_INSTANCE_STATE_MAX_STATE + 1,
412  0, _(gnc_sx_instance_state_names[i]), -1);
413  }
414  }
415  return _singleton_slr_state_model;
416 }
417 
418 static void
419 _consume_excess_rows(GtkTreeStore *store, int last_index, GtkTreeIter *parent_iter, GtkTreeIter *maybe_invalid_iter)
420 {
421  if (last_index == -1)
422  {
423  // try to get whatever was there beforehand, if it exists
424  if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(store), maybe_invalid_iter, parent_iter))
425  return;
426  }
427  else
428  {
429  // increment the iter, or bail out.
430  if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store), maybe_invalid_iter))
431  return;
432  }
433 
434  // consume until we're done.
435  while (gtk_tree_store_remove(store, maybe_invalid_iter));
436 }
437 
438 
439 static void
440 gsslrtma_populate_tree_store(GncSxSlrTreeModelAdapter *model)
441 {
442  GtkTreeIter sx_tree_iter;
443  GList *sx_iter;
444  int instances_index = -1;
445 
446  for (sx_iter = model->instances->sx_instance_list; sx_iter != NULL; sx_iter = sx_iter->next)
447  {
448  GncSxInstances *instances = (GncSxInstances*)sx_iter->data;
449  char last_occur_date_buf[MAX_DATE_LENGTH+1];
450 
451  {
452  const GDate *last_occur = xaccSchedXactionGetLastOccurDate(instances->sx);
453  if (last_occur == NULL || !g_date_valid(last_occur))
454  {
455  g_stpcpy(last_occur_date_buf, _("Never"));
456  }
457  else
458  {
459  qof_print_gdate(last_occur_date_buf,
461  last_occur);
462  }
463  }
464 
465  if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real), &sx_tree_iter, NULL, ++instances_index))
466  {
467  gtk_tree_store_append(model->real, &sx_tree_iter, NULL);
468  }
469 
470  gtk_tree_store_set(model->real, &sx_tree_iter,
471  SLR_MODEL_COL_NAME, xaccSchedXactionGetName(instances->sx),
472  SLR_MODEL_COL_INSTANCE_STATE, NULL,
473  SLR_MODEL_COL_VARAIBLE_VALUE, NULL,
474  SLR_MODEL_COL_INSTANCE_VISIBILITY, FALSE,
475  SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
476  SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
477  -1);
478 
479  // Insert instance information
480  {
481  GList *inst_iter;
482  GtkTreeIter inst_tree_iter;
483  char instance_date_buf[MAX_DATE_LENGTH+1];
484  int instance_index = -1;
485 
486  for (inst_iter = instances->instance_list; inst_iter != NULL; inst_iter = inst_iter->next)
487  {
488  GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
489  qof_print_gdate(instance_date_buf, MAX_DATE_LENGTH, &inst->date);
490 
491  if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real), &inst_tree_iter, &sx_tree_iter, ++instance_index))
492  {
493  gtk_tree_store_append(model->real, &inst_tree_iter, &sx_tree_iter);
494  }
495  gtk_tree_store_set(model->real, &inst_tree_iter,
496  SLR_MODEL_COL_NAME, instance_date_buf,
497  SLR_MODEL_COL_INSTANCE_STATE, _(gnc_sx_instance_state_names[inst->state]),
498  SLR_MODEL_COL_VARAIBLE_VALUE, NULL,
499  SLR_MODEL_COL_INSTANCE_VISIBILITY, TRUE,
500  SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
501  SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, inst->state != SX_INSTANCE_STATE_CREATED,
502  -1);
503 
504  // Insert variable information
505  {
506  GList *vars = NULL, *var_iter;
507  GtkTreeIter var_tree_iter;
508  gint visible_variable_index = -1;
509 
510  vars = gnc_sx_instance_get_variables(inst);
511  for (var_iter = vars; var_iter != NULL; var_iter = var_iter->next)
512  {
513  GncSxVariable *var = (GncSxVariable*)var_iter->data;
514  GString *tmp_str;
515 
516  if (!var->editable)
517  continue;
518 
519  if (gnc_numeric_check(var->value) == GNC_ERROR_OK)
520  {
521  _var_numeric_to_string(&var->value, &tmp_str);
522  }
523  else
524  {
525  tmp_str = g_string_new(_("(Need Value)"));
526  }
527 
528  if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real),
529  &var_tree_iter, &inst_tree_iter,
530  ++visible_variable_index))
531  {
532  gtk_tree_store_append(model->real, &var_tree_iter, &inst_tree_iter);
533  }
534  gtk_tree_store_set(model->real, &var_tree_iter,
535  SLR_MODEL_COL_NAME, var->name,
536  SLR_MODEL_COL_INSTANCE_STATE, NULL,
537  SLR_MODEL_COL_VARAIBLE_VALUE, tmp_str->str,
538  SLR_MODEL_COL_INSTANCE_VISIBILITY, FALSE,
539  SLR_MODEL_COL_VARIABLE_VISIBILITY, TRUE,
540  SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
541  -1);
542  g_string_free(tmp_str, TRUE);
543  }
544  g_list_free(vars);
545 
546  _consume_excess_rows(model->real, visible_variable_index, &inst_tree_iter, &var_tree_iter);
547  }
548  }
549 
550  // if there are more instance iters, remove
551  _consume_excess_rows(model->real, instance_index, &sx_tree_iter, &inst_tree_iter);
552  }
553  }
554  _consume_excess_rows(model->real, instances_index, NULL, &sx_tree_iter);
555 }
556 
558 gnc_sx_slr_tree_model_adapter_get_instance_model(GncSxSlrTreeModelAdapter *slr_model)
559 {
560  return slr_model->instances;
561 }
562 
564 gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter)
565 {
566  return _gnc_sx_slr_tree_model_adapter_get_sx_instances(model, iter, TRUE);
567 }
568 
569 static GncSxInstances*
570 _gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
571 {
572  GtkTreePath *path;
573  gint *indices, index;
574  path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
575  if (check_depth && gtk_tree_path_get_depth(path) != 1)
576  {
577  gtk_tree_path_free(path);
578  return NULL;
579  }
580  indices = gtk_tree_path_get_indices(path);
581  index = indices[0];
582  gtk_tree_path_free(path);
583 
584  return (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, index);
585 }
586 
588 gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter)
589 {
590  return _gnc_sx_slr_model_get_instance(model, iter, TRUE);
591 }
592 
593 static GncSxInstance*
594 _gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
595 {
596  GtkTreePath *path;
597  gint *indices, instances_index, instance_index;
598  GncSxInstances *instances;
599  path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
600  if (check_depth && gtk_tree_path_get_depth(path) != 2)
601  {
602  gtk_tree_path_free(path);
603  return NULL;
604  }
605  indices = gtk_tree_path_get_indices(path);
606  instances_index = indices[0];
607  instance_index = indices[1];
608  gtk_tree_path_free(path);
609 
610  instances = (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, instances_index);
611  if (instance_index < 0 || instance_index >= g_list_length(instances->instance_list))
612  {
613  return NULL;
614  }
615 
616  return (GncSxInstance*)g_list_nth_data(instances->instance_list, instance_index);
617 }
618 
619 gboolean
620 gnc_sx_slr_model_get_instance_and_variable(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, GncSxInstance **instance_loc, GncSxVariable **var_loc)
621 {
622  GtkTreePath *path;
623  gint *indices, variable_index;
624  GncSxInstance *instance;
625  GList *variables;
626 
627  instance = _gnc_sx_slr_model_get_instance(model, iter, FALSE);
628  if (instance == NULL)
629  {
630  return FALSE;
631  }
632  variables = gnc_sx_instance_get_variables(instance);
633 
634  path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
635  if (gtk_tree_path_get_depth(path) != 3)
636  {
637  gtk_tree_path_free(path);
638  return FALSE;
639  }
640  indices = gtk_tree_path_get_indices(path);
641  variable_index = indices[2];
642  gtk_tree_path_free(path);
643 
644  if (variable_index < 0 || variable_index >= g_list_length(variables))
645  {
646  g_list_free(variables);
647  return FALSE;
648  }
649 
650  if (instance_loc != NULL)
651  {
652  *instance_loc = instance;
653  }
654 
655  if (var_loc != NULL)
656  {
657  // *var_loc = (GncSxVariable*)g_list_nth_data(variables, variable_index);
658  GList *list_iter = variables;
659  for (; list_iter != NULL; list_iter = list_iter->next)
660  {
661  GncSxVariable *var = (GncSxVariable*)list_iter->data;
662  if (!var->editable)
663  continue;
664  if (variable_index-- == 0)
665  {
666  *var_loc = var;
667  break;
668  }
669  }
670  }
671 
672  g_list_free(variables);
673  return TRUE;
674 }
675 
679 static gint
680 _variable_list_index(GList *variables, GncSxVariable *variable)
681 {
682  gint index = 0;
683  for (; variables != NULL; variables = variables->next)
684  {
685  GncSxVariable *var = (GncSxVariable*)variables->data;
686  if (!var->editable)
687  continue;
688  if (variable == var)
689  return index;
690  index++;
691  }
692  return -1;
693 }
694 
695 static GtkTreePath*
696 _get_path_for_variable(GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxVariable *variable)
697 {
698  GList *variables;
699  int indices[3];
700  GtkTreePath *path;
701 
702  indices[0] = g_list_index(model->instances->sx_instance_list, instance->parent);
703  if (indices[0] == -1)
704  return NULL;
705  indices[1] = g_list_index(instance->parent->instance_list, instance);
706  if (indices[1] == -1)
707  return NULL;
708  variables = gnc_sx_instance_get_variables(instance);
709  indices[2] = _variable_list_index(variables, variable);
710  g_list_free(variables);
711  if (indices[2] == -1)
712  return NULL;
713  path = gtk_tree_path_new_from_indices(indices[0], indices[1], indices[2], -1);
714  return path;
715 }
716 
717 static void
718 gsslrtma_added_cb(GncSxInstanceModel *instances, SchedXaction *added_sx, gpointer user_data)
719 {
720  GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data);
721  // this is wasteful, but fine.
722  gsslrtma_populate_tree_store(model);
723 }
724 
725 static void
726 gsslrtma_updated_cb(GncSxInstanceModel *instances, SchedXaction *updated_sx, gpointer user_data)
727 {
728  GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data);
729  gnc_sx_instance_model_update_sx_instances(instances, updated_sx);
730  gsslrtma_populate_tree_store(model);
731 }
732 
733 static void
734 gsslrtma_removing_cb(GncSxInstanceModel *instances, SchedXaction *to_remove_sx, gpointer user_data)
735 {
736  GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data);
737  GtkTreeIter tree_iter;
738  GList *iter;
739  int index = 0;
740  // get index, create path, remove
741  for (iter = instances->sx_instance_list; iter != NULL; iter = iter->next, index++)
742  {
743  GncSxInstances *instances = (GncSxInstances*)iter->data;
744  if (instances->sx == to_remove_sx)
745  break;
746  }
747  if (iter == NULL)
748  return; // couldn't find sx in our model, which is weird.
749  if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real), &tree_iter, NULL, index))
750  return; // perr(couldn't get something that should exist.
751  gtk_tree_store_remove(model->real, &tree_iter);
752 
753  gnc_sx_instance_model_remove_sx_instances(instances, to_remove_sx);
754 }
755 
756 static void
757 gnc_sx_slr_tree_model_adapter_dispose(GObject *obj)
758 {
759  GncSxSlrTreeModelAdapter *adapter;
760  g_return_if_fail(obj != NULL);
761  adapter = GNC_SX_SLR_TREE_MODEL_ADAPTER(obj);
762  g_return_if_fail(!adapter->disposed);
763  adapter->disposed = TRUE;
764 
765  g_object_unref(G_OBJECT(adapter->instances));
766  adapter->instances = NULL;
767  g_object_unref(G_OBJECT(adapter->real));
768  adapter->real = NULL;
769 
770  G_OBJECT_CLASS(parent_class)->dispose(obj);
771 }
772 
773 static void
774 gnc_sx_slr_tree_model_adapter_finalize(GObject *obj)
775 {
776  g_return_if_fail(obj != NULL);
777  G_OBJECT_CLASS(parent_class)->finalize(obj);
778 }
779 
781 gnc_sx_slr_tree_model_adapter_new(GncSxInstanceModel *instances)
782 {
784  rtn = GNC_SX_SLR_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, NULL));
785  rtn->instances = instances;
786  g_object_ref(G_OBJECT(rtn->instances));
787  gsslrtma_populate_tree_store(rtn);
788  g_signal_connect(G_OBJECT(rtn->instances), "added", (GCallback)gsslrtma_added_cb, (gpointer)rtn);
789  rtn->updated_cb_id = g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsslrtma_updated_cb, (gpointer)rtn);
790  g_signal_connect(G_OBJECT(rtn->instances), "removing", (GCallback)gsslrtma_removing_cb, (gpointer)rtn);
791  return rtn;
792 }
793 
794 void
795 gnc_sx_sxsincelast_book_opened(void)
796 {
797  GList *auto_created_txns = NULL;
798  GncSxInstanceModel *inst_model;
799  GncSxSummary summary;
800 
801  if (!gnc_prefs_get_bool (GNC_PREFS_GROUP_STARTUP, GNC_PREF_RUN_AT_FOPEN))
802  return;
803 
804  if (qof_book_is_readonly(gnc_get_current_book()))
805  {
806  /* Is the book read-only? Then don't change anything here. */
807  return;
808  }
809 
810  inst_model = gnc_sx_get_current_instances();
811  gnc_sx_instance_model_summarize(inst_model, &summary);
812  gnc_sx_summary_print(&summary);
813  gnc_sx_instance_model_effect_change(inst_model, TRUE, &auto_created_txns, NULL);
814 
815  if (summary.need_dialog)
816  {
817  gnc_ui_sx_since_last_run_dialog(inst_model, auto_created_txns);
818  auto_created_txns = NULL;
819  }
820  else
821  {
822  if (summary.num_auto_create_no_notify_instances != 0)
823  {
824  if (!gnc_prefs_get_bool(GNC_PREFS_GROUP_STARTUP, GNC_PREF_SHOW_AT_FOPEN))
825  return;
826 
827  gnc_info_dialog
828  (NULL,
829  ngettext
830  ("There are no Scheduled Transactions to be entered at this time. "
831  "(One transaction automatically created)",
832  "There are no Scheduled Transactions to be entered at this time. "
833  "(%d transactions automatically created)",
836  }
837  }
838  g_list_free(auto_created_txns);
839  g_object_unref(G_OBJECT(inst_model));
840 }
841 
842 static void
843 instance_state_changed_cb(GtkCellRendererText *cell,
844  const gchar *path,
845  const gchar *value,
846  GncSxSinceLastRunDialog *dialog)
847 {
848  GtkTreeIter tree_iter;
849  GncSxInstance *inst;
850  int i;
851  GncSxInstanceState new_state;
852 
853  for (i = 0; i < SX_INSTANCE_STATE_CREATED; i++)
854  {
855  if (strcmp(value, _(gnc_sx_instance_state_names[i])) == 0)
856  break;
857  }
858  if (i == SX_INSTANCE_STATE_CREATED)
859  {
860  g_warning("unknown value [%s]", value);
861  return;
862  }
863  new_state = i;
864 
865  if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(dialog->editing_model), &tree_iter, path))
866  {
867  g_warning("unknown path [%s]", path);
868  return;
869  }
870 
871  inst = gnc_sx_slr_model_get_instance(dialog->editing_model, &tree_iter);
872  if (inst == NULL)
873  {
874  g_warning("invalid path [%s]", path);
875  return;
876  }
877 
878  gnc_sx_instance_model_change_instance_state(dialog->editing_model->instances, inst, new_state);
879 }
880 
881 static void
882 variable_value_changed_cb(GtkCellRendererText *cell,
883  const gchar *path,
884  const gchar *value,
885  GncSxSinceLastRunDialog *dialog)
886 {
887  GncSxVariable *var;
888  GncSxInstance *inst;
889  GtkTreeIter tree_iter;
890  gnc_numeric parsed_num;
891  char *endStr = NULL;
892 
893  g_debug("variable to [%s] at path [%s]", value, path);
894  if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(dialog->editing_model), &tree_iter, path))
895  {
896  g_warning("invalid path [%s]", path);
897  return;
898  }
899 
900  if (!gnc_sx_slr_model_get_instance_and_variable(dialog->editing_model, &tree_iter, &inst, &var))
901  {
902  g_critical("path [%s] doesn't correspond to a valid variable", path);
903  return;
904  }
905 
906  if (!xaccParseAmount(value, TRUE, &parsed_num, &endStr)
907  || gnc_numeric_check(parsed_num) != GNC_ERROR_OK)
908  {
909  gchar *value_copy = g_strdup(value);
910  g_debug("value=[%s] endStr[%s]", value, endStr);
911  if (strlen(g_strstrip(value_copy)) == 0)
912  {
914  gnc_sx_instance_model_set_variable(dialog->editing_model->instances, inst, var, &invalid_num);
915  }
916  else
917  {
918  g_warning("error parsing value [%s]", value);
919  }
920  g_free(value_copy);
921  return;
922  }
923  gnc_sx_instance_model_set_variable(dialog->editing_model->instances, inst, var, &parsed_num);
924 }
925 
927 gnc_ui_sx_since_last_run_dialog(GncSxInstanceModel *sx_instances, GList *auto_created_txn_guids)
928 {
929  GncSxSinceLastRunDialog *dialog;
930  GtkBuilder *builder;
931 
932  dialog = g_new0(GncSxSinceLastRunDialog, 1);
933 
934  builder = gtk_builder_new();
935  gnc_builder_add_from_file (builder, "dialog-sx.glade", "since-last-run-dialog");
936 
937  dialog->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "since-last-run-dialog"));
938 
939  dialog->editing_model = gnc_sx_slr_tree_model_adapter_new(sx_instances);
940  dialog->review_created_txns_toggle = GTK_TOGGLE_BUTTON(gtk_builder_get_object (builder, "review_txn_toggle"));
941 
942  dialog->created_txns = auto_created_txn_guids;
943 
944  {
945  GtkCellRenderer *renderer;
946  GtkTreeViewColumn *col;
947 
948  dialog->instance_view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "instance_view"));
949  gtk_tree_view_set_model(dialog->instance_view, GTK_TREE_MODEL(dialog->editing_model));
950 
951  renderer = gtk_cell_renderer_text_new();
952  col = gtk_tree_view_column_new_with_attributes(_("Transaction"), renderer,
953  "text", SLR_MODEL_COL_NAME,
954  NULL);
955  gtk_tree_view_append_column(dialog->instance_view, col);
956 
957  renderer = gtk_cell_renderer_combo_new();
958  g_object_set(G_OBJECT(renderer),
959  "model", gnc_sx_get_slr_state_model(),
960  "text-column", 0,
961  "has-entry", FALSE,
962  "editable", TRUE,
963  NULL);
964  g_signal_connect(G_OBJECT(renderer),
965  "edited",
966  G_CALLBACK(instance_state_changed_cb),
967  dialog);
968  col = gtk_tree_view_column_new_with_attributes(_("Status"), renderer,
969  "text", SLR_MODEL_COL_INSTANCE_STATE,
970  "visible", SLR_MODEL_COL_INSTANCE_VISIBILITY,
971  // you might think only "sensitive" is required to
972  // control the ability of the combo box to select
973  // a new state, but you'd be wrong.
974  "editable", SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
975  "sensitive", SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
976  NULL);
977  gtk_tree_view_append_column(dialog->instance_view, col);
978  gtk_tree_view_column_set_resizable(col, TRUE);
979 
980  renderer = gtk_cell_renderer_text_new();
981  g_object_set(G_OBJECT(renderer),
982  "editable", TRUE,
983  NULL);
984  g_signal_connect(G_OBJECT(renderer),
985  "edited",
986  G_CALLBACK(variable_value_changed_cb),
987  dialog);
988  col = gtk_tree_view_column_new_with_attributes(_("Value"), renderer,
989  "text", SLR_MODEL_COL_VARAIBLE_VALUE,
990  "visible", SLR_MODEL_COL_VARIABLE_VISIBILITY,
991  NULL);
992  gtk_tree_view_append_column(dialog->instance_view, col);
993 
994  gtk_tree_view_expand_all(dialog->instance_view);
995  }
996 
997  g_signal_connect(G_OBJECT(dialog->dialog), "response", G_CALLBACK(dialog_response_cb), dialog);
998  g_signal_connect(G_OBJECT(dialog->dialog), "destroy", G_CALLBACK(dialog_destroy_cb), dialog);
999 
1000  gnc_restore_window_size(GNC_PREFS_GROUP_STARTUP, GTK_WINDOW(dialog->dialog));
1001 
1002  dialog->component_id = gnc_register_gui_component
1003  (DIALOG_SX_SINCE_LAST_RUN_CM_CLASS, NULL, close_handler, dialog);
1004  gnc_gui_component_set_session(dialog->component_id,
1005  gnc_get_current_session());
1006 
1007  gtk_widget_show_all(dialog->dialog);
1008 
1009  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, dialog);
1010 
1011  g_object_unref(G_OBJECT(builder));
1012 
1013  return dialog;
1014 }
1015 
1016 static void
1017 _show_created_transactions(GncSxSinceLastRunDialog *app_dialog, GList *created_txn_guids)
1018 {
1019 #ifdef REGISTER2_ENABLED
1020  GNCLedgerDisplay2 *ledger;
1021 #else
1022  GNCLedgerDisplay *ledger;
1023 #endif
1024  GncPluginPage *page;
1025  Query *book_query, *guid_query, *query;
1026  GList *guid_iter;
1027 
1028  book_query = qof_query_create_for(GNC_ID_SPLIT);
1029  guid_query = qof_query_create_for(GNC_ID_SPLIT);
1030  qof_query_set_book(book_query, gnc_get_current_book());
1031  for (guid_iter = created_txn_guids; guid_iter != NULL; guid_iter = guid_iter->next)
1032  {
1033  xaccQueryAddGUIDMatch(guid_query, (GncGUID*)guid_iter->data, GNC_ID_TRANS, QOF_QUERY_OR);
1034  }
1035  query = qof_query_merge(book_query, guid_query, QOF_QUERY_AND);
1036 #ifdef REGISTER2_ENABLED
1037  /*################## Added for Reg2 #################*/
1038  // inspired by dialog-find-transactions:do_find_cb:
1039  ledger = gnc_ledger_display2_query(query, SEARCH_LEDGER2, REG2_STYLE_JOURNAL);
1040  gnc_ledger_display2_refresh(ledger);
1041  page = gnc_plugin_page_register2_new_ledger(ledger);
1042  /*################## Added for Reg2 #################*/
1043 #else
1044  // inspired by dialog-find-transactions:do_find_cb:
1045  ledger = gnc_ledger_display_query(query, SEARCH_LEDGER, REG_STYLE_JOURNAL);
1046  gnc_ledger_display_refresh(ledger);
1047  page = gnc_plugin_page_register_new_ledger(ledger);
1048 #endif
1049  g_object_set(G_OBJECT(page), "page-name", _("Created Transactions"), NULL);
1050  gnc_main_window_open_page(NULL, page);
1051 
1052  qof_query_destroy(query);
1053  qof_query_destroy(book_query);
1054  qof_query_destroy(guid_query);
1055 }
1056 
1057 static void
1058 close_handler(gpointer user_data)
1059 {
1060  GncSxSinceLastRunDialog *app_dialog = user_data;
1061 
1062  gnc_save_window_size(GNC_PREFS_GROUP_STARTUP, GTK_WINDOW(app_dialog->dialog));
1063  gtk_widget_destroy(app_dialog->dialog);
1064 }
1065 
1066 static void
1067 dialog_destroy_cb(GtkObject *object, GncSxSinceLastRunDialog *app_dialog)
1068 {
1069  gnc_unregister_gui_component(app_dialog->component_id);
1070 
1071  g_object_unref(G_OBJECT(app_dialog->editing_model));
1072  app_dialog->editing_model = NULL;
1073 }
1074 
1075 static void
1076 dialog_response_cb(GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog *app_dialog)
1077 {
1078  switch (response_id)
1079  {
1080  case GTK_RESPONSE_OK:
1081  // @@fixme validate current state(GError *errs);
1082  // - [ ] instance state constraints
1083  // - [x] required variable binding
1084  // - [?] ability to create transactions
1085  {
1086  GList *unbound_variables;
1087  unbound_variables = gnc_sx_instance_model_check_variables(app_dialog->editing_model->instances);
1088  g_message("%d variables unbound", g_list_length(unbound_variables));
1089  if (g_list_length(unbound_variables) > 0)
1090  {
1091  // focus first variable
1092  GncSxVariableNeeded *first_unbound;
1093  GtkTreePath *variable_path;
1094  GtkTreeViewColumn *variable_col;
1095  gint variable_view_column = 2;
1096  gboolean start_editing = TRUE;
1097 
1098  first_unbound = (GncSxVariableNeeded*)unbound_variables->data;
1099  variable_path = _get_path_for_variable(app_dialog->editing_model, first_unbound->instance, first_unbound->variable);
1100  variable_col = gtk_tree_view_get_column(app_dialog->instance_view, variable_view_column);
1101 
1102  gtk_tree_view_set_cursor(app_dialog->instance_view, variable_path, variable_col, start_editing);
1103 
1104  gtk_tree_path_free(variable_path);
1105  g_list_foreach(unbound_variables, (GFunc)g_free, NULL);
1106  g_list_free(unbound_variables);
1107  return;
1108  }
1109  }
1110  gnc_suspend_gui_refresh();
1111  gnc_sx_slr_model_effect_change(app_dialog->editing_model, FALSE, &app_dialog->created_txns, NULL);
1112  gnc_resume_gui_refresh();
1113  if (gtk_toggle_button_get_active(app_dialog->review_created_txns_toggle)
1114  && g_list_length(app_dialog->created_txns) > 0)
1115  {
1116  _show_created_transactions(app_dialog, app_dialog->created_txns);
1117  }
1118  g_list_free(app_dialog->created_txns);
1119  app_dialog->created_txns = NULL;
1120 
1121  /* FALL THROUGH */
1122  case GTK_RESPONSE_CANCEL:
1123  case GTK_RESPONSE_DELETE_EVENT:
1124  gnc_close_gui_component(app_dialog->component_id);
1125  break;
1126  default:
1127  g_error("unknown response id [%d]", response_id);
1128  break;
1129  }
1130 }
1131 
1136 void
1137 gnc_sx_slr_model_effect_change(GncSxSlrTreeModelAdapter *model,
1138  gboolean auto_create_only,
1139  GList **created_transaction_guids,
1140  GList **creation_errors)
1141 {
1142  if (qof_book_is_readonly(gnc_get_current_book()))
1143  {
1144  /* Is the book read-only? Then don't change anything here. */
1145  return;
1146  }
1147 
1148  g_signal_handler_block(model->instances, model->updated_cb_id);
1149  gnc_sx_instance_model_effect_change(model->instances, auto_create_only, created_transaction_guids, creation_errors);
1150  g_signal_handler_unblock(model->instances, model->updated_cb_id);
1151 }
gint num_auto_create_no_notify_instances
void gnc_sx_instance_model_change_instance_state(GncSxInstanceModel *model, GncSxInstance *instance, GncSxInstanceState new_state)
utility functions for the GnuCash UI
void gnc_sx_instance_model_summarize(GncSxInstanceModel *model, GncSxSummary *summary)
void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
void gnc_sx_instance_model_effect_change(GncSxInstanceModel *model, gboolean auto_create_only, GList **created_transaction_guids, GList **creation_errors)
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Functions for adding content to a window.
GncPluginPage * gnc_plugin_page_register_new_ledger(GNCLedgerDisplay *ledger)
Definition: guid.h:65
void gnc_sx_summary_print(const GncSxSummary *summary)
gdouble gnc_numeric_to_double(gnc_numeric n)
Functions providing a register page for the GnuCash UI.
void qof_query_destroy(QofQuery *q)
GncPluginPage * gnc_plugin_page_register2_new_ledger(GNCLedgerDisplay2 *ledger)
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
GncSxInstances * parent
void qof_query_set_book(QofQuery *q, QofBook *book)
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
#define MAX_DATE_LENGTH
Definition: gnc-date.h:106
GList * gnc_sx_instance_get_variables(GncSxInstance *inst)
Generic api to store and retrieve preferences.
gboolean qof_book_is_readonly(const QofBook *book)
GncSxInstanceState state
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
GncSxInstanceModel * gnc_sx_get_current_instances(void)
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)
const gchar * QofLogModule
Definition: qofid.h:89
GList * gnc_sx_instance_model_check_variables(GncSxInstanceModel *model)