30 #include <glib/gi18n.h>
33 #include "gnc-tree-model-split-reg.h"
34 #include "gnc-component-manager.h"
45 #include "engine-helpers.h"
47 #define TREE_MODEL_SPLIT_REG_CM_CLASS "tree-model-split-reg"
56 SELECTION_MOVE_DELETE,
67 static void gnc_tree_model_split_reg_finalize (GObject *
object);
68 static void gnc_tree_model_split_reg_dispose (GObject *
object);
70 static guint gnc_tree_model_split_reg_signals[LAST_SIGNAL] = {0};
72 static const gchar *iter_to_string (GtkTreeIter *iter);
75 static void gnc_tree_model_split_reg_tree_model_init (GtkTreeModelIface *iface);
77 static GtkTreeModelFlags gnc_tree_model_split_reg_get_flags (GtkTreeModel *tree_model);
78 static int gnc_tree_model_split_reg_get_n_columns (GtkTreeModel *tree_model);
79 static GType gnc_tree_model_split_reg_get_column_type (GtkTreeModel *tree_model,
int index);
80 static gboolean gnc_tree_model_split_reg_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path);
81 static GtkTreePath *gnc_tree_model_split_reg_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter);
82 static void gnc_tree_model_split_reg_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter,
int column, GValue *value);
83 static gboolean gnc_tree_model_split_reg_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter);
84 static gboolean gnc_tree_model_split_reg_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent);
85 static gboolean gnc_tree_model_split_reg_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter);
86 static int gnc_tree_model_split_reg_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter);
87 static gboolean gnc_tree_model_split_reg_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent,
int n);
88 static gboolean gnc_tree_model_split_reg_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child);
112 GList *bsplit_parent_node;
114 gboolean display_subacc;
117 const GncGUID *template_account;
120 SRGetParentCallback2 get_parent;
122 GtkListStore *description_list;
123 GtkListStore *notes_list;
124 GtkListStore *memo_list;
125 GtkListStore *action_list;
126 GtkListStore *account_list;
128 gint event_handler_id;
133 #define GREENROW "#BFDEB9"
134 #define TANROW "#F6FFDA"
135 #define SPLITROW "#EDE7D3"
136 #define YELLOWROW "#FFEF98"
138 #define TROW1 0x1 // Transaction row 1 depth 1
139 #define TROW2 0x2 // Transaction row 2 depth 2
140 #define SPLIT 0x4 // Split row depth 3
141 #define BLANK 0x8 // Blank row
142 #define IS_TROW1(x) (GPOINTER_TO_INT((x)->user_data) & TROW1)
143 #define IS_TROW2(x) (GPOINTER_TO_INT((x)->user_data) & TROW2)
144 #define IS_BLANK(x) (GPOINTER_TO_INT((x)->user_data) & BLANK)
145 #define IS_SPLIT(x) (GPOINTER_TO_INT((x)->user_data) & SPLIT)
146 #define IS_BLANK_SPLIT(x) (IS_BLANK(x) && IS_SPLIT(x))
147 #define IS_BLANK_TRANS(x) (IS_BLANK(x) && !IS_SPLIT(x))
170 #define VALID_ITER (model, iter) \
171 (GNC_IS_TREE_MODEL_SPLIT_REG (model) && \
172 ((iter).user_data != NULL) && ((iter).user_data2 != NULL) && (model->stamp == (gint)(iter).stamp) && \
173 ( (IS_SPLIT (iter) && (iter).user_data3) || (IS_BLANK_SPLIT (iter) && ((GList *)(iter).user_data2 == model->priv->bsplit_parent_node)) || \
174 (!IS_SPLIT (iter) && (iter).user_data2) || (IS_BLANK_TRANS (iter) && (iter).user_data3 == NULL)))
181 return IS_BLANK_TRANS (iter);
189 if (GNC_IS_TREE_MODEL_SPLIT_REG (model) && (iter->user_data != NULL) && (iter->user_data2 != NULL) && (model->
stamp == (gint)iter->stamp)
190 && ( (IS_SPLIT (iter) && iter->user_data3) || (IS_BLANK_SPLIT (iter) && ((GList *)iter->user_data2 == model->priv->bsplit_parent_node))
191 || (!IS_SPLIT (iter) && iter->user_data2) || (IS_BLANK_TRANS (iter) && iter->user_data3 == NULL)))
202 GtkTreeIter iter, *iter_p;
204 iter.stamp = model->
stamp;
205 iter.user_data = GINT_TO_POINTER(f);
206 iter.user_data2 = tnode;
207 iter.user_data3 = snode;
216 if (!(gtm_sr_valid_iter (model, iter_p)))
217 PERR (
"Making invalid iter %s", iter_to_string (iter_p));
222 #define GNC_TREE_MODEL_SPLIT_REG_GET_PRIVATE(o) \
223 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_MODEL_SPLIT_REG, GncTreeModelSplitRegPrivate))
230 static GtkObjectClass *parent_class = NULL;
233 gnc_tree_model_split_reg_get_type (
void)
235 static GType gnc_tree_model_split_reg_type = 0;
237 if (gnc_tree_model_split_reg_type == 0)
239 static const GTypeInfo our_info =
244 (GClassInitFunc) gnc_tree_model_split_reg_class_init,
249 (GInstanceInitFunc) gnc_tree_model_split_reg_init
252 static const GInterfaceInfo tree_model_info =
254 (GInterfaceInitFunc) gnc_tree_model_split_reg_tree_model_init,
259 gnc_tree_model_split_reg_type = g_type_register_static (GNC_TYPE_TREE_MODEL,
260 GNC_TREE_MODEL_SPLIT_REG_NAME,
263 g_type_add_interface_static (gnc_tree_model_split_reg_type,
267 return gnc_tree_model_split_reg_type;
274 GObjectClass *o_class;
276 parent_class = g_type_class_peek_parent (klass);
278 o_class = G_OBJECT_CLASS (klass);
281 o_class->finalize = gnc_tree_model_split_reg_finalize;
282 o_class->dispose = gnc_tree_model_split_reg_dispose;
284 gnc_tree_model_split_reg_signals[REFRESH_TRANS] =
285 g_signal_new(
"refresh_trans",
286 G_TYPE_FROM_CLASS (o_class),
290 g_cclosure_marshal_VOID__POINTER,
295 gnc_tree_model_split_reg_signals[REFRESH_STATUS_BAR] =
296 g_signal_new(
"refresh_status_bar",
297 G_TYPE_FROM_CLASS (o_class),
301 g_cclosure_marshal_VOID__VOID,
304 gnc_tree_model_split_reg_signals[REFRESH_VIEW] =
305 g_signal_new(
"refresh_view",
306 G_TYPE_FROM_CLASS (o_class),
310 g_cclosure_marshal_VOID__VOID,
313 gnc_tree_model_split_reg_signals[SCROLL_SYNC] =
314 g_signal_new(
"scroll_sync",
315 G_TYPE_FROM_CLASS (o_class),
319 g_cclosure_marshal_VOID__VOID,
322 gnc_tree_model_split_reg_signals[SELECTION_MOVE_DELETE] =
323 g_signal_new(
"selection_move_delete",
324 G_TYPE_FROM_CLASS (o_class),
328 g_cclosure_marshal_VOID__POINTER,
333 klass->refresh_trans = NULL;
334 klass->refresh_status_bar = NULL;
335 klass->refresh_view = NULL;
336 klass->scroll_sync = NULL;
337 klass->selection_move_delete = NULL;
342 gnc_tree_model_split_reg_prefs_changed (gpointer prefs, gchar *pref, gpointer user_data)
346 g_return_if_fail (pref);
351 if (g_str_has_suffix (pref, GNC_PREF_ACCOUNTING_LABELS))
355 else if (g_str_has_suffix (pref, GNC_PREF_ACCOUNT_SEPARATOR))
361 g_warning(
"gnc_tree_model_split_reg_prefs_changed: Unknown preference %s", pref);
371 ENTER(
"model %p", model);
372 while (model->
stamp == 0)
374 model->
stamp = g_random_int ();
380 GNC_PREF_ACCOUNTING_LABELS,
381 gnc_tree_model_split_reg_prefs_changed,
384 GNC_PREF_ACCOUNT_SEPARATOR,
385 gnc_tree_model_split_reg_prefs_changed,
392 gnc_tree_model_split_reg_finalize (GObject *
object)
396 ENTER(
"model split reg %p",
object);
397 g_return_if_fail (
object != NULL);
398 g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (
object));
400 model = GNC_TREE_MODEL_SPLIT_REG (
object);
402 if (G_OBJECT_CLASS (parent_class)->finalize)
403 G_OBJECT_CLASS (parent_class)->finalize (
object);
409 gnc_tree_model_split_reg_dispose (GObject *
object)
414 ENTER(
"model split reg %p",
object);
415 g_return_if_fail (
object != NULL);
416 g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (
object));
418 model = GNC_TREE_MODEL_SPLIT_REG (
object);
421 if (priv->event_handler_id)
424 priv->event_handler_id = 0;
430 g_list_free (priv->tlist);
434 g_list_free (priv->full_tlist);
435 priv->full_tlist = NULL;
439 priv->bsplit_node = NULL;
448 if (G_OBJECT_CLASS (parent_class)->dispose)
449 G_OBJECT_CLASS (parent_class)->dispose (
object);
459 gnc_tree_model_split_reg_new (SplitRegisterType2 reg_type, SplitRegisterStyle2 style,
460 gboolean use_double_line, gboolean is_template)
465 ENTER(
"Create Model");
467 model = g_object_new (GNC_TYPE_TREE_MODEL_SPLIT_REG, NULL);
470 priv->book = gnc_get_current_book();
471 priv->display_gl = FALSE;
472 priv->display_subacc = FALSE;
474 model->
type = reg_type;
475 model->
style = style;
491 priv->bsplit_node = g_list_append (priv->bsplit_node, priv->bsplit);
500 priv->description_list = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
501 priv->notes_list = gtk_list_store_new (1, G_TYPE_STRING);
502 priv->memo_list = gtk_list_store_new (1, G_TYPE_STRING);
503 priv->action_list = gtk_list_store_new (1, G_TYPE_STRING);
504 priv->account_list = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
509 LEAVE(
"model %p", model);
515 gtm_sr_foreach_func (GtkTreeModel *model,
520 GtkTreeRowReference *rowref;
521 g_assert ( rowref_list != NULL );
523 rowref = gtk_tree_row_reference_new (model, path);
524 *rowref_list = g_list_append (*rowref_list, rowref);
533 GList *rr_list = NULL;
536 gtk_tree_model_foreach (GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)gtm_sr_foreach_func, &rr_list);
538 rr_list = g_list_reverse (rr_list);
540 for ( node = rr_list; node != NULL; node = node->next )
543 path = gtk_tree_row_reference_get_path ((GtkTreeRowReference*)node->data);
547 gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
548 gtk_tree_path_free (path);
551 g_list_foreach (rr_list, (GFunc) gtk_tree_row_reference_free, NULL);
552 g_list_free (rr_list);
556 gtm_sr_reg_load (
GncTreeModelSplitReg *model, GncTreeModelSplitRegUpdate model_update, gint num_of_rows)
564 if (model_update == VIEW_HOME)
566 priv->tlist_start = 0;
568 for (node = g_list_nth (priv->full_tlist, priv->tlist_start); node; node = node->next)
572 priv->tlist = g_list_append (priv->tlist, trans);
575 if (rows == num_of_rows)
580 if (model_update == VIEW_END)
582 priv->tlist_start = g_list_length (priv->full_tlist) - num_of_rows;
584 for (node = g_list_nth (priv->full_tlist, priv->tlist_start); node; node = node->next)
588 priv->tlist = g_list_append (priv->tlist, trans);
591 if (rows == num_of_rows)
596 if (model_update == VIEW_GOTO)
598 priv->tlist_start = num_of_rows - NUM_OF_TRANS*1.5;
600 for (node = g_list_nth (priv->full_tlist, priv->tlist_start); node; node = node->next)
604 priv->tlist = g_list_append (priv->tlist, trans);
607 if (rows == (NUM_OF_TRANS*3))
622 ENTER(
"#### Load ModelSplitReg = %p and slist length is %d ####", model, g_list_length (slist));
627 gtm_sr_remove_all_rows (model);
628 priv->full_tlist = NULL;
637 priv->full_tlist = xaccSplitListGetUniqueTransactions (slist);
640 priv->full_tlist = g_list_append (priv->full_tlist, priv->btrans);
645 priv->full_tlist = xaccSplitListGetUniqueTransactions (slist);
648 priv->full_tlist = g_list_append (priv->full_tlist, priv->btrans);
651 priv->full_tlist = g_list_reverse (priv->full_tlist);
655 gnc_tree_model_split_reg_sync_scrollbar (model);
659 if (g_list_length (priv->full_tlist) < NUM_OF_TRANS*3)
662 priv->tlist = g_list_copy (priv->full_tlist);
667 gtm_sr_reg_load (model, VIEW_HOME, NUM_OF_TRANS*3);
669 gtm_sr_reg_load (model, VIEW_END, NUM_OF_TRANS*3);
674 PINFO(
"#### Register for Account '%s' has %d transactions and %d splits and tlist is %d ####",
675 default_account ?
xaccAccountGetName (default_account) :
"NULL", g_list_length (priv->full_tlist), g_list_length (slist), g_list_length (priv->tlist));
678 g_idle_add ((GSourceFunc) gnc_tree_model_split_reg_update_completion, model);
680 priv->anchor = default_account;
681 priv->bsplit_parent_node = NULL;
683 LEAVE(
"#### Leave Model Load ####");
688 gnc_tree_model_split_reg_move (
GncTreeModelSplitReg *model, GncTreeModelSplitRegUpdate model_update)
691 GList *inode, *dnode;
699 if (g_list_length (priv->full_tlist) < NUM_OF_TRANS*3)
702 if ((model_update == VIEW_UP) && (model->
current_row < NUM_OF_TRANS) && (priv->tlist_start > 0))
705 gint iblock_start = priv->tlist_start - NUM_OF_TRANS;
706 gint iblock_end = priv->tlist_start - 1;
707 gint dblock_start = priv->tlist_start + NUM_OF_TRANS*2;
709 if (iblock_start < 0)
712 icount = iblock_end - iblock_start + 1;
715 dblock_end = dblock_start + dcount - 1;
717 priv->tlist_start = iblock_start;
720 for (inode = g_list_nth (priv->full_tlist, iblock_end); inode; inode = inode->prev)
724 gtm_sr_insert_trans (model, trans, TRUE);
733 for (dnode = g_list_nth (priv->full_tlist, dblock_end); dnode; dnode = dnode->prev)
737 gtm_sr_delete_trans (model, trans);
744 g_signal_emit_by_name (model,
"refresh_view");
747 if ((model_update == VIEW_DOWN) && (model->
current_row > NUM_OF_TRANS*2) && (priv->tlist_start < (g_list_length (priv->full_tlist) - NUM_OF_TRANS*3 )))
750 gint iblock_start = priv->tlist_start + NUM_OF_TRANS*3;
751 gint iblock_end = iblock_start + NUM_OF_TRANS - 1;
752 gint dblock_start = priv->tlist_start;
754 if (iblock_start < 0)
757 if (iblock_end > g_list_length (priv->full_tlist))
758 iblock_end = g_list_length (priv->full_tlist) - 1;
760 icount = iblock_end - iblock_start + 1;
763 dblock_end = dblock_start + dcount;
765 priv->tlist_start = dblock_end;
768 for (inode = g_list_nth (priv->full_tlist, iblock_start); inode; inode = inode->next)
772 gtm_sr_insert_trans (model, trans, FALSE);
781 for (dnode = g_list_nth (priv->full_tlist, dblock_start); dnode; dnode = dnode->next)
785 gtm_sr_delete_trans (model, trans);
792 g_signal_emit_by_name (model,
"refresh_view");
807 node = g_list_first (priv->full_tlist);
811 if (trans == priv->btrans)
813 node = g_list_last (priv->full_tlist);
828 if (g_list_index (priv->tlist, trans) == -1)
841 const gchar *date_text;
842 const gchar *desc_text;
848 node = g_list_nth (priv->full_tlist, position);
850 return g_strconcat (
"Error", NULL);
855 return g_strconcat (
"Error", NULL);
856 else if (trans == priv->btrans)
857 return g_strconcat (
"Blank Transaction", NULL);
864 return g_strconcat (date_text,
"\n", desc_text, NULL);
872 gnc_tree_model_split_reg_set_current_trans_by_position (
GncTreeModelSplitReg *model, gint position)
879 node = g_list_nth (priv->full_tlist, position);
881 node = g_list_last (priv->full_tlist);
897 g_signal_emit_by_name (model,
"scroll_sync");
940 ENTER(
"Model is %p", model);
944 g_object_unref (priv->description_list);
945 g_object_unref (priv->notes_list);
946 g_object_unref (priv->memo_list);
947 g_object_unref (priv->action_list);
948 g_object_unref (priv->account_list);
951 GNC_PREF_ACCOUNTING_LABELS,
952 gnc_tree_model_split_reg_prefs_changed,
955 GNC_PREF_ACCOUNT_SEPARATOR,
956 gnc_tree_model_split_reg_prefs_changed,
965 SRGetParentCallback2 get_parent)
972 priv->user_data = user_data;
973 priv->get_parent = get_parent;
980 SplitRegisterStyle2 newstyle, gboolean use_double_line)
982 model->
type = newtype;
984 if (model->
type >= NUM_SINGLE_REGISTER_TYPES2)
985 newstyle = REG2_STYLE_JOURNAL;
987 model->
style = newstyle;
996 return model->priv->display_subacc;
1003 GSList *p1 = NULL, *p2 = NULL, *p3 = NULL, *standard;
1010 PINFO(
"## gnc_tree_model_split_reg_update_query - query is %p ##", query);
1014 case GNC_TREE_MODEL_SPLIT_REG_COL_DATE:
1017 p1 = g_slist_prepend (p1, TRANS_DATE_POSTED);
1018 p1 = g_slist_prepend (p1, SPLIT_TRANS);
1023 p1 = g_slist_prepend (p1, TRANS_DATE_ENTERED);
1024 p1 = g_slist_prepend (p1, SPLIT_TRANS);
1029 p1 = g_slist_prepend (p1, SPLIT_RECONCILE);
1030 p1 = g_slist_prepend (p2, SPLIT_DATE_RECONCILED);
1035 case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
1038 p1 = g_slist_prepend (p1, TRANS_DESCRIPTION);
1039 p1 = g_slist_prepend (p1, SPLIT_TRANS);
1044 p1 = g_slist_prepend (p1, TRANS_NOTES);
1045 p1 = g_slist_prepend (p1, SPLIT_TRANS);
1050 p1 = g_slist_prepend (p1, SPLIT_MEMO);
1055 case GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT:
1058 p1 = g_slist_prepend (p1, TRANS_NUM);
1059 p1 = g_slist_prepend (p1, SPLIT_TRANS);
1064 p1 = g_slist_prepend (p1, SPLIT_ACTION);
1069 case GNC_TREE_MODEL_SPLIT_REG_COL_RECN:
1071 p1 = g_slist_prepend (p1, SPLIT_RECONCILE);
1072 p1 = g_slist_prepend (p2, SPLIT_DATE_RECONCILED);
1077 case GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT:
1078 case GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT:
1080 p1 = g_slist_prepend (p1, SPLIT_VALUE);
1091 if (model->priv->display_gl == TRUE && model->
type == GENERAL_LEDGER2)
1096 xaccQueryAddDateMatchTT (query, TRUE, start, FALSE, 0, QOF_QUERY_AND);
1106 #define ITER_STRING_LEN 128
1108 static const gchar *
1109 iter_to_string (GtkTreeIter *iter)
1111 #ifdef G_THREADS_ENABLED
1112 #ifndef HAVE_GLIB_2_32
1113 static GStaticPrivate gtmits_buffer_key = G_STATIC_PRIVATE_INIT;
1116 string = g_static_private_get (>mits_buffer_key);
1119 string = g_malloc (ITER_STRING_LEN + 1);
1120 g_static_private_set (>mits_buffer_key,
string, g_free);
1123 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT (g_free);
1126 string = g_private_get (>mits_buffer_key);
1129 string = g_malloc (ITER_STRING_LEN + 1);
1130 g_private_set (>mits_buffer_key,
string);
1134 static char string[ITER_STRING_LEN + 1];
1139 string, ITER_STRING_LEN,
1140 "[stamp:%x data:%d, %p (%p:%s), %p (%p:%s)]",
1141 iter->stamp, GPOINTER_TO_INT (iter->user_data),
1143 iter->user_data2 ? ((GList *) iter->user_data2)->data : 0,
1145 (QOF_INSTANCE (((GList *) iter->user_data2)->data))->e_type :
"",
1147 iter->user_data3 ? ((GList *) iter->user_data3)->data : 0,
1149 (QOF_INSTANCE (((GList *) iter->user_data3)->data))->e_type :
"");
1151 strcpy (
string,
"(null)");
1160 gnc_tree_model_split_reg_tree_model_init (GtkTreeModelIface *iface)
1162 iface->get_flags = gnc_tree_model_split_reg_get_flags;
1163 iface->get_n_columns = gnc_tree_model_split_reg_get_n_columns;
1164 iface->get_column_type = gnc_tree_model_split_reg_get_column_type;
1165 iface->get_iter = gnc_tree_model_split_reg_get_iter;
1166 iface->get_path = gnc_tree_model_split_reg_get_path;
1167 iface->get_value = gnc_tree_model_split_reg_get_value;
1168 iface->iter_next = gnc_tree_model_split_reg_iter_next;
1169 iface->iter_children = gnc_tree_model_split_reg_iter_children;
1170 iface->iter_has_child = gnc_tree_model_split_reg_iter_has_child;
1171 iface->iter_n_children = gnc_tree_model_split_reg_iter_n_children;
1172 iface->iter_nth_child = gnc_tree_model_split_reg_iter_nth_child;
1173 iface->iter_parent = gnc_tree_model_split_reg_iter_parent;
1177 static GtkTreeModelFlags
1178 gnc_tree_model_split_reg_get_flags (GtkTreeModel *tree_model)
1188 gnc_tree_model_split_reg_get_n_columns (GtkTreeModel *tree_model)
1191 g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(tree_model), -1);
1193 return GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS;
1198 gnc_tree_model_split_reg_get_column_type (GtkTreeModel *tree_model,
int index)
1201 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), G_TYPE_INVALID);
1202 g_return_val_if_fail ((index < GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
1206 case GNC_TREE_MODEL_SPLIT_REG_COL_GUID:
1207 return G_TYPE_POINTER;
1209 case GNC_TREE_MODEL_SPLIT_REG_COL_DATE:
1210 case GNC_TREE_MODEL_SPLIT_REG_COL_DUEDATE:
1211 case GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT:
1212 case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
1213 case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSFERVOID:
1214 case GNC_TREE_MODEL_SPLIT_REG_COL_RECN:
1215 case GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT:
1216 case GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT:
1217 return G_TYPE_STRING;
1219 case GNC_TREE_MODEL_SPLIT_REG_COL_RO:
1220 case GNC_TREE_MODEL_SPLIT_REG_COL_NUM_VIS:
1221 case GNC_TREE_MODEL_SPLIT_REG_COL_ACT_VIS:
1222 return G_TYPE_BOOLEAN;
1225 g_assert_not_reached ();
1226 return G_TYPE_INVALID;
1232 gnc_tree_model_split_reg_get_iter (GtkTreeModel *tree_model,
1242 gint depth, *indices, flags = 0;
1244 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
1247 gchar *path_string = gtk_tree_path_to_string (path);
1249 g_free (path_string);
1252 depth = gtk_tree_path_get_depth (path);
1254 indices = gtk_tree_path_get_indices (path);
1256 tnode = g_list_nth (model->priv->tlist, indices[0]);
1259 DEBUG(
"path index off end of tlist");
1268 if (tnode->data == model->priv->btrans)
1274 if (model->priv->bsplit_parent_node == tnode)
1275 snode = model->priv->bsplit_node;
1282 snode = g_list_find (slist, split);
1288 snode = g_list_find (slist, split);
1291 else if (depth == 2) {
1294 if (tnode->data == model->priv->btrans)
1300 if (model->priv->bsplit_parent_node == tnode)
1301 snode = model->priv->bsplit_node;
1308 snode = g_list_find (slist, split);
1314 snode = g_list_find (slist, split);
1317 else if (depth == 3) {
1321 if ((tnode == model->priv->bsplit_parent_node) && (
xaccTransCountSplits (tnode->data) == indices[2]))
1324 snode = model->priv->bsplit_node;
1329 snode = g_list_find (slist, split);
1333 DEBUG(
"path index off end of slist");
1338 DEBUG(
"Invalid path depth");
1342 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
1353 static GtkTreePath *
1354 gnc_tree_model_split_reg_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
1361 GList *tnode, *snode;
1363 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
1368 path = gtk_tree_path_new();
1370 tnode = iter->user_data2;
1372 snode = iter->user_data3;
1375 tpos = g_list_position (model->priv->tlist, tnode);
1380 gtk_tree_path_append_index (path, tpos);
1383 if (IS_TROW2 (iter))
1384 gtk_tree_path_append_index (path, 0);
1387 if (IS_SPLIT (iter))
1390 if ((tnode == model->priv->bsplit_parent_node) && (IS_BLANK (iter)))
1404 gtk_tree_path_append_index (path, 0);
1405 gtk_tree_path_append_index (path, spos);
1409 gchar *path_string = gtk_tree_path_to_string (path);
1411 g_free (path_string);
1423 gnc_tree_model_split_reg_get_numact_vis (
GncTreeModelSplitReg *model, gboolean trow1, gboolean trow2)
1457 if (trans == model->priv->btrans)
1468 gnc_tree_model_split_reg_get_row_color (
GncTreeModelSplitReg *model, gboolean is_trow1, gboolean is_trow2, gboolean is_split, gint num)
1471 gchar *cell_color = NULL;
1481 if (is_trow1 || is_trow2)
1482 cell_color = (gchar*)GREENROW;
1486 if (is_trow1 || is_trow2)
1487 cell_color = (gchar*)TANROW;
1493 cell_color = (gchar*)GREENROW;
1495 cell_color = (gchar*)TANROW;
1503 cell_color = (gchar*)GREENROW;
1505 cell_color = (gchar*)TANROW;
1510 cell_color = (gchar*)TANROW;
1512 cell_color = (gchar*)GREENROW;
1516 cell_color = (gchar*)SPLITROW;
1519 cell_color = (gchar*)NULL;
1526 gnc_tree_model_split_reg_get_value (GtkTreeModel *tree_model,
1536 gint depth, *indices;
1538 g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model));
1542 tnode = (GList *) iter->user_data2;
1544 g_value_init (value, gnc_tree_model_split_reg_get_column_type (tree_model, column));
1548 case GNC_TREE_MODEL_SPLIT_REG_COL_GUID:
1550 g_value_set_pointer (value, (gpointer) guid);
1553 case GNC_TREE_MODEL_SPLIT_REG_COL_DATE:
1556 case GNC_TREE_MODEL_SPLIT_REG_COL_DUEDATE:
1559 case GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT:
1562 case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
1565 case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSFERVOID:
1568 case GNC_TREE_MODEL_SPLIT_REG_COL_RECN:
1571 case GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT:
1574 case GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT:
1577 case GNC_TREE_MODEL_SPLIT_REG_COL_RO:
1578 g_value_set_boolean (value, gnc_tree_model_split_reg_get_read_only (model, tnode->data));
1581 case GNC_TREE_MODEL_SPLIT_REG_COL_NUM_VIS:
1582 g_value_set_boolean (value, gnc_tree_model_split_reg_get_numact_vis (model, IS_TROW1(iter), IS_TROW2(iter)));
1585 case GNC_TREE_MODEL_SPLIT_REG_COL_ACT_VIS:
1586 g_value_set_boolean (value, !gnc_tree_model_split_reg_get_numact_vis (model, IS_TROW1(iter), IS_TROW2(iter)));
1590 g_assert_not_reached ();
1597 gnc_tree_model_split_reg_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
1605 GList *tnode = NULL, *snode = NULL;
1608 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), FALSE);
1610 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1612 if (IS_TROW2 (iter)) {
1613 LEAVE(
"Transaction row 2 never has a next");
1617 if (IS_TROW1 (iter)) {
1619 tnode = iter->user_data2;
1620 tnode = g_list_next (tnode);
1623 LEAVE(
"last trans has no next");
1630 if (tnode->data == model->priv->btrans)
1636 if (model->priv->bsplit_parent_node == tnode)
1637 snode = model->priv->bsplit_node;
1644 snode = g_list_find (slist, split);
1650 snode = g_list_find (slist, split);
1654 if (IS_SPLIT (iter)) {
1658 tnode = iter->user_data2;
1660 if (IS_BLANK (iter)) {
1661 LEAVE(
"Blank split never has a next");
1666 snode = iter->user_data3;
1671 snode = g_list_find (slist, split);
1674 if (tnode == model->priv->bsplit_parent_node) {
1675 snode = model->priv->bsplit_node;
1678 LEAVE(
"Last non-blank split has no next");
1684 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
1685 LEAVE(
"iter %s", iter_to_string (iter));
1694 gnc_tree_model_split_reg_iter_children (GtkTreeModel *tree_model,
1696 GtkTreeIter *parent_iter)
1702 GList *tnode = NULL, *snode = NULL;
1707 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
1708 ENTER(
"model %p, iter %p , parent %s",
1709 tree_model, iter, (parent_iter ? iter_to_string (parent_iter) :
"(null)"));
1714 tnode = g_list_first (model->priv->tlist);
1719 if (tnode->data == model->priv->btrans)
1725 if (model->priv->bsplit_parent_node == tnode)
1726 snode = model->priv->bsplit_node;
1733 snode = g_list_find (slist, split);
1739 snode = g_list_find (slist, split);
1742 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
1743 LEAVE(
"Parent iter NULL, First iter is %s", iter_to_string (iter));
1748 PERR(
"We should never have a NULL trans list.");
1755 if (IS_TROW1 (parent_iter))
1758 tnode = parent_iter->user_data2;
1761 if (tnode->data == model->priv->btrans)
1767 if (model->priv->bsplit_parent_node == tnode)
1768 snode = model->priv->bsplit_node;
1775 snode = g_list_find (slist, split);
1781 snode = g_list_find (slist, split);
1785 if (IS_TROW2 (parent_iter))
1787 tnode = parent_iter->user_data2;
1789 if ((tnode->data == model->priv->btrans) && (tnode != model->priv->bsplit_parent_node))
1791 else if ((tnode->data != model->priv->btrans) && (
xaccTransCountSplits (tnode->data) == 0) && (tnode != model->priv->bsplit_parent_node))
1796 tnode = parent_iter->user_data2;
1799 if (((tnode->data == model->priv->btrans) || (
xaccTransCountSplits (tnode->data) == 0)) && (tnode == model->priv->bsplit_parent_node))
1802 snode = model->priv->bsplit_node;
1807 snode = g_list_find (slist, split);
1812 if (IS_SPLIT (parent_iter))
1815 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
1816 LEAVE(
"First Child iter is %s", iter_to_string (iter));
1819 LEAVE(
"iter has no children");
1826 gnc_tree_model_split_reg_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
1832 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
1834 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1836 tnode = iter->user_data2;
1838 if (IS_TROW1 (iter))
1840 LEAVE (
"Transaction Row 1 is yes");
1844 if (IS_TROW2 (iter) && !(IS_BLANK (iter)))
1848 LEAVE (
"Transaction Row 2 is yes");
1853 if (tnode == model->priv->bsplit_parent_node)
1855 LEAVE (
"Transaction Row 2 is yes, blank split");
1861 if (IS_TROW2 (iter) && IS_BLANK (iter) && (tnode == model->priv->bsplit_parent_node))
1863 LEAVE (
"Blank Transaction Row 2 is yes");
1867 LEAVE (
"We have no child");
1873 gnc_tree_model_split_reg_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
1881 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
1882 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1885 i = g_list_length (model->priv->tlist);
1886 LEAVE (
"toplevel count is %d", i);
1890 if (IS_SPLIT (iter))
1893 if (IS_TROW1 (iter))
1896 if (IS_TROW2 (iter))
1898 tnode = iter->user_data2;
1900 if (tnode == model->priv->bsplit_parent_node)
1904 LEAVE (
"The number of children iter has is %d", i);
1910 gnc_tree_model_split_reg_iter_nth_child (GtkTreeModel *tree_model,
1912 GtkTreeIter *parent_iter,
1919 GList *tnode, *snode;
1922 ENTER(
"model %p, iter %s, n %d", tree_model, iter_to_string (parent_iter), n);
1923 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
1925 if (parent_iter == NULL) {
1927 tnode = g_list_nth (model->priv->tlist, n);
1930 PERR(
"Index greater than trans list.");
1937 if (tnode->data == model->priv->btrans)
1943 if (model->priv->bsplit_parent_node == tnode)
1944 snode = model->priv->bsplit_node;
1951 snode = g_list_find (slist, split);
1957 snode = g_list_find (slist, split);
1960 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
1961 LEAVE (
"iter (2) %s", iter_to_string (iter));
1967 if (IS_SPLIT (parent_iter))
1970 if (IS_TROW1 (parent_iter) && (n != 0))
1976 tnode = parent_iter->user_data2;
1978 if (IS_TROW1 (parent_iter) && IS_BLANK (parent_iter))
1989 if (tnode->data == model->priv->btrans)
1993 else if ((tnode == model->priv->bsplit_parent_node) && (
xaccTransCountSplits (tnode->data) == n))
1995 flags = SPLIT | BLANK;
1996 snode = model->priv->bsplit_node;
2003 snode = g_list_find (slist, split);
2007 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
2008 LEAVE(
"iter of child with index %u is %s", n, iter_to_string (iter));
2011 LEAVE(
"iter has no child with index %u", n);
2018 gnc_tree_model_split_reg_iter_parent (GtkTreeModel *tree_model,
2027 GList *tnode, *snode;
2030 ENTER(
"model %p, child %s", tree_model, iter_to_string (child));
2034 tnode = child->user_data2;
2035 snode = child->user_data3;
2037 if (IS_TROW1 (child))
2040 if (IS_TROW2 (child))
2043 if (IS_SPLIT (child))
2046 if (tnode->data == model->priv->btrans)
2049 *iter = gtm_sr_make_iter (model, flags, tnode, snode);
2050 LEAVE(
"parent iter is %s", iter_to_string (iter));
2053 LEAVE(
"we have no parent");
2065 while (model->
stamp == 0);
2071 gnc_tree_model_split_reg_get_split_and_trans (
2073 gboolean *is_trow1, gboolean *is_trow2, gboolean *is_split,
2081 *is_trow1 = !!IS_TROW1(iter);
2083 *is_trow2 = !!IS_TROW2(iter);
2085 *is_split = !!IS_SPLIT(iter);
2087 *is_blank = !!IS_BLANK(iter);
2091 node = iter->user_data2;
2092 *trans = node ? (
Transaction *) node->data : NULL;
2097 node = iter->user_data3;
2098 *split = node ? (
Split *) node->data : NULL;
2113 node = priv->bsplit_parent_node;
2118 if (trans == priv->bsplit_parent_node->data)
2132 gint tpos, spos, number;
2134 ENTER(
"transaction is %p, split is %p", trans, split);
2136 path = gtk_tree_path_new();
2138 number = gnc_tree_model_split_reg_iter_n_children (GTK_TREE_MODEL (model), NULL) - 1;
2140 if (trans == NULL && split == NULL)
2145 tpos = g_list_index (model->priv->tlist, model->priv->btrans);
2148 gtk_tree_path_append_index (path, tpos);
2150 path_string = gtk_tree_path_to_string (path);
2151 LEAVE(
"path is %s", path_string);
2152 g_free (path_string);
2156 if (trans == NULL && split != NULL)
2158 if (split == model->priv->bsplit)
2159 trans = model->priv->bsplit_parent_node->data;
2167 tpos = g_list_index (model->priv->tlist, trans);
2170 gtk_tree_path_append_index (path, tpos);
2180 if (model->priv->bsplit == split)
2185 gtk_tree_path_append_index (path, 0);
2187 gtk_tree_path_append_index (path, spos);
2191 gchar *path_string = gtk_tree_path_to_string (path);
2192 LEAVE(
"path is %s", path_string);
2193 g_free (path_string);
2199 #define get_iter gnc_tree_model_split_reg_get_iter_from_trans_and_split
2201 gnc_tree_model_split_reg_get_iter_from_trans_and_split (
2203 GtkTreeIter *iter1, GtkTreeIter *iter2)
2206 GList *tnode, *snode = NULL;
2207 gint flags1 = TROW1;
2208 gint flags2 = TROW2;
2210 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), FALSE);
2211 g_return_val_if_fail (iter1, FALSE);
2212 g_return_val_if_fail (iter2, FALSE);
2213 PINFO(
"get_iter model %p, trans %p, split %p\n", model, trans, split);
2216 if (split && !trans)
2221 if (split && !xaccTransStillHasSplit (trans, split))
return FALSE;
2223 tnode = g_list_find (priv->tlist, trans);
2224 if (!tnode)
return FALSE;
2226 if (trans == priv->btrans)
2235 snode = g_list_find (slist, split);
2237 if (!snode && split == (
Split *) ((GList *)priv->bsplit_node)->data)
2239 snode = priv->bsplit_node;
2242 if (!snode)
return FALSE;
2245 *iter1 = gtm_sr_make_iter (model, flags1, tnode, snode);
2246 *iter2 = gtm_sr_make_iter (model, flags2, tnode, snode);
2256 return model->priv->bsplit;
2264 return model->priv->btrans;
2270 gnc_tree_model_split_reg_sort_iter_compare_func (GtkTreeModel *tm,
2280 return gtk_tree_path_compare (gnc_tree_model_split_reg_get_path (tm, a),
2281 gnc_tree_model_split_reg_get_path (tm, b));
2283 return gtk_tree_path_compare (gnc_tree_model_split_reg_get_path (tm, b),
2284 gnc_tree_model_split_reg_get_path (tm, a));
2297 if (gtk_tree_path_up (path) && gnc_tree_model_split_reg_get_iter (GTK_TREE_MODEL (model), &iter, path))
2299 gchar *path_string = gtk_tree_path_to_string (path);
2300 PINFO(
"row_changed - '%s'", path_string);
2301 g_free (path_string);
2303 gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
2305 tnode = iter.user_data2;
2308 if (IS_BLANK_TRANS (&iter) && (tnode->data == model->priv->btrans) && (
xaccTransCountSplits (model->priv->btrans) == 0))
2311 path_string = gtk_tree_path_to_string (path);
2312 PINFO(
"toggling has_child at row '%s'", path_string);
2313 g_free (path_string);
2314 gtm_sr_increment_stamp (model);
2315 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter);
2330 path = gnc_tree_model_split_reg_get_path (GTK_TREE_MODEL (model), iter);
2334 gtm_sr_increment_stamp (model);
2335 if (gnc_tree_model_split_reg_get_iter (GTK_TREE_MODEL (model), iter, path))
2337 gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, iter);
2340 PERR(
"Tried to insert with invalid iter.");
2342 gtm_sr_update_parent (model, path);
2343 gtk_tree_path_free (path);
2359 gtm_sr_increment_stamp (model);
2360 gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
2362 depth = gtk_tree_path_get_depth (path);
2366 gtm_sr_update_parent (model, path);
2368 else if (depth == 3)
2370 gtm_sr_update_parent (model, path);
2375 if (gnc_tree_model_split_reg_get_iter (GTK_TREE_MODEL (model), &iter, path))
2377 GList *tnode = iter.user_data2;
2379 if (tnode == priv->bsplit_parent_node)
2380 priv->bsplit_parent_node = NULL;
2395 path = gnc_tree_model_split_reg_get_path (GTK_TREE_MODEL (model), iter);
2396 gtm_sr_delete_row_at_path (model, path);
2397 gtk_tree_path_free (path);
2410 path = gnc_tree_model_split_reg_get_path (GTK_TREE_MODEL (model), iter);
2414 gtm_sr_increment_stamp (model);
2415 if (gnc_tree_model_split_reg_get_iter (GTK_TREE_MODEL (model), iter, path))
2417 gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, iter);
2420 PERR (
"Tried to change with invalid iter.");
2422 gtk_tree_path_free (path);
2433 GList *tnode = NULL, *snode = NULL;
2435 ENTER(
"insert transaction %p into model %p", trans, model);
2437 model->priv->tlist = g_list_prepend (model->priv->tlist, trans);
2439 model->priv->tlist = g_list_append (model->priv->tlist, trans);
2440 tnode = g_list_find (model->priv->tlist, trans);
2442 iter = gtm_sr_make_iter (model, TROW1, tnode, NULL);
2443 gtm_sr_insert_row_at (model, &iter);
2445 iter = gtm_sr_make_iter (model, TROW2, tnode, NULL);
2446 gtm_sr_insert_row_at (model, &iter);
2447 path = gnc_tree_model_split_reg_get_path (GTK_TREE_MODEL (model), &iter);
2449 gtk_tree_path_up (path);
2450 gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
2451 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter);
2457 if (xaccTransStillHasSplit (trans, snode->data))
2459 iter = gtm_sr_make_iter (model, SPLIT, tnode, snode);
2460 gtm_sr_insert_row_at (model, &iter);
2463 gtk_tree_path_down (path);
2464 gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
2465 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter);
2466 gtk_tree_path_free (path);
2477 GList *tnode = NULL, *snode = NULL;
2479 ENTER(
"delete trans %p", trans);
2480 tnode = g_list_find (model->priv->tlist, trans);
2484 if (tnode == model->priv->bsplit_parent_node)
2487 iter = gtm_sr_make_iter (model, SPLIT | BLANK, tnode, model->priv->bsplit_node);
2488 gtm_sr_delete_row_at (model, &iter);
2489 model->priv->bsplit_parent_node = NULL;
2494 if (xaccTransStillHasSplit (trans, snode->data))
2496 iter = gtm_sr_make_iter (model, SPLIT, tnode, snode);
2497 gtm_sr_delete_row_at (model, &iter);
2501 iter = gtm_sr_make_iter (model, TROW2, tnode, NULL);
2502 gtm_sr_delete_row_at (model, &iter);
2504 iter = gtm_sr_make_iter (model, TROW1, tnode, NULL);
2505 gtm_sr_delete_row_at (model, &iter);
2507 model->priv->tlist = g_list_delete_link (model->priv->tlist, tnode);
2516 GList *tnode, *bs_parent_node;
2524 tnode = g_list_last (priv->tlist);
2526 tnode = g_list_find (priv->tlist, trans);
2528 ENTER(
"set blank split %p parent to trans %p and remove_only is %d", priv->bsplit, trans, remove_only);
2530 bs_parent_node = priv->bsplit_parent_node;
2532 if (tnode != bs_parent_node || remove_only == TRUE)
2534 moved = (bs_parent_node != NULL || remove_only == TRUE);
2538 iter = gtm_sr_make_iter (model, SPLIT | BLANK, bs_parent_node, priv->bsplit_node);
2539 gtm_sr_delete_row_at (model, &iter);
2540 priv->bsplit_parent_node = NULL;
2543 if (remove_only == FALSE)
2546 priv->bsplit_parent_node = tnode;
2547 iter = gtm_sr_make_iter (model, SPLIT | BLANK, tnode, priv->bsplit_node);
2548 gtm_sr_insert_row_at (model, &iter);
2549 xaccSplitReinit (priv->bsplit);
2566 GList *tnode = model->priv->bsplit_parent_node;
2571 model->priv->bsplit = split;
2572 model->priv->bsplit_node->data = model->priv->bsplit;
2574 DEBUG(
"make new blank split %p and insert at trans %p", split, tnode->data);
2577 iter = gtm_sr_make_iter (model, BLANK|SPLIT, tnode, model->priv->bsplit_node);
2578 gtm_sr_insert_row_at (model, &iter);
2592 GList *tnode, *snode;
2597 tnode = model->priv->bsplit_parent_node;
2598 bsplit = model->priv->bsplit;
2600 if (!tnode || !tnode->data) {
2601 LEAVE(
"blank split has no trans");
2606 LEAVE(
"blank split has been removed from this trans");
2612 LEAVE(
"Failed to turn blank split into real split");
2632 rate = xaccTransGetAccountConvRate (tnode->data, acct);
2642 iter = gtm_sr_make_iter (model, SPLIT, tnode, snode);
2643 gtm_sr_changed_row_at (model, &iter);
2644 gtm_sr_make_new_blank_split (model);
2652 gnc_tree_model_split_reg_set_display (
GncTreeModelSplitReg *model, gboolean subacc, gboolean gl)
2656 priv->display_subacc = subacc;
2657 priv->display_gl = gl;
2662 static GtkTreePath *
2667 GList *tnode = NULL;
2671 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
2672 g_return_val_if_fail (trans, NULL);
2678 tnode = g_list_find (priv->tlist, trans);
2682 iter = gtm_sr_make_iter (model, TROW1, tnode, NULL);
2683 path = gnc_tree_model_split_reg_get_path (GTK_TREE_MODEL (model), &iter);
2685 if (idx_of_split >= 0)
2687 gtk_tree_path_append_index (path, 0);
2688 gtk_tree_path_append_index (path, idx_of_split);
2690 else if (idx_of_split != -1)
2691 PERR(
"Invalid idx_of_split");
2703 g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model), NULL);
2704 return model->priv->anchor;
2710 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
2711 return model->priv->description_list;
2717 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
2718 return model->priv->notes_list;
2724 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
2725 return model->priv->memo_list;
2731 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
2732 return model->priv->action_list;
2738 g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
2739 return model->priv->account_list;
2746 gtm_sr_check_for_duplicates (GtkListStore *liststore,
const gchar *
string)
2751 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
2756 gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, 0, &text, -1);
2758 if(!(g_strcmp0 (text,
string)))
2765 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter);
2776 GtkTreeIter d_iter, n_iter, m_iter;
2777 GList *tlist_cpy, *tnode, *slist, *snode;
2785 tlist_cpy = g_list_copy (priv->tlist);
2786 tlist_cpy = g_list_sort (tlist_cpy, (GCompareFunc)
xaccTransOrder );
2787 tlist_cpy = g_list_reverse (tlist_cpy);
2790 gtk_list_store_clear (priv->description_list);
2791 gtk_list_store_clear (priv->notes_list);
2792 gtk_list_store_clear (priv->memo_list);
2794 for (tnode = tlist_cpy; tnode; tnode = tnode->next)
2797 const gchar *string;
2804 if (g_strcmp0 (
string,
""))
2806 if (gtm_sr_check_for_duplicates (priv->description_list,
string) == FALSE)
2808 gtk_list_store_append (priv->description_list, &d_iter);
2809 gtk_list_store_set (priv->description_list, &d_iter, 0,
string, 1, tnode->data, -1);
2815 if (g_strcmp0 (
string,
""))
2817 if (gtm_sr_check_for_duplicates (priv->notes_list,
string) == FALSE)
2819 gtk_list_store_append (priv->notes_list, &n_iter);
2820 gtk_list_store_set (priv->notes_list, &n_iter, 0,
string, -1);
2827 while (cnt < nSplits)
2829 split = snode->data;
2833 if (g_strcmp0 (
string,
""))
2835 if (gtm_sr_check_for_duplicates (priv->memo_list,
string) == FALSE)
2837 gtk_list_store_append (priv->memo_list, &m_iter);
2838 gtk_list_store_set (priv->memo_list, &m_iter, 0,
string, -1);
2842 snode = snode->next;
2846 g_list_free (tlist_cpy);
2847 PINFO(
"desc list is %d long", gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->description_list), NULL));
2848 PINFO(
"notes list is %d long", gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->notes_list), NULL));
2849 PINFO(
"memo list is %d long", gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->memo_list), NULL));
2859 GtkListStore *store;
2863 store = priv->action_list;
2868 gtk_list_store_clear (store);
2871 switch (model->
type)
2873 case BANK_REGISTER2:
2875 case SEARCH_LEDGER2:
2879 gtk_list_store_insert_with_values (store, &iter, 100, 0, Q_(
"Action Column|Deposit"), -1);
2880 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Withdraw"), -1);
2881 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Check"), -1);
2882 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Interest"), -1);
2883 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"ATM Deposit"), -1);
2884 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"ATM Draw"), -1);
2885 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Teller"), -1);
2886 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Charge"), -1);
2887 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Payment"), -1);
2888 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Receipt"), -1);
2889 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Increase"), -1);
2890 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Decrease"), -1);
2892 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"POS"), -1);
2893 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Phone"), -1);
2894 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Online"), -1);
2896 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"AutoDep"), -1);
2897 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Wire"), -1);
2898 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Credit"), -1);
2899 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Direct Debit"), -1);
2900 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Transfer"), -1);
2902 case CASH_REGISTER2:
2903 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Increase"), -1);
2904 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Decrease"), -1);
2905 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2906 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2908 case ASSET_REGISTER2:
2909 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2910 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2911 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Fee"), -1);
2913 case CREDIT_REGISTER2:
2914 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"ATM Deposit"), -1);
2915 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"ATM Withdraw"), -1);
2916 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2917 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Credit"), -1);
2918 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Fee"), -1);
2919 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Interest"), -1);
2920 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Online"), -1);
2921 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2923 case LIABILITY_REGISTER2:
2924 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2925 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2926 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Loan"), -1);
2927 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Interest"), -1);
2928 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Payment"), -1);
2930 case RECEIVABLE_REGISTER2:
2931 case PAYABLE_REGISTER2:
2932 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Invoice"), -1);
2933 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Payment"), -1);
2934 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Interest"), -1);
2935 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Credit"), -1);
2937 case INCOME_LEDGER2:
2938 case INCOME_REGISTER2:
2939 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Increase"), -1);
2940 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Decrease"), -1);
2941 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2942 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2943 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Interest"), -1);
2944 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Payment"), -1);
2945 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Rebate"), -1);
2946 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Paycheck"), -1);
2948 case EXPENSE_REGISTER2:
2949 case TRADING_REGISTER2:
2950 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Increase"), -1);
2951 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Decrease"), -1);
2952 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2953 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2955 case GENERAL_LEDGER2:
2956 case EQUITY_REGISTER2:
2957 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2958 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2959 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Equity"), -1);
2961 case STOCK_REGISTER2:
2962 case PORTFOLIO_LEDGER2:
2963 case CURRENCY_REGISTER2:
2964 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2965 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2966 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Price"), -1);
2967 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Fee"), -1);
2969 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Dividend"), -1);
2970 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Interest"), -1);
2972 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"LTCG"), -1);
2974 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"STCG"), -1);
2975 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Income"), -1);
2977 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Dist"), -1);
2979 gtk_list_store_insert_with_values (store, &iter, 100, 0, Q_(
"Action Column|Split"), -1);
2983 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Increase"), -1);
2984 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Decrease"), -1);
2985 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Buy"), -1);
2986 gtk_list_store_insert_with_values (store, &iter, 100, 0, _(
"Sell"), -1);
2989 priv->action_list = store;
2993 gtm_sr_account_order_by_name (
const Account *aa,
const Account *ab)
2995 const char *na, *nb;
3001 retval = g_utf8_collate (na, nb);
3009 gtm_sr_account_order_by_full_name (
const Account *aa,
const Account *ab)
3017 retval = g_utf8_collate (fna, fnb);
3036 GList *accts, *accts_cpy, *ptr;
3045 gtk_list_store_clear (priv->account_list);
3047 root = gnc_book_get_root_account (priv->book);
3053 accts_cpy = g_list_copy (accts);
3055 if (
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
3056 accts_cpy = g_list_sort (accts_cpy, (GCompareFunc)gtm_sr_account_order_by_name);
3058 accts_cpy = g_list_sort (accts_cpy, (GCompareFunc)gtm_sr_account_order_by_full_name);
3060 for (ptr = accts_cpy, i = 0; ptr; ptr = g_list_next (ptr), i++)
3064 if(!(acc == model->priv->anchor))
3068 gtk_list_store_append (priv->account_list, &iter);
3069 gtk_list_store_set (priv->account_list, &iter, 0, name, 1, fname, 2, acc, -1);
3073 g_list_free (accts);
3074 g_list_free (accts_cpy);
3080 gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor (
const Transaction *trans,
const Account *ancestor)
3086 Split *split = node->data;
3089 if (!xaccTransStillHasSplit (trans, split))
3092 if (ancestor == split_acc)
3135 gnc_tree_model_split_reg_event_handler (
QofInstance *entity,
3142 GtkTreeIter iter1, iter2;
3145 Split *split = NULL;
3147 const gchar *name = NULL;
3150 g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model));
3156 if (g_strcmp0 (type, GNC_ID_SPLIT) == 0)
3159 split = (
Split *) entity;
3164 case QOF_EVENT_MODIFY:
3165 if (get_iter (model, NULL, split, &iter1, &iter2))
3167 DEBUG (
"change split %p (%s)", split, name);
3168 gtm_sr_changed_row_at (model, &iter1);
3171 if (priv->anchor != NULL)
3176 if (priv->display_subacc)
3177 find_split = gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor (trans, priv->anchor);
3179 find_split = xaccTransFindSplitByAccount (trans, priv->anchor);
3181 if (find_split == NULL)
3183 g_signal_emit_by_name (model,
"selection_move_delete", trans);
3184 gtm_sr_delete_trans (model, trans);
3190 DEBUG (
"ignored event for %p (%s)", split, name);
3193 else if (g_strcmp0 (type, GNC_ID_TRANS) == 0)
3202 split = (
Split *) ed->node;
3207 if (split == priv->bsplit)
break;
3212 if (get_iter (model, trans, split, &iter1, &iter2))
3214 DEBUG (
"add split %p (%s)", split, name);
3215 gtm_sr_insert_row_at (model, &iter1);
3218 case GNC_EVENT_ITEM_REMOVED:
3219 split = (
Split *) ed->node;
3221 path = gtm_sr_get_removal_path (model, trans, ed->idx);
3224 DEBUG (
"remove split %p from trans %p (%s)", split, trans, name);
3226 gtm_sr_delete_trans (model, trans);
3228 gtm_sr_delete_row_at_path (model, path);
3229 gtk_tree_path_free (path);
3231 if (split == priv->bsplit)
3232 gtm_sr_make_new_blank_split (model);
3234 case QOF_EVENT_MODIFY:
3236 if (priv->btrans == trans)
3239 priv->tlist = g_list_append (priv->tlist, priv->btrans);
3241 tnode = g_list_find (priv->tlist, priv->btrans);
3243 iter1 = gtm_sr_make_iter (model, TROW1 | BLANK, tnode, NULL);
3244 gtm_sr_insert_row_at (model, &iter1);
3245 iter2 = gtm_sr_make_iter (model, TROW2 | BLANK, tnode, NULL);
3246 gtm_sr_insert_row_at (model, &iter2);
3247 g_signal_emit_by_name (model,
"refresh_trans", priv->btrans);
3250 if (get_iter (model, trans, NULL, &iter1, &iter2))
3252 DEBUG (
"change trans %p (%s)", trans, name);
3253 gtm_sr_changed_row_at (model, &iter1);
3254 gtm_sr_changed_row_at (model, &iter2);
3255 g_signal_emit_by_name (model,
"refresh_trans", trans);
3258 case QOF_EVENT_DESTROY:
3259 if (priv->btrans == trans)
3261 tnode = g_list_find (priv->tlist, priv->btrans);
3263 tnode->data = priv->btrans;
3264 iter1 = gtm_sr_make_iter (model, TROW1 | BLANK, tnode, NULL);
3265 gtm_sr_changed_row_at (model, &iter1);
3266 iter2 = gtm_sr_make_iter (model, TROW2 | BLANK, tnode, NULL);
3267 gtm_sr_changed_row_at (model, &iter2);
3269 else if (get_iter (model, trans, NULL, &iter1, &iter2))
3271 DEBUG(
"destroy trans %p (%s)", trans, name);
3272 g_signal_emit_by_name (model,
"selection_move_delete", trans);
3273 gtm_sr_delete_trans (model, trans);
3274 g_signal_emit_by_name (model,
"refresh_trans", trans);
3278 DEBUG(
"ignored event for %p (%s)", trans, name);
3281 else if (g_strcmp0 (type, GNC_ID_ACCOUNT) == 0)
3287 split = (
Split *) ed;
3291 if (!g_list_find (priv->tlist, trans) && priv->display_gl)
3297 DEBUG(
"Insert trans %p for gl (%s)", trans, name);
3298 gtm_sr_insert_trans (model, trans, TRUE);
3299 g_signal_emit_by_name (model,
"refresh_trans", trans);
3302 else if (!g_list_find (priv->tlist, trans) && ((
xaccAccountHasAncestor (acc, priv->anchor) && priv->display_subacc) || acc == priv->anchor ))
3304 DEBUG(
"Insert trans %p (%s)", trans, name);
3305 gtm_sr_insert_trans (model, trans, TRUE);
3306 g_signal_emit_by_name (model,
"refresh_trans", trans);
3313 g_signal_emit_by_name (model,
"refresh_status_bar", NULL);
3323 GtkWidget *parent = NULL;
3327 if (priv->get_parent)
3328 parent = priv->get_parent (priv->user_data);
void xaccSplitSetValue(Split *s, gnc_numeric amt)
gint number_of_trans_in_full_tlist
gint position_of_trans_in_full_tlist
Transaction * xaccMallocTransaction(QofBook *book)
Split * xaccTransGetSplit(const Transaction *trans, int i)
const char * gnc_print_date(Timespec ts)
gboolean xaccTransIsReadonlyByPostedDate(const Transaction *trans)
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
QofBook * qof_instance_get_book(gconstpointer)
utility functions for the GnuCash UI
#define PINFO(format, args...)
void qof_query_set_sort_order(QofQuery *q, QofQueryParamList *primary_sort_params, QofQueryParamList *secondary_sort_params, QofQueryParamList *tertiary_sort_params)
gboolean use_theme_colors
int xaccAccountGetCommoditySCU(const Account *acc)
gnc_numeric gnc_numeric_neg(gnc_numeric a)
#define DEBUG(format, args...)
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
void(* QofEventHandler)(QofInstance *ent, QofEventId event_type, gpointer handler_data, gpointer event_data)
Handler invoked when an event is generated.
Use a 64-bit unsigned int timespec.
GtkSortType sort_direction
gboolean gnc_numeric_zero_p(gnc_numeric a)
Transaction * xaccSplitGetParent(const Split *split)
gboolean separator_changed
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
#define PERR(format, args...)
QofBook * xaccSplitGetBook(const Split *split)
#define ENTER(format, args...)
gboolean alt_colors_by_txn
gint qof_event_register_handler(QofEventHandler handler, gpointer handler_data)
Register a handler for events.
Transaction * current_trans
const char * xaccTransGetNotes(const Transaction *trans)
int xaccTransCountSplits(const Transaction *trans)
#define xaccAccountGetGUID(X)
convert single-entry accounts to clean double-entry
gboolean xaccTransHasSplitsInState(const Transaction *trans, const char state)
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
gchar * gnc_account_get_full_name(const Account *account)
gboolean use_accounting_labels
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
SplitRegisterStyle2 style
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
const char * xaccTransGetDescription(const Transaction *trans)
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
#define xaccTransGetBook(X)
Additional event handling code.
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
All type declarations for the whole Gnucash engine.
const GncGUID * qof_entity_get_guid(gconstpointer)
Split * xaccMallocSplit(QofBook *book)
Generic api to store and retrieve preferences.
GList * gnc_account_get_descendants(const Account *account)
void gnc_tm_get_today_start(struct tm *tm)
gboolean qof_book_is_readonly(const QofBook *book)
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor)
Account * xaccSplitGetAccount(const Split *s)
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
#define LEAVE(format, args...)
#define QUERY_DEFAULT_SORT
int xaccTransOrder(const Transaction *ta, const Transaction *tb)
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
const char * xaccSplitGetMemo(const Split *split)
gboolean qof_book_uses_autoreadonly(const QofBook *book)
const char * xaccAccountGetName(const Account *acc)
#define GNC_EVENT_ITEM_ADDED
API for Transactions and Splits (journal entries)
SplitList * xaccTransGetSplitList(const Transaction *trans)
Commodity handling public routines.
void xaccTransGetDatePostedTS(const Transaction *trans, Timespec *ts)
const gchar * QofLogModule
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
gnc_numeric xaccSplitGetAmount(const Split *split)
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)