29 #include <glib/gi18n.h> 33 #include "dialog-utils.h" 34 #include "gnc-component-manager.h" 40 #include "gnc-warnings.h" 41 #include "split-register-copy-ops.h" 53 #include "dialog-dup-trans.h" 54 #include "engine-helpers.h" 55 #include "qofbookslots.h" 61 static QofLogModule log_module = GNC_MOD_LEDGER;
75 static CursorClass copied_class = CURSOR_CLASS_NONE;
76 static GncGUID copied_leader_guid;
80 static gboolean gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
83 gboolean use_cut_semantics);
84 static gboolean gnc_split_register_auto_calc (SplitRegister *reg,
91 gnc_copy_split_onto_split (Split* from, Split* to, gboolean use_cut_semantics)
95 if ((from == NULL) || (to == NULL))
98 fs = gnc_split_to_float_split (from);
102 gnc_float_split_to_split (fs, to);
103 gnc_float_split_free (fs);
108 gboolean use_cut_semantics,
113 if ((from == NULL) || (to == NULL))
116 ft = gnc_txn_to_float_txn (from, use_cut_semantics);
120 gnc_float_txn_to_txn (ft, to, do_commit);
121 gnc_float_txn_free (ft);
125 gnc_split_get_value_denom (Split* split)
127 gnc_commodity* currency;
144 gnc_split_get_amount_denom (Split* split)
162 gnc_split_register_begin_edit_or_warn (SRInfo* info, Transaction* trans)
164 ENTER (
"info=%p, trans=%p", info, trans);
171 LEAVE (
"opened and marked pending");
177 gnc_get_current_book ());
180 if (trans == blank_trans)
185 LEAVE (
"already open, now pending.");
190 GtkWindow* parent = NULL;
191 if (info->get_parent)
192 parent = GTK_WINDOW (info->get_parent (info->user_data));
193 gnc_error_dialog (parent,
"%s",
194 _ (
"This transaction is already being edited in another register. Please finish editing it there first."));
195 LEAVE (
"already editing");
206 SRInfo* info = gnc_split_register_get_info (reg);
207 VirtualLocation virt_loc;
212 if (reg->style == REG_STYLE_AUTO_LEDGER ||
213 reg->style == REG_STYLE_JOURNAL)
217 if (! (expand ^ info->trans_expanded))
222 virt_loc = reg->table->current_cursor_loc;
223 gnc_split_register_get_trans_split (reg, virt_loc.vcell_loc,
224 &virt_loc.vcell_loc);
230 PERR (
"Can't find place to go!");
235 info->trans_expanded = expand;
238 reg->table->current_cursor_loc.vcell_loc,
239 gnc_split_register_get_active_cursor (reg));
242 reg, reg->table->current_cursor_loc.vcell_loc, expand, FALSE);
244 virt_loc = reg->table->current_cursor_loc;
245 if (!expand || !gnc_table_virtual_loc_valid (reg->table, virt_loc, FALSE))
251 PERR (
"Can't find place to go!");
259 gnc_split_register_show_trans (reg,
260 reg->table->current_cursor_loc.vcell_loc);
266 SRInfo* info = gnc_split_register_get_info (reg);
271 if (reg->style == REG_STYLE_AUTO_LEDGER ||
272 reg->style == REG_STYLE_JOURNAL)
275 return info->trans_expanded;
282 VirtualCellLocation vcell_loc;
293 vcell_loc = reg->table->current_cursor_loc.vcell_loc;
295 vcell_loc.virt_row--;
297 split = gnc_split_register_get_split (reg, vcell_loc);
308 return gnc_split_register_get_split (
309 reg, reg->table->current_cursor_loc.vcell_loc);
315 SRInfo* info = gnc_split_register_get_info (reg);
317 if (!reg)
return NULL;
319 return xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ());
324 VirtualCellLocation* vcell_loc)
330 if (!reg || !split)
return FALSE;
337 for (v_row =
table->num_virt_rows - 1; v_row > 0; v_row--)
338 for (v_col = 0; v_col <
table->num_virt_cols; v_col++)
340 VirtualCellLocation vc_loc = { v_row, v_col };
364 VirtualLocation* virt_loc)
366 VirtualLocation v_loc;
368 const char* cell_name;
378 switch (cursor_class)
380 case CURSOR_CLASS_SPLIT:
381 case CURSOR_CLASS_TRANS:
388 if (!gnc_table_get_cell_location (reg->table, cell_name,
389 v_loc.vcell_loc, &v_loc))
392 if (virt_loc == NULL)
403 SRInfo* info = gnc_split_register_get_info (reg);
412 ENTER (
"reg=%p", reg);
415 gnc_get_current_book ());
423 LEAVE (
"no transaction");
430 if (cursor_class == CURSOR_CLASS_NONE)
432 LEAVE (
"no cursor class");
437 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
439 LEAVE (
"no split with transaction class");
443 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
447 if (!changed && ((split == NULL) || (split == blank_split)))
449 LEAVE (
"skip unchanged blank split");
453 gnc_suspend_gui_refresh ();
459 GtkWidget* dialog, *window;
461 const char* title = _ (
"Save transaction before duplicating?");
462 const char* message =
463 _ (
"The current transaction has been changed. Would you like to " 464 "record the changes before duplicating the transaction, or " 465 "cancel the duplication?");
467 window = gnc_split_register_get_parent (reg);
468 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
469 GTK_DIALOG_DESTROY_WITH_PARENT,
470 GTK_MESSAGE_QUESTION,
473 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
475 gtk_dialog_add_button (GTK_DIALOG (dialog),
476 _ (
"_Record"), GTK_RESPONSE_ACCEPT);
477 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_DUP);
478 gtk_widget_destroy (dialog);
480 if (response != GTK_RESPONSE_ACCEPT)
482 gnc_resume_gui_refresh ();
483 LEAVE (
"save cancelled");
499 if (cursor_class == CURSOR_CLASS_SPLIT)
503 gboolean new_act_num = FALSE;
512 if (!reg->use_tran_num_for_num_field
516 const char* in_num = NULL;
517 const char* title = _ (
"New Split Information");
518 time64 date = info->last_date_entered;
523 in_num = gnc_get_num_action (NULL, split);
525 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg),
526 title, FALSE, &date, in_num, &out_num,
527 NULL, NULL, NULL, NULL))
529 gnc_resume_gui_refresh ();
530 LEAVE (
"dup cancelled");
539 xaccSplitSetParent (new_split, trans);
540 gnc_copy_split_onto_split (split, new_split, FALSE);
542 gnc_set_num_action (NULL, new_split, out_num, NULL);
552 gnc_split_register_get_default_account (reg),
556 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
558 if (gnc_num_cell_set_last_num (num_cell, out_num))
559 gnc_split_register_set_last_num (reg, out_num);
567 return_split = new_split;
569 info->cursor_hint_split = new_split;
570 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
578 Transaction* new_trans;
579 int trans_split_index;
581 const char* in_num = NULL;
582 const char* in_tnum = NULL;
583 char* out_num = NULL;
584 char* out_tnum = NULL;
585 char* out_tdoclink = NULL;
588 gnc_get_current_book ());
592 date = info->last_date_entered;
594 account = gnc_split_register_get_default_account (reg);
596 if (account &&
gnc_strisnum (gnc_get_num_action (trans, trans_split)))
599 in_num = gnc_get_num_action (trans, trans_split);
601 in_tnum = (reg->use_tran_num_for_num_field
603 : gnc_get_num_action (trans, NULL));
605 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg), NULL,
606 TRUE, &date, in_num, &out_num, in_tnum, &out_tnum,
609 gnc_resume_gui_refresh ();
610 LEAVE (
"dup cancelled");
614 if (use_autoreadonly)
618 gnc_get_current_book ());
620 if (g_date_compare (&d, readonly_threshold) < 0)
622 GtkWidget* dialog = gtk_message_dialog_new (NULL,
626 "%s", _ (
"Cannot store a transaction at this date"));
627 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
628 "%s", _ (
"The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. " 629 "This setting can be changed in File->Properties->Accounts."));
630 gtk_dialog_run (GTK_DIALOG (dialog));
631 gtk_widget_destroy (dialog);
633 g_date_free (readonly_threshold);
636 g_date_free (readonly_threshold);
645 gnc_resume_gui_refresh ();
660 if (out_tdoclink == NULL)
663 g_free (out_tdoclink);
666 gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
667 if (!reg->use_tran_num_for_num_field)
671 gnc_set_num_action (NULL,
680 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
682 if (gnc_num_cell_set_last_num (num_cell, out_num))
683 gnc_split_register_set_last_num (reg, out_num);
686 if (!reg->use_tran_num_for_num_field)
696 info->cursor_hint_trans = new_trans;
697 info->cursor_hint_split = return_split;
698 info->cursor_hint_trans_split = trans_split;
699 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
701 info->trans_expanded = FALSE;
705 gnc_resume_gui_refresh ();
712 gnc_split_register_copy_current_internal (SplitRegister* reg,
713 gboolean use_cut_semantics)
715 SRInfo* info = gnc_split_register_get_info (reg);
724 g_return_if_fail (reg);
725 ENTER (
"reg=%p, use_cut_semantics=%s", reg,
726 use_cut_semantics ?
"TRUE" :
"FALSE");
729 gnc_get_current_book ());
743 if (cursor_class == CURSOR_CLASS_NONE)
745 LEAVE (
"no cursor class");
750 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
752 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
753 LEAVE (
"transaction cursor with no anchoring split");
757 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
760 if (!changed && ((split == NULL) || (split == blank_split)))
769 LEAVE (
"nothing to copy/cut");
775 if (cursor_class == CURSOR_CLASS_SPLIT)
778 new_fs = gnc_split_to_float_split (split);
783 gnc_split_register_save_to_copy_buffer (reg, NULL, new_fs,
792 new_ft = gnc_txn_to_float_txn (trans, use_cut_semantics);
802 if (split_index >= 0)
803 fs = gnc_float_txn_get_float_split (new_ft, split_index);
807 gnc_split_register_save_to_copy_buffer (reg, new_ft, fs,
811 copied_leader_guid = info->default_account;
815 if (!new_fs && !new_ft)
817 g_warning (
"BUG DETECTED: copy failed");
818 LEAVE (
"copy failed");
823 if (copied_item.ftype == GNC_TYPE_SPLIT)
824 gnc_float_split_free (copied_item.fs);
825 if (copied_item.ftype == GNC_TYPE_TRANSACTION)
826 gnc_float_txn_free (copied_item.ft);
827 copied_item.ftype = 0;
831 copied_item.fs = new_fs;
832 copied_item.ftype = GNC_TYPE_SPLIT;
836 copied_item.ft = new_ft;
837 copied_item.ftype = GNC_TYPE_TRANSACTION;
840 copied_class = cursor_class;
841 LEAVE (
"%s %s", use_cut_semantics ?
"cut" :
"copied",
842 cursor_class == CURSOR_CLASS_SPLIT ?
"split" :
"transaction");
848 gnc_split_register_copy_current_internal (reg, FALSE);
854 SRInfo* info = gnc_split_register_get_info (reg);
862 gnc_get_current_book ());
873 if (cursor_class == CURSOR_CLASS_NONE)
877 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
880 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
883 if (!changed && ((split == NULL) || (split == blank_split)))
886 gnc_split_register_copy_current_internal (reg, TRUE);
888 if (cursor_class == CURSOR_CLASS_SPLIT)
897 SRInfo* info = gnc_split_register_get_info (reg);
900 Transaction* blank_trans;
905 ENTER (
"reg=%p", reg);
907 if (copied_class == CURSOR_CLASS_NONE)
909 LEAVE (
"no copied cursor class");
914 gnc_get_current_book ());
924 LEAVE (
"no transaction");
931 if (cursor_class == CURSOR_CLASS_NONE)
933 LEAVE (
"no current cursor class");
938 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
940 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
941 LEAVE (
"transaction cursor with no anchoring split");
945 if (cursor_class == CURSOR_CLASS_SPLIT)
947 const char* message = _ (
"You are about to overwrite an existing split. " 948 "Are you sure you want to do that?");
949 const char* anchor_message = _ (
"This is the split anchoring this transaction " 950 "to the register. You may not overwrite it from " 951 "this register window. You may overwrite it if " 952 "you navigate to a register that shows another " 953 "side of this same transaction.");
955 if (copied_class == CURSOR_CLASS_TRANS)
958 LEAVE (
"can't copy trans to split");
965 if ((reg->type != GENERAL_JOURNAL) &&
968 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
969 "%s", anchor_message);
970 LEAVE (
"anchore split");
973 else if (!gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
974 FALSE,
"%s", message))
976 LEAVE (
"user cancelled");
982 if (gnc_split_register_begin_edit_or_warn (info, trans))
984 LEAVE (
"can't begin editing");
988 gnc_suspend_gui_refresh ();
994 xaccSplitSetParent (split, trans);
997 if (copied_item.ftype != GNC_TYPE_SPLIT)
999 LEAVE (
"copy buffer doesn't represent a split");
1003 gnc_float_split_to_split (copied_item.fs, split);
1007 const char *message = _(
"You are about to overwrite an existing " 1009 "Are you sure you want to do that?");
1013 int trans_split_index;
1017 if (copied_class == CURSOR_CLASS_SPLIT)
1019 LEAVE (
"can't copy split to transaction");
1024 if (copied_item.ftype != GNC_TYPE_TRANSACTION)
1026 LEAVE (
"copy buffer doesn't represent a transaction");
1031 if (split != blank_split &&
1032 !gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1033 FALSE,
"%s", message))
1035 LEAVE (
"user cancelled");
1040 if (gnc_split_register_begin_edit_or_warn (info, trans))
1042 LEAVE (
"can't begin editing");
1046 gnc_suspend_gui_refresh ();
1048 DEBUG (
"Pasting txn, trans=%p, split=%p, blank_trans=%p, blank_split=%p",
1049 trans, split, blank_trans, blank_split);
1055 gnc_get_current_book ());
1056 default_account = gnc_split_register_get_default_account (reg);
1057 if (copied_leader && default_account)
1059 gnc_float_txn_to_txn_swap_accounts (copied_item.ft, trans,
1061 default_account, FALSE);
1064 gnc_float_txn_to_txn (copied_item.ft, trans, FALSE);
1067 if (split_index >= num_splits)
1070 if (trans == blank_trans)
1075 info->blank_split_edited = TRUE;
1076 info->auto_complete = FALSE;
1077 DEBUG (
"replacement blank_split=%p", blank_split);
1084 info->cursor_hint_trans = trans;
1088 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
1092 gnc_resume_gui_refresh ();
1099 SRInfo* info = gnc_split_register_get_info (reg);
1100 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1101 gnc_get_current_book ());
1103 if (split == current_blank_split)
1112 SRInfo* info = gnc_split_register_get_info (reg);
1113 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1114 gnc_get_current_book ());
1115 Split* pref_split = NULL;
1116 Split* other_split = NULL;
1124 if (s != current_blank_split)
1133 if (pref_split != NULL)
1135 else if (other_split != NULL)
1142 SRInfo* info = gnc_split_register_get_info (reg);
1143 Transaction* pending_trans;
1151 gnc_get_current_book ());
1154 gnc_get_current_book ());
1164 if (split == blank_split)
1170 gnc_suspend_gui_refresh ();
1175 if (trans == pending_trans)
1181 g_assert (!pending_trans);
1182 if (gnc_split_register_begin_edit_or_warn (info, trans))
1184 gnc_resume_gui_refresh ();
1190 gnc_resume_gui_refresh ();
1197 SRInfo* info = gnc_split_register_get_info (reg);
1198 Transaction* pending_trans;
1204 ENTER (
"reg=%p", reg);
1207 LEAVE (
"no register");
1212 gnc_get_current_book ());
1214 gnc_get_current_book ());
1224 gnc_suspend_gui_refresh ();
1230 if (split == blank_split)
1232 DEBUG (
"deleting blank split");
1234 info->auto_complete = FALSE;
1238 info->trans_expanded = FALSE;
1242 if (trans == pending_trans)
1244 DEBUG (
"clearing pending trans");
1245 info->pending_trans_guid = *
guid_null ();
1246 pending_trans = NULL;
1253 DEBUG (
"committing");
1256 gnc_resume_gui_refresh ();
1264 SRInfo* info = gnc_split_register_get_info (reg);
1265 Transaction* pending_trans;
1273 gnc_get_current_book ());
1275 gnc_get_current_book ());
1283 if (split == blank_split)
1290 info->trans_expanded = FALSE;
1292 gnc_suspend_gui_refresh ();
1298 if (trans == pending_trans)
1300 info->pending_trans_guid = *
guid_null ();
1301 pending_trans = NULL;
1305 PERR (
"We should not be voiding an open transaction.");
1308 gnc_resume_gui_refresh ();
1314 SRInfo* info = gnc_split_register_get_info (reg);
1315 Transaction* pending_trans;
1323 gnc_get_current_book ());
1325 gnc_get_current_book ());
1333 if (split == blank_split)
1340 info->trans_expanded = FALSE;
1342 gnc_suspend_gui_refresh ();
1349 if (trans == pending_trans)
1351 info->pending_trans_guid = *
guid_null ();
1352 pending_trans = NULL;
1355 gnc_resume_gui_refresh ();
1364 Transaction* pending;
1368 if ((reg == NULL) || (split == NULL))
1371 gnc_suspend_gui_refresh ();
1372 info = gnc_split_register_get_info (reg);
1373 pending =
xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ());
1378 if (gnc_split_register_begin_edit_or_warn (info, trans))
1380 gnc_resume_gui_refresh ();
1384 else if (pending == trans)
1388 else g_assert_not_reached ();
1397 gnc_resume_gui_refresh ();
1402 gnc_split_register_empty_current_trans (SplitRegister* reg)
1414 VirtualLocation virt_loc;
1419 virt_loc = reg->table->current_cursor_loc;
1421 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1426 gnc_table_clear_current_cursor_changes (reg->table);
1437 SRInfo* info = gnc_split_register_get_info (reg);
1438 Transaction* pending_trans, *blank_trans;
1439 gboolean refresh_all = FALSE;
1442 gnc_get_current_book ());
1446 if (pending_trans == blank_trans)
1461 gnc_suspend_gui_refresh ();
1465 info->pending_trans_guid = *
guid_null ();
1467 gnc_resume_gui_refresh ();
1470 gnc_gui_refresh_all ();
1478 gnc_ledger_display_refresh_by_split_register (reg);
1484 gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
1486 gboolean use_cut_semantics)
1494 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1503 if (gnc_table_layout_get_cell_changed (reg->table->layout, DATE_CELL, TRUE))
1507 cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
1512 if (gnc_table_layout_get_cell_changed (reg->table->layout, NUM_CELL, TRUE))
1516 value = gnc_table_layout_get_cell_value (reg->table->layout, NUM_CELL);
1517 if (reg->use_tran_num_for_num_field)
1524 if (gnc_table_layout_get_cell_changed (reg->table->layout, TNUM_CELL, TRUE))
1528 value = gnc_table_layout_get_cell_value (reg->table->layout, TNUM_CELL);
1529 if (!reg->use_tran_num_for_num_field)
1534 if (gnc_table_layout_get_cell_changed (reg->table->layout, DESC_CELL, TRUE))
1538 value = gnc_table_layout_get_cell_value (reg->table->layout, DESC_CELL);
1542 if (gnc_table_layout_get_cell_changed (reg->table->layout, NOTES_CELL, TRUE))
1546 value = gnc_table_layout_get_cell_value (reg->table->layout, NOTES_CELL);
1550 if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, TRUE))
1555 cell = gnc_table_layout_get_cell (reg->table->layout, RECN_CELL);
1556 flag = gnc_recn_cell_get_flag ((
RecnCell*) cell);
1558 gnc_float_split_set_reconcile_state (fs, flag);
1561 if (gnc_table_layout_get_cell_changed (reg->table->layout, ACTN_CELL, TRUE))
1565 value = gnc_table_layout_get_cell_value (reg->table->layout, ACTN_CELL);
1566 gnc_float_split_set_action (fs, value);
1569 if (gnc_table_layout_get_cell_changed (reg->table->layout, MEMO_CELL, TRUE))
1573 value = gnc_table_layout_get_cell_value (reg->table->layout, MEMO_CELL);
1574 gnc_float_split_set_memo (fs, value);
1577 if (gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, TRUE))
1581 new_account = gnc_split_register_get_account (reg, XFRM_CELL);
1583 if (new_account != NULL)
1584 gnc_float_split_set_account (fs, new_account);
1587 if (reg->style == REG_STYLE_LEDGER)
1588 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1590 if (gnc_table_layout_get_cell_changed (reg->table->layout, MXFRM_CELL, TRUE))
1592 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1596 if (g_list_length (ft->m_splits) == 1)
1601 other_fs = gnc_split_to_float_split (temp_split);
1604 gnc_float_txn_append_float_split (ft, other_fs);
1612 new_account = gnc_split_register_get_account (reg, MXFRM_CELL);
1614 if (new_account != NULL)
1615 gnc_float_split_set_account (other_fs, new_account);
1619 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1621 gnc_table_layout_get_cell_changed (reg->table->layout,
1625 gnc_numeric new_value;
1629 cell = gnc_table_layout_get_cell (reg->table->layout, CRED_CELL);
1632 cell = gnc_table_layout_get_cell (reg->table->layout, DEBT_CELL);
1635 new_value = gnc_numeric_sub_fixed (debit, credit);
1637 gnc_float_split_set_value (fs, new_value);
1640 if (gnc_table_layout_get_cell_changed (reg->table->layout, PRIC_CELL, TRUE))
1645 if (gnc_table_layout_get_cell_changed (reg->table->layout, SHRS_CELL, TRUE))
1650 cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
1654 gnc_float_split_set_amount (fs, shares);
1657 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1659 gnc_table_layout_get_cell_changed (reg->table->layout,
1661 gnc_table_layout_get_cell_changed (reg->table->layout,
1663 gnc_table_layout_get_cell_changed (reg->table->layout,
1670 num = gnc_float_split_get_amount (fs);
1673 num = gnc_float_split_get_value (fs);
1681 unreconcile_splits (SplitRegister* reg)
1683 if (reg->unrecn_splits == NULL)
1685 PINFO (
"Unreconcile %d splits of reconciled transaction",
1686 g_list_length (reg->unrecn_splits));
1688 for (GList* node = reg->unrecn_splits; node; node = node->next)
1690 Split* split = node->data;
1693 PWARN (
"Unreconcile of split failed because its parent transaction wasn't open for editing");
1697 g_list_free (reg->unrecn_splits);
1698 reg->unrecn_splits = NULL;
1704 SRInfo* info = gnc_split_register_get_info (reg);
1705 Transaction* pending_trans;
1706 Transaction* blank_trans;
1714 ENTER (
"reg=%p, do_commit=%s", reg, do_commit ?
"TRUE" :
"FALSE");
1718 LEAVE (
"no register");
1723 gnc_get_current_book ());
1726 gnc_get_current_book ());
1735 LEAVE (
"no transaction");
1742 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1746 LEAVE (
"commit unnecessary");
1752 LEAVE (
"transaction not open");
1756 if (trans == pending_trans ||
1757 (trans == blank_trans && info->blank_split_edited))
1761 gnc_suspend_gui_refresh ();
1763 if (trans == blank_trans)
1769 info->blank_split_edited = FALSE;
1770 info->auto_complete = FALSE;
1775 if (trans == pending_trans)
1776 info->pending_trans_guid = *
guid_null ();
1778 PINFO (
"committing trans (%p)", trans);
1779 unreconcile_splits (reg);
1783 gnc_resume_gui_refresh ();
1786 DEBUG (
"leaving trans (%p) open", trans);
1788 LEAVE (
"unchanged cursor");
1792 DEBUG (
"save split=%p", split);
1793 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p, trans=%p",
1794 blank_split, blank_trans, pending_trans, trans);
1797 if (!gnc_split_register_check_cell (reg,
1798 gnc_table_get_current_cell_name (reg->table)))
1800 LEAVE (
"need another go at changing cell");
1804 if (!gnc_split_register_auto_calc (reg, split))
1806 LEAVE (
"auto calc failed");
1811 (void)gnc_split_register_get_account (reg, MXFRM_CELL);
1812 (void)gnc_split_register_get_account (reg, XFRM_CELL);
1817 LEAVE (
"no exchange rate");
1821 gnc_suspend_gui_refresh ();
1824 if (pending_trans != trans)
1831 g_warning (
"Impossible? committing pending %p", pending_trans);
1832 unreconcile_splits (reg);
1836 else if (pending_trans)
1838 g_critical (
"BUG DETECTED! pending transaction (%p) not open",
1840 g_assert_not_reached ();
1843 if (trans == blank_trans)
1853 PINFO (
"beginning edit of trans %p", trans);
1854 if (gnc_split_register_begin_edit_or_warn (info, trans))
1856 gnc_resume_gui_refresh ();
1857 LEAVE (
"transaction opened elsewhere");
1861 pending_trans = trans;
1872 if (split == blank_split && !info->blank_split_edited)
1879 account = gnc_split_register_get_default_account (reg);
1881 xaccSplitSetAccount (blank_split, account);
1901 reg->table->current_cursor_loc.vcell_loc,
1903 DEBUG (
"assigned cell to new split=%p", split);
1906 if ((info->cursor_hint_trans == trans) &&
1907 (info->cursor_hint_trans_split == trans_split) &&
1908 (info->cursor_hint_split == NULL))
1910 info->cursor_hint_split = split;
1911 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1915 DEBUG (
"updating trans=%p", trans);
1920 sd = gnc_split_register_save_data_new (
1921 trans, split, (info->trans_expanded ||
1922 reg->style == REG_STYLE_AUTO_LEDGER ||
1923 reg->style == REG_STYLE_JOURNAL));
1924 gnc_table_save_cells (reg->table, sd);
1925 gnc_split_register_save_data_destroy (sd);
1929 memo = memo ? memo :
"(null)";
1931 desc = desc ? desc :
"(null)";
1932 PINFO (
"finished saving split \"%s\" of trans \"%s\"", memo, desc);
1938 if (trans == blank_trans)
1943 info->auto_complete = FALSE;
1948 info->blank_split_edited = TRUE;
1955 g_assert (trans == blank_trans || trans == pending_trans);
1956 if (pending_trans == trans)
1958 pending_trans = NULL;
1959 info->pending_trans_guid = *
guid_null ();
1961 unreconcile_splits (reg);
1966 gnc_table_clear_current_cursor_changes (reg->table);
1968 gnc_resume_gui_refresh ();
1976 gnc_split_register_get_account_by_name (SplitRegister* reg, BasicCell* bcell,
1979 const char* placeholder = _ (
"The account %s does not allow transactions.");
1980 const char* missing = _ (
"The account %s does not exist. " 1981 "Would you like to create it?");
1985 static gboolean creating_account = FALSE;
1986 GtkWindow* parent = GTK_WINDOW (gnc_split_register_get_parent (reg));
1988 if (!name || (strlen (name) == 0))
2001 if (!account && !creating_account)
2004 if (!gnc_verify_dialog (parent, TRUE, missing, name))
2006 creating_account = TRUE;
2009 creating_account = FALSE;
2014 if (!creating_account)
2018 reg->show_leaf_accounts);
2019 if (g_strcmp0 (account_name, gnc_basic_cell_get_value (bcell)))
2022 gnc_combo_cell_set_value (cell, account_name);
2023 gnc_basic_cell_set_changed (&cell->cell, TRUE);
2025 g_free (account_name);
2031 gnc_error_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
2032 placeholder, fullname);
2043 gnc_split_register_get_account (SplitRegister* reg,
const char* cell_name)
2048 if (!gnc_table_layout_get_cell_changed (reg->table->layout, cell_name, TRUE))
2051 cell = gnc_table_layout_get_cell (reg->table->layout, cell_name);
2054 name = gnc_basic_cell_get_value (cell);
2055 return gnc_split_register_get_account_by_name (reg, cell, name);
2059 calculate_value (SplitRegister* reg)
2068 cell = (
PriceCell*)gnc_table_layout_get_cell (reg->table->layout,
2072 return gnc_numeric_sub_fixed (debit, credit);
2077 recalc_message_box (SplitRegister* reg, gboolean shares_changed,
2078 gboolean price_changed, gboolean value_changed)
2083 GList* radio_list = NULL;
2084 const char* title = _ (
"Recalculate Transaction");
2085 const char* message = _ (
"The values entered for this transaction " 2086 "are inconsistent. Which value would you " 2087 "like to have recalculated?");
2090 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2094 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Shares")));
2097 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2101 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Price")));
2104 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2108 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Value")));
2110 if (price_changed) default_value = 2;
2111 else default_value = 1;
2113 choice = gnc_choose_radio_option_dialog
2114 (gnc_split_register_get_parent (reg),
2121 for (node = radio_list; node; node = node->next)
2122 g_free (node->data);
2124 g_list_free (radio_list);
2130 recalculate_shares (Split* split, SplitRegister* reg,
2131 gnc_numeric value, gnc_numeric price, gboolean value_changed)
2133 gint64 denom = gnc_split_get_amount_denom (split);
2137 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
2139 gnc_basic_cell_set_changed (cell, TRUE);
2143 cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2144 gnc_basic_cell_set_changed (cell, FALSE);
2149 recalculate_price (Split* split, SplitRegister* reg,
2150 gnc_numeric value, gnc_numeric amount)
2152 BasicCell* price_cell;
2159 BasicCell* debit_cell;
2160 BasicCell* credit_cell;
2162 debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2165 credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2174 gnc_basic_cell_set_changed (debit_cell, TRUE);
2175 gnc_basic_cell_set_changed (credit_cell, TRUE);
2178 price_cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2180 gnc_basic_cell_set_changed (price_cell, TRUE);
2184 recalculate_value (Split* split, SplitRegister* reg,
2185 gnc_numeric price, gnc_numeric amount, gboolean shares_changed)
2187 BasicCell* debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2189 BasicCell* credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2191 gint64 denom = gnc_split_get_value_denom (split);
2198 gnc_basic_cell_set_changed (debit_cell, TRUE);
2199 gnc_basic_cell_set_changed (credit_cell, TRUE);
2203 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout,
2205 gnc_basic_cell_set_changed (cell, FALSE);
2210 gnc_split_register_auto_calc (SplitRegister* reg, Split* split)
2213 gboolean recalc_shares = FALSE;
2214 gboolean recalc_price = FALSE;
2215 gboolean recalc_value = FALSE;
2216 gboolean price_changed;
2217 gboolean value_changed;
2218 gboolean shares_changed;
2219 gnc_numeric calc_value;
2227 if (STOCK_REGISTER != reg->type &&
2228 CURRENCY_REGISTER != reg->type &&
2229 PORTFOLIO_LEDGER != reg->type)
2232 account = gnc_split_register_get_account (reg, XFRM_CELL);
2238 account = gnc_split_register_get_default_account (reg);
2243 price_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2245 value_changed = (gnc_table_layout_get_cell_changed (reg->table->layout,
2247 gnc_table_layout_get_cell_changed (reg->table->layout,
2249 shares_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2252 if (!price_changed && !value_changed && !shares_changed)
2259 gnc_commodity* acc_commodity;
2268 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2277 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2285 value = calculate_value (reg);
2307 recalc_price = TRUE;
2310 recalc_value = TRUE;
2314 recalc_shares = TRUE;
2319 if ((!recalc_shares) &&
2323 if (price_changed && value_changed)
2325 if (!shares_changed)
2326 recalc_shares = TRUE;
2328 else if (value_changed && shares_changed)
2329 recalc_price = TRUE;
2330 else if (price_changed && shares_changed)
2331 recalc_value = TRUE;
2337 denom = gnc_split_get_value_denom (split);
2343 if (!recalc_shares &&
2348 choice = recalc_message_box (reg, shares_changed,
2354 recalc_shares = TRUE;
2357 recalc_price = TRUE;
2360 recalc_value = TRUE;
2368 recalculate_shares (split, reg, value, price, value_changed);
2372 recalculate_price (split, reg, value, amount);
2373 price_changed = TRUE;
2376 recalculate_value (split, reg, price, amount, shares_changed);
2390 case ASSET_REGISTER:
2392 case CREDIT_REGISTER:
2394 case LIABILITY_REGISTER:
2396 case PAYABLE_REGISTER:
2398 case RECEIVABLE_REGISTER:
2401 case INCOME_REGISTER:
2403 case EXPENSE_REGISTER:
2405 case STOCK_REGISTER:
2406 case PORTFOLIO_LEDGER:
2408 case CURRENCY_REGISTER:
2410 case TRADING_REGISTER:
2412 case GENERAL_JOURNAL:
2414 case EQUITY_REGISTER:
2426 SRInfo* info = gnc_split_register_get_info (reg);
2431 if (info->debit_str)
2432 return info->debit_str;
2436 (gnc_split_register_type_to_account_type (reg->type));
2438 if (info->debit_str)
2439 return info->debit_str;
2441 info->debit_str = g_strdup (_ (
"Debit"));
2443 return info->debit_str;
2449 SRInfo* info = gnc_split_register_get_info (reg);
2454 if (info->credit_str)
2455 return info->credit_str;
2459 (gnc_split_register_type_to_account_type (reg->type));
2461 if (info->credit_str)
2462 return info->credit_str;
2464 info->credit_str = g_strdup (_ (
"Credit"));
2466 return info->credit_str;
2472 SRInfo* info = gnc_split_register_get_info (reg);
2473 Transaction* pending_trans;
2475 ENTER (
"reg=%p", reg);
2479 LEAVE (
"no register");
2483 if (gnc_table_current_cursor_changed (reg->table, FALSE))
2485 LEAVE (
"cursor changed");
2490 gnc_get_current_book ());
2493 LEAVE (
"open and pending txn");
2497 LEAVE (
"register unchanged");
2503 gboolean show_present)
2505 SRInfo* info = gnc_split_register_get_info (reg);
2510 info->show_present_divider = show_present;
2516 SRInfo* info = gnc_split_register_get_info (reg);
2521 return info->full_refresh;
2527 gnc_split_register_config_action (SplitRegister* reg)
2531 cell = (
ComboCell*) gnc_table_layout_get_cell (reg->table->layout,
2569 case ASSET_REGISTER:
2574 case CREDIT_REGISTER:
2584 case LIABILITY_REGISTER:
2591 case RECEIVABLE_REGISTER:
2592 case PAYABLE_REGISTER:
2599 case INCOME_REGISTER:
2609 case EXPENSE_REGISTER:
2610 case TRADING_REGISTER:
2616 case GENERAL_JOURNAL:
2617 case EQUITY_REGISTER:
2622 case STOCK_REGISTER:
2623 case PORTFOLIO_LEDGER:
2624 case CURRENCY_REGISTER:
2652 gnc_split_register_config_cells (SplitRegister* reg)
2656 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2661 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2667 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), TRUE);
2672 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2677 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL),
2678 gnc_default_share_print_info ());
2681 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, TSHRS_CELL),
2682 gnc_default_share_print_info ());
2688 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, RATE_CELL),
2689 gnc_default_share_print_info ());
2694 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), FALSE);
2699 case CURRENCY_REGISTER:
2700 case STOCK_REGISTER:
2701 case PORTFOLIO_LEDGER:
2704 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2713 gnc_split_register_config_action (reg);
2717 split_register_pref_changed (gpointer prefs, gchar* pref, gpointer user_data)
2719 SplitRegister* reg = user_data;
2722 g_return_if_fail (pref);
2726 info = reg->sr_info;
2730 if (g_str_has_suffix (pref, GNC_PREF_ACCOUNTING_LABELS))
2733 g_free (info->tdebit_str);
2734 g_free (info->tcredit_str);
2736 info->debit_str = NULL;
2737 info->tdebit_str = NULL;
2738 info->credit_str = NULL;
2739 info->tcredit_str = NULL;
2742 else if (g_str_has_suffix (pref, GNC_PREF_ACCOUNT_SEPARATOR))
2744 info->separator_changed = TRUE;
2746 else if (g_str_has_suffix (pref, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
2749 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2751 else if (g_str_has_suffix (pref, GNC_PREF_ALT_COLOR_BY_TRANS))
2754 GNC_PREF_ALT_COLOR_BY_TRANS);
2758 g_warning (
"split_register_pref_changed: Unknown preference %s", pref);
2763 split_register_book_option_changed (gpointer new_val, gpointer user_data)
2765 SplitRegister* reg = user_data;
2766 gboolean* new_data = (gboolean*)new_val;
2771 reg->use_tran_num_for_num_field = (*new_data ? FALSE : TRUE);
2775 gnc_split_register_init (SplitRegister* reg,
2778 gboolean use_double_line,
2779 gboolean do_auto_complete,
2780 gboolean is_template,
2781 gboolean mismatched_commodities)
2783 TableLayout* layout;
2789 GNC_PREF_ACCOUNTING_LABELS,
2790 split_register_pref_changed,
2793 GNC_PREF_ACCOUNT_SEPARATOR,
2794 split_register_pref_changed,
2797 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
2798 split_register_pref_changed,
2801 GNC_PREF_ALT_COLOR_BY_TRANS,
2802 split_register_pref_changed,
2804 gnc_book_option_register_cb (OPTION_NAME_NUM_FIELD_SOURCE,
2805 split_register_book_option_changed,
2808 reg->sr_info = NULL;
2810 reg->unrecn_splits = NULL;
2813 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2815 GNC_PREF_ALT_COLOR_BY_TRANS);
2819 reg->use_double_line = use_double_line;
2820 reg->do_auto_complete = do_auto_complete;
2821 reg->is_template = is_template;
2822 reg->mismatched_commodities = mismatched_commodities;
2823 reg->use_tran_num_for_num_field =
2830 model = gnc_template_register_model_new ();
2832 model = gnc_split_register_model_new ();
2833 model->handler_user_data = reg;
2836 control->user_data = reg;
2838 reg->table = gnc_table_new (layout, model, control);
2840 gnc_split_register_config_cells (reg);
2844 VirtualCellLocation vcell_loc = { 0, 0 };
2847 header = gnc_table_layout_get_cursor (reg->table->layout,
CURSOR_HEADER);
2854 VirtualLocation vloc;
2857 vloc.vcell_loc.virt_row = 1;
2858 vloc.vcell_loc.virt_col = 0;
2859 vloc.phys_row_offset = 0;
2860 vloc.phys_col_offset = 0;
2862 cursor = gnc_table_layout_get_cursor (reg->table->layout,
2863 CURSOR_SINGLE_LEDGER);
2871 PERR (
"Can't find valid initial location");
2879 gboolean use_double_line,
2880 gboolean is_template,
2881 gboolean mismatched_commodities)
2884 gboolean default_do_auto_complete = TRUE;
2886 reg = g_new0 (SplitRegister, 1);
2888 if (type >= NUM_SINGLE_REGISTER_TYPES)
2889 style = REG_STYLE_JOURNAL;
2891 gnc_split_register_init (reg,
2895 default_do_auto_complete,
2897 mismatched_commodities);
2906 gboolean use_double_line)
2911 if (reg->use_double_line && !use_double_line)
2913 VirtualLocation virt_loc = reg->table->current_cursor_loc;
2916 if (virt_loc.phys_row_offset)
2919 -virt_loc.phys_row_offset);
2926 virt_loc.vcell_loc.virt_row = 1;
2927 virt_loc.vcell_loc.virt_col = 0;
2928 virt_loc.phys_row_offset = 0;
2929 virt_loc.phys_col_offset = 0;
2934 reg->type = newtype;
2936 if (reg->type >= NUM_SINGLE_REGISTER_TYPES)
2937 newstyle = REG_STYLE_JOURNAL;
2939 reg->style = newstyle;
2940 reg->use_double_line = use_double_line;
2942 gnc_table_realize_gui (reg->table);
2948 g_return_if_fail (reg);
2949 gnc_table_model_set_reverse_sort (reg->table->model, reverse_sort);
2954 gboolean do_auto_complete)
2956 g_return_if_fail (reg);
2957 reg->do_auto_complete = do_auto_complete;
2961 gnc_split_register_destroy_info (SplitRegister* reg)
2968 if (reg->unrecn_splits != NULL)
2970 g_list_free (reg->unrecn_splits);
2971 reg->unrecn_splits = NULL;
2974 info = reg->sr_info;
2978 g_free (info->tdebit_str);
2979 g_free (info->tcredit_str);
2981 info->debit_str = NULL;
2982 info->tdebit_str = NULL;
2983 info->credit_str = NULL;
2984 info->tcredit_str = NULL;
2986 g_free (reg->sr_info);
2988 reg->sr_info = NULL;
2995 SRInfo* info = gnc_split_register_get_info (reg);
2997 g_return_if_fail (reg != NULL);
2999 info->user_data = user_data;
3000 info->get_parent = get_parent;
3004 gnc_split_register_cleanup (SplitRegister* reg)
3006 SRInfo* info = gnc_split_register_get_info (reg);
3007 Transaction* pending_trans;
3008 Transaction* blank_trans = NULL;
3011 ENTER (
"reg=%p", reg);
3014 gnc_get_current_book ());
3017 gnc_get_current_book ());
3019 gnc_suspend_gui_refresh ();
3024 if (blank_split != NULL)
3030 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p",
3031 blank_split, blank_trans, pending_trans);
3040 if (blank_trans == pending_trans)
3042 info->pending_trans_guid = *
guid_null ();
3043 pending_trans = NULL;
3046 info->auto_complete = FALSE;
3051 if (pending_trans != NULL)
3053 g_critical (
"BUG DETECTED: pending_trans=%p, blank_split=%p, blank_trans=%p",
3054 pending_trans, blank_split, blank_trans);
3055 g_assert_not_reached ();
3056 info->pending_trans_guid = *
guid_null ();
3062 else g_assert_not_reached ();
3064 pending_trans = NULL;
3067 gnc_split_register_destroy_info (reg);
3069 gnc_resume_gui_refresh ();
3077 g_return_if_fail (reg);
3079 ENTER (
"reg=%p", reg);
3082 GNC_PREF_ACCOUNTING_LABELS,
3083 split_register_pref_changed,
3086 GNC_PREF_ACCOUNT_SEPARATOR,
3087 split_register_pref_changed,
3090 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
3091 split_register_pref_changed,
3094 GNC_PREF_ALT_COLOR_BY_TRANS,
3095 split_register_pref_changed,
3097 gnc_book_option_remove_cb (OPTION_NAME_NUM_FIELD_SOURCE,
3098 split_register_book_option_changed,
3101 gnc_split_register_cleanup (reg);
3103 gnc_table_destroy (reg->table);
3114 gnc_table_model_set_read_only (reg->table->model, read_only);
3124 case ASSET_REGISTER:
3125 case CREDIT_REGISTER:
3126 case LIABILITY_REGISTER:
3127 case INCOME_REGISTER:
3128 case EXPENSE_REGISTER:
3129 case EQUITY_REGISTER:
3130 case TRADING_REGISTER:
3132 return REG_TYPE_GROUP_CURRENCY;
3135 case PAYABLE_REGISTER:
3136 case RECEIVABLE_REGISTER:
3138 return REG_TYPE_GROUP_APAR;
3142 case GENERAL_JOURNAL:
3145 return REG_TYPE_GROUP_JOURNAL;
3148 case STOCK_REGISTER:
3149 case CURRENCY_REGISTER:
3151 return REG_TYPE_GROUP_STOCK;
3154 case PORTFOLIO_LEDGER:
3156 return REG_TYPE_GROUP_PORTFOLIO;
3160 return REG_TYPE_GROUP_UNKNOWN;
3161 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.
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.
Use any denominator which gives an exactly correct ratio of numerator to denominator.
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.
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.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
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.
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.
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.
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
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.
gchar * 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.
#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_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.
gboolean gnc_price_cell_set_value(PriceCell *cell, gnc_numeric amount)
updates amount, returns TRUE if string representation actually changed
time64 gnc_time(time64 *tbuf)
get the current local time
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
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.
Account * gnc_account_lookup_for_register(const Account *base_account, const gchar *name)
Retrieve the account matching the given name starting from the descendants of base_account.
#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...