From f05bbe24752d576f5356472f6441ca166e988196 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 19 Mar 2018 15:52:06 -0700 Subject: [PATCH 01/12] Bug 794330 - Scheduled Transaction Editor Transfer Button Does Not Work It works fine, it just doesn't have anything to do with scheduled transactions. Remove it from the SX Editor toolbar. --- gnucash/ui/gnc-sxed-window-ui-full.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/gnucash/ui/gnc-sxed-window-ui-full.xml b/gnucash/ui/gnc-sxed-window-ui-full.xml index 65ea884554..df8a774d97 100644 --- a/gnucash/ui/gnc-sxed-window-ui-full.xml +++ b/gnucash/ui/gnc-sxed-window-ui-full.xml @@ -45,7 +45,6 @@ - From 2b6047f9529b6cde899e8bb208636f64e9e90ed9 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 20 Mar 2018 11:41:21 -0700 Subject: [PATCH 02/12] Fix a string msgid generation. Call gettext in the macro, not on the macro. xgettext doesn't run cpp and can't see inside macros. --- src/gnome/gnc-plugin-page-account-tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gnome/gnc-plugin-page-account-tree.c b/src/gnome/gnc-plugin-page-account-tree.c index ce67bd6f78..0d24978c1f 100644 --- a/src/gnome/gnc-plugin-page-account-tree.c +++ b/src/gnome/gnc-plugin-page-account-tree.c @@ -1162,9 +1162,9 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag list = qof_instance_get_referring_object_list(QOF_INSTANCE(account)); if (list != NULL) { -#define EXPLANATION "The list below shows objects which make use of the account which you want to delete.\nBefore you can delete it, you must either delete those objects or else modify them so they make use\nof another account" +#define EXPLANATION _("The list below shows objects which make use of the account which you want to delete.\nBefore you can delete it, you must either delete those objects or else modify them so they make use\nof another account") - gnc_ui_object_references_show( _(EXPLANATION), list); + gnc_ui_object_references_show (EXPLANATION, list); g_list_free(list); return; } From 34d921803de8d8bbd7b29280f59c99bb6050fdca Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Wed, 21 Mar 2018 12:24:00 +0000 Subject: [PATCH 03/12] Bug 794360 Critical error when deleting accounts with children When an account is deleted which has sub accounts a dialog is displayed that had parts destroyed so they are not shown depending on certain criteria and as a result an error occurred as it tried to get the sensitivity of a destroyed widget. Change this so all parts of the dialog are present but made in-sensitive when not applicable so the dialog layout is the same on all occurrences. --- gnucash/gnome/gnc-plugin-page-account-tree.c | 116 +++++++++++-------- gnucash/gtkbuilder/dialog-account.glade | 4 +- 2 files changed, 70 insertions(+), 50 deletions(-) diff --git a/gnucash/gnome/gnc-plugin-page-account-tree.c b/gnucash/gnome/gnc-plugin-page-account-tree.c index d4dbd5cd2a..176e9bc0bb 100644 --- a/gnucash/gnome/gnc-plugin-page-account-tree.c +++ b/gnucash/gnome/gnc-plugin-page-account-tree.c @@ -82,6 +82,8 @@ static QofLogModule log_module = GNC_MOD_GUI; #define DELETE_DIALOG_TRANS_MAS "trans_mas" #define DELETE_DIALOG_SA_MAS "sa_mas" #define DELETE_DIALOG_SA_TRANS_MAS "sa_trans_mas" +#define DELETE_DIALOG_SA_TRANS "sa_trans" +#define DELETE_DIALOG_SA_SPLITS "sa_has_split" #define DELETE_DIALOG_OK_BUTTON "deletebutton" enum @@ -1286,8 +1288,36 @@ gppat_populate_trans_mas_list(GtkToggleButton *sa_mrb, void gppat_set_insensitive_iff_rb_active(GtkWidget *widget, GtkToggleButton *b) { + GtkWidget *dialog = gtk_widget_get_toplevel(widget); + GtkWidget *subaccount_trans = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_SA_TRANS); + GtkWidget *sa_mas = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_SA_MAS); + gboolean have_splits = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_SA_SPLITS)); + gtk_widget_set_sensitive(widget, !gtk_toggle_button_get_active(b)); - set_ok_sensitivity(gtk_widget_get_toplevel(widget)); + + // If we have subaccount splits & delete subaccounts, enable subaccount_trans + if ((have_splits) && !gtk_widget_is_sensitive(sa_mas)) + gtk_widget_set_sensitive(subaccount_trans, TRUE); + else + gtk_widget_set_sensitive(subaccount_trans, FALSE); + + set_ok_sensitivity(dialog); +} + +static GtkWidget * +gppat_setup_account_selector (GtkBuilder *builder, GtkWidget *dialog, + const gchar *hbox, const gchar *sel_name) +{ + GtkWidget *selector = gnc_account_sel_new(); + GtkWidget *box = GTK_WIDGET(gtk_builder_get_object (builder, hbox)); + + gtk_box_pack_start (GTK_BOX(box), selector, TRUE, TRUE, 0); + g_object_set_data(G_OBJECT(dialog), sel_name, selector); + + gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(selector), TRUE); + gtk_widget_show_all(box); + + return selector; } static void @@ -1332,7 +1362,7 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag splits = xaccAccountGetSplitList(account); /* - * If the account has transactions or child accounts then conduct a + * If the account has transactions or child accounts then present a * dialog to allow the user to specify what should be done with them. */ if ((NULL != splits) || (gnc_account_n_children(account) > 0)) @@ -1340,7 +1370,6 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag GList *filter = NULL; GtkBuilder *builder = NULL; GtkWidget *dialog = NULL; - GtkWidget *box = NULL; GtkWidget *widget = NULL; gchar *title = NULL; @@ -1366,78 +1395,70 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_FILTER, filter); g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_ACCOUNT, account); - /* - * Adjust the dialog based on whether the account has - * transactions. - */ + // Add the account selectors and enable sections as appropiate + // setup transactions selector + trans_mas = gppat_setup_account_selector (builder, dialog, "trans_mas_hbox", DELETE_DIALOG_TRANS_MAS); + + // Does the selected account have splits if (splits) { delete_helper_t delete_res2 = { FALSE, FALSE }; - trans_mas = gnc_account_sel_new(); - box = GTK_WIDGET(gtk_builder_get_object (builder, "trans_mas_hbox")); - gtk_box_pack_start (GTK_BOX(box), trans_mas, TRUE, TRUE, 0); - g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_TRANS_MAS, trans_mas); - gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(trans_mas), FALSE); - delete_account_helper(account, &delete_res2); if (delete_res2.has_ro_splits) { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "trans_rw"))); + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "trans_rw"))); widget = GTK_WIDGET(gtk_builder_get_object (builder, "trans_drb")); gtk_widget_set_sensitive(widget, FALSE); } else - { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "trans_ro"))); - } + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "trans_ro"))); } else { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "transactions"))); + gtk_widget_set_sensitive (GTK_WIDGET(gtk_builder_get_object (builder, "transactions")), FALSE); + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "trans_ro"))); } - /* - * Adjust the dialog based on whether the account has children. - */ + // setup subaccount account selector + sa_mas = gppat_setup_account_selector (builder, dialog, "sa_mas_hbox", DELETE_DIALOG_SA_MAS); + + // setup subaccount transaction selector + sa_trans_mas = gppat_setup_account_selector (builder, dialog, "sa_trans_mas_hbox", DELETE_DIALOG_SA_TRANS_MAS); + g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_TRANS, + GTK_WIDGET(gtk_builder_get_object (builder, "subaccount_trans"))); + + // Does the selected account have sub accounts if (gnc_account_n_children(account) > 0) { - /* - * Check for RO txns in descendants - */ + // Check for RO txns in descendants gnc_account_foreach_descendant_until(account, delete_account_helper, &delete_res); - if (delete_res.has_ro_splits) + if (delete_res.has_splits) { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_rw"))); - widget = GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_drb")); - gtk_widget_set_sensitive(widget, FALSE); - } - else if (delete_res.has_splits) - { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_ro"))); + if (delete_res.has_ro_splits) + { + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_rw"))); + widget = GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_drb")); + gtk_widget_set_sensitive(widget, FALSE); + } + else + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_ro"))); + + g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_SPLITS, GINT_TO_POINTER(1)); } else { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "subaccount_trans"))); + g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_SPLITS, GINT_TO_POINTER(0)); + gtk_widget_set_sensitive (GTK_WIDGET(gtk_builder_get_object (builder, "subaccount_trans")), FALSE); + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_ro"))); } - - sa_mas = gnc_account_sel_new(); - box = GTK_WIDGET(gtk_builder_get_object (builder, "sa_mas_hbox")); - gtk_box_pack_start (GTK_BOX(box), sa_mas, TRUE, TRUE, 0); - g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_MAS, sa_mas); - gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(sa_mas), TRUE); - - sa_trans_mas = gnc_account_sel_new(); - box = GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_mas_hbox")); - gtk_box_pack_start (GTK_BOX(box), sa_trans_mas, TRUE, TRUE, 0); - g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_TRANS_MAS, sa_trans_mas); - gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(sa_trans_mas), TRUE); } else { - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "subaccounts"))); - gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "subaccount_trans"))); + gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object (builder, "subaccounts")), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object (builder, "subaccount_trans")), FALSE); + gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder, "sa_trans_ro"))); } /* default to cancel */ @@ -1450,7 +1471,6 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag * Note that one effect of the modal dialog is preventing * the account selectors from being repopulated. */ - gtk_widget_show_all(dialog); response = gtk_dialog_run(GTK_DIALOG(dialog)); if (GTK_RESPONSE_ACCEPT != response) { diff --git a/gnucash/gtkbuilder/dialog-account.glade b/gnucash/gtkbuilder/dialog-account.glade index 9569ca71ad..5a9c21007c 100644 --- a/gnucash/gtkbuilder/dialog-account.glade +++ b/gnucash/gtkbuilder/dialog-account.glade @@ -195,7 +195,7 @@ False False - 1 + 2 @@ -302,7 +302,7 @@ False False - 2 + 1 From f1dd8cfaf13395e8fe44768211a76a98fe358e1f Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Wed, 21 Mar 2018 12:28:34 +0000 Subject: [PATCH 04/12] Component not found error when accounts are deleted When accounts are deleted that have an open register window a component not found error is triggered. After the account is destroyed, a call to 'gnc_resume_gui_refresh' calls 'gnc_gui_refresh_internal' and this then calls 'find_component_ids_by_class' which is used in order resulting in 'register-single' being unregistered before 'GncPluginPageRegister' and hence 'ld' being freed but the register not knowing this. Reversing the list fixes this. --- gnucash/register/ledger-core/gnc-ledger-display.c | 1 + libgnucash/app-utils/gnc-component-manager.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/gnucash/register/ledger-core/gnc-ledger-display.c b/gnucash/register/ledger-core/gnc-ledger-display.c index ea390ee1e1..c84c1f7cd7 100644 --- a/gnucash/register/ledger-core/gnc-ledger-display.c +++ b/gnucash/register/ledger-core/gnc-ledger-display.c @@ -594,6 +594,7 @@ close_handler (gpointer user_data) return; gnc_unregister_gui_component (ld->component_id); + ld->component_id = NO_COMPONENT; if (ld->destroy) ld->destroy (ld); diff --git a/libgnucash/app-utils/gnc-component-manager.c b/libgnucash/app-utils/gnc-component-manager.c index e788b48995..c32be015df 100644 --- a/libgnucash/app-utils/gnc-component-manager.c +++ b/libgnucash/app-utils/gnc-component-manager.c @@ -690,6 +690,8 @@ gnc_gui_refresh_internal (gboolean force) #endif list = find_component_ids_by_class (NULL); + // reverse the list so class GncPluginPageRegister is before register-single + list = g_list_reverse (list); for (node = list; node; node = node->next) { From 9135ec45244f193d75b95e894b394a3593297363 Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Wed, 21 Mar 2018 13:04:42 +0000 Subject: [PATCH 05/12] Fix a couple of Transient parent warnings --- gnucash/gnome/gnc-split-reg.c | 12 ++++++------ gnucash/register/ledger-core/split-register-model.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gnucash/gnome/gnc-split-reg.c b/gnucash/gnome/gnc-split-reg.c index 1cb02f2c2a..ac909430e8 100644 --- a/gnucash/gnome/gnc-split-reg.c +++ b/gnucash/gnome/gnc-split-reg.c @@ -786,7 +786,7 @@ gnc_split_reg_reverse_trans_cb (GtkWidget *w, gpointer data) static gboolean -is_trans_readonly_and_warn (const Transaction *trans) +is_trans_readonly_and_warn (GtkWindow *parent, const Transaction *trans) { GtkWidget *dialog; const gchar *reason; @@ -798,7 +798,7 @@ is_trans_readonly_and_warn (const Transaction *trans) if (xaccTransIsReadonlyByPostedDate (trans)) { - dialog = gtk_message_dialog_new(NULL, + dialog = gtk_message_dialog_new(parent, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, @@ -814,7 +814,7 @@ is_trans_readonly_and_warn (const Transaction *trans) reason = xaccTransGetReadOnly (trans); if (reason) { - dialog = gtk_message_dialog_new(NULL, + dialog = gtk_message_dialog_new(parent, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, @@ -848,7 +848,7 @@ gsr_default_reinit_handler( GNCSplitReg *gsr, gpointer data ) reg = gnc_ledger_display_get_split_register( gsr->ledger ); trans = gnc_split_register_get_current_trans (reg); - if (is_trans_readonly_and_warn(trans)) + if (is_trans_readonly_and_warn(GTK_WINDOW(gsr->window), trans)) return; dialog = gtk_message_dialog_new(GTK_WINDOW(gsr->window), GTK_DIALOG_DESTROY_WITH_PARENT, @@ -1056,7 +1056,7 @@ gsr_default_associate_handler (GNCSplitReg *gsr, gboolean uri_is_file) if (cursor_class == CURSOR_CLASS_NONE) return; - if (is_trans_readonly_and_warn (trans)) + if (is_trans_readonly_and_warn (GTK_WINDOW(gsr->window), trans)) return; // get the existing uri @@ -1183,7 +1183,7 @@ gsr_default_delete_handler( GNCSplitReg *gsr, gpointer data ) if (cursor_class == CURSOR_CLASS_NONE) return; - if (is_trans_readonly_and_warn(trans)) + if (is_trans_readonly_and_warn(GTK_WINDOW(gsr->window), trans)) return; /* On a split cursor, just delete the one split. */ diff --git a/gnucash/register/ledger-core/split-register-model.c b/gnucash/register/ledger-core/split-register-model.c index 48d7a0b2ac..bd132953ca 100644 --- a/gnucash/register/ledger-core/split-register-model.c +++ b/gnucash/register/ledger-core/split-register-model.c @@ -1957,7 +1957,7 @@ gnc_split_register_get_security_io_flags (VirtualLocation virt_loc, } static gboolean -xaccTransWarnReadOnly (const Transaction *trans) +xaccTransWarnReadOnly (GtkWidget *parent, const Transaction *trans) { GtkWidget *dialog; const gchar *reason; @@ -1970,7 +1970,7 @@ xaccTransWarnReadOnly (const Transaction *trans) reason = xaccTransGetReadOnly (trans); if (reason) { - dialog = gtk_message_dialog_new(NULL, + dialog = gtk_message_dialog_new(GTK_WINDOW(parent), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, @@ -2007,7 +2007,7 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data) return TRUE; trans = xaccSplitGetParent (split); - if (xaccTransWarnReadOnly(trans)) + if (xaccTransWarnReadOnly(gnc_split_register_get_parent(reg), trans)) return FALSE; if (!xaccTransHasReconciledSplits (trans)) From 2571baff9fde514791ad8f2eb1758ee16ec3499c Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Wed, 21 Mar 2018 13:05:49 +0000 Subject: [PATCH 06/12] Bug 794644 - Deleting prices slow Detach the price tree model from the price tree view while prices are being deleted and then reattach. --- gnucash/gnome/dialog-price-edit-db.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gnucash/gnome/dialog-price-edit-db.c b/gnucash/gnome/dialog-price-edit-db.c index f6d5efb695..4fdcc0971e 100644 --- a/gnucash/gnome/dialog-price-edit-db.c +++ b/gnucash/gnome/dialog-price-edit-db.c @@ -387,6 +387,7 @@ gnc_prices_dialog_remove_old_clicked (GtkWidget *widget, gpointer data) { PricesDialog *pdb_dialog = data; GtkBuilder *builder; + GtkTreeModel *model; GtkWidget *date, *label, *box; GtkWidget *button; GtkTreeSelection *selection; @@ -459,6 +460,11 @@ gnc_prices_dialog_remove_old_clicked (GtkWidget *widget, gpointer data) PriceRemoveSourceFlags source = PRICE_REMOVE_SOURCE_FQ; PriceRemoveKeepOptions keep = PRICE_REMOVE_KEEP_NONE; + // disconnect the model to the price treeview + model = gtk_tree_view_get_model (GTK_TREE_VIEW(pdb_dialog->price_tree)); + g_object_ref (G_OBJECT(model)); + gtk_tree_view_set_model (GTK_TREE_VIEW(pdb_dialog->price_tree), NULL); + DEBUG("deleting prices"); last_ts.tv_sec = gnc_date_edit_get_date (GNC_DATE_EDIT (date)); last_ts.tv_nsec = 0; @@ -498,6 +504,9 @@ gnc_prices_dialog_remove_old_clicked (GtkWidget *widget, gpointer data) gnc_pricedb_remove_old_prices (pdb_dialog->price_db, comm_list, &fiscal_end_date, tmp_ts, pdb_dialog->remove_source, PRICE_REMOVE_KEEP_LAST_MONTHLY); } + // reconnect the model to the price treeview + gtk_tree_view_set_model (GTK_TREE_VIEW(pdb_dialog->price_tree), model); + g_object_unref(G_OBJECT(model)); } g_list_free (comm_list); } From bea89a50ac0656c229c0ec6e54053fc08563397c Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 22 Mar 2018 15:08:22 -0700 Subject: [PATCH 07/12] More python 3 fixups. --- .../example_scripts/account_analysis.py | 14 ++-- .../example_scripts/gncinvoice_jinja.py | 70 +++++++++---------- .../python/example_scripts/gncinvoicefkt.py | 6 +- .../python/example_scripts/latex_invoices.py | 70 +++++++++---------- .../new_book_with_opening_balances.py | 10 +-- .../python/example_scripts/priceDB_test.py | 4 +- .../example_scripts/price_database_example.py | 12 ++-- .../python/example_scripts/quotes_historic.py | 6 +- .../example_scripts/rest-api/gnucash_rest.py | 10 +-- .../python/example_scripts/simple_book.py | 8 +-- .../example_scripts/simple_business_create.py | 8 +-- .../test_imbalance_transaction.py | 14 ++-- gnucash/python/pycons/ishell.py | 4 +- gnucash/python/pycons/shell.py | 6 +- 14 files changed, 121 insertions(+), 121 deletions(-) diff --git a/bindings/python/example_scripts/account_analysis.py b/bindings/python/example_scripts/account_analysis.py index dd7fc4a9a0..87e1dfe7b7 100644 --- a/bindings/python/example_scripts/account_analysis.py +++ b/bindings/python/example_scripts/account_analysis.py @@ -152,13 +152,13 @@ def account_from_path(top_account, account_path, original_path=None): def main(): if len(argv) < 10: - print 'not enough parameters' - print 'usage: account_analysis.py {book url} {start year} {start month, numeric} {period type: monthly, quarterly, or yearly} {number of periods to show, from start year and month} {whether to show debits: debits-show for true, all other values false} {whether to show credits: credits-show for true, all other values false} {space separated account path, as many nested levels as desired} ' - print 'examples:\n' - print "The following example analyzes 12 months of 'Assets:Test Account' from /home/username/test.gnucash, starting in January of 2010, and shows both credits and debits" - print "gnucash-env python account_analysis.py '/home/username/test.gnucash' 2010 1 monthly 12 debits-show credits-show Assets 'Test Account'\n" - print "The following example analyzes 2 quarters of 'Liabilities:First Level:Second Level' from /home/username/test.gnucash, starting March 2011, and shows credits but not debits" - print "gnucash-env python account_analysis.py '/home/username/test.gnucash' 2011 3 quarterly 2 debits-noshow credits-show Liabilities 'First Level' 'Second Level" + print('not enough parameters') + print('usage: account_analysis.py {book url} {start year} {start month, numeric} {period type: monthly, quarterly, or yearly} {number of periods to show, from start year and month} {whether to show debits: debits-show for true, all other values false} {whether to show credits: credits-show for true, all other values false} {space separated account path, as many nested levels as desired} ') + print('examples:\n') + print("The following example analyzes 12 months of 'Assets:Test Account' from /home/username/test.gnucash, starting in January of 2010, and shows both credits and debits") + print("gnucash-env python account_analysis.py '/home/username/test.gnucash' 2010 1 monthly 12 debits-show credits-show Assets 'Test Account'\n") + print("The following example analyzes 2 quarters of 'Liabilities:First Level:Second Level' from /home/username/test.gnucash, starting March 2011, and shows credits but not debits") + print("gnucash-env python account_analysis.py '/home/username/test.gnucash' 2011 3 quarterly 2 debits-noshow credits-show Liabilities 'First Level' 'Second Level") return try: diff --git a/bindings/python/example_scripts/gncinvoice_jinja.py b/bindings/python/example_scripts/gncinvoice_jinja.py index 6e4eaff5c0..ec93ed030f 100644 --- a/bindings/python/example_scripts/gncinvoice_jinja.py +++ b/bindings/python/example_scripts/gncinvoice_jinja.py @@ -39,8 +39,8 @@ try: import jinja2 from gncinvoicefkt import * except ImportError as import_error: - print "Problem importing modules." - print import_error + print("Problem importing modules.") + print(import_error) sys.exit(2) class Usage(Exception): @@ -68,26 +68,26 @@ def main(argv=None): for opt in opts: if opt[0] in ["-f"]: - print "ignoring lock" + print("ignoring lock") ignore_lock = True if opt[0] in ["-h","--help"]: raise Usage("Help:") if opt[0] in ["-I"]: invoice_id = opt[1] - print "using invoice ID '" + str(invoice_id) + "'." + print("using invoice ID '" + str(invoice_id) + "'.") if opt[0] in ["-o"]: filename_output = opt[1] - print "using output file", filename_output + print("using output file", filename_output) if opt[0] in ["-t"]: filename_template = opt[1] - print "using template file", filename_template + print("using template file", filename_template) if opt[0] in ["-l"]: list_invoices = True - print "listing invoices" + print("listing invoices") # Check for correct input if len(args)>1: - print "opts:",opts,"args:",args + print("opts:",opts,"args:",args) raise Usage("Only one input possible !") if len(args)==0: raise Usage("No input given !") @@ -103,41 +103,41 @@ def main(argv=None): if not filename_output: if filename_template: filename_output = filename_template + ".out" - print "no output filename given, will be:", filename_output + print("no output filename given, will be:", filename_output) except Usage, err: if err.msg == "Help:": retcode=0 else: - print >>sys.stderr, "Error:",err.msg - print >>sys.stderr, "for help use --help" + print(>>sys.stderr, "Error:",err.msg) + print(>>sys.stderr, "for help use --help") retcode=2 - print - print "Usage:" - print - print "Invoke with",prog_name,"gnucash_url." - print "where input is" - print " filename" - print "or file://filename" - print "or mysql://user:password@host/databasename" - print - print "-f force open = ignore lock" - print "-l list all invoices" - print "-h or --help for this help" - print "-I ID use invoice ID" - print "-t filename use filename as template file" - print "-o filename use filename as output file" + print() + print("Usage:") + print() + print("Invoke with",prog_name,"gnucash_url.") + print("where input is") + print(" filename") + print("or file://filename") + print("or mysql://user:password@host/databasename") + print() + print("-f force open = ignore lock") + print("-l list all invoices") + print("-h or --help for this help") + print("-I ID use invoice ID") + print("-t filename use filename as template file") + print("-o filename use filename as output file") return retcode # Try to open the given input try: - print "Opening", input_url, "." + print("Opening", input_url, ".") session = gnucash.Session(input_url, ignore_lock=ignore_lock) except Exception as exception: - print "Problem opening input." - print exception + print("Problem opening input.") + print(exception) return 2 book = session.book @@ -149,22 +149,22 @@ def main(argv=None): if list_invoices: for number,invoice in enumerate(invoice_list): - print str(number)+")" - print invoice + print(str(number)+")") + print(invoice) if not (no_output): if invoice_id: invoice = book.InvoiceLookupByID(invoice_id) if not invoice: - print "ID not found." + print("ID not found.") return 2 if invoice_number: invoice = invoice_list[invoice_number] - print "Using the following invoice:" - print invoice + print("Using the following invoice:") + print(invoice) loader = jinja2.FileSystemLoader('.') env = jinja2.Environment(loader=loader) @@ -174,7 +174,7 @@ def main(argv=None): #IPython.embed() output = template.render(invoice=invoice, locale=locale) - print "Writing output", filename_output, "." + print("Writing output", filename_output, ".") with open(filename_output, 'w') as f: f.write(output.encode('utf-8')) diff --git a/bindings/python/example_scripts/gncinvoicefkt.py b/bindings/python/example_scripts/gncinvoicefkt.py index 9e0ffa05a0..ef778b4370 100644 --- a/bindings/python/example_scripts/gncinvoicefkt.py +++ b/bindings/python/example_scripts/gncinvoicefkt.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# -*- coding: utf-8 -*- ##@file # @brief some help for working with invoices, used in \ref py_invoice_export @@ -22,8 +22,8 @@ try: GNC_DISC_PRETAX import str_methods except ImportError as import_error: - print "Problem importing modules." - print import_error + print("Problem importing modules.") + print(import_error) sys.exit(2) def get_all_lots(account): diff --git a/bindings/python/example_scripts/latex_invoices.py b/bindings/python/example_scripts/latex_invoices.py index 8b738fa715..4c6c1d45fb 100644 --- a/bindings/python/example_scripts/latex_invoices.py +++ b/bindings/python/example_scripts/latex_invoices.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# -*- coding: utf-8 -*- ##@file # @brief Exports an invoice to lco-file for use with LaTeX, see \ref py_invoice_export @@ -66,8 +66,8 @@ try: GNC_DISC_PRETAX import locale except ImportError as import_error: - print "Problem importing modules." - print import_error + print("Problem importing modules.") + print(import_error) sys.exit(2) class Usage(Exception): @@ -157,7 +157,7 @@ def invoice_to_lco(invoice): line_str += uprice line_str += u"}" - #print line_str + #print(line_str) ent_str += line_str lco_out += write_variable("entries",ent_str) @@ -184,25 +184,25 @@ def main(argv=None): for opt in opts: if opt[0] in ["-f"]: - print "ignoring lock" + print("ignoring lock") ignore_lock = True if opt[0] in ["-h","--help"]: raise Usage("Help:") if opt[0] in ["-i"]: - print "Using ipshell" + print("Using ipshell") with_ipshell = True if opt[0] in ["-l"]: - print "listing all invoices" + print("listing all invoices") list_invoices=True if opt[0] in ["-n"]: invoice_number = int(opt[1]) - print "using invoice number", invoice_number + print("using invoice number", invoice_number) no_latex_output = False if opt[0] in ["-o"]: output_file_name = opt[1] - print "using output file", output_file_name + print("using output file", output_file_name) if len(args)>1: - print "opts:",opts,"args:",args + print("opts:",opts,"args:",args) raise Usage("Only one input can be accepted !") if len(args)==0: raise Usage("No input given !") @@ -211,26 +211,26 @@ def main(argv=None): if err.msg == "Help:": retcode=0 else: - print >>sys.stderr, "Error:",err.msg - print >>sys.stderr, "for help use --help" + print(>>sys.stderr, "Error:",err.msg) + print(>>sys.stderr, "for help use --help") retcode=2 - print "Generate a LaTeX invoice or print out all invoices." - print - print "Usage:" - print - print "Invoke with",prog_name,"input." - print "where input is" - print " filename" - print "or file://filename" - print "or mysql://user:password@host/databasename" - print - print "-f force open = ignore lock" - print "-h or --help for this help" - print "-i for ipython shell" - print "-l list all invoices" - print "-n number use invoice number (no. from previous run with -l)" - print "-o name use name as outputfile. default: data.lco" + print("Generate a LaTeX invoice or print out all invoices.") + print() + print("Usage:") + print() + print("Invoke with",prog_name,"input.") + print("where input is") + print(" filename") + print("or file://filename") + print("or mysql://user:password@host/databasename") + print() + print("-f force open = ignore lock") + print("-h or --help for this help") + print("-i for ipython shell") + print("-l list all invoices") + print("-n number use invoice number (no. from previous run with -l)") + print("-o name use name as outputfile. default: data.lco") return retcode @@ -238,8 +238,8 @@ def main(argv=None): try: session = gnucash.Session(input_url,ignore_lock=ignore_lock) except Exception as exception: - print "Problem opening input." - print exception + print("Problem opening input.") + print(exception) return 2 book = session.book @@ -251,18 +251,18 @@ def main(argv=None): if list_invoices: for number,invoice in enumerate(invoice_list): - print str(number)+")" - print invoice + print(str(number)+")") + print(invoice) if not (no_latex_output): if invoice_number == None: - print "Using the first invoice:" + print("Using the first invoice:") invoice_number=0 invoice=invoice_list[invoice_number] - print "Using the following invoice:" - print invoice + print("Using the following invoice:") + print(invoice) lco_str=invoice_to_lco(invoice) diff --git a/bindings/python/example_scripts/new_book_with_opening_balances.py b/bindings/python/example_scripts/new_book_with_opening_balances.py index 08a08deca5..0ee02c4031 100644 --- a/bindings/python/example_scripts/new_book_with_opening_balances.py +++ b/bindings/python/example_scripts/new_book_with_opening_balances.py @@ -290,11 +290,11 @@ def create_opening_balance_transaction(commodtable, namespace, mnemonic, def main(): if len(argv) < 3: - print 'not enough parameters' - print 'usage: new_book_with_opening_balances.py {source_book_url} {destination_book_url}' - print 'examples:' - print "gnucash-env python new_book_with_opening_balances.py '/home/username/test.gnucash' 'sqlite3:///home/username/new_test.gnucash'" - print "gnucash-env python new_book_with_opening_balances.py '/home/username/test.gnucash' 'xml:///crypthome/username/finances/new_test.gnucash'" + print('not enough parameters') + print('usage: new_book_with_opening_balances.py {source_book_url} {destination_book_url}') + print('examples:') + print("gnucash-env python new_book_with_opening_balances.py '/home/username/test.gnucash' 'sqlite3:///home/username/new_test.gnucash'") + print("gnucash-env python new_book_with_opening_balances.py '/home/username/test.gnucash' 'xml:///crypthome/username/finances/new_test.gnucash'") return #have everything in a try block to unable us to release our hold on stuff to the extent possible diff --git a/bindings/python/example_scripts/priceDB_test.py b/bindings/python/example_scripts/priceDB_test.py index fcd30e2750..41f42fb95b 100644 --- a/bindings/python/example_scripts/priceDB_test.py +++ b/bindings/python/example_scripts/priceDB_test.py @@ -41,11 +41,11 @@ for pr in pl: time = pr.get_time() v=pr.get_value() price = float(v.num)/v.denom - print time, source, price + print(time, source, price) if len(pl) > 0: v0 = pl[0].get_value() - print arm.get_fullname(), float(v0.num) / float(v0.denom ) + print(arm.get_fullname(), float(v0.num) / float(v0.denom )) session.end() session.destroy() diff --git a/bindings/python/example_scripts/price_database_example.py b/bindings/python/example_scripts/price_database_example.py index 86db03328e..b9b10e85ce 100755 --- a/bindings/python/example_scripts/price_database_example.py +++ b/bindings/python/example_scripts/price_database_example.py @@ -57,12 +57,12 @@ for namespace in namespaces: if len(commodities) == 0 : - print "No commodity in namespace "+namespace_name+"." + print("No commodity in namespace "+namespace_name+".") else: if commodity_fullname: - print "Searching commodity '"+commodity_fullname+"' in namespace "+namespace_name + print("Searching commodity '"+commodity_fullname+"' in namespace "+namespace_name) else: - print "Commoditys in namespace "+namespace_name+":" + print("Commoditys in namespace "+namespace_name+":") for i, c in enumerate(commodities): @@ -70,12 +70,12 @@ for namespace in namespaces: c_fullname = c.get_fullname() if not(commodity_fullname) or (commodity_fullname == c_fullname): - print "["+str(i)+"] Full Name :", c.get_fullname() + print("["+str(i)+"] Full Name :", c.get_fullname()) if show_prices: pl = pdb.get_prices(c,cur) if len(pl) > 0 : - print "{0} {1:20}{2:>10} {3}".format("Time ","Source","Price","Currency") + print("{0} {1:20}{2:>10} {3}".format("Time ","Source","Price","Currency")) for pr in pl: source = pr.get_source() @@ -83,7 +83,7 @@ for namespace in namespaces: v=pr.get_value() price = float(v.num)/v.denom - print "{0} {1:20}{2:10.4f} {3}".format(time,source,price,cur_name) + print("{0} {1:20}{2:10.4f} {3}".format(time,source,price,cur_name)) # I didn't find out how to format the time option... session.end() diff --git a/bindings/python/example_scripts/quotes_historic.py b/bindings/python/example_scripts/quotes_historic.py index da70cc7fe1..964c70f029 100644 --- a/bindings/python/example_scripts/quotes_historic.py +++ b/bindings/python/example_scripts/quotes_historic.py @@ -60,14 +60,14 @@ stock = ac.GetCommodity() # Add the prices pdb = book.get_price_db() if len(ac.GetSplitList())<1: - print 'Need at least one Split to get currency info ... ' + print('Need at least one Split to get currency info ... ') raise SystemExit cur = ac.GetSplitList()[0].GetParent().GetCurrency() # Get stock data pl = pdb.get_prices(stock,cur) if len(pl)<1: - print 'Need at least one database entry to clone ...' + print('Need at least one database entry to clone ...') raise SystemExit pl0 = pl[0] @@ -77,7 +77,7 @@ for i in range(1,len(pl)): for i in range(0,len(stock_date)): p_new = pl0.clone(book) p_new = gnucash.GncPrice(instance=p_new) - print 'Adding',i,stock_date[i],stock_price[i] + print('Adding',i,stock_date[i],stock_price[i]) p_new.set_time(stock_date[i]) v = p_new.get_value() v.num = int(Fraction.from_float(stock_price[i]).limit_denominator(100000).numerator) diff --git a/bindings/python/example_scripts/rest-api/gnucash_rest.py b/bindings/python/example_scripts/rest-api/gnucash_rest.py index f6a4dc99cd..5444b98e98 100644 --- a/bindings/python/example_scripts/rest-api/gnucash_rest.py +++ b/bindings/python/example_scripts/rest-api/gnucash_rest.py @@ -835,7 +835,7 @@ def getAccountsFlat(book): for n, account in enumerate(flat_accounts): if account['type_id'] in type_ids: filtered_flat_account.append(account) - print account['name'] + ' ' + str(account['type_id']) + print(account['name'] + ' ' + str(account['type_id'])) return filtered_flat_account @@ -1846,7 +1846,7 @@ def shutdown(): session.save() session.end() session.destroy() - print 'Shutdown' + print('Shutdown') class Error(Exception): """Base class for exceptions in this module.""" @@ -1858,12 +1858,12 @@ class Error(Exception): try: options, arguments = getopt.getopt(sys.argv[1:], 'nh:', ['host=', 'new=']) except getopt.GetoptError as err: - print str(err) # will print something like "option -a not recognized" - print 'Usage: python-rest.py ' + print(str(err) # will print something like "option -a not recognized") + print('Usage: python-rest.py ') sys.exit(2) if len(arguments) == 0: - print 'Usage: python-rest.py ' + print('Usage: python-rest.py ') sys.exit(2) #set default host for Flask diff --git a/bindings/python/example_scripts/simple_book.py b/bindings/python/example_scripts/simple_book.py index bbc33546b0..4bde60817e 100644 --- a/bindings/python/example_scripts/simple_book.py +++ b/bindings/python/example_scripts/simple_book.py @@ -10,16 +10,16 @@ from gnucash import Session # We need to tell GnuCash the data format to create the new file as (xml://) uri = "xml:///tmp/simple_book.gnucash" -print "uri:", uri +print("uri:", uri) ses = Session(uri, is_new=True) book = ses.get_book() #Call some methods that produce output to show that Book works book.get_root_account().SetDescription("hello, book") -print "Book is saved:", not book.session_not_saved() +print("Book is saved:", not book.session_not_saved()) -print "saving..." +print("saving...") ses.save() -print "Book is saved:", not book.session_not_saved() +print("Book is saved:", not book.session_not_saved()) ses.end() diff --git a/bindings/python/example_scripts/simple_business_create.py b/bindings/python/example_scripts/simple_business_create.py index 40a2c3a02b..75a00228bb 100644 --- a/bindings/python/example_scripts/simple_business_create.py +++ b/bindings/python/example_scripts/simple_business_create.py @@ -62,10 +62,10 @@ from gnucash.gnucash_core_c import \ GNC_OWNER_CUSTOMER, ACCT_TYPE_LIABILITY if len(argv) < 2: - print 'not enough parameters' - print 'usage: simple_business_create.py {new_book_url}' - print 'example:' - print "gnucash-env python simple_business_create.py sqlite3:///home/blah/blah.gnucash" + print('not enough parameters') + print('usage: simple_business_create.py {new_book_url}') + print('example:') + print("gnucash-env python simple_business_create.py sqlite3:///home/blah/blah.gnucash") exit() diff --git a/bindings/python/example_scripts/test_imbalance_transaction.py b/bindings/python/example_scripts/test_imbalance_transaction.py index f50dea946f..d22072867d 100644 --- a/bindings/python/example_scripts/test_imbalance_transaction.py +++ b/bindings/python/example_scripts/test_imbalance_transaction.py @@ -42,10 +42,10 @@ from gnucash import Session, Transaction, Split, Account, GncNumeric, \ # and trading accounts disabled if len(argv) < 2: - print 'not enough parameters' - print 'usage: test_imbalance_transaction.py {book_url}' - print 'examples:' - print "gnucash-env python test_imbalance_transaction.py '/home/username/test.gnucash'" + print('not enough parameters') + print('usage: test_imbalance_transaction.py {book_url}') + print('examples:') + print("gnucash-env python test_imbalance_transaction.py '/home/username/test.gnucash'") exit() @@ -86,12 +86,12 @@ try: s2.SetAccount(account2) s2.SetValue(GncNumeric(4)) s2.SetAmount(GncNumeric(4)) - print 'overall imbalance', a.GetImbalanceValue().to_string() + print('overall imbalance', a.GetImbalanceValue().to_string()) - print 'per-currency imbalances' + print('per-currency imbalances') imbalance_list = a.GetImbalance() for (commod, value) in imbalance_list: - print value.to_string(), commod.get_mnemonic() + print(value.to_string(), commod.get_mnemonic()) a.CommitEdit() diff --git a/gnucash/python/pycons/ishell.py b/gnucash/python/pycons/ishell.py index aa84467b67..371f32c4a4 100644 --- a/gnucash/python/pycons/ishell.py +++ b/gnucash/python/pycons/ishell.py @@ -125,10 +125,10 @@ class Shell: def shell(self, cmd,verbose=0,debug=0,header=''): stat = 0 - if verbose or debug: print header+cmd + if verbose or debug: print(header+cmd) if not debug: input, output = os.popen4(cmd) - print output.read() + print(output.read()) output.close() input.close() diff --git a/gnucash/python/pycons/shell.py b/gnucash/python/pycons/shell.py index 6569d17cb0..d50043eb95 100644 --- a/gnucash/python/pycons/shell.py +++ b/gnucash/python/pycons/shell.py @@ -153,7 +153,7 @@ class Shell: console.write (buf, 'output') if len(buf) < 256: break # Command output - print `r` + print(`r`) except SyntaxError: exec self.command in self.globals except: @@ -166,8 +166,8 @@ class Shell: tb = sys.exc_traceback if tb: tb=tb.tb_next - traceback.print_exception (sys.exc_type, sys.exc_value, tb) + traceback.print(_exception (sys.exc_type, sys.exc_value, tb)) except: sys.stderr, console.stderr = console.stderr, sys.stderr - traceback.print_exc() + traceback.print(_exc()) From 148c02d231f3c1e545e62e23616a6f32018c5208 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 22 Mar 2018 15:29:08 -0700 Subject: [PATCH 08/12] [python bindings] Add required posted dates to the transactions. --- bindings/python/example_scripts/simple_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bindings/python/example_scripts/simple_test.py b/bindings/python/example_scripts/simple_test.py index 7156fd9f3a..274164168d 100644 --- a/bindings/python/example_scripts/simple_test.py +++ b/bindings/python/example_scripts/simple_test.py @@ -61,9 +61,11 @@ split3.SetAccount(savings_acct) split3.SetParent(trans2) trans1.SetCurrency(cad) +trans1.SetDate(14, 3, 2006) trans1.SetDescription("Groceries") trans2.SetCurrency(cad) +trans2.SetDate(7, 11, 1995) trans2.SetDescription("Opening Savings Balance") split2 = Split(book) From 7b6854c1631e27e634a6b3d4e22ee6a8389836dd Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 24 Mar 2018 17:49:01 -0700 Subject: [PATCH 09/12] Load the environment file when initializing the python bindings. --- bindings/python/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/__init__.py b/bindings/python/__init__.py index 1c874734e3..4082cfe7cc 100644 --- a/bindings/python/__init__.py +++ b/bindings/python/__init__.py @@ -4,6 +4,7 @@ # instead of # >>> from gnucash.gnucash_core import thingy from gnucash.gnucash_core import * +gnc_environment_setup() ## @file # @brief helper file for the importing of gnucash # @author Mark Jenkins, ParIT Worker Co-operative From a670238f80a92552f7b4771be424f7fc382df69b Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sun, 25 Mar 2018 15:47:35 +0800 Subject: [PATCH 10/12] Bug 794030 - relative date functions compute wrong day of month Convert > to < and rename month-length to month-days for consistency. --- src/app-utils/date-utilities.scm | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/app-utils/date-utilities.scm b/src/app-utils/date-utilities.scm index 72eb0f35ec..5ecd844a5e 100644 --- a/src/app-utils/date-utilities.scm +++ b/src/app-utils/date-utilities.scm @@ -718,10 +718,10 @@ (set-tm:mon now 11) (set-tm:year now (- (tm:year now) 1))) (set-tm:mon now (- (tm:mon now) 1))) - (let ((month-length (gnc:days-in-month (+ (tm:mon now) 1) - (+ (tm:year now) 1900)))) - (if (> month-length (tm:mday now)) - (set-tm:mday now month-length)) + (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) + (+ (tm:year now) 1900)))) + (if (< month-days (tm:mday now)) + (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -734,7 +734,7 @@ (set:tm-mon now (- (tm:mon now) 3)) (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) (+ (tm:year now) 1900)))) - (if (> month-days (tm:mday now)) + (if (< month-days (tm:mday now)) (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -748,7 +748,7 @@ (set:tm-mon now (- (tm:mon now) 6)) (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) (+ (tm:year now) 1900)))) - (if (> month-days (tm:mday now)) + (if (< month-days (tm:mday now)) (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -757,8 +757,8 @@ (let ((now (gnc-localtime (current-time)))) (set:tm-year now (- (tm:year now) 1)) (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) - (+ (tm:year now) 1900)))) - (if (> month-days (tm:mday now)) + (+ (tm:year now) 1900)))) + (if (< month-days (tm:mday now)) (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -770,10 +770,10 @@ (set-tm:mon now 0) (set-tm:year now (+ (tm:year now) 1))) (set-tm:mon now (+ (tm:mon now) 1))) - (let ((month-length (gnc:days-in-month (+ (tm:mon now) 1) - (+ (tm:year now) 1900)))) - (if (> month-length (tm:mday now)) - (set-tm:mday now month-length)) + (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) + (+ (tm:year now) 1900)))) + (if (< month-days (tm:mday now)) + (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -783,10 +783,10 @@ (begin (set:tm-mon now (- (tm:mon now) 9)) (set:tm-year now (+ (tm:year now) 1)) - (set:tm-mon now (+ (tm:mon now) 3)))) + (set:tm-mon now (+ (tm:mon now) 3)))) (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) (+ (tm:year now) 1900)))) - (if (> month-days (tm:mday now)) + (if (< month-days (tm:mday now)) (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -797,10 +797,10 @@ (begin (set:tm-mon now (- (tm:mon now) 6)) (set:tm-year now (+ (tm:year now) 1)) - (set:tm-mon now (+ (tm:mon now) 6)))) + (set:tm-mon now (+ (tm:mon now) 6)))) (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) (+ (tm:year now) 1900)))) - (if (> month-days (tm:mday now)) + (if (< month-days (tm:mday now)) (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) @@ -809,8 +809,8 @@ (let ((now (gnc-localtime (current-time)))) (set:tm-year now (+ (tm:year now) 1)) (let ((month-days (gnc:days-in-month (+ (tm:mon now) 1) - (+ (tm:year now) 1900)))) - (if (> month-days (tm:mday now)) + (+ (tm:year now) 1900)))) + (if (< month-days (tm:mday now)) (set-tm:mday now month-days)) (set-tm:isdst now -1) (gnc:date->timepair now)))) From a0f49d8b17dede2c6f4835b700e18badf4acb025 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 25 Mar 2018 09:17:17 -0700 Subject: [PATCH 11/12] Revert "Load the environment file when initializing the python bindings." It's unnecessary, the swigged gnucash_core init function already does it. This reverts commit 7b6854c1631e27e634a6b3d4e22ee6a8389836dd. --- bindings/python/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bindings/python/__init__.py b/bindings/python/__init__.py index 4082cfe7cc..1c874734e3 100644 --- a/bindings/python/__init__.py +++ b/bindings/python/__init__.py @@ -4,7 +4,6 @@ # instead of # >>> from gnucash.gnucash_core import thingy from gnucash.gnucash_core import * -gnc_environment_setup() ## @file # @brief helper file for the importing of gnucash # @author Mark Jenkins, ParIT Worker Co-operative From dfb5de91ff76cd997ffa0f01a23de36a4f00ad71 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 25 Mar 2018 12:37:11 -0700 Subject: [PATCH 12/12] Release 2.7.8. --- CMakeLists.txt | 4 ++-- NEWS | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cdfba7e233..b8e0adf461 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,14 +13,14 @@ ENABLE_TESTING() # Version number of gnucash SET (GNUCASH_MAJOR_VERSION 2) SET (GNUCASH_MINOR_VERSION 7) -SET (GNUCASH_MICRO_VERSION 7) +SET (GNUCASH_MICRO_VERSION 8) SET (GNUCASH_NANO_VERSION 0) SET (VERSION "${GNUCASH_MAJOR_VERSION}.${GNUCASH_MINOR_VERSION}.${GNUCASH_MICRO_VERSION}") SET (GNUCASH_LATEST_STABLE_SERIES 2.6) SET (PACKAGE gnucash) SET (PACKAGE_NAME GnuCash) -SET (PACKAGE_VERSION 2.7.7) +SET (PACKAGE_VERSION 2.7.8) SET (PACKAGE_BUGREPORT gnucash-devel@gnucash.org) SET (PACKAGE_TARNAME ${PACKAGE}) SET (PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") diff --git a/NEWS b/NEWS index c79d29893c..ed44f6084b 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,40 @@ Version history: ------- ------- +2.7.8 - 25 March 2018 + + The Gnucash Development Team is pleased to release Gnucash 2.7.8, + the ninth release of an unstable series leading to Gnucash 3.0. This + release is a Release Candidate: If no bugs requiring major work are + reported the next release will be 3.0. + + This release changes file locations, binding APIs, report options, + and can make your data file no longer compatible with previous + versions. See https://wiki.gnucash.org/wiki/UpdateNotes for + details. + +The following bugs are fixed only in unstable/master: + Bug 787439 - Segmentation Fault in Transfer dialog after clearing + Date field and pressing escape. + Bug 794242 - Remove keep above setting for assistant hierarchy + +Other repairs not marked as bugs in git: + When doing a file save from the a new start we have no key file + Test for Key_file not being NULL before trying to free it. + Stop critical error due to testing null filename + g_filename_from_uri returns NULL if it is not a file uri so test + for the file:// prefix before doing g_file_test + More transient-parent fixes. + Add missing response section to the account picker dialog. + Glade 3.20 adds surplus padding option to action area + When glade files are saved which have GtkAssistants defined a packing + section is added to the assistant action area which then causes a + warning so remove them. + Add XML namespaces for all Account Hierarchy Templates. + Increase default options dialog size: The old 400x400 was woefully + inadequate for most options especially options involving account trees. + +Updated Translations: None. + 2.7.7 - 18 March 2018 The Gnucash Development Team is pleased to release Gnucash 2.7.7,