From 5d0939c3c64f357b5c4fcbcc98ccb4cfa6314182 Mon Sep 17 00:00:00 2001 From: am Date: Thu, 2 Jul 2009 19:28:19 +0000 Subject: -Working on making MovieModel editable... git-svn-id: file:///var/svn/repos2/shemov/trunk@374 f440f766-f032-0410-8965-dc7d17de2ca0 --- listitem.h | 27 +++++++++ listmodel.cpp | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ listmodel.h | 51 ++++++++++++++++ main.cpp | 17 ++++++ movieitem.cpp | 101 +++++++++++++++++++++++++++++++ movieitem.h | 47 +++++++++++++++ moviemodel.cpp | 109 +++++++++++++++++++++++++++++++++ moviemodel.h | 41 +++++++++++++ shemov.pro | 12 ++++ 9 files changed, 591 insertions(+) create mode 100644 listitem.h create mode 100644 listmodel.cpp create mode 100644 listmodel.h create mode 100644 main.cpp create mode 100644 movieitem.cpp create mode 100644 movieitem.h create mode 100644 moviemodel.cpp create mode 100644 moviemodel.h create mode 100644 shemov.pro diff --git a/listitem.h b/listitem.h new file mode 100644 index 0000000..4b48d41 --- /dev/null +++ b/listitem.h @@ -0,0 +1,27 @@ +/* + 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 LISTITEM_H +#define LISTITEM_H + +class QString; + +class ListItem { + public: + ListItem(QString name, int id) : mId(id), mName(name) {}; + ~ListItem() {}; + int id() const { return mId; }; + const QString name() const { return mName; }; + void setId(int id) { mId = id; }; + void setName(const QString &name) { mName = name; }; + private: + int mId; + QString mName; +}; + +#endif + diff --git a/listmodel.cpp b/listmodel.cpp new file mode 100644 index 0000000..d8b6ccc --- /dev/null +++ b/listmodel.cpp @@ -0,0 +1,186 @@ + +/* + 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 "listmodel.h" +#include "listitem.h" + +ListModel::ListModel(const QString table, QObject *parent) : QAbstractItemModel(parent), mTable(table){ + QString updateQuery = QString("UPDATE %1 SET t%1name = :name WHERE i%1id = :id").arg(mTable); + mUpdateQuery = new QSqlQuery(updateQuery); + QString insertQuery = QString("INSERT INTO %1(t%1name) VALUES(:name)").arg(mTable); + mInsertQuery = new QSqlQuery(insertQuery); + QString deleteQuery = QString("DELETE FROM %1 WHERE t%1name = :name").arg(mTable); + mDeleteQuery = new QSqlQuery(deleteQuery); + QString idQuery = QString("SELECT i%1id FROM %1 WHERE t%1name = :name").arg(mTable); + mIdQuery = new QSqlQuery(idQuery); + populate(); +} + +ListModel::~ListModel(){ + qDeleteAll(mItems); +} + +QModelIndex ListModel::index(int row, int column, const QModelIndex &) const{ + if(column != 0){ + return QModelIndex(); + } + if(row > mItems.size()){ + return QModelIndex(); + } + return createIndex(row, 0); +} + +int ListModel::rowCount(const QModelIndex &) const{ + return mItems.size(); +} + +QVariant ListModel::data(const QModelIndex &index, int role) const{ + if(!index.isValid()){ + return QVariant(); + } + if(index.column() > 0){ + return QVariant(); + } + if(index.row() > mItems.size()){ + return QVariant(); + } + ListItem *item = static_cast(index.internalPointer()); + Q_ASSERT(item != 0); + switch (role){ + case Qt::DisplayRole: + return item->name(); + break; + case IdRole: + return item->id(); + } + return QVariant(); +} + +bool ListModel::insertRows(int row, int count, const QModelIndex &){ + beginInsertRows(QModelIndex(), row, row + count - 1); + for(int i = row; i < (row + count); ++i){ + ListItem *newItem = new ListItem(QString(), -1); + mItems.insert(i, newItem); + } + endInsertRows(); + return true; +} + +bool ListModel::removeRows(int row, int count, const QModelIndex&){ + if(row > mItems.size()){ + return false; + } + if((row - count - mItems.size()) < 0){ + return false; + } + beginRemoveRows(QModelIndex(), row, row + (count - 1)); + for(int i = row; i < (row + count); ++i){ + ListItem *delItem = mItems.at(i); + delete delItem; + mItems.removeAt(i); + } + endRemoveRows(); + return true; +} + +bool ListModel::setData(const QModelIndex &idx, const QVariant &data, int role){ + if((!idx.isValid()) || (role != Qt::EditRole) || (idx.column() != 0)){ + return false; + } + ListItem *item = static_cast(idx.internalPointer()); + Q_ASSERT(item != 0); + int id = item->id(); + bool success = false; + if(id == -1){ + //this is an update + mUpdateQuery->bindValue(":id", id); + success = mUpdateQuery->exec(); + }else{ + //this is an insert + mInsertQuery->bindValue(":name", data); + success = mInsertQuery->exec(); + if(success){ + mIdQuery->bindValue(":name", data); + success = mIdQuery->exec(); + int count = 0; + while(mIdQuery->next()){ + id = mIdQuery->value(0).toInt(); + ++count; + } + Q_ASSERT(count == 1); + item->setName(data.toString()); + item->setId(id); + } + } + if(success){ + qSort(mItems.begin(), mItems.end(), sortListItems); + dataChanged(index(0, 0), index((mItems.size() - 1), 0)); + } + return success; +} + +bool ListModel::addItem(const QVariant &item){ + bool success = false; + if(insertRows(0, 1, QModelIndex())){ + QModelIndex idx = index(0, 0); + if(idx.isValid()){ + success = setData(idx, item); + } + } + return success; +} + +bool ListModel::removeItem(const QVariant &item){ + QString text = item.toString(); + int rowToDelete = -1; + for(int row = 0; row < rowCount(); ++row){ + QString data = index(row, 0).data().toString(); + if(data == text){ + rowToDelete = row; + break; + } + } + if(rowToDelete == -1){ + return false; + } + bool success = removeRows(rowToDelete, 1, QModelIndex()); + if(success){ + mDeleteQuery->bindValue(":name", item.toString()); + success = mDeleteQuery->exec(); + } + return success; +} + +bool ListModel::renameItem(const QVariant &oldName, const QVariant &newName){ + QModelIndex idx = QModelIndex(); + bool success = false; + for(int i = 0; i < rowCount(); ++i){ + idx = index(i, 0); + if(idx.data().toString() == oldName.toString()){ + success = setData(idx, newName); + } + } + return success; +} + +void ListModel::populate(){ + QString query = QString("SELECT i%1id, t%1name FROM %1 ORDER BY t%1name").arg(mTable); + QSqlQuery q(query); + q.exec(); + while(q.next()){ + ListItem *newItem = new ListItem(q.value(1).toString(), q.value(0).toInt()); + mItems << newItem; + } +} + +bool sortListItems(const ListItem *lhs, const ListItem *rhs){ + return lhs->name().toLower() < rhs->name().toLower(); +} diff --git a/listmodel.h b/listmodel.h new file mode 100644 index 0000000..1ecf10b --- /dev/null +++ b/listmodel.h @@ -0,0 +1,51 @@ +/* + 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 LISTMODEL_H +#define LISTMODEL_H + +#include +#include + +class QString; +class ListItem; +class QModelIndex; +class QSqlQuery; + +class ListModel : public QAbstractItemModel { + Q_OBJECT + Q_ENUMS(CustomRoles) + public: + enum CustomRoles {IdRole = Qt::UserRole + 1}; + ListModel(const QString table, QObject *parent); + ~ListModel(); + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &) const { return 1; }; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool insertRows(int row, int count, const QModelIndex &parent); + bool removeRows(int row, int count, const QModelIndex &parent); + bool setData(const QModelIndex &idx, const QVariant &data, int role = Qt::EditRole); + bool addItem(const QVariant &item); + bool removeItem(const QVariant &item); + bool renameItem(const QVariant &oldName, const QVariant &newName); + + private: + void populate(); + QString mTable; + QList mItems; + QSqlQuery *mUpdateQuery; + QSqlQuery *mInsertQuery; + QSqlQuery *mDeleteQuery; + QSqlQuery *mIdQuery; +}; + +bool sortListItems(const ListItem *lhs, const ListItem *rhs); + +#endif + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..34f2917 --- /dev/null +++ b/main.cpp @@ -0,0 +1,17 @@ +/* + 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 + +int main(int argc, char **argv){ + QApplication app(argc, argv); + QCoreApplication::setOrganizationName("Sissie's, Inc."); + QCoreApplication::setOrganizationDomain("hadante.servebeer.com"); + QCoreApplication::setApplicationName("SheMov"); + QCoreApplication::setApplicationVersion("0.1"); + return app.exec(); +} diff --git a/movieitem.cpp b/movieitem.cpp new file mode 100644 index 0000000..defca5c --- /dev/null +++ b/movieitem.cpp @@ -0,0 +1,101 @@ +/* + 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 "movieitem.h" + +MovieItem::MovieItem(int id, QObject *parent) : QObject(parent), mNumRows(7), mId(id), mGenreId(-1) { + for(int i = 0; i < mNumRows; ++i){ + mRows << QVariant(); + } + if(mId != -1){ + populate(); + setGenreName(); + setActors(); + setSize(); + } +} + +void MovieItem::setId(int id){ + mId = id; + populate(); + setGenreName(); + setActors(); + setSize(); +} + +bool MovieItem::setData(const QList &data){ + if(!data.size() == mNumRows){ + return false; + } + mRows = data; + return true; +} + +void MovieItem::setDataAt(const QVariant &data, Columns column){ + mRows[column] = data; +} + +const QList MovieItem::data() const { + return mRows; +} + +const QVariant MovieItem::dataAt(int column) const { + if(column >= NumRows){ + return QVariant(); + } + return mRows[column]; +} + +void MovieItem::populate(){ + QSqlQuery movieData("SELECT ttitle, tfilename, cmd5sum, bisize, igenreid, iquality, idvd FROM movies WHERE imovid = :id"); + movieData.bindValue(":id", mId); + movieData.exec(); + for(int i = 0; i < mNumRows; ++i){ + if(movieData.next()){ + mRows[i] = movieData.value(i); + } + } +} + +void MovieItem::setGenreName(){ + qint32 genreId = dataAt(Genre).toInt(); + QSqlQuery genreQuery("SELECT tgenrename FROM genre WHERE igenreid = :id"); + genreQuery.bindValue(":id", genreId); + genreQuery.exec(); + while(genreQuery.next()){ + setDataAt(genreQuery.value(0), Genre); + } +} + +void MovieItem::setActors(){ + QSqlQuery actorQuery("SELECT actor.tactorname FROM actors, actormoviemap WHERE actormoviemap.iactorid = actor.iactorid AND actormoviemap.imovid = :id"); + actorQuery.bindValue(":id", mId); + actorQuery.exec(); + while(actorQuery.next()){ + mActors << actorQuery.value(0); + } +} + +void MovieItem::setSize(){ + qint64 size = dataAt(Size).toInt(); + QString sizeString(tr("%1 %2iB")); + if(size > 1024){ + double value = size / 1024.0; + setDataAt(sizeString.arg(QString::number(value, 'f', 2), "K"), Size); + } + if(size > (1024 * 1024)){ + double value = size / (1024.0 * 1024.0); + setDataAt(sizeString.arg(QString::number(value, 'f', 2), "M"), Size); + } + if(size > (1024 * 1024 * 1024)){ + double value = size / (1024.0 * 1024.0 * 1024.0); + setDataAt(sizeString.arg(QString::number(value, 'f', 2), "G"), Size); + } +} + diff --git a/movieitem.h b/movieitem.h new file mode 100644 index 0000000..af8e530 --- /dev/null +++ b/movieitem.h @@ -0,0 +1,47 @@ +/* + 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 MOVIEITEM_H +#define MOVIEITEM_H + +#include +#include +#include + +class QSqlQuery; + +class MovieItem : public QObject { + Q_OBJECT + Q_ENUMS(Columns) + public: + enum Columns { Title = 1, Filename = 2, Md5Sum = 3, Size = 4, Genre = 5, Quality = 6, Dvd = 7 }; + enum { NumRows = 7 }; + MovieItem(int id = -1, QObject *parent = 0); + ~MovieItem() {}; + int id() const { return mId; }; + void setId(int id); + int genreId() const { return mGenreId; }; + bool setData(const QList &data); + void setDataAt(const QVariant &data, Columns column); + const QList data() const; + const QVariant dataAt(int column) const; + const QList actors() const { return mActors; }; + void populate(); + + private: + void setGenreName(); + void setActors(); + void setSize(); + const int mNumRows; + int mId; + int mGenreId; + QList mRows; + QList mActors; +}; + +#endif + diff --git a/moviemodel.cpp b/moviemodel.cpp new file mode 100644 index 0000000..a4f47dc --- /dev/null +++ b/moviemodel.cpp @@ -0,0 +1,109 @@ +/* + 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 "moviemodel.h" + +MovieModel::MovieModel(QObject *parent) : QAbstractItemModel(parent) { + mHeaders << tr("Title") << tr("Filename") << tr("MD5Sum") << tr("Size") << tr("Genre") << tr("Quality") << tr("Archived"); + populate(); +} + +MovieModel::~MovieModel(){ + qDeleteAll(mItems); +} + +QModelIndex MovieModel::index(int row, int column, const QModelIndex &parent) const{ + if((parent != QModelIndex()) || (!hasIndex(row, column, parent)) || (row > mItems.size())){ + return QModelIndex(); + } + MovieItem *internal = mItems.at(row); + return createIndex(row, column, internal); +} + +QVariant MovieModel::data(const QModelIndex &index, int role) const{ + if(!index.isValid()){ + return QVariant(); + } + if(role == Qt::DisplayRole){ + MovieItem *item = static_cast(index.internalPointer()); + Q_ASSERT(item != 0); + switch (index.column()){ + case MovieItem::Dvd: + return QVariant(QString(tr("DVD %1")).arg(QString::number(item->dataAt(MovieItem::Dvd).toInt()))); + } + return item->dataAt(index.column()); + } + return QVariant(); +} + +Qt::ItemFlags MovieModel::flags(const QModelIndex &index) const{ + if(!index.isValid()){ + return 0; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant MovieModel::headerData(int section, Qt::Orientation o, int role) const{ + if((o == Qt::Horizontal) && (role == Qt::DisplayRole)){ + if(section < mHeaders.size()){ + return mHeaders.at(section); + } + } + return QVariant(); +} + +bool MovieModel::insertRows(int row, int count, const QModelIndex &){ + if(row > rowCount(QModelIndex())){ + return false; + } + Q_ASSERT(count == 1); + beginInsertRows(QModelIndex(), row, row); + MovieItem *newItem = new MovieItem(-1, 0); + mItems.insert(row, newItem); + endInsertRows(); + return true; +} + +bool MovieModel::removeRows(int row, int count, const QModelIndex &){ + if(row >= rowCount(QModelIndex())){ + return false; + } + beginRemoveRows(QModelIndex(), row, row + count - 1); + for(int i = row; i < (row + count); ++i){ + MovieItem *item = mItems.at(i); + delete item; + mItems.removeAt(i); + } + endRemoveRows(); + return true; +} + +bool MovieModel::setDataAt(const QModelIndex &index, const QList &data, qint32 genre, const QList &actors, const QList &covers){ + if(!index.isValid() || (data.size() > MovieItem::NumRows)){ + return false; + } + MovieItem *item = static_cast(index.internalPointer()); + Q_ASSERT(item != 0); + if(item->id() != -1){ + qWarning("ID not as expected: item->id() == %d", item->id()); + return false; + } + return true; +} + +void MovieModel::populate(){ + QSqlQuery movieQuery("SELECT imovid FROM movies"); + movieQuery.exec(); + while(movieQuery.next()){ + int id = movieQuery.value(0).toInt(); + MovieItem *item = new MovieItem(id); + mItems << item; + } +} + diff --git a/moviemodel.h b/moviemodel.h new file mode 100644 index 0000000..8ff8c87 --- /dev/null +++ b/moviemodel.h @@ -0,0 +1,41 @@ +/* + 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 MOVIEMODEL_H +#define MOVIEMODEL_H + +#include +#include + +#include "movieitem.h" + +class MovieModel : public QAbstractItemModel { + Q_OBJECT + Q_ENUMS(CustomRoles) + public: + enum CustomRoles { Md5Role = Qt::UserRole + 1}; + MovieModel(QObject *parent = 0); + ~MovieModel(); + QModelIndex index(int row, int column, const QModelIndex &parent) const; + QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }; + int columnCount(const QModelIndex &) const { return MovieItem::NumRows; }; + int rowCount(const QModelIndex &) const { return mItems.size(); }; + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation o, int role) const; + bool insertRows(int row, int count, const QModelIndex &); + bool removeRows(int row, int count, const QModelIndex &); + bool setDataAt(const QModelIndex &index, const QList &data, qint32 genre, const QList &actors, const QList &covers); + + private: + void populate(); + QList mItems; + QList mHeaders; +}; + +#endif + diff --git a/shemov.pro b/shemov.pro new file mode 100644 index 0000000..bba50ae --- /dev/null +++ b/shemov.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +CONFIG += warn_on thread qt debug +CONFIG -= release +QT += sql +SOURCES = main.cpp \ +listmodel.cpp \ +movieitem.cpp \ +moviemodel.cpp +HEADERS = listitem.h \ +listmodel.h \ +movieitem.h \ +moviemodel.h -- cgit v1.2.3-70-g09d2