/* HomeBank -- Free, easy, personal accounting for everyone. * Copyright (C) 1995-2014 Maxime DOYEN * * This file is part of HomeBank. * * HomeBank 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. * * HomeBank 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, see . */ #include "homebank.h" #include "hb-payee.h" /****************************************************************************/ /* Debug macros */ /****************************************************************************/ #define MYDEBUG 0 #if MYDEBUG #define DB(x) (x); #else #define DB(x); #endif /* our global datas */ extern struct HomeBank *GLOBALS; /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ void da_pay_free(Payee *item) { DB( g_print("da_pay_free\n") ); if(item != NULL) { DB( g_print(" => %d, %s\n", item->key, item->name) ); g_free(item->name); g_free(item); } } Payee * da_pay_malloc(void) { DB( g_print("da_pay_malloc\n") ); return g_malloc0(sizeof(Payee)); } void da_pay_destroy(void) { DB( g_print("da_pay_destroy\n") ); g_hash_table_destroy(GLOBALS->h_pay); } void da_pay_new(void) { Payee *item; DB( g_print("da_pay_new\n") ); GLOBALS->h_pay = g_hash_table_new_full(g_int_hash, g_int_equal, (GDestroyNotify)g_free, (GDestroyNotify)da_pay_free); // insert our 'no payee' item = da_pay_malloc(); item->name = g_strdup(""); da_pay_insert(item); } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ static void da_pay_max_key_ghfunc(gpointer key, Payee *item, guint32 *max_key) { *max_key = MAX(*max_key, item->key); } static gboolean da_pay_name_grfunc(gpointer key, Payee *item, gchar *name) { if( name && item->name ) { if(!strcasecmp(name, item->name)) return TRUE; } return FALSE; } /** * da_pay_length: * * Return value: the number of elements */ guint da_pay_length(void) { return g_hash_table_size(GLOBALS->h_pay); } /* gboolean da_pay_create_none(void) { Payee *pay; guint32 *new_key; DB( g_print("da_pay_insert none\n") ); pay = da_pay_malloc(); new_key = g_new0(guint32, 1); *new_key = 0; pay->key = 0; pay->name = g_strdup(""); DB( g_print(" -> insert id: %d\n", *new_key) ); g_hash_table_insert(GLOBALS->h_pay, new_key, pay); return TRUE; } */ /** * da_pay_remove: * * remove an payee from the GHashTable * * Return value: TRUE if the key was found and removed * */ gboolean da_pay_remove(guint32 key) { DB( g_print("da_pay_remove %d\n", key) ); return g_hash_table_remove(GLOBALS->h_pay, &key); } /** * da_pay_insert: * * insert an payee into the GHashTable * * Return value: TRUE if inserted * */ gboolean da_pay_insert(Payee *item) { guint32 *new_key; DB( g_print("da_pay_insert\n") ); new_key = g_new0(guint32, 1); *new_key = item->key; g_hash_table_insert(GLOBALS->h_pay, new_key, item); return TRUE; } /** * da_pay_append: * * append a new payee into the GHashTable * * Return value: TRUE if inserted * */ gboolean da_pay_append(Payee *item) { Payee *existitem; guint32 *new_key; DB( g_print("da_pay_append\n") ); /* ensure no duplicate */ //g_strstrip(item->name); if( item->name != NULL ) { existitem = da_pay_get_by_name( item->name ); if( existitem == NULL ) { new_key = g_new0(guint32, 1); *new_key = da_pay_get_max_key() + 1; item->key = *new_key; DB( g_print(" -> append id: %d\n", *new_key) ); g_hash_table_insert(GLOBALS->h_pay, new_key, item); return TRUE; } } DB( g_print(" -> %s already exist: %d\n", item->name, item->key) ); return FALSE; } /** * da_pay_get_max_key: * * Get the biggest key from the GHashTable * * Return value: the biggest key value * */ guint32 da_pay_get_max_key(void) { guint32 max_key = 0; g_hash_table_foreach(GLOBALS->h_pay, (GHFunc)da_pay_max_key_ghfunc, &max_key); return max_key; } /** * da_pay_get_by_name: * * Get an payee structure by its name * * Return value: Payee * or NULL if not found * */ Payee * da_pay_get_by_name(gchar *name) { DB( g_print("da_pay_get_by_name\n") ); return g_hash_table_find(GLOBALS->h_pay, (GHRFunc)da_pay_name_grfunc, name); } /** * da_pay_get: * * Get an payee structure by key * * Return value: Payee * or NULL if not found * */ Payee * da_pay_get(guint32 key) { //DB( g_print("da_pay_get\n") ); return g_hash_table_lookup(GLOBALS->h_pay, &key); } void da_pay_consistency(Payee *item) { g_strstrip(item->name); } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ #if MYDEBUG static void da_pay_debug_list_ghfunc(gpointer key, gpointer value, gpointer user_data) { guint32 *id = key; Payee *item = value; DB( g_print(" %d :: %s\n", *id, item->name) ); } static void da_pay_debug_list(void) { DB( g_print("\n** debug **\n") ); g_hash_table_foreach(GLOBALS->h_pay, da_pay_debug_list_ghfunc, NULL); DB( g_print("\n** end debug **\n") ); } #endif /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ gboolean payee_is_used(guint32 key) { GList *lrul, *list; list = g_list_first(GLOBALS->ope_list); while (list != NULL) { Transaction *entry = list->data; if( key == entry->kpay ) return TRUE; list = g_list_next(list); } list = g_list_first(GLOBALS->arc_list); while (list != NULL) { Archive *entry = list->data; if( key == entry->kpay ) return TRUE; list = g_list_next(list); } lrul = list = g_hash_table_get_values(GLOBALS->h_rul); while (list != NULL) { Assign *entry = list->data; if( key == entry->kpay) return TRUE; list = g_list_next(list); } g_list_free(lrul); return FALSE; } void payee_move(guint32 key1, guint32 key2) { GList *lrul, *list; list = g_list_first(GLOBALS->ope_list); while (list != NULL) { Transaction *entry = list->data; if(entry->kpay == key1) { entry->kpay = key2; entry->flags |= OF_CHANGED; } list = g_list_next(list); } list = g_list_first(GLOBALS->arc_list); while (list != NULL) { Archive *entry = list->data; if(entry->kpay == key1) { entry->kpay = key2; } list = g_list_next(list); } lrul = list = g_hash_table_get_values(GLOBALS->h_rul); while (list != NULL) { Assign *entry = list->data; if(entry->kpay == key1) { entry->kpay = key2; } list = g_list_next(list); } g_list_free(lrul); } gboolean payee_rename(Payee *item, const gchar *newname) { Payee *existitem; gchar *stripname; stripname = g_strdup(newname); g_strstrip(stripname); existitem = da_pay_get_by_name(stripname); if( existitem != NULL ) { if( existitem->key == item->key ) return TRUE; } else { g_free(item->name); item->name = g_strdup(stripname); return TRUE; } g_free(stripname); return FALSE; } /** * payee_append_if_new: * * append a new payee into the GHashTable * * Return value: a new Payee or NULL * */ Payee * payee_append_if_new(gchar *name) { gchar *stripname; Payee *item; stripname = g_strdup(name); g_strstrip(stripname); item = da_pay_get_by_name(stripname); if(item == NULL) { item = da_pay_malloc(); item->name = g_strdup(stripname); da_pay_append(item); } else item = NULL; g_free(stripname); return item; } static gint payee_glist_name_compare_func(Payee *a, Payee *b) { return hb_string_utf8_compare(a->name, b->name); } static gint payee_glist_key_compare_func(Payee *a, Payee *b) { return a->key - b->key; } GList *payee_glist_sorted(gint column) { GList *list = g_hash_table_get_values(GLOBALS->h_pay); if(column == 0) return g_list_sort(list, (GCompareFunc)payee_glist_key_compare_func); else return g_list_sort(list, (GCompareFunc)payee_glist_name_compare_func); } void payee_load_csv(gchar *filename) { GIOChannel *io; gchar *tmpstr; gint io_stat; const gchar *encoding; encoding = homebank_file_getencoding(filename); io = g_io_channel_new_file(filename, "r", NULL); if(io != NULL) { DB( g_print(" -> encoding should be %s\n", encoding) ); if( encoding != NULL ) { g_io_channel_set_encoding(io, encoding, NULL); } for(;;) { io_stat = g_io_channel_read_line(io, &tmpstr, NULL, NULL, NULL); if( io_stat == G_IO_STATUS_EOF) break; if( io_stat == G_IO_STATUS_NORMAL) { if( tmpstr != NULL) { hb_string_strip_crlf(tmpstr); DB( g_print(" read %s\n", tmpstr) ); if( payee_append_if_new( tmpstr ) ) { GLOBALS->changes_count++; } } g_free(tmpstr); } } g_io_channel_unref (io); } } void payee_save_csv(gchar *filename) { GIOChannel *io; GList *lpay, *list; gchar *outstr; io = g_io_channel_new_file(filename, "w", NULL); if(io != NULL) { lpay = list = payee_glist_sorted(1); while (list != NULL) { Payee *item = list->data; if(item->key != 0) { outstr = g_strdup_printf("%s\n", item->name); g_io_channel_write_chars(io, outstr, -1, NULL, NULL); DB( g_print("%s", outstr) ); g_free(outstr); } list = g_list_next(list); } g_list_free(lpay); g_io_channel_unref (io); } }