GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-sx-list-tree-model-adapter.c
1 /*
2  * gnc-sx-list-tree-model-adapter.c
3  *
4  * Copyright (C) 2006 Josh 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 GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * As a special exception, permission is granted to link the binary module
11  * resultant from this code with the OpenSSL project's "OpenSSL" library (or
12  * modified versions of it that use the same license as the "OpenSSL"
13  * library), and distribute the linked executable. You must obey the GNU
14  * General Public License in all respects for all of the code used other than
15  * "OpenSSL". If you modify this file, you may extend this exception to your
16  * version of the file, but you are not obligated to do so. If you do not
17  * wish to do so, delete this exception statement from your version of this
18  * file.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, contact:
27  *
28  * Free Software Foundation Voice: +1-617-542-5942
29  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
30  * Boston, MA 02110-1301, USA [email protected]
31  */
32 
33 #include "config.h"
34 #include <glib.h>
35 #include <glib/gi18n.h>
36 #include <glib-object.h>
37 #include "gnc-sx-instance-model.h"
38 #include "gnc-sx-list-tree-model-adapter.h"
39 #include <gtk/gtk.h>
40 
42 {
43  GObject parent;
44 
45  /* protected */
46  gboolean disposed;
47  GncSxInstanceModel *instances;
48  GtkTreeStore *orig;
49  GtkTreeModelSort *real;
50 };
51 
53 {
54  GObjectClass parent;
55 };
56 
57 static GObjectClass *parent_class = NULL;
58 
59 static void gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass);
60 static void gsltma_tree_model_interface_init(gpointer g_iface, gpointer iface_data);
61 static void gsltma_tree_sortable_interface_init(gpointer g_iface, gpointer iface_data);
62 static void gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointer klass);
63 static void gnc_sx_list_tree_model_adapter_dispose(GObject *obj);
64 static void gnc_sx_list_tree_model_adapter_finalize(GObject *obj);
65 
66 static GncSxInstances* gsltma_get_sx_instances_from_orig_iter(GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter);
67 
68 GType
69 gnc_sx_list_tree_model_adapter_get_type(void)
70 {
71  static GType type = 0;
72  if (type == 0)
73  {
74  static const GTypeInfo info =
75  {
77  NULL, /* base_init */
78  NULL, /* base_finalize */
79  (GClassInitFunc)gnc_sx_list_tree_model_adapter_class_init, /* class_init */
80  NULL, /* class_finalize */
81  NULL, /* class_data */
83  0, /* n_preallocs */
84  (GInstanceInitFunc)gnc_sx_list_tree_model_adapter_init /* instance_init */
85  };
86  static const GInterfaceInfo itree_model_info =
87  {
88  (GInterfaceInitFunc) gsltma_tree_model_interface_init, /* interface_init */
89  NULL, /* interface_finalize */
90  NULL /* interface_data */
91  };
92  static const GInterfaceInfo itree_sortable_info =
93  {
94  (GInterfaceInitFunc) gsltma_tree_sortable_interface_init, /* interface_init */
95  NULL, /* interface_finalize */
96  NULL /* interface_data */
97  };
98 
99  type = g_type_register_static (G_TYPE_OBJECT,
100  "GncSxListTreeModelAdapterType",
101  &info, 0);
102  g_type_add_interface_static(type,
103  GTK_TYPE_TREE_MODEL,
104  &itree_model_info);
105  g_type_add_interface_static(type,
106  GTK_TYPE_TREE_SORTABLE,
107  &itree_sortable_info);
108  }
109  return type;
110 }
111 
112 static void
113 gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass)
114 {
115  GObjectClass *obj_class = G_OBJECT_CLASS(klass);
116 
117  parent_class = g_type_class_peek_parent(klass);
118 
119  obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
120  obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
121 
122 }
123 
124 static GtkTreeModelFlags
125 gsltma_get_flags(GtkTreeModel *tree_model)
126 {
127  return gtk_tree_model_get_flags(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
128 }
129 
130 static gint
131 gsltma_get_n_columns(GtkTreeModel *tree_model)
132 {
133  return gtk_tree_model_get_n_columns(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
134 }
135 
136 static GType
137 gsltma_get_column_type(GtkTreeModel *tree_model, gint index)
138 {
139  return gtk_tree_model_get_column_type(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), index);
140 }
141 
142 static gboolean
143 gsltma_get_iter(GtkTreeModel *tree_model,
144  GtkTreeIter *iter,
145  GtkTreePath *path)
146 {
147  return gtk_tree_model_get_iter(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, path);
148 }
149 
150 static GtkTreePath*
151 gsltma_get_path(GtkTreeModel *tree_model,
152  GtkTreeIter *iter)
153 {
154  return gtk_tree_model_get_path(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
155 }
156 
157 static void
158 gsltma_get_value(GtkTreeModel *tree_model,
159  GtkTreeIter *iter,
160  gint column,
161  GValue *value)
162 {
163  gtk_tree_model_get_value(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, column, value);
164 }
165 
166 static gboolean
167 gsltma_iter_next(GtkTreeModel *tree_model,
168  GtkTreeIter *iter)
169 {
170  return gtk_tree_model_iter_next(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
171 }
172 
173 static gboolean
174 gsltma_iter_children(GtkTreeModel *tree_model,
175  GtkTreeIter *iter,
176  GtkTreeIter *parent)
177 {
178  return gtk_tree_model_iter_children(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent);
179 }
180 
181 static gboolean
182 gsltma_iter_has_child(GtkTreeModel *tree_model,
183  GtkTreeIter *iter)
184 {
185  return gtk_tree_model_iter_has_child(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
186 }
187 
188 static gint
189 gsltma_iter_n_children(GtkTreeModel *tree_model,
190  GtkTreeIter *iter)
191 {
192  return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
193 }
194 
195 static gboolean
196 gsltma_iter_nth_child(GtkTreeModel *tree_model,
197  GtkTreeIter *iter,
198  GtkTreeIter *parent,
199  gint n)
200 {
201  return gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent, n);
202 }
203 
204 static gboolean
205 gsltma_iter_parent(GtkTreeModel *tree_model,
206  GtkTreeIter *iter,
207  GtkTreeIter *child)
208 {
209  return gtk_tree_model_iter_parent(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, child);
210 }
211 
212 static void
213 gsltma_ref_node(GtkTreeModel *tree_model,
214  GtkTreeIter *iter)
215 {
216  gtk_tree_model_ref_node(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
217 }
218 
219 static void
220 gsltma_unref_node(GtkTreeModel *tree_model,
221  GtkTreeIter *iter)
222 {
223  gtk_tree_model_unref_node(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
224 }
225 
226 static void
227 gsltma_tree_model_interface_init(gpointer g_iface, gpointer iface_data)
228 {
229  GtkTreeModelIface *tree_model = (GtkTreeModelIface*)g_iface;
230  tree_model->get_flags = gsltma_get_flags;
231  tree_model->get_n_columns = gsltma_get_n_columns;
232  tree_model->get_column_type = gsltma_get_column_type;
233  tree_model->get_iter = gsltma_get_iter;
234  tree_model->get_path = gsltma_get_path;
235  tree_model->get_value = gsltma_get_value;
236  tree_model->iter_next = gsltma_iter_next;
237  tree_model->iter_children = gsltma_iter_children;
238  tree_model->iter_has_child = gsltma_iter_has_child;
239  tree_model->iter_n_children = gsltma_iter_n_children;
240  tree_model->iter_nth_child = gsltma_iter_nth_child;
241  tree_model->iter_parent = gsltma_iter_parent;
242  tree_model->ref_node = gsltma_ref_node;
243  tree_model->unref_node = gsltma_unref_node;
244 }
245 
246 static gboolean
247 gsltma_get_sort_column_id(GtkTreeSortable *sortable,
248  gint *sort_column_id,
249  GtkSortType *order)
250 {
251  return gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
252  sort_column_id,
253  order);
254 }
255 
256 static void
257 gsltma_set_sort_column_id(GtkTreeSortable *sortable,
258  gint sort_column_id,
259  GtkSortType order)
260 {
261  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
262  sort_column_id,
263  order);
264 }
265 
266 static void
267 gsltma_set_sort_func(GtkTreeSortable *sortable,
268  gint sort_column_id,
269  GtkTreeIterCompareFunc func,
270  gpointer data,
271  GDestroyNotify destroy)
272 {
273  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
274  sort_column_id,
275  func,
276  data,
277  destroy);
278 }
279 
280 static void
281 gsltma_set_default_sort_func(GtkTreeSortable *sortable,
282  GtkTreeIterCompareFunc func,
283  gpointer data,
284  GDestroyNotify destroy)
285 {
286  gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
287  func, data, destroy);
288 }
289 
290 static gboolean
291 gsltma_has_default_sort_func(GtkTreeSortable *sortable)
292 {
293  return gtk_tree_sortable_has_default_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real));
294 }
295 
296 static void
297 gsltma_tree_sortable_interface_init(gpointer g_iface, gpointer iface_data)
298 {
299  GtkTreeSortableIface *tree_sortable = (GtkTreeSortableIface*)g_iface;
300  tree_sortable->get_sort_column_id = gsltma_get_sort_column_id;
301  tree_sortable->set_sort_column_id = gsltma_set_sort_column_id;
302  tree_sortable->set_sort_func = gsltma_set_sort_func;
303  tree_sortable->set_default_sort_func = gsltma_set_default_sort_func;
304  tree_sortable->has_default_sort_func = gsltma_has_default_sort_func;
305  tree_sortable->get_sort_column_id = gsltma_get_sort_column_id;
306  tree_sortable->set_sort_column_id = gsltma_set_sort_column_id;
307  tree_sortable->set_sort_func = gsltma_set_sort_func;
308  tree_sortable->set_default_sort_func = gsltma_set_default_sort_func;
309  tree_sortable->has_default_sort_func = gsltma_has_default_sort_func;
310 }
311 
312 static void
313 gsltma_proxy_row_changed(GtkTreeModel *treemodel,
314  GtkTreePath *arg1,
315  GtkTreeIter *arg2,
316  gpointer user_data)
317 {
318  g_signal_emit_by_name(user_data, "row-changed", arg1, arg2);
319 }
320 
321 static void
322 gsltma_proxy_row_deleted(GtkTreeModel *treemodel,
323  GtkTreePath *arg1,
324  gpointer user_data)
325 {
326  g_signal_emit_by_name(user_data, "row-deleted", arg1);
327 }
328 
329 static void
330 gsltma_proxy_row_has_child_toggled(GtkTreeModel *treemodel,
331  GtkTreePath *arg1,
332  GtkTreeIter *arg2,
333  gpointer user_data)
334 {
335  g_signal_emit_by_name(user_data, "row-has-child-toggled", arg1, arg2);
336 }
337 
338 static void
339 gsltma_proxy_row_inserted(GtkTreeModel *treemodel,
340  GtkTreePath *arg1,
341  GtkTreeIter *arg2,
342  gpointer user_data)
343 {
344  g_signal_emit_by_name(user_data, "row-inserted", arg1, arg2);
345 }
346 
347 static void
348 gsltma_proxy_rows_reordered(GtkTreeModel *treemodel,
349  GtkTreePath *arg1,
350  GtkTreeIter *arg2,
351  gpointer arg3,
352  gpointer user_data)
353 {
354  g_signal_emit_by_name(user_data, "rows-reordered", arg1, arg2, arg3);
355 }
356 
357 static void
358 gsltma_proxy_sort_column_changed(GtkTreeSortable *sortable, gpointer user_data)
359 {
360  g_signal_emit_by_name(user_data, "sort-column-changed");
361 }
362 
363 static gint
364 _name_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
365 {
366  gint rtn;
367  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
368  GncSxInstances *a_inst, *b_inst;
369  gchar *a_caseless, *b_caseless;
370 
371  a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
372  b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
373 
374  if (a_inst == NULL && b_inst == NULL) return 0;
375  if (a_inst == NULL) return 1;
376  if (b_inst == NULL) return -1;
377 
378  a_caseless = g_utf8_casefold(xaccSchedXactionGetName(a_inst->sx), -1);
379  b_caseless = g_utf8_casefold(xaccSchedXactionGetName(b_inst->sx), -1);
380  rtn = g_strcmp0(a_caseless, b_caseless);
381  g_free(a_caseless);
382  g_free(b_caseless);
383 
384  return rtn;
385 }
386 
387 static gint
388 _freq_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
389 {
390  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
391  GncSxInstances *a_inst, *b_inst;
392 
393  a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
394  b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
395 
396  if (a_inst == NULL && b_inst == NULL) return 0;
397  if (a_inst == NULL) return 1;
398  if (b_inst == NULL) return -1;
399 
400  return recurrenceListCmp(gnc_sx_get_schedule(a_inst->sx), gnc_sx_get_schedule(b_inst->sx));
401 }
402 
403 static gint
404 _safe_invalidable_date_compare(const GDate *a, const GDate *b)
405 {
406  if (!g_date_valid(a) && !g_date_valid(b))
407  {
408  return 0;
409  }
410  if (!g_date_valid(a))
411  {
412  return 1;
413  }
414  if (!g_date_valid(b))
415  {
416  return -1;
417  }
418  return g_date_compare(a, b);
419 }
420 
421 static gint
422 _last_occur_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
423 {
424  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
425  GncSxInstances *a_inst, *b_inst;
426 
427  a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
428  b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
429 
430  return _safe_invalidable_date_compare(xaccSchedXactionGetLastOccurDate(a_inst->sx),
431  xaccSchedXactionGetLastOccurDate(b_inst->sx));
432 }
433 
434 static gint
435 _next_occur_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
436 {
437  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
438  GncSxInstances *a_inst, *b_inst;
439 
440  a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
441  b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
442 
443  return _safe_invalidable_date_compare(&a_inst->next_instance_date,
444  &b_inst->next_instance_date);
445 }
446 
447 static gint
448 _enabled_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
449 {
450  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
451  GncSxInstances *a_inst, *b_inst;
452 
453  a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
454  b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
455 
456  if (xaccSchedXactionGetEnabled(a_inst->sx) && !xaccSchedXactionGetEnabled(b_inst->sx)) return 1;
457  if (!xaccSchedXactionGetEnabled(a_inst->sx) && xaccSchedXactionGetEnabled(b_inst->sx)) return -1;
458  return 0;
459 }
460 
461 static void
462 gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointer klass)
463 {
464  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(instance);
465  adapter->orig = gtk_tree_store_new(5, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
466  adapter->real = GTK_TREE_MODEL_SORT(gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(adapter->orig)));
467 
468  // setup sorting
469  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NAME, _name_comparator, adapter, NULL);
470  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_ENABLED, _enabled_comparator, adapter, NULL);
471  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_FREQUENCY, _freq_comparator, adapter, NULL);
472  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_LAST_OCCUR, _last_occur_comparator, adapter, NULL);
473  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NEXT_OCCUR, _next_occur_comparator, adapter, NULL);
474  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NEXT_OCCUR, GTK_SORT_ASCENDING);
475 
476  g_signal_connect(adapter->real, "row-changed", G_CALLBACK(gsltma_proxy_row_changed), adapter);
477  g_signal_connect(adapter->real, "row-deleted", G_CALLBACK(gsltma_proxy_row_deleted), adapter);
478  g_signal_connect(adapter->real, "row-has-child-toggled", G_CALLBACK(gsltma_proxy_row_has_child_toggled), adapter);
479  g_signal_connect(adapter->real, "row-inserted", G_CALLBACK(gsltma_proxy_row_inserted), adapter);
480  g_signal_connect(adapter->real, "rows-reordered", G_CALLBACK(gsltma_proxy_rows_reordered), adapter);
481 
482  g_signal_connect(adapter->real, "sort-column-changed", G_CALLBACK(gsltma_proxy_sort_column_changed), adapter);
483 }
484 
485 static void
486 _format_conditional_date(const GDate *date, char *date_buf, int buf_max_length)
487 {
488  if (date == NULL || !g_date_valid(date))
489  {
490  g_stpcpy(date_buf, _("never"));
491  }
492  else
493  {
494  qof_print_gdate(date_buf, buf_max_length, date);
495  }
496 }
497 
498 static void
499 gsltma_populate_tree_store(GncSxListTreeModelAdapter *model)
500 {
501  GtkTreeIter iter;
502  GList *list;
503 
504  for (list = model->instances->sx_instance_list; list != NULL; list = list->next)
505  {
506  GncSxInstances *instances = (GncSxInstances*)list->data;
507  gchar *frequency_str;
508  char last_occur_date_buf[MAX_DATE_LENGTH+1];
509  char next_occur_date_buf[MAX_DATE_LENGTH+1];
510 
511  frequency_str = recurrenceListToCompactString(gnc_sx_get_schedule(instances->sx));
512 
513  _format_conditional_date(xaccSchedXactionGetLastOccurDate(instances->sx),
514  last_occur_date_buf, MAX_DATE_LENGTH);
515  _format_conditional_date(&instances->next_instance_date,
516  next_occur_date_buf, MAX_DATE_LENGTH);
517 
518  gtk_tree_store_append(model->orig, &iter, NULL);
519  gtk_tree_store_set(model->orig, &iter,
520  SXLTMA_COL_NAME, xaccSchedXactionGetName(instances->sx),
521  SXLTMA_COL_ENABLED, xaccSchedXactionGetEnabled(instances->sx),
522  SXLTMA_COL_FREQUENCY, frequency_str,
523  SXLTMA_COL_LAST_OCCUR, last_occur_date_buf,
524  SXLTMA_COL_NEXT_OCCUR, next_occur_date_buf,
525  -1);
526  g_free(frequency_str);
527  }
528 }
529 
530 static void
531 gsltma_added_cb(GncSxInstanceModel *instances, SchedXaction *sx_added, gpointer user_data)
532 {
533  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
534  gtk_tree_store_clear(model->orig);
535  gsltma_populate_tree_store(model);
536 }
537 
538 static void
539 gsltma_updated_cb(GncSxInstanceModel *instances, SchedXaction *sx_updated, gpointer user_data)
540 {
541  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
542  gnc_sx_instance_model_update_sx_instances(instances, sx_updated);
543  gtk_tree_store_clear(model->orig);
544  gsltma_populate_tree_store(model);
545 }
546 
547 static void
548 gsltma_removing_cb(GncSxInstanceModel *instances, SchedXaction *sx_removing, gpointer user_data)
549 {
550  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
551  gnc_sx_instance_model_remove_sx_instances(instances, sx_removing);
552  gtk_tree_store_clear(model->orig);
553  gsltma_populate_tree_store(model);
554 }
555 
557 gnc_sx_list_tree_model_adapter_new(GncSxInstanceModel *instances)
558 {
560 
561  rtn = GNC_SX_LIST_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, NULL));
562  rtn->instances = instances;
563  g_object_ref(G_OBJECT(rtn->instances));
564 
565  gsltma_populate_tree_store(rtn);
566 
567  g_signal_connect(G_OBJECT(rtn->instances), "added", (GCallback)gsltma_added_cb, (gpointer)rtn);
568  g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsltma_updated_cb, (gpointer)rtn);
569  g_signal_connect(G_OBJECT(rtn->instances), "removing", (GCallback)gsltma_removing_cb, (gpointer)rtn);
570 
571  return rtn;
572 }
573 
575 gsltma_get_sx_instances_from_orig_iter(GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter)
576 {
577  GtkTreePath *path;
578  gint *indices;
579  gint index;
580 
581  path = gtk_tree_model_get_path(GTK_TREE_MODEL(model->orig), orig_iter);
582  if (gtk_tree_path_get_depth(path) > 1)
583  {
584  gtk_tree_path_free(path);
585  return NULL;
586  }
587  indices = gtk_tree_path_get_indices(path);
588  index = indices[0];
589 
590  gtk_tree_path_free(path);
591  return (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, index);
592 }
593 
595 gnc_sx_list_tree_model_adapter_get_sx_instances(GncSxListTreeModelAdapter *model, GtkTreeIter *sort_iter)
596 {
597  GtkTreeIter translated_iter;
598  gtk_tree_model_sort_convert_iter_to_child_iter(model->real,
599  &translated_iter,
600  sort_iter);
601  return gsltma_get_sx_instances_from_orig_iter(model, &translated_iter);
602 }
603 
604 static void
605 gnc_sx_list_tree_model_adapter_dispose(GObject *obj)
606 {
607  GncSxListTreeModelAdapter *adapter;
608 
609  g_return_if_fail(obj != NULL);
610  adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
611 
612  if (adapter->disposed) return;
613  adapter->disposed = TRUE;
614 
615  g_object_unref(G_OBJECT(adapter->instances));
616  adapter->instances = NULL;
617  g_object_unref(G_OBJECT(adapter->real));
618  adapter->real = NULL;
619  g_object_unref(G_OBJECT(adapter->orig));
620  adapter->orig = NULL;
621 
622  G_OBJECT_CLASS(parent_class)->dispose(obj);
623 }
624 
625 static void
626 gnc_sx_list_tree_model_adapter_finalize(GObject *obj)
627 {
628  g_return_if_fail(obj != NULL);
629  G_OBJECT_CLASS(parent_class)->finalize(obj);
630 }
GList * gnc_sx_get_schedule(const SchedXaction *sx)
Definition: SchedXaction.c:559
void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
#define MAX_DATE_LENGTH
Definition: gnc-date.h:106
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)