2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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.
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.
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.
26 #include "destination.h"
33 #include "projection.h"
34 #include "navit_nls.h"
38 static struct search_param {
41 struct search_list *sl;
44 GtkWidget *entry_country, *entry_postal, *entry_city, *entry_district;
45 GtkWidget *entry_street, *entry_number;
48 GtkListStore *liststore;
49 GtkTreeModel *liststore2;
52 static void button_map(GtkWidget *widget, struct search_param *search)
55 GtkTreeViewColumn *focus_column;
56 struct pcoord *c=NULL;
59 gtk_tree_view_get_cursor(GTK_TREE_VIEW(search->treeview), &path, &focus_column);
62 if(!gtk_tree_model_get_iter(search->liststore2, &iter, path))
64 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), &iter, COL_COUNT, &c, -1);
66 navit_set_center(search->nav, c);
70 static char *description(struct search_param *search, GtkTreeIter *iter)
72 char *desc,*car,*postal,*town,*street;
73 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 0, &car, -1);
74 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 1, &postal, -1);
75 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 2, &town, -1);
76 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 4, &street, -1);
77 if (search->attr.type == attr_town_name)
78 desc=g_strdup_printf("%s-%s %s", car, postal, town);
80 desc=g_strdup_printf("%s-%s %s, %s", car, postal, town, street);
84 static void button_destination(GtkWidget *widget, struct search_param *search)
86 struct pcoord *c=NULL;
90 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (search->liststore2), &iter))
92 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), &iter, COL_COUNT, &c, -1);
94 desc=description(search, &iter);
95 navit_set_destination(search->nav, c, desc);
100 static void button_bookmark(GtkWidget *widget, struct search_param *search)
102 struct pcoord *c=NULL;
106 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (search->liststore2), &iter))
108 gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), &iter, COL_COUNT, &c, -1);
110 desc=description(search, &iter);
111 navit_add_bookmark(search->nav, c, desc);
117 char **columns_text[] = {
118 (char *[]){_n("Car"),_n("Iso2"),_n("Iso3"),_n("Country"),NULL},
119 (char *[]){_n("Car"),_n("Postal"),_n("Town"),_n("District"),NULL},
120 (char *[]){_n("Car"),_n("Postal"),_n("Town"),_n("District"),_n("Street"),NULL},
121 (char *[]){_n("Car"),_n("Postal"),_n("Town"),_n("District"),_n("Street"),_n("Number"),NULL},
124 static void set_columns(struct search_param *param, int mode)
126 GList *columns_list,*columns;
127 char **column_text=columns_text[mode];
130 columns_list=gtk_tree_view_get_columns(GTK_TREE_VIEW(param->treeview));
131 columns=columns_list;
133 gtk_tree_view_remove_column(GTK_TREE_VIEW(param->treeview), columns->data);
134 columns=g_list_next(columns);
136 g_list_free(columns_list);
137 while (*column_text) {
138 printf("column_text=%p\n", column_text);
139 printf("*column_text=%s\n", *column_text);
140 GtkCellRenderer *cell=gtk_cell_renderer_text_new();
141 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (param->treeview),-1, gettext(*column_text), cell, "text", i, NULL);
148 static void row_activated(GtkWidget *widget, GtkTreePath *p1, GtkTreeViewColumn *c, struct search_param *search)
151 GtkTreeViewColumn *focus_column;
153 GtkWidget *entry_widget;
158 gtk_tree_view_get_cursor(GTK_TREE_VIEW(search->treeview), &path, &focus_column);
161 if(!gtk_tree_model_get_iter(search->liststore2, &iter, path))
163 switch(search->attr.type) {
164 case attr_country_all:
165 entry_widget=search->entry_country;
169 entry_widget=search->entry_city;
172 case attr_street_name:
173 entry_widget=search->entry_street;
177 dbg(0,"Unknown mode\n");
180 gtk_tree_model_get(search->liststore2, &iter, column, &str, -1);
181 dbg(0,"str=%s\n", str);
183 gtk_entry_set_text(GTK_ENTRY(entry_widget), str);
186 static void tree_view_button_release(GtkWidget *widget, GdkEventButton *event, struct search_param *search)
189 GtkTreeViewColumn *column;
190 gtk_tree_view_get_cursor(GTK_TREE_VIEW(search->treeview), &path, &column);
191 gtk_tree_view_row_activated(GTK_TREE_VIEW(search->treeview), path, column);
195 next_focus(struct search_param *search, GtkWidget *widget)
197 if (widget == search->entry_country)
198 gtk_widget_grab_focus(search->entry_city);
199 if (widget == search->entry_city)
200 gtk_widget_grab_focus(search->entry_street);
201 if (widget == search->entry_street)
202 gtk_widget_grab_focus(search->entry_number);
206 static void changed(GtkWidget *widget, struct search_param *search)
208 struct search_list_result *res;
211 search->attr.u.str=(char *)gtk_entry_get_text(GTK_ENTRY(widget));
212 printf("changed %s partial %d\n", search->attr.u.str, search->partial);
213 if (widget == search->entry_country) {
214 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 3, GTK_SORT_ASCENDING);
216 search->attr.type=attr_country_all;
217 set_columns(search, 0);
219 if (widget == search->entry_postal) {
220 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 1, GTK_SORT_ASCENDING);
222 search->attr.type=attr_town_postal;
223 if (strlen(search->attr.u.str) < 2)
225 set_columns(search, 1);
227 if (widget == search->entry_city) {
228 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 2, GTK_SORT_ASCENDING);
230 search->attr.type=attr_town_name;
231 if (strlen(search->attr.u.str) < 3)
233 set_columns(search, 1);
235 if (widget == search->entry_street) {
237 search->attr.type=attr_street_name;
238 set_columns(search, 2);
242 search_list_search(search->sl, &search->attr, search->partial);
243 gtk_list_store_clear(search->liststore);
244 while((res=search_list_get_result(search->sl))) {
245 gtk_list_store_append(search->liststore,&iter);
246 gtk_list_store_set(search->liststore,&iter,COL_COUNT,res->c,-1);
247 if (widget == search->entry_country) {
249 gtk_list_store_set(search->liststore,&iter,0,res->country->car,-1);
250 gtk_list_store_set(search->liststore,&iter,1,res->country->iso3,-1);
251 gtk_list_store_set(search->liststore,&iter,2,res->country->iso2,-1);
252 gtk_list_store_set(search->liststore,&iter,3,res->country->name,-1);
256 gtk_list_store_set(search->liststore,&iter,0,res->country->car,-1);
258 gtk_list_store_set(search->liststore,&iter,0,"",-1);
260 gtk_list_store_set(search->liststore,&iter,1,res->town->postal,-1);
261 gtk_list_store_set(search->liststore,&iter,2,res->town->name,-1);
262 gtk_list_store_set(search->liststore,&iter,3,res->town->district,-1);
264 gtk_list_store_set(search->liststore,&iter,1,"",-1);
265 gtk_list_store_set(search->liststore,&iter,2,"",-1);
266 gtk_list_store_set(search->liststore,&iter,3,"",-1);
269 gtk_list_store_set(search->liststore,&iter,4,res->street->name,-1);
271 gtk_list_store_set(search->liststore,&iter,4,"",-1);
275 if (! search->partial)
276 next_focus(search, widget);
280 /* borrowed from gpe-login */
286 parse_xkbd_args (const char *cmd, char **argv)
289 char buf[strlen (cmd) + 1], *bufp = buf;
291 int escape = 0, squote = 0, dquote = 0;
320 if (!squote && !dquote)
323 if (nargs < MAX_ARGS)
324 argv[nargs++] = strdup (buf);
339 if (nargs < MAX_ARGS)
340 argv[nargs++] = strdup (buf);
348 spawn_xkbd (char *xkbd_path, char *xkbd_str)
350 #ifdef _WIN32 // AF FIXME for WIN32
355 char *xkbd_args[MAX_ARGS + 1];
367 if (dup2 (fd[1], 1) < 0)
370 if (fcntl (1, F_SETFD, 0))
372 xkbd_args[0] = (char *)xkbd_path;
373 xkbd_args[1] = "-xid";
375 parse_xkbd_args (xkbd_str, xkbd_args + 2);
378 execvp (xkbd_path, xkbd_args);
384 n = read (fd[0], &c, 1);
389 } while (n && (c != 10) && (a < (sizeof (buf) - 1)));
400 int destination_address(struct navit *nav)
403 GtkWidget *window2, *keyboard, *vbox, *table;
404 GtkWidget *label_country;
405 GtkWidget *label_postal, *label_city, *label_district;
406 GtkWidget *label_street, *label_number;
407 GtkWidget *hseparator1,*hseparator2;
408 GtkWidget *button1,*button2,*button3;
410 struct search_param *search=&search_param;
411 struct attr search_attr, country_name, *country_attr;
412 struct tracking *tracking;
413 struct country_search *cs;
418 search->ms=navit_get_mapset(nav);
419 search->sl=search_list_new(search->ms);
421 window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
422 gtk_window_set_title(GTK_WINDOW(window2),_("Enter Destination"));
423 gtk_window_set_wmclass (GTK_WINDOW (window2), "navit", "Navit");
424 vbox = gtk_vbox_new(FALSE, 0);
425 table = gtk_table_new(3, 8, FALSE);
427 search->entry_country = gtk_entry_new();
428 label_country = gtk_label_new(_("Country"));
429 search->entry_postal = gtk_entry_new();
430 gtk_widget_set_sensitive(GTK_WIDGET(search->entry_postal), FALSE);
431 label_postal = gtk_label_new(_("Zip Code"));
432 search->entry_city = gtk_entry_new();
433 label_city = gtk_label_new(_("City"));
434 search->entry_district = gtk_entry_new();
435 gtk_widget_set_sensitive(GTK_WIDGET(search->entry_district), FALSE);
436 label_district = gtk_label_new(_("District/Township"));
437 hseparator1 = gtk_vseparator_new();
438 search->entry_street = gtk_entry_new();
439 label_street = gtk_label_new(_("Street"));
440 search->entry_number = gtk_entry_new();
441 label_number = gtk_label_new(_("Number"));
442 search->treeview=gtk_tree_view_new();
443 search->listbox = gtk_scrolled_window_new (NULL, NULL);
444 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (search->listbox),
445 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
447 gtk_tree_view_set_model (GTK_TREE_VIEW (search->treeview), NULL);
448 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(search->listbox),search->treeview);
450 GType types[COL_COUNT+1];
451 for(i=0;i<COL_COUNT;i++)
452 types[i]=G_TYPE_STRING;
453 types[i]=G_TYPE_POINTER;
454 search->liststore=gtk_list_store_newv(COL_COUNT+1,types);
455 search->liststore2=gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(search->liststore));
456 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 3, GTK_SORT_ASCENDING);
457 gtk_tree_view_set_model (GTK_TREE_VIEW (search->treeview), GTK_TREE_MODEL(search->liststore2));
463 hseparator2 = gtk_vseparator_new();
464 button1 = gtk_button_new_with_label(_("Map"));
465 button2 = gtk_button_new_with_label(_("Bookmark"));
466 button3 = gtk_button_new_with_label(_("Destination"));
468 gtk_table_attach(GTK_TABLE(table), label_country, 0, 1, 0, 1, 0, GTK_FILL, 0, 0);
469 gtk_table_attach(GTK_TABLE(table), label_postal, 1, 2, 0, 1, 0, GTK_FILL, 0, 0);
470 gtk_table_attach(GTK_TABLE(table), label_city, 2, 3, 0, 1, 0, GTK_FILL, 0, 0);
472 gtk_table_attach(GTK_TABLE(table), search->entry_country, 0, 1, 1, 2, 0, GTK_FILL, 0, 0);
473 gtk_table_attach(GTK_TABLE(table), search->entry_postal, 1, 2, 1, 2, 0, GTK_FILL, 0, 0);
474 gtk_table_attach(GTK_TABLE(table), search->entry_city, 2, 3, 1, 2, 0, GTK_FILL, 0, 0);
476 gtk_table_attach(GTK_TABLE(table), label_district, 0, 1, 2, 3, 0, GTK_FILL, 0, 0);
477 gtk_table_attach(GTK_TABLE(table), label_street, 1, 2, 2, 3, 0, GTK_FILL, 0, 0);
478 gtk_table_attach(GTK_TABLE(table), label_number, 2, 3, 2, 3, 0, GTK_FILL, 0, 0);
480 gtk_table_attach(GTK_TABLE(table), search->entry_district, 0, 1, 3, 4, 0, GTK_FILL, 0, 0);
481 gtk_table_attach(GTK_TABLE(table), search->entry_street, 1, 2, 3, 4, 0, GTK_FILL, 0, 0);
482 gtk_table_attach(GTK_TABLE(table), search->entry_number, 2, 3, 3, 4, 0, GTK_FILL, 0, 0);
484 gtk_table_attach(GTK_TABLE(table), search->listbox, 0, 3, 4, 5, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
486 gtk_table_attach(GTK_TABLE(table), button1, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
487 gtk_table_attach(GTK_TABLE(table), button2, 1, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
488 gtk_table_attach(GTK_TABLE(table), button3, 2, 3, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
490 g_signal_connect(G_OBJECT(search->entry_country), "changed", G_CALLBACK(changed), search);
491 g_signal_connect(G_OBJECT(search->entry_postal), "changed", G_CALLBACK(changed), search);
492 g_signal_connect(G_OBJECT(search->entry_city), "changed", G_CALLBACK(changed), search);
493 g_signal_connect(G_OBJECT(search->entry_district), "changed", G_CALLBACK(changed), search);
494 g_signal_connect(G_OBJECT(search->entry_street), "changed", G_CALLBACK(changed), search);
495 g_signal_connect(G_OBJECT(search->entry_number), "changed", G_CALLBACK(changed), search);
496 g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK(button_map), search);
497 g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(button_bookmark), search);
498 g_signal_connect(G_OBJECT(button3), "clicked", G_CALLBACK(button_destination), search);
499 g_signal_connect(G_OBJECT(search->treeview), "button-release-event", G_CALLBACK(tree_view_button_release), search);
500 g_signal_connect(G_OBJECT(search->treeview), "row_activated", G_CALLBACK(row_activated), search);
502 gtk_widget_grab_focus(search->entry_city);
504 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
505 keyboard=gtk_socket_new();
506 gtk_box_pack_end(GTK_BOX(vbox), keyboard, FALSE, FALSE, 0);
507 gtk_container_add(GTK_CONTAINER(window2), vbox);
509 g_signal_connect(G_OBJECT(listbox), "select-row", G_CALLBACK(select_row), NULL);
511 gtk_widget_show_all(window2);
514 gtk_socket_steal(GTK_SOCKET(keyboard), spawn_xkbd("xkbd","-geometry 200x100"));
517 country_attr=country_default();
518 tracking=navit_get_tracking(nav);
519 if (tracking && tracking_get_current_attr(tracking, attr_country_id, &search_attr))
520 country_attr=&search_attr;
522 cs=country_search_new(country_attr, 0);
523 item=country_search_get_item(cs);
524 if (item && item_attr_get(item, attr_country_name, &country_name))
525 gtk_entry_set_text(GTK_ENTRY(search->entry_country), country_name.u.str);
526 country_search_destroy(cs);
528 dbg(0,"warning: no default country found\n");