]> git.street.me.uk Git - andy/viking.git/blob - src/datasource_geotag.c
Fix routes not saved in GPX when tracks are made invisible.
[andy/viking.git] / src / datasource_geotag.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4  *
5  * Copyright (C) 2012-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 "acquire.h"
34 #include "geotag_exif.h"
35
36 typedef struct {
37         GtkWidget *files;
38         GSList *filelist;  // Files selected
39 } datasource_geotag_user_data_t;
40
41 /* The last used directory */
42 static gchar *last_folder_uri = NULL;
43
44 static gpointer datasource_geotag_init ( acq_vik_t *avt );
45 static void datasource_geotag_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data );
46 static void datasource_geotag_get_process_options ( gpointer user_data, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 );
47 static gboolean datasource_geotag_process ( VikTrwLayer *vtl, ProcessOptions *po, BabelStatusFunc status_cb, acq_dialog_widgets_t *adw, gpointer not_used );
48 static void datasource_geotag_cleanup ( gpointer user_data );
49
50 VikDataSourceInterface vik_datasource_geotag_interface = {
51   N_("Create Waypoints from Geotagged Images"),
52   N_("Geotagged Images"),
53   VIK_DATASOURCE_AUTO_LAYER_MANAGEMENT,
54   VIK_DATASOURCE_INPUTTYPE_NONE,
55   TRUE,
56   FALSE, // We should be able to see the data on the screen so no point in keeping the dialog open
57   TRUE,
58   (VikDataSourceInitFunc)                       datasource_geotag_init,
59   (VikDataSourceCheckExistenceFunc)         NULL,
60   (VikDataSourceAddSetupWidgetsFunc)    datasource_geotag_add_setup_widgets,
61   (VikDataSourceGetProcessOptionsFunc)  datasource_geotag_get_process_options,
62   (VikDataSourceProcessFunc)            datasource_geotag_process,
63   (VikDataSourceProgressFunc)               NULL,
64   (VikDataSourceAddProgressWidgetsFunc) NULL,
65   (VikDataSourceCleanupFunc)                datasource_geotag_cleanup,
66   (VikDataSourceOffFunc)                NULL,
67
68   NULL,
69   0,
70   NULL,
71   NULL,
72   0
73 };
74
75 /* See VikDataSourceInterface */
76 static gpointer datasource_geotag_init ( acq_vik_t *avt )
77 {
78         datasource_geotag_user_data_t *user_data = g_malloc(sizeof(datasource_geotag_user_data_t));
79         user_data->filelist = NULL;
80         return user_data;
81 }
82
83 /* See VikDataSourceInterface */
84 static void datasource_geotag_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data )
85 {
86         datasource_geotag_user_data_t *userdata = (datasource_geotag_user_data_t *)user_data;
87
88         /* The files selector */
89         userdata->files = gtk_file_chooser_widget_new ( GTK_FILE_CHOOSER_ACTION_OPEN );
90
91         // try to make it a nice size - otherwise seems to default to something impractically small
92         gtk_window_set_default_size ( GTK_WINDOW (dialog) , 600, 300 );
93
94         if ( last_folder_uri )
95                 gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(userdata->files), last_folder_uri );
96
97         GtkFileChooser *chooser = GTK_FILE_CHOOSER ( userdata->files );
98
99         /* Add filters */
100         GtkFileFilter *filter;
101         filter = gtk_file_filter_new ();
102         gtk_file_filter_set_name ( filter, _("All") );
103         gtk_file_filter_add_pattern ( filter, "*" );
104         gtk_file_chooser_add_filter ( chooser, filter );
105
106         filter = gtk_file_filter_new ();
107         gtk_file_filter_set_name ( filter, _("JPG") );
108         gtk_file_filter_add_mime_type ( filter, "image/jpeg");
109         gtk_file_chooser_add_filter ( chooser, filter );
110
111         // Default to jpgs
112         gtk_file_chooser_set_filter ( chooser, filter );
113
114         // Allow selecting more than one
115         gtk_file_chooser_set_select_multiple ( chooser, TRUE );
116
117         // Could add code to setup a default symbol (see dialog.c for symbol usage)
118         //  Store in user_data type and then apply when creating the waypoints
119         //  However not much point since these will have images associated with them!
120
121         /* Packing all widgets */
122         GtkBox *box = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
123         gtk_box_pack_start ( box, userdata->files, TRUE, TRUE, 0 );
124
125         gtk_widget_show_all ( dialog );
126 }
127
128 static void datasource_geotag_get_process_options ( gpointer user_data, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 )
129 {
130         datasource_geotag_user_data_t *userdata = (datasource_geotag_user_data_t *)user_data;
131         /* Retrieve the files selected */
132         userdata->filelist = gtk_file_chooser_get_filenames ( GTK_FILE_CHOOSER(userdata->files) ); // Not reusable !!
133
134         /* Memorize the directory for later use */
135         g_free ( last_folder_uri );
136         last_folder_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(userdata->files) );
137         last_folder_uri = g_strdup ( last_folder_uri );
138
139         /* TODO Memorize the file filter for later use... */
140         //GtkFileFilter *filter = gtk_file_chooser_get_filter ( GTK_FILE_CHOOSER(userdata->files) );
141
142         // return some value so *thread* processing will continue
143         po->babelargs = g_strdup ("fake command"); // Not really used, thus no translations
144 }
145
146 /**
147  * Process selected files and try to generate waypoints storing them in the given vtl
148  */
149 static gboolean datasource_geotag_process ( VikTrwLayer *vtl, ProcessOptions *po, BabelStatusFunc status_cb, acq_dialog_widgets_t *adw, gpointer not_used )
150 {
151         datasource_geotag_user_data_t *user_data = (datasource_geotag_user_data_t *)adw->user_data;
152
153         // Process selected files
154         // In prinicple this loading should be quite fast and so don't need to have any progress monitoring
155         GSList *cur_file = user_data->filelist;
156         while ( cur_file ) {
157                 gchar *filename = cur_file->data;
158                 gchar *name;
159                 VikWaypoint *wp = a_geotag_create_waypoint_from_file ( filename, vik_viewport_get_coord_mode ( adw->vvp ), &name );
160                 if ( wp ) {
161                         // Create name if geotag method didn't return one
162                         if ( !name )
163                                 name = g_strdup ( a_file_basename ( filename ) );
164                         vik_trw_layer_filein_add_waypoint ( vtl, name, wp );
165                         g_free ( name );
166                 }
167                 else {
168                         gchar* msg = g_strdup_printf ( _("Unable to create waypoint from %s"), filename );
169                         vik_window_statusbar_update ( adw->vw, msg, VIK_STATUSBAR_INFO );
170                         g_free (msg);
171                 }
172                 g_free ( filename );
173                 cur_file = g_slist_next ( cur_file );
174         }
175
176         /* Free memory */
177         g_slist_free ( user_data->filelist );
178
179         // No failure
180         return TRUE;
181 }
182
183 /* See VikDataSourceInterface */
184 static void datasource_geotag_cleanup ( gpointer user_data )
185 {
186         g_free ( user_data );
187 }