summaryrefslogtreecommitdiff
path: root/navit/bookmarks.c
diff options
context:
space:
mode:
authormdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2012-11-09 22:09:37 +0000
committermdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2012-11-09 22:09:37 +0000
commit6f03504eeda8799fa1098c2f50a7570e1ed90e2a (patch)
tree0f8c91fbd5628d0a7791dfd8cb7713c084278364 /navit/bookmarks.c
parent8f2a5742605d56049aa8ca371877b30f19bae44b (diff)
downloadnavit-6f03504eeda8799fa1098c2f50a7570e1ed90e2a.tar.gz
Add:core:Better waypoints handling, see #1040 |Based on ideas & patches from pini and antiram
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5264 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/bookmarks.c')
-rw-r--r--navit/bookmarks.c117
1 files changed, 85 insertions, 32 deletions
diff --git a/navit/bookmarks.c b/navit/bookmarks.c
index bcad314e8..6c1c79665 100644
--- a/navit/bookmarks.c
+++ b/navit/bookmarks.c
@@ -645,29 +645,40 @@ bookmarks_rename_bookmark(struct bookmarks *this_, const char *oldName, const ch
struct former_destination{
enum item_type type;
char* description;
- struct coord c;
+ GList* c;
};
static void free_former_destination(struct former_destination* former_destination){
g_free(former_destination->description);
+ g_list_foreach(former_destination->c, (GFunc)g_free, NULL);
+ g_list_free(former_destination->c);
g_free(former_destination);
}
-
+/*
+ * Doesn't read any items besides former_destination. So active waypoints items of type former_itinerary and former_itinerary_part are skipped.
+ */
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;
+ struct coord c;
+ int more;
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 = g_new0(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);
+ more = item_coord_get(item, &c, 1);
+ while (more) {
+ dest->c = g_list_append(dest->c, g_new(struct coord, 1));
+ *(struct coord *)g_list_last(dest->c)->data = c;
+ more = item_coord_get(item, &c, 1);
+ }
list = g_list_prepend(list, dest);
}
map_rect_destroy(mr);
@@ -676,41 +687,57 @@ static GList* read_former_destination_map_as_list(struct map *map){
}
static int
-destination_equal(struct former_destination* dest1, struct former_destination* dest2)
+destination_equal(struct former_destination* dest1, struct former_destination* dest2, int ignore_descriptions)
{
if ((dest1->type == dest2->type) &&
- (!strcmp(dest1->description, dest2->description)) &&
- (coord_equal(&(dest1->c), &(dest2->c)))){
+ (ignore_descriptions || !strcmp(dest1->description, dest2->description)) &&
+ (coord_equal((struct coord *)g_list_last(dest1->c)->data, (struct coord *)g_list_last(dest2->c)->data))){
return TRUE;
}
return FALSE;
}
+/*
+ * Find destination in given GList. If remove_found is non-zero, any matching items are removed and new beginning of the list is returned.
+ * If remove_found is zero, last matching item is returned. In the latter case, description is ignored and can be NULL.
+ */
static GList*
-remove_destination_from_list(struct former_destination* dest_to_remove, GList* former_destinations)
+find_destination_in_list(struct former_destination* dest_to_remove, GList* former_destinations, int remove_found)
{
GList* curr_el = former_destinations;
GList* prev_el = NULL;
+ GList* found_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);
+ if (destination_equal(dest_to_remove, curr_dest, remove_found?0:1)) {
+ if(remove_found) {
+ free_former_destination(curr_dest);
+ curr_el = g_list_remove(curr_el, curr_dest);
+ continue;
+ } else {
+ found_el=curr_el;
+ }
}
+ prev_el = curr_el;
+ curr_el = g_list_next(curr_el);
+
}
- return g_list_first(prev_el);
+ if(remove_found)
+ return g_list_first(prev_el);
+ else
+ return found_el;
+
}
+
static void
write_former_destinations(GList* former_destinations, char *former_destination_file, enum projection proj)
{
FILE *f;
GList* currdest = NULL;
+ GList* c_list = NULL;
+ struct coord *c;
struct former_destination *dest;
const char* prostr = projection_to_name(proj);
f=fopen(former_destination_file, "w");
@@ -721,40 +748,66 @@ write_former_destinations(GList* former_destinations, char *former_destination_f
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);
-
+ c_list = dest->c;
+ do {
+ c = (struct coord *)c_list->data;
+ fprintf(f,"%s%s%s0x%x %s0x%x\n",
+ prostr, *prostr ? ":" : "",
+ c->x >= 0 ? "":"-", c->x >= 0 ? c->x : -c->x,
+ c->y >= 0 ? "":"-", c->y >= 0 ? c->y : -c->y);
+ c_list = g_list_next(c_list);
+ } while (c_list);
}
fclose(f);
} else {
dbg(0, "Error updating destinations file %s: %s\n", former_destination_file, strerror(errno));
}
}
-
/**
+ * Append recent destination(s) item to the former destionations map.
+ * @param former_destination_map
+ * @param former_destination_file
+ * @param c coordinates of item point(s). Can be set to NULL when navigation is stopped to remove type_former_itinerary and
+ * type_former_itinerary_part items from the file.
+ * @param count number of points in this item. Set to 0 when navigation is stopped.
+ * @param type type_former_destination, type_former_itinerary and type_former_itinerary_part are meaningful here
+ * @param description character string used to identify this destination. If NULL, most recent waypoint at these coordinates will be used
+ * to get description.
* @param limit Limits the number of entries in the "backlog". Set to 0 for "infinite"
*/
void
-bookmarks_append_coord(struct map *former_destination_map, char *former_destination_file,
- struct pcoord *c, enum item_type type, const char *description, int limit)
+bookmarks_append_destinations(struct map *former_destination_map, char *former_destination_file,
+ struct pcoord *c, int count, enum item_type type, const char *description, int limit)
{
- struct former_destination *new_dest;
+ struct former_destination *new_dest=NULL;
GList* former_destinations = NULL;
GList* former_destinations_shortened = NULL;
+ struct coord* c_dup;
int no_of_former_destinations;
+ int i;
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?description:_("Map Point"));
- 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);
+ if(c && count>0) {
+ GList *older;
+ struct coord ctmp;
+ new_dest = g_new0(struct former_destination, 1);
+ new_dest->type = type;
+ for (i=0; i<count; i++) {
+ ctmp.x=c[i].x;
+ ctmp.y=c[i].y;
+ c_dup = g_new(struct coord, 1);
+ transform_from_to(&ctmp,c[i].pro, c_dup, map_projection(former_destination_map));
+ new_dest->c = g_list_append(new_dest->c, c_dup);
+ }
+ older=find_destination_in_list(new_dest, former_destinations,0);
+ if(!description && older)
+ description=((struct former_destination *)older->data)->description;
+ new_dest->description = g_strdup(description?description:_("Map point"));
+ former_destinations = find_destination_in_list(new_dest, former_destinations, 1);
+ 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);