]> git.street.me.uk Git - andy/viking.git/blame - src/datasource_gps.c
Add support for acquiring OpenStreetMap Notes as GPX files.
[andy/viking.git] / src / datasource_gps.c
CommitLineData
7b3479e3
EB
1/*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3 *
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
a482007a 5 * Copyright (C) 2006, Alex Foobarian <foobarian@gmail.com>
d80e59ba 6 * Copyright (C) 2012, Rob Norris <rw_norris@hotmail.com>
7b3479e3
EB
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
8aad4ca3
GB
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
7b3479e3 26#include <string.h>
99163c34
RN
27#ifdef HAVE_UNISTD_H
28#include <unistd.h>
29#endif
4c77d5e0 30
99163c34 31#include <glib/gstdio.h>
7b3479e3 32#include <glib/gprintf.h>
4c77d5e0 33#include <glib/gi18n.h>
7b3479e3 34
d80e59ba 35#include "datasource_gps.h"
7b3479e3
EB
36#include "viking.h"
37#include "babel.h"
38#include "gpx.h"
39#include "acquire.h"
40
41static gboolean gps_acquire_in_progress = FALSE;
42
3f6db253 43static gint last_active = -1;
7f23d292 44static gboolean last_get_tracks = TRUE;
0d2b891f 45static gboolean last_get_routes = TRUE;
7f23d292 46static gboolean last_get_waypoints = TRUE;
8627bd99 47
307abf54 48static gpointer datasource_gps_init_func ( acq_vik_t *avt );
ed691ed1 49static void datasource_gps_get_cmd_string ( gpointer add_widgets_data_not_used, gchar **babelargs, gchar **input_file, gpointer not_used );
65f0ccab 50static void datasource_gps_cleanup ( gpointer user_data );
7b3479e3 51static void datasource_gps_progress ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w );
65f0ccab
AF
52static void datasource_gps_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data );
53static void datasource_gps_add_progress_widgets ( GtkWidget *dialog, gpointer user_data );
2b756ea0 54static void datasource_gps_off ( gpointer add_widgets_data_not_used, gchar **babelargs, gchar **input_file );
7b3479e3
EB
55
56VikDataSourceInterface vik_datasource_gps_interface = {
4c77d5e0
GB
57 N_("Acquire from GPS"),
58 N_("Acquired from GPS"),
805d282e 59 VIK_DATASOURCE_CREATENEWLAYER,
28c82d8b
EB
60 VIK_DATASOURCE_INPUTTYPE_NONE,
61 TRUE,
d2525524 62 TRUE,
b2aa700f 63 TRUE,
65f0ccab 64 (VikDataSourceInitFunc) datasource_gps_init_func,
92255687 65 (VikDataSourceCheckExistenceFunc) NULL,
65f0ccab 66 (VikDataSourceAddSetupWidgetsFunc) datasource_gps_add_setup_widgets,
7b3479e3 67 (VikDataSourceGetCmdStringFunc) datasource_gps_get_cmd_string,
eb3f9398 68 (VikDataSourceProcessFunc) a_babel_convert_from,
7b3479e3
EB
69 (VikDataSourceProgressFunc) datasource_gps_progress,
70 (VikDataSourceAddProgressWidgetsFunc) datasource_gps_add_progress_widgets,
2b756ea0
RN
71 (VikDataSourceCleanupFunc) datasource_gps_cleanup,
72 (VikDataSourceOffFunc) datasource_gps_off
7b3479e3
EB
73};
74
75/*********************************************************
76 * Definitions and routines for acquiring data from GPS
77 *********************************************************/
78
65f0ccab 79/* widgets in setup dialog specific to GPS */
7b3479e3
EB
80/* widgets in progress dialog specific to GPS */
81/* also counts needed for progress */
82typedef struct {
65f0ccab
AF
83 /* setup dialog */
84 GtkWidget *proto_l;
1bc1c05b 85 GtkWidget *proto_b;
65f0ccab 86 GtkWidget *ser_l;
1bc1c05b 87 GtkWidget *ser_b;
2b756ea0
RN
88 GtkWidget *off_request_l;
89 GtkCheckButton *off_request_b;
d6c58ab9
RN
90 GtkWidget *get_tracks_l;
91 GtkCheckButton *get_tracks_b;
0d2b891f
RN
92 GtkWidget *get_routes_l;
93 GtkCheckButton *get_routes_b;
d6c58ab9
RN
94 GtkWidget *get_waypoints_l;
95 GtkCheckButton *get_waypoints_b;
65f0ccab
AF
96
97 /* progress dialog */
7b3479e3
EB
98 GtkWidget *gps_label;
99 GtkWidget *ver_label;
100 GtkWidget *id_label;
101 GtkWidget *wp_label;
102 GtkWidget *trk_label;
0d2b891f 103 GtkWidget *rte_label;
7b3479e3 104 GtkWidget *progress_label;
0d2b891f 105 vik_gps_xfer_type progress_type;
65f0ccab
AF
106
107 /* state */
7b3479e3
EB
108 int total_count;
109 int count;
65f0ccab
AF
110} gps_user_data_t;
111
307abf54 112static gpointer datasource_gps_init_func ( acq_vik_t *avt )
65f0ccab
AF
113{
114 return g_malloc (sizeof(gps_user_data_t));
115}
7b3479e3 116
d80e59ba
RN
117/**
118 * datasource_gps_get_protocol:
119 *
120 * Method to get the communication protocol of the GPS device from the widget structure
121 */
122gchar* datasource_gps_get_protocol ( gpointer user_data )
123{
124 // Uses the list of supported devices
125 gps_user_data_t *w = (gps_user_data_t *)user_data;
126 last_active = gtk_combo_box_get_active(GTK_COMBO_BOX(w->proto_b));
127 if (a_babel_device_list)
128 return ((BabelDevice*)g_list_nth_data(a_babel_device_list, last_active))->name;
129
130 return NULL;
131}
132
133/**
134 * datasource_gps_get_descriptor:
135 *
136 * Method to get the descriptor from the widget structure
137 * "Everything is a file"
138 * Could actually be normal file or a serial port
139 */
140gchar* datasource_gps_get_descriptor ( gpointer user_data )
141{
142 gps_user_data_t *w = (gps_user_data_t *)user_data;
1bc1c05b
RN
143
144#if GTK_CHECK_VERSION (2, 24, 0)
145 return gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w->ser_b));
146#else
d80e59ba 147 return gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
1bc1c05b 148#endif
d80e59ba
RN
149}
150
151/**
152 * datasource_gps_get_do_tracks:
153 *
154 * Method to get the track handling behaviour from the widget structure
155 */
156gboolean datasource_gps_get_do_tracks ( gpointer user_data )
157{
158 gps_user_data_t *w = (gps_user_data_t *)user_data;
159 last_get_tracks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_tracks_b));
160 return last_get_tracks;
161}
162
0d2b891f
RN
163/**
164 * datasource_gps_get_do_routes:
165 *
166 * Method to get the route handling behaviour from the widget structure
167 */
168gboolean datasource_gps_get_do_routes ( gpointer user_data )
169{
170 gps_user_data_t *w = (gps_user_data_t *)user_data;
171 last_get_routes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_routes_b));
172 return last_get_routes;
173}
174
d80e59ba
RN
175/**
176 * datasource_gps_get_do_waypoints:
177 *
178 * Method to get the waypoint handling behaviour from the widget structure
179 */
180gboolean datasource_gps_get_do_waypoints ( gpointer user_data )
181{
182 gps_user_data_t *w = (gps_user_data_t *)user_data;
183 last_get_waypoints = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_waypoints_b));
184 return last_get_waypoints;
185}
186
ed691ed1 187static void datasource_gps_get_cmd_string ( gpointer user_data, gchar **babelargs, gchar **input_file, gpointer not_used )
7b3479e3 188{
cf7fdc15 189 char *device = NULL;
d6c58ab9 190 char *tracks = NULL;
0d2b891f 191 char *routes = NULL;
d6c58ab9 192 char *waypoints = NULL;
65f0ccab 193
7b3479e3
EB
194 if (gps_acquire_in_progress) {
195 *babelargs = *input_file = NULL;
196 }
65f0ccab
AF
197
198 gps_acquire_in_progress = TRUE;
199
d80e59ba 200 device = datasource_gps_get_protocol ( user_data );
2b756ea0 201
d80e59ba 202 if ( datasource_gps_get_do_tracks ( user_data ) )
d6c58ab9
RN
203 tracks = "-t";
204 else
205 tracks = "";
d80e59ba 206
0d2b891f
RN
207 if ( datasource_gps_get_do_routes ( user_data ) )
208 routes = "-r";
209 else
210 routes = "";
211
d80e59ba 212 if ( datasource_gps_get_do_waypoints ( user_data ) )
d6c58ab9
RN
213 waypoints = "-w";
214 else
215 waypoints = "";
216
0d2b891f 217 *babelargs = g_strdup_printf("-D 9 %s %s %s -i %s", tracks, routes, waypoints, device);
cf7fdc15
GB
218 /* device points to static content => no free */
219 device = NULL;
d6c58ab9 220 tracks = NULL;
0d2b891f 221 routes = NULL;
d6c58ab9
RN
222 waypoints = NULL;
223
d80e59ba 224 *input_file = g_strdup(datasource_gps_get_descriptor(user_data));
7b3479e3 225
4c77d5e0 226 g_debug(_("using cmdline '%s' and file '%s'\n"), *babelargs, *input_file);
7b3479e3
EB
227}
228
d80e59ba
RN
229/**
230 * datasource_gps_get_off:
231 *
232 * Method to get the off behaviour from the widget structure
233 */
234gboolean datasource_gps_get_off ( gpointer user_data )
235{
236 gps_user_data_t *w = (gps_user_data_t *)user_data;
237 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->off_request_b));
238}
2b756ea0
RN
239
240static void datasource_gps_off ( gpointer user_data, gchar **babelargs, gchar **input_file )
241{
2b756ea0
RN
242 char *ser = NULL;
243 char *device = NULL;
2b756ea0
RN
244 gps_user_data_t *w = (gps_user_data_t *)user_data;
245
246 if (gps_acquire_in_progress) {
247 *babelargs = *input_file = NULL;
248 }
249
250 /* See if we should turn off the device */
d80e59ba 251 if (!datasource_gps_get_off ( user_data )){
2b756ea0
RN
252 return;
253 }
254
78f6c63d
RN
255 if (!a_babel_device_list)
256 return;
8627bd99
GB
257 last_active = gtk_combo_box_get_active(GTK_COMBO_BOX(w->proto_b));
258 device = ((BabelDevice*)g_list_nth_data(a_babel_device_list, last_active))->name;
259 if (!strcmp(device, "garmin")) {
2b756ea0 260 device = "garmin,power_off";
4136d029 261 }
8627bd99 262 else if (!strcmp(device, "navilink")) {
4136d029
RN
263 device = "navilink,power_off";
264 }
265 else {
2b756ea0
RN
266 return;
267 }
268
269 *babelargs = g_strdup_printf("-i %s", device);
270 /* device points to static content => no free */
271 device = NULL;
272
1bc1c05b
RN
273#if GTK_CHECK_VERSION (2, 24, 0)
274 ser = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w->ser_b));
275#else
2b756ea0 276 ser = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
1bc1c05b 277#endif
2b756ea0
RN
278 *input_file = g_strdup(ser);
279}
280
281
65f0ccab 282static void datasource_gps_cleanup ( gpointer user_data )
7b3479e3 283{
65f0ccab 284 g_free ( user_data );
7b3479e3
EB
285 gps_acquire_in_progress = FALSE;
286}
287
d80e59ba
RN
288/**
289 * datasource_gps_clean_up:
290 *
291 * External method to tidy up
292 */
293void datasource_gps_clean_up ( gpointer user_data )
294{
295 datasource_gps_cleanup ( user_data );
296}
297
7b3479e3
EB
298static void set_total_count(gint cnt, acq_dialog_widgets_t *w)
299{
cf7fdc15 300 gchar *s = NULL;
7b3479e3 301 gdk_threads_enter();
b2aa700f 302 if (w->running) {
65f0ccab 303 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
97634600 304 const gchar *tmp_str;
0d2b891f
RN
305 switch (gps_data->progress_type) {
306 case WPT: tmp_str = ngettext("Downloading %d waypoint...", "Downloading %d waypoints...", cnt); gps_data->total_count = cnt; break;
307 case TRK: tmp_str = ngettext("Downloading %d trackpoint...", "Downloading %d trackpoints...", cnt); gps_data->total_count = cnt; break;
308 default:
309 {
310 // Maybe a gpsbabel bug/feature (upto at least v1.4.3 or maybe my Garmin device) but the count always seems x2 too many for routepoints
311 gint mycnt = (cnt / 2) + 1;
312 tmp_str = ngettext("Downloading %d routepoint...", "Downloading %d routepoints...", mycnt);
313 gps_data->total_count = mycnt;
314 break;
315 }
316 }
97634600 317 s = g_strdup_printf(tmp_str, cnt);
7b3479e3
EB
318 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
319 gtk_widget_show ( gps_data->progress_label );
7b3479e3 320 }
cf7fdc15 321 g_free(s); s = NULL;
7b3479e3
EB
322 gdk_threads_leave();
323}
324
325static void set_current_count(gint cnt, acq_dialog_widgets_t *w)
326{
cf7fdc15 327 gchar *s = NULL;
7b3479e3 328 gdk_threads_enter();
b2aa700f 329 if (w->running) {
65f0ccab 330 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
7b3479e3
EB
331
332 if (cnt < gps_data->total_count) {
0d2b891f
RN
333 switch (gps_data->progress_type) {
334 case WPT: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "waypoints"); break;
335 case TRK: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "trackpoints"); break;
336 default: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "routepoints"); break;
337 }
7b3479e3 338 } else {
0d2b891f
RN
339 switch (gps_data->progress_type) {
340 case WPT: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "waypoints"); break;
341 case TRK: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "trackpoints"); break;
342 default: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "routepoints"); break;
343 }
344 }
7b3479e3
EB
345 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
346 }
cf7fdc15 347 g_free(s); s = NULL;
7b3479e3
EB
348 gdk_threads_leave();
349}
350
351static void set_gps_info(const gchar *info, acq_dialog_widgets_t *w)
352{
cf7fdc15 353 gchar *s = NULL;
7b3479e3 354 gdk_threads_enter();
b2aa700f 355 if (w->running) {
4c77d5e0 356 s = g_strdup_printf(_("GPS Device: %s"), info);
65f0ccab 357 gtk_label_set_text ( GTK_LABEL(((gps_user_data_t *)w->user_data)->gps_label), s );
7b3479e3 358 }
cf7fdc15 359 g_free(s); s = NULL;
7b3479e3
EB
360 gdk_threads_leave();
361}
362
363/*
364 * This routine relies on gpsbabel's diagnostic output to display the progress information.
365 * These outputs differ when different GPS devices are used, so we will need to test
366 * them on several and add the corresponding support.
367 */
368static void datasource_gps_progress ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w )
369{
370 gchar *line;
65f0ccab 371 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
7b3479e3 372
7b3479e3
EB
373 switch(c) {
374 case BABEL_DIAG_OUTPUT:
375 line = (gchar *)data;
376
8d0586c6 377 gdk_threads_enter();
b2aa700f 378 if (w->running) {
8d0586c6
RN
379 gtk_label_set_text ( GTK_LABEL(w->status), _("Status: Working...") );
380 }
381 gdk_threads_leave();
382
0d2b891f
RN
383 /* tells us the type of items that will follow */
384 if (strstr(line, "Xfer Wpt")) {
7b3479e3 385 gps_data->progress_label = gps_data->wp_label;
0d2b891f 386 gps_data->progress_type = WPT;
7b3479e3 387 }
0d2b891f 388 if (strstr(line, "Xfer Trk")) {
7b3479e3 389 gps_data->progress_label = gps_data->trk_label;
0d2b891f
RN
390 gps_data->progress_type = TRK;
391 }
392 if (strstr(line, "Xfer Rte")) {
393 gps_data->progress_label = gps_data->rte_label;
394 gps_data->progress_type = RTE;
7b3479e3 395 }
0d2b891f 396
7b3479e3
EB
397 if (strstr(line, "PRDDAT")) {
398 gchar **tokens = g_strsplit(line, " ", 0);
399 gchar info[128];
400 int ilen = 0;
401 int i;
c83b5ad9
QT
402 int n_tokens = 0;
403
404 while (tokens[n_tokens])
405 n_tokens++;
406
407 if (n_tokens > 8) {
408 for (i=8; tokens[i] && ilen < sizeof(info)-2 && strcmp(tokens[i], "00"); i++) {
409 guint ch;
410 sscanf(tokens[i], "%x", &ch);
411 info[ilen++] = ch;
412 }
413 info[ilen++] = 0;
414 set_gps_info(info, w);
7b3479e3 415 }
c83b5ad9 416 g_strfreev(tokens);
7b3479e3 417 }
0a3f9142
RN
418 /* eg: "Unit:\teTrex Legend HCx Software Version 2.90\n" */
419 if (strstr(line, "Unit:")) {
420 gchar **tokens = g_strsplit(line, "\t", 0);
421 int n_tokens = 0;
422 while (tokens[n_tokens])
423 n_tokens++;
424
425 if (n_tokens > 1) {
426 set_gps_info(tokens[1], w);
427 }
428 g_strfreev(tokens);
429 }
0d2b891f
RN
430 /* tells us how many items there will be */
431 if (strstr(line, "RECORD")) {
7b3479e3
EB
432 int lsb, msb, cnt;
433
c83b5ad9
QT
434 if (strlen(line) > 20) {
435 sscanf(line+17, "%x", &lsb);
436 sscanf(line+20, "%x", &msb);
437 cnt = lsb + msb * 256;
438 set_total_count(cnt, w);
439 gps_data->count = 0;
440 }
7b3479e3 441 }
0d2b891f 442 if ( strstr(line, "WPTDAT") || strstr(line, "TRKHDR") || strstr(line, "TRKDAT") || strstr(line, "RTEHDR") || strstr(line, "RTEWPT") ) {
7b3479e3
EB
443 gps_data->count++;
444 set_current_count(gps_data->count, w);
445 }
446 break;
447 case BABEL_DONE:
448 break;
449 default:
450 break;
451 }
452}
453
8627bd99
GB
454void append_element (gpointer elem, gpointer user_data)
455{
8627bd99 456 const gchar *text = ((BabelDevice*)elem)->label;
1bc1c05b 457 vik_combo_box_text_append (GTK_WIDGET(user_data), text);
8627bd99
GB
458}
459
3f6db253
RN
460static gint find_entry = -1;
461static gint garmin_entry = -1;
462
463static void find_garmin (gpointer elem, gpointer user_data)
464{
465 const gchar *name = ((BabelDevice*)elem)->name;
466 find_entry++;
467 if (!strcmp(name, "garmin")) {
468 garmin_entry = find_entry;
469 }
470}
471
d80e59ba 472static void datasource_gps_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data )
65f0ccab
AF
473{
474 gps_user_data_t *w = (gps_user_data_t *)user_data;
d6c58ab9 475 GtkTable *box, *data_type_box;
65f0ccab 476
4c77d5e0 477 w->proto_l = gtk_label_new (_("GPS Protocol:"));
1bc1c05b 478 w->proto_b = vik_combo_box_text_new ();
8627bd99 479 g_list_foreach (a_babel_device_list, append_element, w->proto_b);
3f6db253
RN
480
481 // Maintain default to Garmin devices (assumed most popular/numerous device)
482 if ( last_active < 0 ) {
483 find_entry = -1;
484 g_list_foreach (a_babel_device_list, find_garmin, NULL);
485 if ( garmin_entry < 0 )
486 // Not found - so set it to the first entry
487 last_active = 0;
488 else
489 // Found
490 last_active = garmin_entry;
491 }
492
1bc1c05b 493 gtk_combo_box_set_active (GTK_COMBO_BOX(w->proto_b), last_active);
65f0ccab
AF
494 g_object_ref(w->proto_b);
495
4c77d5e0 496 w->ser_l = gtk_label_new (_("Serial Port:"));
1bc1c05b
RN
497#if GTK_CHECK_VERSION (2, 24, 0)
498 w->ser_b = gtk_combo_box_text_new_with_entry ();
499#else
500 w->ser_b = gtk_combo_box_entry_new_text ();
501#endif
8d70f073 502#ifdef WINDOWS
1bc1c05b 503 vik_combo_box_text_append (w->ser_b, "com1");
8d70f073 504#else
99163c34
RN
505 /* Here just try to see if the device is available which gets passed onto gpsbabel
506 List USB devices first as these will generally only be present if autogenerated by udev or similar
507 User is still able to set their own free text entry */
508 if (g_access ("/dev/ttyUSB0", R_OK) == 0)
1bc1c05b 509 vik_combo_box_text_append (w->ser_b, "/dev/ttyUSB0");
99163c34 510 if (g_access ("/dev/ttyUSB1", R_OK) == 0)
1bc1c05b 511 vik_combo_box_text_append (w->ser_b, "/dev/ttyUSB1");
99163c34 512 if (g_access ("/dev/ttyS0", R_OK) == 0)
1bc1c05b 513 vik_combo_box_text_append (w->ser_b, "/dev/ttyS0");
99163c34 514 if (g_access ("/dev/ttyS1", R_OK) == 0)
1bc1c05b 515 vik_combo_box_text_append (w->ser_b, "/dev/ttyS1");
8d70f073 516#endif
1bc1c05b
RN
517 vik_combo_box_text_append (w->ser_b, "usb:");
518 gtk_combo_box_set_active (GTK_COMBO_BOX(w->ser_b), 0);
65f0ccab
AF
519 g_object_ref(w->ser_b);
520
4136d029 521 w->off_request_l = gtk_label_new (_("Turn Off After Transfer\n(Garmin/NAViLink Only)"));
2b756ea0
RN
522 w->off_request_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
523
d6c58ab9
RN
524 w->get_tracks_l = gtk_label_new (_("Tracks:"));
525 w->get_tracks_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
7f23d292 526 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_tracks_b), last_get_tracks);
d6c58ab9 527
0d2b891f
RN
528 w->get_routes_l = gtk_label_new (_("Routes:"));
529 w->get_routes_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
530 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_routes_b), last_get_routes);
531
d6c58ab9
RN
532 w->get_waypoints_l = gtk_label_new (_("Waypoints:"));
533 w->get_waypoints_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
7f23d292 534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_waypoints_b), last_get_waypoints);
d6c58ab9
RN
535
536 box = GTK_TABLE(gtk_table_new(2, 4, FALSE));
537 data_type_box = GTK_TABLE(gtk_table_new(4, 1, FALSE));
538
65f0ccab
AF
539 gtk_table_attach_defaults(box, GTK_WIDGET(w->proto_l), 0, 1, 0, 1);
540 gtk_table_attach_defaults(box, GTK_WIDGET(w->proto_b), 1, 2, 0, 1);
541 gtk_table_attach_defaults(box, GTK_WIDGET(w->ser_l), 0, 1, 1, 2);
542 gtk_table_attach_defaults(box, GTK_WIDGET(w->ser_b), 1, 2, 1, 2);
d6c58ab9
RN
543 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_tracks_l), 0, 1, 0, 1);
544 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_tracks_b), 1, 2, 0, 1);
0d2b891f
RN
545 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_routes_l), 2, 3, 0, 1);
546 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_routes_b), 3, 4, 0, 1);
547 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_waypoints_l), 4, 5, 0, 1);
548 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_waypoints_b), 5, 6, 0, 1);
d6c58ab9
RN
549 gtk_table_attach_defaults(box, GTK_WIDGET(data_type_box), 0, 2, 2, 3);
550 gtk_table_attach_defaults(box, GTK_WIDGET(w->off_request_l), 0, 1, 3, 4);
551 gtk_table_attach_defaults(box, GTK_WIDGET(w->off_request_b), 1, 3, 3, 4);
9b082b39 552 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), GTK_WIDGET(box), FALSE, FALSE, 5 );
65f0ccab
AF
553
554 gtk_widget_show_all ( dialog );
555}
556
d80e59ba
RN
557/**
558 * datasource_gps_setup:
559 * @dialog: The GTK dialog. The caller is responsible for managing the dialog creation/deletion
0d2b891f
RN
560 * @xfer: The default type of items enabled for transfer, others disabled.
561 * @xfer_all: When specified all items are enabled for transfer.
d80e59ba
RN
562 *
563 * Returns: A gpointer to the private structure for GPS progress/information widgets
564 * Pass this pointer back into the other exposed datasource_gps_X functions
565 */
0d2b891f 566gpointer datasource_gps_setup ( GtkWidget *dialog, vik_gps_xfer_type xfer, gboolean xfer_all )
d80e59ba 567{
307abf54 568 gps_user_data_t *w_gps = (gps_user_data_t *)datasource_gps_init_func ( NULL );
d80e59ba
RN
569 datasource_gps_add_setup_widgets ( dialog, NULL, w_gps );
570
0d2b891f
RN
571 gboolean way = xfer_all;
572 gboolean trk = xfer_all;
573 gboolean rte = xfer_all;
574
575 // Selectively turn bits on
576 if ( !xfer_all ) {
577 switch (xfer) {
578 case WPT: way = TRUE; break;
579 case RTE: rte = TRUE; break;
580 default: trk = TRUE; break;
581 }
d80e59ba 582 }
0d2b891f
RN
583
584 // Apply
585 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_tracks_b), trk );
586 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_tracks_l), trk );
587 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_tracks_b), trk );
588
589 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_routes_b), rte );
590 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_routes_l), rte );
591 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_routes_b), rte );
592
593 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_waypoints_b), way );
594 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_waypoints_l), way );
595 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_waypoints_b), way );
596
d80e59ba
RN
597 return (gpointer)w_gps;
598}
599
65f0ccab 600void datasource_gps_add_progress_widgets ( GtkWidget *dialog, gpointer user_data )
7b3479e3 601{
0d2b891f 602 GtkWidget *gpslabel, *verlabel, *idlabel, *wplabel, *trklabel, *rtelabel;
7b3479e3 603
65f0ccab 604 gps_user_data_t *w_gps = (gps_user_data_t *)user_data;
7b3479e3 605
4c77d5e0 606 gpslabel = gtk_label_new (_("GPS device: N/A"));
7b3479e3
EB
607 verlabel = gtk_label_new ("");
608 idlabel = gtk_label_new ("");
609 wplabel = gtk_label_new ("");
610 trklabel = gtk_label_new ("");
0d2b891f 611 rtelabel = gtk_label_new ("");
7b3479e3 612
9b082b39
RN
613 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), gpslabel, FALSE, FALSE, 5 );
614 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), wplabel, FALSE, FALSE, 5 );
615 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), trklabel, FALSE, FALSE, 5 );
616 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), rtelabel, FALSE, FALSE, 5 );
7b3479e3 617
7b3479e3
EB
618 gtk_widget_show_all ( dialog );
619
620 w_gps->gps_label = gpslabel;
621 w_gps->id_label = idlabel;
622 w_gps->ver_label = verlabel;
623 w_gps->progress_label = w_gps->wp_label = wplabel;
624 w_gps->trk_label = trklabel;
0d2b891f 625 w_gps->rte_label = rtelabel;
7b3479e3 626 w_gps->total_count = -1;
7b3479e3 627}