]> git.street.me.uk Git - andy/viking.git/blob - src/datasource_file.c
Really empty GPS realtime layers.
[andy/viking.git] / src / datasource_file.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2011, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
5  * Copyright (C) 2015, Rob Norris <rw_norris@hotmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <string.h>
26
27 #include <glib/gprintf.h>
28 #include <glib/gi18n.h>
29
30 #include <gtk/gtk.h>
31
32 #include "viking.h"
33 #include "babel.h"
34 #include "gpx.h"
35 #include "babel_ui.h"
36 #include "acquire.h"
37
38 typedef struct {
39   GtkWidget *file;
40   GtkWidget *type;
41 } datasource_file_widgets_t;
42
43 /* The last used directory */
44 static gchar *last_folder_uri = NULL;
45
46 /* The last used file filter */
47 /* Nb: we use a complex strategy for this because the UI is rebuild each
48  time, so it is not possible to reuse directly the GtkFileFilter as they are
49  differents. */
50 static BabelFile *last_file_filter = NULL;
51
52 /* The last file format selected */
53 static int last_type = 0;
54
55 static gpointer datasource_file_init ( acq_vik_t *avt );
56 static void datasource_file_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data );
57 static void datasource_file_get_process_options ( datasource_file_widgets_t *widgets, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 );
58 static void datasource_file_cleanup ( gpointer data );
59
60 VikDataSourceInterface vik_datasource_file_interface = {
61   N_("Import file with GPSBabel"),
62   N_("Imported file"),
63   VIK_DATASOURCE_AUTO_LAYER_MANAGEMENT,
64   VIK_DATASOURCE_INPUTTYPE_NONE,
65   TRUE,
66   TRUE,
67   TRUE,
68   (VikDataSourceInitFunc)               datasource_file_init,
69   (VikDataSourceCheckExistenceFunc)     NULL,
70   (VikDataSourceAddSetupWidgetsFunc)    datasource_file_add_setup_widgets,
71   (VikDataSourceGetProcessOptionsFunc)  datasource_file_get_process_options,
72   (VikDataSourceProcessFunc)            a_babel_convert_from,
73   (VikDataSourceProgressFunc)           NULL,
74   (VikDataSourceAddProgressWidgetsFunc) NULL,
75   (VikDataSourceCleanupFunc)            datasource_file_cleanup,
76   (VikDataSourceOffFunc)                NULL,
77
78   NULL,
79   0,
80   NULL,
81   NULL,
82   0
83 };
84
85 /* See VikDataSourceInterface */
86 static gpointer datasource_file_init ( acq_vik_t *avt )
87 {
88   datasource_file_widgets_t *widgets = g_malloc(sizeof(*widgets));
89   return widgets;
90 }
91
92 static void add_file_filter (gpointer data, gpointer user_data)
93 {
94   GtkFileChooser *chooser = GTK_FILE_CHOOSER ( user_data );
95   const gchar *label = ((BabelFile*) data)->label;
96   const gchar *ext = ((BabelFile*) data)->ext;
97   if ( ext == NULL || ext[0] == '\0' )
98     /* No file extension => no filter */
99         return;
100   gchar *pattern = g_strdup_printf ( "*.%s", ext );
101
102   GtkFileFilter *filter = gtk_file_filter_new ();
103   gtk_file_filter_add_pattern ( filter, pattern );
104   if ( strstr ( label, pattern+1 ) ) {
105     gtk_file_filter_set_name ( filter, label );
106   } else {
107     /* Ensure displayed label contains file pattern */
108         /* NB: we skip the '*' in the pattern */
109         gchar *name = g_strdup_printf ( "%s (%s)", label, pattern+1 );
110     gtk_file_filter_set_name ( filter, name );
111         g_free ( name );
112   }
113   g_object_set_data ( G_OBJECT(filter), "Babel", data );
114   gtk_file_chooser_add_filter ( chooser, filter );
115   if ( last_file_filter == data )
116     /* Previous selection used this filter */
117     gtk_file_chooser_set_filter ( chooser, filter );
118
119   g_free ( pattern );
120 }
121
122 /* See VikDataSourceInterface */
123 static void datasource_file_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data )
124 {
125   datasource_file_widgets_t *widgets = (datasource_file_widgets_t *)user_data;
126   GtkWidget *filename_label, *type_label;
127
128   /* The file selector */
129   filename_label = gtk_label_new (_("File:"));
130   widgets->file = gtk_file_chooser_button_new (_("File to import"), GTK_FILE_CHOOSER_ACTION_OPEN);
131   if (last_folder_uri)
132     gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(widgets->file), last_folder_uri);
133   /* Add filters */
134   g_list_foreach ( a_babel_file_list, add_file_filter, widgets->file );
135   GtkFileFilter *all_filter = gtk_file_filter_new ();
136   gtk_file_filter_add_pattern ( all_filter, "*" );
137   gtk_file_filter_set_name ( all_filter, _("All files") );
138   gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER(widgets->file), all_filter );
139   if ( last_file_filter == NULL )
140     /* No previously selected filter or 'All files' selected */
141     gtk_file_chooser_set_filter ( GTK_FILE_CHOOSER(widgets->file), all_filter );
142
143   /* The file format selector */
144   type_label = gtk_label_new (_("File type:"));
145   /* Propose any readable file */
146   BabelMode mode = { 1, 0, 1, 0, 1, 0 };
147   widgets->type = a_babel_ui_file_type_selector_new ( mode );
148   g_signal_connect ( G_OBJECT(widgets->type), "changed",
149       G_CALLBACK(a_babel_ui_type_selector_dialog_sensitivity_cb), dialog );
150   gtk_combo_box_set_active ( GTK_COMBO_BOX(widgets->type), last_type );
151   /* Manually call the callback to fix the state */
152   a_babel_ui_type_selector_dialog_sensitivity_cb ( GTK_COMBO_BOX(widgets->type), dialog );
153
154   /* Packing all these widgets */
155   GtkBox *box = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
156   gtk_box_pack_start ( box, filename_label, FALSE, FALSE, 5 );
157   gtk_box_pack_start ( box, widgets->file, FALSE, FALSE, 5 );
158   gtk_box_pack_start ( box, type_label, FALSE, FALSE, 5 );
159   gtk_box_pack_start ( box, widgets->type, FALSE, FALSE, 5 );
160   gtk_widget_show_all(dialog);
161 }
162
163 /* See VikDataSourceInterface */
164 static void datasource_file_get_process_options ( datasource_file_widgets_t *widgets, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 )
165 {
166   /* Retrieve the file selected */
167   gchar *filename = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(widgets->file) );
168
169   /* Memorize the directory for later use */
170   g_free (last_folder_uri);
171   last_folder_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(widgets->file) );
172
173   /* Memorize the file filter for later use */
174   GtkFileFilter *filter = gtk_file_chooser_get_filter ( GTK_FILE_CHOOSER(widgets->file) );
175   last_file_filter = g_object_get_data ( G_OBJECT(filter), "Babel" );
176
177   /* Retrieve and memorize file format selected */
178   gchar *type = NULL;
179   last_type = gtk_combo_box_get_active ( GTK_COMBO_BOX (widgets->type) );
180   type = (a_babel_ui_file_type_selector_get ( widgets->type ))->name;
181
182   /* Generate the process options */
183   po->babelargs = g_strdup_printf( "-i %s", type);
184   po->filename = g_strdup(filename);
185
186   /* Free memory */
187   g_free (filename);
188
189   g_debug(_("using babel args '%s' and file '%s'"), po->babelargs, po->filename);
190 }
191
192 /* See VikDataSourceInterface */
193 static void datasource_file_cleanup ( gpointer data )
194 {
195   g_free ( data );
196 }
197