]> git.street.me.uk Git - andy/viking.git/blame - src/datasource_gps.c
Fix waypoints may not be drawn when created by paste of a text location.
[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;
8627bd99 44
307abf54 45static gpointer datasource_gps_init_func ( acq_vik_t *avt );
ed691ed1 46static void datasource_gps_get_cmd_string ( gpointer add_widgets_data_not_used, gchar **babelargs, gchar **input_file, gpointer not_used );
65f0ccab 47static void datasource_gps_cleanup ( gpointer user_data );
7b3479e3 48static void datasource_gps_progress ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w );
65f0ccab
AF
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 );
2b756ea0 51static void datasource_gps_off ( gpointer add_widgets_data_not_used, gchar **babelargs, gchar **input_file );
7b3479e3
EB
52
53VikDataSourceInterface vik_datasource_gps_interface = {
4c77d5e0
GB
54 N_("Acquire from GPS"),
55 N_("Acquired from GPS"),
9cc13848 56 VIK_DATASOURCE_AUTO_LAYER_MANAGEMENT,
28c82d8b
EB
57 VIK_DATASOURCE_INPUTTYPE_NONE,
58 TRUE,
d2525524 59 TRUE,
b2aa700f 60 TRUE,
65f0ccab 61 (VikDataSourceInitFunc) datasource_gps_init_func,
92255687 62 (VikDataSourceCheckExistenceFunc) NULL,
65f0ccab 63 (VikDataSourceAddSetupWidgetsFunc) datasource_gps_add_setup_widgets,
7b3479e3 64 (VikDataSourceGetCmdStringFunc) datasource_gps_get_cmd_string,
eb3f9398 65 (VikDataSourceProcessFunc) a_babel_convert_from,
7b3479e3
EB
66 (VikDataSourceProgressFunc) datasource_gps_progress,
67 (VikDataSourceAddProgressWidgetsFunc) datasource_gps_add_progress_widgets,
2b756ea0 68 (VikDataSourceCleanupFunc) datasource_gps_cleanup,
63959706
RN
69 (VikDataSourceOffFunc) datasource_gps_off,
70
71 NULL,
72 0,
73 NULL,
74 NULL,
75 0
7b3479e3
EB
76};
77
78/*********************************************************
79 * Definitions and routines for acquiring data from GPS
80 *********************************************************/
81
65f0ccab 82/* widgets in setup dialog specific to GPS */
7b3479e3
EB
83/* widgets in progress dialog specific to GPS */
84/* also counts needed for progress */
85typedef struct {
65f0ccab
AF
86 /* setup dialog */
87 GtkWidget *proto_l;
1bc1c05b 88 GtkWidget *proto_b;
65f0ccab 89 GtkWidget *ser_l;
1bc1c05b 90 GtkWidget *ser_b;
2b756ea0
RN
91 GtkWidget *off_request_l;
92 GtkCheckButton *off_request_b;
d6c58ab9
RN
93 GtkWidget *get_tracks_l;
94 GtkCheckButton *get_tracks_b;
0d2b891f
RN
95 GtkWidget *get_routes_l;
96 GtkCheckButton *get_routes_b;
d6c58ab9
RN
97 GtkWidget *get_waypoints_l;
98 GtkCheckButton *get_waypoints_b;
65f0ccab
AF
99
100 /* progress dialog */
7b3479e3
EB
101 GtkWidget *gps_label;
102 GtkWidget *ver_label;
103 GtkWidget *id_label;
104 GtkWidget *wp_label;
105 GtkWidget *trk_label;
0d2b891f 106 GtkWidget *rte_label;
7b3479e3 107 GtkWidget *progress_label;
0d2b891f 108 vik_gps_xfer_type progress_type;
65f0ccab
AF
109
110 /* state */
7b3479e3
EB
111 int total_count;
112 int count;
aa6dfd27
RN
113 // Know which way xfer is so xfer setting types are only stored for download
114 vik_gps_dir direction;
65f0ccab
AF
115} gps_user_data_t;
116
aa6dfd27
RN
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
307abf54 124static gpointer datasource_gps_init_func ( acq_vik_t *avt )
65f0ccab 125{
aa6dfd27
RN
126 gps_user_data_t *gps_ud = g_malloc (sizeof(gps_user_data_t));
127 gps_ud->direction = GPS_DOWN;
128 return gps_ud;
65f0ccab 129}
7b3479e3 130
d80e59ba
RN
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));
aa6dfd27
RN
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 }
d80e59ba
RN
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;
1bc1c05b
RN
160
161#if GTK_CHECK_VERSION (2, 24, 0)
aa6dfd27 162 gchar *descriptor = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w->ser_b));
1bc1c05b 163#else
aa6dfd27 164 gchar *descriptor = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
1bc1c05b 165#endif
aa6dfd27
RN
166 a_settings_set_string ( VIK_SETTINGS_GPS_PORT, descriptor );
167 return descriptor;
d80e59ba
RN
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;
aa6dfd27
RN
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;
d80e59ba
RN
182}
183
0d2b891f
RN
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;
aa6dfd27
RN
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;
0d2b891f
RN
196}
197
d80e59ba
RN
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;
aa6dfd27
RN
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;
d80e59ba
RN
210}
211
ed691ed1 212static void datasource_gps_get_cmd_string ( gpointer user_data, gchar **babelargs, gchar **input_file, gpointer not_used )
7b3479e3 213{
cf7fdc15 214 char *device = NULL;
d6c58ab9 215 char *tracks = NULL;
0d2b891f 216 char *routes = NULL;
d6c58ab9 217 char *waypoints = NULL;
65f0ccab 218
7b3479e3
EB
219 if (gps_acquire_in_progress) {
220 *babelargs = *input_file = NULL;
221 }
65f0ccab
AF
222
223 gps_acquire_in_progress = TRUE;
224
d80e59ba 225 device = datasource_gps_get_protocol ( user_data );
2b756ea0 226
d80e59ba 227 if ( datasource_gps_get_do_tracks ( user_data ) )
d6c58ab9
RN
228 tracks = "-t";
229 else
230 tracks = "";
d80e59ba 231
0d2b891f
RN
232 if ( datasource_gps_get_do_routes ( user_data ) )
233 routes = "-r";
234 else
235 routes = "";
236
d80e59ba 237 if ( datasource_gps_get_do_waypoints ( user_data ) )
d6c58ab9
RN
238 waypoints = "-w";
239 else
240 waypoints = "";
241
0d2b891f 242 *babelargs = g_strdup_printf("-D 9 %s %s %s -i %s", tracks, routes, waypoints, device);
cf7fdc15
GB
243 /* device points to static content => no free */
244 device = NULL;
d6c58ab9 245 tracks = NULL;
0d2b891f 246 routes = NULL;
d6c58ab9
RN
247 waypoints = NULL;
248
d80e59ba 249 *input_file = g_strdup(datasource_gps_get_descriptor(user_data));
7b3479e3 250
4c77d5e0 251 g_debug(_("using cmdline '%s' and file '%s'\n"), *babelargs, *input_file);
7b3479e3
EB
252}
253
d80e59ba
RN
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;
aa6dfd27
RN
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;
d80e59ba 265}
2b756ea0
RN
266
267static void datasource_gps_off ( gpointer user_data, gchar **babelargs, gchar **input_file )
268{
2b756ea0
RN
269 char *ser = NULL;
270 char *device = NULL;
2b756ea0
RN
271 gps_user_data_t *w = (gps_user_data_t *)user_data;
272
273 if (gps_acquire_in_progress) {
274 *babelargs = *input_file = NULL;
275 }
276
277 /* See if we should turn off the device */
d80e59ba 278 if (!datasource_gps_get_off ( user_data )){
2b756ea0
RN
279 return;
280 }
281
78f6c63d
RN
282 if (!a_babel_device_list)
283 return;
8627bd99
GB
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")) {
2b756ea0 287 device = "garmin,power_off";
4136d029 288 }
8627bd99 289 else if (!strcmp(device, "navilink")) {
4136d029
RN
290 device = "navilink,power_off";
291 }
292 else {
2b756ea0
RN
293 return;
294 }
295
296 *babelargs = g_strdup_printf("-i %s", device);
297 /* device points to static content => no free */
298 device = NULL;
299
1bc1c05b
RN
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
2b756ea0 303 ser = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->ser_b));
1bc1c05b 304#endif
2b756ea0
RN
305 *input_file = g_strdup(ser);
306}
307
308
65f0ccab 309static void datasource_gps_cleanup ( gpointer user_data )
7b3479e3 310{
65f0ccab 311 g_free ( user_data );
7b3479e3
EB
312 gps_acquire_in_progress = FALSE;
313}
314
d80e59ba
RN
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
7b3479e3
EB
325static void set_total_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;
97634600 331 const gchar *tmp_str;
0d2b891f
RN
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 }
97634600 344 s = g_strdup_printf(tmp_str, cnt);
7b3479e3
EB
345 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
346 gtk_widget_show ( gps_data->progress_label );
7b3479e3 347 }
cf7fdc15 348 g_free(s); s = NULL;
7b3479e3
EB
349 gdk_threads_leave();
350}
351
352static void set_current_count(gint cnt, acq_dialog_widgets_t *w)
353{
cf7fdc15 354 gchar *s = NULL;
7b3479e3 355 gdk_threads_enter();
b2aa700f 356 if (w->running) {
65f0ccab 357 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
7b3479e3
EB
358
359 if (cnt < gps_data->total_count) {
0d2b891f
RN
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 }
7b3479e3 365 } else {
0d2b891f
RN
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 }
7b3479e3
EB
372 gtk_label_set_text ( GTK_LABEL(gps_data->progress_label), s );
373 }
cf7fdc15 374 g_free(s); s = NULL;
7b3479e3
EB
375 gdk_threads_leave();
376}
377
378static void set_gps_info(const gchar *info, acq_dialog_widgets_t *w)
379{
cf7fdc15 380 gchar *s = NULL;
7b3479e3 381 gdk_threads_enter();
b2aa700f 382 if (w->running) {
4c77d5e0 383 s = g_strdup_printf(_("GPS Device: %s"), info);
65f0ccab 384 gtk_label_set_text ( GTK_LABEL(((gps_user_data_t *)w->user_data)->gps_label), s );
7b3479e3 385 }
cf7fdc15 386 g_free(s); s = NULL;
7b3479e3
EB
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;
65f0ccab 398 gps_user_data_t *gps_data = (gps_user_data_t *)w->user_data;
7b3479e3 399
7b3479e3
EB
400 switch(c) {
401 case BABEL_DIAG_OUTPUT:
402 line = (gchar *)data;
403
8d0586c6 404 gdk_threads_enter();
b2aa700f 405 if (w->running) {
8d0586c6
RN
406 gtk_label_set_text ( GTK_LABEL(w->status), _("Status: Working...") );
407 }
408 gdk_threads_leave();
409
0d2b891f
RN
410 /* tells us the type of items that will follow */
411 if (strstr(line, "Xfer Wpt")) {
7b3479e3 412 gps_data->progress_label = gps_data->wp_label;
0d2b891f 413 gps_data->progress_type = WPT;
7b3479e3 414 }
0d2b891f 415 if (strstr(line, "Xfer Trk")) {
7b3479e3 416 gps_data->progress_label = gps_data->trk_label;
0d2b891f
RN
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;
7b3479e3 422 }
0d2b891f 423
7b3479e3
EB
424 if (strstr(line, "PRDDAT")) {
425 gchar **tokens = g_strsplit(line, " ", 0);
426 gchar info[128];
427 int ilen = 0;
428 int i;
c83b5ad9
QT
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);
7b3479e3 442 }
c83b5ad9 443 g_strfreev(tokens);
7b3479e3 444 }
0a3f9142
RN
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 }
0d2b891f
RN
457 /* tells us how many items there will be */
458 if (strstr(line, "RECORD")) {
7b3479e3
EB
459 int lsb, msb, cnt;
460
c83b5ad9
QT
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 }
7b3479e3 468 }
0d2b891f 469 if ( strstr(line, "WPTDAT") || strstr(line, "TRKHDR") || strstr(line, "TRKDAT") || strstr(line, "RTEHDR") || strstr(line, "RTEWPT") ) {
7b3479e3
EB
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
8627bd99
GB
481void append_element (gpointer elem, gpointer user_data)
482{
8627bd99 483 const gchar *text = ((BabelDevice*)elem)->label;
1bc1c05b 484 vik_combo_box_text_append (GTK_WIDGET(user_data), text);
8627bd99
GB
485}
486
3f6db253 487static gint find_entry = -1;
aa6dfd27 488static gint wanted_entry = -1;
3f6db253 489
aa6dfd27 490static void find_protocol (gpointer elem, gpointer user_data)
3f6db253
RN
491{
492 const gchar *name = ((BabelDevice*)elem)->name;
aa6dfd27 493 const gchar *protocol = user_data;
3f6db253 494 find_entry++;
aa6dfd27
RN
495 if (!strcmp(name, protocol)) {
496 wanted_entry = find_entry;
3f6db253
RN
497 }
498}
499
d80e59ba 500static void datasource_gps_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data )
65f0ccab
AF
501{
502 gps_user_data_t *w = (gps_user_data_t *)user_data;
d6c58ab9 503 GtkTable *box, *data_type_box;
65f0ccab 504
4c77d5e0 505 w->proto_l = gtk_label_new (_("GPS Protocol:"));
1bc1c05b 506 w->proto_b = vik_combo_box_text_new ();
8627bd99 507 g_list_foreach (a_babel_device_list, append_element, w->proto_b);
3f6db253 508
3f6db253
RN
509 if ( last_active < 0 ) {
510 find_entry = -1;
aa6dfd27
RN
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);
aa6dfd27
RN
517 }
518 else {
a8ae980e 519 // Attempt to maintain default to Garmin devices (assumed most popular/numerous device)
aa6dfd27 520 g_list_foreach (a_babel_device_list, find_protocol, "garmin");
aa6dfd27 521 }
a8ae980e
RN
522 // If not found set it to the first entry, otherwise use the entry
523 last_active = ( wanted_entry < 0 ) ? 0 : wanted_entry;
3f6db253
RN
524 }
525
1bc1c05b 526 gtk_combo_box_set_active (GTK_COMBO_BOX(w->proto_b), last_active);
65f0ccab
AF
527 g_object_ref(w->proto_b);
528
4c77d5e0 529 w->ser_l = gtk_label_new (_("Serial Port:"));
1bc1c05b
RN
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
aa6dfd27
RN
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
8d70f073 553#ifdef WINDOWS
aa6dfd27
RN
554 if ( gps_port && strcmp (gps_port, "com1") )
555 vik_combo_box_text_append (w->ser_b, "com1");
8d70f073 556#else
99163c34
RN
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 */
aa6dfd27
RN
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");
8d70f073 572#endif
aa6dfd27
RN
573 if ( gps_port && strcmp (gps_port, "usb:") )
574 vik_combo_box_text_append (w->ser_b, "usb:");
575
1bc1c05b 576 gtk_combo_box_set_active (GTK_COMBO_BOX(w->ser_b), 0);
65f0ccab
AF
577 g_object_ref(w->ser_b);
578
4136d029 579 w->off_request_l = gtk_label_new (_("Turn Off After Transfer\n(Garmin/NAViLink Only)"));
2b756ea0 580 w->off_request_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
aa6dfd27
RN
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);
2b756ea0 585
d6c58ab9
RN
586 w->get_tracks_l = gtk_label_new (_("Tracks:"));
587 w->get_tracks_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
aa6dfd27
RN
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);
d6c58ab9 592
0d2b891f
RN
593 w->get_routes_l = gtk_label_new (_("Routes:"));
594 w->get_routes_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
aa6dfd27
RN
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);
0d2b891f 599
d6c58ab9
RN
600 w->get_waypoints_l = gtk_label_new (_("Waypoints:"));
601 w->get_waypoints_b = GTK_CHECK_BUTTON ( gtk_check_button_new () );
aa6dfd27
RN
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);
d6c58ab9
RN
606
607 box = GTK_TABLE(gtk_table_new(2, 4, FALSE));
608 data_type_box = GTK_TABLE(gtk_table_new(4, 1, FALSE));
609
65f0ccab
AF
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);
d6c58ab9
RN
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);
0d2b891f
RN
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);
d6c58ab9
RN
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);
9b082b39 623 gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), GTK_WIDGET(box), FALSE, FALSE, 5 );
65f0ccab
AF
624
625 gtk_widget_show_all ( dialog );
626}
627
d80e59ba
RN
628/**
629 * datasource_gps_setup:
630 * @dialog: The GTK dialog. The caller is responsible for managing the dialog creation/deletion
0d2b891f
RN
631 * @xfer: The default type of items enabled for transfer, others disabled.
632 * @xfer_all: When specified all items are enabled for transfer.
d80e59ba
RN
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 */
0d2b891f 637gpointer datasource_gps_setup ( GtkWidget *dialog, vik_gps_xfer_type xfer, gboolean xfer_all )
d80e59ba 638{
307abf54 639 gps_user_data_t *w_gps = (gps_user_data_t *)datasource_gps_init_func ( NULL );
aa6dfd27 640 w_gps->direction = GPS_UP;
d80e59ba
RN
641 datasource_gps_add_setup_widgets ( dialog, NULL, w_gps );
642
0d2b891f
RN
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 }
d80e59ba 654 }
0d2b891f
RN
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
d80e59ba
RN
669 return (gpointer)w_gps;
670}
671
65f0ccab 672void datasource_gps_add_progress_widgets ( GtkWidget *dialog, gpointer user_data )
7b3479e3 673{
0d2b891f 674 GtkWidget *gpslabel, *verlabel, *idlabel, *wplabel, *trklabel, *rtelabel;
7b3479e3 675
65f0ccab 676 gps_user_data_t *w_gps = (gps_user_data_t *)user_data;
7b3479e3 677
4c77d5e0 678 gpslabel = gtk_label_new (_("GPS device: N/A"));
7b3479e3
EB
679 verlabel = gtk_label_new ("");
680 idlabel = gtk_label_new ("");
681 wplabel = gtk_label_new ("");
682 trklabel = gtk_label_new ("");
0d2b891f 683 rtelabel = gtk_label_new ("");
7b3479e3 684
9b082b39
RN
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 );
7b3479e3 689
7b3479e3
EB
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;
0d2b891f 697 w_gps->rte_label = rtelabel;
7b3479e3 698 w_gps->total_count = -1;
7b3479e3 699}