/*
* Copyright (c) 2018 Frank Fischer <frank-fischer@shadow-soft.de>
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "Document.hxx"
#include "BaseImage.hxx"
#include "Page.hxx"
#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonValue>
#include <QtCore/QJsonValueRef>
#include <QtCore/QList>
#include <QtCore/QSharedPointer>
#include <memory>
#include <QDebug>
const QString Document::FilenameFormat = QStringLiteral("yyyyMMddTHHmmss");
struct Document::Data {
QString title; ///< document title
QString filename; ///< filename of the document data
QDateTime creation_time; ///< time when the document has been created
QList<QSharedPointer<Page>> pages; ///< page of the document
};
Document::Document(QObject *parent) : QAbstractListModel(parent), d(new Data)
{
// QString path = QDir::homePath() + QStringLiteral("/fotokopierer/doc1");
// d->title = QStringLiteral("TestDocument");
// d->filename = path + QStringLiteral("/doc.json");
// d->creation_time = QDateTime::currentDateTime();
// // d->pages.push_back(QSharedPointer<Page>(new Page(QDateTime::currentDateTime(),
// // path +
// // QStringLiteral("/page1-original.jpg"),
// path
// // + QStringLiteral("/page1-result.jpg"),
// // {},
// // this)));
// // d->pages.push_back(QSharedPointer<Page>(new Page(QDateTime::currentDateTime(),
// // path +
// // QStringLiteral("/page2-original.jpg"),
// path
// // + QStringLiteral("/page2-result.jpg"),
// // {},
// // this)));
// // d->pages.push_back(QSharedPointer<Page>(new Page(QDateTime::currentDateTime(),
// // path +
// // QStringLiteral("/page3-original.jpg"),
// path
// // + QStringLiteral("/page3-result.jpg"),
// // {},
// // this)));
// load(d->filename);
}
Document::~Document() = default;
int Document::rowCount(const QModelIndex &parent) const
{
return d->pages.size();
}
QVariant Document::data(const QModelIndex &index, int role) const
{
switch (role) {
case PageRole: {
if (index.column() == 0 && index.row() < d->pages.size()) {
return QVariant::fromValue(d->pages[index.row()].data());
}
break;
}
}
return {};
}
QHash<int, QByteArray> Document::roleNames() const
{
static const QHash<int, QByteArray> roles = {{PageRole, "role_page"}};
return roles;
}
void Document::move(int from, int to)
{
if (beginMoveRows({}, from, from, {}, to > from ? to + 1 : to)) {
auto p = d->pages[from];
d->pages.removeAt(from);
d->pages.insert(to, p);
endMoveRows();
save();
}
}
void Document::addPage(BaseImage *original, BaseImage *result)
{
QImage original_img = original->image();
if (original_img.isNull()) {
emit error(QStringLiteral("Page could not be created: no original image"));
return;
}
QImage result_img = result->image();
if (result_img.isNull()) {
emit error(QStringLiteral("Page could not be created: no result image"));
return;
}
auto ctime = QDateTime::currentDateTime();
auto dir = QFileInfo(d->filename).dir();
auto original_path =
dir.filePath(ctime.toString(FilenameFormat) + QStringLiteral("-original.png"));
auto result_path = dir.filePath(ctime.toString(FilenameFormat) + QStringLiteral("-result.png"));
if (!original_img.save(original_path)) {
emit error(QStringLiteral("Page could not be created: error saving original image"));
return;
};
if (!result_img.save(result_path)) {
emit error(QStringLiteral("Page could not be created: error saving result image"));
return;
};
QSharedPointer<Page> p(new Page(ctime, original_path, result_path, {}, this));
beginInsertRows({}, d->pages.size(), d->pages.size());
d->pages.push_back(p);
endInsertRows();
save();
}
bool Document::save() const
{
QFileInfo finfo(d->filename);
if (!finfo.dir().exists()) {
finfo.dir().mkpath(QStringLiteral("."));
}
QFile file(d->filename);
if (!file.open(QIODevice::WriteOnly)) {
qWarning() << tr("Can't write document file %1").arg(d->filename);
return false;
}
QJsonObject doc;
doc[QStringLiteral("title")] = d->title;
doc[QStringLiteral("filename")] = d->filename;
doc[QStringLiteral("creationTime")] = d->creation_time.toString(FilenameFormat);
QJsonArray pages;
for (auto page : d->pages) {
QJsonObject p;
if (!page->write(p)) return false;
pages << p;
}
doc[QStringLiteral("pages")] = pages;
if (file.write(QJsonDocument(doc).toJson()) < 0) return false;
return true;
}
bool Document::load(const QString &filename, QObject *parent)
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << tr("Can't open document file %1").arg(filename);
return false;
}
auto docdata = file.readAll();
auto doc = QJsonDocument::fromJson(docdata);
auto json = doc.object();
auto title = json[QStringLiteral("title")];
if (!title.isString()) return false;
auto creation_time = json[QStringLiteral("creationTime")];
if (!creation_time.isString()) return false;
auto ctime = QDateTime::fromString(creation_time.toString(), FilenameFormat);
auto pages = json[QStringLiteral("pages")];
if (!pages.isArray()) return false;
QList<QSharedPointer<Page>> docpages;
for (auto page : pages.toArray()) {
if (!page.isObject()) return false;
QSharedPointer<Page> p(new Page);
if (!p->read(page.toObject())) return false;
docpages.push_back(p);
}
d->title = title.toString();
d->filename = filename;
d->creation_time = ctime;
d->pages = docpages;
return true;
}