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 && xaccTransStillHasSplit (trans, s))
1152 if (pref_split != NULL)
1154 else if (other_split != NULL)
1163 SRInfo* info = gnc_split_register_get_info (reg);
1164 Transaction* pending_trans;
1172 gnc_get_current_book ());
1175 gnc_get_current_book ());
1185 if (split == blank_split)
1191 gnc_suspend_gui_refresh ();
1196 if (trans == pending_trans)
1202 g_assert (!pending_trans);
1203 if (gnc_split_register_begin_edit_or_warn (info, trans))
1205 gnc_resume_gui_refresh ();
1211 gnc_resume_gui_refresh ();
1218 SRInfo* info = gnc_split_register_get_info (reg);
1219 Transaction* pending_trans;
1225 ENTER (
"reg=%p", reg);
1228 LEAVE (
"no register");
1233 gnc_get_current_book ());
1235 gnc_get_current_book ());
1245 gnc_suspend_gui_refresh ();
1251 if (split == blank_split)
1253 DEBUG (
"deleting blank split");
1255 info->auto_complete = FALSE;
1259 info->trans_expanded = FALSE;
1263 if (trans == pending_trans)
1265 DEBUG (
"clearing pending trans");
1266 info->pending_trans_guid = *
guid_null ();
1267 pending_trans = NULL;
1274 DEBUG (
"committing");
1277 gnc_resume_gui_refresh ();
1285 SRInfo* info = gnc_split_register_get_info (reg);
1286 Transaction* pending_trans;
1294 gnc_get_current_book ());
1296 gnc_get_current_book ());
1304 if (split == blank_split)
1311 info->trans_expanded = FALSE;
1313 gnc_suspend_gui_refresh ();
1319 if (trans == pending_trans)
1321 info->pending_trans_guid = *
guid_null ();
1322 pending_trans = NULL;
1326 PERR (
"We should not be voiding an open transaction.");
1329 gnc_resume_gui_refresh ();
1335 SRInfo* info = gnc_split_register_get_info (reg);
1336 Transaction* pending_trans;
1344 gnc_get_current_book ());
1346 gnc_get_current_book ());
1354 if (split == blank_split)
1361 info->trans_expanded = FALSE;
1363 gnc_suspend_gui_refresh ();
1370 if (trans == pending_trans)
1372 info->pending_trans_guid = *
guid_null ();
1373 pending_trans = NULL;
1376 gnc_resume_gui_refresh ();
1385 Transaction* pending;
1389 if ((reg == NULL) || (split == NULL))
1392 gnc_suspend_gui_refresh ();
1393 info = gnc_split_register_get_info (reg);
1394 pending =
xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ());
1399 if (gnc_split_register_begin_edit_or_warn (info, trans))
1401 gnc_resume_gui_refresh ();
1405 else if (pending == trans)
1409 else g_assert_not_reached ();
1418 gnc_resume_gui_refresh ();
1423 gnc_split_register_empty_current_trans (SplitRegister* reg)
1435 VirtualLocation virt_loc;
1440 virt_loc = reg->table->current_cursor_loc;
1442 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1447 gnc_table_clear_current_cursor_changes (reg->table);
1458 SRInfo* info = gnc_split_register_get_info (reg);
1459 Transaction* pending_trans, *blank_trans;
1460 gboolean refresh_all = FALSE;
1463 gnc_get_current_book ());
1467 if (pending_trans == blank_trans)
1482 gnc_suspend_gui_refresh ();
1486 info->pending_trans_guid = *
guid_null ();
1488 gnc_resume_gui_refresh ();
1491 gnc_gui_refresh_all ();
1499 gnc_ledger_display_refresh_by_split_register (reg);
1505 gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
1507 gboolean use_cut_semantics)
1515 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1524 if (gnc_table_layout_get_cell_changed (reg->table->layout, DATE_CELL, TRUE))
1528 cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
1533 if (gnc_table_layout_get_cell_changed (reg->table->layout, NUM_CELL, TRUE))
1537 value = gnc_table_layout_get_cell_value (reg->table->layout, NUM_CELL);
1538 if (reg->use_tran_num_for_num_field)
1545 if (gnc_table_layout_get_cell_changed (reg->table->layout, TNUM_CELL, TRUE))
1549 value = gnc_table_layout_get_cell_value (reg->table->layout, TNUM_CELL);
1550 if (!reg->use_tran_num_for_num_field)
1555 if (gnc_table_layout_get_cell_changed (reg->table->layout, DESC_CELL, TRUE))
1559 value = gnc_table_layout_get_cell_value (reg->table->layout, DESC_CELL);
1563 if (gnc_table_layout_get_cell_changed (reg->table->layout, NOTES_CELL, TRUE))
1567 value = gnc_table_layout_get_cell_value (reg->table->layout, NOTES_CELL);
1571 if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, TRUE))
1576 cell = gnc_table_layout_get_cell (reg->table->layout, RECN_CELL);
1577 flag = gnc_recn_cell_get_flag ((
RecnCell*) cell);
1579 gnc_float_split_set_reconcile_state (fs, flag);
1582 if (gnc_table_layout_get_cell_changed (reg->table->layout, ACTN_CELL, TRUE))
1586 value = gnc_table_layout_get_cell_value (reg->table->layout, ACTN_CELL);
1587 gnc_float_split_set_action (fs, value);
1590 if (gnc_table_layout_get_cell_changed (reg->table->layout, MEMO_CELL, TRUE))
1594 value = gnc_table_layout_get_cell_value (reg->table->layout, MEMO_CELL);
1595 gnc_float_split_set_memo (fs, value);
1598 if (gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, TRUE))
1602 new_account = gnc_split_register_get_account (reg, XFRM_CELL);
1604 if (new_account != NULL)
1605 gnc_float_split_set_account (fs, new_account);
1608 if (reg->style == REG_STYLE_LEDGER)
1609 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1611 if (gnc_table_layout_get_cell_changed (reg->table->layout, MXFRM_CELL, TRUE))
1613 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1617 if (ft && g_list_length (ft->m_splits) == 1)
1622 other_fs = gnc_split_to_float_split (temp_split);
1625 gnc_float_txn_append_float_split (ft, other_fs);
1633 new_account = gnc_split_register_get_account (reg, MXFRM_CELL);
1635 if (new_account != NULL)
1636 gnc_float_split_set_account (other_fs, new_account);
1640 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1642 gnc_table_layout_get_cell_changed (reg->table->layout,
1646 gnc_numeric new_value;
1650 cell = gnc_table_layout_get_cell (reg->table->layout, CRED_CELL);
1653 cell = gnc_table_layout_get_cell (reg->table->layout, DEBT_CELL);
1656 new_value = gnc_numeric_sub_fixed (debit, credit);
1658 gnc_float_split_set_value (fs, new_value);
1661 if (gnc_table_layout_get_cell_changed (reg->table->layout, PRIC_CELL, TRUE))
1666 if (gnc_table_layout_get_cell_changed (reg->table->layout, SHRS_CELL, TRUE))
1671 cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
1675 gnc_float_split_set_amount (fs, shares);
1678 if (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,
1684 gnc_table_layout_get_cell_changed (reg->table->layout,
1691 num = gnc_float_split_get_amount (fs);
1694 num = gnc_float_split_get_value (fs);
1702 unreconcile_splits (SplitRegister* reg)
1704 if (reg->unrecn_splits == NULL)
1706 PINFO (
"Unreconcile %d splits of reconciled transaction",
1707 g_list_length (reg->unrecn_splits));
1709 for (GList* node = reg->unrecn_splits; node; node = node->next)
1711 Split* split = node->data;
1714 PWARN (
"Unreconcile of split failed because its parent transaction wasn't open for editing");
1718 g_list_free (reg->unrecn_splits);
1719 reg->unrecn_splits = NULL;
1725 SRInfo* info = gnc_split_register_get_info (reg);
1726 Transaction* pending_trans;
1727 Transaction* blank_trans;
1735 ENTER (
"reg=%p, do_commit=%s", reg, do_commit ?
"TRUE" :
"FALSE");
1739 LEAVE (
"no register");
1744 gnc_get_current_book ());
1747 gnc_get_current_book ());
1756 LEAVE (
"no transaction");
1763 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1767 LEAVE (
"commit unnecessary");
1773 LEAVE (
"transaction not open");
1777 if (trans == pending_trans ||
1778 (trans == blank_trans && info->blank_split_edited))
1782 gnc_suspend_gui_refresh ();
1784 if (trans == blank_trans)
1790 info->blank_split_edited = FALSE;
1791 info->auto_complete = FALSE;
1796 if (trans == pending_trans)
1797 info->pending_trans_guid = *
guid_null ();
1799 PINFO (
"committing trans (%p)", trans);
1800 unreconcile_splits (reg);
1804 gnc_resume_gui_refresh ();
1807 DEBUG (
"leaving trans (%p) open", trans);
1809 LEAVE (
"unchanged cursor");
1813 DEBUG (
"save split=%p", split);
1814 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p, trans=%p",
1815 blank_split, blank_trans, pending_trans, trans);
1818 if (!gnc_split_register_check_cell (reg,
1819 gnc_table_get_current_cell_name (reg->table)))
1821 LEAVE (
"need another go at changing cell");
1825 if (!gnc_split_register_auto_calc (reg, split))
1827 LEAVE (
"auto calc failed");
1832 (void)gnc_split_register_get_account (reg, MXFRM_CELL);
1833 (void)gnc_split_register_get_account (reg, XFRM_CELL);
1838 LEAVE (
"no exchange rate");
1842 gnc_suspend_gui_refresh ();
1845 if (pending_trans != trans)
1852 g_warning (
"Impossible? committing pending %p", pending_trans);
1853 unreconcile_splits (reg);
1857 else if (pending_trans)
1859 g_critical (
"BUG DETECTED! pending transaction (%p) not open",
1861 g_assert_not_reached ();
1864 if (trans == blank_trans)
1874 PINFO (
"beginning edit of trans %p", trans);
1875 if (gnc_split_register_begin_edit_or_warn (info, trans))
1877 gnc_resume_gui_refresh ();
1878 LEAVE (
"transaction opened elsewhere");
1882 pending_trans = trans;
1893 if (split == blank_split && !info->blank_split_edited)
1900 account = gnc_split_register_get_default_account (reg);
1902 xaccSplitSetAccount (blank_split, account);
1922 reg->table->current_cursor_loc.vcell_loc,
1924 DEBUG (
"assigned cell to new split=%p", split);
1927 if ((info->cursor_hint_trans == trans) &&
1928 (info->cursor_hint_trans_split == trans_split) &&
1929 (info->cursor_hint_split == NULL))
1931 info->cursor_hint_split = split;
1932 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1936 DEBUG (
"updating trans=%p", trans);
1941 sd = gnc_split_register_save_data_new (
1942 trans, split, (info->trans_expanded ||
1943 reg->style == REG_STYLE_AUTO_LEDGER ||
1944 reg->style == REG_STYLE_JOURNAL));
1945 gnc_table_save_cells (reg->table, sd);
1946 gnc_split_register_save_data_destroy (sd);
1950 memo = memo ? memo :
"(null)";
1952 desc = desc ? desc :
"(null)";
1953 PINFO (
"finished saving split \"%s\" of trans \"%s\"", memo, desc);
1959 if (trans == blank_trans)
1964 info->auto_complete = FALSE;
1969 info->blank_split_edited = TRUE;
1976 g_assert (trans == blank_trans || trans == pending_trans);
1977 if (pending_trans == trans)
1979 pending_trans = NULL;
1980 info->pending_trans_guid = *
guid_null ();
1982 unreconcile_splits (reg);
1987 gnc_table_clear_current_cursor_changes (reg->table);
1989 gnc_resume_gui_refresh ();
1997 gnc_split_register_get_account_by_name (SplitRegister* reg, BasicCell* bcell,
2000 const char* placeholder = _ (
"The account %s does not allow transactions.");
2001 const char* missing = _ (
"The account %s does not exist. " 2002 "Would you like to create it?");
2006 static gboolean creating_account = FALSE;
2007 GtkWindow* parent = GTK_WINDOW (gnc_split_register_get_parent (reg));
2009 if (!name || (strlen (name) == 0))
2022 if (!account && !creating_account)
2025 if (!gnc_verify_dialog (parent, TRUE, missing, name))
2027 creating_account = TRUE;
2030 creating_account = FALSE;
2035 if (!creating_account)
2039 reg->show_leaf_accounts);
2040 if (g_strcmp0 (account_name, gnc_basic_cell_get_value (bcell)))
2043 gnc_combo_cell_set_value (cell, account_name);
2044 gnc_basic_cell_set_changed (&cell->cell, TRUE);
2046 g_free (account_name);
2052 gnc_error_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
2053 placeholder, fullname);
2064 gnc_split_register_get_account (SplitRegister* reg,
const char* cell_name)
2069 if (!gnc_table_layout_get_cell_changed (reg->table->layout, cell_name, TRUE))
2072 cell = gnc_table_layout_get_cell (reg->table->layout, cell_name);
2075 name = gnc_basic_cell_get_value (cell);
2076 return gnc_split_register_get_account_by_name (reg, cell, name);
2080 calculate_value (SplitRegister* reg)
2089 cell = (
PriceCell*)gnc_table_layout_get_cell (reg->table->layout,
2093 return gnc_numeric_sub_fixed (debit, credit);
2098 recalc_message_box (SplitRegister* reg, gboolean shares_changed,
2099 gboolean price_changed, gboolean value_changed)
2104 GList* radio_list = NULL;
2105 const char* title = _ (
"Recalculate Transaction");
2106 const char* message = _ (
"The values entered for this transaction " 2107 "are inconsistent. Which value would you " 2108 "like to have recalculated?");
2111 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2115 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Shares")));
2118 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2122 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Price")));
2125 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2129 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Value")));
2131 if (price_changed) default_value = 2;
2132 else default_value = 1;
2134 choice = gnc_choose_radio_option_dialog
2135 (gnc_split_register_get_parent (reg),
2142 for (node = radio_list; node; node = node->next)
2143 g_free (node->data);
2145 g_list_free (radio_list);
2151 recalculate_shares (Split* split, SplitRegister* reg,
2152 gnc_numeric value, gnc_numeric price, gboolean value_changed)
2154 gint64 denom = gnc_split_get_amount_denom (split);
2158 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
2160 gnc_basic_cell_set_changed (cell, TRUE);
2164 cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2165 gnc_basic_cell_set_changed (cell, FALSE);
2170 recalculate_price (Split* split, SplitRegister* reg,
2171 gnc_numeric value, gnc_numeric amount)
2173 BasicCell* price_cell;
2180 BasicCell* debit_cell;
2181 BasicCell* credit_cell;
2183 debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2186 credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2195 gnc_basic_cell_set_changed (debit_cell, TRUE);
2196 gnc_basic_cell_set_changed (credit_cell, TRUE);
2199 price_cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2201 gnc_basic_cell_set_changed (price_cell, TRUE);
2205 recalculate_value (Split* split, SplitRegister* reg,
2206 gnc_numeric price, gnc_numeric amount, gboolean shares_changed)
2208 BasicCell* debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2210 BasicCell* credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2212 gint64 denom = gnc_split_get_value_denom (split);
2219 gnc_basic_cell_set_changed (debit_cell, TRUE);
2220 gnc_basic_cell_set_changed (credit_cell, TRUE);
2224 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout,
2226 gnc_basic_cell_set_changed (cell, FALSE);
2231 gnc_split_register_auto_calc (SplitRegister* reg, Split* split)
2234 gboolean recalc_shares = FALSE;
2235 gboolean recalc_price = FALSE;
2236 gboolean recalc_value = FALSE;
2237 gboolean price_changed;
2238 gboolean value_changed;
2239 gboolean shares_changed;
2240 gnc_numeric calc_value;
2248 if (STOCK_REGISTER != reg->type &&
2249 CURRENCY_REGISTER != reg->type &&
2250 PORTFOLIO_LEDGER != reg->type)
2253 account = gnc_split_register_get_account (reg, XFRM_CELL);
2259 account = gnc_split_register_get_default_account (reg);
2264 price_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2266 value_changed = (gnc_table_layout_get_cell_changed (reg->table->layout,
2268 gnc_table_layout_get_cell_changed (reg->table->layout,
2270 shares_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2273 if (!price_changed && !value_changed && !shares_changed)
2280 gnc_commodity* acc_commodity;
2289 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2298 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2306 value = calculate_value (reg);
2328 recalc_price = TRUE;
2331 recalc_value = TRUE;
2335 recalc_shares = TRUE;
2340 if ((!recalc_shares) &&
2344 if (price_changed && value_changed)
2346 if (!shares_changed)
2347 recalc_shares = TRUE;
2349 else if (value_changed && shares_changed)
2350 recalc_price = TRUE;
2351 else if (price_changed && shares_changed)
2352 recalc_value = TRUE;
2358 denom = gnc_split_get_value_denom (split);
2364 if (!recalc_shares &&
2369 choice = recalc_message_box (reg, shares_changed,
2375 recalc_shares = TRUE;
2378 recalc_price = TRUE;
2381 recalc_value = TRUE;
2389 recalculate_shares (split, reg, value, price, value_changed);
2393 recalculate_price (split, reg, value, amount);
2394 price_changed = TRUE;
2397 recalculate_value (split, reg, price, amount, shares_changed);
2411 case ASSET_REGISTER:
2413 case CREDIT_REGISTER:
2415 case LIABILITY_REGISTER:
2417 case PAYABLE_REGISTER:
2419 case RECEIVABLE_REGISTER:
2422 case INCOME_REGISTER:
2424 case EXPENSE_REGISTER:
2426 case STOCK_REGISTER:
2427 case PORTFOLIO_LEDGER:
2429 case CURRENCY_REGISTER:
2431 case TRADING_REGISTER:
2433 case GENERAL_JOURNAL:
2435 case EQUITY_REGISTER:
2447 SRInfo* info = gnc_split_register_get_info (reg);
2452 if (info->debit_str)
2453 return info->debit_str;
2457 (gnc_split_register_type_to_account_type (reg->type));
2459 if (info->debit_str)
2460 return info->debit_str;
2462 info->debit_str = g_strdup (_ (
"Debit"));
2464 return info->debit_str;
2470 SRInfo* info = gnc_split_register_get_info (reg);
2475 if (info->credit_str)
2476 return info->credit_str;
2480 (gnc_split_register_type_to_account_type (reg->type));
2482 if (info->credit_str)
2483 return info->credit_str;
2485 info->credit_str = g_strdup (_ (
"Credit"));
2487 return info->credit_str;
2493 SRInfo* info = gnc_split_register_get_info (reg);
2494 Transaction* pending_trans;
2496 ENTER (
"reg=%p", reg);
2500 LEAVE (
"no register");
2504 if (gnc_table_current_cursor_changed (reg->table, FALSE))
2506 LEAVE (
"cursor changed");
2511 gnc_get_current_book ());
2514 LEAVE (
"open and pending txn");
2518 LEAVE (
"register unchanged");
2524 gboolean show_present)
2526 SRInfo* info = gnc_split_register_get_info (reg);
2531 info->show_present_divider = show_present;
2537 SRInfo* info = gnc_split_register_get_info (reg);
2542 return info->full_refresh;
2548 gnc_split_register_config_action (SplitRegister* reg)
2552 cell = (
ComboCell*) gnc_table_layout_get_cell (reg->table->layout,
2590 case ASSET_REGISTER:
2595 case CREDIT_REGISTER:
2605 case LIABILITY_REGISTER:
2612 case RECEIVABLE_REGISTER:
2613 case PAYABLE_REGISTER:
2620 case INCOME_REGISTER:
2630 case EXPENSE_REGISTER:
2631 case TRADING_REGISTER:
2637 case GENERAL_JOURNAL:
2638 case EQUITY_REGISTER:
2643 case STOCK_REGISTER:
2644 case PORTFOLIO_LEDGER:
2645 case CURRENCY_REGISTER:
2673 gnc_split_register_config_cells (SplitRegister* reg)
2677 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2682 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2688 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), TRUE);
2693 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), TRUE);
2698 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2703 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL),
2704 gnc_default_share_print_info ());
2707 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, TSHRS_CELL),
2708 gnc_default_share_print_info ());
2714 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, RATE_CELL),
2715 gnc_default_share_print_info ());
2720 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), FALSE);
2725 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), FALSE);
2730 case CURRENCY_REGISTER:
2731 case STOCK_REGISTER:
2732 case PORTFOLIO_LEDGER:
2735 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2744 gnc_split_register_config_action (reg);
2748 split_register_pref_changed (gpointer prefs, gchar* pref, gpointer user_data)
2750 SplitRegister* reg = user_data;
2753 g_return_if_fail (pref);
2757 info = reg->sr_info;
2761 if (g_str_has_suffix (pref, GNC_PREF_ACCOUNTING_LABELS))
2764 g_free (info->tdebit_str);
2765 g_free (info->tcredit_str);
2767 info->debit_str = NULL;
2768 info->tdebit_str = NULL;
2769 info->credit_str = NULL;
2770 info->tcredit_str = NULL;
2773 else if (g_str_has_suffix (pref, GNC_PREF_ACCOUNT_SEPARATOR))
2775 info->separator_changed = TRUE;
2777 else if (g_str_has_suffix (pref, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
2780 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2782 else if (g_str_has_suffix (pref, GNC_PREF_ALT_COLOR_BY_TRANS))
2785 GNC_PREF_ALT_COLOR_BY_TRANS);
2789 g_warning (
"split_register_pref_changed: Unknown preference %s", pref);
2794 split_register_book_option_changed (gpointer new_val, gpointer user_data)
2796 SplitRegister* reg = user_data;
2797 gboolean* new_data = (gboolean*)new_val;
2802 reg->use_tran_num_for_num_field = (*new_data ? FALSE : TRUE);
2806 gnc_split_register_init (SplitRegister* reg,
2809 gboolean use_double_line,
2810 gboolean do_auto_complete,
2811 gboolean is_template,
2812 gboolean mismatched_commodities)
2814 TableLayout* layout;
2820 GNC_PREF_ACCOUNTING_LABELS,
2821 split_register_pref_changed,
2824 GNC_PREF_ACCOUNT_SEPARATOR,
2825 split_register_pref_changed,
2828 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
2829 split_register_pref_changed,
2832 GNC_PREF_ALT_COLOR_BY_TRANS,
2833 split_register_pref_changed,
2835 gnc_book_option_register_cb (OPTION_NAME_NUM_FIELD_SOURCE,
2836 split_register_book_option_changed,
2839 reg->sr_info = NULL;
2841 reg->unrecn_splits = NULL;
2844 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2846 GNC_PREF_ALT_COLOR_BY_TRANS);
2850 reg->use_double_line = use_double_line;
2851 reg->do_auto_complete = do_auto_complete;
2852 reg->is_template = is_template;
2853 reg->mismatched_commodities = mismatched_commodities;
2854 reg->use_tran_num_for_num_field =
2861 model = gnc_template_register_model_new ();
2863 model = gnc_split_register_model_new ();
2864 model->handler_user_data = reg;
2867 control->user_data = reg;
2869 reg->table = gnc_table_new (layout, model, control);
2871 gnc_split_register_config_cells (reg);
2875 VirtualCellLocation vcell_loc = { 0, 0 };
2878 header = gnc_table_layout_get_cursor (reg->table->layout,
CURSOR_HEADER);
2885 VirtualLocation vloc;
2888 vloc.vcell_loc.virt_row = 1;
2889 vloc.vcell_loc.virt_col = 0;
2890 vloc.phys_row_offset = 0;
2891 vloc.phys_col_offset = 0;
2893 cursor = gnc_table_layout_get_cursor (reg->table->layout,
2894 CURSOR_SINGLE_LEDGER);
2902 PERR (
"Can't find valid initial location");
2910 gboolean use_double_line,
2911 gboolean is_template,
2912 gboolean mismatched_commodities)
2915 gboolean default_do_auto_complete = TRUE;
2917 reg = g_new0 (SplitRegister, 1);
2919 if (type >= NUM_SINGLE_REGISTER_TYPES)
2920 style = REG_STYLE_JOURNAL;
2922 gnc_split_register_init (reg,
2926 default_do_auto_complete,
2928 mismatched_commodities);
2937 gboolean use_double_line)
2942 if (reg->use_double_line && !use_double_line)
2944 VirtualLocation virt_loc = reg->table->current_cursor_loc;
2947 if (virt_loc.phys_row_offset)
2950 -virt_loc.phys_row_offset);
2957 virt_loc.vcell_loc.virt_row = 1;
2958 virt_loc.vcell_loc.virt_col = 0;
2959 virt_loc.phys_row_offset = 0;
2960 virt_loc.phys_col_offset = 0;
2965 reg->type = newtype;
2967 if (reg->type >= NUM_SINGLE_REGISTER_TYPES)
2968 newstyle = REG_STYLE_JOURNAL;
2970 reg->style = newstyle;
2971 reg->use_double_line = use_double_line;
2973 gnc_table_realize_gui (reg->table);
2979 g_return_if_fail (reg);
2980 gnc_table_model_set_reverse_sort (reg->table->model, reverse_sort);
2985 gboolean do_auto_complete)
2987 g_return_if_fail (reg);
2988 reg->do_auto_complete = do_auto_complete;
2992 gnc_split_register_destroy_info (SplitRegister* reg)
2999 if (reg->unrecn_splits != NULL)
3001 g_list_free (reg->unrecn_splits);
3002 reg->unrecn_splits = NULL;
3005 info = reg->sr_info;
3009 g_free (info->tdebit_str);
3010 g_free (info->tcredit_str);
3012 info->debit_str = NULL;
3013 info->tdebit_str = NULL;
3014 info->credit_str = NULL;
3015 info->tcredit_str = NULL;
3017 g_free (reg->sr_info);
3019 reg->sr_info = NULL;
3026 SRInfo* info = gnc_split_register_get_info (reg);
3028 g_return_if_fail (reg != NULL);
3030 info->user_data = user_data;
3031 info->get_parent = get_parent;
3035 gnc_split_register_cleanup (SplitRegister* reg)
3037 SRInfo* info = gnc_split_register_get_info (reg);
3038 Transaction* pending_trans;
3039 Transaction* blank_trans = NULL;
3042 ENTER (
"reg=%p", reg);
3045 gnc_get_current_book ());
3048 gnc_get_current_book ());
3050 gnc_suspend_gui_refresh ();
3055 if (blank_split != NULL)
3061 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p",
3062 blank_split, blank_trans, pending_trans);
3071 if (blank_trans == pending_trans)
3073 info->pending_trans_guid = *
guid_null ();
3074 pending_trans = NULL;
3077 info->auto_complete = FALSE;
3082 if (pending_trans != NULL)
3084 g_critical (
"BUG DETECTED: pending_trans=%p, blank_split=%p, blank_trans=%p",
3085 pending_trans, blank_split, blank_trans);
3086 g_assert_not_reached ();
3087 info->pending_trans_guid = *
guid_null ();
3093 else g_assert_not_reached ();
3095 pending_trans = NULL;
3098 gnc_split_register_destroy_info (reg);
3100 gnc_resume_gui_refresh ();
3108 g_return_if_fail (reg);
3110 ENTER (
"reg=%p", reg);
3113 GNC_PREF_ACCOUNTING_LABELS,
3114 split_register_pref_changed,
3117 GNC_PREF_ACCOUNT_SEPARATOR,
3118 split_register_pref_changed,
3121 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
3122 split_register_pref_changed,
3125 GNC_PREF_ALT_COLOR_BY_TRANS,
3126 split_register_pref_changed,
3128 gnc_book_option_remove_cb (OPTION_NAME_NUM_FIELD_SOURCE,
3129 split_register_book_option_changed,
3132 gnc_split_register_cleanup (reg);
3134 gnc_table_destroy (reg->table);
3145 gnc_table_model_set_read_only (reg->table->model, read_only);
3155 case ASSET_REGISTER:
3156 case CREDIT_REGISTER:
3157 case LIABILITY_REGISTER:
3158 case INCOME_REGISTER:
3159 case EXPENSE_REGISTER:
3160 case EQUITY_REGISTER:
3161 case TRADING_REGISTER:
3163 return REG_TYPE_GROUP_CURRENCY;
3166 case PAYABLE_REGISTER:
3167 case RECEIVABLE_REGISTER:
3169 return REG_TYPE_GROUP_APAR;
3173 case GENERAL_JOURNAL:
3176 return REG_TYPE_GROUP_JOURNAL;
3179 case STOCK_REGISTER:
3180 case CURRENCY_REGISTER:
3182 return REG_TYPE_GROUP_STOCK;
3185 case PORTFOLIO_LEDGER:
3187 return REG_TYPE_GROUP_PORTFOLIO;
3191 return REG_TYPE_GROUP_UNKNOWN;
3192 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 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...