Commit graph

1844 commits

Author SHA1 Message Date
Dirk Hohndel
7d6552ff65 cleanup: replace QRegExp with QRegularExpression
Qt 6 will drop support for QRegExp.
Use QRegularExpression instead.

The syntax for matches and captures has changed and needed to be
adjusted.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-27 12:37:54 -07:00
Dirk Hohndel
73e9c099eb cleanup: replace QRegExp with QRegularExpression
Qt 6 will drop support for QRegExp.
Use QRegularExpression instead.

The syntax for matches has changed and needed to be adjusted.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-27 12:37:31 -07:00
Dirk Hohndel
7a6f2581e8 cleanup: replace QRegExp with QRegularExpression
Qt 6 will drop support for QRegExp.
Use QRegularExpression instead.

The syntax for matches and captures has changed and needed to be
adjusted.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-27 12:36:27 -07:00
Tim Segers
b618d93241 desktop: fix div-by-zero when selecting multiple invalid dives
Signed-off-by: Tim Segers <tsegers@pm.me>
2021-10-11 20:53:41 +03:00
Dirk Hohndel
f50585a906 desktop/image-time-shift: use better filename filter
We already have a function to select all supported image formats. Let's
just use that.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-22 09:09:12 -07:00
Tim Segers
10798c2a8d desktop/image-time-shift: reorder UI
The camera sync feature has been moved above the Ok and Cancel buttons
and given its own descriptive header. The checkbox to ignore unaligned
image timestamps has been moved closer to the buttons.

Signed-off-by: Tim Segers <tsegers@pm.me>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-22 09:09:12 -07:00
Dirk Hohndel
4167b2ff14 desktop/image: allow larger range for manual time shift
The QTimeEdit field is severely limited when it comes to the supported
time range. By coding our own input / validation we can allow far larger
time shifts. For simplicity, this always assumes hours:minutes format.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-22 09:09:12 -07:00
Tim Segers
6ea4cfcc02 desktop: add support for camera sync delta of more than 24h
When using the camera sync feature to sync media to the dive timeline,
the calculated time difference was considered invalid if it was more
than 24 hours.

To prevent this, this commit disables the manual time offset input
fields when the camera sync button is clicked. It then uses the epoch
difference in the final offset calculation, enabling arbitrary time
differences between camera and divecomputer.

Signed-off-by: Tim Segers <tsegers@pm.me>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-22 09:09:12 -07:00
Linus Torvalds
85392343fa Re-do the libdivecomputer fingerprint save/load code
This tries to make our fingerprinting code work better, by avoiding
using the "deviceid" field that has always been unreliable because we've
calculated it multiple different ways, and even for the same version of
subsurface, it ends up changing in the middle (ie we calculate one value
initially, then re-calculate it when we have a proper serial number
string).

So instead, the fingerprinting code will look up and save the
fingerprint file using purely "stable" information that is available
early during the download:

 - the device model name (which is a string with vendor and product name
   separated by a space)

 - the DC_EVENT_DEVINFO 32-bit 'serial' number (which is not necessarily
   a real serial number at all, but hopefully at least a unique number
   for the particular product)

but because the model name is not necessarily a good filename (think
slashes and other possibly invalid characters), we hash that model name
and use the resulting hex number in the fingerprint file name.

This way the fingerprint file is unambiguous at load and save time, and
depends purely on libdivecomputer data.

But because we also need to verify that we have the actual _dive_
associated with that fingerprint, we also need to save the final
deviceid and diveid when saving the fingerprint file, so that when we
load it again we can look up the dive and verify that we have it before
we use the fingerprint data.

To do that, the fingerprint file itself contains not just the
fingerprint data from libdivecomputer, but the last 8 bytes of the file
are the (subsurface) deviceid and the diveid of the dive that is
associated with the fingerprint.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-09-19 16:51:46 -07:00
Berthold Stoeger
9376721873 desktop: warn when deleting a cylinder with sensor readings
This makes the sensors pointless and in the future, they
will be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-09-03 13:35:28 -07:00
Linus Torvalds
ba6f7361da Remove the divecomputer naming tab
The TabDiveComputer model won't work in the new world order, where you
can't even insert a new device entry without a nickname to be edited.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-08-18 13:22:02 -07:00
Berthold Stoeger
67769235e7 desktop: fix crash when right-clicking of trip headers
Commit e42fc1a1e9 introduced a
crash condition. Apparently the code attempts to test whether
the clicked-on item is a top-level dive. The "Collapse others"
menu item should not be shown in that case. It does this by
testing "d->divetrip". However, "d" might quite logically be
null if clicking on an unexpanded trip header.

Therefore, check explicitly for the trip header case (which
should show the menu item) and for good measure prevent
the nullpointer access (that should be caught by testing
for trip, but who knows).

Fixes #3301.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-08-12 20:57:26 +02:00
Berthold Stoeger
16b31985c3 cleanup: replace membuffer by membufferpp in C-code
Thus, the membuffer data is automatically freed when going
out of scope - one thing less to worry about.

This fixes one use-after-free bug in uploadDiveLogsDE.cpp
and one extremely questionable practice in divetooltipitem.cpp:
The membuffer was a shared instance across all instances
of the DiveToolTipItem.

Remves unnecessary #include directives in files that didn't
even use membuffer.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-23 11:22:43 -07:00
Dirk Hohndel
8ac0519a99 desktop: explicitly enable shortcuts
The changes in commit 4daf687876 ("profile: remove [disable|enable]Shortcuts()
signals") resulted in us no longer enabling the shortcuts on the desktop (at
least on macOS where I debugged this). This placement of the call feels like a
bit of overkill, but at least it shouldn't be wrong.

Fixes #3293

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-23 10:20:50 -07:00
Berthold Stoeger
cfc87e9da3 cleanup: remove Printer::dpi member variable
This variable is not used outside a single function, where it
is reset every time the function runs. This can be realized by
a function-local variable just as well.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-07 07:57:11 -07:00
Robert C. Helling
6b2e56e513 Handle dives with no samples
This occurs upon importing dives for example via CSV.

Make sure the profile display is cleared when selecting
such a dive rather than showing a different dive.

Allow editing the profile for such a dive.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-07-03 14:38:19 -07:00
Berthold Stoeger
4a7cf0e970 profile: rename ADD state to EDIT state
The ADD state is not used for adding dives since adding dives
was made undoable. Therefore, rename it to EDIT state, since
that is what it is used for.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-03 14:30:46 -07:00
Dirk Hohndel
329fcf7fdc cleanup: update copyrights
That should have been done six months ago.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-03 14:28:37 -07:00
Dirk Hohndel
50ef42d580 cleanup: remove long obsolete code
We have stopped playing with beta versions many many years ago.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-03 14:28:37 -07:00
Mark Stiebel
e42fc1a1e9 desktop: add numerus translation for dive context menu
Add numerus translation lookup for the right-click context menu in the dive
list to show proper singular/plural text.

Fixes #3256

Signed-off-by: Mark Stiebel <mark@aretha.stiebel.me>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-06-04 09:35:16 -07:00
mikeller
2d734c529b desktop: Add the capability to copy / paste dive number and date / time.
This is adding the capability to select 'Dive number' and 'Date / Time'
in the 'Copy dive components' dialog, and then copy them into the
clipboard.
When using 'Paste dive components, these values will then be pasted into
the selected dive(s).
This is intended to help with workflows that import dive information
from two different sources, like general information from another
logging program, and CCR ppO2 sensor readings from a unit log, and then
stitch them together into one cohesive entry with all data per dive.
Copied data is also output into formatted text when pasting the
clipboard outside of the application:

```
Dive number: 401
Date / time: Sun 2 May 2021 12:00 AM
```

No translations have been added as of now - I could not find any
information on how strings are translated for this project.

Signed-off-by: Michael Keller <github@ike.ch>
2021-05-19 15:15:34 -07:00
Berthold Stoeger
2264a5e166 cleanup: remove double layout name in statswidget.ui
This gave an annoying warning.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-17 11:58:59 -07:00
Robert C. Helling
41f87f3e77 Translate header strings for APD
We are matching translated header names. Thus, when composing
a header line for APD, make sure it contains translations.

This mechanism is quite brittle. Our German translations had
two different translations for "Sample time" and this already
broke it. This is why this patch also includes a fix for a
translation string (should be fixed in transiflex as well
of course).

Fixes #3246

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-05-13 12:28:38 -07:00
Berthold Stoeger
3e1ade5206 cleanup: free print dialog in planner
When printing the plan, a print-dialog was created with "new",
but not freed later. Strictly speaking, this is not a leak,
because the dialog is attached to the main-window in Qt's
object hierarchy. Thus it is freed on application exit. On
the other hand, it is a leak in the sense that resources are
pointlessly hogged until application exit.

Let's just turn it into a stack-allocated object.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-06 08:46:57 -07:00
Berthold Stoeger
38d0fac2d1 export: show progress dialog for profile exports
Simply reuse QProgressDialog interface for the TeX exports.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-06 08:21:04 -07:00
Berthold Stoeger
9ee8807af7 export: show progress dialog for TeX exports
The TeX exports may hang the UI for a long time.

Show a progress-dialog that is updated after every exported dive
and allows the user to cancel the export.

This is pretty lame, because it is synchronous (export still runs
in UI thread) and therefore the UI still is sluggish. But it
is an improvement.

Since the TeX-exporting code is in a shared directory (desktop and
mobile), this uses a slim interface class. Mobile does not
yet use TeX export, but you never know. Better than #ifdefs
sprinkled all around, I reckon.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-06 08:21:04 -07:00
Berthold Stoeger
573de51e48 export: remove redundant QString::isNull() checks
If QString::isEmpty() is false, QString::isNull() is likewise
false, so these tests are redundant.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-06 08:21:04 -07:00
Berthold Stoeger
bd6b714be1 profile: ignore animation-speed setting when printing
When printing, the animation speed was set to 0 by the
caller and later reset to the original value. Instead of
modifying global state, set it internally (in the profile-code)
to zero when in print mode.

This is another small step in making the printing independent
from the shown profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-25 12:33:20 -07:00
Berthold Stoeger
267c82d85f cleanup: remove MainWindow::turnOffNdlTts()
This flag is handled directly by the profile code
since 2015 (000c9cc21c).

The function therefore can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-21 10:04:26 -07:00
Dirk Hohndel
7fa031b648 cloudstorage: try to pick between multiple cloud servers
The backend infrastructure will soon be able to support more than one
cloud server which automagically stay in sync with each other.

One critical requirement for that to work is that once a session was
started with one of the servers, the complete session happens with that
server - we must not switch from server to server while doing a git
transaction. To make sure that's the case, we aren't trying to use DNS
tricks to make this load balancing scheme work, but instead try to
determine at program start which server is the best one to use.

Right now this is super simplistic. Two servers, one in the US, one in
Europe. By default we use the European server (most of our users appear
to be in Europe), but if we can figure out that the client is actually
in the Americas, use the US server. We might improve that heuristic over
time, but as a first attempt it seems not entirely bogus.

The way this is implemented is a simple combination of two free
webservices that together appear to give us a very reliable estimate
which continent the user is located on.

api.ipify.org gives us our external IP address
ip-api.com gives us the continent that IP address is on

If any of this fails or takes too long to respond, we simply ignore it
since either server will work. One oddity is that if we decide to change
servers we only change the settings that are stored on disk, not the
runtime preferences. This goes back to the comment above that we have to
avoid changing servers in mid sync.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
c5eb806adb cloudstorage: some cleanup of cloud url handling
We know the preference is never empty, so stop testing for this. But
don't maintain two different preferences with basically the same
content. Instead add the '/git' suffix where needed and keep this all in
one place.

Simplify the extraction of the branch name from the cloud URL.

Also a typo fix and a new comment.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Berthold Stoeger
8939b6a99b profile: remove enableToolbar() signal
When showing the "empty-state", the profile toolbar was
disabled. This was done via a "reverse" signal from the
profile to the MainWindow. Instead control the toolbar
in the MainWindow directly. Break out the plot-dive
functionality into a member function and there test
whether a dive is shown or not.

The signal makes no sense in the context of mobile
or printing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-10 14:15:35 -07:00
Berthold Stoeger
8c72ac6b9b profile: remove force parameter from ProfileWidget2::plotDive()
The last user was removed in 2789bb05b1.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-10 14:15:35 -07:00
Berthold Stoeger
4daf687876 profile: remove [disable|enable]Shortcuts() signals
When switching to the "plan" or "add" (which should rather be
called "edit", by the way) mode of the profile, the "shortcuts"
for copy&paste, undo&redo, etc. are disabled. When switching
to "profile" mode, they are reenabled.

This was done in a most convoluted way:

- The MainWindow calls the set*State() function of the profile.
- The Profile emits [disable|enable]Shortcuts() signals.
- The MainWindow catches these signals and does the enabling
  or disabling.

Not only is this very hard to reason about, it is also in
contradiction to the profile being part of the display layer.

Moreover, in editCurrentDive() the MainWindow disabled the
shortcuts itself, so this was all redundant.

For the sake of sanity, let's just move this logic to the
MainWindow, unslotify the [disable|enable]Shortcuts() functions
and make them private.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-10 14:15:35 -07:00
Berthold Stoeger
71e117669d profile: populate dive handlers when switching to edit/plan mode
The dive handlers are only updated by signals. This means that
switching into edit-mode has to be done in steps:
 1) initialize the DivePointsPlannerModel
 2) switch profile mode
 3) load dive into DivePointsPlannerModel

2) and 3) cannot be exchanged, or the dive handlers are not
initialized.

To avoid this sandwitching of profile- and model-initialization,
populate the dive handlers when switching the profile mode.
Thus, the profile can be switched into edit/plan mode when
the DivePointsPlannerModel is fully initialized.

This will be important in upcoming commits, when the initialization
of the dive is moved from the profile to the DivePointsPlannerModel.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
4009d4c87f planner: remove DivePlannerPointsModel::setRecalc()
The only external user of setRecalc() was turning recalculation
on. In fact, this happened when constructing the planner-widget.
However, for example editing of the profile only works when
the recalc flag is on.

This is all very confusing, let's just turn the flag on by
default and remove the accessor. Internally, the planner can
simply use the std::exchange function to set and reset the
recalc flag.

Perhaps the setting/resetting can be replaced by simple
        recalc = true;
        ...
        recalc = false;
pairs. It is unclear whether there is need for recursion.
Something to be investigated.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
ed8ad9ac80 desktop: query DivePlannerPointsModel for planner state
MainTab::updateDiveInfo() is not executed when in the planner.
To decide whether the application is in the planner state,
it queried the profile. Instead, query the DivePlannerPointsModel.

Currently, there is no autoritative carrier of that flag.
However, the MainTab has a dependency on DivePlannerPointsModel
anyway, and therefore this removes a dependency on the
profile. This brings us closer to a state where we can have
multiple profiles.

Ultimately, it is hoped that the whole check can be removed
at this place, making the point moot.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
b4c307c775 planner: set profile to planner state in main window
Remove mainwindow-access from the planner, by setting
the profile to planner state in the owner of the profile,
viz. the MainWindow.

The MainWindow sets the application state to planner, so
it seems legit that it also sets the profile state.

This removes a further interdependency.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
4d60662531 desktop: remove check for editMode in maintab
The accept / reject message is only shown in edit-mode, no
need to check it. This is a step in simplification / removal
of the edit mode.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
2789bb05b1 profile: display arbitrary dive
So far the profile operated on the global displayed_dive. Instead,
take the dive to be displayed as a parameter to the plotDive()
functions.

This is necessary if we want to have multiple concurrent
profile objects. Think for example for printing or for mobile
where multiple dive objects are active at the same time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
1ec0790d50 planner: remove displayed_dive from DivePlannerModel
To remove global state, make the dive that DivePlannerModel
works on a member variable. Pass the dive in createSimpleDive()
and loadFromDive(). Moreover, this should pave the way to more
fine-grained undo in the planner. Ultimately, the planner
should not be modal.

Attention: for now, the dive must still be displayed_dive,
because of the convoluted way in which the profile and the
planner work on the same dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
e419ebf55a planner: move clearing of model into loadFromDive() function
Both loadFromDive() callers were clearing the model before
calling loadFromDive(). Move the clearing into that function
since it makes no sense to load into a non-cleared model.

Apparently this changes the way that no-cylinder dives are
treated and the code in ProfileWidget2::repositionDiveHandlers()
must now explicitly check for that condition.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
b9673df60b profile: pass DivePlannerPointsModel at construction time
This model is only needed when in plan mode. To enable multiple
profilewidgets at the same time (e.g. for the mobile app or
for printing), make the pointer to DivePlannerPointsModel a
member variable that is initialized at construction time.

Moreover, allow passing null as the DivePlannerPointsModel,
in which case planning will be disabled. This will be useful
for simple printing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
d68c3d8ab5 cleanup: add DivePlannerPointsModel::addDefaultStop() function
When clicking on "+" in the planner, a default stop point was
added using a signal/slot connection. This used the archaic
string-based connect syntax, because it was realized with
default parameters passed to "addStop()". Instead, add a
"addDefaultStop()" slot, which passes the default parameters.
Since all other callers do not use callbacks, unslotify
"addStop()". The slot was the only user of the default parameters,
so they can be removed alltogether.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 13:53:23 -07:00
Berthold Stoeger
8cd389c0af printing: use sensible font-size in profiles
The font-size in printed profiles is based on the size of the profile
in the main window. This makes no sense. Why should changing the
window size change the font-size on printouts?

Matter of fact, when making shrinking the height of the window to
its minimum, comical printouts are obtained (font way too big).

Therefore use an arbitrary rule: Say that profiles 600 pixels high
look reasonable and then scale up to the actual size on the printout.

This may need some tweaking for high-DPI mode. But that seems not
to be supported on desktop anyway?

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02 08:22:00 -07:00
Berthold Stoeger
f299fa37f9 stats: fix visibility check of the statistics tab on desktop
Apparently, the visibility flag of the view is not inherited
from the statistics widget. Therefore, the statistics is
redrawn on every action even if not visible.

Set the visibility explicitly in the show- and hide-events.

This is crazy.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-03-31 13:41:39 +02:00
Berthold Stoeger
5b3cb5898f desktop: fold ApplicationState into MainWindow
The application state is a desktop-only thing. The mobile UI
also has its application state, but that is something completely
different.

The last remaining user of the application state was to flag
whether the planner is active. Since this has all been
unglobalized, the ApplicationState structure can be moved
from core to the desktop UI. And there it can be made local
to the MainWindow class.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
42cff9b3a5 planner: pass in_planner down to TemplateLayout
The TemplateLayout prints different dives depending on
whether the planner is active. Instead of accessing a
global variable, pass the status down from the MainWindow.
That's all quite convoluted, since there are multiple
layers involved.

On the positive side, the in_planner() function has now
no users an can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
18049bc8d0 cleanup: remove unused includes in mainwindow.cpp
The printing code moved elsewhere, so these includes are not
needed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
5a8d7617ce statistics: implement primitive "restrict to selection" feature
Allow the user to restrict the analyzed dives based on the
current selection. One button restricts to the current selection
and one button resets the restriction.

Thus, the user can for example select bars in the bar chart
or a range in the scatter plot and perform statistics on
these sets.

The restriction works on top of the filter.

The UI can certainly be improved, but it is a start.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-13 13:02:54 -08:00