From bd6a6a7c42dabe2d0d86e309a6dc6b04de7c0a10 Mon Sep 17 00:00:00 2001 From: Arno Date: Sat, 6 Jul 2013 08:06:52 +0200 Subject: Basic ArchiveFilesModel and ArchiveController Implement a new file model for the archive. It's quite basic at this stage, but finally something happens when clicking the archive tree. Also, implement the interaction (signal -> slot) between the views and models in an explicit controller to prevent the mess from the old archive. --- archivemodel.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) (limited to 'archivemodel.cpp') diff --git a/archivemodel.cpp b/archivemodel.cpp index 14757af..3746105 100644 --- a/archivemodel.cpp +++ b/archivemodel.cpp @@ -11,9 +11,11 @@ #include #include #include +#include #include "smtreeitem.h" #include "archivemodel.h" +#include "helper.h" ArchiveModel::ArchiveModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mOrder(NoOrder){ mDb = QSqlDatabase::database("treedb"); @@ -225,6 +227,32 @@ QModelIndexList ArchiveModel::pathToIndex(const QStringList &path) const { return retval; } +QSet ArchiveModel::seriesPartIds(const QModelIndex &idx) const{ + if(!idx.isValid()){ + return QSet(); + } + SmTreeItem *cur = itemAt(idx); + QVector remaining; + remaining << cur; + QSet retval; + for(int i = 0; i < cur->childCount(); ++i){ + remaining << cur->child(i); + } + while(cur){ + cur = remaining.last(); + remaining.pop_back(); + for(int i = 0; i < cur->childCount(); ++i){ + remaining << cur->child(i); + } + int curId = cur->data(SeriesPartId).toInt(); + retval << curId; + if(remaining.isEmpty()){ + break; + } + } + return retval; +} + void ArchiveModel::setOrder(int order) { mOrder = order; SmTreeItem *rootItem = readCache(mOrder); @@ -368,6 +396,133 @@ const QString ArchiveModel::cacheFile(int o) const{ return cacheFile; } +/* + * ArchiveFilesModel BEGIN */ + +ArchiveFilesModel::ArchiveFilesModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent) { + mDb = QSqlDatabase::database("treedb"); + mRoleDbColumnMap.insert(FilenameRole, "tfilename"); + mRoleDbColumnMap.insert(DvdNoRole, "idvd"); + mRoleDbColumnMap.insert(FileTypeRole, "sifiletype"); + mRoleDbColumnMap.insert(FileNumberRole, "sifileno"); + mRoleDbColumnMap.insert(QualityRole, "siquality"); +} + +QVariant ArchiveFilesModel::data(const QModelIndex &index, int role) const { + if(!index.isValid()){ + return QVariant(); + } + SmTreeItem *item = itemAt(index); + if(role == SeriesPartIdRole){ + return item->data(SeriesPartId); + } + if(role == FilenameRole){ + return item->data(Filename); + } + if(role == Md5SumRole){ + return item->data(Md5Sum); + } + if(role == SizeRole){ + return item->data(Size); + } + if(role == DvdNoRole){ + return item->data(DvdNo); + } + if(role == FileTypeRole){ + return item->data(FileType); + } + if(role == FileNumberRole){ + return item->data(FileNumber); + } + if(role == QualityRole){ + return item->data(Quality); + } + if(role == FileIdRole){ + return item->data(FileId); + } + if(role == PicSizeRole){ + return item->data(PicSize); + } + if(role == DurationRole){ + return item->data(Duration); + } + if(role == FullPathRole){ + return item->data(FullPath); + } + return SmTreeModel::data(index, role); +} + +bool ArchiveFilesModel::setData(const QModelIndex &idx, const QVariant &value, int role){ + const QString dbColumn = mRoleDbColumnMap.value(role); + if(dbColumn.isEmpty()){ + return SmTreeModel::setData(idx, value, role); + } + QString queryString = QString("UPDATE files SET %1 = :value WHERE ifiles_id = :id").arg(dbColumn); + QSqlQuery q(queryString, mDb); + q.bindValue(":value", value); + q.bindValue(":id", idx.data()); + mDb.transaction(); + bool success = q.exec(); + if(success){ + if(role == FilenameRole){ + QFile f(idx.data(FullPathRole).toString()); + QFileInfo fi(f); + QString dir = fi.absolutePath(); + QString newName = QString("%1/%2").arg(dir).arg(value.toString()); + success = f.rename(newName); + } + // check rename, too! + if(success){ + mDb.commit(); + emit dataChanged(idx, idx); + return true; + } + } + mDb.rollback(); + return false; +} + +void ArchiveFilesModel::populate(const QSet &seriesPartIds){ + if(seriesPartIds.isEmpty()){ + return; + } + SmTreeItem *root = new SmTreeItem(NumFields); + SmTreeItem *movies = new SmTreeItem(NumFields, root); + movies->setData(Filename, tr("Movies")); + root->appendChild(movies); + SmTreeItem *pictures = new SmTreeItem(NumFields, root); + pictures->setData(Filename, tr("Pictures")); + root->appendChild(pictures); + QSettings s; + QString archivePath = s.value("paths/archive").toString(); + + QStringList ids; + foreach(int i, seriesPartIds){ + ids << QString::number(i); + } + QString queryString = QString("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, cpicsize, iduration FROM files WHERE iseriespart_id IN (%1) ORDER BY tfilename ASC").arg(ids.join(",")); + QSqlQuery q(queryString, mDb); + while(q.next()){ + QList data; + for(int i = 0; i < NumFields - 1; ++i){ + data << q.value(i); + } + QString fullPath = Helper::createArchivePath(archivePath, data.at(Md5Sum).toString()); + data << fullPath; + if(data.at(FileType).toInt() == Movie){ + SmTreeItem *newItem = new SmTreeItem(data, movies); + movies->appendChild(newItem); + }else{ + SmTreeItem *newItem = new SmTreeItem(data, pictures); + pictures->appendChild(newItem); + } + } + setRoot(root); +} + +/* + * ArchiveCollector BEGIN */ + ArchiveCollector::ArchiveCollector(int numFields, int order, QObject *parent) : QThread(parent), mRootItem(0), mNumFields(numFields), mSortOrder(order) { QString dbName = QString("%1").arg((qint64(this))); mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), dbName); -- cgit v1.2.3-70-g09d2