2017-04-27 18:18:03 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2013-09-09 08:59:03 +00:00
|
|
|
#include "subsurfacestartup.h"
|
2015-02-15 18:25:18 +00:00
|
|
|
#include "version.h"
|
2013-09-09 08:59:03 +00:00
|
|
|
#include <stdbool.h>
|
2013-10-05 07:29:09 +00:00
|
|
|
#include <string.h>
|
2013-10-06 15:55:58 +00:00
|
|
|
#include "gettext.h"
|
2015-09-23 09:13:07 +00:00
|
|
|
#include "qthelperfromc.h"
|
|
|
|
#include "git-access.h"
|
2016-03-06 14:52:55 +00:00
|
|
|
#include "libdivecomputer/version.h"
|
2015-09-23 09:13:07 +00:00
|
|
|
|
2017-02-05 20:44:11 +00:00
|
|
|
struct preferences prefs, git_prefs;
|
2013-01-11 01:55:44 +00:00
|
|
|
struct preferences default_prefs = {
|
2015-06-15 12:52:12 +00:00
|
|
|
.cloud_base_url = "https://cloud.subsurface-divelog.org/",
|
2016-04-30 17:36:01 +00:00
|
|
|
#if defined(SUBSURFACE_MOBILE)
|
|
|
|
.git_local_only = true,
|
|
|
|
#endif
|
2013-01-11 01:55:44 +00:00
|
|
|
.units = SI_UNITS,
|
2013-06-03 12:08:49 +00:00
|
|
|
.unit_system = METRIC,
|
2015-05-20 10:25:46 +00:00
|
|
|
.coordinates_traditional = true,
|
2013-01-11 01:55:44 +00:00
|
|
|
.pp_graphs = {
|
2014-01-15 18:54:41 +00:00
|
|
|
.po2 = false,
|
|
|
|
.pn2 = false,
|
|
|
|
.phe = false,
|
2017-03-24 18:11:31 +00:00
|
|
|
.po2_threshold_min = 0.16,
|
|
|
|
.po2_threshold_max = 1.6,
|
2014-02-28 04:09:57 +00:00
|
|
|
.pn2_threshold = 4.0,
|
2013-01-11 01:55:44 +00:00
|
|
|
.phe_threshold = 13.0,
|
|
|
|
},
|
2014-02-28 04:09:57 +00:00
|
|
|
.mod = false,
|
2014-06-22 14:41:44 +00:00
|
|
|
.modpO2 = 1.6,
|
2014-02-28 04:09:57 +00:00
|
|
|
.ead = false,
|
2014-12-14 19:15:52 +00:00
|
|
|
.hrgraph = false,
|
|
|
|
.percentagegraph = false,
|
2014-04-16 20:03:44 +00:00
|
|
|
.dcceiling = true,
|
|
|
|
.redceiling = false,
|
|
|
|
.calcceiling = false,
|
|
|
|
.calcceiling3m = false,
|
|
|
|
.calcndltts = false,
|
2013-05-28 18:21:27 +00:00
|
|
|
.gflow = 30,
|
|
|
|
.gfhigh = 75,
|
2014-07-21 22:10:31 +00:00
|
|
|
.animation_speed = 500,
|
2014-01-15 18:54:41 +00:00
|
|
|
.gf_low_at_maxdepth = false,
|
2015-01-05 07:20:26 +00:00
|
|
|
.show_ccr_setpoint = false,
|
2015-01-20 18:13:53 +00:00
|
|
|
.show_ccr_sensors = false,
|
2014-02-26 19:33:27 +00:00
|
|
|
.font_size = -1,
|
2014-01-15 18:54:41 +00:00
|
|
|
.display_invalid_dives = false,
|
|
|
|
.show_sac = false,
|
2014-03-11 03:49:08 +00:00
|
|
|
.display_unused_tanks = false,
|
2014-06-24 22:08:36 +00:00
|
|
|
.show_average_depth = true,
|
|
|
|
.ascrate75 = 9000 / 60,
|
2017-09-27 21:52:39 +00:00
|
|
|
.ascrate50 = 9000 / 60,
|
|
|
|
.ascratestops = 9000 / 60,
|
|
|
|
.ascratelast6m = 9000 / 60,
|
2014-06-25 12:00:03 +00:00
|
|
|
.descrate = 18000 / 60,
|
2017-02-11 19:24:18 +00:00
|
|
|
.sacfactor = 400,
|
|
|
|
.problemsolvingtime = 4,
|
2014-06-25 12:00:03 +00:00
|
|
|
.bottompo2 = 1400,
|
2014-07-02 20:07:38 +00:00
|
|
|
.decopo2 = 1600,
|
2016-07-06 12:40:31 +00:00
|
|
|
.bestmixend.mm = 30000,
|
2014-07-09 21:37:30 +00:00
|
|
|
.doo2breaks = false,
|
2014-07-10 16:50:49 +00:00
|
|
|
.drop_stone_mode = false,
|
2015-06-22 11:48:42 +00:00
|
|
|
.switch_at_req_stop = false,
|
2015-06-19 10:25:03 +00:00
|
|
|
.min_switch_duration = 60,
|
2015-03-24 21:57:22 +00:00
|
|
|
.last_stop = false,
|
|
|
|
.verbatim_plan = false,
|
|
|
|
.display_runtime = true,
|
|
|
|
.display_duration = true,
|
|
|
|
.display_transitions = true,
|
2017-09-18 14:10:47 +00:00
|
|
|
.display_variations = false,
|
2015-04-02 08:32:14 +00:00
|
|
|
.safetystop = true,
|
2014-07-19 11:36:57 +00:00
|
|
|
.bottomsac = 20000,
|
|
|
|
.decosac = 17000,
|
2015-04-09 15:41:41 +00:00
|
|
|
.reserve_gas=40000,
|
2015-01-16 12:02:26 +00:00
|
|
|
.o2consumption = 720,
|
2014-10-24 14:40:21 +00:00
|
|
|
.pscr_ratio = 100,
|
2014-08-15 14:11:14 +00:00
|
|
|
.show_pictures_in_profile = true,
|
2014-12-23 23:45:06 +00:00
|
|
|
.tankbar = false,
|
|
|
|
.facebook = {
|
2014-12-24 23:34:23 +00:00
|
|
|
.user_id = NULL,
|
|
|
|
.album_id = NULL,
|
|
|
|
.access_token = NULL
|
2015-01-10 23:01:15 +00:00
|
|
|
},
|
2015-06-12 18:48:56 +00:00
|
|
|
.defaultsetpoint = 1100,
|
2015-06-22 21:44:05 +00:00
|
|
|
.cloud_background_sync = true,
|
|
|
|
.geocoding = {
|
2015-10-05 22:02:55 +00:00
|
|
|
.enable_geocoding = true,
|
2015-06-22 21:44:05 +00:00
|
|
|
.parse_dive_without_gps = false,
|
|
|
|
.tag_existing_dives = false,
|
2015-07-01 19:32:46 +00:00
|
|
|
.category = { 0 }
|
2015-07-03 21:07:58 +00:00
|
|
|
},
|
2016-11-01 13:57:47 +00:00
|
|
|
.locale = {
|
|
|
|
.use_system_language = true,
|
|
|
|
},
|
2017-01-07 02:11:19 +00:00
|
|
|
.planner_deco_mode = BUEHLMANN,
|
2016-09-24 08:02:07 +00:00
|
|
|
.vpmb_conservatism = 3,
|
2015-11-14 17:10:06 +00:00
|
|
|
.distance_threshold = 1000,
|
2016-07-23 03:54:30 +00:00
|
|
|
.time_threshold = 600,
|
2017-06-17 12:17:56 +00:00
|
|
|
#if defined(SUBSURFACE_MOBILE)
|
|
|
|
.cloud_timeout = 10,
|
|
|
|
#else
|
|
|
|
.cloud_timeout = 5,
|
|
|
|
#endif
|
2013-01-11 01:55:44 +00:00
|
|
|
};
|
2011-09-07 02:07:17 +00:00
|
|
|
|
2014-06-14 21:45:42 +00:00
|
|
|
int run_survey;
|
|
|
|
|
2013-05-29 21:00:26 +00:00
|
|
|
struct units *get_units()
|
|
|
|
{
|
|
|
|
return &prefs.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)
|
|
|
|
{
|
2014-02-28 04:09:57 +00:00
|
|
|
const struct dive *a = (const struct dive *)*(void **)_a;
|
|
|
|
const struct dive *b = (const struct dive *)*(void **)_b;
|
2011-08-31 01:40:25 +00:00
|
|
|
|
|
|
|
if (a->when < b->when)
|
|
|
|
return -1;
|
|
|
|
if (a->when > b->when)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-31 03:09:16 +00:00
|
|
|
void sort_table(struct dive_table *table)
|
|
|
|
{
|
|
|
|
qsort(table->dives, table->nr, sizeof(struct dive *), sortfn);
|
|
|
|
}
|
|
|
|
|
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 */
|
2014-02-28 04:09:57 +00:00
|
|
|
QT_TRANSLATE_NOOP("gettextFromC", "Sun"), QT_TRANSLATE_NOOP("gettextFromC", "Mon"), QT_TRANSLATE_NOOP("gettextFromC", "Tue"), QT_TRANSLATE_NOOP("gettextFromC", "Wed"), QT_TRANSLATE_NOOP("gettextFromC", "Thu"), QT_TRANSLATE_NOOP("gettextFromC", "Fri"), QT_TRANSLATE_NOOP("gettextFromC", "Sat")
|
2011-09-20 19:40:34 +00:00
|
|
|
};
|
2014-02-28 04:09:57 +00:00
|
|
|
return translate("gettextFromC", 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*/
|
2014-02-28 04:09:57 +00:00
|
|
|
QT_TRANSLATE_NOOP("gettextFromC", "Jan"), QT_TRANSLATE_NOOP("gettextFromC", "Feb"), QT_TRANSLATE_NOOP("gettextFromC", "Mar"), QT_TRANSLATE_NOOP("gettextFromC", "Apr"), QT_TRANSLATE_NOOP("gettextFromC", "May"), QT_TRANSLATE_NOOP("gettextFromC", "Jun"),
|
|
|
|
QT_TRANSLATE_NOOP("gettextFromC", "Jul"), QT_TRANSLATE_NOOP("gettextFromC", "Aug"), QT_TRANSLATE_NOOP("gettextFromC", "Sep"), QT_TRANSLATE_NOOP("gettextFromC", "Oct"), QT_TRANSLATE_NOOP("gettextFromC", "Nov"), QT_TRANSLATE_NOOP("gettextFromC", "Dec"),
|
2011-09-20 19:40:34 +00:00
|
|
|
};
|
2014-02-28 04:09:57 +00:00
|
|
|
return translate("gettextFromC", month_array[mon]);
|
2011-09-20 19:40:34 +00:00
|
|
|
}
|
|
|
|
|
2011-10-05 21:09:49 +00:00
|
|
|
/*
|
|
|
|
* track whether we switched to importing dives
|
|
|
|
*/
|
2014-01-15 18:54:41 +00:00
|
|
|
bool imported = false;
|
2011-10-05 21:09:49 +00:00
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
static void print_version()
|
|
|
|
{
|
2015-02-15 18:25:18 +00:00
|
|
|
printf("Subsurface v%s, ", subsurface_git_version());
|
2013-05-29 11:50:38 +00:00
|
|
|
printf("built with libdivecomputer v%s\n", dc_version(NULL));
|
|
|
|
}
|
|
|
|
|
2015-09-23 09:13:07 +00:00
|
|
|
void print_files()
|
|
|
|
{
|
2015-10-06 09:10:08 +00:00
|
|
|
const char *branch = 0;
|
|
|
|
const char *remote = 0;
|
2015-09-23 09:13:07 +00:00
|
|
|
const char *filename, *local_git;
|
|
|
|
|
|
|
|
printf("\nFile locations:\n\n");
|
2017-10-26 13:52:45 +00:00
|
|
|
if (!same_string(prefs.cloud_storage_email, "") && !same_string(prefs.cloud_storage_password, "")) {
|
|
|
|
filename = cloud_url();
|
|
|
|
|
|
|
|
is_git_repository(filename, &branch, &remote, true);
|
|
|
|
} else {
|
|
|
|
/* strdup so the free below works in either case */
|
|
|
|
filename = strdup("No valid cloud credentials set.\n");
|
|
|
|
}
|
2015-10-06 09:10:08 +00:00
|
|
|
if (branch && remote) {
|
|
|
|
local_git = get_local_dir(remote, branch);
|
|
|
|
printf("Local git storage: %s\n", local_git);
|
|
|
|
} else {
|
|
|
|
printf("Unable to get local git directory\n");
|
|
|
|
}
|
2017-10-26 13:52:45 +00:00
|
|
|
printf("Cloud URL: %s\n", filename);
|
|
|
|
free((void *)filename);
|
|
|
|
char *tmp = hashfile_name_string();
|
2015-10-06 21:30:06 +00:00
|
|
|
printf("Image hashes: %s\n", tmp);
|
|
|
|
free(tmp);
|
|
|
|
tmp = picturedir_string();
|
|
|
|
printf("Local picture directory: %s\n\n", tmp);
|
|
|
|
free(tmp);
|
2015-09-23 09:13:07 +00:00
|
|
|
}
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
static void print_help()
|
|
|
|
{
|
2013-05-29 11:50:38 +00:00
|
|
|
print_version();
|
|
|
|
printf("\nUsage: subsurface [options] [logfile ...] [--import logfile ...]");
|
|
|
|
printf("\n\noptions include:");
|
|
|
|
printf("\n --help|-h This help text");
|
|
|
|
printf("\n --import logfile ... Logs before this option is treated as base, everything after is imported");
|
|
|
|
printf("\n --verbose|-v Verbose debug (repeat to increase verbosity)");
|
2014-03-25 14:55:56 +00:00
|
|
|
printf("\n --version Prints current version");
|
2014-06-14 21:45:42 +00:00
|
|
|
printf("\n --survey Offer to submit a user survey");
|
2017-01-06 10:23:13 +00:00
|
|
|
printf("\n --user=<test> Choose configuration space for user <test>");
|
|
|
|
printf("\n --cloud-timeout=<nr> Set timeout for cloud connection (0 < timeout < 60)");
|
2017-02-02 19:50:47 +00:00
|
|
|
printf("\n --win32console Create a dedicated console if needed (Windows only). Add option before everything else");
|
|
|
|
printf("\n --win32log Write the program output to subsurface.log (Windows only). Add option before everything else\n\n");
|
2013-05-29 11:50:38 +00:00
|
|
|
}
|
|
|
|
|
2013-09-09 08:59:03 +00:00
|
|
|
void parse_argument(const char *arg)
|
2011-08-31 01:40:25 +00:00
|
|
|
{
|
2014-02-28 04:09:57 +00:00
|
|
|
const char *p = arg + 1;
|
2011-08-31 01:40:25 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
switch (*p) {
|
2013-05-29 11:50:38 +00:00
|
|
|
case 'h':
|
|
|
|
print_help();
|
|
|
|
exit(0);
|
2011-08-31 01:40:25 +00:00
|
|
|
case 'v':
|
|
|
|
verbose++;
|
|
|
|
continue;
|
2013-11-02 19:00:16 +00:00
|
|
|
case 'q':
|
|
|
|
quit++;
|
|
|
|
continue;
|
2011-10-05 18:36:15 +00:00
|
|
|
case '-':
|
|
|
|
/* long options with -- */
|
2016-04-29 13:17:02 +00:00
|
|
|
/* first test for --user=bla which allows the use of user specific settings */
|
|
|
|
if (strncmp(arg, "--user=", sizeof("--user=") - 1) == 0) {
|
|
|
|
settings_suffix = strdup(arg + sizeof("--user=") - 1);
|
|
|
|
return;
|
|
|
|
}
|
2016-07-23 03:54:30 +00:00
|
|
|
if (strncmp(arg, "--cloud-timeout=", sizeof("--cloud-timeout=") - 1) == 0) {
|
|
|
|
const char *timeout = arg + sizeof("--cloud-timeout=") - 1;
|
|
|
|
int to = strtol(timeout, NULL, 10);
|
|
|
|
if (0 < to && to < 60)
|
|
|
|
default_prefs.cloud_timeout = to;
|
|
|
|
return;
|
|
|
|
}
|
2013-05-29 11:50:38 +00:00
|
|
|
if (strcmp(arg, "--help") == 0) {
|
|
|
|
print_help();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
if (strcmp(arg, "--import") == 0) {
|
2014-01-15 18:54:41 +00:00
|
|
|
imported = true; /* mark the dives so far as the base, * everything after is imported */
|
2011-10-05 18:36:15 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-05-29 11:50:38 +00:00
|
|
|
if (strcmp(arg, "--verbose") == 0) {
|
|
|
|
verbose++;
|
|
|
|
return;
|
|
|
|
}
|
2013-05-27 10:15:34 +00:00
|
|
|
if (strcmp(arg, "--version") == 0) {
|
2013-05-29 11:50:38 +00:00
|
|
|
print_version();
|
2013-05-27 10:15:34 +00:00
|
|
|
exit(0);
|
|
|
|
}
|
2014-06-14 21:45:42 +00:00
|
|
|
if (strcmp(arg, "--survey") == 0) {
|
|
|
|
run_survey = true;
|
|
|
|
return;
|
|
|
|
}
|
2016-03-25 08:21:45 +00:00
|
|
|
if (strcmp(arg, "--allow_run_as_root") == 0) {
|
|
|
|
++force_root;
|
|
|
|
return;
|
|
|
|
}
|
2014-03-25 14:55:56 +00:00
|
|
|
if (strcmp(arg, "--win32console") == 0)
|
|
|
|
return;
|
2017-02-02 19:50:47 +00:00
|
|
|
if (strcmp(arg, "--win32log") == 0)
|
|
|
|
return;
|
2014-02-28 04:09:57 +00:00
|
|
|
/* fallthrough */
|
2011-10-30 19:56:28 +00:00
|
|
|
case 'p':
|
|
|
|
/* ignore process serial number argument when run as native macosx app */
|
2013-10-06 15:55:58 +00:00
|
|
|
if (strncmp(arg, "-psQT_TR_NOOP(", 5) == 0) {
|
2011-10-30 19:56:28 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-02-28 04:09:57 +00:00
|
|
|
/* fallthrough */
|
2011-08-31 01:40:25 +00:00
|
|
|
default:
|
|
|
|
fprintf(stderr, "Bad argument '%s'\n", arg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
} while (*++p);
|
|
|
|
}
|
|
|
|
|
2013-01-11 01:55:44 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-09-09 08:59:03 +00:00
|
|
|
void setup_system_prefs(void)
|
2013-01-11 01:55:44 +00:00
|
|
|
{
|
2013-01-12 01:07:22 +00:00
|
|
|
const char *env;
|
2013-01-11 01:55:44 +00:00
|
|
|
|
2014-08-22 22:22:02 +00:00
|
|
|
subsurface_OS_pref_setup();
|
2013-01-12 01:07:22 +00:00
|
|
|
default_prefs.divelist_font = strdup(system_divelist_default_font);
|
2014-03-21 17:56:10 +00:00
|
|
|
default_prefs.font_size = system_divelist_default_font_size;
|
2013-01-12 01:07:22 +00:00
|
|
|
|
2016-04-29 13:17:02 +00:00
|
|
|
#if !defined(SUBSURFACE_MOBILE)
|
|
|
|
default_prefs.default_filename = system_default_filename();
|
|
|
|
#endif
|
2013-01-12 01:07:22 +00:00
|
|
|
env = getenv("LC_MEASUREMENT");
|
2013-01-11 01:55:44 +00:00
|
|
|
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;
|
|
|
|
}
|
2014-12-18 07:47:42 +00:00
|
|
|
|
2015-10-06 09:15:38 +00:00
|
|
|
/* copy a preferences block, including making copies of all included strings */
|
|
|
|
void copy_prefs(struct preferences *src, struct preferences *dest)
|
|
|
|
{
|
|
|
|
*dest = *src;
|
|
|
|
dest->divelist_font = copy_string(src->divelist_font);
|
|
|
|
dest->default_filename = copy_string(src->default_filename);
|
|
|
|
dest->default_cylinder = copy_string(src->default_cylinder);
|
|
|
|
dest->cloud_base_url = copy_string(src->cloud_base_url);
|
|
|
|
dest->cloud_git_url = copy_string(src->cloud_git_url);
|
|
|
|
dest->userid = copy_string(src->userid);
|
|
|
|
dest->proxy_host = copy_string(src->proxy_host);
|
|
|
|
dest->proxy_user = copy_string(src->proxy_user);
|
|
|
|
dest->proxy_pass = copy_string(src->proxy_pass);
|
2015-10-29 23:57:43 +00:00
|
|
|
dest->time_format = copy_string(src->time_format);
|
|
|
|
dest->date_format = copy_string(src->date_format);
|
|
|
|
dest->date_format_short = copy_string(src->date_format_short);
|
2015-10-06 09:15:38 +00:00
|
|
|
dest->cloud_storage_password = copy_string(src->cloud_storage_password);
|
|
|
|
dest->cloud_storage_newpassword = copy_string(src->cloud_storage_newpassword);
|
|
|
|
dest->cloud_storage_email = copy_string(src->cloud_storage_email);
|
|
|
|
dest->cloud_storage_email_encoded = copy_string(src->cloud_storage_email_encoded);
|
|
|
|
dest->facebook.access_token = copy_string(src->facebook.access_token);
|
|
|
|
dest->facebook.user_id = copy_string(src->facebook.user_id);
|
|
|
|
dest->facebook.album_id = copy_string(src->facebook.album_id);
|
|
|
|
}
|
|
|
|
|
2014-12-18 07:47:42 +00:00
|
|
|
/*
|
|
|
|
* Free strduped prefs before exit.
|
|
|
|
*
|
|
|
|
* These are not real leaks but they plug the holes found by eg.
|
|
|
|
* valgrind so you can find the real leaks.
|
|
|
|
*/
|
|
|
|
void free_prefs(void)
|
|
|
|
{
|
2015-11-13 13:20:48 +00:00
|
|
|
// nop
|
2014-12-18 07:47:42 +00:00
|
|
|
}
|