Skip to content

Commit

Permalink
AnalyzeView: Fix GeoTagWorker Threading
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Sep 8, 2024
1 parent 990189b commit 056dbac
Show file tree
Hide file tree
Showing 18 changed files with 352 additions and 227 deletions.
2 changes: 1 addition & 1 deletion src/AnalyzeView/ExifParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ double readTime(const QByteArray &buf)
return (tagTime.toMSecsSinceEpoch() / 1000.0);
}

bool write(QByteArray &buf, const GeoTagWorker::cameraFeedbackPacket &geotag)
bool write(QByteArray &buf, const GeoTagWorker::CameraFeedbackPacket &geotag)
{
static const QByteArray app1Header("\xff\xe1", 2);

Expand Down
2 changes: 1 addition & 1 deletion src/AnalyzeView/ExifParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Q_DECLARE_LOGGING_CATEGORY(ExifParserLog)

namespace ExifParser {
double readTime(const QByteArray &buf);
bool write(QByteArray &buf, const GeoTagWorker::cameraFeedbackPacket &geotag);
bool write(QByteArray &buf, const GeoTagWorker::CameraFeedbackPacket &geotag);
} // namespace ExifParser
147 changes: 81 additions & 66 deletions src/AnalyzeView/GeoTagController.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,120 +8,135 @@
****************************************************************************/

#include "GeoTagController.h"
#include "GeoTagWorker.h"
#include "QGCLoggingCategory.h"

#include <QtCore/QDir>
#include <QtCore/QThread>
#include <QtCore/QUrl>

QGC_LOGGING_CATEGORY(GeoTagControllerLog, "qgc.analyzeview.geotagcontroller")

GeoTagController::GeoTagController()
: _progress(0)
, _inProgress(false)
GeoTagController::GeoTagController(QObject *parent)
: QObject(parent)
, _worker(new GeoTagWorker(this))
, _workerThread(new QThread(this))
{
connect(&_worker, &GeoTagWorker::progressChanged, this, &GeoTagController::_workerProgressChanged);
connect(&_worker, &GeoTagWorker::error, this, &GeoTagController::_workerError);
connect(&_worker, &GeoTagWorker::started, this, &GeoTagController::inProgressChanged);
connect(&_worker, &GeoTagWorker::finished, this, &GeoTagController::inProgressChanged);
// qCDebug(GeoTagControllerLog) << Q_FUNC_INFO << this;

(void) connect(_worker, &GeoTagWorker::progressChanged, this, &GeoTagController::_workerProgressChanged);
(void) connect(_worker, &GeoTagWorker::error, this, &GeoTagController::_workerError);
(void) connect(_workerThread, &QThread::started, this, &GeoTagController::inProgressChanged);
(void) connect(_workerThread, &QThread::finished, this, &GeoTagController::inProgressChanged);

_worker->moveToThread(_workerThread);
}

GeoTagController::~GeoTagController()
{
// qCDebug(GeoTagControllerLog) << Q_FUNC_INFO << this;
}

void GeoTagController::cancelTagging()
{
(void) QMetaObject::invokeMethod(_worker, "cancelTagging", Qt::AutoConnection);
}

QString GeoTagController::logFile() const
{
return _worker->logFile();
}

QString GeoTagController::imageDirectory() const
{
return _worker->imageDirectory();
}

QString GeoTagController::saveDirectory() const
{
return _worker->saveDirectory();
}

bool GeoTagController::inProgress() const
{
return _workerThread->isRunning();
}

void GeoTagController::setLogFile(QString filename)
void GeoTagController::setLogFile(const QString &filename)
{
filename = QUrl(filename).toLocalFile();
if (!filename.isEmpty()) {
_worker.setLogFile(filename);
emit logFileChanged(filename);
const QString logFile = QUrl(filename).toLocalFile();
if (!logFile.isEmpty()) {
_worker->setLogFile(logFile);
emit logFileChanged(logFile);
}
}

void GeoTagController::setImageDirectory(QString dir)
void GeoTagController::setImageDirectory(const QString &dir)
{
dir = QUrl(dir).toLocalFile();
if (!dir.isEmpty()) {
_worker.setImageDirectory(dir);
emit imageDirectoryChanged(dir);
if(_worker.saveDirectory() == "") {
QDir saveDirectory = QDir(_worker.imageDirectory() + kTagged);
if(saveDirectory.exists()) {
_setErrorMessage(tr("Images have alreay been tagged. Existing images will be removed."));
const QString imageDir = QUrl(dir).toLocalFile();
if (!imageDir.isEmpty()) {
_worker->setImageDirectory(imageDir);
emit imageDirectoryChanged(imageDir);
if (_worker->saveDirectory().isEmpty()) {
const QDir saveDirectory = QDir(_worker->imageDirectory() + kTagged);
if (saveDirectory.exists()) {
_setErrorMessage(QStringLiteral("Images have alreay been tagged. Existing images will be removed."));
return;
}
}
}
_errorMessage.clear();
emit errorMessageChanged(_errorMessage);

_setErrorMessage(QString());
}

void GeoTagController::setSaveDirectory(QString dir)
void GeoTagController::setSaveDirectory(const QString &dir)
{
dir = QUrl(dir).toLocalFile();
const QString saveDir = QUrl(dir).toLocalFile();
if (!dir.isEmpty()) {
_worker.setSaveDirectory(dir);
emit saveDirectoryChanged(dir);
//-- Check and see if there are images already there
QDir saveDirectory = QDir(_worker.saveDirectory());
_worker->setSaveDirectory(saveDir);
emit saveDirectoryChanged(saveDir);
QDir saveDirectory = QDir(_worker->saveDirectory());
saveDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable);
QStringList nameFilters;
nameFilters << "*.jpg" << "*.JPG";
saveDirectory.setNameFilters(nameFilters);
QStringList imageList = saveDirectory.entryList();
if(!imageList.isEmpty()) {
_setErrorMessage(tr("The save folder already contains images."));
const QStringList imageList = saveDirectory.entryList();
if (!imageList.isEmpty()) {
_setErrorMessage(QStringLiteral("The save folder already contains images."));
return;
}
}
_errorMessage.clear();
emit errorMessageChanged(_errorMessage);

_setErrorMessage(QString());
}

void GeoTagController::startTagging()
{
_errorMessage.clear();
emit errorMessageChanged(_errorMessage);
QDir imageDirectory = QDir(_worker.imageDirectory());
if(!imageDirectory.exists()) {
_setErrorMessage(tr("Cannot find the image directory."));
_setErrorMessage(QString());

const QDir imageDirectory = QDir(_worker->imageDirectory());
if (!imageDirectory.exists()) {
_setErrorMessage(QStringLiteral("Cannot find the image directory."));
return;
}
if(_worker.saveDirectory() == "") {
QDir oldTaggedFolder = QDir(_worker.imageDirectory() + kTagged);
if(oldTaggedFolder.exists()) {

if (_worker->saveDirectory().isEmpty()) {
QDir oldTaggedFolder = QDir(_worker->imageDirectory() + kTagged);
if (oldTaggedFolder.exists()) {
oldTaggedFolder.removeRecursively();
if(!imageDirectory.mkdir(_worker.imageDirectory() + kTagged)) {
_setErrorMessage(tr("Couldn't replace the previously tagged images"));
if (!imageDirectory.mkdir(_worker->imageDirectory() + kTagged)) {
_setErrorMessage(QStringLiteral("Couldn't replace the previously tagged images"));
return;
}
}
} else {
QDir saveDirectory = QDir(_worker.saveDirectory());
if(!saveDirectory.exists()) {
_setErrorMessage(tr("Cannot find the save directory."));
const QDir saveDirectory = QDir(_worker->saveDirectory());
if (!saveDirectory.exists()) {
_setErrorMessage(QStringLiteral("Cannot find the save directory."));
return;
}
}
_worker.start();
}

void GeoTagController::_workerProgressChanged(double progress)
{
_progress = progress;
emit progressChanged(progress);
}

void GeoTagController::_workerError(QString errorMessage)
{
_errorMessage = errorMessage;
emit errorMessageChanged(errorMessage);
}


void GeoTagController::_setErrorMessage(const QString& error)
{
_errorMessage = error;
emit errorMessageChanged(error);
(void) QMetaObject::invokeMethod(_workerThread, "start", Qt::AutoConnection);
(void) QMetaObject::invokeMethod(_worker, "process", Qt::AutoConnection);
}
72 changes: 35 additions & 37 deletions src/AnalyzeView/GeoTagController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@

#pragma once

#include <QtCore/QLoggingCategory>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QLoggingCategory>
#include <QtQmlIntegration/QtQmlIntegration>

#include "GeoTagWorker.h"
class GeoTagWorker;
class QThread;

Q_DECLARE_LOGGING_CATEGORY(GeoTagControllerLog)

Expand All @@ -24,56 +25,53 @@ class GeoTagController : public QObject
Q_OBJECT
QML_ELEMENT

public:
GeoTagController();
~GeoTagController();

Q_PROPERTY(QString logFile READ logFile WRITE setLogFile NOTIFY logFileChanged)
Q_PROPERTY(QString imageDirectory READ imageDirectory WRITE setImageDirectory NOTIFY imageDirectoryChanged)
Q_PROPERTY(QString saveDirectory READ saveDirectory WRITE setSaveDirectory NOTIFY saveDirectoryChanged)

/// Set to an error message is geotagging fails
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)

Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
/// Progress indicator: 0-100
Q_PROPERTY(double progress READ progress NOTIFY progressChanged)

Q_PROPERTY(double progress READ progress NOTIFY progressChanged)
/// true: Currently in the process of tagging
Q_PROPERTY(bool inProgress READ inProgress NOTIFY inProgressChanged)
Q_PROPERTY(bool inProgress READ inProgress NOTIFY inProgressChanged)

public:
GeoTagController(QObject *parent = nullptr);
~GeoTagController();

Q_INVOKABLE void startTagging();
Q_INVOKABLE void cancelTagging() { _worker.cancelTagging(); }
Q_INVOKABLE void cancelTagging();

QString logFile () const { return _worker.logFile(); }
QString imageDirectory () const { return _worker.imageDirectory(); }
QString saveDirectory () const { return _worker.saveDirectory(); }
double progress () const { return _progress; }
bool inProgress () const { return _worker.isRunning(); }
QString errorMessage () const { return _errorMessage; }
QString logFile() const;
QString imageDirectory() const;
QString saveDirectory() const;
double progress() const { return _progress; }
bool inProgress() const;
QString errorMessage() const { return _errorMessage; }

void setLogFile (QString file);
void setImageDirectory (QString dir);
void setSaveDirectory (QString dir);
void setLogFile(const QString &file);
void setImageDirectory(const QString &dir);
void setSaveDirectory(const QString &dir);

signals:
void logFileChanged (QString logFile);
void imageDirectoryChanged (QString imageDirectory);
void saveDirectoryChanged (QString saveDirectory);
void progressChanged (double progress);
void inProgressChanged ();
void errorMessageChanged (QString errorMessage);
void logFileChanged(const QString &logFile);
void imageDirectoryChanged(const QString &imageDirectory);
void saveDirectoryChanged(const QString &saveDirectory);
void progressChanged(double progress);
void inProgressChanged();
void errorMessageChanged(const QString &errorMessage);

private slots:
void _workerProgressChanged (double progress);
void _workerError (QString errorMsg);
void _setErrorMessage (const QString& error);
void _workerProgressChanged(double progress) { if (progress != _progress) { _progress = progress; emit progressChanged(_progress); } }
void _setErrorMessage(const QString &errorMsg) { if (errorMsg != _errorMessage) { _errorMessage = errorMsg; emit errorMessageChanged(_errorMessage); } }
void _workerError(const QString &errorMsg) { _setErrorMessage(errorMsg); }

private:
QString _errorMessage;
double _progress;
bool _inProgress;

GeoTagWorker _worker;
QString _errorMessage;
double _progress = 0.;
bool _inProgress = false;
GeoTagWorker *_worker = nullptr;
QThread *_workerThread = nullptr;

static constexpr const char* kTagged = "/TAGGED";
static constexpr const char *kTagged = "/TAGGED";
};
Loading

0 comments on commit 056dbac

Please sign in to comment.