summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/images/DC_import_Bluetooth.jpgbin0 -> 24388 bytes
-rw-r--r--Documentation/user-manual.txt262
-rw-r--r--checkcloudconnection.cpp37
-rw-r--r--checkcloudconnection.h9
-rw-r--r--deco.c2
-rw-r--r--dive.c114
-rw-r--r--dive.h2
-rw-r--r--divesite.c6
-rw-r--r--file.c2
-rw-r--r--git-access.c38
-rw-r--r--libdivecomputer.c2
-rw-r--r--load-git.c2
-rwxr-xr-xpackaging/windows/mxe-based-build.sh130
-rw-r--r--planner.c3
-rw-r--r--qt-ui/divelistview.cpp6
-rw-r--r--qt-ui/maintab.cpp3
-rw-r--r--qt-ui/mainwindow.cpp14
-rw-r--r--qt-ui/mainwindow.h1
-rw-r--r--qt-ui/profile/profilewidget2.cpp4
-rw-r--r--qt-ui/profile/profilewidget2.h2
-rw-r--r--qt-ui/subsurfacewebservices.cpp20
-rw-r--r--qthelper.cpp25
-rw-r--r--qthelperfromc.h1
-rw-r--r--qtserialbluetooth.cpp11
24 files changed, 360 insertions, 336 deletions
diff --git a/Documentation/images/DC_import_Bluetooth.jpg b/Documentation/images/DC_import_Bluetooth.jpg
new file mode 100644
index 000000000..c4ff5fc61
--- /dev/null
+++ b/Documentation/images/DC_import_Bluetooth.jpg
Binary files differ
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 87c138d7e..2340f41de 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -465,6 +465,49 @@ make and model
as well as contextual information about the dives recorded on the dive computer.
****
+[[S_Bluetooth]]
+==== Connecting _Subsurface_ to a Bluetooth-enabled dive computer
+[icon="images/icons/bluetooth.jpg"]
+
+Bluetooth is becoming a more common way of communication between dive computer and _Subsurface_.
+For instance, this mechanism is used by the Shearwater Petrel Mk2 and the OSTC Mk3. _Subsurface_
+provides a largely operating system independent Bluetooth interface. Setting up
+_Subsurface_ for Bluetooth communication requires four steps:
+
+- Ensure that Bluetooth is activated on the host computer running _Subsurface_.
+- Ensure that _Subsurface_ sees the Bluetooth adapter on the host computer.
+- Ensure the Bluetooth-enabled dive computer is Bluetooth-discoverable and in PC upload mode.
+- Ensure that _Subsurface_ is paired with the Bluetooth-enabled dive computer.
+
+Select
+_Import -> Import from dive computer_ from the *Main Menu*. If one checks the check box labelled
+_"Choose Bluetooth download mode"_, the dialogue below appears.
+
+image::images/DC_import_Bluetooth.jpg["FIGURE: Download Bluetooth",align="center"]
+
+On the righthand side, the name of the _Subsurface_ computer and its Bluetooth address are shown.
+If the Bluetooth address is not shown, then _Subsurface_ does not see the local
+Bluetooth device. Ensure that Bluetooth is activated on the _Subsurface_ computer and restart
+_Subsurface_. This achieves the first two steps above.
+
+Ensure that the Bluetooth-enabled dive computer is in PC-upload mode and that it is
+discoverable by other Bluetooth devices. Consult the manual of the dive computer to
+perform this. Now the third item in the list above has been achieved.
+
+Select the _Scan_ button towards the bottom left of the dialogue above. After searching for a small
+amount of time, the dive computer
+should be listed (perhaps as one of a number of Bluetooth devices) in the main list box
+on the lefthand side of the dialogue (see image above). If this is not achieved, select the
+_Clear_ button and then scan again for Bluetooth devices using the _Scan_ button. After
+performing these actions _Subsurface_ sees the dive computer. Now select the dive computer by clicking its name. This
+initiates pairing between _Subsurface_ and the dive computer, thus achieving
+the last item on the list above..
+
+Select the _Save_ button of the dialogue. This closes the Bluetooth dialogue. Now select
+_Download_ in the _Download from dive computer_ dialogue which should still be open.
+The downloaded dives are shown on the righthand side of the download dialogue.
+
+
[[S_DeviceNames]]
==== Changing the name of a dive computer
@@ -2365,9 +2408,8 @@ _Facebook_ connection.
image::images/facebook1_f20.jpg["Figure: Facebook login",align="center"]
Having established a login to _Facebook_, transfer of a dive profile to one's _Facebook_ timeline is easy.
-A _Facebook_ icon appears in the *Notes* panel of _Subsurface_ (See image *A* below). Ensure that the dive
-to transfer to the timeline is depicted in the _Subsurface_ *Dive Profile* panel. Select the
-_Facebook_ icon, and a dialogue is shown, determining the amount of additional information transferred
+Ensure that the dive
+to transfer to the timeline is depicted in the _Subsurface_ *Dive Profile* panel. If one selects _Share on -> Facebook_ from the *Main Menu* a dialogue is shown, determining the amount of additional information transferred
with the dive profile (see image *B*, below). In order to transfer a dive profile to _Facebook_, the name of a
_Facebook_ album needs to be provided. The checkboxes on the lefthand side allow one to determine how much
additional information should be transferred with the dive profile. This information is shown in the text box
@@ -3395,206 +3437,6 @@ to the USB
port, the dive computer interface can connect and one should be able to import
dives.
-[[S_HowFindBluetoothDeviceName]]
-=== Setting up bluetooth enabled devices
-[icon="images/icons/bluetooth.jpg"]
-[NOTE]
-For dive computers communicating through bluetooth like the Heinrichs
-Weikamp Frog or the Shearwater Predator and Petrel there is a
-different procedure to get the devices name to communicate with
-_Subsurface_. Follow these steps:
-
- * *For the dive computer, after enabling Bluetooth, ensure it is in Upload mode.*
-
-For Bluetooth pairing of the dive computer, refer to the
-manufacturer's user guide. When using a Shearwater Predator/Petrel, select
-_Dive Log -> Upload Log_ and wait for the _Wait PC_ message.
-
- * *Pair the _Subsurface_ computer with the dive computer.*
-
-==== On Windows:
-
-Bluetooth is most likely already enabled. For pairing with the dive computer choose
-_Control Panel -> Bluetooth Devices -> Add Wireless Device_.
-This should bring up a dialog showing your dive computer (which should be in Bluetooth mode) and
-allowing pairing. Right click on it and choose _Properties-> COM
-Ports_ to identify the port used for your dive computer. If there are several
-ports listed, use the one saying "Outgoing" instead of "Incoming".
-
-For downloading to _Subsurface_, the _Subsurface_ drop-down list should contain
-this COM port already. If not, enter it manually.
-
-Note: If there are issues afterwards when downloading from the dive computer using
-other software, remove the existing pairing with the dive computer.
-
-==== On MacOS:
-
-Click on the Bluetooth symbol in the menu bar and select _Set up
-Bluetooth Device..._. The dive computer should then show up in the list of devices. Select it and go
-through the pairing process. This step should only be needed once for
-initial setup.
-
-Once the pairing is completed the correct device is shown in the
-'Device or Mount Point' drop-down in the _Subsurface_ *Import* dialog.
-
-==== On Linux
-Ensure Bluetooth is enabled on the _Subsurface_ computer.
-On most common distributions this should be true out of the box and
-pairing should be straight forward. For instance, Gnome3 shows a
-Bluetooth icon on the right of the toolbar at the top of the screen.
-Users have reported difficulties with some Bluetooth controllers. If you have an onboard controller,
-try that first. It is simplest if you remove any USB Bluetooth dongles. If you have a USB dongle that
-came with your dive computer, try that before any others.
-
-Setting up a connection to download dives from your Bluetooth-enabled device, such as the
-_Shearwater Petrel_, is not yet an automated process and will generally require the command prompt.
-It is essentially a three step process.
-
- - Enable the Bluetooth controller and pair your dive computer</li>
- - Establish an RFCOMM connection
- - Download the dives with Subsurface
-
-Ensure the dive computer is in upload mode. On the _Shearwater Petrel_ and _Petrel 2_,
-cycle through the menu, select 'Dive Log', then 'Upload Log'. The display will read 'Initializing', then
-'Wait PC 3:00' and will countdown. Once the connection is established, the display reads 'Wait CMD ...'
-and the countdown continues. When downloading the dive from Subsurface, the display reads 'Sending' then
-'Sent Dive'.
-
-To establish the connection, establish root access through +sudo+ or +su+.
-The correct permission is required to download the dives in the computer. On most Linux systems this means becoming
-a member of the dialout group (This is identical as for many dive computers using a Linux USB port, descibed
-in the previous section). On the command terminal, enter:
-
-+sudo usermod -a -G dialout username+
-
-Then log out and log in for the change to take effect.
-
-===== Enabling the Bluetooth controller and pairing your dive computer
-
-Attempt to set up the Bluetooth controller and pair your dive computer using the graphical
-environment of the operating system. After setting the dive computer to upload mode, click the Bluetooth icon in the system tray
-and select 'Add new device'. The dive computer should appear. If asked for a password, enter 0000.
-Write down or copy the MAC address of your dive computer - this needed later and should be in the form 00:11:22:33:44:55.
-
-If the graphical method didn't work, pair the device from the command line. Open a terminal
-and use +hciconfig+ to check the Bluetooth controller status
-
- $ hciconfig
- hci0: Type: BR/EDR Bus: USB
- BD Address: 01:23:45:67:89:AB ACL MTU: 310:10 SCO MTU: 64:8
- *DOWN*
- RX bytes:504 acl:0 sco:0 events:22 errors:0
- TX bytes:92 acl:0 sco:0 commands:21 errors:0
-
-This indicates a Bluetooth controller with MAC address 01:23:45:67:89:AB, connected as hci0.
-Its status is 'DOWN', i.e. not powered. Additional controllers will appear as hci1, etc.
-If there is not a Bluetooth dongle plugged in upon booting the computer, hci0 is probably the onboard.
-Now power on the controller and enable authentication:
-
- sudo hciconfig hci0 up auth+ (enter password when prompted)
- hciconfig
- hci0: Type: BR/EDR Bus: USB
- BD Address: 01:23:45:67:89:AB ACL MTU: 310:10 SCO MTU: 64:8
- *UP RUNNING PSCAN AUTH*
- RX bytes:1026 acl:0 sco:0 events:47 errors:0
- TX bytes:449 acl:0 sco:0 commands:46 errors:0
-
-+Check that the status now includes +'UP', 'RUNNING' AND 'AUTH'+.
-
-If there are multiple controllers running, it's easiest to off the unused controller(s). For example, for +hci1+:
-
- sudo hciconfig hci1 down
-
-Next step is to 'trust' and 'pair' the dive computer. On distros with Bluez 5, such as Fedora 22,
-one can use a tool called +blutootctl+, which will bring up its own command prompt.
-
- bluetoothctl
- [NEW] Controller 01:23:45:67:89:AB localhost.localdomain [default]
- [bluetooth]# agent on
- Agent registered
- [bluetooth]# default-agent
- Default agent request successful
- [bluetooth]# scan on <----now set your dive computer to upload mode
- Discovery started
- [CHG] Controller 01:23:45:67:89:AB Discovering: yes
- [NEW] Device 00:11:22:33:44:55 Petrel
- [bluetooth]# trust 00:11:22:33:44:55 <----you can use the tab key to autocomplete the MAC address
- [CHG] Device 00:11:22:33:44:55 Trusted: yes
- Changing 00:11:22:33:44:55 trust succeeded
- [bluetooth]# pair 00:11:22:33:44:55
- Attempting to pair with 00:11:22:33:44:55
- [CHG] Device 00:11:22:33:44:55 Connected: yes
- [CHG] Device 00:11:22:33:44:55 UUIDs: 00001101-0000-1000-8000-0089abc12345
- [CHG] Device 00:11:22:33:44:55 Paired: yes
- Pairing successful
- [CHG] Device 00:11:22:33:44:55 Connected: no
-
-If asked for a password, enter 0000. It's ok if the last line says 'Connected: no'. The important part
-is the line above, +Pairing successful+.
-
-If the system has Bluez version 4 (e.g. Ubuntu 12.04 through to 15.04), there is probably not a
-+bluetoothctl+, but a script called +bluez-simple-agent+ or just +simple-agent+.
-
- hcitool -i hci0 scanning
- Scanning ...
- 00:11:22:33:44:55 Petrel
- bluez-simple-agent hci0 00:11:22:33:44:55
-
-Once ther dive computer is pired, set up the RFCOMM connection
-
-===== Establishing the RFCOMM connection
-
-The command to establish an RFCOMM connection is:
-
-+sudo rfcomm -i <controller> connect <dev> <bdaddr> [channel]+
-
-- <controller>+ is the Bluetooth controller, +hci0+.
-- <dev> is the RFCOMM device file, +rfcomm0+
-- <bdaddr> is the dive computer's MAC address, +00:11:22:33:44:55+
-- [channel] is the dive computer's Bluetooth channel we need to connect to.
-
-If one omits it, channel 1 is assumed. Based on a limited number of user reports,
-the appropriate channel for the dive computer is probably:
-
-- _Shearwater Petrel 2_: channel 5
-- _Shearwater Petrel 1_: channel 1
-- _Heinrichs-Weikamp OSTC Sport_: channel 1
-
-E.g. to connect a _Shearwater Petrel 2_, set the dive computer to upload mode and enter:
-
- sudo rfcomm -i hci0 connect rfcomm0 00:11:22:33:44:55 5 (enter a password, probably 0000, when prompted)
-
-This gives the response:
-
- Connected /dev/rfcomm0 to 00:11:22:33:44:55 on channel 5
- Press CTRL-C for hangup
-
-To connect a _Shearwater Petrel 1+ or + HW OSTC Sport+, set the dive computer to upload mode and enter:
-
- sudo rfcomm -i hci0 connect rfcomm0 00:11:22:33:44:55 (enter a password, probably 0000, when prompted)
- Connected /dev/rfcomm0 to 00:11:22:33:44:55 on channel 1
- Press CTRL-C for hangup
-
-If the specific channel the dive computer needs is not known, or the channel in the list above doesn't
-work, the command +sdptool records+ should help determine the appropriate channel. The output
-below is for a _Shearwater Petrel 2_.
-
- sdptool -i hci0 records 00:11:22:33:44:55
- Service Name: Serial Port
- Service RecHandle: 0x10000
- Service Class ID List:
- "Serial Port" (0x1101)
- Protocol Descriptor List:
- "L2CAP" (0x0100)
- "RFCOMM" (0x0003)
- Channel: 5
-
-For a Bluetooth dive computer not in the list above, or if the channel listed is not correct, please
-let the Subsurface developers know on the user forum or the developer mailing list _subsurface@subsurface-divelog.org_.
-
-===== Download the dives with Subsurface</em>
-After establishing the RFCOMM connection and while the dive computer's upload mode countdown is still running, go to_Subsurface_, select _Import->Import from dive computer_ and enter appropriate Vendor (e.g. _Shearwater_), Dive Computer (_Petrel_), Device or Mount Point (_/dev/rfcomm0_) and click _Download_.
-
[[_appendix_b_dive_computer_specific_information_for_importing_dive_information]]
== APPENDIX B: Dive Computer specific information for importing dive data.
@@ -3694,21 +3536,11 @@ _Subsurface_ *Dive Profile* panel but please note that the deco calculated by
_Subsurface_ will most likely differ from the one displayed on the xDEEP BLACK.
-=== Importing from Shearwater Predator using Bluetooth
+=== Importing from Shearwater Predator/Petrel using Bluetooth
[icon="images/icons/predator.jpg"]
[NOTE]
-Using a Shearwater Predator one may be able to pair Bluetooth but then encounter
-issues when downloading, showing errors like _Slip RX: unexp. SLIP END_ on the
-Predator.
-This might also arise when using other dive log software and operating
-systems other than Linux. We have no detailed idea about the source and how to fix
-this, but it is reported to be solved sometimes by one of these steps:
-
- * use the Bluetooth dongle which came with the Shearwater Predator instead of
- the built-in one of the _Subsurface_ computer
- * switch to different Bluetooth drivers for the same hardware
- * switch off WiFi while using Bluetooth
+Specific instructions for downloading dives using Bluetooth are given in the section above, <<S_Bluetooth,_Connecting Subsurface to a Bluetooth-enabled dive computer_>>.
[[S_PoseidonMkVI]]
=== Importing from Poseidon MkVI Discovery
diff --git a/checkcloudconnection.cpp b/checkcloudconnection.cpp
index ef37c6a55..b780453fc 100644
--- a/checkcloudconnection.cpp
+++ b/checkcloudconnection.cpp
@@ -28,9 +28,10 @@ bool CheckCloudConnection::checkServer()
request.setRawHeader("User-Agent", getUserAgent().toUtf8());
request.setUrl(QString(prefs.cloud_base_url) + TEAPOT);
QNetworkAccessManager *mgr = new QNetworkAccessManager();
- QNetworkReply *reply = mgr->get(request);
+ reply = mgr->get(request);
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
+ connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
timer.start(2000); // wait two seconds
loop.exec();
if (timer.isActive()) {
@@ -44,14 +45,15 @@ bool CheckCloudConnection::checkServer()
qWarning() << "Cloud storage: successfully checked connection to cloud server";
return true;
}
- // qDebug() << "did not get expected response - server unreachable" <<
- // reply->error() << reply->errorString() <<
- // reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() <<
- // reply->readAll();
} else {
disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
reply->abort();
}
+ if (verbose)
+ qDebug() << "connection test to cloud server failed" <<
+ reply->error() << reply->errorString() <<
+ reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() <<
+ reply->readAll();
reply->deleteLater();
mgr->deleteLater();
if (verbose)
@@ -59,10 +61,33 @@ bool CheckCloudConnection::checkServer()
return false;
}
+void CheckCloudConnection::sslErrors(QList<QSslError> errorList)
+{
+ if (verbose) {
+ qDebug() << "Received error response trying to set up https connection with cloud storage backend:";
+ Q_FOREACH (QSslError err, errorList) {
+ qDebug() << err.errorString();
+ }
+ }
+ QSslConfiguration conf = reply->sslConfiguration();
+ QSslCertificate cert = conf.peerCertificate();
+ QByteArray hexDigest = cert.digest().toHex();
+ if (reply->url().toString().contains(prefs.cloud_base_url) &&
+ hexDigest == "13ff44c62996cfa5cd69d6810675490e") {
+ if (verbose)
+ qDebug() << "Overriding SSL check as I recognize the certificate digest" << hexDigest;
+ reply->ignoreSslErrors();
+ } else {
+ if (verbose)
+ qDebug() << "got invalid SSL certificate with hex digest" << hexDigest;
+ }
+}
+
// helper to be used from C code
extern "C" bool canReachCloudServer()
{
if (verbose)
qWarning() << "Cloud storage: checking connection to cloud server";
- return CheckCloudConnection::checkServer();
+ CheckCloudConnection *checker = new CheckCloudConnection;
+ return checker->checkServer();
}
diff --git a/checkcloudconnection.h b/checkcloudconnection.h
index 6c85203ac..58a412797 100644
--- a/checkcloudconnection.h
+++ b/checkcloudconnection.h
@@ -2,6 +2,8 @@
#define CHECKCLOUDCONNECTION_H
#include <QObject>
+#include <QNetworkReply>
+#include <QSsl>
#include "checkcloudconnection.h"
@@ -9,7 +11,12 @@ class CheckCloudConnection : public QObject {
Q_OBJECT
public:
CheckCloudConnection(QObject *parent = 0);
- static bool checkServer();
+ bool checkServer();
+private:
+ QNetworkReply *reply;
+private
+slots:
+ void sslErrors(QList<QSslError> errorList);
};
#endif // CHECKCLOUDCONNECTION_H
diff --git a/deco.c b/deco.c
index 39a6b348c..f9d60326d 100644
--- a/deco.c
+++ b/deco.c
@@ -369,7 +369,6 @@ double calc_surface_phase(double surface_pressure, double he_pressure, double n2
void vpmb_start_gradient()
{
int ci;
- double gradient_n2, gradient_he;
for (ci = 0; ci < 16; ++ci) {
initial_n2_gradient[ci] = bottom_n2_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / n2_regen_radius[ci]);
@@ -380,7 +379,6 @@ void vpmb_start_gradient()
void vpmb_next_gradient(double deco_time, double surface_pressure)
{
int ci;
- double gradient_n2, gradient_he;
double n2_b, n2_c;
double he_b, he_c;
double desat_time;
diff --git a/dive.c b/dive.c
index 10ce63859..0248888a3 100644
--- a/dive.c
+++ b/dive.c
@@ -2743,28 +2743,48 @@ int count_dives_with_suit(const char *suit)
return counter;
}
-
+/*
+ * Merging two dives can be subtle, because there's two different ways
+ * of merging:
+ *
+ * (a) two distinctly _different_ dives that have the same dive computer
+ * are merged into one longer dive, because the user asked for it
+ * in the divelist.
+ *
+ * Because this case is with teh same dive computer, we *know* the
+ * two must have a different start time, and "offset" is the relative
+ * time difference between the two.
+ *
+ * (a) two different dive computers that we migth want to merge into
+ * one single dive with multiple dive computers.
+ *
+ * This is the "try_to_merge()" case, which will have offset == 0,
+ * even if the dive times migth be different.
+ */
struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded)
{
struct dive *res = alloc_dive();
struct dive *dl = NULL;
- /* Aim for newly downloaded dives to be 'b' (keep old dive data first) */
- if (a->downloaded && !b->downloaded) {
- struct dive *tmp = a;
- a = b;
- b = tmp;
+ if (offset) {
+ /*
+ * If "likely_same_dive()" returns true, that means that
+ * it is *not* the same dive computer, and we do not want
+ * to try to turn it into a single longer dive. So we'd
+ * join them as two separate dive computers at zero offset.
+ */
+ if (likely_same_dive(a, b))
+ offset = 0;
+ } else {
+ /* Aim for newly downloaded dives to be 'b' (keep old dive data first) */
+ if (a->downloaded && !b->downloaded) {
+ struct dive *tmp = a;
+ a = b;
+ b = tmp;
+ }
+ if (prefer_downloaded && b->downloaded)
+ dl = b;
}
- if (prefer_downloaded && b->downloaded)
- dl = b;
-
- /*
- * Did the user ask us to merge dives in the dive list?
- * We may want to just join the dive computers, not try to
- * interleave them at some offset.
- */
- if (offset && likely_same_dive(a, b))
- offset = 0;
res->when = dl ? dl->when : a->when;
res->selected = a->selected || b->selected;
@@ -2793,6 +2813,56 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer
return res;
}
+/*
+ * "dc_maxtime()" is how much total time this dive computer
+ * has for this dive. Note that it can differ from "duration"
+ * if there are surface events in the middle.
+ *
+ * Still, we do ignore all but the last surface samples from the
+ * end, because some divecomputers just generate lots of them.
+ */
+static inline int dc_totaltime(const struct divecomputer *dc)
+{
+ int time = dc->duration.seconds;
+ int nr = dc->samples;
+
+ while (nr--) {
+ struct sample *s = dc->sample + nr;
+ time = s->time.seconds;
+ if (s->depth.mm >= SURFACE_THRESHOLD)
+ break;
+ }
+ return time;
+}
+
+/*
+ * The end of a dive is actually not trivial, because "duration"
+ * is not the duration until the end, but the time we spend under
+ * water, which can be very different if there are surface events
+ * during the dive.
+ *
+ * So walk the dive computers, looking for the longest actual
+ * time in the samples (and just default to the dive duration if
+ * there are no samples).
+ */
+static inline int dive_totaltime(const struct dive *dive)
+{
+ int time = dive->duration.seconds;
+ const struct divecomputer *dc;
+
+ for_each_dc(dive, dc) {
+ int dc_time = dc_totaltime(dc);
+ if (dc_time > time)
+ time = dc_time;
+ }
+ return time;
+}
+
+timestamp_t dive_endtime(const struct dive *dive)
+{
+ return dive->when + dive_totaltime(dive);
+}
+
struct dive *find_dive_including(timestamp_t when)
{
int i;
@@ -2802,7 +2872,7 @@ struct dive *find_dive_including(timestamp_t when)
* also we always use the duration from the first divecomputer
* could this ever be a problem? */
for_each_dive (i, dive) {
- if (dive->when <= when && when <= dive->when + dive->duration.seconds)
+ if (dive->when <= when && when <= dive_endtime(dive))
return dive;
}
return NULL;
@@ -2810,12 +2880,16 @@ struct dive *find_dive_including(timestamp_t when)
bool time_during_dive_with_offset(struct dive *dive, timestamp_t when, timestamp_t offset)
{
- return dive->when - offset <= when && when <= dive->when + dive->duration.seconds + offset;
+ timestamp_t start = dive->when;
+ timestamp_t end = dive_endtime(dive);
+ return start - offset <= when && when <= end + offset;
}
bool dive_within_time_range(struct dive *dive, timestamp_t when, timestamp_t offset)
{
- return when - offset <= dive->when && dive->when + dive->duration.seconds <= when + offset;
+ timestamp_t start = dive->when;
+ timestamp_t end = dive_endtime(dive);
+ return when - offset <= start && end <= when + offset;
}
/* find the n-th dive that is part of a group of dives within the offset around 'when'.
@@ -2970,7 +3044,7 @@ bool dive_check_picture_time(struct dive *d, int shift_time, timestamp_t timesta
offset_t offset;
if (timestamp) {
offset.seconds = timestamp - d->when + shift_time;
- if (offset.seconds > -D30MIN && offset.seconds < (int)d->duration.seconds + D30MIN) {
+ if (offset.seconds > -D30MIN && offset.seconds < dive_totaltime(d) + D30MIN) {
// this picture belongs to this dive
return true;
}
diff --git a/dive.h b/dive.h
index 4eb44cfc9..3bcc7b0e2 100644
--- a/dive.h
+++ b/dive.h
@@ -562,6 +562,8 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
return dc;
}
+extern timestamp_t dive_endtime(const struct dive *dive);
+
extern void make_first_dc(void);
extern int count_divecomputers(void);
extern void delete_current_divecomputer(void);
diff --git a/divesite.c b/divesite.c
index a8c5ea4be..f668889f3 100644
--- a/divesite.c
+++ b/divesite.c
@@ -55,7 +55,6 @@ uint32_t get_dive_site_uuid_by_gps_and_name(char *name, degrees_t latitude, degr
// Calculate the distance in meters between two coordinates.
unsigned int get_distance(degrees_t lat1, degrees_t lon1, degrees_t lat2, degrees_t lon2)
{
- double lat1_r = udeg_to_radians(lat1.udeg);
double lat2_r = udeg_to_radians(lat2.udeg);
double lat_d_r = udeg_to_radians(lat2.udeg-lat1.udeg);
double lon_d_r = udeg_to_radians(lon2.udeg-lon1.udeg);
@@ -304,12 +303,9 @@ uint32_t find_or_create_dive_site_with_name(const char *name, timestamp_t diveti
{
int i;
struct dive_site *ds;
- bool found = false;
for_each_dive_site(i,ds) {
- if (same_string(name, ds->name)) {
- found = true;
+ if (same_string(name, ds->name))
break;
- }
}
if (ds)
return ds->uuid;
diff --git a/file.c b/file.c
index a7a340f09..a7b407f6d 100644
--- a/file.c
+++ b/file.c
@@ -844,7 +844,6 @@ int parse_csv_file(const char *filename, char **params, int pnr, const char *csv
struct memblock mem;
time_t now;
struct tm *timep = NULL;
- int previous;
char tmpbuf[MAXCOLDIGITS];
/* Increase the limits for recursion and variables on XSLT
@@ -889,7 +888,6 @@ int parse_csv_file(const char *filename, char **params, int pnr, const char *csv
fprintf(stderr, "%s/xslt/csv2xml.xslt -\n", SUBSURFACE_SOURCE);
}
- previous = dive_table.nr;
ret = parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params);
free(mem.buffer);
diff --git a/git-access.c b/git-access.c
index cd371cf9b..aa7d38776 100644
--- a/git-access.c
+++ b/git-access.c
@@ -115,6 +115,12 @@ char *get_local_dir(const char *remote, const char *branch)
hash[4], hash[5], hash[6], hash[7]);
}
+static char *move_local_cache(const char *remote, const char *branch)
+{
+ char *old_path = get_local_dir(remote, branch);
+ return move_away(old_path);
+}
+
static int check_clean(const char *path, unsigned int status, void *payload)
{
status &= ~GIT_STATUS_CURRENT | GIT_STATUS_IGNORED;
@@ -371,7 +377,19 @@ write_error:
return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: writing the data failed (%s)"), giterr_last()->message);
}
-static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, enum remote_transport rt)
+// if accessing the local cache of Subsurface cloud storage fails, we simplify things
+// for the user and simply move the cache away (in case they want to try and extract data)
+// and ask them to retry the operation (which will then refresh the data from the cloud server)
+static int cleanup_local_cache(const char *remote_url, const char *branch)
+{
+ char *backup_path = move_local_cache(remote_url, branch);
+ report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
+ report_error(translate("gettextFromC", "Moved cache data to %s. Please try the operation again."), backup_path);
+ free(backup_path);
+ return -1;
+}
+static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote,
+ const char *remote_url, const char *branch, enum remote_transport rt)
{
git_oid base;
const git_oid *local_id, *remote_id;
@@ -431,11 +449,13 @@ static int try_to_update(git_repository *repo, git_remote *origin, git_reference
return try_to_git_merge(repo, local, remote, &base, local_id, remote_id);
cloud_data_error:
- return report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
-
+ // since we are working with Subsurface cloud storage we want to make the user interaction
+ // as painless as possible. So if something went wrong with the local cache, tell the user
+ // about it an move it away
+ return cleanup_local_cache(remote_url, branch);
}
-static int check_remote_status(git_repository *repo, git_remote *origin, const char *branch, enum remote_transport rt)
+static int check_remote_status(git_repository *repo, git_remote *origin, const char *remote, const char *branch, enum remote_transport rt)
{
int error = 0;
@@ -446,7 +466,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c
if (git_branch_lookup(&local_ref, repo, branch, GIT_BRANCH_LOCAL)) {
if (is_subsurface_cloud)
- report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
+ return cleanup_local_cache(remote, branch);
else
return report_error("Git cache branch %s no longer exists", branch);
}
@@ -468,7 +488,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c
error = git_remote_push(origin, &refspec, NULL);
#endif
} else {
- error = try_to_update(repo, origin, local_ref, remote_ref, rt);
+ error = try_to_update(repo, origin, local_ref, remote_ref, remote, branch, rt);
git_reference_free(remote_ref);
}
git_reference_free(local_ref);
@@ -529,7 +549,7 @@ int sync_with_remote(git_repository *repo, const char *remote, const char *branc
report_error("Unable to fetch remote '%s'", remote);
error = 0;
} else {
- error = check_remote_status(repo, origin, branch, rt);
+ error = check_remote_status(repo, origin, remote, branch, rt);
}
git_remote_free(origin);
return error;
@@ -546,7 +566,7 @@ static git_repository *update_local_repo(const char *localdir, const char *remot
error = git_repository_open(&repo, localdir);
if (error) {
if (is_subsurface_cloud)
- report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
+ (void)cleanup_local_cache(remote, branch);
else
report_error("Unable to open git cache repository at %s: %s", localdir, giterr_last()->message);
return NULL;
@@ -679,7 +699,7 @@ static struct git_repository *get_remote_repo(const char *localdir, const char *
if (!stat(localdir, &st)) {
if (!S_ISDIR(st.st_mode)) {
if (is_subsurface_cloud)
- report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
+ (void)cleanup_local_cache(remote, branch);
else
report_error("local git cache at '%s' is corrupt");
return NULL;
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 631e0dade..26f5e59bd 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -614,8 +614,6 @@ static int dive_cb(const unsigned char *data, unsigned int size,
int rc;
dc_parser_t *parser = NULL;
device_data_t *devdata = userdata;
- dc_datetime_t dt = { 0 };
- struct tm tm;
struct dive *dive = NULL;
/* reset the deco / ndl data */
diff --git a/load-git.c b/load-git.c
index e6e0840ab..d50a53d6c 100644
--- a/load-git.c
+++ b/load-git.c
@@ -306,7 +306,7 @@ static void parse_site_geo(char *line, struct membuffer *str, void *_ds)
if (nr < TC_NR_CATEGORIES) {
struct taxonomy *t = &ds->taxonomy.category[nr];
t->value = strdup(mb_cstring(str));
- sscanf(line, "cat %d origin %d \"", &t->category, &t->origin);
+ sscanf(line, "cat %d origin %d \"", &t->category, (int *)&t->origin);
ds->taxonomy.nr++;
}
}
diff --git a/packaging/windows/mxe-based-build.sh b/packaging/windows/mxe-based-build.sh
index 7d88f085d..ec9deee91 100755
--- a/packaging/windows/mxe-based-build.sh
+++ b/packaging/windows/mxe-based-build.sh
@@ -23,7 +23,7 @@
#
# now you can start the build
#
-# make libxml2 libxslt libusb1 qt5
+# make libxml2 libxslt libusb1 qt5 nsis
#
# after qtbase has finished building you need to edit
# ~/src/win/mxe/usr/i686-w64-mingw32.shared/qt5/mkspecs/qconfig.pri
@@ -126,10 +126,10 @@ exec 1> >(tee ./winbuild.log) 2>&1
# this is run on a rather powerful machine - if you want less
# build parallelism, please change this variable
JOBS="-j12"
-BASEDIR=$(cd "`dirname $0`/.."; pwd)
-BUILDDIR=$(cd "`dirname $0`"; pwd)
+BASEDIR=$(cd "$(dirname $0)/.."; pwd)
+BUILDDIR=$(cd "$(dirname $0)"; pwd)
-if [[ ! -d $BASEDIR/mxe ]] ; then
+if [[ ! -d "$BASEDIR"/mxe ]] ; then
echo "Please start this from the right directory "
echo "usually a winbuild directory parallel to the mxe directory"
exit 1
@@ -137,20 +137,26 @@ fi
echo "Building in $BUILDDIR ..."
-export PATH=$BASEDIR/mxe/usr/bin:$PATH:$BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/bin/
+export PATH="$BASEDIR"/mxe/usr/bin:$PATH:"$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/bin/
+if [[ "$1" == "debug" ]] ; then
+ RELEASE="Debug"
+ shift
+else
+ RELEASE="Release"
+fi
# grantlee
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d grantlee || -f build.grantlee ]] ; then
rm -f build.grantlee
mkdir -p grantlee
cd grantlee
- cmake -DCMAKE_TOOLCHAIN_FILE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
- -DCMAKE_BUILD_TYPE=Release \
+ cmake -DCMAKE_TOOLCHAIN_FILE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+ -DCMAKE_BUILD_TYPE=$RELEASE \
-DBUILD_TESTS=OFF \
- $BASEDIR/grantlee
+ "$BASEDIR"/grantlee
make $JOBS
make install
@@ -159,33 +165,34 @@ fi
# libssh2:
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d libssh2 || -f build.libssh2 ]] ; then
rm -f build.libssh2
mkdir -p libssh2
cd libssh2
- cmake -DCMAKE_TOOLCHAIN_FILE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+ cmake -DCMAKE_TOOLCHAIN_FILE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+ -DCMAKE_BUILD_TYPE=$RELEASE \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=ON \
- $BASEDIR/libssh2
+ "$BASEDIR"/libssh2
make $JOBS
make install
# don't install your dlls in bin, please
- cp $BASEDIR/mxe/usr/i686-w64-mingw32.shared/bin/libssh2.dll $BASEDIR/mxe/usr/i686-w64-mingw32.shared/lib
+ cp "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/bin/libssh2.dll "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/lib
fi
# libcurl
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d libcurl || -f build.libcurl ]] ; then
rm -f build.libcurl
mkdir -p libcurl
cd libcurl
../../libcurl/configure --host=i686-w64-mingw32.shared \
- --prefix=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/ \
+ --prefix="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/ \
--disable-ftp \
--disable-ldap \
--disable-ldaps \
@@ -200,7 +207,7 @@ if [[ ! -d libcurl || -f build.libcurl ]] ; then
--disable-smtp \
--disable-gopher \
--disable-manual \
- --with-libssh2=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/
+ --with-libssh2="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/
# now remove building the executable
sed -i 's/SUBDIRS = lib src include/SUBDIRS = lib include/' Makefile
@@ -212,15 +219,15 @@ fi
# libzip
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d libzip || -f build.libzip ]] ; then
rm -f build.libzip
mkdir -p libzip
cd libzip
-# cmake -DCMAKE_TOOLCHAIN_FILE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+# cmake -DCMAKE_TOOLCHAIN_FILE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
# -DCMAKE_BUILD_TYPE=Release \
-# $BASEDIR/libzip
- $BASEDIR/libzip/configure --host=i686-w64-mingw32.shared --prefix=$BASEDIR/mxe/usr/i686-w64-mingw32.shared
+# "$BASEDIR"/libzip
+ "$BASEDIR"/libzip/configure --host=i686-w64-mingw32.shared --prefix="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared
make $JOBS
make install
fi
@@ -228,15 +235,16 @@ fi
# libgit2:
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d libgit2 || -f build.libgit2 ]] ; then
rm -f build.libgit2
mkdir -p libgit2
cd libgit2
- cmake -DCMAKE_TOOLCHAIN_FILE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+ cmake -DCMAKE_TOOLCHAIN_FILE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
-DBUILD_CLAR=OFF -DTHREADSAFE=ON \
- -DDLLTOOL=$BASEDIR/mxe/usr/bin/i686-w64-mingw32.shared-dlltool \
- $BASEDIR/libgit2
+ -DCMAKE_BUILD_TYPE=$RELEASE \
+ -DDLLTOOL="$BASEDIR"/mxe/usr/bin/i686-w64-mingw32.shared-dlltool \
+ "$BASEDIR"/libgit2
make $JOBS
make install
fi
@@ -245,21 +253,21 @@ fi
#
# this one is special because we want to make sure it's in sync
# with the Linux builds, but we don't want the autoconf files cluttering
-# the original source directory... so the $BASEDIR/libdivecomputer is
+# the original source directory... so the "$BASEDIR"/libdivecomputer is
# a local clone of the "real" libdivecomputer directory
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d libdivecomputer || -f build.libdivecomputer ]] ; then
rm build.libdivecomputer
- cd $BASEDIR/libdivecomputer
+ cd "$BASEDIR"/libdivecomputer
git pull
- cd $BUILDDIR
+ cd "$BUILDDIR"
mkdir -p libdivecomputer
cd libdivecomputer
- $BASEDIR/libdivecomputer/configure --host=i686-w64-mingw32.shared \
+ "$BASEDIR"/libdivecomputer/configure --host=i686-w64-mingw32.shared \
--enable-static --disable-shared \
- --prefix=$BASEDIR/mxe/usr/i686-w64-mingw32.shared
+ --prefix="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared
make $JOBS
make install
else
@@ -274,67 +282,79 @@ fi
# marble:
-cd $BUILDDIR
+cd "$BUILDDIR"
if [[ ! -d marble || -f build.marble ]] ; then
rm build.marble
mkdir -p marble
cd marble
- cmake -DCMAKE_TOOLCHAIN_FILE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
- -DCMAKE_PREFIX_PATH=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5 \
+ cmake -DCMAKE_TOOLCHAIN_FILE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+ -DCMAKE_PREFIX_PATH="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5 \
-DQTONLY=ON -DQT5BUILD=ON \
-DBUILD_MARBLE_APPS=OFF -DBUILD_MARBLE_EXAMPLES=OFF \
-DBUILD_MARBLE_TESTS=OFF -DBUILD_MARBLE_TOOLS=OFF \
-DBUILD_TESTING=OFF -DWITH_DESIGNER_PLUGIN=OFF \
-DBUILD_WITH_DBUS=OFF \
- $BASEDIR/marble-source
+ -DCMAKE_BUILD_TYPE=$RELEASE \
+ "$BASEDIR"/marble-source
make $JOBS
make install
# what the heck is marble doing?
- mv $BASEDIR/mxe/usr/i686-w64-mingw32.shared/libssrfmarblewidget.dll $BASEDIR/mxe/usr/i686-w64-mingw32.shared/lib
+ mv "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/libssrfmarblewidget.dll "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/lib
fi
###############
# finally, Subsurface
-cd $BUILDDIR
+cd "$BUILDDIR"
+
+# things go weird if we don't create a new build directory... Subsurface
+# suddenly gets linked against Qt5Guid.a etc...
+rm -rf subsurface
+
+# first copy the Qt plugins in place
mkdir -p subsurface/staging/plugins
cd subsurface/staging/plugins
-cp -a $BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/iconengines .
-cp -a $BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/imageformats .
-cp -a $BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/platforms .
-cp -a $BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/printsupport .
+cp -a "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/iconengines .
+cp -a "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/imageformats .
+cp -a "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/platforms .
+cp -a "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/plugins/printsupport .
+
+# for some reason we aren't installing libssrfmarblewidget.dll and # Qt5Xml.dll
+# I need to figure out why and fix that, but for now just manually copy that as well
+cp "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/lib/libssrfmarblewidget.dll "$BUILDDIR"/subsurface/staging
+cp "$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/bin/Qt5Xml.dll "$BUILDDIR"/subsurface/staging
-cd $BUILDDIR/subsurface
+cd "$BUILDDIR"/subsurface
if [[ "$1" == "qmake" ]] ; then
shift
- export objdump=$BASEDIR/mxe/usr/bin/i686-w64-mingw32.shared-objdump
+ export objdump="$BASEDIR"/mxe/usr/bin/i686-w64-mingw32.shared-objdump
i686-w64-mingw32.shared-qmake-qt5 \
LIBMARBLEDEVEL=../marble \
LIBGIT2DEVEL=../libgit2 CONFIG+=libgit21-api \
- CROSS_PATH=$BASEDIR/mxe/usr/i686-w64-mingw32.shared \
- QMAKE_LRELEASE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/bin/lrelease \
+ CROSS_PATH="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared \
+ QMAKE_LRELEASE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/bin/lrelease \
SPECIAL_MARBLE_PREFIX=1 \
MAKENSIS=i686-w64-mingw32.shared-makensis \
- $BASEDIR/../subsurface/subsurface.pro
+ "$BASEDIR"/../subsurface/subsurface.pro
# LIBDCDEVEL=../libdivecomputer \
else
- cmake -DCMAKE_TOOLCHAIN_FILE=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
- -DCMAKE_PREFIX_PATH=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5 \
- -DCMAKE_BUILD_TYPE=Release \
- -DQT_TRANSLATION_DIR=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/qt5/translations \
+ cmake -DCMAKE_TOOLCHAIN_FILE="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake \
+ -DCMAKE_PREFIX_PATH="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5 \
+ -DCMAKE_BUILD_TYPE=$RELEASE \
+ -DQT_TRANSLATION_DIR="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/qt5/translations \
-DMAKENSIS=i686-w64-mingw32.shared-makensis \
-DUSE_LIBGIT23_API=1 \
- -DLIBDIVECOMPUTER_INCLUDE_DIR=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/include \
- -DLIBDIVECOMPUTER_LIBRARIES=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/lib/libdivecomputer.a \
- -DMARBLE_INCLUDE_DIR=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/include \
- -DMARBLE_LIBRARIES=$BASEDIR/mxe/usr/i686-w64-mingw32.shared/lib/libssrfmarblewidget.dll \
- $BASEDIR/subsurface
+ -DLIBDIVECOMPUTER_INCLUDE_DIR="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/include \
+ -DLIBDIVECOMPUTER_LIBRARIES="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/lib/libdivecomputer.a \
+ -DMARBLE_INCLUDE_DIR="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/include \
+ -DMARBLE_LIBRARIES="$BASEDIR"/mxe/usr/i686-w64-mingw32.shared/lib/libssrfmarblewidget.dll \
+ "$BASEDIR"/subsurface
#sed -i 's@-lssh2@/home/hohndel/src/win/win32/libgit2/libssh2.dll@g' CMakeFiles/subsurface.dir/link.txt
fi
-make $JOBS $@
+make $JOBS "$@"
diff --git a/planner.c b/planner.c
index 722eeb12e..67d999fa3 100644
--- a/planner.c
+++ b/planner.c
@@ -536,7 +536,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool
char *temp = (char *)malloc(sz_temp);
char buf[1000], *deco;
int len, lastdepth = 0, lasttime = 0, lastsetpoint = -1, newdepth = 0, lastprintdepth = 0, lastprintsetpoint = -1;
- struct gasmix lastprintgasmix = { -1, -1 };
+ struct gasmix lastprintgasmix = {{ -1 }, { -1 }};
struct divedatapoint *dp = diveplan->dp;
bool gaschange_after = !plan_verbatim;
bool gaschange_before;
@@ -975,7 +975,6 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
unsigned int *stoplevels = NULL;
bool stopping = false;
bool pendinggaschange = false;
- bool clear_to_ascend;
int clock, previous_point_time;
int avg_depth, max_depth, bottom_time = 0;
int last_ascend_rate;
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index 2ee5f5dcd..90d0b4627 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -22,6 +22,7 @@
#include "divelistview.h"
#include "divepicturemodel.h"
#include "metrics.h"
+#include "helpers.h"
// # Date Rtg Dpth Dur Tmp Wght Suit Cyl Gas SAC OTU CNS Loc
static int defaultWidth[] = { 70, 140, 90, 50, 50, 50, 50, 70, 50, 50, 70, 50, 50, 500};
@@ -575,12 +576,12 @@ static bool can_merge(const struct dive *a, const struct dive *b, enum asked_use
if (a->when > b->when)
return false;
/* Don't merge dives if there's more than half an hour between them */
- if (a->when + a->duration.seconds + 30 * 60 < b->when) {
+ if (dive_endtime(a) + 30 * 60 < b->when) {
if (*have_asked == NOTYET) {
if (QMessageBox::warning(MainWindow::instance(),
MainWindow::instance()->tr("Warning"),
MainWindow::instance()->tr("Trying to merge dives with %1min interval in between").arg(
- (b->when - a->when - a->duration.seconds) / 60),
+ (b->when - dive_endtime(a)) / 60),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
*have_asked = DONTMERGE;
return false;
@@ -611,6 +612,7 @@ void DiveListView::mergeDives()
}
}
}
+ MainWindow::instance()->refreshProfile();
MainWindow::instance()->refreshDisplay();
}
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index d1b635095..f9aeabd0d 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -736,7 +736,8 @@ void MainTab::updateDiveInfo(bool clear)
else
ui.cylinders->view()->hideColumn(CylindersModel::USE);
- qDebug() << "Set the current dive site:" << displayed_dive.dive_site_uuid;
+ if (verbose)
+ qDebug() << "Set the current dive site:" << displayed_dive.dive_site_uuid;
emit diveSiteChanged(get_dive_site_by_uuid(displayed_dive.dive_site_uuid));
}
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 1678cd6d4..9feb8f684 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -648,15 +648,19 @@ bool MainWindow::plannerStateClean()
return true;
}
+void MainWindow::refreshProfile()
+{
+ showProfile();
+ graphics()->replot(get_dive(selected_dive));
+ DivePictureModel::instance()->updateDivePictures();
+}
+
void MainWindow::planCanceled()
{
// while planning we might have modified the displayed_dive
// let's refresh what's shown on the profile
- showProfile();
- graphics()->replot();
+ refreshProfile();
refreshDisplay(false);
- graphics()->plotDive(get_dive(selected_dive));
- DivePictureModel::instance()->updateDivePictures();
}
void MainWindow::planCreated()
@@ -1570,6 +1574,7 @@ void MainWindow::loadFiles(const QStringList fileNames)
QByteArray fileNamePtr;
QStringList failedParses;
+ showProgressBar();
for (int i = 0; i < fileNames.size(); ++i) {
int error;
@@ -1588,6 +1593,7 @@ void MainWindow::loadFiles(const QStringList fileNames)
failedParses.append(fileNames.at(i));
}
}
+ hideProgressBar();
if (!showWarning)
getNotificationWidget()->hideNotification();
process_dives(false, false);
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index 9ff2a2041..25c9b3eba 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -189,6 +189,7 @@ slots:
void refreshDisplay(bool doRecreateDiveList = true);
void recreateDiveList();
void showProfile();
+ void refreshProfile();
void editCurrentDive();
void planCanceled();
void planCreated();
diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp
index 514edcfc5..5b7c3832a 100644
--- a/qt-ui/profile/profilewidget2.cpp
+++ b/qt-ui/profile/profilewidget2.cpp
@@ -342,12 +342,12 @@ void ProfileWidget2::setupItemOnScene()
replotEnabled = true;
}
-void ProfileWidget2::replot()
+void ProfileWidget2::replot(struct dive *d)
{
if (!replotEnabled)
return;
dataModel->clear();
- plotDive(0, true); // simply plot the displayed_dive again
+ plotDive(d, true);
}
void ProfileWidget2::setupItemSizes()
diff --git a/qt-ui/profile/profilewidget2.h b/qt-ui/profile/profilewidget2.h
index 1127b8498..7e038edc3 100644
--- a/qt-ui/profile/profilewidget2.h
+++ b/qt-ui/profile/profilewidget2.h
@@ -109,7 +109,7 @@ slots: // Necessary to call from QAction's signals.
void pointsRemoved(const QModelIndex &, int start, int end);
void plotPictures();
void setReplot(bool state);
- void replot();
+ void replot(dive *d = 0);
/* this is called for every move on the handlers. maybe we can speed up this a bit? */
void recreatePlannedDive();
diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp
index e2e3b3e78..c34ddd7bf 100644
--- a/qt-ui/subsurfacewebservices.cpp
+++ b/qt-ui/subsurfacewebservices.cpp
@@ -1069,8 +1069,22 @@ void CloudStorageAuthenticate::uploadError(QNetworkReply::NetworkError error)
void CloudStorageAuthenticate::sslErrors(QList<QSslError> errorList)
{
- qDebug() << "Received error response trying to set up https connection with cloud storage backend:";
- Q_FOREACH (QSslError err, errorList) {
- qDebug() << err.errorString();
+ if (verbose) {
+ qDebug() << "Received error response trying to set up https connection with cloud storage backend:";
+ Q_FOREACH (QSslError err, errorList) {
+ qDebug() << err.errorString();
+ }
+ }
+ QSslConfiguration conf = reply->sslConfiguration();
+ QSslCertificate cert = conf.peerCertificate();
+ QByteArray hexDigest = cert.digest().toHex();
+ if (reply->url().toString().contains(prefs.cloud_base_url) &&
+ hexDigest == "13ff44c62996cfa5cd69d6810675490e") {
+ if (verbose)
+ qDebug() << "Overriding SSL check as I recognize the certificate digest" << hexDigest;
+ reply->ignoreSslErrors();
+ } else {
+ if (verbose)
+ qDebug() << "got invalid SSL certificate with hex digest" << hexDigest;
}
}
diff --git a/qthelper.cpp b/qthelper.cpp
index 6e3c957a6..06a6610f0 100644
--- a/qthelper.cpp
+++ b/qthelper.cpp
@@ -627,6 +627,28 @@ extern "C" const char *system_default_directory(void)
return filename;
}
+extern "C" char *move_away(const char *old_path)
+{
+ if (verbose > 1)
+ qDebug() << "move away" << old_path;
+ QFile oldFile(old_path);
+ QFile newFile;
+ QString newPath;
+ int i = 0;
+ do {
+ newPath = QString(old_path) + QString(".%1").arg(++i);
+ newFile.setFileName(newPath);
+ } while(newFile.exists());
+ if (verbose > 1)
+ qDebug() << "renaming to" << newPath;
+ if (!oldFile.rename(newPath)) {
+ qDebug() << "rename of" << old_path << "to" << newPath << "failed";
+ return strdup("");
+ }
+ return strdup(qPrintable(newPath));
+
+}
+
extern "C" char *get_file_name(const char *fileName)
{
QFileInfo fileInfo(fileName);
@@ -1354,7 +1376,8 @@ int getCloudURL(QString &filename)
prefs.cloud_storage_email_encoded = strdup(qPrintable(email));
}
filename = QString(QString(prefs.cloud_git_url) + "/%1[%1]").arg(email);
- qDebug() << "cloud URL set as" << filename;
+ if (verbose)
+ qDebug() << "cloud URL set as" << filename;
return 0;
}
diff --git a/qthelperfromc.h b/qthelperfromc.h
index d64bfc04a..21b2a6f80 100644
--- a/qthelperfromc.h
+++ b/qthelperfromc.h
@@ -10,6 +10,7 @@ char *get_file_name(const char *fileName);
void copy_image_and_overwrite(const char *cfileName, const char *path, const char *cnewName);
char *hashstring(char *filename);
bool picture_exists(struct picture *picture);
+char *move_away(const char *path);
const char *local_file_path(struct picture *picture);
void savePictureLocal(struct picture *picture, const char *data, int len);
void cache_picture(struct picture *picture);
diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 442702da7..6f93d8cab 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -234,7 +234,7 @@ static int qt_serial_read(serial_t *device, void* data, unsigned int size)
unsigned int nbytes = 0;
int rc;
- while(nbytes < size)
+ while(nbytes < size && device->socket->state() == QBluetoothSocket::ConnectedState)
{
device->socket->waitForReadyRead(device->timeout);
@@ -248,8 +248,15 @@ static int qt_serial_read(serial_t *device, void* data, unsigned int size)
} else if (rc == 0) {
// Wait until the device is available for read operations
QEventLoop loop;
+ QTimer timer;
+ timer.setSingleShot(true);
+ loop.connect(&timer, SIGNAL(timeout()), SLOT(quit()));
loop.connect(device->socket, SIGNAL(readyRead()), SLOT(quit()));
+ timer.start(device->timeout);
loop.exec();
+
+ if (!timer.isActive())
+ return nbytes;
}
nbytes += rc;
@@ -286,7 +293,7 @@ static int qt_serial_write(serial_t *device, const void* data, unsigned int size
unsigned int nbytes = 0;
int rc;
- while(nbytes < size)
+ while(nbytes < size && device->socket->state() == QBluetoothSocket::ConnectedState)
{
device->socket->waitForBytesWritten(device->timeout);