Update FolderModel to support new functionality

This commit is contained in:
Luis Ángel San Martín 2022-10-09 11:24:33 +02:00
parent 0a00fd3020
commit 2e16dec51a
2 changed files with 178 additions and 16 deletions

View File

@ -54,26 +54,26 @@ void drawMacOSXFinishedFolderIcon()
#define ROOT 1 #define ROOT 1
FolderModel::FolderModel(QObject *parent) FolderModel::FolderModel(QObject *parent)
: QAbstractItemModel(parent), rootItem(0) : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr)
{ {
} }
FolderModel::FolderModel(QSqlQuery &sqlquery, QObject *parent) FolderModel::FolderModel(QSqlQuery &sqlquery, QObject *parent)
: QAbstractItemModel(parent), rootItem(0) : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr)
{ {
// lo m<>s probable es que el nodo ra<72>z no necesite tener informaci<63>n // lo m<>s probable es que el nodo ra<72>z no necesite tener informaci<63>n
QList<QVariant> rootData; QList<QVariant> rootData;
rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem) rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
rootItem = new FolderItem(rootData); rootItem = new FolderItem(rootData);
rootItem->id = ROOT; rootItem->id = ROOT;
rootItem->parentItem = 0; rootItem->parentItem = nullptr;
setupModelData(sqlquery, rootItem); setupModelData(sqlquery, rootItem);
// sqlquery.finish(); // sqlquery.finish();
} }
FolderModel::~FolderModel() FolderModel::~FolderModel()
{ {
if (rootItem != 0) if (rootItem != nullptr)
delete rootItem; delete rootItem;
} }
@ -81,9 +81,32 @@ int FolderModel::columnCount(const QModelIndex &parent) const
{ {
if (parent.isValid()) if (parent.isValid())
return static_cast<FolderItem *>(parent.internalPointer())->columnCount(); return static_cast<FolderItem *>(parent.internalPointer())->columnCount();
else else {
if (rootItem == nullptr) {
return 0;
}
return rootItem->columnCount(); return rootItem->columnCount();
} }
}
QHash<int, QByteArray> FolderModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[FinishedRole] = "is_finished";
roles[CompletedRole] = "is_completed";
roles[IdRole] = "id";
roles[MangaRole] = "is_manga";
roles[CoverPathRole] = "cover_path";
roles[FolderName] = "name";
return roles;
}
void FolderModel::reload()
{
setupModelData(_databasePath);
}
QVariant FolderModel::data(const QModelIndex &index, int role) const QVariant FolderModel::data(const QModelIndex &index, int role) const
{ {
@ -121,6 +144,10 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
#endif #endif
} }
if (role == FolderModel::FolderName) {
return item->data(FolderModel::Name);
}
if (role == FolderModel::CompletedRole) if (role == FolderModel::CompletedRole)
return item->data(FolderModel::Completed); return item->data(FolderModel::Completed);
@ -133,6 +160,9 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
if (role == FolderModel::IdRole) if (role == FolderModel::IdRole)
return item->id; return item->id;
if (role == FolderModel::CoverPathRole)
return getCoverUrlPathForComicHash(item->data(FirstChildHash).toString());
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
@ -150,6 +180,10 @@ Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const
QVariant FolderModel::headerData(int section, Qt::Orientation orientation, QVariant FolderModel::headerData(int section, Qt::Orientation orientation,
int role) const int role) const
{ {
if (rootItem == nullptr) {
return QVariant();
}
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return rootItem->data(section); return rootItem->data(section);
@ -196,10 +230,14 @@ int FolderModel::rowCount(const QModelIndex &parent) const
if (parent.column() > 0) if (parent.column() > 0)
return 0; return 0;
if (!parent.isValid()) if (!parent.isValid()) {
if (rootItem == nullptr) {
return 0;
}
parentItem = rootItem; parentItem = rootItem;
else } else {
parentItem = static_cast<FolderItem *>(parent.internalPointer()); parentItem = static_cast<FolderItem *>(parent.internalPointer());
}
return parentItem->childCount(); return parentItem->childCount();
} }
@ -207,17 +245,17 @@ int FolderModel::rowCount(const QModelIndex &parent) const
void FolderModel::setupModelData(QString path) void FolderModel::setupModelData(QString path)
{ {
beginResetModel(); beginResetModel();
if (rootItem != 0) if (rootItem != nullptr)
delete rootItem; // TODO comprobar que se libera bien la memoria delete rootItem; // TODO comprobar que se libera bien la memoria
rootItem = 0; rootItem = nullptr;
// inicializar el nodo ra<72>z // inicializar el nodo ra<72>z
QList<QVariant> rootData; QList<QVariant> rootData;
rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem) rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
rootItem = new FolderItem(rootData); rootItem = new FolderItem(rootData);
rootItem->id = ROOT; rootItem->id = ROOT;
rootItem->parentItem = 0; rootItem->parentItem = nullptr;
// cargar la base de datos // cargar la base de datos
_databasePath = path; _databasePath = path;
@ -235,6 +273,13 @@ void FolderModel::setupModelData(QString path)
endResetModel(); endResetModel();
} }
void FolderModel::fullSetup(QSqlQuery &sqlquery, FolderItem *parent)
{
rootItem = parent;
setupModelData(sqlquery, parent);
}
void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent) void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
{ {
// 64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64 // 64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64
@ -252,6 +297,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
int manga = record.indexOf("manga"); int manga = record.indexOf("manga");
int id = record.indexOf("id"); int id = record.indexOf("id");
int parentId = record.indexOf("parentId"); int parentId = record.indexOf("parentId");
int firstChildHash = record.indexOf("firstChildHash");
while (sqlquery.next()) { while (sqlquery.next()) {
QList<QVariant> data; QList<QVariant> data;
@ -261,6 +307,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
data << sqlquery.value(finished).toBool(); data << sqlquery.value(finished).toBool();
data << sqlquery.value(completed).toBool(); data << sqlquery.value(completed).toBool();
data << sqlquery.value(manga).toBool(); data << sqlquery.value(manga).toBool();
data << sqlquery.value(firstChildHash).toString();
auto item = new FolderItem(data); auto item = new FolderItem(data);
item->id = sqlquery.value(id).toULongLong(); item->id = sqlquery.value(id).toULongLong();
@ -286,6 +333,7 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent)
int manga = record.indexOf("manga"); int manga = record.indexOf("manga");
int id = record.indexOf("id"); int id = record.indexOf("id");
int parentId = record.indexOf("parentId"); int parentId = record.indexOf("parentId");
int firstChildHash = record.indexOf("firstChildHash");
while (sqlquery.next()) { while (sqlquery.next()) {
QList<QVariant> data; QList<QVariant> data;
@ -295,6 +343,7 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent)
data << sqlquery.value(finished).toBool(); data << sqlquery.value(finished).toBool();
data << sqlquery.value(completed).toBool(); data << sqlquery.value(completed).toBool();
data << sqlquery.value(manga).toBool(); data << sqlquery.value(manga).toBool();
data << sqlquery.value(firstChildHash).toString();
auto item = new FolderItem(data); auto item = new FolderItem(data);
item->id = sqlquery.value(id).toULongLong(); item->id = sqlquery.value(id).toULongLong();
@ -338,7 +387,7 @@ void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool
} }
QSqlDatabase::removeDatabase(connectionName); QSqlDatabase::removeDatabase(connectionName);
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed)); emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash));
} }
void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool status) void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool status)
@ -360,7 +409,7 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s
} }
QSqlDatabase::removeDatabase(connectionName); QSqlDatabase::removeDatabase(connectionName);
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed)); emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash));
} }
void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga) void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga)
@ -390,7 +439,7 @@ void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga)
} }
QSqlDatabase::removeDatabase(connectionName); QSqlDatabase::removeDatabase(connectionName);
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Manga)); emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash));
} }
QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi) QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
@ -417,6 +466,97 @@ QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
return result; return result;
} }
FolderModel *FolderModel::getSubfoldersModel(const QModelIndex &mi)
{
qulonglong id = 1;
FolderItem *parent = nullptr;
if (mi.isValid()) {
auto item = static_cast<FolderItem *>(mi.internalPointer());
parent = new FolderItem(item->getData(), item->parent());
id = parent->id = item->id;
}
if (id == 1) {
if (parent != nullptr) {
delete parent;
}
return this;
}
auto model = new FolderModel();
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlQuery selectQuery(db); // TODO check
selectQuery.prepare("SELECT * FROM folder WHERE parentId = :parentId and id <> 1");
selectQuery.bindValue(":parentId", id);
selectQuery.exec();
if (parent != nullptr) {
model->fullSetup(selectQuery, parent);
}
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
model->_databasePath = _databasePath;
model->isSubfolder = true;
return model;
}
Folder FolderModel::getFolder(const QModelIndex &mi)
{
auto folderItem = static_cast<FolderItem *>(mi.internalPointer());
auto name = folderItem->data(FolderModel::Name).toString();
auto parentItem = folderItem->parent();
auto folder = Folder(folderItem->id,
parentItem->id,
name,
folderItem->parent()->data(Columns::Path).toString() + "/" + name,
folderItem->data(Columns::Completed).toBool(),
folderItem->data(Columns::Finished).toBool(),
folderItem->data(Columns::Manga).toBool());
return folder;
}
QModelIndex FolderModel::getIndexFromFolder(const Folder &folder, const QModelIndex &parent)
{
if (rootItem == nullptr) {
return QModelIndex();
}
auto numRows = rowCount(parent);
for (auto i = 0; i < numRows; i++) {
auto modelIndex = index(i, 0, parent);
if (modelIndex.isValid()) {
auto folderItem = static_cast<FolderItem *>(modelIndex.internalPointer());
if (folderItem->id == folder.id) {
return modelIndex;
}
auto childModelIndex = getIndexFromFolder(folder, modelIndex);
if (childModelIndex.isValid()) {
auto folderItem = static_cast<FolderItem *>(childModelIndex.internalPointer());
if (folderItem->id == folder.id) {
return childModelIndex;
}
}
}
}
return QModelIndex();
}
void FolderModel::fetchMoreFromDB(const QModelIndex &parent) void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
{ {
FolderItem *item; FolderItem *item;
@ -531,6 +671,11 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod
return index(destRow, 0, parent); return index(destRow, 0, parent);
} }
QUrl FolderModel::getCoverUrlPathForComicHash(const QString &hash) const
{
return QUrl("file:" + _databasePath + "/covers/" + hash + ".jpg");
}
void FolderModel::deleteFolder(const QModelIndex &mi) void FolderModel::deleteFolder(const QModelIndex &mi)
{ {
beginRemoveRows(mi.parent(), mi.row(), mi.row()); beginRemoveRows(mi.parent(), mi.row(), mi.row());

View File

@ -7,9 +7,11 @@
#include <QVariant> #include <QVariant>
#include <QSqlQuery> #include <QSqlQuery>
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QUrl>
#include "yacreader_global.h" #include "folder.h"
#include "folder_query_result_processor.h" #include "folder_query_result_processor.h"
#include "yacreader_global.h"
class FolderItem; class FolderItem;
@ -54,8 +56,10 @@ public:
QModelIndex parent(const QModelIndex &index) const override; QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
// Convenience methods // Convenience methods
void reload();
void setupModelData(QString path); void setupModelData(QString path);
QString getDatabase(); QString getDatabase();
QString getFolderPath(const QModelIndex &folder); QString getFolderPath(const QModelIndex &folder);
@ -68,31 +72,44 @@ public:
void updateFolderManga(const QModelIndexList &list, bool manga); void updateFolderManga(const QModelIndexList &list, bool manga);
QStringList getSubfoldersNames(const QModelIndex &mi); QStringList getSubfoldersNames(const QModelIndex &mi);
FolderModel *getSubfoldersModel(const QModelIndex &mi);
Folder getFolder(const QModelIndex &mi);
QModelIndex getIndexFromFolder(const Folder &folder, const QModelIndex &parent = QModelIndex());
void fetchMoreFromDB(const QModelIndex &parent); void fetchMoreFromDB(const QModelIndex &parent);
QModelIndex addFolderAtParent(const QString &folderName, const QModelIndex &parent); QModelIndex addFolderAtParent(const QString &folderName, const QModelIndex &parent);
Q_INVOKABLE QUrl getCoverUrlPathForComicHash(const QString &hash) const;
enum Columns { enum Columns {
Name = 0, Name = 0,
Path = 1, Path = 1,
Finished = 2, Finished = 2,
Completed = 3, Completed = 3,
Manga = 4 Manga = 4,
FirstChildHash = 5
}; // id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL }; // id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL
enum Roles { enum Roles {
FinishedRole = Qt::UserRole + 1, FinishedRole = Qt::UserRole + 1,
CompletedRole, CompletedRole,
IdRole, IdRole,
MangaRole MangaRole,
CoverPathRole,
FolderName,
}; };
bool isSubfolder;
public slots: public slots:
void deleteFolder(const QModelIndex &mi); void deleteFolder(const QModelIndex &mi);
void updateFolderChildrenInfo(qulonglong folderId); void updateFolderChildrenInfo(qulonglong folderId);
private: private:
void fullSetup(QSqlQuery &sqlquery, FolderItem *parent);
void setupModelData(QSqlQuery &sqlquery, FolderItem *parent); void setupModelData(QSqlQuery &sqlquery, FolderItem *parent);
void updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent); void updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent);