import homebank-5.1.2
[chaz/homebank] / src / hb-xml.c
index d859c3510c8353ea9e7c6b90967382a2d61d04d0..2338e581857133d5402597ec6a0a280fc62ced50 100644 (file)
@@ -1,5 +1,5 @@
 /*  HomeBank -- Free, easy, personal accounting for everyone.
- *  Copyright (C) 1995-2014 Maxime DOYEN
+ *  Copyright (C) 1995-2016 Maxime DOYEN
  *
  *  This file is part of HomeBank.
  *
@@ -23,6 +23,8 @@
 #include "hb-transaction.h"
 #include "hb-xml.h"
 
+#include "ui-dialogs.h"
+
 /****************************************************************************/
 /* Debug macros                                                             */
 /****************************************************************************/
 extern struct HomeBank *GLOBALS;
 extern struct Preferences *PREFS;
 
-typedef struct _ParseContext ParseContext;
-struct _ParseContext
-{
-       gdouble version;
 
-};
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
-static void homebank_upgrade_to_v02(void);
-static void homebank_upgrade_to_v03(void);
-static void homebank_upgrade_to_v04(void);
-static void homebank_upgrade_to_v05(void);
-static void homebank_upgrade_lower_v06(void);
-static void homebank_upgrade_to_v06(void);
-static void homebank_upgrade_to_v07(void);
-static void homebank_upgrade_to_v08(void);
 
-static void
-start_element_handler (GMarkupParseContext *context,
-                      const gchar         *element_name,
-                      const gchar        **attribute_names,
-                      const gchar        **attribute_values,
-                      gpointer             user_data,
-                      GError             **error)
+// v0.1 to v0.2 : we must change account reference by making a +1 to its index references
+static void homebank_upgrade_to_v02(void)
 {
-ParseContext *ctx = user_data;
-//GtkUIManager *self = ctx->self;
-gint i, j;
+GList *lst_acc, *lnk_acc;
+GList *list;
+GHashTable *h_old_acc;
+       
 
-       //DB( g_print("** start element: %s\n", element_name) );
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v02\n") );
 
-       switch(element_name[0])
+       //keep old hashtable with us
+       h_old_acc = GLOBALS->h_acc;
+       da_acc_new();
+
+       lst_acc = g_hash_table_get_values(h_old_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
        {
-               //get file version
-               /*
-               case 'h':
-               {
-                       if(!strcmp (element_name, "homebank"))
-                       {
-                            if(!strcmp (attribute_names[0], "v" ))
-                            {
-                                       version = g_ascii_strtod(attribute_values[0], NULL);
-                               DB( g_print(" version %f\n", version) );
-                            }
+       Account *acc = lnk_acc->data;
 
-                       }
-               }
-               */
+               acc->key++;
+               acc->pos++;
+               da_acc_insert (acc);
 
-               case 'a':
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
                {
-                       if(!strcmp (element_name, "account"))
-                       {
-                       Account *entry = da_acc_malloc();
+               Transaction *entry = list->data;
+                       entry->kacc++;
+                       entry->kxferacc++;
+                       list = g_list_next(list);
+               }
+               lnk_acc = g_list_next(lnk_acc);
+       }
+       g_list_free(lst_acc);
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
-                                            if(!strcmp (attribute_names[i], "key"     )) { entry->key   = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "flags"   )) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "pos"     )) { entry->pos   = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "type"    )) { entry->type = atoi(attribute_values[i]); }
-                                       //else if(!strcmp (attribute_names[i], "curr"    )) { entry->kcur = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "name"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->name = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "number"  )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->number = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "bankname")) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->bankname = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "initial" )) { entry->initial = g_ascii_strtod(attribute_values[i], NULL); }
-                                       else if(!strcmp (attribute_names[i], "minimum" )) { entry->minimum = g_ascii_strtod(attribute_values[i], NULL); }
-                                       else if(!strcmp (attribute_names[i], "cheque1" )) { entry->cheque1 = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "cheque2" )) { entry->cheque2 = atoi(attribute_values[i]); }
+       //we loose some small memory here
+       g_hash_table_steal_all(h_old_acc);
 
-                               }
+       list = g_list_first(GLOBALS->arc_list);
+       while (list != NULL)
+       {
+       Archive *entry = list->data;
+               entry->kacc++;
+               entry->kxferacc++;
+               list = g_list_next(list);
+       }
+}
 
-                               //version upgrade: type was added in 0.2
-                               //todo: for stock account
-                               /*
-                               if(version <= 0.1)
-                               {
-                                       entry->type = ACC_TYPE_BANK;
-                                       DB( g_print(" acctype forced to BANK\n") );
-                               }
-                       */
+// v0.2 to v0.3 : we must assume categories exists : bugs 303886, 303738
+static void homebank_upgrade_to_v03(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
 
-                               DB( g_print(" version %f\n", ctx->version) );
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v03\n") );
 
-                               //upgrade to v0.2 file
-                               // we must change account reference by making a +1 to its index references
-                               if( ctx->version == 0.1 )
-                               {
-                                       entry->key++;
-                                       entry->pos = entry->key;
-                               }
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
+       {
+       Account *acc = lnk_acc->data;
 
-                               //all attribute loaded: append
-                               da_acc_insert(entry);
-                       }
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
+               {
+               Transaction *entry = list->data;
 
-                       //assign
-                       else if(!strcmp (element_name, "asg"))
-                       {
-                       Assign *entry = da_asg_malloc();
-                       gint exact = 0;
+                       da_transaction_consistency(entry);
+                       list = g_list_next(list);
+               }
+               lnk_acc = g_list_next(lnk_acc);
+       }
+       g_list_free(lst_acc);
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
-                                            if(!strcmp (attribute_names[i], "key"     )) { entry->key   = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "flags"   )) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "field"   )) { entry->field = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "name"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->name = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "payee"   )) { entry->kpay = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "category")) { entry->kcat = atoi(attribute_values[i]); }
-                                       //else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
-                                       // prior v08
-                                       else if(!strcmp (attribute_names[i], "exact" )) { exact = atoi(attribute_values[i]); }
-                               }
 
-                               /* in v08 exact moved to flag */
-                               if( ctx->version <= 0.7)
-                               {
-                                       entry->flags = (ASGF_DOCAT|ASGF_DOPAY);
-                                       if( exact > 0 )
-                                          entry->flags |= ASGF_EXACT;
-                               }
+       list = g_list_first(GLOBALS->arc_list);
+       while (list != NULL)
+       {
+       Archive *entry = list->data;
 
-                               //all attribute loaded: append
-                               da_asg_append(entry);
+               da_archive_consistency(entry);
+               list = g_list_next(list);
+       }
+}
 
-                       }
+static void homebank_upgrade_to_v04(void)
+{
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v04\n") );
 
-               }
-               break;
+       GLOBALS->arc_list = da_archive_sort(GLOBALS->arc_list);
+}
 
-               case 'p':
-               {
-                       if(!strcmp (element_name, "pay"))
-                       {
-                       Payee *entry = da_pay_malloc();
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
+// v0.4 to v0.5 :
+// we must assume kxferacc exists in archives for internal xfer : bug 528923
+// if not, delete automation from the archive
+static void homebank_upgrade_to_v05(void)
+{
+GList *list;
 
-                                            if(!strcmp (attribute_names[i], "key"  )) { entry->key = atoi(attribute_values[i]); }
-                                       //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
-                               }
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v05\n") );
 
-                               //all attribute loaded: append
-                               da_pay_insert(entry);
+       list = g_list_first(GLOBALS->arc_list);
+       while (list != NULL)
+       {
+       Archive *entry = list->data;
 
-                       }
-                       else if(!strcmp (element_name, "properties"))
-                       {
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                            if(!strcmp (attribute_names[i], "title"       )) { g_free(GLOBALS->owner); GLOBALS->owner = g_strdup(attribute_values[i]); }
-                                       //else if(!strcmp (attribute_names[i], "curr"        )) { GLOBALS->kcur = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "car_category")) { GLOBALS->vehicle_category = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "auto_smode"  )) { GLOBALS->auto_smode = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "auto_weekday")) { GLOBALS->auto_weekday = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "auto_nbdays" )) { GLOBALS->auto_nbdays = atoi(attribute_values[i]); }
-                               }
-                       }
-               }
-               break;
+               da_archive_consistency(entry);
+               list = g_list_next(list);
+       }
+}
 
-               case 'c':
-               {
-                       if(!strcmp (element_name, "cat"))
-                       {
-                       Category *entry = da_cat_malloc();
-                       gboolean budget;
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
+// v0.5 to v0.6 : we must change kxferacc to 0 on non Xfer transactions
+//#677351
+static void homebank_upgrade_to_v06(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
 
-                                            if(!strcmp (attribute_names[i], "key"   )) { entry->key = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "parent")) { entry->parent = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "name"  )) { entry->name = g_strdup(attribute_values[i]); }
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v06\n") );
 
-                                       budget = FALSE;
-                                       for(j=0;j<=12;j++)
-                                       {
-                                       gchar *tmpname;
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
+       {
+       Account *acc = lnk_acc->data;
 
-                                               tmpname = g_strdup_printf ("b%d", j);
-                                               if(!(strcmp (attribute_names[i], tmpname))) { entry->budget[j] = g_ascii_strtod(attribute_values[i], NULL); }
-                                               g_free(tmpname);
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
+               {
+               Transaction *entry = list->data;
+                       da_transaction_consistency(entry);
+                       list = g_list_next(list);
+               }
+               lnk_acc = g_list_next(lnk_acc);
+       }
+       g_list_free(lst_acc);
 
-                                               if(entry->budget[j]) budget = TRUE;
-                                       }
-                                       if(budget == TRUE)
-                                               entry->flags |= GF_BUDGET;
 
-                               }
+       list = g_list_first(GLOBALS->arc_list);
+       while (list != NULL)
+       {
+       Archive *entry = list->data;
+               da_archive_consistency(entry);
+               list = g_list_next(list);
+       }
+}
 
-                               //all attribute loaded: append
-                               da_cat_insert( entry);
-                       }
-/*                     else if(!strcmp (element_name, "cur"))
-                       {
-                       Currency *entry = da_cur_malloc ();
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
-                                                if(!strcmp (attribute_names[i], "key"    )) { entry->key = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "name"  )) { entry->name = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "iso"   )) { entry->iso_code = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "symb"  )) { entry->symbol = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "syprf" )) { entry->sym_prefix = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "dchar" )) { entry->decimal_char = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "gchar" )) { entry->grouping_char = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "frac"  )) { entry->frac_digits = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "rate"  )) { entry->rate = g_ascii_strtod(attribute_values[i], NULL); }
-                                       else if(!strcmp (attribute_names[i], "mdate ")) { entry->mdate = atoi(attribute_values[i]); }
+// v0.7 AF_BUDGET deleted instead of AF_NOBUDGET
+static void homebank_upgrade_to_v07(void)
+{
+GList *lacc, *list;
 
-                               }
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v07\n") );
 
-                               //all attribute loaded: append
-                               da_cur_insert (entry);
-                       }
-                       */
-               }
-               break;
+       lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
+       while (list != NULL)
+       {
+       Account *acc = list->data;
 
-               case 't':
+               if( acc->flags & AF_OLDBUDGET ) // budget include
                {
-                       if(!strcmp (element_name, "tags"))
-                       {
-                       Tag *entry = da_tag_malloc();
-
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
-                                            if(!strcmp (attribute_names[i], "key"  )) { entry->key = atoi(attribute_values[i]); }
-                                       //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
-                               }
-
-                               //all attribute loaded: append
-                               da_tag_insert(entry);
-
-                       }
+                       acc->flags &= ~(AF_OLDBUDGET);
                }
-
-               case 'f':
+               else
                {
-                       if(!strcmp (element_name, "fav"))
-                       {
-                       Archive *entry = da_archive_malloc();
+                       acc->flags |= AF_NOBUDGET;
+               }
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
-                                            if(!strcmp (attribute_names[i], "amount"     )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
-                                       else if(!strcmp (attribute_names[i], "account"    )) { entry->kacc = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "paymode"    )) { entry->paymode = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "flags"      )) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "payee"      )) { entry->kpay = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "category"   )) { entry->kcat = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "wording"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->wording = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "nextdate"   )) { entry->nextdate = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "every"      )) { entry->every = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "unit"       )) { entry->unit = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "limit"      )) { entry->limit = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "weekend"    )) { entry->weekend = atoi(attribute_values[i]); }
+               list = g_list_next(list);
+       }
+       g_list_free(lacc);
 
-                               }
+}
 
-                               //all attribute loaded: append
-                               GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, entry);
+static void homebank_upgrade_to_v08(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
 
-                       }
-               }
-               break;
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v08\n") );
+
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
+       {
+       Account *acc = lnk_acc->data;
 
-               /*
-               case 'r':
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
                {
+               Transaction *entry = list->data;
+                       da_transaction_consistency(entry);
+                       list = g_list_next(list);
                }
-               break;
-               */
+               lnk_acc = g_list_next(lnk_acc);
+       }
+       g_list_free(lst_acc);
 
-               case 'o':
-               {
-                       if(!strcmp (element_name, "ope"))
-                       {
-                       Transaction *entry = da_transaction_malloc();
-                       gchar *scat = NULL;
-                       gchar *samt = NULL;
-                       gchar *smem = NULL;
-                       gboolean split = FALSE;
 
-                               for (i = 0; attribute_names[i] != NULL; i++)
-                               {
-                                       //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
-                                            if(!strcmp (attribute_names[i], "date"       )) { entry->date = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "amount"     )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
-                                       else if(!strcmp (attribute_names[i], "account"    )) { entry->kacc = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "paymode"    )) { entry->paymode = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "flags"      )) { entry->flags = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "payee"      )) { entry->kpay = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "category"   )) { entry->kcat = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "wording"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->wording = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "info"       )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->info = g_strdup(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "tags"       ))
-                                       {
-                                               if(attribute_values[i] != NULL && strlen(attribute_values[i]) > 0 && strcmp(attribute_values[i],"(null)") != 0 )
-                                               {
-                                                       transaction_tags_parse(entry, attribute_values[i]);
-                                               }
-                                       }
-                                       else if(!strcmp (attribute_names[i], "kxfer"    )) { entry->kxfer = atoi(attribute_values[i]); }
-                                       else if(!strcmp (attribute_names[i], "scat"     )) { scat = (gchar *)attribute_values[i]; split = TRUE; }
-                                       else if(!strcmp (attribute_names[i], "samt"     )) { samt = (gchar *)attribute_values[i]; split = TRUE; }
-                                       else if(!strcmp (attribute_names[i], "smem"     )) { smem = (gchar *)attribute_values[i]; split = TRUE; }
-                               }
+}
 
-                               //bugfix 303886
-                               //if(entry->kcat < 0)
-                               //      entry->kcat = 0;
 
-                               if(split == TRUE)
-                               {
-                                       transaction_splits_parse(entry, scat, samt, smem);
-                               }
+static void homebank_upgrade_to_v10(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
 
-                               //all attribute loaded: append
-                               // we use prepend here, the list will be reversed later for perf reason
-                               da_transaction_prepend(entry);
-                       }
-               }
-               break;
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v10\n") );
+
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
+       {
+       Account *acc = lnk_acc->data;
+       
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
+               {
+               Transaction *entry = list->data;
 
+                       entry->status = TXN_STATUS_NONE;
+                       if(entry->flags & OF_OLDVALID)
+                               entry->status = TXN_STATUS_RECONCILED;
+                       else 
+                               if(entry->flags & OF_OLDREMIND)
+                                       entry->status = TXN_STATUS_REMIND;
 
+                       //remove those flags
+                       entry->flags &= ~(OF_OLDVALID|OF_OLDREMIND);
 
+                       list = g_list_next(list);
+               }
+               lnk_acc = g_list_next(lnk_acc);
        }
+       g_list_free(lst_acc);
 
 }
 
-/*
-static void
-end_element_handler (GMarkupParseContext *context,
-                    const gchar         *element_name,
-                    gpointer             user_data,
-                    GError             **error)
+
+static void homebank_upgrade_to_v11(void)
 {
-  ParseContext *ctx = user_data;
+GList *list;
 
-       //DB( g_print("-- end element: %s\n", element_name) );
+       DB( g_print("\n[hb-xml] homebank_upgrade_to_v11\n") );
 
+       list = g_list_first(GLOBALS->arc_list);
+       while (list != NULL)
+       {
+       Archive *entry = list->data;
+
+               entry->status = TXN_STATUS_NONE;
+               if(entry->flags & OF_OLDVALID)
+                       entry->status = TXN_STATUS_RECONCILED;
+               else 
+                       if(entry->flags & OF_OLDREMIND)
+                               entry->status = TXN_STATUS_REMIND;
+
+               //remove those flags
+               entry->flags &= ~(OF_OLDVALID|OF_OLDREMIND);
+
+               list = g_list_next(list);
+       }
 
 }
-*/
 
-static GMarkupParser hb_parser = {
-  start_element_handler,
-  NULL,        //end_element_handler,
-  NULL, //text_handler,
-  NULL,
-  NULL  //cleanup
-};
 
-/*
-** XML load homebank file: hbfile
-*/
-gint homebank_load_xml(gchar *filename)
+// v0.6 to v0.7 : assign a default currency
+static void homebank_upgrade_to_v12(void)
 {
-gint retval;
-gchar *buffer;
-gsize length;
-GError *error = NULL;
-ParseContext ctx = { 0 };
-GMarkupParseContext *context;
-gboolean rc;
-
-       DB( g_print("\n[hb-xml] homebank_load_xml\n") );
+       // set a base currency to the hbfile if not
+       DB( g_print("GLOBALS->kcur %d\n", GLOBALS->kcur) );
 
-       retval = XML_OK;
-       if (!g_file_get_contents (filename, &buffer, &length, &error))
-       {
-               //g_message ("%s", error->message);
-               retval = XML_IO_ERROR;
-               g_error_free (error);
-       }
-       else
-       {
-       gchar *v_buffer;
-       gdouble version;
+       ui_dialog_upgrade_choose_currency();
+}
 
-               /* v3.4 add :: prevent load of future file version */
-               v_buffer = g_strstr_len(buffer, 50, "<homebank v=");
-               if( v_buffer == NULL )
-                       return XML_FILE_ERROR;
 
-               DB( g_print("- id line: --(%.50s)\n\n", v_buffer) );
 
-               version = g_ascii_strtod(v_buffer+13, NULL);    /* a little hacky, but works ! */
-               if( version == 0.0 )
-                       version = 0.1;
+// lower v0.6 : we must assume categories/payee exists
+// and strong link to xfer
+// #632496
+static void homebank_upgrade_lower_v06(void)
+{
+GList *lst_acc, *lnk_acc;
+Category *cat;
+Payee *pay;
+GList *lrul, *list;
 
-               ctx.version = version;
+       DB( g_print("\n[hb-xml] homebank_upgrade_lower_v06\n") );
 
-               if( version > FILE_VERSION )
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
+       {
+       Account *acc = lnk_acc->data;
+       
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
                {
-                       DB( g_print("- failed: version %f is not supported (max is %f)\n", version, FILE_VERSION) );
-                       return XML_VERSION_ERROR;
+               Transaction *entry = list->data;
+
+                       //also strong link internal xfer
+                       if(entry->paymode == PAYMODE_INTXFER && entry->kxfer == 0)
+                       {
+                       Transaction *child = transaction_old_get_child_transfer(entry);
+                               if(child != NULL)
+                               {
+                                       transaction_xfer_change_to_child(entry, child);
+                               }
+                       }
+
+                       da_transaction_consistency(entry);
+                       
+                       list = g_list_next(list);
                }
-               else
-               {
-                       DB( g_print("- ok : version=%.1f\n", version) );
+               lnk_acc = g_list_next(lnk_acc);
+       }
+       g_list_free(lst_acc);
 
-                       /* 1st: validate the file is well in utf-8 */
-                       DB( g_print("- ensure UTF-8\n") );
-                       buffer = homebank_utf8_ensure(buffer);
 
-                       /* then process the buffer */
-                       #if MYDEBUG == 1
-                               GTimer *t = g_timer_new();
-                               g_print("- start parse\n");
-                       #endif
+       lrul = list = g_hash_table_get_values(GLOBALS->h_rul);
+       while (list != NULL)
+       {
+       Assign *entry = list->data;
 
-                       context = g_markup_parse_context_new (&hb_parser, 0, &ctx, NULL);
+               cat = da_cat_get(entry->kcat);
+               if(cat == NULL)
+               {
+                       DB( g_print(" !! fixing cat for rul: %d is unknow\n", entry->kcat) );
+                       entry->kcat = 0;
+               }
 
-                       error = NULL;
-                       rc = g_markup_parse_context_parse (context, buffer, length, &error);
+               pay = da_pay_get(entry->kpay);
+               if(pay == NULL)
+               {
+                       DB( g_print(" !! fixing pay for rul: %d is unknow\n", entry->kpay) );
+                       entry->kpay = 0;
+               }
 
-                       if( error )
-                               g_print("failed: %s\n", error->message);
 
-                       if( rc == FALSE )
-                       {
-                               error = NULL;
-                               g_markup_parse_context_end_parse(context, &error);
+               list = g_list_next(list);
+       }
+       g_list_free(lrul);
+}
 
-                               if( error )
-                                       g_print("failed: %s\n", error->message);
-                       }
 
-                       g_markup_parse_context_free (context);
-                       g_free (buffer);
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
-                       //reverse the glist (see g_list append idiom to perf for reason
-                       // we use prepend and then reverse
-                       GLOBALS->ope_list = g_list_reverse(GLOBALS->ope_list);
-                       
-                       DB( g_print("- end parse : %f sec\n", g_timer_elapsed(t, NULL)) );
-                       DB( g_timer_destroy (t) );
 
-                       /* file upgrade / bugfix */
-                       if( version <= 0.1 )
-                               homebank_upgrade_to_v02();
-                       if( version <= 0.2 )
-                               homebank_upgrade_to_v03();
-                       if( version <= 0.3 )
-                               homebank_upgrade_to_v04();
-                       if( version <= 0.4 )
-                               homebank_upgrade_to_v05();
-                       if( version <= 0.5 )
-                       {
-                               homebank_upgrade_to_v06();
-                               homebank_upgrade_lower_v06();
-                       }
-                       if( version <= 0.6 )
-                       {
-                               homebank_upgrade_to_v07();
-                               hbfile_sanity_check();
-                       }
-                       if( version <= 0.7 )
-                               homebank_upgrade_to_v08();
-                       if( version <= 0.8 )
-                               hbfile_sanity_check();
+static void homebank_load_xml_acc(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+Account *entry = da_acc_malloc();
+gint i;
 
-                       // next ?
-                       
-               }
+       for (i = 0; attribute_names[i] != NULL; i++)
+       {
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+                    if(!strcmp (attribute_names[i], "key"     )) { entry->key   = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "flags"   )) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "pos"     )) { entry->pos   = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "type"    )) { entry->type = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "curr"    )) { entry->kcur = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "name"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->name = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "number"  )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->number = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "bankname")) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->bankname = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "initial" )) { entry->initial = g_ascii_strtod(attribute_values[i], NULL); }
+
+               else if(!strcmp (attribute_names[i], "minimum" )) { entry->minimum = g_ascii_strtod(attribute_values[i], NULL); }
+               else if(!strcmp (attribute_names[i], "cheque1" )) { entry->cheque1 = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "cheque2" )) { entry->cheque2 = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "notes"   )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->notes = g_strdup(attribute_values[i]); }
        }
 
-       return retval;
+       //all attribute loaded: append
+       da_acc_insert(entry);
 }
 
 
-/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-
-// v0.1 to v0.2 : we must change account reference by making a +1 to its index references
-static void homebank_upgrade_to_v02(void)
+static void homebank_load_xml_asg(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
 {
-GList *list;
-
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v02\n") );
+Assign *entry = da_asg_malloc();
+gint exact = 0;
+gint i;
 
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
+       for (i = 0; attribute_names[i] != NULL; i++)
        {
-       Transaction *entry = list->data;
-               entry->kacc++;
-               entry->kxferacc++;
-               list = g_list_next(list);
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+                    if(!strcmp (attribute_names[i], "key"     )) { entry->key   = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "flags"   )) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "field"   )) { entry->field = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "name"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->text = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "payee"   )) { entry->kpay = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "category")) { entry->kcat = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
+               // prior v08
+               else if(!strcmp (attribute_names[i], "exact" )) { exact = atoi(attribute_values[i]); }
        }
 
-       list = g_list_first(GLOBALS->arc_list);
-       while (list != NULL)
+       /* in v08 exact moved to flag */
+       if( ctx->file_version <= 0.7)
        {
-       Archive *entry = list->data;
-               entry->kacc++;
-               entry->kxferacc++;
-               list = g_list_next(list);
+               entry->flags = (ASGF_DOCAT|ASGF_DOPAY);
+               if( exact > 0 )
+                  entry->flags |= ASGF_EXACT;
        }
+
+       //all attribute loaded: append
+       da_asg_append(entry);
+
 }
 
-// v0.2 to v0.3 : we must assume categories exists : bugs 303886, 303738
-static void homebank_upgrade_to_v03(void)
+
+static void homebank_load_xml_pay(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
 {
-GList *list;
+Payee *entry = da_pay_malloc();
+gint i;
 
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v03\n") );
-       
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
+       for (i = 0; attribute_names[i] != NULL; i++)
        {
-       Transaction *entry = list->data;
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
 
-               da_transaction_consistency(entry);
-               list = g_list_next(list);
+                        if(!strcmp (attribute_names[i], "key"  )) { entry->key = atoi(attribute_values[i]); }
+               //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "category")) { entry->kcat = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
        }
 
-       list = g_list_first(GLOBALS->arc_list);
-       while (list != NULL)
-       {
-       Archive *entry = list->data;
+       //all attribute loaded: append
+       da_pay_insert(entry);
+}
 
-               da_archive_consistency(entry);
-               list = g_list_next(list);
+
+static void homebank_load_xml_prop(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+gint i;
+
+       for (i = 0; attribute_names[i] != NULL; i++)
+       {
+                    if(!strcmp (attribute_names[i], "title"       )) { g_free(GLOBALS->owner); GLOBALS->owner = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "curr"        )) { GLOBALS->kcur = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "car_category")) { GLOBALS->vehicle_category = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "auto_smode"  )) { GLOBALS->auto_smode = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "auto_weekday")) { GLOBALS->auto_weekday = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "auto_nbdays" )) { GLOBALS->auto_nbdays = atoi(attribute_values[i]); }
        }
 }
 
-static void homebank_upgrade_to_v04(void)
+
+static void homebank_load_xml_cat(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
 {
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v04\n") );
+Category *entry = da_cat_malloc();
+gboolean budget;
+gint i, j;
 
-       GLOBALS->arc_list = da_archive_sort(GLOBALS->arc_list);
+       for (i = 0; attribute_names[i] != NULL; i++)
+       {
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+                    if(!strcmp (attribute_names[i], "key"   )) { entry->key = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "parent")) { entry->parent = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "name"  )) { entry->name = g_strdup(attribute_values[i]); }
+
+               budget = FALSE;
+               for(j=0;j<=12;j++)
+               {
+               gchar *tmpname;
+
+                       tmpname = g_strdup_printf ("b%d", j);
+                       if(!(strcmp (attribute_names[i], tmpname))) { entry->budget[j] = g_ascii_strtod(attribute_values[i], NULL); }
+                       g_free(tmpname);
+
+                       if(entry->budget[j]) budget = TRUE;
+               }
+               if(budget == TRUE)
+                       entry->flags |= GF_BUDGET;
+
+       }
+
+       //all attribute loaded: append
+       da_cat_insert( entry);
 }
 
 
-// v0.4 to v0.5 :
-// we must assume kxferacc exists in archives for internal xfer : bug 528923
-// if not, remove automation from the archive
-static void homebank_upgrade_to_v05(void)
+static void homebank_load_xml_cur(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
 {
-GList *list;
+Currency *entry = da_cur_malloc ();
+gint i;
 
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v05\n") );
+       for (i = 0; attribute_names[i] != NULL; i++)
+       {
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+                        if(!strcmp (attribute_names[i], "key"    )) { entry->key = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "name"  )) { entry->name = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "iso"   )) { entry->iso_code = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "symb"  )) { entry->symbol = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "syprf" )) { entry->sym_prefix = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "dchar" )) { entry->decimal_char = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "gchar" )) { entry->grouping_char = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "frac"  )) { entry->frac_digits = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "rate"  )) { entry->rate = g_ascii_strtod(attribute_values[i], NULL); }
+               else if(!strcmp (attribute_names[i], "mdate ")) { entry->mdate = atoi(attribute_values[i]); }
 
-       list = g_list_first(GLOBALS->arc_list);
-       while (list != NULL)
+       }
+
+       //all attribute loaded: append
+       da_cur_insert (entry);
+}
+
+
+static void homebank_load_xml_tag(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+Tag *entry = da_tag_malloc();
+gint i;
+
+       for (i = 0; attribute_names[i] != NULL; i++)
        {
-       Archive *entry = list->data;
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
 
-               da_archive_consistency(entry);
-               list = g_list_next(list);
+                    if(!strcmp (attribute_names[i], "key"  )) { entry->key = atoi(attribute_values[i]); }
+               //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
        }
+
+       //all attribute loaded: append
+       da_tag_insert(entry);
 }
 
 
-// v0.5 to v0.6 : we must change kxferacc to 0 on non Xfer transactions
-//#677351
-static void homebank_upgrade_to_v06(void)
+static void homebank_load_xml_fav(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
 {
-GList *list;
+Archive *entry = da_archive_malloc();
+gchar *scat = NULL;
+gchar *samt = NULL;
+gchar *smem = NULL;
+gboolean split = FALSE;
+gint i;
+
+       for (i = 0; attribute_names[i] != NULL; i++)
+       {
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+                    if(!strcmp (attribute_names[i], "amount"     )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
+               else if(!strcmp (attribute_names[i], "account"    )) { entry->kacc = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "paymode"    )) { entry->paymode = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "st"         )) { entry->status = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "flags"      )) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "payee"      )) { entry->kpay = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "category"   )) { entry->kcat = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "wording"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->wording = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "nextdate"   )) { entry->nextdate = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "every"      )) { entry->every = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "unit"       )) { entry->unit = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "limit"      )) { entry->limit = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "weekend"    )) { entry->weekend = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "scat"       )) { scat = (gchar *)attribute_values[i]; split = TRUE; }
+               else if(!strcmp (attribute_names[i], "samt"       )) { samt = (gchar *)attribute_values[i]; split = TRUE; }
+               else if(!strcmp (attribute_names[i], "smem"       )) { smem = (gchar *)attribute_values[i]; split = TRUE; }
 
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v06\n") );
+       }
 
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
+       if(split == TRUE)
        {
-       Transaction *entry = list->data;
-               da_transaction_consistency(entry);
-               list = g_list_next(list);
+               if (da_splits_parse(entry->splits, scat, samt, smem) > 0)
+               {
+                       entry->flags |= OF_SPLIT; //Flag that Splits are active
+               }
        }
 
-       list = g_list_first(GLOBALS->arc_list);
-       while (list != NULL)
+       //all attribute loaded: append
+       GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, entry);
+}
+
+
+static void homebank_load_xml_ope(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+Transaction *entry = da_transaction_malloc();
+gchar *scat = NULL;
+gchar *samt = NULL;
+gchar *smem = NULL;
+gboolean split = FALSE;
+gint i;
+
+       for (i = 0; attribute_names[i] != NULL; i++)
        {
-       Archive *entry = list->data;
-               da_archive_consistency(entry);
-               list = g_list_next(list);
+               //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+                    if(!strcmp (attribute_names[i], "date"       )) { entry->date = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "amount"     )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
+               else if(!strcmp (attribute_names[i], "account"    )) { entry->kacc = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "paymode"    )) { entry->paymode = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "st"         )) { entry->status = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "flags"      )) { entry->flags = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "payee"      )) { entry->kpay = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "category"   )) { entry->kcat = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "wording"    )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->wording = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "info"       )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->info = g_strdup(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "tags"       ))
+               {
+                       if(attribute_values[i] != NULL && strlen(attribute_values[i]) > 0 && strcmp(attribute_values[i],"(null)") != 0 )
+                       {
+                               transaction_tags_parse(entry, attribute_values[i]);
+                       }
+               }
+               else if(!strcmp (attribute_names[i], "kxfer"    )) { entry->kxfer = atoi(attribute_values[i]); }
+               else if(!strcmp (attribute_names[i], "scat"     )) { scat = (gchar *)attribute_values[i]; split = TRUE; }
+               else if(!strcmp (attribute_names[i], "samt"     )) { samt = (gchar *)attribute_values[i]; split = TRUE; }
+               else if(!strcmp (attribute_names[i], "smem"     )) { smem = (gchar *)attribute_values[i]; split = TRUE; }
        }
+
+       //bugfix 303886
+       //if(entry->kcat < 0)
+       //      entry->kcat = 0;
+
+       if(split == TRUE)
+       {
+               if (da_splits_parse(entry->splits, scat, samt, smem) > 0)
+               {
+                       entry->flags |= OF_SPLIT; //Flag that Splits are active
+               }
+       }
+       
+       //all attribute loaded: append
+       // we use prepend here, the list will be reversed later for perf reason
+       da_transaction_prepend(entry);
 }
 
 
-// v0.7 AF_BUDGET removed instead of AF_NOBUDGET
-static void homebank_upgrade_to_v07(void)
+
+
+static void
+start_element_handler (GMarkupParseContext *context,
+                      const gchar         *element_name,
+                      const gchar        **attribute_names,
+                      const gchar        **attribute_values,
+                      gpointer             user_data,
+                      GError             **error)
 {
-GList *lacc, *list;
+ParseContext *ctx = user_data;
+//GtkUIManager *self = ctx->self;
 
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v07\n") );
+       //DB( g_print("** start element: %s\n", element_name) );
 
-       lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
-       while (list != NULL)
+       switch(element_name[0])
        {
-       Account *acc = list->data;
+               case 'a':
+               {
+                       if(!strcmp (element_name, "account"))   //account
+                       {
+                               homebank_load_xml_acc(ctx, attribute_names, attribute_values);
+                       }
+                       else if(!strcmp (element_name, "asg"))  //assign
+                       {
+                               homebank_load_xml_asg(ctx, attribute_names, attribute_values);
+                       }
+               }
+               break;
 
-               if( acc->flags & AF_OLDBUDGET ) // budget include
+               case 'p':
                {
-                       acc->flags &= ~(AF_OLDBUDGET);
+                       if(!strcmp (element_name, "pay"))
+                       {
+                               homebank_load_xml_pay(ctx, attribute_names, attribute_values);
+                       }
+                       else if(!strcmp (element_name, "properties"))
+                       {
+                               homebank_load_xml_prop(ctx, attribute_names, attribute_values);
+                       }
                }
-               else
+               break;
+
+               case 'c':
                {
-                       acc->flags |= AF_NOBUDGET;
+                       if(!strcmp (element_name, "cat"))
+                       {
+                               homebank_load_xml_cat(ctx, attribute_names, attribute_values);
+                       }
+                       else if(!strcmp (element_name, "cur"))
+                       {
+                               homebank_load_xml_cur(ctx, attribute_names, attribute_values);
+                       }
                }
+               break;
 
-               list = g_list_next(list);
+               case 't':
+               {
+                       if(!strcmp (element_name, "tags"))
+                       {
+                               homebank_load_xml_tag(ctx, attribute_names, attribute_values);
+                       }
+               }
+
+               case 'f':
+               {
+                       if(!strcmp (element_name, "fav"))
+                       {
+                               homebank_load_xml_fav(ctx, attribute_names, attribute_values);
+                       }
+               }
+               break;
+
+               case 'o':
+               {
+                       if(!strcmp (element_name, "ope"))
+                       {
+                               homebank_load_xml_ope(ctx, attribute_names, attribute_values);
+                       }
+               }
+               break;
        }
-       g_list_free(lacc);
+}
+
+
+/*
+static void
+end_element_handler (GMarkupParseContext *context,
+                    const gchar         *element_name,
+                    gpointer             user_data,
+                    GError             **error)
+{
+  ParseContext *ctx = user_data;
+
+       //DB( g_print("-- end element: %s\n", element_name) );
+
 
 }
+*/
 
-static void homebank_upgrade_to_v08(void)
+static GMarkupParser hb_parser = {
+       start_element_handler,
+       NULL,   //end_element_handler,
+       NULL, //text_handler,
+       NULL,
+       NULL  //cleanup
+};
+
+
+static gboolean hb_xml_get_version(ParseContext *ctx, gchar *buffer)
 {
-GList *list;
+gchar *v_buffer;
 
-       DB( g_print("\n[hb-xml] homebank_upgrade_to_v08\n") );
+       ctx->file_version = 0.0;
+       ctx->data_version = 0;
 
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
-       {
-       Transaction *entry = list->data;
-               da_transaction_consistency(entry);
-               list = g_list_next(list);
-       }
+       /* v3.4 add :: prevent load of future file version */
+       v_buffer = g_strstr_len(buffer, 50, "<homebank v=");
+       if( v_buffer == NULL )
+               return FALSE;
 
+       DB( g_print("- id line: --(%.50s)\n\n", v_buffer) );
 
+       ctx->file_version = g_ascii_strtod(v_buffer+13, NULL);  /* a little hacky, but works ! */
+       if( ctx->file_version == 0.0 ) 
+               ctx->file_version = 0.1;
+       else if( ctx->file_version == 5.0 ) //was a mistake
+               ctx->file_version = 1.0;
+
+       v_buffer = g_strstr_len(buffer+13, 50, "d=");
+       if( v_buffer )
+       {
+               DB( g_print(" d=%s)\n\n", v_buffer) );
+       
+               ctx->data_version = atoi(v_buffer+3);
+       }
+       return TRUE;
 }
 
 
-// v0.6 to v0.7 : assign a default currency
 /*
-static void homebank_upgrade_to_v08(void)
+** XML load homebank file: hbfile
+*/
+gint homebank_load_xml(gchar *filename)
 {
+gint retval;
+gchar *buffer;
+gsize length;
+GError *error = NULL;
+ParseContext ctx;
+GMarkupParseContext *context;
+gboolean rc;
+
+       DB( g_print("\n[hb-xml] homebank_load_xml\n") );
+
+       retval = XML_OK;
+       if (!g_file_get_contents (filename, &buffer, &length, &error))
+       {
+               //g_message ("%s", error->message);
+               retval = XML_IO_ERROR;
+               g_error_free (error);
+       }
+       else
+       {
+               if( hb_xml_get_version(&ctx, buffer) == FALSE )
+               {
+                       return XML_FILE_ERROR;
+               }
 
-       // set a base currency to the hbfile if not
-       g_print("GLOBALS->kcur %d\n", GLOBALS->kcur);
+               if( ctx.file_version > FILE_VERSION )
+               {
+                       DB( g_print("- failed: version %f is not supported (max is %f)\n", ctx.file_version, FILE_VERSION) );
+                       return XML_VERSION_ERROR;
+               }
+               else
+               {
+                       DB( g_print("- file ok : v=%.1f data_v=%06d\n", ctx.file_version, ctx.data_version) );
 
-       if(GLOBALS->kcur == 0)
-       {
-       //struct iso4217format *choice = ui_cur_select_dialog_new(GLOBALS->mainwindow);
-       struct iso4217format *curfmt =  iso4217format_get(PREFS->curr_default);
+                       /* 1st: validate the file is well in utf-8 */
+                       DB( g_print("- ensure UTF-8\n") );
+                       buffer = homebank_utf8_ensure(buffer);
 
-               if(curfmt == NULL)
-                       curfmt = iso4217format_get_en_us();
-               
-               
-               Currency *item = currency_add_from_user(curfmt);
+                       /* then process the buffer */
+                       #if MYDEBUG == 1
+                               GTimer *t = g_timer_new();
+                               g_print("- start parse\n");
+                       #endif
 
-                       GLOBALS->kcur = item->key;
+                       context = g_markup_parse_context_new (&hb_parser, 0, &ctx, NULL);
 
-                       g_print("GLOBALS->kcur %d\n", GLOBALS->kcur);
+                       error = NULL;
+                       rc = g_markup_parse_context_parse (context, buffer, length, &error);
 
-                       // set every accounts to base currecny
-                       GList *list = g_hash_table_get_values(GLOBALS->h_acc);
-                       while (list != NULL)
-                       {
-                       Account *acc;
-                               acc = list->data;
+                       if( error )
+                               g_print("failed: %s\n", error->message);
 
-                               acc->kcur = item->key;
+                       if( rc == FALSE )
+                       {
+                               error = NULL;
+                               g_markup_parse_context_end_parse(context, &error);
 
-                               list = g_list_next(list);
+                               if( error )
+                                       g_print("failed: %s\n", error->message);
                        }
-                       g_list_free(list);
-
-               
-       }
-}
-*/
-
-
-// lower v0.6 : we must assume categories/payee exists
-// and strong link to xfer
-// #632496
-static void homebank_upgrade_lower_v06(void)
-{
-Category *cat;
-Payee *pay;
-GList *lrul, *list;
 
-       DB( g_print("\n[hb-xml] homebank_upgrade_lower_v06\n") );
-
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
-       {
-       Transaction *entry = list->data;
+                       g_markup_parse_context_free (context);
+                       g_free (buffer);
 
-               da_transaction_consistency(entry);
+                       DB( g_print("- end parse : %f sec\n", g_timer_elapsed(t, NULL)) );
+                       DB( g_timer_destroy (t) );
 
-               //also strong link internal xfer
-               if(entry->paymode == PAYMODE_INTXFER)
-               {
-               Transaction *child = transaction_old_get_child_transfer(entry);
-                       if(child != NULL)
+                       /* file upgrade / bugfix */
+                       if( ctx.file_version <= 0.1 )
+                               homebank_upgrade_to_v02();
+                       if( ctx.file_version <= 0.2 )
+                               homebank_upgrade_to_v03();
+                       if( ctx.file_version <= 0.3 )
+                               homebank_upgrade_to_v04();
+                       if( ctx.file_version <= 0.4 )
+                               homebank_upgrade_to_v05();
+                       if( ctx.file_version <= 0.5 )
                        {
-                               transaction_xfer_change_to_child(entry, child);
+                               homebank_upgrade_to_v06();
+                               homebank_upgrade_lower_v06();
+                       }
+                       if( ctx.file_version <= 0.6 )
+                       {
+                               homebank_upgrade_to_v07();
+                               hbfile_sanity_check();
+                       }
+                       if( ctx.file_version <= 0.7 )   // <= 4.5
+                       {       
+                               homebank_upgrade_to_v08();
+                       }
+                       if( ctx.file_version <= 0.8 )   // <= 4.6
+                       {
+                               hbfile_sanity_check();
+                       }
+                       if( ctx.file_version <= 0.9 )   // <= 4.6.3
+                       {
+                               hbfile_sanity_check();
+                               homebank_upgrade_to_v10();
+                       }
+                       if( ctx.file_version <= 1.0 )   // <= 5.0.0 
+                       {
+                               hbfile_sanity_check();
+                               homebank_upgrade_to_v11();
+                       }
+                       //starting 5.0.4 data upgrade is done without changing file_version
+                       if( ctx.data_version < 050005 ) // <= 5.0.5 
+                       {
+                               hbfile_sanity_check();
+                       }
+                       if( ctx.file_version <= 1.1 )   // <= 5.1.0 
+                       {
+                               hbfile_sanity_check();
+                               homebank_upgrade_to_v12();
                        }
-               }
-
-               list = g_list_next(list);
-       }
-
-
-       lrul = list = g_hash_table_get_values(GLOBALS->h_rul);
-       while (list != NULL)
-       {
-       Assign *entry = list->data;
-
-               cat = da_cat_get(entry->kcat);
-               if(cat == NULL)
-               {
-                       DB( g_print(" !! fixing cat for rul: %d is unknow\n", entry->kcat) );
-                       entry->kcat = 0;
-               }
 
-               pay = da_pay_get(entry->kpay);
-               if(pay == NULL)
-               {
-                       DB( g_print(" !! fixing pay for rul: %d is unknow\n", entry->kpay) );
-                       entry->kpay = 0;
+                       // next ?
+                       
                }
-
-
-               list = g_list_next(list);
        }
-       g_list_free(lrul);
-
 
+       return retval;
 }
 
 
+
 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
 /*
@@ -801,6 +965,79 @@ static void hb_xml_append_txt(GString *gstring, gchar *attrname, gchar *value)
        }
 }
 
+static void
+append_escaped_text (GString     *str,
+                     const gchar *text,
+                     gssize       length)
+{
+  const gchar *p;
+  const gchar *end;
+  gunichar c;
+
+  p = text;
+  end = text + length;
+
+  while (p < end)
+    {
+      const gchar *next;
+      next = g_utf8_next_char (p);
+
+      switch (*p)
+        {
+        case '&':
+          g_string_append (str, "&amp;");
+          break;
+
+        case '<':
+          g_string_append (str, "&lt;");
+          break;
+
+        case '>':
+          g_string_append (str, "&gt;");
+          break;
+
+        case '\'':
+          g_string_append (str, "&apos;");
+          break;
+
+        case '"':
+          g_string_append (str, "&quot;");
+          break;
+
+        default:
+          c = g_utf8_get_char (p);
+          if ((0x1 <= c && c <= 0x8) ||
+              (0xa <= c && c  <= 0xd) ||       //chnaged here from b<->c to a<->d
+              (0xe <= c && c <= 0x1f) ||
+              (0x7f <= c && c <= 0x84) ||
+              (0x86 <= c && c <= 0x9f))
+            g_string_append_printf (str, "&#x%x;", c);
+          else
+            g_string_append_len (str, p, next - p);
+          break;
+        }
+
+      p = next;
+    }
+}
+
+// we override g_markup_escape_text from glib to encode \n (LF) & \r (CR)
+static void hb_xml_append_txt_crlf(GString *gstring, gchar *attrname, gchar *value)
+{
+       if(value != NULL && *value != 0)
+       {
+       gssize length;
+       GString *escaped;
+               
+               //gchar *escaped = g_markup_escape_text(value, -1);
+               length = strlen (value);
+               escaped = g_string_sized_new (length);
+               append_escaped_text (escaped, value, length);
+               g_string_append_printf(gstring, "%s=\"%s\" ", attrname, escaped->str);
+               g_string_free (escaped, TRUE);
+       }
+}
+
 static void hb_xml_append_int0(GString *gstring, gchar *attrname, guint32 value)
 {
        g_string_append_printf(gstring, "%s=\"%d\" ", attrname, value);
@@ -824,13 +1061,18 @@ char buf[G_ASCII_DTOSTR_BUF_SIZE];
 }
 
 
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
+
+
 /*
 ** XML properties save
 */
-static void homebank_save_xml_prop(GIOChannel *io)
+static gint homebank_save_xml_prop(GIOChannel *io)
 {
 gchar *title;
 GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
 
        title = GLOBALS->owner == NULL ? "" : GLOBALS->owner;
 
@@ -839,6 +1081,7 @@ GString *node;
        g_string_assign(node, "<properties ");
        
        hb_xml_append_txt(node, "title", title);
+       hb_xml_append_int(node, "curr", GLOBALS->kcur);
        hb_xml_append_int(node, "car_category", GLOBALS->vehicle_category);
        hb_xml_append_int0(node, "auto_smode", GLOBALS->auto_smode);
        hb_xml_append_int(node, "auto_weekday", GLOBALS->auto_weekday);
@@ -846,61 +1089,67 @@ GString *node;
 
        g_string_append(node, "/>\n");
 
-       g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+       error = NULL;
+       g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+       if(error)
+       {
+               retval = XML_IO_ERROR;
+               g_error_free(error);
+       }
 
        g_string_free(node, TRUE);
+       return retval;
 }
 
 
 /*
 ** XML currency save
 */
-/*
-static void homebank_save_xml_cur(GIOChannel *io)
+static gint homebank_save_xml_cur(GIOChannel *io)
 {
 GList *list;
 gchar *tmpstr;
 char buf1[G_ASCII_DTOSTR_BUF_SIZE];
+gint retval = XML_OK;
 
        list = g_hash_table_get_values(GLOBALS->h_cur);
        while (list != NULL)
        {
        Currency *item = list->data;
 
-               if(item->key != 0)
-               {
-                       tmpstr = g_markup_printf_escaped(
-                           "<cur key=\"%d\" iso=\"%s\" name=\"%s\" symb=\"%s\" syprf=\"%d\" dchar=\"%s\" gchar=\"%s\" frac=\"%d\" rate=\"%s\" mdate=\"%d\" />\n",
-                               item->key,
-                               item->iso_code,
-                           item->name,
-                           item->symbol,
-                           item->sym_prefix,
-                           item->decimal_char,
-                           item->grouping_char,
-                           item->frac_digits,
-                           g_ascii_dtostr (buf1, sizeof (buf1), item->rate),
-                           item->mdate
-                       );
-
-                       g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
-                       g_free(tmpstr);
+               tmpstr = g_markup_printf_escaped(
+                   "<cur key=\"%d\" iso=\"%s\" name=\"%s\" symb=\"%s\" syprf=\"%d\" dchar=\"%s\" gchar=\"%s\" frac=\"%d\" rate=\"%s\" mdate=\"%d\" />\n",
+                       item->key,
+                       item->iso_code,
+                   item->name,
+                   item->symbol,
+                   item->sym_prefix,
+                   item->decimal_char,
+                   item->grouping_char,
+                   item->frac_digits,
+                   g_ascii_dtostr (buf1, sizeof (buf1), item->rate),
+                   item->mdate
+               );
+
+               g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
+               g_free(tmpstr);
 
-               }
                list = g_list_next(list);
        }
        g_list_free(list);
+       return retval;
 }
-*/
 
 
 /*
 ** XML account save
 */
-static void homebank_save_xml_acc(GIOChannel *io)
+static gint homebank_save_xml_acc(GIOChannel *io)
 {
 GList *lacc, *list;
 GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
 
        node = g_string_sized_new(255);
 
@@ -909,7 +1158,7 @@ GString *node;
        {
        Account *item = list->data;
 
-               item->flags &= ~(AF_ADDED|AF_CHANGED);  //remove flag
+               item->flags &= ~(AF_ADDED|AF_CHANGED);  //delete flag
 
                g_string_assign(node, "<account ");
                
@@ -917,31 +1166,46 @@ GString *node;
                hb_xml_append_int(node, "flags", item->flags);
                hb_xml_append_int(node, "pos", item->pos);
                hb_xml_append_int(node, "type", item->type);
-               //hb_xml_append_int(node, "curr", item->kcur);
+               hb_xml_append_int(node, "curr", item->kcur);
                hb_xml_append_txt(node, "name", item->name);
                hb_xml_append_txt(node, "number", item->number);
                hb_xml_append_txt(node, "bankname", item->bankname);
                hb_xml_append_amt(node, "initial", item->initial);
+
                hb_xml_append_amt(node, "minimum", item->minimum);
                hb_xml_append_int(node, "cheque1", item->cheque1);
                hb_xml_append_int(node, "cheque2", item->cheque2);
+               hb_xml_append_txt_crlf(node, "notes", item->notes);
 
                g_string_append(node, "/>\n");
 
-               g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+               error = NULL;
+               g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+               if(error)
+               {
+                       retval = XML_IO_ERROR;
+                       g_error_free(error);
+               }
+
                list = g_list_next(list);
        }
        g_list_free(lacc);
        g_string_free(node, TRUE);
+       return retval;
 }
 
 /*
 ** XML payee save
 */
-static void homebank_save_xml_pay(GIOChannel *io)
+static gint homebank_save_xml_pay(GIOChannel *io)
 {
 GList *lpay, *list;
-gchar *tmpstr;
+GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
+
+       node = g_string_sized_new(255);
 
        lpay = list = payee_glist_sorted(0);
        while (list != NULL)
@@ -950,29 +1214,43 @@ gchar *tmpstr;
 
                if(item->key != 0)
                {
-                       tmpstr = g_markup_printf_escaped("<pay key=\"%d\" name=\"%s\"/>\n",
-                               item->key,
-                               item->name
-                       );
+                       g_string_assign(node, "<pay ");
 
-                       g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
-                       g_free(tmpstr);
+                       hb_xml_append_int(node, "key", item->key);
+                       hb_xml_append_txt(node, "name", item->name);
+                       hb_xml_append_int(node, "category", item->kcat);
+                       hb_xml_append_int(node, "paymode" , item->paymode);
+
+                       g_string_append(node, "/>\n");
+
+                       error = NULL;
+                       g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+                       if(error)
+                       {
+                               retval = XML_IO_ERROR;
+                               g_error_free(error);
+                       }
 
                }
                list = g_list_next(list);
        }
        g_list_free(lpay);
+       g_string_free(node, TRUE);
+       return retval;
 }
 
 /*
 ** XML category save
 */
-static void homebank_save_xml_cat(GIOChannel *io)
+static gint homebank_save_xml_cat(GIOChannel *io)
 {
 GList *lcat, *list;
 GString *node;
 char buf[G_ASCII_DTOSTR_BUF_SIZE];
 guint i;
+gint retval = XML_OK;
+GError *error = NULL;
 
        node = g_string_sized_new(255);
 
@@ -999,22 +1277,33 @@ guint i;
                        }
 
                        g_string_append(node, "/>\n");
-                       g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+                       
+                       error = NULL;
+                       g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+                       if(error)
+                       {
+                               retval = XML_IO_ERROR;
+                               g_error_free(error);
+                       }
 
                }
                list = g_list_next(list);
        }
        g_list_free(lcat);
        g_string_free(node, TRUE);
+       return retval;
 }
 
 /*
 ** XML tag save
 */
-static void homebank_save_xml_tag(GIOChannel *io)
+static gint homebank_save_xml_tag(GIOChannel *io)
 {
 GList *ltag, *list;
 gchar *tmpstr;
+gint retval = XML_OK;
+GError *error = NULL;
 
        ltag = list = tag_glist_sorted(0);
        while (list != NULL)
@@ -1023,28 +1312,37 @@ gchar *tmpstr;
 
                if(item->key != 0)
                {
-                       tmpstr = g_markup_printf_escaped("<tag key=\"%d\" name=\"%s\" />\n",
+                       tmpstr = g_markup_printf_escaped("<tag key=\"%d\" name=\"%s\"/>\n",
                                item->key,
                                item->name
                        );
 
-                       g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
+                       error = NULL;
+                       g_io_channel_write_chars(io, tmpstr, -1, NULL, &error);
                        g_free(tmpstr);
-
+                       
+                       if(error)
+                       {
+                               retval = XML_IO_ERROR;
+                               g_error_free(error);
+                       }
                }
                list = g_list_next(list);
        }
        g_list_free(ltag);
+       return retval;
 }
 
 
 /*
 ** XML assign save
 */
-static void homebank_save_xml_asg(GIOChannel *io)
+static gint homebank_save_xml_asg(GIOChannel *io)
 {
 GList *lasg, *list;
 GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
 
        node = g_string_sized_new(255);
        
@@ -1058,19 +1356,27 @@ GString *node;
                hb_xml_append_int(node, "key"     , item->key);
                hb_xml_append_int(node, "flags"   , item->flags);
                hb_xml_append_int(node, "field"   , item->field);
-               hb_xml_append_txt(node, "name"    , item->name);        
+               hb_xml_append_txt(node, "name"    , item->text);        
                hb_xml_append_int(node, "payee"   , item->kpay);
                hb_xml_append_int(node, "category", item->kcat);
-               //hb_xml_append_int(node, "paymode" , item->paymode);
+               hb_xml_append_int(node, "paymode" , item->paymode);
 
                g_string_append(node, "/>\n");
                
-               g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+               error = NULL;
+               g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+               if(error)
+               {
+                       retval = XML_IO_ERROR;
+                       g_error_free(error);
+               }
 
                list = g_list_next(list);
        }
        g_list_free(lasg);
        g_string_free(node, TRUE);
+       return retval;
 }
 
 
@@ -1078,10 +1384,12 @@ GString *node;
 /*
 ** XML archive save
 */
-static void homebank_save_xml_arc(GIOChannel *io)
+static gint homebank_save_xml_arc(GIOChannel *io)
 {
 GList *list;
 GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
 
        node = g_string_sized_new(255);
 
@@ -1096,6 +1404,7 @@ GString *node;
                hb_xml_append_int(node, "account", item->kacc);
                hb_xml_append_int(node, "dst_account", item->kxferacc);
                hb_xml_append_int(node, "paymode", item->paymode);
+               hb_xml_append_int(node, "st", item->status);
                hb_xml_append_int(node, "flags", item->flags);
                hb_xml_append_int(node, "payee", item->kpay);
                hb_xml_append_int(node, "category", item->kcat);
@@ -1106,74 +1415,125 @@ GString *node;
                hb_xml_append_int(node, "limit", item->limit);
                hb_xml_append_int(node, "weekend", item->weekend);
 
+               if(da_splits_count(item->splits) > 0)
+               {
+                       gchar *cats, *amounts, *memos;
+               
+                       da_splits_tostring(item->splits, &cats, &amounts, &memos);
+                       g_string_append_printf(node, "scat=\"%s\" ", cats);
+                       g_string_append_printf(node, "samt=\"%s\" ", amounts);
+
+                       //fix #1173910
+                       gchar *escaped = g_markup_escape_text(memos, -1);
+                       g_string_append_printf(node, "smem=\"%s\" ", escaped);
+                       g_free(escaped);
+
+                       g_free(cats);
+                       g_free(amounts);
+                       g_free(memos);
+               }
+
                g_string_append(node, "/>\n");
 
-               g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+               error = NULL;
+               g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+               if(error)
+               {
+                       retval = XML_IO_ERROR;
+                       g_error_free(error);
+               }
+
                list = g_list_next(list);
        }
        g_string_free(node, TRUE);
+       return retval;
 }
 
 
 /*
 ** XML transaction save
 */
-static void homebank_save_xml_ope(GIOChannel *io)
+static gint homebank_save_xml_ope(GIOChannel *io)
 {
+GList *lst_acc, *lnk_acc;
 GList *list;
 GString *node;
 gchar *tagstr;
+gint retval = XML_OK;
+GError *error = NULL;
 
        node = g_string_sized_new(255);
 
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
        {
-       Transaction *item = list->data;
+       Account *acc = lnk_acc->data;
 
-               item->flags &= ~(OF_AUTO|OF_ADDED|OF_CHANGED);  //remove flag
-               tagstr = transaction_tags_tostring(item);
+               list = g_queue_peek_head_link(acc->txn_queue);
+               while (list != NULL)
+               {
+               Transaction *item = list->data;
 
-               g_string_assign(node, "<ope ");
-               
-               hb_xml_append_int(node, "date", item->date);
-               hb_xml_append_amt(node, "amount", item->amount);
-               hb_xml_append_int(node, "account", item->kacc);
-               hb_xml_append_int(node, "dst_account", item->kxferacc);
-               hb_xml_append_int(node, "paymode", item->paymode);
-               hb_xml_append_int(node, "flags", item->flags);
-               hb_xml_append_int(node, "payee", item->kpay);
-               hb_xml_append_int(node, "category", item->kcat);
-               hb_xml_append_txt(node, "wording", item->wording);      
-               hb_xml_append_txt(node, "info", item->info);    
-               hb_xml_append_txt(node, "tags", tagstr);        
-               hb_xml_append_int(node, "kxfer", item->kxfer);
+                       item->flags &= ~(OF_AUTO|OF_ADDED|OF_CHANGED);  //delete flag
+                       tagstr = transaction_tags_tostring(item);
 
-               if(da_transaction_splits_count(item) > 0)
+                       g_string_assign(node, "<ope ");
+               
+                       hb_xml_append_int(node, "date", item->date);
+                       hb_xml_append_amt(node, "amount", item->amount);
+                       hb_xml_append_int(node, "account", item->kacc);
+                       hb_xml_append_int(node, "dst_account", item->kxferacc);
+                       hb_xml_append_int(node, "paymode", item->paymode);
+                       hb_xml_append_int(node, "st", item->status);
+                       hb_xml_append_int(node, "flags", item->flags);
+                       hb_xml_append_int(node, "payee", item->kpay);
+                       hb_xml_append_int(node, "category", item->kcat);
+                       hb_xml_append_txt(node, "wording", item->wording);      
+                       hb_xml_append_txt(node, "info", item->info);    
+                       hb_xml_append_txt(node, "tags", tagstr);        
+                       hb_xml_append_int(node, "kxfer", item->kxfer);
+
+               if(da_splits_count(item->splits) > 0)
                {
-               gchar *cats, *amounts, *memos;
+                       gchar *cats, *amounts, *memos;
                
-                       transaction_splits_tostring(item, &cats, &amounts, &memos);
-                       g_string_append_printf(node, "scat=\"%s\" ", cats);
-                       g_string_append_printf(node, "samt=\"%s\" ", amounts);
-
-                       //fix #1173910
-                       gchar *escaped = g_markup_escape_text(memos, -1);
-                       g_string_append_printf(node, "smem=\"%s\" ", escaped);
-                       g_free(escaped);
+                               da_splits_tostring(item->splits, &cats, &amounts, &memos);
+                               g_string_append_printf(node, "scat=\"%s\" ", cats);
+                               g_string_append_printf(node, "samt=\"%s\" ", amounts);
+
+                               //fix #1173910
+                               gchar *escaped = g_markup_escape_text(memos, -1);
+                               g_string_append_printf(node, "smem=\"%s\" ", escaped);
+                               g_free(escaped);
+
+                               g_free(cats);
+                               g_free(amounts);
+                               g_free(memos);
+                       }
 
-                       g_free(cats);
-                       g_free(amounts);
-                       g_free(memos);
-               }
+                       g_string_append(node, "/>\n");
 
-               g_string_append(node, "/>\n");
+                       g_free(tagstr);
+               
+                       error = NULL;
+                       g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+               
+                       if(error)
+                       {
+                               retval = XML_IO_ERROR;
+                               g_error_free(error);
+                       }
 
-               g_free(tagstr);
-               g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
-               list = g_list_next(list);
+                       list = g_list_next(list);
+               }
+               
+               lnk_acc = g_list_next(lnk_acc);
        }
+       g_list_free(lst_acc);
+
        g_string_free(node, TRUE);
+       return retval;
 }
 
 /*
@@ -1185,30 +1545,36 @@ GIOChannel *io;
 char buf1[G_ASCII_DTOSTR_BUF_SIZE];
 gchar *outstr;
 gint retval = XML_OK;
+GError *error = NULL;
 
-       io = g_io_channel_new_file(filename, "w", NULL);
+       io = g_io_channel_new_file(filename, "w", &error);
        if(io == NULL)
        {
                g_message("file error on: %s", filename);
                retval = XML_IO_ERROR;
+               
+               if(error)
+                       g_print("failed: %s\n", error->message);
+               
+               g_error_free(error);
        }
        else
        {
                g_io_channel_write_chars(io, "<?xml version=\"1.0\"?>\n", -1, NULL, NULL);
 
-               outstr = g_strdup_printf("<homebank v=\"%s\">\n", g_ascii_dtostr (buf1, sizeof (buf1), FILE_VERSION));
+               outstr = g_strdup_printf("<homebank v=\"%s\" d=\"%06d\">\n", g_ascii_dtostr (buf1, sizeof (buf1), FILE_VERSION), HB_VERSION_NUM);
                g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
                g_free(outstr);
 
-               homebank_save_xml_prop(io);
-               //homebank_save_xml_cur(io);
-               homebank_save_xml_acc(io);
-               homebank_save_xml_pay(io);
-               homebank_save_xml_cat(io);
-               homebank_save_xml_tag(io);
-               homebank_save_xml_asg(io);
-               homebank_save_xml_arc(io);
-               homebank_save_xml_ope(io);
+               retval = homebank_save_xml_prop(io);
+               retval = homebank_save_xml_cur(io);
+               retval = homebank_save_xml_acc(io);
+               retval = homebank_save_xml_pay(io);
+               retval = homebank_save_xml_cat(io);
+               retval = homebank_save_xml_tag(io);
+               retval = homebank_save_xml_asg(io);
+               retval = homebank_save_xml_arc(io);
+               retval = homebank_save_xml_ope(io);
 
                g_io_channel_write_chars(io, "</homebank>\n", -1, NULL, NULL);
 
This page took 0.101511 seconds and 4 git commands to generate.