summaryrefslogtreecommitdiffstats
path: root/qt-models/diveplannermodel.h
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: 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: 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-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-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: 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-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-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>
2020-05-04planner: send plan in calculatedPlanNotesGravatar Berthold Stoeger
Thus, the MainWindow doesn't have to extract the plan from displayed_dive. This is a tiny step in an attempt to detangle the interfaces. The bigger goal will be to make displayed_dive local to the planner. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04planner: update variations in planner not mainwindowGravatar Berthold Stoeger
When calculating variations, they were sent to the mainwindow, which updated displayed_dive accordingly. Do this directly in the planner-model. The idea is to detangle interdependencies and to make the code reusable (planner on mobile?). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-04-13Preserve events when editing dive in plannerGravatar Robert C. Helling
The planner does not know about events except gas changes. But if the dive comes from the log, we should preserve the dive computer events. At least those that happend before we started to delete waypoints to let the planner take over. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-02-11Planner: don't filter cylindersGravatar Berthold Stoeger
In the planner we used to filter out "unused" cylinders as in the equipment tab. It is unclear whether that makes sense or can even easily be reproduced, since such cylinders have to come from an imported dive. To be on the save side, let's not do this. Replace the CylindersFilteredModel introduced recently by a plain CylindersModel. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-02-11Planner: make cylinder-model subobject of planner-modelGravatar Berthold Stoeger
The cylinder-model had an instance() function, but actually there were two cylinder models: one used by the equipment tab, one used by the planner. This is misleading. Therefore, remove the instance() function and make the cylinder-model a subobject of the planner-model. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-01-20qt-models: add suffix Display to unit system aware asc/desc settersGravatar jan Iversen
Change ascent/descent setter function names to set_<name>Display to show the value is prepared for displaying (common for desktop and QML). Signed-off-by: jan Iversen <jan@casacondor.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-01-20qt-models: add getters to diveplanner modelGravatar jan Iversen
diveplannermodel already contains set_<asc/desc> function that convert from screen value to real value; this adds get functions that convert real value to screen value, so now all conversions are done in one place. Use prefix Display to identify this is values prepared for the UI (both desktop and QML). Signed-off-by: jan Iversen <jan@casacondor.com> 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-08-08Cleanup: move planner/deco related declarations planner/deco.hGravatar Berthold Stoeger
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-03-29Add UI element for final surface segment in plannerGravatar Robert C. Helling
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-09-29Cleanup: reinstate override modifiersGravatar Berthold Stoeger
This reverts commit 1c4a859c8d0b37b2e938209fe9c4d99e9758327a, where the override modifiers were removed owing to the noisy "inconsistent override modifiers" which is default-on in clang. This warning was disabled in 77577f717f5aad38ea8c4c41c10c181486c4337f, so we can reinstate the overrides. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-08-01Cleanup: remove all override modifiersGravatar Berthold Stoeger
Commit df156a56c08a56eb380711a507ef739d8150a71f replaced "virtual" by "override" where appropriate. Unfortunately, this had the unintended consequence of producing numerous clang warnings. If clang finds a override-modified function in a class definition, it warns for *all* overriden virtual functions without the override modifier. To solve this, go the easy route and remove all overrides. At least it is consistent. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-31Cleanup: replace virtual by override where appropriateGravatar Berthold Stoeger
The keyword "virtual" signalizes that the function is virtual, i.e. the function of the derived class is called, even if the call is on the parent class. It is not necessary to repeat the "virtual" keyword in derived classes. To highlight derived virtual functions, the keyword "override" should be used instead. It results in a hard compile- error, if no function is overridden, thus avoiding subtle bugs. Replace "virtual" by "override" where appropriate. Moreover, replace Q_DECL_OVERRIDE by override, since we require reasonably recent compilers anyway. Likewise, replace /* reimp */ by "override" for consistency and compiler support. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-24Copy divemode to ReplanGravatar Robert C. Helling
this needs copying the divemode from the dive to the plan. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-05-14Add planner infra structure for bailoutGravatar Robert C. Helling
Add a divemode column to the planner model and a corresponding field to struct divepoint and fill it in the corresponding functions. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-01-10Move function to proper placeGravatar Jan Mulder
Instead of writing TODO comment blocks, just do the work, and move the function to the proper class. Further, after review from Berthold, cleanup the function. There is no reason that getGasList() is member of any class. It is just a non-class helper, and as it is only used here, a static helper. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2017-12-24Simplify update of gflow and gfhigh values in the codeGravatar Stefan Fuchs
The more complex handling is no longer needed because: - Keyboard tracking for gfhigh/low UI fields was switched off here: 030c094854aeab4aaade523d7126728d9ce98a5b - GFhigh was limited to 40 here: 53fffe0ce3696de33ce4657e20d295e4a43e0fd9 Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2017-12-24Correcty typo ghflow -> gflow in diveplannermodel.cppGravatar Stefan Fuchs
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2017-12-01Actually compute variations in backgroundGravatar Robert C. Helling
This reenables the computation of plan variations but now in a separate thread. Once finieshed, a signal is sent to update the notes. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-11-25Hand planner variables to profileGravatar Robert C. Helling
Pass the planner state struct to the profile computation so it can use deco_time and first ceiling to display VPM-B ceiling. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-11-25Localize global planner stateGravatar Robert C. Helling
For UI responsiveness, we need to be able to run the planner in the background. This needs the planner state to be localized (and we need to pass a pointer around). In order to not let too many lines overrun (and to save typing in the future) I have renamed instances of struct deco_state to ds. Yes this should have gone to a separate commit but I accidentally commit --amend'ed it. Computing of planner variations is temporarily disabled. Unlock the planner when returning early So we don't deadlock in add dive and recreational mode (which use the planner without actually planning). Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-11-25Run variations calculation in backgroundGravatar Robert C. Helling
but there are still side effects and thus it crashes. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-10-16Correctly name member function gasChange of DivePlannerPointsModelGravatar Stefan Fuchs
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2017-10-16Update diveplannerpoints cylinderidx when deleting a cylinderGravatar Stefan Fuchs
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2017-10-04Planner settings ascend and descende rate: Wire up UI elements correctlyGravatar Stefan Fuchs
Wire up the UI elements (QSpinBoxes) for ascend rates (4x) and descend rate (1x) correctly so that the profile and calculation is updated immediately after the value is changed (e.g. increased/decresed by 1) by clicking the QSpinBox arrows. Until now one had to click into the profile or change another planner preference first before the change became effective. Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2017-09-20Add a checkbox to turn off plan variationsGravatar Robert C. Helling
... as those come with a performance penalty Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-08-29Show variations in Runtime stringGravatar Robert C. Helling
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-08-29Compute variations of plansGravatar Robert C. Helling
Print out partial derivatives of stop times with respect to variation of depth and duratin of last manual segment. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2017-04-29Add SPDX header to Qt modelsGravatar Dirk Hohndel
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-03-11Minimum gas calculation - Calculations and UI parametersGravatar Stefan Fuchs
Add minimum gas calculation to planner output. Add the two UI parameters prefs.sacfactor and prefs.problemsolvingtime. Connect UI signals and slots for recalculation of diveplan. Disable minimum gas calculation if there was already a warning before. If minimum gas result is larger then cylinder start pressure give warning message instead of result. Add line break before pO2 warnings but only if warnings exist. Signed-off-by: Joachim Ritter <jritter@bitsenke.de> Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2017-02-04Let cylinderid = -1 mean same gas as beforeGravatar Robert C. Helling
It's not too clever to give 0 a special meaning (as here: use same gas as for previous leg) when 0 is a legitimate value. This should solve Willem's gas disappearance problem when reediting a dive in the planner. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2016-09-24Rename conservatism_level to vpmb_conservatismGravatar Rick Walsh
Make the variable purpose less ambiguous Signed-off-by: Rick Walsh <rickmwalsh@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>