diff --git a/gnucash/gnome-utils/dialog-preferences.c b/gnucash/gnome-utils/dialog-preferences.c index 2904d011e9..f4de4a5510 100644 --- a/gnucash/gnome-utils/dialog-preferences.c +++ b/gnucash/gnome-utils/dialog-preferences.c @@ -781,14 +781,18 @@ gnc_prefs_sort_pages (GtkNotebook *notebook) /*******************************/ static void -gnc_prefs_split_widget_name (const gchar *name, gchar **group, gchar **pref) +gnc_prefs_split_widget_name (const gchar *name, gchar **group, gchar **pref, gchar **value) { const gchar *group_with_pref = name + PREF_PREFIX_LEN; gchar **splits = g_strsplit (group_with_pref, "/", 0); + gchar **value_splits = g_strsplit (splits[1], "=", 0); *group = g_strdup (splits[0]); - *pref = g_strdup (splits[1]); + *pref = g_strdup (value_splits[0]); + if (value) + *value = g_strdup (value_splits[1]); /* may be NULL */ g_strfreev (splits); + g_strfreev (value_splits); } /****************************************************************************/ @@ -806,8 +810,8 @@ gnc_prefs_connect_font_button (GtkFontButton *fb) g_return_if_fail (GTK_IS_FONT_BUTTON(fb)); - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(fb)), &group, &pref); - gnc_prefs_bind (group, pref, G_OBJECT (fb), "font-name"); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(fb)), &group, &pref, NULL); + gnc_prefs_bind (group, pref, NULL, G_OBJECT (fb), "font-name"); g_free (group); g_free (pref); @@ -873,9 +877,9 @@ gnc_prefs_connect_file_chooser_button (GtkFileChooserButton *fcb, const gchar *b g_return_if_fail (GTK_FILE_CHOOSER_BUTTON(fcb)); if (boxname == NULL) - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(fcb)), &group, &pref); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(fcb)), &group, &pref, NULL); else - gnc_prefs_split_widget_name (boxname, &group, &pref); + gnc_prefs_split_widget_name (boxname, &group, &pref, NULL); uri = gnc_prefs_get_string (group, pref); @@ -990,16 +994,17 @@ file_chooser_clear_cb (GtkButton *button, gpointer user_data) static void gnc_prefs_connect_radio_button (GtkRadioButton *button) { - gchar *group, *pref; + gchar *group, *pref, *value; g_return_if_fail (GTK_IS_RADIO_BUTTON(button)); - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(button)), &group, &pref); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(button)), &group, &pref, &value); - gnc_prefs_bind (group, pref, G_OBJECT(button), "active"); + gnc_prefs_bind (group, pref, value, G_OBJECT(button), "active"); g_free (group); g_free (pref); + g_free (value); } /****************************************************************************/ @@ -1014,16 +1019,17 @@ gnc_prefs_connect_radio_button (GtkRadioButton *button) static void gnc_prefs_connect_check_button (GtkCheckButton *button) { - gchar *group, *pref; + gchar *group, *pref, *value; g_return_if_fail (GTK_IS_CHECK_BUTTON(button)); - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(button)), &group, &pref); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(button)), &group, &pref, &value); - gnc_prefs_bind (group, pref, G_OBJECT(button), "active"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(button), "active"); g_free (group); g_free (pref); + g_free (value); } /****************************************************************************/ @@ -1042,9 +1048,9 @@ gnc_prefs_connect_spin_button (GtkSpinButton *spin) g_return_if_fail (GTK_IS_SPIN_BUTTON(spin)); - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(spin)), &group, &pref); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(spin)), &group, &pref, NULL); - gnc_prefs_bind (group, pref, G_OBJECT(spin), "value"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(spin), "value"); g_free (group); g_free (pref); @@ -1065,9 +1071,9 @@ gnc_prefs_connect_combo_box (GtkComboBox *box) g_return_if_fail (GTK_IS_COMBO_BOX(box)); - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(box)), &group, &pref); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(box)), &group, &pref, NULL); - gnc_prefs_bind (group, pref, G_OBJECT(box), "active"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(box), "active"); g_free (group); g_free (pref); @@ -1088,9 +1094,9 @@ gnc_prefs_connect_currency_edit (GNCCurrencyEdit *gce, const gchar *boxname ) g_return_if_fail (GNC_IS_CURRENCY_EDIT(gce)); - gnc_prefs_split_widget_name (boxname, &group, &pref); + gnc_prefs_split_widget_name (boxname, &group, &pref, NULL); - gnc_prefs_bind (group, pref, G_OBJECT(gce), "mnemonic"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(gce), "mnemonic"); g_free (group); g_free (pref); @@ -1113,9 +1119,9 @@ gnc_prefs_connect_entry (GtkEntry *entry) g_return_if_fail (GTK_IS_ENTRY(entry)); - gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(entry)), &group, &pref); + gnc_prefs_split_widget_name (gtk_buildable_get_name (GTK_BUILDABLE(entry)), &group, &pref, NULL); - gnc_prefs_bind (group, pref, G_OBJECT(entry), "text"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(entry), "text"); g_free (group); g_free (pref); @@ -1136,9 +1142,9 @@ gnc_prefs_connect_period_select (GncPeriodSelect *period, const gchar *boxname ) g_return_if_fail (GNC_IS_PERIOD_SELECT(period)); - gnc_prefs_split_widget_name (boxname, &group, &pref); + gnc_prefs_split_widget_name (boxname, &group, &pref, NULL); - gnc_prefs_bind (group, pref, G_OBJECT(period), "active"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(period), "active"); g_free (group); g_free (pref); @@ -1159,9 +1165,9 @@ gnc_prefs_connect_date_edit (GNCDateEdit *gde , const gchar *boxname ) g_return_if_fail (GNC_IS_DATE_EDIT(gde)); - gnc_prefs_split_widget_name (boxname, &group, &pref); + gnc_prefs_split_widget_name (boxname, &group, &pref, NULL); - gnc_prefs_bind (group, pref, G_OBJECT(gde), "time"); + gnc_prefs_bind (group, pref, NULL, G_OBJECT(gde), "time"); g_free (group); g_free (pref); diff --git a/gnucash/gnome-utils/dialog-utils.c b/gnucash/gnome-utils/dialog-utils.c index 01f8c49b75..e96e4d77e3 100644 --- a/gnucash/gnome-utils/dialog-utils.c +++ b/gnucash/gnome-utils/dialog-utils.c @@ -749,18 +749,12 @@ gnc_dialog_run (GtkDialog *dialog, const gchar *pref_name) return response; /* Add in the checkboxes to find out if the answer should be remembered. */ -#if 0 if (GTK_IS_MESSAGE_DIALOG(dialog)) { GtkMessageType type; g_object_get(dialog, "message-type", &type, (gchar*)NULL); - ask = (type == GTK_MESSAGE_QUESTION); + ask = (type == GTK_MESSAGE_QUESTION || type == GTK_MESSAGE_WARNING); } - else - { - ask = FALSE; - } -#endif perm = gtk_check_button_new_with_mnemonic (ask ? _("Remember and don't _ask me again.") diff --git a/gnucash/gnome/dialog-lot-viewer.c b/gnucash/gnome/dialog-lot-viewer.c index cf1d4a69ca..061617a9ab 100644 --- a/gnucash/gnome/dialog-lot-viewer.c +++ b/gnucash/gnome/dialog-lot-viewer.c @@ -1129,10 +1129,10 @@ lv_create (GNCLotViewer *lv, GtkWindow *parent) { GObject *object; object = gtk_builder_get_object (builder, "lot_vpaned"); - gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_VPOS, object, "position"); + gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_VPOS, NULL, object, "position"); object = gtk_builder_get_object (builder, "lot_hpaned"); - gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_HPOS, object, "position"); + gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_HPOS, NULL, object, "position"); } lv->selected_lot = NULL; diff --git a/gnucash/gnome/dialog-tax-info.c b/gnucash/gnome/dialog-tax-info.c index dd1feb2f79..dcb093b34a 100644 --- a/gnucash/gnome/dialog-tax-info.c +++ b/gnucash/gnome/dialog-tax-info.c @@ -1509,7 +1509,7 @@ gnc_tax_info_dialog_create (GtkWidget * parent, TaxInfoDialog *ti_dialog) if (gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_GEOMETRY)) { GObject *object = gtk_builder_get_object (builder, "paned"); - gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_PANED_POS, object, "position"); + gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_PANED_POS, NULL, object, "position"); } g_object_unref (builder); } diff --git a/gnucash/gnome/gnc-plugin-business.c b/gnucash/gnome/gnc-plugin-business.c index a4c62e83f5..136e6d1082 100644 --- a/gnucash/gnome/gnc-plugin-business.c +++ b/gnucash/gnome/gnc-plugin-business.c @@ -968,7 +968,7 @@ bind_extra_toolbuttons_visibility (GncMainWindow *mainwindow) { gnc_prefs_bind (GNC_PREFS_GROUP_INVOICE, GNC_PREF_EXTRA_TOOLBUTTONS, - G_OBJECT(tool_item), "visible"); + NULL, G_OBJECT(tool_item), "visible"); } } @@ -984,7 +984,7 @@ bind_extra_toolbuttons_visibility (GncMainWindow *mainwindow) { gnc_prefs_bind (GNC_PREFS_GROUP_INVOICE, GNC_PREF_EXTRA_TOOLBUTTONS, - G_OBJECT(tool_item), "visible"); + NULL, G_OBJECT(tool_item), "visible"); } } } diff --git a/gnucash/gnome/gnc-plugin-page-register.cpp b/gnucash/gnome/gnc-plugin-page-register.cpp index 49d594b11d..b5f5fcf494 100644 --- a/gnucash/gnome/gnc-plugin-page-register.cpp +++ b/gnucash/gnome/gnc-plugin-page-register.cpp @@ -91,6 +91,14 @@ #include "qofbookslots.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. */ static QofLogModule log_module = GNC_MOD_GUI; @@ -4854,6 +4862,115 @@ gnc_plugin_page_register_cmd_exchange_rate (GSimpleAction *simple, LEAVE (" "); } +static Split* +jump_multiple_splits_by_single_account (Account *account, Split *split) +{ + Transaction *trans; + SplitList *splits; + Account *other_account = NULL; + Split *other_split = NULL; + + trans = xaccSplitGetParent(split); + if (!trans) + return NULL; + + for (splits = xaccTransGetSplitList(trans); splits; splits = splits->next) + { + Split *s = (Split*)splits->data; + Account *a = xaccSplitGetAccount(s); + + if (!xaccTransStillHasSplit(trans, s)) + continue; + + if (a == account) + continue; + + if (other_split) + { + if (other_account != a) + return NULL; + + continue; + } + + other_account = a; + other_split = s; + } + + // Jump to the same account so that the right warning is triggered + if (!other_split) + other_split = split; + + return other_split; +} + +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; + } + + // Jump to the same account so that the right warning is triggered + if (!other_split) + other_split = split; + + 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; + } + + // If there's only one other account, use that one + return jump_multiple_splits_by_single_account (account, split); +} + static void gnc_plugin_page_register_cmd_jump (GSimpleAction *simple, GVariant *paramter, @@ -4868,6 +4985,8 @@ gnc_plugin_page_register_cmd_jump (GSimpleAction *simple, Account* account; Account* leader; Split* split; + Split* other_split; + gboolean multiple_splits; ENTER ("(action %p, page %p)", simple, page); @@ -4896,16 +5015,62 @@ gnc_plugin_page_register_cmd_jump (GSimpleAction *simple, return; } + other_split = xaccSplitGetOtherSplit (split); + multiple_splits = other_split == NULL; + leader = gnc_ledger_display_leader (priv->ledger); if (account == leader) { - split = xaccSplitGetOtherSplit (split); - if (split == NULL) + CursorClass cursor_class = gnc_split_register_get_current_cursor_class (reg); + if (cursor_class == CURSOR_CLASS_SPLIT) { + /* If you've selected the transaction itself, we jump to the "other" + * account corresponding to the anchoring split. + * + * If you've selected the split for another account, we jump to that + * split's account (account != leader, so this block is never + * reached). + * + * If you've selected a split for this account, for consistency with + * selecting the split of another account we should do nothing. + * 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 + * subtle and only cause problems because it'll have to save any + * modifications to the current register. + */ + LEAVE ("split for this account"); + return; + } + + if (multiple_splits) + { + other_split = jump_multiple_splits (account, split); + } + if (other_split == NULL) + { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(window), + (GtkDialogFlags)(GTK_DIALOG_MODAL + | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_ERROR, + GTK_BUTTONS_NONE, + "%s", + _("Unable to jump to other account")); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog), + "%s", _("This transaction involves more than one other account. Select a specific split to jump to that account.")); + gtk_dialog_add_button (GTK_DIALOG(dialog), _("_OK"), GTK_RESPONSE_OK); + gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_REG_TRANS_JUMP_MULTIPLE_SPLITS); + gtk_widget_destroy (dialog); + LEAVE ("no split (2)"); return; } + split = other_split; + account = xaccSplitGetAccount (split); if (account == NULL) { @@ -4915,6 +5080,20 @@ gnc_plugin_page_register_cmd_jump (GSimpleAction *simple, if (account == leader) { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(window), + (GtkDialogFlags)(GTK_DIALOG_MODAL + | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_ERROR, + GTK_BUTTONS_NONE, + "%s", + _("Unable to jump to other account")); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog), + "%s", _("This transaction only involves the current account so there is no other account to jump to.")); + gtk_dialog_add_button (GTK_DIALOG(dialog), _("_OK"), GTK_RESPONSE_OK); + gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_REG_TRANS_JUMP_SINGLE_ACCOUNT); + gtk_widget_destroy (dialog); + LEAVE ("register open for account"); return; } @@ -4930,11 +5109,30 @@ gnc_plugin_page_register_cmd_jump (GSimpleAction *simple, gnc_main_window_open_page (GNC_MAIN_WINDOW (window), new_page); gsr = gnc_plugin_page_register_get_gsr (new_page); + SplitRegister *new_page_reg = gnc_ledger_display_get_split_register (gsr->ledger); + gboolean jump_twice = FALSE; + + /* Selecting the split (instead of just the transaction to open the "other" + * account) requires jumping a second time after expanding the transaction, + * in the basic and auto ledger modes. + */ + if (new_page_reg->style != REG_STYLE_JOURNAL) + jump_twice = TRUE; + /* Test for visibility of split */ if (gnc_split_reg_clear_filter_for_split (gsr, split)) gnc_plugin_page_register_clear_current_filter (GNC_PLUGIN_PAGE(new_page)); gnc_split_reg_jump_to_split (gsr, split); + + if (multiple_splits && jump_twice) + { + /* Expand the transaction for the basic and auto ledger to identify the + * split in this register, but only if there are more than two splits. + */ + gnc_split_register_expand_current_trans (new_page_reg, TRUE); + gnc_split_reg_jump_to_split (gsr, split); + } LEAVE (" "); } diff --git a/gnucash/gschemas/org.gnucash.GnuCash.gschema.xml.in b/gnucash/gschemas/org.gnucash.GnuCash.gschema.xml.in index 933a6507c0..3d32c99b5a 100644 --- a/gnucash/gschemas/org.gnucash.GnuCash.gschema.xml.in +++ b/gnucash/gschemas/org.gnucash.GnuCash.gschema.xml.in @@ -235,6 +235,12 @@ + + + + + + true @@ -256,6 +262,11 @@ Move to Transfer field when memorised transaction auto filled 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. + + 'default' + "Jump" behaviour when there are multiple splits + Select how the "Jump" operation should behave when a transaction has multiple splits. + false Create a new window for each new register @@ -337,7 +348,7 @@ This sets the number of characters before auto complete starts for description, notes and memo fields. - + false diff --git a/gnucash/gschemas/org.gnucash.GnuCash.warnings.gschema.xml.in b/gnucash/gschemas/org.gnucash.GnuCash.warnings.gschema.xml.in index 8db0304cd7..253553124c 100644 --- a/gnucash/gschemas/org.gnucash.GnuCash.warnings.gschema.xml.in +++ b/gnucash/gschemas/org.gnucash.GnuCash.warnings.gschema.xml.in @@ -124,6 +124,16 @@ Commit changes to a transaction This dialog is presented when you attempt to move out of a modified transaction. The changed data must be either saved or discarded. + + 0 + Jump when there are multiple other accounts + This dialog is presented when you are unable to jump on a transaction because it has splits for multiple other accounts. A specific split must be selected to jump to the other account. + + + 0 + Jump when there are no other accounts + This dialog is presented when you are unable to jump on a transaction because it only has splits for the current account. + @@ -247,5 +257,15 @@ Commit changes to a transaction This dialog is presented when you attempt to move out of a modified transaction. The changed data must be either saved or discarded. + + 0 + Jump when there are multiple other accounts + This dialog is presented when you are unable to jump on a transaction because it has splits for multiple other accounts. A specific split must be selected to jump to the other account. + + + 0 + Jump when there are no other accounts + This dialog is presented when you are unable to jump on a transaction because it only has splits for the current account. + diff --git a/gnucash/gtkbuilder/dialog-preferences.glade b/gnucash/gtkbuilder/dialog-preferences.glade index ee6977bf9f..0545d7c32a 100644 --- a/gnucash/gtkbuilder/dialog-preferences.glade +++ b/gnucash/gtkbuilder/dialog-preferences.glade @@ -2578,7 +2578,9 @@ many months before the current month True False start - <b>Reconciling</b> + <b>Jump action for multiple splits</b> + Transaction jump action when there are more than two splits. + Transaction jump action when there are more than two splits. True @@ -2587,16 +2589,17 @@ many months before the current month - - Check cleared _transactions + + Do _nothing True True False True - Pre-check cleared transactions when creating a reconcile dialog. - Pre-check cleared transactions when creating a reconcile dialog. + Do nothing. + Do nothing. start True + True True @@ -2605,17 +2608,19 @@ many months before the current month - - Automatic credit card _payment + + Go to the first split with the _largest value True True False True - After reconciling a credit card statement, prompt the user to enter a credit card payment. - After reconciling a credit card statement, prompt the user to enter a credit card payment. + Use the first split with the largest value to determine the other account. + Use the first split with the largest value to determine the other account. start True + True True + pref/general.register/jump-multiple-splits=default 0 @@ -2623,17 +2628,19 @@ many months before the current month - - Always reconcile to t_oday + + Go to the first split with the _smallest value True True False True - Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations. - Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations. + Use the first split with the smallest value to determine the other account. + Use the first split with the smallest value to determine the other account. start True + True True + pref/general.register/jump-multiple-splits=default 0 @@ -2655,7 +2662,7 @@ many months before the current month True False start - <b>Graphics</b> + <b>Reconciling</b> True @@ -2663,6 +2670,83 @@ many months before the current month 10 + + + Check cleared _transactions + True + True + False + True + Pre-check cleared transactions when creating a reconcile dialog. + Pre-check cleared transactions when creating a reconcile dialog. + start + True + True + + + 0 + 11 + + + + + Automatic credit card _payment + True + True + False + True + After reconciling a credit card statement, prompt the user to enter a credit card payment. + After reconciling a credit card statement, prompt the user to enter a credit card payment. + start + True + True + + + 0 + 12 + + + + + Always reconcile to t_oday + True + True + False + True + Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations. + Always open the reconcile dialog using today's date for the statement date, regardless of previous reconciliations. + start + True + True + + + 0 + 13 + + + + + True + False + + + 0 + 14 + + + + + True + False + start + <b>Graphics</b> + True + + + 0 + 15 + + _Use GnuCash built-in color theme @@ -2678,7 +2762,7 @@ many months before the current month 0 - 11 + 16 @@ -2696,7 +2780,7 @@ many months before the current month 0 - 12 + 17 @@ -2714,7 +2798,7 @@ many months before the current month 0 - 13 + 18 @@ -2732,7 +2816,7 @@ many months before the current month 0 - 14 + 19 @@ -2742,7 +2826,7 @@ many months before the current month 0 - 15 + 20 @@ -2757,7 +2841,7 @@ many months before the current month 0 - 16 + 21 @@ -2775,7 +2859,7 @@ many months before the current month 0 - 17 + 22 diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.c b/gnucash/import-export/csv-exp/assistant-csv-export.c index eb0be03544..89fab55db0 100644 --- a/gnucash/import-export/csv-exp/assistant-csv-export.c +++ b/gnucash/import-export/csv-exp/assistant-csv-export.c @@ -991,7 +991,7 @@ csv_export_assistant_create (CsvExportInfo *info) if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_GEOMETRY)) { GObject *object = gtk_builder_get_object (builder, "paned"); - gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_PANED_POS, object, "position"); + gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_PANED_POS, NULL, object, "position"); } gtk_builder_connect_signals (builder, info); diff --git a/gnucash/import-export/import-match-picker.cpp b/gnucash/import-export/import-match-picker.cpp index 732012b698..f43c20b572 100644 --- a/gnucash/import-export/import-match-picker.cpp +++ b/gnucash/import-export/import-match-picker.cpp @@ -394,7 +394,7 @@ init_match_picker_gui(GtkWidget *parent, GNCImportMatchPicker * matcher) gtk_window_set_transient_for (GTK_WINDOW (matcher->transaction_matcher), GTK_WINDOW(parent)); - gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_DISPLAY_RECONCILED, + gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_DISPLAY_RECONCILED, nullptr, matcher->reconciled_chk, "active"); gnc_import_match_picker_init_downloaded_view(matcher); diff --git a/libgnucash/app-utils/gnc-gsettings.cpp b/libgnucash/app-utils/gnc-gsettings.cpp index fcc60ed248..40aac9dd71 100644 --- a/libgnucash/app-utils/gnc-gsettings.cpp +++ b/libgnucash/app-utils/gnc-gsettings.cpp @@ -279,8 +279,36 @@ gnc_gsettings_remove_any_cb_by_func (const gchar *schema, } +static gboolean gnc_gsettings_enum_bool_mapping_get (GValue *value, + GVariant *variant, + gpointer user_data) +{ + g_value_set_boolean (value, + !g_strcmp0 ((const gchar *)user_data, + g_variant_get_string (variant, nullptr))); + + return true; +} + +static GVariant* gnc_gsettings_enum_bool_mapping_set (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) +{ + if (g_value_get_boolean (value)) + { + return g_variant_new_string ((const gchar *)user_data); + } + else + { + /* GtkRadioButtons will set the value to false when another option is + * selected, just ignore this. */ + return nullptr; + } +} + void gnc_gsettings_bind (const gchar *schema, /*@ null @*/ const gchar *key, + /*@ null @*/ const gchar *value, gpointer object, const gchar *property) { @@ -288,9 +316,24 @@ void gnc_gsettings_bind (const gchar *schema, g_return_if_fail (G_IS_SETTINGS (gs_obj)); if (gnc_gsettings_is_valid_key (gs_obj, key)) - g_settings_bind (gs_obj, key, object, property, G_SETTINGS_BIND_DEFAULT); + { + if (value) + { + g_settings_bind_with_mapping (gs_obj, key, object, property, + G_SETTINGS_BIND_DEFAULT, + gnc_gsettings_enum_bool_mapping_get, + gnc_gsettings_enum_bool_mapping_set, + g_strdup (value), g_free); + } + else + { + g_settings_bind (gs_obj, key, object, property, G_SETTINGS_BIND_DEFAULT); + } + } else + { PERR ("Invalid key %s for schema %s", key, schema); + } } diff --git a/libgnucash/app-utils/gnc-gsettings.h b/libgnucash/app-utils/gnc-gsettings.h index 9c9059897a..2f60b7ad49 100644 --- a/libgnucash/app-utils/gnc-gsettings.h +++ b/libgnucash/app-utils/gnc-gsettings.h @@ -199,12 +199,15 @@ void gnc_gsettings_remove_any_cb_by_func (const gchar *schema, * @param key This string is the name of the particular key within * the named schema of gsettings. * + * @param value This string is the enum value of the particular setting. + * * @param object The object to be bound. * * @param property The property of the object to bind to. */ void gnc_gsettings_bind (const gchar *schema, /*@ null @*/ const gchar *key, + /*@ null @*/ const gchar *value, gpointer object, const gchar *property); diff --git a/libgnucash/core-utils/gnc-prefs-p.h b/libgnucash/core-utils/gnc-prefs-p.h index a5ab85580e..7897fe4e26 100644 --- a/libgnucash/core-utils/gnc-prefs-p.h +++ b/libgnucash/core-utils/gnc-prefs-p.h @@ -54,6 +54,7 @@ typedef struct void (*bind) (const gchar *group, /*@ null @*/ const gchar *pref_name, + /*@ null @*/ const gchar *pref_value, gpointer object, const gchar *property); diff --git a/libgnucash/core-utils/gnc-prefs.c b/libgnucash/core-utils/gnc-prefs.c index dec3b23421..f3d8503454 100644 --- a/libgnucash/core-utils/gnc-prefs.c +++ b/libgnucash/core-utils/gnc-prefs.c @@ -180,11 +180,12 @@ void gnc_prefs_remove_group_cb_by_func (const gchar *group, void gnc_prefs_bind (const gchar *group, /*@ null @*/ const gchar *pref_name, + /*@ null @*/ const gchar *pref_value, gpointer object, const gchar *property) { if (prefsbackend && prefsbackend->bind) - (prefsbackend->bind) (group, pref_name, object, property); + (prefsbackend->bind) (group, pref_name, pref_value, object, property); } diff --git a/libgnucash/core-utils/gnc-prefs.h b/libgnucash/core-utils/gnc-prefs.h index 5010bfc951..00549dd2e8 100644 --- a/libgnucash/core-utils/gnc-prefs.h +++ b/libgnucash/core-utils/gnc-prefs.h @@ -79,6 +79,7 @@ #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_FUTURE_AFTER_BLANK "future-after-blank-transaction" +#define GNC_PREF_JUMP_MULT_SPLITS "jump-multiple-splits" /* Date preferences */ #define GNC_PREF_START_CHOICE_ABS "start-choice-absolute" #define GNC_PREF_START_CHOICE_REL "start-choice-relative" @@ -254,15 +255,18 @@ void gnc_prefs_remove_group_cb_by_func (const gchar *group, * * @param group This string contains the group name of the preference to bind to. * - * @param preference This string is the name of the particular preference to + * @param pref_name This string is the name of the particular preference to * bind to. * + * @param pref_value This string is the enum value of the preference to bind to. + * * @param object The object to be bound. * * @param property The property of the object to bind to. */ void gnc_prefs_bind (const gchar *group, /*@ null @*/ const gchar *pref_name, + /*@ null @*/ const gchar *pref_value, gpointer object, const gchar *property);