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
}
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;
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);
}
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))) {
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);
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);
}
}
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)
{
int cursor_flag;
int tracking_flag;
int orient_north_flag;
+ int recentdest_count;
GList *vehicles;
GList *windows_items;
struct navit_vehicle *vehicle;
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;
this_->cursor_flag=1;
this_->orient_north_flag=0;
this_->tracking_flag=1;
+ this_->recentdest_count=10;
for (;*attrs; attrs++) {
switch((*attrs)->type) {
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;
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",
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
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)
{
} 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)
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_)
}
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_);
case attr_navigation:
this_->navigation=attr->u.navigation;
break;
+ case attr_recent_dest:
+ this_->recentdest_count = attr->u.num;
+ break;
default:
return 0;
}