When the dive mode is changed, the profile has to be replot. This
is by a function of the TabDiveInformation. However, that function
was also executed when populating the tab. Thus, when changing dive,
the profile was plot twice.
Move the profile plotting out of the function. Ultimately, the profile
should listen to the appropriate signals itself.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To check wether the tab widgets should show the trip view, they called
the selectedTrips() function. The trip view was shown if that contained
only one trip. However, the selectedTrips() function was very slow,
because it has to query to core models.
Change the function to singleSelectedTrip(), which returns a trip
if there is exactly one trip selected. The function returns early
if there is more than one trip selected. This makes the select-all
case much faster.
There are two cases which are still very slow:
- List mode, because here all top-level items are queried.
- Dive log with many only top-level items.
Ultimately, we will have to cache the trip selection because
querying the model is too slow.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code would call QItemSelectionModel::select() once for every dive.
Instead collect the selection in a QItemSelection and only call
QItemSelectionModel::select() once. This makes selecting multiple dives
significantly faster.
The loop also expanded the trips with selections. This has now to be
done in an extra loop.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When determining the selected dive sites to highlight them on the
map, the DiveListView code used the local indices of the selected
dives. However, that was unreasonably slow. Even though a layering
violation, let's access the core data structures directly. In my
tests this improved from 700 ms to 0 ms!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It makes reasoning about code so much easier when one knows that
functions cannot be accessed from the outside. Therefore, make
a number of DiveListView slots private. Moreover, unslotize
functions that never were used in connect calls.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveListView widget has to differentiate between programmatical
und user-initiated selection changes. It did so by using the
DiveListNotifier::inCommand() flag.
However,
1) There is only one point of entry for such selection changes,
viz. the MultiFilterSortModel::selectionChanged() signal
2) This signal is not only emitted in command-context.
Another source is for example dive-map selection changes.
Therefore, move the programmatical-selection-change status down
to the widget and set/reset it in the diveSelectionChanged() slot.
This makes "select all visible dive sites" somewhat faster. Sadly,
not as much as expected.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Outside callers had no business calling these functions.
Especially some functions that were simply there to override
default DiveListView behavior. Mark these as overridden.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was used by the map to select dives. However, the map now calls
the core function directly, so this can be removed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The map widget called the dive list to select dives. This is
inconsistent and complex. The dive list has to call down to
the core anyway. Therefore, change the code to call the common
core function.
This means that we have to transform integer ids into dive-pointers.
That is a bit sad, because the dives were just transformed into
indices. Let's address that in a future commit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was erroneous, as it should only be called at the end of
a selection change, not after every single dive. It made selection
of multiple dives extremely slow.
Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Debugged-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
DiveListView::selectDive() is an overloaded function. The second
version was only called by the first version, so we can fold one
into the other.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The undo-machinery makes sure that a current_dive always exists
after an undo command. This part of the code should never be
called.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This appears to be an artifact. Collapsing does not unselect
the current dive, so reselecting it appears pointless.
Also it is unclear why the selection should be restricted to
a single dive after collapsing.
Probably that was originally meant to expand only the trip
with the current dive in it?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Thus, it is made clear that these member functions can only be
accessed from DiveListView itself. This should make debugging
easier.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Move this to the core so that desktop and mobile don't have
to call this explicitly. Matter of fact, mobile didn't call
this. It is unclear, whether that was even used on mobile,
though.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It makes no sense to keep the device nodes if all the other data
is cleared. Let's do this automatically and not explicitly.
This ensures that the function is also called on mobile.
Currently it was only called on desktop.
Weirdly, the parser-tests were expecting that the device nodes
were not reset by clear_dive_file_data() and therefore divecomputers
were accumulating in the test results. Thus, the additional
computers had to be removed from the expected test results.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This only checks the first divecomputer as the semantics for
multiple dive computers with different dive modes are not
clear. Should we check them all?
The implementation is a bit hackish: the indexes [0...n] of the
combobox are mapped onto [-1...n-1], where -1 means don't filter
and n-1 is the last valid dive mode.
Implements #2329
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>
TabDiveInformation::updateProfile() does some statistics via the
per_cylinder_mean_depth function. It passes down arrays with one
entry per cylinder, which are allocated by means std::vector.
To pass the array, the expression "&vector[0]" is used. It seems
like some compilers through an assertion violation if vector
has no elements. They are technically correct in that this is
undefined, but still this appears like very unfriendly behavior.
After all, std::vector should behave just like a dynamic C-array
that is automatically freed, when going out of scope.
Replace the "&vector[0]" by "vector.data()" and don't do the
call if there aren't any cylinders for good measure.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Move the more commonly used filter to the left and the less
commonly used "purge unused sites" button to the right. Add
a spacer so that the filter-textbox doesn't extend over the
whole free space.
With apologies to sinistroverse users (is there an option to
make the layout direction depend on the locale?).
Suggested-by: Hartley Horwitz <hhrwtz@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Perform slight reorganisation and rewording of the divelog export
panel. Specifically the wording is changed and expanded to make clear
the 2 types of export of profile data. All the CSV export options are
grouped together. With respect to profile export to CSV format, it is
made clear that one option concerns export of dive computer-related
profile data, whereas the other option involves export of computed
dive profile data from the Dive Profile panel.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
When creating a TankInfoDelegate editor, reploting of the profile
was disabled to avoid replotting when the user scrolls through
the tank-info list. Since the code was changed to only set the
tank-info when the editor is closed, this became unnecessary
(hopefully). Indeed the clearing of the flag was removed in a
previous commit. This means that we also have to remove the setting
of the flag. Since this is all the TankInfoDelegate::createEditor()
function was doing, we can remove the whole function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
MainWindow::on_actionAddDive_triggered() updated the profile after
calling Command::addDive(). However, that is redundant because the
undo-machinery does the profile reload. Remove the call.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The comment states that Qt treats TAB as cancel when in the combobox.
However, testing shows that this use-case works without this hack.
Since it caused weird behavior (the data was set *after* the editor
was closed, leading to inconsistent state), remove it.
Note: this overrides the previous commit, which is therefore redundant
from a history point of view. However, I'll leave the previous commit
in so that if something turns out to break, we can figure out which
of the two changes it was.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
fixTabBehavior() set the editor text *after* closing the editor.
This left us in an inconsistent state where we thought that the
editor is active. By reversing two connects, this problem is resolved.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
All combobox-delegates shared a number of static status fields.
In a quest to make the code more reentrant, move that to the
actual object. The fields have to be defined as mutable, since
they are set in const member functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Update of the profile is now done by the undo-commands. If the
planner needs this, it is probably better to connect directly
to the model, not the delegate.
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>
There was only one editMode left (MANUALLY_ADDED_DIVE).
Therefore replace by a flag. This makes the code more consistent,
because the conditions "editMode != NONE" and "editMode ==
MANUALLY_ADDED_DIVE) actually meant the same thing.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The editMode was set to IGNORE_MODE when programatically setting
fields so that we can ignore changed-signals.
That seems to be orthogonal to whether we are in edit mode
and indeed when setting IGNORE_MODE the edit mode was
saved and restored.
Therefore, replace the IGNORE_MODE by an independent ignoreInput
flag.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For reasons that I don't understand, we keep track of the
current combo-box text for our model-delegates. However,
that text was not initialized when the editor was generated,
leading to a UI bug in the cylinder and weight widgets:
Activate a field, click somewhere else -> either the empty
string or the previous string was set.
Reported-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a simple copy of the other add-event commands. It could
be made more friendly by stating the pO2 value in the text.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since pointers to divecomputers may not be stable, the undo
commands take a dive + a divecomputer number. Update the
SetpointDialog accordingly.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
While touching this dialog, might as well change away from the MOC
version of the connect() statements.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We have too many global objects. There is no reason why this dialog
should be a persistent global object.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
That mode is not used anymore, since only the editing of
profiles of manually added dives enters editing mode. For
that case we have the MANUALLY_ADDED_DIVE edit mode.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
All remaining callers were passing MANUALLY_ADDED_DIVE as a new
mode, so we may just as well remove the parameter and thus
simplify the logic.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The only way to enter edit mode is to edit the profile. However,
that means that the profile is already visible, so there is no
need to change the mode. Simply remove the EDIT mode.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When entering the edit state, we don't want the user to be able
to undo/redo lest things become inconsistent. Since the only way
to enter edit state is to edit the profile, we can simply use
the disableShortcuts() function that is used by the profile
when it goes into edit state.
This has one desirable side-effect: Undo is now also disabled in
the planner. Undo during planning likewise can lead to inconsistent
state.
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>
The profile can only be edited for manually added or planned
dives. No point in keeping code for other kinds of dives.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The edit state is now only used to edit the profile. There is no
reason to disable random tabs.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The editing of the dive site is controlled via an undo command.
No point in centering the map when cancelling a profile-edit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This stored the old editMode. However, it was not read after
editMode was changed, so there is no point to it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>