+ g_slist_free (files);
+ }
+ }
+ gtk_widget_destroy ( dialog );
+}
+
+static gboolean save_file_as ( GtkAction *a, VikWindow *vw )
+{
+ gboolean rv = FALSE;
+ const gchar *fn;
+
+ GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Save as Viking File."),
+ GTK_WINDOW(vw),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ if ( last_folder_files_uri )
+ gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(dialog), last_folder_files_uri );
+
+ GtkFileFilter *filter;
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name( filter, _("All") );
+ gtk_file_filter_add_pattern ( filter, "*" );
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name( filter, _("Viking") );
+ gtk_file_filter_add_pattern ( filter, "*.vik" );
+ gtk_file_filter_add_pattern ( filter, "*.viking" );
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+ // Default to a Viking file
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter);
+
+ gtk_window_set_transient_for ( GTK_WINDOW(dialog), GTK_WINDOW(vw) );
+ gtk_window_set_destroy_with_parent ( GTK_WINDOW(dialog), TRUE );
+
+ // Auto append / replace extension with '.vik' to the suggested file name as it's going to be a Viking File
+ gchar* auto_save_name = g_strdup ( window_get_filename ( vw ) );
+ if ( ! a_file_check_ext ( auto_save_name, ".vik" ) )
+ auto_save_name = g_strconcat ( auto_save_name, ".vik", NULL );
+
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(dialog), auto_save_name);
+
+ while ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
+ {
+ fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog) );
+ if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE || a_dialog_yes_or_no ( GTK_WINDOW(dialog), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
+ {
+ window_set_filename ( vw, fn );
+ rv = window_save ( vw );
+ if ( rv ) {
+ vw->modified = FALSE;
+ g_free ( last_folder_files_uri );
+ last_folder_files_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(dialog) );
+ }
+ break;
+ }
+ }
+ g_free ( auto_save_name );
+ gtk_widget_destroy ( dialog );
+ return rv;
+}
+
+static gboolean window_save ( VikWindow *vw )
+{
+ vik_window_set_busy_cursor ( vw );
+ gboolean success = TRUE;
+
+ if ( a_file_save ( vik_layers_panel_get_top_layer ( vw->viking_vlp ), vw->viking_vvp, vw->filename ) )
+ {
+ update_recently_used_document ( vw, vw->filename );
+ }
+ else
+ {
+ a_dialog_error_msg ( GTK_WINDOW(vw), _("The filename you requested could not be opened for writing.") );
+ success = FALSE;
+ }
+ vik_window_clear_busy_cursor ( vw );
+ return success;
+}
+
+static gboolean save_file ( GtkAction *a, VikWindow *vw )
+{
+ if ( ! vw->filename )
+ return save_file_as ( NULL, vw );
+ else
+ {
+ vw->modified = FALSE;
+ return window_save ( vw );
+ }
+}
+
+/**
+ * export_to:
+ *
+ * Export all TRW Layers in the list to individual files in the specified directory
+ *
+ * Returns: %TRUE on success
+ */
+static gboolean export_to ( VikWindow *vw, GList *gl, VikFileType_t vft, const gchar *dir, const gchar *extension )
+{
+ gboolean success = TRUE;
+
+ gint export_count = 0;
+
+ vik_window_set_busy_cursor ( vw );
+
+ while ( gl ) {
+
+ gchar *fn = g_strconcat ( dir, G_DIR_SEPARATOR_S, VIK_LAYER(gl->data)->name, extension, NULL );
+
+ // Some protection in attempting to write too many same named files
+ // As this will get horribly slow...
+ gboolean safe = FALSE;
+ gint ii = 2;
+ while ( ii < 5000 ) {
+ if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) ) {
+ // Try rename
+ g_free ( fn );
+ fn = g_strdup_printf ( "%s%s%s#%03d%s", dir, G_DIR_SEPARATOR_S, VIK_LAYER(gl->data)->name, ii, extension );
+ }
+ else {
+ safe = TRUE;
+ break;
+ }
+ ii++;
+ }
+ if ( ii == 5000 )
+ success = FALSE;
+
+ // NB: We allow exporting empty layers
+ if ( safe ) {
+ gboolean this_success = a_file_export ( VIK_TRW_LAYER(gl->data), fn, vft, NULL, TRUE );
+
+ // Show some progress
+ if ( this_success ) {
+ export_count++;
+ gchar *message = g_strdup_printf ( _("Exporting to file: %s"), fn );
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, message );
+ while ( gtk_events_pending() )
+ gtk_main_iteration ();
+ g_free ( message );
+ }
+
+ success = success && this_success;
+ }
+
+ g_free ( fn );
+ gl = g_list_next ( gl );
+ }
+
+ vik_window_clear_busy_cursor ( vw );
+
+ // Confirm what happened.
+ gchar *message = g_strdup_printf ( _("Exported files: %d"), export_count );
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, message );
+ g_free ( message );
+
+ return success;
+}
+
+static void export_to_common ( VikWindow *vw, VikFileType_t vft, const gchar *extension )
+{
+ GList *gl = vik_layers_panel_get_all_layers_of_type ( vw->viking_vlp, VIK_LAYER_TRW, TRUE );
+
+ if ( !gl ) {
+ a_dialog_info_msg ( GTK_WINDOW(vw), _("Nothing to Export!") );
+ return;
+ }
+
+ GtkWidget *dialog = gtk_file_chooser_dialog_new ( _("Export to directory"),
+ GTK_WINDOW(vw),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_REJECT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_ACCEPT,
+ NULL );
+ gtk_window_set_transient_for ( GTK_WINDOW(dialog), GTK_WINDOW(vw) );
+ gtk_window_set_destroy_with_parent ( GTK_WINDOW(dialog), TRUE );
+ gtk_window_set_modal ( GTK_WINDOW(dialog), TRUE );
+
+ gtk_widget_show_all ( dialog );
+
+ if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) {
+ gchar *dir = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(dialog) );
+ gtk_widget_destroy ( dialog );
+ if ( dir ) {
+ if ( !export_to ( vw, gl, vft, dir, extension ) )
+ a_dialog_error_msg ( GTK_WINDOW(vw),_("Could not convert all files") );
+ g_free ( dir );
+ }
+ }
+ else
+ gtk_widget_destroy ( dialog );
+
+ g_list_free ( gl );
+}
+
+static void export_to_gpx ( GtkAction *a, VikWindow *vw )
+{
+ export_to_common ( vw, FILE_TYPE_GPX, ".gpx" );
+}
+
+static void export_to_kml ( GtkAction *a, VikWindow *vw )
+{
+ export_to_common ( vw, FILE_TYPE_KML, ".kml" );
+}
+
+#if !GLIB_CHECK_VERSION(2,26,0)
+typedef struct stat GStatBuf;
+#endif
+
+static void file_properties_cb ( GtkAction *a, VikWindow *vw )
+{
+ gchar *message = NULL;
+ if ( vw->filename ) {
+ if ( g_file_test ( vw->filename, G_FILE_TEST_EXISTS ) ) {
+ // Get some timestamp information of the file
+ GStatBuf stat_buf;
+ if ( g_stat ( vw->filename, &stat_buf ) == 0 ) {
+ gchar time_buf[64];
+ strftime ( time_buf, sizeof(time_buf), "%c", gmtime((const time_t *)&stat_buf.st_mtime) );
+ gchar *size = NULL;
+ gint byte_size = stat_buf.st_size;
+#if GLIB_CHECK_VERSION(2,30,0)
+ size = g_format_size_full ( byte_size, G_FORMAT_SIZE_DEFAULT );
+#else
+ size = g_format_size_for_display ( byte_size );
+#endif
+ message = g_strdup_printf ( "%s\n\n%s\n\n%s", vw->filename, time_buf, size );
+ g_free (size);
+ }