/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "smglobals.h" #include "seriestreemodel.h" #include "filestreemodel.h" #include "mappingtablemodel.h" #include "seriesmetadatamodel.h" #include "mappingtreemodel.h" #include "pictureviewer2.h" SmGlobals *SmGlobals::mInstance = 0; SmGlobals::~SmGlobals(){ foreach(QAbstractItemModel *model, mModels.values()){ delete model; } delete mFrameCache; } SmGlobals *SmGlobals::instance(){ if(!mInstance){ mInstance = new SmGlobals; if(!QSqlDatabase::contains("treedb")){ QSettings s; QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL", "treedb"); db.setHostName(s.value("database/hostname").toString()); db.setUserName(s.value("database/dbuser").toString()); db.setPassword(s.value("database/dbpass").toString()); db.setDatabaseName(s.value("database/dbname").toString()); if(!db.open()){ QMessageBox::critical(0, tr("Error"), tr("Could not open database. Please configure it and restart program.")); } } } return mInstance; } QAbstractItemModel *SmGlobals::model(const QString &which){ if(which == "SeriesModel"){ if(!mModels.contains(which)){ QStringList headers = QStringList() << tr("Series") << tr("Series ID") << tr("Series part ID") << tr("Part") << tr("Type") << tr("Favorite") << tr("Subtitle") << tr("Is Local"); SeriesTreeModel *model = new SeriesTreeModel(headers); mModels.insert(which, model); } }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 (int)") << tr("Type") << tr("Md5 sum") << tr("Series part ID") << tr("File ID") << tr("Seriespart") << tr("Display name") << tr("Dur./Size") << tr("Series name") << tr("Favorite"); FilesTreeModel *model = new FilesTreeModel(headers); mModels.insert(which, model); } }else if(which == "actors"){ if(!mModels.contains(which)){ QStringList headers = QStringList() << tr("Actor") << tr("Id"); MappingTableModel *model = new MappingTableModel(headers, "actors"); mModels.insert(which, model); } }else if(which == "genres"){ if(!mModels.contains(which)){ QStringList headers = QStringList() << tr("Genre") << tr("Id"); MappingTableModel *model = new MappingTableModel(headers, "genres"); mModels.insert(which, model); } }else if(which == "SeriesMetadata"){ if(!mModels.contains(which)){ QStringList headers = QStringList() << tr("SeriesPartId") << tr("Release Year") << tr("Source Medium") << tr("Subject") << tr("Release Group") << tr("Encoder Options") << tr("Comment") << tr("Encoding Passes") << tr("Added"); SeriesMetadataModel *model = new SeriesMetadataModel(headers); mModels.insert(which, model); } }else if(which == "MappingTree"){ if(!mModels.contains("MappingTree")){ QStringList headers = QStringList() << tr("Name") << tr("Id") << tr("Date"); MappingTreeModel *model = new MappingTreeModel(headers); mModels.insert(which, model); } } return mModels.contains(which) ? mModels.value(which) : 0; } PictureViewer2 *SmGlobals::pictureViewer() { if(!mPictureViewer){ mPictureViewer = new PictureViewer2; } return mPictureViewer; } SmGlobals::FrameCache *SmGlobals::frameCache() { if(!mFrameCache){ mFrameCache = new SmGlobals::FrameCache; } return mFrameCache; } QSize SmGlobals::cursorSize() { if(!mCursorSize.isValid()){ XFixesCursorImage *curImage = XFixesGetCursorImage(QX11Info::display()); mCursorSize = QSize(curImage->width, curImage->height); XFree(curImage); } return mCursorSize; } SmGlobals::SmGlobals() : mPictureViewer(0), mFrameCache(0){ mIcons.insert("Dildo", ":/dildo.png"); mIcons.insert("Dick to left", ":/back_dick.png"); mIcons.insert("Dick pointing up", ":/up_dick.png"); mIcons.insert("Chastity belt", ":/chastity_belt.png"); mIcons.insert("Clitoris", ":/clitoris.png"); mIcons.insert("Gaping ass", ":/gaping_ass.png"); mIcons.insert("Nipple pointing up", ":/nipple_up.png"); mIcons.insert("Bald pussy", ":/bald_pussy.png"); mIcons.insert("Prince Albert", ":/prince_albert.png"); mIcons.insert("Diaper", ":/diaper.png"); mIcons.insert("High heels", ":/higheels.png"); mIcons.insert("Ball gag", ":/ball_gag.png"); mIcons.insert("French Maid Dress", ":/french_maid_dress.png"); mIcons.insert("Shackles", ":/shackles.png"); mIcons.insert("Steel collar", ":/steel_collar.png"); mIcons.insert("Butt plug", ":/butt_plug.png"); mIcons.insert("Hourglass figure", ":/hourglass_figure.png"); mIcons.insert("Big ass", ":/big_ass.png"); mIcons.insert("Big tit", ":/big_tit.png"); mIcons.insert("Bizarre amputee", ":/bizarre_amputee.png"); mIcons.insert("Spreading pants", ":/spreadingpants.png"); mIcons.insert("Leather dog hood", ":/dog_hood.png"); mIcons.insert("Male chastity belt", ":/male_chastity_belt.png"); mIcons.insert("Anal stretcher", ":/analstretcher.png"); mIcons.insert("Big balls", ":/big_balls.png"); mIcons.insert("Big pierced balls", ":/huge_balls_pierced.png"); mIcons.insert("Huge bra", ":/huge_bra.png"); mIcons.insert("Squirting nipple", ":/squirting_nipple.png"); mIcons.insert("Dick in a cage", ":/dick_in_cage.png"); mIcons.insert("Used tampon", ":/used_tampon.png"); mIcons.insert("Clean tampon", ":/clean_tampon.png"); mDvdSize = Q_INT64_C(4707319808) - 20 * 1024 *1024; } //FrameCache SmGlobals::FrameCache::FrameCache(QObject *parent) : QObject(parent), mMagic(0xDEADBEEF), mCacheSubDir(".frameCache"), mCacheFileName("cache") { readConfig(); readCache(); } SmGlobals::FrameCache::~FrameCache(){ QFile outfile(mCacheFile); outfile.open(QIODevice::WriteOnly | QIODevice::Truncate); QDataStream ds(&outfile); ds << (qint32)mMagic; for(QHash, QString>::const_iterator it = mFrameCache.constBegin(); it != mFrameCache.constEnd(); ++it){ ds << it.key().first << it.key().second << it.value(); } outfile.close(); } void SmGlobals::FrameCache::readConfig(){ QSettings s; QString archive = s.value("paths/archivedir").toString(); if(archive.isEmpty()){ return; } QDir archiveDir(archive); if(!archiveDir.exists(mCacheSubDir)){ archiveDir.mkdir(mCacheSubDir); } mCacheDir = QString("%1/%2").arg(archive).arg(mCacheSubDir); mCacheFile = QString("%1/%2").arg(mCacheDir).arg(mCacheFileName); mWhen = s.value("ui/grabframe", "00:00:00").toString(); mFfMpegPath = s.value("paths/ffmpeg").toString(); } const QPixmap SmGlobals::FrameCache::entry(const QString &sourcePath, const QString &when){ const QPair source = prepFrame(sourcePath, when); return QPixmap(mFrameCache.value(source)); } const QString SmGlobals::FrameCache::entryPath(const QString &sourcePath, const QString &when){ const QPair source = prepFrame(sourcePath, when); return mFrameCache.value(source); } const QPair SmGlobals::FrameCache::prepFrame(const QString &sourceFile, QString when){ if(when.isEmpty()){ when = mWhen; } const QString fileName = QFileInfo(sourceFile).fileName(); const QPair source(fileName, when); if(!mFrameCache.contains(source)){ grabFrame(sourceFile, when); } return source; } void SmGlobals::FrameCache::grabFrame(const QString &sourceFile, QString when){ QFileInfo sourceInfo(sourceFile); if(!sourceInfo.exists()){ return; } QString tmpTemplate = QString("%1/%2_%3-XXXXXX.png").arg(mCacheDir).arg(sourceInfo.fileName()).arg(when); QTemporaryFile tempFile(tmpTemplate); tempFile.setAutoRemove(false); if(tempFile.open()){ QStringList ffMpegArgs = QStringList() << "-vframes" << "1" << "-ss" << when << "-i" << sourceFile << "-y" << tempFile.fileName(); QProcess ffmpeg; ffmpeg.start(mFfMpegPath, ffMpegArgs); if(!ffmpeg.waitForStarted()){ return; } ffmpeg.waitForFinished(); QPair pair(sourceInfo.fileName(), when); mFrameCache.insert(pair, tempFile.fileName()); } } void SmGlobals::FrameCache::readCache(){ QFile cache(mCacheFile); cache.open(QIODevice::ReadOnly); QDataStream ds(&cache); qint32 magic; ds >> magic; if(magic != mMagic){ return; } while(!ds.atEnd()){ QString source, pos, cacheFile; ds >> source >> pos >> cacheFile; QFileInfo fi(cacheFile); if(fi.size() == 0){ QFile::remove(fi.absoluteFilePath()); continue; } QPair pair(source, pos); mFrameCache.insert(pair, cacheFile); } cleanup(); } /* cleanup function for fucked up framecache: Key was full path until recently, not just the filename, so duplicates showed up when hovering over the same in different paths, eg, archive or filesystem. Should be removed in the future */ void SmGlobals::FrameCache::cleanup(){ QHash, QString> newFrameCache; QHash, QString>::const_iterator it = mFrameCache.constBegin(); while(it != mFrameCache.constEnd()){ QPair key = it.key(); QFileInfo fi(key.first); QPair newEntry(fi.fileName(), key.second); if(!newFrameCache.contains(newEntry)){ newFrameCache.insert(newEntry, it.value()); }else{ QFile::remove(it.value()); } ++it; } mFrameCache = newFrameCache; }