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>
The code follows the other edit-commands, but uses its own base
class, because it is distinctly different. Editing the tag field
does not simply mean setting the tag for all dives, but rather
adding and removing individual tags.
This class will be reused for editing of dive buddies and masters.
Modify the tag widget thus that it sends an editingFinished()
signal when it goes out of focus. The editingFinished() signal
was prevented by hooking into the return, enter and tab key-events.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
This is different from the other editing commands, because
date and time editing may change the order of the dive list.
Therefore, this uses an already implemented dive list command.
The command is extended to send a divesEdited() signal.
This signal and the divesChanged() signal, which is used by
the dive list, will be unified in a later commit.
Update of the graphics is now not done via signals, a direct
call is performed in MainTab::divesEdited(). This simplifies
things.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Mostly trivial. Since now on editing the field is re-set, the
validation function becomes unnecessary.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was rather trivial and modeled after the previous edit
UndoCommands. Since this is the first time we're editing
integers a new constructor instantiation had to be added.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This one was trivially modelled after notes editing. Only difference:
the textChanged() signal was replaced by the editingFinished()
signal so that we're not generating undo-commands on every key-press.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Add a new UndoCommand for dive mode editing. This one is a bit
special, as the mode is associated with a dive computer (DC),
not a dive. Thus the edit command has an additional parameter,
viz. the index of the DC.
This does not fit properly to the EditBase class, as this class
isn't aware of additional parameters and therefore this parameter
is not sent via signals. At the moment this doesn't matter. In
any case, the semantics of editing are weird and therefore let's
do the simple thing (derive from EditBase) and let's see what
the future brings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Implement a first rudimentary dive-editing command. The main code
resides in a base class Command::Edit, which calls virtual functions
to read / set the fields and extract the field name.
Implement an example: editing of dive notes.
This dose not yet update the UI on undo / redo.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The edit dive site button was connected to a *signal* of MainWindow,
which was connected to a slot of MainWindow. Remove the unnecessary
intermediate signal.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This feature will be replaced by.
1) An explicit purge empty dive sites feature.
2) Not allocating dummy dive sites for GPS coordinates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Add a very simple tab-widget presenting the list of known dive sites.
The table is rendered using our custom "TableView".
The (mis)uses the "LocationInformationModel". It moves the items
to be displayed (delete, name, description, number of dives) to the
front and makes the others hidden.
Moreover, it was necessary to limit the geo-tag decoration role to
the name to avoid having the icon next to each column.
Make the trash-can icon active and the name and description editable.
This is modelled after the cylinders-table code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of setting dive->dive_site directly, call the
add_dive_to_dive_site() and unregister_dive_from_dive_site()
functions. In the parser this turned out to be a bit tricky.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since the UUID will be overwritten on save and is only used on save
and load, set it only on save or load. For other created dive sites,
leave the UUID field uninitialized.
This means that the UUID will change between saves. Let's see how
the git saver handles that.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When a new dive site is created in MainTab::updateDiveSite()
and there is no text, it gets a generic name. But: the function
exits early if there is no text, so this is dead code. Remove.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To enable undo of dive site functions, it is crucial to work
with different dive site tables. Therefore add a dive site table
parameter to dive site functions. For now, always pass the global
dive site table. Thus, this commit shouldn't alter any functionality.
After this change, a simple search for dive_site_table reveals all
places where the global dive site table is accessed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-return the result instead of storing in a parameter, we now know that the list
contains only those results that are generated in the function
-allocate the result with the correct length right from the start
-do not iterate over keys of a map and then do a map lookup to get the value but
use an iterator that gives us both right from the start
-remove one call alltogether as the results were not used there
Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
See https://www.kdab.com/goodbye-q_foreach/
This is reduced to the places where the container is const or can be made const
without the need to always introduce an extra variable. Sadly qAsConst (Qt 5.7)
and std::as_const (C++17) are not available in all supported setups.
Also do some minor cleanups along the way.
Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
printGPSCoords() returned a newly allocated C-style string. Most
callers simply made a QString out of it and freed the C-style string.
This is paradoxical, as printGPSCoords internally works with QStrings
and converts them to C-style on return.
Therefore, let printGPSCoords() return a QString and create a
printGPSCoordsC() wrapper for the two C-callers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The printGPSCoords() function returns a copied C-style string. Since
the owndership is transferred to the caller, the correct return type
is "char *" instead of "const char *".
Thus a number of casts when calling free can be removed.
Moreover a number of callers didn't free the string and thus were
leaking memory. Fix them. Ultimately we might want two versions
of the function: one for QString, one for C-style strings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The undo-work reversed the direction of the offset. This was apparently
only fixed when using the menu entry, but not when editing dives directly.
Invert the offset to get the correct time.
While doing so, remove a redundant if: First it checked whether the
dates are the same, then whether the offset is non-zero.
Fixes#1975.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In MainTab::acceptChanges there was a "editMode != ADD" condition
inside a else block to "editMode == ADD", which is therefore
redundant. Remove.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The when field gives the time of the first dive. Instead of keeping
this field in sync, replace it by a function that determines the time
of the first dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveListView code had a very fundamental problem with its
header: Each had its own idea of who is responsible for sorting.
Since we can't easily change QHeaderView, accept QHeaderView
as the authority on sort-column and order.
To make this possible, split the reload() function in two
distinct functions:
- reload() reloads the model and sorts according to the
current sort criterion.
- setSortOrder() tells the header to display a certain
sort criterion. If this is a new criterion, it will then
emit a signal. In this signal, resort according to that
criterion.
Thus, the actual sorting code has to be moved from the
headerClicked() to a new sortIndicatorChanged() slot.
Morover, the sorting of the QHeaderView has to be used.
Reported-by: Stefan Fuchs <sfuchs@gmx.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
DiveListView::reload() was called for full reset of the dive list
and for changing the view (tree vs. lis) in DiveListView::headerClicked().
Since the latter does sorting by itself, a parameter "forceSort" was
introduced, which defaulted to true, but was set to false by
DiveListView::headerClicked().
To remove complexity, simply let DiveListView::headerClicked() set
the view by itself and remove tha parameter.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Import dives from a DC, and have ssrf started in verbose mode. After
downloading dives, hit ok, to add them to the dive list. This crashes
as we cannot get the uuid from the null dive site.
Added a simple guard to fix this.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
Replace the UUID reference of struct dive by a pointer to dive_site.
This commit is rather large in lines, but nevertheless quite simple
since most of the UUID->pointer work was done in previous commits.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Replace UUIDs from LocationInformationModel and fix the fallout.
Notably, replace the UUID "column" by a DIVESITE "column".
Getting pointers through Qt's QVariant is horrible, we'll have
to think about a better solution.
RECENTLY_ADDED_DIVESITE now defines to a special pointer to
struct dive_site (defined as ~0).
This fixes an interesting logic bug:
The old code checked the uuid of the LocationInformationModel (currUuid)
for the value "1", which corresponded to RECENTLY_ADDED_DIVESITE.
If equal, currType would be set to NEW_DIVE_SITE. Later, _currType_
was compared against _RECENTLY_ADDED_DIVESITE_. This would only work
because NEW_DIVE_SITE and RECENTLY_ADDED_DIVESITE both were defined
as 1.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of passing a uuid, pass a pointer to the dive site.
This is small step in an effort to remove uuids.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of passing a uuid, pass a pointer to the dive site.
This is small step in an effort to remove uuids.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This changes more of the dive-site interface to return pointers
instead of UUIDs. Currently, most call sites directly extract
UUIDs afterwards. Ultimately, the UUIDs will be generally replaced
by pointers, which will then simplify these callers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This will display the dive site coordinates after the Location label if
there are no associated tags from reverse geolookup. Thus it'll be
clearer for users that we do have GPS location stored for the dive, and
might be able to see more easily if the recorded coordinates are
correct.
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
There was still code in MainTab::updateDiveSite() related to
dive-sites obtained from the obsolete web-service. Remove.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of having people treat latitude and longitude as separate
things, just add a 'location_t' data structure that contains both.
Almost all cases want to always act on them together.
This is really just prep-work for adding a few more locations that we
track: I want to add a entry/exit location to each dive (independent of
the dive site) because of how the Garmin Descent gives us the
information (and hopefully, some day, other dive computers too).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Instead of the weirdly named "information" and the inconsistent
"dive_list" use the logical "mainTab" and the camel-cased
"diveList", respectively.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The keeps track of different sub widgets needed by other parts
of the code, notably:
MainTab
PlannerDetails
PlannerSettingsWidget
ProfileWidget2
DivePlannerWidget
DiveListView
Access to these widgets was provided with accessor functions.
Now these functions were very weird: instead of simply returning
pointers that were stored in the class, they accessed a data
structure which describes the different application states.
But this data structure was "duck-typed", so there was an
implicit agreement at which position the pointers to the
widgets were put inside. The widgets were then down-cast by
the accessor functions. This might make sense if the individual
widgets could for some reason be replaced by other widgets
[dynamic plugins?], but even then it would be strange, as one
would expect to get a pointer to some base class.
Therefore, directly store the properly typed pointers to the
widgets and simply remove the accessor functions. Why bother?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The dive-site-edit widget uses a copy of the to-be-edited site
to compare with old values. Generally, this seems overkill
(the original dive-site can be used for such a comparison).
But one place where it can't simply be removed is the taxonomy,
because the widget needs a place to store the unsaved data.
Change the code to use an explicit taxonomy structure instead
of the one provided in the copy. This should ultimately allow
removal of the latter.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The global object "displayed_dive_site" is used to store the
old dive site data for the edit-dive-site widget. The fields
of the widget were initialized from this object in the show
event. Therefore the object was updated in numerous parts of
the code to make sure that it was up-to-date. Instead, move
the initialization of the object to the function that also
initiatlizes the fields. Call this function explicitly before
showing the widget.
This makes the data-fow distinctly easier to understand.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Remove a comment which is outdated in two ways:
1) The global variable "displayed_dive_site" was not used at all.
2) The location box cannot be used to rename dive sites.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
MainTab::refreshDisplayedDiveSite() was used after dive-site edit
to update the information of the location entry box. This should
always display the dive-site of the currently shown/edited dive,
therefore it makes no sense to use the displayed_dive_site here.
Simply use the dive site of displayed_dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code had a special case for dive-editing mode:
The dive site uuid of displayed_dive_site instead of displayed_dive
was used.
This makes no sense, because displayed_dive_site is only used by
the dive-site-edit widget, which firstly cannot be activated
during dive-edit and secondly doesn't change the dive site id
anyway.
Thus, use the dive site of the currently edited/displayed dive
in all cases.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>