Commit graph

1999 commits

Author SHA1 Message Date
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
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
Berthold Stoeger
622e9ba373 printing: "fix" progress indicator
In TemplateLayout, there was a progress indication, which reported
the progress - not of the actual rendering - but of adding the
dives to the "to render" list. Which is of course done in less than
a ms, making the whole thing completely pointless.

Instead, emit progress when actually looping over the dives or
statistics.

Nobody ever noticed the problem because even rendering is done in
fractions of a second and indeed is accounted to only one fifth
of the total progress.

The real purpose of this "fix" is to get rid of the getTotalWork()
function, which was just insane. Instead of asking the TemplateLayout
how many dives it rendered, this number was extracted from
global state. Simply store the number of dives in the TemplateLayout
object instead.

Moreover, fix two coding style issues:
 - "Page" variable identifier starting with a capital
 - The Printer::render() being defined (as opposed to declared) with
   a default parameter. This is not how C++'s default parameters work,
   sorry.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-13 12:20:25 -08:00
Berthold Stoeger
646aead629 desktop: disable animation when selecting multiple dives
Selecting many dives when the animation was active
was increadibly slow, so disable it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-10 14:33:15 -08:00
Berthold Stoeger
f1203d365a desktop: improve splitter defaults
On first startup, use the splitter values suggested by Dirk:
Top/Bottom: 60/40
Info/Profile: 50/50
List/Map: 60/40

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
0b0e6672d5 profile: detect dive-mode change in profile
The profile must be replotted when the dive mode changes.
Weirdly, this was routed via the dive-information tab
(making it inherently non-mobile compatible). Detect
such a change directly in the profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
aefbde93ce desktop: be smarter about filling splitters
On state change, the splitters were completely emptied and
refilled. Instead try to reuse already existing splitter
slots. This reduces annoying flickering.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
c584e28f2e desktop: don't access profile directly to redraw it
The MainWindow has a function to replot the profile. Use that
instead of accessing the profile directly.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
64dae43bdd desktop: do own memory management of quadrant widgets
The memory management of the quadrant widgets is a total mess:
When setting the widget, the QSplitters take ownership, which
means that they will delete the widget in their destructor.

This is inherently incompatible with singletons, which must
not be deleted.

To avoid all these troubles, remove the widgets from the
QSplitters in the desctructor of the MainWindow. This of
course means that we now have to take care about deletion
of the widgets.

For local widgets use std::unique_ptr, for singletons use
a static variable that is deleted on application exit.

Sadly, for the map widget we can't use a normal singleton,
because the QML MapWidget's memory management is buggy.
Add a comment in the source code explaining this.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
8a36a100ce desktop: don't allow view change in planner
When in planner mode, don't allow the user to change the application
state. This brought us nothing but troubles and inconsistencies.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
1ed2f1681a desktop: remove the view-state
There was the "application state", which decided what to show
in the "quadrants" and the "view state" which decided which
quadrant to show. These interacted in a hard-to-grasp way.

The "view state" is used to show the map or dive list in
full screen.

I simply couldn't get these two orthogonal states to interact
properly. Moreover the thing was buggy: If a quadrant was hidden,
the user could still show it, by dragging from the side of the
window, at least under KDE.

To solve these woes, merge the two states into a single
application state. If the widget of a quadrant is set to null,
don't show it. So the four "view states" are now "application
states" where three of the four quadrants are not shown.

This also changes the memory management of the widgets:
widgets that are not shown are now removed from the QSplitter
objects. This makes it possible that the same widget is
shown in *different* quadrants.

While writing this, I stumbled upon a Qt bug, which is known
since 2014:
https://forum.qt.io/topic/43176/qsplitter-sizes-return-0

When restoring the quadrant sizes there was a test whether
the quadrant size is 0. If that was the case, a default size
was set. This seems not to work if the widgets were recently
added. Since this test now always fails, make the quadrants
non-collapsible and thus guarantee that 0 is never saved as
a size.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Berthold Stoeger
764aa6c512 planner: remove DivePlannerPointsModel::startTimeChanged signal
The way the starting time of a new plan was set was bonkers:

1) PlannerWidgets::planDive() invokes DivePlannerPointsModel::
   createSimpleDive().

2) createSimpleDive() calls DivePlannerPointsModel::
   setupStartTime()

3) setupStartTime() emits a signal startTimeChanged()

4) startTimeChanged is caught by PlannerWidget and sets
   the UI field

5) change of the UI field emits a timeChanged() signal which
   is connected to DivePlannerPointsModel::setStartTime()

6) setStartTime() sets the time of the plan and displayed_dive
   and emits dataChanged()

7) dataChanged() replots the dive()

8) Back in DivePlannerPointsModel::createSimpleDive() the diveplan
   start time is overwritten with displayed_dive (the value are
   equal owing to 6)

Wow!

But it gets worse:

9) The initial dive plan is set up in createSimpleDive().

Since the profile is drawn in 7) after clearing the displayed_dive
and before constructing the initial plan, the profile is shown
on a dive without samples. It therefore generates a dummy profile.

To make this somewhat less insane, remove the startTimeChanged()
signal in 3), explicitly set the start time of plan and dive to
the one calculated by setupStartTime() and explicitly set the UI
filed in the plannerWidget.

This still indirectly draws the profile via signals in a convoluted
way, but at it straightens out things somewhat. Most importantly,
the profile doesn't have to generate a fake DC.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 10:01:50 -08:00
Berthold Stoeger
ff536e98fc statistics: don't replot chart when changing features
Up to now, when the user changed the visibility of chart features
(legend, quartiles, labels, etc.) the whole chart was replot.
Instead, only change the visibility status of these items.

After all, this modularity is one of the things the conversion
to QSG was all about.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 08:47:18 +01:00
Berthold Stoeger
9b7565e81a statistics: turn ChartGrid into QSGNodes
Turn the background grid into QSGNodes. Each grid line is
represented by a QSG line item. An alternative would be
drawing the grid into a QImage and blasting that onto the
screen. It is unclear which one is preferred.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 08:47:18 +01:00
Doug Junkins
31e26fd144 mobile: add GF fields for ceiling calculation
Adds fields to the advanced preferences page to modify GFLow and GFHigh for
the Buhlmann decompression model for calculating ceilings. Updated preferences
code to set the Buhlmann parameters in core/deco.c when the GF prefs are
updated.

Signed-off-by: Doug Junkins <douglas.junkins@gmail.com>
2021-01-19 12:34:46 -08:00
Berthold Stoeger
32ec9a8726 undo: remove invalidate_dive_cache call from MainTab
When creating the RenumberDive undo command, the MainTab
would manually call invalidate_dive_cache(). However, this
is done on undo/redo, therefore the call can (should) be
removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-11 08:42:17 -08:00
Berthold Stoeger
7819683990 profile: remove ProfileWidget2::dateTimeChanged()
This function sent a signal and the only listener was removed
in the previous commit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
e7907c494f statistics: convert chart to QQuickItem
It turns out that the wrong base class was used for the chart.
QQuickWidget can only be used on desktop, not in a mobile UI.

Therefore, turn this into a QQuickItem and move the container
QQuickWidget into desktop-only code.

Currently, this code is insane: The chart is rendered onto a
QGraphicsScene (as it was before), which is then rendered into
a QImage, which is transformed into a QSGTexture, which is then
projected onto the device. This is performed on every mouse
move event, since these events in general change the position
of the info-box.

The plan is to slowly convert elements such as the info-box into
QQuickItems. Browsing the QtQuick documentation, this will
not be much fun.

Also note that the rendering currently tears, flickers and has
antialiasing artifacts, most likely owing to integer (QImage)
to floating point (QGraphicsScene, QQuickItem) conversion
problems. The data flow is
QGraphicsScene (float) -> QImage (int) -> QQuickItem (float).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:16:52 -08:00
Dirk Hohndel
d63910caa3 desktop/update-check: fix logic when to ask about update check
Checking a field that we intentionally don't store to disk is obviously
wrong. It's been this way for a long time and it has annoyed me many
times, but somehow I never spent the time to track down why this was
happening.

It makes much more sense to use the presence of either the don't check
flag or a next check date as an indication that we have already asked
this question.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06 10:18:23 -08:00
Dirk Hohndel
fabeb71ade desktop/UI: move statistics to View menu
It seems to make more sense to have it there with the 'Yearly Statistics'
and not in the Log menu. Interestingly enough, both locations were clearly
considered when first adding this in commit 106f7a8e0e ("desktop: add
statistics widget dummy and application state") as you can tell by the
never implemented actionViewStats.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06 10:11:31 -08:00
Dirk Hohndel
2305ecc877 dekstop/UI: remove duplicate resource
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06 10:11:31 -08:00
Dirk Hohndel
19828510d9 desktop/UI: add shortcut for 'Open cloud storage'
This seems like a logical extension of the shortcuts we already have.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06 10:11:31 -08:00
Dirk Hohndel
77bc0c7c93 desktop: rename Statistics tab to Summary
We now have three different things that are kinda like statistics:
- the summary tab (reasonably useful when looking at selected dives)
- the yearly statistics (Ctrl/CMD-Y)
- the full statistics (Ctrl/CMD-T)

I'd argue that's at least one too many. But I'm sure some people will disagree.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-03 13:56:25 -08:00
Berthold Stoeger
7b0455b4d8 statistics: reverse chart selection logic
The old ways was to select the chart first, then depending on
the chart choose the binning.

Willem says that it should work the other way round: select
the binning (or operation) and make the charts depend on
that.

I'm not arguing one way or the other, just note that the new
way is much more tricky, because it is easy to get unsupported
combinations. For example, there is no chart where the
first variable is unbinned, but the second axis is binned
or has an operation. This makes things distinctly more tricky
and this code still needs a thorough audit.

Since this is all more tricky, implement a "invalid" chart
state. Ideally that should be never shown to the user, but
let's try to be defensive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-03 13:41:15 -08:00
Berthold Stoeger
106f7a8e0e desktop: add statistics widget dummy and application state
Add a new "statistics" application state. In the statistics state
show the statistics widget and the filter in the top quadrants.
The idea is to allow filtering and doing statistics at the same
time.

Sadly, we can't use the filter-widget in different quadrants,
because Qt's ownership model is completely broken / inflexible.
It does not support a widget having different parents and
thus a widget can only belong to one QStackedWidget.

Hiding the map in the statistics view is quite hacky:
Since the view of the quadrants is not determined by the
"ApplicationState", we have to restore the original quadrant
visibility when exiting the stats mode. Therefore, set the
original visibility-state when changing application state.

The MainWindow-quadrant code really needs to be rewritten!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-03 13:41:15 -08:00
Berthold Stoeger
165dce4a0e statistics: implement a statistics widget on desktop
Implement a widget that shows the statistics state as comboboxes
and the statistics chart. Calls into the statistics code if any
of the comboboxes changes.

The hardest part here is the formatting of the charts list with
its icons and with headings. Sadly, it is not trivial to arrange
icons horizontally. Therefore we would have to fully reimplement
the ComboBox view, which is probably not fun.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-03 13:41:15 -08:00
Berthold Stoeger
e943065977 cleanup: remove "GpsLocation *locationProvider" from MainWindow
This is mobile only and not used on desktop.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 12:38:50 -08:00
Berthold Stoeger
bbbd4c8818 cleanup: remove getDivesInTrip() in qthelper.cpp
This function was not used anywhere. Moreover, remove a few
unused includes from qthelper.h. Surprisingly, a number of users
of qthelper.h depend on these, so readd them at the appropriate
places.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
cc5ebd7414 printing: remove CylinderObjectHelper
With the removal of grantlee, this became pointless glue
code. Call the formatting functions directly.

Since the printing code was the only user of CylinderObjectHelper,
remove the whole thing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
ae182c386b printing: remove DiveObjectHelper from printing code
At this point (post grantlee), DiveObjectHelper is just pointless
glue code. Let's remove it from the printing code and call the
formatting functions directly. If necessary, move these functions
to core/string-format.cpp.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
d9942269a9 printing: remove DiveObjectHelperGrantlee
This was a weird helper object, needed for grantlee. Instead
of storing this object, loop over cylinders and dives directly.

The actual accessor function is unchanged and now generates
a DiveObjectHelper or DiveCylinderHelper for every variable
access. Obviously, this is very inefficient. However, this
will be replaced in future commits by direct calls to formatting
functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
dc37ba7758 cleanup: remove QPointer instances
QPointer is a strange "smart" pointer class, which resets itself
when the pointed-to QObject is deleted. It does this by listening
to the corresponding signal and therefore is surprisingly heavy
for a plain pointer. A cynic would say that the existence of
QPointer is an expression of Qt's broken ownership model.

In any case, QPointer was only used at two places, were it was
100% useless: As a parameter to a function and as a locally scoped
pointer. It only makes sense if
a) there is a chance that the object disappears during the pointer's
   lifetime and
b) it is actually checked for null before use
None of which was the case here. Remove.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
fa6eb6144b printing: move #includes from headers to source files
To decrease include-file interdependencies.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
2239ffe13c printing: remove YearInfo structure
This is a wrapper around "stats *" used to pass statistics
through Qt's weird metatype system. Not needed anymore.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
0310eb31da printing: refactor if and loop code
The loop code was buggy: the current position was only increased
inside when executing the loop once. This would obviously fail
for empty lists. Moreover, the whole thing was quite difficult
to reason about, since a reference to the current position was
passed down in the call hierarchy.

Instead, pass from and to values to the parse function and
create a generic function that can search for the end of
loop and if blocks. This function handles nested if and for
loops.

The if-code now formats the block only if the condition is true.
The old code would format the block and throw it away if not
needed.

This should now provide better diagnostics for mismatched tags.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
f42a70586b printing: remove objects QVariant map
An artifact from the old grantlee code: the whole parser state
was kept in an untyped QVariant map. One case was particularly
bizarre: the options were a class member and yet added to the
weird map.

Replace this by a strongly typed state structure. Ultimately,
this will allow us to replace the "dive object helper".

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
0cbb448740 cleanup: make templateOptions and printOptions reference types
These two structs describe options used during printing.
They are passed through numerous classes as pointer. In this
case, reference semantics are preferred, as references:
 - can never be null
 - can not change during their lifetime
This not only helps the compiler, as it can optimize away null
checks, but also your fellow coder. Moreover, it prevents
unintentional creation of uninitialized references: one can't
create an instance of a class without initializing a reference
member. It does not prevent references from going dangling.
However, pointers have the same disadvantage.

Contains a few whitespace cleanups.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
8d93192537 cleanup: remove MainWindow::stateBeforeEdit member
The last user was removed in accf1fcc8f.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:50:56 -08:00
Berthold Stoeger
53c2f34930 cleanup: remove unused typedefs
Last users removed in ca6aa38139.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:50:56 -08:00
Berthold Stoeger
296a391faa prefs: add option to display only actually used tanks
A user complained about the default cylinders list. Provide
a preferences option to turn this off.

When changing the preferences, the tank-info model will be
completely rebuilt. Currently, this is a bit crude as this
will be done for any preferences change.

Suggested-by: Adolph Weidanz <weidanz.adolph@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
11e576ffbf core: remove the "no-name" tank info
There was a tank info with an empty name. According to a comment,
this is needed for the "no cylinder" case. However, we now support
empty cylinder tables, so this is not needed anymore. Therefore,
remove it.

Make sure that the user can still enter the empty name, just in
case. But don't save the size and pressure in that case.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
a55c7ff079 desktop: don't save data to the "no-name" tank
There seems to be no point to saving data to the tank with
the empty name. Don't save tank-pressure and size to that
tank info.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
50b11024d6 core: keep tank infos in a dynamic table
The list of known tank types were kept in a fixed size table.
Instead, use a dynamic table with our horrendous table macros.
This is more flexible and sensible.

While doing this, clean up the TankInfoModel, which was leaking
memory.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
2e328c7633 cleanup: remove unused #undefs in mainwindow.cpp
These macros were removed 2016-ish.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12 15:52:40 -08:00
Berthold Stoeger
0ea5374f62 profile: move connect() calls to profile
The mainwindow was connecting preferences changes to the profile.
Do this directly in the profile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12 15:52:40 -08:00
Berthold Stoeger
41751a5899 cleanup: remove unused signal ProfileWidget2::updateDiveInfo
Last user was remove in 0bd821183d.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12 15:52:40 -08:00
Berthold Stoeger
3b2ae46eb8 profile: move DiveHandler to profile-widget folder
These are the small dots that describe dragable points on
the profile when in the planner. It makes no sense to have
them in desktop's planner-widget code. They belong to the
profile.

Therefore, move the code there and compile on mobile.

Not everything can be compiled on mobile for now, but it
is a start.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12 15:52:40 -08:00