I was coninced that that rather than doing an order of
magnitude estimate of the confidence region it's better
to have the correct concave shapes that indicate the
95% confidence level for the regression line.
It also turned out that the previous expression was
missing a factor of 1/sqrt(n).
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The goodness of fit of a regression line is the percentage
of the variance of the y values that is explained by the
dependence on the x values.
Set the alpha value of the regression line to this goodness
of fit.
Further, set the width of the regression line to a standard
deviation of the values from the regression line valies.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The repositioning message when a virtual keyboard opens is useful enough
to keep it and just hide it unless in verbose mode. The others have all
outlived their usefulness.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There are two sets of messages that tend to dominate the logs
- the RSSI updates from the Qt BLE stack
- the warnings about deprecated signal use in Kirigami
Neither of them provide any value to us when trying to find bugs; and
often they end up hiding the things that we really care about. So let's
just not log them - which is easy as we have our own message handler.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
First, the time zone adjustment was wrong - this as written could only
ever have worked in UTC or by pure chance.
Second, the order of alerting the UI of the availability of a GPS fix
was also incorrect creating a race between the UI and our data
structures.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Based on a dummy commit from Berthold, this provides a styled popup of
the available chart types for the current variables.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Create a QML ChartListModel in the StatisticsPage and pass that to the
StatsManager on initialization.
[extracted from a slightly larger commit]
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In order to be able to correctly size the chart type popup, we'll need
access to the total count or rows as a property that signals changes to
QML.
The hack to use rowCount() as the READ function requires that rowCount()
can be called without argument, therefore the addition of a default
parent.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For QML, the roles have to be associated dynamically with
name. Moreover, the model has to be registered as a QML
type to make it accessible from QML.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
That seems to be the most commonly usefule chart.
This also removes some noisy log messages; these were super useful
during development, but should have been merged.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
After spending so much time trying to make things work well on smaller
screens I completely missed that there was an off by one error making
the statistics display way too small on larger tablets in landscape mode.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This changes most readonly combo boxes to use the smaller, more modern
looking TemplateSlimComboBox and makes some layout adjustments on a few
pages to overall create a better UI.
A lot of this is just cleaning up things that were rather rough in the
first place.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Especially on smaller screens in landscape mode (which is nice for
statistics) the image took up way too much space. Now it gets cropped in
a way that makes sure all the information text is visible, but not too
much space is stolen from the rest of the menu.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This one is designed to be fixed size and space efficient, non editable.
It's used in the statistics page for now and looks much better than what
we have elsewhere, so the style should propagate to the rest of them as
well, but this is trickier for the once that are editable - and of
course the fixed width might also not be appropriate in other places.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The code was protecting against the wrong member being NULL.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When setting a CCR setpoint, the profile code(!) would turn
the dive into a CCR dive. Not only should the display layer
not alter dives, this also means that the action is not
undoable.
Move that to the appropriate undo command, where it makes
more sense, but obviously also makes things more complicated.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The make_first_dc() function clones a dive with a certain dive
computer moved to the front. This is used by the
MoveDiveComputerToFront undo command.
make_first_dc() calls invalidate_dive(). However, the undo
command does that by itself on every undo/redo. Thus,
remove the call in make_first_dc().
Aside from consistency, the goal is to move invalidate_dive()
to command/* so that we can be more aggressive about the whole
topic: Store only "const dive *" pointers and thus force any
writing access to explicitly invalidate the dive cache.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
The AddWeight, RemoveWeight, EditWeight and ReplanDive
commands were missing invalidate_dive_cache() calls.
Add them to ensure that the dives are written to git
logs on save.
Fixes#3150
Reported-by: Peter Zaal <peter.zaal@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In categorical axes all labels were printed leading to a big
tohu wa-bohu for two many bins. Therefore, if a label is
larger than the space between two ticks, replace by an ellipsis.
Adjust the size of the ellipsis (".", ".." or "...") to the
available space.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code didn't consider that labels can peak out of
horizontal axes if labels are under ticks.
This commit takes this into account. However, it must be
noted that this is only heuristics: Before setting the
size of the axes, the actual minimum and maximum label are
not known, because we round to "nice" numbers. But the
size of the axis can only be set after knowing the overhang,
leading to a circular dependency. Therefore, the code
currently simply uses the minimum and maximum value of
the data, hoping that the "nice" values will not format
to something significantly larger. We could do a multi-pass
scheme, but let's not for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This also includes the already merged statistics for mobile.
All of this still needs to be added to the user manual.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
So far only DC provided ceiling information was available and visibility
of that was simply inherited via cloud storage from the desktop.
With this the user can set both DC reported and calculated ceilings in
the advanced settings in the mobile app.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This allows us to force a redraw of the dive profile when settings change
that require a refresh of the profile.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This now actually displays the calculated ceiling in the profile. There is
still an issue where if the user toggles the setting the already cached profiles
aren't recalculated - that's part of a bigger profile cleanup effort.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The profile had a static variable which prevented animation
when first showing the profile. It appears more logical to
don't show the animation when switching from the empty state.
This removes global state, as a function static variable
exists only once, even if there are multiple objects.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveHandler shows a context menu where a cylinder can be
chosen. This indirectly accesses the global displayed_dive
variable.
Remove this in a step to make the profile reentrant.
The code was quite ominous: instead of simply generating the
list of cylinders, a global model was reset and then accessed
with Qt's cumbersome model/view API. All this trampling over
global state can be removed by simply making the function
that generates the list globally accessible.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of accessing the global displayed_dive variable
in RulerItem, pass the dive. This is a step in making the
profile reentrant.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of accessing the global displayed_dive variable,
pass the dive to the various profile items. This is a
step in making the profile code reentrant.
This removes the last user of the displayed_dc macro,
which can now be removed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Don't access the global displayed_dive variable in an effort
to make the profile reentrant.
Note that this still accesses the global dc_number variable,
which will likely have to be removed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The profile item that shows the ceilings adds a warning event
if the ceiling is violated. This is very unfortunate.
Improve this situation by adding the event up to the function
that calculates the ceiling. This is still not how it should
be - the display layer should not modify the dive that it
displays.
To make this clear, add a comment that details that this
is a contract between planner and display layer: The planner
uses a dive that can be trampled upon by the profile.
Still, this should be solved differently.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The in_planner() function is incompatible with a reentrant
profile, since it accesses a global variable. In
create_plot_info_new() it is essentially redundant, because
there is a planner_ds (ds = deco_state) parameter that
is used only when in the planner. Therefore use that as
the in_planner indicator: when non-null, the profile is
showing a planned dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was used to force a replot on preferences changes.
However, the profile now does a replot in such a case
by itself. This can be removed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
With the same argument as for DivePercentageItem, move access
to live data out of the paint() function. Instead, calculate
colors in replot(), where the other data are calculated.
This is slightly more complicated than in DivePercentageItem,
since there are multiple polygons. Therefore, replace QPolygonF
by a vector of structures contained the position and color
of the data point.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DivePercentageItem is a polygon-item with a custom paint()
method. Calculation of the polygon is done once in replot(),
but calculation of the corresponding colors is done in every
paint() call. The problem is, we have no control over paint().
It is called whenever Qt feels like. Therefore using live
dive data is a dangerous proposition if we ever want to get
rid of the global displayed_dive.
Do all the calculations in replot(). Store the colors in an
additional array of the same size as the polygon.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The only time the TankItem is replot is when new data is set.
Therefore, replot() can be folded into setData().
The good thing is that setData() is passed the dive to be
plot. So the data can be extracted from there instead of
the global displayed_dive variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The code tried to only replot the profile if necessary, notably
when in edit mode or the ceilings are shown.
That seems like pointless premature optimization, which only
complicates things: The profile is replot every time a
"dive handle" is moved, which means that we depend on the
replotting being reasonably fast. Why should it then not
be redrawn if the settings change?
Let's remove this, as it makes control flow easier to reason
about.
This makes the isPlotZoomed member variable redundant. Remove it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old mechanism to replot the profile items was to listen
to model-change signals. Then the code checked whether it
actually had to update anything by looking at the changed
model-indices.
However, the crucial replot was always initialized with
emitDataChanged(), which simple invalidated the full model
and therefore shouldCalculateStuff() always returned true.
Since now the replot() is called explicitly, remove the whole
logic and simply rename modelDataChanged() to replot().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of listening to the dive-data-model changed and
axis changed signals, update the profile items explicitly
once per plot() call. This avoids double replotting of the
dive items.
The old code had at least two replots per plot() call:
one after profileYAxis()->setMaximum() and one after
dataModel->emitDataChanged().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
On each profile replot, the gas axis was implicitly reset
by calling "dataModel->emitDataChanged()", which would send
a signal recieved by the axis. To make the code less confusing
and, more importantly, make order of execution deterministic,
explicitly reset the axis.
Rename the function that resets the axis from "settingsChanged"
to "update" to reflect its usage.
Moreover, remove the "setModel()" function and pass the model
to the constructore. Make it a const reference to make clear
that it can't change during the life time of the axis.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These functions return the maximum partial pressures in the
given dive. Obviously, being pure accessors, they should be
const.
This commit also replaces the macro generating these functions
by a call to a function taking a pointer-to-member. Arguably,
C++'s pointer-to-member syntax is just as horrible as macros,
but at least it doesn't mess with syntax highlighting of
my editor and should be better to debug.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This virtual function is not used as the target of a signal
anywhere, which means that it shouldn't be a slot.
Moreover, mark the one place it is overriden as override.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In contrast to most other items, which are cleared in the
setEmptyState() function, the profile items are cleared
indirectly via a signal from the model. Very hard to follow
and indeed, I thought I could just remove the slot.
Do this explicitly instead for deterministic code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>