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;
109 gnc_copy_split_onto_split (Split* from, Split* to, gboolean use_cut_semantics)
113 if ((from == NULL) || (to == NULL))
116 fs = gnc_split_to_float_split (from);
120 gnc_float_split_to_split (fs, to);
121 gnc_float_split_free (fs);
126 gboolean use_cut_semantics,
131 if ((from == NULL) || (to == NULL))
134 ft = gnc_txn_to_float_txn (from, use_cut_semantics);
138 gnc_float_txn_to_txn (ft, to, do_commit);
139 gnc_float_txn_free (ft);
143 gnc_split_get_value_denom (Split* split)
145 gnc_commodity* currency;
162 gnc_split_get_amount_denom (Split* split)
180 gnc_split_register_begin_edit_or_warn (SRInfo* info, Transaction* trans)
182 ENTER (
"info=%p, trans=%p", info, trans);
189 LEAVE (
"opened and marked pending");
195 gnc_get_current_book ());
198 if (trans == blank_trans)
203 LEAVE (
"already open, now pending.");
208 GtkWindow* parent = NULL;
209 if (info->get_parent)
210 parent = GTK_WINDOW (info->get_parent (info->user_data));
211 gnc_error_dialog (parent,
"%s",
212 _ (
"This transaction is already being edited in another register. Please finish editing it there first."));
213 LEAVE (
"already editing");
224 SRInfo* info = gnc_split_register_get_info (reg);
225 VirtualLocation virt_loc;
230 if (reg->style == REG_STYLE_AUTO_LEDGER ||
231 reg->style == REG_STYLE_JOURNAL)
235 if (! (expand ^ info->trans_expanded))
240 virt_loc = reg->table->current_cursor_loc;
241 gnc_split_register_get_trans_split (reg, virt_loc.vcell_loc,
242 &virt_loc.vcell_loc);
248 PERR (
"Can't find place to go!");
253 info->trans_expanded = expand;
256 reg->table->current_cursor_loc.vcell_loc,
257 gnc_split_register_get_active_cursor (reg));
260 reg, reg->table->current_cursor_loc.vcell_loc, expand, FALSE);
262 virt_loc = reg->table->current_cursor_loc;
263 if (!expand || !gnc_table_virtual_loc_valid (reg->table, virt_loc, FALSE))
269 PERR (
"Can't find place to go!");
277 gnc_split_register_show_trans (reg,
278 reg->table->current_cursor_loc.vcell_loc);
284 SRInfo* info = gnc_split_register_get_info (reg);
289 if (reg->style == REG_STYLE_AUTO_LEDGER ||
290 reg->style == REG_STYLE_JOURNAL)
293 return info->trans_expanded;
300 VirtualCellLocation vcell_loc;
311 vcell_loc = reg->table->current_cursor_loc.vcell_loc;
313 vcell_loc.virt_row--;
315 split = gnc_split_register_get_split (reg, vcell_loc);
326 return gnc_split_register_get_split (
327 reg, reg->table->current_cursor_loc.vcell_loc);
333 SRInfo* info = gnc_split_register_get_info (reg);
335 if (!reg)
return NULL;
337 return xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ());
342 VirtualCellLocation* vcell_loc)
348 if (!reg || !split)
return FALSE;
355 for (v_row =
table->num_virt_rows - 1; v_row > 0; v_row--)
356 for (v_col = 0; v_col <
table->num_virt_cols; v_col++)
358 VirtualCellLocation vc_loc = { v_row, v_col };
382 VirtualLocation* virt_loc)
384 VirtualLocation v_loc;
386 const char* cell_name;
396 switch (cursor_class)
398 case CURSOR_CLASS_SPLIT:
399 case CURSOR_CLASS_TRANS:
406 if (!gnc_table_get_cell_location (reg->table, cell_name,
407 v_loc.vcell_loc, &v_loc))
410 if (virt_loc == NULL)
421 SRInfo* info = gnc_split_register_get_info (reg);
430 ENTER (
"reg=%p", reg);
433 gnc_get_current_book ());
441 LEAVE (
"no transaction");
448 if (cursor_class == CURSOR_CLASS_NONE)
450 LEAVE (
"no cursor class");
455 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
457 LEAVE (
"no split with transaction class");
461 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
465 if (!changed && ((split == NULL) || (split == blank_split)))
467 LEAVE (
"skip unchanged blank split");
471 gnc_suspend_gui_refresh ();
477 GtkWidget* dialog, *window;
479 const char* title = _ (
"Save transaction before duplicating?");
480 const char* message =
481 _ (
"The current transaction has been changed. Would you like to " 482 "record the changes before duplicating the transaction, or " 483 "cancel the duplication?");
485 window = gnc_split_register_get_parent (reg);
486 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
487 GTK_DIALOG_DESTROY_WITH_PARENT,
488 GTK_MESSAGE_QUESTION,
491 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
493 gtk_dialog_add_button (GTK_DIALOG (dialog),
494 _ (
"_Record"), GTK_RESPONSE_ACCEPT);
495 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_DUP);
496 gtk_widget_destroy (dialog);
498 if (response != GTK_RESPONSE_ACCEPT)
500 gnc_resume_gui_refresh ();
501 LEAVE (
"save cancelled");
517 if (cursor_class == CURSOR_CLASS_SPLIT)
521 gboolean new_act_num = FALSE;
530 if (!reg->use_tran_num_for_num_field
534 const char* in_num = NULL;
535 const char* title = _ (
"New Split Information");
536 time64 date = info->last_date_entered;
541 in_num = gnc_get_num_action (NULL, split);
543 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg),
544 title, FALSE, &date, in_num, &out_num,
545 NULL, NULL, NULL, NULL))
547 gnc_resume_gui_refresh ();
548 LEAVE (
"dup cancelled");
557 xaccSplitSetParent (new_split, trans);
558 gnc_copy_split_onto_split (split, new_split, FALSE);
560 gnc_set_num_action (NULL, new_split, out_num, NULL);
570 gnc_split_register_get_default_account (reg),
574 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
576 if (gnc_num_cell_set_last_num (num_cell, out_num))
577 gnc_split_register_set_last_num (reg, out_num);
585 return_split = new_split;
587 info->cursor_hint_split = new_split;
588 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
596 Transaction* new_trans;
597 int trans_split_index;
599 const char* in_num = NULL;
600 const char* in_tnum = NULL;
601 char* out_num = NULL;
602 char* out_tnum = NULL;
603 char* out_tdoclink = NULL;
606 gnc_get_current_book ());
610 date = info->last_date_entered;
612 account = gnc_split_register_get_default_account (reg);
614 if (account &&
gnc_strisnum (gnc_get_num_action (trans, trans_split)))
617 in_num = gnc_get_num_action (trans, trans_split);
619 in_tnum = (reg->use_tran_num_for_num_field
621 : gnc_get_num_action (trans, NULL));
623 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg), NULL,
624 TRUE, &date, in_num, &out_num, in_tnum, &out_tnum,
627 gnc_resume_gui_refresh ();
628 LEAVE (
"dup cancelled");
632 if (use_autoreadonly)
636 gnc_get_current_book ());
638 if (g_date_compare (&d, readonly_threshold) < 0)
640 GtkWidget* dialog = gtk_message_dialog_new (NULL,
644 "%s", _ (
"Cannot store a transaction at this date"));
645 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
646 "%s", _ (
"The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. " 647 "This setting can be changed in File->Properties->Accounts."));
648 gtk_dialog_run (GTK_DIALOG (dialog));
649 gtk_widget_destroy (dialog);
651 g_date_free (readonly_threshold);
654 g_date_free (readonly_threshold);
663 gnc_resume_gui_refresh ();
678 if (out_tdoclink == NULL)
681 g_free (out_tdoclink);
684 gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
685 if (!reg->use_tran_num_for_num_field)
689 gnc_set_num_action (NULL,
698 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
700 if (gnc_num_cell_set_last_num (num_cell, out_num))
701 gnc_split_register_set_last_num (reg, out_num);
704 if (!reg->use_tran_num_for_num_field)
714 info->cursor_hint_trans = new_trans;
715 info->cursor_hint_split = return_split;
716 info->cursor_hint_trans_split = trans_split;
717 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
719 info->trans_expanded = FALSE;
723 gnc_resume_gui_refresh ();
730 gnc_split_register_copy_current_internal (SplitRegister* reg,
731 gboolean use_cut_semantics)
733 SRInfo* info = gnc_split_register_get_info (reg);
742 g_return_if_fail (reg);
743 ENTER (
"reg=%p, use_cut_semantics=%s", reg,
744 use_cut_semantics ?
"TRUE" :
"FALSE");
747 gnc_get_current_book ());
761 if (cursor_class == CURSOR_CLASS_NONE)
763 LEAVE (
"no cursor class");
768 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
770 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
771 LEAVE (
"transaction cursor with no anchoring split");
775 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
778 if (!changed && ((split == NULL) || (split == blank_split)))
787 LEAVE (
"nothing to copy/cut");
796 if (cursor_class == CURSOR_CLASS_SPLIT)
799 new_fs = gnc_split_to_float_split (split);
804 gnc_split_register_save_to_copy_buffer (reg, NULL, new_fs,
813 new_ft = gnc_txn_to_float_txn (trans, use_cut_semantics);
823 if (split_index >= 0)
824 fs = gnc_float_txn_get_float_split (new_ft, split_index);
828 gnc_split_register_save_to_copy_buffer (reg, new_ft, fs,
832 copied_item.leader_guid = info->default_account;
837 if (!new_fs && !new_ft)
839 g_warning (
"BUG DETECTED: copy failed");
840 LEAVE (
"copy failed");
846 copied_item.fs = new_fs;
847 copied_item.ftype = GNC_TYPE_SPLIT;
851 copied_item.ft = new_ft;
852 copied_item.ftype = GNC_TYPE_TRANSACTION;
855 copied_item.cursor_class = cursor_class;
856 gnc_hook_add_dangler (HOOK_BOOK_CLOSED, clear_copied_item, NULL, NULL);
857 LEAVE (
"%s %s", use_cut_semantics ?
"cut" :
"copied",
858 cursor_class == CURSOR_CLASS_SPLIT ?
"split" :
"transaction");
864 gnc_split_register_copy_current_internal (reg, FALSE);
870 SRInfo* info = gnc_split_register_get_info (reg);
878 gnc_get_current_book ());
889 if (cursor_class == CURSOR_CLASS_NONE)
893 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
896 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
899 if (!changed && ((split == NULL) || (split == blank_split)))
902 gnc_split_register_copy_current_internal (reg, TRUE);
904 if (cursor_class == CURSOR_CLASS_SPLIT)
913 SRInfo* info = gnc_split_register_get_info (reg);
916 Transaction* blank_trans;
921 ENTER (
"reg=%p", reg);
923 if (copied_item.cursor_class == CURSOR_CLASS_NONE)
925 LEAVE (
"no copied cursor class");
930 gnc_get_current_book ());
940 LEAVE (
"no transaction");
947 if (cursor_class == CURSOR_CLASS_NONE)
949 LEAVE (
"no current cursor class");
954 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
956 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
957 LEAVE (
"transaction cursor with no anchoring split");
961 if (cursor_class == CURSOR_CLASS_SPLIT)
963 const char* message = _ (
"You are about to overwrite an existing split. " 964 "Are you sure you want to do that?");
965 const char* anchor_message = _ (
"This is the split anchoring this transaction " 966 "to the register. You may not overwrite it from " 967 "this register window. You may overwrite it if " 968 "you navigate to a register that shows another " 969 "side of this same transaction.");
971 if (copied_item.cursor_class == CURSOR_CLASS_TRANS)
974 LEAVE (
"can't copy trans to split");
981 if ((reg->type != GENERAL_JOURNAL) &&
984 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
985 "%s", anchor_message);
986 LEAVE (
"anchore split");
989 else if (!gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
990 FALSE,
"%s", message))
992 LEAVE (
"user cancelled");
998 if (gnc_split_register_begin_edit_or_warn (info, trans))
1000 LEAVE (
"can't begin editing");
1004 gnc_suspend_gui_refresh ();
1010 xaccSplitSetParent (split, trans);
1013 if (copied_item.ftype != GNC_TYPE_SPLIT)
1015 LEAVE (
"copy buffer doesn't represent a split");
1019 gnc_float_split_to_split (copied_item.fs, split);
1023 const char *message = _(
"You are about to overwrite an existing " 1025 "Are you sure you want to do that?");
1028 int trans_split_index;
1032 if (copied_item.cursor_class == CURSOR_CLASS_SPLIT)
1034 LEAVE (
"can't copy split to transaction");
1039 if (copied_item.ftype != GNC_TYPE_TRANSACTION)
1041 LEAVE (
"copy buffer doesn't represent a transaction");
1046 if (split != blank_split &&
1047 !gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1048 FALSE,
"%s", message))
1050 LEAVE (
"user cancelled");
1055 if (gnc_split_register_begin_edit_or_warn (info, trans))
1057 LEAVE (
"can't begin editing");
1061 gnc_suspend_gui_refresh ();
1063 DEBUG (
"Pasting txn, trans=%p, split=%p, blank_trans=%p, blank_split=%p",
1064 trans, split, blank_trans, blank_split);
1070 gnc_get_current_book ());
1071 default_account = gnc_split_register_get_default_account (reg);
1072 if (copied_leader && default_account)
1074 gnc_float_txn_to_txn_swap_accounts (copied_item.ft, trans,
1076 default_account, FALSE);
1079 gnc_float_txn_to_txn (copied_item.ft, trans, FALSE);
1082 if (split_index >= num_splits)
1085 if (trans == blank_trans)
1088 gint anchor_split_index = copied_item.anchor_split_index;
1089 if (anchor_split_index > num_splits)
1090 anchor_split_index = 0;
1094 info->blank_split_edited = TRUE;
1095 info->auto_complete = FALSE;
1096 DEBUG (
"replacement blank_split=%p", blank_split);
1103 info->cursor_hint_trans = trans;
1107 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
1111 gnc_resume_gui_refresh ();
1118 SRInfo* info = gnc_split_register_get_info (reg);
1119 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1120 gnc_get_current_book ());
1122 if (split == current_blank_split)
1131 SRInfo* info = gnc_split_register_get_info (reg);
1132 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1133 gnc_get_current_book ());
1134 Split* pref_split = NULL;
1135 Split* other_split = NULL;
1143 if (s != current_blank_split)
1152 if (pref_split != NULL)
1154 else if (other_split != NULL)
1161 SRInfo* info = gnc_split_register_get_info (reg);
1162 Transaction* pending_trans;
1170 gnc_get_current_book ());
1173 gnc_get_current_book ());
1183 if (split == blank_split)
1189 gnc_suspend_gui_refresh ();
1194 if (trans == pending_trans)
1200 g_assert (!pending_trans);
1201 if (gnc_split_register_begin_edit_or_warn (info, trans))
1203 gnc_resume_gui_refresh ();
1209 gnc_resume_gui_refresh ();
1216 SRInfo* info = gnc_split_register_get_info (reg);
1217 Transaction* pending_trans;
1223 ENTER (
"reg=%p", reg);
1226 LEAVE (
"no register");
1231 gnc_get_current_book ());
1233 gnc_get_current_book ());
1243 gnc_suspend_gui_refresh ();
1249 if (split == blank_split)
1251 DEBUG (
"deleting blank split");
1253 info->auto_complete = FALSE;
1257 info->trans_expanded = FALSE;
1261 if (trans == pending_trans)
1263 DEBUG (
"clearing pending trans");
1264 info->pending_trans_guid = *
guid_null ();
1265 pending_trans = NULL;
1272 DEBUG (
"committing");
1275 gnc_resume_gui_refresh ();
1283 SRInfo* info = gnc_split_register_get_info (reg);
1284 Transaction* pending_trans;
1292 gnc_get_current_book ());
1294 gnc_get_current_book ());
1302 if (split == blank_split)
1309 info->trans_expanded = FALSE;
1311 gnc_suspend_gui_refresh ();
1317 if (trans == pending_trans)
1319 info->pending_trans_guid = *
guid_null ();
1320 pending_trans = NULL;
1324 PERR (
"We should not be voiding an open transaction.");
1327 gnc_resume_gui_refresh ();
1333 SRInfo* info = gnc_split_register_get_info (reg);
1334 Transaction* pending_trans;
1342 gnc_get_current_book ());
1344 gnc_get_current_book ());
1352 if (split == blank_split)
1359 info->trans_expanded = FALSE;
1361 gnc_suspend_gui_refresh ();
1368 if (trans == pending_trans)
1370 info->pending_trans_guid = *
guid_null ();
1371 pending_trans = NULL;
1374 gnc_resume_gui_refresh ();
1383 Transaction* pending;
1387 if ((reg == NULL) || (split == NULL))
1390 gnc_suspend_gui_refresh ();
1391 info = gnc_split_register_get_info (reg);
1392 pending =
xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ());
1397 if (gnc_split_register_begin_edit_or_warn (info, trans))
1399 gnc_resume_gui_refresh ();
1403 else if (pending == trans)
1407 else g_assert_not_reached ();
1416 gnc_resume_gui_refresh ();
1421 gnc_split_register_empty_current_trans (SplitRegister* reg)
1433 VirtualLocation virt_loc;
1438 virt_loc = reg->table->current_cursor_loc;
1440 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1445 gnc_table_clear_current_cursor_changes (reg->table);
1456 SRInfo* info = gnc_split_register_get_info (reg);
1457 Transaction* pending_trans, *blank_trans;
1458 gboolean refresh_all = FALSE;
1461 gnc_get_current_book ());
1465 if (pending_trans == blank_trans)
1480 gnc_suspend_gui_refresh ();
1484 info->pending_trans_guid = *
guid_null ();
1486 gnc_resume_gui_refresh ();
1489 gnc_gui_refresh_all ();
1497 gnc_ledger_display_refresh_by_split_register (reg);
1503 gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
1505 gboolean use_cut_semantics)
1513 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1522 if (gnc_table_layout_get_cell_changed (reg->table->layout, DATE_CELL, TRUE))
1526 cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
1531 if (gnc_table_layout_get_cell_changed (reg->table->layout, NUM_CELL, TRUE))
1535 value = gnc_table_layout_get_cell_value (reg->table->layout, NUM_CELL);
1536 if (reg->use_tran_num_for_num_field)
1543 if (gnc_table_layout_get_cell_changed (reg->table->layout, TNUM_CELL, TRUE))
1547 value = gnc_table_layout_get_cell_value (reg->table->layout, TNUM_CELL);
1548 if (!reg->use_tran_num_for_num_field)
1553 if (gnc_table_layout_get_cell_changed (reg->table->layout, DESC_CELL, TRUE))
1557 value = gnc_table_layout_get_cell_value (reg->table->layout, DESC_CELL);
1561 if (gnc_table_layout_get_cell_changed (reg->table->layout, NOTES_CELL, TRUE))
1565 value = gnc_table_layout_get_cell_value (reg->table->layout, NOTES_CELL);
1569 if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, TRUE))
1574 cell = gnc_table_layout_get_cell (reg->table->layout, RECN_CELL);
1575 flag = gnc_recn_cell_get_flag ((
RecnCell*) cell);
1577 gnc_float_split_set_reconcile_state (fs, flag);
1580 if (gnc_table_layout_get_cell_changed (reg->table->layout, ACTN_CELL, TRUE))
1584 value = gnc_table_layout_get_cell_value (reg->table->layout, ACTN_CELL);
1585 gnc_float_split_set_action (fs, value);
1588 if (gnc_table_layout_get_cell_changed (reg->table->layout, MEMO_CELL, TRUE))
1592 value = gnc_table_layout_get_cell_value (reg->table->layout, MEMO_CELL);
1593 gnc_float_split_set_memo (fs, value);
1596 if (gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, TRUE))
1600 new_account = gnc_split_register_get_account (reg, XFRM_CELL);
1602 if (new_account != NULL)
1603 gnc_float_split_set_account (fs, new_account);
1606 if (reg->style == REG_STYLE_LEDGER)
1607 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1609 if (gnc_table_layout_get_cell_changed (reg->table->layout, MXFRM_CELL, TRUE))
1611 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1615 if (ft && g_list_length (ft->m_splits) == 1)
1620 other_fs = gnc_split_to_float_split (temp_split);
1623 gnc_float_txn_append_float_split (ft, other_fs);
1631 new_account = gnc_split_register_get_account (reg, MXFRM_CELL);
1633 if (new_account != NULL)
1634 gnc_float_split_set_account (other_fs, new_account);
1638 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1640 gnc_table_layout_get_cell_changed (reg->table->layout,
1644 gnc_numeric new_value;
1648 cell = gnc_table_layout_get_cell (reg->table->layout, CRED_CELL);
1651 cell = gnc_table_layout_get_cell (reg->table->layout, DEBT_CELL);
1654 new_value = gnc_numeric_sub_fixed (debit, credit);
1656 gnc_float_split_set_value (fs, new_value);
1659 if (gnc_table_layout_get_cell_changed (reg->table->layout, PRIC_CELL, TRUE))
1664 if (gnc_table_layout_get_cell_changed (reg->table->layout, SHRS_CELL, TRUE))
1669 cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
1673 gnc_float_split_set_amount (fs, shares);
1676 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1678 gnc_table_layout_get_cell_changed (reg->table->layout,
1680 gnc_table_layout_get_cell_changed (reg->table->layout,
1682 gnc_table_layout_get_cell_changed (reg->table->layout,
1689 num = gnc_float_split_get_amount (fs);
1692 num = gnc_float_split_get_value (fs);
1700 unreconcile_splits (SplitRegister* reg)
1702 if (reg->unrecn_splits == NULL)
1704 PINFO (
"Unreconcile %d splits of reconciled transaction",
1705 g_list_length (reg->unrecn_splits));
1707 for (GList* node = reg->unrecn_splits; node; node = node->next)
1709 Split* split = node->data;
1712 PWARN (
"Unreconcile of split failed because its parent transaction wasn't open for editing");
1716 g_list_free (reg->unrecn_splits);
1717 reg->unrecn_splits = NULL;
1723 SRInfo* info = gnc_split_register_get_info (reg);
1724 Transaction* pending_trans;
1725 Transaction* blank_trans;
1733 ENTER (
"reg=%p, do_commit=%s", reg, do_commit ?
"TRUE" :
"FALSE");
1737 LEAVE (
"no register");
1742 gnc_get_current_book ());
1745 gnc_get_current_book ());
1754 LEAVE (
"no transaction");
1761 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1765 LEAVE (
"commit unnecessary");
1771 LEAVE (
"transaction not open");
1775 if (trans == pending_trans ||
1776 (trans == blank_trans && info->blank_split_edited))
1780 gnc_suspend_gui_refresh ();
1782 if (trans == blank_trans)
1788 info->blank_split_edited = FALSE;
1789 info->auto_complete = FALSE;
1794 if (trans == pending_trans)
1795 info->pending_trans_guid = *
guid_null ();
1797 PINFO (
"committing trans (%p)", trans);
1798 unreconcile_splits (reg);
1802 gnc_resume_gui_refresh ();
1805 DEBUG (
"leaving trans (%p) open", trans);
1807 LEAVE (
"unchanged cursor");
1811 DEBUG (
"save split=%p", split);
1812 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p, trans=%p",
1813 blank_split, blank_trans, pending_trans, trans);
1816 if (!gnc_split_register_check_cell (reg,
1817 gnc_table_get_current_cell_name (reg->table)))
1819 LEAVE (
"need another go at changing cell");
1823 if (!gnc_split_register_auto_calc (reg, split))
1825 LEAVE (
"auto calc failed");
1830 (void)gnc_split_register_get_account (reg, MXFRM_CELL);
1831 (void)gnc_split_register_get_account (reg, XFRM_CELL);
1836 LEAVE (
"no exchange rate");
1840 gnc_suspend_gui_refresh ();
1843 if (pending_trans != trans)
1850 g_warning (
"Impossible? committing pending %p", pending_trans);
1851 unreconcile_splits (reg);
1855 else if (pending_trans)
1857 g_critical (
"BUG DETECTED! pending transaction (%p) not open",
1859 g_assert_not_reached ();
1862 if (trans == blank_trans)
1872 PINFO (
"beginning edit of trans %p", trans);
1873 if (gnc_split_register_begin_edit_or_warn (info, trans))
1875 gnc_resume_gui_refresh ();
1876 LEAVE (
"transaction opened elsewhere");
1880 pending_trans = trans;
1891 if (split == blank_split && !info->blank_split_edited)
1898 account = gnc_split_register_get_default_account (reg);
1900 xaccSplitSetAccount (blank_split, account);
1920 reg->table->current_cursor_loc.vcell_loc,
1922 DEBUG (
"assigned cell to new split=%p", split);
1925 if ((info->cursor_hint_trans == trans) &&
1926 (info->cursor_hint_trans_split == trans_split) &&
1927 (info->cursor_hint_split == NULL))
1929 info->cursor_hint_split = split;
1930 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1934 DEBUG (
"updating trans=%p", trans);
1939 sd = gnc_split_register_save_data_new (
1940 trans, split, (info->trans_expanded ||
1941 reg->style == REG_STYLE_AUTO_LEDGER ||
1942 reg->style == REG_STYLE_JOURNAL));
1943 gnc_table_save_cells (reg->table, sd);
1944 gnc_split_register_save_data_destroy (sd);
1948 memo = memo ? memo :
"(null)";
1950 desc = desc ? desc :
"(null)";
1951 PINFO (
"finished saving split \"%s\" of trans \"%s\"", memo, desc);
1957 if (trans == blank_trans)
1962 info->auto_complete = FALSE;
1967 info->blank_split_edited = TRUE;
1974 g_assert (trans == blank_trans || trans == pending_trans);
1975 if (pending_trans == trans)
1977 pending_trans = NULL;
1978 info->pending_trans_guid = *
guid_null ();
1980 unreconcile_splits (reg);
1985 gnc_table_clear_current_cursor_changes (reg->table);
1987 gnc_resume_gui_refresh ();
1995 gnc_split_register_get_account_by_name (SplitRegister* reg, BasicCell* bcell,
1998 const char* placeholder = _ (
"The account %s does not allow transactions.");
1999 const char* missing = _ (
"The account %s does not exist. " 2000 "Would you like to create it?");
2004 static gboolean creating_account = FALSE;
2005 GtkWindow* parent = GTK_WINDOW (gnc_split_register_get_parent (reg));
2007 if (!name || (strlen (name) == 0))
2020 if (!account && !creating_account)
2023 if (!gnc_verify_dialog (parent, TRUE, missing, name))
2025 creating_account = TRUE;
2028 creating_account = FALSE;
2033 if (!creating_account)
2037 reg->show_leaf_accounts);
2038 if (g_strcmp0 (account_name, gnc_basic_cell_get_value (bcell)))
2041 gnc_combo_cell_set_value (cell, account_name);
2042 gnc_basic_cell_set_changed (&cell->cell, TRUE);
2044 g_free (account_name);
2050 gnc_error_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
2051 placeholder, fullname);
2062 gnc_split_register_get_account (SplitRegister* reg,
const char* cell_name)
2067 if (!gnc_table_layout_get_cell_changed (reg->table->layout, cell_name, TRUE))
2070 cell = gnc_table_layout_get_cell (reg->table->layout, cell_name);
2073 name = gnc_basic_cell_get_value (cell);
2074 return gnc_split_register_get_account_by_name (reg, cell, name);
2078 calculate_value (SplitRegister* reg)
2087 cell = (
PriceCell*)gnc_table_layout_get_cell (reg->table->layout,
2091 return gnc_numeric_sub_fixed (debit, credit);
2096 recalc_message_box (SplitRegister* reg, gboolean shares_changed,
2097 gboolean price_changed, gboolean value_changed)
2102 GList* radio_list = NULL;
2103 const char* title = _ (
"Recalculate Transaction");
2104 const char* message = _ (
"The values entered for this transaction " 2105 "are inconsistent. Which value would you " 2106 "like to have recalculated?");
2109 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2113 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Shares")));
2116 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2120 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Price")));
2123 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2127 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Value")));
2129 if (price_changed) default_value = 2;
2130 else default_value = 1;
2132 choice = gnc_choose_radio_option_dialog
2133 (gnc_split_register_get_parent (reg),
2140 for (node = radio_list; node; node = node->next)
2141 g_free (node->data);
2143 g_list_free (radio_list);
2149 recalculate_shares (Split* split, SplitRegister* reg,
2150 gnc_numeric value, gnc_numeric price, gboolean value_changed)
2152 gint64 denom = gnc_split_get_amount_denom (split);
2156 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
2158 gnc_basic_cell_set_changed (cell, TRUE);
2162 cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2163 gnc_basic_cell_set_changed (cell, FALSE);
2168 recalculate_price (Split* split, SplitRegister* reg,
2169 gnc_numeric value, gnc_numeric amount)
2171 BasicCell* price_cell;
2178 BasicCell* debit_cell;
2179 BasicCell* credit_cell;
2181 debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2184 credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2193 gnc_basic_cell_set_changed (debit_cell, TRUE);
2194 gnc_basic_cell_set_changed (credit_cell, TRUE);
2197 price_cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2199 gnc_basic_cell_set_changed (price_cell, TRUE);
2203 recalculate_value (Split* split, SplitRegister* reg,
2204 gnc_numeric price, gnc_numeric amount, gboolean shares_changed)
2206 BasicCell* debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2208 BasicCell* credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2210 gint64 denom = gnc_split_get_value_denom (split);
2217 gnc_basic_cell_set_changed (debit_cell, TRUE);
2218 gnc_basic_cell_set_changed (credit_cell, TRUE);
2222 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout,
2224 gnc_basic_cell_set_changed (cell, FALSE);
2229 gnc_split_register_auto_calc (SplitRegister* reg, Split* split)
2232 gboolean recalc_shares = FALSE;
2233 gboolean recalc_price = FALSE;
2234 gboolean recalc_value = FALSE;
2235 gboolean price_changed;
2236 gboolean value_changed;
2237 gboolean shares_changed;
2238 gnc_numeric calc_value;
2246 if (STOCK_REGISTER != reg->type &&
2247 CURRENCY_REGISTER != reg->type &&
2248 PORTFOLIO_LEDGER != reg->type)
2251 account = gnc_split_register_get_account (reg, XFRM_CELL);
2257 account = gnc_split_register_get_default_account (reg);
2262 price_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2264 value_changed = (gnc_table_layout_get_cell_changed (reg->table->layout,
2266 gnc_table_layout_get_cell_changed (reg->table->layout,
2268 shares_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2271 if (!price_changed && !value_changed && !shares_changed)
2278 gnc_commodity* acc_commodity;
2287 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2296 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2304 value = calculate_value (reg);
2326 recalc_price = TRUE;
2329 recalc_value = TRUE;
2333 recalc_shares = TRUE;
2338 if ((!recalc_shares) &&
2342 if (price_changed && value_changed)
2344 if (!shares_changed)
2345 recalc_shares = TRUE;
2347 else if (value_changed && shares_changed)
2348 recalc_price = TRUE;
2349 else if (price_changed && shares_changed)
2350 recalc_value = TRUE;
2356 denom = gnc_split_get_value_denom (split);
2362 if (!recalc_shares &&
2367 choice = recalc_message_box (reg, shares_changed,
2373 recalc_shares = TRUE;
2376 recalc_price = TRUE;
2379 recalc_value = TRUE;
2387 recalculate_shares (split, reg, value, price, value_changed);
2391 recalculate_price (split, reg, value, amount);
2392 price_changed = TRUE;
2395 recalculate_value (split, reg, price, amount, shares_changed);
2409 case ASSET_REGISTER:
2411 case CREDIT_REGISTER:
2413 case LIABILITY_REGISTER:
2415 case PAYABLE_REGISTER:
2417 case RECEIVABLE_REGISTER:
2420 case INCOME_REGISTER:
2422 case EXPENSE_REGISTER:
2424 case STOCK_REGISTER:
2425 case PORTFOLIO_LEDGER:
2427 case CURRENCY_REGISTER:
2429 case TRADING_REGISTER:
2431 case GENERAL_JOURNAL:
2433 case EQUITY_REGISTER:
2445 SRInfo* info = gnc_split_register_get_info (reg);
2450 if (info->debit_str)
2451 return info->debit_str;
2455 (gnc_split_register_type_to_account_type (reg->type));
2457 if (info->debit_str)
2458 return info->debit_str;
2460 info->debit_str = g_strdup (_ (
"Debit"));
2462 return info->debit_str;
2468 SRInfo* info = gnc_split_register_get_info (reg);
2473 if (info->credit_str)
2474 return info->credit_str;
2478 (gnc_split_register_type_to_account_type (reg->type));
2480 if (info->credit_str)
2481 return info->credit_str;
2483 info->credit_str = g_strdup (_ (
"Credit"));
2485 return info->credit_str;
2491 SRInfo* info = gnc_split_register_get_info (reg);
2492 Transaction* pending_trans;
2494 ENTER (
"reg=%p", reg);
2498 LEAVE (
"no register");
2502 if (gnc_table_current_cursor_changed (reg->table, FALSE))
2504 LEAVE (
"cursor changed");
2509 gnc_get_current_book ());
2512 LEAVE (
"open and pending txn");
2516 LEAVE (
"register unchanged");
2522 gboolean show_present)
2524 SRInfo* info = gnc_split_register_get_info (reg);
2529 info->show_present_divider = show_present;
2535 SRInfo* info = gnc_split_register_get_info (reg);
2540 return info->full_refresh;
2546 gnc_split_register_config_action (SplitRegister* reg)
2550 cell = (
ComboCell*) gnc_table_layout_get_cell (reg->table->layout,
2588 case ASSET_REGISTER:
2593 case CREDIT_REGISTER:
2603 case LIABILITY_REGISTER:
2610 case RECEIVABLE_REGISTER:
2611 case PAYABLE_REGISTER:
2618 case INCOME_REGISTER:
2628 case EXPENSE_REGISTER:
2629 case TRADING_REGISTER:
2635 case GENERAL_JOURNAL:
2636 case EQUITY_REGISTER:
2641 case STOCK_REGISTER:
2642 case PORTFOLIO_LEDGER:
2643 case CURRENCY_REGISTER:
2671 gnc_split_register_config_cells (SplitRegister* reg)
2675 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2680 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2686 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), TRUE);
2691 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), TRUE);
2696 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2701 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL),
2702 gnc_default_share_print_info ());
2705 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, TSHRS_CELL),
2706 gnc_default_share_print_info ());
2712 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, RATE_CELL),
2713 gnc_default_share_print_info ());
2718 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), FALSE);
2723 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), FALSE);
2728 case CURRENCY_REGISTER:
2729 case STOCK_REGISTER:
2730 case PORTFOLIO_LEDGER:
2733 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2742 gnc_split_register_config_action (reg);
2746 split_register_pref_changed (gpointer prefs, gchar* pref, gpointer user_data)
2748 SplitRegister* reg = user_data;
2751 g_return_if_fail (pref);
2755 info = reg->sr_info;
2759 if (g_str_has_suffix (pref, GNC_PREF_ACCOUNTING_LABELS))
2762 g_free (info->tdebit_str);
2763 g_free (info->tcredit_str);
2765 info->debit_str = NULL;
2766 info->tdebit_str = NULL;
2767 info->credit_str = NULL;
2768 info->tcredit_str = NULL;
2771 else if (g_str_has_suffix (pref, GNC_PREF_ACCOUNT_SEPARATOR))
2773 info->separator_changed = TRUE;
2775 else if (g_str_has_suffix (pref, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
2778 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2780 else if (g_str_has_suffix (pref, GNC_PREF_ALT_COLOR_BY_TRANS))
2783 GNC_PREF_ALT_COLOR_BY_TRANS);
2787 g_warning (
"split_register_pref_changed: Unknown preference %s", pref);
2792 split_register_book_option_changed (gpointer new_val, gpointer user_data)
2794 SplitRegister* reg = user_data;
2795 gboolean* new_data = (gboolean*)new_val;
2800 reg->use_tran_num_for_num_field = (*new_data ? FALSE : TRUE);
2804 gnc_split_register_init (SplitRegister* reg,
2807 gboolean use_double_line,
2808 gboolean do_auto_complete,
2809 gboolean is_template,
2810 gboolean mismatched_commodities)
2812 TableLayout* layout;
2818 GNC_PREF_ACCOUNTING_LABELS,
2819 split_register_pref_changed,
2822 GNC_PREF_ACCOUNT_SEPARATOR,
2823 split_register_pref_changed,
2826 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
2827 split_register_pref_changed,
2830 GNC_PREF_ALT_COLOR_BY_TRANS,
2831 split_register_pref_changed,
2833 gnc_book_option_register_cb (OPTION_NAME_NUM_FIELD_SOURCE,
2834 split_register_book_option_changed,
2837 reg->sr_info = NULL;
2839 reg->unrecn_splits = NULL;
2842 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2844 GNC_PREF_ALT_COLOR_BY_TRANS);
2848 reg->use_double_line = use_double_line;
2849 reg->do_auto_complete = do_auto_complete;
2850 reg->is_template = is_template;
2851 reg->mismatched_commodities = mismatched_commodities;
2852 reg->use_tran_num_for_num_field =
2859 model = gnc_template_register_model_new ();
2861 model = gnc_split_register_model_new ();
2862 model->handler_user_data = reg;
2865 control->user_data = reg;
2867 reg->table = gnc_table_new (layout, model, control);
2869 gnc_split_register_config_cells (reg);
2873 VirtualCellLocation vcell_loc = { 0, 0 };
2876 header = gnc_table_layout_get_cursor (reg->table->layout,
CURSOR_HEADER);
2883 VirtualLocation vloc;
2886 vloc.vcell_loc.virt_row = 1;
2887 vloc.vcell_loc.virt_col = 0;
2888 vloc.phys_row_offset = 0;
2889 vloc.phys_col_offset = 0;
2891 cursor = gnc_table_layout_get_cursor (reg->table->layout,
2892 CURSOR_SINGLE_LEDGER);
2900 PERR (
"Can't find valid initial location");
2908 gboolean use_double_line,
2909 gboolean is_template,
2910 gboolean mismatched_commodities)
2913 gboolean default_do_auto_complete = TRUE;
2915 reg = g_new0 (SplitRegister, 1);
2917 if (type >= NUM_SINGLE_REGISTER_TYPES)
2918 style = REG_STYLE_JOURNAL;
2920 gnc_split_register_init (reg,
2924 default_do_auto_complete,
2926 mismatched_commodities);
2935 gboolean use_double_line)
2940 if (reg->use_double_line && !use_double_line)
2942 VirtualLocation virt_loc = reg->table->current_cursor_loc;
2945 if (virt_loc.phys_row_offset)
2948 -virt_loc.phys_row_offset);
2955 virt_loc.vcell_loc.virt_row = 1;
2956 virt_loc.vcell_loc.virt_col = 0;
2957 virt_loc.phys_row_offset = 0;
2958 virt_loc.phys_col_offset = 0;
2963 reg->type = newtype;
2965 if (reg->type >= NUM_SINGLE_REGISTER_TYPES)
2966 newstyle = REG_STYLE_JOURNAL;
2968 reg->style = newstyle;
2969 reg->use_double_line = use_double_line;
2971 gnc_table_realize_gui (reg->table);
2977 g_return_if_fail (reg);
2978 gnc_table_model_set_reverse_sort (reg->table->model, reverse_sort);
2983 gboolean do_auto_complete)
2985 g_return_if_fail (reg);
2986 reg->do_auto_complete = do_auto_complete;
2990 gnc_split_register_destroy_info (SplitRegister* reg)
2997 if (reg->unrecn_splits != NULL)
2999 g_list_free (reg->unrecn_splits);
3000 reg->unrecn_splits = NULL;
3003 info = reg->sr_info;
3007 g_free (info->tdebit_str);
3008 g_free (info->tcredit_str);
3010 info->debit_str = NULL;
3011 info->tdebit_str = NULL;
3012 info->credit_str = NULL;
3013 info->tcredit_str = NULL;
3015 g_free (reg->sr_info);
3017 reg->sr_info = NULL;
3024 SRInfo* info = gnc_split_register_get_info (reg);
3026 g_return_if_fail (reg != NULL);
3028 info->user_data = user_data;
3029 info->get_parent = get_parent;
3033 gnc_split_register_cleanup (SplitRegister* reg)
3035 SRInfo* info = gnc_split_register_get_info (reg);
3036 Transaction* pending_trans;
3037 Transaction* blank_trans = NULL;
3040 ENTER (
"reg=%p", reg);
3043 gnc_get_current_book ());
3046 gnc_get_current_book ());
3048 gnc_suspend_gui_refresh ();
3053 if (blank_split != NULL)
3059 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p",
3060 blank_split, blank_trans, pending_trans);
3069 if (blank_trans == pending_trans)
3071 info->pending_trans_guid = *
guid_null ();
3072 pending_trans = NULL;
3075 info->auto_complete = FALSE;
3080 if (pending_trans != NULL)
3082 g_critical (
"BUG DETECTED: pending_trans=%p, blank_split=%p, blank_trans=%p",
3083 pending_trans, blank_split, blank_trans);
3084 g_assert_not_reached ();
3085 info->pending_trans_guid = *
guid_null ();
3091 else g_assert_not_reached ();
3093 pending_trans = NULL;
3096 gnc_split_register_destroy_info (reg);
3098 gnc_resume_gui_refresh ();
3106 g_return_if_fail (reg);
3108 ENTER (
"reg=%p", reg);
3111 GNC_PREF_ACCOUNTING_LABELS,
3112 split_register_pref_changed,
3115 GNC_PREF_ACCOUNT_SEPARATOR,
3116 split_register_pref_changed,
3119 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
3120 split_register_pref_changed,
3123 GNC_PREF_ALT_COLOR_BY_TRANS,
3124 split_register_pref_changed,
3126 gnc_book_option_remove_cb (OPTION_NAME_NUM_FIELD_SOURCE,
3127 split_register_book_option_changed,
3130 gnc_split_register_cleanup (reg);
3132 gnc_table_destroy (reg->table);
3143 gnc_table_model_set_read_only (reg->table->model, read_only);
3153 case ASSET_REGISTER:
3154 case CREDIT_REGISTER:
3155 case LIABILITY_REGISTER:
3156 case INCOME_REGISTER:
3157 case EXPENSE_REGISTER:
3158 case EQUITY_REGISTER:
3159 case TRADING_REGISTER:
3161 return REG_TYPE_GROUP_CURRENCY;
3164 case PAYABLE_REGISTER:
3165 case RECEIVABLE_REGISTER:
3167 return REG_TYPE_GROUP_APAR;
3171 case GENERAL_JOURNAL:
3174 return REG_TYPE_GROUP_JOURNAL;
3177 case STOCK_REGISTER:
3178 case CURRENCY_REGISTER:
3180 return REG_TYPE_GROUP_STOCK;
3183 case PORTFOLIO_LEDGER:
3185 return REG_TYPE_GROUP_PORTFOLIO;
3189 return REG_TYPE_GROUP_UNKNOWN;
3190 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...
void gnc_copy_trans_onto_trans(Transaction *from, Transaction *to, gboolean use_cut_semantics, gboolean do_commit)
Private function – outsiders must not use this.
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.
#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.
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 a, gnc_numeric b, 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.
int 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...