Parent Directory | Revision Log
File selection fremantleized
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 | #ifdef USE_MAEMO | ||
215 | GtkWidget *launch; | ||
216 | #endif | ||
217 | } export_context_t; | ||
218 | |||
219 | static gboolean export_list_update(gpointer data) { | ||
220 | char str[256]; | ||
221 | export_context_t *context = (export_context_t*)data; | ||
222 | |||
223 | printf("updating list ...\n"); | ||
224 | |||
225 | int cnum = export_list_count(context->appdata, context->gpx); | ||
226 | printf("About to export %d caches\n", cnum); | ||
227 | |||
228 | snprintf(str, sizeof(str), | ||
229 | _("This will export %d caches from %s."), | ||
230 | cnum, _(mode_str[context->mode])); | ||
231 | |||
232 | gtk_label_set_text(GTK_LABEL(context->info_label), str); | ||
233 | |||
234 | return FALSE; | ||
235 | } | ||
236 | |||
237 | /* Our usual callback function */ | ||
238 | static void export_update(GtkWidget *widget, gpointer data) { | ||
239 | export_context_t *context = (export_context_t *)data; | ||
240 | |||
241 | harbaum | 233 | if(check_button_get_active(context->use_radius)) { |
242 | harbaum | 1 | textbox_enable(context->entry); |
243 | context->appdata->mmpoi_use_radius = TRUE; | ||
244 | } else { | ||
245 | textbox_disable(context->entry); | ||
246 | context->appdata->mmpoi_use_radius = FALSE; | ||
247 | } | ||
248 | |||
249 | context->appdata->mmpoi_dont_export_found = | ||
250 | harbaum | 233 | toggle_button_get_active(context->no_found); |
251 | harbaum | 1 | |
252 | context->appdata->mmpoi_dont_export_disabled = | ||
253 | harbaum | 233 | toggle_button_get_active(context->no_disabled); |
254 | harbaum | 1 | |
255 | export_list_update(context); | ||
256 | } | ||
257 | |||
258 | static void export_radius_modified(GtkWidget *widget, gpointer data ) { | ||
259 | export_context_t *context = (export_context_t*)data; | ||
260 | |||
261 | harbaum | 233 | context->appdata->mmpoi_radius = |
262 | dist_entry_get(context->entry, context->appdata->imperial); | ||
263 | harbaum | 1 | |
264 | printf("Distance is %.2f km\n", context->appdata->mmpoi_radius); | ||
265 | |||
266 | if(context->handler_id) { | ||
267 | printf("resetting running timer\n"); | ||
268 | gtk_timeout_remove(context->handler_id); | ||
269 | context->handler_id = 0; | ||
270 | } | ||
271 | |||
272 | if(!isnan(context->appdata->mmpoi_radius)) | ||
273 | context->handler_id = | ||
274 | gtk_timeout_add(1000, export_list_update, context); | ||
275 | } | ||
276 | |||
277 | /* Our usual callback function */ | ||
278 | static void on_cancel(GtkWidget *widget, gpointer data) { | ||
279 | int *flag = (int*)data; | ||
280 | *flag = TRUE; | ||
281 | } | ||
282 | |||
283 | void mmpoi_export(appdata_t *appdata) { | ||
284 | sqlite3 *db; | ||
285 | char *zErrMsg = 0; | ||
286 | char cmd[256]; | ||
287 | int rc, i; | ||
288 | char *old_mmpoi_path = strdup(appdata->mmpoi_path); | ||
289 | |||
290 | export_context_t context; | ||
291 | memset(&context, 0, sizeof(export_context_t)); | ||
292 | context.appdata = appdata; | ||
293 | |||
294 | printf("export poi\n"); | ||
295 | |||
296 | /* first create a new faked gpx file containing all caches to */ | ||
297 | /* be exported */ | ||
298 | context.gpx = export_list_create(appdata, &context.mode); | ||
299 | if(!context.gpx) { | ||
300 | errorf(_("Out of memory")); | ||
301 | return; | ||
302 | } | ||
303 | |||
304 | /* --------- do confirmation dialog ----------- */ | ||
305 | context.dialog = gtk_dialog_new_with_buttons(_("Maemo Mapper POI export"), | ||
306 | GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL, | ||
307 | GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, | ||
308 | GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, | ||
309 | NULL); | ||
310 | |||
311 | #if defined(USE_MAEMO) && defined(HILDON_HELP) | ||
312 | hildon_help_dialog_help_enable(GTK_DIALOG(context.dialog), | ||
313 | HELP_ID_EXPORT, appdata->osso_context); | ||
314 | #endif | ||
315 | |||
316 | GtkWidget *vbox = gtk_vbox_new(FALSE,0); | ||
317 | |||
318 | /* ------------------ radius limit gui ------------------ */ | ||
319 | |||
320 | GtkWidget *label, *hbox = gtk_hbox_new(FALSE,2); | ||
321 | harbaum | 233 | context.use_radius = check_button_new_with_label( |
322 | harbaum | 1 | _("Limit export radius to:")); |
323 | context.entry = dist_entry_new(appdata->mmpoi_radius, appdata->imperial); | ||
324 | |||
325 | gtk_box_pack_start_defaults(GTK_BOX(hbox), context.use_radius); | ||
326 | gtk_box_pack_start_defaults(GTK_BOX(hbox), context.entry); | ||
327 | gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox); | ||
328 | |||
329 | harbaum | 233 | check_button_set_active(context.use_radius, appdata->mmpoi_use_radius); |
330 | harbaum | 1 | |
331 | /* Connect the "clicked" signal of the button to our callback */ | ||
332 | gtk_signal_connect (GTK_OBJECT(context.use_radius), "clicked", | ||
333 | GTK_SIGNAL_FUNC(export_update), (gpointer)&context); | ||
334 | |||
335 | g_signal_connect(G_OBJECT(context.entry), "changed", | ||
336 | G_CALLBACK(export_radius_modified), (gpointer)&context); | ||
337 | |||
338 | /* ------------------ don't export found/disabled/archived -------------- */ | ||
339 | hbox = gtk_hbox_new(FALSE,2); | ||
340 | |||
341 | label = gtk_label_new(_("Don't export")); | ||
342 | gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f); | ||
343 | harbaum | 233 | GtkWidget *ihbox = gtk_hbox_new(FALSE,0); |
344 | context.no_found = toggle_button_new_with_label(_("found")); | ||
345 | context.no_disabled = toggle_button_new_with_label(_("disabled/archived")); | ||
346 | harbaum | 1 | |
347 | harbaum | 233 | toggle_button_set_active(context.no_found, |
348 | appdata->mmpoi_dont_export_found); | ||
349 | harbaum | 1 | |
350 | harbaum | 233 | toggle_button_set_active(context.no_disabled, |
351 | appdata->mmpoi_dont_export_disabled); | ||
352 | harbaum | 1 | |
353 | gtk_box_pack_start_defaults(GTK_BOX(hbox), label); | ||
354 | harbaum | 233 | gtk_box_pack_start_defaults(GTK_BOX(ihbox), context.no_found); |
355 | gtk_box_pack_start_defaults(GTK_BOX(ihbox), context.no_disabled); | ||
356 | gtk_box_pack_start_defaults(GTK_BOX(hbox), ihbox); | ||
357 | harbaum | 1 | |
358 | gtk_signal_connect (GTK_OBJECT(context.no_found), "clicked", | ||
359 | GTK_SIGNAL_FUNC(export_update), (gpointer)&context); | ||
360 | gtk_signal_connect (GTK_OBJECT(context.no_disabled), "clicked", | ||
361 | GTK_SIGNAL_FUNC(export_update), (gpointer)&context); | ||
362 | |||
363 | gtk_box_pack_start_defaults(GTK_BOX(vbox),hbox); | ||
364 | |||
365 | /* ------------------ info text -------------- */ | ||
366 | |||
367 | context.info_label = gtk_label_new(""); | ||
368 | gtk_label_set_line_wrap_mode(GTK_LABEL(context.info_label), PANGO_WRAP_WORD); | ||
369 | gtk_label_set_line_wrap(GTK_LABEL(context.info_label), TRUE); | ||
370 | gtk_misc_set_alignment(GTK_MISC(context.info_label), 0.f, 0.5f); | ||
371 | gtk_box_pack_start_defaults(GTK_BOX(vbox), context.info_label); | ||
372 | |||
373 | export_update(NULL, &context); | ||
374 | |||
375 | #ifdef USE_MAEMO | ||
376 | gtk_box_pack_start_defaults(GTK_BOX(vbox), | ||
377 | harbaum | 233 | context.launch = check_button_new_with_label( |
378 | harbaum | 1 | _("Launch Maemo Mapper after export"))); |
379 | harbaum | 233 | check_button_set_active(context.launch, !appdata->mmpoi_dontlaunch); |
380 | harbaum | 1 | #endif |
381 | |||
382 | /* ------------------ path/file ------------------ */ | ||
383 | gtk_box_pack_start_defaults(GTK_BOX(vbox), gtk_hseparator_new()); | ||
384 | |||
385 | harbaum | 233 | gtk_box_pack_start_defaults(GTK_BOX(vbox), |
386 | export_file(_("Save POI database"), &appdata->mmpoi_path)); | ||
387 | harbaum | 1 | |
388 | /* ------------------ info ------------------ */ | ||
389 | |||
390 | gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox), vbox); | ||
391 | |||
392 | gtk_widget_show_all(context.dialog); | ||
393 | |||
394 | if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) { | ||
395 | #ifdef USE_MAEMO | ||
396 | appdata->mmpoi_dontlaunch = | ||
397 | harbaum | 233 | !check_button_get_active(context.launch); |
398 | harbaum | 1 | #endif |
399 | |||
400 | /* remove existing database */ | ||
401 | remove(appdata->mmpoi_path); | ||
402 | |||
403 | if(checkdir(appdata->mmpoi_path) != 0) | ||
404 | errorf(_("Unable to access or create output directory!")); | ||
405 | else { | ||
406 | |||
407 | /* build a progress dialog which can even be stopped */ | ||
408 | |||
409 | GtkWidget *pbar, *wait_dialog = gtk_dialog_new(); | ||
410 | gtk_dialog_set_has_separator(GTK_DIALOG(wait_dialog), FALSE); | ||
411 | gtk_window_set_default_size(GTK_WINDOW(wait_dialog), 250, 100); | ||
412 | harbaum | 7 | gtk_window_set_title(GTK_WINDOW(wait_dialog), _("Exporting")); |
413 | harbaum | 1 | gtk_window_set_modal(GTK_WINDOW(wait_dialog), TRUE); |
414 | gtk_window_set_transient_for(GTK_WINDOW(wait_dialog), | ||
415 | GTK_WINDOW(context.dialog)); | ||
416 | gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wait_dialog)->vbox), | ||
417 | pbar = gtk_progress_bar_new()); | ||
418 | |||
419 | harbaum | 233 | GtkWidget *button = button_new_with_label(_("Cancel")); |
420 | harbaum | 1 | int cancelled = 0; |
421 | gtk_signal_connect(GTK_OBJECT(button), "clicked", | ||
422 | GTK_SIGNAL_FUNC(on_cancel), (gpointer)&cancelled); | ||
423 | gtk_container_add(GTK_CONTAINER(GTK_DIALOG(wait_dialog)->action_area), | ||
424 | button); | ||
425 | |||
426 | gtk_widget_show_all(wait_dialog); | ||
427 | |||
428 | /* ---------------------- copy icons --------------------- */ | ||
429 | for(i=0;cache_type_icons[i][0];i++) { | ||
430 | char *src = malloc(strlen(ICONPATH)+strlen(cache_type_icons[i])+ | ||
431 | harbaum | 179 | strlen("cache_type_.png")+1); |
432 | sprintf(src, ICONPATH "cache_type_%s.png", cache_type_icons[i]); | ||
433 | harbaum | 1 | if(!g_file_test(src, G_FILE_TEST_EXISTS)) |
434 | harbaum | 179 | sprintf(src, "./icons/cache_type_%s.png", cache_type_icons[i]); |
435 | harbaum | 1 | |
436 | if(g_file_test(src, G_FILE_TEST_EXISTS)) { | ||
437 | char *dest = malloc(strlen(appdata->mmpoi_path)+ | ||
438 | strlen(cache_type_icons[i])+strlen(".jpg")+1); | ||
439 | strcpy(dest, appdata->mmpoi_path); | ||
440 | *(strrchr(dest, '/')+1) = 0; | ||
441 | sprintf(dest+strlen(dest), "%s.jpg", cache_type_icons[i]); | ||
442 | |||
443 | /* read source file */ | ||
444 | FILE *file = fopen(src, "rb"); | ||
445 | fseek(file, 0, SEEK_END); | ||
446 | int len = ftell(file); | ||
447 | fseek(file, 0, SEEK_SET); | ||
448 | char *buffer = malloc(len); | ||
449 | fread(buffer, 1l, len, file); | ||
450 | fclose(file); | ||
451 | |||
452 | /* write destination file */ | ||
453 | file = fopen(dest, "wb"); | ||
454 | fwrite(buffer, 1l, len, file); | ||
455 | fclose(file); | ||
456 | |||
457 | free(buffer); | ||
458 | free(dest); | ||
459 | } | ||
460 | |||
461 | free(src); | ||
462 | } | ||
463 | |||
464 | /* ---------------------- database export --------------------- */ | ||
465 | |||
466 | printf("exporting to %s\n", appdata->mmpoi_path); | ||
467 | rc = sqlite3_open(appdata->mmpoi_path, &db); | ||
468 | if( rc ){ | ||
469 | errorf(_("Can't open SQL database:\n\n%s"), sqlite3_errmsg(db)); | ||
470 | sqlite3_close(db); | ||
471 | export_list_free(context.gpx); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | /* create the table */ | ||
476 | rc = sqlite3_exec(db, "create table category (cat_id integer PRIMARY " | ||
477 | "KEY, label text, desc text, enabled integer)", | ||
478 | callback, 0, &zErrMsg); | ||
479 | if( rc!=SQLITE_OK ) { | ||
480 | errorf(_("Creating cathegory table:\n\n%s"), zErrMsg); | ||
481 | sqlite3_close(db); | ||
482 | export_list_free(context.gpx); | ||
483 | return; | ||
484 | } | ||
485 | |||
486 | /* create all types */ | ||
487 | i = 0; | ||
488 | while(cache_type_str[i][0]) { | ||
489 | snprintf(cmd, sizeof(cmd), | ||
490 | "insert into category values (%d, '%s', '%s', 1)", | ||
491 | 12+i, cache_type_str[i], cache_type_desc[i]); | ||
492 | |||
493 | rc = sqlite3_exec(db, cmd, callback, 0, &zErrMsg); | ||
494 | if( rc != SQLITE_OK ){ | ||
495 | errorf(_("Creating cathegory:\n\n%s"), zErrMsg); | ||
496 | sqlite3_close(db); | ||
497 | export_list_free(context.gpx); | ||
498 | return; | ||
499 | } | ||
500 | i++; | ||
501 | } | ||
502 | |||
503 | rc = sqlite3_exec(db, "create table poi (poi_id integer PRIMARY KEY, " | ||
504 | "lat real, lon real, label text, desc text, " | ||
505 | "cat_id integer)", callback, 0, &zErrMsg); | ||
506 | if( rc!=SQLITE_OK ){ | ||
507 | errorf(_("Creating POI table:\n\n%s"), zErrMsg); | ||
508 | sqlite3_close(db); | ||
509 | export_list_free(context.gpx); | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | pos_t *refpos = get_pos(appdata); | ||
514 | |||
515 | /* export the caches */ | ||
516 | int id = 1; | ||
517 | cache_t *cache = context.gpx->cache; | ||
518 | int total = export_list_count(appdata, context.gpx); | ||
519 | |||
520 | while(cache && !cancelled) { | ||
521 | |||
522 | /* no disabled/archived if requested */ | ||
523 | if(!(appdata->mmpoi_dont_export_disabled && | ||
524 | (!cache->available || cache->archived))) { | ||
525 | |||
526 | /* no found if requested */ | ||
527 | if(!(appdata->mmpoi_dont_export_found && | ||
528 | cache->notes && cache->notes->found)) { | ||
529 | |||
530 | if(appdata->mmpoi_use_radius && !isnan(appdata->mmpoi_radius)) { | ||
531 | /* count all caches within given radius around current position */ | ||
532 | if(gpx_pos_get_distance(*refpos, gpx_cache_pos(cache), 0) < | ||
533 | appdata->mmpoi_radius) { | ||
534 | printf("%d exporting %s\n", id, cache->id); | ||
535 | cache_export(db, id++, cache); | ||
536 | } | ||
537 | } else { | ||
538 | printf("%d exporting %s\n", id, cache->id); | ||
539 | cache_export(db, id++, cache); | ||
540 | } | ||
541 | } | ||
542 | } | ||
543 | cache = cache->next; | ||
544 | |||
545 | gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pbar), | ||
546 | (float)(id-2)/(float)total); | ||
547 | |||
548 | while(gtk_events_pending ()) | ||
549 | gtk_main_iteration (); | ||
550 | } | ||
551 | sqlite3_close(db); | ||
552 | |||
553 | gtk_widget_destroy(wait_dialog); | ||
554 | |||
555 | #ifdef USE_MAEMO | ||
556 | if(!cancelled && !appdata->mmpoi_dontlaunch) | ||
557 | dbus_mm_set_position(appdata, NULL); | ||
558 | #endif | ||
559 | } | ||
560 | } else { | ||
561 | /* restore old mmpoi_path, in case it has been altered but not been used */ | ||
562 | free(appdata->mmpoi_path); | ||
563 | appdata->mmpoi_path = strdup(old_mmpoi_path); | ||
564 | } | ||
565 | |||
566 | gtk_widget_destroy(context.dialog); | ||
567 | |||
568 | if(context.handler_id) { | ||
569 | printf("removing timer\n"); | ||
570 | gtk_timeout_remove(context.handler_id); | ||
571 | } | ||
572 | |||
573 | export_list_free(context.gpx); | ||
574 | |||
575 | free(old_mmpoi_path); | ||
576 | } |