29 #include <glib/gi18n.h> 32 #include "completioncell.h" 34 #include "dialog-utils.h" 35 #include "gnc-component-manager.h" 38 #include <gnc-hooks.h> 42 #include "gnc-warnings.h" 43 #include "split-register-copy-ops.h" 55 #include "dialog-dup-trans.h" 56 #include "engine-helpers.h" 57 #include "qofbookslots.h" 63 static QofLogModule log_module = GNC_MOD_LEDGER;
76 gint anchor_split_index;
83 static gboolean gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
86 gboolean use_cut_semantics);
87 static gboolean gnc_split_register_auto_calc (SplitRegister *reg,
96 if (copied_item.ftype == GNC_TYPE_SPLIT)
97 gnc_float_split_free (copied_item.fs);
98 if (copied_item.ftype == GNC_TYPE_TRANSACTION)
99 gnc_float_txn_free (copied_item.ft);
100 copied_item.ftype = 0;
101 copied_item.fs = NULL;
102 copied_item.ft = NULL;
103 copied_item.cursor_class = CURSOR_CLASS_NONE;
105 copied_item.anchor_split_index = 0;
111 return copied_item.ft || copied_item.fs;
115 gnc_copy_split_onto_split (Split* from, Split* to,
117 gboolean use_cut_semantics)
120 gboolean is_template = FALSE;
122 if ((from == NULL) || (to == NULL))
125 if (template_account)
128 fs = gnc_split_to_float_split (from, is_template);
132 gnc_float_split_to_split (fs, to, template_account);
133 gnc_float_split_free (fs);
138 gboolean use_cut_semantics,
143 gboolean is_template = FALSE;
145 if ((from == NULL) || (to == NULL))
148 if (template_account)
151 ft = gnc_txn_to_float_txn (from, use_cut_semantics, is_template);
156 gnc_float_txn_to_template_txn (ft, to, template_account, do_commit);
158 gnc_float_txn_to_txn (ft, to, do_commit);
160 gnc_float_txn_free (ft);
164 gnc_split_get_value_denom (Split* split)
166 gnc_commodity* currency;
183 gnc_split_get_amount_denom (Split* split)
201 gnc_split_register_begin_edit_or_warn (SRInfo* info, Transaction* trans)
203 ENTER (
"info=%p, trans=%p", info, trans);
210 LEAVE (
"opened and marked pending");
216 gnc_get_current_book ());
219 if (trans == blank_trans)
224 LEAVE (
"already open, now pending.");
229 GtkWindow* parent = NULL;
230 if (info->get_parent)
231 parent = GTK_WINDOW (info->get_parent (info->user_data));
232 gnc_error_dialog (parent,
"%s",
233 _ (
"This transaction is already being edited in another register. Please finish editing it there first."));
234 LEAVE (
"already editing");
245 SRInfo* info = gnc_split_register_get_info (reg);
246 VirtualLocation virt_loc;
251 if (reg->style == REG_STYLE_AUTO_LEDGER ||
252 reg->style == REG_STYLE_JOURNAL)
256 if (! (expand ^ info->trans_expanded))
261 virt_loc = reg->table->current_cursor_loc;
262 gnc_split_register_get_trans_split (reg, virt_loc.vcell_loc,
263 &virt_loc.vcell_loc);
269 PERR (
"Can't find place to go!");
274 info->trans_expanded = expand;
277 reg->table->current_cursor_loc.vcell_loc,
278 gnc_split_register_get_active_cursor (reg));
281 reg, reg->table->current_cursor_loc.vcell_loc, expand, FALSE);
283 virt_loc = reg->table->current_cursor_loc;
284 if (!expand || !gnc_table_virtual_loc_valid (reg->table, virt_loc, FALSE))
290 PERR (
"Can't find place to go!");
298 gnc_split_register_show_trans (reg,
299 reg->table->current_cursor_loc.vcell_loc);
305 SRInfo* info = gnc_split_register_get_info (reg);
310 if (reg->style == REG_STYLE_AUTO_LEDGER ||
311 reg->style == REG_STYLE_JOURNAL)
314 return info->trans_expanded;
321 VirtualCellLocation vcell_loc;
332 vcell_loc = reg->table->current_cursor_loc.vcell_loc;
334 vcell_loc.virt_row--;
336 split = gnc_split_register_get_split (reg, vcell_loc);
347 return gnc_split_register_get_split (
348 reg, reg->table->current_cursor_loc.vcell_loc);
354 SRInfo* info = gnc_split_register_get_info (reg);
356 if (!reg)
return NULL;
358 return xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ());
363 VirtualCellLocation* vcell_loc)
369 if (!reg || !split)
return FALSE;
376 for (v_row =
table->num_virt_rows - 1; v_row > 0; v_row--)
377 for (v_col = 0; v_col <
table->num_virt_cols; v_col++)
379 VirtualCellLocation vc_loc = { v_row, v_col };
403 VirtualLocation* virt_loc)
405 VirtualLocation v_loc;
407 const char* cell_name;
417 switch (cursor_class)
419 case CURSOR_CLASS_SPLIT:
420 case CURSOR_CLASS_TRANS:
427 if (!gnc_table_get_cell_location (reg->table, cell_name,
428 v_loc.vcell_loc, &v_loc))
431 if (virt_loc == NULL)
442 SRInfo* info = gnc_split_register_get_info (reg);
451 ENTER (
"reg=%p", reg);
454 gnc_get_current_book ());
462 LEAVE (
"no transaction");
469 if (cursor_class == CURSOR_CLASS_NONE)
471 LEAVE (
"no cursor class");
476 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
478 LEAVE (
"no split with transaction class");
482 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
486 if (!changed && ((split == NULL) || (split == blank_split)))
488 LEAVE (
"skip unchanged blank split");
492 gnc_suspend_gui_refresh ();
498 GtkWidget* dialog, *window;
500 const char* title = _ (
"Save transaction before duplicating?");
501 const char* message =
502 _ (
"The current transaction has been changed. Would you like to " 503 "record the changes before duplicating the transaction, or " 504 "cancel the duplication?");
506 window = gnc_split_register_get_parent (reg);
507 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
508 GTK_DIALOG_DESTROY_WITH_PARENT,
509 GTK_MESSAGE_QUESTION,
512 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
514 gtk_dialog_add_button (GTK_DIALOG (dialog),
515 _ (
"_Record"), GTK_RESPONSE_ACCEPT);
516 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_DUP);
517 gtk_widget_destroy (dialog);
519 if (response != GTK_RESPONSE_ACCEPT)
521 gnc_resume_gui_refresh ();
522 LEAVE (
"save cancelled");
538 if (cursor_class == CURSOR_CLASS_SPLIT)
542 gboolean new_act_num = FALSE;
551 if (!reg->use_tran_num_for_num_field
555 const char* in_num = NULL;
556 const char* title = _ (
"New Split Information");
557 time64 date = info->last_date_entered;
562 in_num = gnc_get_num_action (NULL, split);
564 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg),
565 title, FALSE, &date, in_num, &out_num,
566 NULL, NULL, NULL, NULL))
568 gnc_resume_gui_refresh ();
569 LEAVE (
"dup cancelled");
578 xaccSplitSetParent (new_split, trans);
581 gnc_get_current_book ());
583 gnc_copy_split_onto_split (split, new_split, template_account, FALSE);
585 gnc_set_num_action (NULL, new_split, out_num, NULL);
595 gnc_split_register_get_default_account (reg),
599 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
601 if (gnc_num_cell_set_last_num (num_cell, out_num))
602 gnc_split_register_set_last_num (reg, out_num);
610 return_split = new_split;
612 info->cursor_hint_split = new_split;
613 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
621 Transaction* new_trans;
622 int trans_split_index;
624 const char* in_num = NULL;
625 const char* in_tnum = NULL;
626 char* out_num = NULL;
627 char* out_tnum = NULL;
628 char* out_tdoclink = NULL;
631 gnc_get_current_book ());
635 date = info->last_date_entered;
637 account = gnc_split_register_get_default_account (reg);
639 if (account &&
gnc_strisnum (gnc_get_num_action (trans, trans_split)))
642 in_num = gnc_get_num_action (trans, trans_split);
644 in_tnum = (reg->use_tran_num_for_num_field
646 : gnc_get_num_action (trans, NULL));
648 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg), NULL,
649 !reg->is_template, &date,
650 in_num, &out_num, in_tnum, &out_tnum,
653 gnc_resume_gui_refresh ();
654 LEAVE (
"dup cancelled");
658 if (use_autoreadonly)
662 gnc_get_current_book ());
664 if (g_date_compare (&d, readonly_threshold) < 0)
666 GtkWidget* dialog = gtk_message_dialog_new (NULL,
670 "%s", _ (
"Cannot store a transaction at this date"));
671 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
672 "%s", _ (
"The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. " 673 "This setting can be changed in File->Properties->Accounts."));
674 gtk_dialog_run (GTK_DIALOG (dialog));
675 gtk_widget_destroy (dialog);
677 g_date_free (readonly_threshold);
680 g_date_free (readonly_threshold);
689 gnc_resume_gui_refresh ();
699 gnc_get_current_book ());
708 if (out_tdoclink == NULL)
711 g_free (out_tdoclink);
714 gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
715 if (!reg->use_tran_num_for_num_field)
719 gnc_set_num_action (NULL,
728 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
730 if (gnc_num_cell_set_last_num (num_cell, out_num))
731 gnc_split_register_set_last_num (reg, out_num);
734 if (!reg->use_tran_num_for_num_field)
744 info->cursor_hint_trans = new_trans;
745 info->cursor_hint_split = return_split;
746 info->cursor_hint_trans_split = trans_split;
747 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
749 info->trans_expanded = FALSE;
753 gnc_resume_gui_refresh ();
760 gnc_split_register_copy_current_internal (SplitRegister* reg,
761 gboolean use_cut_semantics)
763 SRInfo* info = gnc_split_register_get_info (reg);
772 g_return_if_fail (reg);
773 ENTER (
"reg=%p, use_cut_semantics=%s", reg,
774 use_cut_semantics ?
"TRUE" :
"FALSE");
777 gnc_get_current_book ());
791 if (cursor_class == CURSOR_CLASS_NONE)
793 LEAVE (
"no cursor class");
798 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
800 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
801 LEAVE (
"transaction cursor with no anchoring split");
805 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
808 if (!changed && ((split == NULL) || (split == blank_split)))
817 LEAVE (
"nothing to copy/cut");
826 if (cursor_class == CURSOR_CLASS_SPLIT)
829 new_fs = gnc_split_to_float_split (split, reg->is_template);
834 gnc_split_register_save_to_copy_buffer (reg, NULL, new_fs,
843 new_ft = gnc_txn_to_float_txn (trans, use_cut_semantics, reg->is_template);
853 if (split_index >= 0)
854 fs = gnc_float_txn_get_float_split (new_ft, split_index);
858 gnc_split_register_save_to_copy_buffer (reg, new_ft, fs,
862 copied_item.leader_guid = info->default_account;
867 if (!new_fs && !new_ft)
869 g_warning (
"BUG DETECTED: copy failed");
870 LEAVE (
"copy failed");
876 copied_item.fs = new_fs;
877 copied_item.ftype = GNC_TYPE_SPLIT;
881 copied_item.ft = new_ft;
882 copied_item.ftype = GNC_TYPE_TRANSACTION;
885 copied_item.cursor_class = cursor_class;
886 gnc_hook_add_dangler (HOOK_BOOK_CLOSED, clear_copied_item, NULL, NULL);
887 LEAVE (
"%s %s", use_cut_semantics ?
"cut" :
"copied",
888 cursor_class == CURSOR_CLASS_SPLIT ?
"split" :
"transaction");
894 gnc_split_register_copy_current_internal (reg, FALSE);
900 SRInfo* info = gnc_split_register_get_info (reg);
908 gnc_get_current_book ());
919 if (cursor_class == CURSOR_CLASS_NONE)
923 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
926 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
929 if (!changed && ((split == NULL) || (split == blank_split)))
932 gnc_split_register_copy_current_internal (reg, TRUE);
934 if (cursor_class == CURSOR_CLASS_SPLIT)
943 SRInfo* info = gnc_split_register_get_info (reg);
946 Transaction* blank_trans;
950 Account *template_account = NULL;
952 ENTER (
"reg=%p", reg);
954 if (copied_item.cursor_class == CURSOR_CLASS_NONE)
956 LEAVE (
"no copied cursor class");
961 gnc_get_current_book ());
969 gnc_get_current_book ());
974 LEAVE (
"no transaction");
981 if (cursor_class == CURSOR_CLASS_NONE)
983 LEAVE (
"no current cursor class");
988 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
990 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
991 LEAVE (
"transaction cursor with no anchoring split");
995 if (cursor_class == CURSOR_CLASS_SPLIT)
997 const char* message = _ (
"You are about to overwrite an existing split. " 998 "Are you sure you want to do that?");
999 const char* anchor_message = _ (
"This is the split anchoring this transaction " 1000 "to the register. You may not overwrite it from " 1001 "this register window. You may overwrite it if " 1002 "you navigate to a register that shows another " 1003 "side of this same transaction.");
1005 if (copied_item.cursor_class == CURSOR_CLASS_TRANS)
1008 LEAVE (
"can't copy trans to split");
1015 if ((reg->type != GENERAL_JOURNAL) &&
1018 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1019 "%s", anchor_message);
1020 LEAVE (
"anchore split");
1023 else if (!gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1024 FALSE,
"%s", message))
1026 LEAVE (
"user cancelled");
1032 if (gnc_split_register_begin_edit_or_warn (info, trans))
1034 LEAVE (
"can't begin editing");
1038 gnc_suspend_gui_refresh ();
1044 xaccSplitSetParent (split, trans);
1047 if (copied_item.ftype != GNC_TYPE_SPLIT)
1049 LEAVE (
"copy buffer doesn't represent a split");
1052 gnc_float_split_to_split (copied_item.fs, split, template_account);
1056 const char *message = _(
"You are about to overwrite an existing " 1058 "Are you sure you want to do that?");
1061 int trans_split_index;
1065 if (copied_item.cursor_class == CURSOR_CLASS_SPLIT)
1067 LEAVE (
"can't copy split to transaction");
1071 if (copied_item.ftype != GNC_TYPE_TRANSACTION)
1073 LEAVE (
"copy buffer doesn't represent a transaction");
1077 if ((reg->type != SEARCH_LEDGER) && (reg->type != GENERAL_JOURNAL))
1079 if (gnc_float_txn_has_template (copied_item.ft))
1081 const gchar *msg_text = _(
"Scheduled transactions can only be pasted to the General Journal");
1083 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
"%s", msg_text);
1085 LEAVE (
"Paste only allowed to General Journal from scheduled transactions");
1091 if (split != blank_split &&
1092 !gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1093 FALSE,
"%s", message))
1095 LEAVE (
"user cancelled");
1100 if (gnc_split_register_begin_edit_or_warn (info, trans))
1102 LEAVE (
"can't begin editing");
1106 gnc_suspend_gui_refresh ();
1108 DEBUG (
"Pasting txn, trans=%p, split=%p, blank_trans=%p, blank_split=%p",
1109 trans, split, blank_trans, blank_split);
1115 gnc_get_current_book ());
1116 default_account = gnc_split_register_get_default_account (reg);
1118 if (copied_leader && default_account)
1120 gnc_float_txn_to_txn_swap_accounts (copied_item.ft, trans,
1127 if (reg->is_template)
1129 gnc_float_txn_to_template_txn (copied_item.ft, trans,
1130 template_account, FALSE);
1133 gnc_float_txn_to_txn (copied_item.ft, trans, FALSE);
1136 if (split_index >= num_splits)
1139 if (trans == blank_trans)
1142 gint anchor_split_index = copied_item.anchor_split_index;
1143 if (anchor_split_index > num_splits)
1144 anchor_split_index = 0;
1148 info->blank_split_edited = TRUE;
1149 info->auto_complete = FALSE;
1150 DEBUG (
"replacement blank_split=%p", blank_split);
1157 info->cursor_hint_trans = trans;
1161 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
1165 gnc_resume_gui_refresh ();
1172 SRInfo* info = gnc_split_register_get_info (reg);
1173 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1174 gnc_get_current_book ());
1176 if (split == current_blank_split)
1185 SRInfo* info = gnc_split_register_get_info (reg);
1186 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1187 gnc_get_current_book ());
1188 Split* pref_split = NULL;
1189 Split* other_split = NULL;
1197 if (s != current_blank_split && xaccTransStillHasSplit (trans, s))
1206 if (pref_split != NULL)
1208 else if (other_split != NULL)
1217 SRInfo* info = gnc_split_register_get_info (reg);
1218 Transaction* pending_trans;
1226 gnc_get_current_book ());
1229 gnc_get_current_book ());
1239 if (split == blank_split)
1245 gnc_suspend_gui_refresh ();
1250 if (trans == pending_trans)
1256 g_assert (!pending_trans);
1257 if (gnc_split_register_begin_edit_or_warn (info, trans))
1259 gnc_resume_gui_refresh ();
1265 gnc_resume_gui_refresh ();
1272 SRInfo* info = gnc_split_register_get_info (reg);
1273 Transaction* pending_trans;
1279 ENTER (
"reg=%p", reg);
1282 LEAVE (
"no register");
1287 gnc_get_current_book ());
1289 gnc_get_current_book ());
1299 gnc_suspend_gui_refresh ();
1305 if (split == blank_split)
1307 DEBUG (
"deleting blank split");
1309 info->auto_complete = FALSE;
1313 info->trans_expanded = FALSE;
1317 if (trans == pending_trans)
1319 DEBUG (
"clearing pending trans");
1320 info->pending_trans_guid = *
guid_null ();
1321 pending_trans = NULL;
1328 DEBUG (
"committing");
1331 gnc_resume_gui_refresh ();
1339 SRInfo* info = gnc_split_register_get_info (reg);
1340 Transaction* pending_trans;
1348 gnc_get_current_book ());
1350 gnc_get_current_book ());
1358 if (split == blank_split)
1365 info->trans_expanded = FALSE;
1367 gnc_suspend_gui_refresh ();
1373 if (trans == pending_trans)
1375 info->pending_trans_guid = *
guid_null ();
1376 pending_trans = NULL;
1380 PERR (
"We should not be voiding an open transaction.");
1383 gnc_resume_gui_refresh ();
1389 SRInfo* info = gnc_split_register_get_info (reg);
1390 Transaction* pending_trans;
1398 gnc_get_current_book ());
1400 gnc_get_current_book ());
1408 if (split == blank_split)
1415 info->trans_expanded = FALSE;
1417 gnc_suspend_gui_refresh ();
1424 if (trans == pending_trans)
1426 info->pending_trans_guid = *
guid_null ();
1427 pending_trans = NULL;
1430 gnc_resume_gui_refresh ();
1439 Transaction* pending;
1443 if ((reg == NULL) || (split == NULL))
1446 gnc_suspend_gui_refresh ();
1447 info = gnc_split_register_get_info (reg);
1448 pending =
xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ());
1453 if (gnc_split_register_begin_edit_or_warn (info, trans))
1455 gnc_resume_gui_refresh ();
1459 else if (pending == trans)
1463 else g_assert_not_reached ();
1472 gnc_resume_gui_refresh ();
1477 gnc_split_register_empty_current_trans (SplitRegister* reg)
1489 VirtualLocation virt_loc;
1494 virt_loc = reg->table->current_cursor_loc;
1496 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1501 gnc_table_clear_current_cursor_changes (reg->table);
1512 SRInfo* info = gnc_split_register_get_info (reg);
1513 Transaction* pending_trans, *blank_trans;
1514 gboolean refresh_all = FALSE;
1517 gnc_get_current_book ());
1521 if (pending_trans == blank_trans)
1536 gnc_suspend_gui_refresh ();
1540 info->pending_trans_guid = *
guid_null ();
1542 gnc_resume_gui_refresh ();
1545 gnc_gui_refresh_all ();
1553 gnc_ledger_display_refresh_by_split_register (reg);
1559 gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
1561 gboolean use_cut_semantics)
1569 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1578 if (gnc_table_layout_get_cell_changed (reg->table->layout, DATE_CELL, TRUE))
1582 cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
1587 if (gnc_table_layout_get_cell_changed (reg->table->layout, NUM_CELL, TRUE))
1591 value = gnc_table_layout_get_cell_value (reg->table->layout, NUM_CELL);
1592 if (reg->use_tran_num_for_num_field)
1599 if (gnc_table_layout_get_cell_changed (reg->table->layout, TNUM_CELL, TRUE))
1603 value = gnc_table_layout_get_cell_value (reg->table->layout, TNUM_CELL);
1604 if (!reg->use_tran_num_for_num_field)
1609 if (gnc_table_layout_get_cell_changed (reg->table->layout, DESC_CELL, TRUE))
1613 value = gnc_table_layout_get_cell_value (reg->table->layout, DESC_CELL);
1617 if (gnc_table_layout_get_cell_changed (reg->table->layout, NOTES_CELL, TRUE))
1621 value = gnc_table_layout_get_cell_value (reg->table->layout, NOTES_CELL);
1625 if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, TRUE))
1630 cell = gnc_table_layout_get_cell (reg->table->layout, RECN_CELL);
1631 flag = gnc_recn_cell_get_flag ((
RecnCell*) cell);
1633 gnc_float_split_set_reconcile_state (fs, flag);
1636 if (gnc_table_layout_get_cell_changed (reg->table->layout, ACTN_CELL, TRUE))
1640 value = gnc_table_layout_get_cell_value (reg->table->layout, ACTN_CELL);
1641 gnc_float_split_set_action (fs, value);
1644 if (gnc_table_layout_get_cell_changed (reg->table->layout, MEMO_CELL, TRUE))
1648 value = gnc_table_layout_get_cell_value (reg->table->layout, MEMO_CELL);
1649 gnc_float_split_set_memo (fs, value);
1652 if (gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, TRUE))
1656 new_account = gnc_split_register_get_account (reg, XFRM_CELL);
1658 if (new_account != NULL)
1659 gnc_float_split_set_account (fs, new_account);
1662 if (reg->style == REG_STYLE_LEDGER)
1663 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1665 if (gnc_table_layout_get_cell_changed (reg->table->layout, MXFRM_CELL, TRUE))
1667 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1671 if (ft && g_list_length (ft->m_splits) == 1)
1676 other_fs = gnc_split_to_float_split (temp_split, reg->is_template);
1679 gnc_float_txn_append_float_split (ft, other_fs);
1687 new_account = gnc_split_register_get_account (reg, MXFRM_CELL);
1689 if (new_account != NULL)
1690 gnc_float_split_set_account (other_fs, new_account);
1694 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1696 gnc_table_layout_get_cell_changed (reg->table->layout,
1700 gnc_numeric new_value;
1704 cell = gnc_table_layout_get_cell (reg->table->layout, CRED_CELL);
1707 cell = gnc_table_layout_get_cell (reg->table->layout, DEBT_CELL);
1710 new_value = gnc_numeric_sub_fixed (debit, credit);
1712 gnc_float_split_set_value (fs, new_value);
1715 if (gnc_table_layout_get_cell_changed (reg->table->layout, PRIC_CELL, TRUE))
1720 if (gnc_table_layout_get_cell_changed (reg->table->layout, SHRS_CELL, TRUE))
1725 cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
1729 gnc_float_split_set_amount (fs, shares);
1732 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1734 gnc_table_layout_get_cell_changed (reg->table->layout,
1736 gnc_table_layout_get_cell_changed (reg->table->layout,
1738 gnc_table_layout_get_cell_changed (reg->table->layout,
1745 num = gnc_float_split_get_amount (fs);
1748 num = gnc_float_split_get_value (fs);
1756 unreconcile_splits (SplitRegister* reg)
1758 if (reg->unrecn_splits == NULL)
1760 PINFO (
"Unreconcile %d splits of reconciled transaction",
1761 g_list_length (reg->unrecn_splits));
1763 for (GList* node = reg->unrecn_splits; node; node = node->next)
1765 Split* split = node->data;
1768 PWARN (
"Unreconcile of split failed because its parent transaction wasn't open for editing");
1772 g_list_free (reg->unrecn_splits);
1773 reg->unrecn_splits = NULL;
1779 SRInfo* info = gnc_split_register_get_info (reg);
1780 Transaction* pending_trans;
1781 Transaction* blank_trans;
1789 ENTER (
"reg=%p, do_commit=%s", reg, do_commit ?
"TRUE" :
"FALSE");
1793 LEAVE (
"no register");
1798 gnc_get_current_book ());
1801 gnc_get_current_book ());
1810 LEAVE (
"no transaction");
1817 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1821 LEAVE (
"commit unnecessary");
1827 LEAVE (
"transaction not open");
1831 if (trans == pending_trans ||
1832 (trans == blank_trans && info->blank_split_edited))
1836 gnc_suspend_gui_refresh ();
1838 if (trans == blank_trans)
1844 info->blank_split_edited = FALSE;
1845 info->auto_complete = FALSE;
1850 if (trans == pending_trans)
1851 info->pending_trans_guid = *
guid_null ();
1853 PINFO (
"committing trans (%p)", trans);
1854 unreconcile_splits (reg);
1858 gnc_resume_gui_refresh ();
1861 DEBUG (
"leaving trans (%p) open", trans);
1863 LEAVE (
"unchanged cursor");
1867 DEBUG (
"save split=%p", split);
1868 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p, trans=%p",
1869 blank_split, blank_trans, pending_trans, trans);
1872 if (!gnc_split_register_check_cell (reg,
1873 gnc_table_get_current_cell_name (reg->table)))
1875 LEAVE (
"need another go at changing cell");
1879 if (!gnc_split_register_auto_calc (reg, split))
1881 LEAVE (
"auto calc failed");
1886 (void)gnc_split_register_get_account (reg, MXFRM_CELL);
1887 (void)gnc_split_register_get_account (reg, XFRM_CELL);
1892 LEAVE (
"no exchange rate");
1896 gnc_suspend_gui_refresh ();
1899 if (pending_trans != trans)
1906 g_warning (
"Impossible? committing pending %p", pending_trans);
1907 unreconcile_splits (reg);
1911 else if (pending_trans)
1913 g_critical (
"BUG DETECTED! pending transaction (%p) not open",
1915 g_assert_not_reached ();
1918 if (trans == blank_trans)
1928 PINFO (
"beginning edit of trans %p", trans);
1929 if (gnc_split_register_begin_edit_or_warn (info, trans))
1931 gnc_resume_gui_refresh ();
1932 LEAVE (
"transaction opened elsewhere");
1936 pending_trans = trans;
1947 if (split == blank_split && !info->blank_split_edited)
1954 account = gnc_split_register_get_default_account (reg);
1956 xaccSplitSetAccount (blank_split, account);
1976 reg->table->current_cursor_loc.vcell_loc,
1978 DEBUG (
"assigned cell to new split=%p", split);
1981 if ((info->cursor_hint_trans == trans) &&
1982 (info->cursor_hint_trans_split == trans_split) &&
1983 (info->cursor_hint_split == NULL))
1985 info->cursor_hint_split = split;
1986 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1990 DEBUG (
"updating trans=%p", trans);
1995 sd = gnc_split_register_save_data_new (
1996 trans, split, (info->trans_expanded ||
1997 reg->style == REG_STYLE_AUTO_LEDGER ||
1998 reg->style == REG_STYLE_JOURNAL));
1999 gnc_table_save_cells (reg->table, sd);
2000 gnc_split_register_save_data_destroy (sd);
2004 memo = memo ? memo :
"(null)";
2006 desc = desc ? desc :
"(null)";
2007 PINFO (
"finished saving split \"%s\" of trans \"%s\"", memo, desc);
2013 if (trans == blank_trans)
2018 info->auto_complete = FALSE;
2023 info->blank_split_edited = TRUE;
2030 g_assert (trans == blank_trans || trans == pending_trans);
2031 if (pending_trans == trans)
2033 pending_trans = NULL;
2034 info->pending_trans_guid = *
guid_null ();
2036 unreconcile_splits (reg);
2041 gnc_table_clear_current_cursor_changes (reg->table);
2043 gnc_resume_gui_refresh ();
2051 gnc_split_register_get_account_by_name (SplitRegister* reg, BasicCell* bcell,
2054 const char* placeholder = _ (
"The account %s does not allow transactions.");
2055 const char* missing = _ (
"The account %s does not exist. " 2056 "Would you like to create it?");
2060 static gboolean creating_account = FALSE;
2061 GtkWindow* parent = GTK_WINDOW (gnc_split_register_get_parent (reg));
2063 if (!name || (strlen (name) == 0))
2076 if (!account && !creating_account)
2079 if (!gnc_verify_dialog (parent, TRUE, missing, name))
2081 creating_account = TRUE;
2084 creating_account = FALSE;
2089 if (!creating_account)
2093 reg->show_leaf_accounts);
2094 if (g_strcmp0 (account_name, gnc_basic_cell_get_value (bcell)))
2097 gnc_combo_cell_set_value (cell, account_name);
2098 gnc_basic_cell_set_changed (&cell->cell, TRUE);
2100 g_free (account_name);
2106 gnc_error_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
2107 placeholder, fullname);
2118 gnc_split_register_get_account (SplitRegister* reg,
const char* cell_name)
2123 if (!gnc_table_layout_get_cell_changed (reg->table->layout, cell_name, TRUE))
2126 cell = gnc_table_layout_get_cell (reg->table->layout, cell_name);
2129 name = gnc_basic_cell_get_value (cell);
2130 return gnc_split_register_get_account_by_name (reg, cell, name);
2134 calculate_value (SplitRegister* reg)
2143 cell = (
PriceCell*)gnc_table_layout_get_cell (reg->table->layout,
2147 return gnc_numeric_sub_fixed (debit, credit);
2152 recalc_message_box (SplitRegister* reg, gboolean shares_changed,
2153 gboolean price_changed, gboolean value_changed)
2158 GList* radio_list = NULL;
2159 const char* title = _ (
"Recalculate Transaction");
2160 const char* message = _ (
"The values entered for this transaction " 2161 "are inconsistent. Which value would you " 2162 "like to have recalculated?");
2165 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2169 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Shares")));
2172 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2176 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Price")));
2179 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2183 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Value")));
2185 if (price_changed) default_value = 2;
2186 else default_value = 1;
2188 choice = gnc_choose_radio_option_dialog
2189 (gnc_split_register_get_parent (reg),
2196 for (node = radio_list; node; node = node->next)
2197 g_free (node->data);
2199 g_list_free (radio_list);
2205 recalculate_shares (Split* split, SplitRegister* reg,
2206 gnc_numeric value, gnc_numeric price, gboolean value_changed)
2208 gint64 denom = gnc_split_get_amount_denom (split);
2212 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
2214 gnc_basic_cell_set_changed (cell, TRUE);
2218 cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2219 gnc_basic_cell_set_changed (cell, FALSE);
2224 recalculate_price (Split* split, SplitRegister* reg,
2225 gnc_numeric value, gnc_numeric amount)
2227 BasicCell* price_cell;
2234 BasicCell* debit_cell;
2235 BasicCell* credit_cell;
2237 debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2240 credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2249 gnc_basic_cell_set_changed (debit_cell, TRUE);
2250 gnc_basic_cell_set_changed (credit_cell, TRUE);
2253 price_cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2255 gnc_basic_cell_set_changed (price_cell, TRUE);
2259 recalculate_value (Split* split, SplitRegister* reg,
2260 gnc_numeric price, gnc_numeric amount, gboolean shares_changed)
2262 BasicCell* debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2264 BasicCell* credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2266 gint64 denom = gnc_split_get_value_denom (split);
2273 gnc_basic_cell_set_changed (debit_cell, TRUE);
2274 gnc_basic_cell_set_changed (credit_cell, TRUE);
2278 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout,
2280 gnc_basic_cell_set_changed (cell, FALSE);
2285 gnc_split_register_auto_calc (SplitRegister* reg, Split* split)
2288 gboolean recalc_shares = FALSE;
2289 gboolean recalc_price = FALSE;
2290 gboolean recalc_value = FALSE;
2291 gboolean price_changed;
2292 gboolean value_changed;
2293 gboolean shares_changed;
2294 gnc_numeric calc_value;
2302 if (STOCK_REGISTER != reg->type &&
2303 CURRENCY_REGISTER != reg->type &&
2304 PORTFOLIO_LEDGER != reg->type)
2307 account = gnc_split_register_get_account (reg, XFRM_CELL);
2313 account = gnc_split_register_get_default_account (reg);
2318 price_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2320 value_changed = (gnc_table_layout_get_cell_changed (reg->table->layout,
2322 gnc_table_layout_get_cell_changed (reg->table->layout,
2324 shares_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2327 if (!price_changed && !value_changed && !shares_changed)
2334 gnc_commodity* acc_commodity;
2343 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2352 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2360 value = calculate_value (reg);
2382 recalc_price = TRUE;
2385 recalc_value = TRUE;
2389 recalc_shares = TRUE;
2394 if ((!recalc_shares) &&
2398 if (price_changed && value_changed)
2400 if (!shares_changed)
2401 recalc_shares = TRUE;
2403 else if (value_changed && shares_changed)
2404 recalc_price = TRUE;
2405 else if (price_changed && shares_changed)
2406 recalc_value = TRUE;
2412 denom = gnc_split_get_value_denom (split);
2418 if (!recalc_shares &&
2423 choice = recalc_message_box (reg, shares_changed,
2429 recalc_shares = TRUE;
2432 recalc_price = TRUE;
2435 recalc_value = TRUE;
2443 recalculate_shares (split, reg, value, price, value_changed);
2447 recalculate_price (split, reg, value, amount);
2448 price_changed = TRUE;
2451 recalculate_value (split, reg, price, amount, shares_changed);
2465 case ASSET_REGISTER:
2467 case CREDIT_REGISTER:
2469 case LIABILITY_REGISTER:
2471 case PAYABLE_REGISTER:
2473 case RECEIVABLE_REGISTER:
2476 case INCOME_REGISTER:
2478 case EXPENSE_REGISTER:
2480 case STOCK_REGISTER:
2481 case PORTFOLIO_LEDGER:
2483 case CURRENCY_REGISTER:
2485 case TRADING_REGISTER:
2487 case GENERAL_JOURNAL:
2489 case EQUITY_REGISTER:
2501 SRInfo* info = gnc_split_register_get_info (reg);
2506 if (info->debit_str)
2507 return info->debit_str;
2511 (gnc_split_register_type_to_account_type (reg->type));
2513 if (info->debit_str)
2514 return info->debit_str;
2516 info->debit_str = g_strdup (_ (
"Debit"));
2518 return info->debit_str;
2524 SRInfo* info = gnc_split_register_get_info (reg);
2529 if (info->credit_str)
2530 return info->credit_str;
2534 (gnc_split_register_type_to_account_type (reg->type));
2536 if (info->credit_str)
2537 return info->credit_str;
2539 info->credit_str = g_strdup (_ (
"Credit"));
2541 return info->credit_str;
2547 SRInfo* info = gnc_split_register_get_info (reg);
2548 Transaction* pending_trans;
2550 ENTER (
"reg=%p", reg);
2554 LEAVE (
"no register");
2558 if (gnc_table_current_cursor_changed (reg->table, FALSE))
2560 LEAVE (
"cursor changed");
2565 gnc_get_current_book ());
2568 LEAVE (
"open and pending txn");
2572 LEAVE (
"register unchanged");
2578 gboolean show_present)
2580 SRInfo* info = gnc_split_register_get_info (reg);
2585 info->show_present_divider = show_present;
2591 SRInfo* info = gnc_split_register_get_info (reg);
2596 return info->full_refresh;
2602 gnc_split_register_config_action (SplitRegister* reg)
2606 cell = (
ComboCell*) gnc_table_layout_get_cell (reg->table->layout,
2644 case ASSET_REGISTER:
2649 case CREDIT_REGISTER:
2659 case LIABILITY_REGISTER:
2666 case RECEIVABLE_REGISTER:
2667 case PAYABLE_REGISTER:
2674 case INCOME_REGISTER:
2684 case EXPENSE_REGISTER:
2685 case TRADING_REGISTER:
2691 case GENERAL_JOURNAL:
2692 case EQUITY_REGISTER:
2697 case STOCK_REGISTER:
2698 case PORTFOLIO_LEDGER:
2699 case CURRENCY_REGISTER:
2727 gnc_split_register_config_cells (SplitRegister* reg)
2731 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2736 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2742 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), TRUE);
2747 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), TRUE);
2752 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2757 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL),
2758 gnc_default_share_print_info ());
2761 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, TSHRS_CELL),
2762 gnc_default_share_print_info ());
2768 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, RATE_CELL),
2769 gnc_default_share_print_info ());
2774 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), FALSE);
2779 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), FALSE);
2784 case CURRENCY_REGISTER:
2785 case STOCK_REGISTER:
2786 case PORTFOLIO_LEDGER:
2789 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2798 gnc_split_register_config_action (reg);
2802 split_register_pref_changed (gpointer prefs, gchar* pref, gpointer user_data)
2804 SplitRegister* reg = user_data;
2807 g_return_if_fail (pref);
2811 info = reg->sr_info;
2815 if (g_str_has_suffix (pref, GNC_PREF_ACCOUNTING_LABELS))
2818 g_free (info->tdebit_str);
2819 g_free (info->tcredit_str);
2821 info->debit_str = NULL;
2822 info->tdebit_str = NULL;
2823 info->credit_str = NULL;
2824 info->tcredit_str = NULL;
2827 else if (g_str_has_suffix (pref, GNC_PREF_ACCOUNT_SEPARATOR))
2829 info->separator_changed = TRUE;
2831 else if (g_str_has_suffix (pref, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
2834 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2836 else if (g_str_has_suffix (pref, GNC_PREF_ALT_COLOR_BY_TRANS))
2839 GNC_PREF_ALT_COLOR_BY_TRANS);
2843 g_warning (
"split_register_pref_changed: Unknown preference %s", pref);
2848 split_register_book_option_changed (gpointer new_val, gpointer user_data)
2850 SplitRegister* reg = user_data;
2851 gboolean* new_data = (gboolean*)new_val;
2856 reg->use_tran_num_for_num_field = (*new_data ? FALSE : TRUE);
2860 gnc_split_register_init (SplitRegister* reg,
2863 gboolean use_double_line,
2864 gboolean do_auto_complete,
2865 gboolean is_template,
2866 gboolean mismatched_commodities)
2868 TableLayout* layout;
2874 GNC_PREF_ACCOUNTING_LABELS,
2875 split_register_pref_changed,
2878 GNC_PREF_ACCOUNT_SEPARATOR,
2879 split_register_pref_changed,
2882 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
2883 split_register_pref_changed,
2886 GNC_PREF_ALT_COLOR_BY_TRANS,
2887 split_register_pref_changed,
2889 gnc_book_option_register_cb (OPTION_NAME_NUM_FIELD_SOURCE,
2890 split_register_book_option_changed,
2893 reg->sr_info = NULL;
2895 reg->unrecn_splits = NULL;
2898 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2900 GNC_PREF_ALT_COLOR_BY_TRANS);
2904 reg->use_double_line = use_double_line;
2905 reg->do_auto_complete = do_auto_complete;
2906 reg->is_template = is_template;
2907 reg->mismatched_commodities = mismatched_commodities;
2908 reg->use_tran_num_for_num_field =
2915 model = gnc_template_register_model_new ();
2917 model = gnc_split_register_model_new ();
2918 model->handler_user_data = reg;
2921 control->user_data = reg;
2923 reg->table = gnc_table_new (layout, model, control);
2925 gnc_split_register_config_cells (reg);
2929 VirtualCellLocation vcell_loc = { 0, 0 };
2932 header = gnc_table_layout_get_cursor (reg->table->layout,
CURSOR_HEADER);
2939 VirtualLocation vloc;
2942 vloc.vcell_loc.virt_row = 1;
2943 vloc.vcell_loc.virt_col = 0;
2944 vloc.phys_row_offset = 0;
2945 vloc.phys_col_offset = 0;
2947 cursor = gnc_table_layout_get_cursor (reg->table->layout,
2948 CURSOR_SINGLE_LEDGER);
2956 PERR (
"Can't find valid initial location");
2964 gboolean use_double_line,
2965 gboolean is_template,
2966 gboolean mismatched_commodities)
2969 gboolean default_do_auto_complete = TRUE;
2971 reg = g_new0 (SplitRegister, 1);
2973 if (type >= NUM_SINGLE_REGISTER_TYPES)
2974 style = REG_STYLE_JOURNAL;
2976 gnc_split_register_init (reg,
2980 default_do_auto_complete,
2982 mismatched_commodities);
2991 gboolean use_double_line)
2996 if (reg->use_double_line && !use_double_line)
2998 VirtualLocation virt_loc = reg->table->current_cursor_loc;
3001 if (virt_loc.phys_row_offset)
3004 -virt_loc.phys_row_offset);
3011 virt_loc.vcell_loc.virt_row = 1;
3012 virt_loc.vcell_loc.virt_col = 0;
3013 virt_loc.phys_row_offset = 0;
3014 virt_loc.phys_col_offset = 0;
3019 reg->type = newtype;
3021 if (reg->type >= NUM_SINGLE_REGISTER_TYPES)
3022 newstyle = REG_STYLE_JOURNAL;
3024 reg->style = newstyle;
3025 reg->use_double_line = use_double_line;
3027 gnc_table_realize_gui (reg->table);
3033 g_return_if_fail (reg);
3034 gnc_table_model_set_reverse_sort (reg->table->model, reverse_sort);
3039 gboolean do_auto_complete)
3041 g_return_if_fail (reg);
3042 reg->do_auto_complete = do_auto_complete;
3046 gnc_split_register_destroy_info (SplitRegister* reg)
3053 if (reg->unrecn_splits != NULL)
3055 g_list_free (reg->unrecn_splits);
3056 reg->unrecn_splits = NULL;
3059 info = reg->sr_info;
3063 g_free (info->tdebit_str);
3064 g_free (info->tcredit_str);
3066 info->debit_str = NULL;
3067 info->tdebit_str = NULL;
3068 info->credit_str = NULL;
3069 info->tcredit_str = NULL;
3071 g_free (reg->sr_info);
3073 reg->sr_info = NULL;
3080 SRInfo* info = gnc_split_register_get_info (reg);
3082 g_return_if_fail (reg != NULL);
3084 info->user_data = user_data;
3085 info->get_parent = get_parent;
3089 gnc_split_register_cleanup (SplitRegister* reg)
3091 SRInfo* info = gnc_split_register_get_info (reg);
3092 Transaction* pending_trans;
3093 Transaction* blank_trans = NULL;
3096 ENTER (
"reg=%p", reg);
3099 gnc_get_current_book ());
3102 gnc_get_current_book ());
3104 gnc_suspend_gui_refresh ();
3109 if (blank_split != NULL)
3115 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p",
3116 blank_split, blank_trans, pending_trans);
3125 if (blank_trans == pending_trans)
3127 info->pending_trans_guid = *
guid_null ();
3128 pending_trans = NULL;
3131 info->auto_complete = FALSE;
3136 if (pending_trans != NULL)
3138 g_critical (
"BUG DETECTED: pending_trans=%p, blank_split=%p, blank_trans=%p",
3139 pending_trans, blank_split, blank_trans);
3140 g_assert_not_reached ();
3141 info->pending_trans_guid = *
guid_null ();
3147 else g_assert_not_reached ();
3149 pending_trans = NULL;
3152 gnc_split_register_destroy_info (reg);
3154 gnc_resume_gui_refresh ();
3162 g_return_if_fail (reg);
3164 ENTER (
"reg=%p", reg);
3167 GNC_PREF_ACCOUNTING_LABELS,
3168 split_register_pref_changed,
3171 GNC_PREF_ACCOUNT_SEPARATOR,
3172 split_register_pref_changed,
3175 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
3176 split_register_pref_changed,
3179 GNC_PREF_ALT_COLOR_BY_TRANS,
3180 split_register_pref_changed,
3182 gnc_book_option_remove_cb (OPTION_NAME_NUM_FIELD_SOURCE,
3183 split_register_book_option_changed,
3186 gnc_split_register_cleanup (reg);
3188 gnc_table_destroy (reg->table);
3199 gnc_table_model_set_read_only (reg->table->model, read_only);
3209 case ASSET_REGISTER:
3210 case CREDIT_REGISTER:
3211 case LIABILITY_REGISTER:
3212 case INCOME_REGISTER:
3213 case EXPENSE_REGISTER:
3214 case EQUITY_REGISTER:
3215 case TRADING_REGISTER:
3217 return REG_TYPE_GROUP_CURRENCY;
3220 case PAYABLE_REGISTER:
3221 case RECEIVABLE_REGISTER:
3223 return REG_TYPE_GROUP_APAR;
3227 case GENERAL_JOURNAL:
3230 return REG_TYPE_GROUP_JOURNAL;
3233 case STOCK_REGISTER:
3234 case CURRENCY_REGISTER:
3236 return REG_TYPE_GROUP_STOCK;
3239 case PORTFOLIO_LEDGER:
3241 return REG_TYPE_GROUP_PORTFOLIO;
3245 return REG_TYPE_GROUP_UNKNOWN;
3246 PERR (
"unknown register type %d\n", reg->type);
CursorClass gnc_split_register_get_current_cursor_class(SplitRegister *reg)
Returns the class of a register's current cursor.
Split * gnc_split_register_get_current_trans_split(SplitRegister *reg, VirtualCellLocation *trans_split_loc)
Gets the anchoring split of the transaction at the current cursor location, which may be on the trans...
Public declarations for GncLedgerDisplay class.
The RecnCell object implements a cell handler that will cycle through a series of single-character va...
gpointer vcell_data
Array of physical cells.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
The CompletionCell object implements a cell handler with a "combination-box" pull-down menu in it...
const char * gnc_split_register_get_credit_string(SplitRegister *reg)
Return the credit string used in the register.
const char * xaccAccountGetLastNum(const Account *acc)
Get the last num field of an Account.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
void gnc_split_register_set_reverse_sort(SplitRegister *reg, gboolean reverse_sort)
Sets a split register's reverse sort order based on register.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
Account * gnc_ui_new_accounts_from_name_window(GtkWindow *parent, const char *name)
Display a modal window for creating a new account.
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.
Date and Time handling routines.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
#define GNC_COMMODITY_MAX_FRACTION
Max fraction is 10^9 because 10^10 would require changing it to an int64_t.
gboolean gnc_split_register_save(SplitRegister *reg, gboolean do_commit)
Copy the contents of the current cursor to a split.
This file contains the functions to present a gui to the user for creating a new account or editing a...
void gnc_split_register_destroy(SplitRegister *reg)
Destroys a split register.
void gnc_split_register_unvoid_current_trans(SplitRegister *reg)
Unvoids the transaction associated with the current cursor, if non-NULL.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false. ...
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. ...
void gnc_split_register_expand_current_trans(SplitRegister *reg, gboolean expand)
Expand the current transaction if it is collapsed.
Expense accounts are used to denote expenses.
#define PINFO(format, args...)
Print an informational note.
void gnc_split_register_set_trans_visible(SplitRegister *reg, VirtualCellLocation vcell_loc, gboolean visible, gboolean only_blank_split)
Set the visibility of the split rows belonging to a transaction located at vcell_loc.
Transaction * gnc_split_register_get_current_trans(SplitRegister *reg)
Gets the transaction at the current cursor location, which may be on the transaction itself or on any...
gboolean xaccSplitDestroy(Split *split)
Destructor.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
SplitRegisterTypeGroup gnc_split_register_get_register_group(SplitRegister *reg)
Group registers for common layouts.
void gnc_split_register_delete_current_split(SplitRegister *reg)
Deletes the split associated with the current cursor, if both are non-NULL.
holds information about each virtual cell.
#define DEBUG(format, args...)
Print a debugging message.
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
Returns TRUE if this book uses split action field as the 'Num' field, FALSE if it uses transaction nu...
char xaccSplitGetReconcile(const Split *split)
Returns the value of the reconcile flag.
void gnc_table_move_cursor_gui(Table *table, VirtualLocation new_virt_loc)
will move the cursor and its GUI to the indicated location.
TableControl specialized for the SplitRegister.
gboolean gnc_table_find_close_valid_cell(Table *table, VirtualLocation *virt_loc, gboolean exact_pointer)
Find a close valid cell.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
CursorClass gnc_split_register_get_cursor_class(SplitRegister *reg, VirtualCellLocation vcell_loc)
Returns the class of the cursor at the given virtual cell location.
gboolean gnc_split_register_full_refresh_ok(SplitRegister *reg)
Private function – outsiders must not use this.
void xaccTransSetNum(Transaction *trans, const char *xnum)
Sets the transaction Number (or ID) field; rather than use this function directly, see 'gnc_set_num_action' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically.
Save handlers for the SplitRegister Model and Template SplitRegister model.
void xaccTransRecordPrice(Transaction *trans, PriceSource source)
The xaccTransRecordPrice() method iterates through the splits and and record the non-currency equival...
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
TableModels specialized for SplitRegister and template SplitRegister.
Use any denominator which gives an exactly correct ratio of numerator to denominator.
Create the actual register visual layout.
void gnc_split_register_set_data(SplitRegister *reg, gpointer user_data, SRGetParentCallback get_parent)
Sets the user data and callback hooks for the register.
void gnc_split_register_delete_current_trans(SplitRegister *reg)
Deletes the transaction associated with the current cursor, if both are non-NULL. ...
SplitRegisterTypeGroup
Register group types.
void gnc_split_register_set_read_only(SplitRegister *reg, gboolean read_only)
Sets whether a register window is "read only".
#define PERR(format, args...)
Log a serious error.
void gnc_copy_trans_onto_trans(Transaction *from, Transaction *to, gboolean use_cut_semantics, Account *template_account, gboolean do_commit)
Private function – outsiders must not use this.
#define ENTER(format, args...)
Print a function entry debugging message.
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
const char * gnc_account_get_debit_string(GNCAccountType acct_type)
Get the debit string associated with this account type.
gboolean gnc_strisnum(const gchar *s)
Returns true if string s is a number, possibly surrounded by whitespace.
void gnc_combo_cell_add_ignore_string(ComboCell *cell, const char *ignore_string)
Add a string to a list of strings which, if the cell has that value, will cause the cell to be unedit...
void gnc_table_set_virt_cell_data(Table *table, VirtualCellLocation vcell_loc, gconstpointer vcell_data)
Set the virtual cell data for a particular location.
void xaccAccountSetLastNum(Account *acc, const char *num)
Set the last num field of an Account.
gboolean gnc_split_register_current_trans_expanded(SplitRegister *reg)
Return TRUE if current trans is expanded and style is REG_STYLE_LEDGER.
const char * xaccTransGetDocLink(const Transaction *trans)
Gets the transaction Document Link.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
#define VREC
split is void
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
Account used to record multiple commodity transactions.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
#define PWARN(format, args...)
Log a warning.
Stock accounts will typically be shown in registers which show three columns: price, number of shares, and value.
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
The xaccTransLookup() subroutine will return the transaction associated with the given id...
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
gboolean gnc_split_register_has_copied_item(void)
Return TRUE if copied_item holds a transaction or split.
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
The xaccSplitLookup() subroutine will return the split associated with the given id, or NULL if there is no such split.
void gnc_table_refresh_gui(Table *table, gboolean do_scroll)
Refresh the whole GUI from the table.
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
void gnc_split_register_redraw(SplitRegister *reg)
Causes a redraw of the register window associated with reg.
const char * gnc_split_register_get_debit_string(SplitRegister *reg)
Return the debit string used in the register.
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it...
void xaccTransVoid(Transaction *trans, const char *reason)
xaccTransVoid voids a transaction.
CursorClass
Types of cursors.
Income accounts are used to denote income.
#define YREC
The Split has been reconciled.
Account * gnc_account_lookup_by_code(const Account *parent, const char *code)
The gnc_account_lookup_by_code() subroutine works like gnc_account_lookup_by_name, but uses the account code.
char * gnc_get_account_name_for_split_register(const Account *account, gboolean show_leaf_accounts)
Get either the full name of the account or the simple name, depending on the show_leaf_accounts.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
void gnc_split_register_cut_current(SplitRegister *reg)
Equivalent to copying the current entity and the deleting it with the appropriate delete method...
The PriceCell object implements a cell handler that stores a single double-precision value...
void gnc_combo_cell_add_menu_item(ComboCell *cell, const char *menustr)
Add a menu item to the list.
Split * gnc_split_register_get_blank_split(SplitRegister *reg)
Gets the blank split for a register.
VirtualCell * gnc_table_get_virtual_cell(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell associated with a particular virtual location.
#define CURSOR_HEADER
Standard Cursor Names.
void gnc_date_cell_get_date(DateCell *cell, time64 *time, gboolean warn)
Set a time64 to the value in the DateCell.
gboolean gnc_split_register_changed(SplitRegister *reg)
Returns TRUE if the register has changed cells.
void gnc_combo_cell_set_strict(ComboCell *cell, gboolean strict)
Determines whether the cell will accept strings not in the menu.
The bank account type denotes a savings or checking account held at a bank.
void gnc_split_register_config(SplitRegister *reg, SplitRegisterType newtype, SplitRegisterStyle newstyle, gboolean use_double_line)
Sets a split register's type, style or line use.
private declarations for SplitRegister
void gnc_split_register_cancel_cursor_split_changes(SplitRegister *reg)
Cancels any changes made to the current cursor, reloads the cursor from the engine, reloads the table from the cursor, and updates the GUI.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
void gnc_split_register_void_current_trans(SplitRegister *reg, const char *reason)
Voids the transaction associated with the current cursor, if non-NULL.
TableControl * gnc_split_register_control_new(void)
Create a new TableControl specialized for the SplitRegister.
void gnc_table_set_vcell(Table *table, CellBlock *cursor, gconstpointer vcell_data, gboolean visible, gboolean start_primary_color, VirtualCellLocation vcell_loc)
Indicate what handler should be used for a given virtual block.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
Division.
#define xaccSplitGetGUID(X)
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
gboolean gnc_split_register_get_split_amount_virt_loc(SplitRegister *reg, Split *split, VirtualLocation *virt_loc)
Searches the split register for the given split and determines the location of either its credit (if ...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
gnc_numeric xaccSplitGetSharePrice(const Split *split)
Returns the price of the split, that is, the value divided by the amount.
gboolean gnc_table_move_vertical_position(Table *table, VirtualLocation *virt_loc, int phys_row_offset)
Moves away from virtual location virt_loc by phys_row_offset physical rows.
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
Inverse of xaccTransGetSplit()
void xaccTransUnvoid(Transaction *trans)
xaccTransUnvoid restores a voided transaction to its original state.
API for checkbook register display area.
The currency account type indicates that the account is a currency trading account.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
void gnc_price_cell_set_fraction(PriceCell *cell, int fraction)
Sets the fraction used for rounding.
Split * xaccMallocSplit(QofBook *book)
Constructor.
gboolean gnc_split_register_is_blank_split(SplitRegister *reg, Split *split)
Return TRUE if split is the blank_split.
Account * gnc_account_lookup_for_register(const Account *base_account, const char *name)
Retrieve the account matching the given name starting from the descendants of base_account.
#define xaccTransGetGUID(X)
Generic api to store and retrieve preferences.
Split * gnc_split_register_duplicate_current(SplitRegister *reg)
Duplicates either the current transaction or the current split depending on the register mode and cur...
void gnc_split_register_cancel_cursor_trans_changes(SplitRegister *reg)
Cancels any changes made to the current pending transaction, reloads the table from the engine...
The NumCell object implements a number handling cell.
void gnc_split_register_paste_current(SplitRegister *reg)
Pastes a previous copied entity onto the current entity, but only if the copied and current entity ha...
unsigned int visible
Used by higher-level code.
void gnc_price_cell_set_print_info(PriceCell *cell, GNCPrintAmountInfo print_info)
set the printing context of the price cell
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
gboolean gnc_split_register_get_split_virt_loc(SplitRegister *reg, Split *split, VirtualCellLocation *vcell_loc)
Searches the split register for a given split.
const char * gnc_account_get_credit_string(GNCAccountType acct_type)
Get the credit string associated with this account type.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
void gnc_completion_cell_set_strict(CompletionCell *cell, gboolean strict)
Determines whether the cell will accept strings not in the menu.
void gnc_split_register_empty_current_trans_except_split(SplitRegister *reg, Split *split)
Deletes the non-transaction splits associated with the current cursor, if both are non-NULL...
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
void gnc_split_register_set_auto_complete(SplitRegister *reg, gboolean do_auto_complete)
Sets whether a register uses auto-completion.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
void gnc_table_set_virt_cell_cursor(Table *table, VirtualCellLocation vcell_loc, CellBlock *cursor)
Set the cellblock handler for a virtual cell.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
void xaccTransSetDocLink(Transaction *trans, const char *doclink)
Sets the transaction Document Link.
Declarations for the Table object.
#define LEAVE(format, args...)
Print a function exit debugging message.
GtkWidget *(* SRGetParentCallback)(gpointer user_data)
Callback function type.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
gboolean gnc_price_cell_set_value(PriceCell *cell, gnc_numeric amount)
updates amount, returns TRUE if string representation actually changed
void gnc_completion_cell_set_autosize(CompletionCell *cell, gboolean autosize)
Determines whether the popup list autosizes itself or uses all available space.
time64 gnc_time(time64 *tbuf)
get the current time
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
The DateCell object implements a date handling cell.
void gnc_split_register_change_blank_split_ref(SplitRegister *reg, Split *split)
Change the blank_split reference from pointing to split to another split of the transaction.
gboolean gnc_split_register_handle_exchange(SplitRegister *reg, gboolean force_dialog)
If needed display the transfer dialog to get a price/exchange rate and adjust the price cell accordin...
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
void gnc_split_register_show_present_divider(SplitRegister *reg, gboolean show_present)
If TRUE, visually indicate the demarcation between splits with post dates prior to the present...
Equity account is used to balance the balance sheet.
SplitRegisterType
Register types.
gint gnc_numeric_same(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Equivalence predicate: Convert both a and b to denom using the specified DENOM and method HOW...
TableLayout * gnc_split_register_layout_new(SplitRegister *reg)
Generate the split register layout.
void gnc_price_cell_set_debt_credit_value(PriceCell *debit, PriceCell *credit, gnc_numeric amount)
updates two cells; the deb cell if amt is negative, the credit cell if amount is positive, and makes the other cell blank.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
The type used to store guids in C.
gnc_numeric gnc_price_cell_get_value(PriceCell *cell)
return the value of a price cell
Split * gnc_split_register_get_current_split(SplitRegister *reg)
Returns the split at which the cursor is currently located.
SplitRegister * gnc_split_register_new(SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line, gboolean is_template, gboolean mismatched_commodities)
Creates a new split register.
void gnc_table_move_cursor(Table *table, VirtualLocation new_virt_loc)
will move the cursor (but not the cursor GUI) to the indicated location.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
void xaccTransRollbackEdit(Transaction *trans)
The xaccTransRollbackEdit() routine rejects all edits made, and sets the transaction back to where it...
SplitRegisterStyle
Register styles.
void gnc_combo_cell_set_autosize(ComboCell *cell, gboolean autosize)
Determines whether the popup list autosizes itself or uses all available space.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
The Credit card account is used to denote credit (e.g.
#define NREC
not reconciled or cleared
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
void gnc_split_register_copy_current(SplitRegister *reg)
Makes a copy of the current entity, either a split or a transaction, so that it can be pasted later...
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...