]> Dogcows Code - chaz/homebank/blob - src/hb-tag.c
Merge branch 'master' into ext-perl
[chaz/homebank] / src / hb-tag.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 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-tag.h"
22
23 #include "ext.h"
24 #include "refcount.h"
25
26 #define MYDEBUG 0
27
28 #if MYDEBUG
29 #define DB(x) (x);
30 #else
31 #define DB(x);
32 #endif
33
34 /* our global datas */
35 extern struct HomeBank *GLOBALS;
36
37
38 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
39
40 void da_tag_free(Tag *item)
41 {
42 DB( g_print("da_tag_free\n") );
43 if(rc_unref(item))
44 {
45 DB( g_print(" => %d, %s\n", item->key, item->name) );
46
47 g_free(item->name);
48 rc_free(item);
49 }
50 }
51
52
53 Tag *da_tag_malloc(void)
54 {
55 DB( g_print("da_tag_malloc\n") );
56 return rc_alloc(sizeof(Tag));
57 }
58
59
60 void da_tag_destroy(void)
61 {
62 DB( g_print("da_tag_destroy\n") );
63 g_hash_table_destroy(GLOBALS->h_tag);
64 }
65
66
67 void da_tag_new(void)
68 {
69 DB( g_print("da_tag_new\n") );
70 GLOBALS->h_tag = g_hash_table_new_full(g_int_hash, g_int_equal, (GDestroyNotify)g_free, (GDestroyNotify)da_tag_free);
71 }
72
73
74 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
75 static void da_tag_max_key_ghfunc(gpointer key, Tag *item, guint32 *max_key)
76 {
77 *max_key = MAX(*max_key, item->key);
78 }
79
80 static gboolean da_tag_name_grfunc(gpointer key, Tag *item, gchar *name)
81 {
82 if( name && item->name )
83 {
84 if(!strcasecmp(name, item->name))
85 return TRUE;
86 }
87 return FALSE;
88 }
89
90 /**
91 * da_tag_length:
92 *
93 * Return value: the number of elements
94 */
95 guint da_tag_length(void)
96 {
97 return g_hash_table_size(GLOBALS->h_tag);
98 }
99
100 /**
101 * da_tag_remove:
102 *
103 * delete an tag from the GHashTable
104 *
105 * Return value: TRUE if the key was found and deleted
106 *
107 */
108 gboolean da_tag_remove(guint32 key)
109 {
110 DB( g_print("da_tag_remove %d\n", key) );
111
112 return g_hash_table_remove(GLOBALS->h_tag, &key);
113 }
114
115 /**
116 * da_tag_insert:
117 *
118 * insert an tag into the GHashTable
119 *
120 * Return value: TRUE if inserted
121 *
122 */
123 gboolean da_tag_insert(Tag *item)
124 {
125 guint32 *new_key;
126
127 DB( g_print("da_tag_insert\n") );
128
129 new_key = g_new0(guint32, 1);
130 *new_key = item->key;
131 g_hash_table_insert(GLOBALS->h_tag, new_key, item);
132
133 return TRUE;
134 }
135
136
137 /**
138 * da_tag_append:
139 *
140 * append a new tag into the GHashTable
141 *
142 * Return value: TRUE if inserted
143 *
144 */
145 gboolean da_tag_append(Tag *item)
146 {
147 Tag *existitem;
148 guint32 *new_key;
149
150 DB( g_print("da_tag_append\n") );
151
152 if( item->name != NULL )
153 {
154 /* ensure no duplicate */
155 //g_strstrip(item->name);
156 existitem = da_tag_get_by_name( item->name );
157 if( existitem == NULL )
158 {
159 new_key = g_new0(guint32, 1);
160 *new_key = da_tag_get_max_key() + 1;
161 item->key = *new_key;
162
163 DB( g_print(" -> append id: %d\n", *new_key) );
164
165 g_hash_table_insert(GLOBALS->h_tag, new_key, item);
166 return TRUE;
167 }
168 }
169
170 DB( g_print(" -> %s already exist: %d\n", item->name, item->key) );
171
172 return FALSE;
173 }
174
175 /**
176 * da_tag_get_max_key:
177 *
178 * Get the biggest key from the GHashTable
179 *
180 * Return value: the biggest key value
181 *
182 */
183 guint32 da_tag_get_max_key(void)
184 {
185 guint32 max_key = 0;
186
187 g_hash_table_foreach(GLOBALS->h_tag, (GHFunc)da_tag_max_key_ghfunc, &max_key);
188 return max_key;
189 }
190
191
192 /**
193 * da_tag_get_by_name:
194 *
195 * Get an tag structure by its name
196 *
197 * Return value: Tag * or NULL if not found
198 *
199 */
200 Tag *da_tag_get_by_name(gchar *name)
201 {
202 DB( g_print("da_tag_get_by_name\n") );
203
204 return g_hash_table_find(GLOBALS->h_tag, (GHRFunc)da_tag_name_grfunc, name);
205 }
206
207
208
209 /**
210 * da_tag_get:
211 *
212 * Get an tag structure by key
213 *
214 * Return value: Tag * or NULL if not found
215 *
216 */
217 Tag *da_tag_get(guint32 key)
218 {
219 DB( g_print("da_tag_get_tag\n") );
220
221 return g_hash_table_lookup(GLOBALS->h_tag, &key);
222 }
223
224
225 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
226
227 guint
228 tags_count(guint32 *tags)
229 {
230 guint count = 0;
231
232 DB( g_print("\n[tags] count\n") );
233
234 if( tags == NULL )
235 return 0;
236
237 while(*tags++ != 0 && count < 32)
238 count++;
239
240 return count;
241 }
242
243
244 guint32 *tags_clone(guint32 *tags)
245 {
246 guint32 *newtags = NULL;
247 guint count;
248
249 count = tags_count(tags);
250 if(count > 0)
251 {
252 //1501962: we must also copy the final 0
253 newtags = g_memdup(tags, (count+1)*sizeof(guint32));
254 }
255
256 return newtags;
257 }
258
259
260 static gboolean
261 tags_key_exists(guint32 *tags, guint32 key)
262 {
263 guint count = 0;
264 while(*tags != 0 && count < 32)
265 {
266 if( *tags == key )
267 return TRUE;
268 tags++;
269 count++;
270 }
271 return FALSE;
272 }
273
274
275 guint32 *
276 tags_parse(const gchar *tagstring)
277 {
278 gchar **str_array;
279 guint32 *tags = NULL;
280 guint32 *ptags;
281 guint count, i;
282 Tag *tag;
283
284 DB( g_print("\n[tags] parse\n") );
285
286 if( tagstring )
287 {
288 str_array = g_strsplit (tagstring, " ", 0);
289 count = g_strv_length( str_array );
290 DB( g_print("- %d tags '%s'\n", count, tagstring) );
291 if( count > 0 )
292 {
293 tags = g_new0(guint32, count + 1);
294 ptags = tags;
295 for(i=0;i<count;i++)
296 {
297 //5.2.3 fixed empty tag
298 if( strlen(str_array[i]) == 0 )
299 continue;
300
301 DB( g_print("- %d search '%s'\n", i, str_array[i]) );
302 tag = da_tag_get_by_name(str_array[i]);
303 if(tag == NULL)
304 {
305 Tag *newtag = da_tag_malloc();
306
307 newtag->name = g_strdup(str_array[i]);
308 da_tag_append(newtag);
309 tag = da_tag_get_by_name(str_array[i]);
310 }
311 DB( g_print("- array add %d '%s'\n", tag->key, tag->name) );
312
313 //5.3 fixed duplicate tag in same tags
314 if( tags_key_exists(tags, tag->key) == FALSE )
315 *ptags++ = tag->key;
316 }
317 *ptags = 0;
318 }
319
320 g_strfreev (str_array);
321 }
322 return tags;
323 }
324
325
326
327 gchar *
328 tags_tostring(guint32 *tags)
329 {
330 guint count, i;
331 gchar **str_array, **tptr;
332 gchar *tagstring;
333 Tag *tag;
334
335 DB( g_print("\n[tags] tostring\n") );
336 if( tags == NULL )
337 {
338 return NULL;
339 }
340 else
341 {
342 count = tags_count(tags);
343 str_array = g_new0(gchar*, count+1);
344 tptr = str_array;
345 for(i=0;i<count;i++)
346 {
347 tag = da_tag_get(tags[i]);
348 if( tag )
349 {
350 *tptr++ = tag->name;
351 }
352 }
353 *tptr = NULL;
354
355 tagstring = g_strjoinv(" ", str_array);
356 g_free (str_array);
357 }
358 return tagstring;
359 }
360
361
362 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
363
364
365 #if MYDEBUG
366
367 static void
368 da_tag_debug_list_ghfunc(gpointer key, gpointer value, gpointer user_data)
369 {
370 guint32 *id = key;
371 Tag *item = value;
372
373 DB( g_print(" %d :: %s\n", *id, item->name) );
374
375 }
376
377 static void
378 da_tag_debug_list(void)
379 {
380
381 DB( g_print("\n** debug **\n") );
382
383 g_hash_table_foreach(GLOBALS->h_tag, da_tag_debug_list_ghfunc, NULL);
384
385 DB( g_print("\n** end debug **\n") );
386
387 }
388
389 #endif
390
391 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
392
393
394 gboolean
395 tag_rename(Tag *item, const gchar *newname)
396 {
397 Tag *existitem;
398 gchar *stripname;
399 gboolean retval = FALSE;
400
401 stripname = g_strdup(newname);
402 g_strstrip(stripname);
403
404 existitem = da_tag_get_by_name(stripname);
405
406 if( existitem != NULL && existitem->key != item->key)
407 {
408 DB( g_print("- error, same name already exist with other key %d <> %d\n",existitem->key, item->key) );
409 g_free(stripname);
410 }
411 else
412 {
413 DB( g_print("- renaming\n") );
414 g_free(item->name);
415 item->name = stripname;
416 retval = TRUE;
417 }
418
419 return retval;
420 }
421
422
423
424 static gint
425 tag_glist_name_compare_func(Tag *a, Tag *b)
426 {
427 return hb_string_utf8_compare(a->name, b->name);
428 }
429
430
431 static gint
432 tag_glist_key_compare_func(Tag *a, Tag *b)
433 {
434 return a->key - b->key;
435 }
436
437
438 GList *tag_glist_sorted(gint column)
439 {
440 GList *list = g_hash_table_get_values(GLOBALS->h_tag);
441
442 if(column == 0)
443 return g_list_sort(list, (GCompareFunc)tag_glist_key_compare_func);
444 else
445 return g_list_sort(list, (GCompareFunc)tag_glist_name_compare_func);
446 }
447
448
449
450
451
This page took 0.050759 seconds and 4 git commands to generate.