37 #include <glib/gi18n.h> 38 #include <glib-object.h> 40 #include "gnc-sx-list-tree-model-adapter.h" 49 GncSxInstanceModel *instances;
51 GtkTreeModelSort *real;
61 static void gsltma_tree_model_interface_init (GtkTreeModelIface *tree_model);
62 static void gsltma_tree_sortable_interface_init (GtkTreeSortableIface *tree_sortable);
64 static void gnc_sx_list_tree_model_adapter_dispose (GObject *obj);
65 static void gnc_sx_list_tree_model_adapter_finalize (GObject *obj);
67 static guint gnc_sx_list_tree_model_adapter_signals[LAST_SIGNAL] = {0};
69 static GncSxInstances* gsltma_get_sx_instances_from_orig_iter (GncSxListTreeModelAdapter *model,
70 GtkTreeIter *orig_iter);
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))
77 gnc_sx_list_tree_model_adapter_class_init (GncSxListTreeModelAdapterClass *klass)
79 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
81 obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
82 obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
84 gnc_sx_list_tree_model_adapter_signals[MODEL_POPULATED] =
85 g_signal_new (
"model_populated",
86 G_TYPE_FROM_CLASS(obj_class),
90 g_cclosure_marshal_VOID__VOID,
94 static GtkTreeModelFlags
95 gsltma_get_flags (GtkTreeModel *tree_model)
97 return gtk_tree_model_get_flags (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
101 gsltma_get_n_columns (GtkTreeModel *tree_model)
103 return gtk_tree_model_get_n_columns (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
107 gsltma_get_column_type (GtkTreeModel *tree_model, gint index)
109 return gtk_tree_model_get_column_type (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
114 gsltma_get_iter (GtkTreeModel *tree_model,
118 return gtk_tree_model_get_iter (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
123 gsltma_get_path (GtkTreeModel *tree_model,
126 return gtk_tree_model_get_path (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
131 gsltma_get_value (GtkTreeModel *tree_model,
136 gtk_tree_model_get_value (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
137 iter, column, value);
141 gsltma_iter_next (GtkTreeModel *tree_model,
144 return gtk_tree_model_iter_next (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
149 gsltma_iter_children (GtkTreeModel *tree_model,
153 return gtk_tree_model_iter_children (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
158 gsltma_iter_has_child (GtkTreeModel *tree_model,
161 return gtk_tree_model_iter_has_child (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
166 gsltma_iter_n_children (GtkTreeModel *tree_model,
169 return gtk_tree_model_iter_n_children (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
174 gsltma_iter_nth_child (GtkTreeModel *tree_model,
179 return gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
184 gsltma_iter_parent (GtkTreeModel *tree_model,
188 return gtk_tree_model_iter_parent (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
193 gsltma_ref_node (GtkTreeModel *tree_model,
196 gtk_tree_model_ref_node (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
201 gsltma_unref_node (GtkTreeModel *tree_model,
204 gtk_tree_model_unref_node (GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real),
209 gsltma_tree_model_interface_init (GtkTreeModelIface *tree_model)
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;
228 gsltma_get_sort_column_id (GtkTreeSortable *sortable,
229 gint *sort_column_id,
232 return gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
238 gsltma_set_sort_column_id (GtkTreeSortable *sortable,
242 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
248 gsltma_set_sort_func (GtkTreeSortable *sortable,
250 GtkTreeIterCompareFunc func,
252 GDestroyNotify destroy)
254 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
262 gsltma_set_default_sort_func (GtkTreeSortable *sortable,
263 GtkTreeIterCompareFunc func,
265 GDestroyNotify destroy)
267 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
274 gsltma_has_default_sort_func (GtkTreeSortable *sortable)
276 return gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real));
280 gsltma_tree_sortable_interface_init (GtkTreeSortableIface *tree_sortable)
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;
295 gsltma_proxy_row_changed (GtkTreeModel *treemodel,
300 g_signal_emit_by_name (user_data,
"row-changed", arg1, arg2);
304 gsltma_proxy_row_deleted (GtkTreeModel *treemodel,
308 g_signal_emit_by_name (user_data,
"row-deleted", arg1);
312 gsltma_proxy_row_has_child_toggled (GtkTreeModel *treemodel,
317 g_signal_emit_by_name (user_data,
"row-has-child-toggled", arg1, arg2);
321 gsltma_proxy_row_inserted (GtkTreeModel *treemodel,
326 g_signal_emit_by_name (user_data,
"row-inserted", arg1, arg2);
330 gsltma_proxy_rows_reordered (GtkTreeModel *treemodel,
336 g_signal_emit_by_name (user_data,
"rows-reordered", arg1, arg2, arg3);
340 gsltma_proxy_sort_column_changed (GtkTreeSortable *sortable, gpointer user_data)
342 g_signal_emit_by_name (user_data,
"sort-column-changed");
346 _sort_iterators_to_instances (gpointer *user_data, GtkTreeIter *a, GtkTreeIter *b,
349 GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
352 a_inst = gsltma_get_sx_instances_from_orig_iter (adapter, a);
353 b_inst = gsltma_get_sx_instances_from_orig_iter (adapter, b);
355 if (a_inst == NULL && b_inst == NULL)
return 0;
356 if (a_inst == NULL)
return 1;
357 if (b_inst == NULL)
return -1;
359 return instances_comparator (a_inst, b_inst);
365 gchar *a_caseless, *b_caseless;
368 a_caseless = g_utf8_casefold (xaccSchedXactionGetName (a_inst->sx), -1);
369 b_caseless = g_utf8_casefold (xaccSchedXactionGetName (b_inst->sx), -1);
371 rtn = g_strcmp0 (a_caseless, b_caseless);
380 _name_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
382 return _sort_iterators_to_instances (user_data, a, b, _name_instances_compare);
392 return rtn ? rtn : _name_instances_compare (a_inst, b_inst);
396 _freq_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
398 return _sort_iterators_to_instances (user_data, a, b, _freq_instances_compare);
402 _safe_invalidable_date_compare (
const GDate *a,
const GDate *b)
404 gboolean a_valid, b_valid;
406 a_valid = g_date_valid (a);
407 b_valid = g_date_valid (b);
409 if (!a_valid && !b_valid)
return 0;
410 if (!a_valid)
return 1;
411 if (!b_valid)
return -1;
413 return g_date_compare (a, b);
421 rtn = _safe_invalidable_date_compare (xaccSchedXactionGetLastOccurDate (a_inst->sx),
422 xaccSchedXactionGetLastOccurDate (b_inst->sx));
424 return rtn ? rtn : _name_instances_compare (a_inst, b_inst);
428 _last_occur_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
430 return _sort_iterators_to_instances (user_data, a, b, _last_occur_instances_compare);
438 rtn = _safe_invalidable_date_compare (&a_inst->next_instance_date,
439 &b_inst->next_instance_date);
441 return rtn ? rtn : _name_instances_compare (a_inst, b_inst);
445 _next_occur_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
447 return _sort_iterators_to_instances (user_data, a, b, _next_occur_instances_compare);
453 gboolean a_enabled, b_enabled;
455 a_enabled = xaccSchedXactionGetEnabled (a_inst->sx);
456 b_enabled = xaccSchedXactionGetEnabled (b_inst->sx);
458 if (a_enabled && !b_enabled)
return 1;
459 if (!a_enabled && b_enabled)
return -1;
461 return _name_instances_compare (a_inst, b_inst);
465 _enabled_comparator (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
467 return _sort_iterators_to_instances (user_data, a, b, _enabled_instances_compare);
471 gnc_sx_list_tree_model_adapter_init (GncSxListTreeModelAdapter *adapter)
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)));
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);
488 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(adapter->real),
489 SXLTMA_COL_NAME, GTK_SORT_ASCENDING);
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);
506 _format_conditional_date (
const GDate *date,
char *date_buf,
int buf_max_length)
508 if (date == NULL || !g_date_valid (date))
509 g_stpcpy (date_buf, _(
"never"));
515 gsltma_populate_tree_store (GncSxListTreeModelAdapter *model)
523 gchar *frequency_str;
525 unsigned postponed_count;
530 _format_conditional_date (xaccSchedXactionGetLastOccurDate (instances->sx),
533 _format_conditional_date (&instances->next_instance_date,
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,
545 g_free (frequency_str);
547 g_signal_emit_by_name (model,
"model_populated");
551 gsltma_added_cb (GncSxInstanceModel *instances, SchedXaction *sx_added, gpointer user_data)
553 GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
554 gtk_tree_store_clear (model->orig);
555 gsltma_populate_tree_store (model);
559 gsltma_updated_cb (GncSxInstanceModel *instances, SchedXaction *sx_updated, gpointer user_data)
561 GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
563 gtk_tree_store_clear (model->orig);
564 gsltma_populate_tree_store (model);
568 gsltma_removing_cb (GncSxInstanceModel *instances, SchedXaction *sx_removing, gpointer user_data)
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);
576 GncSxListTreeModelAdapter*
577 gnc_sx_list_tree_model_adapter_new (GncSxInstanceModel *instances)
579 GncSxListTreeModelAdapter *rtn;
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));
585 gsltma_populate_tree_store (rtn);
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);
598 gsltma_get_sx_instances_from_orig_iter (GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter)
604 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model->orig), orig_iter);
605 if (gtk_tree_path_get_depth (path) > 1)
607 gtk_tree_path_free (path);
610 indices = gtk_tree_path_get_indices (path);
613 gtk_tree_path_free (path);
618 gnc_sx_list_tree_model_adapter_get_sx_instances (GncSxListTreeModelAdapter *model, GtkTreeIter *sort_iter)
620 GtkTreeIter translated_iter;
621 gtk_tree_model_sort_convert_iter_to_child_iter (model->real,
624 return gsltma_get_sx_instances_from_orig_iter (model, &translated_iter);
628 gnc_sx_list_tree_model_adapter_dispose (GObject *obj)
630 GncSxListTreeModelAdapter *adapter;
632 g_return_if_fail (obj != NULL);
633 adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
635 if (adapter->disposed)
return;
636 adapter->disposed = TRUE;
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;
645 G_OBJECT_CLASS(gnc_sx_list_tree_model_adapter_parent_class)->dispose (obj);
649 gnc_sx_list_tree_model_adapter_finalize (GObject *obj)
651 g_return_if_fail (obj != NULL);
652 G_OBJECT_CLASS(gnc_sx_list_tree_model_adapter_parent_class)->finalize (obj);
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().
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.
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...