]> git.street.me.uk Git - andy/viking.git/blame - src/datasource_gps.c
Allow an acquire datasource method to *not* have to use a threading mechanism.
[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
65f0ccab 48static gpointer datasource_gps_init_func ( );
7b3479e3 49static void datasource_gps_get_cmd_string ( gpointer add_widgets_data_not_used, gchar **babelargs, gchar **input_file );
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;
85 GtkComboBox *proto_b;
86 GtkWidget *ser_l;
87 GtkComboBox *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
112static gpointer datasource_gps_init_func ()
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;
143 return gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
144}
145
146/**
147 * datasource_gps_get_do_tracks:
148 *
149 * Method to get the track handling behaviour from the widget structure
150 */
151gboolean datasource_gps_get_do_tracks ( gpointer user_data )
152{
153 gps_user_data_t *w = (gps_user_data_t *)user_data;
154 last_get_tracks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_tracks_b));
155 return last_get_tracks;
156}
157
0d2b891f
RN
158/**
159 * datasource_gps_get_do_routes:
160 *
161 * Method to get the route handling behaviour from the widget structure
162 */
163gboolean datasource_gps_get_do_routes ( gpointer user_data )
164{
165 gps_user_data_t *w = (gps_user_data_t *)user_data;
166 last_get_routes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_routes_b));
167 return last_get_routes;
168}
169
d80e59ba
RN
170/**
171 * datasource_gps_get_do_waypoints:
172 *
173 * Method to get the waypoint handling behaviour from the widget structure
174 */
175gboolean datasource_gps_get_do_waypoints ( gpointer user_data )
176{
177 gps_user_data_t *w = (gps_user_data_t *)user_data;
178 last_get_waypoints = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_waypoints_b));
179 return last_get_waypoints;
180}
181
65f0ccab 182static void datasource_gps_get_cmd_string ( gpointer user_data, gchar **babelargs, gchar **input_file )
7b3479e3 183{
cf7fdc15 184 char *device = NULL;
d6c58ab9 185 char *tracks = NULL;
0d2b891f 186 char *routes = NULL;
d6c58ab9 187 char *waypoints = NULL;
65f0ccab 188
7b3479e3
EB
189 if (gps_acquire_in_progress) {
190 *babelargs = *input_file = NULL;
191 }
65f0ccab
AF
192
193 gps_acquire_in_progress = TRUE;
194
d80e59ba 195 device = datasource_gps_get_protocol ( user_data );
2b756ea0 196
d80e59ba 197 if ( datasource_gps_get_do_tracks ( user_data ) )
d6c58ab9
RN
198 tracks = "-t";
199 else
200 tracks = "";
d80e59ba 201
0d2b891f
RN
202 if ( datasource_gps_get_do_routes ( user_data ) )
203 routes = "-r";
204 else
205 routes = "";
206
d80e59ba 207 if ( datasource_gps_get_do_waypoints ( user_data ) )
d6c58ab9
RN
208 waypoints = "-w";
209 else
210 waypoints = "";
211
0d2b891f 212 *babelargs = g_strdup_printf("-D 9 %s %s %s -i %s", tracks, routes, waypoints, device);
cf7fdc15
GB
213 /* device points to static content => no free */
214 device = NULL;
d6c58ab9 215 tracks = NULL;
0d2b891f 216 routes = NULL;
d6c58ab9
RN
217 waypoints = NULL;
218
d80e59ba 219 *input_file = g_strdup(datasource_gps_get_descriptor(user_data));
7b3479e3 220
4c77d5e0 221 g_debug(_("using cmdline '%s' and file '%s'\n"), *babelargs, *input_file);
7b3479e3
EB
222}
223
d80e59ba
RN
224/**
225 * datasource_gps_get_off:
226 *
227 * Method to get the off behaviour from the widget structure
228 */
229gboolean datasource_gps_get_off ( gpointer user_data )
230{
231 gps_user_data_t *w = (gps_user_data_t *)user_data;
232 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->off_request_b));
233}
2b756ea0
RN
234
235static void datasource_gps_off ( gpointer user_data, gchar **babelargs, gchar **input_file )
236{
2b756ea0
RN
237 char *ser = NULL;
238 char *device = NULL;
2b756ea0
RN
239 gps_user_data_t *w = (gps_user_data_t *)user_data;
240
241 if (gps_acquire_in_progress) {
242 *babelargs = *input_file = NULL;
243 }
244
245 /* See if we should turn off the device */
d80e59ba 246 if (!datasource_gps_get_off ( user_data )){
2b756ea0
RN
247 return;
248 }
249
78f6c63d
RN
250 if (!a_babel_device_list)
251 return;
8627bd99
GB
252 last_active = gtk_combo_box_get_active(GTK_COMBO_BOX(w->proto_b));
253 device = ((BabelDevice*)g_list_nth_data(a_babel_device_list, last_active))->name;
254 if (!strcmp(device, "garmin")) {
2b756ea0 255 device = "garmin,power_off";
4136d029 256 }
8627bd99 257 else if (!strcmp(device, "navilink")) {
4136d029
RN
258 device = "navilink,power_off";
259 }
260 else {
2b756ea0
RN
261 return;
262 }
263
264 *babelargs = g_strdup_printf("-i %s", device);
265 /* device points to static content => no free */
266 device = NULL;
267
2b756ea0 268 ser = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
2b756ea0
RN
269 *input_file = g_strdup(ser);
270}
271
272
65f0ccab 273static void datasource_gps_cleanup ( gpointer user_data )
7b3479e3 274{
65f0ccab 275 g_free ( user_data );
7b3479e3
EB
276 gps_acquire_in_progress = FALSE;
277}
278
d80e59ba
RN
279/**
280 * datasource_gps_clean_up:
281 *
282 * External method to tidy up
283 */
284void datasource_gps_clean_up ( gpointer user_data )
285{
286 datasource_gps_cleanup ( user_data );
287}
288
7b3479e3
EB
289static void set_total_count(gint cnt, acq_dialog_widgets_t *w)
290{
cf7fdc15 291 gchar *s = NULL;
7b3479e3 292 gdk_threads_enter();
b2aa700f 293 if (w->running) {
65f0ccab 294 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
97634600 295 const gchar *tmp_str;
0d2b891f
RN
296 switch (gps_data->progress_type) {
297 case WPT: tmp_str = ngettext("Downloading %d waypoint...", "Downloading %d waypoints...", cnt); gps_data->total_count = cnt; break;
298 case TRK: tmp_str = ngettext("Downloading %d trackpoint...", "Downloading %d trackpoints...", cnt); gps_data->total_count = cnt; break;
299 default:
300 {
301 // 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
302 gint mycnt = (cnt / 2) + 1;
303 tmp_str = ngettext("Downloading %d routepoint...", "Downloading %d routepoints...", mycnt);
304 gps_data->total_count = mycnt;
305 break;
306 }
307 }
97634600 308 s = g_strdup_printf(tmp_str, cnt);
7b3479e3
EB
309 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
310 gtk_widget_show ( gps_data->progress_label );
7b3479e3 311 }
cf7fdc15 312 g_free(s); s = NULL;
7b3479e3
EB
313 gdk_threads_leave();
314}
315
316static void set_current_count(gint cnt, acq_dialog_widgets_t *w)
317{
cf7fdc15 318 gchar *s = NULL;
7b3479e3 319 gdk_threads_enter();
b2aa700f 320 if (w->running) {
65f0ccab 321 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
7b3479e3
EB
322
323 if (cnt < gps_data->total_count) {
0d2b891f
RN
324 switch (gps_data->progress_type) {
325 case WPT: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "waypoints"); break;
326 case TRK: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "trackpoints"); break;
327 default: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "routepoints"); break;
328 }
7b3479e3 329 } else {
0d2b891f
RN
330 switch (gps_data->progress_type) {
331 case WPT: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "waypoints"); break;
332 case TRK: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "trackpoints"); break;
333 default: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "routepoints"); break;
334 }
335 }
7b3479e3
EB
336 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
337 }
cf7fdc15 338 g_free(s); s = NULL;
7b3479e3
EB
339 gdk_threads_leave();
340}
341
342static void set_gps_info(const gchar *info, acq_dialog_widgets_t *w)
343{
cf7fdc15 344 gchar *s = NULL;
7b3479e3 345 gdk_threads_enter();
b2aa700f 346 if (w->running) {
4c77d5e0 347 s = g_strdup_printf(_("GPS Device: %s"), info);
65f0ccab 348 gtk_label_set_text ( GTK_LABEL(((gps_user_data_t *)w->user_data)->gps_label), s );
7b3479e3 349 }
cf7fdc15 350 g_free(s); s = NULL;
7b3479e3
EB
351 gdk_threads_leave();
352}
353
354/*
355 * This routine relies on gpsbabel's diagnostic output to display the progress information.
356 * These outputs differ when different GPS devices are used, so we will need to test
357 * them on several and add the corresponding support.
358 */
359static void datasource_gps_progress ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w )
360{
361 gchar *line;
65f0ccab 362 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
7b3479e3 363
7b3479e3
EB
364 switch(c) {
365 case BABEL_DIAG_OUTPUT:
366 line = (gchar *)data;
367
8d0586c6 368 gdk_threads_enter();
b2aa700f 369 if (w->running) {
8d0586c6
RN
370 gtk_label_set_text ( GTK_LABEL(w->status), _("Status: Working...") );
371 }
372 gdk_threads_leave();
373
0d2b891f
RN
374 /* tells us the type of items that will follow */
375 if (strstr(line, "Xfer Wpt")) {
7b3479e3 376 gps_data->progress_label = gps_data->wp_label;
0d2b891f 377 gps_data->progress_type = WPT;
7b3479e3 378 }
0d2b891f 379 if (strstr(line, "Xfer Trk")) {
7b3479e3 380 gps_data->progress_label = gps_data->trk_label;
0d2b891f
RN
381 gps_data->progress_type = TRK;
382 }
383 if (strstr(line, "Xfer Rte")) {
384 gps_data->progress_label = gps_data->rte_label;
385 gps_data->progress_type = RTE;
7b3479e3 386 }
0d2b891f 387
7b3479e3
EB
388 if (strstr(line, "PRDDAT")) {
389 gchar **tokens = g_strsplit(line, " ", 0);
390 gchar info[128];
391 int ilen = 0;
392 int i;
c83b5ad9
QT
393 int n_tokens = 0;
394
395 while (tokens[n_tokens])
396 n_tokens++;
397
398 if (n_tokens > 8) {
399 for (i=8; tokens[i] && ilen < sizeof(info)-2 && strcmp(tokens[i], "00"); i++) {
400 guint ch;
401 sscanf(tokens[i], "%x", &ch);
402 info[ilen++] = ch;
403 }
404 info[ilen++] = 0;
405 set_gps_info(info, w);
7b3479e3 406 }
c83b5ad9 407 g_strfreev(tokens);
7b3479e3 408 }
0a3f9142
RN
409 /* eg: "Unit:\teTrex Legend HCx Software Version 2.90\n" */
410 if (strstr(line, "Unit:")) {
411 gchar **tokens = g_strsplit(line, "\t", 0);
412 int n_tokens = 0;
413 while (tokens[n_tokens])
414 n_tokens++;
415
416 if (n_tokens > 1) {
417 set_gps_info(tokens[1], w);
418 }
419 g_strfreev(tokens);
420 }
0d2b891f
RN
421 /* tells us how many items there will be */
422 if (strstr(line, "RECORD")) {
7b3479e3
EB
423 int lsb, msb, cnt;
424
c83b5ad9
QT
425 if (strlen(line) > 20) {
426 sscanf(line+17, "%x", &lsb);
427 sscanf(line+20, "%x", &msb);
428 cnt = lsb + msb * 256;
429 set_total_count(cnt, w);
430 gps_data->count = 0;
431 }
7b3479e3 432 }
0d2b891f 433 if ( strstr(line, "WPTDAT") || strstr(line, "TRKHDR") || strstr(line, "TRKDAT") || strstr(line, "RTEHDR") || strstr(line, "RTEWPT") ) {
7b3479e3
EB
434 gps_data->count++;
435 set_current_count(gps_data->count, w);
436 }
437 break;
438 case BABEL_DONE:
439 break;
440 default:
441 break;
442 }
443}
444
8627bd99
GB
445void append_element (gpointer elem, gpointer user_data)
446{
447 GtkComboBox *combo = GTK_COMBO_BOX (user_data);
448 const gchar *text = ((BabelDevice*)elem)->label;
449 gtk_combo_box_append_text (combo, text);
450}
451
3f6db253
RN
452static gint find_entry = -1;
453static gint garmin_entry = -1;
454
455static void find_garmin (gpointer elem, gpointer user_data)
456{
457 const gchar *name = ((BabelDevice*)elem)->name;
458 find_entry++;
459 if (!strcmp(name, "garmin")) {
460 garmin_entry = find_entry;
461 }
462}
463
d80e59ba 464static void datasource_gps_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data )
65f0ccab
AF
465{
466 gps_user_data_t *w = (gps_user_data_t *)user_data;
d6c58ab9 467 GtkTable *box, *data_type_box;
65f0ccab 468
4c77d5e0 469 w->proto_l = gtk_label_new (_("GPS Protocol:"));
65f0ccab 470 w->proto_b = GTK_COMBO_BOX(gtk_combo_box_new_text ());
8627bd99 471 g_list_foreach (a_babel_device_list, append_element, w->proto_b);
3f6db253
RN
472
473 // Maintain default to Garmin devices (assumed most popular/numerous device)
474 if ( last_active < 0 ) {
475 find_entry = -1;
476 g_list_foreach (a_babel_device_list, find_garmin, NULL);
477 if ( garmin_entry < 0 )
478 // Not found - so set it to the first entry
479 last_active = 0;
480 else
481 // Found
482 last_active = garmin_entry;
483 }
484
8627bd99 485 gtk_combo_box_set_active (w->proto_b, last_active);
65f0ccab
AF
486 g_object_ref(w->proto_b);
487
4c77d5e0 488 w->ser_l = gtk_label_new (_("Serial Port:"));
65f0ccab 489 w->ser_b = GTK_COMBO_BOX(gtk_combo_box_entry_new_text ());
8d70f073
MA
490#ifdef WINDOWS
491 gtk_combo_box_append_text (w->ser_b, "com1");
492#else
99163c34
RN
493 /* Here just try to see if the device is available which gets passed onto gpsbabel
494 List USB devices first as these will generally only be present if autogenerated by udev or similar
495 User is still able to set their own free text entry */
496 if (g_access ("/dev/ttyUSB0", R_OK) == 0)
497 gtk_combo_box_append_text (w->ser_b, "/dev/ttyUSB0");
498 if (g_access ("/dev/ttyUSB1", R_OK) == 0)
499 gtk_combo_box_append_text (w->ser_b, "/dev/ttyUSB1");
500 if (g_access ("/dev/ttyS0", R_OK) == 0)
501 gtk_combo_box_append_text (w->ser_b, "/dev/ttyS0");
502 if (g_access ("/dev/ttyS1", R_OK) == 0)
503 gtk_combo_box_append_text (w->ser_b, "/dev/ttyS1");
8d70f073 504#endif
7963d365 505 gtk_combo_box_append_text (w->ser_b, "usb:");
65f0ccab
AF
506 gtk_combo_box_set_active (w->ser_b, 0);
507 g_object_ref(w->ser_b);
508
4136d029 509 w->off_request_l = gtk_label_new (_("Turn Off After Transfer\n(Garmin/NAViLink Only)"));
2b756ea0
RN
510 w->off_request_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
511
d6c58ab9
RN
512 w->get_tracks_l = gtk_label_new (_("Tracks:"));
513 w->get_tracks_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
7f23d292 514 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_tracks_b), last_get_tracks);
d6c58ab9 515
0d2b891f
RN
516 w->get_routes_l = gtk_label_new (_("Routes:"));
517 w->get_routes_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
518 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_routes_b), last_get_routes);
519
d6c58ab9
RN
520 w->get_waypoints_l = gtk_label_new (_("Waypoints:"));
521 w->get_waypoints_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
7f23d292 522 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_waypoints_b), last_get_waypoints);
d6c58ab9
RN
523
524 box = GTK_TABLE(gtk_table_new(2, 4, FALSE));
525 data_type_box = GTK_TABLE(gtk_table_new(4, 1, FALSE));
526
65f0ccab
AF
527 gtk_table_attach_defaults(box, GTK_WIDGET(w->proto_l), 0, 1, 0, 1);
528 gtk_table_attach_defaults(box, GTK_WIDGET(w->proto_b), 1, 2, 0, 1);
529 gtk_table_attach_defaults(box, GTK_WIDGET(w->ser_l), 0, 1, 1, 2);
530 gtk_table_attach_defaults(box, GTK_WIDGET(w->ser_b), 1, 2, 1, 2);
d6c58ab9
RN
531 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_tracks_l), 0, 1, 0, 1);
532 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_tracks_b), 1, 2, 0, 1);
0d2b891f
RN
533 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_routes_l), 2, 3, 0, 1);
534 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_routes_b), 3, 4, 0, 1);
535 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_waypoints_l), 4, 5, 0, 1);
536 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_waypoints_b), 5, 6, 0, 1);
d6c58ab9
RN
537 gtk_table_attach_defaults(box, GTK_WIDGET(data_type_box), 0, 2, 2, 3);
538 gtk_table_attach_defaults(box, GTK_WIDGET(w->off_request_l), 0, 1, 3, 4);
539 gtk_table_attach_defaults(box, GTK_WIDGET(w->off_request_b), 1, 3, 3, 4);
65f0ccab
AF
540 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(box), FALSE, FALSE, 5 );
541
542 gtk_widget_show_all ( dialog );
543}
544
d80e59ba
RN
545/**
546 * datasource_gps_setup:
547 * @dialog: The GTK dialog. The caller is responsible for managing the dialog creation/deletion
0d2b891f
RN
548 * @xfer: The default type of items enabled for transfer, others disabled.
549 * @xfer_all: When specified all items are enabled for transfer.
d80e59ba
RN
550 *
551 * Returns: A gpointer to the private structure for GPS progress/information widgets
552 * Pass this pointer back into the other exposed datasource_gps_X functions
553 */
0d2b891f 554gpointer datasource_gps_setup ( GtkWidget *dialog, vik_gps_xfer_type xfer, gboolean xfer_all )
d80e59ba
RN
555{
556 gps_user_data_t *w_gps = (gps_user_data_t *)datasource_gps_init_func();
557 datasource_gps_add_setup_widgets ( dialog, NULL, w_gps );
558
0d2b891f
RN
559 gboolean way = xfer_all;
560 gboolean trk = xfer_all;
561 gboolean rte = xfer_all;
562
563 // Selectively turn bits on
564 if ( !xfer_all ) {
565 switch (xfer) {
566 case WPT: way = TRUE; break;
567 case RTE: rte = TRUE; break;
568 default: trk = TRUE; break;
569 }
d80e59ba 570 }
0d2b891f
RN
571
572 // Apply
573 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_tracks_b), trk );
574 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_tracks_l), trk );
575 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_tracks_b), trk );
576
577 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_routes_b), rte );
578 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_routes_l), rte );
579 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_routes_b), rte );
580
581 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_waypoints_b), way );
582 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_waypoints_l), way );
583 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_waypoints_b), way );
584
d80e59ba
RN
585 return (gpointer)w_gps;
586}
587
65f0ccab 588void datasource_gps_add_progress_widgets ( GtkWidget *dialog, gpointer user_data )
7b3479e3 589{
0d2b891f 590 GtkWidget *gpslabel, *verlabel, *idlabel, *wplabel, *trklabel, *rtelabel;
7b3479e3 591
65f0ccab 592 gps_user_data_t *w_gps = (gps_user_data_t *)user_data;
7b3479e3 593
4c77d5e0 594 gpslabel = gtk_label_new (_("GPS device: N/A"));
7b3479e3
EB
595 verlabel = gtk_label_new ("");
596 idlabel = gtk_label_new ("");
597 wplabel = gtk_label_new ("");
598 trklabel = gtk_label_new ("");
0d2b891f 599 rtelabel = gtk_label_new ("");
7b3479e3
EB
600
601 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), gpslabel, FALSE, FALSE, 5 );
602 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), wplabel, FALSE, FALSE, 5 );
603 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), trklabel, FALSE, FALSE, 5 );
0d2b891f 604 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), rtelabel, FALSE, FALSE, 5 );
7b3479e3 605
7b3479e3
EB
606 gtk_widget_show_all ( dialog );
607
608 w_gps->gps_label = gpslabel;
609 w_gps->id_label = idlabel;
610 w_gps->ver_label = verlabel;
611 w_gps->progress_label = w_gps->wp_label = wplabel;
612 w_gps->trk_label = trklabel;
0d2b891f 613 w_gps->rte_label = rtelabel;
7b3479e3 614 w_gps->total_count = -1;
7b3479e3 615}