2017-04-27 18:25:32 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2016-04-05 05:02:03 +00:00
|
|
|
#include "qt-models/divepicturemodel.h"
|
|
|
|
#include "core/metrics.h"
|
2020-04-10 07:42:14 +00:00
|
|
|
#include "core/divelist.h" // for mark_divelist_changed()
|
2020-05-01 11:43:52 +00:00
|
|
|
#include "core/dive.h"
|
2016-04-05 05:02:03 +00:00
|
|
|
#include "core/imagedownloader.h"
|
2020-04-10 07:42:14 +00:00
|
|
|
#include "core/picture.h"
|
2018-04-29 20:07:05 +00:00
|
|
|
#include "core/qthelper.h"
|
2015-05-29 17:42:57 +00:00
|
|
|
|
2018-03-10 13:15:50 +00:00
|
|
|
#include <QFileInfo>
|
2018-07-25 15:26:56 +00:00
|
|
|
#include <QPainter>
|
2015-05-29 17:42:57 +00:00
|
|
|
|
|
|
|
DivePictureModel *DivePictureModel::instance()
|
|
|
|
{
|
|
|
|
static DivePictureModel *self = new DivePictureModel();
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2018-06-30 09:36:37 +00:00
|
|
|
DivePictureModel::DivePictureModel() : zoomLevel(0.0)
|
2015-05-29 17:42:57 +00:00
|
|
|
{
|
2018-03-10 15:36:20 +00:00
|
|
|
connect(Thumbnailer::instance(), &Thumbnailer::thumbnailChanged,
|
|
|
|
this, &DivePictureModel::updateThumbnail, Qt::QueuedConnection);
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
|
2017-12-17 15:17:38 +00:00
|
|
|
void DivePictureModel::setZoomLevel(int level)
|
|
|
|
{
|
|
|
|
zoomLevel = level / 10.0;
|
|
|
|
// zoomLevel is bound by [-1.0 1.0], see comment below.
|
|
|
|
if (zoomLevel < -1.0)
|
|
|
|
zoomLevel = -1.0;
|
|
|
|
if (zoomLevel > 1.0)
|
|
|
|
zoomLevel = 1.0;
|
2018-04-11 04:56:46 +00:00
|
|
|
updateZoom();
|
2017-12-17 15:17:38 +00:00
|
|
|
layoutChanged();
|
|
|
|
}
|
|
|
|
|
2018-04-11 04:56:46 +00:00
|
|
|
void DivePictureModel::updateZoom()
|
2017-12-17 15:17:38 +00:00
|
|
|
{
|
2018-03-11 09:19:08 +00:00
|
|
|
size = Thumbnailer::thumbnailSize(zoomLevel);
|
2018-04-11 04:56:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DivePictureModel::updateThumbnails()
|
|
|
|
{
|
|
|
|
updateZoom();
|
2018-03-10 13:15:50 +00:00
|
|
|
for (PictureEntry &entry: pictures)
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
entry.image = Thumbnailer::instance()->fetchThumbnail(QString::fromStdString(entry.filename), false);
|
2017-12-17 15:17:38 +00:00
|
|
|
}
|
|
|
|
|
2015-05-29 17:42:57 +00:00
|
|
|
void DivePictureModel::updateDivePictures()
|
|
|
|
{
|
2018-05-18 18:33:01 +00:00
|
|
|
beginResetModel();
|
2017-12-09 23:07:46 +00:00
|
|
|
if (!pictures.isEmpty()) {
|
|
|
|
pictures.clear();
|
2018-03-10 13:15:50 +00:00
|
|
|
Thumbnailer::instance()->clearWorkQueue();
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
|
2017-12-03 08:19:26 +00:00
|
|
|
int i;
|
|
|
|
struct dive *dive;
|
|
|
|
for_each_dive (i, dive) {
|
|
|
|
if (dive->selected) {
|
2018-06-30 19:32:14 +00:00
|
|
|
int first = pictures.count();
|
2017-12-03 08:19:26 +00:00
|
|
|
FOR_EACH_PICTURE(dive)
|
2020-04-11 16:50:53 +00:00
|
|
|
pictures.push_back({ dive->id, picture->filename, {}, picture->offset.seconds, {.seconds = 0}});
|
2018-06-30 19:32:14 +00:00
|
|
|
|
|
|
|
// Sort pictures of this dive by offset.
|
|
|
|
// Thus, the list will be sorted by (diveId, offset).
|
|
|
|
std::sort(pictures.begin() + first, pictures.end(),
|
|
|
|
[](const PictureEntry &a, const PictureEntry &b) { return a.offsetSeconds < b.offsetSeconds; });
|
2017-12-03 08:19:26 +00:00
|
|
|
}
|
|
|
|
}
|
2017-12-17 15:17:38 +00:00
|
|
|
|
|
|
|
updateThumbnails();
|
2018-05-18 18:33:01 +00:00
|
|
|
endResetModel();
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
|
2018-05-21 15:53:42 +00:00
|
|
|
int DivePictureModel::columnCount(const QModelIndex&) const
|
2015-05-29 17:42:57 +00:00
|
|
|
{
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant DivePictureModel::data(const QModelIndex &index, int role) const
|
|
|
|
{
|
|
|
|
if (!index.isValid())
|
2020-04-10 07:50:57 +00:00
|
|
|
return QVariant();
|
2015-05-29 17:42:57 +00:00
|
|
|
|
2017-12-09 23:07:46 +00:00
|
|
|
const PictureEntry &entry = pictures.at(index.row());
|
2015-05-29 17:42:57 +00:00
|
|
|
if (index.column() == 0) {
|
|
|
|
switch (role) {
|
|
|
|
case Qt::ToolTipRole:
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
return QString::fromStdString(entry.filename);
|
2015-05-29 17:42:57 +00:00
|
|
|
case Qt::DecorationRole:
|
2020-04-10 07:50:57 +00:00
|
|
|
return entry.image.scaled(size, size, Qt::KeepAspectRatio);
|
2015-05-29 17:42:57 +00:00
|
|
|
case Qt::DisplayRole:
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
return QFileInfo(QString::fromStdString(entry.filename)).fileName();
|
2015-05-29 17:42:57 +00:00
|
|
|
case Qt::DisplayPropertyRole:
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
return QFileInfo(QString::fromStdString(entry.filename)).filePath();
|
2018-07-14 15:40:24 +00:00
|
|
|
case Qt::UserRole:
|
2020-04-10 07:50:57 +00:00
|
|
|
return entry.diveId;
|
2019-04-14 14:19:23 +00:00
|
|
|
case Qt::UserRole + 1:
|
2020-04-10 07:50:57 +00:00
|
|
|
return entry.offsetSeconds;
|
2019-04-14 14:19:23 +00:00
|
|
|
case Qt::UserRole + 2:
|
2020-04-10 07:50:57 +00:00
|
|
|
return entry.length.seconds;
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
} else if (index.column() == 1) {
|
|
|
|
switch (role) {
|
|
|
|
case Qt::DisplayRole:
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
return QString::fromStdString(entry.filename);
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-10 07:50:57 +00:00
|
|
|
return QVariant();
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
|
2018-05-18 19:57:18 +00:00
|
|
|
// Return true if we actually removed a picture
|
|
|
|
static bool removePictureFromSelectedDive(const char *fileUrl)
|
2015-05-29 17:42:57 +00:00
|
|
|
{
|
2017-12-11 20:40:06 +00:00
|
|
|
int i;
|
|
|
|
struct dive *dive;
|
|
|
|
for_each_dive (i, dive) {
|
2020-04-11 15:41:56 +00:00
|
|
|
if (dive->selected && remove_picture(&dive->pictures, fileUrl)) {
|
|
|
|
invalidate_dive_cache(dive);
|
2018-05-18 19:57:18 +00:00
|
|
|
return true;
|
2020-04-11 15:41:56 +00:00
|
|
|
}
|
2015-10-20 19:03:53 +00:00
|
|
|
}
|
2018-05-18 19:57:18 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
void DivePictureModel::removePictures(const QVector<QString> &fileUrlsIn)
|
2018-05-18 19:57:18 +00:00
|
|
|
{
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
// Transform vector of QStrings into vector of std::strings
|
|
|
|
std::vector<std::string> fileUrls;
|
|
|
|
fileUrls.reserve(fileUrlsIn.size());
|
|
|
|
std::transform(fileUrlsIn.begin(), fileUrlsIn.end(), std::back_inserter(fileUrls),
|
|
|
|
[] (const QString &s) { return s.toStdString(); });
|
|
|
|
|
2018-05-18 19:57:18 +00:00
|
|
|
bool removed = false;
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
for (const std::string &fileUrl: fileUrls)
|
|
|
|
removed |= removePictureFromSelectedDive(fileUrl.c_str());
|
2018-05-18 19:57:18 +00:00
|
|
|
if (!removed)
|
|
|
|
return;
|
|
|
|
copy_dive(current_dive, &displayed_dive);
|
|
|
|
mark_divelist_changed(true);
|
|
|
|
|
2018-05-19 19:18:39 +00:00
|
|
|
for (int i = 0; i < pictures.size(); ++i) {
|
|
|
|
// Find range [i j) of pictures to remove
|
|
|
|
if (std::find(fileUrls.begin(), fileUrls.end(), pictures[i].filename) == fileUrls.end())
|
|
|
|
continue;
|
|
|
|
int j;
|
|
|
|
for (j = i + 1; j < pictures.size(); ++j) {
|
|
|
|
if (std::find(fileUrls.begin(), fileUrls.end(), pictures[j].filename) == fileUrls.end())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Qt's model-interface is surprisingly idiosyncratic: you don't pass [first last), but [first last] ranges.
|
|
|
|
// For example, an empty list would be [0 -1].
|
|
|
|
beginRemoveRows(QModelIndex(), i, j - 1);
|
|
|
|
pictures.erase(pictures.begin() + i, pictures.begin() + j);
|
|
|
|
endRemoveRows();
|
|
|
|
}
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
emit picturesRemoved(fileUrlsIn);
|
2015-05-29 17:42:57 +00:00
|
|
|
}
|
|
|
|
|
2018-05-21 15:53:42 +00:00
|
|
|
int DivePictureModel::rowCount(const QModelIndex&) const
|
2015-05-29 17:42:57 +00:00
|
|
|
{
|
2017-12-09 23:07:46 +00:00
|
|
|
return pictures.count();
|
2015-08-06 13:14:18 +00:00
|
|
|
}
|
2018-03-10 15:36:20 +00:00
|
|
|
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
int DivePictureModel::findPictureId(const std::string &filename)
|
2018-05-01 10:35:18 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < pictures.size(); ++i)
|
|
|
|
if (pictures[i].filename == filename)
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-07-25 15:26:56 +00:00
|
|
|
static void addDurationToThumbnail(QImage &img, duration_t duration)
|
|
|
|
{
|
|
|
|
int seconds = duration.seconds;
|
|
|
|
if (seconds < 0)
|
|
|
|
return;
|
|
|
|
QString s = seconds >= 3600 ?
|
|
|
|
QStringLiteral("%1:%2:%3").arg(seconds / 3600, 2, 10, QChar('0'))
|
|
|
|
.arg((seconds % 3600) / 60, 2, 10, QChar('0'))
|
|
|
|
.arg(seconds % 60, 2, 10, QChar('0')) :
|
|
|
|
QStringLiteral("%1:%2").arg(seconds / 60, 2, 10, QChar('0'))
|
|
|
|
.arg(seconds % 60, 2, 10, QChar('0'));
|
|
|
|
|
|
|
|
QFont font(system_divelist_default_font, 30);
|
|
|
|
QFontMetrics metrics(font);
|
|
|
|
QSize size = metrics.size(Qt::TextSingleLine, s);
|
|
|
|
QSize imgSize = img.size();
|
|
|
|
int x = imgSize.width() - size.width();
|
|
|
|
int y = imgSize.height() - size.height() + metrics.descent();
|
|
|
|
QPainter painter(&img);
|
|
|
|
painter.setBrush(Qt::white);
|
|
|
|
painter.setPen(Qt::NoPen);
|
|
|
|
painter.drawRect(x, y, size.width(), size.height() - metrics.descent());
|
|
|
|
painter.setFont(font);
|
|
|
|
painter.setPen(Qt::black);
|
|
|
|
painter.drawText(x, imgSize.height(), s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DivePictureModel::updateThumbnail(QString filename, QImage thumbnail, duration_t duration)
|
2018-03-10 15:36:20 +00:00
|
|
|
{
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
int i = findPictureId(filename.toStdString());
|
2018-05-01 10:35:18 +00:00
|
|
|
if (i >= 0) {
|
2019-04-14 14:19:23 +00:00
|
|
|
if (duration.seconds > 0) {
|
2018-07-25 15:26:56 +00:00
|
|
|
addDurationToThumbnail(thumbnail, duration); // If we know the duration paint it on top of the thumbnail
|
2019-04-14 14:19:23 +00:00
|
|
|
pictures[i].length = duration;
|
|
|
|
}
|
2018-03-10 15:36:20 +00:00
|
|
|
pictures[i].image = thumbnail;
|
|
|
|
emit dataChanged(createIndex(i, 0), createIndex(i, 1));
|
|
|
|
}
|
|
|
|
}
|
2018-05-01 10:35:18 +00:00
|
|
|
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
void DivePictureModel::updateDivePictureOffset(int diveId, const QString &filenameIn, int offsetSeconds)
|
2018-05-01 10:35:18 +00:00
|
|
|
{
|
pictures: turn QString into std::string for filenames
For undo of picture manipulation, it will be crucial that the
model and the core have the same order of pictures. The first
sort criterion will be time, the second filename in the case
that two pictures have, for whatever reason, the same timestamp.
However in the core we us C-strings and thus sort byte-wise
using strcmp. In the Qt-part we use QStrings, which sort according
to unicode encoding. To enable consistent sorting, change the
Qt-part to std::string, which uses a C-style 0-terminated string
as its backing store.
One might argue that in general filenames should use system-encoding
and therefore use std::string instead of QString. However, a
broader conversion to std::string turned out to be very painful,
since Qt is (deliberately?) difficult to use with std::string.
Notable all the file-manipulation functions don't take std::string
by default. Thus, this commit only converts the internal data
of DivePictureModel, but continues to use QString for the Qt-facing
interface.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-04 07:47:55 +00:00
|
|
|
std::string filename = filenameIn.toStdString();
|
|
|
|
|
2018-06-30 19:32:14 +00:00
|
|
|
// Find the pictures of the given dive.
|
|
|
|
auto from = std::find_if(pictures.begin(), pictures.end(), [diveId](const PictureEntry &e) { return e.diveId == diveId; });
|
|
|
|
auto to = std::find_if(from, pictures.end(), [diveId](const PictureEntry &e) { return e.diveId != diveId; });
|
|
|
|
|
|
|
|
// Find picture with the given filename
|
|
|
|
auto oldPos = std::find_if(from, to, [filename](const PictureEntry &e) { return e.filename == filename; });
|
|
|
|
if (oldPos == to)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Find new position
|
|
|
|
auto newPos = std::find_if(from, to, [offsetSeconds](const PictureEntry &e) { return e.offsetSeconds > offsetSeconds; });
|
|
|
|
|
|
|
|
// Update the offset here and in the backend
|
|
|
|
oldPos->offsetSeconds = offsetSeconds;
|
|
|
|
if (struct dive *dive = get_dive_by_uniq_id(diveId)) {
|
|
|
|
FOR_EACH_PICTURE(dive) {
|
|
|
|
if (picture->filename == filename) {
|
|
|
|
picture->offset.seconds = offsetSeconds;
|
|
|
|
mark_divelist_changed(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
copy_dive(current_dive, &displayed_dive);
|
2018-05-01 10:35:18 +00:00
|
|
|
}
|
2018-06-30 19:32:14 +00:00
|
|
|
|
|
|
|
// Henceforth we will work with indices instead of iterators
|
|
|
|
int oldIndex = oldPos - pictures.begin();
|
|
|
|
int newIndex = newPos - pictures.begin();
|
|
|
|
if (oldIndex == newIndex || oldIndex + 1 == newIndex)
|
|
|
|
return;
|
|
|
|
beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
|
|
|
|
moveInVector(pictures, oldIndex, oldIndex + 1, newIndex);
|
|
|
|
endMoveRows();
|
2018-05-01 10:35:18 +00:00
|
|
|
}
|