Commit graph

44 commits

Author SHA1 Message Date
Robert C. Helling
79df0ded3c Core: remove variable name conflict
Addresses LGTM.com issue.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-03-18 19:40:32 -07:00
Berthold Stoeger
8a8063c1cd Profile: add "synchronous" mode for picture plotting
The thumbnails were fetched in the background to achieve a
snappier UI. The problem with that is that on LaTeX etc.
export only placeholder thumbnails were shown.

Therefore, implement a synchronous mode. This only tries
to fetch cached thumbnails or calculate thumbnails for
images. Videos and remote files are not supported.

Fixes #1963

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-02-07 16:06:43 +01:00
Berthold Stoeger
fce42d4858 Dive media: Extract thumbnails from videos with ffmpeg
Extract thumbnails using ffmpeg.
Behavior is controlled by three new preferences fields:
 - extract_video_thumbnails (bool): if true, thumbnails are calculated.
 - extract_video_thumbnail_position (int 0..100): position in video
   where thumbnail is fetched.
 - ffmpeg_executable (string): path of ffmpeg executable.

If ffmpeg refuses to start, extract_video_thumbnails is set to false
to avoid unnecessary churn.

Video thumbnails are marked by an overlay.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-28 15:31:25 -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
c742885984 Dive media: prepare for video-thumbnails
Video thumbnails are more complex than simple picture thumbnails.
We store a duration and might want to store multiple images.

Therefore, refactor the thumbnailing in imagedownloader.cpp. Move
the thumbnail-writing down in the call chain to where the thumbnails
are created, since we have more information there (i.e. whether we
could parse the file but not extract an image, etc.).

Split the write-to-cache function into three versions:
  - pictures
  - videos
  - unknown

Define the video-thumbnail on-disk format as
  - uint32  MEDIATYPE_VIDEO
  - uint32  duration of video in seconds
  - uint32  number of pictures
  for each picture:
	- uint32  offset in msec from begining of video
	- QImage  frame

Currently, we write 0 pictures. This will be filled in subsequent commits.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-23 15:58:55 -07:00
Berthold Stoeger
a741f505ca Dive pictures: differentiate between IO-error and unknown format
Show different images for IO-error and unknow file format.

Use file-extensions to recognize video files if we couldn't
parse them.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-09 09:12:58 -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
b28dba6087 Dive pictures: Recognize video files
When generating thumbnails, test for video files. If it is, use
a dummy-thumbnail. Write only the type (video), but no image to
the thumbnail cache, for forward-compatibility.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-08 07:41:15 -07:00
Berthold Stoeger
f3ef38ca0d Dive pictures: remove hashes
In the last commits, the canonical-to-local filename map was made
independent from the image hashes and the location of moved images
was based on filename not hashes. The hashes are now in principle
unused (except for conversion of old-style local filename lookups).

Therefore, remove the hashes in this commit. This makes addition
of images distinctly faster.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-04 02:27:36 +08:00
Berthold Stoeger
08962cb38d Dive pictures: index local file name by canonical filname
The connection canonical filename to local filename was done via
two maps:
  1) canonical filename -> hash
  2) hash -> local filename
But the local filename was always queried from the canonical filename.
Therefore, directly index the former with the latter.

On startup, convert the old map to the new one.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-04 02:27:36 +08:00
Berthold Stoeger
1a5e54e5eb Dive pictures: render icons with white instead of transparent background
The SVG icons for failed / still-loading pictures were rendered with an
alpha channel. This lead to strange behavior when hovering over the
icon in the profile plot: When hitting a "hole" the icon would be
minimized again.

Therefore, render the SVGs onto a white background.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-28 21:58:29 +08:00
Berthold Stoeger
c65617661a Dive pictures: fix loading of remote images without local version
Owing to the recent churn in imagedownloader.cpp, some of the
code was bogus.

Notably, in f60343eebb the code
was changed such that always the local filename was used to access
the images. Yet, the old code remained, which after failure tried
again to access the local picture. This second access can obviously
be removed completely.

More seriously, after failing to load the local version, no
attempt was made to fetch the image via canonical filename. This
could produce the following sequence of events:
  - Import remote image
  - Delete thumbnail and local cache of image
  - Image loading would fail

Therefore, first try to load using local file-location. If
that fails, load using the canonical file-location. To do
so, split the file-access code in two functions. The code
should now be distinctly easier to follow.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-22 00:26:02 +03:00
Berthold Stoeger
4c19d3da1d Dive pictures: Make failure of loading images less noisy
For debug reasons, failure to load the original image was spilled
to the console, even if the local file was then found.

Only print a message, when also the local image failed loading.
This needed a bit of code reshuffling. To know when to print a
failed-loading message, the URL is now checked at the Thumbnailer
level, not the ImageDownloader level. The ImageDownloader is
passed the URL and the original filename (if different). The
image is loaded from the URL, but the signals send the original
filename, so that the thumbnail can be associated to the proper
image.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-13 08:35:23 -07:00
Berthold Stoeger
308e079ad6 Dive pictures: automatically recalculate thumbnails
If a thumbnail and the original picture can be accessed and the
modification date of the thumbnail is before the modification date
of the picture, recalculate the thumbnail.

This causes more disk access and might give strange effects for
picture files with messed up file timestamps (i.e. lying in the
future) or messed up computer clocks (i.e. running in the past).
Therefore, add a preference option to disable the new behavior.
Default is set to enabled.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-27 23:08:12 +03:00
Berthold Stoeger
23d38a982d Dive pictures: give user option to recalculate thumbnails
Even though hashes of image contents are calculated, the hashes are
not compared to actual file contents in routine-operation. Therefore
give the user the option to recalculate thumbnails, should they have
edited the picture.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-27 23:08:12 +03:00
Berthold Stoeger
80224a98b1 Dive pictures: Derive thumbnail file from picture filename
Since commit 6618c9ebfc, thumbnails
are saved in individual files. The filename was simply the picture-hash.
In a mailing-list discussion it turned out that in the future we might
not hash images or change the hash. Therefore, derive the thumbnail
filename from the image filename, using the SHA1 algorithm.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-26 09:24:28 -07:00
Berthold Stoeger
b34eeeaba2 Cleanup: remove code related to pictures in the cloud-repository
Storing pictures in the cloud never came to be, so remove the code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-26 09:23:49 -07:00
Berthold Stoeger
afe8843509 Dive pictures: don't attempt reading the same image twice
If loading of an image failed, we tried to see if we find a
canonical filename in the cache. There's no point in rereading
the picture if the canonical and the original filename are
the same.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-16 15:20:30 +03:00
Berthold Stoeger
c3c2c2f606 Dive pictures: Don't enter infinity loop on invalid pictures
The recently committed refactoring of the dive-picture code introduced
a severe bug:

If an image couldn't be loaded from disk owing to an invalid file, the
filename was interpreted as an url and loaded in the background. This
succeeded, because the file actually exists. After download, the file
would then still be invalid and the whole thing restarted, leading to
an infinity loop.

To fix this, do two things:

1) Don't even try to download local files.
2) If interpreting a downloaded file fails, don't try the downloading
business again.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-16 02:01:26 +03:00
Berthold Stoeger
d33e3b22fc Dive pictures: refactor image downloader
Instead of generating one ImageDownloader object per image to be
downloaded and running every image download in a separate worker
thread, use one global ImageDownloader object owned by the UI thread.

The images are downloaded using event based IO (as probably was the
intention of the QNetworkManager class).

User-visible change: after download from the internet, the thumbnail
is shown without having to change dives.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-13 13:52:35 -07:00
Berthold Stoeger
19fa2966ef Dive pictures: Import camera icon
Import a camera icon from the KDE breeze theme, which is licensed
under the LGPL. Use this icon to display not-yet-loaded images
in the photos tab and the profile.

Source: https://github.com/KDE/breeze-icons

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-13 13:52:35 -07:00
Berthold Stoeger
b450c155fd Dive pictures: Move thumbnail-size to Thumbnailer class
The size of the to-be-created thumbnails was passed from DivePictureModel
to Thumbnailer. This became more and more bothersome, because the size
had to be stored with the request. Calling from Thumbnailer into
DivePictureModel was not an option, since this is not linked to all tests.
Therefore, move these functions to the Thumbnailer class.

Since the maximum thumbnail size is now known to the thumbnailer, the
dummy and failure images can be precalculated, which makes switching
between dives faster.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-13 13:52:35 -07:00
Berthold Stoeger
3967b1fd4d Dive pictures: Introduce thumbnailer class
Create a new class, which performs all thumbnailing code.
This is mostly code reshuffling. Thumbnails are extracted
either from a cache or thumbnail calculation is started in
a worker thread.

Since getHashedImage() is called from a worker thread it
makes no sense to call subfunctions in yet another worker
thread. Remove these calls.

In contrast to the previous code, on error the background
thread produces a failure image, but it is not yet shown.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-13 13:52:35 -07:00
Berthold Stoeger
f60343eebb Dive pictures: replace picture struct by QString
In imagedownloader.cpp the only thing we need from the picture struct
is the filename. Therefore, use QStrings instead of the picture struct.
This simplifies memory management.

Remove the clone_picture() function, which is not needed anymore.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-13 13:52:35 -07:00
Berthold Stoeger
5d372cfda3 Dive pictures: turn SHashedImage class into getHashedImage() function
SHashedImage was a subclass of QImage, which fetched the image according
to the filename hashes. Turn this into a function, as this is much more
idiomatic and flexible.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-13 13:52:35 -07:00
Berthold Stoeger
d9df8c3f47 Debug: Error reporting for SHashedImage loading
Overwrite QImage::load() in SHashedImage so that we can perform better
error reporting.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-04-01 15:59:46 +03:00
Berthold Stoeger
376b737891 Debug: sprinkle debug messages in thumbnailing code
To ease trouble-shooting of the picture thumbnailer add a number
of debug- and info-messages.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-04-01 15:59:46 +03:00
Berthold Stoeger
bdc470a80e Cleanup: Remove hash field from picture-structure
The hash field in the picture-structure was in principle non-operational.
It was set on loading, but never actually changed. The authoritative
hash comes from the filename->hash map.

Therefore, make this explicit by removing the hash field from the
picture structure.

Instead of filling the picture structure on loading, add the
hash directly to the filename->hash map. This is done in the
register_hash() function, which does not overwrite old entries.
I.e. the local hash has priority over the save-file. This
policy might be refined in the future.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
f5eafe2a71 Cleanup: Fold add_hash() call into learnHash() function
learnHash() was always called in conjunction with add_hash(). The
pattern was that a local filename and a hash were connected in
the hash-to-filename and the filename-to-hash maps. Then, the
original picture-filename or url were registered in the filename-to-hash
map.

This commit changes learnHash() to take three parameters (original-filename,
local-filename and hash) and do all of the above. The new code is
simpler because no dummy picture struct has to be generated in
DiveListView::loadImageFromURL().

The tests were extended to check for all hash<->filename associations.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
a0d02bacf3 Cleanup: remove updateHash() function
updateHash() and hashPicture() did the same thing, with the exception
that hashPicture() marked the dive list as changed if a hash changed.
This seems like a good idea in any case, therefore always use
hashPicture().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
eaff0ddee7 core/imagedownloader.cpp: Use signal to exit eventloop
Don't do busy-waiting.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
907c07ce50 core/imagedownloader.cpp: Use implicit default constructor of QImage
No point in move-constructing from a different default constructed
QImage.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
117f4a0d7d core/imagedownloader.cpp: remove recursion
If loading from hash failed in the saveImage() slot(!) it would
recurse into loadFromUrl(), which would generate a new network
reply. Very scary and a (small) wonder that it worked.

Let's try to make this all more explicit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
54d56a74aa core/imagedownloader.cpp: Make the manager object local to load()
The QNetworkAccessManager is only used in the load() function. No
point in it being a subobject.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
2803b7d385 core/imagedownloader.cpp: Simplify deletion of objects
1) Destroying the QNetworkManager seems like a bug: this was a
subobject of ImageDonwloader. It's mysterious how this didn't
crash.

2) Instead of calling deleteLater() on the reply object, simply
delete it after completion.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
c1cd2e0f02 core/imagedownloader.cpp: Fix memory leak
A cloned picture struct would not be freed if the filename was already
in the queued-for-download set.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-03-05 18:04:57 +02:00
Berthold Stoeger
fe133e2cca Cleanup: unserialize loading of pictures
The images to load are kept in a set to avoid multiple loading of
the same picture. The set was protected with a mutex.

Problem: the mutex was not released before loading the picture,
effectively serializing the loading of pictures.

Therefore unlock the mutex once the set is updated.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-02-07 09:44:43 +01:00
Berthold Stoeger
9986ce25d7 Cleanup: Make local helpers and variables of static linkage
In core/imagedownloader.cpp the helpers cloudImageUrl() and loadPicture()
are made of static linkage.

The global variables queuedPictures and pictureQueueMutex were moved
into the loadPicture() function, because they are used only there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-02-07 09:44:43 +01:00
Jan Mulder
13305e7745 cleanup: Uninitialized scalar field
CID 208303

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2017-12-29 09:14:20 -08:00
Dirk Hohndel
b368ecd5aa Add SPDX header to remaining core files
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-04-29 13:32:55 -07:00
Robert C. Helling
10b8bda662 Fix picture hashing logic for pictures on the web.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2016-12-30 19:43:00 +01:00
Robert C. Helling
c2c0cb48d2 Only attempt to download each picture once
Otherwise we keep downloading the same image multiple times instead
of new images.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2016-04-30 16:18:44 -07:00
Robert C. Helling
2e6588dc0e Protect access to image hash dictionaries with lock
Otherwise we step on our own feet when downloading several images,
like after import from divelogs.de with many linked images.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2016-04-29 09:08:20 -07:00
Dirk Hohndel
7be962bfc2 Move subsurface-core to core and qt-mobile to mobile-widgets
Having subsurface-core as a directory name really messes with
autocomplete and is obviously redundant. Simmilarly, qt-mobile caused an
autocomplete conflict and also was inconsistent with the desktop-widget
name for the directory containing the "other" UI.

And while cleaning up the resulting change in the path name for include
files, I decided to clean up those even more to make them consistent
overall.

This could have been handled in more commits, but since this requires a
make clean before the build, it seemed more sensible to do it all in one.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2016-04-04 22:33:58 -07:00
Renamed from subsurface-core/imagedownloader.cpp (Browse further)