mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Remove the ability to 'Import' .SDA files
We can instead 'Open' these files as they are just bastardized XML files. This gets us back to a more consistent point where 'Import' gets data directly from the dive computer (and hopefully soon we will add the ability to load a dive directly from a uemis SDA to libdivecomputer), and 'Open' loads a file from the filesystem of the computer we are running on (this last sentence phrased so awkwardly as the uemis Zurich SDA is a computer and presents a file system when connected via USB - it just doesn't have the dive data in an accessible format in that file system). As a bonus we get to throw away quite a bit of code (the uemis specific file handling, mini-XML parser with helper functions, the file open dialog in the importer). Yay! Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
254b851e44
commit
c15f798a85
5 changed files with 2 additions and 163 deletions
2
dive.h
2
dive.h
|
@ -262,8 +262,6 @@ extern void report_error(GError* error);
|
|||
extern void dive_list_update_dives(void);
|
||||
extern void flush_divelist(struct dive *dive);
|
||||
|
||||
extern int open_import_file_dialog(char *filterpattern, char *filtertext,
|
||||
void(* parse_function)(char *));
|
||||
#define DIVE_ERROR_PARSE 1
|
||||
|
||||
const char *weekday(int wday);
|
||||
|
|
42
gtk-gui.c
42
gtk-gui.c
|
@ -103,6 +103,8 @@ static void file_open(GtkWidget *w, gpointer data)
|
|||
filter = gtk_file_filter_new();
|
||||
gtk_file_filter_add_pattern(filter, "*.xml");
|
||||
gtk_file_filter_add_pattern(filter, "*.XML");
|
||||
gtk_file_filter_add_pattern(filter, "*.sda");
|
||||
gtk_file_filter_add_pattern(filter, "*.SDA");
|
||||
gtk_file_filter_add_mime_type(filter, "text/xml");
|
||||
gtk_file_filter_set_name(filter, "XML file");
|
||||
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
|
||||
|
@ -632,46 +634,6 @@ void run_ui(void)
|
|||
gtk_main();
|
||||
}
|
||||
|
||||
/* get the filenames the user selects and call the parsing function
|
||||
* on them
|
||||
* return 0 if the user cancelled the dialog
|
||||
*/
|
||||
int open_import_file_dialog(char *filterpattern, char *filtertext,
|
||||
void(* parse_function)(char *))
|
||||
{
|
||||
int ret=0;
|
||||
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_pattern (filter, filterpattern);
|
||||
gtk_file_filter_set_name(filter, filtertext);
|
||||
dialog = gtk_file_chooser_dialog_new("Open File",
|
||||
GTK_WINDOW(main_window),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
|
||||
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
GSList *filenames;
|
||||
char *filename;
|
||||
filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
|
||||
while(filenames != NULL) {
|
||||
filename = (char *)filenames->data;
|
||||
parse_function(filename);
|
||||
g_free(filename);
|
||||
filenames = g_slist_next(filenames);
|
||||
}
|
||||
g_slist_free(filenames);
|
||||
ret = 1;
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
{
|
||||
struct dive *dive = current_dive;
|
||||
|
|
|
@ -497,9 +497,6 @@ void do_import(device_data_t *data)
|
|||
pthread_t pthread;
|
||||
void *retval;
|
||||
|
||||
if (data->type == DEVICE_TYPE_UEMIS)
|
||||
return uemis_import();
|
||||
|
||||
/* I'm sure there is some better interface for waiting on a thread in a UI main loop */
|
||||
import_thread_done = 0;
|
||||
pthread_create(&pthread, NULL, pthread_wrapper, data);
|
||||
|
@ -542,6 +539,5 @@ struct device_list device_list[] = {
|
|||
{ "Cressi Edy", DEVICE_TYPE_CRESSI_EDY },
|
||||
{ "Zeagle N2iTiON 3", DEVICE_TYPE_ZEAGLE_N2ITION3 },
|
||||
{ "Atomics Cobalt", DEVICE_TYPE_ATOMICS_COBALT },
|
||||
{ "Uemis Zurich SDA", DEVICE_TYPE_UEMIS },
|
||||
{ NULL }
|
||||
};
|
||||
|
|
113
uemis.c
113
uemis.c
|
@ -73,64 +73,6 @@ static void decode( uint8_t *inbuf, uint8_t *outbuf, int inbuf_len ) {
|
|||
}
|
||||
/* end code from Bob Trower */
|
||||
|
||||
/* small helper functions */
|
||||
/* simpleregex allocates (and reallocates) the found buffer
|
||||
* don't forget to free it when you are done
|
||||
*/
|
||||
static int simpleregex(char *buffer, char *regex, char **found) {
|
||||
int status;
|
||||
regex_t re;
|
||||
regmatch_t match[5];
|
||||
|
||||
if (regcomp(&re, regex, 0) !=0) {
|
||||
fprintf(stderr,"internal error, regex failed!\n");
|
||||
exit(1);
|
||||
}
|
||||
status = regexec(&re,buffer,5,match,0);
|
||||
if(status == 0) {
|
||||
*found = realloc(*found,match[1].rm_eo-match[1].rm_so + 1);
|
||||
strncpy(*found,buffer+match[1].rm_so,match[1].rm_eo-match[1].rm_so);
|
||||
(*found)[match[1].rm_eo-match[1].rm_so] = '\0';
|
||||
}
|
||||
return(status == 0);
|
||||
}
|
||||
|
||||
/* read in line of arbitrary length (important for SDA files that can
|
||||
* have lines that are tens of kB long
|
||||
* don't forget to free it when you are done
|
||||
*/
|
||||
#define MYGETL_INCR 1024
|
||||
static char * mygetline(FILE * f) {
|
||||
size_t size = 0;
|
||||
size_t len = 0;
|
||||
char * buf = NULL;
|
||||
|
||||
do {
|
||||
size += MYGETL_INCR;
|
||||
if ((buf = realloc(buf,size)) == NULL)
|
||||
break;
|
||||
fgets(buf+len,MYGETL_INCR,f);
|
||||
len = strlen(buf);
|
||||
} while (!feof(f) && buf[len-1]!='\n');
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* text matching, used to build very poor man's XML parser */
|
||||
int matchit(FILE *infd, char *regex, char *typeregex, char **found) {
|
||||
char *buffer;
|
||||
|
||||
while (!feof(infd)) {
|
||||
buffer = mygetline(infd);
|
||||
if (buffer && simpleregex(buffer,regex,found)) {
|
||||
buffer = mygetline(infd);
|
||||
if (buffer && simpleregex(buffer,typeregex,found)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* pressure_to_depth: In centibar. And when converting to
|
||||
* depth, I'm just going to always use saltwater, because I
|
||||
|
@ -233,58 +175,3 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
|
|||
dive->duration.seconds = sample->time.seconds - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse a single file
|
||||
* TODO: we don't report any errors when the parse fails - we simply don't add them to the list
|
||||
*/
|
||||
void
|
||||
parse_uemis_file(char *divelogfilename) {
|
||||
char *found=NULL;
|
||||
struct tm tm;
|
||||
struct dive *dive;
|
||||
|
||||
FILE *divelogfile = fopen(divelogfilename,"r");
|
||||
|
||||
dive = alloc_dive();
|
||||
|
||||
if (! matchit(divelogfile,"val key=\"date\"","<ts>\\([^<]*\\)</ts>",&found)) {
|
||||
/* some error handling */
|
||||
goto bail;
|
||||
}
|
||||
strptime(found, "%Y-%m-%dT%H:%M:%S", &tm);
|
||||
dive->when = utc_mktime(&tm);
|
||||
if (! matchit(divelogfile,"<val key=\"duration\">",
|
||||
"<float>\\([0-9.]*\\)</float>", &found)) {
|
||||
/* some error handling */
|
||||
goto bail;
|
||||
}
|
||||
dive->duration.seconds = 60.0 * atof(found);
|
||||
|
||||
if (! matchit(divelogfile,"<val key=\"depth\">",
|
||||
"<int>\\([0-9.]*\\)</int>", &found)) {
|
||||
/* some error handling */
|
||||
goto bail;
|
||||
}
|
||||
dive->maxdepth.mm = pressure_to_depth(atoi(found));
|
||||
|
||||
if (! matchit(divelogfile,"<val key=\"file_content\">",
|
||||
">\\([a-zA-Z0-9+/=]*\\)<", &found)) {
|
||||
/* some error handling */
|
||||
goto bail;
|
||||
}
|
||||
uemis_parse_divelog_binary(found,&dive);
|
||||
record_dive(dive);
|
||||
bail:
|
||||
if (found)
|
||||
free(found);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse the two files extracted from the SDA
|
||||
*/
|
||||
void
|
||||
uemis_import() {
|
||||
if (open_import_file_dialog("*.SDA","uemis Zurich SDA files",
|
||||
&parse_uemis_file))
|
||||
report_dives();
|
||||
}
|
||||
|
|
4
uemis.h
4
uemis.h
|
@ -3,12 +3,8 @@
|
|||
|
||||
/*
|
||||
* defines and prototypes for the uemis Zurich SDA file parser
|
||||
* we add this to the list of dive computers that is supported
|
||||
* in libdivecomputer by using a negative value for the type enum
|
||||
*/
|
||||
#define DEVICE_TYPE_UEMIS (-1)
|
||||
|
||||
void uemis_import();
|
||||
void uemis_parse_divelog_binary(char *base64, void *divep);
|
||||
|
||||
#endif /* DIVE_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue