30 #include <glib/gi18n.h>
34 #include "gnc-tree-control-split-reg.h"
35 #include "gnc-tree-model-split-reg.h"
36 #include "gnc-tree-util-split-reg.h"
37 #include "gnc-tree-view-split-reg.h"
38 #include "gnc-component-manager.h"
42 #include "gnome-utils/gnc-warnings.h"
43 #include "dialog-utils.h"
44 #include "dialog-dup-trans.h"
48 #include "engine-helpers.h"
66 const gchar *title = _(
"Cannot modify or delete this transaction.");
67 const gchar *message_reason =
68 _(
"This transaction is marked read-only with the comment: '%s'");
70 if (!trans)
return FALSE;
72 window = gnc_tree_view_split_reg_get_parent (view);
73 model = gnc_tree_view_split_reg_get_model_from_view (view);
77 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
82 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
83 "%s", _(
"The date of this transaction is older than the \"Read-Only Threshold\" set for this book. "
84 "This setting can be changed in File -> Properties -> Accounts."));
85 gtk_dialog_run (GTK_DIALOG (dialog));
86 gtk_widget_destroy (dialog);
93 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
98 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
99 message_reason, reason);
100 gtk_dialog_run (GTK_DIALOG (dialog));
101 gtk_widget_destroy (dialog);
105 if (gnc_tree_model_split_reg_get_read_only (model, trans))
107 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
112 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
113 "%s", _(
"You can not change this transaction, the Book or Register is set to Read Only."));
114 gtk_dialog_run (GTK_DIALOG (dialog));
115 gtk_widget_destroy (dialog);
123 #define gtc_sr_trans_open_and_warn gnc_tree_control_split_reg_trans_open_and_warn
131 const char *title = _(
"Save Transaction before proceeding?");
132 const char *message =
133 _(
"The current transaction has been changed. Would you like to "
134 "record the changes before proceeding, or cancel?");
136 window = gnc_tree_view_split_reg_get_parent (view);
137 dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
139 if (trans == dirty_trans)
141 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
142 GTK_DIALOG_DESTROY_WITH_PARENT,
143 GTK_MESSAGE_QUESTION,
146 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
148 gtk_dialog_add_button (GTK_DIALOG (dialog),
149 _(
"_Record"), GTK_RESPONSE_ACCEPT);
150 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_MOD);
151 gtk_widget_destroy (dialog);
153 if (response != GTK_RESPONSE_ACCEPT)
157 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
166 #define gtc_sr_trans_test_for_edit gnc_tree_control_split_reg_trans_test_for_edit
174 gnc_tree_view_split_reg_finish_edit (view);
176 window = gnc_tree_view_split_reg_get_parent (view);
179 dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
184 gnc_error_dialog (window,
"%s",
185 _(
"This transaction is being edited in a different register."));
204 GList *radio_list = NULL;
205 const char *title = _(
"Rebalance Transaction");
206 const char *message = _(
"The current transaction is not balanced.");
209 gboolean two_accounts;
210 gboolean multi_currency;
216 window = gnc_tree_view_split_reg_get_parent (view);
217 model = gnc_tree_view_split_reg_get_model_from_view (view);
221 MonetaryList *imbal_list;
230 multi_currency = TRUE;
233 imbal_mon = imbal_list->data;
234 if (!imbal_list->next &&
237 multi_currency = FALSE;
239 multi_currency = TRUE;
247 multi_currency = FALSE;
252 if (other_split == NULL)
259 if (other_split == NULL || multi_currency)
261 two_accounts = FALSE;
262 other_account = NULL;
270 default_account = gnc_tree_model_split_reg_get_anchor (model);
276 if (default_account == other_account)
283 if (default_account == other_account)
284 two_accounts = FALSE;
286 radio_list = g_list_append (radio_list,
287 _(
"Balance it _manually"));
288 radio_list = g_list_append (radio_list,
289 _(
"Let GnuCash _add an adjusting split"));
291 if (model->
type < NUM_SINGLE_REGISTER_TYPES2 && !multi_currency)
293 radio_list = g_list_append (radio_list,
294 _(
"Adjust current account _split total"));
299 radio_list = g_list_append (radio_list,
300 _(
"Adjust _other account split total"));
307 choice = gnc_choose_radio_option_dialog
315 g_list_free (radio_list);
346 gnc_tree_view_split_reg_finish_edit (view);
348 gnc_tree_view_split_reg_cancel_edit (view, reg_closing);
361 Split *osplit = NULL;
369 model = gnc_tree_view_split_reg_get_model_from_view (view);
371 trans = gnc_tree_view_split_reg_get_current_trans (view);
372 expanded = gnc_tree_view_split_reg_trans_expanded (view, NULL);
373 depth = gnc_tree_view_reg_get_selected_row_depth (view);
375 anchor = gnc_tree_model_split_reg_get_anchor (model);
382 if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
386 if (gtc_sr_is_trans_readonly_and_warn (view, trans))
390 if (gtc_sr_trans_test_for_edit (view, trans))
394 if (gtc_sr_trans_open_and_warn (view, trans))
400 window = gnc_tree_view_split_reg_get_parent (view);
403 if (!gnc_tree_util_split_reg_has_rate (view))
405 message = _(
"This register does not support editing exchange rates.");
406 gnc_error_dialog(window,
"%s", message);
413 message = _(
"This register does not support editing exchange rates.");
414 gnc_error_dialog (window,
"%s", message);
419 if ((gnc_tree_util_split_reg_is_multi (
xaccTransGetSplit (trans, 0))) && !expanded)
421 message = _(
"You need to expand the transaction in order to modify its "
423 gnc_error_dialog (window,
"%s", message);
427 if (!gnc_tree_util_split_reg_is_multi (
xaccTransGetSplit (trans, 0)) && anchor != NULL && !expanded)
429 split = gnc_tree_control_split_reg_get_current_trans_split (view);
438 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
442 gnc_tree_util_split_reg_set_value_for (view, trans, osplit,
gnc_numeric_neg (value), TRUE);
444 gnc_tree_util_split_reg_set_value_for (view, trans, split, value, TRUE);
447 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
450 if (num_splits > 1 && expanded && depth == 3)
452 split = gnc_tree_view_split_reg_get_current_split (view);
461 message = _(
"The two currencies involved equal each other.");
462 gnc_error_dialog (window,
"%s", message);
467 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
470 gnc_tree_util_split_reg_set_value_for (view, trans, split, value, TRUE);
473 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
481 gnc_tree_control_split_reg_void_current_trans (
GncTreeViewSplitReg *view,
const char *reason)
489 blank_split = gnc_tree_control_split_reg_get_blank_split (view);
492 split = gnc_tree_view_split_reg_get_current_split (view);
497 if (split == blank_split)
510 if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
514 if (gtc_sr_is_trans_readonly_and_warn (view, trans))
518 if (gtc_sr_trans_test_for_edit (view, trans))
522 if (gtc_sr_trans_open_and_warn (view, trans))
525 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
531 PERR(
"We should not be voiding an open transaction.");
534 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
548 blank_split = gnc_tree_control_split_reg_get_blank_split (view);
551 split = gnc_tree_view_split_reg_get_current_split (view);
556 if (split == blank_split)
569 if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
572 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
576 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
585 GtkTreePath *mpath, *spath;
588 model = gnc_tree_view_split_reg_get_model_from_view (view);
590 btrans = gnc_tree_model_split_get_blank_trans (model);
594 if (!gnc_tree_model_split_reg_trans_is_in_view (model, btrans))
595 g_signal_emit_by_name (model,
"refresh_trans");
598 mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, NULL, btrans);
600 spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
603 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, NULL, FALSE);
605 gtk_tree_path_free (spath);
606 gtk_tree_path_free (mpath);
609 g_idle_add ((GSourceFunc)gnc_tree_view_split_reg_scroll_to_cell, view );
620 GtkTreePath *mpath, *spath;
622 model = gnc_tree_view_split_reg_get_model_from_view (view);
627 mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, split, trans);
629 spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
637 GtkCellRenderer *cr0;
643 columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
645 for (column = columns, i = 1; column; column = g_list_next (column), i++)
647 GtkTreeViewColumn *tvc;
653 renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tvc));
654 cr0 = g_list_nth_data (renderers, 0);
655 g_list_free (renderers);
657 viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cr0),
"view_column"));
660 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, tvc, TRUE);
663 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, tvc, TRUE);
665 g_list_free (columns);
668 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, NULL, FALSE);
671 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), spath, NULL, TRUE, 0.5, 0.0);
673 gtk_tree_path_free (spath);
674 gtk_tree_path_free (mpath);
684 model = gnc_tree_view_split_reg_get_model_from_view (view);
686 return gnc_tree_model_split_get_blank_trans (model);
700 gboolean is_trow1, is_trow2, is_split, is_blank;
702 model = gnc_tree_view_split_reg_get_model_from_view (view);
704 mpath = gnc_tree_view_split_reg_get_current_path (view);
706 gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath);
708 gnc_tree_model_split_reg_get_split_and_trans (
709 GNC_TREE_MODEL_SPLIT_REG (model), &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
711 anchor = gnc_tree_model_split_reg_get_anchor (model);
713 split = gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor (trans, anchor);
715 gtk_tree_path_free (mpath);
727 model = gnc_tree_view_split_reg_get_model_from_view (view);
729 return gnc_tree_model_split_get_blank_split (model);
738 GtkTreePath *mpath, *spath;
739 GtkTreePath *new_mpath, *new_spath;
740 gint *indices, sort_direction;
743 ENTER(
"Move relative, view is %p, relative is %d", view, relative);
747 model = gnc_tree_view_split_reg_get_model_from_view (view);
749 mpath = gnc_tree_view_split_reg_get_current_path (view);
751 spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
753 indices = gtk_tree_path_get_indices (spath);
760 new_spath = gtk_tree_path_new_from_indices (indices[0] + (relative * sort_direction), -1);
763 gnc_tree_view_split_reg_block_selection (view, TRUE);
764 gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), spath);
767 gnc_tree_view_split_reg_block_selection (view, FALSE);
770 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), new_spath, NULL, FALSE);
774 gnc_tree_view_split_reg_block_selection (view, FALSE);
777 new_mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, new_spath);
780 gnc_tree_view_split_reg_set_current_path (view, new_mpath);
781 gtk_tree_path_free (new_mpath);
784 sstring = gtk_tree_path_to_string (new_spath);
785 LEAVE(
"new_spath is %s", sstring);
788 gtk_tree_path_free (new_spath);
789 gtk_tree_path_free (mpath);
790 gtk_tree_path_free (spath);
800 gboolean goto_blank = FALSE;
801 gboolean next_trans = TRUE;
803 model = gnc_tree_view_split_reg_get_model_from_view (view);
806 GNC_PREF_ENTER_MOVES_TO_END);
808 ENTER(
"view=%p, goto_blank = %s", view, goto_blank ?
"TRUE" :
"FALSE");
810 btrans = gnc_tree_model_split_get_blank_trans (model);
812 ctrans = gnc_tree_view_split_reg_get_current_trans (view);
815 if (btrans == ctrans)
819 if (gnc_tree_view_split_reg_enter (view))
823 gnc_tree_control_split_reg_jump_to_blank (view);
825 gnc_tree_control_split_reg_goto_rel_trans_row (view, 1);
837 GtkWidget *dialog, *window;
839 const gchar *warning;
841 const char *title = _(
"Remove the splits from this transaction?");
842 const char *recn_warn = _(
"This transaction contains reconciled splits. "
843 "Modifying it is not a good idea because that will "
844 "cause your reconciled balance to be off.");
846 trans = gnc_tree_view_split_reg_get_current_trans (view);
852 if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
856 if (gtc_sr_is_trans_readonly_and_warn (view, trans))
860 if (gtc_sr_trans_test_for_edit (view, trans))
864 if (gtc_sr_trans_open_and_warn (view, trans))
867 window = gnc_tree_view_split_reg_get_parent (view);
869 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
870 GTK_DIALOG_DESTROY_WITH_PARENT,
877 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
879 warning = GNC_PREF_WARN_REG_SPLIT_DEL_ALL_RECD;
883 warning = GNC_PREF_WARN_REG_SPLIT_DEL_ALL;
886 gtk_dialog_add_button (GTK_DIALOG (dialog),
887 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
888 gnc_gtk_dialog_add_button(dialog, _(
"_Remove Splits"),
889 GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT);
890 response = gnc_dialog_run (GTK_DIALOG(dialog), warning);
891 gtk_widget_destroy (dialog);
892 if (response != GTK_RESPONSE_ACCEPT)
895 gnc_tree_view_split_reg_reinit_trans (view);
908 GtkWidget *dialog, *window;
910 const gchar *warning;
913 split = gnc_tree_view_split_reg_get_current_split (view);
916 split = gnc_tree_control_split_reg_get_current_trans_split (view);
919 LEAVE(
"split is NULL");
924 model = gnc_tree_view_split_reg_get_model_from_view (view);
926 anchor = gnc_tree_model_split_reg_get_anchor (model);
934 if (gtc_sr_is_trans_readonly_and_warn (view, trans))
938 if (gtc_sr_trans_test_for_edit (view, trans))
941 depth = gnc_tree_view_reg_get_selected_row_depth (view);
945 Split *blank_split = gnc_tree_control_split_reg_get_blank_split (view);
947 if (split == blank_split)
953 Transaction *blank_trans = gnc_tree_control_split_reg_get_blank_trans (view);
955 if (trans == blank_trans)
959 window = gnc_tree_view_split_reg_get_parent (view);
964 const char *format = _(
"Delete the split '%s' from the transaction '%s'?");
965 const char *recn_warn = _(
"You would be deleting a reconciled split! "
966 "This is not a good idea as it will cause your "
967 "reconciled balance to be off.");
968 const char *anchor_error = _(
"You cannot delete this split.");
969 const char *anchor_split = _(
"This is the split anchoring this transaction "
970 "to the register. You may not delete it from "
971 "this register window. You may delete the "
972 "entire transaction from this window, or you "
973 "may navigate to a register that shows "
974 "another side of this same transaction and "
975 "delete the split from that register.");
980 if ((split == gnc_tree_control_split_reg_get_current_trans_split (view)) ||
981 (split == gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor (trans, anchor)))
983 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
985 | GTK_DIALOG_DESTROY_WITH_PARENT,
989 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
991 gtk_dialog_run (GTK_DIALOG (dialog));
992 gtk_widget_destroy (dialog);
997 memo = (memo && *memo) ? memo : _(
"(no memo)");
1000 desc = (desc && *desc) ? desc : _(
"(no description)");
1003 buf = g_strdup_printf (format, memo, desc);
1004 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1006 | GTK_DIALOG_DESTROY_WITH_PARENT,
1007 GTK_MESSAGE_QUESTION,
1014 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1016 warning = GNC_PREF_WARN_REG_SPLIT_DEL_RECD;
1020 warning = GNC_PREF_WARN_REG_SPLIT_DEL;
1023 gtk_dialog_add_button (GTK_DIALOG (dialog),
1024 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1025 gnc_gtk_dialog_add_button (dialog, _(
"_Delete Split"),
1026 GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT);
1027 response = gnc_dialog_run (GTK_DIALOG (dialog), warning);
1028 gtk_widget_destroy (dialog);
1029 if (response != GTK_RESPONSE_ACCEPT)
1032 gnc_tree_view_split_reg_delete_current_split (view);
1036 g_return_if_fail (depth == TRANS1 || depth == TRANS2);
1041 const char *title = _(
"Delete the current transaction?");
1042 const char *recn_warn = _(
"You would be deleting a transaction "
1043 "with reconciled splits! "
1044 "This is not a good idea as it will cause your "
1045 "reconciled balance to be off.");
1047 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1049 | GTK_DIALOG_DESTROY_WITH_PARENT,
1050 GTK_MESSAGE_WARNING,
1055 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1057 warning = GNC_PREF_WARN_REG_TRANS_DEL_RECD;
1061 warning = GNC_PREF_WARN_REG_TRANS_DEL;
1063 gtk_dialog_add_button (GTK_DIALOG (dialog),
1064 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1065 gnc_gtk_dialog_add_button (dialog, _(
"_Delete Transaction"),
1066 GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT);
1067 response = gnc_dialog_run (GTK_DIALOG (dialog), warning);
1068 gtk_widget_destroy (dialog);
1069 if (response != GTK_RESPONSE_ACCEPT)
1072 gnc_tree_view_split_reg_delete_current_trans (view);
1084 GList *snode = NULL;
1085 gboolean changed = FALSE;
1089 trans = gnc_tree_view_split_reg_get_current_trans (view);
1093 LEAVE(
"Trans is Null");
1098 if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
1100 LEAVE(
"Skip blank trans");
1105 if (gtc_sr_is_trans_readonly_and_warn (view, trans))
1112 if (gtc_sr_trans_test_for_edit (view, trans))
1114 LEAVE(
"Open in different register");
1118 window = gnc_tree_view_split_reg_get_parent (view);
1122 gnc_error_dialog (window,
"%s",
1123 _(
"A reversing entry has already been created for this transaction."));
1124 LEAVE(
"Already have reversing transaction");
1129 if (gtc_sr_trans_open_and_warn (view, trans))
1131 LEAVE(
"save cancelled");
1149 if (xaccTransStillHasSplit (new_trans, snode->data))
1157 while (gtk_events_pending ())
1158 gtk_main_iteration ();
1161 gnc_tree_control_split_reg_jump_to (view, NULL,
xaccTransGetSplit (new_trans, 0), FALSE);
1163 LEAVE(
"Reverse transaction created");
1176 Split *split, *trans_split;
1177 gboolean changed = FALSE;
1178 gboolean use_split_action_for_num_field = FALSE;
1182 model = gnc_tree_view_split_reg_get_model_from_view (view);
1184 blank_split = gnc_tree_control_split_reg_get_blank_split (view);
1185 split = gnc_tree_view_split_reg_get_current_split (view);
1186 trans_split = gnc_tree_control_split_reg_get_current_trans_split (view);
1189 depth = gnc_tree_view_reg_get_selected_row_depth (view);
1193 trans = gnc_tree_view_split_reg_get_current_trans (view);
1200 if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
1202 LEAVE(
"Skip blank trans");
1207 if (split == blank_split)
1209 LEAVE(
"Skip blank split");
1214 if (gtc_sr_is_trans_readonly_and_warn (view, trans))
1221 if (gtc_sr_trans_test_for_edit (view, trans))
1223 LEAVE(
"Open in different register");
1228 if (gtc_sr_trans_open_and_warn (view, trans))
1230 LEAVE(
"save cancelled");
1234 window = gnc_tree_view_split_reg_get_parent (view);
1237 if (depth == SPLIT3)
1240 gboolean new_act_num = FALSE;
1251 if (split != trans_split)
1253 if (use_split_action_for_num_field &&
gnc_strisnum (gnc_get_num_action (NULL, split)))
1256 const char* title = _(
"New Split Information");
1257 const char *in_num = NULL;
1263 in_num = gnc_get_num_action (NULL, split);
1265 if (!gnc_dup_trans_dialog (window, title, FALSE,
1266 &date, in_num, &out_num, NULL, NULL))
1268 LEAVE(
"dup cancelled");
1277 gnc_tree_model_split_reg_set_blank_split_parent (model, trans, TRUE);
1281 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
1284 xaccSplitSetParent (new_split, trans);
1287 gnc_tree_model_split_reg_set_blank_split_parent (model, trans, FALSE);
1290 gnc_set_num_action (NULL, new_split, out_num, NULL);
1297 if (account == gnc_tree_model_split_reg_get_anchor (model))
1305 gnc_error_dialog (window,
"%s",
1306 _(
"This is the split anchoring this transaction to the register."
1307 " You can not duplicate it from this register window."));
1308 LEAVE(
"split anchoring this transaction");
1315 int trans_split_index;
1317 const char *in_num = NULL;
1318 const char *in_tnum = NULL;
1327 if (
gnc_strisnum (gnc_get_num_action (trans, trans_split)))
1329 Account *account = gnc_tree_model_split_reg_get_anchor (model);
1334 in_num = gnc_get_num_action (trans, trans_split);
1337 in_tnum = (use_split_action_for_num_field
1338 ? gnc_get_num_action (trans, NULL)
1341 if (!gnc_dup_trans_dialog (window, NULL, TRUE,
1342 &date, in_num, &out_num, in_tnum, &out_tnum))
1344 LEAVE(
"dup cancelled");
1348 if (use_autoreadonly)
1353 if (g_date_compare (&d, readonly_threshold) < 0)
1355 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1359 "%s", _(
"Cannot store a transaction at this date"));
1360 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1361 "%s", _(
"The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. "
1362 "This setting can be changed in File -> Properties -> Accounts."));
1363 gtk_dialog_run (GTK_DIALOG (dialog));
1364 gtk_widget_destroy (dialog);
1366 g_date_free (readonly_threshold);
1367 LEAVE(
"entered date older than read-only threshold");
1370 g_date_free (readonly_threshold);
1388 gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
1392 Account *account = gnc_tree_model_split_reg_get_anchor (model);
1399 if (use_split_action_for_num_field)
1403 gnc_set_num_action (NULL,
1413 if (out_num != NULL)
1416 if (use_split_action_for_num_field && out_tnum != NULL)
1425 gboolean move_up, gboolean really_do_it)
1428 GtkTreePath *mpath = NULL, *spath = NULL, *spath_target = NULL, *mpath_target = NULL;
1429 GtkTreeIter m_iter, m_iter_target;
1430 gboolean resultvalue = FALSE;
1431 g_return_val_if_fail(view, FALSE);
1438 model = gnc_tree_view_split_reg_get_model_from_view (view);
1439 g_return_val_if_fail(model, FALSE);
1443 LEAVE(
"Not sorted by date - no up/down move available");
1447 mpath = gnc_tree_view_split_reg_get_current_path (view);
1450 LEAVE(
"No current path available - probably on the blank split.");
1454 spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
1455 g_return_val_if_fail(spath, FALSE);
1457 spath_target = gtk_tree_path_copy(spath);
1460 gboolean move_was_made = gtk_tree_path_prev(spath_target);
1463 LEAVE(
"huh, no path_prev() possible");
1469 gtk_tree_path_next(spath_target);
1474 if (gtk_tree_path_compare(spath, spath_target) == 0)
1476 LEAVE(
"oops, paths are equal");
1480 mpath_target = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath_target);
1483 LEAVE(
"no path to target row");
1487 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
1489 LEAVE(
"No iter for current row");
1492 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter_target, mpath_target))
1494 LEAVE(
"No iter for target row");
1499 gboolean is_blank, is_blank_target;
1500 Split *current_split, *target_split;
1502 gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
1503 NULL, NULL, NULL, &is_blank,
1504 ¤t_split, ¤t_trans);
1505 gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter_target,
1506 NULL, NULL, NULL, &is_blank_target,
1507 &target_split, &target_trans);
1508 if (is_blank || is_blank_target)
1510 LEAVE(
"blank split involved, ignored.");
1513 if (
xaccTransEqual(current_trans, target_trans, TRUE, FALSE, FALSE, FALSE))
1515 LEAVE(
"two times the same txn, ignored.");
1521 LEAVE(
"One of the txn is book-closing - no re-ordering allowed.");
1531 if (g_date_compare(&d1, &d2) != 0)
1533 LEAVE(
"unequal DatePosted, ignoring");
1539 LEAVE(
"unequal Num, ignoring");
1563 LEAVE(
"either current or target split is frozen. No modification allowed.");
1573 && !gnc_tree_control_split_reg_recn_test(view, spath))
1575 LEAVE(
"current split is reconciled and user chose not to modify it");
1579 && !gnc_tree_control_split_reg_recn_test(view, spath_target))
1581 LEAVE(
"target split is reconciled and user chose not to modify it");
1585 PINFO(
"Ok, about to switch ordering for current desc='%s' target desc='%s'",
1589 gnc_suspend_gui_refresh ();
1601 g_warning(
"Surprise - both DateEntered are equal.");
1607 time_current.tv_sec++;
1609 time_target.tv_sec++;
1619 gnc_resume_gui_refresh ();
1621 LEAVE(
"two txn switched, done.");
1629 gtk_tree_path_free(spath);
1630 gtk_tree_path_free(spath_target);
1631 gtk_tree_path_free(mpath_target);
1638 return gtcsr_move_current_entry_updown(view, move_up, TRUE);
1644 return gtcsr_move_current_entry_updown(view, move_up, FALSE);
1661 Split *split, *current_trans_split;
1663 ENTER(
"view=%p, reg_closing=%s", view, reg_closing ?
"TRUE" :
"FALSE");
1672 gnc_tree_view_split_reg_finish_edit (view);
1675 view->reg_closing = TRUE;
1677 model = gnc_tree_view_split_reg_get_model_from_view (view);
1679 blank_split = gnc_tree_control_split_reg_get_blank_split (view);
1680 dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
1681 blank_trans = gnc_tree_control_split_reg_get_blank_trans (view);
1684 split = gnc_tree_view_split_reg_get_current_split (view);
1685 trans = gnc_tree_view_split_reg_get_current_trans (view);
1687 current_trans_split = gnc_tree_control_split_reg_get_current_trans_split (view);
1691 LEAVE(
"no transaction");
1697 LEAVE(
"transaction not open");
1701 if (trans == dirty_trans )
1703 if (trans != blank_trans)
1707 PINFO(
"committing trans (%p)", trans);
1709 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
1711 LEAVE(
"Existing Transaction committed");
1718 PINFO(
"start committing blank trans (%p)", trans);
1723 GtkWidget *dialog, *window;
1725 const char *title = _(
"Not enough information for Blank Transaction?");
1726 const char *message =
1727 _(
"The blank transaction does not have enough information to save it. Would you like to "
1728 "return to the transaction to update, or cancel the save?");
1729 window = gnc_tree_view_split_reg_get_parent (view);
1730 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1731 GTK_DIALOG_DESTROY_WITH_PARENT,
1732 GTK_MESSAGE_QUESTION,
1735 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1737 gtk_dialog_add_button (GTK_DIALOG (dialog),
1738 _(
"_Return"), GTK_RESPONSE_ACCEPT);
1740 gtk_widget_grab_focus (gtk_dialog_get_widget_for_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT));
1742 response = gtk_dialog_run (GTK_DIALOG (dialog));
1744 gtk_widget_destroy (dialog);
1746 if (response != GTK_RESPONSE_ACCEPT)
1748 LEAVE(
"save cancelled");
1751 LEAVE(
"return to transaction");
1756 gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
1758 LEAVE(
"Blank Transaction committed");
1772 GtkWidget *dialog, *window;
1776 Split *split = NULL;
1778 gboolean is_trow1, is_trow2, is_split, is_blank;
1781 const gchar *title = _(
"Mark split as unreconciled?");
1782 const gchar *message =
1783 _(
"You are about to mark a reconciled split as unreconciled. Doing "
1784 "so might make future reconciliation difficult! Continue "
1785 "with this change?");
1790 model = gnc_tree_view_split_reg_get_model_from_view (view);
1792 anchor = gnc_tree_model_split_reg_get_anchor (model);
1794 mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath);
1796 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
1798 gtk_tree_path_free (mpath);
1802 gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
1803 &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
1805 if (is_trow1 || is_trow2)
1806 split = xaccTransFindSplitByAccount (trans, anchor);
1812 gtk_tree_path_free (mpath);
1813 LEAVE(
"Not reconciled");
1818 window = gnc_tree_view_split_reg_get_parent (view);
1820 gtk_message_dialog_new (GTK_WINDOW (window),
1821 GTK_DIALOG_DESTROY_WITH_PARENT,
1822 GTK_MESSAGE_WARNING,
1825 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1827 gtk_dialog_add_button (GTK_DIALOG (dialog), _(
"_Unreconcile"),
1829 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_RECD_SPLIT_UNREC);
1830 gtk_widget_destroy (dialog);
1832 if (response == GTK_RESPONSE_YES)
1837 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
1843 gtk_tree_path_free (mpath);
1844 LEAVE(
"mark split unreconciled");
1847 gtk_tree_path_free (mpath);
1848 LEAVE(
"Canceled split unreconciled");
1860 Split *split = NULL;
1862 gboolean is_trow1, is_trow2, is_split, is_blank;
1869 if (view->change_allowed)
1871 LEAVE(
"change allowed is set");
1875 model = gnc_tree_view_split_reg_get_model_from_view (view);
1877 anchor = gnc_tree_model_split_reg_get_anchor (model);
1879 mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath);
1881 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
1883 gtk_tree_path_free (mpath);
1888 gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
1889 &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
1891 if (is_trow1 || is_trow2)
1892 split = xaccTransFindSplitByAccount (trans, anchor);
1896 gtk_tree_path_free (mpath);
1905 GtkWidget *dialog, *window;
1908 const gchar *message;
1912 title = _(
"Change reconciled split?");
1914 _(
"You are about to change a reconciled split. Doing so might make "
1915 "future reconciliation difficult! Continue with this change?");
1919 title = _(
"Change split linked to a reconciled split?");
1921 _(
"You are about to change a split that is linked to a reconciled split. "
1922 "Doing so might make future reconciliation difficult! Continue with this change?");
1926 window = gnc_tree_view_split_reg_get_parent (view);
1928 gtk_message_dialog_new (GTK_WINDOW (window),
1929 GTK_DIALOG_DESTROY_WITH_PARENT,
1930 GTK_MESSAGE_WARNING,
1933 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1935 gtk_dialog_add_button (GTK_DIALOG (dialog), _(
"Chan_ge Split"),
1937 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_RECD_SPLIT_MOD);
1938 gtk_widget_destroy (dialog);
1940 if (response != GTK_RESPONSE_YES)
1942 gtk_tree_path_free (mpath);
1943 LEAVE(
"cancel reconciled split");
1947 view->change_allowed = TRUE;
1948 gtk_tree_path_free (mpath);
1956 gnc_tree_control_split_reg_get_account_by_name (
GncTreeViewSplitReg *view,
const char *name)
1959 const char *placeholder = _(
"The account %s does not allow transactions.");
1960 const char *missing = _(
"The account %s does not exist. "
1961 "Would you like to create it?");
1965 if (!name || (strlen(name) == 0))
1969 if (
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
1977 window = gnc_tree_view_split_reg_get_parent (view);
1982 if (!gnc_verify_dialog (window, TRUE, missing, name))
1994 gnc_error_dialog (window, placeholder, name);
2005 static const Account *clipboard_acct = NULL;
2010 gtc_sr_get_account_for_trans_ancestor (
const Transaction *trans,
const Account *ancestor)
2016 Split *split = node->data;
2019 if (!xaccTransStillHasSplit (trans, split))
2022 if (ancestor == split_acc)
2039 g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
2041 model = gnc_tree_view_split_reg_get_model_from_view (view);
2043 anchor = gnc_tree_model_split_reg_get_anchor (model);
2045 from_trans = gnc_tree_view_split_reg_get_current_trans (view);
2050 if (gtc_sr_is_trans_readonly_and_warn (view, from_trans))
2055 if (clipboard_trans)
2059 clipboard_acct = gtc_sr_get_account_for_trans_ancestor (from_trans, anchor);
2061 gnc_tree_view_split_reg_delete_current_trans (view);
2072 g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
2074 model = gnc_tree_view_split_reg_get_model_from_view (view);
2076 from_trans = gnc_tree_view_split_reg_get_current_trans (view);
2080 anchor = gnc_tree_model_split_reg_get_anchor (model);
2082 clipboard_acct = gtc_sr_get_account_for_trans_ancestor (from_trans, anchor);
2086 if (clipboard_trans)
2099 g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
2101 model = gnc_tree_view_split_reg_get_model_from_view (view);
2102 anchor_acct = gnc_tree_model_split_reg_get_anchor (model);
2104 to_trans = gnc_tree_view_split_reg_get_current_trans (view);
2105 if (!to_trans || !clipboard_trans)
2109 if (gtc_sr_trans_test_for_edit (view, to_trans))
2113 if (gtc_sr_is_trans_readonly_and_warn (view, to_trans))
2117 if (clipboard_acct == NULL && anchor_acct != NULL)
2121 window = gnc_tree_view_split_reg_get_parent (view);
2122 gnc_error_dialog (window,
"%s",
2123 _(
"You can not paste from the general ledger to a register."));
2127 gnc_tree_view_split_reg_set_dirty_trans (view, to_trans);
2132 gnc_tree_model_split_reg_set_blank_split_parent (model, to_trans, TRUE);
2137 gnc_tree_model_split_reg_set_blank_split_parent (model, to_trans, FALSE);
2140 g_signal_emit_by_name (model,
"refresh_trans", NULL);
2148 GtkListStore *desc_list;
2152 g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
2153 DEBUG(
"auto_complete - trans %p and description '%s'", trans, new_text);
2155 model = gnc_tree_view_split_reg_get_model_from_view (view);
2157 btrans = gnc_tree_model_split_get_blank_trans (model);
2160 if (trans != btrans)
2163 desc_list = gnc_tree_model_split_reg_get_description_list (model);
2165 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (desc_list), &iter);
2171 gtk_tree_model_get (GTK_TREE_MODEL (desc_list), &iter, 0, &text, 1, &trans_from, -1);
2173 if (g_strcmp0 (text, new_text) == 0)
2181 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (desc_list), &iter);
gboolean xaccTransHasReconciledSplits(const Transaction *trans)
Transaction * xaccMallocTransaction(QofBook *book)
const char * xaccAccountGetLastNum(const Account *acc)
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
Split * xaccTransGetSplit(const Transaction *trans, int i)
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
gboolean xaccTransIsReadonlyByPostedDate(const Transaction *trans)
Dialog for create/edit an account.
gboolean xaccTransIsOpen(const Transaction *trans)
#define PINFO(format, args...)
GNCAccountType xaccAccountGetType(const Account *acc)
gnc_numeric gnc_numeric_neg(gnc_numeric a)
#define DEBUG(format, args...)
void xaccSplitCopyOnto(const Split *from_split, Split *to_split)
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
char xaccSplitGetReconcile(const Split *split)
gboolean timespec_equal(const Timespec *ta, const Timespec *tb)
Account * gnc_ui_new_accounts_from_name_window(const char *name)
Use a 64-bit unsigned int timespec.
GtkSortType sort_direction
void xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans)
void xaccSplitSetReconcile(Split *split, char recn)
Transaction * xaccSplitGetParent(const Split *split)
gboolean xaccTransIsBalanced(const Transaction *trans)
const char * xaccTransGetNum(const Transaction *trans)
#define PERR(format, args...)
#define ENTER(format, args...)
gboolean gnc_strisnum(const gchar *s)
void xaccAccountSetLastNum(Account *acc, const char *num)
void xaccTransSetDatePostedGDate(Transaction *trans, GDate date)
void xaccTransSetDateEnteredTS(Transaction *trans, const Timespec *ts)
gboolean gnc_numeric_negative_p(gnc_numeric a)
void xaccTransDestroy(Transaction *trans)
Transaction * current_trans
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
int xaccTransCountSplits(const Transaction *trans)
convert single-entry accounts to clean double-entry
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
gboolean xaccTransEqual(const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
void xaccTransVoid(Transaction *trans, const char *reason)
Account * gnc_account_lookup_by_code(const Account *parent, const char *code)
void gnc_monetary_list_free(MonetaryList *list)
Timespec xaccTransRetDateEnteredTS(const Transaction *trans)
void xaccTransScrubImbalance(Transaction *trans, Account *root, Account *account)
void xaccTransCopyFromClipBoard(const Transaction *from_trans, Transaction *to_trans, const Account *from_acc, Account *to_acc, gboolean no_date)
const char * xaccTransGetDescription(const Transaction *trans)
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
void xaccTransCommitEdit(Transaction *trans)
Additional event handling code.
void xaccTransBeginEdit(Transaction *trans)
const char * xaccTransGetReadOnly(const Transaction *trans)
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
void xaccTransUnvoid(Transaction *trans)
gboolean gnc_numeric_positive_p(gnc_numeric a)
Split * xaccMallocSplit(QofBook *book)
Generic api to store and retrieve preferences.
Transaction * xaccTransReverse(Transaction *orig)
gnc_numeric xaccSplitGetValue(const Split *split)
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor)
Account * xaccSplitGetAccount(const Split *s)
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
gboolean xaccTransGetIsClosingTxn(const Transaction *trans)
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
gboolean xaccAccountGetPlaceholder(const Account *acc)
MonetaryList * xaccTransGetImbalance(const Transaction *trans)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Transaction * xaccTransGetReversedBy(const Transaction *trans)
Timespec xaccTransRetDatePostedTS(const Transaction *trans)
Split * xaccSplitGetOtherSplit(const Split *split)
#define LEAVE(format, args...)
time64 gnc_time(time64 *tbuf)
get the current local time
const char * xaccSplitGetMemo(const Split *split)
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Account * gnc_account_get_root(Account *acc)
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
#define GNC_EVENT_ITEM_ADDED
GDate xaccTransGetDatePostedGDate(const Transaction *trans)
API for Transactions and Splits (journal entries)
SplitList * xaccTransGetSplitList(const Transaction *trans)
Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
const gchar * QofLogModule
void gnc_gdate_set_time64(GDate *gd, time64 time)
gnc_numeric xaccSplitGetAmount(const Split *split)