summaryrefslogtreecommitdiffstats
path: root/qt-models
AgeCommit message (Collapse)Author
2018-10-11Cleanup: Remove SsrfFilterSortProxyModelGravatar Berthold Stoeger
SsrfFilterSortProxyModel was a thin wrapper around QFilterSortProxyModel, which was intended as a convenience class to avoid deriving from the latter. The filter and sort functions were replaced by simple function pointers. Unfortunately, by using function-pointers, the whole thing was rather weak as these functions do not have state. The last user was removed in ac8dcd7f65b78958587ba025280ed4c529b0b519. Therefore, remove the whole class. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Map: remove access to displayed_dive_site in GPS-filter modelGravatar Berthold Stoeger
The location information shows a list of dive sites at the same location as the edited dive site. This was done by passing a function to an "SsrfSortFilterProxyModel". Unfortunately, the latter does only support function pointers without state and therefore had to access the global "displayed_dive_site" object. Replace the SsrfSortFilterProxyModel by a proper subclass of QSortFilterProxyModel that contains information on the position and id of the currently edited dive site. Update the filter model if the location of the dive site changes. This introduces a behavioral change: editing the GPS location will lead to an updated list. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: make adding of planned dive undo-ableGravatar Berthold Stoeger
Planned dives were still added by directly calling core code. This could confuse the undo-machinery, leading to crashes. Instead, use the proper undo-command. The problem is that as opposed to the other AddDive-commands, planned dives may belong to a trip. Thus, the interface to the AddDive command was changed to respect the divetrip field. Make sure that the other callers reset that field (actually, it should never be set). Add a comment describing the perhaps surprising interface (the passed-in dive, usually displayed dive, is reset). Moreover, a dive cloned in the planner is not assigned a new number. Thus, add an argument to the AddDive-command, which expresses whether a new number should be generated for the to-be-added dive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Filter: reload only when checkstate changedGravatar Berthold Stoeger
Currently, the filter is recalculated if a filter-entry is changed. This also happens if the counts of a filter-entry changes. This is to be avoided, as it causes unnecessary churn. Therefore, send the proper role with the dataChanged() signal and add a new slot, which invalidates only if a field with the Qt::CheckStateRole is changed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Filter: Make filters aware of added / removed divesGravatar Berthold Stoeger
Instead of reloading all the filter, only increment / decrement the count of the entries of added / removed dives. Originally, this was planned to be done via the signals from the divelist, but it turned out that this was suboptimal, because if the filter decides that the new item is selected, this has to be done *before* adding the dive. Otherwise, it wouldn't be shown. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: unify sorting in core and Qt-modelGravatar Berthold Stoeger
Ultimately, we want to use a single dive-list and not replicate it in the Qt-model code. To this goal, let's start with using the same sort function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: retain selection on moval of divesGravatar Berthold Stoeger
The current code cheats when it comes to move dives inside a trip or move dives between trips: Instead of using the *MoveRows() functionality, the dives are removed from and re-added to the respective trips. This loses the selection. Therefore, remember which of the moved dives are selected and select them manually after they are re-added. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: propagate current-item to frontendGravatar Berthold Stoeger
The command-objects select a current item, but this selection was not propagated to the front-end. The current item is the base for keyboard-navigation through the dive-list and therefore should be set correctly. It took some experimentation to get the flags right: QItemSelectionModel::Current Hopefully, these are the correct flags across all supported Qt versions! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: select dives after add, remove, merge, split dive commandsGravatar Berthold Stoeger
Select the proper dives after the add, remove, split and merge dives commands on undo *and* redo. Generally, select the added dives. For undo of add, remember the pre-addition selection. For redo of remove, select the closest dive to the first removed dive. The biggest part of the commit is the signal-interface between the dive commands and the dive-list model and dive-list view. This is done in two steps: 1) To the DiveTripModel in batches of trips. The dive trip model transforms the dives into indices. 2) To the DiveListView. The DiveListView has to translate the DiveTripModel indexes to actual indexes via its QSortFilterProxy- model. For code-reuse, derive all divelist-changing commands from a new base-class, which has a flag that describes whether the divelist changed. The helper functions which add and remove dives are made members of the base class and set the flag is a selected dive is added or removed. To properly detect when the current dive was deleted it became necessary to turn the current dive from an index to a pointer, because indices are not stable. Unfortunately, in some cases an index was expected and these places now have to transform the dive into an index. These should be converted in due course. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: remember selected divesGravatar Berthold Stoeger
Don't delesect dives, when unregistering them from the backend. If a previously selected dive is added, select it in the dive-list. For this purpose introduce a SELECTED_ROLE to query the DiveTripModel for selected dives. Unfortunately, when adding multiple selected dives, current_dive_changed is called for each of them, making this very slow. This will have to be fixed in subsequent commits. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: implement proper Qt-model semantics for DiveTripModelGravatar Berthold Stoeger
Previously, each dive-list modifying function would lead to a full model reset. Instead, implement proper Qt-model semantics using beginInsertRows()/endInsertRows(), beginRemoveRows()/ endRemoveRows(), dataChange(). To do so, a DiveListNotifer singleton is generatated, which broadcasts all changes to the dive-list. Signals are sent by the commands and received by the DiveTripModel. Signals are batched by dive-trip. This seems to be an adequate compromise for the two kinds of list-views (tree and list). In the common usecase mostly dives of a single trip are affected. Thus, batching of dives is performed in two positions: - At command-level to batch by trip - In DiveTripModel to feed batches of contiguous elements to Qt's begin*/end*-functions. This is conceptually simple, but rather complex code. To avoid repetition of complex loops, the batching is implemented in templated-functions, which are passed lambda-functions, which are called for each batch. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: make diverse trip-related operations undo-ableGravatar Berthold Stoeger
AddDivesToTrip, CreateTrip, AutogroupDives, RemoveAutogenTrips and MergeTrips basically all did the same thing as RemoveDivesFromTrip, which was already implemented. Thus, factor our the common functionality and hook it up to make all these functions undo-able. Don't do the autogroup-call everytime the dive-list is rebuilt (that would create innumberable undo-actions), but only on dive-load / import or if expressly asked by the user [by switching the autogroup flag]. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: hand-code the DiveTripModelGravatar Berthold Stoeger
The dive list is fed data by means of a sorted "DiveTripModel". There are two modes: list and tree. This was implemented rather elegantly with a general "TreeModel", which can represent trees of arbitrary depths. Nevertheless, we have at most two levels and on the second level only dives can reside. Implementing proper model-semantics (insert, delete, move) will be quite a challenge and implementing it under the umbrella of a very general model will not make it easier. Therefore, for now, hardcode the model: At the top-level there are items which may either be a trip (can contain multiple dives) or a dive (contains exactly one dive). Thus, we can completely de-virutalize the DiveItem and TripItem classes, which are now trivial wrappers around dive * and dive_trip *. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: replace dive-id by dive pointerGravatar Berthold Stoeger
The undo-system now guarantees that pointers to dives are stable throughout their lifetime. Therefore, replace the unique index by pointers. This is a small performance improvement, but much more importantly, it will make it more natural to transport a pointer to the dive inside QModelIndex's private pointer. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-09Dive locations: factor out common code of modelsGravatar Berthold Stoeger
For increased maintainability, use the same columns, roles and the same accessor function for both dive-site models. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-09Dive sites: remove internalRowCount from LocationInformationModelGravatar Berthold Stoeger
This was redundant. Directly use dive_site_table.nr instead. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-09Dive sites: don't add dummy entries to LocationInformationModelGravatar Berthold Stoeger
The LocationInformationModel added two dummy sites to the front of the list (add new dive site). This was never used - desktop uses its own model, mobile only extracts the list of dive site names with a custom function. Remove this functionality. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-09Dive sites: remove LocationInformationModel::setData() functionGravatar Berthold Stoeger
Editing of dive sites does not work via this model and the function was broken anyway (it didn't subtract 2 from the index). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07Statistics: only consider selected dives in HTML export statisticsGravatar Berthold Stoeger
If only selected dives were exported into HTML, the statistics would nevertheless cover all dives. A counter-intuitive behavior. Fix by adding a selected_only flag to calculate_stats_summary(). Reported-by: Jan Mulder <jlmulder@xs4all.nl> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07Statistics: remove global state / calculate only when neededGravatar Berthold Stoeger
Statistics were calculated into global variables every time the current dive was changed. Calculate statistics only when needed and into a structure provided by the caller. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06Import: pass "downloaded" parameter to process_imported_dives()Gravatar Berthold Stoeger
process_imported_dives() is more efficient for downloaded than for imported (from a file) dives, because it checks only the divecomputer of the first dive. This condition is checked via the "downloaded" flag of the first dive. Instead, pass an argument to process_imported_dives(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06Core: remove preexisting field from struct dive_tableGravatar Berthold Stoeger
Dives are now in all cases imported via distinct dive_tables. Therefore the "preexisting" marker is useless. Remove. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06Import: pass a dive table to process_imported_dives()Gravatar Berthold Stoeger
Dives were directly imported into the global dive table and then merged in process_imported_dives(). Make this interface more flexible, by passing an independent dive table. The dive table of the to-be-imported dives will be sorted and merged. Then each dive is inserted in a one-by-one manner to into the global dive table. This actually introduces (at least) two functional changes: 1) If a new dive spans two old dives, it will only be merged to the first dive. But this seems like a pathological case, which is of dubious value anyway. 2) Dives unrelated to the import will not be merged. The old code would happily merge dives that were not even close to the newly imported dives. A surprising behavior. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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-09-23Core: split process_dives() in post-import and post-load versionsGravatar Berthold Stoeger
process_dives() is used to post-process the dive table after loading or importing. The first parameter states whether this was after load or import. Especially in the light of undo, load and import are fundamentally different things. Notably, that latter should be undo-able, whereas the former is not. Therefore, as a first step to make import undo-able, split the function in two versions and remove the first parameter. It turns out the the load-version is very light. It only sets the DC nicknames and sorts the dive-table. There seems to be no reason to merge dives. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-14Fix compilation problemGravatar Dirk Hohndel
Never commit a change you didn't test. Oh well. Sorry. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-14Add Q_OBJECT macro to two more classesGravatar Dirk Hohndel
These also showed up as concerns when creating translation strings. Adding them thankfully didn't create new strings, but not having them potentially leads to incorrect runtime behavior. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-04Desktop: buddies in the dive listGravatar Jan Mulder
As proposed in RFC #1587, now also alllow buddies to be shown in the divelist. Fixes: #1587 Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-09-01Cleanup: make DiveTripModel a global objectGravatar Berthold Stoeger
DiveTripModel (the model describing the dive-list) was destroyed and recreated on every reset of the list. This seems excessive. Instead - in analogy to most other models - make it a single global object. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-31Filter: sort filter items in FilterModelBase::updateList()Gravatar Berthold Stoeger
All callers of FilterModelBase::updateList() sorted the items (except the last one). Thus we can do the sorting inside the function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-31Filter: Make FilterModelBase a proper Qt model (mostly)Gravatar Berthold Stoeger
Since FilterModelBase now contains complex data (counts and checked), we might just as well make it a full model and keep track of the name as well. I.e. do not derive from QStringListModel but from QAbstractListModel and add the name to the item structure. Implement proper reset / add / rename semantics. This is overkill at the moment, as after all any modification the model will be reset, but ultimately it will allow us to be smarter and only update rows when needed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-31Zero initialize deco state structGravatar Robert C. Helling
Valgrind found use of some uninitialized variable (probably ds->gf_low_pressure_this_dive ), see #1614. Zero is the correct value to start with. Lacking a working version of valgrind I cannot check this actually fixes the problem. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-08-28Filter: cache number of dives fulfilling filter rulesGravatar Berthold Stoeger
Currently, in FilterModelBase::data() the number of dives is recalculated. This happens for every mouse-over event! Calculate the number of dives only on recalculation and store the count in the items-struct. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-28Whitespace: make range based for loops consistent in filtermodels.cppGravatar Berthold Stoeger
Consistently use "for(item: items)" instead if "for(item : items)". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-28Filter: replace checked-state by structGravatar Berthold Stoeger
In the future, we might be smarter about the dive-counts and calculate them only once and incrementally (if e.g. new dives are added). Prepare for more complex caching by turning the checked boolean into a struct, which can then be extended by a count and other things (e.g. the name). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-25Merge branch 'filter8' of https://github.com/bstoeger/subsurfaceGravatar Dirk Hohndel
2018-08-23Cleanup: const-ify functions taking pointers to eventsGravatar Berthold Stoeger
This is another entry in the series to make more things "const-clean" with the ultimate goal of merge_dive() take const pointers. This concerns functions taking pointers to events and the fallout from making these const. The somewhat debatable part of this commit might be that get_next_event() is split in a two distinct (const and non-const) versions with different names, since C doesn't allow overloading. The linker should recognize that these functions are identical and remove one of them. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-23Cleanup: pass gasmix by valueGravatar Berthold Stoeger
In a previous commit, the get_gasmix_* functions were changed to return by value. For consistency, also pass gasmix by value. Note that on common 64-bit platforms struct gasmix is the size of a pointer [2 * 32 bit vs. 64 bit] and therefore uses the same space on the stack. On 32-bit platforms, the stack use is probably doubled, but in return a dereference is avoided. Supporting arbitrary gas-mixes (H2, Ar, ...) will be such an invasive change that going back to pointers is probably the least of our worries. This commit is a step in const-ifying input parameters (passing by value is the ultimate way of signaling that the input parameter will not be changed [unless there are references to said parameter]). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-16Filter: separate backend from frontend logicGravatar Berthold Stoeger
The filter code was an unholy intermixture of backend and frontend logic, which made it hard to access it from outside of the UI. Notably, it expected that Qt would call filterAcceptsRow on all rows. For trip-view, apparently the filter functions were called twice (once for filtering the trip, then for filtering the individual dives). Make the filtering explicit, by calling showDive() for all dives in MultiFilterSortModel::myInvalidate(), setting the hidden_by_filter flags accordingly and ultimately invalidating the filter. The UI code only accesses the hidden_by_filter flag set previously. The "justCleared" flag can then be removed, since accessing the filter does not have side effects. Moreover, there is no noticeable performance gain by returning out early. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-15qt-models: remove SettingsObjectWrapper and update qPref callsGravatar jan Iversen
remove use of SettingsObjectWrapper:: remove include of SettingsObjectWrapper.h use qPrefFoo:: for setters and getters replace prefs.foo with qPrefXYZ::foo() where feasible (this expands to the same code, but gives us more control over the variable). Signed-off-by: Jan Iversen <jani@apache.org>
2018-08-14Filter: break out showDive() function from filterAcceptsRow()Gravatar Berthold Stoeger
To make dive-filtering accessible from other parts of the code, break out the actual dive-filtering code into a function that takes a pointer-to-dive instead of QModelIndex. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-14Filter: constify doFilter() argumentGravatar Berthold Stoeger
Conceptually, the doFilter() functions shouldn't modify the dive they test. Therefore, make the argument const. To do this, constify the parameter of get_dive_location(), which likewise seems to be the right thing to do. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-14Filter: remove unused parameters from doFilter functionsGravatar Berthold Stoeger
Change the signature from of the virtual doFilter() functions from bool doFilter(struct dive *d, QModelIndex&, QAbstractItemModel*) const; to bool LocationFilterModel::doFilter(struct dive *d) const; as the QModelIndex and QAbstractItemModel parameters were not used. This makes this functions independent from Qt's model/view framework. This is in preparation for making the undo-machinery compatible with the filtering. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-08core: activate qPrefDivePlannerGravatar jan Iversen
remove DivePlanner from SettingsObjectWrapper and reference qPrefDivePlanner update files using SettingsObjectWrapper/DivePlanner to use qPrefDivePlanner this activated qPrefDivePlanner and removed the similar class from SettingsObjectWrapper. Signed-off-by: Jan Iversen <jani@apache.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-07-30Cleanup: remove DiveListView::fixMessyQtModelBehaviour()Gravatar Berthold Stoeger
The function DiveListView::fixMessyQtModelBehaviour() was used to expand the first columns of dive-trips in the dive-list view. This function was called everytime that the dive-list was modified. It is kind of ludicrous that external callers would have to tell the DiveListView, when it has to update its column headers. Instead, place this functionality in the overriden reset() and rowsInserted() functions, as these are the only ways that rows can be added. Change the DiveTripModel to use the proper beginResetModel()/endResetModel() pair instead of the previous full deletion and full repopulation using the beginRemoveRows()/ endRemoveRows() and beginInsertRows()/endInsertRows(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-28Dive media: put duration on video thumbnailsGravatar Berthold Stoeger
On the profile, the run-length of the videos is visualized by a bar. Add the same information to video-thumbnails in the dive-photo-tab. Though in this case, render it as text on top of the thumbnails. Fixes #359 Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-27Dive list view: move column width logic back from DiveTripModelGravatar Berthold Stoeger
Conceptually, the width of the columns should probably reside in the view not the model. But much more severly, the old code didn't work: Columns were set in a DiveTripModel, which was deleted right away. Therefore, move the logic back to the DiveListView. Introduce a QVector<int> of the initial column widths, so that they can be erased from the setting if unchanged. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-23Dive video: paint duration-bar above thumbnail in profile plotGravatar Berthold Stoeger
Paint a rectangle on top of thumbnails indicating the run-time of the video. Use the z=100.0-101.0 range for painting the thumbnails, whereby the z-value increases uniformly from first to last thumbnail (sorted by timestamp). The duration-bars are placed at z-values midway between those of the thumbnails. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>