subsurface/main.c
Dirk Hohndel 92a5a5c35b Split report_dives into UI and logic and move to divelist files
Functionality is unchanged, except we now have a nice process_dives
function that deals with all the logic and that gets called from
report_dives from the Gtk code.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-04-24 16:38:25 -07:00

260 lines
5.8 KiB
C

/* main.c */
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <libintl.h>
#include <glib/gi18n.h>
#include "dive.h"
#include "divelist.h"
#if HAVE_OSM_GPS_MAP
#include <osm-gps-map.h>
#endif
#ifdef DEBUGFILE
char *debugfilename;
FILE *debugfile;
#endif
struct preferences prefs;
struct preferences default_prefs = {
.units = SI_UNITS,
.visible_cols = { TRUE, FALSE, },
.pp_graphs = {
.po2 = FALSE,
.pn2 = FALSE,
.phe = FALSE,
.po2_threshold = 1.6,
.pn2_threshold = 4.0,
.phe_threshold = 13.0,
},
.mod = FALSE,
.mod_ppO2 = 1.6,
.ead = FALSE,
.profile_red_ceiling = FALSE,
.profile_calc_ceiling = FALSE,
.calc_ceiling_3m_incr = FALSE,
.gflow = 0.30,
.gfhigh = 0.75,
#if HAVE_OSM_GPS_MAP
.map_provider = OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID,
#endif
};
/* random helper functions, used here or elsewhere */
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;
}
void sort_table(struct dive_table *table)
{
qsort(table->dives, table->nr, sizeof(struct dive *), sortfn);
}
const char *weekday(int wday)
{
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")
};
return _(wday_array[wday]);
}
const char *monthname(int mon)
{
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"),
};
return _(month_array[mon]);
}
/*
* track whether we switched to importing dives
*/
static gboolean imported = FALSE;
static void parse_argument(const char *arg)
{
const char *p = arg+1;
do {
switch (*p) {
case 'v':
verbose++;
continue;
case '-':
/* long options with -- */
if (strcmp(arg,"--import") == 0) {
/* mark the dives so far as the base,
* everything after is imported */
report_dives(FALSE, FALSE);
imported = TRUE;
return;
}
/* fallthrough */
case 'p':
/* ignore process serial number argument when run as native macosx app */
if (strncmp(arg, "-psn_", 5) == 0) {
return;
}
/* fallthrough */
default:
fprintf(stderr, "Bad argument '%s'\n", arg);
exit(1);
}
} while (*++p);
}
void update_dive(struct dive *new_dive)
{
static struct dive *buffered_dive;
struct dive *old_dive = buffered_dive;
if (old_dive) {
flush_divelist(old_dive);
}
show_dive_info(new_dive);
show_dive_equipment(new_dive, W_IDX_PRIMARY);
show_dive_stats(new_dive);
buffered_dive = new_dive;
}
void renumber_dives(int nr)
{
int i;
for (i = 0; i < dive_table.nr; i++) {
struct dive *dive = dive_table.dives[i];
dive->number = nr + i;
flush_divelist(dive);
}
mark_divelist_changed(TRUE);
}
/*
* Under a POSIX setup, the locale string should have a format
* like [language[_territory][.codeset][@modifier]].
*
* So search for the underscore, and see if the "territory" is
* US, and turn on imperial units by default.
*
* I guess Burma and Liberia should trigger this too. I'm too
* lazy to look up the territory names, though.
*/
static void setup_system_prefs(void)
{
const char *env;
default_prefs.divelist_font = strdup(system_divelist_default_font);
default_prefs.default_filename = system_default_filename();
env = getenv("LC_MEASUREMENT");
if (!env)
env = getenv("LC_ALL");
if (!env)
env = getenv("LANG");
if (!env)
return;
env = strchr(env, '_');
if (!env)
return;
env++;
if (strncmp(env, "US", 2))
return;
default_prefs.units = IMPERIAL_units;
}
int main(int argc, char **argv)
{
int i;
gboolean no_filenames = TRUE;
const char *path;
/* 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 */
path = subsurface_gettext_domainpath(argv[0]);
setlocale(LC_ALL, "");
bindtextdomain("subsurface", path);
bind_textdomain_codeset("subsurface", "utf-8");
textdomain("subsurface");
setup_system_prefs();
prefs = default_prefs;
#if DEBUGFILE > 1
debugfile = stderr;
#elif defined(DEBUGFILE)
debugfilename = strdup(prefs.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
subsurface_command_line_init(&argc, &argv);
parse_xml_init();
init_ui(&argc, &argv); /* the gtk stuff is needed for parsing below */
for (i = 1; i < argc; i++) {
const char *a = argv[i];
if (a[0] == '-') {
parse_argument(a);
continue;
}
GError *error = NULL;
/* if we have exactly one filename, parse_file will set
* that to be the default. Otherwise there will be no default filename */
set_filename(NULL, TRUE);
parse_file(a, &error);
if (no_filenames)
{
set_filename(a, TRUE);
no_filenames = FALSE;
}
if (error != NULL)
{
report_error(error);
g_error_free(error);
error = NULL;
}
}
if (no_filenames) {
GError *error = NULL;
const char *filename = prefs.default_filename;
parse_file(filename, &error);
/* don't report errors - this file may not exist, but make
sure we remember this as the filename in use */
set_filename(filename, FALSE);
}
report_dives(imported, FALSE);
if (dive_table.nr == 0)
show_dive_info(NULL);
parse_xml_exit();
subsurface_command_line_exit(&argc, &argv);
init_qt_ui(&argc, &argv); /* qt bit delayed until dives are parsed */
run_ui();
exit_ui();
#ifdef DEBUGFILE
if (debugfile)
fclose(debugfile);
#endif
return 0;
}