This one a is quite an improvement on customisation of reports/charts. User can decide now what kind of point style should be used, including size, hover range and such.
On top of that:
- some tooltip improvements were made as well, including configurable one in GC's Properties.
- Price Scatterplot - fixed colors, got rid of a superfluous markers
- global defaults to be tuned in the next batch
Settings available at: GnuCash -> Edit -> Preferences -> Reports
Use the existence of void timestamp instead of void reason to
determine if a transaction is voided. A user can void a transaction
without providing a reason.
An account event should be generated for the original account if a lot is moved to a different account in xaccAccountInsertLot() as it is, if the lot is removed in xaccAccountRemoveLot().
The gain/loss displayed for splits in the "Splits free" is historical. It may or may not be correct. Instead, the gain should be calculated against the selected lot for appropriate splits.
Implements xaccSplitLotCapGain() to obtain the gain for the selected lot.
session_begin() runs dbi_library_test() (Bug #611936) on every open to
detect a libdbi/-ffast-math miscompilation that mangles 64-bit values.
The probe CREATEs, INSERTs into, SELECTs from and DROPs a temporary
table, so it needs write privileges on the database -- even for
SESSION_READ_ONLY. A least-privilege, read-only database user therefore
cannot open the book at all: the temporary-table create fails and
session_begin returns ERR_SQL_DBI_UNTESTABLE.
The defect the probe guards against is on the write side of libdbi, so it
can be neither triggered nor detected by a read-only session, which never
writes. Skip the probe when the session is opened SESSION_READ_ONLY, at
the two call sites a read-only open reaches (the SQLite session_begin and
the shared MySQL/PostgreSQL session_begin); the third call site is inside
the create branch, which read-only never enters. The write-capable modes
(NORMAL_OPEN, NEW_STORE, NEW_OVERWRITE, BREAK_LOCK) still run the probe
unchanged.
This lets a SELECT-only database user open a book read-only through the API.
qof_session_end() is documented to release the session lock and shut the
backend connection but it does not release the session lock in all scenarios
(BUG). qof_session_end() looked the backend up via qof_book_get_backend().
The book's backend pointer is only set by load() or a data-changing save() (an
empty book's save() early-returns before attaching it); begin() sets only the
session's own m_backend. So a session that creates a store and ends it without
loading or making a real change had a backend on the session but not on the
book: end() found none, skipped session_end(), and never released the lock --
it was only released later at destroy().
Because the fault is in backend-agnostic engine code it affects every backend
that locks at begin(): the SQL/DBI backends leave a stale row in the gnclock
table, and the XML/file backend leaves an abandoned <file>.LCK sentinel (with
no data file, since XML data is only written at save). The store then appears
locked to the next opener.
End the session's own backend (m_backend, always set at begin()) instead. It
already equals the book's backend whenever the latter is set, so the change is
a no-op for loaded/saved sessions and additionally covers the
created-but-not-attached case.
Add regression tests for both backends, each of which begins a create-mode
session, ends it without a data-changing save, and checks the lock is gone:
- test-backend-dbi-basic.cpp (test_dbi_new_store_end_releases_lock): reopens
the store and asserts it is not ERR_BACKEND_LOCKED.
- test-load-backend.cpp (test_new_store_end_releases_lock): asserts the XML
<file>.LCK lockfile has been removed.
Added has_stock_split field to Account private. This flag is set to true when xaccAccountRecomputeBalance() detects a stock-split split otherwise it is false. Defined and declared xaccAccountHasStockSplit() for use by the Lot Viewer to whether to display the check box.
The algorithm to determine the current adjusted_amount is implemented in xaccAccountRecomputeBalance().
If the balance or new balance is nil, the stock-split split is ignored as it isn't possible to calculate the stock-split ratio. This means the prior split adjusted amounts will not reflect the true current adjusted amounts. These are conditions that should be raised appropriately to the user with sufficient details for resolution.
Noted split_type field in Split exists but is not used...
Reset split_type field's data type to hold the type of the getter.
Implemented xaccSplitIsStockSplit() abstraction to limit the split type string reference to Split.cpp and propagated it's use.
The adjusted_amount field of a split will hold the stock split adjusted amount. The adjusted amount is initially the same as the original amount. When the account balances are recomputed and a stock-split split type is encountered, the ratio of the stock split will be applied to the preceding splits adjusted_amounts. If there are no stock splits in the split's account, the adjusted amount remains the original amount.
Promote the OFX/HBCI online_id to named engine accessors:
xaccSplitGetOnlineID / SetOnlineID / HasOnlineID
xaccAccountGetOnlineID / SetOnlineID
The getters return an instance-owned const char* (mirroring
xaccTransGetDocLink / xaccTransGetNotes), so the existing
add_methods_with_prefix auto-wrapper exposes them in the Python bindings
with no .i changes and no %newobject. They write to the same engine KVP
slot ("online_id") the desktop importer uses, so there is no data or
behavior change.
With the accessors in place the gnc_import_*_online_id wrappers in
import-utilities are redundant, so replace every call site (OFX,
AqBanking, and the generic matcher/backend) with them, delete
import-utilities.cpp, and drop the online_id declarations from
import-utilities.h (its importer preference-key macros are retained).
- The engine getters return an instance-owned const char* instead of a
g_strdup'd copy, so callers no longer free the result; the affected
locals are retyped const and their g_free()s dropped.
hash_account_online_ids() g_strdups before inserting, since its hash
table owns its keys (g_free key-destructor).
- xaccAccountSetOnlineID(acc, "") clears the slot, matching the OFX
"delete the online_id" intent (the old wrapper stored an empty string).
- Drop the two unused wrappers: gnc_import_set_trans_online_id (marked
"Not actually used") and gnc_import_trans_has_online_id (no callers).
- Add xaccSplitGet/SetOnlineID to the Split gmock so test-import-backend
links without import-utilities.
The "online-id" GObject property on Transaction (KVP slot "online_id")
was vestigial: GnuCash records the OFX/HBCI import identifier on the
bank/asset Split, not on the Transaction. Drop the property, its
get/set_property cases, the xaccTransClone special-case that cleared it,
and the corresponding test_trans_kvp_properties coverage.
When an already-committed split is moved to another transaction with
xaccSplitSetParent(), the split was marked dirty *after* the old
transaction was committed. trans_cleanup_commit() only drops a
moved-out split from the old transaction's split list when the split is
dirty at that commit, so the still-clean split was left dangling in the
old transaction's split list.
On the SQL/DBI backends, destroying the now-vacated old transaction then
deleted the moved split's KVP slots (online_id, cap-gains links, ...) by
the split's own GUID, even though the split now belongs to another
transaction. The split's native columns survive -- they are rewritten
under the new tx_guid -- but its slots are lost; in some sequences the
save fails outright with "UNIQUE constraint failed: transactions.guid".
The XML backend is unaffected because it re-serializes the whole book.
Mark the split dirty before committing the old transaction so
trans_cleanup_commit() removes it from the old transaction's split list,
as that code already intends. This is a no-op for split creation (the
overwhelmingly common caller), where the prior parent is NULL.
Add a DBI round-trip regression test (sqlite3, and mysql/pgsql when the
TEST_*_URL variables are set): seed a split carrying an online_id, save
and reload, reparent it onto another transaction, destroy the old
transaction, then save and reload again and assert the online_id
survived.
Free API key (personal/non-professional use) available at https://finnhub.io.
Set FINNHUB_API_KEY environment variable to API key to use this source.
As of June 2026, free tier API limit is 60 API calls/minute.
numerator/denominator properly
- Use GNC_HOW_DENOM_REDUCE | GNC_HOW_RND_ROUND to preserve precision while
avoiding overflows.
- Rearrange the function's tests to perform only one division or
multiplication instead of unconditionally dividing
- Rename the from_ and to_ variables to p(rice)1 and p2 to reduce
conflation with the input from and to.
Implements the approach suggested by jralls in PR #2222: instead of a
context menu action, introduce GncCellRendererLabel - a
GtkCellRendererText subclass that returns a read-only, selectable
GtkEntry when a cell is activated.
All numeric columns (Balance, Total, Cleared, Reconciled, Present,
Future Minimum, and their report/period variants) are affected because
they all go through gnc_tree_view_add_numeric_column.
Usage:
- Click once to select the row (unchanged behaviour)
- Click again on a numeric cell to activate it; the value appears in a
read-only entry field with the text pre-selected
- Ctrl+C copies the value to the clipboard; Escape or clicking away
dismisses the field without modifying the model
- Unicode bidi control characters (added by GnuCash for RTL display)
are stripped before showing the value so the copied text is clean
If qof_book_destroy is called on a QofBook* freshly created with
qof_book_new (usually because it was used to create a session that now
must be destroyed) it would try to empty the non-existent hash tables,
crashing.
This patch adds a “Run” command to the “Scheduled Transactions” tab to allow users to select the scheduled transactions to be included in a “Since Last Run…” window. If there are no instances of a selected transaction triggered by today’s date, the next instance is triggered.