When editing a dive site, the user can search for close dive sites
to merge duplicates. Dive sites without location are treated as
being located at 0N0E. This makes no sense, because:
When selecting a dive site without location, we shouldn't list
dive sites close to 0N0E.
Likewise when having a dive site close to 0N0E, we shouldn't list
dive sites that have no location.
Therefore, ignore these cases.
This also means that now dive sites without location are not
considered as close to other dive sites without location. That
might be a debatable point.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We tend to use lower-case filenames. Let's do it for these files
as well. Simple search & replace.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It shouldn't happen, but currently we overwrite the displayed_dive
without updating the CylindersModel. Thus, CylindersModel may now
crash when the new displayed_dive has less cylinders than the old
one.
For now, catch this condition. Treat the root cause later.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In some case the scaling (real value <-> UI value) is different
for mobile and desktop. In order to make the difference understandable
comments are added to each function.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
setBottomSac, setDecoSac and setFactor in diveplannermodel
receives display value which are then converted.
subsurface-mobile have slightly different values, move the
correction of these from plannershared to diveplannermodel, in
order to keep the whole convert in one place.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Change ascent/descent setter function names to set_<name>Display
to show the value is prepared for displaying (common for desktop and QML).
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
diveplannermodel already contains set_<asc/desc> function that convert from
screen value to real value; this adds get functions that convert real value to
screen value, so now all conversions are done in one place.
Use prefix Display to identify this is values prepared for the UI (both desktop
and QML).
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In order to make tests for plannerShared, some qt-models must
be linked, and due to the fact that commands are currently not
available for mobile (which also makes the tests) and #ifdef must
be added.
The test version of diveplannermodel will be specially compiled in
(SUBSURFACE_TESTING set) in the tests directory.
Signed-off-by: Jan Iversen <jan@casacondor.com>
add diveplannermodel to GENERIC instead of DESKTOP
as a consequence other models are need, move those
from DESKTOP to GENERIC
Signed-off-by: Jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
commands (undo) are not available for mobile, but diveplannermodel
is needed
add #ifndef MOBILE around Commands::
Signed-off-by: Jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Use std::equal_to instead of lambdas that compare two dive pointers.
One could argue over which version is more readable. For whatever
it's worth, std::equal_to is more compact and expressive.
This removes an old erroneous comment that stated that std::equal_to
is only available since C++14.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
LOG_STP is on longer providing the data needed, since a lot of the startup
is indirectly in QML, furthermore using the xcode project and running profiler
gives much more detailed information
Signed-off-by: Jan Iversen <jani@apache.org>
On desktop, resetting the model is realized by generating a new
model object. This is due to the fact that we have two different
models (tree and list) and for switching between those, we have
to create a new object.
On mobile, currently there are no plans to support the list-mode.
Therefore, there is no reason the recreate the object. Instead,
implement a reset() function that reloads the core data.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveTripModelList forgot to collect the changed dives
when resetting the filter. Fix that.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Updating the filter can lead to changes of the current dive.
Keep the UI in the know by re-initializing the selection.
This is not optimal, because the whole selection is reset,
but the pragmatic thing to do for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This part of the code had that horrible pattern, where reseting
the model would invalidate all pointers to the DiveTrip model.
Internalize these complexities in the MultiFilterSortModel.
All accesses are now performed via that proxy model.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The UI talks to the filter model. Therefore route clearing of
data through that model instead of accessing the source model
directly.
This will allow us to remove the DiveTripModel::instance()
function and makes control flow less "jumpy".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code called directly into the DiveListModel. Instead,
send a signal and hook into the signal from the model. This
will allow us to remove the DiveListModel::instance() function.
This, in turn, is a step towards supporting multiple models
at the same time. However, currently the model manually
sets the hidden_by_filter flag in the core and therefore
only one active model is supported at a time.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently, the caller is responsible for not reusing a freed
weightsystem / cylinder or resetting the description field to
null. This is very unfriendly. Set the description field to null,
because that allows us to call free_* repeatedly on the same
object. Use the new behavior to make the weightsystem model code
a bit cleaner.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since changes to the weight model are not modal anymore, nobody
queries the changed-flag. Remove it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Implement the EditWeight undo command. Since there is common code
(storage of the old weight), this creates a common base class for
RemoveWeight and EditWeight. The model calls directly into the undo
command, which is somewhat unfortunate as it feels like a layering
violation. It's the easy thing to do for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The WSInfoDelegate (weight-system-info delegate) is used to display
a combo box of known weightsystem-types and auto-fills the weight if
the weightsystem-type is changed.
This would overwrite the weight data of the displayed dive when the
user hovers over the different entries. Moreover, it saves the original
weight in case the user cancels the editing action.
This is not viable when implementing undo of weightsystem changes,
because hovering over entries should not produce individual undo
commands. Instead, implement a special "temporary" row in the
weightsystem model. On canceling of the edit actions, simply reload
the weightsystem from the unmodified dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To make things more future-proof, introduce an empty_weightsystem
constant. Replace explicit aggragate initialization of empty
weightsystems by this constant.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Before undoization, the WeightModel could be out-of-sync with
the actual dive and therefore had a row member variable. This
became redundant. Therefore, remove it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There is only one caller of WeightModel::weightSystemAt() and that
certainly does not need a pointer into the weightsystem-table of
the current dive. Return a value type instead of a pointer.
This allows us to mark WeightModel::weightSystemAt() as const and
use it from WeightModel::data(). Slightly cleaner code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This one is a bit more complicated than weight adding, because the
multiple-dive case is not well defined. If multiple dives are selected,
this implementation will search for weights that are identical to the
weight deleted in the currently shown dive. The position of the weight
in the list is ignored.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When connecting a model to the TableModel class, it would connect
clicking on an item to the remove() slot of the model.
This breaks the program flow implied by the undo code:
Ui --> Undo-Command --> Model --> UI
Moreover, the naming of the remove() slot is illogical, because
clicks can also have different effects, as for example in the
cylinder-table.
Therefore, move the connect() call from TableModel to the
callers. In the case of TabDiveSite, move the remove() function
from the model to the TabWidget, where it makes more sense.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Introduce an AddWeight undo command. This is modelled after the
numerous dive-edit undo commands. The redo and undo actions are
connected to the WeightModel via two new signals, weightAdded
and weightRemoved.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The WeightModel always acted on the displayed dive. To support undo
of weightsystem changes, operate on an arbitrary dive. This is
in line with other models, where the updateDive() function resets
the model to represent a certain dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveListView caught signals from the DiveTripModel
with the corresponding indexes. However, the DiveListView
is actually connected to the MultiFilterSortModel and
thus has to translate the indexes.
Instead, catch the signals in the MultiFilterSortModel,
transform them and resend. Let the DiveListView get
its signal from the MultiFilterSortModel.
Yes, this makes things less efficient because there is
an extra signal. On the upside, the makes data-flow much
more logical. Selection will have to be fixed anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The goal here is to unify desktop and mobile by moving
selection code from the desktop-only view.
Currently, initialization of the selection still has to be
called from the view after connecting the appropriate signals.
This is due to the weird way in which create completely new
models when resetting them.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The dive-trip models now send changed-events if the shown-status
changed. Thus, there is no reason to fully reset the filter on
filter changes.
Simply tell the filter that it has to react to changes of SHOWN_ROLE.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In analogy to the tree-model send signals when dives change
their shown status in the list-view. Do this in two passes
(collect changes; send changes) to be able to reuse the
already existing functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Send signals if the shown-status of top level items changed.
Do this in two passes to be able to use the previously created
function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To avoid having to do full filter reloads, send dive-changed signals
for dives in trips when the shown-status changed. But only for trips
where not all dives are hidden. Because for those, the plan is to
hide the trip as a whole.
Implement the signal sending in its own function so that it can be
reused for top-level items and the list-view.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Implementing proper model semantics (only sending a changed
signal for items that actually changed) will be somewhat
complicated. Therefore, move the filtering of trip-items
to its own function to make the nesting a little bit less
deep.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Change the remove() function of the cylinder and weight models
to take the index by value. The code used to take it by reference
and the reference would be invalidated when removing rows from
the model!
Reported-by: Gaetan Bisson <bisson@archlinux.org>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveListModelBase::clear() implementation was flawed: It cleared
the data in the core, but left the data in the model untouched.
The code was relying on the fact that the caller would reset the
model manually. Not a good idea.
Therefore, clear the internal data to keep the model consistent at
all times.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The way this was accessed via Qt's model semantics was horrible.
This gives arguably more readable code, since we don't have to
shoehorn things through QVariants.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Split out the actual filtering from the MultiFilterSortModel.
Create a DiveFilter class that does the actual filtering.
Currently, mobile and desktop have their own version of this
class, though ultimately we may want to merge them.
The idea here is that the trip-model and undo-commands have
direct access to the filter-function and thus can take care
of keeping track of the number of shown dives, etc.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The filter-model was catching dives-added / dives-deleted signals
from the models to keep track of the number of shown dives.
To simplify the data flow, do this directly in the undo-command.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We mark hidden/shown dives in the core but store the number
of shown dives in the MultiFilterSortModel. Move this datum
to the core for improved locality.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>