/** * a_babel_convert: * @vt: The TRW layer to modify. All data will be deleted, and replaced by what gpsbabel outputs. * @babelargs: A string containing gpsbabel command line filter options. No file types or names should * be specified. * @cb: A callback function. * @user_data: passed along to cb * @not_used: Must use NULL * * This function modifies data in a trw layer using gpsbabel filters. This routine is synchronous; * that is, it will block the calling program until the conversion is done. To avoid blocking, call * this routine from a worker thread. * * Returns: %TRUE on success */ gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, gpointer user_data, gpointer not_used ) { gboolean ret = FALSE; gchar *bargs = g_strconcat(babelargs, " -i gpx", NULL); gchar *name_src = a_gpx_write_tmp_file ( vt, NULL ); if ( name_src ) { ProcessOptions po = { bargs, name_src, NULL, NULL, NULL }; ret = a_babel_convert_from ( vt, &po, cb, user_data, not_used ); (void)g_remove(name_src); g_free(name_src); } g_free(bargs); return ret; }
/** * uploading function executed by the background" thread */ static void osm_traces_upload_thread ( OsmTracesInfo *oti, gpointer threaddata ) { /* Due to OSM limits, we have to enforce ele and time fields also don't upload invisible tracks */ static GpxWritingOptions options = { TRUE, TRUE, FALSE, FALSE }; if (!oti) return; gchar *filename = NULL; /* writing gpx file */ if (oti->trk != NULL) { /* Upload only the selected track */ if ( oti->anonymize_times ) { VikTrack *trk = vik_track_copy(oti->trk, TRUE); vik_track_anonymize_times(trk); filename = a_gpx_write_track_tmp_file(trk, &options); vik_track_free(trk); } else filename = a_gpx_write_track_tmp_file (oti->trk, &options); } else { /* Upload the whole VikTrwLayer */ filename = a_gpx_write_tmp_file (oti->vtl, &options); } if ( !filename ) return; /* finally, upload it */ gint ans = osm_traces_upload_file(osm_user, osm_password, filename, oti->name, oti->description, oti->tags, oti->vistype); // // Show result in statusbar or failure in dialog for user feedback // // Get current time to put into message to show when result was generated // since need to show difference between operations (when displayed on statusbar) // NB If on dialog then don't need time. time_t timenow; struct tm* timeinfo; time ( &timenow ); timeinfo = localtime ( &timenow ); gchar timestr[80]; // Compact time only - as days/date isn't very useful here strftime ( timestr, sizeof(timestr), "%X)", timeinfo ); // // Test to see if window it was invoked on is still valid // Not sure if this test really works! (i.e. if the window was closed in the mean time) // if ( IS_VIK_WINDOW ((VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(oti->vtl)) ) { gchar* msg; if ( ans == 0 ) { // Success msg = g_strdup_printf ( "%s (@%s)", _("Uploaded to OSM"), timestr ); } // Use UPPER CASE for bad news :( else if ( ans == 1001 ) { msg = g_strdup_printf ( "%s (@%s)", _("FAILED TO UPLOAD DATA TO OSM - Ensure the OSM access token preferences are setup."), timestr ); } else if ( ans < 0 ) { msg = g_strdup_printf ( "%s (@%s)", _("FAILED TO UPLOAD DATA TO OSM - CURL PROBLEM"), timestr ); } else { msg = g_strdup_printf ( "%s : %s %d (@%s)", _("FAILED TO UPLOAD DATA TO OSM"), _("HTTP response code"), ans, timestr ); } vik_window_statusbar_update ( (VikWindow*)VIK_GTK_WINDOW_FROM_LAYER(oti->vtl), msg, VIK_STATUSBAR_INFO ); g_free (msg); } /* Removing temporary file */ int ret = g_unlink(filename); if (ret != 0) { g_critical(_("failed to unlink temporary file: %s"), strerror(errno)); } }
/* depending on type of filter, often only vtl or track will be given. * the other can be NULL. */ static void acquire ( VikWindow *vw, VikLayersPanel *vlp, VikViewport *vvp, vik_datasource_mode_t mode, VikDataSourceInterface *source_interface, VikTrwLayer *vtl, VikTrack *track, gpointer userdata, VikDataSourceCleanupFunc cleanup_function ) { /* for manual dialogs */ GtkWidget *dialog = NULL; GtkWidget *status; gchar *cmd = NULL; gchar *extra = NULL; gchar *cmd_off = NULL; gchar *extra_off = NULL; acq_dialog_widgets_t *w; gpointer user_data; gpointer options = NULL; acq_vik_t avt; avt.vlp = vlp; avt.vvp = vvp; avt.vw = vw; avt.userdata = userdata; /* for UI builder */ gpointer pass_along_data; VikLayerParamData *paramdatas = NULL; w_and_interface_t *wi; /*** INIT AND CHECK EXISTENCE ***/ if ( source_interface->init_func ) user_data = source_interface->init_func(&avt); else user_data = NULL; pass_along_data = user_data; if ( source_interface->check_existence_func ) { gchar *error_str = source_interface->check_existence_func(); if ( error_str ) { a_dialog_error_msg ( GTK_WINDOW(vw), error_str ); g_free ( error_str ); return; } } /* BUILD UI & GET OPTIONS IF NECESSARY. */ /* POSSIBILITY 0: NO OPTIONS. DO NOTHING HERE. */ /* POSSIBILITY 1: ADD_SETUP_WIDGETS_FUNC */ if ( source_interface->add_setup_widgets_func ) { dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL ); gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT ); GtkWidget *response_w = NULL; #if GTK_CHECK_VERSION (2, 20, 0) response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT ); #endif source_interface->add_setup_widgets_func(dialog, vvp, user_data); gtk_window_set_title ( GTK_WINDOW(dialog), _(source_interface->window_title) ); if ( response_w ) gtk_widget_grab_focus ( response_w ); if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_ACCEPT ) { source_interface->cleanup_func(user_data); gtk_widget_destroy(dialog); return; } } /* POSSIBILITY 2: UI BUILDER */ else if ( source_interface->params ) { paramdatas = a_uibuilder_run_dialog ( source_interface->window_title, GTK_WINDOW(vw), source_interface->params, source_interface->params_count, source_interface->params_groups, source_interface->params_groups_count, source_interface->params_defaults ); if ( paramdatas ) pass_along_data = paramdatas; else return; /* TODO: do we have to free anything here? */ } /* CREATE INPUT DATA & GET COMMAND STRING */ if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRWLAYER ) { gchar *name_src = a_gpx_write_tmp_file ( vtl, NULL ); ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func) ( pass_along_data, &cmd, &extra, name_src ); util_add_to_deletion_list ( name_src ); g_free ( name_src ); } else if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRWLAYER_TRACK ) { gchar *name_src = a_gpx_write_tmp_file ( vtl, NULL ); gchar *name_src_track = a_gpx_write_track_tmp_file ( track, NULL ); ((VikDataSourceGetCmdStringFuncWithInputInput) source_interface->get_cmd_string_func) ( pass_along_data, &cmd, &extra, name_src, name_src_track ); util_add_to_deletion_list ( name_src ); util_add_to_deletion_list ( name_src_track ); g_free ( name_src ); g_free ( name_src_track ); } else if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRACK ) { gchar *name_src_track = a_gpx_write_track_tmp_file ( track, NULL ); ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func) ( pass_along_data, &cmd, &extra, name_src_track ); g_free ( name_src_track ); } else if ( source_interface->get_cmd_string_func ) source_interface->get_cmd_string_func ( pass_along_data, &cmd, &extra, &options ); /* Get data for Off command */ if ( source_interface->off_func ) { source_interface->off_func ( pass_along_data, &cmd_off, &extra_off ); } /* cleanup for option dialogs */ if ( source_interface->add_setup_widgets_func ) { gtk_widget_destroy(dialog); dialog = NULL; } else if ( source_interface->params ) { a_uibuilder_free_paramdatas ( paramdatas, source_interface->params, source_interface->params_count ); } w = g_malloc(sizeof(*w)); wi = g_malloc(sizeof(*wi)); wi->w = w; wi->w->source_interface = source_interface; wi->cmd = cmd; wi->extra = extra; /* usually input data type (?) */ wi->options = options; wi->vtl = vtl; wi->creating_new_layer = (!vtl); // Default if Auto Layer Management is passed in dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL ); gtk_dialog_set_response_sensitive ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, FALSE ); gtk_window_set_title ( GTK_WINDOW(dialog), _(source_interface->window_title) ); w->dialog = dialog; w->running = TRUE; status = gtk_label_new (_("Working...")); gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), status, FALSE, FALSE, 5 ); gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT ); // May not want to see the dialog at all if ( source_interface->is_thread || source_interface->keep_dialog_open ) gtk_widget_show_all(dialog); w->status = status; w->vw = vw; w->vlp = vlp; w->vvp = vvp; if ( source_interface->add_progress_widgets_func ) { source_interface->add_progress_widgets_func ( dialog, user_data ); } w->user_data = user_data; if ( mode == VIK_DATASOURCE_ADDTOLAYER ) { VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp ); if ( IS_VIK_TRW_LAYER(current_selected) ) { wi->vtl = VIK_TRW_LAYER(current_selected); wi->creating_new_layer = FALSE; } } else if ( mode == VIK_DATASOURCE_CREATENEWLAYER ) { wi->creating_new_layer = TRUE; } else if ( mode == VIK_DATASOURCE_MANUAL_LAYER_MANAGEMENT ) { // Don't create in acquire - as datasource will perform the necessary actions wi->creating_new_layer = FALSE; VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp ); if ( IS_VIK_TRW_LAYER(current_selected) ) wi->vtl = VIK_TRW_LAYER(current_selected); } if ( wi->creating_new_layer ) { wi->vtl = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, w->vvp, FALSE ) ); vik_layer_rename ( VIK_LAYER ( wi->vtl ), _(source_interface->layer_title) ); } if ( source_interface->is_thread ) { if ( cmd ) { #if GLIB_CHECK_VERSION (2, 32, 0) g_thread_try_new ( "get_from_anything", (GThreadFunc)get_from_anything, wi, NULL ); #else g_thread_create ( (GThreadFunc)get_from_anything, wi, FALSE, NULL ); #endif gtk_dialog_run ( GTK_DIALOG(dialog) ); if (w->running) { // Cancel and mark for thread to finish w->running = FALSE; // NB Thread will free memory } else { if ( cmd_off ) { /* Turn off */ a_babel_convert_from (NULL, cmd_off, extra_off, NULL, NULL, NULL); g_free ( cmd_off ); } if ( extra_off ) g_free ( extra_off ); // Thread finished by normal completion - free memory g_free ( w ); g_free ( wi ); } } else { // This shouldn't happen... gtk_label_set_text ( GTK_LABEL(w->status), _("Unable to create command\nAcquire method failed.") ); gtk_dialog_run (GTK_DIALOG (dialog)); } } else { // bypass thread method malarkly - you'll just have to wait... if ( source_interface->process_func ) { gboolean result = source_interface->process_func ( wi->vtl, cmd, extra, (BabelStatusFunc) progress_func, w, options ); if ( !result ) a_dialog_msg ( GTK_WINDOW(vw), GTK_MESSAGE_ERROR, _("Error: acquisition failed."), NULL ); } g_free ( cmd ); g_free ( extra ); g_free ( options ); on_complete_process ( wi ); // Actually show it if necessary if ( wi->w->source_interface->keep_dialog_open ) gtk_dialog_run ( GTK_DIALOG(dialog) ); g_free ( w ); g_free ( wi ); } gtk_widget_destroy ( dialog ); if ( cleanup_function ) cleanup_function ( source_interface ); }