summaryrefslogtreecommitdiffstats
path: root/qt-models
AgeCommit message (Collapse)Author
2020-12-13core: keep tank infos in a dynamic tableGravatar Berthold Stoeger
The list of known tank types were kept in a fixed size table. Instead, use a dynamic table with our horrendous table macros. This is more flexible and sensible. While doing this, clean up the TankInfoModel, which was leaking memory. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12preferences: create global settingsChanged signalGravatar Berthold Stoeger
So far, the PreferencesDialog emitted a settingsChanged signal. This meant that models that listened to that signal had to conditionally compile out the code for mobile or the connection had to be made in MainWindow. Instead, introduce a global signal that does this and move the connects to the listeners to remove inter-dependencies. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-03downloader: save downloaded divesGravatar Robert C. Helling
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-12-03downloader: wait for download threadGravatar Robert C. Helling
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-12-03build-system: add models and shared backends to the downloaderGravatar Dirk Hohndel
We'll need this in order to be able to actually open dive files and download things from a dive computer. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-24cylindermodel: remove in_planner() useGravatar Berthold Stoeger
in_planner() is problematic, since it is uses desktop-only application state. Since the cylinder-model already has an appropriate inPlanner flag, use this instead. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-24diveplannermodel: replace in_planner() by isPlanner()Gravatar Berthold Stoeger
The in_planner() function is problematic, because it depends on the application state that is only available on desktop. If we ever want to port the planner to mobile, we have to get rid of it. Luckily, the DivePlannerModel already has an appropriate flag that can be used instead. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-14desktop: automatically reload completion-modelsGravatar Berthold Stoeger
Instead of programatically reload the completion models, listen to the relevant signals in the models. To that goal, derive all the models from a base class. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-14cleanup: remove macros from qt-models/completionmodels.cppGravatar Berthold Stoeger
There were macros to auto-generate functions to reload the models. One was only used once and therefore is pointless. The other can be replaced by a function with a pointer-to-member-variable argument. While doing this, adapt the coding style. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-07desktop: fix saving of column-widths of device and site tablesGravatar Berthold Stoeger
Qt's memory management scheme is completely broken and messes with common expectations. QObjects are organized as a tree. The children are destroyed in the destructor of QObject. This means that they are destructed after the destructor of the parent object has run and its sub-object were destructed. Obviously, this makes no sense as the child objects should be able to access their parent at any time. To restore the commonly expected deterministic order of construction and destruction, one might simply do away with Qt's silly object tree and organise things using classical subobjects. However, that breaks with the Qt-generated UI classes: The objects generated by these classes are *not* destructed with the UI class. Instead, they are attached to the widget's QObject tree. Thus these are again destructed *after* the widget! Who comes up with such a scheme? In our case this means that we cannot have models used for TableViews as subobjects, because the TableView needs the model to save the column widths in the destructor. Which, as detailed above is called *after* the desctructor of the widget! Thus, turn these models into heap-allocated objects and add them to the QObject tree. Funilly, this exposes another insanity of Qt's QObject tree: Children are destructed in order of construction! One would expect that if objects are constructed in the sequence A, B, C one can expect that C can, at any time, access B and A. Not so in Qt: The destruction order is likewise A, B, C! Thus, take care to init the widgets before the model. Jeez. Finally, print a warning in the column-saving code of TableWidget, so that these kind of subtleties are caught in the future. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-26cleanup: SkipEmptyParts syntax has changedGravatar Dirk Hohndel
Sadly, the new enum has only been available since Qt 5.14, so this is a rather ugly replacement. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-25cleanup: split out divecomputer functions from dive.cGravatar Berthold Stoeger
Since dive.c is so huge, split out divecomputer-related functions into divecomputer.[c|h], sample.[c|h] and extradata.[c|h]. This does not give huge compile time improvements, since struct dive contains a struct divecomputer and therefore dive.h has to include divecomputer.h. However, it make things distinctly more clear. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25cleanup: remove DiveComputerModel::removeGravatar Berthold Stoeger
This was used by the DiveComputerDialog, which does not exist anymore. The new tab uses the function in the corresponding sorted model. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25devices: connect DiveComputerModel to undo-commandGravatar Berthold Stoeger
Instead of modifying the device table directly, call the undo commands. Moreover, don't keep our own copy in the mode - show the original version. Connect to the appropriate signals. This means that the calls from the DiveComputerManagement dialog have to be removed, since this mode of editing is not supported. The whole dialog will be removed in a future commit. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25models: update DiveComputerModel when core data is resetGravatar Berthold Stoeger
To implement undo-semantics, we want a longer-lived dive-computer-model (currently, it is regenerated when the dialog is opened). Therefore, it must be reloaded when the core data is reset. Do this like for other models: listen to the dataReset() signal of DiveListNotifier. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25desktop: add tab-widget for dive computer namesGravatar Berthold Stoeger
If we want to include dive computer names in the undo system, there should be visual feedback on undo/redo. This would mean opening the divecomputer dialog, which would appear quite strange. Therefore, add a tab. This is not ideal, but consistent with the dive site tab, which probably shouldn't be there either. In the future, the UI needs some rethinking. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25cleanup: fix over-eager Coverity warningsGravatar Dirk Hohndel
Technically get_dive(i) could return a nullptr. But given the range for i that can never happen. Still, the test is extremely cheap and doesn't hurt. Fixes CID 354768 Fixes CID 354766 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-24divecomputer: add device_table pointer to device_data_tGravatar Berthold Stoeger
In one weird case (suunto), the code in libdivecomputer.c generates a device node directly instead of going the usual way (setting the data in the dc-structure of the imported dive). It is unclear to me whether that has to be that way, as it depends on the chronological order of callbacks to event_cb() and dive_cb(). Therefore add a device_table pointer to device_data_t so that the downloader can add the device to this table. This only adds the pointer, but does not yet use it in the downloading code. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24devices: add devices in Command::importTable()Gravatar Berthold Stoeger
Add a device_table parameters to Command::importTable() and add_imported_dives(). The content of this table will be added to the global device list (respectively removed on undo). This is currently a no-op, as the parser doesn't yet fill out the device table, but adds devices directly to the global device table. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16cleanup: use std::vector in struct device_tableGravatar Berthold Stoeger
Since we converted from QString to std::string, let's also use std::vector instead of QVector. We don't need COW semantics and all the rigmarole. Let's try to keep Qt data structures out of the core. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16cleanup: use std::string in struct deviceGravatar Berthold Stoeger
struct device is a core data structure and therefore shouldn't use QString. QString stores as UTF-16 (which is a very questionable choice in itself). However, the real problem is that this puts us in lifetime-management hell when interfacing with C code: The UTF-16 has to be converted to UTF-8, but when returning such a string, this puts burden on the caller who has to free it. In fact, instead of looping over devices from C-code we had a callback that sent down temporary C-strings with qPrintable. In contrast, std::string is guaranteed to store its data as contiguous null-terminated and C-compatible strings. Therefore, replace the QString by std::string. Keep the QString just in one place that formats a hexadecimal number to avoid any potential change. The disadvantage of using std::string is that it will crash when constructed with a NULL argument, consistent with C-style functions such as strcmp, etc. Arguably, NULL is different from the empty string even though we treat both as the same. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-11desktop: make divecomputer table sortableGravatar Berthold Stoeger
Add a small proxy-model on top of DiveComputerModel so that clicking on table headers makes the table sortable. The UI feature here is not as important as the fact that the UI does its own sorting and we can keep the device-table in the core sorted differently. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03cleanup: make device code more consistent with coreGravatar Berthold Stoeger
We keep track of device, i.e. distinct dive computers with id in the core. The corresponding code stuck out like a sore thumb. Firstly, because it is C++. But more importantly, because it used inconsistent nameing conventions. Notably it defined a "DiveComputerNode" when this is something very different from "struct dive_computer", the latter being the dive-computer related data of a single dive. Since the whole thing is defined in "device.h" and the function to create such an entry is called "create_device_node", call the structure "device". Use snake_case for consistency with the other core structures. Moreover, call the collection of devices "device_table" in analogy with "dive_table", etc. Overall, this should make the core code more consistent style-wise. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03dive list: when moving dives, delete first and add laterGravatar Berthold Stoeger
When moving dives between trips, the core moves the dives internally and sends a signal to the model. The model adds and removes the dives accordingly. However, when adding the new dive, the old trip hasn't changed its position, so the ordering is wrong leading to an inconsistent state. Therefore, remove the dives first and then readd them. There could still be pathological cases where this fails. However, in the short term this is an improvement. Note that in similar cases, the dives were indeed removed then added, so this case here seems to be an oversight. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03cleanup: use getDiveSelection() to loop over selected divesGravatar Berthold Stoeger
getDiveSelection() returns a vector of the selected dives. Use that instead of looping over the dive table and checking manually. This removes a few lines of code. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03cleanup: replace get_trip_date_string() by get_trip_string()Gravatar Berthold Stoeger
The get_trip_date_string() formatted, as the name implies, the date of a trip. It was passed a number of parameters and had only one caller, which would also add the location if it existed. Therefore, move all that logic into the helper function and name it get_trip_string(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29filter: implement importing of filter presetsGravatar Berthold Stoeger
When importing a divelog, import filter presets. If there are equal names, import only if the presets differ. In that case, disambiguate the name. This made things a bit more complicated, as comparison of filter presets had to be implemented. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29filter: connect DiveListNotifier signals to filter preset modelGravatar Berthold Stoeger
Thus, the model is kept up to date if filter presets are changed by undo commands. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29filter: add (very primitive) filterpresetmodelGravatar Berthold Stoeger
Implement a trivial model to provide the filter preset names to the UI. Sadly, for now this features the QWidget/QML column / name dichotomy. However, in this simple case that shouldn't be too much of an issue. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29filter: add filter constraint modelGravatar Berthold Stoeger
Add a model that keeps track of a list of filter constraint and makes them accessible from Qt. Sadly, this is mostly repetitive boiler-plate code, but this is due to Qt's model/view-API, which is a perfect example of how *not* to design a reasonable modern API. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29Use correct pO2 when computing MOD in equipment tabGravatar Robert C. Helling
The cylinder model is used both in the planner and the equipment tab. We have three preferences for the pO2 that is used to compute MOD: In the planner, there is one for the bottom part of the dive and another one for deco. Those are set in the planenr UI. There is another value, controlled in the Tec Prefernces. That one should be used in the equipment tab rather than the one from the planner. Fixes #2984 Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-09-27mobile/dive-list: correctly update view when changing dive dateGravatar Dirk Hohndel
If the dive timestamp changes, the dive could move in the dive list. But the current dive actually doesn't change (it's still the same dive, right?). Yet we need to update the dive list as well as the shown dive (especially if this is after adding a dive, which is first inserted with the current time and then updated with whatever the user enters). Fixes: #2971 Suggested-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-09-20dive list: on reload update filter statusGravatar Berthold Stoeger
At some time, when introducing the global reset signal the filter stopped being reloaded when loading a new log. This leads to very strange UI behavior: dives disappear when editing fields unrelated to the filter. Therefore, when reloading the model, reset the filter. One might argue whether this is the correct place. On the other hand, we might even make the filter a sub-object of the dive-list model. Let's think about this. Partially solves #2961 Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-13cleanup: fold core/divecomputer.cpp into core/device.cGravatar Berthold Stoeger
core/device.h was declaring a number of functions that were related to divecomputers (dcs): creating a fake dc for manually entered dives and registering / accessing dc nicknames. On could argue whether these should be lumped together, but it is what it is. However, part of that was implemented in C++/Qt code in a separate core/divecomputer.cpp file. Some function therein where only accessible to C++ and declared in core/divecomputer.h. All in all, a big mess. Let's simply combine the files and conditionally compile the C++-only functions depending on the __cplusplus define. Yes, that means turning device.c into device.cpp. A brave soul might turn the C++/Qt code into C code if they whish later on. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-13cleanup: remove DiveComputerModel::numRowsGravatar Berthold Stoeger
This member variable was unused. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-12desktop: refine auto-fill of weightsGravatar Berthold Stoeger
In a previous commit, auto-filling of weight based on type was changed to be only performed if the user hadn't already set a weight, by testing for weight=0. However, when the user edited the type and tabbed back and forth, that counted as an edit and therefore the weight would not change anymore. To refine this, introduce an "auto_filled" flag to the weightsystem, which is set if the weight is automatically filled and cleared if the weight is edited. Update the weight if it was zero *or* auto-filled. The flag is not saved to disk, but that should be acceptable. If the user saves and reloads, we can assume that they meant the weight to be set to the default value. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-12desktop: on weight type change, don't overwrite weight if already setGravatar Berthold Stoeger
When importing from other software, it happens that weights are imported without their type. When the user changes the type, the imported weight is overwritten, which is not exactly a friendly behavior. On the other hand, when changing the type after creation of a weight entry, it is preferrable to set a default weight. This is convenient for people who commonly use the same weight. As a compromise, set the default weight only if it was unset. We recognize this by a weight value of 0 g. Fixes #2938 Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-08-24Planner: enforce minimal segement durationGravatar Robert C. Helling
You cannot be at two depths at the same time (and it confuses the planner). So give yourself at least 10 seconds. Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-08-24Planner: handle zero length segments when replanningGravatar Robert C. Helling
When setting up a dive for replanning, we ignored zero length segments as those tend to be generated by gas changes. But it is possible to enter those in the planner and the replanning should not ignore those. So be more clever about gas changes. Let's add 10 seconds so we are not at two depths at the same time and help since add_stop also does not like zero length segments (it thinks we are trying to replace a waypoint). Fixes #2901 Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-08-21cleanup: consistently use get_cylinder() accessorGravatar Berthold Stoeger
get_cylinder(d, i) is more readable than d->cylinders.cylinders[i]. Moreover, it does bound checking and is more flexible with respect to changing the core data structures. Most places already used this accessor, but some still accessed the cylinders directly. This patch unifies the accesses by consistently switching to get_cylinder(). The affected code is in C++ and accesses the cylinder as reference or object, whereas the get_cylinder() function is C and returns a pointer. This results in funky looking "*get_cylinder(d, i)" expressions. Arguably still better than the original. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-07-11Make MND display depend on O2 narcotic preferenceGravatar Robert C. Helling
A while ago, we introduced a preference whether O2 should be considered narcotic. We used this when computing best mix or when entering the He content via MND. But we forgot to make the displayed MND depend on this preference. This patch add this. Fixes #2895 Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-05-22cleanup: create common QDateTime -> timestamp conversion functionGravatar Berthold Stoeger
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>
2020-05-22cleanup: move timestampToDateTime() to qthelper.cppGravatar Berthold Stoeger
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>
2020-05-15cleanup: remove redundant model source files in CMakeLists.txtGravatar Berthold Stoeger
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>
2020-05-15cleanup: replace to "dive.h" includes by more specific includesGravatar Berthold Stoeger
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>
2020-05-14mobile/models: add access to tags stringGravatar Dirk Hohndel
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>
2020-05-07cleanup: generalize ExtraDataModel to display data of any dcGravatar Berthold Stoeger
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>
2020-05-07cleanup: return directly in ExtraDataModel::data()Gravatar Berthold Stoeger
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>
2020-05-07cleanup: use begin/endResetModel in ExtraDataModelGravatar Berthold Stoeger
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>
2020-05-07cleanup: invert control-flow when resetting the core structuresGravatar Berthold Stoeger
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>