summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--migdb.py16
-rw-r--r--seriestreemodel.cpp188
-rw-r--r--seriestreemodel.h43
-rw-r--r--shemov.pro6
-rw-r--r--smtreeitem.cpp13
-rw-r--r--smtreeitem.h6
-rw-r--r--smtreemodel.cpp8
-rw-r--r--smtreemodel.h12
-rw-r--r--smubermodel.cpp17
-rw-r--r--smubermodel.h8
10 files changed, 288 insertions, 29 deletions
diff --git a/migdb.py b/migdb.py
index 56eb8e9..d262ce9 100644
--- a/migdb.py
+++ b/migdb.py
@@ -78,8 +78,8 @@ class Migrator:
def newEntry(self, title, partno, filename, md5, size, dvd, filetype, fileno, genreName, actorNames, quality):
seriesid = self.newSeries(title)
- seriespartid = self.newSeriesPart(seriesid, partno, quality)
- self.newFile(seriespartid, filename, md5, size, dvd, 1, partno)
+ seriespartid = self.newSeriesPart(seriesid, partno)
+ self.newFile(seriespartid, filename, md5, size, dvd, 1, partno, quality)
genreId = self.genreId(genreName)
newCur = self.mNewConn.cursor()
if genreId != -1:
@@ -129,18 +129,18 @@ class Migrator:
self.mNewGenreMap[genreName] = retval
return retval
- def newFile(self, seriespartid, filename, md5, size, dvd, filetype, fileno):
- q1 = "INSERT INTO files(iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno) VALUES(%s, %s, %s, %s, %s, %s, %s)"
+ def newFile(self, seriespartid, filename, md5, size, dvd, filetype, fileno, quality):
+ q1 = "INSERT INTO files(iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality) VALUES(%s, %s, %s, %s, %s, %s, %s, %s)"
cur = self.mNewConn.cursor()
try:
- cur.execute(q1, (seriespartid, filename, md5, size, dvd, filetype, fileno))
+ cur.execute(q1, (seriespartid, filename, md5, size, dvd, filetype, fileno, quality))
except psycopg2.Error as ex:
print "Error: %s" %(ex.pgerror, )
self.mNewConn.rollback()
self.mNewConn.commit()
- def newSeriesPart(self, seriesid, part, quality):
+ def newSeriesPart(self, seriesid, part):
part = part == -1 and 1 or part
q1 = "SELECT iseriesparts_id FROM seriesparts WHERE iseries_id = %s AND iseriespart = %s"
cur = self.mNewConn.cursor()
@@ -148,8 +148,8 @@ class Migrator:
spartids = cur.fetchall()
retval = -1
if len(spartids) == 0:
- q2 = "INSERT INTO seriesparts(iseriespart, iseries_id, iquality) VALUES(%s, %s, %s)"
- cur.execute(q2, (part, seriesid, quality))
+ q2 = "INSERT INTO seriesparts(iseriespart, iseries_id) VALUES(%s, %s)"
+ cur.execute(q2, (part, seriesid))
cur.execute("SELECT currval('seriesparts_seriesparts_id__seq')")
retval = cur.fetchall()[0][0]
self.mNewConn.commit()
diff --git a/seriestreemodel.cpp b/seriestreemodel.cpp
new file mode 100644
index 0000000..53098d1
--- /dev/null
+++ b/seriestreemodel.cpp
@@ -0,0 +1,188 @@
+/*
+ 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 <QSqlQuery>
+#include <QSqlError>
+#include <QIcon>
+
+#include <QDebug>
+
+#include "seriestreemodel.h"
+#include "smtreeitem.h"
+
+SeriesTreeModel::SeriesTreeModel(QStringList &headers, QObject *parent) : SmTreeModel(headers, parent){
+ mDb = QSqlDatabase::database("treedb");
+ mSeriesPartsQuery = new QSqlQuery(mDb);
+ mSeriesPartsQuery->prepare("SELECT iseriesparts_id, iseriespart FROM seriesparts WHERE iseries_id = :id ORDER BY iseriespart");
+ mUpdateSeriesIdQuery = new QSqlQuery(mDb);
+ mUpdateSeriesIdQuery->prepare("UPDATE series SET iseries_id = :newid WHERE iseries_id = :oldid");
+ mUpdateSeriesNameQuery = new QSqlQuery(mDb);
+ mUpdateSeriesNameQuery->prepare("UPDATE series SET tseries_name = :newname WHERE iseries_id = :id");
+ mDeleteSeriesQuery = new QSqlQuery(mDb);
+ mDeleteSeriesQuery->prepare("DELETE FROM series where iseries_id = :id");
+ populate();
+}
+
+SeriesTreeModel::~SeriesTreeModel(){
+ qDebug() << "dtor!";
+ delete mSeriesPartsQuery;
+ delete mUpdateSeriesIdQuery;
+ delete mUpdateSeriesNameQuery;
+ delete mDeleteSeriesQuery;
+ mDb.close();
+ QSqlDatabase::removeDatabase("treedb");
+}
+
+Qt::ItemFlags SeriesTreeModel::flags(const QModelIndex &index) const{
+ if(!index.isValid()){
+ return 0;
+ }
+ Qt::ItemFlags retval = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ if(index.data(TypeRole).toInt() == Series){
+ return retval | Qt::ItemIsEditable;
+ }
+ return retval;
+}
+
+QVariant SeriesTreeModel::data(const QModelIndex &index, int role) const{
+ if(!index.isValid()){
+ return QVariant();
+ }
+
+ SmTreeItem *item = static_cast<SmTreeItem*>(index.internalPointer());
+
+ if(role == Qt::DisplayRole){
+ if(index.column() == Name){
+ int type = index.data(TypeRole).toInt();
+ if(type == Series){
+ return item->data(Name);
+ }else if(type == Part){
+ QString retval = QString("%1 %2").arg(item->data(Name).toString()).arg(item->data(SeriesPart).toInt());
+ return retval;
+ }else{
+ return QVariant();
+ }
+ }else{
+ return item->data(index.column());
+ }
+ }
+ if(role == Qt::DecorationRole){
+ if(index.column() == 0){
+ return QIcon(":/dildo.png");
+ }
+ }
+ if(role == Qt::EditRole){
+ if(index.data(TypeRole) == Series){
+ if(index.column() == 0){
+ return item->data(Name);
+ }
+ }
+ }
+ if(role == NameRole){
+ return item->data(Name);
+ }
+ if(role == SeriesIdRole){
+ return item->data(SeriesId);
+ }
+ if(role == SeriesPartIdRole){
+ return item->data(SeriesPartId);
+ }
+ if(role == SeriesPartRole){
+ return item->data(SeriesPart);
+ }
+ if(role == TypeRole){
+ return item->data(Type);
+ }
+ return QVariant();
+}
+
+bool SeriesTreeModel::setData(const QModelIndex &index, const QVariant &value, int role){
+ if(!index.isValid()){
+ return false;
+ }
+ if(role == Qt::EditRole){
+ if(index.data(Type).toInt() == Series){
+ //change of series name
+ if(index.column() == Name){
+ QModelIndex newSeries = findValue(value, index.parent(), index.column());
+ int oldSeriesId = index.data(SeriesId).toInt();
+ if(newSeries != QModelIndex()){
+ //new series name already exists
+ int newSeriesId = newSeries.data(SeriesIdRole).toInt();
+ mUpdateSeriesIdQuery->bindValue(":oldid", oldSeriesId);
+ mUpdateSeriesIdQuery->bindValue(":newid", newSeriesId);
+ if(mUpdateSeriesIdQuery->exec()){
+ SmTreeItem *oldParent = static_cast<SmTreeItem*>(index.internalPointer());
+ SmTreeItem *newParent = static_cast<SmTreeItem*>(newSeries.internalPointer());
+ //reparent items to new series
+ for(int i = oldParent->childCount() - 1; i > -1; --i){
+ SmTreeItem *curItem = oldParent->child(i);
+ curItem->setParent(newParent);
+ curItem->setData(Name, value);
+ newParent->appendChild(curItem);
+ oldParent->removeChild(i, false);
+ }
+ mDeleteSeriesQuery->bindValue(":id", oldSeriesId);
+ if(mDeleteSeriesQuery->exec()){
+ //series has to be empty
+ root()->removeChild(index.row());
+ }
+ reset();
+ return true;
+ }
+ }else{
+ //rename series
+ mUpdateSeriesNameQuery->bindValue(":newname", value);
+ mUpdateSeriesNameQuery->bindValue(":id", oldSeriesId);
+ if(mUpdateSeriesNameQuery->exec()){
+ SmTreeItem *curItem = static_cast<SmTreeItem*>(index.internalPointer());
+ curItem->setData(Name, value);
+ emit dataChanged(index, index);
+ mDb.commit();
+ return true;
+ }
+ }
+
+ }
+ }
+ }
+ return false;
+}
+
+QModelIndex SeriesTreeModel::findValue(const QVariant &value, const QModelIndex &parent, int column) const{
+ SmTreeItem *parentItem = root();
+ if(parent != QModelIndex()){
+ parentItem = static_cast<SmTreeItem*>(parent.internalPointer());
+ }
+ for(int i = 0; i < parentItem->childCount(); ++i){
+ SmTreeItem *childItem = parentItem->child(i);
+ if(value == childItem->data(column)){
+ return createIndex(i, column, childItem);
+ }
+ }
+ return QModelIndex();
+}
+
+void SeriesTreeModel::populate(){
+ QSqlQuery seriesQuery = QSqlQuery("SELECT iseries_id, tseries_name FROM series ORDER BY tseries_name", mDb);
+ SmTreeItem *rootItem = new SmTreeItem(5);
+ while(seriesQuery.next()){
+ QList<QVariant> seriesData;
+ seriesData << seriesQuery.value(1) << seriesQuery.value(0) << QVariant() << QVariant() << Series;
+ SmTreeItem *seriesItem = new SmTreeItem(seriesData, rootItem);
+ rootItem->appendChild(seriesItem);
+ mSeriesPartsQuery->bindValue(":id", seriesData.at(1));
+ mSeriesPartsQuery->exec();
+ while(mSeriesPartsQuery->next()){
+ QList<QVariant> partData;
+ partData << seriesData.at(Name) << seriesData.at(SeriesId) << mSeriesPartsQuery->value(0) << mSeriesPartsQuery->value(1) << Part;
+ SmTreeItem *partItem = new SmTreeItem(partData, seriesItem);
+ seriesItem->appendChild(partItem);
+ }
+ }
+ setRoot(rootItem);
+}
diff --git a/seriestreemodel.h b/seriestreemodel.h
new file mode 100644
index 0000000..a61a4a9
--- /dev/null
+++ b/seriestreemodel.h
@@ -0,0 +1,43 @@
+/*
+ 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 SERIESTREEMODEL_H
+#define SERIESTREEMODEL_H
+
+#include <QSqlDatabase>
+
+#include "smtreemodel.h"
+
+class QSqlQuery;
+
+class SeriesTreeModel : public SmTreeModel {
+ Q_OBJECT
+ public:
+ enum CustomRoles { NameRole = Qt::UserRole + 1, SeriesIdRole = Qt::UserRole + 2, SeriesPartIdRole = Qt::UserRole + 3, SeriesPartRole = Qt::UserRole + 4, TypeRole = Qt::UserRole + 5 };
+ enum Fields { Name = 0, SeriesId = 1, SeriesPartId = 2, SeriesPart = 3, Type = 4 };
+ enum Types { Series, Part };
+ explicit SeriesTreeModel(QStringList &headers, QObject *parent = 0);
+ ~SeriesTreeModel();
+
+ //data + flags
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ //find
+ QModelIndex findValue(const QVariant &value, const QModelIndex &parent = QModelIndex(), int column = 0) const;
+
+ private:
+ void populate();
+ QSqlDatabase mDb;
+ QSqlQuery *mSeriesPartsQuery;
+ QSqlQuery *mUpdateSeriesIdQuery;
+ QSqlQuery *mUpdateSeriesNameQuery;
+ QSqlQuery *mDeleteSeriesQuery;
+};
+
+#endif // SERIESTREEMODEL_H
diff --git a/shemov.pro b/shemov.pro
index 39dd494..46cbbb9 100644
--- a/shemov.pro
+++ b/shemov.pro
@@ -51,7 +51,8 @@ SOURCES = main.cpp \
smubermodel.cpp \
smubermodelsingleton.cpp \
archivetreeview.cpp \
- seriestreewidget.cpp
+ seriestreewidget.cpp \
+ seriestreemodel.cpp
HEADERS = listitem.h \
listmodel.h \
movieitem.h \
@@ -98,6 +99,7 @@ HEADERS = listitem.h \
smubermodel.h \
smubermodelsingleton.h \
archivetreeview.h \
- seriestreewidget.h
+ seriestreewidget.h \
+ seriestreemodel.h
LIBS += -lmagic
RESOURCES = shemov.qrc
diff --git a/smtreeitem.cpp b/smtreeitem.cpp
index 950926e..e7f4336 100644
--- a/smtreeitem.cpp
+++ b/smtreeitem.cpp
@@ -23,7 +23,7 @@ void SmTreeItem::appendChild(SmTreeItem *child){
mChildren.append(child);
}
-SmTreeItem *SmTreeItem::child(int row){
+SmTreeItem *SmTreeItem::child(int row) const{
return mChildren.at(row);
}
@@ -46,6 +46,10 @@ SmTreeItem *SmTreeItem::parent(){
return mParent;
}
+void SmTreeItem::setParent(SmTreeItem *parent){
+ mParent = parent;
+}
+
QVariant SmTreeItem::data(int column) const{
return mData.at(column);
}
@@ -62,10 +66,13 @@ bool SmTreeItem::insertChild(int where, SmTreeItem *child){
return true;
}
-bool SmTreeItem::removeChild(int where){
+bool SmTreeItem::removeChild(int where, bool deleteChild){
if((where < 0) || (where >= mChildren.count())){
return false;
}
- delete mChildren.takeAt(where);
+ SmTreeItem *child = mChildren.takeAt(where);
+ if(deleteChild){
+ delete child;
+ }
return true;
}
diff --git a/smtreeitem.h b/smtreeitem.h
index 807e3d7..402d73f 100644
--- a/smtreeitem.h
+++ b/smtreeitem.h
@@ -17,15 +17,17 @@ class SmTreeItem {
SmTreeItem(int rows, SmTreeItem *parent = 0);
~SmTreeItem();
void appendChild(SmTreeItem *child);
- SmTreeItem *child(int row);
+ SmTreeItem *child(int row) const;
int childCount() const;
int columnCount() const;
int row() const;
SmTreeItem *parent();
+ void setParent(SmTreeItem *parent);
QVariant data(int column) const;
void setData(int column, const QVariant &data);
bool insertChild(int where, SmTreeItem *child);
- bool removeChild(int where);
+ bool removeChild(int where, bool deleteChild = true);
+
private:
QList<SmTreeItem*> mChildren;
diff --git a/smtreemodel.cpp b/smtreemodel.cpp
index c762802..292ed20 100644
--- a/smtreemodel.cpp
+++ b/smtreemodel.cpp
@@ -118,6 +118,14 @@ bool SmTreeModel::setRoot(SmTreeItem *rootItem){
return false;
}
+SmTreeItem *SmTreeModel::parentItem(const QModelIndex &child) const{
+ QModelIndex parent = child.parent();
+ if(parent == QModelIndex()){
+ return mRootItem;
+ }
+ return static_cast<SmTreeItem*>(child.parent().internalPointer());
+}
+
bool SmTreeModel::insertRows(int row, int count, const QModelIndex &parent){
SmTreeItem *parentItem = itemAt(parent);
bool retval;
diff --git a/smtreemodel.h b/smtreemodel.h
index 698a2ce..ae3b5ce 100644
--- a/smtreemodel.h
+++ b/smtreemodel.h
@@ -17,7 +17,7 @@ class SmTreeModel : public QAbstractItemModel {
Q_OBJECT
public:
explicit SmTreeModel(const QStringList &headers, QObject *parent = 0);
- ~SmTreeModel();
+ virtual ~SmTreeModel();
// counts
int rowCount(const QModelIndex &parent) const;
@@ -26,14 +26,18 @@ class SmTreeModel : public QAbstractItemModel {
// index, parent and flags
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
// headers + data
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
- QVariant data(const QModelIndex &index, int role) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role);
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ // root + parent item
bool setRoot(SmTreeItem *rootItem);
+ SmTreeItem *root() const { return mRootItem; }
+ SmTreeItem *parentItem(const QModelIndex &child) const;
// row manipulation
bool insertRows(int row, int count, const QModelIndex &parent);
diff --git a/smubermodel.cpp b/smubermodel.cpp
index d07b762..205b8d7 100644
--- a/smubermodel.cpp
+++ b/smubermodel.cpp
@@ -11,6 +11,7 @@
#include "smubermodel.h"
#include "smtreemodel.h"
+#include "seriestreemodel.h"
#include "smtreeitem.h"
#include "actormodel.h"
@@ -23,19 +24,21 @@ SmUberModel::SmUberModel(QObject *parent) : QObject(parent), mSeriesModel(0), mF
mDb.setDatabaseName("shemov2");
mDb.open();
mSeriesPartsQuery = new QSqlQuery(mDb);
- mSeriesPartsQuery->prepare("SELECT iseriesparts_id, iseriespart, iseries_id, iquality FROM seriesparts WHERE iseries_id = :id ORDER BY iseriespart");
+ //mSeriesPartsQuery->prepare("SELECT iseriesparts_id, iseriespart, iseries_id, iquality FROM seriesparts WHERE iseries_id = :id ORDER BY iseriespart");
//series model
- QStringList seriesHeaders = QStringList() << tr("Series") << tr("Quality") << tr("Id");
- mSeriesModel = new SmTreeModel(seriesHeaders, this);
- populateSeriesmodel();
+ QStringList seriesHeaders = QStringList() << tr("Series") << QString() << QString() << QString() << QString();
+ mSeriesModel = new SeriesTreeModel(seriesHeaders, this);
+ //populateSeriesmodel();
}
SmUberModel::~SmUberModel(){
- delete mSeriesPartsQuery;
+ delete mSeriesModel;
+ QSqlDatabase::removeDatabase("treedb");
+ //delete mSeriesPartsQuery;
}
-void SmUberModel::populateSeriesmodel(){
+/*void SmUberModel::populateSeriesmodel(){
QSqlQuery seriesQuery("SELECT iseries_id, tseries_name FROM series ORDER BY tseries_name", mDb);
SmTreeItem *root = new SmTreeItem(3);
while(seriesQuery.next()){
@@ -53,4 +56,4 @@ void SmUberModel::populateSeriesmodel(){
}
}
mSeriesModel->setRoot(root);
-}
+}*/
diff --git a/smubermodel.h b/smubermodel.h
index fed8d86..8d82a47 100644
--- a/smubermodel.h
+++ b/smubermodel.h
@@ -11,6 +11,8 @@
#include <QObject>
#include <QSqlDatabase>
+#include "seriestreemodel.h"
+
class SmTreeModel;
class ActorModel;
class QSqlQuery;
@@ -19,17 +21,17 @@ class SmUberModel : public QObject {
Q_OBJECT
public:
explicit SmUberModel(QObject *parent = 0);
- SmTreeModel *seriesModel() { return mSeriesModel; }
+ SeriesTreeModel *seriesModel() { return mSeriesModel; }
~SmUberModel();
private:
- void populateSeriesmodel();
+ //void populateSeriesmodel();
//database
QSqlDatabase mDb;
QSqlQuery *mSeriesPartsQuery;
//models
- SmTreeModel *mSeriesModel;
+ SeriesTreeModel *mSeriesModel;
SmTreeModel *mFileModel;
ActorModel *mActorModel;