In analogy to the timestamp -> QDateTime conversion, create a
common function.
1) For symmetry with the opposite conversion.
2) To remove numerous inconsistencies.
3) To remove use of the deprecated QDateTime::toTime_t() function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Move this function from maintab.cpp to qthelper.cpp. Since the
functionality was used in numerous places, use the helper function
there as well. This removes a number of inconsistencies. For example,
sometime setTimeSpec(Qt::UTC) was called, even though the
QDateTime object was already created with that time spec.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The divetripmodel.cpp, models.cpp and tankinfomodel.cpp source
files as well as the corresponding headers were listed as "general"
and as "desktop" models, i.e. twice. Remove the redundant entries in
the desktop list. This should have no consequence whatsoever.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The weightsystem- and cylinder-model headers were including "dive.h".
Inclusion of "equipment.h" is sufficient though.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We already allow filtering by tags, but don't even show them on mobile.
That seems rather inconsistent.
First step is to make the tags available to the QML layer.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The goal here is to remove a dependency on displayed_dive.
While doing so, make the model more general and display any dc.
Pass in the dc of the current dive instead of displayed dive,
since all other tabs are already converted to show data of
the current dive. The QStrings are cached since we generate
them anyway, so we may just keep them. Thus, there is no
danger of the dc becoming invalid.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of assigning to a ret variable and returning at the
end of the function, return directly from the various switch
branches. This is more idiomatic and consistent with the other
models.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
As we do in most other models, use begin/endResetModel() to
reset the model. This is distinctly less errorprone than
the add/removeRows() version as we don't have to check for
empty ranges, etc.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To reset the core data structures, the mobile and desktop UIs
were calling into the dive-list models, which then reset the
core data structures, themselves and the unrelated
locationinformation model. The UI code then reset various other
things, such as the TankInformation model or the map. . This was
unsatisfying from a control-flow perspective, as the models should
display the core data, not act on it. Moreover, this meant lots
of intricate intermodule-dependencies.
Thus, straighten up the control flow: give the C core the
possibility to send a "all data reset" event. And do that
in those functions that reset the core data structures.
Let each module react to this event by itself. This removes
inter-module dependencies. For example, the MainWindow now
doesn't have to reset the TankInfoModel or the MapWidget.
Then, to reset the core data structures, let the UI code
simply directly call the respective core functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We show an icon whether there are pictures and whether they are
before or after the dive. Thus, the list models must emit the
proper signals when the pictures of a dive change.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The code is rather complex. Firstly, we have different representations
of pictures throughout the code. Secondly, this tries to do add the
pictures in batches to the divepicture model and that is always rather
tricky.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
QVector doesn't have a function to insert a range of pictures,
which we will need for undo of image adding/deletion.
Moreover, std::vector gives us stronger guarantees. For example,
if capacity is large enough, it guarantees that there will be
no reallocation and thus iterators stay valid. I have not found
such a guarantee in the Qt docs.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
dive-pointers are stable and the dive picture model is reset
if a selected dive is removed, so there is no risk in keeping
pointers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Even though the functionality is seemingly trivial, this is a bit
invasive, as the code has to be split into two distinct parts:
1) Post undo command
2) React to changes to the divelist
Don't compile that code on mobile.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For consistency with equipment, use our table macros for pictures.
Generally tables (arrays) are preferred over linked lists, because
they allow random access.
This is mostly copy & paste of the equipment code.
Sadly, our table macros are quite messy and need some revamping.
Therefore, the resulting code is likewise somewhat messy.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To display changed SAC values it is necessary that the models
emit changed signals when cylinders are edited. An alternative
might be that the undo commands emit dive-changed signals themselves.
Fixes#2814.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In the planner the undo commands for adding / editing dives were
only called if not on mobile. This is from days were mobile didn't
have undo commands. We can remove these now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There was only one caller of MainWindow::setupForAddAndPlan() left
and that caller immediately called DivePlannerPointsModel::createSimpleDive().
Thus, we might just as fold the former in the latter and thus
concentrate all the prepare-dive-for-plan business in one place.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Thus, the MainWindow doesn't have to extract the plan from
displayed_dive. This is a tiny step in an attempt to detangle
the interfaces. The bigger goal will be to make displayed_dive
local to the planner.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When calculating variations, they were sent to the mainwindow,
which updated displayed_dive accordingly. Do this directly
in the planner-model.
The idea is to detangle interdependencies and to make the
code reusable (planner on mobile?).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This will be temporarilly used by the planner to mark consumption of
air at the surface. Do this by creating a new function add_cylinder,
which replaces add_to_cylinder_table() and takes care of always adding
a dummy cylinder at the end of the table. Make the original
add_to_cylinder_table() local, so that it cannot be accessed anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It appears that some misguided compiler / library combinations crash
on &vector[0] for empty vectors. Even though very unfriendly, they are
technically correct, so let's remove these constructs.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
I would have bet money that Android used to send stderr to the logcat
log, but apparently it doesn't (anymore?). So in order to be able to
have a chance to debug weird cloud storage issues on Android, let's do
some wholesale replacement of fprintf(stderr,...) with our own version
of the INFO macro that we long ago borrowed from libdivecomputer (and
rename it to ensure we don't have a conflict there).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In 9310d72943, resetting of the dive
sites was moved to DiveTripModelBase::reset(). This seemed like a
good idea, because it means that the location list is reloaded
every time the dive list is reset.
Unfortunately that function is only used on mobile, thus on desktop
the dive site model is not updated. Do that in
MultiFilterSortModel::resetModel(), because this is always called
when the dive list is reset. Desktop differs from mobile in that
two different models are used depending on whether we are in list
or in tree mode.
Fixes#2749
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When initializing the fulltext-cache and the dive-list, every
100 dives a notification was shown. I had a feeling that this
made startup significantly slower, but that could have been
purely psychological.
Therefore I measured and indeed, removing the fine-grained
notification, it becomes *significantly* faster. For a 3500
dives test log with mobile-on-desktop:
Initialization of the fulltext: 1350 ms -> 730 ms (-46%)
Initialization of the divelistmodel: 689 ms -> 113 ms (-83%)
Let's remove the fine-grained notification. There *is* a visual
indication of work-in-progress anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The planner does not know about events except gas
changes. But if the dive comes from the log, we
should preserve the dive computer events. At least
those that happend before we started to delete
waypoints to let the planner take over.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The DivePictureModel kept a pointer to picture for each entry.
Firstly, this is dangerous from a data-consistency point of view.
Secondly, the entry wasn't even used anywhere. Remove it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of assigning to a QVariant ret and returning at the end,
return directly in the various switch-cases. This makes the code
more readable, and is more idiomatic C++, as it avoids unnecessary
copies.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Parts of the code were not compiled on mobile, because they used
the undo-command infrastructure. However, since mobile now also
compiles that, we might as well remove the conditional compilation.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When editing cylinders or weights directly in the table widgets,
no warning was shown if multiple dives were affected. To solve this,
emit signals from the respective models and catch them in dive
equipment tab. Not very nice, but it works for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Don't overwrite the full cylinder when editing a single field.
Implement three "modes": editing of type, pressure and gasmix.
Don't consider individual fields, because some of them are
related. E.g. you can change the gasmix by setting the MOD.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
On desktop, we have two CylindersModel concurrently: One in the
planner and one on the equipment-tab. They act differently, because
the former modifies displayed_dive directly, the latter issues
undo commands.
To differentiate, we used the in_planner() function. However, that
appears extremely brittle, especially when combined with undo-commands.
Therefore when generating the model, pass in a parameter that says
whether this is for the planner or the equipment tab and use
that flag to decide how to act.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Call an undo command when editing cylinders, but only if on
the EquipmentTab.
To keep code changes small, make a copy of the cylinder first,
then edit the cylinder as before and then either call an undo
command (EquipmentTab) or overwrite the old cylinder (Planner).
The memory management here is a bit strange: Since the undo-command
itself makes a deep-copy of the passed in cylinder, we only do
a shallow copy. If we have to change the type, we allocate the
string with an std::string, so that the memory is automatically
freed at the end of the function. However, this means that in
the planner we have to make a deep copy first, swap old and
new cylinder and finally release the old cylinder. Certainly
not ideal, but for now the pragmatic thing to do.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This one is tricky, as when browsing through the types-combobox,
the user is presented with presets without actually changing the
dive. We do not want an undo-command for every change-event in
the combo-box.
Therefore, implement a scheme analoguous to the weight-editing:
A temporary row can be set / committed or reset. Sadly, the
code is more complex because we have to consider the planner,
which is not included in the undo system.
Firstly, the planner uses a different model, therefore all
interactions are channeled through setData() with special roles.
Secondly, in the planner we shouldn't place an undo command,
but simply overwrite the dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
add() and remove() are not used anymore since this is done using
undo commands. The planner uses CylindersModel instead.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The CHANGED macro was defined in the cleanerTableModel header.
Since it had only one user, expand it there. The macro was very
questionably anyway, as it would set the local "vString" variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
A small code consolidation:
With one exception, all targets of the switch statement would
test for CHANGED(). Instead do the test once and exit early.
This changes the behavior of the function: if not changed, there
will be no more dataChanged-signal. However, this appears to be
the correct thing to do anyway. And it is easily changed if
it matters after all.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Cylinder-editing is controlled by undo (either by saving a planned
dive or by using the equipment tab). There is no point in setting
the dive_list_changed flag.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The cylinders in the events must be reordered if we remove
a cylinder. To avoid duplication of code, move the reordering
function into qthelper.cpp, though it might not be ideal
there.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The CylinderModel always accessed the global "displayed_dive" and in
some special cases also "current_dive". To implement cylinder undo,
the model should work on an arbitrary dive. Therefore, in analogy
to the weight model, make the dive dynamic.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>