gnucash maint: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Sat Apr 20 15:37:33 EDT 2019
Updated via https://github.com/Gnucash/gnucash/commit/aa53c232 (commit)
via https://github.com/Gnucash/gnucash/commit/3c946a84 (commit)
via https://github.com/Gnucash/gnucash/commit/9afc856c (commit)
via https://github.com/Gnucash/gnucash/commit/5f902001 (commit)
via https://github.com/Gnucash/gnucash/commit/3ddd76f8 (commit)
via https://github.com/Gnucash/gnucash/commit/614932ed (commit)
via https://github.com/Gnucash/gnucash/commit/6eba0d49 (commit)
via https://github.com/Gnucash/gnucash/commit/7706fff3 (commit)
via https://github.com/Gnucash/gnucash/commit/61551526 (commit)
via https://github.com/Gnucash/gnucash/commit/280ed47d (commit)
via https://github.com/Gnucash/gnucash/commit/cae8ecde (commit)
via https://github.com/Gnucash/gnucash/commit/01339a78 (commit)
via https://github.com/Gnucash/gnucash/commit/274f0fd5 (commit)
from https://github.com/Gnucash/gnucash/commit/ce4d3dee (commit)
commit aa53c23239dc05da44c78a085c4db342adfbf707
Merge: 3c946a844 5f9020016
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Apr 20 12:36:51 2019 -0700
Merge T Edmunds's 'amortization-rounding' into maint.
commit 3c946a84496a846196ba04667e3a7f0c7bee0eb5
Merge: ce4d3dee6 9afc856c2
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Apr 20 12:32:17 2019 -0700
Merge T Edmunds's 'computeInterestIncrement' to maint.
commit 9afc856c20a0ad835562a2f8b2abf11a35c390af
Author: thetedmunds <tedmunds at gmail.com>
Date: Mon Apr 15 13:16:32 2019 -0700
Changed gnc:computeInterestIncrement to directly calculate the amount of interest accrued in the specified compounding period. Bug 797195.
diff --git a/libgnucash/app-utils/fin.scm b/libgnucash/app-utils/fin.scm
index be56e543f..a8edf0506 100644
--- a/libgnucash/app-utils/fin.scm
+++ b/libgnucash/app-utils/fin.scm
@@ -63,12 +63,9 @@
;; formula from http://www.riskglossary.com/articles/compounding.htm
(* a (expt (+ 1 (/ r n)) (* n t))))
-(define (gnc:computeInterestIncrement amount interest periods i)
- (let ((thisVal (gnc:futureValue amount interest periods i))
- (prevVal (gnc:futureValue amount interest periods (- i 1))))
- (- thisVal prevVal)
- )
-)
+(define (gnc:computeInterestIncrement pv ann-rate compounds period)
+ (let ((rate (/ ann-rate compounds)))
+ (* rate (* pv (expt (+ 1 rate) (- period 1))))))
;;;;;
;; below: not-exposed/"private" functions, used by the "public" functions
commit 5f9020016a5f1be28b7673ddc2d5f3db8c68ee3f
Author: thetedmunds <tedmunds at gmail.com>
Date: Mon Apr 15 14:31:23 2019 -0700
Amended commit to address pull-request comments.
diff --git a/libgnucash/app-utils/fin.scm b/libgnucash/app-utils/fin.scm
index be56e543f..c3ee43ce6 100644
--- a/libgnucash/app-utils/fin.scm
+++ b/libgnucash/app-utils/fin.scm
@@ -185,3 +185,171 @@
)
)
)
+
+;; Further options to match what some (several? many?) lenders do (at
+;; least in Canada):
+;; The posted interest rate is an annual rate that has a specified
+;; compounding frequency per year (2 for mortgages in Canada).
+;; A payment frequency and amortization length are selected (e.g.
+;; monthly payments for 25 years).
+;; The posted nominal rate is converted from the specified compounding
+;; frequency to the equivalent rate at the payment frequency.
+;; The required payment is calculated.
+;; The payment is rounded up to the next dollar (or $10 dollars,
+;; or whatever...)
+;; Each payment period, interest is calculated on the outstanding
+;; balance.
+;; The interest is rounded to the nearest cent and added to the
+;; balance.
+;; The payment is subtracted from the balance.
+;; The final payment will be smaller because all the other payments
+;; were rounded up.
+;;
+;; For the purpose of creating scheduled transactions that properly
+;; debit a source account while crediting the loan account and the
+;; interest expense account, the first part (the calculation of the
+;; required payment) doesn't really matter. You have agreed
+;; with the lender what the payment terms (interest rate, payment
+;; frequency, payment amount) will be; you keep paying until the
+;; balance is zero.
+;;
+;; To create the scheduled transactions, we need to build an
+;; amortization table.
+;; If it weren't for the rounding of the interest to the nearest cent
+;; each period, we could calculate the ith row of the amortization
+;; table directly from the general annuity equation (as is done by
+;; gnc:ipmt and gnc:ppmt). But to deal with the intermediate
+;; rounding, the amortization table has to be constructed iteratively
+;; (as is done by the AMORT worksheet on the TI BA II Plus
+;; financial calculator).
+;;
+;; =================================
+;; EXAMPLE:
+;; Say you borrow $100,000 at 5%/yr, compounded semi-annually.
+;; You amortize the loan over 2 years with 24 monthly payments.
+;; This calls for payments of $4,384.8418 at the end of each month.
+;; The lender rounds this up to $4,385.
+;;
+;; If you calculate the balance at each period directly using the annuity
+;; formula (like calc-principal does), and then use the those values to calculate
+;; the principal and interest paid, the first 10 rows of the amortization table
+;; look like this (the values are rounded to the nearest cent for _display_, but
+;; not for calculating the next period):
+;;
+;; PERIOD | Open | Interest | Principal | End
+;; 1 |$100,000.00 | $412.39 | $3,972.61 | $96,027.39
+;; 2 | $96,027.39 | $396.01 | $3,988.99 | $92,038.40
+;; 3 | $92,038.40 | $379.56 | $4,005.44 | $88,032.96
+;; 4 | $88,032.96 | $363.04 | $4,021.96 | $84,011.00
+;; 5 | $84,011.00 | $346.45 | $4,038.55 | $79,972.45
+;; 6 | $79,972.45 | $329.80 | $4,055.20 | $75,917.25
+;; 7 | $75,917.25 | $313.08 | $4,071.92 | $71,845.33
+;; 8 | $71,845.33 | $296.28 | $4,088.72 | $67,756.61
+;; 9 | $67,756.61 | $279.43 | $4,105.57 | $63,651.04
+;; 10 | $63,651.04 | $262.49 | $4,122.51 | $59,528.53
+;;
+;; If you calculate each period sequentially (rounding the interest and balance
+;; at each step), you get:
+;;
+;; PERIOD | Open | Interest | Principal | End
+;; 1 |$100,000.00 | $412.39 | $3,972.61 | $96,027.39
+;; 2 | $96,027.39 | $396.01 | $3,988.99 | $92,038.40
+;; 3 | $92,038.40 | $379.56 | $4,005.44 | $88,032.96
+;; 4 | $88,032.96 | $363.04 | $4,021.96 | $84,011.00
+;; 5 | $84,011.00 | $346.45 | $4,038.55 | $79,972.45
+;; 6 | $79,972.45 | $329.80 | $4,055.20 | $75,917.25
+;; 7 | $75,917.25 | $313.08 | $4,071.92 | $71,845.33
+;; 8 | $71,845.33 | $296.28 | $4,088.72 | $67,756.61
+;; 9 | $67,756.61 | $279.42 | $4,105.58 | $63,651.03 <- Different
+;; 10 | $63,651.03 | $262.49 | $4,122.51 | $59,528.52 <- still $0.01 off
+;;
+;; =================================
+;;
+;; For the following functions the argument names are:
+;; py: payment frequency (number of payments per year)
+;; cy: compounding frequency of the nominal rate (per year)
+;; iy: nominal annual interest rate
+;; pv: the present value (opening balance)
+;; pmt: the size of the periodic payment
+;; n: the payment period we are asking about (the first payment is n=1)
+;; places: number of decimal places to round the interest amount to
+;; at each payment (999 does no rounding)
+;;
+;; Note: only ordinary annuities are supported (payments at the end of
+;; each period, not at the beginning of each period)
+;;
+;; Unlike the AMORT worksheet on the BA II Plus, these methods will
+;; handle the smaller payment (bringing the balance to zero, then
+;; zeroing future payments)
+;;
+;; The present value (pv) must be non-negative. If not, the balance will be
+;; treated as 0.
+;; The payment (pmt) can be positive (paying interest, and hopefully
+;; reducing the balance each payment), or negative (increasing the balance
+; each payment).
+;; The payment number (n) must be positive for amort_pmt, amort_ppmt, and
+;; amort_ipmt. I.e., the first payment is payment 1.
+;; The payment number (n) must be non-negative for amort_balance. (In this
+;; case, payment zero is at the _beginning_ of the first period, so
+;; amort_balance will just be the initial balance.)
+;; If the above conditions on n are violated, the functions return -1 (#f is
+;; not used, because it causes gnucash to crash).
+;;
+;; A negative interest rate works (if you can find a lender who charges
+;; negative rates), but negative compounding frequency, or negative payment
+;; frequency is a bad idea.
+
+;; Calculate the balance remaining after the nth payment
+;; (n must be greater than or equal to zero)
+(define (gnc:amort_pmt py cy iy pv pmt n places)
+ (if (< n 1) -1 ;; Returning #f here causes gnucash to crash on startup
+ (let* ((prevBal (gnc:amort_balance py cy iy pv pmt (- n 1) places))
+ (balBeforePayment
+ (amort_balanceAfterInterest prevBal py cy iy places))
+ (balAfterPayment (amort_balanceAfterPayment balBeforePayment pmt)))
+ (- balBeforePayment balAfterPayment))))
+
+;; Calculate the amount of the nth payment that is principal
+;; (n must be greater than zero)
+(define (gnc:amort_ppmt py cy iy pv pmt n places)
+ (if (< n 1) -1
+ (let* ((prevBal (gnc:amort_balance py cy iy pv pmt (- n 1) places))
+ (bal-after-int (amort_balanceAfterInterest prevBal py cy iy places))
+ (newBal (amort_balanceAfterPayment bal-after-int pmt)))
+ (- prevBal newBal))))
+
+;; Calculate the amount of the nth payment that is interest
+;; (n must be greater than zero)
+(define (gnc:amort_ipmt py cy iy pv pmt n places)
+ (if (< n 1) -1
+ (let* ((prevBal(gnc:amort_balance py cy iy pv pmt (- n 1) places)))
+ (amort_interest prevBal py cy iy places))))
+
+;; "Private" helper functions:
+
+;; Calculate the amount of interest on the current balance,
+;; rounded to the specified number of decimal places
+(define (amort_interest balance py cy iy places)
+ (roundToPlaces (* balance (gnc:periodic_rate iy py cy)) places)
+)
+
+;; Calculate the new balance after applying the interest, but before
+;; applying the payment
+(define (amort_balanceAfterInterest prevBalance py cy iy places)
+ (+ prevBalance (amort_interest prevBalance py cy iy places))
+)
+
+;; Apply the payment to the balance (after the interest has been
+;; added), without letting the balance go below zero.
+(define (amort_balanceAfterPayment balanceBeforePmt pmt)
+ (max 0 (- balanceBeforePmt pmt))
+)
+
+;; Round the value to the specified number of decimal places.
+;; 999 places means no rounding (#f is not used, because only numbers can be
+;; entered in the scheduled transaction editor)
+(define (roundToPlaces value places)
+ (if (= places 999) value
+ (/ (round (* value (expt 10 places))) (expt 10 places))
+ )
+)
commit 3ddd76f8f24d937f1e71990517266287e0145eb7
Merge: 614932eda 76a91aa2c
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Mar 31 10:43:33 2019 -0700
Merge branch 'maint'
commit 614932eda59f502c74da3ba867bf4a5efe95e2c6
Merge: 6eba0d494 3ab5a2be5
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jan 15 09:44:14 2019 -0800
Merge branch 'maint'.
diff --cc gnucash/import-export/import-main-matcher.c
index 69ce9a50a,773429602..7172c52e2
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@@ -731,14 -536,15 +739,20 @@@ gnc_gen_trans_init_view (GNCImportMainM
G_CALLBACK(gnc_gen_trans_row_activated_cb), info);
g_signal_connect(selection, "changed",
G_CALLBACK(gnc_gen_trans_row_changed_cb), info);
+
+ g_signal_connect(view, "button-press-event",
+ G_CALLBACK(gnc_gen_trans_onButtonPressed_cb), info);
+ g_signal_connect(view, "popup-menu",
+ G_CALLBACK(gnc_gen_trans_onPopupMenu_cb), info);
}
-
+ static void
+ show_account_column_toggled_cb (GtkToggleButton *togglebutton,
+ GNCImportMainMatcher *info)
+ {
+ gtk_tree_view_column_set_visible (info->account_column,
+ gtk_toggle_button_get_active (togglebutton));
+ }
GNCImportMainMatcher *gnc_gen_trans_list_new (GtkWidget *parent,
const gchar* heading,
commit 6eba0d4940da14e52f78fc172559e3aa940ad6b6
Merge: 7706fff3c 519880545
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Nov 30 17:32:58 2018 +0900
Merge branch 'maint'
diff --cc CMakeLists.txt
index f16d5234a,860954143..c882b0afb
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@@ -18,11 -18,11 +18,11 @@@ set (GNUCASH_LATEST_STABLE_SERIES 3.x
set (PACKAGE gnucash)
set (PACKAGE_NAME GnuCash)
-set (PACKAGE_VERSION 3.3)
+set (PACKAGE_VERSION 3.900)
- set (PACKAGE_BUGREPORT gnucash-devel at gnucash.org)
+ set (PACKAGE_BUGREPORT "https://bugs.gnucash.org")
set (PACKAGE_TARNAME ${PACKAGE})
set (PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
- set (PACKAGE_URL "")
+ set (PACKAGE_URL "https://www.gnucash.org/")
# Change this in development versions when changing anything that
# affects stored data structures. Reset to zero when bumping version.
commit 7706fff3c94143f93030db167c5b51f146a09999
Merge: 61551526a 65c8357f5
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Sep 29 16:49:35 2018 -0700
Merge branch 'maint'
diff --cc CMakeLists.txt
index b2ecf7dc2,e01c22b44..f16d5234a
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@@ -12,13 -12,13 +12,13 @@@ enable_testing(
# Version number of gnucash
set (GNUCASH_MAJOR_VERSION 3)
- set (GNUCASH_MINOR_VERSION 2)
-set (GNUCASH_MINOR_VERSION 3)
++set (GNUCASH_MINOR_VERSION 900)
set (VERSION "${GNUCASH_MAJOR_VERSION}.${GNUCASH_MINOR_VERSION}")
set (GNUCASH_LATEST_STABLE_SERIES 3.x)
set (PACKAGE gnucash)
set (PACKAGE_NAME GnuCash)
- set (PACKAGE_VERSION 3.2)
-set (PACKAGE_VERSION 3.3)
++set (PACKAGE_VERSION 3.900)
set (PACKAGE_BUGREPORT gnucash-devel at gnucash.org)
set (PACKAGE_TARNAME ${PACKAGE})
set (PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
commit 61551526a860acc44c4cc545f699424d7347d41b
Merge: 280ed47d9 148f24135
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Sep 6 16:26:29 2018 -0700
Merge branch 'maint'
commit 280ed47d9d99053f8369962099b4656f8cd662d2
Merge: 274f0fd58 cae8ecde8
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Sep 6 16:24:04 2018 -0700
Merge David Cousins's Bug_796778 into master.
This resolves Bug 796778 - Feature Request: Select multiple transactions
for assignment to a given transfer account when importing OFX (and
similar).
commit cae8ecde8f9ddd615ff47c783ce8136395bd71a9
Author: David Cousens <davidcousens at bigpond.com>
Date: Thu Sep 6 12:43:34 2018 +1000
Changes to import-main-matcher.c and dialog-import.glade to implement multiple selection and assignment of a destination account to the selection.
diff --git a/gnucash/gtkbuilder/dialog-import.glade b/gnucash/gtkbuilder/dialog-import.glade
index b8243dc30..ebbc18945 100644
--- a/gnucash/gtkbuilder/dialog-import.glade
+++ b/gnucash/gtkbuilder/dialog-import.glade
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.20.0 -->
+<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkImage" id="account_new_icon">
@@ -14,6 +14,9 @@
<property name="default_height">600</property>
<property name="type_hint">dialog</property>
<signal name="map" handler="gnc_ui_generic_account_picker_map_cb" swapped="no"/>
+ <child>
+ <placeholder/>
+ </child>
<child internal-child="vbox">
<object class="GtkBox" id="account_picker_vbox">
<property name="visible">True</property>
@@ -165,7 +168,6 @@
<property name="page_increment">10</property>
</object>
<object class="GtkDialog" id="format_picker_dialog">
- <property name="visible">False</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Choose a format</property>
<property name="resizable">False</property>
@@ -173,6 +175,9 @@
<property name="default_width">600</property>
<property name="default_height">400</property>
<property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox16">
<property name="visible">True</property>
@@ -301,6 +306,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Preferences</property>
+ <child>
+ <placeholder/>
+ </child>
<child>
<object class="GtkGrid" id="matcher_prefs">
<property name="visible">True</property>
@@ -554,6 +562,9 @@
<property name="default_width">600</property>
<property name="default_height">400</property>
<property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox14">
<property name="visible">True</property>
@@ -717,7 +728,8 @@
<property name="text" translatable="yes">This transaction requires your intervention or it will NOT be imported.</property>
</object>
<object class="GtkTextBuffer" id="textbuffer5">
- <property name="text" translatable="yes">Double click on the transaction to change the matching transaction to reconcile, or the destination account of the auto-balance split (if required).</property>
+ <property name="text" translatable="yes">Double click on the transaction to change the matching transaction to reconcile, or the destination account of the auto-balance split (if required).
+Multiply select rows using Ctrl-Click, Shift-Click and Rubber banding . Right-Click or Shift-F10 to bring up popup menu and click or select to assign a destination account to the selected rows.</property>
</object>
<object class="GtkDialog" id="matcher_help_dialog">
<property name="can_focus">False</property>
@@ -726,6 +738,9 @@
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
<signal name="close" handler="on_matcher_help_close_clicked" swapped="no"/>
+ <child>
+ <placeholder/>
+ </child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox18">
<property name="visible">True</property>
@@ -764,6 +779,7 @@
<object class="GtkGrid" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="margin_bottom">42</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
@@ -990,6 +1006,7 @@
<object class="GtkTextView" id="textview5">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="margin_bottom">2</property>
<property name="pixels_above_lines">5</property>
<property name="pixels_below_lines">5</property>
<property name="editable">False</property>
@@ -1107,8 +1124,11 @@
<property name="reorderable">True</property>
<property name="rules_hint">True</property>
<property name="enable_search">False</property>
+ <property name="rubber_banding">True</property>
<child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection3"/>
+ <object class="GtkTreeSelection" id="treeview-selection3">
+ <property name="mode">multiple</property>
+ </object>
</child>
</object>
</child>
@@ -1130,6 +1150,9 @@
<property name="default_height">400</property>
<property name="type_hint">dialog</property>
<signal name="close" handler="on_matcher_cancel_clicked" swapped="no"/>
+ <child>
+ <placeholder/>
+ </child>
<child internal-child="vbox">
<object class="GtkBox" id="transaction_matcher_vbox">
<property name="visible">True</property>
diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index 2c23dd1eb..580b09f4a 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -95,14 +95,28 @@ void on_matcher_help_clicked (GtkButton *button, gpointer user_data);
void on_matcher_help_close_clicked (GtkButton *button, gpointer user_data);
/* Local prototypes */
-static Account *
-gnc_gen_trans_assign_transfer_account(GNCImportMainMatcher *gui,
- gboolean first,
- GtkTreePath *path,
- Account *new_acc);
-static void
-refresh_model_row(GNCImportMainMatcher *gui, GtkTreeModel *model,
+static void gnc_gen_trans_assign_transfer_account(
+ GtkTreeView *treeview,
+ gboolean *first,
+ gboolean *is_selection,
+ GtkTreePath *path,
+ Account **new_acc,
+ GNCImportMainMatcher *info);
+static void gnc_gen_trans_assign_transfer_account_to_selection_cb (
+ GtkMenuItem *menuitem,
+ GNCImportMainMatcher *info);
+static void gnc_gen_trans_view_popup_menu (GtkTreeView *treeview,
+ GdkEvent *event,
+ GNCImportMainMatcher *info);
+static gboolean gnc_gen_trans_onButtonPressed_cb (GtkTreeView *treeview,
+ GdkEvent *event,
+ GNCImportMainMatcher *info);
+static gboolean gnc_gen_trans_onPopupMenu_cb (GtkTreeView *treeview,
+ GdkEvent *event,
+ GNCImportMainMatcher *info);
+static void refresh_model_row(GNCImportMainMatcher *gui, GtkTreeModel *model,
GtkTreeIter *iter, GNCImportTransInfo *info);
+/* end local prototypes */
void gnc_gen_trans_list_delete (GNCImportMainMatcher *info)
{
@@ -362,11 +376,13 @@ gnc_gen_trans_update_toggled_cb (GtkCellRendererToggle *cell_renderer,
refresh_model_row(gui, model, &iter, trans_info);
}
-static Account *
-gnc_gen_trans_assign_transfer_account(GNCImportMainMatcher *gui,
- gboolean first,
+static void
+gnc_gen_trans_assign_transfer_account(GtkTreeView *treeview,
+ gboolean *first,
+ gboolean *is_selection,
GtkTreePath *path,
- Account *new_acc)
+ Account **new_acc,
+ GNCImportMainMatcher *info)
{
GtkTreeModel *model;
GtkTreeIter iter;
@@ -374,72 +390,225 @@ gnc_gen_trans_assign_transfer_account(GNCImportMainMatcher *gui,
Account *old_acc;
gboolean ok_pressed;
- model = gtk_tree_view_get_model(gui->view);
- if (!gtk_tree_model_get_iter(model, &iter, path))
- return NULL;
- gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1);
-
- switch (gnc_import_TransInfo_get_action (trans_info))
+ ENTER("");
+ DEBUG("first = %s",*first?"true":"false");
+ DEBUG("is_selection = %s",*is_selection?"true":"false");
+ DEBUG("path = %s", gtk_tree_path_to_string(path));
+ DEBUG("account passed in = %s", gnc_get_account_name_for_register(*new_acc));
+ model = gtk_tree_view_get_model(treeview);
+ if (gtk_tree_model_get_iter(model, &iter, path))
{
- case GNCImport_ADD:
- if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE)
+ gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1);
+
+ switch (gnc_import_TransInfo_get_action (trans_info))
{
- old_acc = gnc_import_TransInfo_get_destacc (trans_info);
- if (first)
+ case GNCImport_ADD:
+ if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE)
{
- new_acc = gnc_import_select_account(gui->main_widget,
- NULL,
- TRUE,
- _("Destination account for the auto-balance split."),
- xaccTransGetCurrency(gnc_import_TransInfo_get_trans(trans_info)),
- ACCT_TYPE_NONE,
- old_acc,
- &ok_pressed);
- first = FALSE;
+ ok_pressed = TRUE;
+ old_acc = gnc_import_TransInfo_get_destacc (trans_info);
+ if (*first)
+ {
+ ok_pressed = FALSE;
+ *new_acc = gnc_import_select_account(info->main_widget,
+ NULL,
+ TRUE,
+ _("Destination account for the auto-balance split."),
+ xaccTransGetCurrency(
+ gnc_import_TransInfo_get_trans(trans_info)),
+ ACCT_TYPE_NONE,
+ old_acc,
+ &ok_pressed);
+ *first = FALSE;
+ DEBUG("account selected = %s",
+ gnc_account_get_full_name(*new_acc));
+ }
+ if (ok_pressed)
+ gnc_import_TransInfo_set_destacc (trans_info,
+ *new_acc, TRUE);
}
- if (ok_pressed)
- gnc_import_TransInfo_set_destacc (trans_info, new_acc, TRUE);
+ break;
+ case GNCImport_CLEAR:
+ case GNCImport_UPDATE:
+ if (first && !is_selection) run_match_dialog (info, trans_info);
+ break;
+ case GNCImport_SKIP:
+ break;
+ default:
+ PERR("InvalidGNCImportValue");
+ break;
}
- break;
- case GNCImport_CLEAR:
- case GNCImport_UPDATE:
- run_match_dialog (gui, trans_info);
- break;
- case GNCImport_SKIP:
- /*The information displayed is only informative, until you select an action*/
- break;
- default:
- PERR("InvalidGNCImportValue");
- break;
+ refresh_model_row(info, model, &iter, trans_info);
}
- refresh_model_row(gui, model, &iter, trans_info);
- return new_acc;
+ LEAVE("");
}
static void
-gnc_gen_trans_row_activated_cb (GtkTreeView *view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GNCImportMainMatcher *gui)
+gnc_gen_trans_assign_transfer_account_to_selection_cb (GtkMenuItem *menuitem,
+ GNCImportMainMatcher *info)
{
- Account *assigned_account =NULL;
- gboolean first = TRUE;
+ GtkTreeView *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GNCImportTransInfo *trans_info;
+ Account *assigned_account;
+ GList *selected_rows, *l;
+ gboolean first, is_selection;
+
+ ENTER("");
+ treeview = GTK_TREE_VIEW(info->view);
+ model = gtk_tree_view_get_model(treeview);
+ selection = gtk_tree_view_get_selection(treeview);
+ selected_rows = gtk_tree_selection_get_selected_rows (selection, &model);
+ assigned_account = NULL;
+ first = TRUE;
+ is_selection = TRUE;
+ DEBUG("Rows in selection = %i",
+ gtk_tree_selection_count_selected_rows(selection));
+ DEBUG("Entering loop over selection");
+
+ for (l = selected_rows; l != NULL; l = l->next)
+ {
+ DEBUG("passing first = %s",
+ first?"true":"false");
+ DEBUG("passing is_selection = %s",
+ is_selection?"true":"false");
+ DEBUG("passing path = %s",
+ gtk_tree_path_to_string(l->data));
+ DEBUG("passing account value = %s",
+ gnc_account_get_full_name(assigned_account));
+ gnc_gen_trans_assign_transfer_account(treeview,
+ &first, &is_selection, l->data, &assigned_account, info);
+ DEBUG("returned value of account = %s",
+ gnc_account_get_full_name(assigned_account));
+ DEBUG("returned value of first = %s",first?"true":"false");
+ if (assigned_account == NULL) break;
+ gtk_tree_selection_unselect_path(selection, l->data);
+ }
- assigned_account = gnc_gen_trans_assign_transfer_account(gui, first, path, assigned_account);
+ g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
+ g_list_free_full(l, (GDestroyNotify) gtk_tree_path_free);
+ LEAVE("");
+}
+
+static void
+gnc_gen_trans_row_activated_cb (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GNCImportMainMatcher *info)
+{
+ Account *assigned_account;
+ gboolean first, is_selection;
+
+ ENTER("");
+ assigned_account = NULL;
+ first = TRUE;
+ is_selection = FALSE;
+ gnc_gen_trans_assign_transfer_account(treeview,
+ &first, &is_selection, path,
+ &assigned_account, info);
+ DEBUG("account returned = %s", gnc_account_get_full_name(assigned_account));
+ LEAVE("");
}
static void
gnc_gen_trans_row_changed_cb (GtkTreeSelection *selection,
- GNCImportMainMatcher *gui)
+ GNCImportMainMatcher *info)
{
GtkTreeModel *model;
GtkTreeIter iter;
+ GtkSelectionMode mode;
- if (!gtk_tree_selection_get_selected(selection, &model, &iter))
- return;
- gtk_tree_selection_unselect_iter(selection, &iter);
+ ENTER("");
+ mode = gtk_tree_selection_get_mode(selection);
+ switch (mode)
+ {
+ case GTK_SELECTION_MULTIPLE:
+ DEBUG("mode = GTK_SELECTION_MULTIPLE, no action");
+ break;
+ case GTK_SELECTION_NONE:
+ DEBUG("mode = GTK_SELECTION_NONE, no action");
+ break;
+ case GTK_SELECTION_BROWSE:
+ DEBUG("mode = GTK_SELECTION_BROWSE->default");
+ case GTK_SELECTION_SINGLE:
+ DEBUG("mode = GTK_SELECTION_SINGLE->default");
+ default:
+ DEBUG("mode = default unselect selected row");
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_selection_unselect_iter(selection, &iter);
+ }
+ }
+ LEAVE("");
+}
+
+static void
+gnc_gen_trans_view_popup_menu (GtkTreeView *treeview,
+ GdkEvent *event,
+ GNCImportMainMatcher *info)
+{
+ GtkWidget *menu, *menuitem;
+ GdkEventButton *event_button;
+
+ ENTER ("");
+ menu = gtk_menu_new();
+ menuitem = gtk_menu_item_new_with_label(_("Assign a transfer account."));
+ g_signal_connect(menuitem, "activate",
+ G_CALLBACK(
+ gnc_gen_trans_assign_transfer_account_to_selection_cb),
+ info);
+ DEBUG("Callback to assign destination account to selection connected");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ gtk_widget_show_all(menu);
+ event_button = (GdkEventButton *) event;
+ /* Note: event can be NULL here when called from view_onPopupMenu;
+ * gdk_event_get_time() accepts a NULL argument */
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
+ (event_button != NULL) ? event_button->button : 0,
+ gdk_event_get_time((GdkEvent*)event));
+ LEAVE ("");
+}
+
+static gboolean
+gnc_gen_trans_onButtonPressed_cb (GtkTreeView *treeview,
+ GdkEvent *event,
+ GNCImportMainMatcher *info)
+{
+ GdkEventButton *event_button;
+ ENTER("");
+ g_return_val_if_fail (treeview != NULL, FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+ /* handle single click with the right mouse button? */
+ if (event->type == GDK_BUTTON_PRESS)
+ {
+ event_button = (GdkEventButton *) event;
+ if (event_button->button == GDK_BUTTON_SECONDARY)
+ {
+ DEBUG("Right mouseClick detected- popup the menu.");
+ gnc_gen_trans_view_popup_menu(treeview, event, info);
+ LEAVE("return TRUE");
+ return TRUE;
+ }
+ }
+ LEAVE("return FALSE");
+ return FALSE;
}
+static gboolean
+gnc_gen_trans_onPopupMenu_cb (GtkTreeView *treeview,
+ GdkEvent *event,
+ GNCImportMainMatcher *info)
+{
+ ENTER("");
+ /* respond to Shift-F10 popup menu hotkey */
+ gnc_gen_trans_view_popup_menu(treeview, NULL, info);
+ LEAVE ("");
+ return TRUE;
+}
+
+
static GtkTreeViewColumn *
add_text_column(GtkTreeView *view, const gchar *title, int col_num)
{
@@ -552,6 +721,11 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
G_CALLBACK(gnc_gen_trans_row_activated_cb), info);
g_signal_connect(selection, "changed",
G_CALLBACK(gnc_gen_trans_row_changed_cb), info);
+
+ g_signal_connect(view, "button-press-event",
+ G_CALLBACK(gnc_gen_trans_onButtonPressed_cb), info);
+ g_signal_connect(view, "popup-menu",
+ G_CALLBACK(gnc_gen_trans_onPopupMenu_cb), info);
}
commit 01339a782c91a8d931cc9d7462ddce19afc60635
Author: David Cousens <davidcousens at bigpond.com>
Date: Tue Aug 28 22:36:42 2018 +1000
Stage 1 Extracting code for assigning a transfer account from gnc_gen_trans_row_activated_cb() into a new function
gnc_gen_trans_assign_transfer account() and calling that function from within gnc_gen_trans_row_activated_cb().
Tested and working as per the original code.
diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index 78d46af77..2c23dd1eb 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -95,6 +95,11 @@ void on_matcher_help_clicked (GtkButton *button, gpointer user_data);
void on_matcher_help_close_clicked (GtkButton *button, gpointer user_data);
/* Local prototypes */
+static Account *
+gnc_gen_trans_assign_transfer_account(GNCImportMainMatcher *gui,
+ gboolean first,
+ GtkTreePath *path,
+ Account *new_acc);
static void
refresh_model_row(GNCImportMainMatcher *gui, GtkTreeModel *model,
GtkTreeIter *iter, GNCImportTransInfo *info);
@@ -357,19 +362,21 @@ gnc_gen_trans_update_toggled_cb (GtkCellRendererToggle *cell_renderer,
refresh_model_row(gui, model, &iter, trans_info);
}
-static void
-gnc_gen_trans_row_activated_cb (GtkTreeView *view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GNCImportMainMatcher *gui)
+static Account *
+gnc_gen_trans_assign_transfer_account(GNCImportMainMatcher *gui,
+ gboolean first,
+ GtkTreePath *path,
+ Account *new_acc)
{
GtkTreeModel *model;
GtkTreeIter iter;
GNCImportTransInfo *trans_info;
+ Account *old_acc;
+ gboolean ok_pressed;
model = gtk_tree_view_get_model(gui->view);
if (!gtk_tree_model_get_iter(model, &iter, path))
- return;
+ return NULL;
gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1);
switch (gnc_import_TransInfo_get_action (trans_info))
@@ -377,7 +384,21 @@ gnc_gen_trans_row_activated_cb (GtkTreeView *view,
case GNCImport_ADD:
if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE)
{
- run_account_picker_dialog (gui, model, &iter, trans_info);
+ old_acc = gnc_import_TransInfo_get_destacc (trans_info);
+ if (first)
+ {
+ new_acc = gnc_import_select_account(gui->main_widget,
+ NULL,
+ TRUE,
+ _("Destination account for the auto-balance split."),
+ xaccTransGetCurrency(gnc_import_TransInfo_get_trans(trans_info)),
+ ACCT_TYPE_NONE,
+ old_acc,
+ &ok_pressed);
+ first = FALSE;
+ }
+ if (ok_pressed)
+ gnc_import_TransInfo_set_destacc (trans_info, new_acc, TRUE);
}
break;
case GNCImport_CLEAR:
@@ -388,10 +409,23 @@ gnc_gen_trans_row_activated_cb (GtkTreeView *view,
/*The information displayed is only informative, until you select an action*/
break;
default:
- PERR("I don't know what to do! (Yet...)");
+ PERR("InvalidGNCImportValue");
break;
}
refresh_model_row(gui, model, &iter, trans_info);
+ return new_acc;
+}
+
+static void
+gnc_gen_trans_row_activated_cb (GtkTreeView *view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GNCImportMainMatcher *gui)
+{
+ Account *assigned_account =NULL;
+ gboolean first = TRUE;
+
+ assigned_account = gnc_gen_trans_assign_transfer_account(gui, first, path, assigned_account);
}
static void
commit 274f0fd5857d521c3059c07987ac91cd6f55122c
Merge: eb67baba5 5d80a52ea
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Jun 24 11:11:59 2018 -0700
Merge branch 'maint'
Summary of changes:
CMakeLists.txt | 4 +-
gnucash/gtkbuilder/dialog-import.glade | 29 ++-
gnucash/import-export/import-main-matcher.c | 270 ++++++++++++++++++++++++----
libgnucash/app-utils/fin.scm | 177 +++++++++++++++++-
4 files changed, 438 insertions(+), 42 deletions(-)
More information about the gnucash-changes
mailing list