]> git.street.me.uk Git - andy/viking.git/blame - src/acquire.c
Refactoring: retrieve the VikWindow from the VikViewport via its GtkWidget nature
[andy/viking.git] / src / acquire.c
CommitLineData
1d1bc3c1
EB
1/*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3 *
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
5 *
6 * This program 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 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program 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 this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21#include <string.h>
22#include <glib/gprintf.h>
23
24#include "viking.h"
25#include "babel.h"
26#include "gpx.h"
7b3479e3 27#include "acquire.h"
1d1bc3c1 28
7b3479e3 29/* passed along to worker thread */
1d1bc3c1 30typedef struct {
7b3479e3 31 acq_dialog_widgets_t *w;
7b3479e3
EB
32 gchar *cmd;
33 gchar *extra;
34} w_and_interface_t;
1d1bc3c1 35
7b3479e3
EB
36extern VikDataSourceInterface vik_datasource_gps_interface;
37extern VikDataSourceInterface vik_datasource_google_interface;
1d1bc3c1 38
7b3479e3 39/*********************************************************
cf697cc2 40 * Definitions and routines for acquiring data from Data Sources in general
7b3479e3 41 *********************************************************/
1d1bc3c1 42
cf697cc2
EB
43static void progress_func ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w )
44{
45 gdk_threads_enter ();
46 if (!w->ok) {
cf697cc2 47 if ( w->interface->cleanup_func )
65f0ccab
AF
48 w->interface->cleanup_func( w->user_data );
49 g_free ( w );
cf697cc2
EB
50 gdk_threads_leave();
51 g_thread_exit ( NULL );
52 }
53 gdk_threads_leave ();
54
55 if ( w->interface->progress_func )
56 w->interface->progress_func ( (gpointer) c, data, w );
57}
58
1d1bc3c1 59/* this routine is the worker thread. there is only one simultaneous download allowed */
7b3479e3 60static void get_from_anything ( w_and_interface_t *wi )
1d1bc3c1 61{
7b3479e3
EB
62 gchar *cmd = wi->cmd;
63 gchar *extra = wi->extra;
64 gboolean result;
805d282e
EB
65 VikTrwLayer *vtl;
66
67 gboolean creating_new_layer = TRUE;
7b3479e3
EB
68
69 acq_dialog_widgets_t *w = wi->w;
cf697cc2 70 VikDataSourceInterface *interface = wi->w->interface;
7b3479e3 71 g_free ( wi );
1d1bc3c1
EB
72
73 gdk_threads_enter();
805d282e
EB
74 if (interface->mode == VIK_DATASOURCE_ADDTOLAYER) {
75 VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp );
76 if ( IS_VIK_TRW_LAYER(current_selected) ) {
77 vtl = VIK_TRW_LAYER(current_selected);
78 creating_new_layer = FALSE;
79 }
80 }
81 if ( creating_new_layer ) {
82 vtl = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, w->vvp, NULL, FALSE ) );
83 vik_layer_rename ( VIK_LAYER ( vtl ), interface->layer_title );
84 gtk_label_set_text ( GTK_LABEL(w->status), "Working..." );
85 }
1d1bc3c1
EB
86 gdk_threads_leave();
87
7b3479e3 88 if ( interface->type == VIK_DATASOURCE_GPSBABEL_DIRECT )
cf697cc2 89 result = a_babel_convert_from (vtl, cmd, (BabelStatusFunc) progress_func, extra, w);
7b3479e3 90 else
cf697cc2 91 result = a_babel_convert_from_shellcommand ( vtl, cmd, extra, (BabelStatusFunc) progress_func, w);
7b3479e3
EB
92
93 g_free ( cmd );
94 g_free ( extra );
95
96 if (!result) {
1d1bc3c1
EB
97 gdk_threads_enter();
98 gtk_label_set_text ( GTK_LABEL(w->status), "Error: couldn't find gpsbabel." );
805d282e
EB
99 if ( creating_new_layer )
100 g_object_unref ( G_OBJECT ( vtl ) );
1d1bc3c1
EB
101 gdk_threads_leave();
102 }
5f304fd7 103 else {
65f0ccab
AF
104 gdk_threads_enter();
105 if (w->ok) {
106 gtk_label_set_text ( GTK_LABEL(w->status), "Done." );
107 if ( creating_new_layer )
108 vik_aggregate_layer_add_layer( vik_layers_panel_get_top_layer(w->vlp), VIK_LAYER(vtl));
109 gtk_dialog_set_response_sensitive ( GTK_DIALOG(w->dialog), GTK_RESPONSE_ACCEPT, TRUE );
110 gtk_dialog_set_response_sensitive ( GTK_DIALOG(w->dialog), GTK_RESPONSE_REJECT, FALSE );
111 } else {
112 /* canceled */
113 if ( creating_new_layer )
114 g_object_unref(vtl);
115 }
1d1bc3c1 116 }
7b3479e3 117 if ( interface->cleanup_func )
65f0ccab 118 interface->cleanup_func ( w->user_data );
7b3479e3
EB
119
120 if ( w->ok ) {
121 w->ok = FALSE;
122 } else {
123 g_free ( w );
124 }
125
1d1bc3c1
EB
126 gdk_threads_leave();
127 g_thread_exit ( NULL );
128}
129
7b3479e3
EB
130
131void a_acquire ( VikWindow *vw, VikLayersPanel *vlp, VikViewport *vvp, VikDataSourceInterface *interface )
1d1bc3c1 132{
1d1bc3c1 133 GtkWidget *dialog = NULL;
7b3479e3
EB
134 GtkWidget *status;
135 gchar *cmd, *extra;
136 acq_dialog_widgets_t *w;
65f0ccab 137 gpointer user_data;
7b3479e3
EB
138
139 w_and_interface_t *wi;
140
65f0ccab
AF
141 g_assert(interface->init_func);
142 user_data = interface->init_func();
143
92255687
EB
144 if ( interface->check_existence_func ) {
145 gchar *error_str = interface->check_existence_func();
146 if ( error_str ) {
147 a_dialog_error_msg ( GTK_WINDOW(vw), error_str );
148 g_free ( error_str );
149 return;
150 }
151 }
152
65f0ccab 153 if ( interface->add_setup_widgets_func ) {
f4b1d29b 154 dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL );
92255687 155
65f0ccab 156 interface->add_setup_widgets_func(dialog, vvp, user_data);
a8d46e0b
EB
157 gtk_window_set_title ( GTK_WINDOW(dialog), interface->window_title );
158
7b3479e3 159 if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_ACCEPT ) {
65f0ccab 160 interface->cleanup_func(user_data);
7b3479e3
EB
161 gtk_widget_destroy(dialog);
162 return;
163 }
65f0ccab 164 interface->get_cmd_string_func ( user_data, &cmd, &extra );
7b3479e3
EB
165 gtk_widget_destroy(dialog);
166 dialog = NULL;
167 } else
65f0ccab 168 interface->get_cmd_string_func ( user_data, &cmd, &extra );
7b3479e3
EB
169
170 if ( ! cmd )
171 return;
172
173 w = g_malloc(sizeof(*w));
174 wi = g_malloc(sizeof(*wi));
175 wi->w = w;
cf697cc2 176 wi->w->interface = interface;
7b3479e3
EB
177 wi->cmd = cmd;
178 wi->extra = extra;
1d1bc3c1 179
f4b1d29b 180 dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL );
1d1bc3c1 181 gtk_dialog_set_response_sensitive ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, FALSE );
a8d46e0b 182 gtk_window_set_title ( GTK_WINDOW(dialog), interface->window_title );
1d1bc3c1 183
1d1bc3c1
EB
184
185 w->dialog = dialog;
7b3479e3 186 w->ok = TRUE;
7b3479e3
EB
187 status = gtk_label_new ("Status: detecting gpsbabel");
188 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), status, FALSE, FALSE, 5 );
189 gtk_widget_show_all(status);
1d1bc3c1 190 w->status = status;
7b3479e3 191
1d1bc3c1
EB
192 w->vw = vw;
193 w->vlp = vlp;
194 w->vvp = vvp;
65f0ccab
AF
195 if ( interface->add_progress_widgets_func ) {
196 interface->add_progress_widgets_func ( dialog, user_data );
197 }
198 w->user_data = user_data;
7b3479e3 199
a8d46e0b 200
7b3479e3 201 g_thread_create((GThreadFunc)get_from_anything, wi, FALSE, NULL );
1d1bc3c1
EB
202
203 gtk_dialog_run ( GTK_DIALOG(dialog) );
7b3479e3
EB
204 if ( w->ok )
205 w->ok = FALSE; /* tell thread to stop. TODO: add mutex */
206 else {
207 g_free ( w ); /* thread has finished; free w */
208 }
1d1bc3c1
EB
209 gtk_widget_destroy ( dialog );
210}
7b3479e3 211