summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArno <am@disconnect.de>2010-08-12 19:40:33 +0200
committerArno <am@disconnect.de>2010-08-12 19:40:33 +0200
commit91cf2978ba97bc8ebda2da9df01d3dde22b99f14 (patch)
tree27dbafd0df752982535e12fc6eb847221649a83d
parent3af9f3f8b900b9dd5e09300e74d6ce49018be98e (diff)
downloadSheMov-91cf2978ba97bc8ebda2da9df01d3dde22b99f14.tar.gz
SheMov-91cf2978ba97bc8ebda2da9df01d3dde22b99f14.tar.bz2
SheMov-91cf2978ba97bc8ebda2da9df01d3dde22b99f14.zip
Show picture size or duration in FilesTreeView
Finally managed to view size of pictures or duration for movies in the file view. That values are not held in the database, they're created on the fly. For this to perform I created a disk based cache. I also had to create some convenience functions: FilesTreeModel::streamInfo(const QString &) FilesTreeModel::pictureInfo(const QString &) The cache is a QDataStream and will be deleted if the magic doesn't fit.
-rw-r--r--archivetreeview.cpp11
-rw-r--r--archivetreeview.h1
-rw-r--r--filestreemodel.cpp125
-rw-r--r--filestreemodel.h16
-rw-r--r--shemov.cpp2
-rw-r--r--smglobals.cpp2
6 files changed, 124 insertions, 33 deletions
diff --git a/archivetreeview.cpp b/archivetreeview.cpp
index 621a7ee..0d91d21 100644
--- a/archivetreeview.cpp
+++ b/archivetreeview.cpp
@@ -45,7 +45,7 @@ ArchiveTreeView::ArchiveTreeView(QWidget *parent) : QWidget(parent){
mFilesWidget = new FilesTreeWidget;
QAbstractItemModel *filesModel = SmGlobals::instance()->model("FilesModel");
mFilesModel = static_cast<FilesTreeModel*>(filesModel);
- for(int i = 5; i < 11; ++i){
+ for(int i = 5; i < 12; ++i){
mFilesWidget->filesTree()->setColumnHidden(i, true);
}
connect(mSeriesWidget, SIGNAL(filesReload()), mFilesWidget->filesTree(), SLOT(expandAll()));
@@ -166,10 +166,11 @@ void ArchiveTreeView::currentChanged(const QItemSelection &selected, const QItem
mFilesModel->setIds(selectedPartIds);
mFilesWidget->filesTree()->expandAll();
- mFilesWidget->filesTree()->resizeColumnToContents(0);
- mFilesWidget->filesTree()->resizeColumnToContents(1);
- mFilesWidget->filesTree()->resizeColumnToContents(2);
- mFilesWidget->filesTree()->resizeColumnToContents(3);
+ mFilesWidget->filesTree()->resizeColumnToContents(FilesTreeModel::FileName);
+ mFilesWidget->filesTree()->resizeColumnToContents(FilesTreeModel::PartNo);
+ mFilesWidget->filesTree()->resizeColumnToContents(FilesTreeModel::Quality);
+ mFilesWidget->filesTree()->resizeColumnToContents(FilesTreeModel::DvdNo);
+ mFilesWidget->filesTree()->resizeColumnToContents(FilesTreeModel::DisplayName);
setMappingItems(selectedPartIds, mActorsModel, mActorsWidget);
setMappingItems(selectedPartIds, mGenresModel, mGenresWidget);
}
diff --git a/archivetreeview.h b/archivetreeview.h
index 9ea2604..ddfad7e 100644
--- a/archivetreeview.h
+++ b/archivetreeview.h
@@ -12,7 +12,6 @@
#include <QModelIndexList>
#include <QList>
-class SmUberModel;
class SeriesTreeWidget;
class FilesTreeWidget;
class FilesTreeModel;
diff --git a/filestreemodel.cpp b/filestreemodel.cpp
index c44e449..fd42802 100644
--- a/filestreemodel.cpp
+++ b/filestreemodel.cpp
@@ -13,6 +13,9 @@
#include <QSettings>
#include <QProcess>
#include <QImage>
+#include <QDataStream>
+#include <QDesktopServices>
+#include <QDir>
#include "filestreemodel.h"
#include "smtreeitem.h"
@@ -20,7 +23,7 @@
#include "seriestreemodel.h"
#include "smglobals.h"
-FilesTreeModel::FilesTreeModel(QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mMode(Normal){
+FilesTreeModel::FilesTreeModel(QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mMode(Normal), mMagic(0xAABBCCDD){
//database setup
mDb = QSqlDatabase::database("treedb");
mUpdateDvdQuery = new QSqlQuery(mDb);
@@ -51,6 +54,7 @@ FilesTreeModel::FilesTreeModel(QStringList &headers, QObject *parent) : SmTreeMo
//misc
mSeriesModel = static_cast<SeriesTreeModel*>(SmGlobals::instance()->model("SeriesModel"));
+ readCache();
}
FilesTreeModel::~FilesTreeModel(){
@@ -265,16 +269,12 @@ QHash<QString, QString> FilesTreeModel::filesBySeriesPartId(int seriesPartId) co
return retval;
}
-QList<QMap<QString, QString> > FilesTreeModel::streamInfo(const QModelIndex &idx){
+QList<QMap<QString, QString> > FilesTreeModel::streamInfo(const QString &path) const{
QList<QMap<QString, QString> > retval;
- if(!idx.isValid()){
- return retval;
- }
QSettings s;
QString ffProbe = s.value("paths/ffprobe").toString();
- QString fullPath = idx.data(FullPathRole).toString();
QStringList args;
- args << "-show_streams" << fullPath;
+ args << "-show_streams" << path;
QProcess ffproc;
ffproc.start(ffProbe, args);
if(!ffproc.waitForStarted()){
@@ -301,13 +301,13 @@ QList<QMap<QString, QString> > FilesTreeModel::streamInfo(const QModelIndex &idx
return retval;
}
-QMap<QString, QString> FilesTreeModel::pictureInfo(const QModelIndex &idx){
+QList<QMap<QString, QString> > FilesTreeModel::streamInfo(const QModelIndex &idx) const{
+ return streamInfo(idx.data(FullPathRole).toString());
+}
+
+QMap<QString, QString> FilesTreeModel::pictureInfo(const QString &path) const{
QMap<QString, QString> retval;
- if(!idx.isValid()){
- return retval;
- }
- QString fullPath = idx.data(FullPathRole).toString();
- QImage img(fullPath);
+ QImage img(path);
if(img.isNull()){
return retval;
}
@@ -322,6 +322,10 @@ QMap<QString, QString> FilesTreeModel::pictureInfo(const QModelIndex &idx){
return retval;
}
+QMap<QString, QString> FilesTreeModel::pictureInfo(const QModelIndex &idx) const{
+ return pictureInfo(idx.data(FullPathRole).toString());
+}
+
QMap<QString, QString> FilesTreeModel::pictureMetaInfo(const QModelIndex &idx){
QMap<QString, QString> retval;
if(!idx.isValid()){
@@ -404,12 +408,55 @@ bool FilesTreeModel::deleteFiles(const QModelIndexList &files){
return true;
}
+void FilesTreeModel::readCache(){
+ QString settingsDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ QString cacheFile = QString("%1/%2").arg(settingsDir).arg("sizeduration.cache");
+ QFileInfo fi(cacheFile);
+ if(!fi.exists()){
+ return;
+ }
+ QFile cache(cacheFile);
+ cache.open(QIODevice::ReadOnly);
+ QDataStream stream(&cache);
+ qint32 magic;
+ stream >> magic;
+ if(magic != mMagic){
+ QFile::remove(cacheFile);
+ return;
+ }
+ while(!stream.atEnd()){
+ QString key, value;
+ stream >> key;
+ stream >> value;
+ mPicsDurationCache.insert(key, value);
+ }
+}
+
+void FilesTreeModel::writeCache(){
+ QString settingsDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ QFileInfo fi(settingsDir);
+ if(!fi.exists()){
+ QDir root = QDir::root();
+ root.mkpath(settingsDir);
+ }
+ QString cacheFile = QString("%1/%2").arg(settingsDir).arg("sizeduration.cache");
+ QFile cache(cacheFile);
+ cache.open(QIODevice::WriteOnly);
+ QDataStream stream(&cache);
+ stream << mMagic;
+ QHash<QString, QString>::const_iterator it = mPicsDurationCache.constBegin();
+ while(it != mPicsDurationCache.constEnd()){
+ stream << it.key() << it.value();
+ ++it;
+ }
+}
+
void FilesTreeModel::populate(QSqlQuery &filesQuery){
- SmTreeItem *root = new SmTreeItem(11);
- SmTreeItem *files = new SmTreeItem(11, root);
+ SmTreeItem *root = new SmTreeItem(14);
+ SmTreeItem *files = new SmTreeItem(14, root);
files->setData(FileName, tr("Movies"));
root->appendChild(files);
- SmTreeItem *covers = new SmTreeItem(11, root);
+ SmTreeItem *covers = new SmTreeItem(14, root);
covers->setData(FileName, tr("Covers"));
root->appendChild(covers);
QLocale l;
@@ -430,19 +477,53 @@ void FilesTreeModel::populate(QSqlQuery &filesQuery){
data << filesQuery.value(10); //seriespart
QString displayName = QString("%1 %2").arg(filesQuery.value(9).toString()).arg(filesQuery.value(10).toString());
data << displayName;
+ data << tr("N/A"); // duration or size
+ QString fullPath = data.at(FullPath).toString();
+ QFileInfo fi(fullPath);
switch(filesQuery.value(5).toInt()){
case Movie:{
- SmTreeItem *item = new SmTreeItem(data, files);
- files->appendChild(item);
- break;
+ if(fi.exists()){
+ if(mPicsDurationCache.contains(fullPath)){
+ data[SizeDuration] = mPicsDurationCache.value(fullPath);
+ SmTreeItem *item = new SmTreeItem(data, files);
+ files->appendChild(item);
+ break;
+ }
+ QList<QMap<QString, QString> > sInfo = streamInfo(fullPath);
+ for(int i = 0; i < sInfo.size(); ++i){
+ QString duration = sInfo.at(i).value("duration");
+ if(!duration.isEmpty() && (duration != "N/A")){
+ QString durFromSeconds = Helper::durationFromSecs(duration.toFloat());
+ mPicsDurationCache.insert(fullPath, durFromSeconds);
+ data[SizeDuration] = durFromSeconds;
+ }
+ }
}
+ SmTreeItem *item = new SmTreeItem(data, files);
+ files->appendChild(item);
+ break;
+ }
case FrontCover:
case BackCover:
case GeneralCover:{
- SmTreeItem *item = new SmTreeItem(data, covers);
- covers->appendChild(item);
- break;
+ if(fi.exists()){
+ if(mPicsDurationCache.contains(fullPath)){
+ data[SizeDuration] = mPicsDurationCache.value(fullPath);
+ SmTreeItem *item = new SmTreeItem(data, files);
+ covers->appendChild(item);
+ break;
+ }
}
+ QMap<QString, QString> pInfo = pictureInfo(fullPath);
+ if(!pInfo.isEmpty()){
+ QString setVal = QString("%1x%2").arg(pInfo.value("Width")).arg(pInfo.value("Height"));
+ mPicsDurationCache.insert(fullPath, setVal);
+ data[SizeDuration] = setVal;
+ }
+ SmTreeItem *item = new SmTreeItem(data, covers);
+ covers->appendChild(item);
+ break;
+ }
default:
;
}
diff --git a/filestreemodel.h b/filestreemodel.h
index 405878b..2a9519f 100644
--- a/filestreemodel.h
+++ b/filestreemodel.h
@@ -21,9 +21,9 @@ class SeriesTreeModel;
class FilesTreeModel : public SmTreeModel {
Q_OBJECT
public:
- enum CustomRoles { FileNameRole = Qt::UserRole + 1, FullPathRole = Qt::UserRole + 2, SizeRole = Qt::UserRole + 3, DvdNoRole = Qt::UserRole + 4, SizeDisplayRole = Qt::UserRole + 5, FileTypeRole = Qt::UserRole + 6, Md5SumRole = Qt::UserRole + 7, PartNoRole = Qt::UserRole + 8, SeriesPartIdRole = Qt::UserRole + 9, QualityRole = Qt::UserRole + 10, FilesIdRole = Qt::UserRole + 11, SeriesPartRole = Qt::UserRole + 12, DisplayNameRole = Qt::UserRole + 13 };
+ enum CustomRoles { FileNameRole = Qt::UserRole + 1, FullPathRole = Qt::UserRole + 2, SizeRole = Qt::UserRole + 3, DvdNoRole = Qt::UserRole + 4, SizeDisplayRole = Qt::UserRole + 5, FileTypeRole = Qt::UserRole + 6, Md5SumRole = Qt::UserRole + 7, PartNoRole = Qt::UserRole + 8, SeriesPartIdRole = Qt::UserRole + 9, QualityRole = Qt::UserRole + 10, FilesIdRole = Qt::UserRole + 11, SeriesPartRole = Qt::UserRole + 12, DisplayNameRole = Qt::UserRole + 13, SizeDurationRole = Qt::UserRole + 14 };
enum FileTypes { Movie = 1, FrontCover = 2, BackCover = 3, GeneralCover = 4 };
- enum Fields { FileName = 0, PartNo = 1, SizeDisplay = 2, Quality = 3, DvdNo = 4, FullPath = 5, Size = 6, FileType = 7, Md5Sum = 8, SeriesPartId = 9, FilesId = 10, SeriesPart = 11, DisplayName = 12 };
+ enum Fields { FileName = 0, PartNo = 1, SizeDisplay = 2, Quality = 3, DvdNo = 4, FullPath = 5, Size = 6, FileType = 7, Md5Sum = 8, SeriesPartId = 9, FilesId = 10, SeriesPart = 11, DisplayName = 12, SizeDuration = 13 };
enum Mode { Normal = 0, Archived = 1, Local = 2 };
explicit FilesTreeModel(QStringList &headers, QObject *parent = 0);
const QHash<int, QString> fileTypes() const { return mFileTypes; }
@@ -39,8 +39,10 @@ class FilesTreeModel : public SmTreeModel {
bool setData(const QModelIndex &index, const QVariant &value, int role);
Qt::ItemFlags flags(const QModelIndex &index) const;
QHash<QString, QString> filesBySeriesPartId(int seriesPartId) const;
- QList<QMap<QString, QString> > streamInfo(const QModelIndex &idx);
- QMap<QString, QString> pictureInfo(const QModelIndex &idx);
+ QList<QMap<QString, QString> > streamInfo(const QModelIndex &idx) const;
+ QList<QMap<QString, QString> > streamInfo(const QString &path) const;
+ QMap<QString, QString> pictureInfo(const QString &path) const;
+ QMap<QString, QString> pictureInfo(const QModelIndex &idx) const;
QMap<QString, QString> pictureMetaInfo(const QModelIndex &idx);
//file manipulation
@@ -48,6 +50,10 @@ class FilesTreeModel : public SmTreeModel {
bool deleteFile(const QModelIndex &file);
bool deleteFiles(const QModelIndexList &files);
+ //misc
+ void readCache();
+ void writeCache();
+
private:
//functions
void populate(QSqlQuery &filesQuery);
@@ -64,8 +70,10 @@ class FilesTreeModel : public SmTreeModel {
QHash<int, QString> mFileTypes;
QHash<int, QString> mCoverTypes;
QHash<int, QString> mModeNames;
+ QHash<QString, QString> mPicsDurationCache;
SeriesTreeModel *mSeriesModel;
int mMode;
+ const int mMagic;
};
#endif // FILESTREEMODEL_H
diff --git a/shemov.cpp b/shemov.cpp
index 359d06a..509848e 100644
--- a/shemov.cpp
+++ b/shemov.cpp
@@ -98,6 +98,8 @@ void SheMov::closeEvent(QCloseEvent *event){
mFSWidget->writeSettings();
mFSWidget->pictureViewer()->close();
mATree->seriesWidget()->writeSettings();
+ FilesTreeModel *filesModel = static_cast<FilesTreeModel*>(SmGlobals::instance()->model("FilesModel"));
+ filesModel->writeCache();
writeSettings();
delete SmGlobals::instance();
event->accept();
diff --git a/smglobals.cpp b/smglobals.cpp
index 61530d1..8c572f1 100644
--- a/smglobals.cpp
+++ b/smglobals.cpp
@@ -53,7 +53,7 @@ QAbstractItemModel *SmGlobals::model(const QString &which){
}
}else if(which == "FilesModel"){
if(!mModels.contains(which)){
- QStringList headers = QStringList() << tr("Name") << tr("Part") << tr("Size") << tr("Qual.") << tr("Dvd") << tr("Full Path") << tr("Size") << tr("Type") << tr("Md5 sum") << tr("Series part ID") << tr("File ID");
+ QStringList headers = QStringList() << tr("Name") << tr("Part") << tr("Size") << tr("Qual.") << tr("Dvd") << tr("Full Path") << tr("Size") << tr("Type") << tr("Md5 sum") << tr("Series part ID") << tr("File ID") << tr("Seriespart") << tr("Display name") << tr("Dur./Size");
FilesTreeModel *model = new FilesTreeModel(headers);
mModels.insert(which, model);
}