Beispiel #1
0
/**
 * Load a single JPG into a Trackwaypoint Layer as a waypoint
 *
 * @top:      The Aggregate layer that a new TRW layer may be created in
 * @filename: The JPG filename
 * @vvp:      The viewport
 *
 * Returns: Whether the loading was a success or not
 *
 * If the JPG has geotag information then the waypoint will be created with the appropriate position.
 *  Otherwise the waypoint will be positioned at the current screen center.
 * If a TRW layer is already selected the waypoint will be created in that layer.
 */
gboolean a_jpg_load_file ( VikAggregateLayer *top, const gchar *filename, VikViewport *vvp )
{
	gboolean auto_zoom = TRUE;
	VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(top)));
	VikLayersPanel *vlp = vik_window_layers_panel ( vw );
	// Auto load into TrackWaypoint layer if one is selected
	VikLayer *vtl = vik_layers_panel_get_selected ( vlp );

	gboolean create_layer = FALSE;
	if ( vtl == NULL || vtl->type != VIK_LAYER_TRW ) {
		// Create layer if necessary
		vtl = vik_layer_create ( VIK_LAYER_TRW, vvp, FALSE );
		vik_layer_rename ( vtl, a_file_basename ( filename ) );
		create_layer = TRUE;
	}

	gchar *name = NULL;
	VikWaypoint *wp = NULL;
#ifdef VIK_CONFIG_GEOTAG
	wp = a_geotag_create_waypoint_from_file ( filename, vik_viewport_get_coord_mode (vvp), &name );
#endif
	if ( wp ) {
		// Create name if geotag method didn't return one
		if ( !name )
			name = g_strdup ( a_file_basename ( filename ) );
		vik_trw_layer_filein_add_waypoint ( VIK_TRW_LAYER(vtl), name, wp );
		g_free ( name );
	}
	else {
		wp = vik_waypoint_new ();
		wp->visible = TRUE;
		vik_trw_layer_filein_add_waypoint ( VIK_TRW_LAYER(vtl), (gchar*) a_file_basename(filename), wp );
		vik_waypoint_set_image ( wp, filename );
		// Simply set position to the current center
		wp->coord = *( vik_viewport_get_center ( vvp ) );
		auto_zoom = FALSE;
	}

	// Complete the setup
	vik_layer_post_read ( vtl, vvp, TRUE );
	if ( create_layer )
		vik_aggregate_layer_add_layer ( top, vtl, FALSE );
	if ( auto_zoom )
		vik_trw_layer_auto_set_view ( VIK_TRW_LAYER(vtl), vvp );

	// ATM This routine can't fail
	return TRUE;
}
Beispiel #2
0
VikGeorefLayer *vik_georef_layer_create ( VikViewport *vp,
                                          VikLayersPanel *vlp,
                                          const gchar *name,
                                          GdkPixbuf *pixbuf,
                                          VikCoord *coord_tl,
                                          VikCoord *coord_br )
{
  VikGeorefLayer *vgl = georef_layer_new ( vp );
  vik_layer_rename ( VIK_LAYER(vgl), name );

  vgl->pixbuf = pixbuf;

  vik_coord_to_utm ( coord_tl, &(vgl->corner) );
  vik_coord_to_latlon ( coord_br, &(vgl->ll_br) );

  if ( vgl->pixbuf ) {
    vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
    vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );

    if ( vgl->width > 0 && vgl->height > 0 ) {

      struct LatLon ll_tl;
      vik_coord_to_latlon ( coord_tl, &ll_tl);
      struct LatLon ll_br;
      vik_coord_to_latlon ( coord_br, &ll_br);

      VikCoordMode mode = vik_viewport_get_coord_mode (vp);

      gdouble xmpp, ympp;
      georef_layer_mpp_from_coords ( mode, ll_tl, ll_br, vgl->width, vgl->height, &xmpp, &ympp );
      vgl->mpp_easting = xmpp;
      vgl->mpp_northing = ympp;

      goto_center_ll ( vp, ll_tl, ll_br);
      // Set best zoom level
      struct LatLon maxmin[2] = { ll_tl, ll_br };
      vu_zoom_to_show_latlons ( vik_viewport_get_coord_mode(vp), vp, maxmin );

      return vgl;
    }
  }

  // Bad image
  georef_layer_free ( vgl );
  return NULL;
}
Beispiel #3
0
static void layers_item_edited (VikLayersPanel *vlp, GtkTreeIter *iter, const gchar *new_text)
{
  if ( vik_treeview_item_get_type ( vlp->vt, iter ) == VIK_TREEVIEW_TYPE_LAYER )
  {
    VikLayer *l;

    /* get iter and layer */
    l = VIK_LAYER ( vik_treeview_item_get_pointer ( vlp->vt, iter ) );

    if ( strcmp ( l->name, new_text ) != 0 )
    {
      vik_layer_rename ( l, new_text );
      vik_treeview_item_set_name ( vlp->vt, iter, l->name );
    }
  }
  else
  {
    const gchar *name = vik_layer_sublayer_rename_request ( vik_treeview_item_get_parent ( vlp->vt, iter ), new_text, vlp, vik_treeview_item_get_data ( vlp->vt, iter ), vik_treeview_item_get_pointer ( vlp->vt, iter ), iter );
    if ( name )
      vik_treeview_item_set_name ( vlp->vt, iter, name);
  }
}
Beispiel #4
0
VikLayer *vik_layer_create ( VikLayerTypeEnum type, VikViewport *vp, gboolean interactive )
{
  VikLayer *new_layer = NULL;
  g_assert ( type < VIK_LAYER_NUM_TYPES );

  new_layer = vik_layer_interfaces[type]->create ( vp );

  g_assert ( new_layer != NULL );

  if ( interactive )
  {
    if ( vik_layer_properties ( new_layer, vp ) )
      /* We translate the name here */
      /* in order to avoid translating name set by user */
      vik_layer_rename ( VIK_LAYER(new_layer), _(vik_layer_interfaces[type]->name) );
    else
    {
      g_object_unref ( G_OBJECT(new_layer) ); /* cancel that */
      new_layer = NULL;
    }
  }
  return new_layer;
}
Beispiel #5
0
static void layers_panel_init ( VikLayersPanel *vlp )
{
  GtkWidget *hbox;
  GtkWidget *addbutton, *addimage;
  GtkWidget *removebutton, *removeimage;
  GtkWidget *upbutton, *upimage;
  GtkWidget *downbutton, *downimage;
  GtkWidget *cutbutton, *cutimage;
  GtkWidget *copybutton, *copyimage;
  GtkWidget *pastebutton, *pasteimage;
  GtkWidget *scrolledwindow;
  GtkItemFactoryEntry entry;
  guint i, tmp;

  vlp->vvp = NULL;

  hbox = gtk_hbox_new ( TRUE, 2 );
  vlp->vt = vik_treeview_new ( );

  vlp->toplayer = vik_aggregate_layer_new ();
  vik_layer_rename ( VIK_LAYER(vlp->toplayer), _("Top Layer"));
  g_signal_connect_swapped ( G_OBJECT(vlp->toplayer), "update", G_CALLBACK(vik_layers_panel_emit_update), vlp );

  vik_treeview_add_layer ( vlp->vt, NULL, &(vlp->toplayer_iter), VIK_LAYER(vlp->toplayer)->name, NULL, vlp->toplayer, VIK_LAYER_AGGREGATE, VIK_LAYER_AGGREGATE );
  vik_layer_realize ( VIK_LAYER(vlp->toplayer), vlp->vt, &(vlp->toplayer_iter) );

  g_signal_connect_swapped ( vlp->vt, "popup_menu", G_CALLBACK(menu_popup_cb), vlp);
  g_signal_connect_swapped ( vlp->vt, "button_press_event", G_CALLBACK(layers_button_press_cb), vlp);
  g_signal_connect_swapped ( vlp->vt, "item_toggled", G_CALLBACK(layers_item_toggled), vlp);
  g_signal_connect_swapped ( vlp->vt, "item_edited", G_CALLBACK(layers_item_edited), vlp);
  g_signal_connect_swapped ( vlp->vt, "key_press_event", G_CALLBACK(layers_key_press_cb), vlp);

  /* Add button */
  addimage = gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR );
  addbutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(addbutton), addimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(addbutton), _("Add new layer"));
  gtk_box_pack_start ( GTK_BOX(hbox), addbutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(addbutton), "clicked", G_CALLBACK(layers_popup_cb), vlp );
  /* Remove button */
  removeimage = gtk_image_new_from_stock ( GTK_STOCK_REMOVE, GTK_ICON_SIZE_SMALL_TOOLBAR );
  removebutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(removebutton), removeimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(removebutton), _("Remove selected layer"));
  gtk_box_pack_start ( GTK_BOX(hbox), removebutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(removebutton), "clicked", G_CALLBACK(vik_layers_panel_delete_selected), vlp );
  /* Up button */
  upimage = gtk_image_new_from_stock ( GTK_STOCK_GO_UP, GTK_ICON_SIZE_SMALL_TOOLBAR );
  upbutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(upbutton), upimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(upbutton), _("Move selected layer up"));
  gtk_box_pack_start ( GTK_BOX(hbox), upbutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(upbutton), "clicked", G_CALLBACK(layers_move_item_up), vlp );
  /* Down button */
  downimage = gtk_image_new_from_stock ( GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_SMALL_TOOLBAR );
  downbutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(downbutton), downimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(downbutton), _("Move selected layer down"));
  gtk_box_pack_start ( GTK_BOX(hbox), downbutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(downbutton), "clicked", G_CALLBACK(layers_move_item_down), vlp );
  /* Cut button */
  cutimage = gtk_image_new_from_stock ( GTK_STOCK_CUT, GTK_ICON_SIZE_SMALL_TOOLBAR );
  cutbutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(cutbutton), cutimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(cutbutton), _("Cut selected layer"));
  gtk_box_pack_start ( GTK_BOX(hbox), cutbutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(cutbutton), "clicked", G_CALLBACK(vik_layers_panel_cut_selected), vlp );
  /* Copy button */
  copyimage = gtk_image_new_from_stock ( GTK_STOCK_COPY, GTK_ICON_SIZE_SMALL_TOOLBAR );
  copybutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(copybutton), copyimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(copybutton), _("Copy selected layer"));
  gtk_box_pack_start ( GTK_BOX(hbox), copybutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(copybutton), "clicked", G_CALLBACK(vik_layers_panel_copy_selected), vlp );
  /* Paste button */
  pasteimage = gtk_image_new_from_stock ( GTK_STOCK_PASTE, GTK_ICON_SIZE_SMALL_TOOLBAR );
  pastebutton = gtk_button_new ( );
  gtk_container_add ( GTK_CONTAINER(pastebutton),pasteimage );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(pastebutton), _("Paste layer below selected layer"));
  gtk_box_pack_start ( GTK_BOX(hbox), pastebutton, TRUE, TRUE, 0 );
  g_signal_connect_swapped ( G_OBJECT(pastebutton), "clicked", G_CALLBACK(vik_layers_panel_paste_selected), vlp );

  scrolledwindow = gtk_scrolled_window_new ( NULL, NULL );
  gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
  gtk_container_add ( GTK_CONTAINER(scrolledwindow), GTK_WIDGET(vlp->vt) );
  
  gtk_box_pack_start ( GTK_BOX(vlp), scrolledwindow, TRUE, TRUE, 0 );
  gtk_box_pack_start ( GTK_BOX(vlp), hbox, FALSE, FALSE, 0 );

  vlp->popup_factory = gtk_item_factory_new ( GTK_TYPE_MENU, "<main>", NULL );
  gtk_item_factory_create_items ( vlp->popup_factory, NUM_BASE_ENTRIES, base_entries, vlp );
  for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ )
  {
    /* TODO: FIXME: if name has a '/' in it it will get all messed up. why not have an itemfactory field with
                    name, icon, shortcut, etc.? */
    /* Note: we use a temporary label in order to share translation with other codde */
    gchar *label = g_strdup_printf(_("New %s Layer"), vik_layer_get_interface(i)->name );
    entry.path = g_strdup_printf("%s/%s", base_entries[NUM_BASE_ENTRIES-1].path, label );
    g_free ( label );
    entry.accelerator = NULL;
    entry.callback = (GtkItemFactoryCallback) vik_layers_panel_new_layer;
    entry.callback_action = i;
    if ( vik_layer_get_interface(i)->icon )
    {
      entry.item_type = "<ImageItem>";
      entry.extra_data = gdk_pixdata_serialize ( vik_layer_get_interface(i)->icon, &tmp );
    }
    else
      entry.item_type = "<Item>";

    gtk_item_factory_create_item ( vlp->popup_factory, &entry, vlp, 1 );
    g_free ( (gpointer) entry.extra_data );
    g_free ( entry.path );
  }
}
static gboolean datasource_osm_my_traces_process ( VikTrwLayer *vtl, const gchar *cmd, const gchar *extra, 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();

    DownloadMapOptions options = { FALSE, FALSE, NULL, 2, NULL, user_pass }; // Allow a couple of redirects

    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;

    gchar *tmpname = a_download_uri_to_tmp_file ( DS_OSM_TRACES_GPX_FILES, &options );
    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 ) {
        g_remove ( tmpname );
        g_free ( tmpname );
    }

    if ( ! result )
        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) );
        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 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, vik_window_viewport(adw->vw), NULL, 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") );
            vik_aggregate_layer_add_layer ( vik_layers_panel_get_top_layer (adw->vlp), VIK_LAYER(vtlX) );
        }

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

            result = a_babel_convert_from_url ( vtlX, url, "gpx", status_cb, adw, &options );
            // TODO investigate using a progress bar:
            // http://developer.gnome.org/gtk/2.24/GtkProgressBar.html

            got_something = got_something || result;
            // TODO feedback to UI to inform which traces failed
            if ( !result )
                g_warning ( _("Unable to get trace: %s"), url );
        }

        if ( result ) {
            // Move to area of the track
            vik_trw_layer_auto_set_view ( vtlX, vik_window_viewport(adw->vw) );
            vik_layer_post_read ( VIK_LAYER(vtlX), vik_window_viewport(adw->vw), TRUE );
            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;

    return result;
}
Beispiel #7
0
void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, VikViewport *vvp )
{
  VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
  VikLayerFuncSetParam set_param = vik_layer_get_interface(vl->type)->set_param;
  gchar *s;
  guint8 *b = (guint8 *)data;
  
#define vlm_size (*(gint *)b)
#define vlm_read(obj)				\
  memcpy((obj), b+sizeof(gint), vlm_size);	\
  b += sizeof(gint) + vlm_size;
  
  s = g_malloc(vlm_size + 1);
  s[vlm_size]=0;
  vlm_read(s);
  
  vik_layer_rename(vl, s);
  
  g_free(s);

  if ( params && set_param )
  {
    VikLayerParamData d;
    guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
    for ( i = 0; i < params_count; i++ )
    {
      g_debug("%s: %s", __FUNCTION__, params[i].name);
      switch ( params[i].type )
      {
      case VIK_LAYER_PARAM_STRING: 
	s = g_malloc(vlm_size + 1);
	s[vlm_size]=0;
	vlm_read(s);
	d.s = s;
	set_param(vl, i, d, vvp, FALSE);
	g_free(s);
	break;
      case VIK_LAYER_PARAM_STRING_LIST:  {
        gint listlen = vlm_size, j;
        GList *list = NULL;
        b += sizeof(gint); /* skip listlen */;

        for ( j = 0; j < listlen; j++ ) {
          /* get a string */
          s = g_malloc(vlm_size + 1);
	  s[vlm_size]=0;
	  vlm_read(s);
          list = g_list_append ( list, s );
        }
        d.sl = list;
        set_param(vl, i, d, vvp, FALSE);
        /* don't free -- string list is responsibility of the layer */

        break;
        }
      default:
	vlm_read(&d);
	set_param(vl, i, d, vvp, FALSE);
	break;
      }
    }
  }
}
Beispiel #8
0
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;
}
Beispiel #9
0
/**
 * Read in a Viking file and return how successful the parsing was
 * ATM this will always work, in that even if there are parsing problems
 *  then there will be no new values to override the defaults
 *
 * TODO flow up line number(s) / error messages of problems encountered...
 *
 */
static gboolean file_read ( VikAggregateLayer *top, FILE *f, const gchar *dirpath, VikViewport *vp )
{
  Stack *stack;
  struct LatLon ll = { 0.0, 0.0 };
  gchar buffer[4096];
  gchar *line;
  guint16 len;
  long line_num = 0;

  VikLayerParam *params = NULL; /* for current layer, so we don't have to keep on looking up interface */
  guint8 params_count = 0;

  GHashTable *string_lists = g_hash_table_new(g_direct_hash,g_direct_equal);

  gboolean successful_read = TRUE;

  push(&stack);
  stack->under = NULL;
  stack->data = (gpointer) top;

  while ( fgets ( buffer, 4096, f ) )
  {
    line_num++;

    line = buffer;
    while ( *line == ' ' || *line =='\t' )
      line++;

    if ( line[0] == '#' )
      continue;
    

    len = strlen(line);
    if ( len > 0 && line[len-1] == '\n' )
      line[--len] = '\0';
    if ( len > 0 && line[len-1] == '\r' )
      line[--len] = '\0';

    if ( len == 0 )
      continue;


    if ( line[0] == '~' )
    {
      line++; len--;
      if ( *line == '\0' )
        continue;
      else if ( str_starts_with ( line, "Layer ", 6, TRUE ) )
      {
        int parent_type = VIK_LAYER(stack->data)->type;
        if ( ( ! stack->data ) || ((parent_type != VIK_LAYER_AGGREGATE) && (parent_type != VIK_LAYER_GPS)) )
        {
          successful_read = FALSE;
          g_warning ( "Line %ld: Layer command inside non-Aggregate Layer (type %d)", line_num, parent_type );
          push(&stack); /* inside INVALID layer */
          stack->data = NULL;
          continue;
        }
        else
        {
          VikLayerTypeEnum type = vik_layer_type_from_string ( line+6 );
          push(&stack);
          if ( type == VIK_LAYER_NUM_TYPES )
          {
            successful_read = FALSE;
            g_warning ( "Line %ld: Unknown type %s", line_num, line+6 );
            stack->data = NULL;
          }
          else if (parent_type == VIK_LAYER_GPS)
          {
            stack->data = (gpointer) vik_gps_layer_get_a_child(VIK_GPS_LAYER(stack->under->data));
            params = vik_layer_get_interface(type)->params;
            params_count = vik_layer_get_interface(type)->params_count;
          }
          else
          {
            stack->data = (gpointer) vik_layer_create ( type, vp, FALSE );
            params = vik_layer_get_interface(type)->params;
            params_count = vik_layer_get_interface(type)->params_count;
          }
        }
      }
      else if ( str_starts_with ( line, "EndLayer", 8, FALSE ) )
      {
        if ( stack->under == NULL ) {
          successful_read = FALSE;
          g_warning ( "Line %ld: Mismatched ~EndLayer command", line_num );
        }
        else
        {
          /* add any string lists we've accumulated */
          gpointer layer_and_vp[2];
          layer_and_vp[0] = stack->data;
          layer_and_vp[1] = vp;
          g_hash_table_foreach ( string_lists, (GHFunc) string_list_set_param, layer_and_vp );
          g_hash_table_remove_all ( string_lists );

          if ( stack->data && stack->under->data )
          {
            if (VIK_LAYER(stack->under->data)->type == VIK_LAYER_AGGREGATE) {
              vik_aggregate_layer_add_layer ( VIK_AGGREGATE_LAYER(stack->under->data), VIK_LAYER(stack->data), FALSE );
              vik_layer_post_read ( VIK_LAYER(stack->data), vp, TRUE );
            }
            else if (VIK_LAYER(stack->under->data)->type == VIK_LAYER_GPS) {
              /* TODO: anything else needs to be done here ? */
            }
            else {
              successful_read = FALSE;
              g_warning ( "Line %ld: EndLayer command inside non-Aggregate Layer (type %d)", line_num, VIK_LAYER(stack->data)->type );
            }
          }
          pop(&stack);
        }
      }
      else if ( str_starts_with ( line, "LayerData", 9, FALSE ) )
      {
        if ( stack->data && vik_layer_get_interface(VIK_LAYER(stack->data)->type)->read_file_data )
        {
          /* must read until hits ~EndLayerData */
          if ( ! vik_layer_get_interface(VIK_LAYER(stack->data)->type)->read_file_data ( VIK_LAYER(stack->data), f, dirpath ) )
            successful_read = FALSE;
        }
        else
        { /* simply skip layer data over */
          while ( fgets ( buffer, 4096, f ) )
          {
            line_num++;

            line = buffer;

            len = strlen(line);
            if ( len > 0 && line[len-1] == '\n' )
              line[--len] = '\0';
            if ( len > 0 && line[len-1] == '\r' )
              line[--len] = '\0';
            if ( strcasecmp ( line, "~EndLayerData" ) == 0 )
              break;
          }
          continue;
        }
      }
      else
      {
        successful_read = FALSE;
        g_warning ( "Line %ld: Unknown tilde command", line_num );
      }
    }
    else
    {
      gint32 eq_pos = -1;
      guint16 i;
      if ( ! stack->data )
        continue;

      for ( i = 0; i < len; i++ )
        if ( line[i] == '=' )
          eq_pos = i;

      if ( stack->under == NULL && eq_pos == 12 && strncasecmp ( line, "FILE_VERSION", eq_pos ) == 0) {
        gint version = strtol(line+13, NULL, 10);
        g_debug ( "%s: reading file version %d", __FUNCTION__, version );
        if ( version > VIKING_FILE_VERSION )
          successful_read = FALSE;
        // However we'll still carry and attempt to read whatever we can
      }
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "xmpp", eq_pos ) == 0) /* "hard coded" params: global & for all layer-types */
        vik_viewport_set_xmpp ( VIK_VIEWPORT(vp), strtod ( line+5, NULL ) );
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "ympp", eq_pos ) == 0)
        vik_viewport_set_ympp ( VIK_VIEWPORT(vp), strtod ( line+5, NULL ) );
      else if ( stack->under == NULL && eq_pos == 3 && strncasecmp ( line, "lat", eq_pos ) == 0 )
        ll.lat = strtod ( line+4, NULL );
      else if ( stack->under == NULL && eq_pos == 3 && strncasecmp ( line, "lon", eq_pos ) == 0 )
        ll.lon = strtod ( line+4, NULL );
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "utm" ) == 0)
        vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_UTM);
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "expedia" ) == 0)
        vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_EXPEDIA );
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "google" ) == 0)
      {
        successful_read = FALSE;
        g_warning ( _("Draw mode '%s' no more supported"), "google" );
      }
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "kh" ) == 0)
      {
        successful_read = FALSE;
        g_warning ( _("Draw mode '%s' no more supported"), "kh" );
      }
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "mercator" ) == 0)
        vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_MERCATOR );
      else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "latlon" ) == 0)
        vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_LATLON );
      else if ( stack->under == NULL && eq_pos == 5 && strncasecmp ( line, "color", eq_pos ) == 0 )
        vik_viewport_set_background_color ( VIK_VIEWPORT(vp), line+6 );
      else if ( stack->under == NULL && eq_pos == 14 && strncasecmp ( line, "highlightcolor", eq_pos ) == 0 )
        vik_viewport_set_highlight_color ( VIK_VIEWPORT(vp), line+15 );
      else if ( stack->under == NULL && eq_pos == 9 && strncasecmp ( line, "drawscale", eq_pos ) == 0 )
        vik_viewport_set_draw_scale ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+10) );
      else if ( stack->under == NULL && eq_pos == 14 && strncasecmp ( line, "drawcentermark", eq_pos ) == 0 )
        vik_viewport_set_draw_centermark ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+15) );
      else if ( stack->under == NULL && eq_pos == 13 && strncasecmp ( line, "drawhighlight", eq_pos ) == 0 )
        vik_viewport_set_draw_highlight ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+14) );
      else if ( stack->under && eq_pos == 4 && strncasecmp ( line, "name", eq_pos ) == 0 )
        vik_layer_rename ( VIK_LAYER(stack->data), line+5 );
      else if ( eq_pos == 7 && strncasecmp ( line, "visible", eq_pos ) == 0 )
        VIK_LAYER(stack->data)->visible = TEST_BOOLEAN(line+8);
      else if ( eq_pos != -1 && stack->under )
      {
        gboolean found_match = FALSE;

        /* go thru layer params. if len == eq_pos && starts_with jazz, set it. */
        /* also got to check for name and visible. */

        if ( ! params )
        {
          successful_read = FALSE;
          g_warning ( "Line %ld: No options for this kind of layer", line_num );
          continue;
        }

        for ( i = 0; i < params_count; i++ )
          if ( strlen(params[i].name) == eq_pos && strncasecmp ( line, params[i].name, eq_pos ) == 0 )
          {
            VikLayerParamData x;
            line += eq_pos+1;
            if ( params[i].type == VIK_LAYER_PARAM_STRING_LIST ) {
              GList *l = g_list_append ( g_hash_table_lookup ( string_lists, GINT_TO_POINTER ((gint) i) ), 
					 g_strdup(line) );
              g_hash_table_replace ( string_lists, GINT_TO_POINTER ((gint)i), l );
              /* add the value to a list, possibly making a new list.
               * this will be passed to the layer when we read an ~EndLayer */
            } else {
              switch ( params[i].type )
              {
                case VIK_LAYER_PARAM_DOUBLE: x.d = strtod(line, NULL); break;
                case VIK_LAYER_PARAM_UINT: x.u = strtoul(line, NULL, 10); break;
                case VIK_LAYER_PARAM_INT: x.i = strtol(line, NULL, 10); break;
	        case VIK_LAYER_PARAM_BOOLEAN: x.b = TEST_BOOLEAN(line); break;
                case VIK_LAYER_PARAM_COLOR: memset(&(x.c), 0, sizeof(x.c)); /* default: black */
                                          gdk_color_parse ( line, &(x.c) ); break;
                /* STRING or STRING_LIST -- if STRING_LIST, just set param to add a STRING */
                default: x.s = line;
              }
              vik_layer_set_param ( VIK_LAYER(stack->data), i, x, vp, TRUE );
            }
            found_match = TRUE;
            break;
          }
        if ( ! found_match ) {
          // ATM don't flow up this issue because at least one internal parameter has changed from version 1.3
          //   and don't what to worry users about raising such issues
          // TODO Maybe hold old values here - compare the line value against them and if a match
          //       generate a different style of message in the GUI...
          // successful_read = FALSE;
          g_warning ( "Line %ld: Unknown parameter. Line:\n%s", line_num, line );
	}
      }
      else {
        successful_read = FALSE;
        g_warning ( "Line %ld: Invalid parameter or parameter outside of layer.", line_num );
      }
    }
/* could be:
[Layer Type=Bla]
[EndLayer]
[LayerData]
name=this
#comment
*/
  }

  while ( stack )
  {
    if ( stack->under && stack->under->data && stack->data )
    {
      vik_aggregate_layer_add_layer ( VIK_AGGREGATE_LAYER(stack->under->data), VIK_LAYER(stack->data), FALSE );
      vik_layer_post_read ( VIK_LAYER(stack->data), vp, TRUE );
    }
    pop(&stack);
  }

  if ( ll.lat != 0.0 || ll.lon != 0.0 )
    vik_viewport_set_center_latlon ( VIK_VIEWPORT(vp), &ll, TRUE );

  if ( ( ! VIK_LAYER(top)->visible ) && VIK_LAYER(top)->realized )
    vik_treeview_item_set_visible ( VIK_LAYER(top)->vt, &(VIK_LAYER(top)->iter), FALSE ); 

  /* delete anything we've forgotten about -- should only happen when file ends before an EndLayer */
  g_hash_table_foreach ( string_lists, string_list_delete, NULL );
  g_hash_table_destroy ( string_lists );

  return successful_read;
}
Beispiel #10
0
static void gpx_end(VikTrwLayer *vtl, const char *el)
{
  static GTimeVal tp_time;
  static GTimeVal wp_time;

  g_string_truncate ( xpath, xpath->len - strlen(el) - 1 );

  switch ( current_tag ) {

     case tt_gpx:
       vik_trw_layer_set_metadata ( vtl, c_md );
       c_md = NULL;
       break;

     case tt_gpx_name:
       vik_layer_rename ( VIK_LAYER(vtl), c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_gpx_author:
       if ( c_md->author )
         g_free ( c_md->description );
       c_md->author = g_strdup ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_gpx_desc:
       if ( c_md->description )
         g_free ( c_md->description );
       c_md->description = g_strdup ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_gpx_keywords:
       if ( c_md->keywords )
         g_free ( c_md->keywords );
       c_md->keywords = g_strdup ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_gpx_time:
       if ( c_md->timestamp )
         g_free ( c_md->timestamp );
       c_md->timestamp = g_strdup ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_waypoint:
     case tt_wpt:
       if ( ! c_wp_name )
         c_wp_name = g_strdup_printf("VIKING_WP%04d", unnamed_waypoints++);
       vik_trw_layer_filein_add_waypoint ( vtl, c_wp_name, c_wp );
       g_free ( c_wp_name );
       c_wp = NULL;
       c_wp_name = NULL;
       break;

     case tt_trk:
       if ( ! c_tr_name )
         c_tr_name = g_strdup_printf("VIKING_TR%03d", unnamed_tracks++);
       // Delibrate fall through
     case tt_rte:
       if ( ! c_tr_name )
         c_tr_name = g_strdup_printf("VIKING_RT%03d", unnamed_routes++);
       vik_trw_layer_filein_add_track ( vtl, c_tr_name, c_tr );
       g_free ( c_tr_name );
       c_tr = NULL;
       c_tr_name = NULL;
       break;

     case tt_wpt_name:
       if ( c_wp_name )
         g_free ( c_wp_name );
       c_wp_name = g_strdup ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_name:
       if ( c_tr_name )
         g_free ( c_tr_name );
       c_tr_name = g_strdup ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_wpt_ele:
       c_wp->altitude = g_ascii_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_ele:
       c_tp->altitude = g_ascii_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_waypoint_name: /* .loc name is really description. */
     case tt_wpt_desc:
       vik_waypoint_set_description ( c_wp, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_wpt_cmt:
       vik_waypoint_set_comment ( c_wp, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_wpt_url:
       vik_waypoint_set_url ( c_wp, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_wpt_link:
       vik_waypoint_set_image ( c_wp, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_wpt_sym: {
       vik_waypoint_set_symbol ( c_wp, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;
       }

     case tt_trk_desc:
       vik_track_set_description ( c_tr, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_cmt:
       vik_track_set_comment ( c_tr, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_wpt_time:
       if ( g_time_val_from_iso8601(c_cdata->str, &wp_time) ) {
         c_wp->timestamp = wp_time.tv_sec;
         c_wp->has_timestamp = TRUE;
       }
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_name:
       vik_trackpoint_set_name ( c_tp, c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_time:
       if ( g_time_val_from_iso8601(c_cdata->str, &tp_time) ) {
         c_tp->timestamp = tp_time.tv_sec;
         c_tp->has_timestamp = TRUE;
       }
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_course:
       c_tp->course = g_ascii_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_speed:
       c_tp->speed = g_ascii_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_fix:
       if (!strcmp("2d", c_cdata->str))
         c_tp->fix_mode = VIK_GPS_MODE_2D;
       else if (!strcmp("3d", c_cdata->str))
         c_tp->fix_mode = VIK_GPS_MODE_3D;
       else  /* TODO: more fix modes here */
         c_tp->fix_mode = VIK_GPS_MODE_NOT_SEEN;
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_sat:
       c_tp->nsats = atoi ( c_cdata->str );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_hdop:
       c_tp->hdop = g_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_vdop:
       c_tp->vdop = g_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     case tt_trk_trkseg_trkpt_pdop:
       c_tp->pdop = g_strtod ( c_cdata->str, NULL );
       g_string_erase ( c_cdata, 0, -1 );
       break;

     default: break;
  }

  current_tag = get_tag ( xpath->str );
}
Beispiel #11
0
VikAggregateLayer *vik_aggregate_layer_create (VikViewport *vp)
{
  VikAggregateLayer *rv = vik_aggregate_layer_new ();
  vik_layer_rename ( VIK_LAYER(rv), vik_aggregate_layer_interface.name );
  return rv;
}
Beispiel #12
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 );
}
Beispiel #13
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 );
}
Beispiel #14
0
/* returns TRUE if OK was pressed. */
static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w )
{
  GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
                                                  w,
                                                  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_STOCK_CANCEL,
                                                  GTK_RESPONSE_REJECT,
                                                  GTK_STOCK_OK,
                                                  GTK_RESPONSE_ACCEPT,
                                                  NULL );
  /* Default to reject as user really needs to specify map file first */
  gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
  GtkWidget *response_w = NULL;
#if GTK_CHECK_VERSION (2, 20, 0)
  response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
#endif
  GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *ce_spin, *cn_label, *cn_spin, *xlabel, *xspin, *ylabel, *yspin, *imagelabel, *imageentry;

  GtkWidget *pass_along[4];

  table = gtk_table_new ( 6, 2, FALSE );
  gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0 );

  wfp_hbox = gtk_hbox_new ( FALSE, 0 );
  wfp_label = gtk_label_new ( _("World File Parameters:") );
  wfp_button = gtk_button_new_with_label ( _("Load From File...") );

  gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
  gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );

  ce_label = gtk_label_new ( _("Corner pixel easting:") );
  ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(ce_spin), _("the UTM \"easting\" value of the upper-left corner pixel of the map") );

  cn_label = gtk_label_new ( _("Corner pixel northing:") );
  cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(cn_spin), _("the UTM \"northing\" value of the upper-left corner pixel of the map") );

  xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
  ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));

  xspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(xspin), _("the scale of the map in the X direction (meters per pixel)") );
  yspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(yspin), _("the scale of the map in the Y direction (meters per pixel)") );

  imagelabel = gtk_label_new ( _("Map Image:") );
  imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN);

  if (*vgl)
  {
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), (*vgl)->corner.easting );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), (*vgl)->corner.northing );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), (*vgl)->mpp_easting );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), (*vgl)->mpp_northing );
    if ( (*vgl)->image )
    vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry), (*vgl)->image );
  }
  else
  {
    VikCoord corner_coord;
    struct UTM utm;
    vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp), 0, 0, &corner_coord );
    vik_coord_to_utm ( &corner_coord, &utm );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), utm.easting );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), utm.northing );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ) );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ) );
  }

  gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
  gtk_table_attach_defaults ( GTK_TABLE(table), imageentry, 1, 2, 0, 1 );
  gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
  gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
  gtk_table_attach_defaults ( GTK_TABLE(table), xspin, 1, 2, 2, 3 );
  gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
  gtk_table_attach_defaults ( GTK_TABLE(table), yspin, 1, 2, 3, 4 );
  gtk_table_attach_defaults ( GTK_TABLE(table), ce_label, 0, 1, 4, 5 );
  gtk_table_attach_defaults ( GTK_TABLE(table), ce_spin, 1, 2, 4, 5 );
  gtk_table_attach_defaults ( GTK_TABLE(table), cn_label, 0, 1, 5, 6 );
  gtk_table_attach_defaults ( GTK_TABLE(table), cn_spin, 1, 2, 5, 6 );

  pass_along[0] = xspin;
  pass_along[1] = yspin;
  pass_along[2] = ce_spin;
  pass_along[3] = cn_spin;
  g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), pass_along );

  if ( response_w )
    gtk_widget_grab_focus ( response_w );

  gtk_widget_show_all ( table );

  if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
  {
    if (! *vgl)
    {
      *vgl = georef_layer_new ( VIK_VIEWPORT(vp) );
       vik_layer_rename ( VIK_LAYER(*vgl), vik_georef_layer_interface.name );
    }
    (*vgl)->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin) );
    (*vgl)->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin) );
    (*vgl)->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin) );
    (*vgl)->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin) );
    if ( (!(*vgl)->image) || strcmp( (*vgl)->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) ) != 0 )
    {
      georef_layer_set_image ( *vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) );
      georef_layer_load_image ( *vgl, VIK_VIEWPORT(vp), FALSE );
    }

    gtk_widget_destroy ( GTK_WIDGET(dialog) );
    return TRUE;
  }
  gtk_widget_destroy ( GTK_WIDGET(dialog) );
  return FALSE;
}