summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-11-23 21:25:30 +0000
committermdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-11-23 21:25:30 +0000
commit669edfcd220a3bd8e69e352578a8fc369477ac08 (patch)
tree36bb26b158d93beead3b9c526cc67a896a9386d9
parent10608d12fc25cae72f8ad3ce67f2310a70988159 (diff)
downloadnavit-669edfcd220a3bd8e69e352578a8fc369477ac08.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
-rw-r--r--navit/bookmarks.c186
-rw-r--r--navit/bookmarks.h2
-rw-r--r--navit/coord.c2
-rw-r--r--navit/navit.c6
-rw-r--r--navit/navit.h2
-rw-r--r--navit/projection.c2
-rw-r--r--navit/projection.h2
7 files changed, 122 insertions, 80 deletions
diff --git a/navit/bookmarks.c b/navit/bookmarks.c
index 40d1174f4..e4e32efba 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);
}
diff --git a/navit/bookmarks.h b/navit/bookmarks.h
index cee28e7db..5630e5151 100644
--- a/navit/bookmarks.h
+++ b/navit/bookmarks.h
@@ -53,7 +53,7 @@ char* bookmarks_get_destination_file(gboolean create);
void bookmarks_set_center_from_file(struct bookmarks *this_, char *file);
char* bookmarks_get_center_file(gboolean create);
void bookmarks_write_center_to_file(struct bookmarks *this_, char *file);
-void bookmarks_append_coord(struct bookmarks *this_, char *file, struct pcoord *c, int count, const char *type, const char *description, GHashTable *h, int limit);
+void bookmarks_append_coord(struct map *former_destination_map, char *file, struct pcoord *c, enum item_type type, const char *description, int limit);
/* end of prototypes */
#ifdef __cplusplus
diff --git a/navit/coord.c b/navit/coord.c
index 39cd513e9..58fa4b107 100644
--- a/navit/coord.c
+++ b/navit/coord.c
@@ -303,7 +303,7 @@ coord_print(enum projection pro, struct coord *c, FILE *out) {
y = c->y;
}
fprintf( out, "%s: %s0x%x %s0x%x\n",
- projection_to_name( pro , NULL),
+ projection_to_name( pro ),
sign_x, x,
sign_y, y );
return;
diff --git a/navit/navit.c b/navit/navit.c
index baddb777a..452b84c6e 100644
--- a/navit/navit.c
+++ b/navit/navit.c
@@ -1480,7 +1480,7 @@ navit_set_destination(struct navit *this_, struct pcoord *c, const char *descrip
} else
this_->destination_valid=0;
destination_file = bookmarks_get_destination_file(TRUE);
- bookmarks_append_coord(this_->bookmarks, destination_file, c, 1, "former_destination", description, NULL, this_->recentdest_count);
+ bookmarks_append_coord(this_->former_destination, destination_file, c, type_former_destination, description, this_->recentdest_count);
g_free(destination_file);
callback_list_call_attr_0(this_->attr_cbl, attr_destination);
if (this_->route) {
@@ -1509,7 +1509,7 @@ navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const c
} else
this_->destination_valid=0;
destination_file = bookmarks_get_destination_file(TRUE);
- bookmarks_append_coord(this_->bookmarks, destination_file, c, count, "former_itinerary", description, NULL, this_->recentdest_count);
+ bookmarks_append_coord(this_->former_destination, destination_file, c, type_former_itinerary, description, this_->recentdest_count);
g_free(destination_file);
callback_list_call_attr_0(this_->attr_cbl, attr_destination);
if (this_->route) {
@@ -2841,7 +2841,7 @@ navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv)
route_remove_waypoint(this_->route);
count=route_get_destinations(this_->route, pc, 16);
destination_file = bookmarks_get_destination_file(TRUE);
- bookmarks_append_coord(this_->bookmarks, destination_file, pc, count, "former_itinerary_part", NULL, NULL, this_->recentdest_count);
+ bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, NULL, this_->recentdest_count);
break;
case 2:
navit_set_destination(this_, NULL, NULL, 0);
diff --git a/navit/navit.h b/navit/navit.h
index 9b3630ba6..3bb5f5e1b 100644
--- a/navit/navit.h
+++ b/navit/navit.h
@@ -79,7 +79,7 @@ GList *navit_get_vehicleprofiles(struct navit *this_);
void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async);
void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async);
int navit_check_route(struct navit *this_);
-struct map* read_former_destinations_from_file();
+struct map* read_former_destinations_from_file(void);
void navit_textfile_debug_log(struct navit *this_, const char *fmt, ...);
void navit_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *fmt, ...);
int navit_speech_estimate(struct navit *this_, char *str);
diff --git a/navit/projection.c b/navit/projection.c
index a89ca3814..79f58026d 100644
--- a/navit/projection.c
+++ b/navit/projection.c
@@ -60,7 +60,7 @@ projection_from_name(const char *name, struct coord *offset)
}
char *
-projection_to_name(enum projection proj, struct coord *offset)
+projection_to_name(enum projection proj)
{
int i;
diff --git a/navit/projection.h b/navit/projection.h
index 449c28fb0..6dd78d17e 100644
--- a/navit/projection.h
+++ b/navit/projection.h
@@ -30,7 +30,7 @@ enum map_datum {
struct coord;
enum projection projection_from_name(const char *name, struct coord *offset);
-char * projection_to_name(enum projection proj, struct coord *offset);
+char * projection_to_name(enum projection proj);
#endif