27 #include <glib/gi18n.h> 35 #include "gnc-component-manager.h" 38 #include "gnc-gui-query.h" 45 #include "engine-helpers.h" 51 static QofLogModule log_module = GNC_MOD_LEDGER;
54 static void gnc_split_register_load_xfer_cells (SplitRegister* reg,
58 gnc_split_register_load_recn_cells (SplitRegister* reg)
66 gnc_table_layout_get_cell (reg->table->layout, RECN_CELL);
70 s = gnc_get_reconcile_valid_flags();
72 gnc_recn_cell_set_flag_order (cell, gnc_get_reconcile_flag_order());
73 gnc_recn_cell_set_string_getter (cell, gnc_get_reconcile_str);
77 gnc_split_register_load_doclink_cells (SplitRegister* reg)
85 gnc_table_layout_get_cell (reg->table->layout, DOCLINK_CELL);
94 gnc_doclink_cell_set_read_only (cell, TRUE);
98 gnc_split_register_load_type_cells (SplitRegister* reg)
105 gnc_table_layout_get_cell (reg->table->layout, TYPE_CELL);
111 gnc_recn_cell_set_flag_order (cell,
"IP");
112 gnc_recn_cell_set_read_only (cell, TRUE);
178 gnc_split_register_add_transaction (SplitRegister* reg,
183 gboolean visible_splits,
184 gboolean start_primary_color,
186 Transaction* find_trans,
190 VirtualCellLocation* vcell_loc)
194 g_return_if_fail (reg);
195 g_return_if_fail (vcell_loc);
197 if (split == find_split)
198 *new_split_row = vcell_loc->virt_row;
202 TRUE, start_primary_color, *vcell_loc);
203 vcell_loc->virt_row++;
209 Split* secondary = node->data;
211 if (!xaccTransStillHasSplit (trans, secondary))
continue;
212 if (secondary == find_split && find_class == CURSOR_CLASS_SPLIT)
213 *new_split_row = vcell_loc->virt_row;
217 visible_splits, TRUE, *vcell_loc);
218 vcell_loc->virt_row++;
224 if (find_trans == trans && find_split == NULL &&
225 find_class == CURSOR_CLASS_SPLIT)
226 *new_split_row = vcell_loc->virt_row;
229 FALSE, TRUE, *vcell_loc);
230 vcell_loc->virt_row++;
235 _find_split_with_parent_txn (gconstpointer a, gconstpointer b)
237 Split* split = (Split*)a;
238 Transaction* txn = (Transaction*)b;
243 static void add_quickfill_completions (TableLayout* layout, Transaction* trans,
244 Split* split, gboolean has_last_num)
246 gnc_quickfill_cell_add_completion (
247 (
QuickFillCell*) gnc_table_layout_get_cell (layout, DESC_CELL),
250 gnc_quickfill_cell_add_completion (
251 (
QuickFillCell*) gnc_table_layout_get_cell (layout, NOTES_CELL),
255 gnc_num_cell_set_last_num (
256 (
NumCell*) gnc_table_layout_get_cell (layout, NUM_CELL),
257 gnc_get_num_action (trans, split));
262 gnc_quickfill_cell_add_completion (
263 (
QuickFillCell*) gnc_table_layout_get_cell (layout, MEMO_CELL),
269 create_blank_split (
Account* default_account, SRInfo* info)
271 Transaction* new_trans;
272 gboolean currency_from_account = TRUE;
273 Split* blank_split = NULL;
279 ¤cy_from_account);
281 if (default_account != NULL && !currency_from_account)
284 gnc_info_dialog (NULL,
"%s",
285 _ (
"Could not determine the account currency. " 286 "Using the default currency provided by your system."));
289 gnc_suspend_gui_refresh();
297 xaccSplitSetParent (blank_split, new_trans);
307 info->blank_split_edited = FALSE;
308 info->auto_complete = FALSE;
309 DEBUG (
"created new blank_split=%p", blank_split);
311 gnc_resume_gui_refresh();
316 change_account_separator (SRInfo* info, Table*
table, SplitRegister* reg)
318 info->separator_changed = FALSE;
322 (
ComboCell*) gnc_table_layout_get_cell (
table->layout, MXFRM_CELL),
323 gnc_get_account_separator());
326 (
ComboCell*) gnc_table_layout_get_cell (
table->layout, XFRM_CELL),
327 gnc_get_account_separator());
330 gnc_recn_cell_set_confirm_cb (
331 (
RecnCell*) gnc_table_layout_get_cell (
table->layout, RECN_CELL),
332 gnc_split_register_recn_cell_confirm, reg);
336 update_info (SRInfo* info, SplitRegister* reg)
341 info->cursor_hint_trans_split =
343 info->cursor_hint_cursor_class =
345 info->hint_set_by_traverse = FALSE;
346 info->traverse_to_new = FALSE;
347 info->exact_traversal = FALSE;
348 info->first_pass = FALSE;
349 info->reg_loaded = TRUE;
357 Transaction* pending_trans;
358 CursorBuffer* cursor_buffer;
359 GHashTable* trans_table = NULL;
363 Transaction* blank_trans;
364 Transaction* find_trans;
367 Split* find_trans_split;
373 gnc_commodity *account_comm = NULL;
375 gboolean start_primary_color = TRUE;
376 gboolean found_pending = FALSE;
377 gboolean need_divider_upper = FALSE;
378 gboolean found_divider_upper = FALSE;
379 gboolean found_divider = FALSE;
380 gboolean has_last_num = FALSE;
383 gboolean we_own_slist = FALSE;
385 gnc_get_current_book());
387 GNC_PREFS_GROUP_GENERAL_REGISTER,
388 GNC_PREF_FUTURE_AFTER_BLANK);
389 gboolean added_blank_trans = FALSE;
391 VirtualCellLocation vcell_loc;
392 VirtualLocation save_loc;
394 int new_trans_split_row = -1;
395 int new_trans_row = -1;
396 int new_split_row = -1;
397 time64 present, autoreadonly_time = 0;
399 g_return_if_fail (reg);
401 g_return_if_fail (
table);
402 info = gnc_split_register_get_info (reg);
403 g_return_if_fail (info);
405 ENTER (
"reg=%p, slist=%p, default_account=%p", reg, slist, default_account);
408 gnc_get_current_book());
411 gnc_get_current_book());
421 ((
PriceCell*) gnc_table_layout_get_cell (
table->layout, DEBT_CELL),
422 gnc_commodity_print_info (account_comm, FALSE));
425 ((
PriceCell*) gnc_table_layout_get_cell (
table->layout, CRED_CELL),
426 gnc_commodity_print_info (account_comm, FALSE));
429 ((
PriceCell*) gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
430 gnc_commodity_print_info (account_comm, FALSE));
432 gnc_doclink_cell_set_use_glyphs
436 if (blank_split == NULL)
441 g_assert (pending_trans == NULL);
442 blank_split = create_blank_split (default_account, info);
446 DEBUG (
"blank_split=%p, blank_trans=%p, pending_trans=%p",
447 blank_split, blank_trans, pending_trans);
453 multi_line = (reg->style == REG_STYLE_JOURNAL);
454 dynamic = (reg->style == REG_STYLE_AUTO_LEDGER);
456 lead_cursor = gnc_split_register_get_passive_cursor (reg);
457 split_cursor = gnc_table_layout_get_cursor (
table->layout, CURSOR_SPLIT);
460 if (info->traverse_to_new)
462 find_trans = blank_trans;
464 find_trans_split = blank_split;
465 find_class = CURSOR_CLASS_SPLIT;
469 find_trans = info->cursor_hint_trans;
470 find_split = info->cursor_hint_split;
471 find_trans_split = info->cursor_hint_trans_split;
472 find_class = info->cursor_hint_cursor_class;
475 save_loc =
table->current_cursor_loc;
479 if (gnc_table_current_cursor_changed (
table, TRUE) &&
482 cursor_buffer = gnc_cursor_buffer_new();
483 gnc_table_save_current_cursor (
table, cursor_buffer);
486 cursor_buffer = NULL;
490 gnc_table_control_allow_move (
table->control, FALSE);
494 VirtualLocation virt_loc;
496 gnc_virtual_location_init (&virt_loc);
501 vcell_loc.virt_row = 0;
502 vcell_loc.virt_col = 0;
505 vcell_loc.virt_row++;
509 if (use_autoreadonly)
517 if (info->first_pass)
527 cell = (
NumCell*) gnc_table_layout_get_cell (
table->layout, NUM_CELL);
528 gnc_num_cell_set_last_num (cell, last_num);
534 gnc_split_register_load_xfer_cells (reg, default_account);
535 gnc_split_register_load_doclink_cells (reg);
536 gnc_split_register_load_recn_cells (reg);
537 gnc_split_register_load_type_cells (reg);
540 if (info->separator_changed)
541 change_account_separator (info,
table, reg);
543 table->model->dividing_row_upper = -1;
544 table->model->dividing_row = -1;
545 table->model->dividing_row_lower = -1;
549 if (pending_trans != NULL)
553 Split* pending_split = (Split*)node->data;
554 if (!xaccTransStillHasSplit (pending_trans, pending_split))
continue;
555 if (g_list_find (slist, pending_split) != NULL)
558 if (g_list_find_custom (slist, pending_trans,
559 _find_split_with_parent_txn) != NULL)
565 slist = g_list_copy (slist);
568 slist = g_list_append (slist, pending_split);
573 trans_table = g_hash_table_new (g_direct_hash, g_direct_equal);
576 for (node = slist; node; node = node->next)
581 if (!xaccTransStillHasSplit (trans, split))
584 if (pending_trans == trans)
585 found_pending = TRUE;
596 if (trans == blank_trans)
602 if (g_hash_table_lookup (trans_table, trans))
605 g_hash_table_insert (trans_table, trans, trans);
608 if (info->show_present_divider &&
610 !found_divider_upper)
615 table->model->dividing_row_upper = vcell_loc.virt_row;
616 found_divider_upper = TRUE;
620 need_divider_upper = TRUE;
624 if (info->show_present_divider && !found_divider &&
628 table->model->dividing_row = vcell_loc.virt_row;
629 found_divider = TRUE;
631 if (future_after_blank)
633 if (blank_trans == find_trans)
634 new_trans_row = vcell_loc.virt_row;
636 if (blank_split == find_trans_split)
637 new_trans_split_row = vcell_loc.virt_row;
640 if (info->first_pass)
642 save_loc.vcell_loc = vcell_loc;
643 save_loc.phys_row_offset = 0;
644 save_loc.phys_col_offset = 0;
648 table->model->blank_trans_row = vcell_loc.virt_row;
650 gnc_split_register_add_transaction (reg,
651 blank_trans, blank_split,
652 lead_cursor, split_cursor,
653 multi_line, start_primary_color,
654 info->blank_split_edited,
655 find_trans, find_split,
656 find_class, &new_split_row,
659 table->model->dividing_row_lower = vcell_loc.virt_row;
661 start_primary_color = !start_primary_color;
663 added_blank_trans = TRUE;
669 if (info->first_pass)
670 add_quickfill_completions (reg->table->layout, trans, split, has_last_num);
672 if (trans == find_trans)
673 new_trans_row = vcell_loc.virt_row;
675 if (split == find_trans_split)
676 new_trans_split_row = vcell_loc.virt_row;
678 gnc_split_register_add_transaction (reg, trans, split,
679 lead_cursor, split_cursor,
680 multi_line, start_primary_color,
682 find_trans, find_split, find_class,
683 &new_split_row, &vcell_loc);
686 start_primary_color = !start_primary_color;
690 g_hash_table_destroy (trans_table);
693 if (pending_trans == blank_trans)
694 found_pending = TRUE;
697 if (info->show_present_divider &&
699 !found_divider_upper && need_divider_upper)
701 table->model->dividing_row_upper = vcell_loc.virt_row;
711 else if (pending_trans)
712 g_assert_not_reached();
714 pending_trans = NULL;
717 if (!added_blank_trans) {
718 if (blank_trans == find_trans)
719 new_trans_row = vcell_loc.virt_row;
721 if (blank_split == find_trans_split)
722 new_trans_split_row = vcell_loc.virt_row;
725 if (info->first_pass)
727 save_loc.vcell_loc = vcell_loc;
728 save_loc.phys_row_offset = 0;
729 save_loc.phys_col_offset = 0;
733 table->model->blank_trans_row = vcell_loc.virt_row;
735 gnc_split_register_add_transaction (reg, blank_trans, blank_split,
736 lead_cursor, split_cursor,
737 multi_line, start_primary_color,
738 info->blank_split_edited,
739 find_trans, find_split,
740 find_class, &new_split_row,
743 if (future_after_blank)
745 table->model->dividing_row_lower = vcell_loc.virt_row;
750 if (info->first_pass)
753 new_trans_split_row = -1;
763 VirtualLocation trans_split_loc;
765 if (new_split_row > 0)
766 save_loc.vcell_loc.virt_row = new_split_row;
767 else if (new_trans_split_row > 0)
768 save_loc.vcell_loc.virt_row = new_trans_split_row;
769 else if (new_trans_row > 0)
770 save_loc.vcell_loc.virt_row = new_trans_row;
772 trans_split_loc = save_loc;
774 gnc_split_register_get_trans_split (reg, save_loc.vcell_loc,
775 &trans_split_loc.vcell_loc);
777 if (dynamic || multi_line || info->trans_expanded)
780 table, trans_split_loc.vcell_loc,
781 gnc_split_register_get_active_cursor (reg));
785 info->trans_expanded = (reg->style == REG_STYLE_LEDGER);
789 save_loc = trans_split_loc;
790 info->trans_expanded = FALSE;
796 new_split_row = save_loc.vcell_loc.virt_row;
799 gnc_table_restore_current_cursor (
table, cursor_buffer);
802 gnc_cursor_buffer_destroy (cursor_buffer);
803 cursor_buffer = NULL;
805 update_info (info, reg);
807 gnc_split_register_set_cell_fractions (
812 gnc_split_register_show_trans (reg,
table->current_cursor_loc.vcell_loc);
815 gnc_table_control_allow_move (
table->control, TRUE);
825 #define QKEY "split_reg_shared_quickfill" 828 skip_cb (
Account* account, gpointer x)
838 gnc_split_register_load_xfer_cells (SplitRegister* reg,
Account* base_account)
848 root = gnc_get_current_root_account();
853 store = gnc_get_shared_account_name_list_store (root, QKEY, skip_cb, NULL);
856 gnc_table_layout_get_cell (reg->table->layout, XFRM_CELL);
858 gnc_combo_cell_use_list_store_cache (cell, store);
861 gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL);
863 gnc_combo_cell_use_list_store_cache (cell, store);
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_recn_cell_set_valid_flags(RecnCell *cell, const char *flags, char default_flag)
note that chars is copied into the RecnCell directly, but remains the "property" of the caller...
The RecnCell object implements a cell handler that will cycle through a series of single-character va...
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
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))...
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
void gnc_split_register_load(SplitRegister *reg, GList *slist, Account *default_account)
Populates the rows of a register.
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. ...
utility functions for the GnuCash UI
The QuickFillCell implements a text cell with quick-fill capabilities.
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...
#define DEBUG(format, args...)
Print a debugging message.
Create an account-name quick-fill.
void gnc_table_move_cursor_gui(Table *table, VirtualLocation new_virt_loc)
will move the cursor and its GUI to the indicated location.
gboolean gnc_table_find_close_valid_cell(Table *table, VirtualLocation *virt_loc, gboolean exact_pointer)
Find a close valid cell.
void gnc_table_set_size(Table *table, int virt_rows, int virt_cols)
The gnc_table_set_size() method will resize the table to the indicated dimensions.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
The Doclinkcell object implements a cell handler that will cycle through a series of single-character...
#define ENTER(format, args...)
Print a function entry debugging message.
void gnc_combo_cell_set_complete_char(ComboCell *cell, gunichar complete_char)
Sets a character used for special completion processing.
QuickFill * gnc_get_shared_account_name_quickfill(Account *root, const char *key, AccountBoolCB cb, gpointer cb_data)
Create/fetch a quickfill of account names.
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
const char * xaccTransGetNotes(const Transaction *trans)
Gets the transaction Notes.
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.
#define xaccAccountGetGUID(X)
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.
Account handling public routines.
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it...
void gnc_doclink_cell_set_valid_flags(Doclinkcell *cell, const char *flags, char default_flag)
note that
CursorClass
Types of cursors.
The PriceCell object implements a cell handler that stores a single double-precision value...
const char * gnc_get_doclink_flag_order(void)
Get a string containing document link flag order.
#define CURSOR_HEADER
Standard Cursor Names.
private declarations for SplitRegister
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
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...
#define xaccSplitGetGUID(X)
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
API for checkbook register display area.
gnc_commodity * gnc_account_get_currency_or_parent(const Account *account)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
Split * xaccMallocSplit(QofBook *book)
Constructor.
Generic api to store and retrieve preferences.
gnc_commodity * gnc_account_or_default_currency(const Account *account, gboolean *currency_from_account_found)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
The NumCell object implements a number handling cell.
void gnc_price_cell_set_print_info(PriceCell *cell, GNCPrintAmountInfo print_info)
set the printing context of the price cell
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
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.
time64 gnc_time64_get_today_end(void)
The gnc_time64_get_today_end() routine returns a time64 value corresponding to the last second of tod...
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
#define LEAVE(format, args...)
Print a function exit debugging message.
void gnc_combo_cell_use_quickfill_cache(ComboCell *cell, QuickFill *shared_qf)
Tell the combocell to use a shared QuickFill object.
const char * gnc_get_doclink_str(char link_flag)
Get a string representing the document link type.
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
const char * gnc_get_doclink_valid_flags(void)
Get a string containing documentation link valid flags.
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
Account * gnc_account_get_root(Account *acc)
This routine returns the root account of the account tree that the specified account belongs to...
API for Transactions and Splits (journal entries)
Split * gnc_split_register_get_current_split(SplitRegister *reg)
Returns the split at which the cursor is currently located.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.