GnuCash  5.6-150-g038405b370+
gnc-sx-list-tree-model-adapter.c
1 /********************************************************************\
2  * gnc-sx-list-tree-model-adapter.c *
3  * *
4  * Copyright (C) 2006 Joshua Sled <jsled@asynchronous.org> *
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 gnu@gnu.org *
33 \********************************************************************/
34 
35 #include <config.h>
36 #include <glib.h>
37 #include <glib/gi18n.h>
38 #include <glib-object.h>
39 #include "gnc-sx-instance-model.h"
40 #include "gnc-sx-list-tree-model-adapter.h"
41 #include <gtk/gtk.h>
42 
44 {
45  GObject parent;
46 
47  /* protected */
48  gboolean disposed;
49  GncSxInstanceModel *instances;
50  GtkTreeStore *orig;
51  GtkTreeModelSort *real;
52 };
53 
54 /* Signal codes */
55 enum
56 {
57  MODEL_POPULATED,
58  LAST_SIGNAL
59 };
60 
61 static void gsltma_tree_model_interface_init (GtkTreeModelIface *tree_model);
62 static void gsltma_tree_sortable_interface_init (GtkTreeSortableIface *tree_sortable);
63 
64 static void gnc_sx_list_tree_model_adapter_dispose (GObject *obj);
65 static void gnc_sx_list_tree_model_adapter_finalize (GObject *obj);
66 
67 static guint gnc_sx_list_tree_model_adapter_signals[LAST_SIGNAL] = {0};
68 
69 static GncSxInstances* gsltma_get_sx_instances_from_orig_iter (GncSxListTreeModelAdapter *model,
70  GtkTreeIter *orig_iter);
71 
72 G_DEFINE_TYPE_WITH_CODE(GncSxListTreeModelAdapter, gnc_sx_list_tree_model_adapter, G_TYPE_OBJECT,
73  G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL, gsltma_tree_model_interface_init)
74  G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_SORTABLE, gsltma_tree_sortable_interface_init))
75 
76 static void
77 gnc_sx_list_tree_model_adapter_class_init (GncSxListTreeModelAdapterClass *klass)
78 {
79  GObjectClass *obj_class = G_OBJECT_CLASS(klass);
80 
81  obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
82  obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
83 
84  gnc_sx_list_tree_model_adapter_signals[MODEL_POPULATED] =
85  g_signal_new ("model_populated",
86  G_TYPE_FROM_CLASS(obj_class),
87  G_SIGNAL_RUN_LAST,
88  0,
89  NULL, NULL,
90  g_cclosure_marshal_VOID__VOID,
91  G_TYPE_NONE, 0);
92 }
93 
94 static GtkTreeModelFlags
95 gsltma_get_flags (GtkTreeModel *tree_model)
96 {
97  return gtk_tree_model_get_flags (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
98 }
99 
100 static gint
101 gsltma_get_n_columns (GtkTreeModel *tree_model)
102 {
103  return gtk_tree_model_get_n_columns (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
104 }
105 
106 static GType
107 gsltma_get_column_type (GtkTreeModel *tree_model, gint index)
108 {
109  return gtk_tree_model_get_column_type (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
110  index);
111 }
112 
113 static gboolean
114 gsltma_get_iter (GtkTreeModel *tree_model,
115  GtkTreeIter *iter,
116  GtkTreePath *path)
117 {
118  return gtk_tree_model_get_iter (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
119  iter, path);
120 }
121 
122 static GtkTreePath*
123 gsltma_get_path (GtkTreeModel *tree_model,
124  GtkTreeIter *iter)
125 {
126  return gtk_tree_model_get_path (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
127  iter);
128 }
129 
130 static void
131 gsltma_get_value (GtkTreeModel *tree_model,
132  GtkTreeIter *iter,
133  gint column,
134  GValue *value)
135 {
136  gtk_tree_model_get_value (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
137  iter, column, value);
138 }
139 
140 static gboolean
141 gsltma_iter_next (GtkTreeModel *tree_model,
142  GtkTreeIter *iter)
143 {
144  return gtk_tree_model_iter_next (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
145  iter);
146 }
147 
148 static gboolean
149 gsltma_iter_children (GtkTreeModel *tree_model,
150  GtkTreeIter *iter,
151  GtkTreeIter *parent)
152 {
153  return gtk_tree_model_iter_children (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
154  iter, parent);
155 }
156 
157 static gboolean
158 gsltma_iter_has_child (GtkTreeModel *tree_model,
159  GtkTreeIter *iter)
160 {
161  return gtk_tree_model_iter_has_child (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
162  iter);
163 }
164 
165 static gint
166 gsltma_iter_n_children (GtkTreeModel *tree_model,
167  GtkTreeIter *iter)
168 {
169  return gtk_tree_model_iter_n_children (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
170  iter);
171 }
172 
173 static gboolean
174 gsltma_iter_nth_child (GtkTreeModel *tree_model,
175  GtkTreeIter *iter,
176  GtkTreeIter *parent,
177  gint n)
178 {
179  return gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
180  iter, parent, n);
181 }
182 
183 static gboolean
184 gsltma_iter_parent (GtkTreeModel *tree_model,
185  GtkTreeIter *iter,
186  GtkTreeIter *child)
187 {
188  return gtk_tree_model_iter_parent (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
189  iter, child);
190 }
191 
192 static void
193 gsltma_ref_node (GtkTreeModel *tree_model,
194  GtkTreeIter *iter)
195 {
196  gtk_tree_model_ref_node (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
197  iter);
198 }
199 
200 static void
201 gsltma_unref_node (GtkTreeModel *tree_model,
202  GtkTreeIter *iter)
203 {
204  gtk_tree_model_unref_node (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
205  iter);
206 }
207 
208 static void
209 gsltma_tree_model_interface_init (GtkTreeModelIface *tree_model)
210 {
211  tree_model->get_flags = gsltma_get_flags;
212  tree_model->get_n_columns = gsltma_get_n_columns;
213  tree_model->get_column_type = gsltma_get_column_type;
214  tree_model->get_iter = gsltma_get_iter;
215  tree_model->get_path = gsltma_get_path;
216  tree_model->get_value = gsltma_get_value;
217  tree_model->iter_next = gsltma_iter_next;
218  tree_model->iter_children = gsltma_iter_children;
219  tree_model->iter_has_child = gsltma_iter_has_child;
220  tree_model->iter_n_children = gsltma_iter_n_children;
221  tree_model->iter_nth_child = gsltma_iter_nth_child;
222  tree_model->iter_parent = gsltma_iter_parent;
223  tree_model->ref_node = gsltma_ref_node;
224  tree_model->unref_node = gsltma_unref_node;
225 }
226 
227 static gboolean
228 gsltma_get_sort_column_id (GtkTreeSortable *sortable,
229  gint *sort_column_id,
230  GtkSortType *order)
231 {
232  return gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
233  sort_column_id,
234  order);
235 }
236 
237 static void
238 gsltma_set_sort_column_id (GtkTreeSortable *sortable,
239  gint sort_column_id,
240  GtkSortType order)
241 {
242  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
243  sort_column_id,
244  order);
245 }
246 
247 static void
248 gsltma_set_sort_func (GtkTreeSortable *sortable,
249  gint sort_column_id,
250  GtkTreeIterCompareFunc func,
251  gpointer data,
252  GDestroyNotify destroy)
253 {
254  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
255  sort_column_id,
256  func,
257  data,
258  destroy);
259 }
260 
261 static void
262 gsltma_set_default_sort_func (GtkTreeSortable *sortable,
263  GtkTreeIterCompareFunc func,
264  gpointer data,
265  GDestroyNotify destroy)
266 {
267  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
268  func,
269  data,
270  destroy);
271 }
272 
273 static gboolean
274 gsltma_has_default_sort_func (GtkTreeSortable *sortable)
275 {
276  return gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real));
277 }
278 
279 static void
280 gsltma_tree_sortable_interface_init (GtkTreeSortableIface *tree_sortable)
281 {
282  tree_sortable->get_sort_column_id = gsltma_get_sort_column_id;
283  tree_sortable->set_sort_column_id = gsltma_set_sort_column_id;
284  tree_sortable->set_sort_func = gsltma_set_sort_func;
285  tree_sortable->set_default_sort_func = gsltma_set_default_sort_func;
286  tree_sortable->has_default_sort_func = gsltma_has_default_sort_func;
287  tree_sortable->get_sort_column_id = gsltma_get_sort_column_id;
288  tree_sortable->set_sort_column_id = gsltma_set_sort_column_id;
289  tree_sortable->set_sort_func = gsltma_set_sort_func;
290  tree_sortable->set_default_sort_func = gsltma_set_default_sort_func;
291  tree_sortable->has_default_sort_func = gsltma_has_default_sort_func;
292 }
293 
294 static void
295 gsltma_proxy_row_changed (GtkTreeModel *treemodel,
296  GtkTreePath *arg1,
297  GtkTreeIter *arg2,
298  gpointer user_data)
299 {
300  g_signal_emit_by_name (user_data, "row-changed", arg1, arg2);
301 }
302 
303 static void
304 gsltma_proxy_row_deleted (GtkTreeModel *treemodel,
305  GtkTreePath *arg1,
306  gpointer user_data)
307 {
308  g_signal_emit_by_name (user_data, "row-deleted", arg1);
309 }
310 
311 static void
312 gsltma_proxy_row_has_child_toggled (GtkTreeModel *treemodel,
313  GtkTreePath *arg1,
314  GtkTreeIter *arg2,
315  gpointer user_data)
316 {
317  g_signal_emit_by_name (user_data, "row-has-child-toggled", arg1, arg2);
318 }
319 
320 static void
321 gsltma_proxy_row_inserted (GtkTreeModel *treemodel,
322  GtkTreePath *arg1,
323  GtkTreeIter *arg2,
324  gpointer user_data)
325 {
326  g_signal_emit_by_name (user_data, "row-inserted", arg1, arg2);
327 }
328 
329 static void
330 gsltma_proxy_rows_reordered (GtkTreeModel *treemodel,
331  GtkTreePath *arg1,
332  GtkTreeIter *arg2,
333  gpointer arg3,
334  gpointer user_data)
335 {
336  g_signal_emit_by_name (user_data, "rows-reordered", arg1, arg2, arg3);
337 }
338 
339 static void
340 gsltma_proxy_sort_column_changed (GtkTreeSortable *sortable, gpointer user_data)
341 {
342  g_signal_emit_by_name (user_data, "sort-column-changed");
343 }
344 
345 static gint
346 _sort_iterators_to_instances (gpointer *user_data, GtkTreeIter *a, GtkTreeIter *b,
347  gint (*instances_comparator)(GncSxInstances *a, GncSxInstances *b))
348 {
349  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
350  GncSxInstances *a_inst, *b_inst;
351 
352  a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
353  b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
354 
355  if (a_inst == NULL && b_inst == NULL) return 0;
356  if (a_inst == NULL) return 1;
357  if (b_inst == NULL) return -1;
358 
359  return instances_comparator (a_inst, b_inst);
360 }
361 
362 static gint
363 _name_instances_compare (GncSxInstances *a_inst, GncSxInstances *b_inst)
364 {
365  gchar *a_caseless, *b_caseless;
366  gint rtn;
367 
368  a_caseless = g_utf8_casefold (xaccSchedXactionGetName (a_inst->sx), -1);
369  b_caseless = g_utf8_casefold (xaccSchedXactionGetName (b_inst->sx), -1);
370 
371  rtn = g_strcmp0 (a_caseless, b_caseless);
372 
373  g_free (a_caseless);
374  g_free (b_caseless);
375 
376  return rtn;
377 }
378 
379 static gint
380 _name_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
381 {
382  return _sort_iterators_to_instances (user_data, a, b, _name_instances_compare);
383 }
384 
385 static gint
386 _freq_instances_compare (GncSxInstances *a_inst, GncSxInstances *b_inst)
387 {
388  gint rtn;
389 
390  rtn = recurrenceListCmp (gnc_sx_get_schedule (a_inst->sx), gnc_sx_get_schedule (b_inst->sx));
391 
392  return rtn ? rtn : _name_instances_compare (a_inst, b_inst);
393 }
394 
395 static gint
396 _freq_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
397 {
398  return _sort_iterators_to_instances (user_data, a, b, _freq_instances_compare);
399 }
400 
401 static gint
402 _safe_invalidable_date_compare (const GDate *a, const GDate *b)
403 {
404  gboolean a_valid, b_valid;
405 
406  a_valid = g_date_valid (a);
407  b_valid = g_date_valid (b);
408 
409  if (!a_valid && !b_valid) return 0;
410  if (!a_valid) return 1;
411  if (!b_valid) return -1;
412 
413  return g_date_compare (a, b);
414 }
415 
416 static gint
417 _last_occur_instances_compare (GncSxInstances *a_inst, GncSxInstances *b_inst)
418 {
419  gint rtn;
420 
421  rtn = _safe_invalidable_date_compare (xaccSchedXactionGetLastOccurDate (a_inst->sx),
422  xaccSchedXactionGetLastOccurDate (b_inst->sx));
423 
424  return rtn ? rtn : _name_instances_compare (a_inst, b_inst);
425 }
426 
427 static gint
428 _last_occur_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
429 {
430  return _sort_iterators_to_instances (user_data, a, b, _last_occur_instances_compare);
431 }
432 
433 static gint
434 _next_occur_instances_compare (GncSxInstances *a_inst, GncSxInstances *b_inst)
435 {
436  gint rtn;
437 
438  rtn = _safe_invalidable_date_compare (&a_inst->next_instance_date,
439  &b_inst->next_instance_date);
440 
441  return rtn ? rtn : _name_instances_compare (a_inst, b_inst);
442 }
443 
444 static gint
445 _next_occur_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
446 {
447  return _sort_iterators_to_instances (user_data, a, b, _next_occur_instances_compare);
448 }
449 
450 static gint
451 _enabled_instances_compare (GncSxInstances *a_inst, GncSxInstances *b_inst)
452 {
453  gboolean a_enabled, b_enabled;
454 
455  a_enabled = xaccSchedXactionGetEnabled (a_inst->sx);
456  b_enabled = xaccSchedXactionGetEnabled (b_inst->sx);
457 
458  if (a_enabled && !b_enabled) return 1;
459  if (!a_enabled && b_enabled) return -1;
460 
461  return _name_instances_compare (a_inst, b_inst);
462 }
463 
464 static gint
465 _enabled_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
466 {
467  return _sort_iterators_to_instances (user_data, a, b, _enabled_instances_compare);
468 }
469 
470 static void
471 gnc_sx_list_tree_model_adapter_init (GncSxListTreeModelAdapter *adapter)
472 {
473  adapter->orig = gtk_tree_store_new (6, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
474  adapter->real = GTK_TREE_MODEL_SORT(gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(adapter->orig)));
475 
476  // setup sorting
477  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NAME,
478  _name_comparator, adapter, NULL);
479  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_ENABLED,
480  _enabled_comparator, adapter, NULL);
481  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_FREQUENCY,
482  _freq_comparator, adapter, NULL);
483  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_LAST_OCCUR,
484  _last_occur_comparator, adapter, NULL);
485  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NEXT_OCCUR,
486  _next_occur_comparator, adapter, NULL);
487 
488  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(adapter->real),
489  SXLTMA_COL_NAME, GTK_SORT_ASCENDING);
490 
491  g_signal_connect (adapter->real, "row-changed",
492  G_CALLBACK(gsltma_proxy_row_changed), adapter);
493  g_signal_connect (adapter->real, "row-deleted",
494  G_CALLBACK(gsltma_proxy_row_deleted), adapter);
495  g_signal_connect (adapter->real, "row-has-child-toggled",
496  G_CALLBACK(gsltma_proxy_row_has_child_toggled), adapter);
497  g_signal_connect (adapter->real, "row-inserted",
498  G_CALLBACK(gsltma_proxy_row_inserted), adapter);
499  g_signal_connect (adapter->real, "rows-reordered",
500  G_CALLBACK(gsltma_proxy_rows_reordered), adapter);
501  g_signal_connect (adapter->real, "sort-column-changed",
502  G_CALLBACK(gsltma_proxy_sort_column_changed), adapter);
503 }
504 
505 static void
506 _format_conditional_date (const GDate *date, char *date_buf, int buf_max_length)
507 {
508  if (date == NULL || !g_date_valid (date))
509  g_stpcpy (date_buf, _("never"));
510  else
511  qof_print_gdate (date_buf, buf_max_length, date);
512 }
513 
514 static void
515 gsltma_populate_tree_store (GncSxListTreeModelAdapter *model)
516 {
517  GtkTreeIter iter;
518  GList *list;
519 
520  for (list = gnc_sx_instance_model_get_sx_instances_list (model->instances); list != NULL; list = list->next)
521  {
522  GncSxInstances *instances = (GncSxInstances*)list->data;
523  gchar *frequency_str;
524  char last_occur_date_buf[MAX_DATE_LENGTH + 1];
525  unsigned postponed_count;
526  char next_occur_date_buf[MAX_DATE_LENGTH+1];
527 
528  frequency_str = recurrenceListToCompactString (gnc_sx_get_schedule (instances->sx));
529 
530  _format_conditional_date (xaccSchedXactionGetLastOccurDate (instances->sx),
531  last_occur_date_buf, MAX_DATE_LENGTH);
532  postponed_count = g_list_length(gnc_sx_get_defer_instances (instances->sx));
533  _format_conditional_date (&instances->next_instance_date,
534  next_occur_date_buf, MAX_DATE_LENGTH);
535 
536  gtk_tree_store_append (model->orig, &iter, NULL);
537  gtk_tree_store_set (model->orig, &iter,
538  SXLTMA_COL_NAME, xaccSchedXactionGetName (instances->sx),
539  SXLTMA_COL_ENABLED, xaccSchedXactionGetEnabled (instances->sx),
540  SXLTMA_COL_FREQUENCY, frequency_str,
541  SXLTMA_COL_NUM_POSTPONED, postponed_count,
542  SXLTMA_COL_LAST_OCCUR, last_occur_date_buf,
543  SXLTMA_COL_NEXT_OCCUR, next_occur_date_buf,
544  -1);
545  g_free (frequency_str);
546  }
547  g_signal_emit_by_name (model, "model_populated");
548 }
549 
550 static void
551 gsltma_added_cb (GncSxInstanceModel *instances, SchedXaction *sx_added, gpointer user_data)
552 {
553  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
554  gtk_tree_store_clear (model->orig);
555  gsltma_populate_tree_store (model);
556 }
557 
558 static void
559 gsltma_updated_cb (GncSxInstanceModel *instances, SchedXaction *sx_updated, gpointer user_data)
560 {
561  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
562  gnc_sx_instance_model_update_sx_instances (instances, sx_updated);
563  gtk_tree_store_clear (model->orig);
564  gsltma_populate_tree_store (model);
565 }
566 
567 static void
568 gsltma_removing_cb (GncSxInstanceModel *instances, SchedXaction *sx_removing, gpointer user_data)
569 {
570  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
571  gnc_sx_instance_model_remove_sx_instances (instances, sx_removing);
572  gtk_tree_store_clear (model->orig);
573  gsltma_populate_tree_store (model);
574 }
575 
576 GncSxListTreeModelAdapter*
577 gnc_sx_list_tree_model_adapter_new (GncSxInstanceModel *instances)
578 {
579  GncSxListTreeModelAdapter *rtn;
580 
581  rtn = GNC_SX_LIST_TREE_MODEL_ADAPTER(g_object_new (GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, NULL));
582  rtn->instances = instances;
583  g_object_ref (G_OBJECT(rtn->instances));
584 
585  gsltma_populate_tree_store (rtn);
586 
587  g_signal_connect (G_OBJECT(rtn->instances), "added",
588  (GCallback)gsltma_added_cb, (gpointer)rtn);
589  g_signal_connect (G_OBJECT(rtn->instances), "updated",
590  (GCallback)gsltma_updated_cb, (gpointer)rtn);
591  g_signal_connect (G_OBJECT(rtn->instances), "removing",
592  (GCallback)gsltma_removing_cb, (gpointer)rtn);
593 
594  return rtn;
595 }
596 
598 gsltma_get_sx_instances_from_orig_iter (GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter)
599 {
600  GtkTreePath *path;
601  gint *indices;
602  gint index;
603 
604  path = gtk_tree_model_get_path (GTK_TREE_MODEL(model->orig), orig_iter);
605  if (gtk_tree_path_get_depth (path) > 1)
606  {
607  gtk_tree_path_free (path);
608  return NULL;
609  }
610  indices = gtk_tree_path_get_indices (path);
611  index = indices[0];
612 
613  gtk_tree_path_free (path);
614  return (GncSxInstances*)g_list_nth_data (gnc_sx_instance_model_get_sx_instances_list (model->instances), index);
615 }
616 
618 gnc_sx_list_tree_model_adapter_get_sx_instances (GncSxListTreeModelAdapter *model, GtkTreeIter *sort_iter)
619 {
620  GtkTreeIter translated_iter;
621  gtk_tree_model_sort_convert_iter_to_child_iter (model->real,
622  &translated_iter,
623  sort_iter);
624  return gsltma_get_sx_instances_from_orig_iter (model, &translated_iter);
625 }
626 
627 static void
628 gnc_sx_list_tree_model_adapter_dispose (GObject *obj)
629 {
630  GncSxListTreeModelAdapter *adapter;
631 
632  g_return_if_fail (obj != NULL);
633  adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
634 
635  if (adapter->disposed) return;
636  adapter->disposed = TRUE;
637 
638  g_object_unref (G_OBJECT(adapter->instances));
639  adapter->instances = NULL;
640  g_object_unref (G_OBJECT(adapter->real));
641  adapter->real = NULL;
642  g_object_unref (G_OBJECT(adapter->orig));
643  adapter->orig = NULL;
644 
645  G_OBJECT_CLASS(gnc_sx_list_tree_model_adapter_parent_class)->dispose (obj);
646 }
647 
648 static void
649 gnc_sx_list_tree_model_adapter_finalize (GObject *obj)
650 {
651  g_return_if_fail (obj != NULL);
652  G_OBJECT_CLASS(gnc_sx_list_tree_model_adapter_parent_class)->finalize (obj);
653 }
GList * gnc_sx_get_schedule(const SchedXaction *sx)
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)
Convenience; calls through to qof_print_date_dmy_buff().
Definition: gnc-date.cpp:598
void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
Regenerates and updates the GncSxInstances* for the given SX.
G_DEFINE_TYPE_WITH_CODE(GncMainWindow, gnc_main_window, GTK_TYPE_APPLICATION_WINDOW, G_IMPLEMENT_INTERFACE(GNC_TYPE_WINDOW, gnc_window_main_window_init)) static guint main_window_signals[LAST_SIGNAL]
A holding place for all the signals generated by the main window code.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
Definition: gnc-date.h:108
GList * gnc_sx_instance_model_get_sx_instances_list(GncSxInstanceModel *model)
Returns the list of GncSxInstances in the model (Each element in the list has type GncSxInstances) ...
GList * gnc_sx_get_defer_instances(SchedXaction *sx)
Returns the defer list from the SX; this is a (date-)sorted temporal-state-data instance list...