diff --git a/YACReaderLibrary/comics_remover.cpp b/YACReaderLibrary/comics_remover.cpp index ef3fd009..7b4eadd7 100644 --- a/YACReaderLibrary/comics_remover.cpp +++ b/YACReaderLibrary/comics_remover.cpp @@ -5,8 +5,8 @@ #include "QsLog.h" -ComicsRemover::ComicsRemover(QModelIndexList & il, QList & ps, QObject *parent) - :QObject(parent),indexList(il), paths(ps) +ComicsRemover::ComicsRemover(QModelIndexList & il, QList & ps, qulonglong parentId, QObject *parent) + :QObject(parent),indexList(il), paths(ps), parentId(parentId) { } @@ -29,6 +29,7 @@ void ComicsRemover::process() } emit finished(); + emit removedItemsFromFolder(parentId); } diff --git a/YACReaderLibrary/comics_remover.h b/YACReaderLibrary/comics_remover.h index ff9d0a21..c844afbb 100644 --- a/YACReaderLibrary/comics_remover.h +++ b/YACReaderLibrary/comics_remover.h @@ -10,12 +10,13 @@ class ComicsRemover : public QObject { Q_OBJECT public: - explicit ComicsRemover(QModelIndexList & indexList, QList & paths, QObject *parent = 0); + explicit ComicsRemover(QModelIndexList & indexList, QList & paths, qulonglong parentId, QObject *parent = 0); signals: void remove(int); void removeError(); void finished(); + void removedItemsFromFolder(qulonglong); public slots: void process(); @@ -23,6 +24,7 @@ public slots: private: QModelIndexList indexList; QList paths; + qulonglong parentId; }; class FoldersRemover : public QObject diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index cb9efa17..33346196 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -981,7 +981,7 @@ void ComicModel::removeInTransaction(int row) endRemoveRows(); } - +/* void ComicModel::remove(ComicDB * comic, int row) { beginRemoveRows(QModelIndex(),row,row); @@ -997,7 +997,7 @@ void ComicModel::remove(ComicDB * comic, int row) QSqlDatabase::removeDatabase(_databasePath); endRemoveRows(); } - +*/ /*ComicDB TableModel::getComic(int row) { return getComic(index(row,0)); diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index bf517298..b23750c3 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -65,7 +65,7 @@ public: //setComicInfoForSelectedComis(QList list); -->inserta la información común para los comics seleccionados QVector setComicsRead(QList list,YACReaderComicReadStatus read); qint64 asignNumbers(QList list,int startingNumber); - void remove(ComicDB * comic, int row); + //void remove(ComicDB * comic, int row); void removeInTransaction(int row); void reload(const ComicDB & comic); void resetComicRating(const QModelIndex & mi); diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 8d18d478..fa5dfa0b 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -124,99 +124,101 @@ QSqlDatabase DataBaseManagement::loadDatabaseFromFile(QString filePath) bool DataBaseManagement::createTables(QSqlDatabase & database) { - bool success = true; + bool success = true; - //FOLDER (representa una carpeta en disco) - { - QSqlQuery queryFolder(database); - queryFolder.prepare("CREATE TABLE folder (" - "id INTEGER PRIMARY KEY," - "parentId INTEGER NOT NULL," - "name TEXT NOT NULL," - "path TEXT NOT NULL," - //new 7.1 fields - "finished BOOLEAN DEFAULT 0," //reading - "completed BOOLEAN DEFAULT 1," //collecting - //-- - "FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)"); - success = success && queryFolder.exec(); + { + //COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes) + QSqlQuery queryComicInfo(database); + queryComicInfo.prepare("CREATE TABLE comic_info (" + "id INTEGER PRIMARY KEY," + "title TEXT," - //COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes) - QSqlQuery queryComicInfo(database); - queryComicInfo.prepare("CREATE TABLE comic_info (" - "id INTEGER PRIMARY KEY," - "title TEXT," + "coverPage INTEGER DEFAULT 1," + "numPages INTEGER," - "coverPage INTEGER DEFAULT 1," - "numPages INTEGER," + "number INTEGER," + "isBis BOOLEAN," + "count INTEGER," - "number INTEGER," - "isBis BOOLEAN," - "count INTEGER," + "volume TEXT," + "storyArc TEXT," + "arcNumber INTEGER," + "arcCount INTEGER," - "volume TEXT," - "storyArc TEXT," - "arcNumber INTEGER," - "arcCount INTEGER," + "genere TEXT," - "genere TEXT," + "writer TEXT," + "penciller TEXT," + "inker TEXT," + "colorist TEXT," + "letterer TEXT," + "coverArtist TEXT," - "writer TEXT," - "penciller TEXT," - "inker TEXT," - "colorist TEXT," - "letterer TEXT," - "coverArtist TEXT," + "date TEXT," //dd/mm/yyyy --> se mostrará en 3 campos diferentes + "publisher TEXT," + "format TEXT," + "color BOOLEAN," + "ageRating BOOLEAN," - "date TEXT," //dd/mm/yyyy --> se mostrará en 3 campos diferentes - "publisher TEXT," - "format TEXT," - "color BOOLEAN," - "ageRating BOOLEAN," + "synopsis TEXT," + "characters TEXT," + "notes TEXT," - "synopsis TEXT," - "characters TEXT," - "notes TEXT," + "hash TEXT UNIQUE NOT NULL," + "edited BOOLEAN DEFAULT 0," + "read BOOLEAN DEFAULT 0," + //new 7.0 fields - "hash TEXT UNIQUE NOT NULL," - "edited BOOLEAN DEFAULT 0," - "read BOOLEAN DEFAULT 0," -//new 7.0 fields - - "hasBeenOpened BOOLEAN DEFAULT 0," - "rating INTEGER DEFAULT 0," - "currentPage INTEGER DEFAULT 1, " - "bookmark1 INTEGER DEFAULT -1, " - "bookmark2 INTEGER DEFAULT -1, " - "bookmark3 INTEGER DEFAULT -1, " - "brightness INTEGER DEFAULT -1, " - "contrast INTEGER DEFAULT -1, " - "gamma INTEGER DEFAULT -1, " -//new 7.1 fields - "comicVineID TEXT" + "hasBeenOpened BOOLEAN DEFAULT 0," + "rating INTEGER DEFAULT 0," + "currentPage INTEGER DEFAULT 1, " + "bookmark1 INTEGER DEFAULT -1, " + "bookmark2 INTEGER DEFAULT -1, " + "bookmark3 INTEGER DEFAULT -1, " + "brightness INTEGER DEFAULT -1, " + "contrast INTEGER DEFAULT -1, " + "gamma INTEGER DEFAULT -1, " + //new 7.1 fields + "comicVineID TEXT" - ")"); - success = success && queryComicInfo.exec(); - //queryComicInfo.finish(); + ")"); + success = success && queryComicInfo.exec(); + //queryComicInfo.finish(); - //COMIC (representa un cómic en disco, contiene el nombre de fichero) - QSqlQuery queryComic(database); - queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))"); - success = success && queryComic.exec(); - //queryComic.finish(); - //DB INFO - QSqlQuery queryDBInfo(database); - queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)"); - success = success && queryDBInfo.exec(); - //queryDBInfo.finish(); + //FOLDER (representa una carpeta en disco) + QSqlQuery queryFolder(database); + queryFolder.prepare("CREATE TABLE folder (" + "id INTEGER PRIMARY KEY," + "parentId INTEGER NOT NULL," + "name TEXT NOT NULL," + "path TEXT NOT NULL," + //new 7.1 fields + "finished BOOLEAN DEFAULT 0," //reading + "completed BOOLEAN DEFAULT 1," //collecting + //new 8.6 fields + "numChildren INTEGER," + "firstChildHash TEXT," + "customImage TEXT," + "FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)"); + success = success && queryFolder.exec(); - QSqlQuery query("INSERT INTO db_info (version) " - "VALUES ('" VERSION "')",database); - //query.finish(); + //COMIC (representa un cómic en disco, contiene el nombre de fichero) + QSqlQuery queryComic(database); + queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))"); + success = success && queryComic.exec(); + //queryComic.finish(); + //DB INFO + QSqlQuery queryDBInfo(database); + queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)"); + success = success && queryDBInfo.exec(); + //queryDBInfo.finish(); - //8.0> tables - success = success && DataBaseManagement::createV8Tables(database); + QSqlQuery query("INSERT INTO db_info (version) " + "VALUES ('" VERSION "')",database); + //query.finish(); + //8.0> tables + success = success && DataBaseManagement::createV8Tables(database); } return success; @@ -616,6 +618,19 @@ bool DataBaseManagement::addColumns(const QString &tableName, const QStringList return returnValue; } +bool DataBaseManagement::addConstraint(const QString &tableName, const QString &constraint, const QSqlDatabase &db) +{ + QString sql = "ALTER TABLE %1 ADD %2"; + bool returnValue = true; + + QSqlQuery alterTable(db); + alterTable.prepare(sql.arg(tableName).arg(constraint)); + alterTable.exec(); + returnValue = returnValue && (alterTable.numRowsAffected() > 0); + + return returnValue; +} + void DataBaseManagement::bindString(const QString & name, const QSqlRecord & record, QSqlQuery & query) { if(!record.value(name).isNull()) @@ -686,6 +701,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath) bool pre7 = false; bool pre7_1 = false; bool pre8 = false; + bool pre8_6 = false; if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"7.0.0")<0) pre7 = true; @@ -693,6 +709,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath) pre7_1 = true; if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"8.0.0")<0) pre8 = true; + if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"8.6.0")<0) + pre8_6 = true; QSqlDatabase db = loadDatabaseFromFile(fullPath); bool returnValue = false; @@ -745,6 +763,16 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath) { returnValue = returnValue && createV8Tables(db); } + + if(pre8_6) + { + QStringList columnDefs; + //TODO + columnDefs << "numChildren INTEGER"; + columnDefs << "firstChildHash TEXT"; + columnDefs << "customImage TEXT"; + //returnValue = returnValue && addColumns("folder", columnDefs, db); + } } db.close(); diff --git a/YACReaderLibrary/db/data_base_management.h b/YACReaderLibrary/db/data_base_management.h index 68540339..3d7139e2 100644 --- a/YACReaderLibrary/db/data_base_management.h +++ b/YACReaderLibrary/db/data_base_management.h @@ -38,6 +38,7 @@ private: static void bindValuesFromRecord(const QSqlRecord & record, QSqlQuery & query); static bool addColumns(const QString & tableName, const QStringList & columnDefs, const QSqlDatabase & db); + static bool addConstraint(const QString &tableName, const QString & constraint, const QSqlDatabase & db); public: DataBaseManagement(); diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index d1ea8c2f..457fb6b5 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -172,11 +172,12 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const if(role == FolderModel::FinishedRole) return item->data(FolderModel::Finished); + if(role == FolderModel::IdRole) + return item->id; + if (role != Qt::DisplayRole) return QVariant(); - - return item->data(index.column()); } //! [3] @@ -305,7 +306,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent) //el diccionario permitir� encontrar cualquier nodo del �rbol r�pidamente, de forma que a�adir un hijo a un padre sea O(1) items.clear(); //se a�ade el nodo 0 - items.insert(parent->id,parent); + items.insert(parent->id,parent); while (sqlquery.next()) { QList data; @@ -537,6 +538,7 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); newFolder.id = DBHelper::insert(&newFolder, db); + DBHelper::updateChildrenInfo(parentItem->id, db); QSqlDatabase::removeDatabase(_databasePath); int destRow = 0; @@ -575,11 +577,18 @@ void FolderModel::deleteFolder(const QModelIndex &mi) QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); DBHelper::removeFromDB(&f,db); + DBHelper::updateChildrenInfo(item->parent()->id, db); QSqlDatabase::removeDatabase(_databasePath); endRemoveRows(); } +void FolderModel::updateFolderChildrenInfo(qulonglong folderId) +{ + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + DBHelper::updateChildrenInfo(folderId, db); + QSqlDatabase::removeDatabase(_databasePath); +} //PROXY diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index 4d0f16bb..ae28a33c 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -127,11 +127,13 @@ public: enum Roles { FinishedRole = Qt::UserRole + 1, - CompletedRole + CompletedRole, + IdRole }; public slots: void deleteFolder(const QModelIndex & mi); + void updateFolderChildrenInfo(qulonglong folderId); private: void setupModelData( QSqlQuery &sqlquery, FolderItem *parent); diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 6b1d995d..3af2b8b4 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -14,6 +14,7 @@ #include +#include "reading_list_item.h" #include "library_item.h" #include "comic_db.h" #include "data_base_management.h" @@ -58,6 +59,38 @@ QList DBHelper::getFolderComicsFromLibrary(qulonglong libraryId, QSqlDatabase::removeDatabase(libraryPath); return list; } + +quint32 DBHelper::getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId) +{ + QString libraryPath = DBHelper::getLibraries().getPath(libraryId); + QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); + + quint32 result = 0; + + { + QSqlQuery selectQuery(db); + selectQuery.prepare("SELECT count(*) FROM folder WHERE parentId = :parentId and id <> 1"); + selectQuery.bindValue(":parentId", folderId); + selectQuery.exec(); + + result += selectQuery.record().value(0).toULongLong(); + } + + { + QSqlQuery selectQuery(db); + selectQuery.prepare("SELECT count(*) FROM comic c WHERE c.parentId = :parentId"); + selectQuery.bindValue(":parentId", folderId); + selectQuery.exec(); + + result += selectQuery.record().value(0).toULongLong(); + } + + db.close(); + QSqlDatabase::removeDatabase(libraryPath); + + return result; +} + qulonglong DBHelper::getParentFromComicFolderId(qulonglong libraryId, qulonglong id) { QString libraryPath = DBHelper::getLibraries().getPath(libraryId); @@ -131,9 +164,9 @@ QString DBHelper::getLibraryName(int id) void DBHelper::removeFromDB(LibraryItem * item, QSqlDatabase & db) { if(item->isDir()) - DBHelper::removeFromDB(dynamic_cast(item),db); + DBHelper::removeFromDB(dynamic_cast(item),db); else - DBHelper::removeFromDB(dynamic_cast(item),db); + DBHelper::removeFromDB(dynamic_cast(item),db); } void DBHelper::removeFromDB(Folder * folder, QSqlDatabase & db) { @@ -376,6 +409,51 @@ void DBHelper::update(const Folder & folder, QSqlDatabase &db) updateFolderInfo.exec(); } +void DBHelper::updateChildrenInfo(const Folder & folder, QSqlDatabase & db) +{ + QSqlQuery updateFolderInfo(db); + updateFolderInfo.prepare("UPDATE folder SET " + "numChildren = :numChildren, " + "firstChildHash = :firstChildHash " + "WHERE id = :id "); + updateFolderInfo.bindValue(":numChildren", folder.getNumChildren()); + updateFolderInfo.bindValue(":firstChildHash", folder.getFirstChildHash()); + updateFolderInfo.bindValue(":id", folder.id); + updateFolderInfo.exec(); +} + +void DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase & db) +{ + QList subfolders = DBHelper::getFoldersFromParent(folderId,db,false); + QList comics = DBHelper::getComicsFromParent(folderId,db,true); + + ComicDB * firstComic = NULL; + if(comics.count() > 0) + firstComic = static_cast(comics.first()); + + QSqlQuery updateFolderInfo(db); + updateFolderInfo.prepare("UPDATE folder SET " + "numChildren = :numChildren, " + "firstChildHash = :firstChildHash " + "WHERE id = :id "); + updateFolderInfo.bindValue(":numChildren", subfolders.count() + comics.count()); + updateFolderInfo.bindValue(":firstChildHash", firstComic != NULL ? firstComic->info.hash : ""); + updateFolderInfo.bindValue(":id", folderId); + updateFolderInfo.exec(); +} + +void DBHelper::updateChildrenInfo(QSqlDatabase & db) +{ + QSqlQuery selectQuery(db); //TODO check + selectQuery.prepare("SELECT id FROM folder"); + selectQuery.exec(); + + while (selectQuery.next()) + { + DBHelper::updateChildrenInfo(selectQuery.record().value(0).toULongLong(), db); + } +} + void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo) { QString libraryPath = DBHelper::getLibraries().getPath(libraryId); @@ -548,6 +626,7 @@ qulonglong DBHelper::insert(Folder * folder, QSqlDatabase & db) query.bindValue(":name", folder->name); query.bindValue(":path", folder->path); query.exec(); + return query.lastInsertId().toULongLong(); } @@ -575,6 +654,7 @@ qulonglong DBHelper::insert(ComicDB * comic, QSqlDatabase & db) query.bindValue(":name", comic->name); query.bindValue(":path", comic->path); query.exec(); + return query.lastInsertId().toULongLong(); } @@ -701,7 +781,13 @@ QList DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDat data << record.value(i); //TODO sort by sort indicator and name currentItem = new Folder(record.value("id").toULongLong(),record.value("parentId").toULongLong(),record.value("name").toString(),record.value("path").toString()); - int lessThan = 0; + + if(!record.value("numChildren").isNull() && record.value("numChildren").isValid()) + currentItem->setNumChildren(record.value("numChildren").toInt()); + currentItem->setFirstChildHash(record.value("firstChildHash").toString()); + currentItem->setCustomImage(record.value("customImage").toString()); + + int lessThan = 0; if(list.isEmpty() || !sort) list.append(currentItem); @@ -876,6 +962,59 @@ QList DBHelper::getComicsFromParent(qulonglong parentId, QSqlData return list; } +QList DBHelper::getLabelItems(qulonglong libraryId) +{ + QString libraryPath = DBHelper::getLibraries().getPath(libraryId); + QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); + + QSqlQuery selectQuery("SELECT * FROM label ORDER BY ordering,name",db); //TODO add some kind of + QList labels; + + while(selectQuery.next()) + { + QSqlRecord record = selectQuery.record(); + LabelItem *item = new LabelItem(QList() + << record.value("name") + << record.value("color") + << record.value("id") + << record.value("ordering")); + + if(labels.isEmpty()) + { + labels << item; + } + else + { + int i = 0; + + while (i < labels.count() && (labels.at(i)->colorid() < item->colorid()) ) + i++; + + if(i < labels.count()) + { + if(labels.at(i)->colorid() == item->colorid()) //sort by name + { + while( i < labels.count() && labels.at(i)->colorid() == item->colorid() && naturalSortLessThanCI(labels.at(i)->name(),item->name())) + i++; + } + } + if(i >= labels.count()) + { + labels << item; + } + else + { + labels.insert(i,item); + } + } + } + + db.close(); + QSqlDatabase::removeDatabase(libraryPath); + + return labels; +} + //loads Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db) { @@ -897,6 +1036,11 @@ Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db) //new 7.1 folder.setFinished(record.value("finished").toBool()); folder.setCompleted(record.value("completed").toBool()); + //new 8.6 + if(!record.value("numChildren").isNull() && record.value("numChildren").isValid()) + folder.setNumChildren(record.value("numChildren").toInt()); + folder.setFirstChildHash(record.value("firstChildHash").toString()); + folder.setCustomImage(record.value("customImage").toString()); } return folder; @@ -925,6 +1069,12 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql //new 7.1 folder.setFinished(record.value("finished").toBool()); folder.setCompleted(record.value("completed").toBool()); + //new 8.6 + if(!record.value("numChildren").isNull() && record.value("numChildren").isValid()) + folder.setNumChildren(record.value("numChildren").toInt()); + folder.setFirstChildHash(record.value("firstChildHash").toString()); + folder.setCustomImage(record.value("customImage").toString()); + QLOG_DEBUG() << "FOUND!!"; } diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h index 5dee01d6..bb9307bb 100644 --- a/YACReaderLibrary/db_helper.h +++ b/YACReaderLibrary/db_helper.h @@ -9,6 +9,7 @@ class QString; class ComicDB; class Folder; class LibraryItem; +class LabelItem; class QSqlDatabase; class ComicInfo; class QSqlRecord; @@ -23,6 +24,7 @@ public: static QList getFolderSubfoldersFromLibrary(qulonglong libraryId, qulonglong folderId); static QList getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId); static QList getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId, bool sort); + static quint32 getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId); static qulonglong getParentFromComicFolderId(qulonglong libraryId, qulonglong id); static ComicDB getComicInfo(qulonglong libraryId, qulonglong id); static QList getSiblings(qulonglong libraryId, qulonglong parentId); @@ -32,9 +34,9 @@ public: //objects management //deletes - static void removeFromDB(LibraryItem * item, QSqlDatabase & db); - static void removeFromDB(Folder * folder, QSqlDatabase & db); - static void removeFromDB(ComicDB * comic, QSqlDatabase & db); + static void removeFromDB(LibraryItem * item, QSqlDatabase & db); + static void removeFromDB(Folder * folder, QSqlDatabase & db); + static void removeFromDB(ComicDB * comic, QSqlDatabase & db); static void removeLabelFromDB(qulonglong id, QSqlDatabase & db); static void removeListFromDB(qulonglong id, QSqlDatabase & db); //logic deletes @@ -42,8 +44,8 @@ public: static void deleteComicsFromLabel(const QList & comicsList, qulonglong labelId, QSqlDatabase & db); static void deleteComicsFromReadingList(const QList & comicsList, qulonglong readingListId, QSqlDatabase & db); //inserts - static qulonglong insert(Folder * folder, QSqlDatabase & db); - static qulonglong insert(ComicDB * comic, QSqlDatabase & db); + static qulonglong insert(Folder * folder, QSqlDatabase & db); + static qulonglong insert(ComicDB * comic, QSqlDatabase & db); static qulonglong insertLabel(const QString & name, YACReader::LabelColors color , QSqlDatabase & db); static qulonglong insertReadingList(const QString & name, QSqlDatabase & db); static qulonglong insertReadingSubList(const QString & name, qulonglong parentId, int ordering, QSqlDatabase & db); @@ -56,6 +58,9 @@ public: static void update(ComicInfo * comicInfo, QSqlDatabase & db); static void updateRead(ComicInfo * comicInfo, QSqlDatabase & db); static void update(const Folder & folder, QSqlDatabase & db); + static void updateChildrenInfo(const Folder & folder, QSqlDatabase & db); + static void updateChildrenInfo(qulonglong folderId, QSqlDatabase & db); + static void updateChildrenInfo(QSqlDatabase & db); static void updateProgress(qulonglong libraryId,const ComicInfo & comicInfo); static void updateReadingRemoteProgress(const ComicInfo & comicInfo, QSqlDatabase & db); static void updateFromRemoteClient(qulonglong libraryId,const ComicInfo & comicInfo); @@ -69,7 +74,8 @@ public: static QList getFoldersFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true); static QList getSortedComicsFromParent(qulonglong parentId, QSqlDatabase & db); static QList getComicsFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true); - //load + static QList getLabelItems(qulonglong libraryId); + //load static Folder loadFolder(qulonglong id, QSqlDatabase & db); static Folder loadFolder(const QString & folderName, qulonglong parentId, QSqlDatabase & db); static ComicDB loadComic(qulonglong id, QSqlDatabase & db); diff --git a/YACReaderLibrary/headless/main.cpp b/YACReaderLibrary/headless/main.cpp index 5888208f..3ac8801a 100644 --- a/YACReaderLibrary/headless/main.cpp +++ b/YACReaderLibrary/headless/main.cpp @@ -9,6 +9,8 @@ #include "console_ui_library_creator.h" +#include + #include "QsLog.h" #include "QsLogDest.h" @@ -118,7 +120,7 @@ int main( int argc, char ** argv ) QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::tr("\nYACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary")); parser.addHelpOption(); - parser.addVersionOption(); + const QCommandLineOption versionOption = parser.addVersionOption(); parser.addPositionalArgument("command", "The command to execute. [start, create-library, update-library, add-library, remove-library, list-libraries]"); parser.parse(QCoreApplication::arguments()); @@ -126,6 +128,13 @@ int main( int argc, char ** argv ) const QStringList args = parser.positionalArguments(); const QString command = args.isEmpty() ? QString() : args.first(); + if(parser.isSet(versionOption)) + { + qout << "YACReaderLibraryServer" << " " << VERSION << endl; + + return 0; + } + if(command == "start") { QString destLog = YACReader::getSettingsPath()+"/yacreaderlibrary.log"; diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 0fa37213..b788c19f 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -162,6 +162,9 @@ void LibraryCreator::run() _database.transaction(); //se crea la librería create(QDir(_source)); + + DBHelper::updateChildrenInfo(_database); + _database.commit(); _database.close(); QSqlDatabase::removeDatabase(_database.connectionName()); @@ -199,6 +202,12 @@ void LibraryCreator::run() { update(QDir(_source)); } + + if(partialUpdate) + DBHelper::updateChildrenInfo(folderDestinationModelIndex.data(FolderModel::IdRole).toULongLong(),_database); + else + DBHelper::updateChildrenInfo(_database); + _database.commit(); _database.close(); QSqlDatabase::removeDatabase(_target); @@ -243,7 +252,7 @@ qulonglong LibraryCreator::insertFolders() if(!(i->knownId)) { i->setFather(currentId); - currentId = DBHelper::insert(&(*i),_database);//insertFolder(currentId,*i); + currentId = DBHelper::insert(&(*i),_database);//insertFolder(currentId,*i); i->setId(currentId); } else diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 9def54cf..8196aef1 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -1233,7 +1233,7 @@ void LibraryWindow::loadLibrary(const QString & name) if(d.exists(path+"/library.ydb")) { - QSqlDatabase db = DataBaseManagement::loadDatabase(path); + QSqlDatabase db = DataBaseManagement::loadDatabase(path); manageOpeningLibraryError(db.lastError().databaseText() + "-" + db.lastError().driverText()); //será possible renombrar y borrar estas bibliotecas renameLibraryAction->setEnabled(true); @@ -2420,7 +2420,7 @@ void LibraryWindow::deleteComicsFromDisk() QLOG_TRACE() << comic.parentId; } - ComicsRemover * remover = new ComicsRemover(indexList,paths); + ComicsRemover * remover = new ComicsRemover(indexList,paths,comics.at(0).parentId); QThread * thread = NULL; thread = new QThread(this); @@ -2433,6 +2433,8 @@ void LibraryWindow::deleteComicsFromDisk() connect(remover, SIGNAL(remove(int)), comicsModel, SLOT(remove(int))); connect(remover, SIGNAL(removeError()),this,SLOT(setRemoveError())); connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction())); + connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction())); + connect(remover, SIGNAL(removedItemsFromFolder(qulonglong)), foldersModel, SLOT(updateFolderChildrenInfo(qulonglong))); connect(remover, SIGNAL(finished()),this,SLOT(checkEmptyFolder())); connect(remover, SIGNAL(finished()),this,SLOT(checkRemoveError())); diff --git a/YACReaderLibrary/server/controllers/comiccontroller.cpp b/YACReaderLibrary/server/controllers/comiccontroller.cpp index abe7dbc4..a77290a4 100644 --- a/YACReaderLibrary/server/controllers/comiccontroller.cpp +++ b/YACReaderLibrary/server/controllers/comiccontroller.cpp @@ -79,7 +79,7 @@ void ComicController::service(HttpRequest& request, HttpResponse& response) session.setCurrentComic(comic.id, comicFile); } - response.setHeader("Content-Type", "plain/text; charset=utf-8"); + response.setHeader("Content-Type", "text/plain; charset=utf-8"); //TODO this field is not used by the client! response.writeText(QString("library:%1\r\n").arg(libraryName)); response.writeText(QString("libraryId:%1\r\n").arg(libraryId)); diff --git a/YACReaderLibrary/server/controllers/comicdownloadinfocontroller.cpp b/YACReaderLibrary/server/controllers/comicdownloadinfocontroller.cpp index aeab979a..8143ec82 100644 --- a/YACReaderLibrary/server/controllers/comicdownloadinfocontroller.cpp +++ b/YACReaderLibrary/server/controllers/comicdownloadinfocontroller.cpp @@ -10,7 +10,7 @@ ComicDownloadInfoController::ComicDownloadInfoController() {} void ComicDownloadInfoController::service(HttpRequest& request, HttpResponse& response) { - response.setHeader("Content-Type", "plain/text; charset=utf-8"); + response.setHeader("Content-Type", "text/plain; charset=utf-8"); QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); diff --git a/YACReaderLibrary/server/controllers/foldercontentcontroller.cpp b/YACReaderLibrary/server/controllers/foldercontentcontroller.cpp new file mode 100644 index 00000000..8d88c96a --- /dev/null +++ b/YACReaderLibrary/server/controllers/foldercontentcontroller.cpp @@ -0,0 +1,70 @@ +#include "foldercontentcontroller.h" + +#include + +#include "db_helper.h" +#include "comic_db.h" +#include "folder.h" + +#include "qnaturalsorting.h" + +#include +using namespace std; + +struct LibraryItemSorter +{ + bool operator()(const LibraryItem * a,const LibraryItem * b) const + { + return naturalSortLessThanCI(a->name,b->name); + } +}; + +FolderContentController::FolderContentController() {} + +void FolderContentController::service(HttpRequest& request, HttpResponse& response) +{ + response.setHeader("Content-Type", "text/plain; charset=utf-8"); + + QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); + QStringList pathElements = path.split('/'); + int libraryId = pathElements.at(2).toInt(); + qulonglong parentId = pathElements.at(4).toULongLong(); + + serviceContent(libraryId, parentId, response); + + response.writeText("",true); +} + +void FolderContentController::serviceContent(const int &library, const qulonglong &folderId, HttpResponse &response) +{ + clock_t begin = clock(); + + QList folderContent = DBHelper::getFolderSubfoldersFromLibrary(library,folderId); + QList folderComics = DBHelper::getFolderComicsFromLibrary(library,folderId); + + folderContent.append(folderComics); + qSort(folderContent.begin(),folderContent.end(),LibraryItemSorter()); + + folderComics.clear(); + + ComicDB * currentComic; + Folder * currentFolder; + for(QList::const_iterator itr = folderContent.constBegin();itr!=folderContent.constEnd();itr++) + { + if((*itr)->isDir()) + { + currentFolder = (Folder *)(*itr); + response.writeText(QString("f\t%1\t%2\t%3\t%4\t%5\r\n").arg(library).arg(currentFolder->id).arg(currentFolder->name).arg(currentFolder->getNumChildren()).arg(currentFolder->getFirstChildHash())); + } + else + { + currentComic = (ComicDB *)(*itr); + response.writeText(QString("c\t%1\t%2\t%3\t%4\t%5\r\n").arg(library).arg(currentComic->id).arg(currentComic->getFileName()).arg(currentComic->getFileSize()).arg(currentComic->info.hash)); + } + } + + clock_t end = clock(); + double msecs = double(end - begin); + + response.writeText(QString("%1ms").arg(msecs)); +} diff --git a/YACReaderLibrary/server/controllers/foldercontentcontroller.h b/YACReaderLibrary/server/controllers/foldercontentcontroller.h new file mode 100644 index 00000000..aa986042 --- /dev/null +++ b/YACReaderLibrary/server/controllers/foldercontentcontroller.h @@ -0,0 +1,22 @@ +#ifndef FOLDERCONTENTCONTROLLER_H +#define FOLDERCONTENTCONTROLLER_H + +#include "httprequest.h" +#include "httpresponse.h" +#include "httprequesthandler.h" + +class FolderContentController : public HttpRequestHandler { + Q_OBJECT + Q_DISABLE_COPY(FolderContentController); +public: + /** Constructor */ + FolderContentController(); + + /** Generates the response */ + void service(HttpRequest& request, HttpResponse& response); + +private: + void serviceContent(const int &library, const qulonglong &folderId, HttpResponse &response); +}; + +#endif // FOLDERCONTENTCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/foldercontroller.cpp b/YACReaderLibrary/server/controllers/foldercontroller.cpp index 30aa657f..3ec241a2 100644 --- a/YACReaderLibrary/server/controllers/foldercontroller.cpp +++ b/YACReaderLibrary/server/controllers/foldercontroller.cpp @@ -167,11 +167,11 @@ void FolderController::service(HttpRequest& request, HttpResponse& response) { t.setVariable(QString("element%1.class").arg(i),"folder"); - QList children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id); - if(children.length()>0) + const Folder * folder = static_cast(item); + + if(folder->getFirstChildHash().length()>0) { - const ComicDB * comic = static_cast(children.at(0)); - t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(comic->info.hash)); + t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(folder->getFirstChildHash())); } else t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png"); diff --git a/YACReaderLibrary/server/controllers/folderinfocontroller.cpp b/YACReaderLibrary/server/controllers/folderinfocontroller.cpp index 0d8f333f..6aaf9029 100644 --- a/YACReaderLibrary/server/controllers/folderinfocontroller.cpp +++ b/YACReaderLibrary/server/controllers/folderinfocontroller.cpp @@ -12,7 +12,7 @@ FolderInfoController::FolderInfoController() {} void FolderInfoController::service(HttpRequest& request, HttpResponse& response) { - response.setHeader("Content-Type", "plain/text; charset=utf-8"); + response.setHeader("Content-Type", "text/plain; charset=utf-8"); QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); diff --git a/YACReaderLibrary/server/controllers/tagscontroller.cpp b/YACReaderLibrary/server/controllers/tagscontroller.cpp new file mode 100644 index 00000000..d1aa877f --- /dev/null +++ b/YACReaderLibrary/server/controllers/tagscontroller.cpp @@ -0,0 +1,30 @@ +#include "tagscontroller.h" + +#include "db_helper.h" +#include "yacreader_libraries.h" + +#include "reading_list_item.h" +#include "../static.h" +#include "yacreader_global.h" + +#include "QsLog.h" + +TagsController::TagsController() {} + +void TagsController::service(HttpRequest& request, HttpResponse& response) +{ + response.setHeader("Content-Type", "text/plain; charset=utf-8"); + + QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); + QStringList pathElements = path.split('/'); + int libraryId = pathElements.at(2).toInt(); + + QList tags = DBHelper::getLabelItems(libraryId); + + foreach(LabelItem * tag, tags) + { + response.writeText(QString("%1\t%2\t%3\r\n").arg(tag->getId()).arg(tag->name()).arg(labelColorToRGBString(tag->colorid()))); + } + + response.writeText("",true); +} diff --git a/YACReaderLibrary/server/controllers/tagscontroller.h b/YACReaderLibrary/server/controllers/tagscontroller.h new file mode 100644 index 00000000..eb97ee04 --- /dev/null +++ b/YACReaderLibrary/server/controllers/tagscontroller.h @@ -0,0 +1,22 @@ +#ifndef TAGSCONTROLLER_H +#define TAGSCONTROLLER_H + +#include "httprequest.h" +#include "httpresponse.h" +#include "httprequesthandler.h" + + + +class TagsController : public HttpRequestHandler { + Q_OBJECT + Q_DISABLE_COPY(TagsController) +public: + + /** Constructor */ + TagsController(); + + /** Generates the response */ + void service(HttpRequest& request, HttpResponse& response); +}; + +#endif // TAGSCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/versioncontroller.cpp b/YACReaderLibrary/server/controllers/versioncontroller.cpp new file mode 100644 index 00000000..341923c7 --- /dev/null +++ b/YACReaderLibrary/server/controllers/versioncontroller.cpp @@ -0,0 +1,10 @@ +#include "versioncontroller.h" + +VersionController::VersionController() {} + +void VersionController::service(HttpRequest& request, HttpResponse& response) +{ + Q_UNUSED(request); + + response.writeText(SERVER_VERSION_NUMBER,true); +} diff --git a/YACReaderLibrary/server/controllers/versioncontroller.h b/YACReaderLibrary/server/controllers/versioncontroller.h new file mode 100644 index 00000000..d645b110 --- /dev/null +++ b/YACReaderLibrary/server/controllers/versioncontroller.h @@ -0,0 +1,21 @@ +#ifndef VERSIONCONTROLLER_H +#define VERSIONCONTROLLER_H + +#include "httprequest.h" +#include "httpresponse.h" +#include "httprequesthandler.h" + +#include + +class VersionController : public HttpRequestHandler { + Q_OBJECT + Q_DISABLE_COPY(VersionController); +public: + /** Constructor */ + VersionController(); + + /** Generates the response */ + void service(HttpRequest& request, HttpResponse& response); +}; + +#endif // VERSIONCONTROLLER_H diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index 66b03413..d9a98162 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -22,6 +22,9 @@ #include "controllers/errorcontroller.h" #include "controllers/comicdownloadinfocontroller.h" #include "controllers/synccontroller.h" +#include "controllers/versioncontroller.h" +#include "controllers/foldercontentcontroller.h" +#include "controllers/tagscontroller.h" #include "db_helper.h" #include "yacreader_libraries.h" @@ -105,6 +108,9 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) { QRegExp cover("/library/.+/cover/[0-9a-f]+.jpg"); //get comic cover (navigation) QRegExp comicPage("/library/.+/comic/[0-9]+/page/[0-9]+/?"); //get comic page QRegExp comicPageRemote("/library/.+/comic/[0-9]+/page/[0-9]+/remote?"); //get comic page (remote reading) + QRegExp serverVersion("/version/?"); + QRegExp folderContent("/library/.+/folder/[0-9]+/content/?"); + QRegExp tags("/library/.+/tags/?"); QRegExp sync("/sync"); @@ -122,8 +128,14 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) { } else { - if(sync.exactMatch(path)) + if(serverVersion.exactMatch(path)) + { + VersionController().service(request, response); + } + else if(sync.exactMatch(path)) + { SyncController().service(request, response); + } else { //se comprueba que la sesión sea la correcta con el fin de evitar accesos no autorizados @@ -161,6 +173,14 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) { { UpdateComicController().service(request, response); } + else if(folderContent.exactMatch(path)) + { + FolderContentController().service(request, response); + } + else if(tags.exactMatch(path)) + { + TagsController().service(request, response); + } } else { diff --git a/YACReaderLibrary/server/server.pri b/YACReaderLibrary/server/server.pri index 4be20612..5b903135 100644 --- a/YACReaderLibrary/server/server.pri +++ b/YACReaderLibrary/server/server.pri @@ -15,7 +15,11 @@ HEADERS += \ $$PWD/controllers/covercontroller.h \ $$PWD/controllers/updatecomiccontroller.h \ $$PWD/controllers/comicdownloadinfocontroller.h \ - $$PWD/controllers/synccontroller.h + $$PWD/controllers/synccontroller.h \ + #v2 + $$PWD/controllers/versioncontroller.h \ + $$PWD/controllers/foldercontentcontroller.h \ + $$PWD/controllers/tagscontroller.h SOURCES += \ $$PWD/static.cpp \ @@ -31,8 +35,14 @@ SOURCES += \ $$PWD/controllers/covercontroller.cpp \ $$PWD/controllers/updatecomiccontroller.cpp \ $$PWD/controllers/comicdownloadinfocontroller.cpp \ - $$PWD/controllers/synccontroller.cpp + $$PWD/controllers/synccontroller.cpp \ + #v2 + $$PWD/controllers/versioncontroller.cpp \ + $$PWD/controllers/foldercontentcontroller.cpp \ + $$PWD/controllers/tagscontroller.cpp include(lib/bfLogging/bfLogging.pri) include(lib/bfHttpServer/bfHttpServer.pri) include(lib/bfTemplateEngine/bfTemplateEngine.pri) + +DEFINES += SERVER_VERSION_NUMBER=\\\"2.0\\\" diff --git a/common/comic_db.cpp b/common/comic_db.cpp index 2f88ee58..b7bbf7d8 100644 --- a/common/comic_db.cpp +++ b/common/comic_db.cpp @@ -16,7 +16,7 @@ ComicDB::ComicDB(const ComicDB &comicDB) operator=(comicDB); } -bool ComicDB::isDir() +bool ComicDB::isDir() const { return false; } diff --git a/common/comic_db.h b/common/comic_db.h index 5850de65..e4cfc6b9 100644 --- a/common/comic_db.h +++ b/common/comic_db.h @@ -210,7 +210,7 @@ public: ComicDB(); ComicDB(const ComicDB & comicDB); - bool isDir(); + bool isDir() const; bool _hasCover; diff --git a/common/folder.cpp b/common/folder.cpp index 4f08207e..4eb672dd 100644 --- a/common/folder.cpp +++ b/common/folder.cpp @@ -1,6 +1,23 @@ - #include "folder.h" +Folder::Folder() + :knownParent(false), + knownId(false), + numChildren(-1) +{} + +Folder::Folder(qulonglong folderId, qulonglong parentId, const QString &folderName, const QString &folderPath) + :knownParent(true), + knownId(true), + numChildren(-1) +{ + this->id = folderId; + this->parentId = parentId; + this->name = folderName; + this->path = folderPath; +} + + Folder::Folder(const Folder &folder) { operator=(folder); @@ -17,3 +34,11 @@ Folder &Folder::operator =(const Folder &other) return *this; } +Folder::Folder(const QString & folderName, const QString & folderPath) + :knownParent(false), + knownId(false), + numChildren(-1) +{ + this->name = folderName; + this->path = folderPath; +} diff --git a/common/folder.h b/common/folder.h index 2dc7002a..c16936ef 100644 --- a/common/folder.h +++ b/common/folder.h @@ -11,22 +11,86 @@ public: bool knownParent; bool knownId; - Folder():knownParent(false), knownId(false){} - Folder(qulonglong sid, qulonglong pid,QString fn, QString fp):knownParent(true), knownId(true){id = sid; parentId = pid;name = fn; path = fp;} - Folder(QString fn, QString fp):knownParent(false), knownId(false){name = fn; path = fp;} + Folder(); + Folder(qulonglong folderId, qulonglong parentId,const QString & folderName, const QString & folderPath); + Folder(const QString & folderName, const QString & folderPath); Folder(const Folder &folder); Folder &operator =(const Folder & other); - void setId(qulonglong sid){id = sid;knownId = true;} - void setFather(qulonglong pid){parentId = pid;knownParent = true;} - bool isDir() {return true;} - bool isFinished() const {return finished;} - bool isCompleted() const {return completed;} - void setFinished(bool b) {finished = b;} - void setCompleted(bool b) {completed = b;} + + inline void setId(qulonglong sid) + { + id = sid; + knownId = true; + } + inline void setFather(qulonglong pid) + { + parentId = pid; + knownParent = true; + } + + inline bool isDir() const + { + return true; + } + + inline bool isFinished() const + { + return finished; + } + + inline bool isCompleted() const + { + return completed; + } + + inline void setFinished(bool b) + { + finished = b; + } + + inline void setCompleted(bool b) + { + completed = b; + } + + inline qint32 getNumChildren() const + { + return numChildren; + } + + inline void setNumChildren(const qint32 v) + { + numChildren = v; + } + + inline QString getFirstChildHash() const + { + return firstChildHash; + } + + inline void setFirstChildHash(const QString & v) + { + firstChildHash = v; + } + + inline QString getCustomImage() const + { + return customImage; + } + + inline void setCustomImage(const QString & s) + { + customImage = s; + } private: bool finished; bool completed; + + qint32 numChildren; //-1 for unknown number of children + QString firstChildHash; //empty for unknown first child + QString customImage; //empty for none custom image + }; #endif diff --git a/common/library_item.h b/common/library_item.h index 5ca1958e..dcb08a6c 100644 --- a/common/library_item.h +++ b/common/library_item.h @@ -7,7 +7,7 @@ class LibraryItem : public QObject { Q_OBJECT public: - virtual bool isDir() = 0; + virtual bool isDir() const = 0; LibraryItem & operator=(const LibraryItem & other); QString name; QString path;