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