redai/src/artdetailwindow.cpp

307 lines
11 KiB
C++
Raw Normal View History

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