Logo Search packages:      
Sourcecode: viking version File versions  Download package

acquire.c

/*
 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
 *
 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#include <string.h>
#include <glib/gprintf.h>

#include "viking.h"
#include "babel.h"
#include "gpx.h"
#include "acquire.h"

/* passed along to worker thread */
typedef struct {
  acq_dialog_widgets_t *w;
  gchar *cmd;
  gchar *extra;
} w_and_interface_t;

extern VikDataSourceInterface vik_datasource_gps_interface;
extern VikDataSourceInterface vik_datasource_google_interface;

/*********************************************************
 * Definitions and routines for acquiring data from Data Sources in general
 *********************************************************/

static void progress_func ( BabelProgressCode c, gpointer data, acq_dialog_widgets_t *w )
{
  gdk_threads_enter ();
  if (!w->ok) {
    if ( w->interface->cleanup_func )
      w->interface->cleanup_func( w->user_data );
    g_free ( w );
    gdk_threads_leave();
    g_thread_exit ( NULL );
  }
  gdk_threads_leave ();

  if ( w->interface->progress_func )
    w->interface->progress_func ( (gpointer) c, data, w );
}

/* 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;
  VikTrwLayer *vtl;

  gboolean creating_new_layer = TRUE;

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

  gdk_threads_enter();
  if (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 ), interface->layer_title );
    gtk_label_set_text ( GTK_LABEL(w->status), "Working..." );
  }
  gdk_threads_leave();

  if ( interface->type == VIK_DATASOURCE_GPSBABEL_DIRECT )
    result = a_babel_convert_from (vtl, cmd, (BabelStatusFunc) progress_func, extra, w);
  else
    result = a_babel_convert_from_shellcommand ( vtl, cmd, extra, (BabelStatusFunc) progress_func, w);

  g_free ( cmd );
  g_free ( extra );

  if (!result) {
    gdk_threads_enter();
    gtk_label_set_text ( GTK_LABEL(w->status), "Error: couldn't find gpsbabel." );
    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 )
      vik_aggregate_layer_add_layer( vik_layers_panel_get_top_layer(w->vlp), VIK_LAYER(vtl));
      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 {
      /* canceled */
      if ( creating_new_layer )
      g_object_unref(vtl);
    }
  }
  if ( interface->cleanup_func )
    interface->cleanup_func ( w->user_data );

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

  gdk_threads_leave();
  g_thread_exit ( NULL );
}


void a_acquire ( VikWindow *vw, VikLayersPanel *vlp, VikViewport *vvp, VikDataSourceInterface *interface )
{
  GtkWidget *dialog = NULL;
  GtkWidget *status;
  gchar *cmd, *extra;
  acq_dialog_widgets_t *w;
  gpointer user_data;

  w_and_interface_t *wi;

  g_assert(interface->init_func);
  user_data = interface->init_func();
  
  if ( interface->check_existence_func ) {
    gchar *error_str = interface->check_existence_func();
    if ( error_str ) {
      a_dialog_error_msg ( GTK_WINDOW(vw), error_str );
      g_free ( error_str );
      return;
    }
  }    

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

    interface->add_setup_widgets_func(dialog, vvp, user_data);
    gtk_window_set_title ( GTK_WINDOW(dialog), interface->window_title );

    if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_ACCEPT ) {
      interface->cleanup_func(user_data);
      gtk_widget_destroy(dialog);
      return;
    }
    interface->get_cmd_string_func ( user_data, &cmd, &extra );
    gtk_widget_destroy(dialog);
    dialog = NULL;
  } else
    interface->get_cmd_string_func ( user_data, &cmd, &extra );

  if ( ! cmd )
    return;

  w = g_malloc(sizeof(*w));
  wi = g_malloc(sizeof(*wi));
  wi->w = w;
  wi->w->interface = interface;
  wi->cmd = cmd;
  wi->extra = extra;

  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), 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_widget_show_all(status);
  w->status = status;

  w->vw = vw;
  w->vlp = vlp;
  w->vvp = vvp;
  if ( interface->add_progress_widgets_func ) {
    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 {
    g_free ( w ); /* thread has finished; free w */
  }
  gtk_widget_destroy ( dialog );
}


Generated by  Doxygen 1.6.0   Back to index