Add support for setting the content type to a whole library

This commit is contained in:
Luis Ángel San Martín 2024-07-09 19:18:22 +02:00
parent 58ec456fc7
commit f9039c7a26
9 changed files with 225 additions and 50 deletions

View File

@ -53,11 +53,76 @@ void drawMacOSXFinishedFolderIcon()
#define ROOT 1
FolderItem *createRoot()
struct FolderColumns {
int name;
int path;
int finished;
int completed;
int id;
int parentId;
int numChildren;
int firstChildHash;
int customImage;
int type;
int added;
int updated;
FolderColumns(QSqlQuery &sqlquery)
{
auto record = sqlquery.record();
name = record.indexOf("name");
path = record.indexOf("path");
finished = record.indexOf("finished");
completed = record.indexOf("completed");
id = record.indexOf("id");
parentId = record.indexOf("parentId");
numChildren = record.indexOf("numChildren");
firstChildHash = record.indexOf("firstChildHash");
customImage = record.indexOf("customImage");
type = record.indexOf("type");
added = record.indexOf("added");
updated = record.indexOf("updated");
}
};
QList<QVariant> folderDataFromQuery(QSqlQuery &query, const FolderColumns &columns)
{
QList<QVariant> rootData;
rootData << "root";
auto root = new FolderItem(rootData);
QList<QVariant> data;
data << query.value(columns.name);
data << query.value(columns.path);
data << query.value(columns.finished);
data << query.value(columns.completed);
data << query.value(columns.numChildren);
data << query.value(columns.firstChildHash);
data << query.value(columns.customImage);
data << query.value(columns.type);
data << query.value(columns.added);
data << query.value(columns.updated);
return data;
}
// TODO: load from DB, type is pretty much needed
FolderItem *createRoot(QSqlDatabase &db)
{
QList<QVariant> data;
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT * FROM folder WHERE id = 1");
selectQuery.exec();
auto columns = FolderColumns(selectQuery);
if (!selectQuery.next()) {
return nullptr;
}
data = folderDataFromQuery(selectQuery, columns);
data[0] = "root";
auto root = new FolderItem(data);
root->id = ROOT;
root->parentItem = nullptr;
@ -83,7 +148,7 @@ int FolderModel::columnCount(const QModelIndex &parent) const
if (rootItem == nullptr) {
return 0;
}
return rootItem->columnCount();
return 1;
}
}
@ -454,7 +519,7 @@ FolderModel::ModelData FolderModel::createModelData(const QString &path) const
QSqlDatabase db = DataBaseManagement::loadDatabase(path);
QSqlQuery selectQuery("select * from folder where id <> 1 order by parentId,name", db);
auto root = createRoot();
auto root = createRoot(db);
modelData = createModelData(selectQuery, root);
connectionName = db.connectionName();
@ -471,40 +536,14 @@ FolderModel::ModelData FolderModel::createModelData(QSqlQuery &sqlquery, FolderI
// add parent to the lookup
itemsLookup.insert(parent->id, parent);
QSqlRecord record = sqlquery.record();
int name = record.indexOf("name");
int path = record.indexOf("path");
int finished = record.indexOf("finished");
int completed = record.indexOf("completed");
int id = record.indexOf("id");
int parentId = record.indexOf("parentId");
int numChildren = record.indexOf("numChildren");
int firstChildHash = record.indexOf("firstChildHash");
int customImage = record.indexOf("customImage");
int type = record.indexOf("type");
int added = record.indexOf("added");
int updated = record.indexOf("updated");
auto columns = FolderColumns(sqlquery);
while (sqlquery.next()) {
QList<QVariant> data;
auto item = new FolderItem(folderDataFromQuery(sqlquery, columns));
data << sqlquery.value(name);
data << sqlquery.value(path);
data << sqlquery.value(finished);
data << sqlquery.value(completed);
data << sqlquery.value(numChildren);
data << sqlquery.value(firstChildHash);
data << sqlquery.value(customImage);
data << sqlquery.value(type);
data << sqlquery.value(added);
data << sqlquery.value(updated);
auto item = new FolderItem(data);
item->id = sqlquery.value(id).toULongLong();
item->id = sqlquery.value(columns.id).toULongLong();
// la inserci<63>n de hijos se hace de forma ordenada
FolderItem *parent = itemsLookup.value(sqlquery.value(parentId).toULongLong());
FolderItem *parent = itemsLookup.value(sqlquery.value(columns.parentId).toULongLong());
parent->appendChild(item);
// se a<>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
itemsLookup.insert(item->id, item);
@ -605,6 +644,35 @@ void FolderModel::updateFolderType(const QModelIndexList &list, YACReader::FileT
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Updated));
}
void FolderModel::updateTreeType(YACReader::FileType type)
{
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
auto item = rootItem;
std::function<void(FolderItem *, YACReader::FileType)> setType;
setType = [&setType](FolderItem *item, YACReader::FileType type) -> void {
item->setData(FolderModel::Type, QVariant::fromValue(type));
for (auto child : item->children()) {
setType(child, type);
}
};
setType(item, type);
if (!isSubfolder) {
DBHelper::updateDBType(db, type);
}
db.commit();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
{
QStringList result;

View File

@ -69,6 +69,7 @@ public:
void updateFolderCompletedStatus(const QModelIndexList &list, bool status);
void updateFolderFinishedStatus(const QModelIndexList &list, bool status);
void updateFolderType(const QModelIndexList &list, YACReader::FileType type);
void updateTreeType(YACReader::FileType type);
QStringList getSubfoldersNames(const QModelIndex &mi);
FolderModel *getSubfoldersModel(const QModelIndex &mi); // it creates a model that contains just the direct subfolders
@ -112,7 +113,6 @@ public:
};
bool isSubfolder;
public slots:
void deleteFolder(const QModelIndex &mi);
void updateFolderChildrenInfo(qulonglong folderId);

View File

@ -1668,6 +1668,21 @@ void DBHelper::updateFolderTreeType(qulonglong id, QSqlDatabase &db, YACReader::
}
}
void DBHelper::updateDBType(QSqlDatabase &db, YACReader::FileType type)
{
QSqlQuery updateFolderQuery(db);
updateFolderQuery.prepare("UPDATE folder "
"SET type = :type");
updateFolderQuery.bindValue(":type", static_cast<int>(type));
updateFolderQuery.exec();
QSqlQuery updateComicInfo(db);
updateComicInfo.prepare("UPDATE comic_info "
"SET type = :type");
updateComicInfo.bindValue(":type", static_cast<int>(type));
updateComicInfo.exec();
}
Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase &db)
{
QSqlQuery query(db);

View File

@ -91,6 +91,7 @@ public:
static QList<Label> getLabels(qulonglong libraryId);
static void updateFolderTreeType(qulonglong id, QSqlDatabase &db, YACReader::FileType type);
static void updateDBType(QSqlDatabase &db, YACReader::FileType type);
// load
static Folder loadFolder(qulonglong id, QSqlDatabase &db);

View File

@ -1,5 +1,4 @@
#include "library_creator.h"
#include "custom_widgets.h"
#include <QMutex>
#include <QDebug>
@ -25,6 +24,25 @@
using namespace std;
using namespace YACReader;
Folder rootFolder(QSqlDatabase &db)
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT * FROM folder WHERE id = 1");
selectQuery.exec();
auto root = Folder(1, 1, "root", "/");
if (!selectQuery.next()) {
root.type = YACReader::FileType::Comic;
return root;
}
root.type = selectQuery.value("type").value<YACReader::FileType>();
return root;
}
//--------------------------------------------------------------------------------
LibraryCreator::LibraryCreator(QSettings *settings)
: creation(false), partialUpdate(false), settings(settings)
@ -54,7 +72,6 @@ void LibraryCreator::updateFolder(const QString &source, const QString &target,
folderDestinationModelIndex = dest;
_currentPathFolders.clear();
_currentPathFolders.append(Folder::rootFolder());
QString relativeFolderPath = sourceFolder;
relativeFolderPath = relativeFolderPath.remove(QDir::cleanPath(source));
@ -83,6 +100,8 @@ void LibraryCreator::updateFolder(const QString &source, const QString &target,
return;
}
_currentPathFolders.append(rootFolder(db));
foreach (QString folderName, folders) {
if (folderName.isEmpty()) {
break;
@ -139,7 +158,6 @@ void LibraryCreator::run()
if (_mode == CREATOR) {
QLOG_INFO() << "Starting to create new library ( " << _source << "," << _target << ")";
_currentPathFolders.clear();
_currentPathFolders.append(Folder::rootFolder());
// se crean los directorios .yacreaderlibrary y .yacreaderlibrary/covers
QDir dir;
dir.mkpath(_target + "/covers");
@ -156,6 +174,8 @@ void LibraryCreator::run()
return;
}
_currentPathFolders.append(rootFolder(_database));
/*QSqlQuery pragma("PRAGMA foreign_keys = ON",_database);*/
_database.transaction();
// se crea la librería
@ -173,7 +193,6 @@ void LibraryCreator::run()
QLOG_INFO() << "Starting to update folder" << _sourceFolder << "in library ( " << _source << "," << _target << ")";
if (!partialUpdate) {
_currentPathFolders.clear();
_currentPathFolders.append(Folder::rootFolder());
QLOG_DEBUG() << "update whole library";
}
{
@ -197,6 +216,9 @@ void LibraryCreator::run()
creation = false;
return;
}
_currentPathFolders.append(rootFolder(_database));
QSqlQuery pragma("PRAGMA foreign_keys = ON", _database);
pragma.exec();
_database.transaction();

View File

@ -541,6 +541,75 @@ void LibraryWindow::createMenus()
selectedLibrary->addAction(actions.removeLibraryAction);
YACReader::addSperator(selectedLibrary);
auto setNormalAction = new QAction();
setNormalAction->setText(tr("comic"));
auto setMangaAction = new QAction();
setMangaAction->setText(tr("manga"));
auto setWesternMangaAction = new QAction();
setWesternMangaAction->setText(tr("western manga (left to right)"));
auto setWebComicAction = new QAction();
setWebComicAction->setText(tr("web comic"));
auto setYonkomaAction = new QAction();
setYonkomaAction->setText(tr("4koma (top to botom)"));
setNormalAction->setCheckable(true);
setMangaAction->setCheckable(true);
setWesternMangaAction->setCheckable(true);
setWebComicAction->setCheckable(true);
setYonkomaAction->setCheckable(true);
auto setupActions = [=](FileType type) {
setNormalAction->setChecked(false);
setMangaAction->setChecked(false);
setWesternMangaAction->setChecked(false);
setWebComicAction->setChecked(false);
setYonkomaAction->setChecked(false);
switch (type) {
case YACReader::FileType::Comic:
setNormalAction->setChecked(true);
break;
case YACReader::FileType::Manga:
setMangaAction->setChecked(true);
break;
case YACReader::FileType::WesternManga:
setWesternMangaAction->setChecked(true);
break;
case YACReader::FileType::WebComic:
setWebComicAction->setChecked(true);
break;
case YACReader::FileType::Yonkoma:
setYonkomaAction->setChecked(true);
break;
}
};
connect(setNormalAction, &QAction::triggered, this, [=]() { setCurrentLibraryAs(FileType::Comic); });
connect(setMangaAction, &QAction::triggered, this, [=]() { setCurrentLibraryAs(FileType::Manga); });
connect(setWesternMangaAction, &QAction::triggered, this, [=]() { setCurrentLibraryAs(FileType::WesternManga); });
connect(setWebComicAction, &QAction::triggered, this, [=]() { setCurrentLibraryAs(FileType::WebComic); });
connect(setYonkomaAction, &QAction::triggered, this, [=]() { setCurrentLibraryAs(FileType::Yonkoma); });
auto typeMenu = new QMenu(tr("Set type"), selectedLibrary);
connect(typeMenu, &QMenu::aboutToShow, this, [=]() {
auto rootIndex = foldersModel->index(0, 0);
auto folder = foldersModel->getFolder(rootIndex);
setupActions(folder.type);
});
selectedLibrary->addAction(typeMenu->menuAction());
YACReader::addSperator(selectedLibrary);
typeMenu->addAction(setNormalAction);
typeMenu->addAction(setMangaAction);
typeMenu->addAction(setWesternMangaAction);
typeMenu->addAction(setWebComicAction);
typeMenu->addAction(setYonkomaAction);
selectedLibrary->addAction(actions.rescanLibraryForXMLInfoAction);
YACReader::addSperator(selectedLibrary);
@ -565,6 +634,9 @@ void LibraryWindow::createMenus()
libraryMenu->addAction(removeLibraryAction);
libraryMenu->addSeparator();
libraryMenu->addAction(typeMenu);
libraryMenu->addSeparator();
libraryMenu->addAction(rescanLibraryForXMLInfoAction);
libraryMenu->addSeparator();
@ -727,6 +799,11 @@ void LibraryWindow::showErrorUpgradingLibrary(const QString &path)
QMessageBox::critical(this, tr("Upgrade failed"), tr("There were errors during library upgrade in: ") + path + "/library.ydb");
}
void LibraryWindow::setCurrentLibraryAs(FileType fileType)
{
foldersModel->updateTreeType(fileType);
}
void LibraryWindow::loadLibrary(const QString &name)
{
if (!libraries.isEmpty()) // si hay bibliotecas...

View File

@ -333,6 +333,7 @@ public slots:
void saveSelectedCoversTo();
void checkMaxNumLibraries();
void showErrorUpgradingLibrary(const QString &path);
void setCurrentLibraryAs(FileType fileType);
void prepareToCloseApp();
void closeApp();

View File

@ -71,13 +71,6 @@ Folder &Folder::operator=(const Folder &other)
return *this;
}
Folder Folder::rootFolder()
{
auto root = Folder(1, 1, "root", "/");
root.type = YACReader::FileType::Comic; // TODO: make this configurable by the user so it can set a default type for a library
return root;
}
Folder::Folder(const QString &folderName, const QString &folderPath)
: knownParent(false),
knownId(false),

View File

@ -41,8 +41,6 @@ public:
Folder(const Folder &folder);
Folder &operator=(const Folder &other);
static Folder rootFolder();
inline void setId(qulonglong sid)
{
id = sid;