From: tinloaf Date: Sun, 19 Oct 2008 19:47:36 +0000 (+0000) Subject: Fixing the way recent destinations and bookmarks are handled. X-Git-Tag: navit-0.5.0.5194svn~3643 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=030f35ede11060e34e7069776837822f52286b9e;p=profile%2Fivi%2Fnavit.git Fixing the way recent destinations and bookmarks are handled. git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1514 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- diff --git a/navit/navit/attr_def.h b/navit/navit/attr_def.h index e1a6d48..d5f0746 100644 --- a/navit/navit/attr_def.h +++ b/navit/navit/attr_def.h @@ -70,6 +70,7 @@ ATTR(icon_xs) ATTR(icon_l) ATTR(icon_s) ATTR(spacing) +ATTR(recent_dest) ATTR(destination_distance) ATTR2(0x00028000,type_boolean_begin) /* boolean */ diff --git a/navit/navit/gui/gtk/gui_gtk.h b/navit/navit/gui/gtk/gui_gtk.h index 0241606..45d144e 100644 --- a/navit/navit/gui/gtk/gui_gtk.h +++ b/navit/navit/gui/gtk/gui_gtk.h @@ -40,6 +40,8 @@ struct gui_priv { GSList *layout_group; GSList *projection_group; GSList *vehicle_group; + GList *dest_menuitems; + GList *bookmarks_menuitems; GtkUIManager *menu_manager; // old struct statusbar_priv *statusbar; int menubar_enable; diff --git a/navit/navit/gui/gtk/gui_gtk_window.c b/navit/navit/gui/gtk/gui_gtk_window.c index fc2ce12..d45ebe3 100644 --- a/navit/navit/gui/gtk/gui_gtk_window.c +++ b/navit/navit/gui/gtk/gui_gtk_window.c @@ -250,18 +250,36 @@ gui_gtk_action_activate(GtkAction *action, struct action_cb_data *data) g_free(label); } } + +struct gui_menu_info { + guint merge_id; + GtkAction *action; +}; + static void +gui_gtk_del_menu(struct gui_priv *this, struct gui_menu_info *meninfo) +{ + gtk_action_group_remove_action(this->dyn_group, meninfo->action); + gtk_ui_manager_remove_ui(this->ui_manager, meninfo->merge_id); +} + +static struct gui_menu_info gui_gtk_add_menu(struct gui_priv *this, char *name, char *label, char *path, int submenu, struct action_cb_data *data) { + struct gui_menu_info meninfo; GtkAction *action; guint merge_id; action=gtk_action_new(name, label, NULL, NULL); + meninfo.action = action; if (data) g_signal_connect(action, "activate", G_CALLBACK(gui_gtk_action_activate), data); gtk_action_group_add_action(this->dyn_group, action); - merge_id=gtk_ui_manager_new_merge_id(this->ui_manager); + merge_id =gtk_ui_manager_new_merge_id(this->ui_manager); + meninfo.merge_id = merge_id; gtk_ui_manager_add_ui(this->ui_manager, merge_id, path, name, name, submenu ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM, FALSE); + + return meninfo; } static void @@ -406,16 +424,29 @@ gui_gtk_maps_init(struct gui_priv *this) } static void -gui_gtk_destinations_init(struct gui_priv *this) +gui_gtk_destinations_update(struct gui_priv *this) { + GList *curr; struct attr attr; struct action_cb_data *data; struct map_rect *mr=NULL; struct item *item; + struct gui_menu_info *meninfo; struct coord c; int count=0; char *name, *label; + curr = g_list_first(this->dest_menuitems); + + while (curr) { + gui_gtk_del_menu(this, (struct gui_menu_info *)curr->data); + g_free((struct gui_menu_info *)curr->data); + curr = g_list_next(curr); + }; + + g_list_free(this->dest_menuitems); + this->dest_menuitems = NULL; + if(navit_get_attr(this->nav, attr_former_destination_map, &attr, NULL) && attr.u.map && (mr=map_rect_new(attr.u.map, NULL))) { while ((item=map_rect_get_item(mr))) { if (item->type != type_former_destination) continue; @@ -430,7 +461,10 @@ gui_gtk_destinations_init(struct gui_priv *this) data->attr.u.pcoord->pro=projection_mg; data->attr.u.pcoord->x=c.x; data->attr.u.pcoord->y=c.y; - gui_gtk_add_menu(this, name, label, "/ui/MenuBar/Route/FormerDestinations/FormerDestinationMenuAdditions",0,data); + + meninfo = g_new(struct gui_menu_info, 1); + *meninfo = gui_gtk_add_menu(this, name, label, "/ui/MenuBar/Route/FormerDestinations/FormerDestinationMenuAdditions",0,data); + this->dest_menuitems = g_list_prepend(this->dest_menuitems, meninfo); g_free(name); } map_rect_destroy(mr); @@ -438,17 +472,37 @@ gui_gtk_destinations_init(struct gui_priv *this) } static void -gui_gtk_bookmarks_init(struct gui_priv *this) +gui_gtk_destinations_init(struct gui_priv *this) { + navit_add_callback(this->nav, callback_new_attr_1(gui_gtk_destinations_update, attr_destination, this)); + gui_gtk_destinations_update(this); +} + +static void +gui_gtk_bookmarks_update(struct gui_priv *this) +{ + GList *curr; struct attr attr; struct action_cb_data *data; struct map_rect *mr=NULL; + struct gui_menu_info *meninfo; struct item *item; struct coord c; int count=0; char *parent, *name, *label, *label_full, *menu_label, *tmp_parent, *s; GHashTable *hash; + curr = g_list_first(this->bookmarks_menuitems); + + while (curr) { + gui_gtk_del_menu(this, (struct gui_menu_info *)curr->data); + g_free((struct gui_menu_info *)curr->data); + curr = g_list_next(curr); + }; + + g_list_free(this->bookmarks_menuitems); + this->bookmarks_menuitems = NULL; + if(navit_get_attr(this->nav, attr_bookmark_map, &attr, NULL) && attr.u.map && (mr=map_rect_new(attr.u.map, NULL))) { hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); while ((item=map_rect_get_item(mr))) { @@ -466,7 +520,9 @@ gui_gtk_bookmarks_init(struct gui_priv *this) tmp_parent=g_strdup(tmp_parent); } else { name=g_strdup_printf("Bookmark %d", count++); - gui_gtk_add_menu(this, name, menu_label+(label-label_full),parent,1,NULL); + meninfo = g_new(struct gui_menu_info, 1); + *meninfo = gui_gtk_add_menu(this, name, menu_label+(label-label_full),parent,1,NULL); + this->bookmarks_menuitems = g_list_prepend(this->bookmarks_menuitems, meninfo); tmp_parent=g_strdup_printf("%s/%s", parent, name); g_hash_table_insert(hash, g_strdup(menu_label), g_strdup(tmp_parent)); g_free(name); @@ -484,7 +540,9 @@ gui_gtk_bookmarks_init(struct gui_priv *this) data->attr.u.pcoord->x=c.x; data->attr.u.pcoord->y=c.y; name=g_strdup_printf("Bookmark %d", count++); - gui_gtk_add_menu(this, name, label, parent,0,data); + meninfo = g_new(struct gui_menu_info, 1); + *meninfo = gui_gtk_add_menu(this, name, label, parent,0,data); + this->bookmarks_menuitems = g_list_prepend(this->bookmarks_menuitems, meninfo); g_free(name); g_free(parent); } @@ -493,6 +551,13 @@ gui_gtk_bookmarks_init(struct gui_priv *this) } static void +gui_gtk_bookmarks_init(struct gui_priv *this) +{ + navit_add_callback(this->nav, callback_new_attr_1(gui_gtk_bookmarks_update, attr_bookmark_map, this)); + gui_gtk_bookmarks_update(this); +} + +static void gui_gtk_init(struct gui_priv *this, struct navit *nav) { diff --git a/navit/navit/navit.c b/navit/navit/navit.c index 9506332..9c8f453 100644 --- a/navit/navit/navit.c +++ b/navit/navit/navit.c @@ -101,6 +101,7 @@ struct navit { int cursor_flag; int tracking_flag; int orient_north_flag; + int recentdest_count; GList *vehicles; GList *windows_items; struct navit_vehicle *vehicle; @@ -112,9 +113,7 @@ struct navit { struct datawindow *roadbook_window; struct map *bookmark; struct map *former_destination; - struct menu *bookmarks; GHashTable *bookmarks_hash; - struct menu *destinations; struct point pressed, last, current; int button_pressed,moved,popped; struct event_timer *button_timeout, *motion_timeout; @@ -428,6 +427,7 @@ navit_new(struct attr *parent, struct attr **attrs) this_->cursor_flag=1; this_->orient_north_flag=0; this_->tracking_flag=1; + this_->recentdest_count=10; for (;*attrs; attrs++) { switch((*attrs)->type) { @@ -446,6 +446,9 @@ navit_new(struct attr *parent, struct attr **attrs) case attr_tracking: this_->tracking_flag=!!(*attrs)->u.num; break; + case attr_recent_dest: + this_->recentdest_count=(*attrs)->u.num; + break; default: dbg(0, "Unexpected attribute %x\n",(*attrs)->type); break; @@ -513,43 +516,73 @@ navit_projection_set(struct navit *this_, enum projection pro) navit_draw(this_); } +/** + * @param limit Limits the number of entries in the "backlog". Set to 0 for "infinite" + */ static void -navit_add_menu_destinations(struct navit *this_, char *name, struct menu *rmen, GHashTable *h, struct callback *cb) -{ - char buffer2[2048]; - char *i,*n; - struct menu *men,*nmen; - - if (rmen) { - i=name; - n=name; - men=rmen; - while (h && (i=strchr(n, '/'))) { - strcpy(buffer2, name); - buffer2[i-name]='\0'; - if (!(nmen=g_hash_table_lookup(h, buffer2))) { - nmen=menu_add(men, buffer2+(n-name), menu_type_submenu, NULL); - g_hash_table_insert(h, g_strdup(buffer2), nmen); - } - n=i+1; - men=nmen; - } - menu_add(men, n, menu_type_menu, cb); - } -} - -static void -navit_append_coord(struct navit *this_, char *file, struct pcoord *c, char *type, char *description, struct menu *rmen, GHashTable *h, void (*cb_func)(void)) +navit_append_coord(struct navit *this_, char *file, struct pcoord *c, char *type, char *description, GHashTable *h, int limit) { FILE *f; int offset=0; char *buffer; + int ch,prev,lines=0; + int numc,readc; + int fd; const char *prostr; struct callback *cb; + f=fopen(file, "r"); + if (limit != 0) { + prev = '\n'; + while ((ch = fgetc(f)) != EOF) { + if ((ch == '\n') && (prev != '\n')) { + lines++; + } + prev = ch; + } + + if (prev != '\n') { // Last line did not end with a newline + lines++; + } + + fclose(f); + f = fopen(file, "r+"); + fd = fileno(f); + while (lines >= limit) { // We have to "scroll up" + rewind(f); + numc = 0; // Counts how many bytes we have in our line to scroll up + while ((ch = fgetc(f)) != EOF) { + numc++; + if (ch == '\n') { + break; + } + } + + buffer=g_malloc(numc); + offset = numc; // Offset holds where we currently are + + do { + fseek(f,offset,SEEK_SET); + readc = fread(buffer,1,numc,f); + + fseek(f,-(numc+readc),SEEK_CUR); + fwrite(buffer,1,readc,f); + + offset += readc; + } while (readc == numc); + + g_free(buffer); + fflush(f); + ftruncate(fd,(offset-numc)); + fsync(fd); + + lines--; + } + fclose(f); + } + f=fopen(file, "a"); if (f) { - offset=ftell(f); if (c) { prostr = projection_to_name(c->pro); fprintf(f,"%s%s%s0x%x %s0x%x type=%s label=\"%s\"\n", @@ -561,12 +594,6 @@ navit_append_coord(struct navit *this_, char *file, struct pcoord *c, char *type fprintf(f,"\n"); fclose(f); } - if (c) { - buffer=g_strdup(description); - cb=callback_new_2(cb_func, this_, (void *)offset); - navit_add_menu_destinations(this_, buffer, rmen, h, cb); - g_free(buffer); - } } static int @@ -673,44 +700,6 @@ navit_get_center_file(gboolean create) return g_strjoin(NULL, navit_get_user_data_directory(create), "center.txt", NULL); } - -static void -navit_set_destination_from_file(struct navit *this_, char *file, int bookmark, int offset) -{ - FILE *f; - char *name, *description, buffer[2048]; - struct pcoord c; - - f=fopen(file, "r"); - if (! f) - return; - fseek(f, offset, SEEK_SET); - if (parse_line(f, buffer, &name, &c) <= 0) - return; - if (bookmark) { - description=g_strdup_printf("Bookmark %s", name); - navit_set_destination(this_, &c, description); - g_free(description); - } else - navit_set_destination(this_, &c, name); -} - -static void -navit_set_destination_from_destination(struct navit *this_, void *offset_p) -{ - char *destination_file = navit_get_destination_file(FALSE); - navit_set_destination_from_file(this_, destination_file, 0, (int)offset_p); - g_free(destination_file); -} - -static void -navit_set_destination_from_bookmark(struct navit *this_, void *offset_p) -{ - char *bookmark_file = navit_get_bookmark_file(FALSE); - navit_set_destination_from_file(this_, bookmark_file, 1, (int)offset_p); - g_free(bookmark_file); -} - static void navit_set_center_from_file(struct navit *this_, char *file) { @@ -772,9 +761,9 @@ navit_set_destination(struct navit *this_, struct pcoord *c, char *description) } else this_->destination_valid=0; char *destination_file = navit_get_destination_file(TRUE); - navit_append_coord(this_, destination_file, c, "former_destination", description, this_->destinations, NULL, callback_cast(navit_set_destination_from_destination)); + navit_append_coord(this_, destination_file, c, "former_destination", description, NULL, this_->recentdest_count); g_free(destination_file); - callback_list_call_attr_1(this_->attr_cbl, attr_destination, this_); + callback_list_call_attr_0(this_->attr_cbl, attr_destination); if (this_->route) { route_set_destination(this_->route, c); if (this_->navigation) @@ -795,66 +784,13 @@ void navit_add_bookmark(struct navit *this_, struct pcoord *c, const char *description) { char *bookmark_file = navit_get_bookmark_file(TRUE); - navit_append_coord(this_,bookmark_file, c, "bookmark", description, this_->bookmarks, this_->bookmarks_hash, callback_cast(navit_set_destination_from_bookmark)); + navit_append_coord(this_,bookmark_file, c, "bookmark", description, this_->bookmarks_hash,0); g_free(bookmark_file); -} -struct navit *global_navit; - -static void -navit_add_menu_destinations_from_file(struct navit *this_, char *file, struct menu *rmen, GHashTable *h, struct route *route, void (*cb_func)(void)) -{ - int pos,flag=0; - FILE *f; - char buffer[2048]; - struct pcoord c; - char *name; - int offset=0; - struct callback *cb; - - f=fopen(file, "r"); - if (f) { - while (! feof(f) && (pos=parse_line(f, buffer, &name, &c)) > -3) { - if (pos > 0) { - cb=callback_new_2(cb_func, this_, (void *)offset); - navit_add_menu_destinations(this_, name, rmen, h, cb); - flag=1; - } else - flag=0; - offset=ftell(f); - } - fclose(f); - if (route && flag) { - this_->destination=c; - this_->destination_valid=1; - route_set_destination(route, &c); - } - } -} - -static void -navit_add_menu_former_destinations(struct navit *this_, struct menu *men, struct route *route) -{ - if (men) - this_->destinations=menu_add(men, _("Former Destinations"), menu_type_submenu, NULL); - else - this_->destinations=NULL; - char *destination_file = navit_get_destination_file(FALSE); - navit_add_menu_destinations_from_file(this_, destination_file, this_->destinations, NULL, route, callback_cast(navit_set_destination_from_destination)); - g_free(destination_file); + callback_list_call_attr_0(this_->attr_cbl, attr_bookmark_map); } -static void -navit_add_menu_bookmarks(struct navit *this_, struct menu *men) -{ - if (men) - this_->bookmarks=menu_add(men, _("Bookmarks"), menu_type_submenu, NULL); - else - this_->bookmarks=NULL; - char *bookmark_file = navit_get_bookmark_file(FALSE); - navit_add_menu_destinations_from_file(this_, bookmark_file, this_->bookmarks, this_->bookmarks_hash, NULL, callback_cast(navit_set_destination_from_bookmark)); - g_free(bookmark_file); -} +struct navit *global_navit; static void navit_add_bookmarks_from_file(struct navit *this_) @@ -1269,7 +1205,6 @@ navit_init(struct navit *this_) } navit_add_bookmarks_from_file(this_); navit_add_former_destinations_from_file(this_); - navit_add_menu_former_destinations(this_, NULL, this_->route); } if (this_->navigation && this_->speech) { this_->nav_speech_cb=callback_new_1(callback_cast(navit_speak), this_); @@ -1545,6 +1480,9 @@ navit_add_attr(struct navit *this_, struct attr *attr) case attr_navigation: this_->navigation=attr->u.navigation; break; + case attr_recent_dest: + this_->recentdest_count = attr->u.num; + break; default: return 0; } diff --git a/navit/navit/navit.xml b/navit/navit/navit.xml index 48ee4f6..eb9690e 100644 --- a/navit/navit/navit.xml +++ b/navit/navit/navit.xml @@ -25,7 +25,7 @@ http://wiki.navit-project.org/index.php/Configuring_NavIt This line defines which location on the map navit will show after startup. It makes sense to set it to your home coordinates. --> - +