Commit graph

453 commits

Author SHA1 Message Date
Berthold Stoeger
66aeaddd0f Filter: cache number of dives fulfilling filter rules
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-28 05:03:59 -07:00
Berthold Stoeger
e3f8615054 Whitespace: make range based for loops consistent in filtermodels.cpp
Consistently use "for(item: items)" instead if "for(item : items)".

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-28 05:03:59 -07:00
Berthold Stoeger
ec586d0e0a Filter: replace checked-state by struct
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-28 05:03:59 -07:00
Dirk Hohndel
eaf1bdbe5f Merge branch 'filter8' of https://github.com/bstoeger/subsurface 2018-08-25 11:58:27 -07:00
Berthold Stoeger
605e1e19ed Cleanup: const-ify functions taking pointers to events
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-23 05:16:38 -07:00
Berthold Stoeger
360f07e453 Cleanup: pass gasmix by value
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-23 05:16:38 -07:00
Berthold Stoeger
979f81f409 Filter: separate backend from frontend logic
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-16 08:07:25 +02:00
jan Iversen
50c58b4065 qt-models: remove SettingsObjectWrapper and update qPref calls
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-15 16:11:39 -07:00
Berthold Stoeger
13fbca3f55 Filter: break out showDive() function from filterAcceptsRow()
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-14 14:16:25 -04:00
Berthold Stoeger
8a394b9db4 Filter: constify doFilter() argument
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-14 14:09:30 -04:00
Berthold Stoeger
fb47c15cd8 Filter: remove unused parameters from doFilter functions
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-14 13:03:33 -04:00
jan Iversen
21243ec4f7 core: activate qPrefDivePlanner
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-08 14:29:50 +02:00
Berthold Stoeger
1c4a859c8d Cleanup: remove all override modifiers
Commit df156a56c0 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-08-01 06:30:00 -07:00
Berthold Stoeger
df156a56c0 Cleanup: replace virtual by override where appropriate
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-31 11:02:34 +02:00
Berthold Stoeger
4bdd811f06 Cleanup: remove DiveListView::fixMessyQtModelBehaviour()
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-30 12:21:17 -07:00
Berthold Stoeger
a76433279e Dive media: put duration on video thumbnails
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-28 15:31:25 -07:00
Berthold Stoeger
079b99135a Dive list view: move column width logic back from DiveTripModel
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-27 09:08:42 -07:00
Berthold Stoeger
b3feaa80e2 Dive video: paint duration-bar above thumbnail in profile plot
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>
2018-07-23 15:58:55 -07:00
Berthold Stoeger
7dd49acf4b Cleanup: remove DiveItem::icon_names member array
Each DiveItem (which is a wrapper around diveId with some virtual
functions), had a member icon_names, which is an array of
four QStrings. These were not used anywhere and must be an obscure
oversight and was probably planned as a static cons array?.
In any case, remove it.

There *was* a function-local analogous icon_names array in
DiveItem::data() though. This array would initialize four
QStrings from C-string literals on every invocation. Make
this array static, local to the translation unit and use
the QStringLiteral macro to construct the QString object at
compile-time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-23 17:05:15 +03:00
Berthold Stoeger
c5f66c5538 Dive media: transport dive-id in drag'n'drop events
9efb56e2d4 introduced rather complex
logic for picture drag'n'drop events onto the profile. Among other
things, the code had to check whether the picture actually belongs
to the displayed dive.

This can be simplified by transporting the dive-id in the drag'n'drop
event structure. The flow goes like this:
DivePictureModel--(1)-->DivePictureWidget--(2)-->ProfileWidget

For (1), we can use the Qt::UserRole role. This was used to transport
the picture-offset, but this is not needed anymore since ProfileWidget
was decoupled from DivePictureModel.

For (2), we simply replace the "position" value, which was never used.
Why would the receiver care which pixel was pressed in the media-tab?

This commit also contains a minor cleanup in DivePictureWidget:
QListView::mousePressEvent(event) was called in both branches of an
if and can therefore be removed from the if. This is so trivial,
that it doesn't warrant its own commit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-18 09:06:37 -07:00
Stefan Fuchs
669277d490 UI change of "images"/"photo" to "media" or "media files"
This changes the above mentioned terms everywhere in the UI to
reflect the fact that Subsurface now also supports video files on top
of image files.

Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2018-07-15 09:38:12 -07:00
Berthold Stoeger
9efb56e2d4 Dive pictures: don't update all images on drag&drop to profile
Gracefully handle drag & drop to the profile, which changes the
offset of the pictures. To do this, keep the pictures in the
DivePictureModel and the ProfileWidget2 sorted by offset and
re-arrange if needed to keep the list sorted. This needs some
code reshuffling.

Introduce a helper-function that moves ranges in arrays.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-07-13 17:07:42 -07:00
Stefan Fuchs
c6db1b12f8 Fix dive mode drop-down in planner for re-planned dive
Also populate the DiveTypeSelectionModel with values for re-planned dive.

Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2018-07-13 11:26:28 -07:00
Berthold Stoeger
3d7865cf26 Dive pictures: detach ProfileWidget2 from DivePictureModel
As long as ProfileWidget2 and DivePictureModel showed the same set of
pictures and any change would lead to a full recalculation of the set,
it made sense to let ProfileWidget2 use DivePictureModel's data.

Recently, keeping the two lists in sync become more and more of a
burden. Therefore, disconnect ProfileWidget2 and DivePictureModel. This
will lead to some code-duplication and perhaps a temporary drop in
UI-performance, but in the end the code is distinctly simpler and also
more flexible.

Thus, for example the DivePhotoTab could be changed to support headings
without having to touch ProfileWidget2 at all.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-08 11:00:44 -07:00
Berthold Stoeger
0646b41275 Dive pictures: find moved pictures based on filename
Users might have edited their pictures. Therefore, instead of identifying
pictures by the hash of the file-content, use the file path. The match
between original and new filename is graded by a score. Currently, this
is the number of path components that match, starting from the filename.
Camparison is case-insensitive.

After having identified the matching images, write the caches so that they
are saved even if the user doesn't cleanly quit the application.

Since the new code uses significantly less resources, it can be run in a
single background thread. Thus, the multi-threading can be simplified.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-04 02:27:36 +08:00
Berthold Stoeger
37c6fe44e4 Dive pictures: remove unnecessary check for no dives
This fixes a bug introduced in fbe1144eaf:
For an empty log, in DivePictureModel::updateDivePictures()
beginResetModel() would be called without a corresponding endResetModel().

It is unclear whether this can ever be hit, because in the no-dives
case, at least in the desktop version no profile is shown.
Note, that this makes the check double-unnecessary.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-03 01:55:47 +08:00
Berthold Stoeger
bf60d29e99 Dive pictures: adjust rowDDEnd and rowDDStart on picture deletion
In DivePictureModel, rowDDEnd and rowDDStart specify the range of
pictures in the profile plot. Obviously, these have to be adjusted
when pictures are deleted.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-29 13:30:48 +08:00
Dirk Hohndel
dde2049027 QML UI: correctly update the model
In order to trigger the redraw of an edited dive we need to make sure
the model realizes that it has been updated. So far the only way to make
sure this happens reliably appears to be to remove the item and
re-insert it. Seems weird, but with this the bug of not redrawing the
profile after an edit appears fixed.

Fixes #1419

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-06-25 20:20:35 +08:00
Berthold Stoeger
879cb73b8b Localization: remove gettextFromC::instance()
There were a handfull instances of the kind
1) gettextFromC::instance()->tr(...)
2) gettextFromC::instance()->trGettext(...)

1) is pointless, as tr is a static function.

All instances of 2) were likewise pointless, because trGettext()
returns a C-string, which was then immediately converted to a
QString.

Thus, replace both constructs by gettextFromC::tr(...).

After this change there was only one user of gettextFromC::instance()
left, viz. the C-interface funtion trGettext(). Therefore, remove
gettextFromC::instance() and do all the caching / translating
directly in the global trGettext().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-24 20:31:14 +02:00
Robert C. Helling
8406cbf187 Fix interpretation of dive mode changes upon replan
... by taking into acount that dive planner points refer
to the sement before the waypoint (while change mode
events are concerned with the future of a waypoint).

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-06-24 09:35:55 +02:00
Robert C. Helling
068b4c65bd When adding new waypoints, use previous setpoint.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-06-24 09:35:55 +02:00
Robert C. Helling
0f77d73df2 Planner: Change segment setpoint according to divemode
When making a segment non-CCR, its setpoint should be 0.
OTOH, when it becomes CCR, use the default setpoint
(or should we try to find the last previous setpoint?)

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-06-24 09:35:55 +02:00
Robert C. Helling
c64e4b159f Copy divemode to Replan
this needs copying the divemode from the dive to the plan.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-06-24 09:35:55 +02:00
Lubomir I. Ivanov
06a870c232 equipment: sanitize 'ws_info' loop limits
Instead of a constant or a macro for the maximum
number of 'ws_info' elements the 100 literal was used.

Define MAX_WS_INFO in dive.h and use it everywhere.

Also clamp loops that iterate `ws_info' to MAX_WS_INFO.
Prevents potential out-of-bounds reading, similarly to
the previous commit about 'tank_info'.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-06-20 09:30:58 +09:00
Lubomir I. Ivanov
769aca9e95 equipment: sanitize 'tank_info' loop limits
In a number of places the global 'tank_info' array
is being iterated based on a 'tank_info[idx].name != NULL'
condition.

This is dangerous because if the user has added a lot of tanks,
such loops can reach 'tank_info[MAX_TANK_INFO]'. This is an
out of bounds read and if the 'name' pointer there happens to be
non-NULL, passing that address to a peace of code that tries
to read it (like strlen()) would either SIGSEGV or have undefined
behavior.

Clamp all loops that iterate 'tank_info' to MAX_TANK_INFO.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-06-20 09:30:58 +09:00
Stefan Fuchs
c953aadcf8 Change from gettextFromC::instance()->tr() to gettextFromC::tr();
Code cleanup.

Suggested-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2018-06-18 07:42:39 +02:00
Stefan Fuchs
88e6ba2f61 Use correct "tr" call for translating dive mode names
Correctly use gettextFromC::instance()->tr(); instead of a simple
tr(); to translate the dive mode names.
This goes on top of 0bc9edf855
and finally makes the whole thing work.

Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2018-06-18 07:42:39 +02:00
Berthold Stoeger
1f654050fa Dive computers: turn QMultiMap into sorted vector
The list of known dive computers was stored in a multi-map indexed
by the device name. Turn this into a sorted QVector. Thus, no
map-to-list conversion is needed in the device editing dialog,
which distinctly simplifies the code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-17 06:53:13 +09:00
Stefan Fuchs
0bc9edf855 Fix an error around translation of dive modes in the UI
This fixes an mistake introduced in
3d1072f886

Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2018-06-17 06:36:20 +09:00
Berthold Stoeger
36b9e5e31e Cleanup: fold core/helpers.h into core/qthelper.h
helpers.h included qthelper.h and all functions declared in helpers.h
were defined in qthelper.h. Therefore fold the former into the latter,
since the split seems completely arbitrary.

While doing so, change the return-type of get_dc_nichname from
"const QString" to "QString".

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-04 08:50:10 -07:00
jan Iversen
b0e48a5e8f qt-models: Change Q_UNUSED to no parameter name
C++ permits use of parameters without name, which signals unused

Signed-off-by: Jan Iversen <jani@apache.org>
2018-05-21 12:48:04 -07:00
Berthold Stoeger
f47f2773fd Dive pictures: don't repopulate DivePictureModel on deletion
On deletion of a single or multiple pictures, the whole DivePictureModel
was repopulated, which was clearly visible in the UI, owing to the
reconstructing of all images in the profile plot.

To avoid this vexing behavior, implement proper deletion routines in
DivePictureModel and ProfileWidget2. Since this needs sensible erase()
semantics the QList<PictureEntry> member of DivePictureModel was
replaced by a QVector. A QVector should be the default anyway, unless
there are very specific reasons to use a QList (which actually is
a deque, not a classical linked list).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-21 22:17:28 +03:00
Berthold Stoeger
3c0c1801cd Dive pictures: change removePicture() interface
The function removePicture() had a flag "last", which would indicate
that the called had finished removing pictures. Only then would
the model be recalculated.

This is a strange interface and, matter of fact, the caller was buggy:
if the last picture to be removed didn't have a proper url, removePicture()
was never called with "last" being set.

Change the interface to take a list of pictures to be deleted. This
will allow us to make picture deletion smarter in follow-up commits.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-21 22:17:28 +03:00
Berthold Stoeger
fbe1144eaf Dive pictures: use modelReset signal when reseting picture list
In the old code a combination of removeRows()/insertRows() was used
to signal a model reset.

Replace this by a single, modelReset signal. This saves a call to
plotPictures() and will allow us to be smarter in the future,
when removing pictures.

Reset-model and remove-items are semantically different.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-21 22:17:28 +03:00
jan Iversen
a181020b19 mobile: add "Copy log to clipboard" button
on iOS it is practically impossible to copy the App log
to e.g. a mail! in iOS 11 the log file is stored within
the subsurface container and you first need to copy (actually
using the clipboard) out from there to the "normal" document
shared space, before it can be used.

At least iOS users (and I believe Android users) are not really
used to work with files, so the process is not easy to document
in an understandable way.

The alternative is to provide a button, which simply puts the
log on the general clipboard, allowing it to be pasted in a
multitud of applications.

Signed-off-by: Jan Iversen <jani@apache.org>
2018-05-18 12:43:15 -07:00
Robert C. Helling
b8c94cad69 Planner: Add combo box for dive mode selection
I am not really sure what I am doing here but I copied
code from the gas selection.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-05-14 23:47:00 +03:00
Robert C. Helling
969dfee9ec Rename enum dive_comp_type to divemode_t
...as the usuage is not anymore about a computer but
a momentary dive mode. Rename the end indicator as well.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-05-14 23:47:00 +03:00
Robert C. Helling
69de9d8f98 Add planner infra structure for bailout
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-05-14 23:47:00 +03:00
Dirk Hohndel
ea83b5ed37 Core: remove dive.h from files that don't need it
Of course, quite a few of them indirectly get it through other header
files.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-05-14 10:13:39 -07:00
Dirk Hohndel
d577467f97 Core: introduce new subsurface-string header
First small step to shrinking dive.h.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-05-14 10:13:39 -07:00