Esempio n. 1
0
/**
 * 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;
}
Esempio n. 2
0
File: babel.c Progetto: gdt/viking
/**
 * a_babel_convert_from_url:
 * @vt: The #VikTrwLayer where to insert the collected data
 * @url: the URL to fetch
 * @cb:	       Optional callback function. Same usage as in a_babel_convert().
 * @user_data: passed along to cb
 * @options:   download options. Maybe NULL.
 *
 * Download the file pointed by the URL and optionally uses GPSBabel to convert from input_file_type.
 * If input_file_type is %NULL, doesn't use GPSBabel. Input must be GPX.
 *
 * Returns: %TRUE on successful invocation of GPSBabel or read of the GPX
 *
 */
gboolean a_babel_convert_from_url ( VikTrwLayer *vt, const char *url, const char *input_type, BabelStatusFunc cb, gpointer user_data, DownloadMapOptions *options )
{
  // If no download options specified, use defaults:
  DownloadMapOptions myoptions = { FALSE, FALSE, NULL, 2, NULL, NULL, NULL };
  if ( options )
    myoptions = *options;
  gint fd_src;
  int fetch_ret;
  gboolean ret = FALSE;
  gchar *name_src = NULL;
  gchar *babelargs = NULL;

  g_debug("%s: input_type=%s url=%s", __FUNCTION__, input_type, url);

  if ((fd_src = g_file_open_tmp("tmp-viking.XXXXXX", &name_src, NULL)) >= 0) {
    g_debug ("%s: temporary file: %s", __FUNCTION__, name_src);
    close(fd_src);
    g_remove(name_src);

    fetch_ret = a_http_download_get_url(url, "", name_src, &myoptions, NULL);
    if (fetch_ret == 0) {
      if (input_type != NULL) {
        babelargs = g_strdup_printf(" -i %s", input_type);
        ret = a_babel_convert_from( vt, babelargs, name_src, NULL, NULL, NULL );
      } else {
        /* Process directly the retrieved file */
        g_debug("%s: directly read GPX file %s", __FUNCTION__, name_src);
        FILE *f = g_fopen(name_src, "r");
        if (f) {
          ret = a_gpx_read_file ( vt, f );
          fclose(f);
          f = NULL;
        }
      }
    }
    g_remove(name_src);
    g_free(babelargs);
    g_free(name_src);
  }

  return ret;
}
Esempio n. 3
0
File: babel.c Progetto: gdt/viking
/**
 * 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 )
{
  int fd_src;
  FILE *f;
  gchar *name_src = NULL;
  gboolean ret = FALSE;
  gchar *bargs = g_strconcat(babelargs, " -i gpx", NULL);

  if ((fd_src = g_file_open_tmp("tmp-viking.XXXXXX", &name_src, NULL)) >= 0) {
    g_debug ("%s: temporary file: %s", __FUNCTION__, name_src);
    f = fdopen(fd_src, "w");
    a_gpx_write_file(vt, f, NULL);
    fclose(f);
    f = NULL;
    ret = a_babel_convert_from ( vt, bargs, name_src, cb, user_data, not_used );
    g_remove(name_src);
    g_free(name_src);
  }

  g_free(bargs);
  return ret;
}
Esempio n. 4
0
File: file.c Progetto: gapato/viking
VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar *filename_or_uri )
{
  g_return_val_if_fail ( vp != NULL, LOAD_TYPE_READ_FAILURE );

  char *filename = (char *)filename_or_uri;
  if (strncmp(filename, "file://", 7) == 0) {
    // Consider replacing this with:
    // filename = g_filename_from_uri ( entry, NULL, NULL );
    // Since this doesn't support URIs properly (i.e. will failure if is it has %20 characters in it)
    filename = filename + 7;
    g_debug ( "Loading file %s from URI %s", filename, filename_or_uri );
  }
  FILE *f = xfopen ( filename );

  if ( ! f )
    return LOAD_TYPE_READ_FAILURE;

  VikLoadType_t load_answer = LOAD_TYPE_OTHER_SUCCESS;

  gchar *dirpath = g_path_get_dirname ( filename );
  // Attempt loading the primary file type first - our internal .vik file:
  if ( check_magic ( f, VIK_MAGIC ) )
  {
    if ( file_read ( top, f, dirpath, vp ) )
      load_answer = LOAD_TYPE_VIK_SUCCESS;
    else
      load_answer = LOAD_TYPE_VIK_FAILURE_NON_FATAL;
  }
  else if ( a_jpg_magic_check ( filename ) ) {
    if ( ! a_jpg_load_file ( top, filename, vp ) )
      load_answer = LOAD_TYPE_UNSUPPORTED_FAILURE;
  }
  else
  {
	// For all other file types which consist of tracks, routes and/or waypoints,
	//  must be loaded into a new TrackWaypoint layer (hence it be created)
    gboolean success = TRUE; // Detect load failures - mainly to remove the layer created as it's not required

    VikLayer *vtl = vik_layer_create ( VIK_LAYER_TRW, vp, FALSE );
    vik_layer_rename ( vtl, a_file_basename ( filename ) );

    // In fact both kml & gpx files start the same as they are in xml
    if ( a_file_check_ext ( filename, ".kml" ) && check_magic ( f, GPX_MAGIC ) ) {
      // Implicit Conversion
      if ( ! ( success = a_babel_convert_from ( VIK_TRW_LAYER(vtl), "-i kml", filename, NULL, NULL, NULL ) ) ) {
        load_answer = LOAD_TYPE_GPSBABEL_FAILURE;
      }
    }
    // NB use a extension check first, as a GPX file header may have a Byte Order Mark (BOM) in it
    //    - which currently confuses our check_magic function
    else if ( a_file_check_ext ( filename, ".gpx" ) || check_magic ( f, GPX_MAGIC ) ) {
      if ( ! ( success = a_gpx_read_file ( VIK_TRW_LAYER(vtl), f ) ) ) {
        load_answer = LOAD_TYPE_GPX_FAILURE;
      }
    }
    else {
      // Try final supported file type
      if ( ! ( success = a_gpspoint_read_file ( VIK_TRW_LAYER(vtl), f, dirpath ) ) ) {
        // Failure here means we don't know how to handle the file
        load_answer = LOAD_TYPE_UNSUPPORTED_FAILURE;
      }
    }
    g_free ( dirpath );

    // Clean up when we can't handle the file
    if ( ! success ) {
      // free up layer
      g_object_unref ( vtl );
    }
    else {
      // Complete the setup from the successful load
      vik_layer_post_read ( vtl, vp, TRUE );
      vik_aggregate_layer_add_layer ( top, vtl, FALSE );
      vik_trw_layer_auto_set_view ( VIK_TRW_LAYER(vtl), vp );
    }
  }
  xfclose(f);
  return load_answer;
}
static gboolean datasource_osm_my_traces_process ( VikTrwLayer *vtl, ProcessOptions *process_options, BabelStatusFunc status_cb, acq_dialog_widgets_t *adw, DownloadMapOptions *options_unused )
{
	//datasource_osm_my_traces_t *data = (datasource_osm_my_traces_t *)adw->user_data;

	gboolean result;

	gchar *user_pass = osm_get_login();

	// Support .zip + bzip2 files directly
	DownloadMapOptions options = { FALSE, FALSE, NULL, 2, NULL, user_pass, a_try_decompress_file }; // Allow a couple of redirects

	gchar *tmpname = a_download_uri_to_tmp_file ( DS_OSM_TRACES_GPX_FILES, &options );
	if ( !tmpname )
		return FALSE;

	xml_data *xd = g_malloc ( sizeof (xml_data) );
	//xd->xpath = g_string_new ( "" );
	xd->c_cdata = g_string_new ( "" );
	xd->current_tag = tt_unknown;
	xd->current_gpx_meta_data = new_gpx_meta_data_t();
	xd->list_of_gpx_meta_data = NULL;

	result = read_gpx_files_metadata_xml ( tmpname, xd );
	// Test already downloaded metadata file: eg:
	//result = read_gpx_files_metadata_xml ( "/tmp/viking-download.GI47PW", xd );

	if ( tmpname ) {
		(void)util_remove ( tmpname );
		g_free ( tmpname );
	}

	if ( ! result ) {
		g_free ( xd );
		return FALSE;
	}

	if ( g_list_length ( xd->list_of_gpx_meta_data ) == 0 ) {
		if (!vik_datasource_osm_my_traces_interface.is_thread)
			none_found ( GTK_WINDOW(adw->vw) );
		g_free ( xd );
		return FALSE;
	}

	xd->list_of_gpx_meta_data = g_list_reverse ( xd->list_of_gpx_meta_data );

	set_in_current_view_property ( vtl, adw->user_data, xd->list_of_gpx_meta_data );

    if (vik_datasource_osm_my_traces_interface.is_thread) gdk_threads_enter();
	GList *selected = select_from_list ( GTK_WINDOW(adw->vw), xd->list_of_gpx_meta_data, "Select GPS Traces", "Select the GPS traces you want to add." );
    if (vik_datasource_osm_my_traces_interface.is_thread) gdk_threads_leave();

	// If non thread - show program is 'doing something...'
	if ( !vik_datasource_osm_my_traces_interface.is_thread )
		vik_window_set_busy_cursor ( adw->vw );

	// If passed in on an existing layer - we will create everything into that.
	//  thus with many differing gpx's - this will combine all waypoints into this single layer!
	// Hence the preference is to create multiple layers
	//  and so this creation of the layers must be managed here

	gboolean create_new_layer = ( !vtl );

	// Only update the screen on the last layer acquired
	VikTrwLayer *vtl_last = vtl;
	gboolean got_something = FALSE;

	GList *selected_iterator = selected;
	while ( selected_iterator ) {

		VikTrwLayer *vtlX = vtl;

		if ( create_new_layer ) {
			// Have data but no layer - so create one
			vtlX = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, adw->vvp, FALSE ) );
			if ( ((gpx_meta_data_t*)selected_iterator->data)->name )
				vik_layer_rename ( VIK_LAYER ( vtlX ), ((gpx_meta_data_t*)selected_iterator->data)->name );
			else
				vik_layer_rename ( VIK_LAYER ( vtlX ), _("My OSM Traces") );
		}

		result = FALSE;
		gint gpx_id = ((gpx_meta_data_t*)selected_iterator->data)->id;
		if ( gpx_id ) {
			gchar *url = g_strdup_printf ( DS_OSM_TRACES_GPX_URL_FMT, gpx_id );

			// NB download type is GPX (or a compressed version)
			ProcessOptions my_po = *process_options;
			my_po.url = url;
			result = a_babel_convert_from ( vtlX, &my_po, status_cb, adw, &options );
			// TODO investigate using a progress bar:
			// http://developer.gnome.org/gtk/2.24/GtkProgressBar.html

			got_something = got_something || result;
			if ( !result ) {
				// Report errors to the status bar
				gchar* msg = g_strdup_printf ( _("Unable to get trace: %s"), url );
				vik_window_statusbar_update ( adw->vw, msg, VIK_STATUSBAR_INFO );
				g_free (msg);
			}
			g_free ( url );
		}

		if ( result ) {
			// Can use the layer
			vik_aggregate_layer_add_layer ( vik_layers_panel_get_top_layer (adw->vlp), VIK_LAYER(vtlX), TRUE );
			// Move to area of the track
			vik_layer_post_read ( VIK_LAYER(vtlX), vik_window_viewport(adw->vw), TRUE );
			vik_trw_layer_auto_set_view ( vtlX, vik_window_viewport(adw->vw) );
			vtl_last = vtlX;
		}
		else if ( create_new_layer ) {
			// Layer not needed as no data has been acquired
			g_object_unref ( vtlX );
		}

		selected_iterator = g_list_next ( selected_iterator );
	}

	// Free memory
	if ( xd->current_gpx_meta_data )
		free_gpx_meta_data ( xd->current_gpx_meta_data, NULL );
	g_free ( xd->current_gpx_meta_data );
	free_gpx_meta_data_list ( xd->list_of_gpx_meta_data );
	free_gpx_meta_data_list ( selected );
	g_free ( xd );
	g_free ( user_pass );

	// Would prefer to keep the update in acquire.c,
	//  however since we may create the layer - need to do the update here
	if ( got_something )
		vik_layer_emit_update ( VIK_LAYER(vtl_last) );

	// ATM The user is only informed if all getting *all* of the traces failed
	if ( selected )
		result = got_something;
	else
		// Process was cancelled but need to return that it proceeded as expected
		result = TRUE;

	if ( !vik_datasource_osm_my_traces_interface.is_thread )
		vik_window_clear_busy_cursor ( adw->vw );

	return result;
}
Esempio n. 6
0
/* this routine is the worker thread.  there is only one simultaneous download allowed */
static void get_from_anything ( w_and_interface_t *wi )
{
    gchar *cmd = wi->cmd;
    gchar *extra = wi->extra;
    gboolean result = TRUE;
    VikTrwLayer *vtl = NULL;

    gboolean creating_new_layer = TRUE;

    acq_dialog_widgets_t *w = wi->w;
    VikDataSourceInterface *source_interface = wi->w->source_interface;
    g_free ( wi );
    wi = NULL;

    gdk_threads_enter();
    if (source_interface->mode == VIK_DATASOURCE_ADDTOLAYER) {
        VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp );
        if ( IS_VIK_TRW_LAYER(current_selected) ) {
            vtl = VIK_TRW_LAYER(current_selected);
            creating_new_layer = FALSE;
        }
    }
    if ( creating_new_layer ) {
        vtl = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, w->vvp, NULL, FALSE ) );
        vik_layer_rename ( VIK_LAYER ( vtl ), _(source_interface->layer_title) );
        gtk_label_set_text ( GTK_LABEL(w->status), _("Working...") );
    }
    gdk_threads_leave();

    switch ( source_interface->type ) {
    case VIK_DATASOURCE_GPSBABEL_DIRECT:
        result = a_babel_convert_from (vtl, cmd, (BabelStatusFunc) progress_func, extra, w);
        break;
    case VIK_DATASOURCE_URL:
        result = a_babel_convert_from_url (vtl, cmd, extra, (BabelStatusFunc) progress_func, w);
        break;
    case VIK_DATASOURCE_SHELL_CMD:
        result = a_babel_convert_from_shellcommand ( vtl, cmd, extra, (BabelStatusFunc) progress_func, w);
        break;
    default:
        g_critical("Houston, we've had a problem.");
    }

    g_free ( cmd );
    g_free ( extra );

    if (!result) {
        gdk_threads_enter();
        gtk_label_set_text ( GTK_LABEL(w->status), _("Error: acquisition failed.") );
        if ( creating_new_layer )
            g_object_unref ( G_OBJECT ( vtl ) );
        gdk_threads_leave();
    }
    else {
        gdk_threads_enter();
        if (w->ok) {
            gtk_label_set_text ( GTK_LABEL(w->status), _("Done.") );
            if ( creating_new_layer ) {
                /* Only create the layer if it actually contains anything useful */
                if ( g_hash_table_size (vik_trw_layer_get_tracks(vtl)) ||
                        g_hash_table_size (vik_trw_layer_get_waypoints(vtl)) )
                    vik_aggregate_layer_add_layer( vik_layers_panel_get_top_layer(w->vlp), VIK_LAYER(vtl));
                else
                    gtk_label_set_text ( GTK_LABEL(w->status), _("No data.") );
            }
            /* View this data if available and is desired */
            if ( vtl && source_interface->autoview ) {
                vik_trw_layer_auto_set_view ( vtl, vik_layers_panel_get_viewport(w->vlp) );
                vik_layers_panel_emit_update (w->vlp);
            }
            if ( source_interface->keep_dialog_open ) {
                gtk_dialog_set_response_sensitive ( GTK_DIALOG(w->dialog), GTK_RESPONSE_ACCEPT, TRUE );
                gtk_dialog_set_response_sensitive ( GTK_DIALOG(w->dialog), GTK_RESPONSE_REJECT, FALSE );
            } else {
                gtk_dialog_response ( GTK_DIALOG(w->dialog), GTK_RESPONSE_ACCEPT );
            }
        } else {
            /* canceled */
            if ( creating_new_layer )
                g_object_unref(vtl);
        }
    }
    if ( source_interface->cleanup_func )
        source_interface->cleanup_func ( w->user_data );

    if ( w->ok ) {
        w->ok = FALSE;
    } else {
        g_free ( w );
    }

    gdk_threads_leave();
    g_thread_exit ( NULL );
}
Esempio n. 7
0
/* 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, VikDataSourceInterface *source_interface,
                      VikTrwLayer *vtl, VikTrack *track )
{
    /* for manual dialogs */
    GtkWidget *dialog = NULL;
    GtkWidget *status;
    gchar *cmd, *extra;
    gchar *cmd_off = NULL;
    gchar *extra_off = NULL;
    acq_dialog_widgets_t *w;
    gpointer user_data;

    /* 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();
    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 = write_tmp_trwlayer ( vtl );

        ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func)
        ( pass_along_data, &cmd, &extra, name_src );

        g_free ( name_src );
        /* TODO: delete the tmp file? or delete it only after we're done with it? */
    } else if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRWLAYER_TRACK ) {
        gchar *name_src = write_tmp_trwlayer ( vtl );
        gchar *name_src_track = write_tmp_track ( track );

        ((VikDataSourceGetCmdStringFuncWithInputInput) source_interface->get_cmd_string_func)
        ( pass_along_data, &cmd, &extra, name_src, 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 = write_tmp_track ( track );

        ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func)
        ( pass_along_data, &cmd, &extra, name_src_track );

        g_free ( name_src_track );
    } else
        source_interface->get_cmd_string_func ( pass_along_data, &cmd, &extra );

    /* 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 );
    }

    /*** LET'S DO IT! ***/

    if ( ! cmd )
        return;

    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 (?) */

    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->ok = TRUE;
    status = gtk_label_new (_("Status: detecting gpsbabel"));
    gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), status, FALSE, FALSE, 5 );
    gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT );
    gtk_widget_show_all(status);
    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;


    g_thread_create((GThreadFunc)get_from_anything, wi, FALSE, NULL );

    gtk_dialog_run ( GTK_DIALOG(dialog) );
    if ( w->ok )
        w->ok = FALSE; /* tell thread to stop. TODO: add mutex */
    else {
        if ( cmd_off ) {
            /* Turn off */
            a_babel_convert_from (NULL, cmd_off, NULL, extra_off, NULL);
        }
        g_free ( w ); /* thread has finished; free w */
    }
    gtk_widget_destroy ( dialog );
}
Esempio n. 8
0
/* 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, VikDataSourceInterface *source_interface,
		      VikTrwLayer *vtl, VikTrack *track )
{
  /* 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;

  /* 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();
  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 = write_tmp_trwlayer ( vtl );

    ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func)
	( pass_along_data, &cmd, &extra, name_src );

    g_free ( name_src );
    /* TODO: delete the tmp file? or delete it only after we're done with it? */
  } else if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRWLAYER_TRACK ) {
    gchar *name_src = write_tmp_trwlayer ( vtl );
    gchar *name_src_track = write_tmp_track ( track );

    ((VikDataSourceGetCmdStringFuncWithInputInput) source_interface->get_cmd_string_func)
	( pass_along_data, &cmd, &extra, name_src, 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 = write_tmp_track ( track );

    ((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);

  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(dialog)->vbox), 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 (source_interface->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 ( source_interface->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, NULL, FALSE ) );
    vik_layer_rename ( VIK_LAYER ( wi->vtl ), _(source_interface->layer_title) );
  }

  if ( source_interface->is_thread ) {
    if ( cmd ) {
      g_thread_create((GThreadFunc)get_from_anything, wi, FALSE, NULL );
      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 );
}