diff options
author | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2011-11-23 21:25:30 +0000 |
---|---|---|
committer | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2011-11-23 21:25:30 +0000 |
commit | 2ab9600579deca1f8cdd6f86295c8757f291124c (patch) | |
tree | 36bb26b158d93beead3b9c526cc67a896a9386d9 /navit/bookmarks.c | |
parent | 9c0107cd4d8a9368eb1aefc9dd931aa9809c0112 (diff) | |
download | navit-svn-2ab9600579deca1f8cdd6f86295c8757f291124c.tar.gz |
Fix:gui_internal:Do not allow duplicate entries in the list of former destinations. Fixes #955. Thank you sleske.
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@4847 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/bookmarks.c')
-rw-r--r-- | navit/bookmarks.c | 186 |
1 files changed, 114 insertions, 72 deletions
diff --git a/navit/bookmarks.c b/navit/bookmarks.c index 40d1174f..e4e32efb 100644 --- a/navit/bookmarks.c +++ b/navit/bookmarks.c @@ -20,6 +20,7 @@ #include <stdlib.h> #include <glib.h> #include <stdio.h> +#include <errno.h> #include "config.h" #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -315,7 +316,7 @@ bookmarks_store_bookmarks_to_file(struct bookmarks *this_, int limit,int replac if (!g_hash_table_lookup(dedup,fullname)) { g_hash_table_insert(dedup,fullname,fullname); if (item->type == type_bookmark) { - prostr = projection_to_name(projection_mg,NULL); + prostr = projection_to_name(projection_mg); if (fprintf(f,"%s%s%s0x%x %s0x%x type=%s label=\"%s\" path=\"%s\"\n", prostr, *prostr ? ":" : "", item->c.x >= 0 ? "":"-", item->c.x >= 0 ? item->c.x : -item->c.x, @@ -326,7 +327,7 @@ bookmarks_store_bookmarks_to_file(struct bookmarks *this_, int limit,int replac } } if (item->type == type_bookmark_folder) { - prostr = projection_to_name(projection_mg,NULL); + prostr = projection_to_name(projection_mg); if (fprintf(f,"%s%s%s0x%x %s0x%x type=%s label=\"%s\" path=\"%s\"\n", prostr, *prostr ? ":" : "", "", 0, @@ -625,86 +626,127 @@ bookmarks_rename_bookmark(struct bookmarks *this_, const char *oldName, const ch return FALSE; } +struct former_destination{ + enum item_type type; + char* description; + struct coord c; +}; + +static void free_former_destination(struct former_destination* former_destination){ + g_free(former_destination->description); + g_free(former_destination); +} + + +static GList* read_former_destination_map_as_list(struct map *map){ + struct map_rect *mr; + struct item *item; + struct attr attr; + struct former_destination *dest; + GList* list = NULL; + if (map && (mr=map_rect_new(map, NULL))) { + while ((item=map_rect_get_item(mr))) { + if (item->type != type_former_destination) continue; + dest = g_new(struct former_destination, 1); + dest->type=item->type; + item_attr_get(item, attr_label, &attr); + dest->description = g_strdup(attr.u.str); + item_coord_get(item, &(dest->c), 1); + list = g_list_prepend(list, dest); + } + map_rect_destroy(mr); + } + return g_list_reverse(list); +} + static int -bookmarks_shrink(char *bookmarks, int offset) +destination_equal(struct former_destination* dest1, struct former_destination* dest2) +{ + if ((dest1->type == dest2->type) && + (!strcmp(dest1->description, dest2->description)) && + (coord_equal(&(dest1->c), &(dest2->c)))){ + return TRUE; + } + return FALSE; +} + +static GList* +remove_destination_from_list(struct former_destination* dest_to_remove, GList* former_destinations) +{ + GList* curr_el = former_destinations; + GList* prev_el = NULL; + struct former_destination* curr_dest; + + while(curr_el){ + curr_dest = curr_el->data; + if (destination_equal(dest_to_remove, curr_dest)){ + free_former_destination(curr_dest); + curr_el = g_list_remove(curr_el, curr_dest); + }else{ + prev_el = curr_el; + curr_el = g_list_next(curr_el); + } + } + return g_list_first(prev_el); +} + +static void +write_former_destinations(GList* former_destinations, char *former_destination_file, enum projection proj) { - char buffer[4096]; - int count,ioffset=offset,ooffset=0; FILE *f; - if (!offset) - return 1; - f = fopen(bookmarks, "r+"); - if (!f) - return 0; - for (;;) { - fseek(f, ioffset, SEEK_SET); - count=fread(buffer, 1, sizeof(buffer), f); - if (!count) - break; - fseek(f, ooffset, SEEK_SET); - if (fwrite(buffer, count, 1, f) != 1) - return 0; - ioffset+=count; - ooffset+=count; + GList* currdest = NULL; + struct former_destination *dest; + const char* prostr = projection_to_name(proj); + f=fopen(former_destination_file, "w"); + if (f) { + for(currdest = former_destinations; currdest; currdest = g_list_next(currdest)){ + dest = currdest->data; + if (dest->description) + fprintf(f,"type=%s label=\"%s\"\n", item_to_name(dest->type), dest->description); + else + fprintf(f,"type=%s\n", item_to_name(dest->type)); + fprintf(f,"%s%s%s0x%x %s0x%x\n", + prostr, *prostr ? ":" : "", + dest->c.x >= 0 ? "":"-", dest->c.x >= 0 ? dest->c.x : -dest->c.x, + dest->c.y >= 0 ? "":"-", dest->c.y >= 0 ? dest->c.y : -dest->c.y); + + } + fclose(f); + } else { + dbg(0, "Error updating destinations file %s: %s\n", former_destination_file, strerror(errno)); } - fflush(f); - ftruncate(fileno(f),ooffset); -#ifdef HAVE_FSYNC - fsync(fileno(f)); -#endif - fclose(f); - return 1; } /** * @param limit Limits the number of entries in the "backlog". Set to 0 for "infinite" */ void -bookmarks_append_coord(struct bookmarks *this_, char *file, struct pcoord *c, int count, const char *type, const char *description, GHashTable *h, int limit) +bookmarks_append_coord(struct map *former_destination_map, char *former_destination_file, + struct pcoord *c, enum item_type type, const char *description, int limit) { - FILE *f; - const char *prostr; - - if (limit != 0 && (f=fopen(file, "r"))) { - int *offsets=g_alloca(sizeof(int)*limit); - int offset_pos=0; - int offset; - char buffer[4096]; - memset(offsets, 0, sizeof(int)*limit); - for (;;) { - offset=ftell(f); - if (!fgets(buffer, sizeof(buffer), f)) - break; - if (strstr(buffer,"type=")) { - offsets[offset_pos]=offset; - offset_pos=(offset_pos+1)%limit; - } - } - fclose(f); - bookmarks_shrink(file, offsets[offset_pos]); - } - f=fopen(file, "a"); - if (f == NULL) { - dbg(0, "Failed to open destination.txt for writing\n"); - return 0; - } - else if (f != NULL) { - if (c) { - int i; - if (description) - fprintf(f,"type=%s label=\"%s\"\n", type, description); - else - fprintf(f,"type=%s\n", type); - for (i = 0 ; i < count ; i++) { - prostr = projection_to_name(c[i].pro,NULL); - fprintf(f,"%s%s%s0x%x %s0x%x\n", - prostr, *prostr ? ":" : "", - c[i].x >= 0 ? "":"-", c[i].x >= 0 ? c[i].x : -c[i].x, - c[i].y >= 0 ? "":"-", c[i].y >= 0 ? c[i].y : -c[i].y); - } - } else - fprintf(f,"\n"); - } - fclose(f); + struct former_destination *new_dest; + GList* former_destinations = NULL; + GList* former_destinations_shortened = NULL; + int no_of_former_destinations; + + former_destinations = read_former_destination_map_as_list(former_destination_map); + + new_dest = g_new(struct former_destination, 1); + new_dest->type = type; + new_dest->description = g_strdup(description); + new_dest->c.x = c->x; + new_dest->c.y = c->y; + former_destinations = remove_destination_from_list(new_dest, former_destinations); + former_destinations = g_list_append(former_destinations, new_dest); + + no_of_former_destinations = g_list_length(former_destinations); + if (limit > 0 && no_of_former_destinations > limit) + former_destinations_shortened = g_list_nth(former_destinations, no_of_former_destinations - limit); + else + former_destinations_shortened = former_destinations; + + write_former_destinations(former_destinations_shortened, former_destination_file, map_projection(former_destination_map)); + g_list_foreach(former_destinations, (GFunc) free_former_destination, NULL); + g_list_free(former_destinations); } |