]> git.street.me.uk Git - andy/viking.git/blame_incremental - src/datasource_gps.c
SF Bugs#133: Remove the auto added map when opening the first .vik file from the...
[andy/viking.git] / src / datasource_gps.c
... / ...
CommitLineData
1/*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3 *
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
5 * Copyright (C) 2006, Alex Foobarian <foobarian@gmail.com>
6 * Copyright (C) 2012-2015, Rob Norris <rw_norris@hotmail.com>
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 */
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26#include <string.h>
27#ifdef HAVE_UNISTD_H
28#include <unistd.h>
29#endif
30
31#include <glib/gstdio.h>
32#include <glib/gprintf.h>
33#include <glib/gi18n.h>
34
35#include "datasource_gps.h"
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
43static gint last_active = -1;
44
45static gpointer datasource_gps_init_func ( acq_vik_t *avt );
46static void datasource_gps_get_process_options ( gpointer user_data, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 );
47static void datasource_gps_cleanup ( gpointer user_data );
48static void datasource_gps_progress ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w );
49static void datasource_gps_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data );
50static void datasource_gps_add_progress_widgets ( GtkWidget *dialog, gpointer user_data );
51static void datasource_gps_off ( gpointer add_widgets_data_not_used, gchar **babelargs, gchar **input_file );
52
53VikDataSourceInterface vik_datasource_gps_interface = {
54 N_("Acquire from GPS"),
55 N_("Acquired from GPS"),
56 VIK_DATASOURCE_AUTO_LAYER_MANAGEMENT,
57 VIK_DATASOURCE_INPUTTYPE_NONE,
58 TRUE,
59 TRUE,
60 TRUE,
61 (VikDataSourceInitFunc) datasource_gps_init_func,
62 (VikDataSourceCheckExistenceFunc) NULL,
63 (VikDataSourceAddSetupWidgetsFunc) datasource_gps_add_setup_widgets,
64 (VikDataSourceGetProcessOptionsFunc) datasource_gps_get_process_options,
65 (VikDataSourceProcessFunc) a_babel_convert_from,
66 (VikDataSourceProgressFunc) datasource_gps_progress,
67 (VikDataSourceAddProgressWidgetsFunc) datasource_gps_add_progress_widgets,
68 (VikDataSourceCleanupFunc) datasource_gps_cleanup,
69 (VikDataSourceOffFunc) datasource_gps_off,
70
71 NULL,
72 0,
73 NULL,
74 NULL,
75 0
76};
77
78/*********************************************************
79 * Definitions and routines for acquiring data from GPS
80 *********************************************************/
81
82/* widgets in setup dialog specific to GPS */
83/* widgets in progress dialog specific to GPS */
84/* also counts needed for progress */
85typedef struct {
86 /* setup dialog */
87 GtkWidget *proto_l;
88 GtkWidget *proto_b;
89 GtkWidget *ser_l;
90 GtkWidget *ser_b;
91 GtkWidget *off_request_l;
92 GtkCheckButton *off_request_b;
93 GtkWidget *get_tracks_l;
94 GtkCheckButton *get_tracks_b;
95 GtkWidget *get_routes_l;
96 GtkCheckButton *get_routes_b;
97 GtkWidget *get_waypoints_l;
98 GtkCheckButton *get_waypoints_b;
99
100 /* progress dialog */
101 GtkWidget *gps_label;
102 GtkWidget *ver_label;
103 GtkWidget *id_label;
104 GtkWidget *wp_label;
105 GtkWidget *trk_label;
106 GtkWidget *rte_label;
107 GtkWidget *progress_label;
108 vik_gps_xfer_type progress_type;
109
110 /* state */
111 int total_count;
112 int count;
113 // Know which way xfer is so xfer setting types are only stored for download
114 vik_gps_dir direction;
115} gps_user_data_t;
116
117#define VIK_SETTINGS_GPS_GET_TRACKS "gps_download_tracks"
118#define VIK_SETTINGS_GPS_GET_ROUTES "gps_download_routes"
119#define VIK_SETTINGS_GPS_GET_WAYPOINTS "gps_download_waypoints"
120#define VIK_SETTINGS_GPS_PROTOCOL "gps_protocol"
121#define VIK_SETTINGS_GPS_PORT "gps_port"
122#define VIK_SETTINGS_GPS_POWER_OFF "gps_power_off"
123
124static gpointer datasource_gps_init_func ( acq_vik_t *avt )
125{
126 gps_user_data_t *gps_ud = g_malloc (sizeof(gps_user_data_t));
127 gps_ud->direction = GPS_DOWN;
128 return gps_ud;
129}
130
131/**
132 * datasource_gps_get_protocol:
133 *
134 * Method to get the communication protocol of the GPS device from the widget structure
135 */
136gchar* datasource_gps_get_protocol ( gpointer user_data )
137{
138 // Uses the list of supported devices
139 gps_user_data_t *w = (gps_user_data_t *)user_data;
140 last_active = gtk_combo_box_get_active(GTK_COMBO_BOX(w->proto_b));
141 if (a_babel_device_list) {
142 gchar *protocol = ((BabelDevice*)g_list_nth_data(a_babel_device_list, last_active))->name;
143 a_settings_set_string ( VIK_SETTINGS_GPS_PROTOCOL, protocol );
144 return protocol;
145 }
146
147 return NULL;
148}
149
150/**
151 * datasource_gps_get_descriptor:
152 *
153 * Method to get the descriptor from the widget structure
154 * "Everything is a file"
155 * Could actually be normal file or a serial port
156 */
157gchar* datasource_gps_get_descriptor ( gpointer user_data )
158{
159 gps_user_data_t *w = (gps_user_data_t *)user_data;
160
161#if GTK_CHECK_VERSION (2, 24, 0)
162 gchar *descriptor = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w->ser_b));
163#else
164 gchar *descriptor = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
165#endif
166 a_settings_set_string ( VIK_SETTINGS_GPS_PORT, descriptor );
167 return descriptor;
168}
169
170/**
171 * datasource_gps_get_do_tracks:
172 *
173 * Method to get the track handling behaviour from the widget structure
174 */
175gboolean datasource_gps_get_do_tracks ( gpointer user_data )
176{
177 gps_user_data_t *w = (gps_user_data_t *)user_data;
178 gboolean get_tracks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_tracks_b));
179 if ( w->direction == GPS_DOWN )
180 a_settings_set_boolean ( VIK_SETTINGS_GPS_GET_TRACKS, get_tracks );
181 return get_tracks;
182}
183
184/**
185 * datasource_gps_get_do_routes:
186 *
187 * Method to get the route handling behaviour from the widget structure
188 */
189gboolean datasource_gps_get_do_routes ( gpointer user_data )
190{
191 gps_user_data_t *w = (gps_user_data_t *)user_data;
192 gboolean get_routes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_routes_b));
193 if ( w->direction == GPS_DOWN )
194 a_settings_set_boolean ( VIK_SETTINGS_GPS_GET_ROUTES, get_routes );
195 return get_routes;
196}
197
198/**
199 * datasource_gps_get_do_waypoints:
200 *
201 * Method to get the waypoint handling behaviour from the widget structure
202 */
203gboolean datasource_gps_get_do_waypoints ( gpointer user_data )
204{
205 gps_user_data_t *w = (gps_user_data_t *)user_data;
206 gboolean get_waypoints = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->get_waypoints_b));
207 if ( w->direction == GPS_DOWN )
208 a_settings_set_boolean ( VIK_SETTINGS_GPS_GET_WAYPOINTS, get_waypoints );
209 return get_waypoints;
210}
211
212static void datasource_gps_get_process_options ( gpointer user_data, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 )
213{
214 char *device = NULL;
215 char *tracks = NULL;
216 char *routes = NULL;
217 char *waypoints = NULL;
218
219 if (gps_acquire_in_progress) {
220 po->babelargs = po->filename = NULL;
221 }
222
223 gps_acquire_in_progress = TRUE;
224
225 device = datasource_gps_get_protocol ( user_data );
226
227 if ( datasource_gps_get_do_tracks ( user_data ) )
228 tracks = "-t";
229 else
230 tracks = "";
231
232 if ( datasource_gps_get_do_routes ( user_data ) )
233 routes = "-r";
234 else
235 routes = "";
236
237 if ( datasource_gps_get_do_waypoints ( user_data ) )
238 waypoints = "-w";
239 else
240 waypoints = "";
241
242 po->babelargs = g_strdup_printf("-D 9 %s %s %s -i %s", tracks, routes, waypoints, device);
243 /* device points to static content => no free */
244 device = NULL;
245 tracks = NULL;
246 routes = NULL;
247 waypoints = NULL;
248
249 po->filename = g_strdup(datasource_gps_get_descriptor(user_data));
250
251 g_debug(_("using cmd '%s' and file '%s'\n"), po->babelargs, po->filename);
252}
253
254/**
255 * datasource_gps_get_off:
256 *
257 * Method to get the off behaviour from the widget structure
258 */
259gboolean datasource_gps_get_off ( gpointer user_data )
260{
261 gps_user_data_t *w = (gps_user_data_t *)user_data;
262 gboolean power_off = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->off_request_b));
263 a_settings_set_boolean ( VIK_SETTINGS_GPS_POWER_OFF, power_off );
264 return power_off;
265}
266
267static void datasource_gps_off ( gpointer user_data, gchar **babelargs, gchar **file_descriptor )
268{
269 char *ser = NULL;
270 char *device = NULL;
271 gps_user_data_t *w = (gps_user_data_t *)user_data;
272
273 if (gps_acquire_in_progress) {
274 *babelargs = *file_descriptor = NULL;
275 }
276
277 /* See if we should turn off the device */
278 if (!datasource_gps_get_off ( user_data )){
279 return;
280 }
281
282 if (!a_babel_device_list)
283 return;
284 last_active = gtk_combo_box_get_active(GTK_COMBO_BOX(w->proto_b));
285 device = ((BabelDevice*)g_list_nth_data(a_babel_device_list, last_active))->name;
286 if (!strcmp(device, "garmin")) {
287 device = "garmin,power_off";
288 }
289 else if (!strcmp(device, "navilink")) {
290 device = "navilink,power_off";
291 }
292 else {
293 return;
294 }
295
296 *babelargs = g_strdup_printf("-i %s", device);
297 /* device points to static content => no free */
298 device = NULL;
299
300#if GTK_CHECK_VERSION (2, 24, 0)
301 ser = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w->ser_b));
302#else
303 ser = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
304#endif
305 *file_descriptor = g_strdup(ser);
306}
307
308
309static void datasource_gps_cleanup ( gpointer user_data )
310{
311 g_free ( user_data );
312 gps_acquire_in_progress = FALSE;
313}
314
315/**
316 * datasource_gps_clean_up:
317 *
318 * External method to tidy up
319 */
320void datasource_gps_clean_up ( gpointer user_data )
321{
322 datasource_gps_cleanup ( user_data );
323}
324
325static void set_total_count(gint cnt, acq_dialog_widgets_t *w)
326{
327 gchar *s = NULL;
328 gdk_threads_enter();
329 if (w->running) {
330 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
331 const gchar *tmp_str;
332 switch (gps_data->progress_type) {
333 case WPT: tmp_str = ngettext("Downloading %d waypoint...", "Downloading %d waypoints...", cnt); gps_data->total_count = cnt; break;
334 case TRK: tmp_str = ngettext("Downloading %d trackpoint...", "Downloading %d trackpoints...", cnt); gps_data->total_count = cnt; break;
335 default:
336 {
337 // 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
338 gint mycnt = (cnt / 2) + 1;
339 tmp_str = ngettext("Downloading %d routepoint...", "Downloading %d routepoints...", mycnt);
340 gps_data->total_count = mycnt;
341 break;
342 }
343 }
344 s = g_strdup_printf(tmp_str, cnt);
345 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
346 gtk_widget_show ( gps_data->progress_label );
347 }
348 g_free(s); s = NULL;
349 gdk_threads_leave();
350}
351
352static void set_current_count(gint cnt, acq_dialog_widgets_t *w)
353{
354 gchar *s = NULL;
355 gdk_threads_enter();
356 if (w->running) {
357 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
358
359 if (cnt < gps_data->total_count) {
360 switch (gps_data->progress_type) {
361 case WPT: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "waypoints"); break;
362 case TRK: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "trackpoints"); break;
363 default: s = g_strdup_printf(_("Downloaded %d out of %d %s..."), cnt, gps_data->total_count, "routepoints"); break;
364 }
365 } else {
366 switch (gps_data->progress_type) {
367 case WPT: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "waypoints"); break;
368 case TRK: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "trackpoints"); break;
369 default: s = g_strdup_printf(_("Downloaded %d %s."), cnt, "routepoints"); break;
370 }
371 }
372 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
373 }
374 g_free(s); s = NULL;
375 gdk_threads_leave();
376}
377
378static void set_gps_info(const gchar *info, acq_dialog_widgets_t *w)
379{
380 gchar *s = NULL;
381 gdk_threads_enter();
382 if (w->running) {
383 s = g_strdup_printf(_("GPS Device: %s"), info);
384 gtk_label_set_text ( GTK_LABEL(((gps_user_data_t *)w->user_data)->gps_label), s );
385 }
386 g_free(s); s = NULL;
387 gdk_threads_leave();
388}
389
390/*
391 * This routine relies on gpsbabel's diagnostic output to display the progress information.
392 * These outputs differ when different GPS devices are used, so we will need to test
393 * them on several and add the corresponding support.
394 */
395static void datasource_gps_progress ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w )
396{
397 gchar *line;
398 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
399
400 switch(c) {
401 case BABEL_DIAG_OUTPUT:
402 line = (gchar *)data;
403
404 gdk_threads_enter();
405 if (w->running) {
406 gtk_label_set_text ( GTK_LABEL(w->status), _("Status: Working...") );
407 }
408 gdk_threads_leave();
409
410 /* tells us the type of items that will follow */
411 if (strstr(line, "Xfer Wpt")) {
412 gps_data->progress_label = gps_data->wp_label;
413 gps_data->progress_type = WPT;
414 }
415 if (strstr(line, "Xfer Trk")) {
416 gps_data->progress_label = gps_data->trk_label;
417 gps_data->progress_type = TRK;
418 }
419 if (strstr(line, "Xfer Rte")) {
420 gps_data->progress_label = gps_data->rte_label;
421 gps_data->progress_type = RTE;
422 }
423
424 if (strstr(line, "PRDDAT")) {
425 gchar **tokens = g_strsplit(line, " ", 0);
426 gchar info[128];
427 int ilen = 0;
428 int i;
429 int n_tokens = 0;
430
431 while (tokens[n_tokens])
432 n_tokens++;
433
434 if (n_tokens > 8) {
435 for (i=8; tokens[i] && ilen < sizeof(info)-2 && strcmp(tokens[i], "00"); i++) {
436 guint ch;
437 sscanf(tokens[i], "%x", &ch);
438 info[ilen++] = ch;
439 }
440 info[ilen++] = 0;
441 set_gps_info(info, w);
442 }
443 g_strfreev(tokens);
444 }
445 /* eg: "Unit:\teTrex Legend HCx Software Version 2.90\n" */
446 if (strstr(line, "Unit:")) {
447 gchar **tokens = g_strsplit(line, "\t", 0);
448 int n_tokens = 0;
449 while (tokens[n_tokens])
450 n_tokens++;
451
452 if (n_tokens > 1) {
453 set_gps_info(tokens[1], w);
454 }
455 g_strfreev(tokens);
456 }
457 /* tells us how many items there will be */
458 if (strstr(line, "RECORD")) {
459 int lsb, msb, cnt;
460
461 if (strlen(line) > 20) {
462 sscanf(line+17, "%x", &lsb);
463 sscanf(line+20, "%x", &msb);
464 cnt = lsb + msb * 256;
465 set_total_count(cnt, w);
466 gps_data->count = 0;
467 }
468 }
469 if ( strstr(line, "WPTDAT") || strstr(line, "TRKHDR") || strstr(line, "TRKDAT") || strstr(line, "RTEHDR") || strstr(line, "RTEWPT") ) {
470 gps_data->count++;
471 set_current_count(gps_data->count, w);
472 }
473 break;
474 case BABEL_DONE:
475 break;
476 default:
477 break;
478 }
479}
480
481void append_element (gpointer elem, gpointer user_data)
482{
483 const gchar *text = ((BabelDevice*)elem)->label;
484 vik_combo_box_text_append (GTK_WIDGET(user_data), text);
485}
486
487static gint find_entry = -1;
488static gint wanted_entry = -1;
489
490static void find_protocol (gpointer elem, gpointer user_data)
491{
492 const gchar *name = ((BabelDevice*)elem)->name;
493 const gchar *protocol = user_data;
494 find_entry++;
495 if (!strcmp(name, protocol)) {
496 wanted_entry = find_entry;
497 }
498}
499
500static void datasource_gps_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data )
501{
502 gps_user_data_t *w = (gps_user_data_t *)user_data;
503 GtkTable *box, *data_type_box;
504
505 w->proto_l = gtk_label_new (_("GPS Protocol:"));
506 w->proto_b = vik_combo_box_text_new ();
507 g_list_foreach (a_babel_device_list, append_element, w->proto_b);
508
509 if ( last_active < 0 ) {
510 find_entry = -1;
511 wanted_entry = -1;
512 gchar *protocol = NULL;
513 if ( a_settings_get_string ( VIK_SETTINGS_GPS_PROTOCOL, &protocol ) ) {
514 // Use setting
515 if ( protocol )
516 g_list_foreach (a_babel_device_list, find_protocol, protocol);
517 }
518 else {
519 // Attempt to maintain default to Garmin devices (assumed most popular/numerous device)
520 g_list_foreach (a_babel_device_list, find_protocol, "garmin");
521 }
522 // If not found set it to the first entry, otherwise use the entry
523 last_active = ( wanted_entry < 0 ) ? 0 : wanted_entry;
524 }
525
526 gtk_combo_box_set_active (GTK_COMBO_BOX(w->proto_b), last_active);
527 g_object_ref(w->proto_b);
528
529 w->ser_l = gtk_label_new (_("Serial Port:"));
530#if GTK_CHECK_VERSION (2, 24, 0)
531 w->ser_b = gtk_combo_box_text_new_with_entry ();
532#else
533 w->ser_b = gtk_combo_box_entry_new_text ();
534#endif
535 // Value from the settings is promoted to the top
536 gchar *gps_port = NULL;
537 if ( a_settings_get_string ( VIK_SETTINGS_GPS_PORT, &gps_port ) ) {
538 // Use setting if available
539 if ( gps_port ) {
540#ifndef WINDOWS
541 if ( !strncmp (gps_port, "/dev/tty", 6) ) {
542 if (g_access (gps_port, R_OK) == 0) {
543 vik_combo_box_text_append (w->ser_b, gps_port);
544 }
545 }
546 else
547#endif
548 vik_combo_box_text_append (w->ser_b, gps_port);
549 }
550 }
551
552 // Note avoid appending the port selected from the settings
553#ifdef WINDOWS
554 if ( gps_port && strcmp (gps_port, "com1") )
555 vik_combo_box_text_append (w->ser_b, "com1");
556#else
557 /* Here just try to see if the device is available which gets passed onto gpsbabel
558 List USB devices first as these will generally only be present if autogenerated by udev or similar
559 User is still able to set their own free text entry */
560 if ( gps_port && strcmp (gps_port, "/dev/ttyUSB0") )
561 if (g_access ("/dev/ttyUSB0", R_OK) == 0)
562 vik_combo_box_text_append (w->ser_b, "/dev/ttyUSB0");
563 if ( gps_port && strcmp (gps_port, "/dev/ttyUSB1") )
564 if (g_access ("/dev/ttyUSB1", R_OK) == 0)
565 vik_combo_box_text_append (w->ser_b, "/dev/ttyUSB1");
566 if ( gps_port && strcmp (gps_port, "/dev/ttyS0") )
567 if (g_access ("/dev/ttyS0", R_OK) == 0)
568 vik_combo_box_text_append (w->ser_b, "/dev/ttyS0");
569 if ( gps_port && strcmp (gps_port, "/dev/ttyS1") )
570 if (g_access ("/dev/ttyS1", R_OK) == 0)
571 vik_combo_box_text_append (w->ser_b, "/dev/ttyS1");
572#endif
573 if ( gps_port && strcmp (gps_port, "usb:") )
574 vik_combo_box_text_append (w->ser_b, "usb:");
575
576 gtk_combo_box_set_active (GTK_COMBO_BOX(w->ser_b), 0);
577 g_object_ref(w->ser_b);
578
579 w->off_request_l = gtk_label_new (_("Turn Off After Transfer\n(Garmin/NAViLink Only)"));
580 w->off_request_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
581 gboolean power_off;
582 if ( ! a_settings_get_boolean ( VIK_SETTINGS_GPS_POWER_OFF, &power_off ) )
583 power_off = FALSE;
584 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->off_request_b), power_off);
585
586 w->get_tracks_l = gtk_label_new (_("Tracks:"));
587 w->get_tracks_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
588 gboolean get_tracks;
589 if ( ! a_settings_get_boolean ( VIK_SETTINGS_GPS_GET_TRACKS, &get_tracks ) )
590 get_tracks = TRUE;
591 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_tracks_b), get_tracks);
592
593 w->get_routes_l = gtk_label_new (_("Routes:"));
594 w->get_routes_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
595 gboolean get_routes;
596 if ( ! a_settings_get_boolean ( VIK_SETTINGS_GPS_GET_ROUTES, &get_routes ) )
597 get_routes = FALSE;
598 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_routes_b), get_routes);
599
600 w->get_waypoints_l = gtk_label_new (_("Waypoints:"));
601 w->get_waypoints_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
602 gboolean get_waypoints;
603 if ( ! a_settings_get_boolean ( VIK_SETTINGS_GPS_GET_WAYPOINTS, &get_waypoints ) )
604 get_waypoints = TRUE;
605 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->get_waypoints_b), get_waypoints);
606
607 box = GTK_TABLE(gtk_table_new(2, 4, FALSE));
608 data_type_box = GTK_TABLE(gtk_table_new(4, 1, FALSE));
609
610 gtk_table_attach_defaults(box, GTK_WIDGET(w->proto_l), 0, 1, 0, 1);
611 gtk_table_attach_defaults(box, GTK_WIDGET(w->proto_b), 1, 2, 0, 1);
612 gtk_table_attach_defaults(box, GTK_WIDGET(w->ser_l), 0, 1, 1, 2);
613 gtk_table_attach_defaults(box, GTK_WIDGET(w->ser_b), 1, 2, 1, 2);
614 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_tracks_l), 0, 1, 0, 1);
615 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_tracks_b), 1, 2, 0, 1);
616 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_routes_l), 2, 3, 0, 1);
617 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_routes_b), 3, 4, 0, 1);
618 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_waypoints_l), 4, 5, 0, 1);
619 gtk_table_attach_defaults(data_type_box, GTK_WIDGET(w->get_waypoints_b), 5, 6, 0, 1);
620 gtk_table_attach_defaults(box, GTK_WIDGET(data_type_box), 0, 2, 2, 3);
621 gtk_table_attach_defaults(box, GTK_WIDGET(w->off_request_l), 0, 1, 3, 4);
622 gtk_table_attach_defaults(box, GTK_WIDGET(w->off_request_b), 1, 3, 3, 4);
623 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), GTK_WIDGET(box), FALSE, FALSE, 5 );
624
625 gtk_widget_show_all ( dialog );
626}
627
628/**
629 * datasource_gps_setup:
630 * @dialog: The GTK dialog. The caller is responsible for managing the dialog creation/deletion
631 * @xfer: The default type of items enabled for transfer, others disabled.
632 * @xfer_all: When specified all items are enabled for transfer.
633 *
634 * Returns: A gpointer to the private structure for GPS progress/information widgets
635 * Pass this pointer back into the other exposed datasource_gps_X functions
636 */
637gpointer datasource_gps_setup ( GtkWidget *dialog, vik_gps_xfer_type xfer, gboolean xfer_all )
638{
639 gps_user_data_t *w_gps = (gps_user_data_t *)datasource_gps_init_func ( NULL );
640 w_gps->direction = GPS_UP;
641 datasource_gps_add_setup_widgets ( dialog, NULL, w_gps );
642
643 gboolean way = xfer_all;
644 gboolean trk = xfer_all;
645 gboolean rte = xfer_all;
646
647 // Selectively turn bits on
648 if ( !xfer_all ) {
649 switch (xfer) {
650 case WPT: way = TRUE; break;
651 case RTE: rte = TRUE; break;
652 default: trk = TRUE; break;
653 }
654 }
655
656 // Apply
657 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_tracks_b), trk );
658 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_tracks_l), trk );
659 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_tracks_b), trk );
660
661 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_routes_b), rte );
662 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_routes_l), rte );
663 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_routes_b), rte );
664
665 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(w_gps->get_waypoints_b), way );
666 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_waypoints_l), way );
667 gtk_widget_set_sensitive ( GTK_WIDGET(w_gps->get_waypoints_b), way );
668
669 return (gpointer)w_gps;
670}
671
672void datasource_gps_add_progress_widgets ( GtkWidget *dialog, gpointer user_data )
673{
674 GtkWidget *gpslabel, *verlabel, *idlabel, *wplabel, *trklabel, *rtelabel;
675
676 gps_user_data_t *w_gps = (gps_user_data_t *)user_data;
677
678 gpslabel = gtk_label_new (_("GPS device: N/A"));
679 verlabel = gtk_label_new ("");
680 idlabel = gtk_label_new ("");
681 wplabel = gtk_label_new ("");
682 trklabel = gtk_label_new ("");
683 rtelabel = gtk_label_new ("");
684
685 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), gpslabel, FALSE, FALSE, 5 );
686 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), wplabel, FALSE, FALSE, 5 );
687 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), trklabel, FALSE, FALSE, 5 );
688 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), rtelabel, FALSE, FALSE, 5 );
689
690 gtk_widget_show_all ( dialog );
691
692 w_gps->gps_label = gpslabel;
693 w_gps->id_label = idlabel;
694 w_gps->ver_label = verlabel;
695 w_gps->progress_label = w_gps->wp_label = wplabel;
696 w_gps->trk_label = trklabel;
697 w_gps->rte_label = rtelabel;
698 w_gps->total_count = -1;
699}