Commit graph

1952 commits

Author SHA1 Message Date
Berthold Stoeger
a4dbe51aee cleanup: remove TabBase::enter/exitEditMode() functions
Since the edit mode was removed, these became unnecessary.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:33:34 +01:00
Berthold Stoeger
152016d293 cleanup: break out the dive-notes tab
There was always this weird asymmetry that the "maintab" widget
is one of the tabs itself, whereas the additional tabs were
treated as extra-widgets. Turn the first tab into explicit
source files to make the distinction between container and
content clear.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:33:32 +01:00
Berthold Stoeger
2657ec9016 cleanup: remove MainWindow::refreshProfile()
This only calls MainWindow::showProfile(), so simply call
that directly.

Moreover make two "public slots" private member functions,
since these were only called locally.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:32:22 +01:00
Berthold Stoeger
4c46a11ed1 profile: update profile in edit mode on undo
When the user undos/redos the profile should update even
when in edit mode. This is a bit more complicated than
anticipated:

1) We should not do the update when emitting an undo command
from the profile. But we *should* update if it is an undo
command from the maintab (change depth/time).

2) The divepointsplannermodel has to be reset. Side note:
the code is truly abysmal as it sends numerous changed-signals.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:32:22 +01:00
Berthold Stoeger
5aa67c134b desktop: remove edit mode of maintab
This was only used for profile-editing, which is now managed
by the profile-widget.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:32:22 +01:00
Berthold Stoeger
fce48367cd undo: more fine-grained undo of profile editing
Place undo commands for every change of the profile, not
only on "saving". Move the edit-mode from the mainwindow
and the maintab to the profile widget.

This is still very rough. For example, the only way to exit
the edit mode is changing the current dive.

The undo-commands are placed by the desktop-profile widget.
We might think about moving that down to the profile-view so
that this will be useable on mobile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:32:22 +01:00
Berthold Stoeger
ea0c030770 undo: split replanDive and editProfile commands
These two actions were using the same command with a flag
controlling the name of the command, which is shown in
the undo menu.

However, the replanDive does much more (such as changing
the notes) and in the future we may want to be more
fine-grained with respect to profile editing. Therefore,
split these commands into two separate ones.

Moreover, make the editProfile command more flexible.
Pass an enum describing the action instead and also
a counter indicating how many points have been
moved or removed.

Finally, don't consume the input dive in the editProfile
command, because we will want to keep the original dive
while editing the profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:32:22 +01:00
Dirk Hohndel
2368a183e1 Qt6: prevent QML object from being garbage collected
It appears that the QML object that is created when assigning the source
to the StatsView in the ui can be garbage collected and therefore
destroyed and re-instantiated without our knowledge. So instead of
trying to keep a pointer around, we end up looking up the object address
when needed.
We still ask the JS code to not garbage collect the object - but that
clearly isn't enough to prevent it from being destroyed when the parent
widget changes.

Without this fix opening the statistics will crash with Qt6.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
c3cc3155fc Qt6: add include files to keep QVectorIterator working
The QVectorIterator is only available in Qt6 when you explicitly add the
include files.

Suggested-by: Thiago Macieira <thiago@macieira.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
fc66352c3c Qt6: if we want the QString argument we need the TextChanged slot
I'm surprised this worked correctly in Qt5.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
5d506e4152 Qt6: move connection into C++ source
This no longer compiles when defined in the .ui file. But functionally this
should be the same and it should work on Qt5 and Qt6.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
63f0af201e Qt6: add required QFile header
This worked without that include in Qt5, but having it there doesn't hurt,
either, so instead of yet another conditional compile, let's just include it
everywhere.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
f9b2d4fa25 Qt6: adjust for changed argument types
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
e61509b032 Qt6: deal with changes to window and layout geometry APIs
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
e29ecf2c9a Qt6: update to newer APIs for QDateTime
Fortunately, these were already available in Qt5.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
6f46238fc4 Qt6: Bluetooth API changes
Use the explicit QBluetoothUuid instead of just QUuid and deal with new
constants and signal names.
At least with Qt6 we no longer need the ugly QOverload hack.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
78361ef8e3 Qt6: deal with changes from QStringRef to QStringView
QStringRef is gone in Qt6 and mostly replaced by QStringView.  The one major
difference is that direct comparisons with string literals are no longer
possible.

Thanks to Thiago Macieira for helping me avoid more conditional compilation
here.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
47d900bee5 Qt6: don't build MapWidget
Since Qt6 doesn't include QtLocation anymore, we can't build MapWidget.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
ce254bee57 build-system: update cmake to allow Qt5 and Qt6
Qt6 builds of course still fail, but now they are at least possible.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
59fe2f3d7e cleanup: prevent distracing conversion warnings
We do want the -Wfloat-conversion warnings where they point out
potential bugs. But they are very distracting when they are triggered by
floating point literals (which the standard defines as double) passed to
a function expecting float arguments.

The fact that Qt6 changes the arguments to all these functions from
double to float is... hard to explain, but it is what it is. With these
changes, for the majority of cases we create inlined helpers that
conditionally compile to do the right thing. And in a handful of other
cases we simply cast to float (and accept that on Qt5 this then gets
cast back to double... for none of these cases the potential loss in
precision makes any difference, anyway - which likely is why the Qt
community made the decision to change the type of the arguments in the
first place).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
325addf385 cleanup: fix incorrect QFuture return value
I'm a abit confused why that didn't cause an error with Qt5.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
df610752c7 cleanup: don't add QKeySequence values
These should be handled as logical OR operations as they are bits.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Dirk Hohndel
9b3a9904b2 cleanup: remove duplicate connections in .ui files
These no longer compile with Qt6 - but they are already duplicated in C++ code,
anyway. So we can simply remove them.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Berthold Stoeger
f682b365a6 cleanup: remove unused MainTab::refreshDisplayedDiveSite()
The last user seems to have been removed in 3a3089770a
and nobody complained.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-06 11:45:47 +01:00
Jason Bramwell
28a5442944 printing: add gas fractions to print template and user manual
Add additional exported values gasO2, gasHe and gasN2 to be available to the
print template.

Also add these to the user manual as well as document some other missing
variables like surge and chill.

Finally, remove references to Grantlee. While the print template still uses the
syntax that we inherited from Grantlee, we aren't actually using Grantlee
anymore.

Reported-by: Rahul Swaminathan <rahul.swaminathan@gmail.com>
Signed-off-by: Jason Bramwell <jb2cool@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-04 12:02:35 -08:00
Jason Bramwell
a70eccea29 printing: make meandepth available to print templates
Adding additional exported value meandepth to be available in the print
template language.

A possible use of this would be

<td class="fieldTitle">
    <h1> Max / mean depth </h1>
</td>
<td class="fieldData">
    <p> {{ dive.depth }} / {{ dive.meandepth }} </p>
</td>

Reported-by: Rahul Swaminathan <rahul.swaminathan@gmail.com>
Signed-off-by: Jason Bramwell <jb2cool@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-04 12:02:28 -08:00
Berthold Stoeger
9e0712d5dc core: replace dive master by dive guide
In general, replace "dive master" by "dive guide".

However, do not change written dive logs for now. On reading,
accept both versions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-02-15 09:35:43 -08:00
Berthold Stoeger
889827aadb desktop: don't update notes field when executing command
User report: when switching focus between windows, the
cursor position gets lost. This is due to a note-edit
command being fired, which then overwrites the notes tab.

To prevent this, don't update the notes field when placing
a command. Moreover, generally don't update the dive
selection when placing a command as that also rewrites all
the values.

Should this be extended to other fields?

Fixes #3365

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-02-15 09:34:23 -08:00
Berthold Stoeger
06d7ba082e cleanup: Fix a Coverity warning
Two pointers were checked against NULL and then both were
dereferenced if at least one was not NULL. Of course, this
should have been an and, not an or expression.

That said, this is a semi-false positive, since both pointers
are set in the constructor and therefore never can be NULL.
In principle, one could remove the whole check. Of course,
realizing that would require a global analysis by Coverity,
which I reckon it doesn't do.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-02-15 09:30:43 -08:00
Berthold Stoeger
5085793d9a cleanup: use setDive() in ProfileWidget::plotCurrentDive()
This removes a block of redundant code that was already broken
out into a helper function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-02-13 15:00:38 -08:00
Dirk Hohndel
a4438c2d07 update copyright year...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-01-17 14:18:59 -08:00
Berthold Stoeger
1e5191e33e statistics: add a sort mode for categorical bar charts
This was a user request: Sort bar charts by height of the bars.
Obviously, this can only work for categorical charts, not for
histograms.

The UI is a break from the old concept: the sorting is chosen
based on the chart, whereas for the rest of the features, the
viable charts are presented based on the binning, etc.

I found it confusing to have the possible charts be selected
based on sorting. I.e. if a non-bin sort mode is selected,
the histogram charts disappear. On the flip side, this would
be more consistent. We can change it later.

For value-based bar charts, there are three sort modes: by
bin, by count (i.e. number of dives in that bar) and by
value (i.e. length of the bar). This hopefully satisfies all
needs.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-01-04 11:14:24 -08:00
Berthold Stoeger
c893d19ea4 cleanup: pass all parameters to weightsystem_t
With -Wextra, gcc/g++ complains that compound initialization
of weightsystem_t misses the auto_filled parameter. Add it.
For C++ code we might think about writing a constructor. However,
we use two versions: with and without copied string.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-01-02 13:51:07 -08:00
Berthold Stoeger
7d3e246680 profile: explicitly reset zoomLevel when plotting a new dive
Currently, the zoomLevel is reset for every plotDive() call,
because the zooming is done via the QGraphicsScene. However,
this does not work well (e.g. axes are likewise zoomed) and
in the future a change of the zoom level will cause a replot.

Thus, remove the zoom-reset in plotDive() and do it explicitly
when switching dives.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
0e9eee0a7f core: return floating point from to_PSI() functions
Dive data are stored internally using integral types using
appropriately fine units (mm, mbar, mkelvin, etc.). These
are converted with functions defined in units.h for display
(m, bar, C, etc.). Usually floating points are returned by
these functions, to retain the necessary precision. There
is one exception: the to_PSI() and mbar_to_PSI() functions.

For consistency, make these functions likewise return floats.
This will be needed for the rework of the profile-axes.
The plan is to use the conversion functions to make the
axes aware of the displayed values. This in turn will be
necessary to place the ticks at sensible distances. However,
the conversions need to be precise, which is not the
case for the current to_PSI() functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
8046a05e95 profile: merge plotDive() into draw() call
Rendering resets the size, which now recalculates the axes.
Therefore, plotDive() must be called. The callers were doing
the opposite: call plotDive() first, then draw().

To make it easier for the callers, present a single interface
that handles these subtleties.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
f713858ba4 profile: rename printFontScale to dpr (device pixel ratio)
The printFontScale is used to scale up fonts (and icons) when
rendering to high-DPI devices. With absolute scaling, this
will also be used to scale the size of different chart
regions, line thickness, etc. Therefore, give it an more
appropriate name. "Device pixel ratio", which is a well
established term, seems to appropriately describe the
concept.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
51dc5113c2 profile: for printing/mobile access ProfileScene directly
Instead of using the interactive ProfileWidget2, just
use the ProfileScene to render the profile for printing,
export and mobile. One layer (QWidget) less.

This removes all the kludges for handling DPR on mobile.
Thus, the rendering will now be off and have to be fixed
by redoing the scaling code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
d9dcf9ef37 profile: move non-interactive chart elements to ProfileScene
This finalizes the split between interactive (ProfileWidget2)
and non-interactive (ProfileScene) parts of the profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
f8fbff9f7d profile: set profile-mode in ProfileWidget, not MainWindow
The mode of the profile (profile, edit, plan) was set in
MainWindow and ProfileWidget. For consistency move the one
setProfileState() call from MainWindow to ProfileWidget.
This removes a direct access to the profile-view and
therefore improves encapsulation.

Also, clear the profile, when no dive is shown to remove
any potentially dangling references.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
12fd102e4f profile: remove empty state from profile
This was moved to the desktop version. Enter the profile in
the constructor. Somewhat surprisingly, this seems to work.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
787a23f017 profile: implement "empty state" in desktop's ProfileWidget
The profile has an "empty state" showing the subsurface logo,
which is active when no dive is selected.

Switching to/from this mode is quite complex, because all the
chart features have to be hidden/shown, etc. Moreover, this mode
is not needed on mobile, where multiple ProfileWidgets can
be active at the same time and every dive has at least a
"faked" profile.

Therefore, implement this mode directly in the desktop
version of the widget. This makes the rescaling distinctly
less cumbersome. It is implemented using a QStackedWidget,
which switches between the profile and the logo.

This commit does not remove the empty state from the profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
9f6e487790 profile: remove redundant parameter in setPrintMode()
Since using separate profile-instances for print/export,
we never exit print mode. Therefore, the mode parameter
can be removed. This is a preparatory commit for passing
the printMode at construction time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
a14f740df0 profile: pass printFontScale on creation of the profile
Not having to readjust the scale on-demand will make the
code distinctly simpler. Let's just pass it once.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
b39e88b8c6 profile: remove need for MainWindow when rendering the profile
Very annoyingly, to render the profile for printing / export,
the profile still had to be show()n, thus requiring a parent
window.

Analysis of qmlprofile.c showed that this was due to the
transformation matrix not being properly set up on non-show()n
scenes.

Instead, we can simply render via the QGraphicsScene
(circumventing the QGraphicsView).

The code was factored out into the ProfileWidget2::draw()
function. This will hopefully make it easier to change
the size-code of the profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
13d4f595cb profile: remove profile widget code from mainwindow
Create a new class that encapsulates the profile-widget UI.

This is called ProfileWidget, which might be confusing since
the actual display is called ProfileWidget2. However, the
plan is to rename the latter to ProfileView. After all, it
is also used to print and to show the profile on mobile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
6b615ccb4b desktop: fold configureToolBar() into plotCurrentDive()
The MainWindow::configureToolBar() function is called every
time plotCurrentDive() is called. Moreover, this is the only
time that it is called. We might just fold the former into
the latter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
c466a8f044 desktop: make MainWindow::graphics private
There are no more external users of the profile. Make it private.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
8f0e2245c2 export: move exportProfile() function to exportfuncs.cpp
The exportProfile function uses the UI and therefore was
supposed to be declared in backend-shared/* but defined
separately for desktop and mobile. Currently, only the
desktop version exists.

The goal however should be that there is no need of the
UI for this function. In a first step, move the function
to the common backend-shared/* code and conditionally
compile for desktop. In upcoming commits, the function
will be made independent of the UI.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
811c8a441e printing: use independent profile instance for printing plan
In analogy to normal printing, don't misuse the mainwindow's
profile widget to do the printing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
956a6d6c68 printing: use independent profile instance for printing
When printing the dives were rendered into the visible profile.
This meant setting a number of flags and reverting after printing.
That's obviously quite brittle.

Instead, use a separate profile instance, since we can have
different profiles showing different dives now.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
d1b8f1ca3d formatting: move get_trip_title to string-format.h and split it
To enable grouping by trip in the statistics module, split
the get_trip_title() function in a version that appends
a "(n dive(s)" string an one that doesn't. The statistics
module doesn't want that added string, since it displays
the number of dives in a different way.

Also, move the functions to string-format.h, where these
are collected. And rename them to camelCase. Yes, it's
ugly, but consistent with most other C++ code in the code
base.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 10:36:13 -08:00
Dirk Hohndel
fdffb870e5 desktop: avoid dangling reference
Let the compiler figure out the correct type...

Suggested-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-12-17 10:33:17 -08:00
Berthold Stoeger
a40b40ae7a cylinders: only hide cylinders at the end of the list
On the equipment tab, unused cylinders (automatically added,
no pressure data) could be hidden. This was implemented using
a QSortFilterProxyModel.

Apparently, it causes confusion if cylinders in the middle of
the list are hidden. Therefore, only hide cylinders at the end
of the list.

QSortFilterProxyModel seems the wrong tool for that job, so
remove it and add a flag "hideUnused" to the base model. Calculate
the number of cylinders when changing the dive.

This is rather complex, because the same model is used for
the planner (which doesn't hide cylinders) and the equipment
tab (which does). Of course, syncing core and model now becomes
harder. For instance, the caching of the number of rows was removed
in a37939889b and now has to be
readded.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-13 11:54:24 -08:00
Berthold Stoeger
8afb0dedc9 planner: hide internal cylinder columns
In cb80ff746b internal columns
were added to the cylinder model. These were not hidden in
the planner. Nobody complained?

Remove this clutter from the UI by hiding the columns.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-13 11:54:24 -08:00
Berthold Stoeger
c6f0fcbb0b cylinder: fix hidden-column logic in cylinder tab
The logic did not consider the WORKINGPRESS_INT and SIZE_INT
columns added in cb80ff746b.

By some unknown magic this worked by routing everything
through the CylindersModelFiltered model.

Let's fix it and explicitly ignore these columns. Put
the test whether a column should be ignored in a function
to avoid inconsistencies should new columns be added.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-13 11:54:24 -08:00
Robert C. Helling
07745893e5 Don't attempt to compute SAC for CCR dives
CCRs are different. It does not make sense to compute
a depth dependent SAC. You could compute the rate of O2
consumption but even that is likely wrong (as O2 in the
diluent would enter that as well), so simply don't attempt
it.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-11-24 11:03:51 -08:00
Dirk Hohndel
cfd6a1634f cleanup: fix SkipEmptyParts warning for mobile
And while doing that, have all the cases where we already include
qthelper.h simply use a define in that header file - but keep the two
other instances of the define where the C++ source don't need qthelper.h
otherwise.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-11-24 10:53:26 -08:00
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