Add:Core:Support for FRA FRA NLS Setting
[navit-package] / navit / popup.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <glib.h>
26 #include "popup.h"
27 #include "debug.h"
28 #include "navit.h"
29 #include "coord.h"
30 #include "gui.h"
31 #include "menu.h"
32 #include "point.h"
33 #include "transform.h"
34 #include "projection.h"
35 #include "item.h"
36 #include "map.h"
37 #include "graphics.h"
38 #include "callback.h"
39 #include "route.h"
40 #include "navit_nls.h"
41
42 #if 0
43 static void
44 popup_set_no_passing(struct popup_item *item, void *param)
45 {
46 #if 0
47         struct display_list *l=param;
48         struct segment *seg=(struct segment *)(l->data);
49         struct street_str *str=(struct street_str *)(seg->data[0]);
50         char log[256];
51         int segid=str->segid;
52         if (segid < 0)
53                 segid=-segid;
54
55         sprintf(log,"Attributes Street 0x%x updated: limit=0x%x(0x%x)", segid, 0x33, str->limit);
56         str->limit=0x33;
57         log_write(log, seg->blk_inf.file, str, sizeof(*str));
58 #endif
59 }
60
61 #endif
62
63 static void
64 popup_traffic_distortion(struct item *item, char *attr)
65 {
66         FILE *map=fopen("distortion.txt","a");
67         struct coord c;
68         struct map_rect *mr;
69         fprintf(map,"type=traffic_distortion %s\n",attr);
70         mr=map_rect_new(item->map,NULL);
71         item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
72         while (item_coord_get(item, &c, 1)) {
73                 fprintf(map,"0x%x 0x%x\n",c.x,c.y);
74         }
75         fclose(map);
76 }
77
78 static void
79 popup_traffic_distortion_blocked(struct item *item)
80 {
81         dbg(0,"item=%p\n",item);
82         popup_traffic_distortion(item, "maxspeed=0");
83 }
84
85 static void
86 popup_traffic_distortion_speed(struct item *item, int maxspeed)
87 {
88         char buffer[256];
89         sprintf(buffer,"maxspeed=%d",maxspeed);
90         popup_traffic_distortion(item,buffer);
91 }
92
93 static void
94 popup_traffic_distortion_delay(struct item *item, int delay)
95 {
96         char buffer[256];
97         sprintf(buffer,"delay=%d",delay*600);
98         popup_traffic_distortion(item,buffer);
99 }
100
101 static void
102 popup_set_destination(struct navit *nav, struct pcoord *pc)
103 {
104         struct coord c;
105         struct coord_geo g;
106         char buffer[1024];
107         char buffer_geo[1024];
108         c.x = pc->x;
109         c.y = pc->y;
110         transform_to_geo(transform_get_projection(navit_get_trans(nav)), &c, &g);
111         coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS,buffer_geo,sizeof(buffer_geo));
112         sprintf(buffer,"Map Point %s", buffer_geo);
113         navit_set_destination(nav, pc, buffer, 1);
114 }
115
116 static void
117 popup_set_bookmark(struct navit *nav, struct pcoord *pc)
118 {
119         struct coord c;
120         struct coord_geo g;
121         char buffer[1024];
122         char buffer_geo[1024];
123         c.x = pc->x;
124         c.y = pc->y;
125         transform_to_geo(pc->pro, &c, &g);
126         coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS,buffer_geo,sizeof(buffer_geo));
127         sprintf(buffer,"Map Point %s", buffer_geo);
128         if (!gui_add_bookmark(navit_get_gui(nav), pc, buffer)) 
129                 navit_add_bookmark(nav, pc, buffer);
130 }
131
132
133 extern void *vehicle;
134
135 static void
136 popup_set_position(struct navit *nav, struct pcoord *pc)
137 {
138         dbg(1,"%p %p\n", nav, pc);
139         navit_set_position(nav, pc);
140 }
141
142 #if 0
143 static void
144 popup_break_crossing(struct display_list *l)
145 {
146         struct segment *seg=(struct segment *)(l->data);
147         struct street_str *str=(struct street_str *)(seg->data[0]);
148         char log[256];
149         int segid=str->segid;
150         if (segid < 0)
151                 segid=-segid;
152
153         sprintf(log,"Coordinates Street 0x%x updated: limit=0x%x(0x%x)", segid, 0x33, str->limit);
154         str->limit=0x33;
155         log_write(log, seg->blk_inf.file, str, sizeof(*str));
156 }
157 #endif
158
159
160 #define popup_printf(menu, type, fmt...) popup_printf_cb(menu, type, NULL, fmt)
161
162 static void *
163 popup_printf_cb(void *menu, enum menu_type type, struct callback *cb, const char *fmt, ...)
164 {
165         gchar *str,*us;
166         int usc=0;
167         va_list ap;
168         void *ret;
169
170         va_start(ap, fmt);
171         str=g_strdup_vprintf(fmt, ap);
172         dbg(0,"%s\n", str);
173         us=str;
174         while (*us) {
175                 if (*us == '_')
176                         usc++;
177                 us++;
178         }
179         if (usc) {
180                 gchar *str2=g_malloc(strlen(str)+usc+1);
181                 gchar *us2=str2;
182                 us=str;
183                 while (*us) {
184                         if (*us == '_')
185                                 *us2++=*us;
186                         *us2++=*us++;
187                 }
188                 *us2='\0';
189                 g_free(str);
190                 str=str2;
191         }
192         ret=menu_add(menu, str, type, cb);
193         va_end(ap);
194         g_free(str);
195         return ret;
196 }
197
198 static void
199 popup_show_attr_val(struct map *map, void *menu, struct attr *attr)
200 {
201         char *attr_name=attr_to_name(attr->type);
202         char *str;
203
204         str=attr_to_text(attr, map, 1);
205         popup_printf(menu, menu_type_menu, "%s: %s", attr_name, str);
206         g_free(str);
207 }
208
209 #if 0
210 static void
211 popup_show_attr(void *menu, struct item *item, enum attr_type attr_type)
212 {
213         struct attr attr;
214         memset(&attr, 0, sizeof(attr));
215         attr.type=attr_type;
216         if (item_attr_get(item, attr_type, &attr)) 
217                 popup_show_attr_val(menu, &attr);
218 }
219 #endif
220
221 static void
222 popup_show_attrs(struct map *map, void *menu, struct item *item)
223 {
224 #if 0
225         popup_show_attr(menu, item, attr_debug);
226         popup_show_attr(menu, item, attr_address);
227         popup_show_attr(menu, item, attr_phone);
228         popup_show_attr(menu, item, attr_phone);
229         popup_show_attr(menu, item, attr_entry_fee);
230         popup_show_attr(menu, item, attr_open_hours);
231 #else
232         struct attr attr;
233         for (;;) {
234                 memset(&attr, 0, sizeof(attr));
235                 if (item_attr_get(item, attr_any, &attr)) 
236                         popup_show_attr_val(map, menu, &attr);
237                 else
238                         break;
239         }
240         
241 #endif
242 }
243
244 static void
245 popup_show_item(struct navit *nav, void *popup, struct displayitem *di)
246 {
247         struct map_rect *mr;
248         void *menu, *menu_map, *menu_item, *menu_dist;
249         char *label;
250         struct item *item,*diitem;
251         int count;
252
253         label=graphics_displayitem_get_label(di);
254         diitem=graphics_displayitem_get_item(di);
255         count=graphics_displayitem_get_coord_count(di);
256
257         dbg_assert(diitem);
258
259         if (label) 
260                 menu=popup_printf(popup, menu_type_submenu, "%s '%s' (%d coords)", item_to_name(diitem->type), label, count);
261         else
262                 menu=popup_printf(popup, menu_type_submenu, "%s (%d coords)", item_to_name(diitem->type), count);
263         menu_item=popup_printf(menu, menu_type_submenu, "Item");
264         popup_printf(menu_item, menu_type_menu, "type: 0x%x", diitem->type);
265         popup_printf(menu_item, menu_type_menu, "id: 0x%x 0x%x", diitem->id_hi, diitem->id_lo);
266         if (diitem->map) {
267                 mr=map_rect_new(diitem->map,NULL);
268                 item=map_rect_get_item_byid(mr, diitem->id_hi, diitem->id_lo);
269                 dbg(1,"item=%p\n", item);
270                 if (item) {
271                         popup_show_attrs(item->map, menu_item, item);
272                         if (item->type < type_line) {
273                                 struct coord co;
274                                 struct pcoord *c;
275                                 if (item_coord_get(item, &co, 1)) {
276                                         c=g_new(struct pcoord, 1);
277                                         c->pro = transform_get_projection(navit_get_trans(nav));
278                                         c->x = co.x;
279                                         c->y = co.y;
280                                         popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_set_position), nav, c), _("Set as position"));
281                                         popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_set_destination), nav, c), _("Set as destination"));
282                                         popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_set_bookmark), nav, c), _("Add as bookmark"));
283                                 }
284                         }
285                 }
286                 map_rect_destroy(mr);
287                 menu_map=popup_printf(menu, menu_type_submenu, "Map");
288         } else {
289                 popup_printf(menu, menu_type_menu, "(No map)");
290         }
291         if (item_get_default_flags(diitem->type)) {
292                 int speeds[]={5,10,20,30,40,50,60,70,80,90,100};
293                 int delays[]={1,2,3,5,10,15,20,30,45,60,75,90,120,150,180,240,300};
294                 int i;
295                 menu_dist=popup_printf(menu, menu_type_submenu, "Traffic distortion");
296                 popup_printf_cb(menu_dist, menu_type_menu, callback_new_1(callback_cast(popup_traffic_distortion_blocked), diitem), "Blocked");
297                 menu_item=popup_printf(menu_dist, menu_type_submenu,"Max speed");
298                 for (i = 0 ; i < sizeof(speeds)/sizeof(int); i++) {
299                         popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_traffic_distortion_speed), diitem, speeds[i]), "%d km/h",speeds[i]);
300                 }
301                 menu_item=popup_printf(menu_dist, menu_type_submenu,"Delay");
302                 for (i = 0 ; i < sizeof(delays)/sizeof(int); i++) {
303                         popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_traffic_distortion_delay), diitem, delays[i]*600), "%d min",delays[i]);
304                 }
305         }
306 }
307
308 static void
309 popup_display(struct navit *nav, void *popup, struct point *p)
310 {
311         struct displaylist_handle *dlh;
312         struct displaylist *display;
313         struct displayitem *di;
314
315         display=navit_get_displaylist(nav);
316         dlh=graphics_displaylist_open(display);
317         while ((di=graphics_displaylist_next(dlh))) {
318                 if (graphics_displayitem_within_dist(display, di, p, 5)) {
319                         popup_show_item(nav, popup, di);
320                 }
321         }
322         graphics_displaylist_close(dlh);
323 }
324
325 static struct pcoord c;
326
327 void
328 popup(struct navit *nav, int button, struct point *p)
329 {
330         void *popup,*men;
331         char buffer[1024];
332         struct coord_geo g;
333         struct coord co;
334
335         popup=gui_popup_new(navit_get_gui(nav));
336         if (! popup)
337                 return;
338         transform_reverse(navit_get_trans(nav), p, &co);
339         men=popup_printf(popup, menu_type_submenu, _("Point 0x%x 0x%x"), co.x, co.y);
340         popup_printf(men, menu_type_menu, _("Screen coord : %d %d"), p->x, p->y);
341         transform_to_geo(transform_get_projection(navit_get_trans(nav)), &co, &g);
342         coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS,buffer,sizeof(buffer));
343         popup_printf(men, menu_type_menu, "%s", buffer);
344         popup_printf(men, menu_type_menu, "%f %f", g.lat, g.lng);
345         dbg(1,"%p %p\n", nav, &c);
346         c.pro = transform_get_projection(navit_get_trans(nav));
347         c.x = co.x;
348         c.y = co.y;
349         popup_printf_cb(men, menu_type_menu, callback_new_2(callback_cast(popup_set_position), nav, &c), _("Set as position"));
350         popup_printf_cb(men, menu_type_menu, callback_new_2(callback_cast(popup_set_destination), nav, &c), _("Set as destination"));
351         popup_printf_cb(men, menu_type_menu, callback_new_2(callback_cast(popup_set_bookmark), nav, &c), _("Add as bookmark"));
352         popup_display(nav, popup, p);
353         menu_popup(popup);
354 }