summaryrefslogtreecommitdiffstats
path: root/desktop-widgets
AgeCommit message (Collapse)Author
2021-03-31stats: fix visibility check of the statistics tab on desktopGravatar Berthold Stoeger
Apparently, the visibility flag of the view is not inherited from the statistics widget. Therefore, the statistics is redrawn on every action even if not visible. Set the visibility explicitly in the show- and hide-events. This is crazy. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17desktop: fold ApplicationState into MainWindowGravatar Berthold Stoeger
The application state is a desktop-only thing. The mobile UI also has its application state, but that is something completely different. The last remaining user of the application state was to flag whether the planner is active. Since this has all been unglobalized, the ApplicationState structure can be moved from core to the desktop UI. And there it can be made local to the MainWindow class. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17planner: pass in_planner down to TemplateLayoutGravatar Berthold Stoeger
The TemplateLayout prints different dives depending on whether the planner is active. Instead of accessing a global variable, pass the status down from the MainWindow. That's all quite convoluted, since there are multiple layers involved. On the positive side, the in_planner() function has now no users an can be removed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17cleanup: remove unused includes in mainwindow.cppGravatar Berthold Stoeger
The printing code moved elsewhere, so these includes are not needed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-13statistics: implement primitive "restrict to selection" featureGravatar Berthold Stoeger
Allow the user to restrict the analyzed dives based on the current selection. One button restricts to the current selection and one button resets the restriction. Thus, the user can for example select bars in the bar chart or a range in the scatter plot and perform statistics on these sets. The restriction works on top of the filter. The UI can certainly be improved, but it is a start. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-13printing: "fix" progress indicatorGravatar Berthold Stoeger
In TemplateLayout, there was a progress indication, which reported the progress - not of the actual rendering - but of adding the dives to the "to render" list. Which is of course done in less than a ms, making the whole thing completely pointless. Instead, emit progress when actually looping over the dives or statistics. Nobody ever noticed the problem because even rendering is done in fractions of a second and indeed is accounted to only one fifth of the total progress. The real purpose of this "fix" is to get rid of the getTotalWork() function, which was just insane. Instead of asking the TemplateLayout how many dives it rendered, this number was extracted from global state. Simply store the number of dives in the TemplateLayout object instead. Moreover, fix two coding style issues: - "Page" variable identifier starting with a capital - The Printer::render() being defined (as opposed to declared) with a default parameter. This is not how C++'s default parameters work, sorry. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-10desktop: disable animation when selecting multiple divesGravatar Berthold Stoeger
Selecting many dives when the animation was active was increadibly slow, so disable it. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06desktop: improve splitter defaultsGravatar Berthold Stoeger
On first startup, use the splitter values suggested by Dirk: Top/Bottom: 60/40 Info/Profile: 50/50 List/Map: 60/40 Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06profile: detect dive-mode change in profileGravatar Berthold Stoeger
The profile must be replotted when the dive mode changes. Weirdly, this was routed via the dive-information tab (making it inherently non-mobile compatible). Detect such a change directly in the profile. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06desktop: be smarter about filling splittersGravatar Berthold Stoeger
On state change, the splitters were completely emptied and refilled. Instead try to reuse already existing splitter slots. This reduces annoying flickering. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06desktop: don't access profile directly to redraw itGravatar Berthold Stoeger
The MainWindow has a function to replot the profile. Use that instead of accessing the profile directly. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06desktop: do own memory management of quadrant widgetsGravatar Berthold Stoeger
The memory management of the quadrant widgets is a total mess: When setting the widget, the QSplitters take ownership, which means that they will delete the widget in their destructor. This is inherently incompatible with singletons, which must not be deleted. To avoid all these troubles, remove the widgets from the QSplitters in the desctructor of the MainWindow. This of course means that we now have to take care about deletion of the widgets. For local widgets use std::unique_ptr, for singletons use a static variable that is deleted on application exit. Sadly, for the map widget we can't use a normal singleton, because the QML MapWidget's memory management is buggy. Add a comment in the source code explaining this. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06desktop: don't allow view change in plannerGravatar Berthold Stoeger
When in planner mode, don't allow the user to change the application state. This brought us nothing but troubles and inconsistencies. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06desktop: remove the view-stateGravatar Berthold Stoeger
There was the "application state", which decided what to show in the "quadrants" and the "view state" which decided which quadrant to show. These interacted in a hard-to-grasp way. The "view state" is used to show the map or dive list in full screen. I simply couldn't get these two orthogonal states to interact properly. Moreover the thing was buggy: If a quadrant was hidden, the user could still show it, by dragging from the side of the window, at least under KDE. To solve these woes, merge the two states into a single application state. If the widget of a quadrant is set to null, don't show it. So the four "view states" are now "application states" where three of the four quadrants are not shown. This also changes the memory management of the widgets: widgets that are not shown are now removed from the QSplitter objects. This makes it possible that the same widget is shown in *different* quadrants. While writing this, I stumbled upon a Qt bug, which is known since 2014: https://forum.qt.io/topic/43176/qsplitter-sizes-return-0 When restoring the quadrant sizes there was a test whether the quadrant size is 0. If that was the case, a default size was set. This seems not to work if the widgets were recently added. Since this test now always fails, make the quadrants non-collapsible and thus guarantee that 0 is never saved as a size. 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-20statistics: don't replot chart when changing featuresGravatar Berthold Stoeger
Up to now, when the user changed the visibility of chart features (legend, quartiles, labels, etc.) the whole chart was replot. Instead, only change the visibility status of these items. After all, this modularity is one of the things the conversion to QSG was all about. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20statistics: turn ChartGrid into QSGNodesGravatar Berthold Stoeger
Turn the background grid into QSGNodes. Each grid line is represented by a QSG line item. An alternative would be drawing the grid into a QImage and blasting that onto the screen. It is unclear which one is preferred. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-19mobile: add GF fields for ceiling calculationGravatar Doug Junkins
Adds fields to the advanced preferences page to modify GFLow and GFHigh for the Buhlmann decompression model for calculating ceilings. Updated preferences code to set the Buhlmann parameters in core/deco.c when the GF prefs are updated. Signed-off-by: Doug Junkins <douglas.junkins@gmail.com>
2021-01-11undo: remove invalidate_dive_cache call from MainTabGravatar Berthold Stoeger
When creating the RenumberDive undo command, the MainTab would manually call invalidate_dive_cache(). However, this is done on undo/redo, therefore the call can (should) be removed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10profile: remove ProfileWidget2::dateTimeChanged()Gravatar Berthold Stoeger
This function sent a signal and the only listener was removed in the previous commit. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10statistics: convert chart to QQuickItemGravatar Berthold Stoeger
It turns out that the wrong base class was used for the chart. QQuickWidget can only be used on desktop, not in a mobile UI. Therefore, turn this into a QQuickItem and move the container QQuickWidget into desktop-only code. Currently, this code is insane: The chart is rendered onto a QGraphicsScene (as it was before), which is then rendered into a QImage, which is transformed into a QSGTexture, which is then projected onto the device. This is performed on every mouse move event, since these events in general change the position of the info-box. The plan is to slowly convert elements such as the info-box into QQuickItems. Browsing the QtQuick documentation, this will not be much fun. Also note that the rendering currently tears, flickers and has antialiasing artifacts, most likely owing to integer (QImage) to floating point (QGraphicsScene, QQuickItem) conversion problems. The data flow is QGraphicsScene (float) -> QImage (int) -> QQuickItem (float). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-06desktop/update-check: fix logic when to ask about update checkGravatar Dirk Hohndel
Checking a field that we intentionally don't store to disk is obviously wrong. It's been this way for a long time and it has annoyed me many times, but somehow I never spent the time to track down why this was happening. It makes much more sense to use the presence of either the don't check flag or a next check date as an indication that we have already asked this question. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06desktop/UI: move statistics to View menuGravatar Dirk Hohndel
It seems to make more sense to have it there with the 'Yearly Statistics' and not in the Log menu. Interestingly enough, both locations were clearly considered when first adding this in commit 106f7a8e0e ("desktop: add statistics widget dummy and application state") as you can tell by the never implemented actionViewStats. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06dekstop/UI: remove duplicate resourceGravatar Dirk Hohndel
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06desktop/UI: add shortcut for 'Open cloud storage'Gravatar Dirk Hohndel
This seems like a logical extension of the shortcuts we already have. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-03desktop: rename Statistics tab to SummaryGravatar Dirk Hohndel
We now have three different things that are kinda like statistics: - the summary tab (reasonably useful when looking at selected dives) - the yearly statistics (Ctrl/CMD-Y) - the full statistics (Ctrl/CMD-T) I'd argue that's at least one too many. But I'm sure some people will disagree. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-03statistics: reverse chart selection logicGravatar Berthold Stoeger
The old ways was to select the chart first, then depending on the chart choose the binning. Willem says that it should work the other way round: select the binning (or operation) and make the charts depend on that. I'm not arguing one way or the other, just note that the new way is much more tricky, because it is easy to get unsupported combinations. For example, there is no chart where the first variable is unbinned, but the second axis is binned or has an operation. This makes things distinctly more tricky and this code still needs a thorough audit. Since this is all more tricky, implement a "invalid" chart state. Ideally that should be never shown to the user, but let's try to be defensive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-03desktop: add statistics widget dummy and application stateGravatar Berthold Stoeger
Add a new "statistics" application state. In the statistics state show the statistics widget and the filter in the top quadrants. The idea is to allow filtering and doing statistics at the same time. Sadly, we can't use the filter-widget in different quadrants, because Qt's ownership model is completely broken / inflexible. It does not support a widget having different parents and thus a widget can only belong to one QStackedWidget. Hiding the map in the statistics view is quite hacky: Since the view of the quadrants is not determined by the "ApplicationState", we have to restore the original quadrant visibility when exiting the stats mode. Therefore, set the original visibility-state when changing application state. The MainWindow-quadrant code really needs to be rewritten! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-03statistics: implement a statistics widget on desktopGravatar Berthold Stoeger
Implement a widget that shows the statistics state as comboboxes and the statistics chart. Calls into the statistics code if any of the comboboxes changes. The hardest part here is the formatting of the charts list with its icons and with headings. Sadly, it is not trivial to arrange icons horizontally. Therefore we would have to fully reimplement the ComboBox view, which is probably not fun. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01cleanup: remove "GpsLocation *locationProvider" from MainWindowGravatar Berthold Stoeger
This is mobile only and not used on desktop. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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-17printing: remove CylinderObjectHelperGravatar Berthold Stoeger
With the removal of grantlee, this became pointless glue code. Call the formatting functions directly. Since the printing code was the only user of CylinderObjectHelper, remove the whole thing. 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-17printing: remove DiveObjectHelperGrantleeGravatar Berthold Stoeger
This was a weird helper object, needed for grantlee. Instead of storing this object, loop over cylinders and dives directly. The actual accessor function is unchanged and now generates a DiveObjectHelper or DiveCylinderHelper for every variable access. Obviously, this is very inefficient. However, this will be replaced in future commits by direct calls to formatting functions. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17cleanup: remove QPointer instancesGravatar Berthold Stoeger
QPointer is a strange "smart" pointer class, which resets itself when the pointed-to QObject is deleted. It does this by listening to the corresponding signal and therefore is surprisingly heavy for a plain pointer. A cynic would say that the existence of QPointer is an expression of Qt's broken ownership model. In any case, QPointer was only used at two places, were it was 100% useless: As a parameter to a function and as a locally scoped pointer. It only makes sense if a) there is a chance that the object disappears during the pointer's lifetime and b) it is actually checked for null before use None of which was the case here. Remove. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17printing: move #includes from headers to source filesGravatar Berthold Stoeger
To decrease include-file interdependencies. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17printing: remove YearInfo structureGravatar Berthold Stoeger
This is a wrapper around "stats *" used to pass statistics through Qt's weird metatype system. Not needed anymore. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17printing: refactor if and loop codeGravatar Berthold Stoeger
The loop code was buggy: the current position was only increased inside when executing the loop once. This would obviously fail for empty lists. Moreover, the whole thing was quite difficult to reason about, since a reference to the current position was passed down in the call hierarchy. Instead, pass from and to values to the parse function and create a generic function that can search for the end of loop and if blocks. This function handles nested if and for loops. The if-code now formats the block only if the condition is true. The old code would format the block and throw it away if not needed. This should now provide better diagnostics for mismatched tags. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17printing: remove objects QVariant mapGravatar Berthold Stoeger
An artifact from the old grantlee code: the whole parser state was kept in an untyped QVariant map. One case was particularly bizarre: the options were a class member and yet added to the weird map. Replace this by a strongly typed state structure. Ultimately, this will allow us to replace the "dive object helper". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17cleanup: make templateOptions and printOptions reference typesGravatar Berthold Stoeger
These two structs describe options used during printing. They are passed through numerous classes as pointer. In this case, reference semantics are preferred, as references: - can never be null - can not change during their lifetime This not only helps the compiler, as it can optimize away null checks, but also your fellow coder. Moreover, it prevents unintentional creation of uninitialized references: one can't create an instance of a class without initializing a reference member. It does not prevent references from going dangling. However, pointers have the same disadvantage. Contains a few whitespace cleanups. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13cleanup: remove MainWindow::stateBeforeEdit memberGravatar Berthold Stoeger
The last user was removed in accf1fcc8f6ad. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13cleanup: remove unused typedefsGravatar Berthold Stoeger
Last users removed in ca6aa3813956b5e8be68b86ed36a5786b3ee746f. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13prefs: add option to display only actually used tanksGravatar Berthold Stoeger
A user complained about the default cylinders list. Provide a preferences option to turn this off. When changing the preferences, the tank-info model will be completely rebuilt. Currently, this is a bit crude as this will be done for any preferences change. Suggested-by: Adolph Weidanz <weidanz.adolph@gmail.com> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13core: remove the "no-name" tank infoGravatar Berthold Stoeger
There was a tank info with an empty name. According to a comment, this is needed for the "no cylinder" case. However, we now support empty cylinder tables, so this is not needed anymore. Therefore, remove it. Make sure that the user can still enter the empty name, just in case. But don't save the size and pressure in that case. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13desktop: don't save data to the "no-name" tankGravatar Berthold Stoeger
There seems to be no point to saving data to the tank with the empty name. Don't save tank-pressure and size to that tank info. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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-12cleanup: remove unused #undefs in mainwindow.cppGravatar Berthold Stoeger
These macros were removed 2016-ish. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12profile: move connect() calls to profileGravatar Berthold Stoeger
The mainwindow was connecting preferences changes to the profile. Do this directly in the profile. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12cleanup: remove unused signal ProfileWidget2::updateDiveInfoGravatar Berthold Stoeger
Last user was remove in 0bd821183d. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12profile: move DiveHandler to profile-widget folderGravatar Berthold Stoeger
These are the small dots that describe dragable points on the profile when in the planner. It makes no sense to have them in desktop's planner-widget code. They belong to the profile. Therefore, move the code there and compile on mobile. Not everything can be compiled on mobile for now, but it is a start. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>