Contents of /trunk/src/mm_poi.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Thu Jun 25 15:24:24 2009 UTC (14 years, 10 months ago) by harbaum
File MIME type: text/plain
File size: 19766 byte(s)
Translations
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 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
305 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 GtkWidget *button = gtk_button_new_with_label(_("Browse"));
448 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 gtk_window_set_title(GTK_WINDOW(wait_dialog), _("Exporting"));
483 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 strlen("cache_type_.gif")+1);
502 sprintf(src, ICONPATH "cache_type_%s.gif", cache_type_icons[i]);
503 if(!g_file_test(src, G_FILE_TEST_EXISTS))
504 sprintf(src, "./icons/cache_type_%s.gif", cache_type_icons[i]);
505
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 }