Commit graph

17 commits

Author SHA1 Message Date
Berthold Stoeger
e1abf9485c Undo: unify selection behavior in dive-list commands
Some commands tried to retain the current selection on undo/redo,
others set the selection to the modified dives.

The latter was introduced because it was easier in some cases, but
it is probably more user-friendly because the user gets feedback
on the change.

Therefore, unify to always select the affected dives on undo()/redo().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-06-23 20:08:46 +02:00
Berthold Stoeger
27944a52b1 Undo: don't send signals batched by trip
Since the default view is batched by trips, signals were sent trip-wise.
This seemed like a good idea at first, but when more and more parts used
these signals, it became a burden. Therefore push the batching to the
part of the code where it is needed: the trip view.

The divesAdded and divesDeleted are not yet converted, because these
are combined with trip addition/deletion. This should also be detangled,
but not now.

Since the dive-lists were sorted in the processByTrip function, the
dive-list model now does its own sorting. This will have to be
audited.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-06-23 20:08:46 +02:00
Berthold Stoeger
12a13d722a Undo: sort dives by dive_less_than() in signals
In signals dives were sorted by date. This criterion is not be unique.
Therefore sort by the dive_less_than() function of the core to avoid
any inconsistencies between the Qt-models and the core data.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-06-19 13:11:10 -07:00
Berthold Stoeger
a20c22d907 Undo: hide multi-dive-edit warning message on subsequent edit
When a different field is edited, hide any old multi-dive-edit
warning message. The reason is that we might want to add an "undo"
button to the message. But this will undo the wrong command if
we don't hide the message.

Sadly, this means that we can't use animated show / hide, because
an animatedHide() followed immediately by an animatedShow() does
not necessarily show the message. In other words, and animatedShow()
does not interupt a started animatedHide()!?

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-06-15 11:20:49 -07:00
willemferguson
1bdf00b2b4 Convert the atmospheric pressure in the Information Tab to an editable field
The Information tab shows the atmospheric pressure. Make this value editable
and also ensure that changes to it are undo-able.

Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
2019-05-15 07:37:14 -07:00
Berthold Stoeger
d7d408a99e Undo: implement undo of dive trip editing
This is copying the dive editing code. It uses an OO design with
virtual functions for getting and setting the values. It doesn't
use templates though, as both fields of strig type. This feels
a bit over-engineered, but it is 1) consistent with the dive edit
code and 2) the number / types of dive trip fields might increase.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
9fd87fa080 Undo: update cylinder and weight models on paste
When pasting (or undoing paste) the cylinders or weights may change.
Send the appropriate signals and update the models accordingly.
Currently, this means copying from current dive to displayed dive,
but hopefully we can get rid of "displayed_dive" in the not so
distant future.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
cddd5942f8 Undo: update dive list after edit command
The dive list was not updated automatically when an edit command was
executed. There was already a signal to do that, viz. divesChanged().
But that signal worked by-trip and didn't have a dive-field specifier.

The edit-commands used the divesEdited() signal that isn't by-trip
but has a dive-field specifier.

Unify these two signals to be by-trip and with dive-field specifier.
This needs common code to generate the by-trip list that is moved to
a command_private.h header.

Since there might now be multiple signals (one per trip) actually
check in the main-tab whether the current trip is affected to
avoid multiple update of fields. This has the positive(?) effect
of not doing any update if the current dive isn't changed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
c82f4487f9 Undo: implement undo of depth and duration editing
This was a bit different from the other editing commands:
1) Only the current dive is edited not all selected dives.
   Therefore, create a function that turns the current dive
   into a one-element list.
2) The profile has to be replot. Here, likewise, create a
   function to do that.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
6f574c53a3 Undo: implement undo of dive site editing
This one is a bit more tricky. There are two modes: set dive site
and set newly created dive site. This is realized using an OO model
with derived classed. Quite convoluted - but it seems to work.

Moreover, editing a dive site is not simply setting a value,
but the list of dives in a dive site has to be kept up to date.

Finally, we have to inform the dive site list of the changed
number of dives. Therefore add a new signal diveSiteDivesChanged.
To send only one signal per dive site, hook into the undo() and
redo() functions and call the functions of the base class there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
45ef879546 Undo: update notes field if changed by undo commands
To keep the UI in a consistent state, update the notes field if
it is changed by an undo command. To that purpose, add a new
signal to diveListNotifier with a list of dives and a field-id
as payload.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
0e1b0cf1da Undo: Implement undo of dive site name editing
Implement an undo command that edits the name of a dive site.
Connect it to the dive site table, so that names can be edited
directly in the table.

Send signals on undo / redo so that the dive site table and
the dive site edit widget can be updated.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
59e602447b Dive site: inform model of dive site addition / deletion
Introduce two DiveListNotifier signals which are sent by
the undo commands if dives are added to / removed from the
core.

The signal has the dive site and the index in the global
dive site table as payload. Thus, the model has only to
remove the appropriate rows.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
8dcc33d8ab Undo: keep frontend informed of changes to dive site count
Add a new signal to DiveListNotifier. Send signal if dives are
added or removed and therefore the dive count of a dive site
changes. The dive sites are collected and the signal is sent
at the end of the command.

Add code to update the table view.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
7067e33596 Undo: select dives after add, remove, merge, split dive commands
Select the proper dives after the add, remove, split and merge
dives commands on undo *and* redo. Generally, select the added
dives. For undo of add, remember the pre-addition selection.
For redo of remove, select the closest dive to the first removed
dive.

The biggest part of the commit is the signal-interface between
the dive commands and the dive-list model and dive-list view.
This is done in two steps:
1) To the DiveTripModel in batches of trips. The dive trip model
   transforms the dives into indices.
2) To the DiveListView. The DiveListView has to translate the
   DiveTripModel indexes to actual indexes via its QSortFilterProxy-
   model.

For code-reuse, derive all divelist-changing commands from a new base-class,
which has a flag that describes whether the divelist changed. The helper
functions which add and remove dives are made members of the base class and
set the flag is a selected dive is added or removed.

To properly detect when the current dive was deleted it
became necessary to turn the current dive from an index
to a pointer, because indices are not stable.

Unfortunately, in some cases an index was expected and these
places now have to transform the dive into an index. These
should be converted in due course.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
23db0ba68d Dive list view: replace signal-magic by flag
In DiveListView, we have a very fundamental problem: When
On the one hand, we get informed of user-selection in the
DiveListView::selectionChanged() slot. This has to set the
correct flags in the C-backend.

On the other hand, sometimes we have to set the selection
programatically, e.g. when selecting a trip. This is done
by calling QItemSelectionModel::select().

But: this will *also* call into the above slot, in which
we can't tell whether it was a user interaction or an
internal call. This can lead to either infinite loops or
very inefficient behavior, because the current dive
is set numerous times.

The current code is aware of that and disconnects the
corresponding signal. This is scary, as these signals are
set internally by the model and view. Replace this
by a global "command executing" flag in DiveListNotifier.
The flag is set using a "marker" class, which resets the flag
once it goes out of scope (cf. RAII pattern).

In DiveListView, only process a selection if the flag is not
set. Otherwise simply call the QTreeView base class, to reflect
the new selection in the UI.

To have a common point for notifications of selection changes,
add such a signal to DiveListNotifier. This signal will be
used by the DiveListView as well as the Command-objects.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
ec7d85835f Dive list: implement proper Qt-model semantics for DiveTripModel
Previously, each dive-list modifying function would lead to a
full model reset. Instead, implement proper Qt-model semantics
using beginInsertRows()/endInsertRows(), beginRemoveRows()/
endRemoveRows(), dataChange().

To do so, a DiveListNotifer singleton is generatated, which
broadcasts all changes to the dive-list. Signals are sent by
the commands and received by the DiveTripModel. Signals are
batched by dive-trip. This seems to be an adequate compromise
for the two kinds of list-views (tree and list). In the common
usecase mostly dives of a single trip are affected.

Thus, batching of dives is performed in two positions:
- At command-level to batch by trip
- In DiveTripModel to feed batches of contiguous elements
  to Qt's begin*/end*-functions.

This is conceptually simple, but rather complex code. To avoid
repetition of complex loops, the batching is implemented in
templated-functions, which are passed lambda-functions, which
are called for each batch.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00