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 _name_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
347 {
348  gint rtn;
349  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
350  GncSxInstances *a_inst, *b_inst;
351  gchar *a_caseless, *b_caseless;
352 
353  a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
354  b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
355 
356  if (a_inst == NULL && b_inst == NULL) return 0;
357  if (a_inst == NULL) return 1;
358  if (b_inst == NULL) return -1;
359 
360  a_caseless = g_utf8_casefold (xaccSchedXactionGetName (a_inst->sx), -1);
361  b_caseless = g_utf8_casefold (xaccSchedXactionGetName (b_inst->sx), -1);
362  rtn = g_strcmp0 (a_caseless, b_caseless);
363  g_free (a_caseless);
364  g_free (b_caseless);
365 
366  return rtn;
367 }
368 
369 static gint
370 _freq_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
371 {
372  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
373  GncSxInstances *a_inst, *b_inst;
374 
375  a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
376  b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
377 
378  if (a_inst == NULL && b_inst == NULL) return 0;
379  if (a_inst == NULL) return 1;
380  if (b_inst == NULL) return -1;
381 
382  return recurrenceListCmp (gnc_sx_get_schedule (a_inst->sx), gnc_sx_get_schedule (b_inst->sx));
383 }
384 
385 static gint
386 _safe_invalidable_date_compare (const GDate *a, const GDate *b)
387 {
388  if (!g_date_valid (a) && !g_date_valid (b))
389  {
390  return 0;
391  }
392  if (!g_date_valid (a))
393  {
394  return 1;
395  }
396  if (!g_date_valid (b))
397  {
398  return -1;
399  }
400  return g_date_compare (a, b);
401 }
402 
403 static gint
404 _last_occur_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
405 {
406  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
407  GncSxInstances *a_inst, *b_inst;
408 
409  a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
410  b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
411 
412  return _safe_invalidable_date_compare (xaccSchedXactionGetLastOccurDate (a_inst->sx),
413  xaccSchedXactionGetLastOccurDate (b_inst->sx));
414 }
415 
416 static gint
417 _next_occur_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
418 {
419  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
420  GncSxInstances *a_inst, *b_inst;
421 
422  a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
423  b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
424 
425  return _safe_invalidable_date_compare (&a_inst->next_instance_date,
426  &b_inst->next_instance_date);
427 }
428 
429 static gint
430 _enabled_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
431 {
432  GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
433  GncSxInstances *a_inst, *b_inst;
434 
435  a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
436  b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
437 
438  if (xaccSchedXactionGetEnabled (a_inst->sx) && !xaccSchedXactionGetEnabled (b_inst->sx)) return 1;
439  if (!xaccSchedXactionGetEnabled (a_inst->sx) && xaccSchedXactionGetEnabled (b_inst->sx)) return -1;
440  return 0;
441 }
442 
443 static void
444 gnc_sx_list_tree_model_adapter_init (GncSxListTreeModelAdapter *adapter)
445 {
446  adapter->orig = gtk_tree_store_new (5, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
447  adapter->real = GTK_TREE_MODEL_SORT(gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(adapter->orig)));
448 
449  // setup sorting
450  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NAME,
451  _name_comparator, adapter, NULL);
452  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_ENABLED,
453  _enabled_comparator, adapter, NULL);
454  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_FREQUENCY,
455  _freq_comparator, adapter, NULL);
456  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_LAST_OCCUR,
457  _last_occur_comparator, adapter, NULL);
458  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NEXT_OCCUR,
459  _next_occur_comparator, adapter, NULL);
460 
461  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(adapter->real),
462  SXLTMA_COL_NAME, GTK_SORT_ASCENDING);
463 
464  g_signal_connect (adapter->real, "row-changed",
465  G_CALLBACK(gsltma_proxy_row_changed), adapter);
466  g_signal_connect (adapter->real, "row-deleted",
467  G_CALLBACK(gsltma_proxy_row_deleted), adapter);
468  g_signal_connect (adapter->real, "row-has-child-toggled",
469  G_CALLBACK(gsltma_proxy_row_has_child_toggled), adapter);
470  g_signal_connect (adapter->real, "row-inserted",
471  G_CALLBACK(gsltma_proxy_row_inserted), adapter);
472  g_signal_connect (adapter->real, "rows-reordered",
473  G_CALLBACK(gsltma_proxy_rows_reordered), adapter);
474  g_signal_connect (adapter->real, "sort-column-changed",
475  G_CALLBACK(gsltma_proxy_sort_column_changed), adapter);
476 }
477 
478 static void
479 _format_conditional_date (const GDate *date, char *date_buf, int buf_max_length)
480 {
481  if (date == NULL || !g_date_valid (date))
482  g_stpcpy (date_buf, _("never"));
483  else
484  qof_print_gdate (date_buf, buf_max_length, date);
485 }
486 
487 static void
488 gsltma_populate_tree_store (GncSxListTreeModelAdapter *model)
489 {
490  GtkTreeIter iter;
491  GList *list;
492 
493  for (list = gnc_sx_instance_model_get_sx_instances_list (model->instances); list != NULL; list = list->next)
494  {
495  GncSxInstances *instances = (GncSxInstances*)list->data;
496  gchar *frequency_str;
497  char last_occur_date_buf[MAX_DATE_LENGTH+1];
498  char next_occur_date_buf[MAX_DATE_LENGTH+1];
499 
500  frequency_str = recurrenceListToCompactString (gnc_sx_get_schedule (instances->sx));
501 
502  _format_conditional_date (xaccSchedXactionGetLastOccurDate (instances->sx),
503  last_occur_date_buf, MAX_DATE_LENGTH);
504  _format_conditional_date (&instances->next_instance_date,
505  next_occur_date_buf, MAX_DATE_LENGTH);
506 
507  gtk_tree_store_append (model->orig, &iter, NULL);
508  gtk_tree_store_set (model->orig, &iter,
509  SXLTMA_COL_NAME, xaccSchedXactionGetName (instances->sx),
510  SXLTMA_COL_ENABLED, xaccSchedXactionGetEnabled (instances->sx),
511  SXLTMA_COL_FREQUENCY, frequency_str,
512  SXLTMA_COL_LAST_OCCUR, last_occur_date_buf,
513  SXLTMA_COL_NEXT_OCCUR, next_occur_date_buf,
514  -1);
515  g_free (frequency_str);
516  }
517  g_signal_emit_by_name (model, "model_populated");
518 }
519 
520 static void
521 gsltma_added_cb (GncSxInstanceModel *instances, SchedXaction *sx_added, gpointer user_data)
522 {
523  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
524  gtk_tree_store_clear (model->orig);
525  gsltma_populate_tree_store (model);
526 }
527 
528 static void
529 gsltma_updated_cb (GncSxInstanceModel *instances, SchedXaction *sx_updated, gpointer user_data)
530 {
531  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
532  gnc_sx_instance_model_update_sx_instances (instances, sx_updated);
533  gtk_tree_store_clear (model->orig);
534  gsltma_populate_tree_store (model);
535 }
536 
537 static void
538 gsltma_removing_cb (GncSxInstanceModel *instances, SchedXaction *sx_removing, gpointer user_data)
539 {
540  GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
541  gnc_sx_instance_model_remove_sx_instances (instances, sx_removing);
542  gtk_tree_store_clear (model->orig);
543  gsltma_populate_tree_store (model);
544 }
545 
546 GncSxListTreeModelAdapter*
547 gnc_sx_list_tree_model_adapter_new (GncSxInstanceModel *instances)
548 {
549  GncSxListTreeModelAdapter *rtn;
550 
551  rtn = GNC_SX_LIST_TREE_MODEL_ADAPTER(g_object_new (GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, NULL));
552  rtn->instances = instances;
553  g_object_ref (G_OBJECT(rtn->instances));
554 
555  gsltma_populate_tree_store (rtn);
556 
557  g_signal_connect (G_OBJECT(rtn->instances), "added",
558  (GCallback)gsltma_added_cb, (gpointer)rtn);
559  g_signal_connect (G_OBJECT(rtn->instances), "updated",
560  (GCallback)gsltma_updated_cb, (gpointer)rtn);
561  g_signal_connect (G_OBJECT(rtn->instances), "removing",
562  (GCallback)gsltma_removing_cb, (gpointer)rtn);
563 
564  return rtn;
565 }
566 
568 gsltma_get_sx_instances_from_orig_iter (GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter)
569 {
570  GtkTreePath *path;
571  gint *indices;
572  gint index;
573 
574  path = gtk_tree_model_get_path (GTK_TREE_MODEL(model->orig), orig_iter);
575  if (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 
583  gtk_tree_path_free (path);
584  return (GncSxInstances*)g_list_nth_data (gnc_sx_instance_model_get_sx_instances_list (model->instances), index);
585 }
586 
588 gnc_sx_list_tree_model_adapter_get_sx_instances (GncSxListTreeModelAdapter *model, GtkTreeIter *sort_iter)
589 {
590  GtkTreeIter translated_iter;
591  gtk_tree_model_sort_convert_iter_to_child_iter (model->real,
592  &translated_iter,
593  sort_iter);
594  return gsltma_get_sx_instances_from_orig_iter (model, &translated_iter);
595 }
596 
597 static void
598 gnc_sx_list_tree_model_adapter_dispose (GObject *obj)
599 {
600  GncSxListTreeModelAdapter *adapter;
601 
602  g_return_if_fail (obj != NULL);
603  adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
604 
605  if (adapter->disposed) return;
606  adapter->disposed = TRUE;
607 
608  g_object_unref (G_OBJECT(adapter->instances));
609  adapter->instances = NULL;
610  g_object_unref (G_OBJECT(adapter->real));
611  adapter->real = NULL;
612  g_object_unref (G_OBJECT(adapter->orig));
613  adapter->orig = NULL;
614 
615  G_OBJECT_CLASS(gnc_sx_list_tree_model_adapter_parent_class)->dispose (obj);
616 }
617 
618 static void
619 gnc_sx_list_tree_model_adapter_finalize (GObject *obj)
620 {
621  g_return_if_fail (obj != NULL);
622  G_OBJECT_CLASS(gnc_sx_list_tree_model_adapter_parent_class)->finalize (obj);
623 }
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:597
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) ...