]> git.street.me.uk Git - andy/viking.git/commitdiff
SF Feature#49: Export via GPSBabel
authorGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Mon, 4 Nov 2013 22:31:23 +0000 (23:31 +0100)
committerGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Mon, 4 Nov 2013 22:31:23 +0000 (23:31 +0100)
Allow to export data in all formats supported by gpsbabel.

Signed-off-by: Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
help/C/viking.xml
src/babel.c
src/file.c
src/file.h
src/viktrwlayer.c
src/viktrwlayer_export.c
src/viktrwlayer_export.h

index 0c314fc96285421eb73b63ebb52a520207021fa3..be4b5542dfb0ea0cbb98f979a105fd6f16df9fb0 100644 (file)
@@ -754,7 +754,7 @@ You are probably better off expanding the waypoint list and directly start typin
 
 <section><title>Export Layer</title>
 <para>
-The layer (all tracks, routes and waypoints) can be exported to a file GPX, GPSPoint, GPSMapper or Google's KML format.
+The layer (all tracks, routes and waypoints) can be exported to a file GPX, GPSPoint, GPSMapper, Google's KML format or any other format supported by GPSbabel.
 </para>
 <para>
 Version1.1+: An individual track can be exported to a GPX file via the track menu.
index c9622926bc7323736f1179ca0dbf0d6da361378d..93ad52e32cbf00f7d0c73634a1bf66c6ca5ba898 100644 (file)
@@ -555,11 +555,11 @@ static void load_feature_parse_line (gchar *line)
         file->label = g_strdup (tokens[4]);
         a_babel_file_list = g_list_append (a_babel_file_list, file);
         g_debug ("New gpsbabel file: %s, %d%d%d%d%d%d(%s)",
-                               file->name,
-                               file->mode.waypointsRead, file->mode.waypointsWrite,
-                               file->mode.tracksRead, file->mode.tracksWrite,
-                               file->mode.routesRead, file->mode.routesWrite,
-                               tokens[1]);
+                       file->name,
+                       file->mode.waypointsRead, file->mode.waypointsWrite,
+                       file->mode.tracksRead, file->mode.tracksWrite,
+                       file->mode.routesRead, file->mode.routesWrite,
+                       tokens[1]);
       } else {
         g_warning ( "Unexpected gpsbabel format string: %s", line);
       }
index ce935d870d0eea220eb35920b8c1009c326b4bf0..ec9e4f33ec361d2dabcc86bc3b7e1efb97de90f7 100644 (file)
@@ -866,6 +866,22 @@ gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, VikFileType_t
   return FALSE;
 }
 
+/**
+ * a_file_export_babel:
+ */
+gboolean a_file_export_babel ( VikTrwLayer *vtl, const gchar *filename, const gchar *format,
+                               gboolean tracks, gboolean routes, gboolean waypoints )
+{
+  gchar *args = g_strdup_printf("%s %s %s -o %s",
+                                tracks ? "-t" : "",
+                                routes ? "-r" : "",
+                                waypoints ? "-w" : "",
+                                format);
+  gboolean result = a_babel_convert_to ( vtl, NULL, args, filename, NULL, NULL );
+  g_free(args);
+  return result;
+}
+
 /**
  * Just a wrapper around realpath, which itself is platform dependent
  */
index 5370f688460309f77e3d784bc3720d510ef8a279..48a05c6546d03ff586fb6217bac5c327455c301c 100644 (file)
@@ -62,6 +62,8 @@ VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar
 gboolean a_file_save ( VikAggregateLayer *top, gpointer vp, const gchar *filename );
 /* Only need to define VikTrack if the file type is FILE_TYPE_GPX_TRACK */
 gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, VikFileType_t file_type, VikTrack *trk, gboolean write_hidden );
+gboolean a_file_export_babel ( VikTrwLayer *vtl, const gchar *filename, const gchar *format,
+    gboolean tracks, gboolean routes, gboolean waypoints );
 
 void file_write_layer_param ( FILE *f, const gchar *name, VikLayerParamType type, VikLayerParamData data );
 
index c085e720220c78829d36856d07ec550f495c4f44..7c9d81a300809511bada5791d7341e987a5ac7dd 100644 (file)
@@ -3281,6 +3281,11 @@ static void trw_layer_export_kml ( menu_array_layer values )
   g_free ( auto_save_name );
 }
 
+static void trw_layer_export_babel ( gpointer layer_and_vlp[2] )
+{
+  gchar *auto_save_name = vik_layer_get_name(VIK_LAYER(layer_and_vlp[0]));
+  vik_trw_layer_export_gpsbabel ( VIK_TRW_LAYER (layer_and_vlp[0]), _("Export Layer"), auto_save_name );
+}
 
 static void trw_layer_export_external_gpx_1 ( menu_array_layer values )
 {
@@ -3936,6 +3941,11 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
+  item = gtk_menu_item_new_with_mnemonic ( _("Export via GPSbabel...") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_babel), pass_along );
+  gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
+  gtk_widget_show ( item );
+
   gchar* external1 = g_strdup_printf ( _("Open with External Program_1: %s"), a_vik_get_external_gpx_program_1() );
   item = gtk_menu_item_new_with_mnemonic ( external1 );
   g_free ( external1 );
index 0dd5e9bb291268020c412b1e1e2d8663a3e23fdd..d89f833be939d015453aa403d189394e6081c13f 100644 (file)
@@ -28,6 +28,7 @@
 #include <glib/gi18n.h>
 
 #include "babel.h"
+#include "babel_ui.h"
 #include "viking.h"
 #include "viktrwlayer_export.h"
 
@@ -105,3 +106,91 @@ void vik_trw_layer_export_external_gpx ( VikTrwLayer *vtl, const gchar* external
   }
 }
 
+
+void vik_trw_layer_export_gpsbabel ( VikTrwLayer *vtl, const gchar *title, const gchar* default_name )
+{
+  BabelMode mode = { 0, 0, 0, 0, 0, 0 };
+  if ( g_hash_table_size (vik_trw_layer_get_routes(vtl)) ) {
+      mode.routesWrite = 1;
+  }
+  if ( g_hash_table_size (vik_trw_layer_get_tracks(vtl)) ) {
+      mode.tracksWrite = 1;
+  }
+  if ( g_hash_table_size (vik_trw_layer_get_waypoints(vtl)) ) {
+      mode.waypointsWrite = 1;
+  }
+
+  GtkWidget *file_selector;
+  const gchar *fn;
+  gboolean failed = FALSE;
+  file_selector = gtk_file_chooser_dialog_new (title,
+                                               NULL,
+                                               GTK_FILE_CHOOSER_ACTION_SAVE,
+                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+                                               NULL);
+  gchar *cwd = g_get_current_dir();
+  if ( cwd ) {
+    gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER(file_selector), cwd );
+    g_free ( cwd );
+  }
+
+  /* Build the extra part of the widget */
+  GtkWidget *babel_selector = a_babel_ui_file_type_selector_new ( mode );
+  GtkWidget *label = gtk_label_new(_("File format:"));
+  GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
+  gtk_box_pack_start ( GTK_BOX(hbox), label, TRUE, TRUE, 0 );
+  gtk_box_pack_start ( GTK_BOX(hbox), babel_selector, TRUE, TRUE, 0 );
+  gtk_widget_show (babel_selector);
+  gtk_widget_show (label);
+  gtk_widget_show_all (hbox);
+
+  gtk_widget_set_tooltip_text( babel_selector, _("Select the file format.") );
+
+  GtkWidget *babel_modes = a_babel_ui_modes_new(mode.tracksWrite, mode.routesWrite, mode.waypointsWrite);
+  gtk_widget_show (babel_modes);
+
+  gtk_widget_set_tooltip_text( babel_modes, _("Select the information to process.\n"
+      "Warning: the behavior of these switches is highly dependent of the file format selected.\n"
+      "Please, refer to GPSbabel if unsure.") );
+
+  GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
+  gtk_box_pack_start ( GTK_BOX(vbox), hbox, TRUE, TRUE, 0 );
+  gtk_box_pack_start ( GTK_BOX(vbox), babel_modes, TRUE, TRUE, 0 );
+  gtk_widget_show_all (vbox);
+
+  gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(file_selector), vbox);
+
+  /* Add some dynamic: only allow dialog's validation when format selection is done */
+  g_signal_connect (babel_selector, "changed", G_CALLBACK(a_babel_ui_type_selector_dialog_sensitivity_cb), file_selector);
+  /* Manually call the callback to fix the state */
+  a_babel_ui_type_selector_dialog_sensitivity_cb (babel_selector, file_selector);
+
+  /* Set possible name of the file */
+  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(file_selector), default_name);
+
+  while ( gtk_dialog_run ( GTK_DIALOG(file_selector) ) == GTK_RESPONSE_ACCEPT )
+  {
+    fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(file_selector) );
+    if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE ||
+         a_dialog_yes_or_no ( GTK_WINDOW(file_selector), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
+    {
+      BabelFile *active = a_babel_ui_file_type_selector_get(babel_selector);
+      if (active == NULL) {
+          a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("You did not select a valid file format.") );
+      } else {
+        gtk_widget_hide ( file_selector );
+        vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+        gboolean tracks, routes, waypoints;
+        a_babel_ui_modes_get( babel_modes, &tracks, &routes, &waypoints );
+        failed = ! a_file_export_babel ( vtl, fn, active->name, tracks, routes, waypoints );
+        vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+        break;
+      }
+    }
+  }
+  //babel_ui_selector_destroy(babel_selector);
+  gtk_widget_destroy ( file_selector );
+  if ( failed )
+    a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("The filename you requested could not be opened for writing.") );
+}
index 05cc2c75a07f2ce6a9c174825f76991200a20647..0d745b21fdc40143b1d521c8df03bcdea92b6427 100644 (file)
@@ -31,6 +31,8 @@ void vik_trw_layer_export ( VikTrwLayer *vtl, const gchar *title, const gchar* d
 
 void vik_trw_layer_export_external_gpx ( VikTrwLayer *vtl, const gchar* external_program );
 
+void vik_trw_layer_export_gpsbabel ( VikTrwLayer *vtl, const gchar *title, const gchar* default_name );
+
 G_END_DECLS
 
 #endif