2023-08-31 09:09:52 +02:00
|
|
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2023-03-27 12:49:53 -04:00
|
|
|
#include "ArtDetailWindow.h"
|
|
|
|
#include "imagelabel.h"
|
|
|
|
|
|
|
|
#include <QDateEdit>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QFormLayout>
|
|
|
|
#include <QGroupBox>
|
|
|
|
#include <QJsonArray>
|
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QTextEdit>
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
2023-06-15 13:54:52 -04:00
|
|
|
ArtDetailWindow::ArtDetailWindow(const QString& filename, const QString& assetDirectory, QWidget* parent) : QDialog(parent) {
|
2023-03-27 12:49:53 -04:00
|
|
|
setMinimumWidth(800);
|
|
|
|
setMinimumHeight(600);
|
2023-06-15 13:54:52 -04:00
|
|
|
setWindowModality(Qt::WindowModality::WindowModal);
|
|
|
|
setWindowTitle(filename);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
QFileInfo info(filename);
|
|
|
|
QString withoutExtension = info.completeBaseName();
|
|
|
|
|
|
|
|
auto mainLayout = new QHBoxLayout();
|
|
|
|
setLayout(mainLayout);
|
|
|
|
|
|
|
|
auto formLayout = new QFormLayout();
|
|
|
|
auto formLayoutWidget = new QWidget();
|
|
|
|
formLayoutWidget->setMaximumWidth(450);
|
|
|
|
formLayoutWidget->setLayout(formLayout);
|
|
|
|
mainLayout->addWidget(formLayoutWidget);
|
|
|
|
|
|
|
|
QImage image;
|
2023-08-31 09:51:57 +02:00
|
|
|
image.load(QStringLiteral("%1/%2.webp").arg(assetDirectory, withoutExtension));
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto previewBox = new QGroupBox(QStringLiteral("Preview"));
|
2023-03-27 12:49:53 -04:00
|
|
|
mainLayout->addWidget(previewBox);
|
|
|
|
|
|
|
|
auto previewLayout = new QVBoxLayout();
|
|
|
|
previewBox->setLayout(previewLayout);
|
|
|
|
|
|
|
|
auto imageView = new ImageLabel();
|
|
|
|
imageView->setPixmap(QPixmap::fromImage(image));
|
|
|
|
previewLayout->addWidget(imageView);
|
|
|
|
|
|
|
|
m_titleEdit = new QLineEdit();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Title"), m_titleEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_knowExactDateBox = new QCheckBox();
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(m_knowExactDateBox, &QCheckBox::toggled, this, [this](bool checked) {
|
2023-06-15 13:55:10 -04:00
|
|
|
if (checked) {
|
2023-08-31 09:51:57 +02:00
|
|
|
m_dateEdit->setDisplayFormat(QStringLiteral("yyyy-MM-dd"));
|
2023-06-15 13:55:10 -04:00
|
|
|
} else {
|
2023-08-31 09:51:57 +02:00
|
|
|
m_dateEdit->setDisplayFormat(QStringLiteral("yyyy"));
|
2023-06-15 13:55:10 -04:00
|
|
|
}
|
|
|
|
});
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Know Exact Date?"), m_knowExactDateBox);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_dateEdit = new QDateEdit();
|
|
|
|
m_dateEdit->setCalendarPopup(true);
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Date"), m_dateEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_altTextEdit = new QTextEdit();
|
|
|
|
m_altTextEdit->setAcceptRichText(false);
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Alt Text"), m_altTextEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_descriptionEdit = new QTextEdit();
|
|
|
|
m_descriptionEdit->setAcceptRichText(false);
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Description"), m_descriptionEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_nsfwBox = new QCheckBox();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Is NSFW?"), m_nsfwBox);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_mastodonUrlEdit = new QLineEdit();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Mastodon URL"), m_mastodonUrlEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_pixivUrlEdit = new QLineEdit();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Pixiv URL"), m_pixivUrlEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_newgroundsUrlEdit = new QLineEdit();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Newgrounds URL"), m_newgroundsUrlEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
m_programEdit = new QLineEdit();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Program"), m_programEdit);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
auto charactersLayout = new QVBoxLayout();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Characters"), charactersLayout);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
auto characterList = new QListView();
|
|
|
|
m_characterListModel = new QStringListModel();
|
|
|
|
characterList->setModel(m_characterListModel);
|
|
|
|
charactersLayout->addWidget(characterList);
|
|
|
|
|
|
|
|
auto characterButtonLayout = new QHBoxLayout();
|
|
|
|
charactersLayout->addLayout(characterButtonLayout);
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto addCharacterButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add")), QStringLiteral("Add"));
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(addCharacterButton, &QPushButton::clicked, this, [this] {
|
2023-03-27 12:49:53 -04:00
|
|
|
auto tmp = m_characterListModel->stringList();;
|
2023-08-31 09:51:57 +02:00
|
|
|
tmp.push_back(QStringLiteral("New Character"));
|
2023-03-27 12:49:53 -04:00
|
|
|
m_characterListModel->setStringList(tmp);
|
|
|
|
});
|
|
|
|
characterButtonLayout->addWidget(addCharacterButton);
|
|
|
|
characterButtonLayout->addStretch(1);
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto removeCharacterButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-remove")), QStringLiteral("Remove"));
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(removeCharacterButton, &QPushButton::clicked, this, [this, characterList] {
|
2023-03-27 12:49:53 -04:00
|
|
|
if(characterList->selectionModel()->hasSelection()) {
|
2023-08-31 10:02:32 +02:00
|
|
|
const QString toRemove = characterList->selectionModel()->selectedRows()[0].data().toString();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
auto tmp = m_characterListModel->stringList();
|
|
|
|
tmp.removeOne(toRemove);
|
|
|
|
m_characterListModel->setStringList(tmp);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
characterButtonLayout->addWidget(removeCharacterButton);
|
|
|
|
|
|
|
|
auto tagLayout = new QVBoxLayout();
|
2023-08-31 09:51:57 +02:00
|
|
|
formLayout->addRow(QStringLiteral("Tags"), tagLayout);
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
auto tagsList = new QListView();
|
|
|
|
m_tagsListModel = new QStringListModel();
|
|
|
|
tagsList->setModel(m_tagsListModel);
|
|
|
|
tagLayout->addWidget(tagsList);
|
|
|
|
|
|
|
|
auto tagButtonLayout = new QHBoxLayout();
|
|
|
|
tagLayout->addLayout(tagButtonLayout);
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto addTagButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add")), QStringLiteral("Add"));
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(addTagButton, &QPushButton::clicked, this, [this] {
|
2023-03-27 12:49:53 -04:00
|
|
|
auto tmp = m_tagsListModel->stringList();;
|
2023-08-31 09:51:57 +02:00
|
|
|
tmp.push_back(QStringLiteral("New Tag"));
|
2023-03-27 12:49:53 -04:00
|
|
|
m_tagsListModel->setStringList(tmp);
|
|
|
|
});
|
|
|
|
tagButtonLayout->addWidget(addTagButton);
|
|
|
|
tagButtonLayout->addStretch(1);
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto removeTagButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-remove")), QStringLiteral("Remove"));
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(removeTagButton, &QPushButton::clicked, this, [this, tagsList] {
|
2023-03-27 12:49:53 -04:00
|
|
|
if(tagsList->selectionModel()->hasSelection()) {
|
2023-08-31 10:02:32 +02:00
|
|
|
const QString toRemove = tagsList->selectionModel()->selectedRows()[0].data().toString();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
auto tmp = m_tagsListModel->stringList();
|
|
|
|
tmp.removeOne(toRemove);
|
|
|
|
m_tagsListModel->setStringList(tmp);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
tagButtonLayout->addWidget(removeTagButton);
|
|
|
|
|
|
|
|
auto bottomButtonLayout = new QHBoxLayout();
|
|
|
|
formLayout->addRow(bottomButtonLayout);
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto cancelButton = new QPushButton(QIcon::fromTheme(QStringLiteral("dialog-close")), QStringLiteral("Cancel"));
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(cancelButton, &QPushButton::clicked, this, &ArtDetailWindow::close);
|
2023-03-27 12:49:53 -04:00
|
|
|
bottomButtonLayout->addWidget(cancelButton);
|
|
|
|
bottomButtonLayout->addStretch(1);
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
auto saveButton = new QPushButton(QIcon::fromTheme(QStringLiteral("dialog-ok")), QStringLiteral("Save"));
|
2023-08-31 10:02:32 +02:00
|
|
|
connect(saveButton, &QPushButton::clicked, this, [this, filename] {
|
2023-03-27 12:49:53 -04:00
|
|
|
saveData(filename);
|
|
|
|
});
|
|
|
|
bottomButtonLayout->addWidget(saveButton);
|
|
|
|
|
|
|
|
if(QFile::exists(filename)) {
|
|
|
|
loadData(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ArtDetailWindow::loadData(const QString& filename) {
|
|
|
|
qDebug() << "Loading data from" << filename;
|
|
|
|
|
|
|
|
QFile artFile(filename);
|
|
|
|
artFile.open(QFile::ReadOnly);
|
|
|
|
QJsonDocument artJson = QJsonDocument::fromJson(artFile.readAll());
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("title")))
|
|
|
|
m_titleEdit->setText(artJson[QStringLiteral("title")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("alt_text")))
|
|
|
|
m_altTextEdit->setText(artJson[QStringLiteral("alt_text")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("description")))
|
|
|
|
m_descriptionEdit->setText(artJson[QStringLiteral("description")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
m_knowExactDateBox->setChecked(artJson[QStringLiteral("date")].toString().contains(QStringLiteral("-")));
|
2023-03-27 12:49:53 -04:00
|
|
|
if(m_knowExactDateBox->isChecked()) {
|
2023-08-31 09:51:57 +02:00
|
|
|
m_dateEdit->setDate(QDate::fromString(artJson[QStringLiteral("date")].toString(), QStringLiteral("yyyy-MM-dd")));
|
|
|
|
m_dateEdit->setDisplayFormat(QStringLiteral("yyyy-MM-dd"));
|
2023-03-27 12:49:53 -04:00
|
|
|
} else {
|
2023-08-31 09:51:57 +02:00
|
|
|
m_dateEdit->setDate(QDate::fromString(artJson[QStringLiteral("date")].toString(), QStringLiteral("yyyy")));
|
|
|
|
m_dateEdit->setDisplayFormat(QStringLiteral("yyyy"));
|
2023-03-27 12:49:53 -04:00
|
|
|
}
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("nsfw")))
|
|
|
|
m_nsfwBox->setChecked(artJson[QStringLiteral("nsfw")].toBool());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("mastodon_url")))
|
|
|
|
m_mastodonUrlEdit->setText(artJson[QStringLiteral("mastodon_url")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("pixiv_url")))
|
|
|
|
m_pixivUrlEdit->setText(artJson[QStringLiteral("pixiv_url")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("newgrounds_url")))
|
|
|
|
m_newgroundsUrlEdit->setText(artJson[QStringLiteral("newgrounds_url")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("program")))
|
|
|
|
m_programEdit->setText(artJson[QStringLiteral("program")].toString());
|
2023-03-27 12:49:53 -04:00
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("characters"))) {
|
2023-03-27 12:49:53 -04:00
|
|
|
QStringList list;
|
2023-08-31 09:51:57 +02:00
|
|
|
for(auto character : artJson[QStringLiteral("characters")].toArray()) {
|
2023-03-27 12:49:53 -04:00
|
|
|
list.append(character.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
m_characterListModel->setStringList(list);
|
|
|
|
}
|
|
|
|
|
2023-08-31 09:51:57 +02:00
|
|
|
if(artJson.object().contains(QStringLiteral("tags"))) {
|
2023-03-27 12:49:53 -04:00
|
|
|
QStringList list;
|
2023-08-31 09:51:57 +02:00
|
|
|
for(auto tag : artJson[QStringLiteral("tags")].toArray()) {
|
2023-03-27 12:49:53 -04:00
|
|
|
list.append(tag.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
m_tagsListModel->setStringList(list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ArtDetailWindow::saveData(const QString& filename) {
|
|
|
|
qDebug() << "Saving data to" << filename;
|
|
|
|
|
|
|
|
QJsonObject object;
|
|
|
|
if(!m_titleEdit->text().isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("title")] = m_titleEdit->text();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(!m_altTextEdit->document()->isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("alt_text")] = m_altTextEdit->document()->toPlainText();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(!m_descriptionEdit->document()->isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("description")] = m_descriptionEdit->document()->toPlainText();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(m_knowExactDateBox->isChecked()) {
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("date")] = m_dateEdit->date().toString(QStringLiteral("yyyy-MM-dd"));
|
2023-03-27 12:49:53 -04:00
|
|
|
} else {
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("date")] = m_dateEdit->date().toString(QStringLiteral("yyyy"));
|
2023-03-27 12:49:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if(m_nsfwBox->isChecked())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("nsfw")] = m_nsfwBox->isChecked();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(!m_mastodonUrlEdit->text().isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("mastodon_url")] = m_mastodonUrlEdit->text();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(!m_pixivUrlEdit->text().isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("pixiv_url")] = m_pixivUrlEdit->text();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(!m_newgroundsUrlEdit->text().isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("newgrounds_url")] = m_newgroundsUrlEdit->text();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
if(!m_programEdit->text().isEmpty())
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("program")] = m_programEdit->text();
|
2023-03-27 12:49:53 -04:00
|
|
|
|
|
|
|
auto tags = m_tagsListModel->stringList();
|
|
|
|
if(!tags.isEmpty()) {
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("tags")] = QJsonArray::fromStringList(tags);
|
2023-03-27 12:49:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
auto characters = m_characterListModel->stringList();
|
|
|
|
if(!characters.isEmpty()) {
|
2023-08-31 09:51:57 +02:00
|
|
|
object[QStringLiteral("characters")] = QJsonArray::fromStringList(characters);
|
2023-03-27 12:49:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
QJsonDocument jsonDoc(object);
|
|
|
|
QFile file(filename);
|
|
|
|
file.open(QFile::WriteOnly);
|
|
|
|
file.write(jsonDoc.toJson());
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|