diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-12-11 22:30:57 +0100 |
---|---|---|
committer | Robert C. Helling <helling@atdotde.de> | 2018-12-13 08:11:22 +0100 |
commit | 3cdc2661d2a2417e557042abe1a0d9e5107822eb (patch) | |
tree | 1862bc03bac773087093663e76372b72fc08603f | |
parent | 09a9fa1ae51bbca3246fb256f5acc2ace0b2b148 (diff) | |
download | subsurface-3cdc2661d2a2417e557042abe1a0d9e5107822eb.tar.gz |
Dive media: add media to closest dive
Currently, when selecting "Load media files even if time does not
match the dive time", the media are added to *all* selected dives.
Instead add it to the closest dive.
This seems like the less surprising behavior. Of course now if the
user really wants to add a media file to multiple dives, they will
have to do it manually.
To avoid a messy interface, this is solved by moving the iterate-
over-selected-dives loop to the core. Thus, a helper-function can
be made local to its translation unit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/dive.c | 61 | ||||
-rw-r--r-- | core/dive.h | 3 | ||||
-rw-r--r-- | desktop-widgets/divelistview.cpp | 11 | ||||
-rw-r--r-- | tests/testpicture.cpp | 6 |
4 files changed, 57 insertions, 24 deletions
diff --git a/core/dive.c b/core/dive.c index 47143aaa3..f37b42a0b 100644 --- a/core/dive.c +++ b/core/dive.c @@ -4004,20 +4004,51 @@ static bool new_picture_for_dive(struct dive *d, const char *filename) return true; } +/* Return distance of timestamp to time of dive. Result is always positive, 0 means during dive. */ +static timestamp_t time_from_dive(const struct dive *d, timestamp_t timestamp) +{ + timestamp_t end_time = dive_endtime(d); + if (timestamp < d->when) + return d->when - timestamp; + else if (timestamp > end_time) + return timestamp - end_time; + else + return 0; +} + // only add pictures that have timestamps between 30 minutes before the dive and // 30 minutes after the dive ends #define D30MIN (30 * 60) -bool dive_check_picture_time(const struct dive *d, int shift_time, timestamp_t timestamp) +static bool dive_check_picture_time(const struct dive *d, timestamp_t timestamp) { - offset_t offset; - if (timestamp) { - offset.seconds = timestamp - d->when + shift_time; - if (offset.seconds > -D30MIN && offset.seconds < dive_totaltime(d) + D30MIN) { - // this picture belongs to this dive - return true; + return time_from_dive(d, timestamp) < D30MIN; +} + +/* Return dive closest selected dive to given timestamp or NULL if no dives are selected. */ +static struct dive *nearest_selected_dive(timestamp_t timestamp) +{ + struct dive *d, *res = NULL; + int i; + timestamp_t offset, min = 0; + + for_each_dive(i, d) { + if (!d->selected) + continue; + offset = time_from_dive(d, timestamp); + if (!res || offset < min) { + res = d; + min = offset; } + + /* We suppose that dives are sorted chronologically. Thus + * if the offset starts to increase, we can end. This ignores + * pathological cases such as overlapping dives. In such a + * case the user will have to add pictures manually. + */ + if (offset == 0 || offset > min) + break; } - return false; + return res; } bool picture_check_valid_time(timestamp_t timestamp, int shift_time) @@ -4026,18 +4057,26 @@ bool picture_check_valid_time(timestamp_t timestamp, int shift_time) struct dive *dive; for_each_dive (i, dive) - if (dive->selected && dive_check_picture_time(dive, shift_time, timestamp)) + if (dive->selected && dive_check_picture_time(dive, timestamp + shift_time)) return true; return false; } -void dive_create_picture(struct dive *dive, const char *filename, int shift_time, bool match_all) +void create_picture(const char *filename, int shift_time, bool match_all) { struct metadata metadata; + struct dive *dive; + timestamp_t timestamp; + get_metadata(filename, &metadata); + timestamp = metadata.timestamp + shift_time; + dive = nearest_selected_dive(timestamp); + + if (!dive) + return; if (!new_picture_for_dive(dive, filename)) return; - if (!match_all && !dive_check_picture_time(dive, shift_time, metadata.timestamp)) + if (!match_all && !dive_check_picture_time(dive, timestamp)) return; struct picture *picture = alloc_picture(); diff --git a/core/dive.h b/core/dive.h index 92bb1bb33..19c39214f 100644 --- a/core/dive.h +++ b/core/dive.h @@ -376,8 +376,7 @@ struct picture { extern struct picture *alloc_picture(); extern void free_picture(struct picture *picture); -extern bool dive_check_picture_time(const struct dive *d, int shift_time, timestamp_t timestamp); -extern void dive_create_picture(struct dive *d, const char *filename, int shift_time, bool match_all); +extern void create_picture(const char *filename, int shift_time, bool match_all); extern void dive_add_picture(struct dive *d, struct picture *newpic); extern bool dive_remove_picture(struct dive *d, const char *filename); extern unsigned int dive_get_picture_count(struct dive *d); diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp index 804bf9b9b..9a9330473 100644 --- a/desktop-widgets/divelistview.cpp +++ b/desktop-widgets/divelistview.cpp @@ -969,15 +969,8 @@ void DiveListView::matchImagesToDives(QStringList fileNames) return; updateLastImageTimeOffset(shiftDialog.amount()); - Q_FOREACH (const QString &fileName, fileNames) { - int j = 0; - struct dive *dive; - for_each_dive (j, dive) { - if (!dive->selected) - continue; - dive_create_picture(dive, qPrintable(fileName), shiftDialog.amount(), shiftDialog.matchAll()); - } - } + for (const QString &fileName: fileNames) + create_picture(qPrintable(fileName), shiftDialog.amount(), shiftDialog.matchAll()); mark_divelist_changed(true); copy_dive(current_dive, &displayed_dive); diff --git a/tests/testpicture.cpp b/tests/testpicture.cpp index 695c965b0..a84925c72 100644 --- a/tests/testpicture.cpp +++ b/tests/testpicture.cpp @@ -25,13 +25,15 @@ void TestPicture::addPicture() QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test44.xml", &dive_table), 0); dive = get_dive(0); + // Pictures will be added to selected dives + dive->selected = true; QVERIFY(dive != NULL); pic1 = dive->picture_list; // So far no picture in dive QVERIFY(pic1 == NULL); - dive_create_picture(dive, SUBSURFACE_TEST_DATA "/dives/images/wreck.jpg", 0, false); - dive_create_picture(dive, SUBSURFACE_TEST_DATA "/dives/images/data_after_EOI.jpg", 0, false); + create_picture(SUBSURFACE_TEST_DATA "/dives/images/wreck.jpg", 0, false); + create_picture(SUBSURFACE_TEST_DATA "/dives/images/data_after_EOI.jpg", 0, false); pic1 = dive->picture_list; pic2 = pic1->next; // Now there are two picture2 |