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