Contents of /trunk/src/misc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 216 - (show annotations)
Thu Nov 26 14:32:41 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 23420 byte(s)
Picker test
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of GPXView.
5 *
6 * GPXView is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GPXView is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <math.h>
21 #include <string.h>
22 #include <ctype.h>
23
24 #include <glib.h>
25 #include <glib/gstdio.h>
26
27 #include "gpxview.h"
28
29 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
30 #include <hildon/hildon-entry.h>
31 #include <hildon/hildon-touch-selector.h>
32 #include <hildon/hildon-picker-button.h>
33 #include <hildon/hildon-picker-dialog.h>
34 #endif
35
36 char strlastchr(char *str) {
37 return str[strlen(str)]-1;
38 }
39
40 /* make sure the entire path "dir" exists and create it if not */
41 int checkdir(char *dir) {
42 struct stat filestat;
43 char *p = dir, tmp;
44
45 /* don't try to create root dir */
46 if(p[0] == '/') p++;
47
48 do {
49 while(*p && *p != '/') p++;
50 tmp = *p;
51 *p = 0;
52
53 int err = stat(dir, &filestat);
54 if(err) {
55 if(mkdir(dir, S_IRWXU) != 0) {
56 perror("mkdir()");
57 *p++ = tmp;
58 return -1;
59 }
60 } else {
61 if(!filestat.st_mode & S_IFDIR) {
62 printf("File %s exists and is _no_ directory\n", dir);
63 *p++ = tmp;
64 return -1;
65 }
66 }
67
68 *p++ = tmp;
69 } while(tmp && strchr(p, '/'));
70
71 return 0;
72 }
73
74 void pos_lat_str(char *str, int len, float latitude) {
75 char *c = _("N");
76 float integral, fractional;
77
78 if(isnan(latitude))
79 str[0] = 0;
80 else {
81 if(latitude < 0) { latitude = fabs(latitude); c = _("S"); }
82 fractional = modff(latitude, &integral);
83
84 snprintf(str, len, "%s %02d° %06.3f'", c, (int)integral, fractional*60.0);
85 }
86 }
87
88 GtkWidget *pos_lat(float latitude, int size, int strikethrough) {
89 char str[32];
90
91 pos_lat_str(str, sizeof(str), latitude);
92 return gtk_label_attrib(str, size, strikethrough);
93 }
94
95 void pos_lon_str(char *str, int len, float longitude) {
96 char *c = _("E");
97 float integral, fractional;
98
99 if(isnan(longitude))
100 str[0] = 0;
101 else {
102 if(longitude < 0) { longitude = fabs(longitude); c = _("W"); }
103 fractional = modff(longitude, &integral);
104
105 snprintf(str, len, "%s %03d° %06.3f'", c, (int)integral, fractional*60.0);
106 }
107 }
108
109 GtkWidget *pos_lon(float longitude, int size, int strikethrough) {
110 char str[32];
111
112 pos_lon_str(str, sizeof(str), longitude);
113 return gtk_label_attrib(str, size, strikethrough);
114 }
115
116 float pos_parse_lat(char *str) {
117 int integral_int;
118 float fractional;
119 char c;
120
121 if(sscanf(str, "%c %d° %f'", &c, &integral_int, &fractional) == 3) {
122 c = toupper(c);
123
124 if(c != 'S' && c != 'N')
125 return NAN;
126
127 /* prevent -0.0 */
128 if(!integral_int && (fractional == 0.0))
129 return 0.0;
130
131 return ((c == 'S')?-1:+1) * (integral_int + fractional/60.0);
132 }
133
134 return NAN;
135 }
136
137 float pos_parse_lon(char *str) {
138 int integral_int;
139 float fractional;
140 char c;
141
142 if(sscanf(str, "%c %d° %f'", &c, &integral_int, &fractional) == 3) {
143 c = toupper(c);
144
145 /* O is german "Ost" for "East" */
146 if(c != 'E' && c != 'W' && c != 'O')
147 return NAN;
148
149 /* prevent -0.0 */
150 if(!integral_int && (fractional == 0.0))
151 return 0.0;
152
153 return ((c == 'W')?-1:+1) * (integral_int + fractional/60.0);
154 }
155
156 return NAN;
157 }
158
159 const char *pos_get_bearing_str(pos_t from, pos_t to) {
160 static const char *bear_str[]={
161 "N", "NE", "E", "SE", "S", "SW", "W", "NW", "" };
162
163 float bearing = gpx_pos_get_bearing(from, to);
164 if(!isnan(bearing)) {
165 int idx = (bearing+22.5)/45.0;
166 /* make sure we stay in icon bounds */
167 while(idx < 0) idx += 8;
168 while(idx > 7) idx -= 8;
169 return _(bear_str[idx]);
170 }
171
172 return bear_str[8]; // empty string
173 }
174
175 /* the maemo font size is quite huge, so we adjust some fonts */
176 /* differently on maemo and non-maemo. Basically "BIG" does nothing */
177 /* on maemo and "SMALL" only does something on maemo */
178 #ifdef USE_MAEMO
179 #define MARKUP_SMALL "<span size='small'>%s</span>"
180 GtkWidget *gtk_label_small(char *str) {
181 GtkWidget *label = gtk_label_new("");
182 char *markup = g_markup_printf_escaped(MARKUP_SMALL, str);
183 gtk_label_set_markup(GTK_LABEL(label), markup);
184 g_free(markup);
185 return label;
186 }
187 #else
188 #define MARKUP_BIG "<span size='x-large'>%s</span>"
189 GtkWidget *gtk_label_big(char *str) {
190 GtkWidget *label = gtk_label_new("");
191 char *markup = g_markup_printf_escaped(MARKUP_BIG, str);
192 gtk_label_set_markup(GTK_LABEL(label), markup);
193 g_free(markup);
194 return label;
195 }
196 #endif
197
198 void gtk_label_attrib_set(GtkWidget *label,
199 char *str, int size, int strikethrough) {
200 char format[80];
201
202 snprintf(format, sizeof(format), "<span%s%s%s>%%s</span>",
203 #ifdef USE_MAEMO
204 (size==SIZE_SMALL)?" size='small'":"",
205 #else
206 (size==SIZE_BIG)?" size='x-large'":"",
207 #endif
208 strikethrough?" strikethrough='yes'":"",
209 (strikethrough==STRIKETHROUGH_RED)?" strikethrough_color='red'":"");
210
211 char *markup = g_markup_printf_escaped(format, str);
212 // printf("markup = %s\n", markup);
213 gtk_label_set_markup(GTK_LABEL(label), markup);
214 g_free(markup);
215 }
216
217 GtkWidget *gtk_label_attrib(char *str, int size, int strikethrough) {
218 GtkWidget *label = gtk_label_new("");
219 gtk_label_attrib_set(label, str, size, strikethrough);
220 return label;
221 }
222
223 GtkWidget *gtk_button_attrib(char *str, int size, int strikethrough) {
224 GtkWidget *button = gtk_button_new_with_label("");
225 gtk_label_attrib_set(gtk_bin_get_child(GTK_BIN(button)),
226 str, size, strikethrough);
227 return button;
228 }
229
230 void textbox_disable(GtkWidget *widget) {
231 gtk_editable_set_editable(GTK_EDITABLE(widget), FALSE);
232 gtk_widget_set_sensitive(widget, FALSE);
233 }
234
235 void textbox_enable(GtkWidget *widget) {
236 gtk_widget_set_sensitive(widget, TRUE);
237 gtk_editable_set_editable(GTK_EDITABLE(widget), TRUE);
238 }
239
240 pos_t *get_pos(appdata_t *appdata) {
241 pos_t *pos = &appdata->home;
242
243 if(appdata->active_location) {
244 int i = appdata->active_location-1;
245 location_t *loc = appdata->location;
246 while(i--) loc = loc->next;
247 pos = &loc->pos;
248 }
249
250 if(appdata->use_gps) {
251 pos = gps_get_pos(appdata);
252
253 if(!pos) pos = &appdata->gps; /* use saved position */
254 else appdata->gps = *pos; /* save position */
255 }
256 return pos;
257 }
258
259 void distance_str(char *str, int len, float dist, gboolean imperial) {
260 if(isnan(dist))
261 snprintf(str, len, "---");
262 else if(imperial) {
263 /* 1 mil = 1760 yd = 5280 ft ... */
264 if(dist<0.018) snprintf(str, len, "%.1f ft", dist*5280.0);
265 else if(dist<0.055) snprintf(str, len, "%.1f yd", dist*1760.0);
266 else if(dist<0.55) snprintf(str, len, "%.0f yd", dist*1760.0);
267 else if(dist<10.0) snprintf(str, len, "%.2f mi", dist);
268 else if(dist<100.0) snprintf(str, len, "%.1f mi", dist);
269 else snprintf(str, len, "%.0f mi", dist);
270 } else {
271 if(dist<0.01) snprintf(str, len, "%.2f m", dist*1000.0);
272 else if(dist<0.1) snprintf(str, len, "%.1f m", dist*1000.0);
273 else if(dist<1.0) snprintf(str, len, "%.0f m", dist*1000.0);
274 else if(dist<100.0) snprintf(str, len, "%.1f km", dist);
275 else snprintf(str, len, "%.0f km", dist);
276 }
277 }
278
279 /* return distance in miles or kilometers */
280 float distance_parse(char *str, gboolean imperial) {
281 char unit[4];
282 float val = NAN;
283
284 if(sscanf(str, "%f %3s", &val, unit) == 2) {
285 gboolean fimp = FALSE;
286
287 if(strcasecmp(unit, "ft") == 0) { fimp = TRUE; val /= 5280.0; }
288 else if(strcasecmp(unit, "yd") == 0) { fimp = TRUE; val /= 1760.0; }
289 else if(strcasecmp(unit, "mi") == 0) { fimp = TRUE; }
290 else if(strcasecmp(unit, "m") == 0) { fimp = FALSE; val /= 1000.0; }
291 else if(strcasecmp(unit, "km") == 0) { fimp = FALSE; }
292 else val = NAN;
293
294 /* found imperial and metric requested? convert miles into kilometers */
295 if(fimp & !imperial) val *= 1.609344;
296
297 /* found metric and imperial requested? convert kilometers into miles */
298 if(!fimp & imperial) val /= 1.609344;
299 }
300 return val;
301 }
302
303 static gboolean mark(GtkWidget *widget, gboolean valid) {
304 gtk_widget_set_state(widget, valid?GTK_STATE_NORMAL:TAG_STATE);
305 return valid;
306 }
307
308 static void callback_modified_lat(GtkWidget *widget, gpointer data ) {
309 float i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(widget)));
310 mark(widget, !isnan(i));
311 }
312
313 /* a entry that is colored red when being "active" */
314 GtkWidget *lat_entry_new(float lat) {
315 GdkColor color;
316
317 GtkWidget *widget = entry_new();
318 gdk_color_parse("#ff0000", &color);
319 gtk_widget_modify_text(widget, TAG_STATE, &color);
320
321 char str[32];
322 pos_lat_str(str, sizeof(str), lat);
323 gtk_entry_set_text(GTK_ENTRY(widget), str);
324
325 g_signal_connect(G_OBJECT(widget), "changed",
326 G_CALLBACK(callback_modified_lat), NULL);
327
328 return widget;
329 }
330
331 static void callback_modified_lon(GtkWidget *widget, gpointer data ) {
332 float i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(widget)));
333 mark(widget, !isnan(i));
334 }
335
336 /* a entry that is colored red when filled with invalid coordinate */
337 GtkWidget *lon_entry_new(float lon) {
338 GdkColor color;
339
340 GtkWidget *widget = entry_new();
341 // gtk_entry_set_width_chars(GTK_ENTRY(widget), 14);
342
343 gdk_color_parse("#ff0000", &color);
344 gtk_widget_modify_text(widget, TAG_STATE, &color);
345
346 char str[32];
347 pos_lon_str(str, sizeof(str), lon);
348 gtk_entry_set_text(GTK_ENTRY(widget), str);
349
350 g_signal_connect(G_OBJECT(widget), "changed",
351 G_CALLBACK(callback_modified_lon), NULL);
352
353 return widget;
354 }
355
356
357 float lat_get(GtkWidget *widget) {
358 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
359 return pos_parse_lat(p);
360 }
361
362 float lon_get(GtkWidget *widget) {
363 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
364 return pos_parse_lon(p);
365 }
366
367 static void callback_modified_dist(GtkWidget *widget, gpointer data ) {
368 /* don't care for metric/imperial since we only want to know if this */
369 /* is parseable at all */
370 float i = distance_parse((char*)gtk_entry_get_text(GTK_ENTRY(widget)), FALSE);
371 mark(widget, !isnan(i));
372 }
373
374 /* a entry that is colored red when filled with invalid distance */
375 GtkWidget *dist_entry_new(float dist, gboolean mil) {
376 GdkColor color;
377 GtkWidget *widget = entry_new();
378 gdk_color_parse("#ff0000", &color);
379 gtk_widget_modify_text(widget, TAG_STATE, &color);
380
381 char str[32];
382 distance_str(str, sizeof(str), dist, mil);
383 gtk_entry_set_text(GTK_ENTRY(widget), str);
384
385 g_signal_connect(G_OBJECT(widget), "changed",
386 G_CALLBACK(callback_modified_dist), NULL);
387
388 return widget;
389 }
390
391 float dist_get(GtkWidget *widget, gboolean mil) {
392 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget));
393 return distance_parse(p, mil);
394 }
395
396 #ifndef USE_MAEMO
397 #ifdef ENABLE_BROWSER_INTERFACE
398 #include <libgnome/gnome-url.h>
399
400 int browser_url(appdata_t *appdata, char *url) {
401 /* taken from gnome-open, part of libgnome */
402 GError *err = NULL;
403 gnome_url_show(url, &err);
404 return 0;
405 }
406 #endif
407 #endif
408
409 /* recursively remove an entire file system */
410 void rmdir_recursive(char *path) {
411 GDir *dir = g_dir_open(path, 0, NULL);
412 if(dir) {
413 const char *name = g_dir_read_name(dir);
414 while(name) {
415 char *fullname = g_strdup_printf("%s/%s", path, name);
416 // printf("deleting %s\n", fullname);
417
418 if(g_file_test(fullname, G_FILE_TEST_IS_DIR))
419 rmdir_recursive(fullname);
420 else if(g_file_test(fullname, G_FILE_TEST_IS_REGULAR))
421 g_remove(fullname);
422
423 g_free(fullname);
424 name = g_dir_read_name(dir);
425 }
426
427 g_dir_close(dir);
428 }
429 g_rmdir(path);
430 }
431
432 #ifdef ENABLE_BROWSER_INTERFACE
433 static void on_link_clicked(GtkButton *button, gpointer data) {
434 appdata_t *appdata = (appdata_t*)data;
435 char *url = g_object_get_data(G_OBJECT(button), "url");
436 if(url) browser_url(appdata, url);
437 }
438 #endif
439
440 /* a button containing a weblink */
441 GtkWidget *link_button_attrib(appdata_t *appdata, char *str, char *url,
442 int size, int strikethrough) {
443
444 #ifdef ENABLE_BROWSER_INTERFACE
445 if(url) {
446 GtkWidget *button = gtk_button_attrib(str, size, strikethrough);
447 g_object_set_data(G_OBJECT(button), "url", url);
448 gtk_signal_connect(GTK_OBJECT(button), "clicked",
449 (GtkSignalFunc)on_link_clicked, appdata);
450
451 return button;
452 }
453 #endif
454 return gtk_label_attrib(str, size, strikethrough);
455 }
456
457 #ifdef ENABLE_BROWSER_INTERFACE
458 static void on_link_id_clicked(GtkButton *button, gpointer data) {
459 appdata_t *appdata = (appdata_t*)data;
460
461 unsigned int id = (unsigned int)g_object_get_data(G_OBJECT(button), "id");
462 char *type = g_object_get_data(G_OBJECT(button), "type");
463
464 char *url = g_strdup_printf("http://www.geocaching.com/%s?id=%u",
465 type, id);
466
467 if(url) {
468 browser_url(appdata, url);
469 g_free(url);
470 }
471 }
472 #endif
473
474 GtkWidget *link_button_by_id(appdata_t *appdata, char *str,
475 const char *type, int id) {
476
477 #ifdef ENABLE_BROWSER_INTERFACE
478 if(id) {
479 GtkWidget *ref = gtk_button_new_with_label(str);
480 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR == 5)
481 // hildon_gtk_widget_set_theme_size(ref,
482 // (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
483 #endif
484 g_object_set_data(G_OBJECT(ref), "id", (gpointer)id);
485 g_object_set_data(G_OBJECT(ref), "type", (gpointer)type);
486 gtk_signal_connect(GTK_OBJECT(ref), "clicked",
487 GTK_SIGNAL_FUNC(on_link_id_clicked), appdata);
488
489 return ref;
490 }
491 #endif
492 return gtk_label_new(str);
493 }
494
495
496 GtkWidget *link_icon_button_by_id(appdata_t *appdata, GtkWidget *icon,
497 const char *type, int id) {
498
499 #ifdef ENABLE_BROWSER_INTERFACE
500 if(id) {
501 GtkWidget *ref = gtk_button_new();
502 gtk_button_set_image(GTK_BUTTON(ref), icon);
503
504 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR == 5)
505 // hildon_gtk_widget_set_theme_size(ref,
506 // (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
507 #endif
508 g_object_set_data(G_OBJECT(ref), "id", (gpointer)id);
509 g_object_set_data(G_OBJECT(ref), "type", (gpointer)type);
510 gtk_signal_connect(GTK_OBJECT(ref), "clicked",
511 GTK_SIGNAL_FUNC(on_link_id_clicked), appdata);
512
513 return ref;
514 }
515 #endif
516 return icon;
517 }
518
519 /* left aligned, word wrapped multiline widget */
520 GtkWidget *simple_text_widget(char *text) {
521 GtkWidget *label = gtk_label_new(text);
522
523 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
524 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD);
525 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
526
527 return label;
528 }
529
530
531 /* a label that is left aligned */
532 GtkWidget *left_label_new(char *str) {
533 GtkWidget *widget = gtk_label_new(str);
534 gtk_misc_set_alignment(GTK_MISC(widget), 0.0f, 0.5f);
535 return widget;
536 }
537
538 static void pos_set(GtkMenuItem *item, float lat, float lon) {
539 char str[32];
540
541 pos_lat_str(str, sizeof(str)-1, lat);
542 GtkWidget *lat_entry = g_object_get_data(G_OBJECT(item), "lat_entry");
543 gtk_entry_set_text(GTK_ENTRY(lat_entry), str);
544
545 pos_lon_str(str, sizeof(str)-1, lon);
546 GtkWidget *lon_entry = g_object_get_data(G_OBJECT(item), "lon_entry");
547 gtk_entry_set_text(GTK_ENTRY(lon_entry), str);
548 }
549
550 static void cb_gps(GtkMenuItem *item, gpointer data) {
551 appdata_t *appdata = (appdata_t*)data;
552
553 pos_t *refpos = get_pos(appdata);
554 if(!refpos) pos_set(item, NAN, NAN);
555 else pos_set(item, refpos->lat, refpos->lon);
556 }
557
558 static void cb_geomath(GtkMenuItem *item, gpointer data) {
559 appdata_t *appdata = (appdata_t*)data;
560
561 pos_set(item, appdata->geomath.lat, appdata->geomath.lon);
562 }
563
564 #ifdef ENABLE_OSM_GPS_MAP
565 static void cb_map(GtkMenuItem *item, gpointer data) {
566 appdata_t *appdata = (appdata_t*)data;
567
568 pos_set(item, appdata->map.pos.lat, appdata->map.pos.lon);
569 }
570 #endif
571
572 static const gchar *menu_item_get_label(GtkMenuItem *menu_item) {
573 GList *children, *l;
574 GtkWidget *child;
575 children = gtk_container_get_children (GTK_CONTAINER (menu_item));
576 for (l = g_list_first (children); l != NULL;
577 l = g_list_next (l)) {
578 child = (GtkWidget *)l->data;
579 if (GTK_IS_LABEL (child)) {
580 return gtk_label_get_label (GTK_LABEL (child));
581 }
582 }
583 return NULL;
584 }
585
586 static void cb_cache(GtkMenuItem *item, gpointer data) {
587 const char *label = menu_item_get_label(item);
588 appdata_t *appdata = (appdata_t*)data;
589
590 cache_t *cache = appdata->cur_cache;
591 g_assert(cache);
592
593 if(!strcmp(label, cache->id))
594 pos_set(item, cache->pos.lat, cache->pos.lon);
595 else {
596 wpt_t *wpt = cache->wpt;
597 while(wpt) {
598 if(!strcmp(label, wpt->id)) {
599 pos_set(item, wpt->pos.lat, wpt->pos.lon);
600 return;
601 }
602
603 wpt = wpt->next;
604 }
605 }
606 }
607
608 static GtkWidget *menu_add(GtkWidget *menu, appdata_t *appdata,
609 GtkWidget *icon, char *menu_str,
610 void(*func)(GtkMenuItem*, gpointer),
611 GtkWidget *lon_entry, GtkWidget *lat_entry) {
612
613 GtkWidget *item = gtk_image_menu_item_new_with_label(menu_str);
614
615 if(icon)
616 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), icon);
617
618 g_object_set_data(G_OBJECT(item), "lat_entry", (gpointer)lat_entry);
619 g_object_set_data(G_OBJECT(item), "lon_entry", (gpointer)lon_entry);
620
621 if(func)
622 gtk_signal_connect(GTK_OBJECT(item), "activate",
623 (GtkSignalFunc)func, appdata);
624
625 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
626
627 return item;
628 }
629
630 static GtkWidget *popup_menu_create(appdata_t *appdata,
631 GtkWidget *lat_entry, GtkWidget *lon_entry) {
632 GtkWidget *menu = gtk_menu_new();
633
634 menu_add(menu, appdata, icon_get_widget(ICON_POS, 18),
635 _("Current position (GPS)"), cb_gps, lon_entry, lat_entry);
636 menu_add(menu, appdata, icon_get_widget(ICON_POS, 19),
637 _("Geomath projection"), cb_geomath, lon_entry, lat_entry);
638 #ifdef ENABLE_OSM_GPS_MAP
639 menu_add(menu, appdata, icon_get_widget(ICON_POS, 20),
640 _("Map position"), cb_map, lon_entry, lat_entry);
641 #endif
642
643 printf("popup cache present: %s\n", appdata->cur_cache?"Yes":"No");
644
645 if(appdata->cur_cache) {
646 cache_t *cache = appdata->cur_cache;
647
648 if(!isnan(cache->pos.lat) && !isnan(cache->pos.lon)) {
649 menu_add(menu, appdata, icon_get_widget(ICON_POS, cache->type + 6),
650 cache->id, cb_cache, lon_entry, lat_entry);
651 }
652
653 printf("appending cache waypoints\n");
654 wpt_t *wpt = cache->wpt;
655 while(wpt) {
656 GtkWidget *icon = NULL;
657 if(wpt->sym != WPT_SYM_UNKNOWN)
658 icon = icon_get_widget(ICON_POS, wpt->sym);
659
660 menu_add(menu, appdata, icon, wpt->id, cb_cache,
661 lon_entry, lat_entry);
662
663 wpt = wpt->next;
664 }
665 }
666
667 gtk_widget_show_all(menu);
668
669 return menu;
670 }
671
672 static gint on_popup_button_press(GtkWidget *button, GdkEventButton *event,
673 gpointer data) {
674
675 if(event->type == GDK_BUTTON_PRESS) {
676 GtkWidget *menu = g_object_get_data(G_OBJECT(button), "menu");
677
678 /* draw a popup menu */
679 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
680 event->button, event->time);
681 return TRUE;
682 }
683 return FALSE;
684 }
685
686 static void on_popup_destroy(GtkWidget *widget, gpointer user_data ) {
687 GtkWidget *menu = g_object_get_data(G_OBJECT(widget), "menu");
688 gtk_widget_destroy(menu);
689 }
690
691 GtkWidget *coo_popup(appdata_t *appdata,
692 GtkWidget *lat_entry, GtkWidget *lon_entry) {
693
694 GtkWidget *button = gtk_button_new();
695 #ifdef FREMANTLE
696 hildon_gtk_widget_set_theme_size(button,
697 (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
698 #endif
699
700 gtk_button_set_image(GTK_BUTTON(button), icon_get_widget(ICON_POS, 17));
701
702 gtk_widget_set_tooltip_text(button, _("Preset coordinates"));
703
704 gtk_signal_connect(GTK_OBJECT(button), "button-press-event",
705 (GtkSignalFunc)on_popup_button_press, appdata);
706
707 gtk_signal_connect(GTK_OBJECT(button), "destroy",
708 (GtkSignalFunc)on_popup_destroy, appdata);
709
710 g_object_set_data(G_OBJECT(button), "menu",
711 popup_menu_create(appdata, lat_entry, lon_entry));
712
713 return button;
714 }
715
716 GtkWidget *entry_new(void) {
717 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
718 return gtk_entry_new();
719 #else
720 return hildon_entry_new(HILDON_SIZE_AUTO);
721 #endif
722 }
723
724 gboolean pos_differ(pos_t *pos1, pos_t *pos2) {
725 int lat1 = (60000 * pos1->lat)+0.5, lon1 = (60000 * pos1->lon)+0.5;
726 int lat2 = (60000 * pos2->lat)+0.5, lon2 = (60000 * pos2->lon)+0.5;
727
728 return((lat1 != lat2) || (lon1 != lon2));
729 }
730
731 #ifdef FREMANTLE
732 void selection_changed (HildonTouchSelector * selector,
733 gpointer *user_data) {
734 gchar *current_selection = NULL;
735
736 current_selection = hildon_touch_selector_get_current_text (selector);
737 g_debug ("Current selection : %s", current_selection);
738 }
739
740 static GtkWidget *create_customized_selector() {
741 GtkWidget *selector = NULL;
742 GSList *icon_list = NULL;
743 GtkListStore *store_icons = NULL;
744 GSList *item = NULL;
745 GtkCellRenderer *renderer = NULL;
746 HildonTouchSelectorColumn *column = NULL;
747
748 selector = hildon_touch_selector_new ();
749
750 icon_list = gtk_stock_list_ids ();
751
752 store_icons = gtk_list_store_new (1, G_TYPE_STRING);
753 for (item = icon_list; item; item = g_slist_next (item)) {
754 GtkTreeIter iter;
755 gchar *label = item->data;
756
757 gtk_list_store_append (store_icons, &iter);
758 gtk_list_store_set (store_icons, &iter, 0, label, -1);
759 g_free (label);
760 }
761 g_slist_free (icon_list);
762
763 renderer = gtk_cell_renderer_pixbuf_new ();
764 gtk_cell_renderer_set_fixed_size (renderer, -1, 100);
765
766 column = hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector),
767 GTK_TREE_MODEL (store_icons),
768 renderer, "stock-id", 0, NULL);
769
770 g_object_set (G_OBJECT (column), "text-column", 0, NULL);
771
772 hildon_touch_selector_set_column_selection_mode (HILDON_TOUCH_SELECTOR (selector),
773 HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE);
774
775
776 g_signal_connect (G_OBJECT (selector), "changed",
777 G_CALLBACK (selection_changed), NULL);
778
779 return selector;
780 }
781
782 static gint on_picker_request(GtkWidget *button, GdkEventButton *event,
783 gpointer data) {
784
785 if(event->type == GDK_BUTTON_PRESS) {
786 GtkWidget *dialog = hildon_picker_dialog_new(NULL);
787 GtkWidget *selector = create_customized_selector();
788 hildon_picker_dialog_set_selector(HILDON_PICKER_DIALOG(dialog),
789 HILDON_TOUCH_SELECTOR(selector));
790
791 hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR (selector), 1, -1);
792
793 gtk_widget_show_all(dialog);
794 gtk_dialog_run(GTK_DIALOG(dialog));
795 gtk_widget_destroy(dialog);
796
797 return TRUE;
798 }
799 return FALSE;
800 }
801
802 GtkWidget *picker_button_new(void) {
803 GtkWidget *button;
804
805 #if 1
806 button = gtk_button_new();
807 hildon_gtk_widget_set_theme_size(button,
808 (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
809
810 gtk_button_set_image(GTK_BUTTON(button), icon_get_widget(ICON_POS, 17));
811
812 gtk_signal_connect(GTK_OBJECT(button), "button-press-event",
813 (GtkSignalFunc)on_picker_request, NULL);
814
815 #else
816 button = hildon_picker_button_new(HILDON_SIZE_AUTO,
817 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
818
819 hildon_button_set_title(HILDON_BUTTON(button), "Test");
820 hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(button),
821 HILDON_TOUCH_SELECTOR(create_customized_selector()));
822 #endif
823
824 return button;
825 }
826 #endif