gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Tue Jun 20 16:44:15 EDT 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/f3eeda3a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/12d85ff6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c80dad74 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4032d33b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/cc3010d8 (commit)
	from  https://github.com/Gnucash/gnucash/commit/7e8b66fa (commit)



commit f3eeda3a9e8e27dc982f070836b63d88ae79a3ed
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Jun 20 22:23:59 2017 +0200

    Stop writing commodity namespaces to xml files in gnucash 1.8 compatible way
    
    Gnucash will still be able to read the old ISO4217 tags, but no longer write them

diff --git a/src/backend/xml/gnc-commodity-xml-v2.cpp b/src/backend/xml/gnc-commodity-xml-v2.cpp
index 69d7f18..2eaf48c 100644
--- a/src/backend/xml/gnc-commodity-xml-v2.cpp
+++ b/src/backend/xml/gnc-commodity-xml-v2.cpp
@@ -76,7 +76,7 @@ gnc_commodity_dom_tree_create (const gnc_commodity* com)
     xmlSetProp (ret, BAD_CAST "version", BAD_CAST commodity_version_string);
 
     xmlAddChild (ret, text_to_dom_tree (cmdty_namespace,
-                                        gnc_commodity_get_namespace_compat (com)));
+                                        gnc_commodity_get_namespace (com)));
     xmlAddChild (ret, text_to_dom_tree (cmdty_id,
                                         gnc_commodity_get_mnemonic (com)));
 
diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp
index 8fd9b7d..d659da5 100644
--- a/src/backend/xml/sixtp-dom-generators.cpp
+++ b/src/backend/xml/sixtp-dom-generators.cpp
@@ -120,7 +120,7 @@ commodity_ref_to_dom_tree (const char* tag, const gnc_commodity* c)
     {
         return NULL;
     }
-    name_space = g_strdup (gnc_commodity_get_namespace_compat (c));
+    name_space = g_strdup (gnc_commodity_get_namespace (c));
     mnemonic = g_strdup (gnc_commodity_get_mnemonic (c));
     xmlNewTextChild (ret, NULL, BAD_CAST "cmdty:space",
                      checked_char_cast (name_space));
diff --git a/src/backend/xml/test/test-xml-commodity.cpp b/src/backend/xml/test/test-xml-commodity.cpp
index afb9d0e..8da5956 100644
--- a/src/backend/xml/test/test-xml-commodity.cpp
+++ b/src/backend/xml/test/test-xml-commodity.cpp
@@ -70,7 +70,7 @@ node_and_commodity_equal (xmlNodePtr node, const gnc_commodity* com)
         else if (g_strcmp0 ((char*)mark->name, "cmdty:space") == 0)
         {
             if (!equals_node_val_vs_string (
-                    mark, gnc_commodity_get_namespace_compat (com)))
+                    mark, gnc_commodity_get_namespace (com)))
             {
                 return "namespaces differ";
             }
diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c
index db97e8f..5b0ce4e 100644
--- a/src/engine/gnc-commodity.c
+++ b/src/engine/gnc-commodity.c
@@ -1020,22 +1020,6 @@ gnc_commodity_get_namespace(const gnc_commodity * cm)
     return gnc_commodity_namespace_get_name(GET_PRIVATE(cm)->name_space);
 }
 
-const char *
-gnc_commodity_get_namespace_compat(const gnc_commodity * cm)
-{
-    CommodityPrivate* priv;
-
-    if (!cm) return NULL;
-    priv = GET_PRIVATE(cm);
-    if (!priv->name_space) return NULL;
-    if (priv->name_space->iso4217)
-    {
-        /* Data files are still written with ISO4217. */
-        return GNC_COMMODITY_NS_ISO;
-    }
-    return gnc_commodity_namespace_get_name(priv->name_space);
-}
-
 gnc_commodity_namespace *
 gnc_commodity_get_namespace_ds(const gnc_commodity * cm)
 {
diff --git a/src/engine/gnc-commodity.h b/src/engine/gnc-commodity.h
index 161996e..8daa83b 100644
--- a/src/engine/gnc-commodity.h
+++ b/src/engine/gnc-commodity.h
@@ -340,20 +340,6 @@ const char * gnc_commodity_get_mnemonic(const gnc_commodity * cm);
  */
 const char * gnc_commodity_get_namespace(const gnc_commodity * cm);
 
-/** Retrieve the namespace for the specified commodity.  This will be
- *  a pointer to a null terminated string of the form "AMEX",
- *  "NASDAQ", etc.  The only difference between function and
- *  gnc_commodity_get_namespace() is that this function returns
- *  ISO4217 instead of CURRENCY for backward compatibility with the
- *  1.8 data files.
- *
- *  @param cm A pointer to a commodity data structure.
- *
- *  @return A pointer to the namespace for this commodity.  This string
- *  is owned by the engine and should not be freed by the caller.
- */
-const char * gnc_commodity_get_namespace_compat(const gnc_commodity * cm);
-
 /** Retrieve the namespace data strucure for the specified commodity.
  *  This will be a pointer to another data structure.
  *

commit 12d85ff647cad7988d6af6d358f0fab930b06a0d
Merge: 7e8b66f c80dad7
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Jun 20 22:35:57 2017 +0200

    Merge branch 'maint'

diff --cc src/backend/xml/gnc-schedxaction-xml-v2.cpp
index f719cde,0000000..dd7a766
mode 100644,000000..100644
--- a/src/backend/xml/gnc-schedxaction-xml-v2.cpp
+++ b/src/backend/xml/gnc-schedxaction-xml-v2.cpp
@@@ -1,941 -1,0 +1,941 @@@
 +/********************************************************************
 + * gnc-schedxactions-xml-v2.c -- xml routines for transactions      *
 + * Copyright (C) 2001,2007 Joshua Sled <jsled at asynchronous.org>     *
 + *                                                                  *
 + * This program is free software; you can redistribute it and/or    *
 + * modify it under the terms of the GNU General Public License as   *
 + * published by the Free Software Foundation; either version 2 of   *
 + * the License, or (at your option) any later version.              *
 + *                                                                  *
 + * This program is distributed in the hope that it will be useful,  *
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
 + * GNU General Public License for more details.                     *
 + *                                                                  *
 + * You should have received a copy of the GNU General Public License*
 + * along with this program; if not, contact:                        *
 + *                                                                  *
 + * Free Software Foundation           Voice:  +1-617-542-5942       *
 + * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
 + * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 + *                                                                  *
 + *******************************************************************/
 +extern "C"
 +{
 +#include "config.h"
 +
 +#include <glib.h>
 +#include <string.h>
 +
 +#include "SX-book.h"
 +}
 +
 +#include "gnc-xml-helper.h"
 +#include "sixtp.h"
 +#include "sixtp-utils.h"
 +#include "sixtp-parsers.h"
 +#include "sixtp-utils.h"
 +#include "sixtp-dom-parsers.h"
 +#include "sixtp-dom-generators.h"
 +
 +#include "gnc-xml.h"
 +
 +#include "io-gncxml-v2.h"
 +#include "io-gncxml-gen.h"
 +
 +#include "sixtp-dom-parsers.h"
 +
 +#undef G_LOG_DOMAIN
 +#define G_LOG_DOMAIN "gnc.backend.file.sx"
 +
 +#define SX_ID                   "sx:id"
 +#define SX_NAME                 "sx:name"
 +#define SX_ENABLED              "sx:enabled"
 +#define SX_AUTOCREATE           "sx:autoCreate"
 +#define SX_AUTOCREATE_NOTIFY    "sx:autoCreateNotify"
 +#define SX_ADVANCE_CREATE_DAYS  "sx:advanceCreateDays"
 +#define SX_ADVANCE_REMIND_DAYS  "sx:advanceRemindDays"
 +#define SX_INSTANCE_COUNT       "sx:instanceCount"
 +#define SX_START                "sx:start"
 +#define SX_LAST                 "sx:last"
 +#define SX_NUM_OCCUR            "sx:num-occur"
 +#define SX_REM_OCCUR            "sx:rem-occur"
 +#define SX_END                  "sx:end"
 +#define SX_TEMPL_ACCT           "sx:templ-acct"
 +#define SX_FREQSPEC             "sx:freqspec"
 +#define SX_SCHEDULE             "sx:schedule"
 +#define SX_SLOTS                "sx:slots"
 +#define SX_DEFER_INSTANCE       "sx:deferredInstance"
 +
 +/*
 + * FIXME: These should be defined in a header somewhere
 + */
 +
 +#define GNC_ACCOUNT_TAG         "gnc:account"
 +#define GNC_TRANSACTION_TAG     "gnc:transaction"
 +#define GNC_SCHEDXACTION_TAG    "gnc:schedxaction"
 +
 +const gchar* schedxaction_version_string = "1.0.0";
 +const gchar* schedxaction_version2_string = "2.0.0";
 +
 +xmlNodePtr
 +gnc_schedXaction_dom_tree_create (SchedXaction* sx)
 +{
 +    xmlNodePtr  ret;
 +    const GDate* date;
 +    gint        instCount;
 +    const GncGUID*        templ_acc_guid;
 +    gboolean allow_2_2_incompat = TRUE;
 +    gchar* name = g_strdup (xaccSchedXactionGetName (sx));
 +
 +    templ_acc_guid = xaccAccountGetGUID (sx->template_acct);
 +
 +    /* FIXME: this should be the same as the def in io-gncxml-v2.c */
 +    ret = xmlNewNode (NULL, BAD_CAST GNC_SCHEDXACTION_TAG);
 +
 +    if (allow_2_2_incompat)
 +        xmlSetProp (ret, BAD_CAST "version", BAD_CAST schedxaction_version2_string);
 +    else
 +        xmlSetProp (ret, BAD_CAST "version", BAD_CAST schedxaction_version_string);
 +
 +    xmlAddChild (ret,
 +                 guid_to_dom_tree (SX_ID,
 +                                   xaccSchedXactionGetGUID (sx)));
 +
 +    xmlNewTextChild (ret, NULL, BAD_CAST SX_NAME, checked_char_cast (name));
 +    g_free (name);
 +
 +    if (allow_2_2_incompat)
 +    {
 +        xmlNewTextChild (ret, NULL, BAD_CAST SX_ENABLED,
 +                         BAD_CAST (sx->enabled ? "y" : "n"));
 +    }
 +
 +    xmlNewTextChild (ret, NULL, BAD_CAST SX_AUTOCREATE,
 +                     BAD_CAST (sx->autoCreateOption ? "y" : "n"));
 +    xmlNewTextChild (ret, NULL, BAD_CAST SX_AUTOCREATE_NOTIFY,
 +                     BAD_CAST (sx->autoCreateNotify ? "y" : "n"));
 +    xmlAddChild (ret, int_to_dom_tree (SX_ADVANCE_CREATE_DAYS,
 +                                       sx->advanceCreateDays));
 +    xmlAddChild (ret, int_to_dom_tree (SX_ADVANCE_REMIND_DAYS,
 +                                       sx->advanceRemindDays));
 +
 +    instCount = gnc_sx_get_instance_count (sx, NULL);
 +    xmlAddChild (ret, int_to_dom_tree (SX_INSTANCE_COUNT,
 +                                       instCount));
 +
 +    xmlAddChild (ret,
 +                 gdate_to_dom_tree (SX_START,
 +                                    xaccSchedXactionGetStartDate (sx)));
 +
 +    date = xaccSchedXactionGetLastOccurDate (sx);
 +    if (g_date_valid (date))
 +    {
 +        xmlAddChild (ret, gdate_to_dom_tree (SX_LAST, date));
 +    }
 +
 +    if (xaccSchedXactionHasOccurDef (sx))
 +    {
 +
 +        xmlAddChild (ret, int_to_dom_tree (SX_NUM_OCCUR,
 +                                           xaccSchedXactionGetNumOccur (sx)));
 +        xmlAddChild (ret, int_to_dom_tree (SX_REM_OCCUR,
 +                                           xaccSchedXactionGetRemOccur (sx)));
 +
 +    }
 +    else if (xaccSchedXactionHasEndDate (sx))
 +    {
 +        xmlAddChild (ret,
 +                     gdate_to_dom_tree (SX_END,
 +                                        xaccSchedXactionGetEndDate (sx)));
 +    }
 +
 +    /* output template account GncGUID */
 +    xmlAddChild (ret,
 +                 guid_to_dom_tree (SX_TEMPL_ACCT,
 +                                   templ_acc_guid));
 +
 +    if (allow_2_2_incompat)
 +    {
 +        xmlNodePtr schedule_node = xmlNewNode (NULL,
 +                                               BAD_CAST "sx:schedule");
 +        GList* schedule = gnc_sx_get_schedule (sx);
 +        for (; schedule != NULL; schedule = schedule->next)
 +        {
 +            xmlAddChild (schedule_node, recurrence_to_dom_tree ("gnc:recurrence",
 +                                                                (Recurrence*)schedule->data));
 +        }
 +        xmlAddChild (ret, schedule_node);
 +    }
 +
 +    /* Output deferred-instance list. */
 +    {
 +        xmlNodePtr instNode;
 +        SXTmpStateData* tsd;
 +        GList* l;
 +
 +        for (l = gnc_sx_get_defer_instances (sx); l; l = l->next)
 +        {
 +            tsd = (SXTmpStateData*)l->data;
 +
 +            instNode = xmlNewNode (NULL, BAD_CAST SX_DEFER_INSTANCE);
 +            if (g_date_valid (&tsd->last_date))
 +            {
 +                xmlAddChild (instNode, gdate_to_dom_tree (SX_LAST,
 +                                                          &tsd->last_date));
 +            }
 +            xmlAddChild (instNode, int_to_dom_tree (SX_REM_OCCUR,
 +                                                    tsd->num_occur_rem));
 +            xmlAddChild (instNode, int_to_dom_tree (SX_INSTANCE_COUNT,
 +                                                    tsd->num_inst));
 +            xmlAddChild (ret, instNode);
 +        }
 +    }
 +
 +    /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */
 +    xmlAddChild (ret, qof_instance_slots_to_dom_tree (SX_SLOTS,
 +                                                      QOF_INSTANCE (sx)));
 +    return ret;
 +}
 +
 +struct sx_pdata
 +{
 +    SchedXaction* sx;
 +    QofBook* book;
 +    gboolean saw_freqspec;
 +    gboolean saw_recurrence;
 +};
 +
 +static
 +gboolean
 +sx_id_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    GncGUID*        tmp = dom_tree_to_guid (node);
 +
 +    g_return_val_if_fail (tmp, FALSE);
 +    xaccSchedXactionSetGUID (sx, tmp);
 +    g_free (tmp);
 +
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_name_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gchar* tmp = dom_tree_to_text (node);
 +    g_debug ("sx named [%s]", tmp);
 +    g_return_val_if_fail (tmp, FALSE);
 +    xaccSchedXactionSetName (sx, tmp);
 +    g_free (tmp);
 +    return TRUE;
 +}
 +
 +static gboolean
 +sx_enabled_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gchar* tmp = dom_tree_to_text (node);
 +
 +    sx->enabled = (g_strcmp0 (tmp, "y") == 0 ? TRUE : FALSE);
 +
 +    return TRUE;
 +}
 +
 +static gboolean
 +sx_autoCreate_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gchar* tmp = dom_tree_to_text (node);
 +
 +    sx->autoCreateOption = (g_strcmp0 (tmp, "y") == 0 ? TRUE : FALSE);
 +
 +    return TRUE;
 +}
 +
 +static gboolean
 +sx_notify_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gchar* tmp = dom_tree_to_text (node);
 +
 +    sx->autoCreateNotify = (g_strcmp0 (tmp, "y") == 0 ? TRUE : FALSE);
 +
 +    return TRUE;
 +}
 +
 +static gboolean
 +sx_advCreate_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gint64 advCreate;
 +
 +    if (! dom_tree_to_integer (node, &advCreate))
 +    {
 +        return FALSE;
 +    }
 +
 +    xaccSchedXactionSetAdvanceCreation (sx, advCreate);
 +    return TRUE;
 +}
 +
 +static gboolean
 +sx_advRemind_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gint64 advRemind;
 +
 +    if (! dom_tree_to_integer (node, &advRemind))
 +    {
 +        return FALSE;
 +    }
 +
 +    xaccSchedXactionSetAdvanceReminder (sx, advRemind);
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_set_date (xmlNodePtr node, SchedXaction* sx,
 +             void (*settor) (SchedXaction* sx, const GDate* d))
 +{
 +    GDate* date;
 +    date = dom_tree_to_gdate (node);
 +    g_return_val_if_fail (date, FALSE);
 +    (*settor) (sx, date);
 +    g_date_free (date);
 +
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_instcount_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gint64 instanceNum;
 +
 +    if (! dom_tree_to_integer (node, &instanceNum))
 +    {
 +        return FALSE;
 +    }
 +
 +    gnc_sx_set_instance_count (sx, instanceNum);
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_start_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +
 +    return sx_set_date (node, sx, xaccSchedXactionSetStartDate);
 +}
 +
 +static
 +gboolean
 +sx_last_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +
 +    return sx_set_date (node, sx, xaccSchedXactionSetLastOccurDate);
 +}
 +
 +static
 +gboolean
 +sx_end_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +
 +    return sx_set_date (node, sx, xaccSchedXactionSetEndDate);
 +}
 +
 +static void
 +_fixup_recurrence_start_dates (const GDate* sx_start_date, GList* schedule)
 +{
 +    GList* iter;
 +    for (iter = schedule; iter != NULL; iter = iter->next)
 +    {
 +        Recurrence* r;
 +        GDate start, next;
 +
 +        r = (Recurrence*)iter->data;
 +
 +        start = *sx_start_date;
 +        g_date_subtract_days (&start, 1);
 +
 +        g_date_clear (&next, 1);
 +
 +        recurrenceNextInstance (r, &start, &next);
 +        g_return_if_fail (g_date_valid (&next));
 +
 +        {
 +            gchar date_str[128];
 +            gchar* sched_str;
 +
 +            g_date_strftime (date_str, 127, "%x", &next);
 +            sched_str = recurrenceToString (r);
 +            g_debug ("setting recurrence [%s] start date to [%s]",
 +                     sched_str, date_str);
 +            g_free (sched_str);
 +        }
 +
 +        recurrenceSet (r,
 +                       recurrenceGetMultiplier (r),
 +                       recurrenceGetPeriodType (r),
 +                       &next,
 +                       recurrenceGetWeekendAdjust (r));
 +    }
 +
 +    if (g_list_length (schedule) == 1
 +        && recurrenceGetPeriodType ((Recurrence*)g_list_nth_data (schedule,
 +                                    0)) == PERIOD_ONCE)
 +    {
 +        char date_buf[128];
 +        Recurrence* fixup = (Recurrence*)g_list_nth_data (schedule, 0);
 +        g_date_strftime (date_buf, 127, "%x", sx_start_date);
 +        recurrenceSet (fixup, 1, PERIOD_ONCE, sx_start_date, WEEKEND_ADJ_NONE);
 +        g_debug ("fixed up period=ONCE Recurrence to date [%s]", date_buf);
 +    }
 +}
 +
 +static gboolean
 +sx_freqspec_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    GList* schedule;
 +    gchar* debug_str;
 +
 +    g_return_val_if_fail (node, FALSE);
 +
 +    schedule = dom_tree_freqSpec_to_recurrences (node, pdata->book);
 +    gnc_sx_set_schedule (sx, schedule);
 +    debug_str = recurrenceListToString (schedule);
 +    g_debug ("parsed from freqspec [%s]", debug_str);
 +    g_free (debug_str);
 +
 +    _fixup_recurrence_start_dates (xaccSchedXactionGetStartDate (sx), schedule);
 +    pdata->saw_freqspec = TRUE;
 +
 +    return TRUE;
 +}
 +
 +static gboolean
 +sx_schedule_recurrence_handler (xmlNodePtr node, gpointer parsing_data)
 +{
 +    GList** schedule = (GList**)parsing_data;
 +    gchar* sched_str;
 +    Recurrence* r = dom_tree_to_recurrence (node);
 +    g_return_val_if_fail (r, FALSE);
 +    sched_str = recurrenceToString (r);
 +    g_debug ("parsed recurrence [%s]", sched_str);
 +    g_free (sched_str);
 +    *schedule = g_list_append (*schedule, r);
 +    return TRUE;
 +}
 +
 +struct dom_tree_handler sx_recurrence_list_handlers[] =
 +{
 +    { "gnc:recurrence", sx_schedule_recurrence_handler, 0, 0 },
 +    { NULL, NULL, 0, 0 }
 +};
 +
 +static gboolean
 +sx_recurrence_handler (xmlNodePtr node, gpointer _pdata)
 +{
 +    struct sx_pdata* parsing_data = static_cast<decltype (parsing_data)> (_pdata);
 +    GList* schedule = NULL;
 +    gchar* debug_str;
 +
 +    g_return_val_if_fail (node, FALSE);
 +
 +    if (!dom_tree_generic_parse (node, sx_recurrence_list_handlers, &schedule))
 +        return FALSE;
 +    // g_return_val_if_fail(schedule, FALSE);
 +    debug_str = recurrenceListToString (schedule);
 +    g_debug ("setting freshly-parsed schedule: [%s]", debug_str);
 +    g_free (debug_str);
 +    gnc_sx_set_schedule (parsing_data->sx, schedule);
 +    parsing_data->saw_recurrence = TRUE;
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_defer_last_handler (xmlNodePtr node, gpointer gpTSD)
 +{
 +    GDate* gd;
 +    SXTmpStateData* tsd = (SXTmpStateData*)gpTSD;
 +
 +    g_return_val_if_fail (node, FALSE);
 +    gd = dom_tree_to_gdate (node);
 +    g_return_val_if_fail (gd, FALSE);
 +    tsd->last_date = *gd;
 +    g_date_free (gd);
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_defer_rem_occur_handler (xmlNodePtr node, gpointer gpTSD)
 +{
 +    gint64 remOccur;
 +    SXTmpStateData* tsd = (SXTmpStateData*)gpTSD;
 +    g_return_val_if_fail (node, FALSE);
 +
 +    if (! dom_tree_to_integer (node, &remOccur))
 +    {
 +        return FALSE;
 +    }
 +    tsd->num_occur_rem = remOccur;
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_defer_inst_count_handler (xmlNodePtr node, gpointer gpTSD)
 +{
 +    gint64 instCount;
 +    SXTmpStateData* tsd = (SXTmpStateData*)gpTSD;
 +    g_return_val_if_fail (node, FALSE);
 +
 +    if (! dom_tree_to_integer (node, &instCount))
 +    {
 +        return FALSE;
 +    }
 +    tsd->num_inst = instCount;
 +    return TRUE;
 +}
 +
 +struct dom_tree_handler sx_defer_dom_handlers[] =
 +{
 +    /* tag name, handler, opt, ? */
 +    { SX_LAST,           sx_defer_last_handler,       1, 0 },
 +    { SX_REM_OCCUR,      sx_defer_rem_occur_handler,  1, 0 },
 +    { SX_INSTANCE_COUNT, sx_defer_inst_count_handler, 1, 0 },
 +    { NULL, NULL, 0, 0 }
 +};
 +
 +static
 +gboolean
 +sx_defer_inst_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    SXTmpStateData* tsd;
 +
 +    g_return_val_if_fail (node, FALSE);
 +
 +    tsd = g_new0 (SXTmpStateData, 1);
 +    g_assert (sx_defer_dom_handlers != NULL);
 +    if (!dom_tree_generic_parse (node,
 +                                 sx_defer_dom_handlers,
 +                                 tsd))
 +    {
 +        xmlElemDump (stdout, NULL, node);
 +        g_free (tsd);
 +        tsd = NULL;
 +        return FALSE;
 +    }
 +
 +    /* We assume they were serialized in sorted order, here. */
 +    sx->deferredList = g_list_append (sx->deferredList, tsd);
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_numOccur_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gint64 numOccur;
 +
 +    if (! dom_tree_to_integer (node, &numOccur))
 +    {
 +        return FALSE;
 +    }
 +
 +    xaccSchedXactionSetNumOccur (sx, numOccur);
 +
 +    return TRUE;
 +}
 +
 +
 +static
 +gboolean
 +sx_templ_acct_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    GncGUID* templ_acct_guid = dom_tree_to_guid (node);
 +    Account* account;
 +
 +    if (!templ_acct_guid)
 +    {
 +        return FALSE;
 +    }
 +
 +    account = xaccAccountLookup (templ_acct_guid, pdata->book);
 +    sx_set_template_account (sx, account);
 +    g_free (templ_acct_guid);
 +
 +    return TRUE;
 +}
 +
 +
 +static
 +gboolean
 +sx_remOccur_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +    gint64        remOccur;
 +
 +    if (! dom_tree_to_integer (node, &remOccur))
 +    {
 +        return FALSE;
 +    }
 +
 +    xaccSchedXactionSetRemOccur (sx, remOccur);
 +
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +sx_slots_handler (xmlNodePtr node, gpointer sx_pdata)
 +{
 +    struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
 +    SchedXaction* sx = pdata->sx;
 +
 +    return dom_tree_create_instance_slots (node, QOF_INSTANCE (sx));
 +}
 +
 +struct dom_tree_handler sx_dom_handlers[] =
 +{
 +    { SX_ID,                  sx_id_handler,         1, 0 },
 +    { SX_NAME,                sx_name_handler,       1, 0 },
 +    { SX_ENABLED,             sx_enabled_handler,    0, 0 },
 +    { SX_AUTOCREATE,          sx_autoCreate_handler, 1, 0 },
 +    { SX_AUTOCREATE_NOTIFY,   sx_notify_handler,     1, 0 },
 +    { SX_ADVANCE_CREATE_DAYS, sx_advCreate_handler,  1, 0 },
 +    { SX_ADVANCE_REMIND_DAYS, sx_advRemind_handler,  1, 0 },
 +    { SX_INSTANCE_COUNT,      sx_instcount_handler,  0, 0 },
 +    { SX_START,               sx_start_handler,      1, 0 },
 +    { SX_LAST,                sx_last_handler,       0, 0 },
 +    { SX_NUM_OCCUR,           sx_numOccur_handler,   0, 0 },
 +    { SX_REM_OCCUR,           sx_remOccur_handler,   0, 0 },
 +    { SX_END,                 sx_end_handler,        0, 0 },
 +    { SX_TEMPL_ACCT,          sx_templ_acct_handler, 0, 0 },
 +    { SX_FREQSPEC,            sx_freqspec_handler,   0, 0 },
 +    { SX_SCHEDULE,            sx_recurrence_handler, 0, 0 },
 +    { SX_DEFER_INSTANCE,      sx_defer_inst_handler, 0, 0 },
 +    { SX_SLOTS,               sx_slots_handler,      0, 0 },
 +    { NULL,                   NULL, 0, 0 }
 +};
 +
 +static gboolean
 +gnc_schedXaction_end_handler (gpointer data_for_children,
 +                              GSList* data_from_children, GSList* sibling_data,
 +                              gpointer parent_data, gpointer global_data,
 +                              gpointer* result, const gchar* tag)
 +{
 +    SchedXaction* sx;
 +    gboolean     successful = FALSE;
 +    xmlNodePtr   tree = (xmlNodePtr)data_for_children;
 +    gxpf_data*    gdata = (gxpf_data*)global_data;
 +    struct sx_pdata sx_pdata;
 +
 +    if (parent_data)
 +    {
 +        return TRUE;
 +    }
 +
 +    if (!tag)
 +    {
 +        return TRUE;
 +    }
 +
 +    g_return_val_if_fail (tree, FALSE);
 +
 +    sx = xaccSchedXactionMalloc (static_cast<QofBook*> (gdata->bookdata));
 +
 +    memset (&sx_pdata, 0, sizeof (sx_pdata));
 +    sx_pdata.sx = sx;
 +    sx_pdata.book = static_cast<decltype (sx_pdata.book)> (gdata->bookdata);
 +
 +    g_assert (sx_dom_handlers != NULL);
 +
 +    successful = dom_tree_generic_parse (tree, sx_dom_handlers, &sx_pdata);
 +    if (!successful)
 +    {
 +        g_critical ("failed to parse scheduled xaction");
 +        xmlElemDump (stdout, NULL, tree);
 +        gnc_sx_begin_edit (sx);
 +        xaccSchedXactionDestroy (sx);
 +        goto done;
 +    }
 +
 +    if (tree->properties)
 +    {
 +        gchar* sx_name = xaccSchedXactionGetName (sx);
 +        xmlAttr* attr;
 +        for (attr = tree->properties; attr != NULL; attr = attr->next)
 +        {
 +            xmlChar* attr_value = attr->children->content;
 +            g_debug ("sx attribute name[%s] value[%s]", attr->name, attr_value);
 +            if (strcmp ((const char*)attr->name, "version") != 0)
 +            {
 +                g_warning ("unknown sx attribute [%s]", attr->name);
 +                continue;
 +            }
 +
 +            // if version == 1.0.0: ensure freqspec, no recurrence
 +            // if version == 2.0.0: ensure recurrence, no freqspec.
 +            if (strcmp ((const char*)attr_value,
 +                        schedxaction_version_string) == 0)
 +            {
 +                if (!sx_pdata.saw_freqspec)
 +                    g_critical ("did not see freqspec in version 1 sx [%s]", sx_name);
 +                if (sx_pdata.saw_recurrence)
 +                    g_warning ("saw recurrence in supposedly version 1 sx [%s]", sx_name);
 +            }
 +
 +            if (strcmp ((const char*)attr_value,
 +                        schedxaction_version2_string) == 0)
 +            {
 +                if (sx_pdata.saw_freqspec)
 +                    g_warning ("saw freqspec in version 2 sx [%s]", sx_name);
 +                if (!sx_pdata.saw_recurrence)
 +                    g_critical ("did not find recurrence in version 2 sx [%s]", sx_name);
 +            }
 +        }
 +    }
 +
 +    // generic_callback -> book_callback: insert the SX in the book
 +    gdata->cb (tag, gdata->parsedata, sx);
 +
 +    /* FIXME: this should be removed somewhere near 1.8 release time. */
 +    if (sx->template_acct == NULL)
 +    {
 +        Account* ra = NULL;
 +        Account* acct = NULL;
 +        sixtp_gdv2* sixdata = static_cast<decltype (sixdata)> (gdata->parsedata);
 +        QofBook* book;
 +        gchar guidstr[GUID_ENCODING_LENGTH + 1];
 +
 +        book = sixdata->book;
 +
 +        /* We're dealing with a pre-200107<near-end-of-month> rgmerk
 +           change re: storing template accounts. */
 +        /* Fix: get account with name of our GncGUID from the template
 +           accounts.  Make that our template_acct pointer. */
 +        guid_to_string_buff (xaccSchedXactionGetGUID (sx), guidstr);
 +        ra = gnc_book_get_template_root (book);
 +        if (ra == NULL)
 +        {
 +            g_warning ("Error getting template root account from being-parsed Book.");
 +            xmlFreeNode (tree);
 +            return FALSE;
 +        }
 +        acct = gnc_account_lookup_by_name (ra, guidstr);
 +        if (acct == NULL)
 +        {
 +            g_warning ("no template account with name [%s]", guidstr);
 +            xmlFreeNode (tree);
 +            return FALSE;
 +        }
 +        g_debug ("template account name [%s] for SX with GncGUID [%s]",
 +                 xaccAccountGetName (acct), guidstr);
 +
 +        /* FIXME: free existing template account.
 +         *  HUH????? We only execute this if there isn't
 +         * currently an existing template account, don't we?
 +         * <rgmerk>
 +         */
 +
 +        sx->template_acct = acct;
 +    }
 +
 +done:
 +    xmlFreeNode (tree);
 +
 +    return successful;
 +}
 +
 +sixtp*
 +gnc_schedXaction_sixtp_parser_create (void)
 +{
 +    return sixtp_dom_parser_new (gnc_schedXaction_end_handler, NULL, NULL);
 +}
 +
 +static
 +gboolean
 +tt_act_handler (xmlNodePtr node, gpointer data)
 +{
 +    gnc_template_xaction_data* txd = static_cast<decltype (txd)> (data);
 +    Account* acc;
 +    gnc_commodity* com;
 +
 +    acc = dom_tree_to_account (node, txd->book);
 +
 +    if (acc == NULL)
 +    {
 +        return FALSE;
 +    }
 +    else
 +    {
 +        xaccAccountBeginEdit (acc);
 +
 +        /* Check for the lack of a commodity [signifying that the
 +           pre-7/11/2001-CIT-change SX template Account was parsed [but
 +           incorrectly]. */
 +        if (xaccAccountGetCommodity (acc) == NULL)
 +        {
 +#if 1
 +            gnc_commodity_table* table;
 +
 +            table = gnc_commodity_table_get_table (txd->book);
 +            com = gnc_commodity_table_lookup (table,
-                                               "template", "template");
++                                              GNC_COMMODITY_NS_TEMPLATE, "template");
 +#else
 +            /* FIXME: This should first look in the table of the
 +               book, maybe? The right thing happens [WRT file
 +               load/save] if we just _new all the time, but it
 +               doesn't seem right. This whole block should go
 +               away at some point, but the same concern still
 +               applies for
 +               SchedXaction.c:xaccSchedXactionInit... */
 +            com = gnc_commodity_new (txd->book,
-                                      "template", "template",
++                                     "template", GNC_COMMODITY_NS_TEMPLATE,
 +                                     "template", "template",
 +                                     1);
 +#endif
 +            xaccAccountSetCommodity (acc, com);
 +        }
 +
 +        txd->accts = g_list_append (txd->accts, acc);
 +    }
 +
 +    return TRUE;
 +}
 +
 +static
 +gboolean
 +tt_trn_handler (xmlNodePtr node, gpointer data)
 +{
 +    gnc_template_xaction_data* txd = static_cast<decltype (txd)> (data);
 +    Transaction*        trn;
 +
 +    trn = dom_tree_to_transaction (node, txd->book);
 +
 +    if (trn == NULL)
 +    {
 +        return FALSE;
 +    }
 +    else
 +    {
 +        txd->transactions = g_list_append (txd->transactions, trn);
 +    }
 +
 +    return TRUE;
 +}
 +
 +struct dom_tree_handler tt_dom_handlers[] =
 +{
 +    { GNC_ACCOUNT_TAG,     tt_act_handler, 0, 0 },
 +    { GNC_TRANSACTION_TAG, tt_trn_handler, 0, 0 },
 +    { NULL, NULL, 0, 0 },
 +};
 +
 +static gboolean
 +gnc_template_transaction_end_handler (gpointer data_for_children,
 +                                      GSList* data_from_children,
 +                                      GSList* sibling_data,
 +                                      gpointer parent_data,
 +                                      gpointer global_data,
 +                                      gpointer* result,
 +                                      const gchar* tag)
 +{
 +    gboolean   successful = FALSE;
 +    xmlNodePtr tree = static_cast<decltype (tree)> (data_for_children);
 +    gxpf_data*  gdata = static_cast<decltype (gdata)> (global_data);
 +    QofBook*    book = static_cast<decltype (book)> (gdata->bookdata);
 +    GList*      n;
 +    gnc_template_xaction_data txd;
 +
 +    txd.book = book;
 +    txd.accts = NULL;
 +    txd.transactions = NULL;
 +
 +    /* the DOM tree will have an account tree [the template
 +       accounts] and a list of transactions [which will be members
 +       of the template account].
 +
 +       we want to parse through the dom trees for each, placing
 +       the null-parent account in the book's template-group slot,
 +       the others under it, and the transactions as normal. */
 +
 +    if (parent_data)
 +    {
 +        return TRUE;
 +    }
 +
 +    if (!tag)
 +    {
 +        return TRUE;
 +    }
 +
 +    g_return_val_if_fail (tree, FALSE);
 +
 +    successful = dom_tree_generic_parse (tree, tt_dom_handlers, &txd);
 +
 +    if (successful)
 +    {
 +        gdata->cb (tag, gdata->parsedata, &txd);
 +    }
 +    else
 +    {
 +        g_warning ("failed to parse template transaction");
 +        xmlElemDump (stdout, NULL, tree);
 +    }
 +
 +    /* cleanup */
 +    for (n = txd.accts; n; n = n->next)
 +    {
 +        n->data = NULL;
 +    }
 +    for (n = txd.transactions; n; n = n->next)
 +    {
 +        n->data = NULL;
 +    }
 +    g_list_free (txd.accts);
 +    g_list_free (txd.transactions);
 +
 +    xmlFreeNode (tree);
 +
 +    return successful;
 +}
 +
 +sixtp*
 +gnc_template_transaction_sixtp_parser_create (void)
 +{
 +    return sixtp_dom_parser_new (gnc_template_transaction_end_handler,
 +                                 NULL, NULL);
 +}
diff --cc src/engine/test/utest-Account.cpp
index 5c67184,45be1e3..a0e9c40
--- a/src/engine/test/utest-Account.cpp
+++ b/src/engine/test/utest-Account.cpp
@@@ -2235,17 -2211,31 +2236,31 @@@ test_xaccAccountType_Compatibility (voi
                                (1 << ACCT_TYPE_ROOT));
      guint32 equity_compat = ((1 << ACCT_TYPE_EQUITY) | (1 << ACCT_TYPE_ROOT));
      guint32 trading_compat = ((1 << ACCT_TYPE_TRADING) | (1 << ACCT_TYPE_ROOT));
+     guint32 currency_compat = ((1 << ACCT_TYPE_BANK)       |
+                                (1 << ACCT_TYPE_CASH)       |
+                                (1 << ACCT_TYPE_ASSET)      |
+                                (1 << ACCT_TYPE_CREDIT)     |
+                                (1 << ACCT_TYPE_LIABILITY)  |
+                                (1 << ACCT_TYPE_INCOME)     |
+                                (1 << ACCT_TYPE_EXPENSE)    |
+                                (1 << ACCT_TYPE_EQUITY));
+     guint32 stock_compat = ((1 << ACCT_TYPE_STOCK)      |
+                             (1 << ACCT_TYPE_MUTUAL)     |
+                             (1 << ACCT_TYPE_CURRENCY));
+     guint32 immutable_ar_compat = (1 << ACCT_TYPE_RECEIVABLE);
+     guint32 immutable_ap_compat = (1 << ACCT_TYPE_PAYABLE);
+     guint32 immutable_trading_compat = (1 << ACCT_TYPE_TRADING);
      guint32 compat;
      GNCAccountType  type;
 -    gchar *msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT);
 -    gchar *msg2 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_SAVINGS);
 -    gchar *logdomain = "gnc.account";
 -    guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
 -    TestErrorStruct check1 = { loglevel, logdomain, msg1, 0 };
 -    TestErrorStruct check2 = { loglevel, logdomain, msg2, 0 };
 +    auto msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT);
 +    auto msg2 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_SAVINGS);
 +    auto logdomain = "gnc.account";
 +    auto loglevel = static_cast<GLogLevelFlags>(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL);
 +    auto check1 = test_error_struct_new(logdomain, loglevel, msg1);
 +    auto check2 = test_error_struct_new(logdomain, loglevel, msg2);
      gint loghandler;
  
 -    for (type = ACCT_TYPE_BANK; type < NUM_ACCOUNT_TYPES; type = type + 1)
 +    for (type = ACCT_TYPE_BANK; type < NUM_ACCOUNT_TYPES; type = ++type)
      {
          GNCAccountType child;
          if (type == ACCT_TYPE_ROOT)

commit c80dad742e4390b053dfbb028874982ed568158c
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Jun 20 21:35:10 2017 +0200

    Bug 603379 - Prevent changing some Account Options if it has transactions - followup
    
    Relax the account type change restrictions again. In the new implementation
    account types can't be changed for an account with splits:
    - if the change woud force a commodity change (to/from normal accounts from/to stock related accounts)
    - for immutable accounts
    
    At the time of this commit the following account types are considered immutable:
    - Accounts Receivable
    - Accounts Payable
    - Trading accounts

diff --git a/src/engine/Account.c b/src/engine/Account.c
index 9099978..9a4e396 100644
--- a/src/engine/Account.c
+++ b/src/engine/Account.c
@@ -4030,6 +4030,46 @@ xaccAccountGetTypeStr(GNCAccountType type)
 \********************************************************************/
 
 guint32
+xaccAccountTypesCompatibleWith (GNCAccountType type)
+{
+    switch (type)
+    {
+        case ACCT_TYPE_BANK:
+        case ACCT_TYPE_CASH:
+        case ACCT_TYPE_ASSET:
+        case ACCT_TYPE_CREDIT:
+        case ACCT_TYPE_LIABILITY:
+        case ACCT_TYPE_INCOME:
+        case ACCT_TYPE_EXPENSE:
+        case ACCT_TYPE_EQUITY:
+            return
+            (1 << ACCT_TYPE_BANK)       |
+            (1 << ACCT_TYPE_CASH)       |
+            (1 << ACCT_TYPE_ASSET)      |
+            (1 << ACCT_TYPE_CREDIT)     |
+            (1 << ACCT_TYPE_LIABILITY)  |
+            (1 << ACCT_TYPE_INCOME)     |
+            (1 << ACCT_TYPE_EXPENSE)    |
+            (1 << ACCT_TYPE_EQUITY);
+        case ACCT_TYPE_STOCK:
+        case ACCT_TYPE_MUTUAL:
+        case ACCT_TYPE_CURRENCY:
+            return
+            (1 << ACCT_TYPE_STOCK)      |
+            (1 << ACCT_TYPE_MUTUAL)     |
+            (1 << ACCT_TYPE_CURRENCY);
+        case ACCT_TYPE_RECEIVABLE:
+            return (1 << ACCT_TYPE_RECEIVABLE);
+        case ACCT_TYPE_PAYABLE:
+            return (1 << ACCT_TYPE_PAYABLE);
+        case ACCT_TYPE_TRADING:
+            return (1 << ACCT_TYPE_TRADING);
+        default:
+            PERR("bad account type: %d", type);
+            return 0;
+    }
+}
+guint32
 xaccParentAccountTypesCompatibleWith (GNCAccountType type)
 {
     switch (type)
diff --git a/src/engine/Account.h b/src/engine/Account.h
index e776110..e4828c3 100644
--- a/src/engine/Account.h
+++ b/src/engine/Account.h
@@ -926,6 +926,11 @@ GNCAccountType xaccAccountStringToEnum (const char* str);
  *  to the local language. */
 const char * xaccAccountGetTypeStr (GNCAccountType type);
 
+/** Return the bitmask of account types compatible with a given type.
+ *  That is, you could switch to any of the account types in the compatible
+ *  list without unwanted side-effects. */
+guint32 xaccAccountTypesCompatibleWith (GNCAccountType type);
+
 /** Return the bitmask of parent account types compatible with a given type. */
 guint32 xaccParentAccountTypesCompatibleWith (GNCAccountType type);
 
diff --git a/src/engine/test/utest-Account.c b/src/engine/test/utest-Account.c
index 6284d18..45be1e3 100644
--- a/src/engine/test/utest-Account.c
+++ b/src/engine/test/utest-Account.c
@@ -2189,6 +2189,7 @@ test_xaccAccountType_Stuff (void)
 }
 /* xaccParentAccountTypesCompatibleWith
  * xaccAccountTypesCompatible
+ * xaccAccountTypesCompatibleWith
 guint32
 xaccParentAccountTypesCompatibleWith (GNCAccountType type)// C: 5 in 3 */
 static void
@@ -2210,6 +2211,20 @@ test_xaccAccountType_Compatibility (void)
                               (1 << ACCT_TYPE_ROOT));
     guint32 equity_compat = ((1 << ACCT_TYPE_EQUITY) | (1 << ACCT_TYPE_ROOT));
     guint32 trading_compat = ((1 << ACCT_TYPE_TRADING) | (1 << ACCT_TYPE_ROOT));
+    guint32 currency_compat = ((1 << ACCT_TYPE_BANK)       |
+                               (1 << ACCT_TYPE_CASH)       |
+                               (1 << ACCT_TYPE_ASSET)      |
+                               (1 << ACCT_TYPE_CREDIT)     |
+                               (1 << ACCT_TYPE_LIABILITY)  |
+                               (1 << ACCT_TYPE_INCOME)     |
+                               (1 << ACCT_TYPE_EXPENSE)    |
+                               (1 << ACCT_TYPE_EQUITY));
+    guint32 stock_compat = ((1 << ACCT_TYPE_STOCK)      |
+                            (1 << ACCT_TYPE_MUTUAL)     |
+                            (1 << ACCT_TYPE_CURRENCY));
+    guint32 immutable_ar_compat = (1 << ACCT_TYPE_RECEIVABLE);
+    guint32 immutable_ap_compat = (1 << ACCT_TYPE_PAYABLE);
+    guint32 immutable_trading_compat = (1 << ACCT_TYPE_TRADING);
     guint32 compat;
     GNCAccountType  type;
     gchar *msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT);
@@ -2252,6 +2267,19 @@ test_xaccAccountType_Compatibility (void)
                 g_assert (xaccAccountTypesCompatible (type, child));
             else
                 g_assert (!xaccAccountTypesCompatible (type, child));
+
+        compat = xaccAccountTypesCompatibleWith (type);
+        if (type <= ACCT_TYPE_LIABILITY ||
+            (type >= ACCT_TYPE_INCOME && type <= ACCT_TYPE_EQUITY))
+            g_assert_cmpint (compat, == , currency_compat);
+        else if (type >= ACCT_TYPE_STOCK && type <= ACCT_TYPE_CURRENCY)
+            g_assert_cmpint (compat, == , stock_compat);
+        else if (type == ACCT_TYPE_RECEIVABLE)
+            g_assert_cmpint (compat, == , immutable_ar_compat);
+        else if (type == ACCT_TYPE_PAYABLE)
+            g_assert_cmpint (compat, == , immutable_ap_compat);
+        else if (type == ACCT_TYPE_TRADING)
+            g_assert_cmpint (compat, == , immutable_trading_compat);
     }
 
     loghandler = g_log_set_handler (logdomain, loglevel,
diff --git a/src/gnome-utils/dialog-account.c b/src/gnome-utils/dialog-account.c
index 20c5231..a3ab6a1 100644
--- a/src/gnome-utils/dialog-account.c
+++ b/src/gnome-utils/dialog-account.c
@@ -1120,17 +1120,18 @@ gnc_account_type_changed_cb (GtkTreeSelection *selection, gpointer data)
 }
 
 static void
-gnc_account_type_view_create (AccountWindow *aw)
+gnc_account_type_view_create (AccountWindow *aw, guint32 compat_types)
 {
     GtkTreeModel *model;
     GtkTreeSelection *selection;
     GtkCellRenderer *renderer;
     GtkTreeView *view;
 
+    aw->valid_types &= compat_types;
     if (aw->valid_types == 0)
     {
         /* no type restrictions, choose aw->type */
-        aw->valid_types = xaccAccountTypesValid () | (1 << aw->type);
+        aw->valid_types = compat_types | (1 << aw->type);
         aw->preferred_account_type = aw->type;
     }
     else if ((aw->valid_types & (1 << aw->type)) != 0)
@@ -1309,6 +1310,7 @@ gnc_account_window_create(AccountWindow *aw)
     GtkBuilder  *builder;
     GtkTreeSelection *selection;
     const gchar *tt = _("This Account contains Transactions.\nChanging this option is not possible.");
+    guint32 compat_types = xaccAccountTypesValid ();
 
     ENTER("aw %p, modal %d", aw, aw->modal);
     builder = gtk_builder_new();
@@ -1413,23 +1415,23 @@ gnc_account_window_create(AccountWindow *aw)
 
     /* This goes at the end so the select callback has good data. */
     aw->type_view = GTK_WIDGET(gtk_builder_get_object (builder, "type_view"));
-    gnc_account_type_view_create (aw);
 
-    // If the account has transactions, prevent changes by displaying a label and tooltip
+    // If the account has transactions, reduce the available account types
+    // to change the current account type to based on the following
+    // restrictions:
+    // - the new account type should not force a change of commodity
+    // - the old/new type is not an immutable type. Types are marked as
+    //   immutable if gnucash depends on details that would be lost/missing
+    //   if changing from/to such a type. At the time of this writing the
+    //   immutable types are AR, AP and trading types.
     if (xaccAccountCountSplits (aw_get_account (aw), FALSE) > 0)
     {
         GNCAccountType atype = xaccAccountGetType (aw_get_account (aw));
-        GtkWidget *label = gtk_label_new (xaccAccountGetTypeStr (atype));
-        GtkWidget *vbox = GTK_WIDGET(gtk_builder_get_object (builder, "type_vbox"));
-        GtkWidget *parent_widget = gtk_widget_get_parent (GTK_WIDGET(aw->type_view));
-
-        g_object_ref (G_OBJECT(aw->type_view));
-        gtk_container_remove (GTK_CONTAINER(vbox), parent_widget);
-        gtk_widget_set_tooltip_text (label, tt);
-        gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
-        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-        gtk_widget_show (label);
+        compat_types = xaccAccountTypesCompatibleWith (atype);
+        if (!compat_types)
+            compat_types = xaccAccountTypesValid ();
     }
+    gnc_account_type_view_create (aw, compat_types);
 
     gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(aw->dialog));
 

commit 4032d33b48c6e86845a1d41be23ddad1825b15cc
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Jun 20 12:06:14 2017 +0200

    Properly define the template namespace rather than using a local string everywhere

diff --git a/src/backend/xml/gnc-schedxaction-xml-v2.c b/src/backend/xml/gnc-schedxaction-xml-v2.c
index b604556..940d853 100644
--- a/src/backend/xml/gnc-schedxaction-xml-v2.c
+++ b/src/backend/xml/gnc-schedxaction-xml-v2.c
@@ -819,7 +819,7 @@ tt_act_handler( xmlNodePtr node, gpointer data )
 
             table = gnc_commodity_table_get_table( txd->book );
             com = gnc_commodity_table_lookup( table,
-                                              "template", "template" );
+                                              GNC_COMMODITY_NS_TEMPLATE, "template" );
 #else
             /* FIXME: This should first look in the table of the
                book, maybe? The right thing happens [WRT file
@@ -829,7 +829,7 @@ tt_act_handler( xmlNodePtr node, gpointer data )
                applies for
                SchedXaction.c:xaccSchedXactionInit... */
             com = gnc_commodity_new( txd->book,
-                                     "template", "template",
+                                     "template", GNC_COMMODITY_NS_TEMPLATE,
                                      "template", "template",
                                      1 );
 #endif
diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c
index 23ffb1f..af10919 100644
--- a/src/engine/SchedXaction.c
+++ b/src/engine/SchedXaction.c
@@ -388,7 +388,7 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
     xaccAccountSetCommodity
     (sx->template_acct,
      gnc_commodity_table_lookup( gnc_commodity_table_get_table(book),
-                                 "template", "template") );
+                                 GNC_COMMODITY_NS_TEMPLATE, "template") );
     xaccAccountSetType( sx->template_acct, ACCT_TYPE_BANK );
     xaccAccountCommitEdit( sx->template_acct );
     ra = gnc_book_get_template_root( book );
diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c
index 54ea771..a48cb79 100644
--- a/src/engine/gnc-commodity.c
+++ b/src/engine/gnc-commodity.c
@@ -848,7 +848,7 @@ gnc_commodity_new(QofBook *book, const char * fullname,
     if ( name_space != NULL )
     {
 	/* Prevent setting anything except template in namespace template. */
-	if (g_strcmp0 (name_space, "template") == 0 &&
+        if (g_strcmp0 (name_space, GNC_COMMODITY_NS_TEMPLATE) == 0 &&
 	    g_strcmp0 (mnemonic, "template") != 0)
 	{
 	    PWARN("Converting commodity %s from namespace template to "
@@ -1939,7 +1939,7 @@ gnc_commodity_table_insert(gnc_commodity_table * table,
     }
 
     /* Prevent setting anything except template in namespace template. */
-    if (g_strcmp0 (ns_name, "template") == 0 &&
+    if (g_strcmp0 (ns_name, GNC_COMMODITY_NS_TEMPLATE) == 0 &&
 	g_strcmp0 (priv->mnemonic, "template") != 0)
     {
 	PWARN("Converting commodity %s from namespace template to "
@@ -2119,7 +2119,7 @@ commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table
     {
         gnc_commodity_namespace *ns = NULL;
         if (g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_CURRENCY) == 0
-            || g_strcmp0((char*)(node->data), "template") == 0)
+            || g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_TEMPLATE) == 0)
             continue;
         ns = gnc_commodity_table_find_namespace(table, (char*)(node->data));
         if (!ns)
@@ -2441,8 +2441,8 @@ gnc_commodity_table_add_default_data(gnc_commodity_table *table, QofBook *book)
     gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_NASDAQ, book);
     gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_EUREX, book);
     gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_MUTUAL, book);
-    gnc_commodity_table_add_namespace(table, "template", book);
-    c = gnc_commodity_new(book, "template", "template", "template", "template", 1);
+    gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_TEMPLATE, book);
+    c = gnc_commodity_new(book, "template", GNC_COMMODITY_NS_TEMPLATE, "template", "template", 1);
     gnc_commodity_table_insert(table, c);
 
 #include "iso-4217-currencies.c"
diff --git a/src/engine/gnc-commodity.h b/src/engine/gnc-commodity.h
index f353e7f..161996e 100644
--- a/src/engine/gnc-commodity.h
+++ b/src/engine/gnc-commodity.h
@@ -96,6 +96,7 @@ GType gnc_commodity_namespace_get_type(void);
  *  window.
  */
 #define GNC_COMMODITY_NS_LEGACY "GNC_LEGACY_CURRENCIES"
+#define GNC_COMMODITY_NS_TEMPLATE "template"
 /* The ISO define is deprecated in favor of CURRENCY */
 #define GNC_COMMODITY_NS_ISO    "ISO4217"
 #define GNC_COMMODITY_NS_CURRENCY "CURRENCY"
diff --git a/src/gnome-utils/dialog-commodity.c b/src/gnome-utils/dialog-commodity.c
index 843a155..0278166 100644
--- a/src/gnome-utils/dialog-commodity.c
+++ b/src/gnome-utils/dialog-commodity.c
@@ -636,7 +636,7 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
         /* Skip template, legacy and currency namespaces.
            The latter was added as first entry earlier */
         if ((g_utf8_collate(node->data, GNC_COMMODITY_NS_LEGACY) == 0) ||
-            (g_utf8_collate(node->data, "template" ) == 0) ||
+            (g_utf8_collate(node->data, GNC_COMMODITY_NS_TEMPLATE ) == 0) ||
             (g_utf8_collate(node->data, GNC_COMMODITY_NS_CURRENCY ) == 0))
             continue;
 
@@ -1280,11 +1280,11 @@ gnc_ui_commodity_dialog_to_object(CommodityWindow * w)
     /* Don't allow user to create commodities in namespace
      * "template". That's reserved for scheduled transaction use.
      */
-    if (g_utf8_collate(name_space, "template") == 0)
+    if (g_utf8_collate(name_space, GNC_COMMODITY_NS_TEMPLATE) == 0)
     {
 	gnc_warning_dialog (w->dialog,
 			    _("%s is a reserved commodity type."
-			      " Please use something else."), "template");
+                            " Please use something else."), GNC_COMMODITY_NS_TEMPLATE);
 	return FALSE;
     }
 
diff --git a/src/gnome-utils/gnc-tree-model-split-reg.c b/src/gnome-utils/gnc-tree-model-split-reg.c
index e895a36..a7f8ae8 100644
--- a/src/gnome-utils/gnc-tree-model-split-reg.c
+++ b/src/gnome-utils/gnc-tree-model-split-reg.c
@@ -3292,7 +3292,7 @@ gnc_tree_model_split_reg_event_handler (QofInstance *entity,
             {
                 gnc_commodity *split_com;
                 split_com = xaccAccountGetCommodity (acc);
-                if (g_strcmp0 (gnc_commodity_get_namespace (split_com), "template") != 0)
+                if (g_strcmp0 (gnc_commodity_get_namespace (split_com), GNC_COMMODITY_NS_TEMPLATE) != 0)
                 {
                     DEBUG("Insert trans %p for gl (%s)", trans, name);
                     gtm_sr_insert_trans (model, trans, TRUE);
diff --git a/src/gnome/dialog-commodities.c b/src/gnome/dialog-commodities.c
index 1a0e385..2495cda 100644
--- a/src/gnome/dialog-commodities.c
+++ b/src/gnome/dialog-commodities.c
@@ -283,7 +283,7 @@ gnc_commodities_dialog_filter_ns_func (gnc_commodity_namespace *name_space,
 
     /* Never show the template list */
     name = gnc_commodity_namespace_get_name (name_space);
-    if (g_strcmp0 (name, "template") == 0)
+    if (g_strcmp0 (name, GNC_COMMODITY_NS_TEMPLATE) == 0)
         return FALSE;
 
     /* Check whether or not to show commodities */
diff --git a/src/gnome/dialog-price-edit-db.c b/src/gnome/dialog-price-edit-db.c
index c79504b..7187e7f 100644
--- a/src/gnome/dialog-price-edit-db.c
+++ b/src/gnome/dialog-price-edit-db.c
@@ -356,7 +356,7 @@ gnc_price_dialog_filter_ns_func (gnc_commodity_namespace *name_space,
 
     /* Never show the template list */
     name = gnc_commodity_namespace_get_name (name_space);
-    if (g_strcmp0 (name, "template") == 0)
+    if (g_strcmp0 (name, GNC_COMMODITY_NS_TEMPLATE) == 0)
         return FALSE;
 
     /* See if this namespace has commodities */

commit cc3010d89b1e72524acb85510978d45ab2334892
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Jun 16 20:30:33 2017 +0200

    Bug 781634 followup - separate translatable commodity namespace strings from those uses in storage
    
    There is now a separate GNC_COMMODITY_NS_ISO_GUI label to be used
    everywhere the users needs to read 'Currency namespace'. It's currently
    set to 'Currencies' and can be translated. It may change in to future
    to better describe this namespace is restricted to ISO4217 defined
    currencies as opposed to all the non-formal currencies in vogue today
    (like bitcoin and friends).

diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c
index ec6b529..54ea771 100644
--- a/src/engine/gnc-commodity.c
+++ b/src/engine/gnc-commodity.c
@@ -1660,6 +1660,16 @@ gnc_commodity_namespace_get_name (const gnc_commodity_namespace *ns)
     return ns->name;
 }
 
+const char *
+gnc_commodity_namespace_get_gui_name (const gnc_commodity_namespace *ns)
+{
+    if (ns == NULL)
+        return NULL;
+    if (g_strcmp0 (ns->name, GNC_COMMODITY_NS_CURRENCY) == 0)
+        return GNC_COMMODITY_NS_ISO_GUI;
+    return ns->name;
+}
+
 GList *
 gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
 {
diff --git a/src/engine/gnc-commodity.h b/src/engine/gnc-commodity.h
index d2624b6..f353e7f 100644
--- a/src/engine/gnc-commodity.h
+++ b/src/engine/gnc-commodity.h
@@ -98,14 +98,17 @@ GType gnc_commodity_namespace_get_type(void);
 #define GNC_COMMODITY_NS_LEGACY "GNC_LEGACY_CURRENCIES"
 /* The ISO define is deprecated in favor of CURRENCY */
 #define GNC_COMMODITY_NS_ISO    "ISO4217"
-#define GNC_COMMODITY_NS_CURRENCY N_("CURRENCY")
+#define GNC_COMMODITY_NS_CURRENCY "CURRENCY"
 #define GNC_COMMODITY_NS_NASDAQ "NASDAQ"
 #define GNC_COMMODITY_NS_NYSE   "NYSE"
 #define GNC_COMMODITY_NS_EUREX  "EUREX"
 #define GNC_COMMODITY_NS_MUTUAL "FUND"
 #define GNC_COMMODITY_NS_AMEX   "AMEX"
 #define GNC_COMMODITY_NS_ASX    "ASX"
-#define GNC_COMMODITY_NS_NONCURRENCY _("ALL NON-CURRENCY")
+#define GNC_COMMODITY_NS_NONCURRENCY _("All non-currency")
+/* Delay translation of this one, we use it in both translated and untranslated form
+   when presenting the currency related namespace to the user */
+#define GNC_COMMODITY_NS_ISO_GUI N_("Currencies")
 
 typedef GList CommodityList;
 
@@ -804,6 +807,19 @@ gboolean gnc_commodity_table_add_default_data(gnc_commodity_table *table, QofBoo
  *  owned by the engine and should not be freed by the caller. */
 const char * gnc_commodity_namespace_get_name (const gnc_commodity_namespace *ns) ;
 
+/** Return the textual name of a namespace data strucure in a form suitable to
+ * present to the user.
+ *
+ *  @param ns A pointer to the namespace data strucure.
+ *
+ *  @return A pointer to the gui friendly name of the namespace.  This string is
+ *  owned by the engine and should not be freed by the caller.
+ *
+ *  @notes The returned string is marked for translation, but not translated yet.
+ *  If you want it translated pass the return value on to gettext.
+ */
+const char * gnc_commodity_namespace_get_gui_name (const gnc_commodity_namespace *ns) ;
+
 
 /** Return a list of all commodity data structures in the specified namespace.
  *
diff --git a/src/gnome-utils/dialog-commodity.c b/src/gnome-utils/dialog-commodity.c
index 6e041e9..843a155 100644
--- a/src/gnome-utils/dialog-commodity.c
+++ b/src/gnome-utils/dialog-commodity.c
@@ -605,27 +605,46 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
         namespaces = g_list_prepend (NULL, GNC_COMMODITY_NS_CURRENCY);
         break;
     }
-/* First insert "ALL" */
+
+    /* First insert "Currencies" entry if requested */
+    if (mode == DIAG_COMM_CURRENCY || mode == DIAG_COMM_ALL)
+    {
+        gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+        gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0,
+                            _(GNC_COMMODITY_NS_ISO_GUI), -1);
+
+        if (init_string &&
+            (g_utf8_collate(GNC_COMMODITY_NS_ISO_GUI, init_string) == 0))
+        {
+            matched = TRUE;
+            match = iter;
+        }
+    }
+
+    /* Next insert insert "All non-currency" entry if requested */
     if (mode == DIAG_COMM_NON_CURRENCY_SELECT || mode == DIAG_COMM_ALL)
     {
         gtk_list_store_append(GTK_LIST_STORE(model), &iter);
         gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0,
                             GNC_COMMODITY_NS_NONCURRENCY, -1);
     }
-    /* add them to the combobox */
+
+    /* add all others to the combobox */
     namespaces = g_list_sort(namespaces, collate);
     for (node = namespaces; node; node = node->next)
     {
-        if (g_utf8_collate(node->data, GNC_COMMODITY_NS_LEGACY) == 0)
+        /* Skip template, legacy and currency namespaces.
+           The latter was added as first entry earlier */
+        if ((g_utf8_collate(node->data, GNC_COMMODITY_NS_LEGACY) == 0) ||
+            (g_utf8_collate(node->data, "template" ) == 0) ||
+            (g_utf8_collate(node->data, GNC_COMMODITY_NS_CURRENCY ) == 0))
             continue;
-        /* Hide the template entry */
-        if (g_utf8_collate(node->data, "template" ) != 0)
-        {
-            gtk_list_store_append(GTK_LIST_STORE(model), &iter);
-            gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, _(node->data), -1);
-        }
 
-        if (init_string && (g_utf8_collate(node->data, init_string) == 0))
+        gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+        gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, node->data, -1);
+
+        if (init_string &&
+            (g_utf8_collate(node->data, init_string) == 0))
         {
             matched = TRUE;
             match = iter;
@@ -648,16 +667,11 @@ gnc_ui_namespace_picker_ns (GtkWidget *cbwe)
 
     name_space = gtk_entry_get_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( GTK_COMBO_BOX(cbwe)))));
 
-    if (g_strcmp0 (name_space, GNC_COMMODITY_NS_ISO) == 0)
-    {
-        /* In case the user types in ISO4217, map it to CURRENCY. */
+    /* Map several currency related names to one common namespace */
+    if ((g_strcmp0 (name_space, GNC_COMMODITY_NS_ISO) == 0) ||
+        (g_strcmp0 (name_space, GNC_COMMODITY_NS_ISO_GUI) == 0) ||
+        (g_strcmp0 (name_space, _(GNC_COMMODITY_NS_ISO_GUI)) == 0))
         return g_strdup(GNC_COMMODITY_NS_CURRENCY);
-    }
-    else if (g_strcmp0 (name_space, _(GNC_COMMODITY_NS_CURRENCY)) == 0)
-    {
-        /* In case the user entered a translation of CURRENCY, return it untranslated. */
-        return g_strdup(GNC_COMMODITY_NS_CURRENCY);
-    }
     else
         return g_strdup(name_space);
 }
diff --git a/src/gnome-utils/gnc-tree-model-commodity.c b/src/gnome-utils/gnc-tree-model-commodity.c
index 5db3802..2085f67 100644
--- a/src/gnome-utils/gnc-tree-model-commodity.c
+++ b/src/gnome-utils/gnc-tree-model-commodity.c
@@ -596,7 +596,7 @@ gnc_tree_model_commodity_get_value (GtkTreeModel *tree_model,
         {
         case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
             g_value_init (value, G_TYPE_STRING);
-            g_value_set_string (value, gnc_commodity_namespace_get_name (name_space));
+            g_value_set_string (value, _(gnc_commodity_namespace_get_gui_name (name_space)));
             break;
         default:
             g_value_init (value, G_TYPE_STRING);
diff --git a/src/gnome-utils/gnc-tree-model-price.c b/src/gnome-utils/gnc-tree-model-price.c
index 20a4409..de89599 100644
--- a/src/gnome-utils/gnc-tree-model-price.c
+++ b/src/gnome-utils/gnc-tree-model-price.c
@@ -708,7 +708,7 @@ gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
         {
         case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
             g_value_init (value, G_TYPE_STRING);
-            g_value_set_string (value, gnc_commodity_namespace_get_name (name_space));
+            g_value_set_string (value, gnc_commodity_namespace_get_gui_name (name_space));
             break;
         case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
             g_value_init (value, G_TYPE_BOOLEAN);
diff --git a/src/gnome-utils/gnc-tree-view-commodity.c b/src/gnome-utils/gnc-tree-view-commodity.c
index eb9a9c2..a6d6f6c 100644
--- a/src/gnome-utils/gnc-tree-view-commodity.c
+++ b/src/gnome-utils/gnc-tree-view-commodity.c
@@ -223,8 +223,8 @@ sort_namespace (GtkTreeModel *f_model,
 
     ns_a = gnc_tree_model_commodity_get_namespace (model, &iter_a);
     ns_b = gnc_tree_model_commodity_get_namespace (model, &iter_b);
-    return safe_utf8_collate (gnc_commodity_namespace_get_name (ns_a),
-                              gnc_commodity_namespace_get_name (ns_b));
+    return safe_utf8_collate (gnc_commodity_namespace_get_gui_name (ns_a),
+                              gnc_commodity_namespace_get_gui_name (ns_b));
 }
 
 static gint
diff --git a/src/gnome-utils/gnc-tree-view-price.c b/src/gnome-utils/gnc-tree-view-price.c
index b0dc599..ae0c525 100644
--- a/src/gnome-utils/gnc-tree-view-price.c
+++ b/src/gnome-utils/gnc-tree-view-price.c
@@ -205,8 +205,8 @@ sort_ns_or_cm (GtkTreeModel *f_model,
     {
         ns_a = gnc_tree_model_price_get_namespace (model, &iter_a);
         ns_b = gnc_tree_model_price_get_namespace (model, &iter_b);
-        return safe_utf8_collate (gnc_commodity_namespace_get_name (ns_a),
-                                  gnc_commodity_namespace_get_name (ns_b));
+        return safe_utf8_collate (gnc_commodity_namespace_get_gui_name (ns_a),
+                                  gnc_commodity_namespace_get_gui_name (ns_b));
     }
 
     comm_a = gnc_tree_model_price_get_commodity (model, &iter_a);



Summary of changes:
 src/backend/xml/gnc-commodity-xml-v2.cpp    |  2 +-
 src/backend/xml/gnc-schedxaction-xml-v2.cpp |  4 +--
 src/backend/xml/sixtp-dom-generators.cpp    |  2 +-
 src/backend/xml/test/test-xml-commodity.cpp |  2 +-
 src/engine/Account.c                        | 40 +++++++++++++++++++++
 src/engine/Account.h                        |  5 +++
 src/engine/SchedXaction.c                   |  2 +-
 src/engine/gnc-commodity.c                  | 36 ++++++++-----------
 src/engine/gnc-commodity.h                  | 35 +++++++++---------
 src/engine/test/utest-Account.cpp           | 28 +++++++++++++++
 src/gnome-utils/dialog-account.c            | 30 ++++++++--------
 src/gnome-utils/dialog-commodity.c          | 56 ++++++++++++++++++-----------
 src/gnome-utils/gnc-tree-model-commodity.c  |  2 +-
 src/gnome-utils/gnc-tree-model-price.c      |  2 +-
 src/gnome-utils/gnc-tree-model-split-reg.c  |  2 +-
 src/gnome-utils/gnc-tree-view-commodity.c   |  4 +--
 src/gnome-utils/gnc-tree-view-price.c       |  4 +--
 src/gnome/dialog-commodities.c              |  2 +-
 src/gnome/dialog-price-edit-db.c            |  2 +-
 19 files changed, 173 insertions(+), 87 deletions(-)



More information about the gnucash-changes mailing list