1 /*  HomeBank -- Free, easy, personal accounting for everyone.
2  *  Copyright (C) 1995-2021 Maxime DOYEN
3  *
4  *  This file is part of HomeBank.
5  *
6  *  HomeBank is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  HomeBank is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "homebank.h"
21 #include "hb-group.h"
22 
23 #define MYDEBUG 0
24 
25 #if MYDEBUG
26 #define DB(x) (x);
27 #else
28 #define DB(x);
29 #endif
30 
31 /* our global datas */
32 extern struct HomeBank *GLOBALS;
33 
34 
35 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
36 
da_grp_free(Group * item)37 void da_grp_free(Group *item)
38 {
39 	DB( g_print("da_group_free\n") );
40 	if(item != NULL)
41 	{
42 		DB( g_print(" => %d, %s\n", item->key, item->name) );
43 
44 		g_free(item->name);
45 		g_free(item);
46 	}
47 }
48 
49 
da_grp_malloc(void)50 Group *da_grp_malloc(void)
51 {
52 	DB( g_print("da_group_malloc\n") );
53 	return g_malloc0(sizeof(Group));
54 }
55 
56 
da_grp_destroy(void)57 void da_grp_destroy(void)
58 {
59 	DB( g_print("da_group_destroy\n") );
60 	g_hash_table_destroy(GLOBALS->h_grp);
61 }
62 
63 
da_grp_new(void)64 void da_grp_new(void)
65 {
66 Group *item;
67 
68 	DB( g_print("da_group_new\n") );
69 	GLOBALS->h_grp = g_hash_table_new_full(g_int_hash, g_int_equal, (GDestroyNotify)g_free, (GDestroyNotify)da_grp_free);
70 
71 	// insert our 'no group'
72 	item = da_grp_malloc();
73 	item->name = g_strdup("");
74 	da_grp_insert(item);
75 }
76 
77 
78 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
79 
80 
81 guint
da_grp_length(void)82 da_grp_length(void)
83 {
84 	return g_hash_table_size(GLOBALS->h_grp);
85 }
86 
87 
88 static void
da_grp_max_key_ghfunc(gpointer key,Group * item,guint32 * max_key)89 da_grp_max_key_ghfunc(gpointer key, Group *item, guint32 *max_key)
90 {
91 	*max_key = MAX(*max_key, item->key);
92 }
93 
94 guint32
da_grp_get_max_key(void)95 da_grp_get_max_key(void)
96 {
97 guint32 max_key = 0;
98 
99 	g_hash_table_foreach(GLOBALS->h_grp, (GHFunc)da_grp_max_key_ghfunc, &max_key);
100 	return max_key;
101 }
102 
103 
104 gboolean
da_grp_remove(guint32 key)105 da_grp_remove(guint32 key)
106 {
107 	DB( g_print("da_grp_remove %d\n", key) );
108 
109 	return g_hash_table_remove(GLOBALS->h_grp, &key);
110 }
111 
112 
113 gboolean
da_grp_insert(Group * item)114 da_grp_insert(Group *item)
115 {
116 guint32 *new_key;
117 
118 	DB( g_print("da_grp_insert\n") );
119 
120 	new_key = g_new0(guint32, 1);
121 	*new_key = item->key;
122 	g_hash_table_insert(GLOBALS->h_grp, new_key, item);
123 
124 	return TRUE;
125 }
126 
127 
128 gboolean
da_grp_append(Group * item)129 da_grp_append(Group *item)
130 {
131 Group *existitem;
132 
133 	DB( g_print("da_grp_append\n") );
134 
135 	existitem = da_grp_get_by_name( item->name);
136 	if( existitem == NULL )
137 	{
138 		item->key = da_grp_get_max_key() + 1;
139 		da_grp_insert(item);
140 		return TRUE;
141 	}
142 
143 	DB( g_print(" -> %s already exist: %d\n", item->name, item->key) );
144 
145 	return FALSE;
146 }
147 
148 
149 Group *
da_grp_get_by_name(gchar * rawname)150 da_grp_get_by_name(gchar *rawname)
151 {
152 Group *retval = NULL;
153 gchar *stripname;
154 GHashTableIter iter;
155 gpointer key, value;
156 
157 	DB( g_print("da_grp_get_by_name\n") );
158 
159 	if( rawname )
160 	{
161 		stripname = g_strdup(rawname);
162 		g_strstrip(stripname);
163 		if( strlen(stripname) > 0 )
164 		{
165 			g_hash_table_iter_init (&iter, GLOBALS->h_grp);
166 			while (g_hash_table_iter_next (&iter, &key, &value))
167 			{
168 			Group *item = value;
169 
170 				//if( item->type != type )
171 				//	continue;
172 
173 				if( stripname && item->name )
174 				{
175 					if(!strcasecmp(stripname, item->name))
176 					{
177 						retval = item;
178 						break;
179 					}
180 				}
181 			}
182 		}
183 		g_free(stripname);
184 	}
185 
186 	return retval;
187 }
188 
189 
190 Group *
da_grp_get(guint32 key)191 da_grp_get(guint32 key)
192 {
193 	//DB( g_print("da_grp_get\n") );
194 
195 	return g_hash_table_lookup(GLOBALS->h_grp, &key);
196 }
197 
198 
199 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
200 
201 
group_delete_unused(void)202 void group_delete_unused(void)
203 {
204 guint32 i, max_key;
205 gboolean *used;
206 GList *lst_acc, *lnk_acc;
207 
208 	max_key = da_grp_get_max_key();
209 	used = g_malloc0((max_key + 1) * sizeof(gboolean));
210 	if( used )
211 	{
212 		// collect usage
213 		lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
214 		lnk_acc = g_list_first(lst_acc);
215 		while (lnk_acc != NULL)
216 		{
217 		Account *acc = lnk_acc->data;
218 
219 			if(acc)
220 				used[acc->kgrp] = TRUE;
221 
222 			lnk_acc = g_list_next(lnk_acc);
223 		}
224 		g_list_free(lst_acc);
225 
226 		//clean unused
227 		for(i=1;i<max_key;i++)
228 		{
229 			if( used[i] == 0 )
230 			{
231 			Group *grp = da_grp_get(i);
232 
233 				if(grp)
234 				{
235 					DB( g_print(" - '%s' is unused, removing\n", grp->name) );
236 					da_grp_remove(i);
237 				}
238 			}
239 		}
240 
241 		g_free(used);
242 	}
243 }
244 
245 
246 static gint
group_glist_name_compare_func(Group * a,Group * b)247 group_glist_name_compare_func(Group *a, Group *b)
248 {
249 	return hb_string_utf8_compare(a->name, b->name);
250 }
251 
252 
253 static gint
group_glist_key_compare_func(Group * a,Group * b)254 group_glist_key_compare_func(Group *a, Group *b)
255 {
256 	return a->key - b->key;
257 }
258 
259 
group_glist_sorted(gint column)260 GList *group_glist_sorted(gint column)
261 {
262 GList *list = g_hash_table_get_values(GLOBALS->h_grp);
263 
264 	if(column == 0)
265 		return g_list_sort(list, (GCompareFunc)group_glist_key_compare_func);
266 	else
267 		return g_list_sort(list, (GCompareFunc)group_glist_name_compare_func);
268 }
269 
270 
271 
272 
273