174 lines
4.4 KiB
C++
174 lines
4.4 KiB
C++
#include "mainwindow.h"
|
|
#include "./ui_mainwindow.h"
|
|
|
|
#include <QFileDialog>
|
|
#include <QMessageBox>
|
|
#include <QJsonDocument>
|
|
|
|
MainWindow::MainWindow(QWidget *parent)
|
|
: QMainWindow(parent)
|
|
, ui(new Ui::MainWindow)
|
|
{
|
|
ui->setupUi(this);
|
|
connect(ui->actionOpen, &QAction::triggered, this, [this](bool){open();});
|
|
connect(ui->nextButton, &QPushButton::clicked, this, [this](bool){setImage(index+1);});
|
|
connect(ui->prevButton, &QPushButton::clicked, this, [this](bool){setImage(index-1);});
|
|
connect(ui->actionSave, &QAction::triggered, this, [this](bool){save();});
|
|
connect(ui->actionQuit, &QAction::triggered, this, [this](bool){close();});
|
|
ui->verticalLayout->addWidget(&status);
|
|
ui->imageLabel->setScaledContents( true );
|
|
ui->imageLabel->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void MainWindow::open()
|
|
{
|
|
QString dirpath = QFileDialog::getExistingDirectory(this, "Choose a directory with images", "", QFlags<QFileDialog::Option>());
|
|
if(dirpath.isEmpty())
|
|
return;
|
|
|
|
openDir(dirpath.toStdString());
|
|
}
|
|
|
|
void MainWindow::openDir(const std::filesystem::path& path)
|
|
{
|
|
imageMetas.clear();
|
|
|
|
QDir dir(path);
|
|
bool hasMetadata = false;
|
|
std::vector<std::filesystem::path> imagePaths;
|
|
for(QString filename : dir.entryList(QDir::Files))
|
|
{
|
|
if(filename == "metadata.jsonl")
|
|
hasMetadata = true;
|
|
else if(filename.endsWith(".jpg") || filename.endsWith(".png"))
|
|
imagePaths.push_back(path/filename.toStdString());
|
|
}
|
|
|
|
if(imagePaths.empty())
|
|
{
|
|
QMessageBox::warning(this, "No images found", "No valid images found in this directory");
|
|
return;
|
|
}
|
|
|
|
if(hasMetadata)
|
|
{
|
|
if(!loadMetadata(path/"metadata.jsonl"))
|
|
QMessageBox::warning(this, "Could not read",
|
|
(std::string("Could not read ") + path.string() + std::string("/metadata.jsonl, file contains errors")).c_str());
|
|
}
|
|
|
|
for(const std::filesystem::path &path : imagePaths)
|
|
{
|
|
if(imageIsKnown(path))
|
|
continue;
|
|
qDebug()<<path.c_str()<<"not in existing metadata.jsonl";
|
|
imageMetas.push_back(ImageMeta(path));
|
|
}
|
|
|
|
this->dir = path;
|
|
|
|
ui->textEdit->document()->setPlainText(imageMetas[0].text);
|
|
setImage(0);
|
|
}
|
|
|
|
void MainWindow::setImage(ssize_t index)
|
|
{
|
|
if(imageMetas.empty())
|
|
return;
|
|
else if(index > imageMetas.size()-1)
|
|
return;
|
|
else if(index < 0)
|
|
return;
|
|
|
|
imageMetas[this->index].text = ui->textEdit->document()->toPlainText();
|
|
this->index = index;
|
|
ui->counterLabel->setText(QString::asprintf("%04zu/%04zu", index, imageMetas.size()-1));
|
|
ui->textEdit->document()->setPlainText(imageMetas[index].text);
|
|
|
|
QPixmap image;
|
|
bool ret = image.load(imageMetas[index].path.string().c_str());
|
|
if(!ret)
|
|
{
|
|
ui->imageLabel->setPixmap(QPixmap());
|
|
ui->imageLabel->setText(("Unable to load " + imageMetas[index].path.string()).c_str());
|
|
ui->imageLabel->setText("No image loaded");
|
|
}
|
|
else
|
|
{
|
|
ui->imageLabel->setPixmap(image);
|
|
}
|
|
|
|
ui->imageLabel->setText("");
|
|
}
|
|
|
|
bool MainWindow::loadMetadata(const std::filesystem::path& path)
|
|
{
|
|
QFile meta(path);
|
|
meta.open(QIODeviceBase::ReadOnly);
|
|
if(!meta.isOpen())
|
|
{
|
|
qWarning()<<("Could not open " + path.string()).c_str();
|
|
return false;
|
|
}
|
|
|
|
QByteArray line = meta.readLine();
|
|
while(!line.isEmpty())
|
|
{
|
|
QJsonParseError error;
|
|
QJsonDocument json = QJsonDocument::fromJson(line, &error);
|
|
if(json.isNull())
|
|
{
|
|
qWarning()<<error.errorString();
|
|
return false;
|
|
}
|
|
|
|
imageMetas.push_back(ImageMeta(json.object(), path.parent_path()));
|
|
line = meta.readLine();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MainWindow::imageIsKnown(const std::filesystem::path& path)
|
|
{
|
|
for(const ImageMeta& meta : imageMetas)
|
|
{
|
|
if(meta.path == path)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void MainWindow::save()
|
|
{
|
|
if(imageMetas.empty())
|
|
return;
|
|
|
|
QFile file(dir/"metadata.jsonl");
|
|
if(!file.open(QIODeviceBase::WriteOnly | QIODeviceBase::Truncate))
|
|
{
|
|
QMessageBox::warning(this, "Could not save",
|
|
("Could not save, can not open " + (dir/"metadata.jsonl").string() + " for writeing").c_str());
|
|
return;
|
|
}
|
|
|
|
for(const ImageMeta& meta : imageMetas)
|
|
{
|
|
QJsonObject obj;
|
|
obj["file_name"] = std::filesystem::relative(meta.path, dir).string().c_str();
|
|
obj["text"] = meta.text;
|
|
QJsonDocument document(obj);
|
|
QByteArray json = document.toJson(QJsonDocument::Compact);
|
|
json.removeIf([](char ch){return ch == '\n';});
|
|
json.append('\n');
|
|
file.write(json);
|
|
}
|
|
file.close();
|
|
QMessageBox::information(this, "Saved", ("Saved to " + (dir/"metadata.jsonl").string()).c_str());
|
|
}
|