Register preference "Jump action for multiple splits"

Make the behaviour when the "Jump" operation encounters a transaction with
more than two splits configurable.

This can be configured as:
* Do nothing (this is the default)
* Use the split with the largest value
* Use the split with the smallest value

This makes it much easier to jump between accounts for stock transactions
that include splits for fees and taxes, or dividend transactions that have
a zero value split for the stock account.
This commit is contained in:
Simon Arlott 2023-06-03 21:18:54 +01:00
parent 6be4c3c363
commit d924e3f624
No known key found for this signature in database
GPG Key ID: DF001BFD83E75990
4 changed files with 199 additions and 25 deletions

View File

@ -91,6 +91,14 @@
#include "qofbookslots.h" #include "qofbookslots.h"
#include "gnc-gtk-utils.h" #include "gnc-gtk-utils.h"
/* gschema: org.gnucash.GnuCash.general.register.JumpMultipleSplits */
typedef enum : gint
{
JUMP_DEFAULT = 0, /* Do nothing */
JUMP_LARGEST_VALUE_FIRST_SPLIT = 1,
JUMP_SMALLEST_VALUE_FIRST_SPLIT = 2,
} GncPrefJumpMultSplits;
/* This static indicates the debugging module that this .o belongs to. */ /* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_GUI; static QofLogModule log_module = GNC_MOD_GUI;
@ -4854,6 +4862,68 @@ gnc_plugin_page_register_cmd_exchange_rate (GSimpleAction *simple,
LEAVE (" "); LEAVE (" ");
} }
static Split*
jump_multiple_splits_by_value (Account *account, Split *split, gboolean largest)
{
Transaction *trans;
SplitList *splits;
Split *other_split = NULL;
gnc_numeric best;
int cmp = largest ? 1 : -1;
trans = xaccSplitGetParent(split);
if (!trans)
return NULL;
for (splits = xaccTransGetSplitList(trans); splits; splits = splits->next)
{
Split *s = (Split*)splits->data;
gnc_numeric value;
if (!xaccTransStillHasSplit(trans, s))
continue;
if (xaccSplitGetAccount(s) == account)
continue;
value = gnc_numeric_abs(xaccSplitGetValue(s));
if (gnc_numeric_check(value))
continue;
/* For splits with the same value as the best, the first split
* encountered is used.
*/
if (other_split && gnc_numeric_compare(value, best) != cmp)
continue;
best = value;
other_split = s;
}
return other_split;
}
static Split*
jump_multiple_splits (Account* account, Split *split)
{
GncPrefJumpMultSplits mode = (GncPrefJumpMultSplits)gnc_prefs_get_enum(GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_JUMP_MULT_SPLITS);
switch (mode)
{
case JUMP_LARGEST_VALUE_FIRST_SPLIT:
return jump_multiple_splits_by_value (account, split, TRUE);
case JUMP_SMALLEST_VALUE_FIRST_SPLIT:
return jump_multiple_splits_by_value (account, split, FALSE);
case JUMP_DEFAULT:
default:
break;
}
return NULL;
}
static void static void
gnc_plugin_page_register_cmd_jump (GSimpleAction *simple, gnc_plugin_page_register_cmd_jump (GSimpleAction *simple,
GVariant *paramter, GVariant *paramter,
@ -4911,7 +4981,9 @@ gnc_plugin_page_register_cmd_jump (GSimpleAction *simple,
* *
* If you've selected a split for this account, for consistency with * If you've selected a split for this account, for consistency with
* selecting the split of another account we should do nothing. * selecting the split of another account we should do nothing.
* You're already on the account for the split you selected. * You're already on the account for the split you selected. Jumping
* to the "other" account now would make the "multiple split"
* options confusing.
* *
* We could jump to a different anchoring split but that'll be very * We could jump to a different anchoring split but that'll be very
* subtle and only cause problems because it'll have to save any * subtle and only cause problems because it'll have to save any
@ -4921,13 +4993,19 @@ gnc_plugin_page_register_cmd_jump (GSimpleAction *simple,
return; return;
} }
split = xaccSplitGetOtherSplit (split); Split* other_split = xaccSplitGetOtherSplit (split);
if (split == NULL) if (other_split == NULL)
{
other_split = jump_multiple_splits (account, split);
}
if (other_split == NULL)
{ {
LEAVE ("no split (2)"); LEAVE ("no split (2)");
return; return;
} }
split = other_split;
account = xaccSplitGetAccount (split); account = xaccSplitGetAccount (split);
if (account == NULL) if (account == NULL)
{ {

View File

@ -235,6 +235,12 @@
<child name="report" schema="org.gnucash.GnuCash.general.report"/> <child name="report" schema="org.gnucash.GnuCash.general.report"/>
</schema> </schema>
<enum id="org.gnucash.GnuCash.general.register.JumpMultipleSplits"><!-- enum GncPrefJumpMultSplits -->
<value nick="default" value="0"/>
<value nick="largest-value-first-split" value="1"/>
<value nick="smallest-value-first-split" value="2"/>
</enum>
<schema id="org.gnucash.GnuCash.general.register" path="/org/gnucash/GnuCash/general/register/"> <schema id="org.gnucash.GnuCash.general.register" path="/org/gnucash/GnuCash/general/register/">
<key name="use-gnucash-color-theme" type="b"> <key name="use-gnucash-color-theme" type="b">
<default>true</default> <default>true</default>
@ -256,6 +262,11 @@
<summary>Move to Transfer field when memorised transaction auto filled</summary> <summary>Move to Transfer field when memorised transaction auto filled</summary>
<description>If active then after a memorised transaction is automatically filled in the cursor will move to the Transfer field. If not active then it skips to the value field.</description> <description>If active then after a memorised transaction is automatically filled in the cursor will move to the Transfer field. If not active then it skips to the value field.</description>
</key> </key>
<key name="jump-multiple-splits" enum="org.gnucash.GnuCash.general.register.JumpMultipleSplits">
<default>'default'</default>
<summary>"Jump" behaviour when there are multiple splits</summary>
<description>Select how the "Jump" operation should behave when a transaction has multiple splits.</description>
</key>
<key name="use-new-window" type="b"> <key name="use-new-window" type="b">
<default>false</default> <default>false</default>
<summary>Create a new window for each new register</summary> <summary>Create a new window for each new register</summary>
@ -337,7 +348,7 @@
<description>This sets the number of characters before auto complete starts for description, notes and memo fields.</description> <description>This sets the number of characters before auto complete starts for description, notes and memo fields.</description>
</key> </key>
</schema> </schema>
<schema id="org.gnucash.GnuCash.general.report" path="/org/gnucash/GnuCash/general/report/"> <schema id="org.gnucash.GnuCash.general.report" path="/org/gnucash/GnuCash/general/report/">
<key name="use-new-window" type="b"> <key name="use-new-window" type="b">
<default>false</default> <default>false</default>

View File

@ -2578,7 +2578,9 @@ many months before the current month</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="label" translatable="yes">&lt;b&gt;Reconciling&lt;/b&gt;</property> <property name="label" translatable="yes">&lt;b&gt;Jump action for multiple splits&lt;/b&gt;</property>
<property name="tooltip-markup">Transaction jump action when there are more than two splits.</property>
<property name="tooltip-text" translatable="yes">Transaction jump action when there are more than two splits.</property>
<property name="use-markup">True</property> <property name="use-markup">True</property>
</object> </object>
<packing> <packing>
@ -2587,16 +2589,17 @@ many months before the current month</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="pref/dialogs.reconcile/check-cleared"> <object class="GtkRadioButton" id="pref/general.register/jump-multiple-splits=default">
<property name="label" translatable="yes">Check cleared _transactions</property> <property name="label" translatable="yes">Do _nothing</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<property name="has-tooltip">True</property> <property name="has-tooltip">True</property>
<property name="tooltip-markup">Pre-check cleared transactions when creating a reconcile dialog.</property> <property name="tooltip-markup">Do nothing.</property>
<property name="tooltip-text" translatable="yes">Pre-check cleared transactions when creating a reconcile dialog.</property> <property name="tooltip-text" translatable="yes">Do nothing.</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<property name="active">True</property>
<property name="draw-indicator">True</property> <property name="draw-indicator">True</property>
</object> </object>
<packing> <packing>
@ -2605,17 +2608,19 @@ many months before the current month</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="pref/dialogs.reconcile/auto-cc-payment"> <object class="GtkRadioButton" id="pref/general.register/jump-multiple-splits=largest-value-first-split">
<property name="label" translatable="yes">Automatic credit card _payment</property> <property name="label" translatable="yes">Go to the first split with the _largest value</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<property name="has-tooltip">True</property> <property name="has-tooltip">True</property>
<property name="tooltip-markup">After reconciling a credit card statement, prompt the user to enter a credit card payment.</property> <property name="tooltip-markup">Use the first split with the largest value to determine the other account.</property>
<property name="tooltip-text" translatable="yes">After reconciling a credit card statement, prompt the user to enter a credit card payment.</property> <property name="tooltip-text" translatable="yes">Use the first split with the largest value to determine the other account.</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<property name="active">True</property>
<property name="draw-indicator">True</property> <property name="draw-indicator">True</property>
<property name="group">pref/general.register/jump-multiple-splits=default</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
@ -2623,17 +2628,19 @@ many months before the current month</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="pref/dialogs.reconcile/always-reconcile-to-today"> <object class="GtkRadioButton" id="pref/general.register/jump-multiple-splits=smallest-value-first-split">
<property name="label" translatable="yes">Always reconcile to t_oday</property> <property name="label" translatable="yes">Go to the first split with the _smallest value</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<property name="has-tooltip">True</property> <property name="has-tooltip">True</property>
<property name="tooltip-markup">Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations.</property> <property name="tooltip-markup">Use the first split with the smallest value to determine the other account.</property>
<property name="tooltip-text" translatable="yes">Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations.</property> <property name="tooltip-text" translatable="yes">Use the first split with the smallest value to determine the other account.</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<property name="active">True</property>
<property name="draw-indicator">True</property> <property name="draw-indicator">True</property>
<property name="group">pref/general.register/jump-multiple-splits=default</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
@ -2655,7 +2662,7 @@ many months before the current month</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="label" translatable="yes">&lt;b&gt;Graphics&lt;/b&gt;</property> <property name="label" translatable="yes">&lt;b&gt;Reconciling&lt;/b&gt;</property>
<property name="use-markup">True</property> <property name="use-markup">True</property>
</object> </object>
<packing> <packing>
@ -2663,6 +2670,83 @@ many months before the current month</property>
<property name="top-attach">10</property> <property name="top-attach">10</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="pref/dialogs.reconcile/check-cleared">
<property name="label" translatable="yes">Check cleared _transactions</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="has-tooltip">True</property>
<property name="tooltip-markup">Pre-check cleared transactions when creating a reconcile dialog.</property>
<property name="tooltip-text" translatable="yes">Pre-check cleared transactions when creating a reconcile dialog.</property>
<property name="halign">start</property>
<property name="use-underline">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">11</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="pref/dialogs.reconcile/auto-cc-payment">
<property name="label" translatable="yes">Automatic credit card _payment</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="has-tooltip">True</property>
<property name="tooltip-markup">After reconciling a credit card statement, prompt the user to enter a credit card payment.</property>
<property name="tooltip-text" translatable="yes">After reconciling a credit card statement, prompt the user to enter a credit card payment.</property>
<property name="halign">start</property>
<property name="use-underline">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">12</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="pref/dialogs.reconcile/always-reconcile-to-today">
<property name="label" translatable="yes">Always reconcile to t_oday</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="has-tooltip">True</property>
<property name="tooltip-markup">Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations.</property>
<property name="tooltip-text" translatable="yes">Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations.</property>
<property name="halign">start</property>
<property name="use-underline">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">13</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">14</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">&lt;b&gt;Graphics&lt;/b&gt;</property>
<property name="use-markup">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">15</property>
</packing>
</child>
<child> <child>
<object class="GtkCheckButton" id="pref/general.register/use-gnucash-color-theme"> <object class="GtkCheckButton" id="pref/general.register/use-gnucash-color-theme">
<property name="label" translatable="yes">_Use GnuCash built-in color theme</property> <property name="label" translatable="yes">_Use GnuCash built-in color theme</property>
@ -2678,7 +2762,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">11</property> <property name="top-attach">16</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2696,7 +2780,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">12</property> <property name="top-attach">17</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2714,7 +2798,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">13</property> <property name="top-attach">18</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2732,7 +2816,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">14</property> <property name="top-attach">19</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2742,7 +2826,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">15</property> <property name="top-attach">20</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2757,7 +2841,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">16</property> <property name="top-attach">21</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2775,7 +2859,7 @@ many months before the current month</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>
<property name="top-attach">17</property> <property name="top-attach">22</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -79,6 +79,7 @@
#define GNC_PREF_USE_GNUCASH_COLOR_THEME "use-gnucash-color-theme" #define GNC_PREF_USE_GNUCASH_COLOR_THEME "use-gnucash-color-theme"
#define GNC_PREF_TAB_TRANS_MEMORISED "tab-to-transfer-on-memorised" #define GNC_PREF_TAB_TRANS_MEMORISED "tab-to-transfer-on-memorised"
#define GNC_PREF_FUTURE_AFTER_BLANK "future-after-blank-transaction" #define GNC_PREF_FUTURE_AFTER_BLANK "future-after-blank-transaction"
#define GNC_PREF_JUMP_MULT_SPLITS "jump-multiple-splits"
/* Date preferences */ /* Date preferences */
#define GNC_PREF_START_CHOICE_ABS "start-choice-absolute" #define GNC_PREF_START_CHOICE_ABS "start-choice-absolute"
#define GNC_PREF_START_CHOICE_REL "start-choice-relative" #define GNC_PREF_START_CHOICE_REL "start-choice-relative"