summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--navit/attr_def.h1
-rw-r--r--navit/gui/gtk/gui_gtk.h2
-rw-r--r--navit/gui/gtk/gui_gtk_window.c77
-rw-r--r--navit/navit.c202
-rw-r--r--navit/navit.xml4
5 files changed, 147 insertions, 139 deletions
diff --git a/navit/attr_def.h b/navit/attr_def.h
index e1a6d480a..d5f0746c4 100644
--- a/navit/attr_def.h
+++ b/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/gui/gtk/gui_gtk.h b/navit/gui/gtk/gui_gtk.h
index 02416065d..45d144e50 100644
--- a/navit/gui/gtk/gui_gtk.h
+++ b/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/gui/gtk/gui_gtk_window.c b/navit/gui/gtk/gui_gtk_window.c
index fc2ce1293..d45ebe339 100644
--- a/navit/gui/gtk/gui_gtk_window.c
+++ b/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.c b/navit/navit.c
index 950633282..9c8f45339 100644
--- a/navit/navit.c
+++ b/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.xml b/navit/navit.xml
index 48ee4f68d..eb9690e67 100644
--- a/navit/navit.xml
+++ b/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.
-->
- <navit center="4808 N 1134 E" zoom="256" tracking="1" cursor="1" orientation="0">
+ <navit center="4808 N 1134 E" zoom="256" tracking="1" cursor="1" orientation="0" recent_dest="10">
<!--
@@ -70,6 +70,8 @@ http://wiki.navit-project.org/index.php/Configuring_NavIt
<tracking>
</tracking>
+
+
<route destination_distance="50">
<speed type="street_0,street_1_city" value="10" />