/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2014 Maxime DOYEN
+ * Copyright (C) 1995-2019 Maxime DOYEN
*
* This file is part of HomeBank.
*
if(new_item)
{
//duplicate the string
- new_item->name = g_strdup(src_item->name);
+ new_item->name = g_strdup(src_item->name);
+ new_item->fullname = g_strdup(src_item->fullname);
}
return new_item;
}
DB( g_print(" => %d, %s\n", item->key, item->name) );
g_free(item->name);
+ g_free(item->fullname);
g_free(item);
}
}
// insert our 'no category'
item = da_cat_malloc();
+ item->key = 0;
item->name = g_strdup("");
+ item->fullname = g_strdup("");
da_cat_insert(item);
}
}
+static void
+da_cat_max_key_ghfunc(gpointer key, Category *cat, guint32 *max_key)
+{
+ *max_key = MAX(*max_key, cat->key);
+}
/**
- * da_cat_remove_grfunc:
+ * da_cat_get_max_key:
*
- * GRFunc to get the max id
+ * Get the biggest key from the GHashTable
*
- * Return value: TRUE if the key/value must be removed
+ * Return value: the biggest key value
*
*/
+guint32
+da_cat_get_max_key(void)
+{
+guint32 max_key = 0;
+
+ g_hash_table_foreach(GLOBALS->h_cat, (GHFunc)da_cat_max_key_ghfunc, &max_key);
+ return max_key;
+}
+
+
static gboolean
da_cat_remove_grfunc(gpointer key, Category *cat, guint32 *remkey)
{
/**
* da_cat_remove:
*
- * remove a category from the GHashTable
+ * delete a category from the GHashTable
*
- * Return value: TRUE if the key was found and removed
+ * Return value: TRUE if the key was found and deleted
*
*/
guint
da_cat_remove(guint32 key)
{
- DB( g_print("da_cat_remove %d\n", key) );
+ DB( g_print("\nda_cat_remove %d\n", key) );
return g_hash_table_foreach_remove(GLOBALS->h_cat, (GHRFunc)da_cat_remove_grfunc, &key);
}
+
+static void
+da_cat_build_fullname(Category *item)
+{
+Category *parent;
+
+ g_free(item->fullname);
+ if( item->parent == 0 )
+ item->fullname = g_strdup(item->name);
+ else
+ {
+ parent = da_cat_get(item->parent);
+ if( parent != NULL )
+ item->fullname = g_strconcat(parent->name, ":", item->name, NULL);
+ }
+
+ DB( g_print("- updated %d:'%s' fullname='%s'\n", item->key, item->name, item->fullname) );
+
+}
+
+
+static void
+da_cat_rename(Category *item, gchar *newname)
+{
+
+ DB( g_print("- renaming %s' => '%s'\n", item->name, newname) );
+
+ g_free(item->name);
+ item->name = g_strdup(newname);
+ da_cat_build_fullname(item);
+
+ if( item->parent == 0 )
+ {
+ GHashTableIter iter;
+ gpointer value;
+
+ DB( g_print("- updating subcat fullname\n") );
+
+ g_hash_table_iter_init (&iter, GLOBALS->h_cat);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ {
+ Category *subcat = value;
+
+ if( subcat->parent == item->key )
+ da_cat_build_fullname(subcat);
+ }
+
+ }
+}
+
+
/**
* da_cat_insert:
*
{
guint32 *new_key;
- DB( g_print("da_cat_insert\n") );
+ DB( g_print("\nda_cat_insert\n") );
+ DB( g_print("- '%s'\n", item->name) );
+
new_key = g_new0(guint32, 1);
*new_key = item->key;
g_hash_table_insert(GLOBALS->h_cat, new_key, item);
+ da_cat_build_fullname(item);
+
return TRUE;
}
* Return value: TRUE if inserted
*
*/
+// used only to add cat/subcat from ui_category with the 2 inputs
gboolean
da_cat_append(Category *cat)
{
Category *existitem;
-guint32 *new_key;
-gchar *fullname;
- DB( g_print("da_cat_append\n") );
+ DB( g_print("\nda_cat_append\n") );
- if( cat->name != NULL)
+ if( !cat->fullname )
+ da_cat_build_fullname(cat);
+
+ existitem = da_cat_get_by_fullname( cat->fullname );
+ if( existitem == NULL )
{
-
- fullname = da_cat_get_fullname(cat);
- existitem = da_cat_get_by_fullname( fullname );
- g_free(fullname);
-
- if( existitem == NULL )
- {
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
- cat->key = *new_key;
-
- DB( g_print(" -> insert id: %d\n", *new_key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, cat);
- return TRUE;
- }
-
+ cat->key = da_cat_get_max_key() + 1;
+ da_cat_insert(cat);
+ return TRUE;
}
DB( g_print(" -> %s already exist\n", cat->name) );
-
- return FALSE;
-}
-
-
-/**
- * da_cat_max_key_ghfunc:
- *
- * GHFunc for biggest key
- *
- */
-static void
-da_cat_max_key_ghfunc(gpointer key, Category *cat, guint32 *max_key)
-{
-
- *max_key = MAX(*max_key, cat->key);
-}
-
-/**
- * da_cat_get_max_key:
- *
- * Get the biggest key from the GHashTable
- *
- * Return value: the biggest key value
- *
- */
-guint32
-da_cat_get_max_key(void)
-{
-guint32 max_key = 0;
-
- g_hash_table_foreach(GLOBALS->h_cat, (GHFunc)da_cat_max_key_ghfunc, &max_key);
- return max_key;
-}
-
-/**
- * da_cat_get_fullname:
- *
- * Get category the fullname 'xxxx:yyyyy'
- *
- * Return value: the category fullname (free it with g_free)
- *
- */
-gchar *
-da_cat_get_fullname(Category *cat)
-{
-Category *parent;
-
- if( cat->parent == 0)
- return g_strdup(cat->name);
- else
- {
- parent = da_cat_get(cat->parent);
- if( parent )
- {
- return g_strdup_printf("%s:%s", parent->name, cat->name);
- }
- }
-
- return NULL;
-}
-
-
-/**
- * da_cat_name_grfunc:
- *
- * GRFunc to get the max id
- *
- * Return value: TRUE if the key/value pair match our name
- *
- */
-static gboolean
-da_cat_name_grfunc(gpointer key, Category *cat, gchar *name)
-{
-
-// DB( g_print("%s == %s\n", name, cat->name) );
- if( name && cat->name)
- {
- if(!strcasecmp(name, cat->name))
- return TRUE;
- }
return FALSE;
}
-/**
- * da_cat_get_key_by_name:
- *
- * Get a category key by its name
- *
- * Return value: the category key or -1 if not found
- *
- */
-guint32
-da_cat_get_key_by_name(gchar *name)
-{
-Category *cat;
-
- DB( g_print("da_cat_get_key_by_name\n") );
-
- cat = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_name_grfunc, name);
- if( cat == NULL)
- return -1;
-
- return cat->key;
-}
-
-/**
- * da_cat_get_by_name:
- *
- * Get a category structure by its name
- *
- * Return value: Category * or NULL if not found
- *
- */
-Category *
-da_cat_get_by_name(gchar *name)
-{
- DB( g_print("da_cat_get_by_name\n") );
- return g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_name_grfunc, name);
-}
/* fullname i.e. car:refuel */
struct fullcatcontext
{
- guint parent;
+ guint32 parent;
gchar *name;
};
//DB( g_print("'%s' == '%s'\n", ctx->name, item->name) );
if( item->parent == ctx->parent )
{
- if(!strcasecmp(ctx->name, item->name))
- return TRUE;
+ if( ctx->name && item->name )
+ if(!strcasecmp(ctx->name, item->name))
+ return TRUE;
}
return FALSE;
}
-Category *
-da_cat_get_by_fullname(gchar *fullname)
+
+static Category *da_cat_get_by_name_find_internal(guint32 parent, gchar *name)
{
struct fullcatcontext ctx;
-gchar **typestr;
-Category *item = NULL;
- DB( g_print("da_cat_get_by_fullname\n") );
+ ctx.parent = parent;
+ ctx.name = name;
+ DB( g_print("- searching %s %d '%s'\n", (parent == 0) ? "lv1cat" : "lv2cat", parent, name) );
+ return g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
+}
+
- typestr = g_strsplit(fullname, ":", 2);
- if( g_strv_length(typestr) == 2 )
+static gchar **da_cat_get_by_fullname_split_clean(gchar *rawfullname, guint *outlen)
+{
+gchar **partstr = g_strsplit(rawfullname, ":", 2);
+guint len = g_strv_length(partstr);
+gboolean valid = TRUE;
+
+ DB( g_print("- spliclean '%s' - %d parts\n", rawfullname, g_strv_length(partstr)) );
+
+ if( outlen != NULL )
+ *outlen = len;
+
+ if(len >= 1)
{
- ctx.parent = 0;
- ctx.name = typestr[0];
- DB( g_print(" [x:x] try to find the parent : '%s'\n", typestr[0]) );
+ g_strstrip(partstr[0]);
+ if( strlen(partstr[0]) == 0 )
+ valid = FALSE;
- Category *parent = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( parent != NULL )
+ if(len == 2)
{
- ctx.parent = parent->key;
- ctx.name = typestr[1];
+ g_strstrip(partstr[1]);
+ if( strlen(partstr[1]) == 0 )
+ valid = FALSE;
+ }
+ }
- DB( g_print(" [x:x] and searching sub %d '%s'\n", ctx.parent, ctx.name) );
+ if(valid == TRUE)
+ return partstr;
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- }
- }
- else
- {
- ctx.parent = 0;
- ctx.name = fullname;
+ DB( g_print("- is invalid\n") );
- DB( g_print(" [x] try to '%s'\n", fullname) );
+ g_strfreev(partstr);
+ return NULL;
+}
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- }
- g_strfreev(typestr);
+Category *
+da_cat_get_by_fullname(gchar *rawfullname)
+{
+gchar **partstr;
+Category *parent = NULL;
+Category *retval = NULL;
+guint len;
+
+ DB( g_print("\nda_cat_get_by_fullname\n") );
- DB( g_print(" return value %p\n", item) );
+ if( rawfullname )
+ {
+ if( (partstr = da_cat_get_by_fullname_split_clean(rawfullname, &len)) != NULL )
+ {
+ if( len >= 1 )
+ {
+ parent = da_cat_get_by_name_find_internal(0, partstr[0]);
+ retval = parent;
+ }
+
+ if( len == 2 && parent != NULL )
+ {
+ retval = da_cat_get_by_name_find_internal(parent->key, partstr[1]);
+ }
- return item;
+ g_strfreev(partstr);
+ }
+ }
+
+ return retval;
}
*
*/
Category *
-da_cat_append_ifnew_by_fullname(gchar *fullname, gboolean imported)
+da_cat_append_ifnew_by_fullname(gchar *rawfullname)
{
-struct fullcatcontext ctx;
-gchar **typestr;
-Category *newcat, *item, *retval = NULL;
-guint32 *new_key;
-
- DB( g_print("da_cat_append_ifnew_by_fullname\n") );
+gchar **partstr;
+Category *parent = NULL;
+Category *newcat = NULL;
+Category *retval = NULL;
+guint len;
- DB( g_print(" -> fullname: '%s' %d\n", fullname, strlen(fullname)) );
+ DB( g_print("\nda_cat_append_ifnew_by_fullname\n") );
- if( strlen(fullname) > 0 )
+ if( rawfullname )
{
- typestr = g_strsplit(fullname, ":", 2);
-
- /* if we have a subcategory : aaaa:bbb */
- if( g_strv_length(typestr) == 2 )
+ if( (partstr = da_cat_get_by_fullname_split_clean(rawfullname, &len)) != NULL )
{
- ctx.parent = 0;
- ctx.name = typestr[0];
- DB( g_print(" try to find the parent:'%s'\n", typestr[0]) );
-
- Category *parent = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( parent == NULL )
- {
- DB( g_print(" -> not found\n") );
-
- // append a new category
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
-
- newcat = da_cat_malloc();
- newcat->key = *new_key;
- newcat->name = g_strdup(typestr[0]);
- newcat->imported = imported;
-
- parent = newcat;
-
- DB( g_print(" -> insert cat '%s' id: %d\n", newcat->name, newcat->key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, newcat);
- }
-
- ctx.parent = parent->key;
- ctx.name = typestr[1];
- DB( g_print(" searching %d '%s'\n", ctx.parent, ctx.name) );
-
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( item == NULL )
+ if( len >= 1 )
{
- // append a new subcategory
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
-
- newcat = da_cat_malloc();
- newcat->key = *new_key;
- newcat->parent = parent->key;
- newcat->name = g_strdup(typestr[1]);
- newcat->imported = imported;
-
- newcat->flags |= GF_SUB;
-
- DB( g_print(" -> insert subcat '%s' id: %d\n", newcat->name, newcat->key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, newcat);
-
- retval = newcat;
+ parent = da_cat_get_by_name_find_internal(0, partstr[0]);
+ if( parent == NULL )
+ {
+ parent = da_cat_malloc();
+ parent->key = da_cat_get_max_key() + 1;
+ parent->name = g_strdup(partstr[0]);
+ da_cat_insert(parent);
+ }
+ retval = parent;
}
- else
- retval = item;
- }
- /* this a single category : aaaa */
- else
- {
- ctx.parent = 0;
- ctx.name = typestr[0];
- DB( g_print(" searching %d '%s'\n", ctx.parent, ctx.name) );
-
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( item == NULL )
+
+ /* if we have a subcategory - xxx:xxx */
+ if( len == 2 && parent != NULL )
{
- // append a new category
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
-
- newcat = da_cat_malloc();
- newcat->key = *new_key;
- newcat->name = g_strdup(typestr[0]);
- newcat->imported = imported;
-
- DB( g_print(" -> insert cat '%s' id: %d\n", newcat->name, newcat->key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, newcat);
-
+ newcat = da_cat_get_by_name_find_internal(parent->key, partstr[1]);
+ if( newcat == NULL )
+ {
+ newcat = da_cat_malloc();
+ newcat->key = da_cat_get_max_key() + 1;
+ newcat->parent = parent->key;
+ newcat->name = g_strdup(partstr[1]);
+ newcat->flags |= GF_SUB;
+ //#1713413 take parent type into account
+ if(parent->flags & GF_INCOME)
+ newcat->flags |= GF_INCOME;
+ da_cat_insert(newcat);
+ }
retval = newcat;
}
- else
- retval = item;
-
+
+ g_strfreev(partstr);
}
-
- g_strfreev(typestr);
}
return retval;
}
-
/**
* da_cat_get:
*
}
+gchar *da_cat_get_name(Category *item)
+{
+gchar *name = NULL;
+
+ if(item != NULL)
+ {
+ name = item->key == 0 ? _("(no category)") : item->fullname;
+ }
+ return name;
+}
+
+
void da_cat_consistency(Category *item)
{
gboolean isIncome;
+ if((item->flags & GF_SUB) && item->key > 0)
+ {
+ //check for existing parent
+ if( da_cat_get(item->parent) == NULL )
+ {
+ Category *parent = da_cat_append_ifnew_by_fullname ("orphaned");
+
+ item->parent = parent->key;
+ da_cat_build_fullname(item);
+ g_warning("category consistency: fixed missing parent %d", item->parent);
+ }
+ }
+
// ensure type equal for categories and its children
if(!(item->flags & GF_SUB) && item->key > 0)
{
isIncome = (item->flags & GF_INCOME) ? TRUE : FALSE;
- category_change_type(item, isIncome);
+ if( category_change_type(item, isIncome) > 0 )
+ {
+ g_warning("category consistency: fixed type for child");
+ GLOBALS->changes_count++;
+ }
}
- g_strstrip(item->name);
+
+ if( item->name != NULL )
+ g_strstrip(item->name);
+ else
+ {
+ item->name = g_strdup("void");
+ da_cat_build_fullname(item);
+ g_warning("category consistency: fixed null name");
+ GLOBALS->changes_count++;
+ }
+
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-gboolean
-category_is_used(guint32 key)
+
+guint32 category_report_id(guint32 key, gboolean subcat)
{
-GList *lrul, *list;
+guint32 retval = 0;
+
+ if(subcat == FALSE)
+ {
+ Category *catentry = da_cat_get(key);
+ if(catentry)
+ retval = (catentry->flags & GF_SUB) ? catentry->parent : catentry->key;
+ }
+ else
+ {
+ retval = key;
+ }
+ //DB( g_print("- cat '%s' reportid = %d\n", catentry->name, retval) );
+ return retval;
+}
+
+
+void
+category_delete_unused(void)
+{
+GList *lcat, *list;
+
+ lcat = list = g_hash_table_get_values(GLOBALS->h_cat);
+ while (list != NULL)
+ {
+ Category *entry = list->data;
+
+ if(entry->usage_count <= 0 && entry->key > 0)
+ da_cat_remove (entry->key);
+
+ list = g_list_next(list);
+ }
+ g_list_free(lcat);
+}
+
+
+static void
+category_fill_usage_count(guint32 kcat)
+{
+Category *cat = da_cat_get (kcat);
+Category *parent;
+
+ if(cat)
+ {
+ cat->usage_count++;
+ if( cat->parent > 0 )
+ {
+ parent = da_cat_get(cat->parent);
+ if( parent )
+ {
+ parent->usage_count++;
+ }
+ }
+ }
+}
+
+
+void
+category_fill_usage(void)
+{
+GList *lcat;
+GList *lst_acc, *lnk_acc;
+GList *lnk_txn;
+GList *lpay, *lrul, *list;
guint i, nbsplit;
- list = g_list_first(GLOBALS->ope_list);
+ lcat = list = g_hash_table_get_values(GLOBALS->h_cat);
while (list != NULL)
{
- Transaction *entry = list->data;
- if( key == entry->kcat )
- return TRUE;
+ Category *entry = list->data;
+ entry->usage_count = 0;
+ list = g_list_next(list);
+ }
+ g_list_free(lcat);
+
+
+ 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;
- // check split category #1340142
- nbsplit = da_transaction_splits_count(entry);
- for(i=0;i<nbsplit;i++)
+ lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+ while (lnk_txn != NULL)
{
- Split *split = entry->splits[i];
+ Transaction *txn = lnk_txn->data;
- if( key == split->kcat )
- return TRUE;
+ //#1689308 count split as well
+ if( txn->flags & OF_SPLIT )
+ {
+ nbsplit = da_splits_length(txn->splits);
+ for(i=0;i<nbsplit;i++)
+ {
+ Split *split = da_splits_get(txn->splits, i);
+
+ category_fill_usage_count(split->kcat);
+ }
+ }
+ else
+ category_fill_usage_count(txn->kcat);
+
+ lnk_txn = g_list_next(lnk_txn);
}
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
+
+ lpay = list = g_hash_table_get_values(GLOBALS->h_pay);
+ while (list != NULL)
+ {
+ Payee *entry = list->data;
+ category_fill_usage_count(entry->kcat);
list = g_list_next(list);
}
+ g_list_free(lpay);
+
list = g_list_first(GLOBALS->arc_list);
while (list != NULL)
{
Archive *entry = list->data;
- if( key == entry->kcat )
- return TRUE;
+
+ //#1689308 count split as well
+ if( entry->flags & OF_SPLIT )
+ {
+ nbsplit = da_splits_length(entry->splits);
+ for(i=0;i<nbsplit;i++)
+ {
+ Split *split = da_splits_get(entry->splits, i);
+
+ category_fill_usage_count(split->kcat);
+ }
+ }
+ else
+ category_fill_usage_count(entry->kcat);
+
list = g_list_next(list);
}
- //todo: add budget use here
-
+
lrul = list = g_hash_table_get_values(GLOBALS->h_rul);
while (list != NULL)
{
Assign *entry = list->data;
- if( key == entry->kcat)
- return TRUE;
+ category_fill_usage_count(entry->kcat);
list = g_list_next(list);
}
g_list_free(lrul);
- return FALSE;
}
+
void
category_move(guint32 key1, guint32 key2)
{
+GList *lst_acc, *lnk_acc;
+GList *lnk_txn;
GList *lrul, *list;
guint i, nbsplit;
- 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 *entry = list->data;
- if(entry->kcat == key1)
- {
- entry->kcat = key2;
- entry->flags |= OF_CHANGED;
- }
+ Account *acc = lnk_acc->data;
- // move split category #1340142
- nbsplit = da_transaction_splits_count(entry);
- for(i=0;i<nbsplit;i++)
+ lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+ while (lnk_txn != NULL)
{
- Split *split = entry->splits[i];
+ Transaction *txn = lnk_txn->data;
+
+ if(txn->kcat == key1)
+ {
+ txn->kcat = key2;
+ txn->flags |= OF_CHANGED;
+ }
- if( split->kcat == key1 )
+ // move split category #1340142
+ nbsplit = da_splits_length(txn->splits);
+ for(i=0;i<nbsplit;i++)
{
- split->kcat = key2;
- entry->flags |= OF_CHANGED;
+ Split *split = da_splits_get(txn->splits, i);
+
+ if( split->kcat == key1 )
+ {
+ split->kcat = key2;
+ txn->flags |= OF_CHANGED;
+ }
}
- }
- list = g_list_next(list);
+ lnk_txn = g_list_next(lnk_txn);
+ }
+
+ lnk_acc = g_list_next(lnk_acc);
}
+ g_list_free(lst_acc);
+
list = g_list_first(GLOBALS->arc_list);
while (list != NULL)
gchar *stripname;
gboolean retval;
- DB( g_print("(category) rename\n") );
+ DB( g_print("\n(category) rename\n") );
stripname = g_strdup(newname);
g_strstrip(stripname);
if( existitem != NULL && existitem->key != item->key)
{
- DB( g_print("error, same name already exist with other key %d <> %d\n",existitem->key, item->key) );
+ DB( g_print("- error, same name already exist with other key %d <> %d\n",existitem->key, item->key) );
retval = FALSE;
}
else
{
- DB( g_print(" -renaming\n") );
+ DB( g_print("- renaming\n") );
- g_free(item->name);
- item->name = g_strdup(stripname);
+ da_cat_rename (item, stripname);
retval = TRUE;
}
}
-static gint category_glist_name_compare_func(Category *c1, Category *c2)
+static gint
+category_glist_name_compare_func(Category *c1, Category *c2)
{
-gchar *name1, *name2;
gint retval = 0;
if( c1 != NULL && c2 != NULL )
{
- name1 = da_cat_get_fullname(c1);
- name2 = da_cat_get_fullname(c2);
-
- retval = hb_string_utf8_compare(name1, name2);
-
- g_free(name2);
- g_free(name1);
+ retval = hb_string_utf8_compare(c1->fullname, c2->fullname);
}
return retval;
}
-static gint category_glist_key_compare_func(Category *a, Category *b)
+static gint
+category_glist_key_compare_func(Category *a, Category *b)
{
gint ka, kb, retval = 0;
}
-GList *category_glist_sorted(gint column)
+GList *
+category_glist_sorted(gint column)
{
GList *list = g_hash_table_get_values(GLOBALS->h_cat);
const gchar *encoding;
encoding = homebank_file_getencoding(filename);
-
- DB( g_print(" -> encoding should be %s\n", encoding) );
-
+ DB( g_print(" -> encoding should be %s\n", encoding) );
retval = TRUE;
*error = NULL;
io = g_io_channel_new_file(filename, "r", NULL);
if(io != NULL)
{
-
if( encoding != NULL )
{
g_io_channel_set_encoding(io, encoding, NULL);
if( tmpstr != NULL )
{
DB( g_print(" + strip %s\n", tmpstr) );
-
hb_string_strip_crlf(tmpstr);
DB( g_print(" + split\n") );
-
str_array = g_strsplit (tmpstr, ";", 3);
// type; sign; name
if( g_strv_length (str_array) != 3 )
{
- *error = _("invalid csv format");
+ *error = _("invalid CSV format");
retval = FALSE;
DB( g_print(" + error %s\n", *error) );
}
fullcatname = g_strdup_printf("%s:%s", lastcatname, str_array[2]);
}
- DB( g_print(" + fullcatname %s\n", fullcatname) );
-
- item = da_cat_append_ifnew_by_fullname(fullcatname, FALSE);
-
+ item = da_cat_append_ifnew_by_fullname(fullcatname);
DB( g_print(" + item %p\n", item) );
if( item != NULL)
g_strfreev (str_array);
}
}
-
}
g_free(tmpstr);
-
}
g_io_channel_unref (io);
-
-
}
g_free(lastcatname);
}
-
gboolean
category_save_csv(gchar *filename, gchar **error)
{
gchar *outstr;
GList *lcat, *list;
-
io = g_io_channel_new_file(filename, "w", NULL);
if(io != NULL)
{
g_io_channel_unref (io);
}
-
return retval;
}
-gint category_change_type(Category *item, gboolean isIncome)
+gint
+category_type_get(Category *item)
+{
+ if( (item->flags & (GF_INCOME)) )
+ return 1;
+ return -1;
+}
+
+
+gchar
+category_get_type_char(Category *item)
+{
+ return (item->flags & GF_INCOME) ? '+' : '-';
+}
+
+
+static gint
+category_change_type_eval(Category *item, gboolean isIncome)
{
-gint changes = 1;
+ if( (item->flags & (GF_INCOME)) && !isIncome )
+ return 1;
+ return 0;
+}
+
+
+gint
+category_change_type(Category *item, gboolean isIncome)
+{
+gint changes = 0;
GList *lcat, *list;
- item->flags &= ~(GF_INCOME); //remove flag
+ changes += category_change_type_eval(item, isIncome);
+
+ item->flags &= ~(GF_INCOME); //delete flag
if(isIncome == TRUE)
item->flags |= GF_INCOME;
if(child->parent == item->key)
{
- child->flags &= ~(GF_INCOME); //remove flag
+ changes += category_change_type_eval(child, isIncome);
+ child->flags &= ~(GF_INCOME); //delete flag
if(isIncome == TRUE)
child->flags |= GF_INCOME;
- changes++;
}
list = g_list_next(list);
}
}
-
-
-
/**
* category_find_preset:
*
* Return value: a pathname to the file or NULL
*
*/
-gchar *category_find_preset(gchar **lang)
+gchar *
+category_find_preset(gchar **lang)
{
gchar **langs;
gchar *filename;
return NULL;
}
-