From 313490094e04a31b987bb0e39df2db7a7e90e8a1 Mon Sep 17 00:00:00 2001 From: Guilhem Bonnefille Date: Sat, 1 Oct 2011 14:25:22 +0200 Subject: [PATCH] Allow to import any file known by gpsbabel A new menu entry allow to import a file as TRW layer. The file must be in a format known by gpsbabel. The user has to specify the format in the long list of file formats supported by gpsbabel. This patch naturally reuses the datasource/acquire set of features. Signed-off-by: Guilhem Bonnefille --- po/POTFILES.in | 1 + src/Makefile.am | 1 + src/datasource_file.c | 199 ++++++++++++++++++++++++++++++++++++++++++ src/datasources.h | 1 + src/menu.xml.h | 1 + src/vikwindow.c | 6 ++ 6 files changed, 209 insertions(+) create mode 100644 src/datasource_file.c diff --git a/po/POTFILES.in b/po/POTFILES.in index 1865700f..de12d13f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -9,6 +9,7 @@ src/geonamessearch.c src/globals.c src/google.c src/googlesearch.c +src/datasource_file.c src/datasource_gc.c src/datasource_google.c src/datasource_gps.c diff --git a/src/Makefile.am b/src/Makefile.am index b52f7447..79cc912d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,6 +102,7 @@ libviking_a_SOURCES = \ garminsymbols.c garminsymbols.h \ acquire.c acquire.h \ babel.c babel.h \ + datasource_file.c \ datasource_gps.c \ datasource_google.c \ datasource_gc.c \ diff --git a/src/datasource_file.c b/src/datasource_file.c new file mode 100644 index 00000000..a40f04a6 --- /dev/null +++ b/src/datasource_file.c @@ -0,0 +1,199 @@ +/* + * viking -- GPS Data and Topo Analyzer, Explorer, and Manager + * + * Copyright (C) 2011, Guilhem Bonnefille + * + * 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 + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include + +#include +#include + +#include + +#include "viking.h" +#include "babel.h" +#include "gpx.h" +#include "acquire.h" + +typedef struct { + GtkWidget *file; + GtkWidget *type; +} datasource_file_widgets_t; + +/* The last used directory */ +static gchar *last_folder_uri = NULL; + +/* The last used file filter */ +/* Nb: we use a complex strategy for this because the UI is rebuild each + time, so it is not possible to reuse directly the GtkFileFilter as they are + differents. */ +static BabelFile *last_file_filter = NULL; + +/* The last file format selected */ +static int last_type = 0; + +static gpointer datasource_file_init( ); +static void datasource_file_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ); +static void datasource_file_get_cmd_string ( datasource_file_widgets_t *widgets, gchar **cmd, gchar **input_file_type ); +static void datasource_file_cleanup ( gpointer data ); + +VikDataSourceInterface vik_datasource_file_interface = { + N_("Import file with GPSBabel"), + N_("Imported file"), + VIK_DATASOURCE_GPSBABEL_DIRECT, + VIK_DATASOURCE_ADDTOLAYER, + VIK_DATASOURCE_INPUTTYPE_NONE, + TRUE, + TRUE, + (VikDataSourceInitFunc) datasource_file_init, + (VikDataSourceCheckExistenceFunc) NULL, + (VikDataSourceAddSetupWidgetsFunc) datasource_file_add_setup_widgets, + (VikDataSourceGetCmdStringFunc) datasource_file_get_cmd_string, + (VikDataSourceProgressFunc) NULL, + (VikDataSourceAddProgressWidgetsFunc) NULL, + (VikDataSourceCleanupFunc) datasource_file_cleanup, + (VikDataSourceOffFunc) NULL, +}; + +/* See VikDataSourceInterface */ +static gpointer datasource_file_init ( ) +{ + datasource_file_widgets_t *widgets = g_malloc(sizeof(*widgets)); + return widgets; +} + +static void fill_combo_box (gpointer data, gpointer user_data) +{ + GtkComboBoxText *combo = GTK_COMBO_BOX_TEXT (user_data); + const gchar *label = ((BabelFile*) data)->label; +#if GTK_CHECK_VERSION (2,24,0) + gtk_combo_box_text_append_text (combo, label); +#else + gtk_combo_box_append_text (combo, label); +#endif +} + +static void add_file_filter (gpointer data, gpointer user_data) +{ + GtkFileChooser *chooser = GTK_FILE_CHOOSER ( user_data ); + const gchar *label = ((BabelFile*) data)->label; + const gchar *ext = ((BabelFile*) data)->ext; + if ( ext == NULL || ext[0] == '\0' ) + /* No file extension => no filter */ + return; + gchar *pattern = g_strdup_printf ( "*.%s", ext ); + + GtkFileFilter *filter = gtk_file_filter_new (); + gtk_file_filter_add_pattern ( filter, pattern ); + if ( strstr ( label, pattern+1 ) ) { + gtk_file_filter_set_name ( filter, label ); + } else { + /* Ensure displayed label contains file pattern */ + /* NB: we skip the '*' in the pattern */ + gchar *name = g_strdup_printf ( "%s (%s)", label, pattern+1 ); + gtk_file_filter_set_name ( filter, name ); + g_free ( name ); + } + g_object_set_data ( G_OBJECT(filter), "Babel", data ); + gtk_file_chooser_add_filter ( chooser, filter ); + if ( last_file_filter == data ) + /* Previous selection used this filter */ + gtk_file_chooser_set_filter ( chooser, filter ); + + g_free ( pattern ); +} + +/* See VikDataSourceInterface */ +static void datasource_file_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ) +{ + datasource_file_widgets_t *widgets = (datasource_file_widgets_t *)user_data; + GtkWidget *filename_label, *type_label; + + /* The file selector */ + filename_label = gtk_label_new (_("File:")); + widgets->file = gtk_file_chooser_button_new (_("File to import"), GTK_FILE_CHOOSER_ACTION_OPEN); + if (last_folder_uri) + gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(widgets->file), last_folder_uri); + /* Add filters */ + g_list_foreach ( a_babel_file_list, add_file_filter, widgets->file ); + GtkFileFilter *all_filter = gtk_file_filter_new (); + gtk_file_filter_add_pattern ( all_filter, "*" ); + gtk_file_filter_set_name ( all_filter, _("All files") ); + gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER(widgets->file), all_filter ); + if ( last_file_filter == NULL ) + /* No previously selected filter or 'All files' selected */ + gtk_file_chooser_set_filter ( GTK_FILE_CHOOSER(widgets->file), all_filter ); + + /* The file format selector */ + type_label = gtk_label_new (_("File type:")); +#if GTK_CHECK_VERSION (2,24,0) + widgets->type = gtk_combo_box_text_new (); +#else + widgets->type = gtk_combo_box_new_text (); +#endif + g_list_foreach (a_babel_file_list, fill_combo_box, widgets->type); + gtk_combo_box_set_active (GTK_COMBO_BOX (widgets->type), last_type); + + /* Packing all these widgets */ + gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), filename_label, FALSE, FALSE, 5 ); + gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), widgets->file, FALSE, FALSE, 5 ); + gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), type_label, FALSE, FALSE, 5 ); + gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), widgets->type, FALSE, FALSE, 5 ); + gtk_widget_show_all(dialog); +} + +/* See VikDataSourceInterface */ +static void datasource_file_get_cmd_string ( datasource_file_widgets_t *widgets, gchar **cmd, gchar **input_file ) +{ + gchar *filename, *type; + + /* Retrieve the file selected */ + filename = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(widgets->file) ); + + /* Memorize the directory for later use */ + g_free (last_folder_uri); + last_folder_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(widgets->file) ); + last_folder_uri = g_strdup (last_folder_uri); + + /* Memorize the file filter for later use */ + GtkFileFilter *filter = gtk_file_chooser_get_filter ( GTK_FILE_CHOOSER(widgets->file) ); + last_file_filter = g_object_get_data ( G_OBJECT(filter), "Babel" ); + + /* Retrieve and memorize file format selected */ + last_type = gtk_combo_box_get_active ( GTK_COMBO_BOX (widgets->type) ); + type = ((BabelFile*)g_list_nth_data (a_babel_file_list, last_type))->name; + + /* Build the string */ + *cmd = g_strdup_printf( "-i %s", type); + *input_file = g_strdup(filename); + + /* Free memory */ + g_free (filename); + + g_debug(_("using babel args '%s' and file '%s'"), *cmd, *input_file); +} + +/* See VikDataSourceInterface */ +static void datasource_file_cleanup ( gpointer data ) +{ + g_free ( data ); +} + diff --git a/src/datasources.h b/src/datasources.h index 15e469c5..48d896eb 100644 --- a/src/datasources.h +++ b/src/datasources.h @@ -24,6 +24,7 @@ #include "acquire.h" extern VikDataSourceInterface vik_datasource_gps_interface; +extern VikDataSourceInterface vik_datasource_file_interface; extern VikDataSourceInterface vik_datasource_google_interface; #ifdef VIK_CONFIG_OPENSTREETMAP extern VikDataSourceInterface vik_datasource_osm_interface; diff --git a/src/menu.xml.h b/src/menu.xml.h index 0e1fee56..ef1fef25 100644 --- a/src/menu.xml.h +++ b/src/menu.xml.h @@ -14,6 +14,7 @@ static const char *menu_xml = " " " " " " + " " " " #ifdef VIK_CONFIG_OPENSTREETMAP " " diff --git a/src/vikwindow.c b/src/vikwindow.c index d0ac467a..e42e2745 100644 --- a/src/vikwindow.c +++ b/src/vikwindow.c @@ -1937,6 +1937,11 @@ static void acquire_from_gps ( GtkAction *a, VikWindow *vw ) a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_gps_interface ); } +static void acquire_from_file ( GtkAction *a, VikWindow *vw ) +{ + a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_file_interface ); +} + static void acquire_from_google ( GtkAction *a, VikWindow *vw ) { a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_google_interface ); @@ -2518,6 +2523,7 @@ static GtkActionEntry entries[] = { { "Append", GTK_STOCK_ADD, N_("Append _File..."), NULL, N_("Append data from a different file"), (GCallback)load_file }, { "Acquire", NULL, N_("A_cquire"), 0, 0, 0 }, { "AcquireGPS", NULL, N_("From _GPS..."), NULL, N_("Transfer data from a GPS device"), (GCallback)acquire_from_gps }, + { "AcquireGPSBabel", NULL, N_("Import File With GPS_Babel..."), NULL, N_("Import file via GPSBabel converter"), (GCallback)acquire_from_file }, { "AcquireGoogle", NULL, N_("Google _Directions..."), NULL, N_("Get driving directions from Google"), (GCallback)acquire_from_google }, #ifdef VIK_CONFIG_OPENSTREETMAP { "AcquireOSM", NULL, N_("_OSM Traces..."), NULL, N_("Get traces from OpenStreetMap"), (GCallback)acquire_from_osm }, -- 2.39.5