26 #include <glib/gi18n.h>
30 #include "gnc-component-manager.h"
33 #include "gnome-utils/gnc-warnings.h"
34 #include "pricecell.h"
36 #include "dialog-transfer.h"
37 #include "dialog-utils.h"
38 #include "split-register-control.h"
39 #include "split-register-model-save.h"
40 #include "split-register-p.h"
42 #include "engine-helpers.h"
57 GList *radio_list = NULL;
58 const char *title = _(
"Rebalance Transaction");
59 const char *message = _(
"The current transaction is not balanced.");
62 gboolean two_accounts;
63 gboolean multi_currency;
71 MonetaryList *imbal_list;
80 multi_currency = TRUE;
83 imbal_mon = imbal_list->data;
84 if (!imbal_list->next &&
87 multi_currency = FALSE;
89 multi_currency = TRUE;
97 multi_currency = FALSE;
102 if (other_split == NULL)
109 if (other_split == NULL || multi_currency)
111 two_accounts = FALSE;
112 other_account = NULL;
120 default_account = gnc_split_register_get_default_account (reg);
126 if (default_account == other_account)
133 if (default_account == other_account)
134 two_accounts = FALSE;
136 radio_list = g_list_append (radio_list,
137 _(
"Balance it _manually"));
138 radio_list = g_list_append (radio_list,
139 _(
"Let GnuCash _add an adjusting split"));
141 if (reg->type < NUM_SINGLE_REGISTER_TYPES && !multi_currency)
143 radio_list = g_list_append (radio_list,
144 _(
"Adjust current account _split total"));
149 radio_list = g_list_append (radio_list,
150 _(
"Adjust _other account split total"));
157 choice = gnc_choose_radio_option_dialog
158 (gnc_split_register_get_parent (reg),
165 g_list_free (radio_list);
197 string = gnc_table_layout_get_cell_value (reg->
table->layout, MEMO_CELL);
198 if ((
string != NULL) && (*
string !=
'\0'))
201 string = gnc_table_layout_get_cell_value (reg->
table->layout, XFRM_CELL);
202 if ((
string != NULL) && (*
string !=
'\0'))
205 cell = gnc_table_layout_get_cell (reg->
table->layout, CRED_CELL);
208 amount = gnc_price_cell_get_value ((
PriceCell *) cell);
213 cell = gnc_table_layout_get_cell (reg->
table->layout, DEBT_CELL);
216 amount = gnc_price_cell_get_value ((
PriceCell *) cell);
229 const char *cell_name)
231 if ((gnc_cell_name_equal (cell_name, DEBT_CELL) &&
232 gnc_table_layout_get_cell_changed (reg->
table->layout,
233 DEBT_CELL, FALSE)) ||
234 (gnc_cell_name_equal (cell_name, CRED_CELL) &&
235 gnc_table_layout_get_cell_changed (reg->
table->layout,
238 SRInfo *info = gnc_split_register_get_info (reg);
241 if (gnc_split_reg_has_rate_cell(reg->type) && info->rate_reset != RATE_RESET_DONE)
244 info->rate_reset = RATE_RESET_REQD;
245 if (info->auto_complete)
249 gnc_price_cell_set_value (rate_cell, gnc_numeric_zero());
261 const char *cell_name)
269 g_return_val_if_fail(reg, TRUE);
272 if (gnc_cell_name_equal (cell_name, XFRM_CELL))
274 if (gnc_table_layout_get_cell_changed (reg->
table->layout,
276 cell = (
ComboCell *) gnc_table_layout_get_cell (reg->
table->layout,
279 else if (gnc_cell_name_equal (cell_name, MXFRM_CELL))
281 if (gnc_table_layout_get_cell_changed (reg->
table->layout,
283 cell = (
ComboCell *) gnc_table_layout_get_cell (reg->
table->layout,
291 name = cell->cell.value;
292 DEBUG(
"Changed to %s", name ? name :
"NULL");
293 if (!name || *name ==
'\0' ||
294 g_strcmp0 (name, SPLIT_TRANS_STR) == 0 ||
295 g_strcmp0 (name, STOCK_SPLIT_STR) == 0)
299 info = gnc_split_register_get_info (reg);
300 new_acct = gnc_split_register_get_account_by_name (reg,
307 gnc_split_register_set_cell_fractions (reg, split);
310 if (gnc_split_reg_has_rate_cell(reg->type))
321 DEBUG(
"Commodity is still %s. Leaving rate unchanged.",
327 DEBUG(
"Commodity now %s (originally %s). Clearing rate.",
331 gnc_price_cell_set_value (rate_cell, gnc_numeric_zero());
332 info->rate_account = new_acct;
333 info->rate_reset = RATE_RESET_REQD;
345 DEBUG(
"Using original rate of %s.",
347 gnc_price_cell_set_value (rate_cell, orig_rate);
348 info->rate_account = new_acct;
349 info->rate_reset = RATE_RESET_NOT_REQD;
353 DEBUG(
"Can't get rate. Using zero.");
354 gnc_price_cell_set_value (rate_cell, gnc_numeric_zero());
355 info->rate_account = new_acct;
356 info->rate_reset = RATE_RESET_REQD;
374 Split *old_trans_split;
375 Split *new_trans_split;
380 gboolean exact_traversal;
385 ENTER(
"reg=%p, p_new_virt_loc=%p (%d, %d)",
387 new_virt_loc.vcell_loc.virt_row,
388 new_virt_loc.vcell_loc.virt_col);
392 LEAVE(
"no register");
396 info = gnc_split_register_get_info (reg);
405 exact_traversal = info->exact_traversal;
407 if (info->traverse_to_new)
409 if (old_class == CURSOR_CLASS_SPLIT)
410 new_trans = old_trans;
415 new_trans_split = NULL;
416 new_class = CURSOR_CLASS_NONE;
418 else if (!info->hint_set_by_traverse)
421 new_trans = gnc_split_register_get_trans (reg, new_virt_loc.vcell_loc);
424 new_split = gnc_split_register_get_split (reg, new_virt_loc.vcell_loc);
427 new_trans_split = gnc_split_register_get_trans_split
428 (reg, new_virt_loc.vcell_loc, NULL);
431 new_virt_loc.vcell_loc);
435 new_trans = info->cursor_hint_trans;
436 new_split = info->cursor_hint_split;
437 new_trans_split = info->cursor_hint_trans_split;
438 new_class = info->cursor_hint_cursor_class;
441 info->hint_set_by_traverse = FALSE;
442 info->reg_loaded = FALSE;
444 gnc_suspend_gui_refresh ();
449 gnc_get_current_book ());
450 if ((old_class == CURSOR_CLASS_SPLIT) &&
452 (old_split != new_split) &&
453 gnc_split_register_old_split_empty_p(reg, old_split))
464 current_row = reg->
table->current_cursor_loc.vcell_loc.virt_row;
465 if (new_virt_loc.vcell_loc.virt_row > current_row)
466 new_virt_loc.vcell_loc.virt_row--;
468 else if ((pending_trans != NULL) &&
469 (pending_trans == old_trans) &&
470 (old_trans != new_trans))
472 if (gnc_split_register_balance_trans (reg, pending_trans))
475 new_trans = old_trans;
476 new_split = old_split;
477 new_trans_split = old_trans_split;
478 new_class = old_class;
479 new_virt_loc = reg->
table->current_cursor_loc;
484 info->pending_trans_guid = *
guid_null ();
487 else g_assert_not_reached();
489 pending_trans = NULL;
493 else if (old_trans &&
494 (old_trans != new_trans) &&
497 gnc_split_register_balance_trans (reg, old_trans))
500 new_trans = old_trans;
501 new_split = old_split;
502 new_trans_split = old_trans_split;
503 new_class = old_class;
504 new_virt_loc = reg->
table->current_cursor_loc;
509 info->cursor_hint_trans = new_trans;
510 info->cursor_hint_split = new_split;
511 info->cursor_hint_trans_split = new_trans_split;
512 info->cursor_hint_cursor_class = new_class;
515 if (old_split != new_split)
517 info->change_confirmed = FALSE;
518 info->rate_account = NULL;
519 info->rate_reset = RATE_RESET_NOT_REQD;
522 gnc_resume_gui_refresh ();
529 if (!info->reg_loaded)
534 if (gnc_split_register_find_split (reg, new_trans, new_trans_split,
535 new_split, new_class, &vcell_loc))
538 gnc_table_get_virtual_cell (reg->
table, vcell_loc);
539 new_virt_loc.vcell_loc = vcell_loc;
542 new_virt_loc.vcell_loc = reg->
table->current_cursor_loc.vcell_loc;
544 new_trans = gnc_split_register_get_trans (reg, new_virt_loc.vcell_loc);
545 new_split = gnc_split_register_get_split (reg, new_virt_loc.vcell_loc);
546 new_trans_split = gnc_split_register_get_trans_split(
547 reg, new_virt_loc.vcell_loc, NULL);
549 new_virt_loc.vcell_loc);
551 else if (info->traverse_to_new)
553 new_trans = info->cursor_hint_trans;
554 new_split = info->cursor_hint_split;
555 new_trans_split = info->cursor_hint_trans_split;
556 new_class = info->cursor_hint_cursor_class;
559 gnc_table_find_close_valid_cell (reg->
table, &new_virt_loc, exact_traversal);
561 *p_new_virt_loc = new_virt_loc;
563 PINFO (
"after move %d %d \n",
564 new_virt_loc.vcell_loc.virt_row,
565 new_virt_loc.vcell_loc.virt_col);
571 gnc_split_register_set_cell_fractions (reg, new_split);
580 (old_trans_split != new_trans_split))
584 vc_loc = old_trans_split_loc;
585 gnc_table_set_virt_cell_cursor(
586 reg->
table, vc_loc, gnc_split_register_get_passive_cursor (reg));
587 gnc_split_register_set_trans_visible (reg, vc_loc, FALSE,
588 reg->style == REG_STYLE_JOURNAL);
590 if ((REG_STYLE_AUTO_LEDGER == reg->style) ||
591 (REG_STYLE_JOURNAL == reg->style))
593 gnc_split_register_get_trans_split (reg, new_virt_loc.vcell_loc,
595 gnc_table_set_virt_cell_cursor
596 (reg->
table, vc_loc, gnc_split_register_get_active_cursor (reg));
597 gnc_split_register_set_trans_visible (reg, vc_loc, TRUE,
598 reg->style == REG_STYLE_JOURNAL);
601 info->trans_expanded = FALSE;
608 info->cursor_hint_trans = new_trans;
609 info->cursor_hint_split = new_split;
610 info->cursor_hint_trans_split = new_trans_split;
611 info->cursor_hint_cursor_class = new_class;
613 gnc_split_register_set_cell_fractions (reg, new_split);
615 gnc_table_find_close_valid_cell (reg->
table, p_new_virt_loc,
622 gnc_table_refresh_gui (reg->
table, FALSE);
623 gnc_table_leave_update (reg->
table, reg->
table->current_cursor_loc);
625 gnc_split_register_get_trans_split (reg, p_new_virt_loc->vcell_loc,
627 gnc_split_register_show_trans (reg, vc_loc);
634 gnc_find_split_in_trans_by_memo (
Transaction *trans,
const char *memo,
658 gnc_find_split_in_account_by_memo (
Account *account,
const char *memo,
663 if (account == NULL)
return NULL;
669 Split *split = slp->data;
672 split = gnc_find_split_in_trans_by_memo (trans, memo, unit_price);
674 if (split)
return split;
681 gnc_find_split_in_reg_by_memo (
SplitRegister *reg,
const char *memo,
684 int virt_row, virt_col;
685 int num_rows, num_cols;
688 if (!reg || !reg->
table)
691 num_rows = reg->
table->num_virt_rows;
692 num_cols = reg->
table->num_virt_cols;
696 for (virt_row = num_rows - 1; virt_row >= 0; virt_row--)
697 for (virt_col = num_cols - 1; virt_col >= 0; virt_col--)
703 split = gnc_split_register_get_split (reg, vcell_loc);
706 if (trans == last_trans)
709 split = gnc_find_split_in_trans_by_memo (trans, memo, unit_price);
720 gnc_find_trans_in_reg_by_desc (
SplitRegister *reg,
const char *description)
722 int virt_row, virt_col;
723 int num_rows, num_cols;
726 if (!reg || !reg->
table)
729 num_rows = reg->
table->num_virt_rows;
730 num_cols = reg->
table->num_virt_cols;
734 for (virt_row = num_rows - 1; virt_row >= 0; virt_row--)
735 for (virt_col = num_cols - 1; virt_col >= 0; virt_col--)
741 split = gnc_split_register_get_split (reg, vcell_loc);
744 if (trans == last_trans)
760 gncTableTraversalDir dir,
763 SRInfo *info = gnc_split_register_get_info (reg);
768 const char *cell_name;
779 gnc_get_current_book ());
783 gnc_get_current_book ());
786 if (dir != GNC_TABLE_TRAVERSE_RIGHT)
795 cell_name = gnc_table_get_current_cell_name (reg->
table);
797 switch (cursor_class)
799 case CURSOR_CLASS_TRANS:
805 if (blank_trans == NULL)
809 if (trans != blank_trans)
813 if (!gnc_cell_name_equal (cell_name, DESC_CELL))
818 if (gnc_table_layout_get_cell_changed (reg->
table->layout,
820 gnc_table_layout_get_cell_changed (reg->
table->layout,
822 gnc_table_layout_get_cell_changed (reg->
table->layout,
824 gnc_table_layout_get_cell_changed (reg->
table->layout,
826 gnc_table_layout_get_cell_changed (reg->
table->layout,
828 gnc_table_layout_get_cell_changed (reg->
table->layout,
830 gnc_table_layout_get_cell_changed (reg->
table->layout,
832 gnc_table_layout_get_cell_changed (reg->
table->layout,
837 if (!gnc_table_layout_get_cell_changed (reg->
table->layout,
842 desc = gnc_table_layout_get_cell_value (reg->
table->layout, DESC_CELL);
843 if ((desc == NULL) || (*desc ==
'\0'))
847 if (gnc_split_register_get_default_account (reg) != NULL)
849 Account *account = gnc_split_register_get_default_account (reg);
854 auto_trans = gnc_find_trans_in_reg_by_desc(reg, desc);
856 if (auto_trans == NULL)
859 gnc_suspend_gui_refresh ();
865 if (pending_trans != trans)
871 if (pending_trans != NULL)
875 else g_assert_not_reached();
880 gnc_get_current_book ());
881 g_assert(pending_trans == trans);
886 if (gnc_split_register_get_default_account (reg) != NULL)
892 default_account = gnc_split_register_get_default_account (reg);
906 if (blank_split == NULL)
911 DEBUG(
"blank_split=%p", blank_split);
913 info->blank_split_edited = TRUE;
918 sd = gnc_split_register_save_data_new(
920 gnc_table_save_cells (reg->
table, sd);
921 gnc_split_register_save_data_destroy (sd);
924 gnc_resume_gui_refresh ();
928 GNC_PREF_TAB_TRANS_MEMORISED) )
933 if (gnc_table_get_current_cell_location (reg->
table, cell_name,
935 *p_new_virt_loc = new_virt_loc;
941 case CURSOR_CLASS_SPLIT:
953 if (!gnc_cell_name_equal (cell_name, MEMO_CELL))
958 if (gnc_table_layout_get_cell_changed (reg->
table->layout,
960 gnc_table_layout_get_cell_changed (reg->
table->layout,
962 gnc_table_layout_get_cell_changed (reg->
table->layout,
964 gnc_table_layout_get_cell_changed (reg->
table->layout,
966 gnc_table_layout_get_cell_changed (reg->
table->layout,
971 if (!gnc_table_layout_get_cell_changed (reg->
table->layout,
976 memo = gnc_table_layout_get_cell_value (reg->
table->layout, MEMO_CELL);
977 if ((memo == NULL) || (*memo ==
'\0'))
982 unit_price = !gnc_table_get_current_cell_location (reg->
table,
986 if (gnc_split_register_get_default_account (reg) != NULL)
988 Account *account = gnc_split_register_get_default_account (reg);
990 auto_split = gnc_find_split_in_account_by_memo (account, memo,
994 auto_split = gnc_find_split_in_reg_by_memo (reg, memo, unit_price);
996 if (auto_split == NULL)
1002 if (!gnc_table_layout_get_cell_changed (reg->
table->layout,
1005 cell = gnc_table_layout_get_cell (reg->
table->layout, ACTN_CELL);
1006 gnc_combo_cell_set_value ((
ComboCell *) cell,
1007 gnc_get_num_action (NULL, auto_split));
1011 cell = gnc_table_layout_get_cell (reg->
table->layout, XFRM_CELL);
1014 gnc_combo_cell_set_value ((
ComboCell *) cell, account_name);
1015 g_free(account_name);
1017 gnc_basic_cell_set_changed (cell, TRUE);
1019 if (!gnc_table_layout_get_cell_changed (reg->
table->layout,
1021 !gnc_table_layout_get_cell_changed (reg->
table->layout,
1029 debit_cell = gnc_table_layout_get_cell (reg->
table->layout,
1031 credit_cell = gnc_table_layout_get_cell (reg->
table->layout,
1034 gnc_price_cell_set_debt_credit_value ((
PriceCell *) debit_cell,
1038 gnc_basic_cell_set_changed (debit_cell, TRUE);
1039 gnc_basic_cell_set_changed (credit_cell, TRUE);
1043 gnc_table_refresh_gui (reg->
table, TRUE);
1049 if (gnc_table_get_current_cell_location (reg->
table, cell_name,
1051 *p_new_virt_loc = new_virt_loc;
1065 const char *cell_name)
1072 if (!gnc_cell_name_equal (cell_name, ACTN_CELL) ||
1073 !gnc_table_layout_get_cell_changed (reg->
table->layout,
1077 cell = gnc_table_layout_get_cell (reg->
table->layout, ACTN_CELL);
1081 if ((name == NULL) || (*name ==
'\0'))
1084 buy = g_strcmp0 (name, ACTION_BUY_STR) == 0;
1085 sell = g_strcmp0 (name, ACTION_SELL_STR) == 0;
1089 cell = gnc_table_layout_get_cell (reg->
table->layout, SHRS_CELL);
1092 shares = gnc_price_cell_get_value ((
PriceCell *) cell);
1098 gnc_basic_cell_set_changed (cell, TRUE);
1104 const char *cell_name)
1111 if (!gnc_cell_name_equal (cell_name, SHRS_CELL) ||
1112 !gnc_table_layout_get_cell_changed (reg->
table->layout,
1116 cell = gnc_table_layout_get_cell (reg->
table->layout, SHRS_CELL);
1119 shares = gnc_price_cell_get_value ((
PriceCell *) cell);
1124 cell = gnc_table_layout_get_cell (reg->
table->layout, ACTN_CELL);
1129 if (!g_strcmp0(name,
"") ||
1130 !g_strcmp0(name, buy ? ACTION_SELL_STR : ACTION_BUY_STR))
1132 gnc_combo_cell_set_value((
ComboCell *)cell,
1133 buy ? ACTION_BUY_STR : ACTION_SELL_STR);
1134 gnc_basic_cell_set_changed (cell, TRUE);
1144 gnc_split_register_check_cell (
SplitRegister *reg,
const char *cell_name)
1146 ENTER(
"reg=%p, cell_name=%s", reg, cell_name ? cell_name :
"NULL");
1149 if (!gnc_split_register_check_account (reg, cell_name))
1151 LEAVE(
"account check failed");
1156 if (!gnc_split_register_check_debcred (reg, cell_name))
1158 LEAVE(
"debit/credit check failed");
1163 if ((reg->type == STOCK_REGISTER) ||
1164 (reg->type == PORTFOLIO_LEDGER) ||
1165 (reg->type == CURRENCY_REGISTER))
1167 gnc_split_register_check_stock_action (reg, cell_name);
1168 gnc_split_register_check_stock_shares (reg, cell_name);
1177 const char * cell_name)
1182 cell = gnc_table_layout_get_cell (reg->
table->layout, cell_name);
1185 name = gnc_basic_cell_get_value (cell);
1189 if (!g_strcmp0 (name, SPLIT_TRANS_STR))
1194 return gnc_split_register_get_account_by_name (reg, cell, name);
1199 gnc_split_register_get_cell_string (
SplitRegister *reg,
const char *cell_name)
1203 cell = gnc_table_layout_get_cell (reg->
table->layout, cell_name);
1207 return gnc_basic_cell_get_value (cell);
1211 gnc_split_register_get_cell_date (
SplitRegister *reg,
const char *cell_name)
1216 cell = (
DateCell*) gnc_table_layout_get_cell (reg->
table->layout, cell_name);
1219 gnc_date_cell_get_date (cell, &ts);
1238 g_return_val_if_fail(reg, NULL);
1239 g_return_val_if_fail(reg->
table, NULL);
1240 cur = reg->
table->current_cursor;
1243 xfer = gnc_xfer_dialog(NULL, NULL);
1244 g_return_val_if_fail(xfer, NULL);
1249 gnc_xfer_dialog_set_description(xfer, gnc_basic_cell_get_value(cell));
1253 gnc_xfer_dialog_set_description(xfer, str ? str :
"");
1259 gnc_xfer_dialog_set_memo(xfer, gnc_basic_cell_get_value(cell));
1263 gnc_xfer_dialog_set_memo(xfer, str ? str :
"");
1269 gnc_xfer_dialog_set_num(xfer, gnc_basic_cell_get_value(cell));
1272 const char *str = gnc_get_num_action (txn, split);
1273 gnc_xfer_dialog_set_num(xfer, str ? str :
"");
1281 gnc_date_cell_get_date((
DateCell*) cell, &ts);
1300 Split *split, *osplit;
1305 gboolean expanded = FALSE;
1307 const char *message;
1310 ENTER(
"reg=%p, force_dialog=%s", reg, force_dialog ?
"TRUE" :
"FALSE" );
1313 if (!gnc_split_reg_has_rate_cell (reg->type))
1317 message = _(
"This register does not support editing exchange rates.");
1318 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1320 LEAVE(
"no rate cell");
1324 rate_cell = (
PriceCell*) gnc_table_layout_get_cell(
1325 reg->
table->layout, RATE_CELL);
1330 message = _(
"This register does not support editing exchange rates.");
1331 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1333 LEAVE(
"null rate cell");
1338 info = gnc_split_register_get_info (reg);
1339 exch_rate = gnc_price_cell_get_value (rate_cell);
1341 info->rate_reset != RATE_RESET_REQD)
1343 LEAVE(
"rate already non-zero");
1352 if (expanded && cursor_class == CURSOR_CLASS_TRANS)
1356 message = _(
"You need to select a split in order to modify its exchange "
1358 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1360 LEAVE(
"expanded with transaction cursor; nothing to do");
1365 xfer_acc = gnc_split_register_get_account_always(
1366 reg, expanded ? XFRM_CELL : MXFRM_CELL);
1369 if (force_dialog && !expanded && !xfer_acc)
1371 message = _(
"You need to expand the transaction in order to modify its "
1373 gnc_error_dialog (gnc_split_register_get_parent (reg),
"%s", message);
1374 LEAVE(
"%s", message);
1383 message = _(
"The entered account could not be found.");
1384 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1386 LEAVE(
"no xfer account");
1396 reg_acc = gnc_split_register_get_default_account (reg);
1411 LEAVE(
"txn and account currencies match, and not forcing");
1416 if (expanded || osplit == NULL)
1418 message = _(
"The two currencies involved equal each other.");
1419 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1420 LEAVE(
"register is expanded or osplit == NULL; not forcing dialog");
1431 message = _(
"The two currencies involved equal each other.");
1432 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1433 LEAVE(
"reg commodity == txn commodity; not forcing");
1442 if (!expanded && osplit &&
1443 gnc_split_register_split_needs_amount (reg, split) &&
1444 gnc_split_register_split_needs_amount (reg, osplit))
1446 message = _(
"You need to expand the transaction in order to modify its "
1450 gnc_error_dialog (gnc_split_register_get_parent (reg),
"%s", message);
1452 LEAVE(
"%s", message);
1472 amount = gnc_split_register_debcred_cell_value (reg);
1482 message = _(
"The split's amount is zero, so no exchange rate is needed.");
1483 gnc_error_dialog(gnc_split_register_get_parent(reg),
"%s", message);
1485 LEAVE(
"amount is zero; no exchange rate needed");
1494 info->rate_reset != RATE_RESET_REQD &&
1497 LEAVE(
"gain/loss split; no exchange rate needed");
1502 xfer = gnc_split_register_xfer_dialog(reg, txn, split);
1503 gnc_xfer_dialog_is_exchange_dialog(xfer, &exch_rate);
1504 if (gnc_xfer_dialog_run_exchange_dialog(
1505 xfer, &exch_rate, amount, reg_acc, txn, xfer_com, expanded))
1508 LEAVE(
"leaving rate unchanged");
1514 gnc_price_cell_set_value (rate_cell, exch_rate);
1515 gnc_basic_cell_set_changed (&rate_cell->cell, TRUE);
1516 info->rate_account = xfer_acc;
1517 info->rate_reset = RATE_RESET_DONE;
1527 gboolean exact_traversal)
1529 GtkWidget *dialog, *window;
1531 const char *title = _(
"Save the changed transaction?");
1532 const char *message =
1533 _(
"The current transaction has been changed. Would you like to "
1534 "record the changes before moving to a new transaction, discard the "
1535 "changes, or return to the changed transaction?");
1537 window = gnc_split_register_get_parent(reg);
1538 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1539 GTK_DIALOG_DESTROY_WITH_PARENT,
1540 GTK_MESSAGE_QUESTION,
1543 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1545 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1546 _(
"_Discard Changes"), GTK_RESPONSE_REJECT,
1547 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1548 _(
"_Record Changes"), GTK_RESPONSE_ACCEPT,
1550 response = gnc_dialog_run(GTK_DIALOG(dialog), GNC_PREF_WARN_REG_TRANS_MOD);
1551 gtk_widget_destroy(dialog);
1555 case GTK_RESPONSE_ACCEPT:
1558 case GTK_RESPONSE_REJECT:
1565 new_split = gnc_split_register_get_split (reg, virt_loc->vcell_loc);
1566 trans_split = gnc_split_register_get_trans_split (reg,
1567 virt_loc->vcell_loc,
1570 virt_loc->vcell_loc);
1574 if (gnc_split_register_find_split (reg, new_trans, trans_split,
1575 new_split, new_class, &vcell_loc))
1576 virt_loc->vcell_loc = vcell_loc;
1578 gnc_table_find_close_valid_cell (reg->
table, virt_loc,
1581 *p_new_virt_loc = *virt_loc;
1585 case GTK_RESPONSE_CANCEL:
1607 gncTableTraversalDir dir,
1617 const char *cell_name;
1619 g_return_val_if_fail(p_new_virt_loc, TRUE);
1621 ENTER(
"reg=%p, p_new_virt_loc=%p (%d,%d), dir=%d",
1622 reg, p_new_virt_loc, (*p_new_virt_loc).vcell_loc.virt_row,
1623 (*p_new_virt_loc).vcell_loc.virt_col, dir);
1627 LEAVE(
"no register");
1631 info = gnc_split_register_get_info (reg);
1633 if (info->first_pass)
1635 LEAVE(
"first pass");
1640 gnc_get_current_book ());
1641 virt_loc = *p_new_virt_loc;
1643 info->exact_traversal = (dir == GNC_TABLE_TRAVERSE_POINTER);
1649 LEAVE(
"no transaction");
1654 changed = gnc_table_current_cursor_changed (reg->
table, FALSE);
1655 if (!changed && (pending_trans != trans))
1657 gnc_table_find_close_valid_cell (reg->
table, &virt_loc,
1658 info->exact_traversal);
1660 *p_new_virt_loc = virt_loc;
1662 LEAVE(
"no changes");
1667 cell_name = gnc_table_get_current_cell_name (reg->
table);
1668 if (!gnc_split_register_check_cell (reg, cell_name))
1670 LEAVE(
"check cell");
1679 if (!changed && !info->blank_split_edited)
1682 if (dir != GNC_TABLE_TRAVERSE_RIGHT)
1685 virt_loc = reg->
table->current_cursor_loc;
1689 virt_loc = reg->
table->current_cursor_loc;
1690 if (gnc_table_move_tab (reg->
table, &virt_loc, TRUE))
1696 LEAVE(
"no exchange rate");
1700 *p_new_virt_loc = reg->
table->current_cursor_loc;
1701 (p_new_virt_loc->vcell_loc.virt_row)++;
1702 p_new_virt_loc->phys_row_offset = 0;
1703 p_new_virt_loc->phys_col_offset = 0;
1705 info->traverse_to_new = TRUE;
1707 LEAVE(
"off end of last line");
1715 if (!gnc_table_virtual_cell_out_of_bounds (reg->
table, virt_loc.vcell_loc))
1717 if (gnc_split_register_auto_completion (reg, dir, p_new_virt_loc))
1719 info->auto_complete = TRUE;
1720 LEAVE(
"auto-complete");
1737 if (dir != GNC_TABLE_TRAVERSE_RIGHT)
1740 virt_loc = reg->
table->current_cursor_loc;
1741 old_virt_row = virt_loc.vcell_loc.virt_row;
1743 if (gnc_table_move_tab (reg->
table, &virt_loc, TRUE) &&
1744 old_virt_row == virt_loc.vcell_loc.virt_row)
1757 LEAVE(
"no exchange rate");
1761 info->cursor_hint_trans = trans;
1762 info->cursor_hint_split = split;
1763 info->cursor_hint_trans_split =
1765 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1766 info->hint_set_by_traverse = TRUE;
1768 LEAVE(
"off end of blank split");
1775 int old_virt_row = reg->
table->current_cursor_loc.vcell_loc.virt_row;
1778 gnc_table_find_close_valid_cell (reg->
table, &virt_loc,
1779 info->exact_traversal);
1783 if (virt_loc.vcell_loc.virt_row != old_virt_row)
1787 LEAVE(
"no exchange rate");
1794 new_trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
1795 if (trans == new_trans)
1797 *p_new_virt_loc = virt_loc;
1799 LEAVE(
"staying within txn");
1806 LEAVE(
"txn change");
1807 return transaction_changed_confirm(p_new_virt_loc, &virt_loc, reg,
1808 new_trans, info->exact_traversal);
1812 gnc_split_register_control_new (
void)
1816 control->move_cursor = gnc_split_register_move_cursor;
1817 control->traverse = gnc_split_register_traverse;
1823 gnc_split_register_recn_cell_confirm (
char old_flag, gpointer data)
1826 GtkWidget *dialog, *window;
1828 const gchar *title = _(
"Mark split as unreconciled?");
1829 const gchar *message =
1830 _(
"You are about to mark a reconciled split as unreconciled. Doing "
1831 "so might make future reconciliation difficult! Continue "
1832 "with this change?");
1834 if (old_flag !=
YREC)
1838 window = gnc_split_register_get_parent(reg);
1840 gtk_message_dialog_new(GTK_WINDOW(window),
1841 GTK_DIALOG_DESTROY_WITH_PARENT,
1842 GTK_MESSAGE_WARNING,
1845 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1847 gtk_dialog_add_button(GTK_DIALOG(dialog), _(
"_Unreconcile"),
1849 response = gnc_dialog_run(GTK_DIALOG(dialog), GNC_PREF_WARN_REG_RECD_SPLIT_UNREC);
1850 gtk_widget_destroy(dialog);
1851 return (response == GTK_RESPONSE_YES);
void gnc_copy_trans_onto_trans(Transaction *from, Transaction *to, gboolean use_cut_semantics, gboolean do_commit)
Transaction * gnc_split_register_get_current_trans(SplitRegister *reg)
gboolean xaccTransHasReconciledSplits(const Transaction *trans)
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
gchar * gnc_num_dbg_to_string(gnc_numeric n)
time64 timespecToTime64(Timespec ts)
Split * xaccTransGetSplit(const Transaction *trans, int i)
time64 xaccTransGetDate(const Transaction *trans)
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
SplitList * xaccAccountGetSplitList(const Account *acc)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
gboolean xaccTransIsOpen(const Transaction *trans)
The type, style and table for the register.
#define PINFO(format, args...)
gboolean xaccSplitDestroy(Split *split)
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Split * gnc_split_register_get_current_split(SplitRegister *reg)
#define DEBUG(format, args...)
Split * gnc_split_register_get_blank_split(SplitRegister *reg)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
CursorClass gnc_split_register_get_cursor_class(SplitRegister *reg, VirtualCellLocation vcell_loc)
Use a 64-bit unsigned int timespec.
Split * gnc_split_register_get_current_trans_split(SplitRegister *reg, VirtualCellLocation *trans_split_loc)
gboolean gnc_numeric_zero_p(gnc_numeric a)
Transaction * xaccSplitGetParent(const Split *split)
gboolean gnc_table_move_vertical_position(Table *table, VirtualLocation *virt_loc, int phys_row_offset)
gboolean xaccTransIsBalanced(const Transaction *trans)
gboolean gnc_split_register_save(SplitRegister *reg, gboolean do_commit)
#define ENTER(format, args...)
gboolean gnc_numeric_negative_p(gnc_numeric a)
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
void gnc_split_register_redraw(SplitRegister *reg)
gchar * gnc_get_account_name_for_register(const Account *account)
convert single-entry accounts to clean double-entry
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
Transaction * xaccAccountFindTransByDesc(const Account *acc, const char *description)
void gnc_monetary_list_free(MonetaryList *list)
void xaccTransScrubImbalance(Transaction *trans, Account *root, Account *account)
gboolean do_auto_complete
BasicCell * gnc_cellblock_get_cell_by_name(CellBlock *cellblock, const char *cell_name, int *row, int *col)
const char * xaccTransGetDescription(const Transaction *trans)
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it...
void xaccTransCommitEdit(Transaction *trans)
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
#define xaccSplitGetGUID(X)
gboolean gnc_split_register_current_trans_expanded(SplitRegister *reg)
void xaccTransBeginEdit(Transaction *trans)
gnc_numeric xaccSplitGetSharePrice(const Split *split)
gboolean gnc_numeric_positive_p(gnc_numeric a)
#define xaccTransGetGUID(X)
Generic api to store and retrieve preferences.
gboolean gnc_split_register_handle_exchange(SplitRegister *reg, gboolean force_dialog)
gnc_numeric xaccSplitGetValue(const Split *split)
CursorClass gnc_split_register_get_current_cursor_class(SplitRegister *reg)
Account * xaccSplitGetAccount(const Split *s)
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
const GncGUID * guid_null(void)
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
MonetaryList * xaccTransGetImbalance(const Transaction *trans)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Declarations for the Table object.
Split * xaccSplitGetOtherSplit(const Split *split)
#define LEAVE(format, args...)
time64 gnc_time(time64 *tbuf)
get the current local time
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
const char * xaccSplitGetMemo(const Split *split)
Account * gnc_account_get_root(Account *acc)
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
void gnc_split_register_cancel_cursor_trans_changes(SplitRegister *reg)
const gchar * QofLogModule
gnc_numeric xaccSplitGetAmount(const Split *split)
void timespecFromTime64(Timespec *ts, time64 t)