mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Move ImageDownloader out of the desktop widgets
This required a bit more untangling, but with this it seems we can build subsurface-mobile again (at least on the desktop). Interesting is the removal from inside the ImageDownloader of the call to DivePictureModel::instance()->updateDivePictures() - which actually could cause some interesting recursion issues. If it turns out we did indeed need this, it needs to be re-architected. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
bb566f7798
commit
9edb4f3fa9
7 changed files with 110 additions and 93 deletions
|
@ -15,79 +15,6 @@
|
||||||
#include <qthelper.h>
|
#include <qthelper.h>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
void loadPicture(struct picture *picture)
|
|
||||||
{
|
|
||||||
ImageDownloader download(picture);
|
|
||||||
download.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
SHashedImage::SHashedImage(struct picture *picture) : QImage()
|
|
||||||
{
|
|
||||||
QUrl url = QUrl::fromUserInput(QString(picture->filename));
|
|
||||||
if(url.isLocalFile())
|
|
||||||
load(url.toLocalFile());
|
|
||||||
if (isNull()) {
|
|
||||||
// Hash lookup.
|
|
||||||
load(fileFromHash(picture->hash));
|
|
||||||
if (!isNull()) {
|
|
||||||
QtConcurrent::run(updateHash, picture);
|
|
||||||
} else {
|
|
||||||
QtConcurrent::run(loadPicture, picture);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QByteArray hash = hashFile(url.toLocalFile());
|
|
||||||
free(picture->hash);
|
|
||||||
picture->hash = strdup(hash.toHex().data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageDownloader::ImageDownloader(struct picture *pic)
|
|
||||||
{
|
|
||||||
picture = pic;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageDownloader::load(){
|
|
||||||
QUrl url = QUrl::fromUserInput(QString(picture->filename));
|
|
||||||
if (url.isValid()) {
|
|
||||||
QEventLoop loop;
|
|
||||||
QNetworkRequest request(url);
|
|
||||||
connect(&manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(saveImage(QNetworkReply *)));
|
|
||||||
QNetworkReply *reply = manager.get(request);
|
|
||||||
while (reply->isRunning()) {
|
|
||||||
loop.processEvents();
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageDownloader::saveImage(QNetworkReply *reply)
|
|
||||||
{
|
|
||||||
QByteArray imageData = reply->readAll();
|
|
||||||
QImage image = QImage();
|
|
||||||
image.loadFromData(imageData);
|
|
||||||
if (image.isNull())
|
|
||||||
return;
|
|
||||||
QCryptographicHash hash(QCryptographicHash::Sha1);
|
|
||||||
hash.addData(imageData);
|
|
||||||
QString path = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first();
|
|
||||||
QDir dir(path);
|
|
||||||
if (!dir.exists())
|
|
||||||
dir.mkpath(path);
|
|
||||||
QFile imageFile(path.append("/").append(hash.result().toHex()));
|
|
||||||
if (imageFile.open(QIODevice::WriteOnly)) {
|
|
||||||
QDataStream stream(&imageFile);
|
|
||||||
stream.writeRawData(imageData.data(), imageData.length());
|
|
||||||
imageFile.waitForBytesWritten(-1);
|
|
||||||
imageFile.close();
|
|
||||||
add_hash(imageFile.fileName(), hash.result());
|
|
||||||
learnHash(picture, hash.result());
|
|
||||||
DivePictureModel::instance()->updateDivePictures();
|
|
||||||
}
|
|
||||||
reply->manager()->deleteLater();
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
DivePictureWidget::DivePictureWidget(QWidget *parent) : QListView(parent)
|
DivePictureWidget::DivePictureWidget(QWidget *parent) : QListView(parent)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(doubleClicked(const QModelIndex &)));
|
connect(this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(doubleClicked(const QModelIndex &)));
|
||||||
|
|
|
@ -5,19 +5,6 @@
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
#include <QNetworkReply>
|
|
||||||
|
|
||||||
class ImageDownloader : public QObject {
|
|
||||||
Q_OBJECT;
|
|
||||||
public:
|
|
||||||
ImageDownloader(struct picture *picture);
|
|
||||||
void load();
|
|
||||||
private:
|
|
||||||
struct picture *picture;
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
private slots:
|
|
||||||
void saveImage(QNetworkReply *reply);
|
|
||||||
};
|
|
||||||
|
|
||||||
class DivePictureWidget : public QListView {
|
class DivePictureWidget : public QListView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "dive.h"
|
#include "dive.h"
|
||||||
#include "metrics.h"
|
#include "metrics.h"
|
||||||
#include "divelist.h"
|
#include "divelist.h"
|
||||||
|
#include "imagedownloader.h"
|
||||||
|
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,6 @@
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
|
||||||
typedef QPair<QString, QByteArray> SHashedFilename;
|
|
||||||
|
|
||||||
class SHashedImage : public QImage {
|
|
||||||
public:
|
|
||||||
SHashedImage(struct picture *picture);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PhotoHelper {
|
struct PhotoHelper {
|
||||||
QImage image;
|
QImage image;
|
||||||
int offsetSeconds;
|
int offsetSeconds;
|
||||||
|
|
|
@ -76,6 +76,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
|
||||||
metrics.cpp
|
metrics.cpp
|
||||||
color.cpp
|
color.cpp
|
||||||
pluginmanager.cpp
|
pluginmanager.cpp
|
||||||
|
imagedownloader.cpp
|
||||||
${SERIAL_FTDI}
|
${SERIAL_FTDI}
|
||||||
${PLATFORM_SRC}
|
${PLATFORM_SRC}
|
||||||
${BT_CORE_SRC_FILES}
|
${BT_CORE_SRC_FILES}
|
||||||
|
|
79
subsurface-core/imagedownloader.cpp
Normal file
79
subsurface-core/imagedownloader.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "dive.h"
|
||||||
|
#include "metrics.h"
|
||||||
|
#include "divelist.h"
|
||||||
|
#include "qthelper.h"
|
||||||
|
#include "imagedownloader.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
ImageDownloader::ImageDownloader(struct picture *pic)
|
||||||
|
{
|
||||||
|
picture = pic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageDownloader::load(){
|
||||||
|
QUrl url = QUrl::fromUserInput(QString(picture->filename));
|
||||||
|
if (url.isValid()) {
|
||||||
|
QEventLoop loop;
|
||||||
|
QNetworkRequest request(url);
|
||||||
|
connect(&manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(saveImage(QNetworkReply *)));
|
||||||
|
QNetworkReply *reply = manager.get(request);
|
||||||
|
while (reply->isRunning()) {
|
||||||
|
loop.processEvents();
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageDownloader::saveImage(QNetworkReply *reply)
|
||||||
|
{
|
||||||
|
QByteArray imageData = reply->readAll();
|
||||||
|
QImage image = QImage();
|
||||||
|
image.loadFromData(imageData);
|
||||||
|
if (image.isNull())
|
||||||
|
return;
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||||
|
hash.addData(imageData);
|
||||||
|
QString path = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first();
|
||||||
|
QDir dir(path);
|
||||||
|
if (!dir.exists())
|
||||||
|
dir.mkpath(path);
|
||||||
|
QFile imageFile(path.append("/").append(hash.result().toHex()));
|
||||||
|
if (imageFile.open(QIODevice::WriteOnly)) {
|
||||||
|
QDataStream stream(&imageFile);
|
||||||
|
stream.writeRawData(imageData.data(), imageData.length());
|
||||||
|
imageFile.waitForBytesWritten(-1);
|
||||||
|
imageFile.close();
|
||||||
|
add_hash(imageFile.fileName(), hash.result());
|
||||||
|
learnHash(picture, hash.result());
|
||||||
|
}
|
||||||
|
reply->manager()->deleteLater();
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadPicture(struct picture *picture)
|
||||||
|
{
|
||||||
|
ImageDownloader download(picture);
|
||||||
|
download.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHashedImage::SHashedImage(struct picture *picture) : QImage()
|
||||||
|
{
|
||||||
|
QUrl url = QUrl::fromUserInput(QString(picture->filename));
|
||||||
|
if(url.isLocalFile())
|
||||||
|
load(url.toLocalFile());
|
||||||
|
if (isNull()) {
|
||||||
|
// Hash lookup.
|
||||||
|
load(fileFromHash(picture->hash));
|
||||||
|
if (!isNull()) {
|
||||||
|
QtConcurrent::run(updateHash, picture);
|
||||||
|
} else {
|
||||||
|
QtConcurrent::run(loadPicture, picture);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QByteArray hash = hashFile(url.toLocalFile());
|
||||||
|
free(picture->hash);
|
||||||
|
picture->hash = strdup(hash.toHex().data());
|
||||||
|
}
|
||||||
|
}
|
29
subsurface-core/imagedownloader.h
Normal file
29
subsurface-core/imagedownloader.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef IMAGEDOWNLOADER_H
|
||||||
|
#define IMAGEDOWNLOADER_H
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
typedef QPair<QString, QByteArray> SHashedFilename;
|
||||||
|
|
||||||
|
class ImageDownloader : public QObject {
|
||||||
|
Q_OBJECT;
|
||||||
|
public:
|
||||||
|
ImageDownloader(struct picture *picture);
|
||||||
|
void load();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct picture *picture;
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void saveImage(QNetworkReply *reply);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHashedImage : public QImage {
|
||||||
|
public:
|
||||||
|
SHashedImage(struct picture *picture);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGEDOWNLOADER_H
|
Loading…
Add table
Add a link
Reference in a new issue