GnuCash c935c2f+
Loading...
Searching...
No Matches
Files | Data Structures | Macros | Typedefs | Enumerations | Functions

GnuCash-specific ledger and journal displays based on RegisterCore. More...

Files

file  split-register-control.h
 TableControl specialized for the SplitRegister.
 
file  split-register-layout.h
 Create the actual register visual layout.
 
file  split-register-model-save.h
 Save handlers for the SplitRegister Model and Template SplitRegister model.
 
file  split-register-model.h
 TableModels specialized for SplitRegister and template SplitRegister.
 
file  split-register-p.h
 private declarations for SplitRegister
 
file  split-register.h
 API for checkbook register display area.
 

Data Structures

struct  SRInfo
 
struct  SplitRegister
 The type, style and table for the register. More...
 

Macros

#define SPLIT_TRANS_STR   _("-- Split Transaction --")
 
#define STOCK_SPLIT_STR   _("-- Stock Split --")
 
#define ACTION_BUY_STR   _("Buy")
 
#define ACTION_SELL_STR   _("Sell")
 

Typedefs

typedef GtkWidget *(* SRGetParentCallback) (gpointer user_data)
 Callback function type.
 

Enumerations

enum  RateReset_t { RATE_RESET_NOT_REQD = 0 , RATE_RESET_REQD = 1 , RATE_RESET_DONE = 2 }
 
enum  SplitRegisterType {
  BANK_REGISTER , CASH_REGISTER , ASSET_REGISTER , CREDIT_REGISTER ,
  LIABILITY_REGISTER , INCOME_REGISTER , EXPENSE_REGISTER , EQUITY_REGISTER ,
  STOCK_REGISTER , CURRENCY_REGISTER , RECEIVABLE_REGISTER , PAYABLE_REGISTER ,
  TRADING_REGISTER , NUM_SINGLE_REGISTER_TYPES , GENERAL_JOURNAL = NUM_SINGLE_REGISTER_TYPES , INCOME_LEDGER ,
  PORTFOLIO_LEDGER , SEARCH_LEDGER , NUM_REGISTER_TYPES
}
 Register types. More...
 
enum  SplitRegisterTypeGroup {
  REG_TYPE_GROUP_UNKNOWN , REG_TYPE_GROUP_CURRENCY , REG_TYPE_GROUP_APAR , REG_TYPE_GROUP_STOCK ,
  REG_TYPE_GROUP_JOURNAL , REG_TYPE_GROUP_PORTFOLIO
}
 Register group types. More...
 
enum  SplitRegisterStyle { REG_STYLE_LEDGER , REG_STYLE_AUTO_LEDGER , REG_STYLE_JOURNAL }
 Register styles. More...
 
enum  CursorClass { CURSOR_CLASS_NONE = -1 , CURSOR_CLASS_SPLIT , CURSOR_CLASS_TRANS , NUM_CURSOR_CLASSES }
 Types of cursors. More...
 

Functions

TableControlgnc_split_register_control_new (void)
 Create a new TableControl specialized for the SplitRegister.
 
TableLayout * gnc_split_register_layout_new (SplitRegister *reg)
 Generate the split register layout.
 
void gnc_split_register_model_add_save_handlers (TableModel *model)
 
void gnc_template_register_model_add_save_handlers (TableModel *model)
 
SRSaveData * gnc_split_register_save_data_new (Transaction *trans, Split *split, gboolean expanded)
 
void gnc_split_register_save_data_destroy (SRSaveData *sd)
 
TableModelgnc_split_register_model_new (void)
 
TableModelgnc_template_register_model_new (void)
 
SRInfo * gnc_split_register_get_info (SplitRegister *reg)
 
GtkWidget * gnc_split_register_get_parent (SplitRegister *reg)
 
Split * gnc_split_register_get_split (SplitRegister *reg, VirtualCellLocation vcell_loc)
 
Accountgnc_split_register_get_default_account (SplitRegister *reg)
 
Transaction * gnc_split_register_get_trans (SplitRegister *reg, VirtualCellLocation vcell_loc)
 
Split * gnc_split_register_get_trans_split (SplitRegister *reg, VirtualCellLocation vcell_loc, VirtualCellLocation *trans_split_loc)
 
gboolean gnc_split_register_find_split (SplitRegister *reg, Transaction *trans, Split *trans_split, Split *split, CursorClass cursor_class, VirtualCellLocation *vcell_loc)
 
void gnc_split_register_show_trans (SplitRegister *reg, VirtualCellLocation start_loc)
 
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.
 
void gnc_split_register_set_cell_fractions (SplitRegister *reg, Split *split)
 
CellBlockgnc_split_register_get_passive_cursor (SplitRegister *reg)
 
CellBlockgnc_split_register_get_active_cursor (SplitRegister *reg)
 
void gnc_split_register_set_last_num (SplitRegister *reg, const char *num)
 
Accountgnc_split_register_get_account_by_name (SplitRegister *reg, BasicCell *cell, const char *name)
 
Accountgnc_split_register_get_account (SplitRegister *reg, const char *cell_name)
 
gboolean gnc_split_register_recn_cell_confirm (char old_flag, gpointer data)
 
gboolean gnc_split_register_check_cell (SplitRegister *reg, const char *cell_name)
 
CursorClass gnc_split_register_cursor_name_to_class (const char *cursor_name)
 
gnc_numeric gnc_split_register_debcred_cell_value (SplitRegister *reg)
 
gboolean gnc_split_reg_has_rate_cell (SplitRegisterType type)
 Determine if we need to perform any conversion on the splits in this transaction, and if so, what conversion we need.
 
gboolean gnc_split_register_split_needs_amount (SplitRegister *reg, Split *split)
 
gboolean gnc_split_register_needs_conv_rate (SplitRegister *reg, Transaction *txn, Account *acc)
 
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_split_register_destroy (SplitRegister *reg)
 Destroys a split register.
 
void gnc_split_register_config (SplitRegister *reg, SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line)
 Sets a split register's type, style or line use.
 
void gnc_split_register_set_reverse_sort (SplitRegister *reg, gboolean reverse_sort)
 Sets a split register's reverse sort order based on register.
 
void gnc_split_register_set_auto_complete (SplitRegister *reg, gboolean do_auto_complete)
 Sets whether a register uses auto-completion.
 
void gnc_split_register_set_read_only (SplitRegister *reg, gboolean read_only)
 Sets whether a register window is "read only".
 
SplitRegisterTypeGroup gnc_split_register_get_register_group (SplitRegister *reg)
 Group registers for common layouts.
 
void gnc_split_register_set_template_account (SplitRegister *reg, Account *template_account)
 Set the template account for use in a template register.
 
void gnc_split_register_set_data (SplitRegister *reg, gpointer user_data, SRGetParentCallback get_parent)
 Sets the user data and callback hooks for the register.
 
CursorClass gnc_split_register_get_current_cursor_class (SplitRegister *reg)
 Returns the class of a register's current cursor.
 
CursorClass gnc_split_register_get_cursor_class (SplitRegister *reg, VirtualCellLocation vcell_loc)
 Returns the class of the cursor at the given virtual cell location.
 
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 of its splits.
 
Split * gnc_split_register_get_current_trans_split (SplitRegister *reg, VirtualCellLocation *vcell_loc)
 Gets the anchoring split of the transaction at the current cursor location, which may be on the transaction itself or on any of its splits.
 
Split * gnc_split_register_get_current_split (SplitRegister *reg)
 Returns the split at which the cursor is currently located.
 
Split * gnc_split_register_get_blank_split (SplitRegister *reg)
 Gets the blank split for a register.
 
gboolean gnc_split_register_get_split_virt_loc (SplitRegister *reg, Split *split, VirtualCellLocation *vcell_loc)
 Searches the split register for a given split.
 
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 non-zero) or debit cell.
 
Split * gnc_split_register_duplicate_current (SplitRegister *reg)
 Duplicates either the current transaction or the current split depending on the register mode and cursor position.
 
gboolean gnc_split_register_has_copied_item (void)
 Return TRUE if copied_item holds a transaction or split.
 
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.
 
void gnc_split_register_cut_current (SplitRegister *reg)
 Equivalent to copying the current entity and the deleting it with the appropriate delete method.
 
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 have the same type.
 
void gnc_split_register_delete_current_split (SplitRegister *reg)
 Deletes the split associated with the current cursor, if both are non-NULL.
 
void gnc_split_register_delete_current_trans (SplitRegister *reg)
 Deletes the transaction associated with the current cursor, if both are non-NULL.
 
void gnc_split_register_void_current_trans (SplitRegister *reg, const char *reason)
 Voids the transaction associated with the current cursor, if non-NULL.
 
void gnc_split_register_unvoid_current_trans (SplitRegister *reg)
 Unvoids the transaction associated with the current cursor, if non-NULL.
 
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.
 
void gnc_split_register_empty_current_trans (SplitRegister *reg)
 
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.
 
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, and updates the GUI.
 
void gnc_split_register_load (SplitRegister *reg, GList *slist, GList *pre_filter_slist, Account *default_account)
 Populates the rows of a register.
 
gboolean gnc_split_register_save (SplitRegister *reg, gboolean do_commit)
 Copy the contents of the current cursor to a split.
 
void gnc_split_register_redraw (SplitRegister *reg)
 Causes a redraw of the register window associated with reg.
 
gboolean gnc_split_register_changed (SplitRegister *reg)
 Returns TRUE if the register has changed cells.
 
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, and after.
 
void gnc_split_register_expand_current_trans (SplitRegister *reg, gboolean expand)
 Expand the current transaction if it is collapsed.
 
void gnc_split_register_collapse_current_trans (SplitRegister *reg)
 Mark the current transaction as collapsed, and do callbacks.
 
gboolean gnc_split_register_current_trans_expanded (SplitRegister *reg)
 Return TRUE if current trans is expanded and style is REG_STYLE_LEDGER.
 
const char * gnc_split_register_get_debit_string (SplitRegister *reg)
 Return the debit string used in the register.
 
const char * gnc_split_register_get_credit_string (SplitRegister *reg)
 Return the credit string used in the register.
 
gboolean gnc_split_register_is_blank_split (SplitRegister *reg, Split *split)
 Return TRUE if split is the blank_split.
 
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)
 Pop up the exchange-rate dialog, maybe, for the current split.
 
gboolean gnc_split_register_begin_edit_or_warn (SRInfo *info, Transaction *trans)
 

Cell Names

T* cells are transaction summary cells

#define ACTN_CELL   "action"
 
#define DOCLINK_CELL   "doclink"
 
#define BALN_CELL   "balance"
 
#define CRED_CELL   "credit"
 
#define DATE_CELL   "date"
 
#define DDUE_CELL   "date-due"
 
#define DEBT_CELL   "debit"
 
#define DESC_CELL   "description"
 
#define FCRED_CELL   "credit-formula"
 
#define FDEBT_CELL   "debit-formula"
 
#define MEMO_CELL   "memo"
 
#define MXFRM_CELL   "transfer"
 
#define NOTES_CELL   "notes"
 
#define NUM_CELL   "num"
 
#define TNUM_CELL   "trans-num"
 
#define PRIC_CELL   "price"
 
#define RATE_CELL   "exchrate"
 
#define RECN_CELL   "reconcile"
 
#define SHRS_CELL   "shares"
 
#define TBALN_CELL   "trans-balance"
 
#define TCRED_CELL   "trans-credit"
 
#define TDEBT_CELL   "trans-debit"
 
#define TSHRS_CELL   "trans-shares"
 
#define TYPE_CELL   "split-type"
 
#define XFRM_CELL   "account"
 
#define VNOTES_CELL   "void-notes"
 
#define RBALN_CELL   "reg-run-balance"
 

Cursor Names

Cursors ending in 'NUM_ACTN' use the split action field for the NUM_CELL rather than the transaction number field which is shown in the TNUM_CELL

#define CURSOR_SINGLE_LEDGER   "cursor-single-ledger"
 
#define CURSOR_DOUBLE_LEDGER   "cursor-double-ledger"
 
#define CURSOR_DOUBLE_LEDGER_NUM_ACTN   "cursor-double-ledger-num-actn"
 
#define CURSOR_SINGLE_JOURNAL   "cursor-single-journal"
 
#define CURSOR_DOUBLE_JOURNAL   "cursor-double-journal"
 
#define CURSOR_DOUBLE_JOURNAL_NUM_ACTN   "cursor-double-journal-num-actn"
 
#define CURSOR_SPLIT   "cursor-split"
 

Detailed Description

GnuCash-specific ledger and journal displays based on RegisterCore.

The split register is a spreadsheet-like area that looks like a checkbook register. It displays transactions and allows the user to edit them in-place. The register does not contain any of the other window decorations that one might want to have for a free standing window (e.g. menubars, * toolbars, etc.)

The layout of the register is configurable. There's a broad variety of cell types to choose from: date cells that know how to parse dates, price cells that know how to parse prices, etc. These cells can be laid out in any column; even a multi-row layout is supported. The name "split register" is derived from the fact that this register can display multiple rows of transaction splits underneath a transaction title/summary row.

An area for entering new transactions is provided at the bottom of the register.

All user input to the register is handled by the 'cursor', which is mapped onto one of the displayed rows.

Design Notes.
Some notes about the "blank split":
Q: What is the "blank split"?
A: A new, empty split appended to the bottom of the ledger window. The blank split provides an area where the user can type in new split/transaction info. The "blank split" is treated in a special way for a number of reasons:
  • it must always appear as the bottom-most split in the Ledger window,
  • it must be committed if the user edits it, and a new blank split must be created.
  • it must be deleted when the ledger window is closed.
To implement the above, the register "user_data" is used to store an SRInfo structure containing the blank split.
Some notes on Commit/Rollback:
There's an engine component and a gui component to the commit/rollback scheme. On the engine side, one must always call BeginEdit() before starting to edit a transaction. When you think you're done, you can call CommitEdit() to commit the changes, or RollbackEdit() to go back to how things were before you started the edit. Think of it as a one-shot mega-undo for that transaction.
Note that the query engine uses the original values, not the currently edited values, when performing a sort. This allows your to e.g. edit the date without having the transaction hop around in the gui while you do it.
On the gui side, commits are now performed on a per-transaction basis, rather than a per-split (per-journal-entry) basis. This means that if you have a transaction with a lot of splits in it, you can edit them all you want without having to commit one before moving to the next.
Similarly, the "cancel" button will now undo the changes to all of the lines in the transaction display, not just to one line (one split) at a time.
Some notes on Reloads & Redraws:
Reloads and redraws tend to be heavyweight. We try to use change flags as much as possible in this code, but imagine the following scenario:
Create two bank accounts. Transfer money from one to the other. Open two registers, showing each account. Change the amount in one window. Note that the other window also redraws, to show the new correct amount.
Since you changed an amount value, potentially all displayed balances change in both register windows (as well as the ledger balance in the main window). Three or more windows may be involved if you have e.g. windows open for bank, employer, taxes and your entering a paycheck (or correcting a typo in an old paycheck). Changing a date might even cause all entries in all three windows to be re-ordered.
The only thing I can think of is a bit stored with every table entry, stating 'this entry has changed since lst time, redraw it'. But that still doesn't avoid the overhead of reloading the table from the engine.

The Register itself is independent of GnuCash, and is designed so that it can be used with other applications. The Ledger is an adaptation of the Register for use by GnuCash. The Ledger sets up an explicit visual layout, putting certain types of cells in specific locations (e.g. date on left, summary in middle, value at right), and hooks up these cells to the various GnuCash financial objects.

This code is also theoretically independent of the actual GUI toolkit/widget-set (it once worked with both Motif and Gnome). The actual GUI-toolkit specific code is supposed to be in a GUI portability layer. Over the years, some gnome-isms may have snuck in; these should also be cleaned up.

Macro Definition Documentation

◆ ACTION_BUY_STR

#define ACTION_BUY_STR   _("Buy")

Definition at line 42 of file split-register-p.h.

◆ ACTION_SELL_STR

#define ACTION_SELL_STR   _("Sell")

Definition at line 43 of file split-register-p.h.

◆ ACTN_CELL

#define ACTN_CELL   "action"

Definition at line 195 of file split-register.h.

◆ BALN_CELL

#define BALN_CELL   "balance"

Definition at line 197 of file split-register.h.

◆ CRED_CELL

#define CRED_CELL   "credit"

Definition at line 198 of file split-register.h.

◆ CURSOR_DOUBLE_JOURNAL

#define CURSOR_DOUBLE_JOURNAL   "cursor-double-journal"

Definition at line 233 of file split-register.h.

◆ CURSOR_DOUBLE_JOURNAL_NUM_ACTN

#define CURSOR_DOUBLE_JOURNAL_NUM_ACTN   "cursor-double-journal-num-actn"

Definition at line 234 of file split-register.h.

◆ CURSOR_DOUBLE_LEDGER

#define CURSOR_DOUBLE_LEDGER   "cursor-double-ledger"

Definition at line 230 of file split-register.h.

◆ CURSOR_DOUBLE_LEDGER_NUM_ACTN

#define CURSOR_DOUBLE_LEDGER_NUM_ACTN   "cursor-double-ledger-num-actn"

Definition at line 231 of file split-register.h.

◆ CURSOR_SINGLE_JOURNAL

#define CURSOR_SINGLE_JOURNAL   "cursor-single-journal"

Definition at line 232 of file split-register.h.

◆ CURSOR_SINGLE_LEDGER

#define CURSOR_SINGLE_LEDGER   "cursor-single-ledger"

Definition at line 229 of file split-register.h.

◆ CURSOR_SPLIT

#define CURSOR_SPLIT   "cursor-split"

Definition at line 235 of file split-register.h.

◆ DATE_CELL

#define DATE_CELL   "date"

Definition at line 199 of file split-register.h.

◆ DDUE_CELL

#define DDUE_CELL   "date-due"

Definition at line 200 of file split-register.h.

◆ DEBT_CELL

#define DEBT_CELL   "debit"

Definition at line 201 of file split-register.h.

◆ DESC_CELL

#define DESC_CELL   "description"

Definition at line 202 of file split-register.h.

◆ DOCLINK_CELL

#define DOCLINK_CELL   "doclink"

Definition at line 196 of file split-register.h.

◆ FCRED_CELL

#define FCRED_CELL   "credit-formula"

Definition at line 203 of file split-register.h.

◆ FDEBT_CELL

#define FDEBT_CELL   "debit-formula"

Definition at line 204 of file split-register.h.

◆ MEMO_CELL

#define MEMO_CELL   "memo"

Definition at line 205 of file split-register.h.

◆ MXFRM_CELL

#define MXFRM_CELL   "transfer"

Definition at line 206 of file split-register.h.

◆ NOTES_CELL

#define NOTES_CELL   "notes"

Definition at line 207 of file split-register.h.

◆ NUM_CELL

#define NUM_CELL   "num"

Definition at line 208 of file split-register.h.

◆ PRIC_CELL

#define PRIC_CELL   "price"

Definition at line 210 of file split-register.h.

◆ RATE_CELL

#define RATE_CELL   "exchrate"

Definition at line 211 of file split-register.h.

◆ RBALN_CELL

#define RBALN_CELL   "reg-run-balance"

Definition at line 221 of file split-register.h.

◆ RECN_CELL

#define RECN_CELL   "reconcile"

Definition at line 212 of file split-register.h.

◆ SHRS_CELL

#define SHRS_CELL   "shares"

Definition at line 213 of file split-register.h.

◆ SPLIT_TRANS_STR

#define SPLIT_TRANS_STR   _("-- Split Transaction --")

Definition at line 39 of file split-register-p.h.

◆ STOCK_SPLIT_STR

#define STOCK_SPLIT_STR   _("-- Stock Split --")

Definition at line 40 of file split-register-p.h.

◆ TBALN_CELL

#define TBALN_CELL   "trans-balance"

Definition at line 214 of file split-register.h.

◆ TCRED_CELL

#define TCRED_CELL   "trans-credit"

Definition at line 215 of file split-register.h.

◆ TDEBT_CELL

#define TDEBT_CELL   "trans-debit"

Definition at line 216 of file split-register.h.

◆ TNUM_CELL

#define TNUM_CELL   "trans-num"

Definition at line 209 of file split-register.h.

◆ TSHRS_CELL

#define TSHRS_CELL   "trans-shares"

Definition at line 217 of file split-register.h.

◆ TYPE_CELL

#define TYPE_CELL   "split-type"

Definition at line 218 of file split-register.h.

◆ VNOTES_CELL

#define VNOTES_CELL   "void-notes"

Definition at line 220 of file split-register.h.

◆ XFRM_CELL

#define XFRM_CELL   "account"

Definition at line 219 of file split-register.h.

Typedef Documentation

◆ SRGetParentCallback

typedef GtkWidget *(* SRGetParentCallback) (gpointer user_data)

Callback function type.

Definition at line 280 of file split-register.h.

Enumeration Type Documentation

◆ CursorClass

Types of cursors.

Definition at line 240 of file split-register.h.

241{
242 CURSOR_CLASS_NONE = -1,
243 CURSOR_CLASS_SPLIT,
244 CURSOR_CLASS_TRANS,
245 NUM_CURSOR_CLASSES
CursorClass
Types of cursors.

◆ RateReset_t

enum RateReset_t

Definition at line 45 of file split-register-p.h.

45 {
46 RATE_RESET_NOT_REQD = 0,
47 RATE_RESET_REQD = 1,
48 RATE_RESET_DONE = 2
49} RateReset_t;

◆ SplitRegisterStyle

Register styles.

Definition at line 184 of file split-register.h.

185{
186 REG_STYLE_LEDGER,
187 REG_STYLE_AUTO_LEDGER,
188 REG_STYLE_JOURNAL
SplitRegisterStyle
Register styles.

◆ SplitRegisterType

Register types.

"registers" are single-account display windows. "ledgers" are multiple-account display windows

Definition at line 145 of file split-register.h.

146{
147 BANK_REGISTER,
148 CASH_REGISTER,
149 ASSET_REGISTER,
150 CREDIT_REGISTER,
151 LIABILITY_REGISTER,
152 INCOME_REGISTER,
153 EXPENSE_REGISTER,
154 EQUITY_REGISTER,
155 STOCK_REGISTER,
156 CURRENCY_REGISTER,
157 RECEIVABLE_REGISTER,
158 PAYABLE_REGISTER,
159 TRADING_REGISTER,
160 NUM_SINGLE_REGISTER_TYPES,
161
162 GENERAL_JOURNAL = NUM_SINGLE_REGISTER_TYPES,
163 INCOME_LEDGER,
164 PORTFOLIO_LEDGER,
165 SEARCH_LEDGER,
166
167 NUM_REGISTER_TYPES
SplitRegisterType
Register types.

◆ SplitRegisterTypeGroup

Register group types.

used for grouping registers that have the same layout

Definition at line 173 of file split-register.h.

174{
175 REG_TYPE_GROUP_UNKNOWN,
176 REG_TYPE_GROUP_CURRENCY,
177 REG_TYPE_GROUP_APAR,
178 REG_TYPE_GROUP_STOCK,
179 REG_TYPE_GROUP_JOURNAL,
180 REG_TYPE_GROUP_PORTFOLIO,
SplitRegisterTypeGroup
Register group types.

Function Documentation

◆ gnc_split_reg_has_rate_cell()

gboolean gnc_split_reg_has_rate_cell ( SplitRegisterType  type)

Determine if we need to perform any conversion on the splits in this transaction, and if so, what conversion we need.

Definition at line 1682 of file split-register-model.c.

1683{
1684 switch (type)
1685 {
1686 case BANK_REGISTER:
1687 case CASH_REGISTER:
1688 case ASSET_REGISTER:
1689 case CREDIT_REGISTER:
1690 case LIABILITY_REGISTER:
1691 case INCOME_REGISTER:
1692 case EXPENSE_REGISTER:
1693 case EQUITY_REGISTER:
1694 case TRADING_REGISTER:
1695 case GENERAL_JOURNAL:
1696 case INCOME_LEDGER:
1697 case SEARCH_LEDGER:
1698 case RECEIVABLE_REGISTER:
1699 case PAYABLE_REGISTER:
1700 return TRUE;
1701
1702 case STOCK_REGISTER:
1703 case CURRENCY_REGISTER:
1704 case PORTFOLIO_LEDGER:
1705 default:
1706 return FALSE;
1707 }
1708}

◆ gnc_split_register_begin_edit_or_warn()

gboolean gnc_split_register_begin_edit_or_warn ( SRInfo *  info,
Transaction *  trans 
)

Definition at line 201 of file split-register.c.

202{
203 ENTER ("info=%p, trans=%p", info, trans);
204
205 if (!xaccTransIsOpen (trans))
206 {
207 xaccTransBeginEdit (trans);
208 /* This is now the pending transaction */
209 info->pending_trans_guid = *xaccTransGetGUID (trans);
210 LEAVE ("opened and marked pending");
211 return FALSE;
212 }
213 else
214 {
215 Split* blank_split = xaccSplitLookup (&info->blank_split_guid,
216 gnc_get_current_book ());
217 Transaction* blank_trans = xaccSplitGetParent (blank_split);
218
219 if (trans == blank_trans)
220 {
221 /* This is a brand-new transaction. It is already
222 * open, so just mark it as pending. */
223 info->pending_trans_guid = *xaccTransGetGUID (trans);
224 LEAVE ("already open, now pending.");
225 return FALSE;
226 }
227 else
228 {
229 GtkWindow* parent = NULL;
230 if (info->get_parent)
231 parent = GTK_WINDOW (info->get_parent (info->user_data));
232 gnc_error_dialog (parent, "%s",
233 _ ("This transaction is already being edited in another register. Please finish editing it there first."));
234 LEAVE ("already editing");
235 return TRUE;
236 }
237 }
238 LEAVE (" ");
239 return FALSE; /* to satisfy static code analysis */
240}
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing.
#define xaccTransGetGUID(X)
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
The xaccSplitLookup() subroutine will return the split associated with the given id,...
Definition Split.cpp:1091

◆ gnc_split_register_cancel_cursor_split_changes()

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.

The change flags are cleared.

Definition at line 1487 of file split-register.c.

1488{
1489 VirtualLocation virt_loc;
1490
1491 if (reg == NULL)
1492 return;
1493
1494 virt_loc = reg->table->current_cursor_loc;
1495
1496 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1497 return;
1498
1499 /* We're just cancelling the current split here, not the transaction.
1500 * When cancelling edits, reload the cursor from the transaction. */
1501 gnc_table_clear_current_cursor_changes (reg->table);
1502
1503 if (gnc_table_find_close_valid_cell (reg->table, &virt_loc, FALSE))
1504 gnc_table_move_cursor_gui (reg->table, virt_loc);
1505
1506 gnc_table_refresh_gui (reg->table, TRUE);
1507}
void gnc_table_refresh_gui(Table *table, gboolean do_scroll)
Refresh the whole GUI from the table.
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.

◆ gnc_split_register_cancel_cursor_trans_changes()

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, and updates the GUI.

The change flags are cleared.

Definition at line 1510 of file split-register.c.

1511{
1512 SRInfo* info = gnc_split_register_get_info (reg);
1513 Transaction* pending_trans, *blank_trans;
1514 gboolean refresh_all = FALSE;
1515
1516 pending_trans = xaccTransLookup (&info->pending_trans_guid,
1517 gnc_get_current_book ());
1518
1520
1521 if (pending_trans == blank_trans)
1522 refresh_all = TRUE;
1523
1524 /* Get the currently open transaction, rollback the edits on it, and
1525 * then repaint everything. To repaint everything, make a note of
1526 * all of the accounts that will be affected by this rollback. */
1527 if (!xaccTransIsOpen (pending_trans))
1528 {
1530 return;
1531 }
1532
1533 if (!pending_trans)
1534 return;
1535
1536 gnc_suspend_gui_refresh ();
1537
1538 xaccTransRollbackEdit (pending_trans);
1539
1540 info->pending_trans_guid = *guid_null ();
1541
1542 gnc_resume_gui_refresh ();
1543
1544 if (refresh_all)
1545 gnc_gui_refresh_all (); // force a refresh of all registers
1546 else
1548}
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
The xaccTransLookup() subroutine will return the transaction associated with the given id,...
void xaccTransRollbackEdit(Transaction *trans)
The xaccTransRollbackEdit() routine rejects all edits made, and sets the transaction back to where it...
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
Definition guid.cpp:165
void gnc_split_register_redraw(SplitRegister *reg)
Causes a redraw of the register window associated with reg.
void gnc_split_register_cancel_cursor_split_changes(SplitRegister *reg)
Cancels any changes made to the current cursor, reloads the cursor from the engine,...
Split * gnc_split_register_get_blank_split(SplitRegister *reg)
Gets the blank split for a register.

◆ gnc_split_register_change_blank_split_ref()

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.

This is used when deleting a split after an autocomplete as the blank_split reference will be pointing to one of the splits so it does not cancel the whole transaction

Definition at line 1183 of file split-register.c.

1184{
1185 SRInfo* info = gnc_split_register_get_info (reg);
1186 Split* current_blank_split = xaccSplitLookup (&info->blank_split_guid,
1187 gnc_get_current_book ());
1188 Split* pref_split = NULL; // has the same account as incoming split
1189 Split* other_split = NULL; // other split
1190 Account* blank_split_account = xaccSplitGetAccount (current_blank_split);
1191 Transaction* trans = xaccSplitGetParent (split);
1192
1193 // loop through splitlist looking for splits other than the blank_split
1194 for (GList *n = xaccTransGetSplitList (trans); n; n = n->next)
1195 {
1196 Split *s = n->data;
1197 if (s != current_blank_split && xaccTransStillHasSplit (trans, s))
1198 {
1199 if (blank_split_account == xaccSplitGetAccount (s))
1200 pref_split = s; // prefer same account
1201 else
1202 other_split = s; // any other split
1203 }
1204 }
1205 // now change the saved blank split reference
1206 if (pref_split != NULL)
1207 info->blank_split_guid = *xaccSplitGetGUID (pref_split);
1208 else if (other_split != NULL)
1209 info->blank_split_guid = *xaccSplitGetGUID (other_split);
1210 else
1211 info->blank_split_guid = *guid_null();
1212}
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
#define xaccSplitGetGUID(X)
Definition Split.h:579
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
STRUCTS.

◆ gnc_split_register_changed()

gboolean gnc_split_register_changed ( SplitRegister *  reg)

Returns TRUE if the register has changed cells.

Definition at line 2545 of file split-register.c.

2546{
2547 SRInfo* info = gnc_split_register_get_info (reg);
2548 Transaction* pending_trans;
2549
2550 ENTER ("reg=%p", reg);
2551
2552 if (reg == NULL)
2553 {
2554 LEAVE ("no register");
2555 return FALSE;
2556 }
2557
2558 if (gnc_table_current_cursor_changed (reg->table, FALSE))
2559 {
2560 LEAVE ("cursor changed");
2561 return TRUE;
2562 }
2563
2564 pending_trans = xaccTransLookup (&info->pending_trans_guid,
2565 gnc_get_current_book ());
2566 if (xaccTransIsOpen (pending_trans))
2567 {
2568 LEAVE ("open and pending txn");
2569 return TRUE;
2570 }
2571
2572 LEAVE ("register unchanged");
2573 return FALSE;
2574}

◆ gnc_split_register_check_cell()

gboolean gnc_split_register_check_cell ( SplitRegister *  reg,
const char *  cell_name 
)

Definition at line 1211 of file split-register-control.cpp.

1212{
1213 ENTER("reg=%p, cell_name=%s", reg, cell_name ? cell_name : "NULL");
1214
1215 /* See if we are leaving an account field. */
1216 if (!gnc_split_register_check_account (reg, cell_name))
1217 {
1218 LEAVE("account check failed");
1219 return FALSE;
1220 }
1221
1222 /* See if we are leaving a debit or credit cell */
1223 if (!gnc_split_register_check_debcred (reg, cell_name))
1224 {
1225 LEAVE("debit/credit check failed");
1226 return FALSE;
1227 }
1228
1229 /* See if we are leaving an action field */
1230 if ((reg->type == STOCK_REGISTER) ||
1231 (reg->type == PORTFOLIO_LEDGER) ||
1232 (reg->type == CURRENCY_REGISTER))
1233 {
1234 gnc_split_register_check_stock_action (reg, cell_name);
1235 gnc_split_register_check_stock_shares (reg, cell_name);
1236 }
1237
1238 LEAVE(" ");
1239 return TRUE;
1240}

◆ gnc_split_register_config()

void gnc_split_register_config ( SplitRegister *  reg,
SplitRegisterType  type,
SplitRegisterStyle  style,
gboolean  use_double_line 
)

Sets a split register's type, style or line use.

Parameters
rega ::SplitRegister
typea SplitRegisterType to use for the register
stylea SplitRegisterStyle to use for the register
use_double_lineTRUE to show two lines for transactions, FALSE for one

Definition at line 2988 of file split-register.c.

2992{
2993 if (!reg) return;
2994
2995 /* If shrinking the transaction split, put the cursor on the first row of the trans */
2996 if (reg->use_double_line && !use_double_line)
2997 {
2998 VirtualLocation virt_loc = reg->table->current_cursor_loc;
2999 if (gnc_table_find_close_valid_cell (reg->table, &virt_loc, FALSE))
3000 {
3001 if (virt_loc.phys_row_offset)
3002 {
3003 gnc_table_move_vertical_position (reg->table, &virt_loc,
3004 -virt_loc.phys_row_offset);
3005 gnc_table_move_cursor_gui (reg->table, virt_loc);
3006 }
3007 }
3008 else
3009 {
3010 /* WTF? Go to a known safe location. */
3011 virt_loc.vcell_loc.virt_row = 1;
3012 virt_loc.vcell_loc.virt_col = 0;
3013 virt_loc.phys_row_offset = 0;
3014 virt_loc.phys_col_offset = 0;
3015 gnc_table_move_cursor_gui (reg->table, virt_loc);
3016 }
3017 }
3018
3019 reg->type = newtype;
3020
3021 if (reg->type >= NUM_SINGLE_REGISTER_TYPES)
3022 newstyle = REG_STYLE_JOURNAL;
3023
3024 reg->style = newstyle;
3025 reg->use_double_line = use_double_line;
3026
3027 gnc_table_realize_gui (reg->table);
3028}
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.

◆ gnc_split_register_control_new()

TableControl * gnc_split_register_control_new ( void  )

Create a new TableControl specialized for the SplitRegister.

Definition at line 1874 of file split-register-control.cpp.

1875{
1876 TableControl *control = gnc_table_control_new ();
1877
1878 control->move_cursor = gnc_split_register_move_cursor;
1879 control->traverse = gnc_split_register_traverse;
1880
1881 return control;
1882}

◆ gnc_split_register_copy_current()

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.

Definition at line 892 of file split-register.c.

893{
894 gnc_split_register_copy_current_internal (reg, FALSE);
895}

◆ gnc_split_register_current_trans_expanded()

gboolean gnc_split_register_current_trans_expanded ( SplitRegister *  reg)

Return TRUE if current trans is expanded and style is REG_STYLE_LEDGER.

Definition at line 303 of file split-register.c.

304{
305 SRInfo* info = gnc_split_register_get_info (reg);
306
307 if (!reg)
308 return FALSE;
309
310 if (reg->style == REG_STYLE_AUTO_LEDGER ||
311 reg->style == REG_STYLE_JOURNAL)
312 return TRUE;
313
314 return info->trans_expanded;
315}

◆ gnc_split_register_cursor_name_to_class()

CursorClass gnc_split_register_cursor_name_to_class ( const char *  cursor_name)

Definition at line 561 of file split-register-util.c.

562{
563 if (cursor_name == NULL)
564 return CURSOR_CLASS_NONE;
565
566 if (strcmp (cursor_name, CURSOR_SINGLE_LEDGER) == 0 ||
567 strcmp (cursor_name, CURSOR_DOUBLE_LEDGER) == 0 ||
568 strcmp (cursor_name, CURSOR_DOUBLE_LEDGER_NUM_ACTN) == 0 ||
569 strcmp (cursor_name, CURSOR_SINGLE_JOURNAL) == 0 ||
570 strcmp (cursor_name, CURSOR_DOUBLE_JOURNAL) == 0 ||
571 strcmp (cursor_name, CURSOR_DOUBLE_JOURNAL_NUM_ACTN) == 0)
572 return CURSOR_CLASS_TRANS;
573
574 if (strcmp (cursor_name, CURSOR_SPLIT) == 0)
575 return CURSOR_CLASS_SPLIT;
576
577 return CURSOR_CLASS_NONE;
578}

◆ gnc_split_register_cut_current()

void gnc_split_register_cut_current ( SplitRegister *  reg)

Equivalent to copying the current entity and the deleting it with the appropriate delete method.

Definition at line 898 of file split-register.c.

899{
900 SRInfo* info = gnc_split_register_get_info (reg);
901 CursorClass cursor_class;
902 Transaction* trans;
903 Split* blank_split;
904 gboolean changed;
905 Split* split;
906
907 blank_split = xaccSplitLookup (&info->blank_split_guid,
908 gnc_get_current_book ());
911
912 /* This shouldn't happen, but be paranoid. */
913 if (trans == NULL)
914 return;
915
917
918 /* Can't do anything with this. */
919 if (cursor_class == CURSOR_CLASS_NONE)
920 return;
921
922 /* This shouldn't happen, but be paranoid. */
923 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
924 return;
925
926 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
927
928 /* See if we were asked to cut an unchanged blank split. Don't. */
929 if (!changed && ((split == NULL) || (split == blank_split)))
930 return;
931
932 gnc_split_register_copy_current_internal (reg, TRUE);
933
934 if (cursor_class == CURSOR_CLASS_SPLIT)
936 else
938}
Split * gnc_split_register_get_current_split(SplitRegister *reg)
Returns the split at which the cursor is currently located.
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...
void gnc_split_register_delete_current_split(SplitRegister *reg)
Deletes the split associated with the current cursor, if both are non-NULL.
CursorClass gnc_split_register_get_current_cursor_class(SplitRegister *reg)
Returns the class of a register's current cursor.
void gnc_split_register_delete_current_trans(SplitRegister *reg)
Deletes the transaction associated with the current cursor, if both are non-NULL.

◆ gnc_split_register_debcred_cell_value()

gnc_numeric gnc_split_register_debcred_cell_value ( SplitRegister *  reg)

Definition at line 359 of file split-register-model-save.c.

360{
361 PriceCell *cell;
362 gnc_numeric new_amount;
363 gnc_numeric credit;
364 gnc_numeric debit;
365
366 cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
367 CRED_CELL);
368 credit = gnc_price_cell_get_value (cell);
369
370 cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
371 DEBT_CELL);
372 debit = gnc_price_cell_get_value (cell);
373
374 new_amount = gnc_numeric_sub_fixed (debit, credit);
375
376 return new_amount;
377}
gnc_numeric gnc_price_cell_get_value(PriceCell *cell)
return the value of a price cell
Definition pricecell.c:208
The PriceCell object implements a cell handler that stores a single double-precision value,...
Definition pricecell.h:55

◆ gnc_split_register_delete_current_split()

void gnc_split_register_delete_current_split ( SplitRegister *  reg)

Deletes the split associated with the current cursor, if both are non-NULL.

Deleting the blank split just clears cursor values.

Definition at line 1215 of file split-register.c.

1216{
1217 SRInfo* info = gnc_split_register_get_info (reg);
1218 Transaction* pending_trans;
1219 Transaction* trans;
1220 Split* blank_split;
1221 Split* split;
1222
1223 if (!reg) return;
1224
1225 blank_split = xaccSplitLookup (&info->blank_split_guid,
1226 gnc_get_current_book ());
1227
1228 pending_trans = xaccTransLookup (&info->pending_trans_guid,
1229 gnc_get_current_book ());
1230
1231 /* get the current split based on cursor position */
1233 if (split == NULL)
1234 return;
1235
1236 /* If we are deleting the blank split, just cancel. The user is
1237 * allowed to delete the blank split as a method for discarding
1238 * any edits they may have made to it. */
1239 if (split == blank_split)
1240 {
1242 return;
1243 }
1244
1245 gnc_suspend_gui_refresh ();
1246
1247 trans = xaccSplitGetParent (split);
1248
1249 /* Check pending transaction */
1250 if (trans == pending_trans)
1251 {
1252 g_assert (xaccTransIsOpen (trans));
1253 }
1254 else
1255 {
1256 g_assert (!pending_trans);
1257 if (gnc_split_register_begin_edit_or_warn (info, trans))
1258 {
1259 gnc_resume_gui_refresh ();
1260 return;
1261 }
1262 }
1263 xaccSplitDestroy (split);
1264
1265 gnc_resume_gui_refresh ();
1267}
gboolean xaccSplitDestroy(Split *split)
Destructor.
Definition Split.cpp:1506

◆ gnc_split_register_delete_current_trans()

void gnc_split_register_delete_current_trans ( SplitRegister *  reg)

Deletes the transaction associated with the current cursor, if both are non-NULL.

Definition at line 1270 of file split-register.c.

1271{
1272 SRInfo* info = gnc_split_register_get_info (reg);
1273 Transaction* pending_trans;
1274 Transaction* trans;
1275 Split* blank_split;
1276 Split* split;
1277 gboolean was_open;
1278
1279 ENTER ("reg=%p", reg);
1280 if (!reg)
1281 {
1282 LEAVE ("no register");
1283 return;
1284 }
1285
1286 blank_split = xaccSplitLookup (&info->blank_split_guid,
1287 gnc_get_current_book ());
1288 pending_trans = xaccTransLookup (&info->pending_trans_guid,
1289 gnc_get_current_book ());
1290
1291 /* get the current split based on cursor position */
1293 if (split == NULL)
1294 {
1295 LEAVE ("no split");
1296 return;
1297 }
1298
1299 gnc_suspend_gui_refresh ();
1300 trans = xaccSplitGetParent (split);
1301
1302 /* If we just deleted the blank split, clean up. The user is
1303 * allowed to delete the blank split as a method for discarding
1304 * any edits they may have made to it. */
1305 if (split == blank_split)
1306 {
1307 DEBUG ("deleting blank split");
1308 info->blank_split_guid = *guid_null ();
1309 info->auto_complete = FALSE;
1310 }
1311 else
1312 {
1313 info->trans_expanded = FALSE;
1314 }
1315
1316 /* Check pending transaction */
1317 if (trans == pending_trans)
1318 {
1319 DEBUG ("clearing pending trans");
1320 info->pending_trans_guid = *guid_null ();
1321 pending_trans = NULL;
1322 }
1323
1324 was_open = xaccTransIsOpen (trans);
1325 xaccTransDestroy (trans);
1326 if (was_open)
1327 {
1328 DEBUG ("committing");
1329 xaccTransCommitEdit (trans);
1330 }
1331 gnc_resume_gui_refresh ();
1333 LEAVE (" ");
1334}
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264

◆ gnc_split_register_destroy()

void gnc_split_register_destroy ( SplitRegister *  reg)

Destroys a split register.

Parameters
rega ::SplitRegister

Definition at line 3160 of file split-register.c.

3161{
3162 g_return_if_fail (reg);
3163
3164 ENTER ("reg=%p", reg);
3165
3166 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
3167 GNC_PREF_ACCOUNTING_LABELS,
3168 split_register_pref_changed,
3169 reg);
3170 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
3171 GNC_PREF_ACCOUNT_SEPARATOR,
3172 split_register_pref_changed,
3173 reg);
3174 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL_REGISTER,
3175 GNC_PREF_SHOW_LEAF_ACCT_NAMES,
3176 split_register_pref_changed,
3177 reg);
3178 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL_REGISTER,
3179 GNC_PREF_ALT_COLOR_BY_TRANS,
3180 split_register_pref_changed,
3181 reg);
3182 gnc_book_option_remove_cb (OPTION_NAME_NUM_FIELD_SOURCE,
3183 split_register_book_option_changed,
3184 reg);
3185
3186 gnc_split_register_cleanup (reg);
3187
3188 gnc_table_destroy (reg->table);
3189 reg->table = NULL;
3190
3191 /* free the memory itself */
3192 g_free (reg);
3193 LEAVE (" ");
3194}
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_split_register_duplicate_current()

Split * gnc_split_register_duplicate_current ( SplitRegister *  reg)

Duplicates either the current transaction or the current split depending on the register mode and cursor position.

Returns the split just created, or the 'main' split of the transaction just created, or NULL if nothing happened.

Definition at line 440 of file split-register.c.

441{
442 SRInfo* info = gnc_split_register_get_info (reg);
443 CursorClass cursor_class;
444 Transaction* trans;
445 Split* return_split;
446 Split* trans_split;
447 Split* blank_split;
448 gboolean changed;
449 Split* split;
450
451 ENTER ("reg=%p", reg);
452
453 blank_split = xaccSplitLookup (&info->blank_split_guid,
454 gnc_get_current_book ());
457 trans_split = gnc_split_register_get_current_trans_split (reg, NULL);
458
459 /* This shouldn't happen, but be paranoid. */
460 if (trans == NULL)
461 {
462 LEAVE ("no transaction");
463 return NULL;
464 }
465
467
468 /* Can't do anything with this. */
469 if (cursor_class == CURSOR_CLASS_NONE)
470 {
471 LEAVE ("no cursor class");
472 return NULL;
473 }
474
475 /* This shouldn't happen, but be paranoid. */
476 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
477 {
478 LEAVE ("no split with transaction class");
479 return NULL;
480 }
481
482 changed = gnc_table_current_cursor_changed (reg->table, FALSE);
483
484 /* See if we were asked to duplicate an unchanged blank split.
485 * There's no point in doing that! */
486 if (!changed && ((split == NULL) || (split == blank_split)))
487 {
488 LEAVE ("skip unchanged blank split");
489 return NULL;
490 }
491
492 gnc_suspend_gui_refresh ();
493
494 /* If the cursor has been edited, we are going to have to commit
495 * it before we can duplicate. Make sure the user wants to do that. */
496 if (changed)
497 {
498 GtkWidget* dialog, *window;
499 gint response;
500 const char* title = _ ("Save transaction before duplicating?");
501 const char* message =
502 _ ("The current transaction has been changed. Would you like to "
503 "record the changes before duplicating the transaction, or "
504 "cancel the duplication?");
505
506 window = gnc_split_register_get_parent (reg);
507 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
508 GTK_DIALOG_DESTROY_WITH_PARENT,
509 GTK_MESSAGE_QUESTION,
510 GTK_BUTTONS_CANCEL,
511 "%s", title);
512 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
513 "%s", message);
514 gtk_dialog_add_button (GTK_DIALOG (dialog),
515 _ ("_Record"), GTK_RESPONSE_ACCEPT);
516 response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_DUP);
517 gtk_widget_destroy (dialog);
518
519 if (response != GTK_RESPONSE_ACCEPT)
520 {
521 gnc_resume_gui_refresh ();
522 LEAVE ("save cancelled");
523 return NULL;
524 }
525
526 gnc_split_register_save (reg, TRUE);
527
528 /* If the split is NULL, then we were on a blank split row
529 * in an expanded transaction. The new split (created by
530 * gnc_split_register_save above) will be the last split in the
531 * current transaction, as it was just added. */
532 if (split == NULL)
533 split = xaccTransGetSplit (trans, xaccTransCountSplits (trans) - 1);
534 }
535
536 /* Ok, we are now ready to make the copy. */
537
538 if (cursor_class == CURSOR_CLASS_SPLIT)
539 {
540 Split* new_split;
541 char* out_num;
542 gboolean new_act_num = FALSE;
543
544 /* We are on a split in an expanded transaction.
545 * Just copy the split and add it to the transaction.
546 * However, if the split-action field is being used as the register
547 * number, and the action field is a number, request a new value or
548 * cancel. Need to get next number and update account last num from
549 * split account not register account, which may be the same or not */
550
551 if (!reg->use_tran_num_for_num_field
552 && gnc_strisnum (gnc_get_num_action (NULL, split)))
553 {
554 Account* account = xaccSplitGetAccount (split);
555 const char* in_num = NULL;
556 const char* title = _ ("New Split Information");
557 time64 date = info->last_date_entered;
558
559 if (account)
560 in_num = xaccAccountGetLastNum (account);
561 else
562 in_num = gnc_get_num_action (NULL, split);
563
564 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg),
565 title, FALSE, &date, in_num, &out_num,
566 NULL, NULL, NULL, NULL))
567 {
568 gnc_resume_gui_refresh ();
569 LEAVE ("dup cancelled");
570 return NULL;
571 }
572 new_act_num = TRUE;
573 }
574
575 new_split = xaccMallocSplit (gnc_get_current_book ());
576
577 xaccTransBeginEdit (trans);
578 xaccSplitSetParent (new_split, trans);
579
580 Account *template_account = xaccAccountLookup (&info->template_account,
581 gnc_get_current_book ());
582
583 gnc_copy_split_onto_split (split, new_split, template_account, FALSE);
584 if (new_act_num) /* if new number supplied by user dialog */
585 gnc_set_num_action (NULL, new_split, out_num, NULL);
586
587 xaccTransCommitEdit (trans);
588
589 if (new_act_num && gnc_strisnum (out_num))
590 {
591 Account* account = xaccSplitGetAccount (new_split);
592
593 /* If current register is for account, set last num */
594 if (xaccAccountEqual (account,
595 gnc_split_register_get_default_account (reg),
596 TRUE))
597 {
598 NumCell* num_cell;
599 num_cell = (NumCell*) gnc_table_layout_get_cell (reg->table->layout,
600 NUM_CELL);
601 if (gnc_num_cell_set_last_num (num_cell, out_num))
602 gnc_split_register_set_last_num (reg, out_num);
603 }
604 else
605 {
606 xaccAccountSetLastNum (account, out_num);
607 }
608 }
609
610 return_split = new_split;
611
612 info->cursor_hint_split = new_split;
613 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
614 if (new_act_num)
615 g_free (out_num);
616 }
617 else
618 {
619 Account* account;
620 NumCell* num_cell;
621 Transaction* new_trans;
622 int trans_split_index;
623 int split_index;
624 const char* in_num = NULL;
625 const char* in_tnum = NULL;
626 char* out_num = NULL;
627 char* out_tnum = NULL;
628 char* out_tdoclink = NULL;
629 time64 date;
630 gboolean use_autoreadonly = qof_book_uses_autoreadonly (
631 gnc_get_current_book ());
632
633 /* We are on a transaction row. Copy the whole transaction. */
634
635 date = info->last_date_entered;
636
637 account = gnc_split_register_get_default_account (reg);
638
639 if (account && gnc_strisnum (gnc_get_num_action (trans, trans_split)))
640 in_num = xaccAccountGetLastNum (account);
641 else
642 in_num = gnc_get_num_action (trans, trans_split);
643
644 in_tnum = (reg->use_tran_num_for_num_field
645 ? NULL
646 : gnc_get_num_action (trans, NULL));
647
648 if (!gnc_dup_trans_dialog (gnc_split_register_get_parent (reg), NULL,
649 !reg->is_template, &date,
650 in_num, &out_num, in_tnum, &out_tnum,
651 xaccTransGetDocLink (trans), &out_tdoclink))
652 {
653 gnc_resume_gui_refresh ();
654 LEAVE ("dup cancelled");
655 return NULL;
656 }
657
658 if (use_autoreadonly)
659 {
660 GDate d;
661 GDate* readonly_threshold = qof_book_get_autoreadonly_gdate (
662 gnc_get_current_book ());
663 gnc_gdate_set_time64 (&d, date);
664 if (g_date_compare (&d, readonly_threshold) < 0)
665 {
666 GtkWidget* dialog = gtk_message_dialog_new (NULL,
667 0,
668 GTK_MESSAGE_ERROR,
669 GTK_BUTTONS_OK,
670 "%s", _ ("Cannot store a transaction at this date"));
671 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
672 "%s", _ ("The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. "
673 "This setting can be changed in File->Properties->Accounts."));
674 gtk_dialog_run (GTK_DIALOG (dialog));
675 gtk_widget_destroy (dialog);
676
677 g_date_free (readonly_threshold);
678 return NULL;
679 }
680 g_date_free (readonly_threshold);
681 }
682
683 split_index = xaccTransGetSplitIndex (trans, split);
684 trans_split_index = xaccTransGetSplitIndex (trans, trans_split);
685
686 /* we should *always* find the split, but be paranoid */
687 if (split_index < 0)
688 {
689 gnc_resume_gui_refresh ();
690 LEAVE ("no split");
691 return NULL;
692 }
693
694 new_trans = xaccMallocTransaction (gnc_get_current_book ());
695
696 xaccTransBeginEdit (new_trans);
697
698 Account *template_account = xaccAccountLookup (&info->template_account,
699 gnc_get_current_book ());
700
701 gnc_copy_trans_onto_trans (trans, new_trans, FALSE, template_account, FALSE);
702 xaccTransSetDatePostedSecsNormalized (new_trans, date);
703 /* We also must set a new DateEntered on the new entry
704 * because otherwise the ordering is not deterministic */
705 xaccTransSetDateEnteredSecs (new_trans, gnc_time (NULL));
706
707 /* clear the document link entry if returned value NULL */
708 if (out_tdoclink == NULL)
709 xaccTransSetDocLink (new_trans, "");
710 else
711 g_free (out_tdoclink);
712
713 /* set per book option */
714 gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
715 if (!reg->use_tran_num_for_num_field)
716 {
717 /* find split in new_trans that equals trans_split and set
718 * split_action to out_num */
719 gnc_set_num_action (NULL,
720 xaccTransGetSplit (new_trans, trans_split_index),
721 out_num, NULL);
722 /* note that if the transaction has multiple splits to the register
723 * account, only the anchor split will be set with user input. The
724 * user will have to adjust other splits manually. */
725 }
726 xaccTransCommitEdit (new_trans);
727
728 num_cell = (NumCell*) gnc_table_layout_get_cell (reg->table->layout,
729 NUM_CELL);
730 if (gnc_num_cell_set_last_num (num_cell, out_num))
731 gnc_split_register_set_last_num (reg, out_num);
732
733 g_free (out_num);
734 if (!reg->use_tran_num_for_num_field)
735 g_free (out_tnum);
736
737 /* This shouldn't happen, but be paranoid. */
738 if (split_index >= xaccTransCountSplits (new_trans))
739 split_index = 0;
740
741 return_split = xaccTransGetSplit (new_trans, split_index);
742 trans_split = xaccTransGetSplit (new_trans, trans_split_index);
743
744 info->cursor_hint_trans = new_trans;
745 info->cursor_hint_split = return_split;
746 info->cursor_hint_trans_split = trans_split;
747 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
748
749 info->trans_expanded = FALSE;
750 }
751
752 /* Refresh the GUI. */
753 gnc_resume_gui_refresh ();
754
755 LEAVE (" ");
756 return return_split;
757}
void xaccAccountSetLastNum(Account *acc, const char *num)
Set the last num field of an Account.
Definition Account.cpp:4692
const char * xaccAccountGetLastNum(const Account *acc)
Get the last num field of an Account.
Definition Account.cpp:4683
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
Definition Account.cpp:1666
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id,...
Definition Account.cpp:2050
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
Definition qofbook.cpp:1006
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
Definition qofbook.cpp:974
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
const char * xaccTransGetDocLink(const Transaction *trans)
Gets the transaction Document Link.
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
Inverse of xaccTransGetSplit()
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
void xaccTransSetDocLink(Transaction *trans, const char *doclink)
Sets the transaction Document Link.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3)).
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
gboolean gnc_split_register_save(SplitRegister *reg, gboolean do_commit)
Copy the contents of the current cursor to a split.
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...
Split * xaccMallocSplit(QofBook *book)
Constructor.
gboolean gnc_strisnum(const gchar *s)
Returns true if string s is a number, possibly surrounded by whitespace.
Definition qofutil.cpp:187
The NumCell object implements a number handling cell.
Definition numcell.h:40

◆ gnc_split_register_empty_current_trans()

void gnc_split_register_empty_current_trans ( SplitRegister *  reg)

Definition at line 1477 of file split-register.c.

1478{
1479 Split* split;
1480
1481 /* get the current split based on cursor position */
1484}
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_split_register_empty_current_trans_except_split()

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.

Definition at line 1434 of file split-register.c.

1436{
1437 SRInfo* info;
1438 Transaction* trans;
1439 Transaction* pending;
1440 int i = 0;
1441 Split* s;
1442
1443 if ((reg == NULL) || (split == NULL))
1444 return;
1445
1446 gnc_suspend_gui_refresh ();
1447 info = gnc_split_register_get_info (reg);
1448 pending = xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ());
1449
1450 trans = xaccSplitGetParent (split);
1451 if (!pending)
1452 {
1453 if (gnc_split_register_begin_edit_or_warn (info, trans))
1454 {
1455 gnc_resume_gui_refresh ();
1456 return;
1457 }
1458 }
1459 else if (pending == trans)
1460 {
1461 g_assert (xaccTransIsOpen (trans));
1462 }
1463 else g_assert_not_reached ();
1464
1465 while ((s = xaccTransGetSplit (trans, i)) != NULL)
1466 {
1467 if (s != split)
1468 xaccSplitDestroy (s);
1469 else i++;
1470 }
1471
1472 gnc_resume_gui_refresh ();
1474}

◆ gnc_split_register_expand_current_trans()

void gnc_split_register_expand_current_trans ( SplitRegister *  reg,
gboolean  expand 
)

Expand the current transaction if it is collapsed.

Definition at line 243 of file split-register.c.

244{
245 SRInfo* info = gnc_split_register_get_info (reg);
246 VirtualLocation virt_loc;
247
248 if (!reg)
249 return;
250
251 if (reg->style == REG_STYLE_AUTO_LEDGER ||
252 reg->style == REG_STYLE_JOURNAL)
253 return;
254
255 /* ok, so I just wanted an excuse to use exclusive-or */
256 if (! (expand ^ info->trans_expanded))
257 return;
258
259 if (!expand)
260 {
261 virt_loc = reg->table->current_cursor_loc;
262 gnc_split_register_get_trans_split (reg, virt_loc.vcell_loc,
263 &virt_loc.vcell_loc);
264
265 if (gnc_table_find_close_valid_cell (reg->table, &virt_loc, FALSE))
266 gnc_table_move_cursor_gui (reg->table, virt_loc);
267 else
268 {
269 PERR ("Can't find place to go!");
270 return;
271 }
272 }
273
274 info->trans_expanded = expand;
275
277 reg->table->current_cursor_loc.vcell_loc,
278 gnc_split_register_get_active_cursor (reg));
279
281 reg, reg->table->current_cursor_loc.vcell_loc, expand, FALSE);
282
283 virt_loc = reg->table->current_cursor_loc;
284 if (!expand || !gnc_table_virtual_loc_valid (reg->table, virt_loc, FALSE))
285 {
286 if (gnc_table_find_close_valid_cell (reg->table, &virt_loc, FALSE))
287 gnc_table_move_cursor_gui (reg->table, virt_loc);
288 else
289 {
290 PERR ("Can't find place to go!");
291 return;
292 }
293 }
294
295 gnc_table_refresh_gui (reg->table, TRUE);
296
297 if (expand)
298 gnc_split_register_show_trans (reg,
299 reg->table->current_cursor_loc.vcell_loc);
300}
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244
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.
void gnc_table_set_virt_cell_cursor(Table *table, VirtualCellLocation vcell_loc, CellBlock *cursor)
Set the cellblock handler for a virtual cell.

◆ gnc_split_register_find_split()

gboolean gnc_split_register_find_split ( SplitRegister *  reg,
Transaction *  trans,
Split *  trans_split,
Split *  split,
CursorClass  cursor_class,
VirtualCellLocation *  vcell_loc 
)

Definition at line 201 of file split-register-util.c.

205{
206 Table *table = reg->table;
207 gboolean found_trans = FALSE;
208 gboolean found_trans_split = FALSE;
209 gboolean found_something = FALSE;
210 CursorClass cursor_class;
211 int v_row, v_col;
212 Transaction *t;
213 Split *s;
214
215 for (v_row = 1; v_row < table->num_virt_rows; v_row++)
216 for (v_col = 0; v_col < table->num_virt_cols; v_col++)
217 {
218 VirtualCellLocation vc_loc = { v_row, v_col };
219
220 s = gnc_split_register_get_split (reg, vc_loc);
221 t = xaccSplitGetParent(s);
222
223 cursor_class = gnc_split_register_get_cursor_class (reg, vc_loc);
224
225 if (t == trans)
226 {
227 /* A register entry for the correct transaction. */
228 found_trans = TRUE;
229
230 if (cursor_class == CURSOR_CLASS_TRANS)
231 {
232 /* This row is the transaction split for this transaction. */
233 if (s == trans_split)
234 /* It's the copy of the transaction that we want. */
235 found_trans_split = TRUE;
236 else
237 found_trans_split = FALSE;
238
239 if (find_class == CURSOR_CLASS_TRANS &&
240 (s == split || reg->style == REG_STYLE_JOURNAL))
241 {
242 /* We're looking for a transaction split and this is the split we're looking for
243 or there is only one entry for this transaction in this register (since it's
244 a journal style register) so we must return the only transaction split there is. */
245 if (vcell_loc != NULL)
246 *vcell_loc = vc_loc;
247 return TRUE;
248 }
249 }
250 }
251 else
252 {
253 /* Not the correct transaction. We shouldn't get here if these are true, but just
254 to be safe reset them. */
255 found_trans = FALSE;
256 found_trans_split = FALSE;
257 }
258
259 if (found_trans && (s == split) && s)
260 {
261 /* We're on the right transaction, but perhaps not the copy of it we want, and
262 this is the correct split, return it if we don't find anything better. */
263 if (vcell_loc != NULL)
264 *vcell_loc = vc_loc;
265
266 found_something = TRUE;
267 }
268
269 if (found_trans_split && (s == split))
270 {
271 /* We're on the right copy of the right transaction, and this is the split we
272 want, return it (it should be the right class since if we wanted a transaction
273 split we would have returned it above. */
274 if (vcell_loc != NULL)
275 *vcell_loc = vc_loc;
276
277 if (cursor_class == find_class)
278 return TRUE;
279 }
280 }
281
282 return found_something;
283}
CursorClass gnc_split_register_get_cursor_class(SplitRegister *reg, VirtualCellLocation vcell_loc)
Returns the class of the cursor at the given virtual cell location.

◆ gnc_split_register_get_account()

Account * gnc_split_register_get_account ( SplitRegister *  reg,
const char *  cell_name 
)

Definition at line 2118 of file split-register.c.

2119{
2120 BasicCell* cell;
2121 const char* name;
2122
2123 if (!gnc_table_layout_get_cell_changed (reg->table->layout, cell_name, TRUE))
2124 return NULL;
2125
2126 cell = gnc_table_layout_get_cell (reg->table->layout, cell_name);
2127 if (!cell)
2128 return NULL;
2129 name = gnc_basic_cell_get_value (cell);
2130 return gnc_split_register_get_account_by_name (reg, cell, name);
2131}

◆ gnc_split_register_get_account_by_name()

Account * gnc_split_register_get_account_by_name ( SplitRegister *  reg,
BasicCell *  cell,
const char *  name 
)

Definition at line 2051 of file split-register.c.

2053{
2054 const char* placeholder = _ ("The account %s does not allow transactions.");
2055 const char* missing = _ ("The account %s does not exist. "
2056 "Would you like to create it?");
2057 char* account_name;
2058 ComboCell* cell = (ComboCell*) bcell;
2059 Account* account;
2060 static gboolean creating_account = FALSE;
2061 GtkWindow* parent = GTK_WINDOW (gnc_split_register_get_parent (reg));
2062
2063 if (!name || (strlen (name) == 0))
2064 return NULL;
2065
2066 /* Find the account */
2067 account = gnc_account_lookup_for_register (gnc_get_current_root_account (),
2068 name);
2069 if (!account)
2070 account = gnc_account_lookup_by_code (gnc_get_current_root_account (), name);
2071
2072 /* if gnc_ui_new_accounts_from_name_window is used, there is a call to
2073 * refresh which subsequently calls this function again, that's the
2074 * reason for static creating_account. */
2075
2076 if (!account && !creating_account)
2077 {
2078 /* Ask if they want to create a new one. */
2079 if (!gnc_verify_dialog (parent, TRUE, missing, name))
2080 return NULL;
2081 creating_account = TRUE;
2082 /* User said yes, they want to create a new account. */
2083 account = gnc_ui_new_accounts_from_name_window (parent, name);
2084 creating_account = FALSE;
2085 if (!account)
2086 return NULL;
2087 }
2088
2089 if (!creating_account)
2090 {
2091 /* Now have the account. */
2092 account_name = gnc_get_account_name_for_split_register (account,
2093 reg->show_leaf_accounts);
2094 if (g_strcmp0 (account_name, gnc_basic_cell_get_value (bcell)))
2095 {
2096 /* The name has changed. Update the cell. */
2097 gnc_combo_cell_set_value (cell, account_name);
2098 gnc_basic_cell_set_changed (&cell->cell, TRUE);
2099 }
2100 g_free (account_name);
2101
2102 /* See if the account (either old or new) is a placeholder. */
2103 if (account && xaccAccountGetPlaceholder (account))
2104 {
2105 gchar* fullname = gnc_account_get_full_name (account);
2106 gnc_error_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
2107 placeholder, fullname);
2108 g_free (fullname);
2109 return NULL;
2110 }
2111 }
2112
2113 /* Be seeing you. */
2114 return account;
2115}
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...
Definition Account.cpp:3305
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
Definition Account.cpp:4119
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,...
Definition Account.cpp:3106
Account * gnc_ui_new_accounts_from_name_window(GtkWindow *parent, const char *name)
Display a modal window for creating a new account.
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.
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.
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it.
Definition combocell.h:53

◆ gnc_split_register_get_active_cursor()

CellBlock * gnc_split_register_get_active_cursor ( SplitRegister *  reg)

Definition at line 466 of file split-register-util.c.

467{
468 SRInfo *info = gnc_split_register_get_info (reg);
469 const char *cursor_name = NULL;
470
471 switch (reg->style)
472 {
473 case REG_STYLE_LEDGER:
474 if (!info->trans_expanded)
475 {
476 cursor_name = reg->use_double_line ?
477 (reg->use_tran_num_for_num_field ? CURSOR_DOUBLE_LEDGER
478 : CURSOR_DOUBLE_LEDGER_NUM_ACTN)
479 : CURSOR_SINGLE_LEDGER;
480 break;
481 }
482
483 /* fall through */
484 case REG_STYLE_AUTO_LEDGER:
485 case REG_STYLE_JOURNAL:
486 cursor_name = reg->use_double_line ?
487 (reg->use_tran_num_for_num_field ? CURSOR_DOUBLE_JOURNAL
488 : CURSOR_DOUBLE_JOURNAL_NUM_ACTN)
489 : CURSOR_SINGLE_JOURNAL;
490 break;
491 }
492
493 if (!cursor_name)
494 {
495 PWARN ("bad register style");
496 return NULL;
497 }
498
499 return gnc_table_layout_get_cursor (reg->table->layout, cursor_name);
500}
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250

◆ gnc_split_register_get_blank_split()

Split * gnc_split_register_get_blank_split ( SplitRegister *  reg)

Gets the blank split for a register.

Parameters
rega ::SplitRegister
Returns
the ::Split used as the blank split, or NULL if there currently isn't one

Definition at line 352 of file split-register.c.

353{
354 SRInfo* info = gnc_split_register_get_info (reg);
355
356 if (!reg) return NULL;
357
358 return xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ());
359}

◆ gnc_split_register_get_credit_string()

const char * gnc_split_register_get_credit_string ( SplitRegister *  reg)

Return the credit string used in the register.

Definition at line 2522 of file split-register.c.

2523{
2524 SRInfo* info = gnc_split_register_get_info (reg);
2525
2526 if (!reg)
2527 return NULL;
2528
2529 if (info->credit_str)
2530 return info->credit_str;
2531
2532 info->credit_str =
2534 (gnc_split_register_type_to_account_type (reg->type));
2535
2536 if (info->credit_str)
2537 return info->credit_str;
2538
2539 info->credit_str = g_strdup (_ ("Credit"));
2540
2541 return info->credit_str;
2542}
const char * gnc_account_get_credit_string(GNCAccountType acct_type)
Get the credit string associated with this account type.
Definition Account.cpp:4103

◆ gnc_split_register_get_current_cursor_class()

CursorClass gnc_split_register_get_current_cursor_class ( SplitRegister *  reg)

Returns the class of a register's current cursor.

Parameters
rega ::SplitRegister
Returns
the CursorClass of the current cursor

Definition at line 546 of file split-register-util.c.

547{
548 Table *table;
549
550 if (reg == NULL)
551 return CURSOR_CLASS_NONE;
552
553 table = reg->table;
554 if (table == NULL)
555 return CURSOR_CLASS_NONE;
556
557 return gnc_split_register_cursor_class (reg, table->current_cursor);
558}

◆ gnc_split_register_get_current_split()

Split * gnc_split_register_get_current_split ( SplitRegister *  reg)

Returns the split at which the cursor is currently located.

Parameters
rega ::SplitRegister
Returns
the ::Split at the cursor location, or the anchoring split if the cursor is currently on a transaction

Definition at line 342 of file split-register.c.

343{
344 if (reg == NULL)
345 return NULL;
346
347 return gnc_split_register_get_split (
348 reg, reg->table->current_cursor_loc.vcell_loc);
349}

◆ gnc_split_register_get_current_trans()

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 of its splits.

Parameters
rega ::SplitRegister
Returns
the ::Transaction at the cursor location, or NULL

Definition at line 318 of file split-register.c.

319{
320 Split* split;
321 VirtualCellLocation vcell_loc;
322
323 if (reg == NULL)
324 return NULL;
325
327 if (split != NULL)
328 return xaccSplitGetParent (split);
329
330 /* Split is blank. Assume it is the blank split of a multi-line
331 * transaction. Go back one row to find a split in the transaction. */
332 vcell_loc = reg->table->current_cursor_loc.vcell_loc;
333
334 vcell_loc.virt_row--;
335
336 split = gnc_split_register_get_split (reg, vcell_loc);
337
338 return xaccSplitGetParent (split);
339}

◆ gnc_split_register_get_current_trans_split()

Split * gnc_split_register_get_current_trans_split ( SplitRegister *  reg,
VirtualCellLocation *  vcell_loc 
)

Gets the anchoring split of the transaction at the current cursor location, which may be on the transaction itself or on any of its splits.

Parameters
rega ::SplitRegister
vcell_loca pointer to be filled with the location of the transaction's virtual cell
Returns
the anchoring ::Split of the transaction

Definition at line 187 of file split-register-util.c.

189{
190 VirtualCellLocation vcell_loc;
191
192 if (reg == NULL)
193 return NULL;
194
195 vcell_loc = reg->table->current_cursor_loc.vcell_loc;
196
197 return gnc_split_register_get_trans_split (reg, vcell_loc, trans_split_loc);
198}

◆ gnc_split_register_get_cursor_class()

CursorClass gnc_split_register_get_cursor_class ( SplitRegister *  reg,
VirtualCellLocation  vcell_loc 
)

Returns the class of the cursor at the given virtual cell location.

Parameters
rega ::SplitRegister
vcell_locthe location of a virtual cell
Returns
the CursorClass of the cursor at vcell_loc

Definition at line 525 of file split-register-util.c.

527{
528 VirtualCell *vcell;
529 Table *table;
530
531 if (reg == NULL)
532 return CURSOR_CLASS_NONE;
533
534 table = reg->table;
535 if (table == NULL)
536 return CURSOR_CLASS_NONE;
537
538 vcell = gnc_table_get_virtual_cell (table, vcell_loc);
539 if (vcell == NULL)
540 return CURSOR_CLASS_NONE;
541
542 return gnc_split_register_cursor_class (reg, vcell->cellblock);
543}
VirtualCell * gnc_table_get_virtual_cell(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell associated with a particular virtual location.
holds information about each virtual cell.

◆ gnc_split_register_get_debit_string()

const char * gnc_split_register_get_debit_string ( SplitRegister *  reg)

Return the debit string used in the register.

Definition at line 2499 of file split-register.c.

2500{
2501 SRInfo* info = gnc_split_register_get_info (reg);
2502
2503 if (!reg)
2504 return NULL;
2505
2506 if (info->debit_str)
2507 return info->debit_str;
2508
2509 info->debit_str =
2511 (gnc_split_register_type_to_account_type (reg->type));
2512
2513 if (info->debit_str)
2514 return info->debit_str;
2515
2516 info->debit_str = g_strdup (_ ("Debit"));
2517
2518 return info->debit_str;
2519}
const char * gnc_account_get_debit_string(GNCAccountType acct_type)
Get the debit string associated with this account type.
Definition Account.cpp:4091

◆ gnc_split_register_get_default_account()

Account * gnc_split_register_get_default_account ( SplitRegister *  reg)

Definition at line 108 of file split-register-util.c.

109{
110 SRInfo *info = gnc_split_register_get_info (reg);
111
112 return xaccAccountLookup (&info->default_account,
113 gnc_get_current_book ());
114}

◆ gnc_split_register_get_info()

SRInfo * gnc_split_register_get_info ( SplitRegister *  reg)

Definition at line 66 of file split-register-util.c.

67{
68 if (!reg)
69 return NULL;
70
71 if (reg->sr_info == NULL)
72 gnc_split_register_init_info (reg);
73
74 return reg->sr_info;
75}

◆ gnc_split_register_get_parent()

GtkWidget * gnc_split_register_get_parent ( SplitRegister *  reg)

Definition at line 78 of file split-register-util.c.

79{
80 SRInfo *info = gnc_split_register_get_info (reg);
81
82 if (reg == NULL)
83 return NULL;
84
85 if (info->get_parent == NULL)
86 return NULL;
87
88 return info->get_parent (info->user_data);
89}

◆ gnc_split_register_get_passive_cursor()

CellBlock * gnc_split_register_get_passive_cursor ( SplitRegister *  reg)

Definition at line 434 of file split-register-util.c.

435{
436 const char *cursor_name = NULL;
437
438 switch (reg->style)
439 {
440 case REG_STYLE_LEDGER:
441 case REG_STYLE_AUTO_LEDGER:
442 cursor_name = reg->use_double_line ?
443 (reg->use_tran_num_for_num_field ? CURSOR_DOUBLE_LEDGER
444 : CURSOR_DOUBLE_LEDGER_NUM_ACTN)
445 : CURSOR_SINGLE_LEDGER;
446 break;
447
448 case REG_STYLE_JOURNAL:
449 cursor_name = reg->use_double_line ?
450 (reg->use_tran_num_for_num_field ? CURSOR_DOUBLE_JOURNAL
451 : CURSOR_DOUBLE_JOURNAL_NUM_ACTN)
452 : CURSOR_SINGLE_JOURNAL;
453 break;
454 }
455
456 if (!cursor_name)
457 {
458 PWARN ("bad register style");
459 return NULL;
460 }
461
462 return gnc_table_layout_get_cursor (reg->table->layout, cursor_name);
463}

◆ gnc_split_register_get_register_group()

SplitRegisterTypeGroup gnc_split_register_get_register_group ( SplitRegister *  reg)

Group registers for common layouts.

Parameters
rega ::SplitRegister
Returns
the SplitRegisterTypeGroup that groups registers together

Definition at line 3203 of file split-register.c.

3204{
3205 switch (reg->type)
3206 {
3207 case BANK_REGISTER:
3208 case CASH_REGISTER:
3209 case ASSET_REGISTER:
3210 case CREDIT_REGISTER:
3211 case LIABILITY_REGISTER:
3212 case INCOME_REGISTER:
3213 case EXPENSE_REGISTER:
3214 case EQUITY_REGISTER:
3215 case TRADING_REGISTER:
3216 {
3217 return REG_TYPE_GROUP_CURRENCY;
3218 break;
3219 }
3220 case PAYABLE_REGISTER:
3221 case RECEIVABLE_REGISTER:
3222 {
3223 return REG_TYPE_GROUP_APAR;
3224 break;
3225 }
3226 case INCOME_LEDGER:
3227 case GENERAL_JOURNAL:
3228 case SEARCH_LEDGER:
3229 {
3230 return REG_TYPE_GROUP_JOURNAL;
3231 break;
3232 }
3233 case STOCK_REGISTER:
3234 case CURRENCY_REGISTER:
3235 {
3236 return REG_TYPE_GROUP_STOCK;
3237 break;
3238 }
3239 case PORTFOLIO_LEDGER:
3240 {
3241 return REG_TYPE_GROUP_PORTFOLIO;
3242 break;
3243 }
3244 default:
3245 return REG_TYPE_GROUP_UNKNOWN;
3246 PERR ("unknown register type %d\n", reg->type);
3247 break;
3248 }
3249}

◆ gnc_split_register_get_split()

Split * gnc_split_register_get_split ( SplitRegister *  reg,
VirtualCellLocation  vcell_loc 
)

Definition at line 92 of file split-register-util.c.

94{
95 GncGUID *guid;
96
97 if (reg == NULL)
98 return NULL;
99
100 guid = gnc_table_get_vcell_data (reg->table, vcell_loc);
101 if (guid == NULL)
102 return NULL;
103
104 return xaccSplitLookup (guid, gnc_get_current_book ());
105}
gpointer gnc_table_get_vcell_data(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell data associated with a cursor located at the given virtual coords,...
The type used to store guids in C.
Definition guid.h:75

◆ gnc_split_register_get_split_amount_virt_loc()

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 non-zero) or debit cell.

Parameters
rega ::SplitRegister
splitthe ::Split to find
virt_loca pointer to be filled with the amount cell's location
Returns
TRUE if the split was found and the location has been stored at virt_loc, FALSE otherwise

Definition at line 402 of file split-register.c.

404{
405 VirtualLocation v_loc;
406 CursorClass cursor_class;
407 const char* cell_name;
408 gnc_numeric value;
409
410 if (!gnc_split_register_get_split_virt_loc (reg, split, &v_loc.vcell_loc))
411 return FALSE;
412
413 cursor_class = gnc_split_register_get_cursor_class (reg, v_loc.vcell_loc);
414
415 value = xaccSplitGetValue (split);
416
417 switch (cursor_class)
418 {
419 case CURSOR_CLASS_SPLIT:
420 case CURSOR_CLASS_TRANS:
421 cell_name = (gnc_numeric_negative_p (value)) ? CRED_CELL : DEBT_CELL;
422 break;
423 default:
424 return FALSE;
425 }
426
427 if (!gnc_table_get_cell_location (reg->table, cell_name,
428 v_loc.vcell_loc, &v_loc))
429 return FALSE;
430
431 if (virt_loc == NULL)
432 return TRUE;
433
434 *virt_loc = v_loc;
435
436 return TRUE;
437}
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gboolean gnc_split_register_get_split_virt_loc(SplitRegister *reg, Split *split, VirtualCellLocation *vcell_loc)
Searches the split register for a given split.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.

◆ gnc_split_register_get_split_virt_loc()

gboolean gnc_split_register_get_split_virt_loc ( SplitRegister *  reg,
Split *  split,
VirtualCellLocation *  vcell_loc 
)

Searches the split register for a given split.

The search begins from the bottom row and works backwards. The location of the first virtual cell that matches will be returned in vcell_loc.

Parameters
rega ::SplitRegister
splitthe ::Split to find
vcell_loca pointer to be filled with the location of the matching virtual cell
Returns
TRUE if the split was found and the location has been stored at vcell_loc, FALSE otherwise

Definition at line 362 of file split-register.c.

364{
365 Table* table;
366 int v_row;
367 int v_col;
368
369 if (!reg || !split) return FALSE;
370
371 table = reg->table;
372
373 /* go backwards because typically you search for splits at the end
374 * and because we find split rows before transaction rows. */
375
376 for (v_row = table->num_virt_rows - 1; v_row > 0; v_row--)
377 for (v_col = 0; v_col < table->num_virt_cols; v_col++)
378 {
379 VirtualCellLocation vc_loc = { v_row, v_col };
380 VirtualCell* vcell;
381 Split* s;
382
383 vcell = gnc_table_get_virtual_cell (table, vc_loc);
384 if (!vcell || !vcell->visible)
385 continue;
386
387 s = xaccSplitLookup (vcell->vcell_data, gnc_get_current_book ());
388
389 if (s == split)
390 {
391 if (vcell_loc)
392 *vcell_loc = vc_loc;
393
394 return TRUE;
395 }
396 }
397
398 return FALSE;
399}
gpointer vcell_data
Array of physical cells.
unsigned int visible
Used by higher-level code.

◆ gnc_split_register_get_trans()

Transaction * gnc_split_register_get_trans ( SplitRegister *  reg,
VirtualCellLocation  vcell_loc 
)

Definition at line 128 of file split-register-util.c.

130{
131 Split *split;
132
133 if (!reg || !reg->table)
134 return NULL;
135
136 split = gnc_split_register_get_split (reg, vcell_loc);
137
138 if (split != NULL)
139 return xaccSplitGetParent(split);
140
141 /* Split is blank. Assume it is the blank split of a multi-line
142 * transaction. Go back one row to find a split in the transaction. */
143 vcell_loc.virt_row--;
144
145 split = gnc_split_register_get_split (reg, vcell_loc);
146
147 /* This split could be NULL during register initialization. */
148 if (split == NULL)
149 return NULL;
150
151 return xaccSplitGetParent(split);
152}

◆ gnc_split_register_get_trans_split()

Split * gnc_split_register_get_trans_split ( SplitRegister *  reg,
VirtualCellLocation  vcell_loc,
VirtualCellLocation *  trans_split_loc 
)

Definition at line 155 of file split-register-util.c.

158{
159 CursorClass cursor_class;
160
161 if (reg == NULL)
162 return NULL;
163
164 while (TRUE)
165 {
166 if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col))
167 {
168 PERR ("bad row\n");
169 return NULL;
170 }
171
172 cursor_class = gnc_split_register_get_cursor_class (reg, vcell_loc);
173
174 if (cursor_class == CURSOR_CLASS_TRANS)
175 {
176 if (trans_split_loc)
177 *trans_split_loc = vcell_loc;
178
179 return gnc_split_register_get_split (reg, vcell_loc);
180 }
181
182 vcell_loc.virt_row--;
183 }
184}

◆ gnc_split_register_handle_exchange()

gboolean gnc_split_register_handle_exchange ( SplitRegister *  reg,
gboolean  force_dialog 
)

Pop up the exchange-rate dialog, maybe, for the current split.

If force_dialog is TRUE, the forces the dialog to be called. If the dialog does not complete successfully, then return TRUE. Return FALSE in all other cases (meaning "move on")

Pop up the exchange-rate dialog, maybe, for the current split.

If the dialog does not complete successfully, then return TRUE. Return FALSE in all other cases (meaning "move on")

Parameters
regthe register to operate on
force_dialogpop a dialog even if we don't think we need it.
Returns
whether more handling is required.

Definition at line 1335 of file split-register-control.cpp.

1336{
1337 SRInfo *info;
1338 Transaction *txn;
1339 Split *split, *osplit;
1340 Account *xfer_acc, *reg_acc;
1341 gnc_commodity *txn_cur, *xfer_com, *reg_com;
1342 gnc_numeric amount, exch_rate;
1343 XferDialog *xfer;
1344 gboolean expanded = FALSE;
1345 PriceCell *rate_cell;
1346 const char *message;
1347 CursorClass cursor_class;
1348
1349 ENTER("reg=%p, force_dialog=%s", reg, force_dialog ? "TRUE" : "FALSE" );
1350
1351 /* No point in setting a rate on a template transaction. */
1352 if (reg->is_template)
1353 {
1354 LEAVE("Template transaction, rate makes no sense.");
1355 return FALSE;
1356 }
1357
1358 /* Registers have either a visible PRIC_CELL (price cell) or a
1359 * hidden RATE_CELL. We need launch the Transfer Dialog to collect
1360 * an exchange rate only when the RATE_CELL is provided. The first
1361 * check looks at the register type to see which kind it's
1362 * supposed to use, the second looks at what's actually in the
1363 * register layout but doesn't always look at the right
1364 * register.
1365 */
1366 if (!gnc_split_reg_has_rate_cell (reg->type))
1367 {
1368 if (force_dialog)
1369 {
1370 message = _("Edit prices/exchange rates directly in the split line.");
1371 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1372 }
1373 LEAVE("no rate cell");
1374 return FALSE;
1375 }
1376
1377 rate_cell = (PriceCell*) gnc_table_layout_get_cell (reg->table->layout, RATE_CELL);
1378
1379 if (!rate_cell)
1380 {
1381 if (force_dialog)
1382 {
1383 message = _("Edit prices/exchange rates directly in the split line.");
1384 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1385 }
1386 LEAVE("null rate cell");
1387 return FALSE;
1388 }
1389
1390 /* See if we already have an exchange rate... */
1391 info = gnc_split_register_get_info (reg);
1392 exch_rate = gnc_price_cell_get_value (rate_cell);
1393 if (!gnc_numeric_zero_p (exch_rate) && !force_dialog &&
1394 info->rate_reset != RATE_RESET_REQD)
1395 {
1396 LEAVE("rate already non-zero");
1397 return FALSE;
1398 }
1399
1400 /* Are we expanded? */
1403
1404 /* If we're expanded AND a transaction cursor, there is nothing to do */
1405 if (expanded && cursor_class == CURSOR_CLASS_TRANS)
1406 {
1407 if (force_dialog)
1408 {
1409 message = _("You need to select a split in order to modify its exchange "
1410 "rate.");
1411 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1412 }
1413 LEAVE("expanded with transaction cursor; nothing to do");
1414 return FALSE;
1415 }
1416
1417 /* Grab the xfer account */
1418 xfer_acc = gnc_split_register_get_account_always (reg,
1419 expanded ? XFRM_CELL : MXFRM_CELL);
1420
1421 /* If this is an un-expanded, multi-split transaction, then warn the user */
1422 if (force_dialog && !expanded && !xfer_acc)
1423 {
1424 message = _("You need to expand the transaction in order to modify its "
1425 "exchange rates.");
1426 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1427 LEAVE("%s", message);
1428 return TRUE;
1429 }
1430
1431 /* No account -- don't run the dialog */
1432 if (!xfer_acc)
1433 {
1434 if (force_dialog)
1435 {
1436 message = _("The entered account could not be found.");
1437 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1438 }
1439 LEAVE("no xfer account");
1440 return FALSE;
1441 }
1442
1443 /* Grab the txn currency and xfer commodity */
1445 txn_cur = xaccTransGetCurrency (txn);
1446 xfer_com = xaccAccountGetCommodity (xfer_acc);
1447
1448 /* Grab the register account and commodity (may be used later) */
1449 reg_acc = gnc_split_register_get_default_account (reg);
1450 reg_com = xaccAccountGetCommodity (reg_acc);
1451
1452 /* Grab the split and perhaps the "other" split (if it is a two-split txn) */
1454 osplit = xaccSplitGetOtherSplit (split);
1455
1456 /* Check if the txn- and xfer- commodities are the same */
1457 if (gnc_commodity_equal (txn_cur, xfer_com))
1458 {
1459 /* If we're not forcing the dialog, then there is no reason to
1460 * go on. We're using the correct accounts.
1461 */
1462 if (!force_dialog)
1463 {
1464 LEAVE("txn and account currencies match, and not forcing");
1465 return FALSE;
1466 }
1467
1468 /* Only proceed with two-split, basic, non-expanded registers */
1469 if (expanded || osplit == NULL)
1470 {
1471 message = _("The two currencies involved equal each other.");
1472 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1473 LEAVE("register is expanded or osplit == NULL; not forcing dialog");
1474 return FALSE;
1475 }
1476
1477 /* If we're forcing, then compare the current account
1478 * commodity to the transaction currency.
1479 */
1480 xfer_acc = reg_acc;
1481 xfer_com = reg_com;
1482 if (gnc_commodity_equal (txn_cur, xfer_com))
1483 {
1484 message = _("The two currencies involved equal each other.");
1485 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1486 LEAVE("reg commodity == txn commodity; not forcing");
1487 return FALSE;
1488 }
1489 }
1490
1491 /* If this is a non-expanded, two-split txn where BOTH splits need
1492 * conversion rates, then require the user to actually expand the
1493 * transaction in order to edit it.
1494 */
1495 if (!expanded && osplit &&
1496 gnc_split_register_split_needs_amount (reg, split) &&
1497 gnc_split_register_split_needs_amount (reg, osplit))
1498 {
1499 message = _("You need to expand the transaction in order to modify its "
1500 "exchange rates.");
1501 if (force_dialog)
1502 {
1503 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1504 }
1505 LEAVE("%s", message);
1506 return TRUE;
1507 }
1508
1509 /* Strangely, if we're in a two-split, non-expanded txn, we need
1510 * to do something really special with the exchange rate! In
1511 * particular, we have to pick it up from the _other_ split --
1512 * right?
1513 * XXX: perhaps I should pop up an error here? Or maybe require the
1514 * user to go into expanded-mode?
1515 */
1516 if (!expanded && osplit &&
1517 !gnc_commodity_equal (reg_com, txn_cur) &&
1518 !gnc_commodity_equal (reg_com, xfer_com))
1519 {
1520 gnc_numeric amt = xaccSplitGetAmount (osplit);
1521 gnc_numeric val = xaccSplitGetValue (osplit);
1522 exch_rate = gnc_numeric_div (amt, val, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
1523 }
1524
1525 /* Ok, we need to grab the exchange rate */
1526 amount = gnc_split_register_debcred_cell_value (reg);
1527
1528 /*
1529 * If "amount" is zero then we don't need an exchange-rate.. Return
1530 * FALSE to let the user continue on.
1531 */
1532 if (gnc_numeric_zero_p (amount))
1533 {
1534 if (force_dialog)
1535 {
1536 message = _("The split's amount is zero, so no exchange rate is needed.");
1537 gnc_error_dialog (GTK_WINDOW(gnc_split_register_get_parent (reg)), "%s", message);
1538 }
1539 LEAVE("amount is zero; no exchange rate needed");
1540 return FALSE;
1541 }
1542
1543 /* If the exch_rate is zero, we're not forcing the dialog, and this is
1544 * _not_ the blank split, then return FALSE -- this is a "special"
1545 * gain/loss stock transaction.
1546 */
1547 if (gnc_numeric_zero_p (exch_rate) && !force_dialog && split &&
1548 info->rate_reset != RATE_RESET_REQD &&
1550 {
1551 LEAVE("gain/loss split; no exchange rate needed");
1552 return FALSE;
1553 }
1554
1555 /* Show the exchange-rate dialog */
1556 xfer = gnc_split_register_xfer_dialog (reg, txn, split);
1557 gnc_xfer_dialog_is_exchange_dialog (xfer, &exch_rate);
1558 if (gnc_xfer_dialog_run_exchange_dialog (xfer, &exch_rate, amount,
1559 reg_acc, txn, xfer_com, expanded))
1560 {
1561 /* FIXME: How should the dialog be destroyed? */
1562 LEAVE("leaving rate unchanged");
1563 return TRUE;
1564 }
1565 /* FIXME: How should the dialog be destroyed? */
1566
1567 /* Set the RATE_CELL on this cursor and mark it changed */
1568 gnc_price_cell_set_value (rate_cell, exch_rate);
1569 gnc_basic_cell_set_changed (&rate_cell->cell, TRUE);
1570 info->rate_account = xfer_acc;
1571 info->rate_reset = RATE_RESET_DONE;
1572 LEAVE("set rate=%s", gnc_num_dbg_to_string (exch_rate));
1573 return FALSE;
1574}
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
Definition Account.cpp:3408
gboolean gnc_price_cell_set_value(PriceCell *cell, gnc_numeric amount)
updates amount, returns TRUE if string representation actually changed
Definition pricecell.c:219
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
gchar * gnc_num_dbg_to_string(gnc_numeric n)
Convert to string.
gboolean gnc_split_register_current_trans_expanded(SplitRegister *reg)
Return TRUE if current trans is expanded and style is REG_STYLE_LEDGER.
gboolean gnc_split_reg_has_rate_cell(SplitRegisterType type)
Determine if we need to perform any conversion on the splits in this transaction, and if so,...
Split * xaccSplitGetOtherSplit(const Split *split)
The xaccSplitGetOtherSplit() is a convenience routine that returns the other of a pair of splits.
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.

◆ gnc_split_register_has_copied_item()

gboolean gnc_split_register_has_copied_item ( void  )

Return TRUE if copied_item holds a transaction or split.

Definition at line 109 of file split-register.c.

110{
111 return copied_item.ft || copied_item.fs;
112}

◆ gnc_split_register_is_blank_split()

gboolean gnc_split_register_is_blank_split ( SplitRegister *  reg,
Split *  split 
)

Return TRUE if split is the blank_split.

Definition at line 1170 of file split-register.c.

1171{
1172 SRInfo* info = gnc_split_register_get_info (reg);
1173 Split* current_blank_split = xaccSplitLookup (&info->blank_split_guid,
1174 gnc_get_current_book ());
1175
1176 if (split == current_blank_split)
1177 return TRUE;
1178
1179 return FALSE;
1180}

◆ gnc_split_register_layout_new()

TableLayout * gnc_split_register_layout_new ( SplitRegister *  reg)

Generate the split register layout.

Definition at line 867 of file split-register-layout.c.

868{
869 TableLayout* layout;
870
871 layout = gnc_table_layout_new();
872
873 gnc_split_register_layout_add_cells (reg, layout);
874 gnc_split_register_layout_add_cursors (reg, layout);
875 gnc_split_register_set_cells (reg, layout);
876
877 return layout;
878}
TableLayout * gnc_table_layout_new(void)
API Declarations.

◆ gnc_split_register_load()

void gnc_split_register_load ( SplitRegister *  reg,
GList *  slist,
GList *  pre_filter_slist,
Account default_account 
)

Populates the rows of a register.

The rows are filled, based on the register style, with data associated with the given list of splits slist. In addition, an area for the user to begin entering new transactions is placed at the tail end of the register. This area is anchored by the "blank split".

The account default_account, if provided, is used to determine various default values for the blank split (such as currency, last check number, and transfer account) for the blank split.

Parameters
rega ::SplitRegister
slista list of splits
pre_filter_slistthe list of splits before applying filter
default_accountan account to provide defaults for the blank split

Definition at line 401 of file split-register-load.c.

403{
404 SRInfo* info;
405 Transaction* pending_trans;
406 CursorBuffer* cursor_buffer;
407 GHashTable* trans_table = NULL;
408 CellBlock* cursor_header;
409 CellBlock* lead_cursor;
410 CellBlock* split_cursor;
411 Transaction* blank_trans;
412 Transaction* find_trans;
413 Transaction* trans;
414 CursorClass find_class;
415 Split* find_trans_split;
416 Split* blank_split;
417 Split* find_split;
418 Split* split;
419 Table* table;
420 GList* node;
421 gnc_commodity *account_comm = NULL;
422
423 gboolean start_primary_color = TRUE;
424 gboolean found_pending = FALSE;
425 gboolean need_divider_upper = FALSE;
426 gboolean found_divider_upper = FALSE;
427 gboolean found_divider = FALSE;
428 gboolean has_last_num = FALSE;
429 gboolean multi_line;
430 gboolean dynamic;
431 gboolean we_own_slist = FALSE;
432 gboolean use_autoreadonly = qof_book_uses_autoreadonly (
433 gnc_get_current_book());
434 gboolean future_after_blank = gnc_prefs_get_bool (
435 GNC_PREFS_GROUP_GENERAL_REGISTER,
436 GNC_PREF_FUTURE_AFTER_BLANK);
437 gboolean added_blank_trans = FALSE;
438
439 VirtualCellLocation vcell_loc;
440 VirtualLocation save_loc;
441
442 int new_trans_split_row = -1;
443 int new_trans_row = -1;
444 int new_split_row = -1;
445 time64 present, autoreadonly_time = 0;
446
447 g_return_if_fail (reg);
448 table = reg->table;
449 g_return_if_fail (table);
450 info = gnc_split_register_get_info (reg);
451 g_return_if_fail (info);
452
453 ENTER ("reg=%p, slist=%p, default_account=%p", reg, slist, default_account);
454
455 blank_split = xaccSplitLookup (&info->blank_split_guid,
456 gnc_get_current_book());
457
458 pending_trans = xaccTransLookup (&info->pending_trans_guid,
459 gnc_get_current_book());
460
461 if (default_account)
462 account_comm = gnc_account_get_currency_or_parent (default_account);
463
464 if (!account_comm)
465 account_comm = gnc_default_currency ();
466
467 /* Bug 742089: Set the debit and credit cells' print_info to the account */
469 ((PriceCell*) gnc_table_layout_get_cell (table->layout, DEBT_CELL),
470 gnc_commodity_print_info (account_comm, FALSE));
471
473 ((PriceCell*) gnc_table_layout_get_cell (table->layout, CRED_CELL),
474 gnc_commodity_print_info (account_comm, FALSE));
475
477 ((PriceCell*) gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
478 gnc_commodity_print_info (account_comm, FALSE));
479
480 /* Only test for linked document glyths once */
481 if (info->first_pass)
482 {
483 gnc_doclink_cell_set_use_glyphs
484 ((Doclinkcell *) gnc_table_layout_get_cell (table->layout, DOCLINK_CELL));
485 }
486
487 /* make sure we have a blank split */
488 if (blank_split == NULL)
489 blank_split = create_blank_split (default_account, info);
490
491 blank_trans = xaccSplitGetParent (blank_split);
492
493 DEBUG ("blank_split=%p, blank_trans=%p, pending_trans=%p",
494 blank_split, blank_trans, pending_trans);
495
496 info->default_account = *xaccAccountGetGUID (default_account);
497
498 // gnc_table_leave_update (table, table->current_cursor_loc);
499
500 multi_line = (reg->style == REG_STYLE_JOURNAL);
501 dynamic = (reg->style == REG_STYLE_AUTO_LEDGER);
502
503 lead_cursor = gnc_split_register_get_passive_cursor (reg);
504 split_cursor = gnc_table_layout_get_cursor (table->layout, CURSOR_SPLIT);
505
506 /* figure out where we are going to. */
507 if (info->traverse_to_new)
508 {
509 find_trans = blank_trans;
510 find_split = NULL;
511 find_trans_split = blank_split;
512 find_class = CURSOR_CLASS_SPLIT;
513 }
514 else
515 {
516 find_trans = info->cursor_hint_trans;
517 find_split = info->cursor_hint_split;
518 find_trans_split = info->cursor_hint_trans_split;
519 find_class = info->cursor_hint_cursor_class;
520 }
521
522 save_loc = table->current_cursor_loc;
523
524 /* If the current cursor has changed we save the values for later
525 * possible restoration. */
526 if (gnc_table_current_cursor_changed (table, TRUE) &&
527 (find_split == gnc_split_register_get_current_split (reg)))
528 {
529 cursor_buffer = gnc_cursor_buffer_new();
530 gnc_table_save_current_cursor (table, cursor_buffer);
531 }
532 else
533 cursor_buffer = NULL;
534
535 /* disable move callback -- we don't want the cascade of
536 * callbacks while we are fiddling with loading the register */
537 gnc_table_control_allow_move (table->control, FALSE);
538
539 /* invalidate the cursor */
540 {
541 VirtualLocation virt_loc;
542
543 gnc_virtual_location_init (&virt_loc);
545 }
546
547 /* make sure that the header is loaded */
548 vcell_loc.virt_row = 0;
549 vcell_loc.virt_col = 0;
550 cursor_header = gnc_table_layout_get_cursor (table->layout, CURSOR_HEADER);
551 gnc_table_set_vcell (table, cursor_header, NULL, TRUE, TRUE, vcell_loc);
552 vcell_loc.virt_row++;
553
554 /* get the current time and reset the dividing row */
555 present = gnc_time64_get_today_end();
556 if (use_autoreadonly)
557 {
558 GDate* d = qof_book_get_autoreadonly_gdate (gnc_get_current_book());
559 // "d" is NULL if use_autoreadonly is FALSE
560 autoreadonly_time = d ? gdate_to_time64 (*d) : 0;
561 g_date_free (d);
562 }
563
564 if (info->first_pass)
565 {
566 if (default_account)
567 {
568 const char* last_num = xaccAccountGetLastNum (default_account);
569
570 if (last_num)
571 {
572 NumCell* cell;
573
574 cell = (NumCell*) gnc_table_layout_get_cell (table->layout, NUM_CELL);
575 gnc_num_cell_set_last_num (cell, last_num);
576 has_last_num = TRUE;
577 }
578 }
579
580 /* load up account names into the transfer combobox menus */
581 gnc_split_register_load_xfer_cells (reg, default_account);
582 gnc_split_register_load_desc_cells (reg);
583 gnc_split_register_load_doclink_cells (reg);
584 gnc_split_register_load_recn_cells (reg);
585 gnc_split_register_load_type_cells (reg);
586 }
587
588 if (info->separator_changed)
589 change_account_separator (info, table, reg);
590
591 table->model->dividing_row_upper = -1;
592 table->model->dividing_row = -1;
593 table->model->dividing_row_lower = -1;
594
595 // Ensure that the transaction and splits being edited are in the split
596 // list we're about to load.
597 if (pending_trans != NULL)
598 {
599 for (node = xaccTransGetSplitList (pending_trans); node; node = node->next)
600 {
601 Split* pending_split = (Split*)node->data;
602 if (!xaccTransStillHasSplit (pending_trans, pending_split)) continue;
603 if (g_list_find (slist, pending_split) != NULL)
604 continue;
605
606 if (g_list_find_custom (slist, pending_trans,
607 _find_split_with_parent_txn) != NULL)
608 continue;
609
610 if (!we_own_slist)
611 {
612 // lazy-copy
613 slist = g_list_copy (slist);
614 we_own_slist = TRUE;
615 }
616 slist = g_list_append (slist, pending_split);
617 }
618 }
619
620 if (multi_line)
621 trans_table = g_hash_table_new (g_direct_hash, g_direct_equal);
622
623 // View reversed add blank transaction at the top
624 if (table->model->reverse_sort && !future_after_blank)
625 {
626 if (blank_trans == find_trans)
627 new_trans_row = vcell_loc.virt_row;
628
629 if (blank_split == find_trans_split)
630 new_trans_split_row = vcell_loc.virt_row;
631
632 /* go to blank on first pass */
633 if (info->first_pass)
634 {
635 save_loc.vcell_loc = vcell_loc;
636 save_loc.phys_row_offset = 0;
637 save_loc.phys_col_offset = 0;
638 }
639
640 // used in the setting the rows insensitive
641 table->model->blank_trans_row = vcell_loc.virt_row;
642
643 gnc_split_register_add_transaction (reg,
644 blank_trans, blank_split,
645 lead_cursor, split_cursor,
646 multi_line, start_primary_color,
647 info->blank_split_edited,
648 find_trans, find_split,
649 find_class, &new_split_row,
650 &vcell_loc);
651
652 if (!multi_line)
653 start_primary_color = !start_primary_color;
654
655 added_blank_trans = TRUE;
656 }
657
658 gnc_completion_cell_clear_menu (
659 (CompletionCell*) gnc_table_layout_get_cell (reg->table->layout, DESC_CELL));
660
662 (CompletionCell*) gnc_table_layout_get_cell (reg->table->layout, DESC_CELL),
663 table->model->reverse_sort);
664
665 if (!info->first_pass && pre_filter_slist)
666 {
667 add_completions_from_pre_filter_slist (reg->table->layout, pre_filter_slist,
668 info->first_pass, info->quickfill_setup,
669 has_last_num);
670 }
671
672 /* populate the table */
673 for (node = slist; node; node = node->next)
674 {
675 split = node->data;
676 trans = xaccSplitGetParent (split);
677
678 if (!xaccTransStillHasSplit (trans, split))
679 continue;
680
681 if (pending_trans == trans)
682 found_pending = TRUE;
683 /* If the transaction has only one split, and it's not our
684 * pending_trans, then it's another register's blank split and
685 * we don't want to see it.
686 */
687 else if (xaccTransCountSplits (trans) == 1 &&
688 xaccSplitGetAccount (split) == NULL)
689 continue;
690
691 /* Do not load splits from the blank transaction. */
692 if (trans == blank_trans)
693 continue;
694
695 if (multi_line)
696 {
697 /* Skip this split if its transaction has already been loaded. */
698 if (g_hash_table_lookup (trans_table, trans))
699 continue;
700
701 g_hash_table_insert (trans_table, trans, trans);
702 }
703
704 if (info->show_present_divider &&
705 use_autoreadonly &&
706 !found_divider_upper)
707 {
708 if (((table->model->reverse_sort && xaccTransGetDate(trans) < autoreadonly_time) ||
709 (!table->model->reverse_sort && xaccTransGetDate (trans) >= autoreadonly_time)))
710 {
711 table->model->dividing_row_upper = vcell_loc.virt_row;
712 found_divider_upper = TRUE;
713 }
714 else
715 {
716 need_divider_upper = TRUE;
717 }
718 }
719
720 if (info->show_present_divider && !found_divider &&
721 ((table->model->reverse_sort && xaccTransGetDate (trans) < present) ||
722 (!table->model->reverse_sort && xaccTransGetDate (trans) > present)))
723 {
724 gint count_blank_splits = 1;
725 gint virt_row_offset = 2;
726 gboolean show_lower_divider = FALSE;
727
728 if (table->model->reverse_sort)
729 {
730 count_blank_splits = xaccTransCountSplits (blank_trans);
731
732 if (count_blank_splits > 1)
733 count_blank_splits ++;
734
735 if (table->model->reverse_sort && future_after_blank)
736 virt_row_offset = 0;
737 }
738
739 if ((table->model->reverse_sort && vcell_loc.virt_row != count_blank_splits + virt_row_offset) ||
740 !table->model->reverse_sort)
741 {
742 table->model->dividing_row = vcell_loc.virt_row; // blue top
743 show_lower_divider = TRUE;
744 }
745
746 found_divider = TRUE;
747
748 if (future_after_blank)
749 {
750 if (blank_trans == find_trans)
751 new_trans_row = vcell_loc.virt_row;
752
753 if (blank_split == find_trans_split)
754 new_trans_split_row = vcell_loc.virt_row;
755
756 /* go to blank on first pass */
757 if (info->first_pass)
758 {
759 save_loc.vcell_loc = vcell_loc;
760 save_loc.phys_row_offset = 0;
761 save_loc.phys_col_offset = 0;
762 }
763
764 // used in the setting the rows insensitive
765 table->model->blank_trans_row = vcell_loc.virt_row;
766
767 gnc_split_register_add_transaction (reg,
768 blank_trans, blank_split,
769 lead_cursor, split_cursor,
770 multi_line, start_primary_color,
771 info->blank_split_edited,
772 find_trans, find_split,
773 find_class, &new_split_row,
774 &vcell_loc);
775
776
777 if (show_lower_divider)
778 table->model->dividing_row_lower = vcell_loc.virt_row; // blue bottom
779
780 if (!multi_line)
781 start_primary_color = !start_primary_color;
782
783 added_blank_trans = TRUE;
784 }
785 }
786
787 /* On first load the split list is empty so fill up the quickfill cells
788 * only on the next load. */
789 if (!info->first_pass && !pre_filter_slist && !info->quickfill_setup)
790 add_quickfill_completions (reg->table->layout, trans, split, has_last_num);
791
792 if (!info->first_pass && !pre_filter_slist)
793 {
795 (CompletionCell*) gnc_table_layout_get_cell (reg->table->layout, DESC_CELL),
797 }
798
799 if (trans == find_trans)
800 new_trans_row = vcell_loc.virt_row;
801
802 if (split == find_trans_split)
803 new_trans_split_row = vcell_loc.virt_row;
804
805 gnc_split_register_add_transaction (reg, trans, split,
806 lead_cursor, split_cursor,
807 multi_line, start_primary_color,
808 TRUE,
809 find_trans, find_split, find_class,
810 &new_split_row, &vcell_loc);
811
812 if (!multi_line)
813 start_primary_color = !start_primary_color;
814 }
815
816 if (multi_line)
817 g_hash_table_destroy (trans_table);
818
819 /* add the blank split at the end. */
820 if (pending_trans == blank_trans)
821 found_pending = TRUE;
822
823 /* No upper divider yet? Store it now */
824 if (info->show_present_divider &&
825 use_autoreadonly &&
826 !found_divider_upper && need_divider_upper)
827 {
828 table->model->dividing_row_upper = vcell_loc.virt_row;
829 }
830
831 /* If we didn't find the pending transaction, it was removed
832 * from the account. */
833 if (!found_pending)
834 {
835 info->pending_trans_guid = *guid_null();
836 if (xaccTransIsOpen (pending_trans))
837 xaccTransCommitEdit (pending_trans);
838 else if (pending_trans)
839 g_assert_not_reached();
840
841 pending_trans = NULL;
842 }
843
844 if (!added_blank_trans)
845 {
846 if (blank_trans == find_trans)
847 new_trans_row = vcell_loc.virt_row;
848
849 if (blank_split == find_trans_split)
850 new_trans_split_row = vcell_loc.virt_row;
851
852 /* go to blank on first pass */
853 if (info->first_pass)
854 {
855 save_loc.vcell_loc = vcell_loc;
856 save_loc.phys_row_offset = 0;
857 save_loc.phys_col_offset = 0;
858 }
859
860 // used in the setting the rows insensitive
861 table->model->blank_trans_row = vcell_loc.virt_row;
862
863 gnc_split_register_add_transaction (reg, blank_trans, blank_split,
864 lead_cursor, split_cursor,
865 multi_line, start_primary_color,
866 info->blank_split_edited,
867 find_trans, find_split,
868 find_class, &new_split_row,
869 &vcell_loc);
870
871 if (future_after_blank)
872 {
873 table->model->dividing_row_lower = vcell_loc.virt_row;
874 }
875 }
876
877 /* go to blank on first pass */
878 if (info->first_pass)
879 {
880 new_split_row = -1;
881 new_trans_split_row = -1;
882 new_trans_row = -1;
883 }
884
885 /* resize the table to the sizes we just counted above */
886 /* num_virt_cols is always one. */
887 gnc_table_set_size (table, vcell_loc.virt_row, 1);
888
889 /* restore the cursor to its rightful position */
890 {
891 VirtualLocation trans_split_loc;
892
893 if (new_split_row > 0)
894 save_loc.vcell_loc.virt_row = new_split_row;
895 else if (new_trans_split_row > 0)
896 save_loc.vcell_loc.virt_row = new_trans_split_row;
897 else if (new_trans_row > 0)
898 save_loc.vcell_loc.virt_row = new_trans_row;
899
900 trans_split_loc = save_loc;
901
902 gnc_split_register_get_trans_split (reg, save_loc.vcell_loc,
903 &trans_split_loc.vcell_loc);
904
905 if (dynamic || multi_line || info->trans_expanded)
906 {
908 table, trans_split_loc.vcell_loc,
909 gnc_split_register_get_active_cursor (reg));
910 gnc_split_register_set_trans_visible (reg, trans_split_loc.vcell_loc,
911 TRUE, multi_line);
912
913 info->trans_expanded = (reg->style == REG_STYLE_LEDGER);
914 }
915 else
916 {
917 save_loc = trans_split_loc;
918 info->trans_expanded = FALSE;
919 }
920
921 if (gnc_table_find_close_valid_cell (table, &save_loc, FALSE))
922 {
924 new_split_row = save_loc.vcell_loc.virt_row;
925
926 if (find_split == gnc_split_register_get_current_split (reg))
927 gnc_table_restore_current_cursor (table, cursor_buffer);
928 }
929 }
930 gnc_cursor_buffer_destroy (cursor_buffer);
931 cursor_buffer = NULL;
932
933 update_info (info, reg);
934
935 gnc_split_register_set_cell_fractions (
937
939
940 // if in reverse order, always show the first transaction
941 if (table->model->reverse_sort)
942 {
943 VirtualCellLocation vc_loc;
944 vc_loc.virt_row = 0;
945 vc_loc.virt_col = 0;
946 gnc_split_register_show_trans (reg, vc_loc);
947 }
948 else
949 gnc_split_register_show_trans (reg, table->current_cursor_loc.vcell_loc);
950
951 /* enable callback for cursor user-driven moves */
952 gnc_table_control_allow_move (table->control, TRUE);
953
954 if (we_own_slist)
955 g_list_free (slist);
956
957 LEAVE (" ");
958}
find_split(split_list, search_string)
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.
Definition Account.cpp:3415
#define xaccAccountGetGUID(X)
Definition Account.h:252
void gnc_completion_cell_add_menu_item(CompletionCell *cell, const char *menustr)
Add a menu item to the hash table list.
void gnc_completion_cell_reverse_sort(CompletionCell *cell, gboolean is_reversed)
Register the sort direction.
void gnc_price_cell_set_print_info(PriceCell *cell, GNCPrintAmountInfo print_info)
set the printing context of the price cell
Definition pricecell.c:272
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
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...
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
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.
#define CURSOR_HEADER
Standard Cursor Names.
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.
The CompletionCell object implements a cell handler with a "combination-box" pull-down menu in it.
The Doclinkcell object implements a cell handler that will cycle through a series of single-character...
Definition doclinkcell.h:53

◆ gnc_split_register_model_add_save_handlers()

void gnc_split_register_model_add_save_handlers ( TableModel model)

Definition at line 763 of file split-register-model-save.c.

764{
765 g_return_if_fail (model != NULL);
766
767 gnc_table_model_set_save_handler (model,
768 gnc_split_register_save_date_cell,
769 DATE_CELL);
770
771 gnc_table_model_set_save_handler (model,
772 gnc_split_register_save_due_date_cell,
773 DDUE_CELL);
774
775 gnc_table_model_set_save_handler (model,
776 gnc_split_register_save_type_cell,
777 TYPE_CELL);
778
779 gnc_table_model_set_save_handler (model,
780 gnc_split_register_save_num_cell,
781 NUM_CELL);
782
783 gnc_table_model_set_save_handler (model,
784 gnc_split_register_save_tnum_cell,
785 TNUM_CELL);
786
787 gnc_table_model_set_save_handler (model,
788 gnc_split_register_save_desc_cell,
789 DESC_CELL);
790
791 gnc_table_model_set_save_handler (model,
792 gnc_split_register_save_notes_cell,
793 NOTES_CELL);
794
795 gnc_table_model_set_save_handler (model,
796 gnc_split_register_save_recn_cell,
797 RECN_CELL);
798
799 gnc_table_model_set_save_handler (model,
800 gnc_split_register_save_actn_cell,
801 ACTN_CELL);
802
803 gnc_table_model_set_save_handler (model,
804 gnc_split_register_save_memo_cell,
805 MEMO_CELL);
806
807 gnc_table_model_set_save_handler (model,
808 gnc_split_register_save_xfrm_cell,
809 XFRM_CELL);
810
811 gnc_table_model_set_save_handler (model,
812 gnc_split_register_save_mxfrm_cell,
813 MXFRM_CELL);
814
815 gnc_table_model_set_save_handler (model,
816 gnc_split_register_save_shares_cell,
817 SHRS_CELL);
818
819 gnc_table_model_set_save_handler (model,
820 gnc_split_register_save_price_cell,
821 PRIC_CELL);
822
823 gnc_table_model_set_save_handler (model,
824 gnc_split_register_save_debcred_cell,
825 DEBT_CELL);
826
827 gnc_table_model_set_save_handler (model,
828 gnc_split_register_save_debcred_cell,
829 CRED_CELL);
830
831 gnc_table_model_set_save_handler (model,
832 gnc_split_register_save_rate_cell,
833 RATE_CELL);
834
835 gnc_table_model_set_post_save_handler (model, gnc_split_register_save_cells);
836}

◆ gnc_split_register_model_new()

TableModel * gnc_split_register_model_new ( void  )

Definition at line 2512 of file split-register-model.c.

2513{
2514 TableModel* model;
2515 static GOnce once = G_ONCE_INIT;
2516
2517 g_once (&once, gnc_split_register_model_add_hooks, NULL);
2518
2519 model = gnc_table_model_new();
2520
2521 // entry handlers
2522 gnc_table_model_set_entry_handler (model,
2523 gnc_split_register_get_date_entry,
2524 DATE_CELL);
2525
2526 gnc_table_model_set_entry_handler (model,
2527 gnc_split_register_get_due_date_entry,
2528 DDUE_CELL);
2529
2530 gnc_table_model_set_entry_handler (model,
2531 gnc_split_register_get_num_entry,
2532 NUM_CELL);
2533
2534 gnc_table_model_set_entry_handler (model,
2535 gnc_split_register_get_tran_num_entry,
2536 TNUM_CELL);
2537
2538 gnc_table_model_set_entry_handler (model,
2539 gnc_split_register_get_desc_entry,
2540 DESC_CELL);
2541
2542 gnc_table_model_set_entry_handler (model,
2543 gnc_split_register_get_notes_entry,
2544 NOTES_CELL);
2545
2546 gnc_table_model_set_entry_handler (model,
2547 gnc_split_register_get_vnotes_entry,
2548 VNOTES_CELL);
2549
2550 gnc_table_model_set_entry_handler (model,
2551 gnc_split_register_get_rate_entry,
2552 RATE_CELL);
2553
2554 gnc_table_model_set_entry_handler (model,
2555 gnc_split_register_get_recn_entry,
2556 RECN_CELL);
2557
2558 gnc_table_model_set_entry_handler (model,
2559 gnc_split_register_get_action_entry,
2560 ACTN_CELL);
2561
2562 gnc_table_model_set_entry_handler (model,
2563 gnc_split_register_get_memo_entry,
2564 MEMO_CELL);
2565
2566 gnc_table_model_set_entry_handler (model,
2567 gnc_split_register_get_balance_entry,
2568 BALN_CELL);
2569
2570 gnc_table_model_set_entry_handler (model,
2571 gnc_split_register_get_balance_entry,
2572 TBALN_CELL);
2573
2574 gnc_table_model_set_entry_handler (model,
2575 gnc_split_register_get_price_entry,
2576 PRIC_CELL);
2577
2578 gnc_table_model_set_entry_handler (model,
2579 gnc_split_register_get_shares_entry,
2580 SHRS_CELL);
2581
2582 gnc_table_model_set_entry_handler (model,
2583 gnc_split_register_get_tshares_entry,
2584 TSHRS_CELL);
2585
2586 gnc_table_model_set_entry_handler (model,
2587 gnc_split_register_get_xfrm_entry,
2588 XFRM_CELL);
2589
2590 gnc_table_model_set_entry_handler (model,
2591 gnc_split_register_get_mxfrm_entry,
2592 MXFRM_CELL);
2593
2594 gnc_table_model_set_entry_handler (model,
2595 gnc_split_register_get_tdebcred_entry,
2596 TDEBT_CELL);
2597
2598 gnc_table_model_set_entry_handler (model,
2599 gnc_split_register_get_tdebcred_entry,
2600 TCRED_CELL);
2601
2602 gnc_table_model_set_entry_handler (model,
2603 gnc_split_register_get_doclink_entry,
2604 DOCLINK_CELL);
2605
2606 gnc_table_model_set_entry_handler (model,
2607 gnc_split_register_get_type_entry,
2608 TYPE_CELL);
2609
2610 gnc_table_model_set_entry_handler (model,
2611 gnc_split_register_get_debcred_entry,
2612 DEBT_CELL);
2613
2614 gnc_table_model_set_entry_handler (model,
2615 gnc_split_register_get_debcred_entry,
2616 CRED_CELL);
2617
2618 gnc_table_model_set_entry_handler (model,
2619 gnc_split_register_get_rbaln_entry,
2620 RBALN_CELL);
2621
2622 // label handlers
2623 gnc_table_model_set_label_handler (model,
2624 gnc_split_register_get_date_label,
2625 DATE_CELL);
2626
2627 gnc_table_model_set_label_handler (model,
2628 gnc_split_register_get_due_date_label,
2629 DDUE_CELL);
2630
2631 gnc_table_model_set_label_handler (model,
2632 gnc_split_register_get_num_label,
2633 NUM_CELL);
2634
2635 gnc_table_model_set_label_handler (model,
2636 gnc_split_register_get_tran_num_label,
2637 TNUM_CELL);
2638
2639 gnc_table_model_set_label_handler (model,
2640 gnc_split_register_get_desc_label,
2641 DESC_CELL);
2642
2643 gnc_table_model_set_label_handler (model,
2644 gnc_split_register_get_recn_label,
2645 RECN_CELL);
2646
2647 gnc_table_model_set_label_handler (model,
2648 gnc_split_register_get_baln_label,
2649 BALN_CELL);
2650
2651 gnc_table_model_set_label_handler (model,
2652 gnc_split_register_get_action_label,
2653 ACTN_CELL);
2654
2655 gnc_table_model_set_label_handler (model,
2656 gnc_split_register_get_xfrm_label,
2657 XFRM_CELL);
2658
2659 gnc_table_model_set_label_handler (model,
2660 gnc_split_register_get_memo_label,
2661 MEMO_CELL);
2662
2663 gnc_table_model_set_label_handler (model,
2664 gnc_split_register_get_debit_label,
2665 DEBT_CELL);
2666
2667 gnc_table_model_set_label_handler (model,
2668 gnc_split_register_get_credit_label,
2669 CRED_CELL);
2670
2671 gnc_table_model_set_label_handler (model,
2672 gnc_split_register_get_price_label,
2673 PRIC_CELL);
2674
2675 gnc_table_model_set_label_handler (model,
2676 gnc_split_register_get_rate_label,
2677 RATE_CELL);
2678
2679 gnc_table_model_set_label_handler (model,
2680 gnc_split_register_get_shares_label,
2681 SHRS_CELL);
2682
2683 gnc_table_model_set_label_handler (model,
2684 gnc_split_register_get_mxfrm_label,
2685 MXFRM_CELL);
2686
2687 gnc_table_model_set_label_handler (model,
2688 gnc_split_register_get_tcredit_label,
2689 TCRED_CELL);
2690
2691 gnc_table_model_set_label_handler (model,
2692 gnc_split_register_get_tdebit_label,
2693 TDEBT_CELL);
2694
2695 gnc_table_model_set_label_handler (model,
2696 gnc_split_register_get_tshares_label,
2697 TSHRS_CELL);
2698
2699 gnc_table_model_set_label_handler (model,
2700 gnc_split_register_get_tbalance_label,
2701 TBALN_CELL);
2702
2703 gnc_table_model_set_label_handler (model,
2704 gnc_split_register_get_doclink_label,
2705 DOCLINK_CELL);
2706
2707 gnc_table_model_set_label_handler (model,
2708 gnc_split_register_get_type_label,
2709 TYPE_CELL);
2710
2711 gnc_table_model_set_label_handler (model,
2712 gnc_split_register_get_notes_label,
2713 NOTES_CELL);
2714
2715 gnc_table_model_set_label_handler (model,
2716 gnc_split_register_get_fdebit_label,
2717 FDEBT_CELL);
2718
2719 gnc_table_model_set_label_handler (model,
2720 gnc_split_register_get_fcredit_label,
2721 FCRED_CELL);
2722
2723 gnc_table_model_set_label_handler (model,
2724 gnc_split_register_get_tbalance_label,
2725 RBALN_CELL);
2726
2727 // tooltip handlers
2728
2729 gnc_table_model_set_tooltip_handler (model,
2730 gnc_split_register_get_recn_tooltip,
2731 RECN_CELL);
2732
2733 gnc_table_model_set_tooltip_handler (model,
2734 gnc_split_register_get_doclink_tooltip,
2735 DOCLINK_CELL);
2736
2737
2738 // help handlers
2739 gnc_table_model_set_default_help_handler (
2740 model, gnc_split_register_get_default_help);
2741
2742 gnc_table_model_set_help_handler (model,
2743 gnc_split_register_get_date_help,
2744 DATE_CELL);
2745
2746 gnc_table_model_set_help_handler (model,
2747 gnc_split_register_get_date_help,
2748 DDUE_CELL);
2749
2750 gnc_table_model_set_help_handler (model,
2751 gnc_split_register_get_num_help,
2752 NUM_CELL);
2753
2754 gnc_table_model_set_help_handler (model,
2755 gnc_split_register_get_tran_num_help,
2756 TNUM_CELL);
2757
2758 gnc_table_model_set_help_handler (model,
2759 gnc_split_register_get_desc_help,
2760 DESC_CELL);
2761
2762 gnc_table_model_set_help_handler (model,
2763 gnc_split_register_get_price_help,
2764 PRIC_CELL);
2765
2766 gnc_table_model_set_help_handler (model,
2767 gnc_split_register_get_shares_help,
2768 SHRS_CELL);
2769
2770 gnc_table_model_set_help_handler (model,
2771 gnc_split_register_get_action_help,
2772 ACTN_CELL);
2773
2774 gnc_table_model_set_help_handler (model,
2775 gnc_split_register_get_memo_help,
2776 MEMO_CELL);
2777
2778 gnc_table_model_set_help_handler (model,
2779 gnc_split_register_get_notes_help,
2780 NOTES_CELL);
2781
2782 gnc_table_model_set_help_handler (model,
2783 gnc_split_register_get_vnotes_help,
2784 VNOTES_CELL);
2785
2786 gnc_table_model_set_help_handler (model,
2787 gnc_split_register_get_xfrm_help,
2788 XFRM_CELL);
2789
2790 gnc_table_model_set_help_handler (model,
2791 gnc_split_register_get_mxfrm_help,
2792 MXFRM_CELL);
2793
2794 gnc_table_model_set_help_handler (model,
2795 gnc_split_register_get_fcred_help,
2796 FCRED_CELL);
2797
2798 gnc_table_model_set_help_handler (model,
2799 gnc_split_register_get_fdebt_help,
2800 FDEBT_CELL);
2801
2802 gnc_table_model_set_help_handler (model,
2803 gnc_split_register_get_doclink_help,
2804 DOCLINK_CELL);
2805
2806 // io flag handlers
2807 gnc_table_model_set_io_flags_handler (
2808 model, gnc_split_register_get_standard_io_flags, DATE_CELL);
2809
2810 /* FIXME: We really only need a due date for 'invoices', not for
2811 * 'payments' or 'receipts'. This implies we really only need the
2812 * due-date for transactions that credit the ACCT_TYPE_RECEIVABLE or
2813 * debit the ACCT_TYPE_PAYABLE account type.
2814 */
2815 gnc_table_model_set_io_flags_handler (
2816 model, gnc_split_register_get_rate_io_flags, RATE_CELL);
2817
2818 gnc_table_model_set_io_flags_handler (
2819 model, gnc_split_register_get_ddue_io_flags, DDUE_CELL);
2820
2821 gnc_table_model_set_io_flags_handler (
2822 model, gnc_split_register_get_standard_io_flags, NUM_CELL);
2823
2824 gnc_table_model_set_io_flags_handler (
2825 model, gnc_split_register_get_standard_io_flags, TNUM_CELL);
2826
2827 gnc_table_model_set_io_flags_handler (
2828 model, gnc_split_register_get_standard_io_flags, DESC_CELL);
2829
2830 gnc_table_model_set_io_flags_handler (
2831 model, gnc_split_register_get_standard_io_flags, ACTN_CELL);
2832
2833 gnc_table_model_set_io_flags_handler (
2834 model, gnc_split_register_get_standard_io_flags, XFRM_CELL);
2835
2836 gnc_table_model_set_io_flags_handler (
2837 model, gnc_split_register_get_standard_io_flags, MEMO_CELL);
2838
2839 gnc_table_model_set_io_flags_handler (
2840 model, gnc_split_register_get_standard_io_flags, MXFRM_CELL);
2841
2842 gnc_table_model_set_io_flags_handler (
2843 model, gnc_split_register_get_standard_io_flags, NOTES_CELL);
2844
2845 gnc_table_model_set_io_flags_handler (
2846 model, gnc_split_register_get_inactive_io_flags, VNOTES_CELL);
2847
2848 gnc_table_model_set_io_flags_handler (
2849 model, gnc_split_register_get_debcred_io_flags, CRED_CELL);
2850
2851 gnc_table_model_set_io_flags_handler (
2852 model, gnc_split_register_get_debcred_io_flags, DEBT_CELL);
2853
2854 gnc_table_model_set_io_flags_handler (
2855 model, gnc_split_register_get_recn_io_flags, RECN_CELL);
2856
2857 gnc_table_model_set_io_flags_handler (
2858 model, gnc_split_register_get_doclink_io_flags, DOCLINK_CELL);
2859
2860 gnc_table_model_set_io_flags_handler (
2861 model, gnc_split_register_get_recn_io_flags, TYPE_CELL);
2862
2863 gnc_table_model_set_io_flags_handler (
2864 model, gnc_split_register_get_security_io_flags, PRIC_CELL);
2865
2866 gnc_table_model_set_io_flags_handler (
2867 model, gnc_split_register_get_security_io_flags, SHRS_CELL);
2868
2869
2870 gnc_table_model_set_default_cell_color_handler (
2871 model, gnc_split_register_get_cell_color);
2872
2873 gnc_table_model_set_cell_color_handler (
2874 model, gnc_split_register_get_debcred_color, DEBT_CELL);
2875
2876 gnc_table_model_set_cell_color_handler (
2877 model, gnc_split_register_get_debcred_color, CRED_CELL);
2878
2879 gnc_table_model_set_cell_color_handler (
2880 model, gnc_split_register_get_debcred_color, TDEBT_CELL);
2881
2882 gnc_table_model_set_cell_color_handler (
2883 model, gnc_split_register_get_debcred_color, TCRED_CELL);
2884
2885 gnc_table_model_set_cell_color_handler (
2886 model, gnc_split_register_get_debcred_color, FCRED_CELL);
2887
2888 gnc_table_model_set_cell_color_handler (
2889 model, gnc_split_register_get_debcred_color, FDEBT_CELL);
2890
2891
2892 gnc_table_model_set_default_cell_border_handler (
2893 model, gnc_split_register_get_border);
2894
2895
2896 gnc_table_model_set_default_confirm_handler (
2897 model, gnc_split_register_confirm);
2898
2899 model->cell_data_allocator = gnc_split_register_guid_malloc;
2900 model->cell_data_deallocator = gnc_split_register_guid_free;
2901 model->cell_data_copy = gnc_split_register_guid_copy;
2902
2903 gnc_split_register_model_add_save_handlers (model);
2904
2905 return model;
2906}

◆ gnc_split_register_needs_conv_rate()

gboolean gnc_split_register_needs_conv_rate ( SplitRegister *  reg,
Transaction *  txn,
Account acc 
)

Definition at line 1715 of file split-register-model.c.

1717{
1718 gnc_commodity* txn_cur, *acc_com;
1719
1720 /* If there is not a RATE_CELL, then don't do anything */
1721 if (!gnc_split_reg_has_rate_cell (reg->type))
1722 return FALSE;
1723
1724 /* if txn->currency == acc->commodity, then return FALSE */
1725 acc_com = xaccAccountGetCommodity (acc);
1726 txn_cur = xaccTransGetCurrency (txn);
1727 if (txn_cur && acc_com && gnc_commodity_equal (txn_cur, acc_com))
1728 return FALSE;
1729
1730 return TRUE;
1731}

◆ gnc_split_register_new()

SplitRegister * gnc_split_register_new ( SplitRegisterType  type,
SplitRegisterStyle  style,
gboolean  use_double_line,
gboolean  is_template,
gboolean  mismatched_commodities 
)

Creates a new split register.

Parameters
typea SplitRegisterType to use for the new register
stylea SplitRegisterStyle to use for the new register
use_double_lineTRUE to show two lines for transactions, FALSE for one
is_templateTRUE for a new template, FALSE otherwise
Returns
a newly created ::SplitRegister

Definition at line 2962 of file split-register.c.

2967{
2968 SplitRegister* reg;
2969 gboolean default_do_auto_complete = TRUE;
2970
2971 reg = g_new0 (SplitRegister, 1);
2972
2973 if (type >= NUM_SINGLE_REGISTER_TYPES)
2974 style = REG_STYLE_JOURNAL;
2975
2976 gnc_split_register_init (reg,
2977 type,
2978 style,
2979 use_double_line,
2980 default_do_auto_complete,
2981 is_template,
2982 mismatched_commodities);
2983
2984 return reg;
2985}

◆ gnc_split_register_paste_current()

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 have the same type.

Definition at line 941 of file split-register.c.

942{
943 SRInfo* info = gnc_split_register_get_info (reg);
944 CursorClass cursor_class;
945 Transaction* trans;
946 Transaction* blank_trans;
947 Split* blank_split;
948 Split* trans_split;
949 Split* split;
950 Account *template_account = NULL;
951
952 ENTER ("reg=%p", reg);
953
954 if (copied_item.cursor_class == CURSOR_CLASS_NONE)
955 {
956 LEAVE ("no copied cursor class");
957 return;
958 }
959
960 blank_split = xaccSplitLookup (&info->blank_split_guid,
961 gnc_get_current_book ());
962 blank_trans = xaccSplitGetParent (blank_split);
965
966 trans_split = gnc_split_register_get_current_trans_split (reg, NULL);
967
968 template_account = xaccAccountLookup (&info->template_account,
969 gnc_get_current_book ());
970
971 /* This shouldn't happen, but be paranoid. */
972 if (trans == NULL)
973 {
974 LEAVE ("no transaction");
975 return;
976 }
977
979
980 /* Can't do anything with this. */
981 if (cursor_class == CURSOR_CLASS_NONE)
982 {
983 LEAVE ("no current cursor class");
984 return;
985 }
986
987 /* This shouldn't happen, but be paranoid. */
988 if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
989 {
990 g_warning ("BUG DETECTED: transaction cursor with no anchoring split!");
991 LEAVE ("transaction cursor with no anchoring split");
992 return;
993 }
994
995 if (cursor_class == CURSOR_CLASS_SPLIT)
996 {
997 const char* message = _ ("You are about to overwrite an existing split. "
998 "Are you sure you want to do that?");
999 const char* anchor_message = _ ("This is the split anchoring this transaction "
1000 "to the register. You may not overwrite it from "
1001 "this register window. You may overwrite it if "
1002 "you navigate to a register that shows another "
1003 "side of this same transaction.");
1004
1005 if (copied_item.cursor_class == CURSOR_CLASS_TRANS)
1006 {
1007 /* An entire transaction was copied, but we're just on a split. */
1008 LEAVE ("can't copy trans to split");
1009 return;
1010 }
1011
1012 if (split != NULL)
1013 {
1014 /* the General Journal does not have any anchoring splits */
1015 if ((reg->type != GENERAL_JOURNAL) &&
1016 split == gnc_split_register_get_current_trans_split (reg, NULL))
1017 {
1018 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1019 "%s", anchor_message);
1020 LEAVE ("anchore split");
1021 return;
1022 }
1023 else if (!gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1024 FALSE, "%s", message))
1025 {
1026 LEAVE ("user cancelled");
1027 return;
1028 }
1029 }
1030
1031 /* Open the transaction for editing. */
1032 if (gnc_split_register_begin_edit_or_warn (info, trans))
1033 {
1034 LEAVE ("can't begin editing");
1035 return;
1036 }
1037
1038 gnc_suspend_gui_refresh ();
1039
1040 if (split == NULL)
1041 {
1042 /* We are on a null split in an expanded transaction. */
1043 split = xaccMallocSplit (gnc_get_current_book ());
1044 xaccSplitSetParent (split, trans);
1045 }
1046
1047 if (copied_item.ftype != GNC_TYPE_SPLIT)
1048 {
1049 LEAVE ("copy buffer doesn't represent a split");
1050 return;
1051 }
1052 gnc_float_split_to_split (copied_item.fs, split, template_account);
1053 }
1054 else
1055 {
1056 const char *message = _("You are about to overwrite an existing "
1057 "transaction. "
1058 "Are you sure you want to do that?");
1059 Account * copied_leader;
1060 Account * default_account;
1061 int trans_split_index;
1062 int split_index;
1063 int num_splits;
1064
1065 if (copied_item.cursor_class == CURSOR_CLASS_SPLIT)
1066 {
1067 LEAVE ("can't copy split to transaction");
1068 return;
1069 }
1070
1071 if (copied_item.ftype != GNC_TYPE_TRANSACTION)
1072 {
1073 LEAVE ("copy buffer doesn't represent a transaction");
1074 return;
1075 }
1076
1077 if ((reg->type != SEARCH_LEDGER) && (reg->type != GENERAL_JOURNAL))
1078 {
1079 if (gnc_float_txn_has_template (copied_item.ft))
1080 {
1081 const gchar *msg_text = _("Scheduled transactions can only be pasted to the General Journal");
1082
1083 gnc_warning_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)), "%s", msg_text);
1084
1085 LEAVE ("Paste only allowed to General Journal from scheduled transactions");
1086 return;
1087 }
1088 }
1089
1090 /* Ask before overwriting an existing transaction. */
1091 if (split != blank_split &&
1092 !gnc_verify_dialog (GTK_WINDOW (gnc_split_register_get_parent (reg)),
1093 FALSE, "%s", message))
1094 {
1095 LEAVE ("user cancelled");
1096 return;
1097 }
1098
1099 /* Open the transaction for editing. */
1100 if (gnc_split_register_begin_edit_or_warn (info, trans))
1101 {
1102 LEAVE ("can't begin editing");
1103 return;
1104 }
1105
1106 gnc_suspend_gui_refresh ();
1107
1108 DEBUG ("Pasting txn, trans=%p, split=%p, blank_trans=%p, blank_split=%p",
1109 trans, split, blank_trans, blank_split);
1110
1111 split_index = xaccTransGetSplitIndex (trans, split);
1112 trans_split_index = xaccTransGetSplitIndex (trans, trans_split);
1113
1114 copied_leader = xaccAccountLookup (&copied_item.leader_guid,
1115 gnc_get_current_book ());
1116 default_account = gnc_split_register_get_default_account (reg);
1117
1118 if (copied_leader && default_account)
1119 {
1120 gnc_float_txn_to_txn_swap_accounts (copied_item.ft, trans,
1121 copied_leader,
1122 default_account,
1123 FALSE);
1124 }
1125 else
1126 {
1127 if (reg->is_template)
1128 {
1129 gnc_float_txn_to_template_txn (copied_item.ft, trans,
1130 template_account, FALSE);
1131 }
1132 else
1133 gnc_float_txn_to_txn (copied_item.ft, trans, FALSE);
1134 }
1135 num_splits = xaccTransCountSplits (trans);
1136 if (split_index >= num_splits)
1137 split_index = 0;
1138
1139 if (trans == blank_trans)
1140 {
1141 /* In pasting, the blank split is deleted. Pick a new one. */
1142 gint anchor_split_index = copied_item.anchor_split_index;
1143 if (anchor_split_index > num_splits)
1144 anchor_split_index = 0;
1145
1146 blank_split = xaccTransGetSplit (trans, anchor_split_index);
1147 info->blank_split_guid = *xaccSplitGetGUID (blank_split);
1148 info->blank_split_edited = TRUE;
1149 info->auto_complete = FALSE;
1150 DEBUG ("replacement blank_split=%p", blank_split);
1151
1152 /* NOTE: At this point, the blank transaction virtual cell is still
1153 * anchored by the old, deleted blank split. The register will
1154 * have to be reloaded (redrawn) to correct this. */
1155 }
1156
1157 info->cursor_hint_trans = trans;
1158 info->cursor_hint_split = xaccTransGetSplit (trans, split_index);
1159 info->cursor_hint_trans_split = xaccTransGetSplit (trans,
1160 trans_split_index);
1161 info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
1162 }
1163
1164 /* Refresh the GUI. */
1165 gnc_resume_gui_refresh ();
1166 LEAVE (" ");
1167}

◆ gnc_split_register_recn_cell_confirm()

gboolean gnc_split_register_recn_cell_confirm ( char  old_flag,
gpointer  data 
)

Definition at line 1885 of file split-register-control.cpp.

1886{
1887 auto reg = static_cast<SplitRegister*>(data);
1888 GtkWidget *dialog, *window;
1889 gint response;
1890 const gchar *title = _("Mark split as unreconciled?");
1891 const gchar *message =
1892 _("You are about to mark a reconciled split as unreconciled. Doing "
1893 "so might make future reconciliation difficult! Continue "
1894 "with this change?");
1895
1896 if (old_flag != YREC)
1897 return TRUE;
1898
1899 /* Does the user want to be warned? */
1900 window = gnc_split_register_get_parent (reg);
1901 dialog = gtk_message_dialog_new (GTK_WINDOW(window),
1902 GTK_DIALOG_DESTROY_WITH_PARENT,
1903 GTK_MESSAGE_WARNING,
1904 GTK_BUTTONS_CANCEL,
1905 "%s", title);
1906 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
1907 "%s", message);
1908 gtk_dialog_add_button (GTK_DIALOG(dialog),
1909 _("_Unreconcile"),
1910 GTK_RESPONSE_YES);
1911 response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_REG_RECD_SPLIT_UNREC);
1912 gtk_widget_destroy (dialog);
1913 return (response == GTK_RESPONSE_YES);
1914}
#define YREC
The Split has been reconciled.
Definition Split.h:74

◆ gnc_split_register_redraw()

void gnc_split_register_redraw ( SplitRegister *  reg)

Causes a redraw of the register window associated with reg.

Definition at line 1551 of file split-register.c.

1552{
1553 gnc_ledger_display_refresh_by_split_register (reg);
1554}

◆ gnc_split_register_save()

gboolean gnc_split_register_save ( SplitRegister *  reg,
gboolean  do_commit 
)

Copy the contents of the current cursor to a split.

The split and transaction that are updated are the ones associated with the current cursor (register entry) position. If the do_commit flag is set, the transaction will also be committed. If it is the blank transaction, and the do_commit flag is set, a refresh will result in a new blank transaction. The method returns TRUE if something was changed.

Definition at line 1777 of file split-register.c.

1778{
1779 SRInfo* info = gnc_split_register_get_info (reg);
1780 Transaction* pending_trans;
1781 Transaction* blank_trans;
1782 Transaction* trans;
1783 Account* account;
1784 Split* blank_split;
1785 const char* memo;
1786 const char* desc;
1787 Split* split;
1788
1789 ENTER ("reg=%p, do_commit=%s", reg, do_commit ? "TRUE" : "FALSE");
1790
1791 if (!reg)
1792 {
1793 LEAVE ("no register");
1794 return FALSE;
1795 }
1796
1797 blank_split = xaccSplitLookup (&info->blank_split_guid,
1798 gnc_get_current_book ());
1799
1800 pending_trans = xaccTransLookup (&info->pending_trans_guid,
1801 gnc_get_current_book ());
1802
1803 blank_trans = xaccSplitGetParent (blank_split);
1804
1805 /* get the handle to the current split and transaction */
1808 if (trans == NULL)
1809 {
1810 LEAVE ("no transaction");
1811 return FALSE;
1812 }
1813
1814 /* use the changed flag to avoid heavy-weight updates
1815 * of the split & transaction fields. This will help
1816 * cut down on unnecessary register redraws. */
1817 if (!gnc_table_current_cursor_changed (reg->table, FALSE))
1818 {
1819 if (!do_commit)
1820 {
1821 LEAVE ("commit unnecessary");
1822 return FALSE;
1823 }
1824
1825 if (!xaccTransIsOpen (trans))
1826 {
1827 LEAVE ("transaction not open");
1828 return FALSE;
1829 }
1830
1831 if (trans == pending_trans ||
1832 (trans == blank_trans && info->blank_split_edited))
1833 {
1834 /* We are going to commit. */
1835
1836 gnc_suspend_gui_refresh ();
1837
1838 if (trans == blank_trans)
1839 {
1840 /* We have to clear the blank split before the
1841 * refresh or a new one won't be created. */
1842 info->last_date_entered = xaccTransGetDate (trans);
1843 info->blank_split_guid = *guid_null ();
1844 info->blank_split_edited = FALSE;
1845 info->auto_complete = FALSE;
1846 }
1847
1848 /* We have to clear the pending guid *before* committing the
1849 * trans, because the event handler will find it otherwise. */
1850 if (trans == pending_trans)
1851 info->pending_trans_guid = *guid_null ();
1852
1853 PINFO ("committing trans (%p)", trans);
1854 unreconcile_splits (reg);
1855 xaccTransCommitEdit (trans);
1856 xaccTransRecordPrice (trans, PRICE_SOURCE_SPLIT_REG);
1857
1858 gnc_resume_gui_refresh ();
1859 }
1860 else
1861 DEBUG ("leaving trans (%p) open", trans);
1862
1863 LEAVE ("unchanged cursor");
1864 return TRUE;
1865 }
1866
1867 DEBUG ("save split=%p", split);
1868 DEBUG ("blank_split=%p, blank_trans=%p, pending_trans=%p, trans=%p",
1869 blank_split, blank_trans, pending_trans, trans);
1870
1871 /* Act on any changes to the current cell before the save. */
1872 if (!gnc_split_register_check_cell (reg,
1873 gnc_table_get_current_cell_name (reg->table)))
1874 {
1875 LEAVE ("need another go at changing cell");
1876 return FALSE;
1877 }
1878
1879 if (!gnc_split_register_auto_calc (reg, split))
1880 {
1881 LEAVE ("auto calc failed");
1882 return FALSE;
1883 }
1884
1885 /* Validate the transfer account names */
1886 (void)gnc_split_register_get_account (reg, MXFRM_CELL);
1887 (void)gnc_split_register_get_account (reg, XFRM_CELL);
1888
1889 /* Maybe deal with exchange-rate transfers */
1890 if (gnc_split_register_handle_exchange (reg, FALSE))
1891 {
1892 LEAVE ("no exchange rate");
1893 return TRUE;
1894 }
1895
1896 gnc_suspend_gui_refresh ();
1897
1898 /* determine whether we should commit the pending transaction */
1899 if (pending_trans != trans)
1900 {
1901 // FIXME: How could the pending transaction not be open?
1902 // FIXME: For that matter, how could an open pending
1903 // transaction ever not be the current trans?
1904 if (xaccTransIsOpen (pending_trans))
1905 {
1906 g_warning ("Impossible? committing pending %p", pending_trans);
1907 unreconcile_splits (reg);
1908 xaccTransCommitEdit (pending_trans);
1909 xaccTransRecordPrice (trans, PRICE_SOURCE_SPLIT_REG);
1910 }
1911 else if (pending_trans)
1912 {
1913 g_critical ("BUG DETECTED! pending transaction (%p) not open",
1914 pending_trans);
1915 g_assert_not_reached ();
1916 }
1917
1918 if (trans == blank_trans)
1919 {
1920 /* Don't begin editing the blank trans, because it's
1921 already open, but mark it pending now. */
1922 g_assert (xaccTransIsOpen (blank_trans));
1923 /* This is now the pending transaction */
1924 info->pending_trans_guid = *xaccTransGetGUID (blank_trans);
1925 }
1926 else
1927 {
1928 PINFO ("beginning edit of trans %p", trans);
1929 if (gnc_split_register_begin_edit_or_warn (info, trans))
1930 {
1931 gnc_resume_gui_refresh ();
1932 LEAVE ("transaction opened elsewhere");
1933 return FALSE;
1934 }
1935 }
1936 pending_trans = trans;
1937 }
1938 g_assert (xaccTransIsOpen (trans));
1939
1940 /* If we are saving a brand new transaction and the blank split hasn't
1941 * been edited, then we need to give it a default account. */
1942 /* Q: Why check 'split == blank_split'? Isn't 'trans == blank_trans'
1943 * even better? What if there were some way that we could be on
1944 * a row other than the transaction row or blank split row, but
1945 * the blank split still hasn't been edited? It seems to be assumed
1946 * that it isn't possible, but... -Charles, Jan 2009 */
1947 if (split == blank_split && !info->blank_split_edited)
1948 {
1949 /* If we've reached this point, it means that the blank split is
1950 * anchoring the transaction - see gnc_split_register_add_transaction ()
1951 * for an explanation - and the transaction has been edited (as evidenced
1952 * by the earlier check for a changed cursor.) Since the blank split
1953 * itself has not been edited, we'll have to assign a default account. */
1954 account = gnc_split_register_get_default_account (reg);
1955 if (account)
1956 xaccSplitSetAccount (blank_split, account);
1957 xaccTransSetDateEnteredSecs (trans, gnc_time (NULL));
1958 }
1959
1960 if (split == NULL)
1961 {
1962 /* If we were asked to save data for a row for which there is no
1963 * associated split, then assume that this was an "empty" row - see
1964 * gnc_split_register_add_transaction () for an explanation. This row
1965 * is used to add splits to an existing transaction, or to add the
1966 * 2nd through nth split rows to a brand new transaction.
1967 * xaccSRGetCurrent will handle this case, too. We will create
1968 * a new split, copy the row contents to that split, and append
1969 * the split to the pre-existing transaction. */
1970 Split* trans_split;
1971
1972 split = xaccMallocSplit (gnc_get_current_book ());
1973 xaccTransAppendSplit (trans, split);
1974
1975 gnc_table_set_virt_cell_data (reg->table,
1976 reg->table->current_cursor_loc.vcell_loc,
1977 xaccSplitGetGUID (split));
1978 DEBUG ("assigned cell to new split=%p", split);
1979
1980 trans_split = gnc_split_register_get_current_trans_split (reg, NULL);
1981 if ((info->cursor_hint_trans == trans) &&
1982 (info->cursor_hint_trans_split == trans_split) &&
1983 (info->cursor_hint_split == NULL))
1984 {
1985 info->cursor_hint_split = split;
1986 info->cursor_hint_cursor_class = CURSOR_CLASS_SPLIT;
1987 }
1988 }
1989
1990 DEBUG ("updating trans=%p", trans);
1991
1992 {
1993 SRSaveData* sd;
1994
1995 sd = gnc_split_register_save_data_new (
1996 trans, split, (info->trans_expanded ||
1997 reg->style == REG_STYLE_AUTO_LEDGER ||
1998 reg->style == REG_STYLE_JOURNAL));
1999 gnc_table_save_cells (reg->table, sd);
2000 gnc_split_register_save_data_destroy (sd);
2001 }
2002
2003 memo = xaccSplitGetMemo (split);
2004 memo = memo ? memo : "(null)";
2005 desc = xaccTransGetDescription (trans);
2006 desc = desc ? desc : "(null)";
2007 PINFO ("finished saving split \"%s\" of trans \"%s\"", memo, desc);
2008
2009 /* If the modified split is the "blank split", then it is now an
2010 * official part of the account. Set the blank split to NULL, so we
2011 * can be sure of getting a new blank split. Also, save the date
2012 * for the new blank split. */
2013 if (trans == blank_trans)
2014 {
2015 if (do_commit)
2016 {
2017 info->blank_split_guid = *guid_null ();
2018 info->auto_complete = FALSE;
2019 blank_split = NULL;
2020 info->last_date_entered = xaccTransGetDate (trans);
2021 }
2022 else
2023 info->blank_split_edited = TRUE;
2024 }
2025
2026 /* If requested, commit the current transaction and set the pending
2027 * transaction to NULL. */
2028 if (do_commit)
2029 {
2030 g_assert (trans == blank_trans || trans == pending_trans);
2031 if (pending_trans == trans)
2032 {
2033 pending_trans = NULL;
2034 info->pending_trans_guid = *guid_null ();
2035 }
2036 unreconcile_splits (reg);
2037 xaccTransCommitEdit (trans);
2038 xaccTransRecordPrice (trans, PRICE_SOURCE_SPLIT_REG);
2039 }
2040
2041 gnc_table_clear_current_cursor_changes (reg->table);
2042
2043 gnc_resume_gui_refresh ();
2044
2045 LEAVE (" ");
2046 return TRUE;
2047}
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
void xaccTransRecordPrice(Transaction *trans, PriceSource source)
The xaccTransRecordPrice() method iterates through the splits and and record the non-currency equival...
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256
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 gnc_table_set_virt_cell_data(Table *table, VirtualCellLocation vcell_loc, gconstpointer vcell_data)
Set the virtual cell data for a particular location.
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.

◆ gnc_split_register_save_data_destroy()

void gnc_split_register_save_data_destroy ( SRSaveData *  sd)

Definition at line 895 of file split-register-model-save.c.

896{
897 g_free (sd);
898}

◆ gnc_split_register_save_data_new()

SRSaveData * gnc_split_register_save_data_new ( Transaction *  trans,
Split *  split,
gboolean  expanded 
)

Definition at line 875 of file split-register-model-save.c.

877{
878 SRSaveData *sd;
879
880 g_return_val_if_fail (trans != NULL, NULL);
881 g_return_val_if_fail (split != NULL, NULL);
882
883 sd = g_new0 (SRSaveData, 1);
884
885 sd->trans = trans;
886 sd->split = split;
887 sd->handled_dc = FALSE;
888 sd->do_scrub = FALSE;
889 sd->reg_expanded = expanded;
890
891 return sd;
892}

◆ gnc_split_register_set_auto_complete()

void gnc_split_register_set_auto_complete ( SplitRegister *  reg,
gboolean  do_auto_complete 
)

Sets whether a register uses auto-completion.

Parameters
rega ::SplitRegister
do_auto_completeTRUE to use auto-completion, FALSE otherwise

Definition at line 3038 of file split-register.c.

3040{
3041 g_return_if_fail (reg);
3042 reg->do_auto_complete = do_auto_complete;
3043}

◆ gnc_split_register_set_cell_fractions()

void gnc_split_register_set_cell_fractions ( SplitRegister *  reg,
Split *  split 
)

Definition at line 340 of file split-register-util.c.

341{
342 Account *split_account;
343 Account *reg_account;
344 Transaction *trans;
345 gnc_commodity *trans_currency; /* or default currency if no transaction */
346 PriceCell *cell;
347 int fraction;
348 gboolean trading_accts;
349 gnc_commodity *commodity;
350
351 /* This function must use the same algorithm as gnc_split_register_get_shares_entry
352 and gnc_split_register_get_debcred_entry. Changes here may require changes in
353 one of them or vice versa. */
354
355 /* If the split has a new account use that, otherwise use the one it
356 had before we started editing it. */
357 split_account = gnc_split_register_get_account (reg, XFRM_CELL);
358 if (!split_account)
359 split_account = xaccSplitGetAccount (split);
360
361 reg_account = gnc_split_register_get_default_account (reg);
362
363 trans = xaccSplitGetParent (split);
364 if (trans)
365 {
366 trading_accts = xaccTransUseTradingAccounts (trans);
367 trans_currency = xaccTransGetCurrency (trans);
368 }
369 else
370 {
371 /* It should be ok to use the current book since that's what
372 gnc_split_register_get_account uses to find the account. */
373 trading_accts = qof_book_use_trading_accounts (gnc_get_current_book());
374 trans_currency = gnc_default_currency();
375 }
376
377 /* What follows is similar to the tests in gnc_split_register_get_debcred_entry */
378 if (trading_accts)
379 {
380 if (reg->type == STOCK_REGISTER ||
381 reg->type == CURRENCY_REGISTER ||
382 reg->type == PORTFOLIO_LEDGER)
383 {
384 /* These tests are similar to gnc_split_register_use_security_cells */
385 if (!split_account)
386 commodity = trans_currency;
387 else if (trading_accts &&
389 commodity = trans_currency;
390 else if (xaccAccountIsPriced (split_account))
391 commodity = trans_currency;
392 else
393 commodity = xaccAccountGetCommodity (split_account);
394 }
395 else
396 {
397 commodity = xaccAccountGetCommodity (split_account);
398 }
399 }
400 else
401 {
402 /* Not trading accounts */
403 if (reg->type == STOCK_REGISTER ||
404 reg->type == CURRENCY_REGISTER ||
405 reg->type == PORTFOLIO_LEDGER)
406 commodity = trans_currency;
407 else
408 commodity = xaccAccountGetCommodity (reg_account);
409 }
410 if (!commodity)
411 commodity = gnc_default_currency ();
412
413 fraction = gnc_commodity_get_fraction (commodity);
414
415 cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
416 DEBT_CELL);
417 gnc_price_cell_set_fraction (cell, fraction);
418
419 cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
420 CRED_CELL);
421 gnc_price_cell_set_fraction (cell, fraction);
422
423 cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
424 SHRS_CELL);
425
426 /* gnc_split_register_get_shares_entry always uses the split's commodity */
427 if (split_account)
429 else
431}
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
Definition Account.cpp:2745
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false.
Definition Account.cpp:4551
gboolean qof_book_use_trading_accounts(const QofBook *book)
Returns flag indicating whether this book uses trading accounts.
Definition qofbook.cpp:921
void gnc_price_cell_set_fraction(PriceCell *cell, int fraction)
Sets the fraction used for rounding.
Definition pricecell.c:242
#define GNC_COMMODITY_MAX_FRACTION
Max fraction is 10^9 because 10^10 would require changing it to an int64_t.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.

◆ gnc_split_register_set_last_num()

void gnc_split_register_set_last_num ( SplitRegister *  reg,
const char *  num 
)

Definition at line 503 of file split-register-util.c.

504{
505 Account *account;
506
507 account = gnc_split_register_get_default_account (reg);
508 if (!account)
509 return;
510
511 xaccAccountSetLastNum (account, num);
512}

◆ gnc_split_register_set_read_only()

void gnc_split_register_set_read_only ( SplitRegister *  reg,
gboolean  read_only 
)

Sets whether a register window is "read only".

Parameters
rega ::SplitRegister
read_onlyTRUE to use "read only" mode, FALSE otherwise

Definition at line 3197 of file split-register.c.

3198{
3199 gnc_table_model_set_read_only (reg->table->model, read_only);
3200}

◆ gnc_split_register_set_reverse_sort()

void gnc_split_register_set_reverse_sort ( SplitRegister *  reg,
gboolean  reverse_sort 
)

Sets a split register's reverse sort order based on register.

Parameters
rega ::SplitRegister
reverse_sortTRUE reverse sort order, FALSE default

Definition at line 3031 of file split-register.c.

3032{
3033 g_return_if_fail (reg);
3034 gnc_table_model_set_reverse_sort (reg->table->model, reverse_sort);
3035}

◆ gnc_split_register_set_template_account()

void gnc_split_register_set_template_account ( SplitRegister *  reg,
Account template_account 
)

Set the template account for use in a template register.

Parameters
rega ::SplitRegister
template_accountthe account to use for the template

Definition at line 117 of file split-register-util.c.

119{
120 SRInfo *info = gnc_split_register_get_info (reg);
121
122 g_return_if_fail (reg != NULL);
123
124 info->template_account = *xaccAccountGetGUID (template_account);
125}

◆ gnc_split_register_set_trans_visible()

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.

If only_blank_split is TRUE, only the row used for entering an additional split is affected. Despite the name, this should not be confused with the "blank split" row used for entering the first split of a brand-new transaction. Instead, here it only refers to rows not tied to any split at all, such as those created for entering new splits on old transactions or the 2nd through nth split on brand-new transactions.

Definition at line 317 of file split-register-util.c.

321{
322 CursorClass cursor_class;
323
324 while (TRUE)
325 {
326 vcell_loc.virt_row++;
327
328 cursor_class = gnc_split_register_get_cursor_class (reg, vcell_loc);
329 if (cursor_class != CURSOR_CLASS_SPLIT)
330 return;
331
332 if (only_blank_split && gnc_split_register_get_split (reg, vcell_loc))
333 continue;
334
335 gnc_table_set_virt_cell_visible (reg->table, vcell_loc, visible);
336 }
337}
void gnc_table_set_virt_cell_visible(Table *table, VirtualCellLocation vcell_loc, gboolean visible)
Set the visibility flag for a particular location.

◆ gnc_split_register_show_present_divider()

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, and after.

This will only make sense if the splits are ordered primarily by post date.

Definition at line 2577 of file split-register.c.

2579{
2580 SRInfo* info = gnc_split_register_get_info (reg);
2581
2582 if (reg == NULL)
2583 return;
2584
2585 info->show_present_divider = show_present;
2586}

◆ gnc_split_register_show_trans()

void gnc_split_register_show_trans ( SplitRegister *  reg,
VirtualCellLocation  start_loc 
)

Definition at line 286 of file split-register-util.c.

288{
289 VirtualCellLocation end_loc;
290 int v_row;
291
292 end_loc = start_loc;
293
294 for (v_row = end_loc.virt_row + 1;
295 v_row < reg->table->num_virt_rows; v_row++)
296 {
297 VirtualCellLocation vc_loc = { v_row, 0 };
298 CursorClass cursor_class;
299
300 cursor_class = gnc_split_register_get_cursor_class (reg, vc_loc);
301 if (cursor_class == CURSOR_CLASS_TRANS)
302 break;
303
304 if (cursor_class != CURSOR_CLASS_SPLIT)
305 {
306 v_row--;
307 break;
308 }
309 }
310
311 end_loc.virt_row = MIN (v_row, reg->table->num_virt_rows - 1);
312
313 gnc_table_show_range (reg->table, start_loc, end_loc);
314}
void gnc_table_show_range(Table *table, VirtualCellLocation start_loc, VirtualCellLocation end_loc)
Try to show the whole range in the register.

◆ gnc_split_register_split_needs_amount()

gboolean gnc_split_register_split_needs_amount ( SplitRegister *  reg,
Split *  split 
)

Definition at line 394 of file split-register-model-save.c.

395{
396 Transaction *txn = xaccSplitGetParent (split);
397 Account *acc = xaccSplitGetAccount (split);
398
399 return gnc_split_register_needs_conv_rate (reg, txn, acc);
400}

◆ gnc_split_register_unvoid_current_trans()

void gnc_split_register_unvoid_current_trans ( SplitRegister *  reg)

Unvoids the transaction associated with the current cursor, if non-NULL.

Definition at line 1387 of file split-register.c.

1388{
1389 SRInfo* info = gnc_split_register_get_info (reg);
1390 Transaction* pending_trans;
1391 Transaction* trans;
1392 Split* blank_split;
1393 Split* split;
1394
1395 if (!reg) return;
1396
1397 blank_split = xaccSplitLookup (&info->blank_split_guid,
1398 gnc_get_current_book ());
1399 pending_trans = xaccTransLookup (&info->pending_trans_guid,
1400 gnc_get_current_book ());
1401
1402 /* get the current split based on cursor position */
1404 if (split == NULL)
1405 return;
1406
1407 /* Bail if trying to unvoid the blank split. */
1408 if (split == blank_split)
1409 return;
1410
1411 /* not voided. */
1412 if (xaccSplitGetReconcile (split) != VREC)
1413 return;
1414
1415 info->trans_expanded = FALSE;
1416
1417 gnc_suspend_gui_refresh ();
1418
1419 trans = xaccSplitGetParent (split);
1420
1421 xaccTransUnvoid (trans);
1422
1423 /* Check pending transaction */
1424 if (trans == pending_trans)
1425 {
1426 info->pending_trans_guid = *guid_null ();
1427 pending_trans = NULL;
1428 }
1429
1430 gnc_resume_gui_refresh ();
1431}
void xaccTransUnvoid(Transaction *trans)
xaccTransUnvoid restores a voided transaction to its original state.
char xaccSplitGetReconcile(const Split *split)
Returns the value of the reconcile flag.
#define VREC
split is void
Definition Split.h:77

◆ gnc_split_register_void_current_trans()

void gnc_split_register_void_current_trans ( SplitRegister *  reg,
const char *  reason 
)

Voids the transaction associated with the current cursor, if non-NULL.

Definition at line 1337 of file split-register.c.

1338{
1339 SRInfo* info = gnc_split_register_get_info (reg);
1340 Transaction* pending_trans;
1341 Transaction* trans;
1342 Split* blank_split;
1343 Split* split;
1344
1345 if (!reg) return;
1346
1347 blank_split = xaccSplitLookup (&info->blank_split_guid,
1348 gnc_get_current_book ());
1349 pending_trans = xaccTransLookup (&info->pending_trans_guid,
1350 gnc_get_current_book ());
1351
1352 /* get the current split based on cursor position */
1354 if (split == NULL)
1355 return;
1356
1357 /* Bail if trying to void the blank split. */
1358 if (split == blank_split)
1359 return;
1360
1361 /* already voided. */
1362 if (xaccSplitGetReconcile (split) == VREC)
1363 return;
1364
1365 info->trans_expanded = FALSE;
1366
1367 gnc_suspend_gui_refresh ();
1368
1369 trans = xaccSplitGetParent (split);
1370 xaccTransVoid (trans, reason);
1371
1372 /* Check pending transaction */
1373 if (trans == pending_trans)
1374 {
1375 info->pending_trans_guid = *guid_null ();
1376 pending_trans = NULL;
1377 }
1378 if (xaccTransIsOpen (trans))
1379 {
1380 PERR ("We should not be voiding an open transaction.");
1381 xaccTransCommitEdit (trans);
1382 }
1383 gnc_resume_gui_refresh ();
1384}
void xaccTransVoid(Transaction *trans, const char *reason)
xaccTransVoid voids a transaction.

◆ gnc_template_register_model_add_save_handlers()

void gnc_template_register_model_add_save_handlers ( TableModel model)

Definition at line 839 of file split-register-model-save.c.

840{
841 g_return_if_fail (model != NULL);
842
843 gnc_split_register_model_add_save_handlers (model);
844
845 gnc_table_model_set_save_handler (model,
846 gnc_template_register_save_unexpected_cell,
847 DATE_CELL);
848
849 gnc_table_model_set_save_handler (model,
850 gnc_template_register_save_unexpected_cell,
851 DDUE_CELL);
852
853 gnc_table_model_set_save_handler (model,
854 gnc_template_register_save_xfrm_cell,
855 XFRM_CELL);
856
857 gnc_table_model_set_save_handler (model,
858 gnc_template_register_save_mxfrm_cell,
859 MXFRM_CELL);
860
861 gnc_table_model_set_save_handler (model,
862 gnc_template_register_save_debcred_cell,
863 FDEBT_CELL);
864
865 gnc_table_model_set_save_handler (model,
866 gnc_template_register_save_debcred_cell,
867 FCRED_CELL);
868
869 gnc_table_model_set_save_handler (model,
870 gnc_template_register_save_shares_cell,
871 SHRS_CELL);
872}

◆ gnc_template_register_model_new()

TableModel * gnc_template_register_model_new ( void  )

Definition at line 2909 of file split-register-model.c.

2910{
2911 TableModel* model;
2912
2913 model = gnc_split_register_model_new();
2914
2915 gnc_table_model_set_entry_handler (
2916 model, gnc_split_register_get_inactive_date_entry, DATE_CELL);
2917
2918 gnc_table_model_set_entry_handler (
2919 model, gnc_split_register_get_inactive_date_entry, DDUE_CELL);
2920
2921 gnc_table_model_set_io_flags_handler (
2922 model, gnc_split_register_get_inactive_io_flags, DATE_CELL);
2923
2924 gnc_table_model_set_io_flags_handler (
2925 model, gnc_split_register_get_inactive_io_flags, DDUE_CELL);
2926
2927 gnc_table_model_set_entry_handler (
2928 model, gnc_template_register_get_xfrm_entry, XFRM_CELL);
2929
2930 gnc_table_model_set_entry_handler (
2931 model, gnc_template_register_get_fdebt_entry, FDEBT_CELL);
2932
2933 gnc_table_model_set_entry_handler (
2934 model, gnc_template_register_get_fcred_entry, FCRED_CELL);
2935
2936 gnc_table_model_set_entry_handler (
2937 model, gnc_template_register_get_debcred_entry, DEBT_CELL);
2938
2939 gnc_table_model_set_entry_handler (
2940 model, gnc_template_register_get_debcred_entry, CRED_CELL);
2941
2942 gnc_table_model_set_io_flags_handler (
2943 model, gnc_split_register_get_standard_io_flags, FCRED_CELL);
2944
2945 gnc_table_model_set_io_flags_handler (
2946 model, gnc_split_register_get_standard_io_flags, FDEBT_CELL);
2947
2948 gnc_template_register_model_add_save_handlers (model);
2949
2950 return model;
2951}