Instead of intializing the text fields and then changing the
font scale via signal-rigmarole, pass down the font-scale
at construction time.
Since the fontPrintScale is only set in print mode, we also
can access it directly instead of testing for printMode.
Since the DiveTextItem is not updated using signals anymore,
the connected flag can be removed.
The commit is larger than I had hoped for, but this makes
things ultimately less brittle.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was just a stub to make the setVisible() function a "slot".
Since there are no more signals using it, remove it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The visibility is set on every redraw, which is called when
the preferences change. No need for these signals.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveCalculatedCeiling had a back-pointer to the profileWidget.
This was used for weird control-flow shenanigans, which were
removed in 975c123a30.
Remove this now useless member variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The "in_planner" condition was inadvertently inverted in
c6d78bc134 and therefore the wrong data was used to draw
the line (density instead of SAC). Revert to original.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To remove reliance on global state, pass an "in_planner" argument
to AbstractProfilePolygonItem::replot(). Thus, calls to in_planner()
can be removed.
This is a bit sad, since the in_planner argument is now passed
to numerous replot() reimplementations of classes derived
from AbstractProfilePolygonItem. However, it is only needed
for one, viz. DiveGasPressureItem. Well, perhaps in the future
more features will depend on the planner mode...
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>
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>
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 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>
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>
settingsChanged() is a virtual function, which is called
when the preferences dialog signals changes. In most derived
classes, the function does nothing.
In two classes, DiveProfileItem and DiveCalculatedTissue, it
replots the item respectively changes its visibility.
However, these two flags are *not* controlled by the preferences
dialog. Indeed, the functions are also connected to finer-grained
qPref signals. Therefore, settingsChanged() can be removed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The profile items had a "setModel()" function to set
the DivePlotDataModel post creation. The model is never
changed. It does however mean that the model might be
null in a short period between construction and setting
the model.
To simplify reasoning about this code, set the model
in the constructor. To drive the point home that the
can never change and cannot be null, turn it into a
reference.
Yes, this is gratuitous bike-shedding, but it helps
me analysis the code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveCalculatedCeiling profile-item has a recalc()
function, which calls "dataModel->calculateDecompression()".
This is a questionable reversal of control-flow: The
profile-item should paint the model-data not change it.
The code was supposed to be called under two conditions:
1) The value of the calcceiling3m preferences flag changed.
This code was buggy for two reasons: Firstly, the cached
value was always initialized to false, which means that
sometimes the first call was missed. Secondly, the
settingsChanged() functions was only called when closing
the preferences window, not when changing the flag in the
profile widgets.
2) The datetime of the dive changed. The whole control-flow is
pretty absurd (due to "bit rot"):
- The replan-dive command sends a date-time changed signal.
- The main tab changes the date-time and informs the profile.
- The profile sends a signal to the item.
- The item instructs the model to recalculate the
decompression.
- The model causes the profile to be redrawn.
In any case, the whole thing is moot, because the decompression
is recalculated for *every* profile plot in create_plot_info_new().
Let's remove the code from the DiveCalculatedCeiling profile-item
and the calculateDecompression() function, which is now not
used anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
So far, the PreferencesDialog emitted a settingsChanged signal.
This meant that models that listened to that signal had to
conditionally compile out the code for mobile or the connection
had to be made in MainWindow.
Instead, introduce a global signal that does this and move
the connects to the listeners to remove inter-dependencies.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Now, that we have this helper function that should have been
introduced long ago, we can make some more expressions
more idiomatic.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
This adds a tab for dive log - related preferences.
A suitable test programs is still required.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of accessing the cylinder table directly, use the get_cylinder()
function. This gives less unwieldy expressions. But more importantly,
the function does bound checking. This is crucial for now as the code
hasn't be properly audited since the change to arbitrarily sized
cylinder tables. Accesses of invalid cylinder indexes may lead to
silent data-corruption that is sometimes not even noticed by
valgrind. Returning NULL instead of an invalid pointer will make
debugging much easier.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of using fixed size arrays, use a new cylinder_table structure.
The code copies the weightsystem code, but is significantly more complex
because cylinders are such an integral part of the core.
Two functions to access the cylinders were added:
get_cylinder() and get_or_create_cylinder()
The former does a simple array access and supposes that the cylinder
exists. The latter is used by the parser(s) and if a cylinder with
the given id does not exist, cylinders up to that id are generated.
One point will make C programmers cringe: the cylinder structure is
passed by value. This is due to the way the table-macros work. A
refactoring of the table macros is planned. It has to be noted that
the size of a cylinder_t is 64 bytes, i.e. 8 long words on a 64-bit
architecture, so passing on the stack is probably not even significantly
slower than passing as reference.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The goal here is to make it possible to detach the pressure related
data from the plot_info structure. Thus, the pressure related data
can be allocated independently depending on the number of cylinders
per dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When keeping track of cylinder related data, the code was using
static arrays of MAX_CYLINDERS length. If we want to use dynamically
sized cylinder arrays, these have to be dynamically allocated.
In C++ code, this is trivial: simply replace the C-style arrays
by std::vector<>. Don't use QVector, as no reference counting or
COW semantics are needed here. These are purely local and unshared
arrays.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The planner can produce negative cylinder pressures when
more gas is used than available. Let's color the pressure
graph in a highly visible color to alert the user of the
fact that current gas planning is insufficient.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
There is absolutely no reason to use a macro here.
The only argument that can be made is consistency with
the other pressure-macros, but those too are questionable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
At some places we use UTF8 string literals. Therefore, we effectively
only support UTF8 build systems. We might just as well remove all
the other UTF_* macros and use direct string literals.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Remove a few cases of
void fun() {
...
}
While touching these functions, fix a few other whitespace
coding style violations.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Commit f5b11daffd changed gasmix
arguments and return values to be passed by value instead of
using pointers.
Notably, get_gasmix() is fed a default-value and returns a
new value. In the old code, NULL was passed in in a first
loop iteration and non-NULL was always returned in the first
iteration. Thus, an equality comparison of passed-in an
returned gasmix would always fail in the first loop iteration.
The new code passed in air as default. Now if air was also
returned, then the matching gases were not calculated in
calculate_sac(). To revert to the old behavior, pass in
an invalid gasmix.
Moreover, give names to the invalid and air gasmixes.
Reported-by: tormento <turment@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These were pointers into the global prefs object. The user must
not use these to modify the settings, therefore make them
pointers-to-const.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is another entry in the series to make more things
"const-clean" with the ultimate goal of merge_dive() take
const pointers.
This concerns functions taking pointers to events and
the fallout from making these const.
The somewhat debatable part of this commit might be
that get_next_event() is split in a two distinct
(const and non-const) versions with different names,
since C doesn't allow overloading. The linker should
recognize that these functions are identical and remove
one of them.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In a previous commit, the get_gasmix_* functions were changed to
return by value. For consistency, also pass gasmix by value.
Note that on common 64-bit platforms struct gasmix is the size
of a pointer [2 * 32 bit vs. 64 bit] and therefore uses the
same space on the stack. On 32-bit platforms, the stack use
is probably doubled, but in return a dereference is avoided.
Supporting arbitrary gas-mixes (H2, Ar, ...) will be such an
invasive change that going back to pointers is probably the
least of our worries.
This commit is a step in const-ifying input parameters (passing
by value is the ultimate way of signaling that the input parameter
will not be changed [unless there are references to said parameter]).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently, get_gasmix_from_event() and get_gasmix() return pointers
to either static or to (possibly changing) dive data. This seems like
a dangerous practice and the returned data should be used immediately.
Instead, return the gasmix by value. This is in preparation of
const-ifying input parameters of a number of core functions, which
will ultimately let the merge() function take const-arguments in
preparation of undo of dive-merging.
On common 64-bit systems gasmix (two "int"s) is the size of a pointer
and can be returned in a register.
On 32-bit systems a pointer to the struct to be filled out will be
passed.
Since get_gasmix() now returns a value, the first invocation is
tested by a NULL-initialized "struct event *". Document this in
a comment.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
remove use of SettingsObjectWrapper::
remove include of SettingsObjectWrapper.h
use qPrefFoo:: for setters and getters
replace prefs.foo with qPrefXYZ::foo() where feasible
(this expands to the same code, but gives us more control
over the variable).
Signed-off-by: Jan Iversen <jani@apache.org>
remove TechnicalDetails from SettingsObjectWrapper and reference qPrefTechnicalDetails
update files using SettingsObjectWrapper/TechnicalDetails to use qPrefTechnicalDetails
this activated qPrefTechnicalDetails and removed the similar class from
SettingsObjectWrapper.
Signed-off-by: Jan Iversen <jani@apache.org>
helpers.h included qthelper.h and all functions declared in helpers.h
were defined in qthelper.h. Therefore fold the former into the latter,
since the split seems completely arbitrary.
While doing so, change the return-type of get_dc_nichname from
"const QString" to "QString".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This changes the numeric format of many values printed to the UI to
reflect the correct numeric format of the selected locale:
- dot or comma as decimal separator
- comma or dot as thousands separator
In the Qt domain the `L` flag is used case specific mostly
in qthelper.cpp.
Then the helper functions get_xxx_string() are used more consistently.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
Use struct temperature_t for temperatures in struct stats_t and
use get_temperature_string() when printing these temperatures for
statistics and HTML export.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
Bring one more value plus unit pair which is the pressure value printed
in the profile in accordance with the coding style/UI style rule of
not having a space between value and unit.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
current_dc is a macro that determines the dive computer
based on the current dive number. When the planner is started
from an emtpy dive list, the dive number ends up being -1 and
that doesn't produce a valid dive computer. Use the divecomputer
of the displayed_dive instead. This is done via a macro that
can also be used in two other places. Without this patch, the
planner crashed when called on an empty dive list.
Signed-off-by: Robert C. Helling <helling@atdotde.de>