35 #include <glib/gi18n.h>
36 #include <glib-object.h>
38 #include "gnc-sx-list-tree-model-adapter.h"
49 GtkTreeModelSort *real;
57 static GObjectClass *parent_class = NULL;
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);
69 gnc_sx_list_tree_model_adapter_get_type(
void)
71 static GType type = 0;
74 static const GTypeInfo info =
79 (GClassInitFunc)gnc_sx_list_tree_model_adapter_class_init,
84 (GInstanceInitFunc)gnc_sx_list_tree_model_adapter_init
86 static const GInterfaceInfo itree_model_info =
88 (GInterfaceInitFunc) gsltma_tree_model_interface_init,
92 static const GInterfaceInfo itree_sortable_info =
94 (GInterfaceInitFunc) gsltma_tree_sortable_interface_init,
99 type = g_type_register_static (G_TYPE_OBJECT,
100 "GncSxListTreeModelAdapterType",
102 g_type_add_interface_static(type,
105 g_type_add_interface_static(type,
106 GTK_TYPE_TREE_SORTABLE,
107 &itree_sortable_info);
115 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
117 parent_class = g_type_class_peek_parent(klass);
119 obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
120 obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
124 static GtkTreeModelFlags
125 gsltma_get_flags(GtkTreeModel *tree_model)
127 return gtk_tree_model_get_flags(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
131 gsltma_get_n_columns(GtkTreeModel *tree_model)
133 return gtk_tree_model_get_n_columns(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
137 gsltma_get_column_type(GtkTreeModel *tree_model, gint index)
139 return gtk_tree_model_get_column_type(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), index);
143 gsltma_get_iter(GtkTreeModel *tree_model,
147 return gtk_tree_model_get_iter(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, path);
151 gsltma_get_path(GtkTreeModel *tree_model,
154 return gtk_tree_model_get_path(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
158 gsltma_get_value(GtkTreeModel *tree_model,
163 gtk_tree_model_get_value(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, column, value);
167 gsltma_iter_next(GtkTreeModel *tree_model,
170 return gtk_tree_model_iter_next(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
174 gsltma_iter_children(GtkTreeModel *tree_model,
178 return gtk_tree_model_iter_children(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent);
182 gsltma_iter_has_child(GtkTreeModel *tree_model,
185 return gtk_tree_model_iter_has_child(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
189 gsltma_iter_n_children(GtkTreeModel *tree_model,
192 return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
196 gsltma_iter_nth_child(GtkTreeModel *tree_model,
201 return gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent, n);
205 gsltma_iter_parent(GtkTreeModel *tree_model,
209 return gtk_tree_model_iter_parent(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, child);
213 gsltma_ref_node(GtkTreeModel *tree_model,
216 gtk_tree_model_ref_node(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
220 gsltma_unref_node(GtkTreeModel *tree_model,
223 gtk_tree_model_unref_node(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
227 gsltma_tree_model_interface_init(gpointer g_iface, gpointer iface_data)
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;
247 gsltma_get_sort_column_id(GtkTreeSortable *sortable,
248 gint *sort_column_id,
251 return gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
257 gsltma_set_sort_column_id(GtkTreeSortable *sortable,
261 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
267 gsltma_set_sort_func(GtkTreeSortable *sortable,
269 GtkTreeIterCompareFunc func,
271 GDestroyNotify destroy)
273 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
281 gsltma_set_default_sort_func(GtkTreeSortable *sortable,
282 GtkTreeIterCompareFunc func,
284 GDestroyNotify destroy)
286 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
287 func, data, destroy);
291 gsltma_has_default_sort_func(GtkTreeSortable *sortable)
293 return gtk_tree_sortable_has_default_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real));
297 gsltma_tree_sortable_interface_init(gpointer g_iface, gpointer iface_data)
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;
313 gsltma_proxy_row_changed(GtkTreeModel *treemodel,
318 g_signal_emit_by_name(user_data,
"row-changed", arg1, arg2);
322 gsltma_proxy_row_deleted(GtkTreeModel *treemodel,
326 g_signal_emit_by_name(user_data,
"row-deleted", arg1);
330 gsltma_proxy_row_has_child_toggled(GtkTreeModel *treemodel,
335 g_signal_emit_by_name(user_data,
"row-has-child-toggled", arg1, arg2);
339 gsltma_proxy_row_inserted(GtkTreeModel *treemodel,
344 g_signal_emit_by_name(user_data,
"row-inserted", arg1, arg2);
348 gsltma_proxy_rows_reordered(GtkTreeModel *treemodel,
354 g_signal_emit_by_name(user_data,
"rows-reordered", arg1, arg2, arg3);
358 gsltma_proxy_sort_column_changed(GtkTreeSortable *sortable, gpointer user_data)
360 g_signal_emit_by_name(user_data,
"sort-column-changed");
364 _name_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
369 gchar *a_caseless, *b_caseless;
371 a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
372 b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
374 if (a_inst == NULL && b_inst == NULL)
return 0;
375 if (a_inst == NULL)
return 1;
376 if (b_inst == NULL)
return -1;
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);
388 _freq_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
393 a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
394 b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
396 if (a_inst == NULL && b_inst == NULL)
return 0;
397 if (a_inst == NULL)
return 1;
398 if (b_inst == NULL)
return -1;
404 _safe_invalidable_date_compare(
const GDate *a,
const GDate *b)
406 if (!g_date_valid(a) && !g_date_valid(b))
410 if (!g_date_valid(a))
414 if (!g_date_valid(b))
418 return g_date_compare(a, b);
422 _last_occur_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
427 a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
428 b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
430 return _safe_invalidable_date_compare(xaccSchedXactionGetLastOccurDate(a_inst->sx),
431 xaccSchedXactionGetLastOccurDate(b_inst->sx));
435 _next_occur_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
440 a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
441 b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
443 return _safe_invalidable_date_compare(&a_inst->next_instance_date,
444 &b_inst->next_instance_date);
448 _enabled_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
453 a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
454 b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
456 if (xaccSchedXactionGetEnabled(a_inst->sx) && !xaccSchedXactionGetEnabled(b_inst->sx))
return 1;
457 if (!xaccSchedXactionGetEnabled(a_inst->sx) && xaccSchedXactionGetEnabled(b_inst->sx))
return -1;
462 gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointer klass)
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)));
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);
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);
482 g_signal_connect(adapter->real,
"sort-column-changed", G_CALLBACK(gsltma_proxy_sort_column_changed), adapter);
486 _format_conditional_date(
const GDate *date,
char *date_buf,
int buf_max_length)
488 if (date == NULL || !g_date_valid(date))
490 g_stpcpy(date_buf, _(
"never"));
504 for (list = model->instances->sx_instance_list; list != NULL; list = list->next)
507 gchar *frequency_str;
513 _format_conditional_date(xaccSchedXactionGetLastOccurDate(instances->sx),
515 _format_conditional_date(&instances->next_instance_date,
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,
526 g_free(frequency_str);
534 gtk_tree_store_clear(model->orig);
535 gsltma_populate_tree_store(model);
543 gtk_tree_store_clear(model->orig);
544 gsltma_populate_tree_store(model);
551 gnc_sx_instance_model_remove_sx_instances(instances, sx_removing);
552 gtk_tree_store_clear(model->orig);
553 gsltma_populate_tree_store(model);
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));
565 gsltma_populate_tree_store(rtn);
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);
581 path = gtk_tree_model_get_path(GTK_TREE_MODEL(model->orig), orig_iter);
582 if (gtk_tree_path_get_depth(path) > 1)
584 gtk_tree_path_free(path);
587 indices = gtk_tree_path_get_indices(path);
590 gtk_tree_path_free(path);
591 return (
GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, index);
597 GtkTreeIter translated_iter;
598 gtk_tree_model_sort_convert_iter_to_child_iter(model->real,
601 return gsltma_get_sx_instances_from_orig_iter(model, &translated_iter);
605 gnc_sx_list_tree_model_adapter_dispose(GObject *obj)
609 g_return_if_fail(obj != NULL);
610 adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
612 if (adapter->disposed)
return;
613 adapter->disposed = TRUE;
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;
622 G_OBJECT_CLASS(parent_class)->dispose(obj);
626 gnc_sx_list_tree_model_adapter_finalize(GObject *obj)
628 g_return_if_fail(obj != NULL);
629 G_OBJECT_CLASS(parent_class)->finalize(obj);
GList * gnc_sx_get_schedule(const SchedXaction *sx)
void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)