Parent Directory | Revision Log
more geotoad
1 | harbaum | 1 | /* |
2 | * Copyright (C) 2008 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 | #include <math.h> | ||
23 | #include <sqlite3.h> | ||
24 | |||
25 | static const char *cache_type_icons[] = { | ||
26 | "traditional", "multi", "mystery", "virtual", | ||
27 | "webcam", "event", "letterbox", "earthcache", | ||
28 | "wherigo", "megaevent", "cito", "" }; | ||
29 | |||
30 | static const char *cache_type_str[] = { | ||
31 | "Traditional", "Multi", "Mystery","Virtual", "Webcam", "Event", | ||
32 | "Letterbox", "Earthcache", "Wherigo","Megaevent", "CITO",""}; | ||
33 | |||
34 | static const char *cache_type_desc[] = { | ||
35 | "Traditional Caches", "Multi-Caches", "Unknown Caches", | ||
36 | "Virtual Caches", "Webcam Caches", "Event Caches", | ||
37 | "Letterbox Hybrids", "Earthcaches", "Wherigo Caches", | ||
38 | "Mega-Event Caches", "Cache In Trash Out Events",""}; | ||
39 | |||
40 | static const char *mode_str[] = { | ||
41 | "???", "the cache listing", "the list of caches", "all GPX files" }; | ||
42 | |||
43 | static int callback(void *NotUsed, int argc, char **argv, char **azColName){ | ||
44 | int i; | ||
45 | NotUsed=0; | ||
46 | |||
47 | for(i=0; i<argc; i++){ | ||
48 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); | ||
49 | } | ||
50 | printf("\n"); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | char *escape(char *str) { | ||
55 | if(!str) return NULL; | ||
56 | |||
57 | char *result = malloc(strlen(str)+1); | ||
58 | char *p = result; | ||
59 | |||
60 | while(*str) { | ||
61 | if(*str != '\'') *p++=*str++; | ||
62 | else { *p++='`'; str++; } | ||
63 | } | ||
64 | *p = 0; | ||
65 | |||
66 | return result; | ||
67 | } | ||
68 | |||
69 | /* export a single cache to the database */ | ||
70 | static void cache_export(sqlite3 *db, int id, cache_t *cache) { | ||
71 | char *zErrMsg = 0; | ||
72 | char cmd[256]; | ||
73 | |||
74 | // printf("exporting %s: %s\n", cache->id, cache->name); | ||
75 | |||
76 | char *desc = escape(cache->id); // short_description | ||
77 | if(!desc) desc = strdup(_("<none>")); | ||
78 | |||
79 | char *name = escape(cache->name); | ||
80 | if(!name) desc = strdup(_("<none>")); | ||
81 | |||
82 | pos_t pos = gpx_cache_pos(cache); | ||
83 | char strlon[32], strlat[32]; | ||
84 | g_ascii_dtostr(strlat, sizeof(strlat), pos.lat); | ||
85 | g_ascii_dtostr(strlon, sizeof(strlon), pos.lon); | ||
86 | |||
87 | snprintf(cmd, sizeof(cmd), | ||
88 | "insert into poi values (%d,%s,%s,'%s','%s',%d)", | ||
89 | id, strlat, strlon, name, desc, cache->type+12); | ||
90 | |||
91 | if(sqlite3_exec(db,cmd, callback, 0, &zErrMsg) != SQLITE_OK) | ||
92 | errorf(_("Creating POI entry:\n\n%s"), zErrMsg); | ||
93 | |||
94 | if(desc) free(desc); | ||
95 | if(name) free(name); | ||
96 | } | ||
97 | |||
98 | /* add a cache to the chain of caches to be exported */ | ||
99 | static void chain_cache(gpx_t *gpx, cache_t *cache) { | ||
100 | cache_t **cur = &gpx->cache; | ||
101 | |||
102 | /* search end of chain */ | ||
103 | while(*cur) { | ||
104 | if(strcmp(cache->id, (*cur)->id) == 0) | ||
105 | return; | ||
106 | |||
107 | cur = &(*cur)->next; | ||
108 | } | ||
109 | |||
110 | *cur = malloc(sizeof(cache_t)); | ||
111 | if(!(*cur)) return; | ||
112 | |||
113 | memcpy(*cur, cache, sizeof(cache_t)); | ||
114 | (*cur)->next = NULL; | ||
115 | } | ||
116 | |||
117 | static gpx_t *export_list_create(appdata_t *appdata, int *mode) { | ||
118 | gpx_t *gpx = g_new0(gpx_t,1); | ||
119 | *mode = 0; | ||
120 | |||
121 | if(!gpx) return gpx; | ||
122 | |||
123 | #ifdef USE_MAEMO | ||
124 | if(appdata->cur_cache) { | ||
125 | printf("cache display, exporting cache only!\n"); | ||
126 | /* appdata->cur_cache */ | ||
127 | chain_cache(gpx, appdata->cur_cache); | ||
128 | *mode = 1; | ||
129 | } else if(appdata->search_results) { | ||
130 | printf("search result display, exporting entire search result\n"); | ||
131 | cache_t *cache = appdata->search_results->cache; | ||
132 | while(cache) { chain_cache(gpx, cache); cache = cache->next; } | ||
133 | *mode = 2; | ||
134 | } else if(appdata->cur_gpx) { | ||
135 | printf("cachelist display, exporting entire cachelist\n"); | ||
136 | cache_t *cache = appdata->cur_gpx->cache; | ||
137 | while(cache) { chain_cache(gpx, cache); cache = cache->next; } | ||
138 | *mode = 2; | ||
139 | } else | ||
140 | #endif | ||
141 | { | ||
142 | printf("gpxlist display, exporting all caches\n"); | ||
143 | gpx_t *lgpx = appdata->gpx; | ||
144 | while(lgpx) { | ||
145 | /* make sure notes are imported */ | ||
146 | if(!lgpx->notes_loaded) { | ||
147 | notes_load_all(appdata, lgpx); | ||
148 | lgpx->notes_loaded = TRUE; | ||
149 | } | ||
150 | |||
151 | cache_t *cache = lgpx->cache; | ||
152 | while(cache) { chain_cache(gpx, cache); cache = cache->next; } | ||
153 | lgpx = lgpx->next; | ||
154 | } | ||
155 | *mode = 3; | ||
156 | } | ||
157 | |||
158 | return gpx; | ||
159 | } | ||
160 | |||
161 | static void export_list_free(gpx_t *gpx) { | ||
162 | printf("freeing export list\n"); | ||
163 | |||
164 | cache_t *cache = gpx->cache; | ||
165 | while(cache) { | ||
166 | cache_t *tmp = cache; | ||
167 | cache = cache->next; | ||
168 | free(tmp); | ||
169 | } | ||
170 | free(gpx); | ||
171 | } | ||
172 | |||
173 | static int export_list_count(appdata_t *appdata, gpx_t *gpx) { | ||
174 | pos_t *refpos = get_pos(appdata); | ||
175 | int cnt = 0; | ||
176 | |||
177 | cache_t *cache = gpx->cache; | ||
178 | while(cache) { | ||
179 | /* no disabled/archived if requested */ | ||
180 | if(!(appdata->mmpoi_dont_export_disabled && | ||
181 | (!cache->available || cache->archived))) { | ||
182 | |||
183 | /* no found if requested */ | ||
184 | if(!(appdata->mmpoi_dont_export_found && | ||
185 | cache->notes && cache->notes->found)) { | ||
186 | |||
187 | if(appdata->mmpoi_use_radius && !isnan(appdata->mmpoi_radius)) { | ||
188 | /* count all caches within given radius around current position */ | ||
189 | if(gpx_pos_get_distance(*refpos, gpx_cache_pos(cache), 0) < | ||
190 | appdata->mmpoi_radius) | ||
191 | cnt++; | ||
192 | } else | ||
193 | cnt++; | ||
194 | } | ||
195 | |||
196 | } | ||
197 | |||
198 | cache = cache->next; | ||
199 | } | ||
200 | return cnt; | ||
201 | } | ||
202 | |||
203 | typedef struct { | ||
204 | GtkWidget *use_radius; | ||
205 | GtkWidget *no_found; | ||
206 | GtkWidget *no_disabled; | ||
207 | GtkWidget *entry; | ||
208 | GtkWidget *info_label; | ||
209 | GtkWidget *dialog; | ||
210 | appdata_t *appdata; | ||
211 | guint handler_id; | ||
212 | int mode; | ||
213 | gpx_t *gpx; | ||
214 | GtkWidget *path_label; | ||
215 | #ifdef USE_MAEMO | ||
216 | GtkWidget *launch; | ||
217 | #endif | ||
218 | } export_context_t; | ||
219 | |||
220 | static float distance_eval(GtkWidget *widget, export_context_t *context) { | ||
221 | char *p = (char*)gtk_entry_get_text(GTK_ENTRY(widget)); | ||
222 | float val = distance_parse(p, context->appdata->imperial); | ||
223 | return val; | ||
224 | } | ||
225 | |||
226 | static gboolean export_list_update(gpointer data) { | ||
227 | char str[256]; | ||
228 | export_context_t *context = (export_context_t*)data; | ||
229 | |||
230 | printf("updating list ...\n"); | ||
231 | |||
232 | int cnum = export_list_count(context->appdata, context->gpx); | ||
233 | printf("About to export %d caches\n", cnum); | ||
234 | |||
235 | snprintf(str, sizeof(str), | ||
236 | _("This will export %d caches from %s."), | ||
237 | cnum, _(mode_str[context->mode])); | ||
238 | |||
239 | gtk_label_set_text(GTK_LABEL(context->info_label), str); | ||
240 | |||
241 | return FALSE; | ||
242 | } | ||
243 | |||
244 | /* Our usual callback function */ | ||
245 | static void export_update(GtkWidget *widget, gpointer data) { | ||
246 | export_context_t *context = (export_context_t *)data; | ||
247 | |||
248 | if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(context->use_radius))) { | ||
249 | textbox_enable(context->entry); | ||
250 | context->appdata->mmpoi_use_radius = TRUE; | ||
251 | } else { | ||
252 | textbox_disable(context->entry); | ||
253 | context->appdata->mmpoi_use_radius = FALSE; | ||
254 | } | ||
255 | |||
256 | context->appdata->mmpoi_dont_export_found = | ||
257 | gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(context->no_found)); | ||
258 | |||
259 | context->appdata->mmpoi_dont_export_disabled = | ||
260 | gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(context->no_disabled)); | ||
261 | |||
262 | export_list_update(context); | ||
263 | } | ||
264 | |||
265 | static void export_radius_modified(GtkWidget *widget, gpointer data ) { | ||
266 | export_context_t *context = (export_context_t*)data; | ||
267 | |||
268 | context->appdata->mmpoi_radius = distance_eval(context->entry, context); | ||
269 | |||
270 | printf("Distance is %.2f km\n", context->appdata->mmpoi_radius); | ||
271 | |||
272 | if(context->handler_id) { | ||
273 | printf("resetting running timer\n"); | ||
274 | gtk_timeout_remove(context->handler_id); | ||
275 | context->handler_id = 0; | ||
276 | } | ||
277 | |||
278 | if(!isnan(context->appdata->mmpoi_radius)) | ||
279 | context->handler_id = | ||
280 | gtk_timeout_add(1000, export_list_update, context); | ||
281 | } | ||
282 | |||
283 | /* Our usual callback function */ | ||
284 | static void on_cancel(GtkWidget *widget, gpointer data) { | ||
285 | int *flag = (int*)data; | ||
286 | *flag = TRUE; | ||
287 | } | ||
288 | |||
289 | static void on_browse(GtkWidget *widget, gpointer data) { | ||
290 | GtkWidget *dialog; | ||
291 | |||
292 | export_context_t *context = (export_context_t*)data; | ||
293 | |||
294 | printf("Browse\n"); | ||
295 | |||
296 | #ifdef USE_MAEMO | ||
297 | dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(context->dialog), | ||
298 | GTK_FILE_CHOOSER_ACTION_SAVE); | ||
299 | #else | ||
300 | dialog = gtk_file_chooser_dialog_new(_("Save POI database"), | ||
301 | GTK_WINDOW(context->dialog), | ||
302 | GTK_FILE_CHOOSER_ACTION_SAVE, | ||
303 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | ||
304 | harbaum | 198 | GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, |
305 | harbaum | 1 | NULL); |
306 | #endif | ||
307 | |||
308 | printf("set filename <%s>\n", context->appdata->mmpoi_path); | ||
309 | |||
310 | if(!g_file_test(context->appdata->mmpoi_path, G_FILE_TEST_EXISTS)) { | ||
311 | char *last_sep = strrchr(context->appdata->mmpoi_path, '/'); | ||
312 | if(last_sep) { | ||
313 | *last_sep = 0; // seperate path from file | ||
314 | |||
315 | /* the user just created a new document */ | ||
316 | gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), | ||
317 | context->appdata->mmpoi_path); | ||
318 | gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), last_sep+1); | ||
319 | |||
320 | /* restore full filename */ | ||
321 | *last_sep = '/'; | ||
322 | } | ||
323 | } else | ||
324 | gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), | ||
325 | context->appdata->mmpoi_path); | ||
326 | |||
327 | if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) { | ||
328 | gchar *name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); | ||
329 | if(name) { | ||
330 | free(context->appdata->mmpoi_path); | ||
331 | context->appdata->mmpoi_path = strdup(name); | ||
332 | gtk_label_set_text(GTK_LABEL(context->path_label), | ||
333 | context->appdata->mmpoi_path); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | gtk_widget_destroy (dialog); | ||
338 | } | ||
339 | |||
340 | void mmpoi_export(appdata_t *appdata) { | ||
341 | sqlite3 *db; | ||
342 | char *zErrMsg = 0; | ||
343 | char cmd[256]; | ||
344 | int rc, i; | ||
345 | char *old_mmpoi_path = strdup(appdata->mmpoi_path); | ||
346 | |||
347 | export_context_t context; | ||
348 | memset(&context, 0, sizeof(export_context_t)); | ||
349 | context.appdata = appdata; | ||
350 | |||
351 | printf("export poi\n"); | ||
352 | |||
353 | /* first create a new faked gpx file containing all caches to */ | ||
354 | /* be exported */ | ||
355 | context.gpx = export_list_create(appdata, &context.mode); | ||
356 | if(!context.gpx) { | ||
357 | errorf(_("Out of memory")); | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | /* --------- do confirmation dialog ----------- */ | ||
362 | context.dialog = gtk_dialog_new_with_buttons(_("Maemo Mapper POI export"), | ||
363 | GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL, | ||
364 | GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, | ||
365 | GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, | ||
366 | NULL); | ||
367 | |||
368 | #if defined(USE_MAEMO) && defined(HILDON_HELP) | ||
369 | hildon_help_dialog_help_enable(GTK_DIALOG(context.dialog), | ||
370 | HELP_ID_EXPORT, appdata->osso_context); | ||
371 | #endif | ||
372 | |||
373 | GtkWidget *vbox = gtk_vbox_new(FALSE,0); | ||
374 | |||
375 | /* ------------------ radius limit gui ------------------ */ | ||
376 | |||
377 | GtkWidget *label, *hbox = gtk_hbox_new(FALSE,2); | ||
378 | context.use_radius = gtk_check_button_new_with_label( | ||
379 | _("Limit export radius to:")); | ||
380 | context.entry = dist_entry_new(appdata->mmpoi_radius, appdata->imperial); | ||
381 | |||
382 | gtk_box_pack_start_defaults(GTK_BOX(hbox), context.use_radius); | ||
383 | gtk_box_pack_start_defaults(GTK_BOX(hbox), context.entry); | ||
384 | gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox); | ||
385 | |||
386 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(context.use_radius), | ||
387 | appdata->mmpoi_use_radius); | ||
388 | |||
389 | /* Connect the "clicked" signal of the button to our callback */ | ||
390 | gtk_signal_connect (GTK_OBJECT(context.use_radius), "clicked", | ||
391 | GTK_SIGNAL_FUNC(export_update), (gpointer)&context); | ||
392 | |||
393 | g_signal_connect(G_OBJECT(context.entry), "changed", | ||
394 | G_CALLBACK(export_radius_modified), (gpointer)&context); | ||
395 | |||
396 | /* ------------------ don't export found/disabled/archived -------------- */ | ||
397 | |||
398 | hbox = gtk_hbox_new(FALSE,2); | ||
399 | |||
400 | label = gtk_label_new(_("Don't export")); | ||
401 | gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f); | ||
402 | context.no_found = gtk_check_button_new_with_label(_("found")); | ||
403 | context.no_disabled = gtk_check_button_new_with_label(_("disabled/archived")); | ||
404 | |||
405 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(context.no_found), | ||
406 | appdata->mmpoi_dont_export_found); | ||
407 | |||
408 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(context.no_disabled), | ||
409 | appdata->mmpoi_dont_export_disabled); | ||
410 | |||
411 | gtk_box_pack_start_defaults(GTK_BOX(hbox), label); | ||
412 | gtk_box_pack_start_defaults(GTK_BOX(hbox), context.no_found); | ||
413 | gtk_box_pack_start_defaults(GTK_BOX(hbox), context.no_disabled); | ||
414 | |||
415 | gtk_signal_connect (GTK_OBJECT(context.no_found), "clicked", | ||
416 | GTK_SIGNAL_FUNC(export_update), (gpointer)&context); | ||
417 | gtk_signal_connect (GTK_OBJECT(context.no_disabled), "clicked", | ||
418 | GTK_SIGNAL_FUNC(export_update), (gpointer)&context); | ||
419 | |||
420 | gtk_box_pack_start_defaults(GTK_BOX(vbox),hbox); | ||
421 | |||
422 | /* ------------------ info text -------------- */ | ||
423 | |||
424 | context.info_label = gtk_label_new(""); | ||
425 | gtk_label_set_line_wrap_mode(GTK_LABEL(context.info_label), PANGO_WRAP_WORD); | ||
426 | gtk_label_set_line_wrap(GTK_LABEL(context.info_label), TRUE); | ||
427 | gtk_misc_set_alignment(GTK_MISC(context.info_label), 0.f, 0.5f); | ||
428 | gtk_box_pack_start_defaults(GTK_BOX(vbox), context.info_label); | ||
429 | |||
430 | export_update(NULL, &context); | ||
431 | |||
432 | #ifdef USE_MAEMO | ||
433 | gtk_box_pack_start_defaults(GTK_BOX(vbox), | ||
434 | context.launch = gtk_check_button_new_with_label( | ||
435 | _("Launch Maemo Mapper after export"))); | ||
436 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(context.launch), | ||
437 | !appdata->mmpoi_dontlaunch); | ||
438 | #endif | ||
439 | |||
440 | /* ------------------ path/file ------------------ */ | ||
441 | gtk_box_pack_start_defaults(GTK_BOX(vbox), gtk_hseparator_new()); | ||
442 | |||
443 | hbox = gtk_hbox_new(FALSE, 0); | ||
444 | label = gtk_label_new(_("Export to:")); | ||
445 | gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE,0); | ||
446 | gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f); | ||
447 | harbaum | 7 | GtkWidget *button = gtk_button_new_with_label(_("Browse")); |
448 | harbaum | 1 | gtk_signal_connect(GTK_OBJECT(button), "clicked", |
449 | GTK_SIGNAL_FUNC(on_browse), (gpointer)&context); | ||
450 | gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE,0); | ||
451 | gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox); | ||
452 | |||
453 | context.path_label = gtk_label_new(appdata->mmpoi_path); | ||
454 | gtk_misc_set_alignment(GTK_MISC(context.path_label), 0.f, 0.5f); | ||
455 | gtk_label_set_ellipsize(GTK_LABEL(context.path_label), PANGO_ELLIPSIZE_MIDDLE); | ||
456 | gtk_box_pack_start_defaults(GTK_BOX(vbox), context.path_label); | ||
457 | |||
458 | /* ------------------ info ------------------ */ | ||
459 | |||
460 | gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox), vbox); | ||
461 | |||
462 | gtk_widget_show_all(context.dialog); | ||
463 | |||
464 | if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) { | ||
465 | #ifdef USE_MAEMO | ||
466 | appdata->mmpoi_dontlaunch = | ||
467 | !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(context.launch)); | ||
468 | #endif | ||
469 | |||
470 | /* remove existing database */ | ||
471 | remove(appdata->mmpoi_path); | ||
472 | |||
473 | if(checkdir(appdata->mmpoi_path) != 0) | ||
474 | errorf(_("Unable to access or create output directory!")); | ||
475 | else { | ||
476 | |||
477 | /* build a progress dialog which can even be stopped */ | ||
478 | |||
479 | GtkWidget *pbar, *wait_dialog = gtk_dialog_new(); | ||
480 | gtk_dialog_set_has_separator(GTK_DIALOG(wait_dialog), FALSE); | ||
481 | gtk_window_set_default_size(GTK_WINDOW(wait_dialog), 250, 100); | ||
482 | harbaum | 7 | gtk_window_set_title(GTK_WINDOW(wait_dialog), _("Exporting")); |
483 | harbaum | 1 | gtk_window_set_modal(GTK_WINDOW(wait_dialog), TRUE); |
484 | gtk_window_set_transient_for(GTK_WINDOW(wait_dialog), | ||
485 | GTK_WINDOW(context.dialog)); | ||
486 | gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wait_dialog)->vbox), | ||
487 | pbar = gtk_progress_bar_new()); | ||
488 | |||
489 | GtkWidget *button = gtk_button_new_with_label(_("Cancel")); | ||
490 | int cancelled = 0; | ||
491 | gtk_signal_connect(GTK_OBJECT(button), "clicked", | ||
492 | GTK_SIGNAL_FUNC(on_cancel), (gpointer)&cancelled); | ||
493 | gtk_container_add(GTK_CONTAINER(GTK_DIALOG(wait_dialog)->action_area), | ||
494 | button); | ||
495 | |||
496 | gtk_widget_show_all(wait_dialog); | ||
497 | |||
498 | /* ---------------------- copy icons --------------------- */ | ||
499 | for(i=0;cache_type_icons[i][0];i++) { | ||
500 | char *src = malloc(strlen(ICONPATH)+strlen(cache_type_icons[i])+ | ||
501 | harbaum | 179 | strlen("cache_type_.png")+1); |
502 | sprintf(src, ICONPATH "cache_type_%s.png", cache_type_icons[i]); | ||
503 | harbaum | 1 | if(!g_file_test(src, G_FILE_TEST_EXISTS)) |
504 | harbaum | 179 | sprintf(src, "./icons/cache_type_%s.png", cache_type_icons[i]); |
505 | harbaum | 1 | |
506 | if(g_file_test(src, G_FILE_TEST_EXISTS)) { | ||
507 | char *dest = malloc(strlen(appdata->mmpoi_path)+ | ||
508 | strlen(cache_type_icons[i])+strlen(".jpg")+1); | ||
509 | strcpy(dest, appdata->mmpoi_path); | ||
510 | *(strrchr(dest, '/')+1) = 0; | ||
511 | sprintf(dest+strlen(dest), "%s.jpg", cache_type_icons[i]); | ||
512 | |||
513 | /* read source file */ | ||
514 | FILE *file = fopen(src, "rb"); | ||
515 | fseek(file, 0, SEEK_END); | ||
516 | int len = ftell(file); | ||
517 | fseek(file, 0, SEEK_SET); | ||
518 | char *buffer = malloc(len); | ||
519 | fread(buffer, 1l, len, file); | ||
520 | fclose(file); | ||
521 | |||
522 | /* write destination file */ | ||
523 | file = fopen(dest, "wb"); | ||
524 | fwrite(buffer, 1l, len, file); | ||
525 | fclose(file); | ||
526 | |||
527 | free(buffer); | ||
528 | free(dest); | ||
529 | } | ||
530 | |||
531 | free(src); | ||
532 | } | ||
533 | |||
534 | /* ---------------------- database export --------------------- */ | ||
535 | |||
536 | printf("exporting to %s\n", appdata->mmpoi_path); | ||
537 | rc = sqlite3_open(appdata->mmpoi_path, &db); | ||
538 | if( rc ){ | ||
539 | errorf(_("Can't open SQL database:\n\n%s"), sqlite3_errmsg(db)); | ||
540 | sqlite3_close(db); | ||
541 | export_list_free(context.gpx); | ||
542 | return; | ||
543 | } | ||
544 | |||
545 | /* create the table */ | ||
546 | rc = sqlite3_exec(db, "create table category (cat_id integer PRIMARY " | ||
547 | "KEY, label text, desc text, enabled integer)", | ||
548 | callback, 0, &zErrMsg); | ||
549 | if( rc!=SQLITE_OK ) { | ||
550 | errorf(_("Creating cathegory table:\n\n%s"), zErrMsg); | ||
551 | sqlite3_close(db); | ||
552 | export_list_free(context.gpx); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | /* create all types */ | ||
557 | i = 0; | ||
558 | while(cache_type_str[i][0]) { | ||
559 | snprintf(cmd, sizeof(cmd), | ||
560 | "insert into category values (%d, '%s', '%s', 1)", | ||
561 | 12+i, cache_type_str[i], cache_type_desc[i]); | ||
562 | |||
563 | rc = sqlite3_exec(db, cmd, callback, 0, &zErrMsg); | ||
564 | if( rc != SQLITE_OK ){ | ||
565 | errorf(_("Creating cathegory:\n\n%s"), zErrMsg); | ||
566 | sqlite3_close(db); | ||
567 | export_list_free(context.gpx); | ||
568 | return; | ||
569 | } | ||
570 | i++; | ||
571 | } | ||
572 | |||
573 | rc = sqlite3_exec(db, "create table poi (poi_id integer PRIMARY KEY, " | ||
574 | "lat real, lon real, label text, desc text, " | ||
575 | "cat_id integer)", callback, 0, &zErrMsg); | ||
576 | if( rc!=SQLITE_OK ){ | ||
577 | errorf(_("Creating POI table:\n\n%s"), zErrMsg); | ||
578 | sqlite3_close(db); | ||
579 | export_list_free(context.gpx); | ||
580 | return; | ||
581 | } | ||
582 | |||
583 | pos_t *refpos = get_pos(appdata); | ||
584 | |||
585 | /* export the caches */ | ||
586 | int id = 1; | ||
587 | cache_t *cache = context.gpx->cache; | ||
588 | int total = export_list_count(appdata, context.gpx); | ||
589 | |||
590 | while(cache && !cancelled) { | ||
591 | |||
592 | /* no disabled/archived if requested */ | ||
593 | if(!(appdata->mmpoi_dont_export_disabled && | ||
594 | (!cache->available || cache->archived))) { | ||
595 | |||
596 | /* no found if requested */ | ||
597 | if(!(appdata->mmpoi_dont_export_found && | ||
598 | cache->notes && cache->notes->found)) { | ||
599 | |||
600 | if(appdata->mmpoi_use_radius && !isnan(appdata->mmpoi_radius)) { | ||
601 | /* count all caches within given radius around current position */ | ||
602 | if(gpx_pos_get_distance(*refpos, gpx_cache_pos(cache), 0) < | ||
603 | appdata->mmpoi_radius) { | ||
604 | printf("%d exporting %s\n", id, cache->id); | ||
605 | cache_export(db, id++, cache); | ||
606 | } | ||
607 | } else { | ||
608 | printf("%d exporting %s\n", id, cache->id); | ||
609 | cache_export(db, id++, cache); | ||
610 | } | ||
611 | } | ||
612 | } | ||
613 | cache = cache->next; | ||
614 | |||
615 | gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pbar), | ||
616 | (float)(id-2)/(float)total); | ||
617 | |||
618 | while(gtk_events_pending ()) | ||
619 | gtk_main_iteration (); | ||
620 | } | ||
621 | sqlite3_close(db); | ||
622 | |||
623 | gtk_widget_destroy(wait_dialog); | ||
624 | |||
625 | #ifdef USE_MAEMO | ||
626 | if(!cancelled && !appdata->mmpoi_dontlaunch) | ||
627 | dbus_mm_set_position(appdata, NULL); | ||
628 | #endif | ||
629 | } | ||
630 | } else { | ||
631 | /* restore old mmpoi_path, in case it has been altered but not been used */ | ||
632 | free(appdata->mmpoi_path); | ||
633 | appdata->mmpoi_path = strdup(old_mmpoi_path); | ||
634 | } | ||
635 | |||
636 | gtk_widget_destroy(context.dialog); | ||
637 | |||
638 | if(context.handler_id) { | ||
639 | printf("removing timer\n"); | ||
640 | gtk_timeout_remove(context.handler_id); | ||
641 | } | ||
642 | |||
643 | export_list_free(context.gpx); | ||
644 | |||
645 | free(old_mmpoi_path); | ||
646 | } |