diff options
-rw-r--r-- | migdb.py | 16 | ||||
-rw-r--r-- | seriestreemodel.cpp | 188 | ||||
-rw-r--r-- | seriestreemodel.h | 43 | ||||
-rw-r--r-- | shemov.pro | 6 | ||||
-rw-r--r-- | smtreeitem.cpp | 13 | ||||
-rw-r--r-- | smtreeitem.h | 6 | ||||
-rw-r--r-- | smtreemodel.cpp | 8 | ||||
-rw-r--r-- | smtreemodel.h | 12 | ||||
-rw-r--r-- | smubermodel.cpp | 17 | ||||
-rw-r--r-- | smubermodel.h | 8 |
10 files changed, 288 insertions, 29 deletions
@@ -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 @@ -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; |