aboutsummaryrefslogtreecommitdiffstats
path: root/qt-models
AgeCommit message (Collapse)Author
2021-04-02planner: split DivePlannerPointsModel::remove() in twoGravatar Berthold Stoeger
There are two cases in this function: with and without holding the control-key. The former deletes one point, the latter all points starting with the selected point to the end. The code was interlaced making it very hard to reason about. Notably, it was buggy: with control, all points could be deleted, leading to a crash. Split the function in two versions, with their own bound checking. This produces a bit of duplicate code, which might be broken out later. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: avoid starting unneeded variation threadGravatar Berthold Stoeger
When updating the dive profile, a thread is started to calculate plan-variations. This is done even when only editing the profile or when variation calculation is disabled by the user. The thread then exits if it shouldn't calculate the variations. Turn this around: test whether variations should be calculated before starting the thread. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: remove DivePlannerPointsModel::recalc flagGravatar Berthold Stoeger
There was no user of that flag left. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: call removeDeco() explicitlyGravatar Berthold Stoeger
removeDeco() was called by addStop() if the recalc flag was set. If the caller didn't want to call removeDeco() it had to clear and restore the flag. Instead, call removeDeco() explicitly when needed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: don't clear recalc in DivePlannerPointsModel::clear()Gravatar Berthold Stoeger
There are no more external users of this flag, therefore clearing that flag is a no-op. Moreover, clear the cylinders array and the preserved_until flag befor emitting the model-reset signal. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: split DivePlannerPointsModel::removePoints() in twoGravatar Berthold Stoeger
Split the function in one external version, that updates the dive profile and cylinders and one internal version, that does no recalculations. In the latter case, the caller is responsible for updating the dive. Thus, the recalculation flag-clearing can be removed from removeDeco(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: don't export recalc flag of DivePlannerPointsModelGravatar Berthold Stoeger
This is not queried anymore, so remove the accessor function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02profile/planner: don't update dive in ProfileWidget2::plotDive()Gravatar Berthold Stoeger
In planner or profile-edit mode, the plotDive() function takes the current plan and turns it into a dive profile. Not only is this a layering violation (the display layer modifying the dive), it is also fundamentally flawed. The control-flow is out of control, if you wish. There are numerous reasons why the profile needs to be replot, many of which do not need a recalculated dive profile. Move the code that updates the dive-profile to the DivePlannerPointsModel. Thus, the profile recalculations and replots can be pooled. This will break the planner, since there now might be missing calls to the profile recalculation. But it already has some positive effects: when removing multiple points, the profile is only recalculated once. This will need much more work, but it is a start. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: split addStop() into external and internal versionsGravatar Berthold Stoeger
The DivePlannerPointsModel::addStop() function is called by the profile to add a planner-stop. It is also used internally to create profiles. If we ever want to include this in the undo system, we have to split these into to versions. One will ultimately place an undo command and update the profile, the other one doesn't. For now, this makes the external interface simpler, as some parameters are redundant. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: make DivePlannerPointsModel::removeDeco() privateGravatar Berthold Stoeger
No outside users. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: remove unused function DivePlannerPointsModel::size()Gravatar Berthold Stoeger
This is not a virtual function and does not seem to be called anywhere..? Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: remove unused member DivePlannerPointsModel::addingDecoGravatar Berthold Stoeger
This was never used. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: split createTemporaryPlan() function.Gravatar Berthold Stoeger
The DivePlannerPointsModel::createTemporaryPlan() function had two distinct and independent parts: 1) create the data points. 2) create the dive sample and calculate variations. The second part was only exectuted if the recalc flag was set. Out of the two callers, one was explicitly disabling and setting the recalc flag to avoid the second part. The much more logical thing is to simply split the function in two and only call the first part. To avoid any functional change, the second caller (the profile) still tests for the recalc flag. However, if it shouldn't replot a new plan, why calculate it in the first place!? And why does the display function change the plan at all? This appears all very ill-thought out and should be changed in due course. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: unify whitespace in switch statementGravatar Berthold Stoeger
The way the blocks in DivePlannerPointsModel::setData()'s switch statement were demarked messed with my mind. There were at least three variants. Let's try to be consistent. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: remove DivePlannerPointsModel::setRecalc()Gravatar Berthold Stoeger
The only external user of setRecalc() was turning recalculation on. In fact, this happened when constructing the planner-widget. However, for example editing of the profile only works when the recalc flag is on. This is all very confusing, let's just turn the flag on by default and remove the accessor. Internally, the planner can simply use the std::exchange function to set and reset the recalc flag. Perhaps the setting/resetting can be replaced by simple recalc = true; ... recalc = false; pairs. It is unclear whether there is need for recursion. Something to be investigated. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02profile: display arbitrary diveGravatar Berthold Stoeger
So far the profile operated on the global displayed_dive. Instead, take the dive to be displayed as a parameter to the plotDive() functions. This is necessary if we want to have multiple concurrent profile objects. Think for example for printing or for mobile where multiple dive objects are active at the same time. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: remove displayed_dive from DivePlannerModelGravatar Berthold Stoeger
To remove global state, make the dive that DivePlannerModel works on a member variable. Pass the dive in createSimpleDive() and loadFromDive(). Moreover, this should pave the way to more fine-grained undo in the planner. Ultimately, the planner should not be modal. Attention: for now, the dive must still be displayed_dive, because of the convoluted way in which the profile and the planner work on the same dive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: move clearing of model into loadFromDive() functionGravatar Berthold Stoeger
Both loadFromDive() callers were clearing the model before calling loadFromDive(). Move the clearing into that function since it makes no sense to load into a non-cleared model. Apparently this changes the way that no-cylinder dives are treated and the code in ProfileWidget2::repositionDiveHandlers() must now explicitly check for that condition. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: remove pointless cylinder model updateGravatar Berthold Stoeger
In DivePlannerPointsModel::clear(), the cylinder model is updated before it is cleared. This must be an artifact. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: move same-time check to DivePlannerPointsModelGravatar Berthold Stoeger
There must not be two dive planner points at the same time stamp, as this violates the laws of physics (and internal assumptions). The corresponding test was done in the profile code at two different places with floating point arithmetics. This is a bad idea, because 1) code duplication 2) danger of rounding issues Instead, do this in one central point in the planner model and use integer arithmetics. Simply add a few seconds until a unique timestamp is obtained. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: implement move semantics in DivePlannerPointsModelGravatar Berthold Stoeger
When reordering the points, the DivePlannerPointsModel would not emit the appropriate move signals, but simply a data-changed signal over all elements. This obviously violates Qt's model/view API, though it is probably harmless. Let's do the right thing so that the frontend knows that the selected item changed place. Also, emit dataChanged only on the actually changed element, not all elements. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: fix removal of points from DivePlannerPointsModelGravatar Berthold Stoeger
The beginRemoveRows() function was fed erroneous values. It is a mystery why this didn't crash. In any case, deletion of multiple points did not work properly. Instead of trying to be fancy, remove each point one-by-one. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: insert point at correct positionGravatar Berthold Stoeger
Instead of inserting the point at the calculated position, the DivePlannerPointsModel would append it at the end and then resort the vector. That's just silly. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: use proper model/view semantics in DivePlannerModelGravatar Berthold Stoeger
When clearing the model, use "beginResetModel/endResetModel" instead of "beginRemoveRows/endRemoveRows". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: add DivePlannerPointsModel::addDefaultStop() functionGravatar Berthold Stoeger
When clicking on "+" in the planner, a default stop point was added using a signal/slot connection. This used the archaic string-based connect syntax, because it was realized with default parameters passed to "addStop()". Instead, add a "addDefaultStop()" slot, which passes the default parameters. Since all other callers do not use callbacks, unslotify "addStop()". The slot was the only user of the default parameters, so they can be removed alltogether. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02cleanup: constify DivePlannerPoints model accessor functionsGravatar Berthold Stoeger
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-04-02planner: unslotify two functions in DivePlannerPointsModelGravatar Berthold Stoeger
There are a few more candidates, but these conceptually really shouldn't be slots. getSurfacePressure() is an accessor and loadFromDive() initializes the model with a dive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-03-31core: initialize dive selection after resetting the dataGravatar Berthold Stoeger
The dive selection was initialized during data-reset. However, this emitted a signal before all data-reset routines were run. Ultimately, this led to access-after-free in the statistics code. Instead, move the select_newest_visible_dive() signal from the divelist-model to the process_loaded_dives() function. There is no point in initializing the selection if the dive data is cleared after all. This change broke closing of the log, because the UI-selection was not reset. Therefore, when clearing the data, clear the selection before proceeding with clearing. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17planner: pass in_planner argument to decoMode()Gravatar Berthold Stoeger
To remove reliance on global state, pass an "in_planner" argument to decoMode(). Thus, calls to in_planner() can be removed. This is a more-or-less automated change. Ultimately it would probably be better to pass the current deco-mode to the affected functions instead of calling decoMode() with an in_planner parameter. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-10desktop: cache photo and geo iconsGravatar Berthold Stoeger
The icons shown in the dive list were rendered for every single access. Render them only once. This supposes that the defaultIconMetrics structure does not change once the icons are rendered! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20cleanup: make a few DivePlannerModel functions privateGravatar Berthold Stoeger
It simplifies reasoning about control flow a lot if it is known that functions can't be invoked from a different part of the code base. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20cleanup: remove dive parameter from DivePlotDataModel::setDive()Gravatar Berthold Stoeger
This was not used, probably an artifact from days long gone. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20planner: remove DivePlannerPointsModel::startTimeChanged signalGravatar Berthold Stoeger
The way the starting time of a new plan was set was bonkers: 1) PlannerWidgets::planDive() invokes DivePlannerPointsModel:: createSimpleDive(). 2) createSimpleDive() calls DivePlannerPointsModel:: setupStartTime() 3) setupStartTime() emits a signal startTimeChanged() 4) startTimeChanged is caught by PlannerWidget and sets the UI field 5) change of the UI field emits a timeChanged() signal which is connected to DivePlannerPointsModel::setStartTime() 6) setStartTime() sets the time of the plan and displayed_dive and emits dataChanged() 7) dataChanged() replots the dive() 8) Back in DivePlannerPointsModel::createSimpleDive() the diveplan start time is overwritten with displayed_dive (the value are equal owing to 6) Wow! But it gets worse: 9) The initial dive plan is set up in createSimpleDive(). Since the profile is drawn in 7) after clearing the displayed_dive and before constructing the initial plan, the profile is shown on a dive without samples. It therefore generates a dummy profile. To make this somewhat less insane, remove the startTimeChanged() signal in 3), explicitly set the start time of plan and dive to the one calculated by setupStartTime() and explicitly set the UI filed in the plannerWidget. This still indirectly draws the profile via signals in a convoluted way, but at it straightens out things somewhat. Most importantly, the profile doesn't have to generate a fake DC. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-13mobile/cleanup: reduce the noise in our logsGravatar Dirk Hohndel
There are two sets of messages that tend to dominate the logs - the RSSI updates from the Qt BLE stack - the warnings about deprecated signal use in Kirigami Neither of them provide any value to us when trying to find bugs; and often they end up hiding the things that we really care about. So let's just not log them - which is easy as we have our own message handler. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-10profile: pass dive to DiveHandlerGravatar Berthold Stoeger
The DiveHandler shows a context menu where a cylinder can be chosen. This indirectly accesses the global displayed_dive variable. Remove this in a step to make the profile reentrant. The code was quite ominous: instead of simply generating the list of cylinders, a global model was reset and then accessed with Qt's cumbersome model/view API. All this trampling over global state can be removed by simply making the function that generates the list globally accessible. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10profile: explicitly update profile itemsGravatar Berthold Stoeger
Instead of listening to the dive-data-model changed and axis changed signals, update the profile items explicitly once per plot() call. This avoids double replotting of the dive items. The old code had at least two replots per plot() call: one after profileYAxis()->setMaximum() and one after dataModel->emitDataChanged(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10cleanup: const-ify DivePlotDataModel::*max() functionsGravatar Berthold Stoeger
These functions return the maximum partial pressures in the given dive. Obviously, being pure accessors, they should be const. This commit also replaces the macro generating these functions by a call to a function taking a pointer-to-member. Arguably, C++'s pointer-to-member syntax is just as horrible as macros, but at least it doesn't mess with syntax highlighting of my editor and should be better to debug. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10profile: remove redundant code in DiveCalculatedCeilingGravatar Berthold Stoeger
The DiveCalculatedCeiling profile-item has a recalc() function, which calls "dataModel->calculateDecompression()". This is a questionable reversal of control-flow: The profile-item should paint the model-data not change it. The code was supposed to be called under two conditions: 1) The value of the calcceiling3m preferences flag changed. This code was buggy for two reasons: Firstly, the cached value was always initialized to false, which means that sometimes the first call was missed. Secondly, the settingsChanged() functions was only called when closing the preferences window, not when changing the flag in the profile widgets. 2) The datetime of the dive changed. The whole control-flow is pretty absurd (due to "bit rot"): - The replan-dive command sends a date-time changed signal. - The main tab changes the date-time and informs the profile. - The profile sends a signal to the item. - The item instructs the model to recalculate the decompression. - The model causes the profile to be redrawn. In any case, the whole thing is moot, because the decompression is recalculated for *every* profile plot in create_plot_info_new(). Let's remove the code from the DiveCalculatedCeiling profile-item and the calculateDecompression() function, which is now not used anymore. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01fix potential crash in GPS codeGravatar Dirk Hohndel
If we don't have a GpsLocation instance, we shouldn't dereference it. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-12-29cleanup: remove getDivesInTrip() in qthelper.cppGravatar Berthold Stoeger
This function was not used anywhere. Moreover, remove a few unused includes from qthelper.h. Surprisingly, a number of users of qthelper.h depend on these, so readd them at the appropriate places. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29filter: internalize shown_dives in DiveFilter classGravatar Berthold Stoeger
one piece of global state removed! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29filter: move shown_dive from divelist.c to divefilter.cppGravatar Berthold Stoeger
Arguably, the number of filtered dives is a matter of the divefilter. Let's move it there. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29filter: reset shown_dives in filterGravatar Berthold Stoeger
The shown_dives variable was reset by the dive_list code. Arguably, the filter should keep track of the number of shown dives, so move the resetting there. This means adding a new "reset()" member function to the filter and call that instead of "updateAll()" when the core data is reset. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17mobile: remove DiveObjectHelper codeGravatar Berthold Stoeger
When editing a dive, a DiveObjectHelper of the unmodified dive was created to compare the edited with the old values. Since the DiveObjectHelper is used here only as a pointless wrapper around the formatting functions, call these functions directly. However, note that the code is in principle wrong since the change to the mobile-models, which do not use the DiveObjectHelper. The real fix would be to reload the data from the model to prevent going out-of-sync with respect to the formatting routines! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17printing: remove DiveObjectHelper from printing codeGravatar Berthold Stoeger
At this point (post grantlee), DiveObjectHelper is just pointless glue code. Let's remove it from the printing code and call the formatting functions directly. If necessary, move these functions to core/string-format.cpp. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17core: create string-format.cpp source fileGravatar Berthold Stoeger
The mobile version of the list used string formatting functions defined in DiveObjectHelper and declared in mobilelistmodels.h. Very confusing. Move them to a separate source file where - in the long run - all the string-formatting functions, which are scattered all over the place, can be collected. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>