2011-09-20 19:40:34 +00:00
|
|
|
/* main.c */
|
2012-10-11 00:42:59 +00:00
|
|
|
#include <locale.h>
|
2011-08-31 01:40:25 +00:00
|
|
|
#include <stdio.h>
|
2011-09-02 23:40:28 +00:00
|
|
|
#include <string.h>
|
2011-08-31 01:40:25 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
2012-10-11 00:42:59 +00:00
|
|
|
#include <libintl.h>
|
|
|
|
#include <glib/gi18n.h>
|
2011-08-31 01:40:25 +00:00
|
|
|
|
|
|
|
#include "dive.h"
|
2011-09-05 19:12:58 +00:00
|
|
|
#include "divelist.h"
|
2011-09-20 18:24:15 +00:00
|
|
|
|
2012-09-26 15:30:37 +00:00
|
|
|
#ifdef DEBUGFILE
|
|
|
|
char *debugfilename;
|
|
|
|
FILE *debugfile;
|
|
|
|
#endif
|
|
|
|
|
2011-09-07 02:07:17 +00:00
|
|
|
struct units output_units;
|
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
/* random helper functions, used here or elsewhere */
|
2011-08-31 01:40:25 +00:00
|
|
|
static int sortfn(const void *_a, const void *_b)
|
|
|
|
{
|
|
|
|
const struct dive *a = *(void **)_a;
|
|
|
|
const struct dive *b = *(void **)_b;
|
|
|
|
|
|
|
|
if (a->when < b->when)
|
|
|
|
return -1;
|
|
|
|
if (a->when > b->when)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
const char *weekday(int wday)
|
|
|
|
{
|
2012-10-11 00:42:59 +00:00
|
|
|
static const char wday_array[7][7] = {
|
|
|
|
/*++GETTEXT: these are three letter days - we allow up to six code bytes */
|
|
|
|
N_("Sun"), N_("Mon"), N_("Tue"), N_("Wed"), N_("Thu"), N_("Fri"), N_("Sat")
|
2011-09-20 19:40:34 +00:00
|
|
|
};
|
2012-10-15 21:37:59 +00:00
|
|
|
return _(wday_array[wday]);
|
2011-09-20 19:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *monthname(int mon)
|
|
|
|
{
|
2012-10-11 00:42:59 +00:00
|
|
|
static const char month_array[12][7] = {
|
|
|
|
/*++GETTEXT: these are three letter months - we allow up to six code bytes*/
|
|
|
|
N_("Jan"), N_("Feb"), N_("Mar"), N_("Apr"), N_("May"), N_("Jun"),
|
|
|
|
N_("Jul"), N_("Aug"), N_("Sep"), N_("Oct"), N_("Nov"), N_("Dec"),
|
2011-09-20 19:40:34 +00:00
|
|
|
};
|
2012-10-15 21:37:59 +00:00
|
|
|
return _(month_array[mon]);
|
2011-09-20 19:40:34 +00:00
|
|
|
}
|
|
|
|
|
2011-10-05 15:31:31 +00:00
|
|
|
/*
|
|
|
|
* When adding dives to the dive table, we try to renumber
|
|
|
|
* the new dives based on any old dives in the dive table.
|
|
|
|
*
|
|
|
|
* But we only do it if:
|
|
|
|
*
|
2012-12-05 17:34:00 +00:00
|
|
|
* - there are no dives in the dive table
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
2011-10-05 15:31:31 +00:00
|
|
|
* - the last dive in the old dive table was numbered
|
|
|
|
*
|
|
|
|
* - all the new dives are strictly at the end (so the
|
|
|
|
* "last dive" is at the same location in the dive table
|
|
|
|
* after re-sorting the dives.
|
|
|
|
*
|
|
|
|
* - none of the new dives have any numbers
|
|
|
|
*
|
|
|
|
* This catches the common case of importing new dives from
|
|
|
|
* a dive computer, and gives them proper numbers based on
|
|
|
|
* your old dive list. But it tries to be very conservative
|
|
|
|
* and not give numbers if there is *any* question about
|
|
|
|
* what the numbers should be - in which case you need to do
|
|
|
|
* a manual re-numbering.
|
|
|
|
*/
|
|
|
|
static void try_to_renumber(struct dive *last, int preexisting)
|
|
|
|
{
|
|
|
|
int i, nr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the new dives aren't all strictly at the end,
|
|
|
|
* we're going to expect the user to do a manual
|
|
|
|
* renumbering.
|
|
|
|
*/
|
2012-12-05 17:34:00 +00:00
|
|
|
if (preexisting && get_dive(preexisting-1) != last)
|
2011-10-05 15:31:31 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If any of the new dives already had a number,
|
|
|
|
* we'll have to do a manual renumbering.
|
|
|
|
*/
|
|
|
|
for (i = preexisting; i < dive_table.nr; i++) {
|
|
|
|
struct dive *dive = get_dive(i);
|
|
|
|
if (dive->number)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ok, renumber..
|
|
|
|
*/
|
2012-12-05 17:34:00 +00:00
|
|
|
if (last)
|
|
|
|
nr = last->number;
|
|
|
|
else
|
|
|
|
nr = 0;
|
2011-10-05 15:31:31 +00:00
|
|
|
for (i = preexisting; i < dive_table.nr; i++) {
|
|
|
|
struct dive *dive = get_dive(i);
|
|
|
|
dive->number = ++nr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-05 21:09:49 +00:00
|
|
|
/*
|
|
|
|
* track whether we switched to importing dives
|
|
|
|
*/
|
|
|
|
static gboolean imported = FALSE;
|
|
|
|
|
2011-08-31 02:48:00 +00:00
|
|
|
/*
|
|
|
|
* This doesn't really report anything at all. We just sort the
|
|
|
|
* dives, the GUI does the reporting
|
|
|
|
*/
|
Add special download modes to force updates from the divecomputer
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-11-11 13:29:26 +00:00
|
|
|
void report_dives(gboolean is_imported, gboolean prefer_imported)
|
2011-08-31 01:40:25 +00:00
|
|
|
{
|
2011-09-02 23:40:28 +00:00
|
|
|
int i;
|
2011-10-05 15:31:31 +00:00
|
|
|
int preexisting = dive_table.preexisting;
|
|
|
|
struct dive *last;
|
|
|
|
|
|
|
|
/* This does the right thing for -1: NULL */
|
|
|
|
last = get_dive(preexisting-1);
|
2011-09-02 23:40:28 +00:00
|
|
|
|
2011-08-31 01:40:25 +00:00
|
|
|
qsort(dive_table.dives, dive_table.nr, sizeof(struct dive *), sortfn);
|
2011-09-02 23:40:28 +00:00
|
|
|
|
|
|
|
for (i = 1; i < dive_table.nr; i++) {
|
|
|
|
struct dive **pp = &dive_table.dives[i-1];
|
|
|
|
struct dive *prev = pp[0];
|
|
|
|
struct dive *dive = pp[1];
|
|
|
|
struct dive *merged;
|
|
|
|
|
|
|
|
if (prev->when + prev->duration.seconds < dive->when)
|
|
|
|
continue;
|
|
|
|
|
Add special download modes to force updates from the divecomputer
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-11-11 13:29:26 +00:00
|
|
|
merged = try_to_merge(prev, dive, prefer_imported);
|
2011-09-02 23:40:28 +00:00
|
|
|
if (!merged)
|
|
|
|
continue;
|
|
|
|
|
2012-09-16 03:47:53 +00:00
|
|
|
/* careful - we might free the dive that last points to. Oops... */
|
|
|
|
if (last == prev || last == dive)
|
|
|
|
last = merged;
|
2011-09-02 23:40:28 +00:00
|
|
|
|
|
|
|
/* Redo the new 'i'th dive */
|
|
|
|
i--;
|
2012-11-11 06:49:19 +00:00
|
|
|
add_single_dive(i, merged);
|
|
|
|
delete_single_dive(i+1);
|
|
|
|
delete_single_dive(i+1);
|
2011-09-02 23:40:28 +00:00
|
|
|
}
|
Add special download modes to force updates from the divecomputer
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-11-11 13:29:26 +00:00
|
|
|
/* make sure no dives are still marked as downloaded */
|
|
|
|
for (i = 1; i < dive_table.nr; i++)
|
|
|
|
dive_table.dives[i]->downloaded = FALSE;
|
2011-10-05 15:06:48 +00:00
|
|
|
|
2012-01-05 16:16:08 +00:00
|
|
|
if (is_imported) {
|
2012-12-05 17:34:00 +00:00
|
|
|
/* If there are dives in the table, are they numbered */
|
|
|
|
if (!last || last->number)
|
2011-10-05 18:36:15 +00:00
|
|
|
try_to_renumber(last, preexisting);
|
2011-10-05 15:31:31 +00:00
|
|
|
|
2012-09-10 21:44:48 +00:00
|
|
|
/* did we add dives to the dive table? */
|
|
|
|
if (preexisting != dive_table.nr)
|
2011-10-05 18:36:15 +00:00
|
|
|
mark_divelist_changed(TRUE);
|
|
|
|
}
|
2011-10-05 15:31:31 +00:00
|
|
|
dive_table.preexisting = dive_table.nr;
|
2011-10-05 15:06:48 +00:00
|
|
|
dive_list_update_dives();
|
2011-08-31 01:40:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void parse_argument(const char *arg)
|
|
|
|
{
|
|
|
|
const char *p = arg+1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
switch (*p) {
|
|
|
|
case 'v':
|
|
|
|
verbose++;
|
|
|
|
continue;
|
2011-10-05 18:36:15 +00:00
|
|
|
case '-':
|
|
|
|
/* long options with -- */
|
|
|
|
if (strcmp(arg,"--import") == 0) {
|
|
|
|
/* mark the dives so far as the base,
|
|
|
|
* everything after is imported */
|
Add special download modes to force updates from the divecomputer
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-11-11 13:29:26 +00:00
|
|
|
report_dives(FALSE, FALSE);
|
2011-10-05 21:09:49 +00:00
|
|
|
imported = TRUE;
|
2011-10-05 18:36:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* fallthrough */
|
2011-10-30 19:56:28 +00:00
|
|
|
case 'p':
|
|
|
|
/* ignore process serial number argument when run as native macosx app */
|
|
|
|
if (strncmp(arg, "-psn_", 5) == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2012-08-26 21:41:05 +00:00
|
|
|
/* fallthrough */
|
2011-08-31 01:40:25 +00:00
|
|
|
default:
|
|
|
|
fprintf(stderr, "Bad argument '%s'\n", arg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
} while (*++p);
|
|
|
|
}
|
|
|
|
|
2011-09-10 00:10:17 +00:00
|
|
|
void update_dive(struct dive *new_dive)
|
|
|
|
{
|
|
|
|
static struct dive *buffered_dive;
|
|
|
|
struct dive *old_dive = buffered_dive;
|
|
|
|
|
|
|
|
if (old_dive) {
|
2011-09-20 17:06:24 +00:00
|
|
|
flush_divelist(old_dive);
|
2011-09-10 00:10:17 +00:00
|
|
|
}
|
2012-10-19 03:45:26 +00:00
|
|
|
show_dive_info(new_dive);
|
2011-09-10 00:10:17 +00:00
|
|
|
if (new_dive) {
|
2012-08-15 22:21:34 +00:00
|
|
|
show_dive_equipment(new_dive, W_IDX_PRIMARY);
|
2011-11-02 16:10:57 +00:00
|
|
|
show_dive_stats(new_dive);
|
2011-09-10 00:10:17 +00:00
|
|
|
}
|
2011-09-11 20:43:37 +00:00
|
|
|
buffered_dive = new_dive;
|
2011-09-10 00:10:17 +00:00
|
|
|
}
|
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
void renumber_dives(int nr)
|
2011-09-11 22:39:46 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < dive_table.nr; i++) {
|
|
|
|
struct dive *dive = dive_table.dives[i];
|
|
|
|
dive->number = nr + i;
|
2011-10-23 15:50:14 +00:00
|
|
|
flush_divelist(dive);
|
2011-09-11 22:39:46 +00:00
|
|
|
}
|
2011-10-05 16:24:52 +00:00
|
|
|
mark_divelist_changed(TRUE);
|
2011-09-11 22:39:46 +00:00
|
|
|
}
|
|
|
|
|
2011-08-31 01:40:25 +00:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int i;
|
2012-09-09 16:06:44 +00:00
|
|
|
gboolean no_filenames = TRUE;
|
2012-10-15 12:44:01 +00:00
|
|
|
const char *path;
|
2011-08-31 01:40:25 +00:00
|
|
|
|
2012-10-11 00:42:59 +00:00
|
|
|
/* set up l18n - the search directory needs to change
|
|
|
|
* so that it uses the correct system directory when
|
|
|
|
* subsurface isn't run from the local directory */
|
2012-10-18 21:30:45 +00:00
|
|
|
path = subsurface_gettext_domainpath(argv[0]);
|
2012-10-15 23:32:11 +00:00
|
|
|
setlocale( LC_ALL, "" );
|
2012-10-15 12:44:01 +00:00
|
|
|
bindtextdomain("subsurface", path);
|
2012-10-11 00:42:59 +00:00
|
|
|
bind_textdomain_codeset("subsurface", "utf-8");
|
|
|
|
textdomain("subsurface");
|
2011-09-07 02:07:17 +00:00
|
|
|
output_units = SI_units;
|
2011-09-27 17:16:40 +00:00
|
|
|
|
2012-10-04 00:44:47 +00:00
|
|
|
subsurface_command_line_init(&argc, &argv);
|
2011-08-31 01:40:25 +00:00
|
|
|
parse_xml_init();
|
|
|
|
|
2011-11-02 00:09:15 +00:00
|
|
|
init_ui(&argc, &argv);
|
2012-08-26 21:41:05 +00:00
|
|
|
|
2012-10-26 03:12:44 +00:00
|
|
|
#if DEBUGFILE > 1
|
|
|
|
debugfile = stderr;
|
|
|
|
#elif defined(DEBUGFILE)
|
2012-09-26 15:30:37 +00:00
|
|
|
debugfilename = (char *)subsurface_default_filename();
|
|
|
|
strncpy(debugfilename + strlen(debugfilename) - 3, "log", 3);
|
|
|
|
if (g_mkdir_with_parents(g_path_get_dirname(debugfilename), 0664) != 0 ||
|
|
|
|
(debugfile = g_fopen(debugfilename, "w")) == NULL)
|
|
|
|
printf("oh boy, can't create debugfile");
|
|
|
|
#endif
|
2011-09-05 20:14:53 +00:00
|
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
const char *a = argv[i];
|
|
|
|
|
|
|
|
if (a[0] == '-') {
|
|
|
|
parse_argument(a);
|
|
|
|
continue;
|
|
|
|
}
|
2012-09-09 16:06:44 +00:00
|
|
|
no_filenames = FALSE;
|
2011-09-05 20:14:53 +00:00
|
|
|
GError *error = NULL;
|
2012-10-09 12:50:16 +00:00
|
|
|
parse_file(a, &error, TRUE);
|
2012-08-26 21:41:05 +00:00
|
|
|
|
2011-09-05 20:14:53 +00:00
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
report_error(error);
|
|
|
|
g_error_free(error);
|
|
|
|
error = NULL;
|
|
|
|
}
|
|
|
|
}
|
2012-09-09 16:06:44 +00:00
|
|
|
if (no_filenames) {
|
|
|
|
GError *error = NULL;
|
|
|
|
const char *filename = subsurface_default_filename();
|
2012-10-09 12:50:16 +00:00
|
|
|
parse_file(filename, &error, TRUE);
|
2012-09-09 16:06:44 +00:00
|
|
|
/* don't report errors - this file may not exist, but make
|
|
|
|
sure we remember this as the filename in use */
|
2012-09-10 19:27:00 +00:00
|
|
|
set_filename(filename, FALSE);
|
2012-09-30 03:57:48 +00:00
|
|
|
free((void *)filename);
|
2012-09-09 16:06:44 +00:00
|
|
|
}
|
Add special download modes to force updates from the divecomputer
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-11-11 13:29:26 +00:00
|
|
|
report_dives(imported, FALSE);
|
2012-09-16 10:04:37 +00:00
|
|
|
if (dive_table.nr == 0)
|
|
|
|
show_dive_info(NULL);
|
2011-09-20 19:40:34 +00:00
|
|
|
run_ui();
|
2012-05-02 17:03:48 +00:00
|
|
|
exit_ui();
|
2012-09-18 15:33:55 +00:00
|
|
|
|
|
|
|
parse_xml_exit();
|
2012-10-04 00:44:47 +00:00
|
|
|
subsurface_command_line_exit(&argc, &argv);
|
2012-09-18 15:33:55 +00:00
|
|
|
|
2012-09-26 15:30:37 +00:00
|
|
|
#ifdef DEBUGFILE
|
|
|
|
if (debugfile)
|
|
|
|
fclose(debugfile);
|
|
|
|
#endif
|
2011-08-31 01:40:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|