]> err.no Git - mapper/blob - src/poi-gui.c
Merge branch 'master' of git+ssh://tal.org/home/git/mapper
[mapper] / src / poi-gui.c
1 #include <config.h>
2
3 #define _GNU_SOURCE
4
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <strings.h>
9 #include <stddef.h>
10 #include <locale.h>
11 #include <math.h>
12 #include <errno.h>
13 #include <sys/wait.h>
14 #include <glib/gstdio.h>
15 #include <gtk/gtk.h>
16 #include <fcntl.h>
17 #include <libintl.h>
18 #include <locale.h>
19
20 #include "utils.h"
21 #include "poi.h"
22 #include "gps.h"
23 #include "map.h"
24 #include "mapper-types.h"
25 #include "ui-common.h"
26 #include "settings.h"
27 #include "poi-gui.h"
28
29 #define POI_QUICK_BUTTONS (9)
30
31 static GtkWidget *dialog_qp;
32
33 typedef struct _PoiCategoryEditInfo PoiCategoryEditInfo;
34 static struct _PoiCategoryEditInfo {
35         GtkWidget *cmb_category;
36         guint cat_id;
37 };
38
39 static gboolean 
40 category_delete(GtkWidget *widget, delete_poi *dpoi)
41 {
42         GtkWidget *dialog;
43         guint i;
44         gchar *buffer;
45
46         buffer = g_strdup_printf("%s\n\t%s\n%s", _("Delete category?"),
47                                  dpoi->txt_label, _("WARNING: All POIs in that category will also be deleted!"));
48         dialog = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
49         g_free(buffer);
50         i = gtk_dialog_run(GTK_DIALOG(dialog));
51         gtk_widget_destroy(GTK_WIDGET(dialog));
52
53         if (i == GTK_RESPONSE_OK) {
54                 if (poi_category_delete(dpoi)==FALSE)
55                         popup_error(_window, _("Problem deleting category or POI"));
56                 gtk_widget_hide_all(dpoi->dialog);
57                 map_force_redraw();
58         }
59
60         return TRUE;
61 }
62
63 gboolean 
64 category_dialog(guint cat_id)
65 {
66         GtkWidget *dialog;
67         GtkWidget *table;
68         GtkWidget *label;
69         GtkWidget *txt_label;
70         GtkWidget *txt_desc;
71         GtkWidget *btn_delete = NULL;
72         GtkWidget *txt_scroll;
73         GtkWidget *chk_enabled;
74         GtkTextBuffer *desc_txt;
75         GtkTextIter begin, end;
76         gboolean results = TRUE;
77         delete_poi dpoi = { NULL, NULL, 0 };
78         poi_category *c;
79
80
81         if (cat_id > 0) {
82                 if (poi_category_get(cat_id, &c)==FALSE)
83                         return FALSE;
84
85                 dialog = gtk_dialog_new_with_buttons(_("Edit Category"),
86                                                      GTK_WINDOW(_window),
87                                                      GTK_DIALOG_MODAL,
88                                                      GTK_STOCK_OK,
89                                                      GTK_RESPONSE_ACCEPT, NULL);
90
91                 gtk_container_add(GTK_CONTAINER
92                                   (GTK_DIALOG(dialog)->action_area),
93                                   btn_delete = gtk_button_new_with_label(_("Delete")));
94
95                 dpoi.dialog = dialog;
96                 dpoi.txt_label = g_strdup(c->label);
97                 dpoi.id = c->id;
98
99                 g_signal_connect(G_OBJECT(btn_delete), "clicked", G_CALLBACK(category_delete), &dpoi);
100
101                 gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
102         } else {
103                 c=poi_category_new();
104                 c->enabled = 1;
105                 c->label = g_strdup("");
106                 c->id = 0;
107                 c->desc = g_strdup("");
108
109                 dialog = gtk_dialog_new_with_buttons(_("Add Category"),
110                                                      GTK_WINDOW(_window),
111                                                      GTK_DIALOG_MODAL,
112                                                      GTK_STOCK_OK,
113                                                      GTK_RESPONSE_ACCEPT,
114                                                      GTK_STOCK_CANCEL,
115                                                      GTK_RESPONSE_REJECT, NULL);
116         }
117
118         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
119                            table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
120
121         gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Label")),
122                          0, 1, 0, 1, GTK_FILL, 0, 2, 4);
123         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
124         gtk_table_attach(GTK_TABLE(table),
125                          txt_label = gtk_entry_new(),
126                          1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
127
128         gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Description")),
129                          0, 1, 1, 2, GTK_FILL, 0, 2, 4);
130         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
131
132         txt_scroll = gtk_scrolled_window_new(NULL, NULL);
133         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll), GTK_SHADOW_IN);
134         gtk_table_attach(GTK_TABLE(table),
135                          txt_scroll, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
136
137         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
138                                        GTK_POLICY_AUTOMATIC,
139                                        GTK_POLICY_AUTOMATIC);
140
141         txt_desc = gtk_text_view_new();
142         gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
143
144         gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
145         gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
146
147         desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
148
149         gtk_table_attach(GTK_TABLE(table),
150                          chk_enabled = gtk_check_button_new_with_label(_("Enabled")), 0, 2, 2,
151                          3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
152
153         /* label */
154         gtk_entry_set_text(GTK_ENTRY(txt_label), c->label);
155
156         /* desc */
157         gtk_text_buffer_set_text(desc_txt, c->desc, -1);
158
159         /* enabled */
160         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enabled), (c->enabled == 1 ? TRUE : FALSE));
161
162         poi_category_free(c);
163
164         gtk_widget_show_all(dialog);
165
166         while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
167                 if (strlen(gtk_entry_get_text(GTK_ENTRY(txt_label)))) {
168                         c=poi_category_new();
169                         c->label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
170                 } else {
171                         popup_error(dialog,_("Please specify a name for the category."));
172                         continue;
173                 }
174
175                 gtk_text_buffer_get_iter_at_offset(desc_txt, &begin, 0);
176                 gtk_text_buffer_get_end_iter(desc_txt, &end);
177                 c->desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
178                 c->enabled = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(chk_enabled)) ? 1 : 0);
179
180                 results=poi_category_update(cat_id, c);
181
182                 if (results==FALSE)
183                         popup_error(_window, _("Problem updating category"));
184                 poi_category_free(c);
185         }
186
187         g_free(dpoi.txt_label);
188         g_object_unref(desc_txt);
189         gtk_widget_hide_all(dialog);
190
191         return results;
192 }
193
194 static void 
195 category_toggled(GtkCellRendererToggle * cell, gchar * path, gpointer data)
196 {
197         GtkTreeIter iter;
198         gboolean cat_enabled;
199         guint cat_id;
200
201         GtkTreeModel *model = GTK_TREE_MODEL(data);
202         if (!gtk_tree_model_get_iter_from_string(model, &iter, path))
203                 return;
204
205         gtk_tree_model_get(model, &iter, CAT_ENABLED, &cat_enabled, -1);
206         gtk_tree_model_get(model, &iter, CAT_ID, &cat_id, -1);
207
208         cat_enabled ^= 1;
209
210         if (poi_category_toggle(cat_id, cat_enabled)==FALSE) {
211                 popup_error(_window, _("Problem updating Category"));
212         } else {
213                 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAT_ENABLED, cat_enabled, -1);
214         }
215
216 }
217
218 static gboolean 
219 category_add(GtkWidget * widget, GtkWidget * tree_view)
220 {
221         GtkListStore *store;
222
223         if (category_dialog(0)) {
224                 store = poi_category_generate_store();
225                 gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view),
226                                         GTK_TREE_MODEL(store));
227                 g_object_unref(G_OBJECT(store));
228         }
229         return TRUE;
230 }
231
232 static gboolean 
233 category_edit(GtkWidget * widget, GtkWidget * tree_view)
234 {
235         GtkTreeIter iter;
236         GtkTreeModel *store;
237         GtkTreeSelection *selection;
238
239         store = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
240         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
241         if (gtk_tree_selection_get_selected(selection, &store, &iter)) {
242                 GValue val;
243                 memset(&val, 0, sizeof(val));
244                 gtk_tree_model_get_value(store, &iter, 0, &val);
245                 if (category_dialog(g_value_get_uint(&val))) {
246                         GtkListStore *new_store = poi_category_generate_store();
247                         gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view),
248                                                 GTK_TREE_MODEL(new_store));
249                         g_object_unref(G_OBJECT(new_store));
250                 }
251         }
252         return TRUE;
253 }
254
255 gboolean 
256 category_list()
257 {
258         GtkWidget *dialog;
259         GtkWidget *tree_view;
260         GtkWidget *sw;
261         GtkWidget *btn_edit;
262         GtkWidget *btn_add;
263         GtkTreeViewColumn *column;
264         GtkCellRenderer *renderer;
265         GtkListStore *store;
266
267         dialog = gtk_dialog_new_with_buttons(_("POI Categories"),
268                                              GTK_WINDOW(_window),
269                                              GTK_DIALOG_MODAL, GTK_STOCK_OK,
270                                              GTK_RESPONSE_ACCEPT, NULL);
271
272 #ifdef WITH_OSSO
273         /* Enable the help button. */
274         ossohelp_dialog_help_enable(GTK_DIALOG(dialog), HELP_ID_POICAT, _osso);
275 #endif
276
277         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
278                           btn_edit = gtk_button_new_with_label(_("Edit")));
279
280         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
281                           btn_add = gtk_button_new_with_label(_("Add")));
282
283         store = poi_category_generate_store();
284
285         if (!store)
286                 return TRUE;
287
288         sw = gtk_scrolled_window_new(NULL, NULL);
289         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
290         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), sw, TRUE, TRUE, 0);
291
292         tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
293         /* Maemo-related? */
294         g_object_set(tree_view, "allow-checkbox-mode", FALSE, NULL);
295         gtk_container_add(GTK_CONTAINER(sw), tree_view);
296
297         gtk_tree_selection_set_mode(gtk_tree_view_get_selection (GTK_TREE_VIEW(tree_view)), GTK_SELECTION_SINGLE);
298         gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
299
300         renderer = gtk_cell_renderer_text_new();
301         column = gtk_tree_view_column_new_with_attributes(_("ID"), renderer, "text", CAT_ID, NULL);
302         gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
303         gtk_tree_view_column_set_max_width(column, 1);
304
305         renderer = gtk_cell_renderer_toggle_new();
306         g_signal_connect(renderer, "toggled", G_CALLBACK(category_toggled), store);
307         column = gtk_tree_view_column_new_with_attributes(_("Enabled"), renderer, "active", CAT_ENABLED, NULL);
308         gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
309         gtk_tree_view_column_set_sort_column_id (column, CAT_ENABLED);
310
311         g_object_unref(G_OBJECT(store));
312
313         renderer = gtk_cell_renderer_text_new();
314         column = gtk_tree_view_column_new_with_attributes(_("Label"), renderer, "text", CAT_LABEL, NULL);
315         gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
316         gtk_tree_view_column_set_sort_column_id (column, CAT_LABEL);
317
318         renderer = gtk_cell_renderer_text_new();
319         column = gtk_tree_view_column_new_with_attributes(_("Description"), renderer, "text", CAT_DESC, NULL);
320         gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
321
322         renderer = gtk_cell_renderer_text_new();
323         column = gtk_tree_view_column_new_with_attributes(_("# POIs"), renderer, "text", CAT_POI_CNT, NULL);
324         gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
325         gtk_tree_view_column_set_sort_column_id (column, CAT_POI_CNT);
326
327         gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
328
329         g_signal_connect(G_OBJECT(btn_edit), "clicked", G_CALLBACK(category_edit), tree_view);
330         g_signal_connect(G_OBJECT(btn_add), "clicked", G_CALLBACK(category_add), tree_view);
331
332         gtk_widget_show_all(dialog);
333         while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
334                 break;
335         }
336         gtk_widget_destroy(dialog);
337
338         return TRUE;
339 }
340
341 gboolean 
342 menu_cb_category(GtkAction * action)
343 {
344
345         if (category_list())
346                 map_force_redraw();
347
348         return TRUE;
349 }
350
351 gboolean 
352 poi_delete_confirm(GtkWidget * widget, delete_poi * dpoi)
353 {
354 GtkWidget *dialog;
355 guint i;
356 gchar *buffer;
357
358 buffer = g_strdup_printf("%s\n%s", _("Delete POI?"), dpoi->txt_label);
359 dialog = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
360 g_free(buffer);
361 i = gtk_dialog_run(GTK_DIALOG(dialog));
362 gtk_widget_destroy(GTK_WIDGET(dialog));
363
364 if (i == GTK_RESPONSE_OK) {
365         if (poi_delete(dpoi)==FALSE) {
366                 popup_error(_window, _("Problem deleting POI"));
367         } else {
368                 gtk_widget_hide_all(dpoi->dialog);
369                 map_force_redraw();
370         }
371 }
372 return TRUE;
373 }
374
375 gboolean 
376 poi_select(guint unitx, guint unity, poi_info *poi)
377 {
378 GtkWidget *dialog;
379 GtkWidget *list;
380 GtkWidget *sw;
381 GtkTreeViewColumn *column;
382 GtkCellRenderer *renderer;
383 GtkListStore *store;
384 GtkTreeIter iter;
385 gboolean selected = FALSE;
386 guint num_cats;
387
388 if (poi_get_list(unitx, unity, &store, &num_cats)==FALSE)
389         return FALSE;
390
391 switch (num_cats) {
392 case 0:
393         MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
394         g_object_unref(G_OBJECT(store));
395         return FALSE;
396         break;
397 case 1:
398         gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
399         gtk_tree_model_get(GTK_TREE_MODEL(store),
400                         &iter,
401                         POI_POIID, &(poi->poi_id),
402                         POI_CATID, &(poi->cat_id),
403                         POI_LAT, &(poi->lat),
404                         POI_LON, &(poi->lon),
405                         POI_LABEL, &(poi->label),
406                         POI_DESC, &(poi->desc), -1);
407         g_object_unref(G_OBJECT(store));
408         return TRUE;
409 break;
410 }
411
412 /* There are at least 2 matching POI's - let the user select one. */
413 dialog = gtk_dialog_new_with_buttons(_("Select POI"),
414                                      GTK_WINDOW(_window),
415                                      GTK_DIALOG_MODAL, GTK_STOCK_OK,
416                                      GTK_RESPONSE_ACCEPT,
417                                      GTK_STOCK_CANCEL,
418                                      GTK_RESPONSE_REJECT, NULL);
419
420 gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
421
422 sw = gtk_scrolled_window_new(NULL, NULL);
423 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
424 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
425 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), sw, TRUE, TRUE, 0);
426
427 list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
428 gtk_container_add(GTK_CONTAINER(sw), list);
429 g_object_unref(G_OBJECT(store));
430
431 gtk_tree_selection_set_mode(gtk_tree_view_get_selection (GTK_TREE_VIEW(list)), GTK_SELECTION_SINGLE);
432 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), TRUE);
433 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list), TRUE);
434 gtk_tree_view_set_search_column (GTK_TREE_VIEW (list), POI_LABEL);
435
436 renderer = gtk_cell_renderer_text_new();
437 column = gtk_tree_view_column_new_with_attributes(_("Location"), renderer, "text", POI_LATLON, NULL);
438 gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
439
440 renderer = gtk_cell_renderer_text_new();
441 column = gtk_tree_view_column_new_with_attributes(_("Label"), renderer, "text", POI_LABEL, NULL);
442 gtk_tree_view_column_set_sort_column_id (column, POI_LABEL);
443 gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
444
445 renderer = gtk_cell_renderer_text_new();
446 column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, "text", POI_CATLAB, NULL);
447 gtk_tree_view_column_set_sort_column_id (column, POI_CATLAB);
448 gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
449
450 gtk_widget_show_all(dialog);
451
452 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
453         if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(list)), NULL, &iter)) {
454                 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, POI_POIID, &(poi->poi_id), -1);
455                 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, POI_CATID, &(poi->cat_id), -1);
456                 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, POI_LAT, &(poi->lat), -1);
457                 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, POI_LON, &(poi->lon), -1);
458                 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, POI_LABEL, &(poi->label), -1);
459                 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, POI_DESC, &(poi->desc), -1);
460                 selected = TRUE;
461                 break;
462         } else {
463                 popup_error(dialog, _("Select one POI from the list."));
464         }
465 }
466
467 gtk_widget_destroy(dialog);
468 return selected;
469 }
470
471 static void 
472 poi_populate_cat_combo(GtkWidget * cmb_category, guint cat_id)
473 {
474 GtkTreeIter active;
475 GtkListStore *store;
476 gboolean has_active = FALSE;
477
478 store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)));
479 gtk_list_store_clear(store);
480
481 while (SQLITE_ROW == sqlite3_step(poisql.selall_cat)) {
482         GtkTreeIter iter;
483         guint cid = sqlite3_column_int(poisql.selall_cat, 0);
484         gtk_list_store_append(store, &iter);
485         gtk_list_store_set(store, &iter, 0, cid, 1, sqlite3_column_text(poisql.selall_cat, 1), -1);
486         if (cid == cat_id) {
487                 active = iter;
488                 has_active = TRUE;
489         }
490 }
491 sqlite3_reset(poisql.selall_cat);
492
493 if (!has_active)
494         gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &active);
495
496 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category), &active);
497 }
498
499 gboolean 
500 poi_edit_cat(GtkWidget * widget, PoiCategoryEditInfo * data)
501 {
502 if (category_list())
503         poi_populate_cat_combo(data->cmb_category, data->cat_id);
504 return TRUE;
505 }
506
507 gboolean 
508 poi_dialog(POIAction action, guint unitx, guint unity)
509 {
510 poi_info poi;
511 gchar slat1[10], slon1[10];
512 gchar *p_latlon;
513 GtkWidget *dialog;
514 GtkWidget *table;
515 GtkWidget *label;
516 GtkWidget *txt_label;
517 GtkWidget *cmb_category;
518 GtkWidget *txt_desc;
519 GtkWidget *btn_delete = NULL;
520 GtkWidget *btn_catedit;
521 GtkWidget *hbox;
522 GtkWidget *txt_scroll;
523 GtkTextBuffer *desc_txt;
524 GtkTextIter begin, end;
525 delete_poi dpoi = { NULL, NULL, 0 };
526 PoiCategoryEditInfo pcedit;
527
528 if (action == ACTION_EDIT_POI) {
529         if (!poi_select(unitx, unity, &poi)) {
530                 return FALSE;
531         }
532
533         dialog = gtk_dialog_new_with_buttons(_("Edit POI"),
534                                              GTK_WINDOW(_window),
535                                              GTK_DIALOG_MODAL,
536                                              GTK_STOCK_OK,
537                                              GTK_RESPONSE_ACCEPT, NULL);
538         gtk_container_add(GTK_CONTAINER
539                           (GTK_DIALOG(dialog)->action_area),
540                           btn_delete = gtk_button_new_with_label(_("Delete")));
541
542         dpoi.dialog = dialog;
543         dpoi.txt_label = g_strdup(poi.label);
544         dpoi.id = poi.poi_id;
545
546         g_signal_connect(G_OBJECT(btn_delete), "clicked",
547                          G_CALLBACK(poi_delete_confirm), &dpoi);
548
549         gtk_dialog_add_button(GTK_DIALOG(dialog),
550                               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
551 } else {
552         if (SQLITE_ROW == sqlite3_step(poisql.nextlabel_poi))
553                 poi.label = g_strdup_printf("Point%06d", sqlite3_column_int(poisql.nextlabel_poi, 0));
554         sqlite3_reset(poisql.nextlabel_poi);
555
556         unit2latlon(unitx, unity, poi.lat, poi.lon);
557
558         poi.poi_id = 0;
559         poi.cat_id = 0;
560         poi.desc = g_strdup("");
561
562         dialog = gtk_dialog_new_with_buttons(_("Add POI"),
563                                      GTK_WINDOW(_window),
564                                      GTK_DIALOG_MODAL,
565                                      GTK_STOCK_OK,
566                                      GTK_RESPONSE_ACCEPT,
567                                      GTK_STOCK_CANCEL,
568                                      GTK_RESPONSE_REJECT, NULL);
569 }
570
571 /* Set the p_latlon string. */
572 {
573         gchar tmp1[16], tmp2[16];
574         lat_format(poi.lat, tmp1);
575         lon_format(poi.lon, tmp2);
576         p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
577 }
578
579 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
580    table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
581
582 gtk_table_attach(GTK_TABLE(table),
583          label = gtk_label_new(_("Lat, Lon")),
584          0, 1, 0, 1, GTK_FILL, 0, 2, 4);
585 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
586
587 gtk_table_attach(GTK_TABLE(table),
588          label = gtk_label_new(p_latlon),
589          1, 3, 0, 1, GTK_FILL, 0, 2, 4);
590 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
591
592 gtk_table_attach(GTK_TABLE(table),
593          label = gtk_label_new(_("Label")),
594          0, 1, 1, 2, GTK_FILL, 0, 2, 4);
595 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
596 gtk_table_attach(GTK_TABLE(table),
597          txt_label = gtk_entry_new(),
598          1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
599
600 gtk_table_attach(GTK_TABLE(table),
601          label = gtk_label_new(_("Category")),
602          0, 1, 3, 4, GTK_FILL, 0, 2, 4);
603 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
604 gtk_table_attach(GTK_TABLE(table),
605          hbox = gtk_hbox_new(FALSE, 4),
606          1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
607 gtk_box_pack_start(GTK_BOX(hbox), cmb_category = gtk_combo_box_new_with_model(GTK_TREE_MODEL(gtk_list_store_new(2, G_TYPE_INT,  /* Category ID */
608                                 G_TYPE_STRING))),       /* Category Label */
609                                 FALSE, FALSE, 4);
610 /* Set up the view for the combo box. */
611 {
612         GtkCellRenderer *renderer;
613         renderer = gtk_cell_renderer_text_new();
614         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cmb_category), renderer, TRUE);
615         gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cmb_category), renderer, "text", 1, NULL);
616 }
617
618 gtk_box_pack_start(GTK_BOX(hbox),
619         btn_catedit = gtk_button_new_with_label(_("Edit Categories...")),
620         FALSE, FALSE, 4);
621
622 gtk_table_attach(GTK_TABLE(table),
623         label = gtk_label_new(_("Description")),
624         0, 1, 5, 6, GTK_FILL, 0, 2, 4);
625 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
626
627 txt_scroll = gtk_scrolled_window_new(NULL, NULL);
628 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll), GTK_SHADOW_IN);
629 gtk_table_attach(GTK_TABLE(table), txt_scroll, 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
630
631 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
632
633 txt_desc = gtk_text_view_new();
634 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
635
636 gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
637 gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
638
639 desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
640
641 /* label */
642 gtk_entry_set_text(GTK_ENTRY(txt_label), poi.label);
643
644 /* category */
645 poi_populate_cat_combo(cmb_category, poi.cat_id);
646
647 /* poi_desc */
648 gtk_text_buffer_set_text(desc_txt, poi.desc, -1);
649
650 /* Connect Signals */
651 pcedit.cmb_category = cmb_category;
652 pcedit.cat_id = poi.cat_id;
653 g_signal_connect(G_OBJECT(btn_catedit), "clicked", G_CALLBACK(poi_edit_cat), &pcedit);
654 gtk_widget_show_all(dialog);
655
656 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
657         gchar *poi_label = NULL;
658         gchar *poi_desc = NULL;
659         GtkTreeIter iter;
660
661         if (strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
662                 poi_label = gtk_entry_get_text(GTK_ENTRY(txt_label));
663         else {
664                 popup_error(dialog, _("Please specify a name for the POI."));
665                 continue;
666         }
667
668         if (!gtk_combo_box_get_active_iter
669             (GTK_COMBO_BOX(cmb_category), &iter)) {
670                 popup_error(dialog, _("Please specify a category for the POI."));
671                 continue;
672         }
673
674         gtk_text_buffer_get_iter_at_offset(desc_txt, &begin, 0);
675         gtk_text_buffer_get_end_iter(desc_txt, &end);
676         poi_desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
677
678         gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter, 0, &poi.cat_id, -1);
679
680         if (action == ACTION_EDIT_POI) {
681                 /* edit poi */
682                 if (poi_update(poi.poi_id, poi.cat_id, poi_label, poi_desc)==FALSE) {
683                         popup_error(_window, _("Problem updating POI"));
684                 } else {
685                         map_render_data();
686                 }
687         } else {
688                 /* add poi */
689                 g_ascii_dtostr(slat1, sizeof(slat1), poi.lat);
690                 g_ascii_dtostr(slon1, sizeof(slon1), poi.lon);
691                 if (poi_add(poi.lat, poi.lon, poi.cat_id, poi_label, poi_desc)==FALSE) {
692                         popup_error(_window, _("Problem adding POI"));
693                 } else {
694                         map_render_data();
695                 }
696         }
697         break;
698 }
699 g_free(dpoi.txt_label);
700
701 g_free(poi.label);
702 g_free(poi.desc);
703 g_free(p_latlon);
704
705 gtk_widget_hide_all(dialog);
706
707 return TRUE;
708 }
709
710 static gboolean
711 poi_quick_button_cb(GtkWidget *w, gpointer data)
712 {
713 gtk_widget_destroy(dialog_qp);
714 return TRUE;
715 }
716
717 gboolean
718 poi_quick_dialog(guint unitx, guint unity)
719 {
720 GtkWidget *table;
721 GtkWidget *buttons[POI_QUICK_BUTTONS];
722 guint x,y;
723 poi_info poi;
724
725 unit2latlon(unitx, unity, poi.lat, poi.lon);
726
727 dialog_qp = gtk_dialog_new_with_buttons(_("Quick POI"),
728                 GTK_WINDOW(_window),
729                     GTK_DIALOG_MODAL,
730                         GTK_STOCK_CANCEL,
731                         GTK_RESPONSE_REJECT,
732                         NULL);
733
734 #ifdef WITH_OSSO_NOTYET
735         /* Enable the help button. */
736         ossohelp_dialog_help_enable(GTK_DIALOG(dialog_qp), HELP_ID_POIQUICK, _osso);
737 #endif
738
739 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_qp)->vbox), table = gtk_table_new(3, 3, FALSE), TRUE, TRUE, 0);
740
741 gtk_table_set_col_spacings(table, 6);
742 gtk_table_set_row_spacings(table, 6);
743 gtk_table_set_homogeneous(table, TRUE);
744
745 for (x=1;x<=3;x++) {
746         for (y=1;y<=3;y++) {
747                 gchar *btnlabel;
748
749                 btnlabel=g_strdup_printf("(%d) %s", (x*y), "Poi name goes here...");
750                 buttons[x*y]=gtk_button_new_with_label(btnlabel);
751                 gtk_table_attach(GTK_TABLE(table), buttons[x*y], x-1, x, y-1, y, GTK_FILL, 0, 2, 4);
752                 g_free(btnlabel);
753                 g_signal_connect(G_OBJECT(buttons[x*y]), "clicked", G_CALLBACK(poi_quick_button_cb), NULL);
754         }
755 }
756
757 gtk_widget_show_all(dialog_qp);
758
759 if (GTK_RESPONSE_REJECT == gtk_dialog_run(GTK_DIALOG(dialog_qp))) {
760         gtk_widget_destroy(dialog_qp);
761         return TRUE;
762 }
763
764 return TRUE;
765 }