aboutsummaryrefslogtreecommitdiffstats
path: root/qt-models
AgeCommit message (Collapse)Author
2019-11-09Cleanup: free plot data on exitGravatar Berthold Stoeger
Some widgets copy the full plot info. Free these data on exit to prevent monstrous valgrind reports. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09Profile: dynamically allocate plot pressure dataGravatar Berthold Stoeger
All accesses to the pressure data were converted to use functions. Therefore it is now rather trivial to dynamically allocate the pressure array and just change the functions. The only thing to take care of is the idiosyncratic memory management. Make sure to free and copy the buffer in the appropriate places. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09Profile: use pressure data functions in DivePlotDataModelGravatar Berthold Stoeger
The model was accessing the pressure data directly. Instead, use the accessor functions so that the core structure can be changed more easily. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09Cleanup: implement proper Qt-model semantics in DivePlotData modelGravatar Berthold Stoeger
User beginResetModel()/endResetModel() pairs to reset the model. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09Cylinders: dynamically allocate cylinder arraysGravatar Berthold Stoeger
When keeping track of cylinder related data, the code was using static arrays of MAX_CYLINDERS length. If we want to use dynamically sized cylinder arrays, these have to be dynamically allocated. In C++ code, this is trivial: simply replace the C-style arrays by std::vector<>. Don't use QVector, as no reference counting or COW semantics are needed here. These are purely local and unshared arrays. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09Core: dynamically allocate the result of get_gas_used()Gravatar Berthold Stoeger
get_gas_used() returns the volume of used gases. Currently, an array with MAX_CYLINDERS is passed in. If we want to make the number of cylinders dynamic, the function must use an arbitrarilly sized array. Therefore, return a dynamically allocated array and free it in the caller. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-08Mobile: correctly update filter text and update all three modelsGravatar Dirk Hohndel
This is even harder because setActiveTrip is called from an action slot from QML. If the C++ code called from that slot causes the object to which this slot belongs to be destroyed, we get very strange crashes. The only workaround I could come up with was to update the filter asynchronously. This all seems very ugly and fragile. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-11-08Mobile: ensure the sort order is always setGravatar Dirk Hohndel
This shouldn't be necessary every time we replace the sort model, but it can't hurt, either (famous last words?). Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-11-08Mobile: add second filter proxy model for dive listGravatar Dirk Hohndel
This one significantly reduces the number of dives that are handed to the ListView in QML. For every trip that isn't expanded (only zero or one trips are expanded at any time, so almost all the others are collapsed), send only first dive to the View to allow creation of the section. Hide the rest so we don't have all these invisible, zero height entries for the vertical dive list. A big part of this commit is moving a few functions from the DiveListSortModel to the CollapsedDiveListSortModel. Those are the ones that are needed for the trip header. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-31Planner: Add option to treat O2 as narcoticGravatar Robert C. Helling
When computing the best mix for a target depth, for helium, one can either require that the partial pressure of N2 is the same as at the target depth or the partial pressure of N2 plus O2. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-10-27Cleanup: NULL check pointer before dereferencingGravatar Dirk Hohndel
I we have no dive, whatever this is shouldn't be shown. Found by Coverity. Fixes CID 350093 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-27Cleanup: add missing break statementsGravatar Dirk Hohndel
The current code of course works just fine. But there's a risk someone might add something to one of these cases and not realize that there is an implicit fall through going on. This is cleaner. Found by Coverity. Fixes CID 350079 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-26Cleanup: avoid resource leak in dive planner modelGravatar Dirk Hohndel
Found by Coverity. Fixes CID 350121 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-26Cleanup: avoid out of bounds accessGravatar Dirk Hohndel
This is extremely unlikely to ever happen since we reserve space for a hundred weight models, but hey, doing this right is quite easy, so let's fix it. Found by Coverity. Fixes CID #350117 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-26Desktop: use undo command when replanning diveGravatar Berthold Stoeger
Instead of copying the displayed dive, generate an undo command. This makes the replanning an undoable action and fixes a bug where the dive details have not been updated correctly. Fixes #2280 Reported-by: Stefan Fuchs <sfuchs@gmx.de> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-20Mobile: remove remaining accesses to DiveObjectHelper from QMLGravatar Dirk Hohndel
Add a couple more roles and remove the dive role that allows accesss to the DiveObjectHelper in the first place. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-20Mobile: get dive details directly from the modelGravatar Dirk Hohndel
By getting a DiveObjectHelper and then dereferencing that we ended up creating hundres and hundreds of these objects, only to immediately destroy them after using a tiny part of the data. Instead make those data available directly from the model, without having to create a DiveObjectHelper forst. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-20Planner: copy deco state before passing it to worker threadGravatar Berthold Stoeger
The planner has a computeVariations() function that can be run in a worker thread. The code was not thread safe: a deco_state object allocated on the stack of the caller was passed down to the worker thread. It's well possible that the object would go out of scope before the thread run. Therefore, when running in the background, copy the object first and free it in the worker thread. Side note: Qt makes proper memory management again as difficult as possible: You can't pass a std::unique_ptr<> to QtConcurrent::run, because move-only objects are not supported. Not very friendly! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-04Cleanup: Make constructor of singletons privateGravatar Berthold Stoeger
This guarantees that they are actually singletons: there can only be one application-wide instantiation of these objects. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-04Cleanup: Turn DiveListSortModel into classical singletonGravatar Berthold Stoeger
To make this class available from QMLManager, the run_ui() function would create the object and then set a pointer in QMLManager. It works, but is inconsistent with the rest of the code. Therefore, make it a classical singleton class, which is generated on demand. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-04Cleanup: turn GpsListModel into standard singletonGravatar Berthold Stoeger
GpsListModel was one of those "special" singletons that could be created explicitly with new. This would make sense if a parameter were passed to the constructor. We only passed null, so one might as well turn that into a classical singleton with default constructor. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-04Cleanup: turn DiveListModel into standard singletonGravatar Berthold Stoeger
DiveListModel was one of those "special" singletons that could be created explicitly with new. This would make sense if a parameter were passed to the constructor. We only passed null, so one might as well turn that into a classical singleton with default constructor. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-04Cleanup: initialize DiveListSortModel in constructorGravatar Berthold Stoeger
The model was initialized in the global run_ui() function. Move that into the constructor of the class. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: remove DiveImportedModel::lastIndexGravatar Berthold Stoeger
This is redundant, as the actual size is stored in the dive table. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Cleanup: remove DiveImportedModel::firstIndexGravatar Berthold Stoeger
This index was never set to anything else than 0. Might as well remove it. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: avoid model inconsistency in DiveImportedModel::recordDives()Gravatar Berthold Stoeger
DiveImportedModel::recordDives() called add_imported_dives(). But that actually consumes the dive and dive-site tables. Which in turn will lead to an inconsistent model. Properly reset the model by using the consumeTables() function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: keep dive and dive site tables in DiveImportedModelGravatar Berthold Stoeger
The DiveImportedModel and DownloadThread used the same table of dives and dive sites. This made it very hard to keep the model consistent: Every modification of the download thread would make the model inconsistent and could lead to memory corruption owing to dangling pointers. Therefore, keep a copy in the model. When updating the model, use move-semantics, i.e. move the data and reset the tables of the thread to zero elements. Since the DiveImportedModel and the DownloadThread are very tightly integrated, remove the accessor-functions of the dive and dive-site tables. They fulfilled no purpose whatsoever as they gave the same access-rights as a public field. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: extract number of dives from model not from threadGravatar Berthold Stoeger
The plan is to make the model the authoritative source of the imported dives. Therefore, access the number of downloaded dives from there. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: get tables from DiveImportedModel not DownloadThreadGravatar Berthold Stoeger
When importing dives, consume the tables from DiveImportedModel and not the DownloadThread. This appears more logical and avoids an inconsistent state of the DiveImportedModel: On import the tables would be reset, but the DiveImportedModel wasn't informed of that. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: keep model state consistent when deleting unselected divesGravatar Berthold Stoeger
In DiveImportedModel::deleteDeselected(), unselected dives were deleted from the dive-table. But this left the model in an inconsistent state and the frontend was not informed of the missing dives. Fix this by invoking the appropriate beginRemoveRows()/ endRemoveRows() pairs. Move the functionality into its own function so that it can be reused by the desktop version. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02Import: Make DownloadThread a subobject of DiveImportedModelGravatar Berthold Stoeger
Currently, desktop and mobile are accessing the DownloadThread and the DiveImportedModel concurrently. This makes a big data flow mess. To achieve a more hierarchical data flow, start by making the DownloadThread a subobject of DiveImportedModel. Start the download by calling a function in DiveImportedModel. Route the finished signal through DiveImportedModel. Thus, the model can reload itself with the new data. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-27Mobile: replace model-reset by row-addition in DiveListModel::reload()Gravatar Berthold Stoeger
Owing to apparent QML breakage, a model-reset leads to the DiveDetail page being reloaded for every dive in the list(!). Therefore, add rows instead. This leads to extremely subtle code, as it is now imperative that the model has been properly cleared beforehand. Nevertheless, for now we have to do this to fix a severe performance regression. Fixes #2295 Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-27Mobile: clear dive data via modelGravatar Berthold Stoeger
Clearing the dive data directly in the core leaves us with an inconsistent model. Therefore, clear via the model. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-27Revert the singleton PRGravatar Dirk Hohndel
It turns out that this isn't working the way it was intended to. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-09-25Cleanup: Pass gpsTrackers directly to GpsListModel::update()Gravatar Berthold Stoeger
Instead of using the GpsLocation singleton in GpsListModel::update() to extract the gpsTrackers, pass the gpsTrackers as function argument. The caller has direct access to the GpsLocation object anyway and this make things less entangled. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-25Cleanup: unify idiosyncratic singletonsGravatar Berthold Stoeger
The way we handle singletons in QML, QML insists on allocating the objects. This leads to a very idiosyncratic way of handling singletons: The global instance pointer is set in the constructor. Unify all these by implementing a "SillySingleton" template. All of the weird singleton-classes can derive from this template and don't have to bother with reimplementing the instance() function with all the safety-checks, etc. This serves firstly as documentation but also improves debugging as we will now see wanted and unwanted creation and destruction of these weird singletons. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-21Mobile: pass section directly to tripTitle() and tripShortDate()Gravatar Berthold Stoeger
Instead of converting the section-heading string to a trip-pointer in QML and pass that to the tripTitle() and tripShortDate() functions, pass the string and convert in C++ code. Hopefully, this makes the code more robust. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-21Mobile: pass trip-ids through QML, not formatted pointersGravatar Berthold Stoeger
The section heading in the QtQuick ListView has to be a string. Therefore, we passed a pointer formatted using hexadecimal notation. Later, that was converted back without being checked. A very scary proposition, so let's pass unique integer trip-id instead. This means that on converting back we have to scan the trip table, but that is a very minor cost comsidering to the gained robustness. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-21Cleanup: remove bogus assignment in startFilterDiveSites()Gravatar Berthold Stoeger
In MultiFilterSortModel::startFilterDiveSites(), the setting of the dive sites to be filtered is done later in the code. Therefore, remove the assignment in the first line of the function. Under some circumstances, this would prevent a needed map reload! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: Map directly from source in DiveListSortModel::getIdxForId()Gravatar Berthold Stoeger
Instead of looping over all dives and search the dive with the given id, let the source model determine the index and map that. Thus, we do only one mapping and don't generate a ton of DiveObjectHelpers. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: provide direct access to dives in DiveListModelGravatar Berthold Stoeger
Accesses were via DiveObjectHelpers. Provide a direct access to struct dive *. Use this for the filter - there is no point in mass generating DiveHelperObjects in the filter code. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: create DiveObjectHelper only when neededGravatar Berthold Stoeger
In DiveListModel::data() a DiveObjectHelper was created for any data-access. Create it only when a DiveObjectHelper is actually returned. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: remove dive argument from DiveListModel::insertDive()Gravatar Berthold Stoeger
Since DiveListModel does not keep its own list of dives anymore, insertDive() doesn't use the DiveObjectHelper argument. Remove it. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: replace clear()/addAllDives() pairs by reload()Gravatar Berthold Stoeger
The clear()/addAllDives() pair was bogus as the former didn't clear the model (this is not possible anymore - the model represents the core dive list) and the latter readded all dives again. Replace this by a reload() function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Cleanup: remove DiveListSortModel::addAllDives()Gravatar Berthold Stoeger
This function was never used. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: Generate DiveObjectHelpers on the flyGravatar Berthold Stoeger
Instead of keeping track of a list of DiveObjectHelpers, generate them on-the-fly in DiveListModel. Thus, there is less danger of model and core getting out of sync. On the flip-side, now the DiveListModel and the DiveListSortModel might get out of sync. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14DiveObjectHelper: Turn DiveObjectHelper into Q_GADGET based objectGravatar Berthold Stoeger
DiveObjectHelper is a tiny wrapper around dive * to allow access to dive data from QML and grantlee. It doesn't have to be a full-fledged QObject with support for signals, etc. Therefore, turn it into a Q_GADGET based object. This allows us passing the object around as object, not as pointer to DiveObjectHelper. This makes memory-management distinctly easier. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: return depthDuration directly from DiveListModelGravatar Berthold Stoeger
We don't want to generate a DiveObjectHelper numerous times for every item in the dive list. Therefore, return this data directly from the model. In this case, don't remove from DiveObjectHelper, as these data might be used by grantlee templates. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: return location directly from DiveListModelGravatar Berthold Stoeger
We don't want to generate a DiveObjectHelper numerous times for every item in the dive list. Therefore, return this datum directly from the model. In this case, don't remove from DiveObjectHelper, as this datum might be used by grantlee templates. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-14Mobile: return dive-number directly from DiveListModelGravatar Berthold Stoeger
We don't want to generate a DiveObjectHelper numerous times for every item in the dive list. Therefore, return this datum directly from the model. In this case, don't remove from DiveObjectHelper, as this datum might be used by grantlee templates. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>