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;
77 static CursorClass copied_class = CURSOR_CLASS_NONE;
78 static GncGUID copied_leader_guid;
82 static gboolean gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
85 gboolean use_cut_semantics);
86 static gboolean gnc_split_register_auto_calc (SplitRegister *reg,
95 if (copied_item.ftype == GNC_TYPE_SPLIT)
96 gnc_float_split_free (copied_item.fs);
97 if (copied_item.ftype == GNC_TYPE_TRANSACTION)
98 gnc_float_txn_free (copied_item.ft);
99 copied_item.ftype = 0;
100 copied_item.fs = NULL;
101 copied_class = CURSOR_CLASS_NONE;
106 gnc_copy_split_onto_split (Split* from, Split* to, gboolean use_cut_semantics)
110 if ((from == NULL) || (to == NULL))
113 fs = gnc_split_to_float_split (from);
117 gnc_float_split_to_split (fs, to);
118 gnc_float_split_free (fs);
123 gboolean use_cut_semantics,
128 if ((from == NULL) || (to == NULL))
131 ft = gnc_txn_to_float_txn (from, use_cut_semantics);
135 gnc_float_txn_to_txn (ft, to, do_commit);
136 gnc_float_txn_free (ft);
140 gnc_split_get_value_denom (Split* split)
142 gnc_commodity* currency;
159 gnc_split_get_amount_denom (Split* split)
177 gnc_split_register_begin_edit_or_warn (SRInfo* info, Transaction* trans)
179 ENTER (
"info=%p, trans=%p", info, trans);
186 LEAVE (
"opened and marked pending");
192 gnc_get_current_book ());
195 if (trans == blank_trans)
200 LEAVE (
"already open, now pending.");
205 GtkWindow* parent = NULL;
206 if (info->get_parent)
207 parent = GTK_WINDOW (info->get_parent (info->user_data));
208 gnc_error_dialog (parent,
"%s",
209 _ (
"This transaction is already being edited in another register. Please finish editing it there first."));
210 LEAVE (
"already editing");
221 SRInfo* info = gnc_split_register_get_info (reg);
222 VirtualLocation virt_loc;
227 if (reg->style == REG_STYLE_AUTO_LEDGER ||
228 reg->style == REG_STYLE_JOURNAL)
232 if (! (expand ^ info->trans_expanded))
237 virt_loc = reg->table->current_cursor_loc;
238 gnc_split_register_get_trans_split (reg, virt_loc.vcell_loc,
239 &virt_loc.vcell_loc);
245 PERR (
"Can't find place to go!");
250 info->trans_expanded = expand;
253 reg->table->current_cursor_loc.vcell_loc,
254 gnc_split_register_get_active_cursor (reg));
257 reg, reg->table->current_cursor_loc.vcell_loc, expand, FALSE);
259 virt_loc = reg->table->current_cursor_loc;
260 if (!expand || !gnc_table_virtual_loc_valid (reg->table, virt_loc, FALSE))
266 PERR (
"Can't find place to go!");
274 gnc_split_register_show_trans (reg,
275 reg->table->current_cursor_loc.vcell_loc);
281 SRInfo* info = gnc_split_register_get_info (reg);
286 if (reg->style == REG_STYLE_AUTO_LEDGER ||
287 reg->style == REG_STYLE_JOURNAL)
290 return info->trans_expanded;
297 VirtualCellLocation vcell_loc;
308 vcell_loc = reg->table->current_cursor_loc.vcell_loc;
310 vcell_loc.virt_row--;
312 split = gnc_split_register_get_split (reg, vcell_loc);
323 return gnc_split_register_get_split (
324 reg, reg->table->current_cursor_loc.vcell_loc);
330 SRInfo* info = gnc_split_register_get_info (reg);
332 if (!reg)
return NULL;
334 return xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ());
339 VirtualCellLocation* vcell_loc)
345 if (!reg || !split)
return FALSE;
352 for (v_row =
table->num_virt_rows - 1; v_row > 0; v_row--)
353 for (v_col = 0; v_col <
table->num_virt_cols; v_col++)
355 VirtualCellLocation vc_loc = { v_row, v_col };
379 VirtualLocation* virt_loc)
381 VirtualLocation v_loc;
383 const char* cell_name;
393 switch (cursor_class)
395 case CURSOR_CLASS_SPLIT:
396 case CURSOR_CLASS_TRANS:
403 if (!gnc_table_get_cell_location (reg->table, cell_name,
404 v_loc.vcell_loc, &v_loc))
407 if (virt_loc == NULL)
418 SRInfo* info = gnc_split_register_get_info (reg);
427 ENTER (
"reg=%p", reg);
430 gnc_get_current_book ());
438 LEAVE (
"no transaction");
445 if (cursor_class == CURSOR_CLASS_NONE)
447 LEAVE (
"no cursor class");
452 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
454 LEAVE (
"no split with transaction class");
458 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
462 if (!changed && ((split == NULL) || (split == blank_split)))
464 LEAVE (
"skip unchanged blank split");
468 gnc_suspend_gui_refresh ();
474 GtkWidget* dialog, *window;
476 const char* title = _ (
"Save transaction before duplicating?");
477 const char* message =
478 _ (
"The current transaction has been changed. Would you like to " 479 "record the changes before duplicating the transaction, or " 480 "cancel the duplication?");
482 window = gnc_split_register_get_parent (reg);
483 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
484 GTK_DIALOG_DESTROY_WITH_PARENT,
485 GTK_MESSAGE_QUESTION,
488 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
490 gtk_dialog_add_button (GTK_DIALOG (dialog),
491 _ (
"_Record"), GTK_RESPONSE_ACCEPT);
492 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_DUP);
493 gtk_widget_destroy (dialog);
495 if (response != GTK_RESPONSE_ACCEPT)
497 gnc_resume_gui_refresh ();
498 LEAVE (
"save cancelled");
514 if (cursor_class == CURSOR_CLASS_SPLIT)
518 gboolean new_act_num = FALSE;
527 if (!reg->use_tran_num_for_num_field
531 const char* in_num = NULL;
532 const char* title = _ (
"New Split Information");
533 time64 date = info->last_date_entered;
538 in_num = gnc_get_num_action (NULL, split);
540 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg),
541 title, FALSE, &date, in_num, &out_num,
542 NULL, NULL, NULL, NULL))
544 gnc_resume_gui_refresh ();
545 LEAVE (
"dup cancelled");
554 xaccSplitSetParent (new_split, trans);
555 gnc_copy_split_onto_split (split, new_split, FALSE);
557 gnc_set_num_action (NULL, new_split, out_num, NULL);
567 gnc_split_register_get_default_account (reg),
571 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
573 if (gnc_num_cell_set_last_num (num_cell, out_num))
574 gnc_split_register_set_last_num (reg, out_num);
582 return_split = new_split;
584 info->cursor_hint_split = new_split;
585 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
593 Transaction* new_trans;
594 int trans_split_index;
596 const char* in_num = NULL;
597 const char* in_tnum = NULL;
598 char* out_num = NULL;
599 char* out_tnum = NULL;
600 char* out_tdoclink = NULL;
603 gnc_get_current_book ());
607 date = info->last_date_entered;
609 account = gnc_split_register_get_default_account (reg);
611 if (account &&
gnc_strisnum (gnc_get_num_action (trans, trans_split)))
614 in_num = gnc_get_num_action (trans, trans_split);
616 in_tnum = (reg->use_tran_num_for_num_field
618 : gnc_get_num_action (trans, NULL));
620 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg), NULL,
621 TRUE, &date, in_num, &out_num, in_tnum, &out_tnum,
624 gnc_resume_gui_refresh ();
625 LEAVE (
"dup cancelled");
629 if (use_autoreadonly)
633 gnc_get_current_book ());
635 if (g_date_compare (&d, readonly_threshold) < 0)
637 GtkWidget* dialog = gtk_message_dialog_new (NULL,
641 "%s", _ (
"Cannot store a transaction at this date"));
642 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
643 "%s", _ (
"The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. " 644 "This setting can be changed in File->Properties->Accounts."));
645 gtk_dialog_run (GTK_DIALOG (dialog));
646 gtk_widget_destroy (dialog);
648 g_date_free (readonly_threshold);
651 g_date_free (readonly_threshold);
660 gnc_resume_gui_refresh ();
675 if (out_tdoclink == NULL)
678 g_free (out_tdoclink);
681 gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
682 if (!reg->use_tran_num_for_num_field)
686 gnc_set_num_action (NULL,
695 num_cell = (
NumCell*) gnc_table_layout_get_cell (reg->table->layout,
697 if (gnc_num_cell_set_last_num (num_cell, out_num))
698 gnc_split_register_set_last_num (reg, out_num);
701 if (!reg->use_tran_num_for_num_field)
711 info->cursor_hint_trans = new_trans;
712 info->cursor_hint_split = return_split;
713 info->cursor_hint_trans_split = trans_split;
714 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
716 info->trans_expanded = FALSE;
720 gnc_resume_gui_refresh ();
727 gnc_split_register_copy_current_internal (SplitRegister* reg,
728 gboolean use_cut_semantics)
730 SRInfo* info = gnc_split_register_get_info (reg);
739 g_return_if_fail (reg);
740 ENTER (
"reg=%p, use_cut_semantics=%s", reg,
741 use_cut_semantics ?
"TRUE" :
"FALSE");
744 gnc_get_current_book ());
758 if (cursor_class == CURSOR_CLASS_NONE)
760 LEAVE (
"no cursor class");
765 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
767 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
768 LEAVE (
"transaction cursor with no anchoring split");
772 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
775 if (!changed && ((split == NULL) || (split == blank_split)))
784 LEAVE (
"nothing to copy/cut");
790 if (cursor_class == CURSOR_CLASS_SPLIT)
793 new_fs = gnc_split_to_float_split (split);
798 gnc_split_register_save_to_copy_buffer (reg, NULL, new_fs,
807 new_ft = gnc_txn_to_float_txn (trans, use_cut_semantics);
817 if (split_index >= 0)
818 fs = gnc_float_txn_get_float_split (new_ft, split_index);
822 gnc_split_register_save_to_copy_buffer (reg, new_ft, fs,
826 copied_leader_guid = info->default_account;
830 if (!new_fs && !new_ft)
832 g_warning (
"BUG DETECTED: copy failed");
833 LEAVE (
"copy failed");
842 copied_item.fs = new_fs;
843 copied_item.ftype = GNC_TYPE_SPLIT;
847 copied_item.ft = new_ft;
848 copied_item.ftype = GNC_TYPE_TRANSACTION;
851 copied_class = cursor_class;
852 gnc_hook_add_dangler (HOOK_BOOK_CLOSED, clear_copied_item, NULL, NULL);
853 LEAVE (
"%s %s", use_cut_semantics ?
"cut" :
"copied",
854 cursor_class == CURSOR_CLASS_SPLIT ?
"split" :
"transaction");
860 gnc_split_register_copy_current_internal (reg, FALSE);
866 SRInfo* info = gnc_split_register_get_info (reg);
874 gnc_get_current_book ());
885 if (cursor_class == CURSOR_CLASS_NONE)
889 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
892 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
895 if (!changed && ((split == NULL) || (split == blank_split)))
898 gnc_split_register_copy_current_internal (reg, TRUE);
900 if (cursor_class == CURSOR_CLASS_SPLIT)
909 SRInfo* info = gnc_split_register_get_info (reg);
912 Transaction* blank_trans;
917 ENTER (
"reg=%p", reg);
919 if (copied_class == CURSOR_CLASS_NONE)
921 LEAVE (
"no copied cursor class");
926 gnc_get_current_book ());
936 LEAVE (
"no transaction");
943 if (cursor_class == CURSOR_CLASS_NONE)
945 LEAVE (
"no current cursor class");
950 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
952 g_warning (
"BUG DETECTED: transaction cursor with no anchoring split!");
953 LEAVE (
"transaction cursor with no anchoring split");
957 if (cursor_class == CURSOR_CLASS_SPLIT)
959 const char* message = _ (
"You are about to overwrite an existing split. " 960 "Are you sure you want to do that?");
961 const char* anchor_message = _ (
"This is the split anchoring this transaction " 962 "to the register. You may not overwrite it from " 963 "this register window. You may overwrite it if " 964 "you navigate to a register that shows another " 965 "side of this same transaction.");
967 if (copied_class == CURSOR_CLASS_TRANS)
970 LEAVE (
"can't copy trans to split");
977 if ((reg->type != GENERAL_JOURNAL) &&
980 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
981 "%s", anchor_message);
982 LEAVE (
"anchore split");
985 else if (!gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
986 FALSE,
"%s", message))
988 LEAVE (
"user cancelled");
994 if (gnc_split_register_begin_edit_or_warn (info, trans))
996 LEAVE (
"can't begin editing");
1000 gnc_suspend_gui_refresh ();
1006 xaccSplitSetParent (split, trans);
1009 if (copied_item.ftype != GNC_TYPE_SPLIT)
1011 LEAVE (
"copy buffer doesn't represent a split");
1015 gnc_float_split_to_split (copied_item.fs, split);
1019 const char *message = _(
"You are about to overwrite an existing " 1021 "Are you sure you want to do that?");
1024 int trans_split_index;
1028 if (copied_class == CURSOR_CLASS_SPLIT)
1030 LEAVE (
"can't copy split to transaction");
1035 if (copied_item.ftype != GNC_TYPE_TRANSACTION)
1037 LEAVE (
"copy buffer doesn't represent a transaction");
1042 if (split != blank_split &&
1043 !gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1044 FALSE,
"%s", message))
1046 LEAVE (
"user cancelled");
1051 if (gnc_split_register_begin_edit_or_warn (info, trans))
1053 LEAVE (
"can't begin editing");
1057 gnc_suspend_gui_refresh ();
1059 DEBUG (
"Pasting txn, trans=%p, split=%p, blank_trans=%p, blank_split=%p",
1060 trans, split, blank_trans, blank_split);
1066 gnc_get_current_book ());
1067 default_account = gnc_split_register_get_default_account (reg);
1068 if (copied_leader && default_account)
1070 gnc_float_txn_to_txn_swap_accounts (copied_item.ft, trans,
1072 default_account, FALSE);
1075 gnc_float_txn_to_txn (copied_item.ft, trans, FALSE);
1078 if (split_index >= num_splits)
1081 if (trans == blank_trans)
1086 info->blank_split_edited = TRUE;
1087 info->auto_complete = FALSE;
1088 DEBUG (
"replacement blank_split=%p", blank_split);
1095 info->cursor_hint_trans = trans;
1099 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
1103 gnc_resume_gui_refresh ();
1110 SRInfo* info = gnc_split_register_get_info (reg);
1111 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1112 gnc_get_current_book ());
1114 if (split == current_blank_split)
1123 SRInfo* info = gnc_split_register_get_info (reg);
1124 Split* current_blank_split =
xaccSplitLookup (&info->blank_split_guid,
1125 gnc_get_current_book ());
1126 Split* pref_split = NULL;
1127 Split* other_split = NULL;
1135 if (s != current_blank_split)
1144 if (pref_split != NULL)
1146 else if (other_split != NULL)
1153 SRInfo* info = gnc_split_register_get_info (reg);
1154 Transaction* pending_trans;
1162 gnc_get_current_book ());
1165 gnc_get_current_book ());
1175 if (split == blank_split)
1181 gnc_suspend_gui_refresh ();
1186 if (trans == pending_trans)
1192 g_assert (!pending_trans);
1193 if (gnc_split_register_begin_edit_or_warn (info, trans))
1195 gnc_resume_gui_refresh ();
1201 gnc_resume_gui_refresh ();
1208 SRInfo* info = gnc_split_register_get_info (reg);
1209 Transaction* pending_trans;
1215 ENTER (
"reg=%p", reg);
1218 LEAVE (
"no register");
1223 gnc_get_current_book ());
1225 gnc_get_current_book ());
1235 gnc_suspend_gui_refresh ();
1241 if (split == blank_split)
1243 DEBUG (
"deleting blank split");
1245 info->auto_complete = FALSE;
1249 info->trans_expanded = FALSE;
1253 if (trans == pending_trans)
1255 DEBUG (
"clearing pending trans");
1256 info->pending_trans_guid = *
guid_null ();
1257 pending_trans = NULL;
1264 DEBUG (
"committing");
1267 gnc_resume_gui_refresh ();
1275 SRInfo* info = gnc_split_register_get_info (reg);
1276 Transaction* pending_trans;
1284 gnc_get_current_book ());
1286 gnc_get_current_book ());
1294 if (split == blank_split)
1301 info->trans_expanded = FALSE;
1303 gnc_suspend_gui_refresh ();
1309 if (trans == pending_trans)
1311 info->pending_trans_guid = *
guid_null ();
1312 pending_trans = NULL;
1316 PERR (
"We should not be voiding an open transaction.");
1319 gnc_resume_gui_refresh ();
1325 SRInfo* info = gnc_split_register_get_info (reg);
1326 Transaction* pending_trans;
1334 gnc_get_current_book ());
1336 gnc_get_current_book ());
1344 if (split == blank_split)
1351 info->trans_expanded = FALSE;
1353 gnc_suspend_gui_refresh ();
1360 if (trans == pending_trans)
1362 info->pending_trans_guid = *
guid_null ();
1363 pending_trans = NULL;
1366 gnc_resume_gui_refresh ();
1375 Transaction* pending;
1379 if ((reg == NULL) || (split == NULL))
1382 gnc_suspend_gui_refresh ();
1383 info = gnc_split_register_get_info (reg);
1384 pending =
xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ());
1389 if (gnc_split_register_begin_edit_or_warn (info, trans))
1391 gnc_resume_gui_refresh ();
1395 else if (pending == trans)
1399 else g_assert_not_reached ();
1408 gnc_resume_gui_refresh ();
1413 gnc_split_register_empty_current_trans (SplitRegister* reg)
1425 VirtualLocation virt_loc;
1430 virt_loc = reg->table->current_cursor_loc;
1432 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1437 gnc_table_clear_current_cursor_changes (reg->table);
1448 SRInfo* info = gnc_split_register_get_info (reg);
1449 Transaction* pending_trans, *blank_trans;
1450 gboolean refresh_all = FALSE;
1453 gnc_get_current_book ());
1457 if (pending_trans == blank_trans)
1472 gnc_suspend_gui_refresh ();
1476 info->pending_trans_guid = *
guid_null ();
1478 gnc_resume_gui_refresh ();
1481 gnc_gui_refresh_all ();
1489 gnc_ledger_display_refresh_by_split_register (reg);
1495 gnc_split_register_save_to_copy_buffer (SplitRegister *reg,
1497 gboolean use_cut_semantics)
1505 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1514 if (gnc_table_layout_get_cell_changed (reg->table->layout, DATE_CELL, TRUE))
1518 cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
1523 if (gnc_table_layout_get_cell_changed (reg->table->layout, NUM_CELL, TRUE))
1527 value = gnc_table_layout_get_cell_value (reg->table->layout, NUM_CELL);
1528 if (reg->use_tran_num_for_num_field)
1535 if (gnc_table_layout_get_cell_changed (reg->table->layout, TNUM_CELL, TRUE))
1539 value = gnc_table_layout_get_cell_value (reg->table->layout, TNUM_CELL);
1540 if (!reg->use_tran_num_for_num_field)
1545 if (gnc_table_layout_get_cell_changed (reg->table->layout, DESC_CELL, TRUE))
1549 value = gnc_table_layout_get_cell_value (reg->table->layout, DESC_CELL);
1553 if (gnc_table_layout_get_cell_changed (reg->table->layout, NOTES_CELL, TRUE))
1557 value = gnc_table_layout_get_cell_value (reg->table->layout, NOTES_CELL);
1561 if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, TRUE))
1566 cell = gnc_table_layout_get_cell (reg->table->layout, RECN_CELL);
1567 flag = gnc_recn_cell_get_flag ((
RecnCell*) cell);
1569 gnc_float_split_set_reconcile_state (fs, flag);
1572 if (gnc_table_layout_get_cell_changed (reg->table->layout, ACTN_CELL, TRUE))
1576 value = gnc_table_layout_get_cell_value (reg->table->layout, ACTN_CELL);
1577 gnc_float_split_set_action (fs, value);
1580 if (gnc_table_layout_get_cell_changed (reg->table->layout, MEMO_CELL, TRUE))
1584 value = gnc_table_layout_get_cell_value (reg->table->layout, MEMO_CELL);
1585 gnc_float_split_set_memo (fs, value);
1588 if (gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, TRUE))
1592 new_account = gnc_split_register_get_account (reg, XFRM_CELL);
1594 if (new_account != NULL)
1595 gnc_float_split_set_account (fs, new_account);
1598 if (reg->style == REG_STYLE_LEDGER)
1599 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1601 if (gnc_table_layout_get_cell_changed (reg->table->layout, MXFRM_CELL, TRUE))
1603 other_fs = gnc_float_txn_get_other_float_split (ft, fs);
1607 if (ft && g_list_length (ft->m_splits) == 1)
1612 other_fs = gnc_split_to_float_split (temp_split);
1615 gnc_float_txn_append_float_split (ft, other_fs);
1623 new_account = gnc_split_register_get_account (reg, MXFRM_CELL);
1625 if (new_account != NULL)
1626 gnc_float_split_set_account (other_fs, new_account);
1630 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1632 gnc_table_layout_get_cell_changed (reg->table->layout,
1636 gnc_numeric new_value;
1640 cell = gnc_table_layout_get_cell (reg->table->layout, CRED_CELL);
1643 cell = gnc_table_layout_get_cell (reg->table->layout, DEBT_CELL);
1646 new_value = gnc_numeric_sub_fixed (debit, credit);
1648 gnc_float_split_set_value (fs, new_value);
1651 if (gnc_table_layout_get_cell_changed (reg->table->layout, PRIC_CELL, TRUE))
1656 if (gnc_table_layout_get_cell_changed (reg->table->layout, SHRS_CELL, TRUE))
1661 cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
1665 gnc_float_split_set_amount (fs, shares);
1668 if (gnc_table_layout_get_cell_changed (reg->table->layout,
1670 gnc_table_layout_get_cell_changed (reg->table->layout,
1672 gnc_table_layout_get_cell_changed (reg->table->layout,
1674 gnc_table_layout_get_cell_changed (reg->table->layout,
1681 num = gnc_float_split_get_amount (fs);
1684 num = gnc_float_split_get_value (fs);
1692 unreconcile_splits (SplitRegister* reg)
1694 if (reg->unrecn_splits == NULL)
1696 PINFO (
"Unreconcile %d splits of reconciled transaction",
1697 g_list_length (reg->unrecn_splits));
1699 for (GList* node = reg->unrecn_splits; node; node = node->next)
1701 Split* split = node->data;
1704 PWARN (
"Unreconcile of split failed because its parent transaction wasn't open for editing");
1708 g_list_free (reg->unrecn_splits);
1709 reg->unrecn_splits = NULL;
1715 SRInfo* info = gnc_split_register_get_info (reg);
1716 Transaction* pending_trans;
1717 Transaction* blank_trans;
1725 ENTER (
"reg=%p, do_commit=%s", reg, do_commit ?
"TRUE" :
"FALSE");
1729 LEAVE (
"no register");
1734 gnc_get_current_book ());
1737 gnc_get_current_book ());
1746 LEAVE (
"no transaction");
1753 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1757 LEAVE (
"commit unnecessary");
1763 LEAVE (
"transaction not open");
1767 if (trans == pending_trans ||
1768 (trans == blank_trans && info->blank_split_edited))
1772 gnc_suspend_gui_refresh ();
1774 if (trans == blank_trans)
1780 info->blank_split_edited = FALSE;
1781 info->auto_complete = FALSE;
1786 if (trans == pending_trans)
1787 info->pending_trans_guid = *
guid_null ();
1789 PINFO (
"committing trans (%p)", trans);
1790 unreconcile_splits (reg);
1794 gnc_resume_gui_refresh ();
1797 DEBUG (
"leaving trans (%p) open", trans);
1799 LEAVE (
"unchanged cursor");
1803 DEBUG (
"save split=%p", split);
1804 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p, trans=%p",
1805 blank_split, blank_trans, pending_trans, trans);
1808 if (!gnc_split_register_check_cell (reg,
1809 gnc_table_get_current_cell_name (reg->table)))
1811 LEAVE (
"need another go at changing cell");
1815 if (!gnc_split_register_auto_calc (reg, split))
1817 LEAVE (
"auto calc failed");
1822 (void)gnc_split_register_get_account (reg, MXFRM_CELL);
1823 (void)gnc_split_register_get_account (reg, XFRM_CELL);
1828 LEAVE (
"no exchange rate");
1832 gnc_suspend_gui_refresh ();
1835 if (pending_trans != trans)
1842 g_warning (
"Impossible? committing pending %p", pending_trans);
1843 unreconcile_splits (reg);
1847 else if (pending_trans)
1849 g_critical (
"BUG DETECTED! pending transaction (%p) not open",
1851 g_assert_not_reached ();
1854 if (trans == blank_trans)
1864 PINFO (
"beginning edit of trans %p", trans);
1865 if (gnc_split_register_begin_edit_or_warn (info, trans))
1867 gnc_resume_gui_refresh ();
1868 LEAVE (
"transaction opened elsewhere");
1872 pending_trans = trans;
1883 if (split == blank_split && !info->blank_split_edited)
1890 account = gnc_split_register_get_default_account (reg);
1892 xaccSplitSetAccount (blank_split, account);
1912 reg->table->current_cursor_loc.vcell_loc,
1914 DEBUG (
"assigned cell to new split=%p", split);
1917 if ((info->cursor_hint_trans == trans) &&
1918 (info->cursor_hint_trans_split == trans_split) &&
1919 (info->cursor_hint_split == NULL))
1921 info->cursor_hint_split = split;
1922 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1926 DEBUG (
"updating trans=%p", trans);
1931 sd = gnc_split_register_save_data_new (
1932 trans, split, (info->trans_expanded ||
1933 reg->style == REG_STYLE_AUTO_LEDGER ||
1934 reg->style == REG_STYLE_JOURNAL));
1935 gnc_table_save_cells (reg->table, sd);
1936 gnc_split_register_save_data_destroy (sd);
1940 memo = memo ? memo :
"(null)";
1942 desc = desc ? desc :
"(null)";
1943 PINFO (
"finished saving split \"%s\" of trans \"%s\"", memo, desc);
1949 if (trans == blank_trans)
1954 info->auto_complete = FALSE;
1959 info->blank_split_edited = TRUE;
1966 g_assert (trans == blank_trans || trans == pending_trans);
1967 if (pending_trans == trans)
1969 pending_trans = NULL;
1970 info->pending_trans_guid = *
guid_null ();
1972 unreconcile_splits (reg);
1977 gnc_table_clear_current_cursor_changes (reg->table);
1979 gnc_resume_gui_refresh ();
1987 gnc_split_register_get_account_by_name (SplitRegister* reg, BasicCell* bcell,
1990 const char* placeholder = _ (
"The account %s does not allow transactions.");
1991 const char* missing = _ (
"The account %s does not exist. " 1992 "Would you like to create it?");
1996 static gboolean creating_account = FALSE;
1997 GtkWindow* parent = GTK_WINDOW (gnc_split_register_get_parent (reg));
1999 if (!name || (strlen (name) == 0))
2012 if (!account && !creating_account)
2015 if (!gnc_verify_dialog (parent, TRUE, missing, name))
2017 creating_account = TRUE;
2020 creating_account = FALSE;
2025 if (!creating_account)
2029 reg->show_leaf_accounts);
2030 if (g_strcmp0 (account_name, gnc_basic_cell_get_value (bcell)))
2033 gnc_combo_cell_set_value (cell, account_name);
2034 gnc_basic_cell_set_changed (&cell->cell, TRUE);
2036 g_free (account_name);
2042 gnc_error_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
2043 placeholder, fullname);
2054 gnc_split_register_get_account (SplitRegister* reg,
const char* cell_name)
2059 if (!gnc_table_layout_get_cell_changed (reg->table->layout, cell_name, TRUE))
2062 cell = gnc_table_layout_get_cell (reg->table->layout, cell_name);
2065 name = gnc_basic_cell_get_value (cell);
2066 return gnc_split_register_get_account_by_name (reg, cell, name);
2070 calculate_value (SplitRegister* reg)
2079 cell = (
PriceCell*)gnc_table_layout_get_cell (reg->table->layout,
2083 return gnc_numeric_sub_fixed (debit, credit);
2088 recalc_message_box (SplitRegister* reg, gboolean shares_changed,
2089 gboolean price_changed, gboolean value_changed)
2094 GList* radio_list = NULL;
2095 const char* title = _ (
"Recalculate Transaction");
2096 const char* message = _ (
"The values entered for this transaction " 2097 "are inconsistent. Which value would you " 2098 "like to have recalculated?");
2101 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2105 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Shares")));
2108 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2112 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Price")));
2115 radio_list = g_list_append (radio_list, g_strdup_printf (
"%s (%s)",
2119 radio_list = g_list_append (radio_list, g_strdup (_ (
"_Value")));
2121 if (price_changed) default_value = 2;
2122 else default_value = 1;
2124 choice = gnc_choose_radio_option_dialog
2125 (gnc_split_register_get_parent (reg),
2132 for (node = radio_list; node; node = node->next)
2133 g_free (node->data);
2135 g_list_free (radio_list);
2141 recalculate_shares (Split* split, SplitRegister* reg,
2142 gnc_numeric value, gnc_numeric price, gboolean value_changed)
2144 gint64 denom = gnc_split_get_amount_denom (split);
2148 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL);
2150 gnc_basic_cell_set_changed (cell, TRUE);
2154 cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2155 gnc_basic_cell_set_changed (cell, FALSE);
2160 recalculate_price (Split* split, SplitRegister* reg,
2161 gnc_numeric value, gnc_numeric amount)
2163 BasicCell* price_cell;
2170 BasicCell* debit_cell;
2171 BasicCell* credit_cell;
2173 debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2176 credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2185 gnc_basic_cell_set_changed (debit_cell, TRUE);
2186 gnc_basic_cell_set_changed (credit_cell, TRUE);
2189 price_cell = gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL);
2191 gnc_basic_cell_set_changed (price_cell, TRUE);
2195 recalculate_value (Split* split, SplitRegister* reg,
2196 gnc_numeric price, gnc_numeric amount, gboolean shares_changed)
2198 BasicCell* debit_cell = gnc_table_layout_get_cell (reg->table->layout,
2200 BasicCell* credit_cell = gnc_table_layout_get_cell (reg->table->layout,
2202 gint64 denom = gnc_split_get_value_denom (split);
2209 gnc_basic_cell_set_changed (debit_cell, TRUE);
2210 gnc_basic_cell_set_changed (credit_cell, TRUE);
2214 BasicCell* cell = gnc_table_layout_get_cell (reg->table->layout,
2216 gnc_basic_cell_set_changed (cell, FALSE);
2221 gnc_split_register_auto_calc (SplitRegister* reg, Split* split)
2224 gboolean recalc_shares = FALSE;
2225 gboolean recalc_price = FALSE;
2226 gboolean recalc_value = FALSE;
2227 gboolean price_changed;
2228 gboolean value_changed;
2229 gboolean shares_changed;
2230 gnc_numeric calc_value;
2238 if (STOCK_REGISTER != reg->type &&
2239 CURRENCY_REGISTER != reg->type &&
2240 PORTFOLIO_LEDGER != reg->type)
2243 account = gnc_split_register_get_account (reg, XFRM_CELL);
2249 account = gnc_split_register_get_default_account (reg);
2254 price_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2256 value_changed = (gnc_table_layout_get_cell_changed (reg->table->layout,
2258 gnc_table_layout_get_cell_changed (reg->table->layout,
2260 shares_changed = gnc_table_layout_get_cell_changed (reg->table->layout,
2263 if (!price_changed && !value_changed && !shares_changed)
2270 gnc_commodity* acc_commodity;
2279 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2288 cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
2296 value = calculate_value (reg);
2318 recalc_price = TRUE;
2321 recalc_value = TRUE;
2325 recalc_shares = TRUE;
2330 if ((!recalc_shares) &&
2334 if (price_changed && value_changed)
2336 if (!shares_changed)
2337 recalc_shares = TRUE;
2339 else if (value_changed && shares_changed)
2340 recalc_price = TRUE;
2341 else if (price_changed && shares_changed)
2342 recalc_value = TRUE;
2348 denom = gnc_split_get_value_denom (split);
2354 if (!recalc_shares &&
2359 choice = recalc_message_box (reg, shares_changed,
2365 recalc_shares = TRUE;
2368 recalc_price = TRUE;
2371 recalc_value = TRUE;
2379 recalculate_shares (split, reg, value, price, value_changed);
2383 recalculate_price (split, reg, value, amount);
2384 price_changed = TRUE;
2387 recalculate_value (split, reg, price, amount, shares_changed);
2401 case ASSET_REGISTER:
2403 case CREDIT_REGISTER:
2405 case LIABILITY_REGISTER:
2407 case PAYABLE_REGISTER:
2409 case RECEIVABLE_REGISTER:
2412 case INCOME_REGISTER:
2414 case EXPENSE_REGISTER:
2416 case STOCK_REGISTER:
2417 case PORTFOLIO_LEDGER:
2419 case CURRENCY_REGISTER:
2421 case TRADING_REGISTER:
2423 case GENERAL_JOURNAL:
2425 case EQUITY_REGISTER:
2437 SRInfo* info = gnc_split_register_get_info (reg);
2442 if (info->debit_str)
2443 return info->debit_str;
2447 (gnc_split_register_type_to_account_type (reg->type));
2449 if (info->debit_str)
2450 return info->debit_str;
2452 info->debit_str = g_strdup (_ (
"Debit"));
2454 return info->debit_str;
2460 SRInfo* info = gnc_split_register_get_info (reg);
2465 if (info->credit_str)
2466 return info->credit_str;
2470 (gnc_split_register_type_to_account_type (reg->type));
2472 if (info->credit_str)
2473 return info->credit_str;
2475 info->credit_str = g_strdup (_ (
"Credit"));
2477 return info->credit_str;
2483 SRInfo* info = gnc_split_register_get_info (reg);
2484 Transaction* pending_trans;
2486 ENTER (
"reg=%p", reg);
2490 LEAVE (
"no register");
2494 if (gnc_table_current_cursor_changed (reg->table, FALSE))
2496 LEAVE (
"cursor changed");
2501 gnc_get_current_book ());
2504 LEAVE (
"open and pending txn");
2508 LEAVE (
"register unchanged");
2514 gboolean show_present)
2516 SRInfo* info = gnc_split_register_get_info (reg);
2521 info->show_present_divider = show_present;
2527 SRInfo* info = gnc_split_register_get_info (reg);
2532 return info->full_refresh;
2538 gnc_split_register_config_action (SplitRegister* reg)
2542 cell = (
ComboCell*) gnc_table_layout_get_cell (reg->table->layout,
2580 case ASSET_REGISTER:
2585 case CREDIT_REGISTER:
2595 case LIABILITY_REGISTER:
2602 case RECEIVABLE_REGISTER:
2603 case PAYABLE_REGISTER:
2610 case INCOME_REGISTER:
2620 case EXPENSE_REGISTER:
2621 case TRADING_REGISTER:
2627 case GENERAL_JOURNAL:
2628 case EQUITY_REGISTER:
2633 case STOCK_REGISTER:
2634 case PORTFOLIO_LEDGER:
2635 case CURRENCY_REGISTER:
2663 gnc_split_register_config_cells (SplitRegister* reg)
2667 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2672 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL),
2678 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), TRUE);
2683 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), TRUE);
2688 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2693 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, SHRS_CELL),
2694 gnc_default_share_print_info ());
2697 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, TSHRS_CELL),
2698 gnc_default_share_print_info ());
2704 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, RATE_CELL),
2705 gnc_default_share_print_info ());
2710 gnc_table_layout_get_cell (reg->table->layout, ACTN_CELL), FALSE);
2715 gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), FALSE);
2720 case CURRENCY_REGISTER:
2721 case STOCK_REGISTER:
2722 case PORTFOLIO_LEDGER:
2725 gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
2734 gnc_split_register_config_action (reg);
2738 split_register_pref_changed (gpointer prefs, gchar* pref, gpointer user_data)
2740 SplitRegister* reg = user_data;
2743 g_return_if_fail (pref);
2747 info = reg->sr_info;
2751 if (g_str_has_suffix (pref, GNC_PREF_ACCOUNTING_LABELS))
2754 g_free (info->tdebit_str);
2755 g_free (info->tcredit_str);
2757 info->debit_str = NULL;
2758 info->tdebit_str = NULL;
2759 info->credit_str = NULL;
2760 info->tcredit_str = NULL;
2763 else if (g_str_has_suffix (pref, GNC_PREF_ACCOUNT_SEPARATOR))
2765 info->separator_changed = TRUE;
2767 else if (g_str_has_suffix (pref, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
2770 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2772 else if (g_str_has_suffix (pref, GNC_PREF_ALT_COLOR_BY_TRANS))
2775 GNC_PREF_ALT_COLOR_BY_TRANS);
2779 g_warning (
"split_register_pref_changed: Unknown preference %s", pref);
2784 split_register_book_option_changed (gpointer new_val, gpointer user_data)
2786 SplitRegister* reg = user_data;
2787 gboolean* new_data = (gboolean*)new_val;
2792 reg->use_tran_num_for_num_field = (*new_data ? FALSE : TRUE);
2796 gnc_split_register_init (SplitRegister* reg,
2799 gboolean use_double_line,
2800 gboolean do_auto_complete,
2801 gboolean is_template,
2802 gboolean mismatched_commodities)
2804 TableLayout* layout;
2810 GNC_PREF_ACCOUNTING_LABELS,
2811 split_register_pref_changed,
2814 GNC_PREF_ACCOUNT_SEPARATOR,
2815 split_register_pref_changed,
2818 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
2819 split_register_pref_changed,
2822 GNC_PREF_ALT_COLOR_BY_TRANS,
2823 split_register_pref_changed,
2825 gnc_book_option_register_cb (OPTION_NAME_NUM_FIELD_SOURCE,
2826 split_register_book_option_changed,
2829 reg->sr_info = NULL;
2831 reg->unrecn_splits = NULL;
2834 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
2836 GNC_PREF_ALT_COLOR_BY_TRANS);
2840 reg->use_double_line = use_double_line;
2841 reg->do_auto_complete = do_auto_complete;
2842 reg->is_template = is_template;
2843 reg->mismatched_commodities = mismatched_commodities;
2844 reg->use_tran_num_for_num_field =
2851 model = gnc_template_register_model_new ();
2853 model = gnc_split_register_model_new ();
2854 model->handler_user_data = reg;
2857 control->user_data = reg;
2859 reg->table = gnc_table_new (layout, model, control);
2861 gnc_split_register_config_cells (reg);
2865 VirtualCellLocation vcell_loc = { 0, 0 };
2868 header = gnc_table_layout_get_cursor (reg->table->layout,
CURSOR_HEADER);
2875 VirtualLocation vloc;
2878 vloc.vcell_loc.virt_row = 1;
2879 vloc.vcell_loc.virt_col = 0;
2880 vloc.phys_row_offset = 0;
2881 vloc.phys_col_offset = 0;
2883 cursor = gnc_table_layout_get_cursor (reg->table->layout,
2884 CURSOR_SINGLE_LEDGER);
2892 PERR (
"Can't find valid initial location");
2900 gboolean use_double_line,
2901 gboolean is_template,
2902 gboolean mismatched_commodities)
2905 gboolean default_do_auto_complete = TRUE;
2907 reg = g_new0 (SplitRegister, 1);
2909 if (type >= NUM_SINGLE_REGISTER_TYPES)
2910 style = REG_STYLE_JOURNAL;
2912 gnc_split_register_init (reg,
2916 default_do_auto_complete,
2918 mismatched_commodities);
2927 gboolean use_double_line)
2932 if (reg->use_double_line && !use_double_line)
2934 VirtualLocation virt_loc = reg->table->current_cursor_loc;
2937 if (virt_loc.phys_row_offset)
2940 -virt_loc.phys_row_offset);
2947 virt_loc.vcell_loc.virt_row = 1;
2948 virt_loc.vcell_loc.virt_col = 0;
2949 virt_loc.phys_row_offset = 0;
2950 virt_loc.phys_col_offset = 0;
2955 reg->type = newtype;
2957 if (reg->type >= NUM_SINGLE_REGISTER_TYPES)
2958 newstyle = REG_STYLE_JOURNAL;
2960 reg->style = newstyle;
2961 reg->use_double_line = use_double_line;
2963 gnc_table_realize_gui (reg->table);
2969 g_return_if_fail (reg);
2970 gnc_table_model_set_reverse_sort (reg->table->model, reverse_sort);
2975 gboolean do_auto_complete)
2977 g_return_if_fail (reg);
2978 reg->do_auto_complete = do_auto_complete;
2982 gnc_split_register_destroy_info (SplitRegister* reg)
2989 if (reg->unrecn_splits != NULL)
2991 g_list_free (reg->unrecn_splits);
2992 reg->unrecn_splits = NULL;
2995 info = reg->sr_info;
2999 g_free (info->tdebit_str);
3000 g_free (info->tcredit_str);
3002 info->debit_str = NULL;
3003 info->tdebit_str = NULL;
3004 info->credit_str = NULL;
3005 info->tcredit_str = NULL;
3007 g_free (reg->sr_info);
3009 reg->sr_info = NULL;
3016 SRInfo* info = gnc_split_register_get_info (reg);
3018 g_return_if_fail (reg != NULL);
3020 info->user_data = user_data;
3021 info->get_parent = get_parent;
3025 gnc_split_register_cleanup (SplitRegister* reg)
3027 SRInfo* info = gnc_split_register_get_info (reg);
3028 Transaction* pending_trans;
3029 Transaction* blank_trans = NULL;
3032 ENTER (
"reg=%p", reg);
3035 gnc_get_current_book ());
3038 gnc_get_current_book ());
3040 gnc_suspend_gui_refresh ();
3045 if (blank_split != NULL)
3051 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p",
3052 blank_split, blank_trans, pending_trans);
3061 if (blank_trans == pending_trans)
3063 info->pending_trans_guid = *
guid_null ();
3064 pending_trans = NULL;
3067 info->auto_complete = FALSE;
3072 if (pending_trans != NULL)
3074 g_critical (
"BUG DETECTED: pending_trans=%p, blank_split=%p, blank_trans=%p",
3075 pending_trans, blank_split, blank_trans);
3076 g_assert_not_reached ();
3077 info->pending_trans_guid = *
guid_null ();
3083 else g_assert_not_reached ();
3085 pending_trans = NULL;
3088 gnc_split_register_destroy_info (reg);
3090 gnc_resume_gui_refresh ();
3098 g_return_if_fail (reg);
3100 ENTER (
"reg=%p", reg);
3103 GNC_PREF_ACCOUNTING_LABELS,
3104 split_register_pref_changed,
3107 GNC_PREF_ACCOUNT_SEPARATOR,
3108 split_register_pref_changed,
3111 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
3112 split_register_pref_changed,
3115 GNC_PREF_ALT_COLOR_BY_TRANS,
3116 split_register_pref_changed,
3118 gnc_book_option_remove_cb (OPTION_NAME_NUM_FIELD_SOURCE,
3119 split_register_book_option_changed,
3122 gnc_split_register_cleanup (reg);
3124 gnc_table_destroy (reg->table);
3135 gnc_table_model_set_read_only (reg->table->model, read_only);
3145 case ASSET_REGISTER:
3146 case CREDIT_REGISTER:
3147 case LIABILITY_REGISTER:
3148 case INCOME_REGISTER:
3149 case EXPENSE_REGISTER:
3150 case EQUITY_REGISTER:
3151 case TRADING_REGISTER:
3153 return REG_TYPE_GROUP_CURRENCY;
3156 case PAYABLE_REGISTER:
3157 case RECEIVABLE_REGISTER:
3159 return REG_TYPE_GROUP_APAR;
3163 case GENERAL_JOURNAL:
3166 return REG_TYPE_GROUP_JOURNAL;
3169 case STOCK_REGISTER:
3170 case CURRENCY_REGISTER:
3172 return REG_TYPE_GROUP_STOCK;
3175 case PORTFOLIO_LEDGER:
3177 return REG_TYPE_GROUP_PORTFOLIO;
3181 return REG_TYPE_GROUP_UNKNOWN;
3182 PERR (
"unknown register type %d\n", reg->type);
CursorClass gnc_split_register_get_current_cursor_class(SplitRegister *reg)
Returns the class of a register's current cursor.
Split * gnc_split_register_get_current_trans_split(SplitRegister *reg, VirtualCellLocation *trans_split_loc)
Gets the anchoring split of the transaction at the current cursor location, which may be on the trans...
void gnc_copy_trans_onto_trans(Transaction *from, Transaction *to, gboolean use_cut_semantics, gboolean do_commit)
Private function – outsiders must not use this.
Public declarations for GncLedgerDisplay class.
The RecnCell object implements a cell handler that will cycle through a series of single-character va...
gpointer vcell_data
Array of physical cells.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
The CompletionCell object implements a cell handler with a "combination-box" pull-down menu in it...
const char * gnc_split_register_get_credit_string(SplitRegister *reg)
Return the credit string used in the register.
const char * xaccAccountGetLastNum(const Account *acc)
Get the last num field of an Account.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
void gnc_split_register_set_reverse_sort(SplitRegister *reg, gboolean reverse_sort)
Sets a split register's reverse sort order based on register.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
Account * gnc_ui_new_accounts_from_name_window(GtkWindow *parent, const char *name)
Display a modal window for creating a new account.
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.
Date and Time handling routines.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
#define GNC_COMMODITY_MAX_FRACTION
Max fraction is 10^9 because 10^10 would require changing it to an int64_t.
gboolean gnc_split_register_save(SplitRegister *reg, gboolean do_commit)
Copy the contents of the current cursor to a split.
This file contains the functions to present a gui to the user for creating a new account or editing a...
void gnc_split_register_destroy(SplitRegister *reg)
Destroys a split register.
void gnc_split_register_unvoid_current_trans(SplitRegister *reg)
Unvoids the transaction associated with the current cursor, if non-NULL.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false. ...
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. ...
void gnc_split_register_expand_current_trans(SplitRegister *reg, gboolean expand)
Expand the current transaction if it is collapsed.
Expense accounts are used to denote expenses.
#define PINFO(format, args...)
Print an informational note.
void gnc_split_register_set_trans_visible(SplitRegister *reg, VirtualCellLocation vcell_loc, gboolean visible, gboolean only_blank_split)
Set the visibility of the split rows belonging to a transaction located at vcell_loc.
Transaction * gnc_split_register_get_current_trans(SplitRegister *reg)
Gets the transaction at the current cursor location, which may be on the transaction itself or on any...
gboolean xaccSplitDestroy(Split *split)
Destructor.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
SplitRegisterTypeGroup gnc_split_register_get_register_group(SplitRegister *reg)
Group registers for common layouts.
void gnc_split_register_delete_current_split(SplitRegister *reg)
Deletes the split associated with the current cursor, if both are non-NULL.
holds information about each virtual cell.
#define DEBUG(format, args...)
Print a debugging message.
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
Returns TRUE if this book uses split action field as the 'Num' field, FALSE if it uses transaction nu...
char xaccSplitGetReconcile(const Split *split)
Returns the value of the reconcile flag.
void gnc_table_move_cursor_gui(Table *table, VirtualLocation new_virt_loc)
will move the cursor and its GUI to the indicated location.
TableControl specialized for the SplitRegister.
gboolean gnc_table_find_close_valid_cell(Table *table, VirtualLocation *virt_loc, gboolean exact_pointer)
Find a close valid cell.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
CursorClass gnc_split_register_get_cursor_class(SplitRegister *reg, VirtualCellLocation vcell_loc)
Returns the class of the cursor at the given virtual cell location.
gboolean gnc_split_register_full_refresh_ok(SplitRegister *reg)
Private function – outsiders must not use this.
void xaccTransSetNum(Transaction *trans, const char *xnum)
Sets the transaction Number (or ID) field; rather than use this function directly, see 'gnc_set_num_action' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically.
Save handlers for the SplitRegister Model and Template SplitRegister model.
void xaccTransRecordPrice(Transaction *trans, PriceSource source)
The xaccTransRecordPrice() method iterates through the splits and and record the non-currency equival...
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
TableModels specialized for SplitRegister and template SplitRegister.
Use any denominator which gives an exactly correct ratio of numerator to denominator.
Create the actual register visual layout.
void gnc_split_register_set_data(SplitRegister *reg, gpointer user_data, SRGetParentCallback get_parent)
Sets the user data and callback hooks for the register.
void gnc_split_register_delete_current_trans(SplitRegister *reg)
Deletes the transaction associated with the current cursor, if both are non-NULL. ...
SplitRegisterTypeGroup
Register group types.
void gnc_split_register_set_read_only(SplitRegister *reg, gboolean read_only)
Sets whether a register window is "read only".
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
const char * gnc_account_get_debit_string(GNCAccountType acct_type)
Get the debit string associated with this account type.
gboolean gnc_strisnum(const gchar *s)
Returns true if string s is a number, possibly surrounded by whitespace.
void gnc_combo_cell_add_ignore_string(ComboCell *cell, const char *ignore_string)
Add a string to a list of strings which, if the cell has that value, will cause the cell to be unedit...
void gnc_table_set_virt_cell_data(Table *table, VirtualCellLocation vcell_loc, gconstpointer vcell_data)
Set the virtual cell data for a particular location.
void xaccAccountSetLastNum(Account *acc, const char *num)
Set the last num field of an Account.
gboolean gnc_split_register_current_trans_expanded(SplitRegister *reg)
Return TRUE if current trans is expanded and style is REG_STYLE_LEDGER.
const char * xaccTransGetDocLink(const Transaction *trans)
Gets the transaction Document Link.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
#define VREC
split is void
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
Account used to record multiple commodity transactions.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
#define PWARN(format, args...)
Log a warning.
Stock accounts will typically be shown in registers which show three columns: price, number of shares, and value.
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
The xaccTransLookup() subroutine will return the transaction associated with the given id...
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
The xaccSplitLookup() subroutine will return the split associated with the given id, or NULL if there is no such split.
void gnc_table_refresh_gui(Table *table, gboolean do_scroll)
Refresh the whole GUI from the table.
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
void gnc_split_register_redraw(SplitRegister *reg)
Causes a redraw of the register window associated with reg.
const char * gnc_split_register_get_debit_string(SplitRegister *reg)
Return the debit string used in the register.
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it...
void xaccTransVoid(Transaction *trans, const char *reason)
xaccTransVoid voids a transaction.
CursorClass
Types of cursors.
Income accounts are used to denote income.
#define YREC
The Split has been reconciled.
Account * gnc_account_lookup_by_code(const Account *parent, const char *code)
The gnc_account_lookup_by_code() subroutine works like gnc_account_lookup_by_name, but uses the account code.
char * gnc_get_account_name_for_split_register(const Account *account, gboolean show_leaf_accounts)
Get either the full name of the account or the simple name, depending on the show_leaf_accounts.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
void gnc_split_register_cut_current(SplitRegister *reg)
Equivalent to copying the current entity and the deleting it with the appropriate delete method...
The PriceCell object implements a cell handler that stores a single double-precision value...
void gnc_combo_cell_add_menu_item(ComboCell *cell, const char *menustr)
Add a menu item to the list.
Split * gnc_split_register_get_blank_split(SplitRegister *reg)
Gets the blank split for a register.
VirtualCell * gnc_table_get_virtual_cell(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell associated with a particular virtual location.
#define CURSOR_HEADER
Standard Cursor Names.
void gnc_date_cell_get_date(DateCell *cell, time64 *time, gboolean warn)
Set a time64 to the value in the DateCell.
gboolean gnc_split_register_changed(SplitRegister *reg)
Returns TRUE if the register has changed cells.
void gnc_combo_cell_set_strict(ComboCell *cell, gboolean strict)
Determines whether the cell will accept strings not in the menu.
The bank account type denotes a savings or checking account held at a bank.
void gnc_split_register_config(SplitRegister *reg, SplitRegisterType newtype, SplitRegisterStyle newstyle, gboolean use_double_line)
Sets a split register's type, style or line use.
private declarations for SplitRegister
void gnc_split_register_cancel_cursor_split_changes(SplitRegister *reg)
Cancels any changes made to the current cursor, reloads the cursor from the engine, reloads the table from the cursor, and updates the GUI.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
void gnc_split_register_void_current_trans(SplitRegister *reg, const char *reason)
Voids the transaction associated with the current cursor, if non-NULL.
TableControl * gnc_split_register_control_new(void)
Create a new TableControl specialized for the SplitRegister.
void gnc_table_set_vcell(Table *table, CellBlock *cursor, gconstpointer vcell_data, gboolean visible, gboolean start_primary_color, VirtualCellLocation vcell_loc)
Indicate what handler should be used for a given virtual block.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
#define xaccSplitGetGUID(X)
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
gboolean gnc_split_register_get_split_amount_virt_loc(SplitRegister *reg, Split *split, VirtualLocation *virt_loc)
Searches the split register for the given split and determines the location of either its credit (if ...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
gnc_numeric xaccSplitGetSharePrice(const Split *split)
Returns the price of the split, that is, the value divided by the amount.
gboolean gnc_table_move_vertical_position(Table *table, VirtualLocation *virt_loc, int phys_row_offset)
Moves away from virtual location virt_loc by phys_row_offset physical rows.
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
Inverse of xaccTransGetSplit()
void xaccTransUnvoid(Transaction *trans)
xaccTransUnvoid restores a voided transaction to its original state.
API for checkbook register display area.
The currency account type indicates that the account is a currency trading account.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
void gnc_price_cell_set_fraction(PriceCell *cell, int fraction)
Sets the fraction used for rounding.
Split * xaccMallocSplit(QofBook *book)
Constructor.
gboolean gnc_split_register_is_blank_split(SplitRegister *reg, Split *split)
Return TRUE if split is the blank_split.
Account * gnc_account_lookup_for_register(const Account *base_account, const char *name)
Retrieve the account matching the given name starting from the descendants of base_account.
#define xaccTransGetGUID(X)
Generic api to store and retrieve preferences.
Split * gnc_split_register_duplicate_current(SplitRegister *reg)
Duplicates either the current transaction or the current split depending on the register mode and cur...
void gnc_split_register_cancel_cursor_trans_changes(SplitRegister *reg)
Cancels any changes made to the current pending transaction, reloads the table from the engine...
The NumCell object implements a number handling cell.
void gnc_split_register_paste_current(SplitRegister *reg)
Pastes a previous copied entity onto the current entity, but only if the copied and current entity ha...
unsigned int visible
Used by higher-level code.
void gnc_price_cell_set_print_info(PriceCell *cell, GNCPrintAmountInfo print_info)
set the printing context of the price cell
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
gboolean gnc_split_register_get_split_virt_loc(SplitRegister *reg, Split *split, VirtualCellLocation *vcell_loc)
Searches the split register for a given split.
const char * gnc_account_get_credit_string(GNCAccountType acct_type)
Get the credit string associated with this account type.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
void gnc_completion_cell_set_strict(CompletionCell *cell, gboolean strict)
Determines whether the cell will accept strings not in the menu.
void gnc_split_register_empty_current_trans_except_split(SplitRegister *reg, Split *split)
Deletes the non-transaction splits associated with the current cursor, if both are non-NULL...
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
void gnc_split_register_set_auto_complete(SplitRegister *reg, gboolean do_auto_complete)
Sets whether a register uses auto-completion.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
void gnc_table_set_virt_cell_cursor(Table *table, VirtualCellLocation vcell_loc, CellBlock *cursor)
Set the cellblock handler for a virtual cell.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
void xaccTransSetDocLink(Transaction *trans, const char *doclink)
Sets the transaction Document Link.
Declarations for the Table object.
#define LEAVE(format, args...)
Print a function exit debugging message.
GtkWidget *(* SRGetParentCallback)(gpointer user_data)
Callback function type.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
gboolean gnc_price_cell_set_value(PriceCell *cell, gnc_numeric amount)
updates amount, returns TRUE if string representation actually changed
void gnc_completion_cell_set_autosize(CompletionCell *cell, gboolean autosize)
Determines whether the popup list autosizes itself or uses all available space.
time64 gnc_time(time64 *tbuf)
get the current time
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
The DateCell object implements a date handling cell.
void gnc_split_register_change_blank_split_ref(SplitRegister *reg, Split *split)
Change the blank_split reference from pointing to split to another split of the transaction.
gboolean gnc_split_register_handle_exchange(SplitRegister *reg, gboolean force_dialog)
If needed display the transfer dialog to get a price/exchange rate and adjust the price cell accordin...
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
void gnc_split_register_show_present_divider(SplitRegister *reg, gboolean show_present)
If TRUE, visually indicate the demarcation between splits with post dates prior to the present...
Equity account is used to balance the balance sheet.
SplitRegisterType
Register types.
int gnc_numeric_same(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Equivalence predicate: Convert both a and b to denom using the specified DENOM and method HOW...
TableLayout * gnc_split_register_layout_new(SplitRegister *reg)
Generate the split register layout.
void gnc_price_cell_set_debt_credit_value(PriceCell *debit, PriceCell *credit, gnc_numeric amount)
updates two cells; the deb cell if amt is negative, the credit cell if amount is positive, and makes the other cell blank.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
The type used to store guids in C.
gnc_numeric gnc_price_cell_get_value(PriceCell *cell)
return the value of a price cell
Split * gnc_split_register_get_current_split(SplitRegister *reg)
Returns the split at which the cursor is currently located.
SplitRegister * gnc_split_register_new(SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line, gboolean is_template, gboolean mismatched_commodities)
Creates a new split register.
void gnc_table_move_cursor(Table *table, VirtualLocation new_virt_loc)
will move the cursor (but not the cursor GUI) to the indicated location.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
void xaccTransRollbackEdit(Transaction *trans)
The xaccTransRollbackEdit() routine rejects all edits made, and sets the transaction back to where it...
SplitRegisterStyle
Register styles.
void gnc_combo_cell_set_autosize(ComboCell *cell, gboolean autosize)
Determines whether the popup list autosizes itself or uses all available space.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
The Credit card account is used to denote credit (e.g.
#define NREC
not reconciled or cleared
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
void gnc_split_register_copy_current(SplitRegister *reg)
Makes a copy of the current entity, either a split or a transaction, so that it can be pasted later...
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...