summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--archivecontroller.cpp54
-rw-r--r--archivecontroller.h46
-rw-r--r--archivemodel.cpp155
-rw-r--r--archivemodel.h20
-rw-r--r--archiveview.cpp20
-rw-r--r--archiveview.h15
-rw-r--r--shemov.pro6
7 files changed, 310 insertions, 6 deletions
diff --git a/archivecontroller.cpp b/archivecontroller.cpp
new file mode 100644
index 0000000..0c67ef7
--- /dev/null
+++ b/archivecontroller.cpp
@@ -0,0 +1,54 @@
+/*
+ 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 "archivecontroller.h"
+#include "archivemodel.h"
+#include "archiveview.h"
+
+ArchiveController::ArchiveController(QObject *parent) : QObject(parent) {}
+
+void ArchiveController::setArchiveView(ArchiveTree *atree, ArchiveProxy *aproxy){
+ mArchiveTree = atree;
+ mArchiveProxy = aproxy;
+ mArchiveSelection = mArchiveTree->selectionModel();
+}
+
+void ArchiveController::setArchiveFiles(ArchiveFiles *afiles, ArchiveFilesProxy *afilesproxy){
+ mArchiveFiles = afiles;
+ mArchiveFilesProxy = afilesproxy;
+}
+
+void ArchiveController::setModels(ArchiveModel *amodel, ArchiveFilesModel *afilesmodel){
+ mArchiveModel = amodel;
+ mArchiveFilesModel = afilesmodel;
+}
+
+void ArchiveController::init(){
+ connect(mArchiveSelection, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(treeSelectionChanged(QItemSelection,QItemSelection)));
+}
+
+void ArchiveController::treeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected){
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+ QModelIndexList sel = mapToSource(mArchiveProxy, mArchiveSelection->selectedRows());
+ if(sel.isEmpty()){
+ return;
+ }
+ QSet<int> ids;
+ foreach(QModelIndex idx, sel){
+ ids.unite(mArchiveModel->seriesPartIds(idx));
+ }
+ mArchiveFilesModel->populate(ids);
+}
+
+QModelIndexList ArchiveController::mapToSource(const QSortFilterProxyModel *proxy, const QModelIndexList idxs) const{
+ QModelIndexList retval;
+ foreach(QModelIndex idx, idxs){
+ retval << proxy->mapToSource(idx);
+ }
+ return retval;
+}
diff --git a/archivecontroller.h b/archivecontroller.h
new file mode 100644
index 0000000..e956d37
--- /dev/null
+++ b/archivecontroller.h
@@ -0,0 +1,46 @@
+/*
+ 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.
+*/
+
+#ifndef ARCHIVECONTROLLER_H
+#define ARCHIVECONTROLLER_H
+
+#include <QObject>
+#include <QItemSelection>
+
+class ArchiveTree;
+class ArchiveProxy;
+class ArchiveFiles;
+class ArchiveFilesProxy;
+class ArchiveModel;
+class ArchiveFilesModel;
+class QItemSelectionModel;
+class QSortFilterProxyModel;
+
+class ArchiveController : public QObject {
+ Q_OBJECT
+ public:
+ explicit ArchiveController(QObject *parent = 0);
+ void setArchiveView(ArchiveTree *atree, ArchiveProxy *aproxy);
+ void setArchiveFiles(ArchiveFiles *afiles, ArchiveFilesProxy *afilesproxy);
+ void setModels(ArchiveModel *amodel, ArchiveFilesModel *afilesmodel);
+ void init();
+
+ private slots:
+ void treeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+
+ private:
+ QModelIndexList mapToSource(const QSortFilterProxyModel *proxy, const QModelIndexList idxs) const;
+ ArchiveTree *mArchiveTree;
+ ArchiveProxy *mArchiveProxy;
+ QItemSelectionModel *mArchiveSelection;
+ ArchiveFiles *mArchiveFiles;
+ ArchiveFilesProxy *mArchiveFilesProxy;
+ ArchiveModel *mArchiveModel;
+ ArchiveFilesModel *mArchiveFilesModel;
+};
+
+#endif // ARCHIVECONTROLLER_H
diff --git a/archivemodel.cpp b/archivemodel.cpp
index 14757af..3746105 100644
--- a/archivemodel.cpp
+++ b/archivemodel.cpp
@@ -11,9 +11,11 @@
#include <QSettings>
#include <QMutexLocker>
#include <QSignalMapper>
+#include <QFileInfo>
#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<int> ArchiveModel::seriesPartIds(const QModelIndex &idx) const{
+ if(!idx.isValid()){
+ return QSet<int>();
+ }
+ SmTreeItem *cur = itemAt(idx);
+ QVector<SmTreeItem*> remaining;
+ remaining << cur;
+ QSet<int> 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<int> &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<QVariant> 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);
diff --git a/archivemodel.h b/archivemodel.h
index 4ef39fa..a9994d0 100644
--- a/archivemodel.h
+++ b/archivemodel.h
@@ -12,6 +12,7 @@
#include <QThread>
#include <QDataStream>
#include <QMutex>
+#include <QSet>
#include "smtreemodel.h"
@@ -35,6 +36,7 @@ class ArchiveModel : public SmTreeModel {
virtual bool removeNode(const QModelIndex &idx);
QStringList indexToPath(const QModelIndex &idx) const;
QModelIndexList pathToIndex(const QStringList &path) const;
+ QSet<int> seriesPartIds(const QModelIndex &idx) const;
signals:
void needRefresh();
@@ -64,6 +66,24 @@ class ArchiveModel : public SmTreeModel {
int mOrder;
};
+class ArchiveFilesModel : public SmTreeModel {
+ Q_OBJECT
+ public:
+ enum CustomRoles { SeriesPartIdRole = Qt::UserRole + 1, FilenameRole = Qt::UserRole + 2, Md5SumRole = Qt::UserRole + 3, SizeRole = Qt::UserRole + 4, DvdNoRole = Qt::UserRole + 5, FileTypeRole = Qt::UserRole + 6, FileNumberRole = Qt::UserRole + 7, QualityRole = Qt::UserRole + 8, FileIdRole = Qt::UserRole + 9, PicSizeRole = Qt::UserRole + 10, DurationRole = Qt::UserRole + 11, FullPathRole = Qt::UserRole + 12 };
+ enum Fields { SeriesPartId = 0, Filename = 1, Md5Sum = 2, Size = 3, DvdNo = 4, FileType = 5, FileNumber = 6, Quality = 7, FileId = 8, PicSize = 9, Duration = 10, FullPath = 11 };
+ enum FileType { Movie = 1, FrontCover = 2, BackCover = 3, GeneralCover = 4 };
+ enum { NumFields = 12 };
+ explicit ArchiveFilesModel(const QStringList &headers, QObject *parent = 0);
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual bool setData(const QModelIndex &idx, const QVariant &value, int role);
+ void populate(const QSet<int> &seriesPartIds);
+
+ private:
+ QList<int> mSeriesPartIds;
+ QHash<int, QString> mRoleDbColumnMap;
+ QSqlDatabase mDb;
+};
+
class ArchiveCollector : public QThread {
Q_OBJECT
public:
diff --git a/archiveview.cpp b/archiveview.cpp
index 34fd169..f570751 100644
--- a/archiveview.cpp
+++ b/archiveview.cpp
@@ -18,9 +18,10 @@
#include <QVBoxLayout>
#include "archiveview.h"
+#include "archivecontroller.h"
#include "smglobals.h"
-ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent), mConstructing(true) {
+ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent) {
QSettings s;
mArchiveModel = static_cast<ArchiveModel*>(SmGlobals::instance()->model("ArchiveModel"));
connect(mArchiveModel, SIGNAL(needRefresh()), this, SLOT(refreshArchive()));
@@ -74,7 +75,13 @@ ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent), mConstructing(true)
treeLayout->addWidget(mTree);
QWidget *treeWidget = new QWidget;
treeWidget->setLayout(treeLayout);
+
mFiles = new ArchiveFiles;
+ mFilesModel = new ArchiveFilesModel(QStringList() << tr("Seriespartid") << tr("Filename") << tr("Md5Sum") << tr("Size") << tr("Dvd") << tr("Type") << tr("No") << tr("Quality") << tr("Fileid") << tr("Pic size") << tr("Duration") << tr("Full Path"), this);
+ mFilesProxy = new ArchiveFilesProxy;
+ mFilesProxy->setSourceModel(mFilesModel);
+ mFiles->setModel(mFilesProxy);
+
QSplitter *treeSplitter = new QSplitter(Qt::Horizontal);
treeSplitter->addWidget(treeWidget);
treeSplitter->addWidget(mFiles);
@@ -83,6 +90,7 @@ ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent), mConstructing(true)
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(treeSplitter);
setLayout(mainLayout);
+ initController();
}
int ArchiveView::currentSortOrder() const {
@@ -165,6 +173,14 @@ void ArchiveView::collapseItem(const QModelIndex &idx){
}
}
+void ArchiveView::initController(){
+ mController = new ArchiveController(this);
+ mController->setArchiveView(mTree, mProxy);
+ mController->setArchiveFiles(mFiles, mFilesProxy);
+ mController->setModels(mArchiveModel, mFilesModel);
+ mController->init();
+}
+
ArchiveTree::ArchiveTree(QWidget *parent) : SmTreeView(parent) {}
void ArchiveTree::setModel(ArchiveProxy *model){
@@ -224,3 +240,5 @@ bool ArchiveProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourcePare
ArchiveModel *model = qobject_cast<ArchiveModel*>(sourceModel());
return model->matchRecursive(nameIdx, mFilter);
}
+
+ArchiveFilesProxy::ArchiveFilesProxy(QObject *parent) : QSortFilterProxyModel(parent) {}
diff --git a/archiveview.h b/archiveview.h
index 27bae35..de9875d 100644
--- a/archiveview.h
+++ b/archiveview.h
@@ -24,7 +24,8 @@ class QSortFilterProxyModel;
class ArchiveTree;
class ArchiveFiles;
class ArchiveProxy;
-class ArchiveProgressDialog;
+class ArchiveFilesProxy;
+class ArchiveController;
class ArchiveView : public QWidget {
Q_OBJECT
@@ -48,15 +49,17 @@ class ArchiveView : public QWidget {
void collapseItem(const QModelIndex &idx);
private:
+ void initController();
QComboBox *mSortOrder;
QLineEdit *mFilter;
ArchiveTree *mTree;
ArchiveFiles *mFiles;
ArchiveModel *mArchiveModel;
+ ArchiveFilesModel *mFilesModel;
ArchiveProxy *mProxy;
- ArchiveProgressDialog *mProgress;
+ ArchiveFilesProxy *mFilesProxy;
QHash<int, QVariantList> mExpandedItems;
- bool mConstructing;
+ ArchiveController *mController;
};
class ArchiveTree : public SmTreeView {
@@ -96,4 +99,10 @@ class ArchiveProxy : public QSortFilterProxyModel {
int mSortOrder;
};
+class ArchiveFilesProxy : public QSortFilterProxyModel {
+ Q_OBJECT
+ public:
+ explicit ArchiveFilesProxy(QObject *parent = 0);
+};
+
#endif // ARCHIVEVIEW_H
diff --git a/shemov.pro b/shemov.pro
index 1bae612..b6f83d0 100644
--- a/shemov.pro
+++ b/shemov.pro
@@ -45,7 +45,8 @@ SOURCES = main.cpp \
framecache.cpp \
smtreeview.cpp \
archivemodel.cpp \
- archiveview.cpp
+ archiveview.cpp \
+ archivecontroller.cpp
HEADERS = \
filesystemdirproxy.h \
filesystemwidget.h \
@@ -86,6 +87,7 @@ HEADERS = \
framecache.h \
smtreeview.h \
archivemodel.h \
- archiveview.h
+ archiveview.h \
+ archivecontroller.h
LIBS += -lmagic -lXfixes -lX11
RESOURCES = shemov.qrc