Contents of /trunk/src/geotoad.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (hide annotations)
Wed Nov 25 10:13:26 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 21045 byte(s)
GeoToad UI interaction
1 harbaum 193 /*
2     * Copyright (C) 2009 Till Harbaum <till@harbaum.org>.
3     *
4     * This file is part of GPXView.
5     *
6     * GPXView is free software: you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * GPXView is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18     */
19    
20     #include "gpxview.h"
21    
22 harbaum 206 #define __USE_GNU
23     #include <string.h>
24    
25 harbaum 193 #include <fcntl.h>
26     #include <sys/types.h>
27     #include <sys/wait.h>
28     #include <errno.h>
29 harbaum 198 #include <math.h>
30 harbaum 193
31 harbaum 198 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
32     #include <hildon/hildon-entry.h>
33     #endif
34    
35 harbaum 196 #define GEOTOAD "/usr/bin/geotoad"
36    
37 harbaum 195 #define COLOR_ERR "red"
38     #define COLOR_OK "darkgreen"
39     #define COLOR_SYSTEM "darkblue"
40 harbaum 194
41 harbaum 195 #define BUFFER_SIZE 256
42 harbaum 193
43 harbaum 206 typedef enum {
44     GT_STATE_ILLEGAL = 0,
45     GT_STATE_STARTED,
46     GT_STATE_PREMATURE_END,
47     GT_STATE_SAVE_FOUND,
48     } gt_state_t;
49    
50 harbaum 193 typedef struct {
51 harbaum 194 appdata_t *appdata;
52 harbaum 206
53     GPtrArray *argv;
54 harbaum 207 gchar *info, *color;
55 harbaum 206 GMutex *update_mutex;
56     GCond *update_cond;
57 harbaum 194
58 harbaum 206 gt_state_t state;
59    
60 harbaum 198 GtkWidget *dialog;
61    
62 harbaum 206 long pid;
63 harbaum 193
64 harbaum 194 struct log_s {
65     GtkTextBuffer *buffer;
66     GtkWidget *view;
67     } log;
68 harbaum 196
69 harbaum 198 GtkWidget *username, *password, *filename;
70     GtkWidget *lat, *lon, *dst;
71 harbaum 208
72     int use_cnt;
73 harbaum 194
74 harbaum 193 } gt_context_t;
75    
76 harbaum 206 static void arg_free(gpointer data, gpointer user_data) {
77     if(data) g_free(data);
78     }
79    
80     static void context_free(gt_context_t *context) {
81 harbaum 208 context->use_cnt--;
82    
83     if(context->use_cnt > 0)
84     printf("still in use by %d, keeping context\n", context->use_cnt);
85     else {
86     printf("freeing context\n");
87 harbaum 206
88 harbaum 208 if(context->info) g_free(context->info);
89 harbaum 206
90 harbaum 208 g_ptr_array_foreach(context->argv, arg_free, NULL);
91     g_ptr_array_free (context->argv, TRUE);
92 harbaum 206
93 harbaum 208 g_free(context);
94     }
95 harbaum 206 }
96    
97 harbaum 194 static void appendf(struct log_s *log, char *colname,
98     const char *fmt, ...) {
99     va_list args;
100     va_start( args, fmt );
101     char *buf = g_strdup_vprintf(fmt, args);
102     va_end( args );
103    
104 harbaum 207 // printf("append: %s", buf);
105 harbaum 195
106 harbaum 194 GtkTextTag *tag = NULL;
107     if(colname)
108     tag = gtk_text_buffer_create_tag(log->buffer, NULL,
109     "foreground", colname,
110     NULL);
111    
112     GtkTextIter end;
113     gtk_text_buffer_get_end_iter(log->buffer, &end);
114     if(tag)
115     gtk_text_buffer_insert_with_tags(log->buffer, &end, buf, -1, tag, NULL);
116     else
117     gtk_text_buffer_insert(log->buffer, &end, buf, -1);
118    
119     g_free(buf);
120    
121     gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(log->view),
122 harbaum 211 &end, 0.0, TRUE, 1.0, 1.0);
123 harbaum 194 }
124    
125 harbaum 206 // This function receives a requst from a worker thread asking to
126     // update the gui with the required info.
127     gboolean cb_update_job(gt_context_t *context) {
128     if (context->info) {
129 harbaum 207
130     /* check if client reports "saved to ..." */
131     if(strstr(context->info, "Saved to "))
132 harbaum 206 context->state = GT_STATE_SAVE_FOUND;
133 harbaum 193
134 harbaum 207 appendf(&context->log, context->color, context->info);
135 harbaum 206
136     g_free(context->info);
137     context->info = NULL;
138     }
139    
140     // Indicate that the update is done
141     g_mutex_lock(context->update_mutex);
142     g_cond_signal(context->update_cond);
143     g_mutex_unlock(context->update_mutex);
144    
145     return FALSE;
146     }
147 harbaum 193
148 harbaum 206 // A helper function run in the job thread receiving the string that
149     // should be displayed in the textview.
150 harbaum 207 void append_parentf(gt_context_t *context, char *colname,
151     const char *fmt, ...) {
152     va_list args;
153     va_start( args, fmt );
154     context->info = g_strdup_vprintf(fmt, args);
155     va_end( args );
156    
157     if(colname)
158     context->color = colname;
159     else
160     context->color = NULL;
161    
162 harbaum 206 // Lock mutex to make sure that we will receive the condition signal
163     g_mutex_lock(context->update_mutex);
164 harbaum 207
165 harbaum 206 g_idle_add((GSourceFunc)cb_update_job, context);
166    
167     // Wait for cb_update_job to tell me that the update is done
168 harbaum 207 g_cond_wait(context->update_cond, context->update_mutex);
169 harbaum 206 g_mutex_unlock(context->update_mutex);
170 harbaum 193 }
171    
172 harbaum 206 /* custom version of popen to get access to the pid and to be able */
173     /* to slaughter the child process */
174 harbaum 207 static FILE *gt_popen(gt_context_t *context, char **args,
175     const char *type, long *tid) {
176 harbaum 206 int p[2];
177     FILE *fp;
178    
179     if (*type != 'r' && *type != 'w')
180     return NULL;
181    
182     if (pipe(p) < 0)
183     return NULL;
184    
185     if ((*tid = fork()) > 0) { /* then we are the parent */
186     if (*type == 'r') {
187     close(p[1]);
188     fp = fdopen(p[0], type);
189     } else {
190     close(p[0]);
191     fp = fdopen(p[1], type);
192     }
193    
194     return fp;
195     } else if (*tid == 0) { /* we're the child */
196 harbaum 193
197 harbaum 206 /* make our thread id the process group leader */
198     setpgid(0, 0);
199 harbaum 193
200 harbaum 206 if (*type == 'r') {
201     fflush(stdout);
202     fflush(stderr);
203     close(1);
204     if (dup(p[1]) < 0)
205     perror("dup of write side of pipe failed");
206     close(2);
207     if (dup(p[1]) < 0)
208     perror("dup of write side of pipe failed");
209     } else {
210     close(0);
211     if (dup(p[0]) < 0)
212     perror("dup of read side of pipe failed");
213 harbaum 193 }
214 harbaum 206
215     close(p[0]); /* close since we dup()'ed what we needed */
216     close(p[1]);
217    
218     execve(args[0], args, NULL);
219    
220 harbaum 207 /* this printf will actually be redirected through the pipe */
221     printf("Error: Failed to execute!\n");
222 harbaum 210 exit(1);
223 harbaum 206 } else { /* we're having major problems... */
224     close(p[0]);
225     close(p[1]);
226 harbaum 207
227 harbaum 208 /* this printf will actually be redirected through the pipe??? No! */
228 harbaum 207 printf("Error: Failed to fork!\n");
229 harbaum 206 }
230    
231     return NULL;
232     }
233 harbaum 193
234 harbaum 206 // The thread entry point. It will do the job, send the data to the
235     // GUI and self destruct when it is done.
236     static gpointer thread_worker(gt_context_t *context)
237     {
238     FILE *fh;
239     GIOStatus status;
240     GError *error = NULL;
241     gsize length;
242     gsize terminator_pos;
243     gchar *str_return;
244 harbaum 193
245 harbaum 207 fh = gt_popen(context, (char**)(context->argv->pdata),"r", &context->pid);
246 harbaum 206 if(!fh) {
247 harbaum 208 printf("fail free\n");
248     context_free(context);
249     // g_thread_exit(NULL);
250 harbaum 206 return NULL;
251 harbaum 193 }
252    
253 harbaum 208 /* the client is running */
254     printf("client inc use_cnt\n");
255     context->use_cnt++;
256    
257 harbaum 206 /* switch to line buffered mode */
258     if(setvbuf(fh, NULL, _IOLBF, 0))
259     perror("setvbuf(_IOLBF)");
260    
261     GIOChannel *gh = g_io_channel_unix_new(fileno(fh));
262 harbaum 193
263 harbaum 206 while( (status = g_io_channel_read_line(gh,
264     &str_return,
265     &length,
266     &terminator_pos,
267     &error)) == G_IO_STATUS_NORMAL) {
268 harbaum 207 char *color = NULL;
269     if(strstr(str_return, "Saved to ")) color = COLOR_OK;
270     if(strcasestr(str_return, "error")) color = COLOR_ERR;
271    
272     append_parentf(context, color, str_return);
273 harbaum 206 g_free(str_return);
274     }
275    
276     g_io_channel_unref(gh);
277     pclose(fh);
278 harbaum 207 append_parentf(context, COLOR_SYSTEM, "Job done!");
279 harbaum 208
280 harbaum 206 context_free(context);
281    
282 harbaum 210 g_thread_exit(NULL);
283 harbaum 206 return NULL;
284 harbaum 200 }
285    
286 harbaum 206
287 harbaum 200 static void arg_dsp(gpointer data, gpointer user_data) {
288     gt_context_t *context = (gt_context_t*)user_data;
289    
290     if(data)
291     appendf(&context->log, COLOR_SYSTEM, "%s\n", data);
292     }
293    
294 harbaum 194 static void run(gt_context_t *context) {
295 harbaum 206 GError *error = NULL;
296 harbaum 200 char str[8];
297    
298 harbaum 194 /* build list of arguments to call geotoad */
299 harbaum 206 context->argv = g_ptr_array_new();
300 harbaum 210 g_ptr_array_add (context->argv, g_strdup_printf(GEOTOAD));
301 harbaum 200 g_ascii_dtostr(str, sizeof(str), context->appdata->gt.distance);
302 harbaum 210 g_ptr_array_add (context->argv,
303     g_strdup_printf("--distanceMax=%s", str));
304     g_ptr_array_add (context->argv,
305     g_strdup_printf("--output=%s", context->appdata->gt.filename));
306     g_ptr_array_add (context->argv,
307     g_strdup_printf("--password=%s", context->appdata->gt.password));
308     g_ptr_array_add (context->argv,
309     g_strdup_printf("--queryType=coord"));
310     g_ptr_array_add (context->argv,
311     g_strdup_printf("--user=%s", context->appdata->username));
312 harbaum 194
313     /* check if we need to add proxy config */
314     char *proxy = NULL;
315 harbaum 211
316 harbaum 194 if(context->appdata->proxy && context->appdata->proxy->host) {
317     if(context->appdata->proxy->use_authentication &&
318     context->appdata->proxy->authentication_user &&
319     context->appdata->proxy->authentication_password)
320     proxy = g_strdup_printf("--proxy=http://%s:%s@%s:%d",
321 harbaum 206 context->appdata->proxy->authentication_user,
322     context->appdata->proxy->authentication_password,
323     context->appdata->proxy->host,
324     context->appdata->proxy->port);
325 harbaum 194 else
326     proxy = g_strdup_printf("--proxy=http://%s:%d",
327 harbaum 206 context->appdata->proxy->host,
328     context->appdata->proxy->port);
329 harbaum 194
330 harbaum 211 } else {
331     /* use environment settings if preset (for scratchbox) */
332     const char *proxy_env = g_getenv("http_proxy");
333     if(proxy_env)
334     proxy = g_strdup_printf("--proxy=%s", proxy_env);
335     }
336    
337     if(proxy)
338 harbaum 206 g_ptr_array_add (context->argv, proxy);
339 harbaum 194
340 harbaum 206 /* convert coordinates into simple ascii format */
341     char n = (context->appdata->gt.lat >= 0)?'N':'S';
342     char e = (context->appdata->gt.lon >= 0)?'E':'W';
343     float lat = fabs(context->appdata->gt.lat);
344     float lon = fabs(context->appdata->gt.lon);
345     float lat_mint, lat_int, lat_frac = modff(lat, &lat_int);
346     float lon_mint, lon_int, lon_frac = modff(lon, &lon_int);
347     lat_frac = modff(lat_frac*60.0, &lat_mint);
348     lon_frac = modff(lon_frac*60.0, &lon_mint);
349 harbaum 194
350 harbaum 206 g_ptr_array_add (context->argv,
351     g_strdup_printf("%c%02u %02u.%03u %c%03u %02u.%03u",
352     n, (int)lat_int, (int)lat_mint, (int)(lat_frac*1000.0+0.5),
353     e, (int)lon_int, (int)lon_mint, (int)(lon_frac*1000.0+0.5)));
354    
355     g_ptr_array_add (context->argv, NULL);
356    
357 harbaum 200 /* show all entries */
358 harbaum 206 g_ptr_array_foreach(context->argv, arg_dsp, context);
359 harbaum 200
360 harbaum 206 g_thread_create((GThreadFunc)thread_worker, context, FALSE, &error);
361     if (error) {
362     appendf(&context->log, COLOR_ERR, "Error: %s\n", error->message);
363 harbaum 193 g_error_free(error);
364     }
365     }
366 harbaum 194
367 harbaum 196 /* show text window and display output of running geotoad */
368     static void gui_run(gt_context_t *context) {
369     GtkWidget *dialog = gtk_dialog_new_with_buttons(_("GeoToad - Run"),
370     GTK_WINDOW(context->appdata->window),
371 harbaum 194 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
372     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
373     NULL);
374    
375     gtk_window_set_default_size(GTK_WINDOW(dialog), 640, 480);
376    
377     #ifndef USE_PANNABLE_AREA
378     GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
379     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
380     GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
381     #else
382     GtkWidget *pannable_area = hildon_pannable_area_new();
383     #endif
384    
385     context->log.buffer = gtk_text_buffer_new(NULL);
386    
387     #ifndef USE_HILDON_TEXT_VIEW
388     context->log.view = gtk_text_view_new_with_buffer(context->log.buffer);
389     #else
390     context->log.view = hildon_text_view_new();
391     hildon_text_view_set_buffer(HILDON_TEXT_VIEW(context->log.view),
392     context->log.buffer);
393     #endif
394    
395     #ifndef USE_PANNABLE_AREA
396     gtk_container_add(GTK_CONTAINER(scrolled_window), context->log.view);
397     gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(scrolled_window),
398     GTK_SHADOW_IN);
399    
400     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
401     scrolled_window, TRUE, TRUE, 0);
402     #else
403     gtk_container_add(GTK_CONTAINER(pannable_area), context->log.view);
404     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
405     pannable_area, TRUE, TRUE, 0);
406     #endif
407    
408     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
409    
410     gtk_widget_show_all(dialog);
411    
412 harbaum 195 appendf(&context->log, COLOR_SYSTEM, "Running GeoToad\n");
413 harbaum 194 run(context);
414    
415     gtk_dialog_run(GTK_DIALOG(dialog));
416    
417     gtk_widget_destroy(dialog);
418     }
419 harbaum 196
420 harbaum 198 static void on_browse(GtkWidget *widget, gpointer data) {
421     gt_context_t *context = (gt_context_t*)data;
422    
423     printf("Browse %p\n", context->dialog);
424    
425     #ifdef USE_MAEMO
426     GtkWidget *dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(context->dialog),
427     GTK_FILE_CHOOSER_ACTION_SAVE);
428     #else
429     GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Save GPX file"),
430     GTK_WINDOW(context->dialog),
431     GTK_FILE_CHOOSER_ACTION_SAVE,
432     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
433     GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
434     NULL);
435     #endif
436    
437     printf("set filename <%s>\n", context->appdata->gt.filename);
438    
439     if(!g_file_test(context->appdata->gt.filename, G_FILE_TEST_EXISTS)) {
440     char *last_sep = strrchr(context->appdata->gt.filename, '/');
441     if(last_sep) {
442     *last_sep = 0; // seperate path from file
443    
444     /* the user just created a new document */
445     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
446     context->appdata->gt.filename);
447     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), last_sep+1);
448    
449     /* restore full filename */
450     *last_sep = '/';
451     }
452     } else
453     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
454     context->appdata->gt.filename);
455    
456     if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
457     gchar *name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
458     gtk_label_set_text(GTK_LABEL(context->filename), name);
459     }
460    
461     gtk_widget_destroy (dialog);
462     }
463    
464 harbaum 196 static gboolean gui_setup(gt_context_t *context) {
465 harbaum 198 appdata_t *appdata = context->appdata;
466 harbaum 196 gboolean ok = FALSE;
467    
468 harbaum 198 /* if no filename has been setup yet, create one */
469     if(!appdata->gt.filename && appdata->path) {
470     printf("creating path\n");
471     appdata->gt.filename =
472     g_strdup_printf("%s/gtoad.gpx", appdata->path);
473     }
474 harbaum 196
475 harbaum 198 context->dialog = gtk_dialog_new_with_buttons(_("GeoToad - Setup"),
476     GTK_WINDOW(appdata->window),
477     GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
478     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
479     GTK_STOCK_OK, GTK_RESPONSE_OK,
480     NULL);
481    
482     /* ------------------- Coordinates ------------------------- */
483 harbaum 196 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
484 harbaum 198
485 harbaum 196 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
486 harbaum 199 gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Position:")));
487 harbaum 198 gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Distance:")));
488     gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
489    
490     /* setup default positions */
491     pos_t *refpos = get_pos(appdata);
492     if((isnan(appdata->gt.lat) || isnan(appdata->gt.lat)) && refpos) {
493     appdata->gt.lat = refpos->lat;
494     appdata->gt.lon = refpos->lon;
495     }
496    
497     vbox = gtk_vbox_new(FALSE, 0);
498 harbaum 199 GtkWidget *ihbox = gtk_hbox_new(FALSE, 0);
499 harbaum 198 context->lat = lat_entry_new(appdata->gt.lat);
500 harbaum 199 gtk_box_pack_start_defaults(GTK_BOX(ihbox), context->lat);
501     context->lon = lon_entry_new(appdata->gt.lon);
502     gtk_box_pack_start_defaults(GTK_BOX(ihbox), context->lon);
503     gtk_box_pack_start_defaults(GTK_BOX(vbox), ihbox);
504 harbaum 200 float dst = appdata->gt.distance; // distance is given in kilometers
505     if(appdata->imperial) dst /= 1.609344;
506     context->dst = dist_entry_new(dst, appdata->imperial);
507 harbaum 198 gtk_box_pack_start_defaults(GTK_BOX(vbox), context->dst);
508 harbaum 196 gtk_box_pack_start_defaults(GTK_BOX(hbox), vbox);
509 harbaum 198
510     gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), hbox);
511    
512     /* ------------------- file name ------------------------- */
513     hbox = gtk_hbox_new(FALSE, 0);
514    
515     context->filename = gtk_label_new(appdata->gt.filename);
516     gtk_misc_set_alignment(GTK_MISC(context->filename), 0.f, 0.5f);
517     gtk_label_set_ellipsize(GTK_LABEL(context->filename), PANGO_ELLIPSIZE_MIDDLE);
518     gtk_box_pack_start_defaults(GTK_BOX(hbox), context->filename);
519    
520     GtkWidget *button = gtk_button_new_with_label(_("Browse"));
521 harbaum 199 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR == 5)
522     hildon_gtk_widget_set_theme_size(button,
523     (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
524     #endif
525 harbaum 198 gtk_signal_connect(GTK_OBJECT(button), "clicked",
526     GTK_SIGNAL_FUNC(on_browse), context);
527     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
528    
529     gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), hbox);
530    
531    
532     /* ------------------- Username/Password ------------------------- */
533     hbox = gtk_hbox_new(FALSE, 0);
534     vbox = gtk_vbox_new(FALSE, 0);
535     gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Username:")));
536     gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Password:")));
537     gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
538 harbaum 196
539     vbox = gtk_vbox_new(FALSE, 0);
540 harbaum 206 #ifndef FREMANTLE
541 harbaum 196 context->username = gtk_entry_new();
542     context->password = gtk_entry_new();
543     #else
544     context->username = hildon_entry_new(HILDON_SIZE_AUTO);
545     hildon_gtk_entry_set_input_mode(GTK_ENTRY(context->username),
546     HILDON_GTK_INPUT_MODE_FULL);
547     context->password = hildon_entry_new(HILDON_SIZE_AUTO);
548     hildon_gtk_entry_set_input_mode(GTK_ENTRY(context->password),
549     HILDON_GTK_INPUT_MODE_FULL);
550     #endif
551     gtk_entry_set_visibility(GTK_ENTRY(context->password), FALSE);
552    
553     /* set saved defaults */
554 harbaum 204 if(appdata->username)
555 harbaum 196 gtk_entry_set_text(GTK_ENTRY(context->username),
556 harbaum 204 appdata->username);
557 harbaum 196
558 harbaum 198 if(appdata->gt.password)
559 harbaum 196 gtk_entry_set_text(GTK_ENTRY(context->password),
560 harbaum 198 appdata->gt.password);
561 harbaum 196
562     gtk_box_pack_start_defaults(GTK_BOX(vbox), context->username);
563     gtk_box_pack_start_defaults(GTK_BOX(vbox), context->password);
564     gtk_box_pack_start_defaults(GTK_BOX(hbox), vbox);
565    
566 harbaum 198 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), hbox);
567 harbaum 196
568 harbaum 198 gtk_dialog_set_default_response(GTK_DIALOG(context->dialog), GTK_RESPONSE_OK);
569 harbaum 196
570 harbaum 198 gtk_widget_show_all(context->dialog);
571 harbaum 196
572 harbaum 198 if(gtk_dialog_run(GTK_DIALOG(context->dialog)) == GTK_RESPONSE_OK) {
573 harbaum 196
574 harbaum 200 /* parse coordinates */
575 harbaum 206 appdata->gt.lat = lat_get(context->lat);
576     appdata->gt.lon = lon_get(context->lon);
577 harbaum 200
578 harbaum 196 /* save values */
579 harbaum 204 if(appdata->username) g_free(appdata->username);
580     appdata->username =
581 harbaum 196 g_strdup(gtk_entry_get_text(GTK_ENTRY(context->username)));
582    
583 harbaum 198 if(appdata->gt.password) g_free(appdata->gt.password);
584     appdata->gt.password =
585 harbaum 196 g_strdup(gtk_entry_get_text(GTK_ENTRY(context->password)));
586    
587 harbaum 198 if(appdata->gt.filename) g_free(appdata->gt.filename);
588     appdata->gt.filename =
589     g_strdup(gtk_label_get_text(GTK_LABEL(context->filename)));
590    
591 harbaum 200 /* get distance in kilometers */
592     appdata->gt.distance = dist_get(context->dst, FALSE);
593    
594 harbaum 206
595     /* check for valid entries */
596     if(isnan(appdata->gt.lat) || isnan(appdata->gt.lon) ||
597     isnan(appdata->gt.distance) || !appdata->gt.filename ||
598     !appdata->username || !appdata->gt.password)
599 harbaum 211 errorf(_("The GeoToad setup is not complete."));
600 harbaum 206 else
601     ok = TRUE;
602 harbaum 196 }
603    
604 harbaum 198 gtk_widget_destroy(context->dialog);
605 harbaum 196
606     return ok;
607     }
608    
609     void geotoad(appdata_t *appdata) {
610     if(!geotoad_available()) {
611     errorf(_("GeoToad is not installed on this device.\n"
612     "You need to install it in order to be able to use it."));
613     return;
614     }
615    
616     gt_context_t *context = g_new0(gt_context_t, 1);
617     context->appdata = appdata;
618 harbaum 208 context->use_cnt++; // parent still uses this
619 harbaum 196
620 harbaum 206 context->update_mutex = g_mutex_new();
621     context->update_cond = g_cond_new();
622    
623 harbaum 196 printf("geoToad\n");
624    
625     if(gui_setup(context))
626     gui_run(context);
627 harbaum 208
628 harbaum 211 /* continue to process if something has actually been saved */
629     if(context->state == GT_STATE_SAVE_FOUND) {
630     /* download seems to be successful. Make sure the GUI is */
631     /* updated if required */
632    
633     gpx_t **gpx = &(appdata->gpx);
634     while(*gpx && strcmp((*gpx)->filename, appdata->gt.filename))
635     gpx = &(*gpx)->next;
636    
637     if(*gpx) {
638     /* return main GUI to GPX list */
639    
640     #ifdef USE_BREAD_CRUMB_TRAIL
641     while(appdata->cur_gpx)
642     hildon_bread_crumb_trail_pop(HILDON_BREAD_CRUMB_TRAIL(appdata->bct));
643     #elif defined(BCT)
644     while(appdata->cur_gpx)
645     bct_pop(appdata->bct);
646     #else
647     HildonWindowStack *stack = hildon_window_stack_get_default();
648     gint num = hildon_window_stack_size(stack)-1;
649     while(num--) {
650     GtkWidget *top = hildon_window_stack_peek(stack);
651     gtk_widget_destroy(top);
652     }
653     #endif
654    
655     GtkTreeIter iter;
656     g_assert(gpxlist_find(appdata, &iter, *gpx));
657    
658     gpx_t *next = (*gpx)->next;
659    
660     gpx_free(*gpx);
661     *gpx = gpx_parse(NULL, appdata->gt.filename, appdata->username);
662     (*gpx)->next = next;
663    
664     /* update gpxlist */
665     gpxlist_set(appdata->gpxstore, &iter, *gpx);
666    
667     /* select that row */
668     GtkTreeSelection *selection =
669     gtk_tree_view_get_selection(GTK_TREE_VIEW(appdata->gpxview));
670     gtk_tree_selection_select_iter(selection, &iter);
671     GtkTreePath *path =
672     gtk_tree_model_get_path(GTK_TREE_MODEL(appdata->gpxstore), &iter);
673     gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(appdata->gpxview),
674     path, NULL, TRUE, 0.0, 0.0);
675     gtk_tree_path_free(path);
676    
677     } else
678     printf("GPX file not imported\n");
679    
680     } else
681     errorf(_("GeoToad finished without result"));
682    
683 harbaum 208 printf("main context free\n");
684     context_free(context);
685 harbaum 196 }
686    
687     gboolean geotoad_available(void) {
688     /* before doing anything make sure geotoad is installed */
689     return g_file_test(GEOTOAD, G_FILE_TEST_IS_EXECUTABLE);
690     }
691    
692