27 #include <glib/gi18n.h>
31 #include "gnc-component-manager.h"
34 #include "gnc-gui-query.h"
36 #include "quickfillcell.h"
39 #include "split-register-p.h"
40 #include "engine-helpers.h"
48 static void gnc_split_register_load_xfer_cells (
SplitRegister *reg,
60 gnc_table_layout_get_cell (reg->
table->layout, RECN_CELL);
64 s = gnc_get_reconcile_valid_flags ();
65 gnc_recn_cell_set_valid_flags (cell, s, *s);
66 gnc_recn_cell_set_flag_order (cell, gnc_get_reconcile_flag_order ());
67 gnc_recn_cell_set_string_getter (cell, gnc_get_reconcile_str);
78 gnc_table_layout_get_cell (reg->
table->layout, TYPE_CELL);
83 gnc_recn_cell_set_valid_flags (cell,
"IP?",
'I');
84 gnc_recn_cell_set_flag_order (cell,
"IP");
155 gboolean visible_splits,
156 gboolean start_primary_color,
166 g_return_if_fail(reg);
167 g_return_if_fail(vcell_loc);
169 if (split == find_split)
170 *new_split_row = vcell_loc->virt_row;
174 TRUE, start_primary_color, *vcell_loc);
175 vcell_loc->virt_row++;
181 Split *secondary = node->data;
183 if (!xaccTransStillHasSplit(trans, secondary))
continue;
184 if (secondary == find_split && find_class == CURSOR_CLASS_SPLIT)
185 *new_split_row = vcell_loc->virt_row;
187 gnc_table_set_vcell (reg->
table, split_cursor,
189 visible_splits, TRUE, *vcell_loc);
190 vcell_loc->virt_row++;
196 if (find_trans == trans && find_split == NULL &&
197 find_class == CURSOR_CLASS_SPLIT)
198 *new_split_row = vcell_loc->virt_row;
201 FALSE, TRUE, *vcell_loc);
202 vcell_loc->virt_row++;
207 _find_split_with_parent_txn(gconstpointer a, gconstpointer b)
216 Split *split, gboolean has_last_num)
221 gnc_quickfill_cell_add_completion(
222 (
QuickFillCell *) gnc_table_layout_get_cell(layout, DESC_CELL),
225 gnc_quickfill_cell_add_completion(
226 (
QuickFillCell *) gnc_table_layout_get_cell(layout, NOTES_CELL),
230 gnc_num_cell_set_last_num(
231 (
NumCell *) gnc_table_layout_get_cell(layout, NUM_CELL),
232 gnc_get_num_action(trans, split));
236 gnc_quickfill_cell_add_completion(
237 (
QuickFillCell *) gnc_table_layout_get_cell(layout, MEMO_CELL),
247 gboolean currency_from_account = TRUE;
248 Split *blank_split = NULL;
255 if (default_account != NULL && !currency_from_account)
258 gnc_info_dialog(NULL,
"%s",
259 _(
"Could not determine the account currency. "
260 "Using the default currency provided by your system."));
263 gnc_suspend_gui_refresh ();
271 xaccSplitSetParent(blank_split, new_trans);
281 info->blank_split_edited = FALSE;
282 info->auto_complete = FALSE;
283 DEBUG(
"created new blank_split=%p", blank_split);
285 gnc_resume_gui_refresh ();
292 info->separator_changed = FALSE;
296 (
ComboCell *) gnc_table_layout_get_cell(table->layout, MXFRM_CELL),
297 gnc_get_account_separator());
300 (
ComboCell *) gnc_table_layout_get_cell(table->layout, XFRM_CELL),
301 gnc_get_account_separator());
304 gnc_recn_cell_set_confirm_cb(
305 (
RecnCell *) gnc_table_layout_get_cell(table->layout, RECN_CELL),
306 gnc_split_register_recn_cell_confirm, reg);
315 info->cursor_hint_trans_split =
317 info->cursor_hint_cursor_class =
319 info->hint_set_by_traverse = FALSE;
320 info->traverse_to_new = FALSE;
321 info->exact_traversal = FALSE;
322 info->first_pass = FALSE;
323 info->reg_loaded = TRUE;
333 GHashTable *trans_table = NULL;
341 Split *find_trans_split;
348 gboolean start_primary_color = TRUE;
349 gboolean found_pending = FALSE;
350 gboolean need_divider_upper = FALSE;
351 gboolean found_divider_upper = FALSE;
352 gboolean found_divider = FALSE;
353 gboolean has_last_num = FALSE;
356 gboolean we_own_slist = FALSE;
359 GNC_PREF_FUTURE_AFTER_BLANK);
360 gboolean added_blank_trans = FALSE;
365 int new_trans_split_row = -1;
366 int new_trans_row = -1;
367 int new_split_row = -1;
368 time64 present, autoreadonly_time = 0;
370 g_return_if_fail(reg);
372 g_return_if_fail(table);
373 info = gnc_split_register_get_info (reg);
374 g_return_if_fail(info);
376 ENTER(
"reg=%p, slist=%p, default_account=%p", reg, slist, default_account);
379 gnc_get_current_book ());
382 gnc_get_current_book ());
385 if (blank_split == NULL)
390 g_assert(pending_trans == NULL);
391 blank_split = create_blank_split (default_account, info);
395 DEBUG(
"blank_split=%p, blank_trans=%p, pending_trans=%p",
396 blank_split, blank_trans, pending_trans);
402 multi_line = (reg->style == REG_STYLE_JOURNAL);
403 dynamic = (reg->style == REG_STYLE_AUTO_LEDGER);
405 lead_cursor = gnc_split_register_get_passive_cursor (reg);
406 split_cursor = gnc_table_layout_get_cursor (table->layout, CURSOR_SPLIT);
409 if (info->traverse_to_new)
411 find_trans = blank_trans;
413 find_trans_split = blank_split;
414 find_class = CURSOR_CLASS_SPLIT;
418 find_trans = info->cursor_hint_trans;
419 find_split = info->cursor_hint_split;
420 find_trans_split = info->cursor_hint_trans_split;
421 find_class = info->cursor_hint_cursor_class;
424 save_loc = table->current_cursor_loc;
428 if (gnc_table_current_cursor_changed (table, TRUE) &&
431 cursor_buffer = gnc_cursor_buffer_new ();
432 gnc_table_save_current_cursor (table, cursor_buffer);
435 cursor_buffer = NULL;
439 gnc_table_control_allow_move (table->control, FALSE);
445 gnc_virtual_location_init(&virt_loc);
446 gnc_table_move_cursor_gui (table, virt_loc);
450 vcell_loc.virt_row = 0;
451 vcell_loc.virt_col = 0;
452 cursor_header = gnc_table_layout_get_cursor (table->layout, CURSOR_HEADER);
453 gnc_table_set_vcell (table, cursor_header, NULL, TRUE, TRUE, vcell_loc);
454 vcell_loc.virt_row++;
458 if (use_autoreadonly)
466 if (info->first_pass)
476 cell = (
NumCell *) gnc_table_layout_get_cell(table->layout, NUM_CELL);
477 gnc_num_cell_set_last_num (cell, last_num);
483 gnc_split_register_load_xfer_cells (reg, default_account);
484 gnc_split_register_load_recn_cells (reg);
485 gnc_split_register_load_type_cells (reg);
488 if (info->separator_changed)
489 change_account_separator (info, table, reg);
491 table->model->dividing_row_upper = -1;
492 table->model->dividing_row = -1;
493 table->model->dividing_row_lower = -1;
497 if (pending_trans != NULL)
502 if (!xaccTransStillHasSplit(pending_trans, pending_split))
continue;
503 if (g_list_find(slist, pending_split) != NULL)
506 if (g_list_find_custom(slist, pending_trans,
507 _find_split_with_parent_txn) != NULL)
513 slist = g_list_copy(slist);
516 slist = g_list_append(slist, pending_split);
521 trans_table = g_hash_table_new (g_direct_hash, g_direct_equal);
524 for (node = slist; node; node = node->next)
529 if (!xaccTransStillHasSplit(trans, split))
532 if (pending_trans == trans)
533 found_pending = TRUE;
544 if (trans == blank_trans)
550 if (g_hash_table_lookup (trans_table, trans))
553 g_hash_table_insert (trans_table, trans, trans);
556 if (info->show_present_divider &&
558 !found_divider_upper)
562 table->model->dividing_row_upper = vcell_loc.virt_row;
563 found_divider_upper = TRUE;
567 need_divider_upper = TRUE;
571 if (info->show_present_divider &&
575 table->model->dividing_row = vcell_loc.virt_row;
576 found_divider = TRUE;
578 if (future_after_blank)
580 if (blank_trans == find_trans)
581 new_trans_row = vcell_loc.virt_row;
583 if (blank_split == find_trans_split)
584 new_trans_split_row = vcell_loc.virt_row;
587 if (info->first_pass)
589 save_loc.vcell_loc = vcell_loc;
590 save_loc.phys_row_offset = 0;
591 save_loc.phys_col_offset = 0;
594 gnc_split_register_add_transaction (reg,
595 blank_trans, blank_split,
596 lead_cursor, split_cursor,
597 multi_line, start_primary_color,
598 info->blank_split_edited,
599 find_trans, find_split,
600 find_class, &new_split_row,
603 table->model->dividing_row_lower = vcell_loc.virt_row;
606 start_primary_color = !start_primary_color;
608 added_blank_trans = TRUE;
614 if (info->first_pass)
615 add_quickfill_completions(reg->
table->layout, trans, split, has_last_num);
617 if (trans == find_trans)
618 new_trans_row = vcell_loc.virt_row;
620 if (split == find_trans_split)
621 new_trans_split_row = vcell_loc.virt_row;
623 gnc_split_register_add_transaction (reg, trans, split,
624 lead_cursor, split_cursor,
625 multi_line, start_primary_color,
627 find_trans, find_split, find_class,
628 &new_split_row, &vcell_loc);
631 start_primary_color = !start_primary_color;
635 g_hash_table_destroy (trans_table);
638 if (pending_trans == blank_trans)
639 found_pending = TRUE;
642 if (info->show_present_divider &&
644 !found_divider_upper && need_divider_upper)
646 table->model->dividing_row_upper = vcell_loc.virt_row;
647 found_divider_upper = TRUE;
654 info->pending_trans_guid = *
guid_null ();
657 else if (pending_trans)
658 g_assert_not_reached();
660 pending_trans = NULL;
663 if (!added_blank_trans) {
664 if (blank_trans == find_trans)
665 new_trans_row = vcell_loc.virt_row;
667 if (blank_split == find_trans_split)
668 new_trans_split_row = vcell_loc.virt_row;
671 if (info->first_pass)
673 save_loc.vcell_loc = vcell_loc;
674 save_loc.phys_row_offset = 0;
675 save_loc.phys_col_offset = 0;
678 gnc_split_register_add_transaction (reg, blank_trans, blank_split,
679 lead_cursor, split_cursor,
680 multi_line, start_primary_color,
681 info->blank_split_edited,
682 find_trans, find_split,
683 find_class, &new_split_row,
686 if (future_after_blank)
687 table->model->dividing_row_lower = vcell_loc.virt_row;
691 if (info->first_pass)
694 new_trans_split_row = -1;
700 gnc_table_set_size (table, vcell_loc.virt_row, 1);
706 if (new_split_row > 0)
707 save_loc.vcell_loc.virt_row = new_split_row;
708 else if (new_trans_split_row > 0)
709 save_loc.vcell_loc.virt_row = new_trans_split_row;
710 else if (new_trans_row > 0)
711 save_loc.vcell_loc.virt_row = new_trans_row;
713 trans_split_loc = save_loc;
715 gnc_split_register_get_trans_split (reg, save_loc.vcell_loc,
716 &trans_split_loc.vcell_loc);
718 if (dynamic || multi_line || info->trans_expanded)
720 gnc_table_set_virt_cell_cursor(
721 table, trans_split_loc.vcell_loc,
722 gnc_split_register_get_active_cursor (reg));
723 gnc_split_register_set_trans_visible (reg, trans_split_loc.vcell_loc,
726 info->trans_expanded = (reg->style == REG_STYLE_LEDGER);
730 save_loc = trans_split_loc;
731 info->trans_expanded = FALSE;
734 if (gnc_table_find_close_valid_cell (table, &save_loc, FALSE))
736 gnc_table_move_cursor_gui (table, save_loc);
737 new_split_row = save_loc.vcell_loc.virt_row;
740 gnc_table_restore_current_cursor (table, cursor_buffer);
743 gnc_cursor_buffer_destroy (cursor_buffer);
744 cursor_buffer = NULL;
746 update_info (info, reg);
748 gnc_split_register_set_cell_fractions(
751 gnc_table_refresh_gui (table, TRUE);
753 gnc_split_register_show_trans (reg, table->current_cursor_loc.vcell_loc);
756 gnc_table_control_allow_move (table->control, TRUE);
766 #define QKEY "split_reg_shared_quickfill"
769 skip_cb (
Account *account, gpointer x)
789 root = gnc_get_current_root_account();
794 store = gnc_get_shared_account_name_list_store (root, QKEY, skip_cb, NULL);
797 gnc_table_layout_get_cell (reg->
table->layout, XFRM_CELL);
799 gnc_combo_cell_use_list_store_cache (cell, store);
802 gnc_table_layout_get_cell (reg->
table->layout, MXFRM_CELL);
804 gnc_combo_cell_use_list_store_cache (cell, store);
Transaction * gnc_split_register_get_current_trans(SplitRegister *reg)
Transaction * xaccMallocTransaction(QofBook *book)
const char * xaccAccountGetLastNum(const Account *acc)
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
time64 timespecToTime64(Timespec ts)
Split * xaccTransGetSplit(const Transaction *trans, int i)
time64 xaccTransGetDate(const Transaction *trans)
time64 gnc_time64_get_today_end(void)
gboolean xaccTransIsOpen(const Transaction *trans)
utility functions for the GnuCash UI
The type, style and table for the register.
Split * gnc_split_register_get_current_split(SplitRegister *reg)
#define DEBUG(format, args...)
Create an account-name quick-fill.
Split * gnc_split_register_get_current_trans_split(SplitRegister *reg, VirtualCellLocation *trans_split_loc)
Transaction * xaccSplitGetParent(const Split *split)
void gnc_combo_cell_use_quickfill_cache(ComboCell *cell, QuickFill *shared_qf)
#define ENTER(format, args...)
QuickFill * gnc_get_shared_account_name_quickfill(Account *root, const char *key, AccountBoolCB cb, gpointer cb_data)
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
const char * xaccTransGetNotes(const Transaction *trans)
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
int xaccTransCountSplits(const Transaction *trans)
#define xaccAccountGetGUID(X)
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
void gnc_combo_cell_set_complete_char(ComboCell *cell, gunichar complete_char)
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)
#define xaccSplitGetGUID(X)
void xaccTransBeginEdit(Transaction *trans)
API for checkbook register display area.
Split * xaccMallocSplit(QofBook *book)
Generic api to store and retrieve preferences.
gnc_commodity * gnc_account_or_default_currency(const Account *account, gboolean *currency_from_account_found)
void gnc_split_register_load(SplitRegister *reg, GList *slist, Account *default_account)
CursorClass gnc_split_register_get_current_cursor_class(SplitRegister *reg)
Account * xaccSplitGetAccount(const Split *s)
const GncGUID * guid_null(void)
gboolean xaccAccountGetPlaceholder(const Account *acc)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
#define LEAVE(format, args...)
const char * xaccSplitGetMemo(const Split *split)
Timespec gdate_to_timespec(GDate d)
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Account * gnc_account_get_root(Account *acc)
SplitList * xaccTransGetSplitList(const Transaction *trans)
const gchar * QofLogModule