diff options
Diffstat (limited to 'listmodel.cpp')
-rw-r--r-- | listmodel.cpp | 186 |
1 files changed, 186 insertions, 0 deletions
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 <QString> +#include <QSqlQuery> + +#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<ListItem*>(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<ListItem*>(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(); +} |