diff options
-rw-r--r-- | mappingtreemodel.cpp | 244 | ||||
-rw-r--r-- | mappingtreemodel.h | 72 | ||||
-rw-r--r-- | shemov.pro | 6 |
3 files changed, 320 insertions, 2 deletions
diff --git a/mappingtreemodel.cpp b/mappingtreemodel.cpp new file mode 100644 index 0000000..e48c608 --- /dev/null +++ b/mappingtreemodel.cpp @@ -0,0 +1,244 @@ +/* + 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 <QSqlDatabase> +#include <QSqlQuery> + +#include "mappingtreemodel.h" +#include "smtreeitem.h" + +MappingTreeModel::MappingTreeModel(QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mType(-1) { + //init database + mDb = QSqlDatabase::database("treedb"); + mTypesQ = new QSqlQuery(mDb); + mTypesQ->prepare("SELECT imappings_type_id, tmappings_type_name FROM mapppings_type"); + getMappingTypes(); + + //prepare Queries + mTypeParentsQ = new QSqlQuery(mDb); + mTypeParentsQ->prepare("SELECT imapping_id, tmapping_name, tscreated FROM mappings WHERE imapping_id NOT IN (SELECT imapping_id FROM mappings_parents) AND imapping_type = :type"); + mChildrenQ = new QSqlQuery(mDb); + mChildrenQ->prepare("SELECT mappings.imapping_id, mappings.tmapping_name, mappings.tscreated FROM mappings, mappings_parents WHERE mappings_parents.iparent_id = :id AND mappings.imapping_id = mappings_parents.imapping_id"); + mUpdateTypeQ = new QSqlQuery(mDb); + mUpdateTypeQ->prepare("UPDATE mappings_type SET tmappings_type_name = :value WHERE imappings_type_id = :id"); + mUpdateChildQ = new QSqlQuery(mDb); + mUpdateChildQ->prepare("UPDATE mappings SET tmapping_name = :value WHERE imapping_id = :id"); + mAddMappingTypeQ = new QSqlQuery(mDb); + mAddMappingTypeQ->prepare("INSERT INTO mappings_type (tmappings_type_name) VALUES(:value)"); + mDeleteMappingTypeQ = new QSqlQuery(mDb); + mDeleteMappingTypeQ->prepare("DELETE FROM mappings_type WHERE imappings_type_id = :id"); + mAddChildQ = new QSqlQuery(mDb); + mAddChildQ->prepare("INSERT INTO mappings (tmapping_name, imapping_type) VALUES(:name, :type)"); + mSelectChildQ = new QSqlQuery(mDb); + mSelectChildQ->prepare("SELECT imapping_id, tmapping_name, tscreated FROM mappings WHERE tmapping_name = :name AND imapping_type = :type"); + mAddParentQ = new QSqlQuery(mDb); + mAddParentQ->prepare("INSERT INTO mappings_parents VALUES(:id, :parentid"); + mDeleteChildQ = new QSqlQuery(mDb); + mDeleteChildQ->prepare("DELETE FROM mappings WHERE imapping_id = :id"); +} + +MappingTreeModel::~MappingTreeModel(){ + delete mTypesQ; + delete mTypeParentsQ; + delete mChildrenQ; + delete mUpdateTypeQ; + delete mUpdateChildQ; + delete mAddMappingTypeQ; + delete mDeleteMappingTypeQ; + delete mAddChildQ; + delete mSelectChildQ; + delete mAddParentQ; + delete mDeleteChildQ; + mDb = QSqlDatabase(); +} + +QStringList MappingTreeModel::mappingTypeNames() const { + QStringList retval; + foreach(mappingType t, mMappingTypes){ + retval << t.name.toString(); + } + qSort(retval); + return retval; +} + +int MappingTreeModel::mappingTypeIdFromName(const QVariant &name) const{ + foreach(const mappingType t, mMappingTypes){ + if(t.name == name){ + return t.id.toInt(); + } + } + return -1; +} + +QString MappingTreeModel::mappingTypeNameFromId(int id) const{ + foreach(const mappingType t, mMappingTypes){ + if(t.id == id){ + return t.name.toString(); + } + } + return QString(); +} + +QVariant MappingTreeModel::data(const QModelIndex &index, int role) const{ + if(!index.isValid()){ + return QVariant(); + } + SmTreeItem *item = itemAt(index); + if(role == NameRole){ + return item->data(Name); + } + if(role == IdRole){ + return item->data(Id); + } + if(role == AddedRole){ + return item->data(Added); + } + return SmTreeModel::data(index, role); +} + +bool MappingTreeModel::setData(const QModelIndex &index, const QVariant &value, int role){ + if(!index.isValid()){ + return false; + } + if(role == Qt::EditRole || role == NameRole){ + mDb.transaction(); + SmTreeItem *item = itemAt(index); + QSqlQuery *q = 0; + if(item == root()){ + q = mUpdateTypeQ; + }else{ + q = mUpdateChildQ; + } + q->bindValue(":value", value); + q->bindValue(":id", item->data(Id)); + if(q->exec()){ + item->setData(Name, value); + emit dataChanged(index, index); + mDb.commit(); + return true; + } + mDb.rollback(); + } + return false; +} + +bool MappingTreeModel::addMappingType(const QString &type){ + mAddMappingTypeQ->bindValue(":value", type); + mDb.transaction(); + if(mAddMappingTypeQ->exec()){ + mDb.commit(); + getMappingTypes(); + return true; + } + mDb.rollback(); + return false; +} + +bool MappingTreeModel::deleteMappingType(int typeId){ + mDeleteMappingTypeQ->bindValue(":id", typeId); + mDb.transaction(); + if(mDeleteMappingTypeQ->exec()){ + mDb.commit(); + getMappingTypes(); + return true; + } + mDb.rollback(); + return false; +} + +bool MappingTreeModel::addChild(const QVariant &name, const QModelIndex &parent){ + if(!parent.isValid()){ + return false; + } + SmTreeItem *pItem = itemAt(parent); + mAddChildQ->bindValue(":name", name); + mAddChildQ->bindValue(":type", mType); + if(mAddChildQ->exec()){ + mSelectChildQ->bindValue(":name", name); + mSelectChildQ->bindValue(":type", mType); + while(mSelectChildQ->next()){ + QList<QVariant> newData; + newData << mSelectChildQ->value(1) << mSelectChildQ->value(0) << mSelectChildQ->value(2); + SmTreeItem *childItem = new SmTreeItem(newData, pItem); + pItem->appendChild(childItem); + mAddParentQ->bindValue(":id", childItem->data(Id)); + mAddParentQ->bindValue(":parentid", pItem->data(Id)); + mAddParentQ->exec(); + emit dataChanged(parent, parent); + return true; + } + } + return false; +} + +bool MappingTreeModel::deleteChild(const QModelIndex &idx){ + if(!idx.isValid()){ + return false; + } + SmTreeItem *item = itemAt(idx); + if(item->childCount() > 0){ + return false; + } + mDeleteChildQ->bindValue(":id", item->data(Id)); + if(mDeleteChildQ->exec()){ + const QModelIndex &parent = idx.parent(); + SmTreeItem *pItem = itemAt(parent); + pItem->removeChild(item->row()); + emit dataChanged(parent, parent); + return true; + } + return false; +} + +void MappingTreeModel::populate(){ + if(mType == -1){ + return; + } + // get nodes with root as parent + mTypeParentsQ->bindValue(":type", mType); + if(mTypeParentsQ->exec()){ + SmTreeItem *rootItem = new SmTreeItem(NumFields); + rootItem->setData(Name, mappingTypeNameFromId(mType)); + rootItem->setData(Id, mType); + //collect children recursive + while(mTypeParentsQ->next()){ + QList<QVariant> childData; + childData << mTypeParentsQ->value(1) << mTypeParentsQ->value(0) << mTypeParentsQ->value(2); + SmTreeItem *childItem = new SmTreeItem(childData, rootItem); + rootItem->appendChild(childItem); + getChildrenRecursive(childItem); + } + setRoot(rootItem); + } +} + +void MappingTreeModel::getMappingTypes(){ + bool qRes = mTypesQ->exec(); + if(qRes){ + mMappingTypes.clear(); + while(mTypesQ->next()){ + mappingType t; + t.id = mTypesQ->value(0); + t.name = mTypesQ->value(1); + mMappingTypes << t; + } + emit mappingTypesChanged(); + } +} + +void MappingTreeModel::getChildrenRecursive(SmTreeItem *item){ + mChildrenQ->bindValue(":id", item->data(Id)); + if(mChildrenQ->exec()){ + while(mChildrenQ->next()){ + QList<QVariant> childData; + childData << mChildrenQ->value(1) << mChildrenQ->value(0) << mChildrenQ->value(2); + SmTreeItem *child = new SmTreeItem(childData, item); + item->appendChild(child); + getChildrenRecursive(child); + } + } +} diff --git a/mappingtreemodel.h b/mappingtreemodel.h new file mode 100644 index 0000000..a18ce57 --- /dev/null +++ b/mappingtreemodel.h @@ -0,0 +1,72 @@ +/* + 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 MAPPINGTREEMODEL_H +#define MAPPINGTREEMODEL_H + +#include <QSqlDatabase> + +#include "smtreemodel.h" + +class QSqlQuery; +class SmTreeItem; + +class MappingTreeModel : public SmTreeModel { + Q_OBJECT + public: + enum Roles { NameRole = Qt::UserRole + 1, IdRole = Qt::UserRole + 2, AddedRole = Qt::UserRole + 3 }; + enum Fields { Name = 0, Id = 1, Added = 2 }; + enum { NumFields = 3 }; + MappingTreeModel(QStringList &headers, QObject *parent = 0); + ~MappingTreeModel(); + + //model type convenience functions + int type() const { return mType; } + QStringList mappingTypeNames() const; + int mappingTypeIdFromName(const QVariant &name) const; + QString mappingTypeNameFromId(int id) const; + + //data + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); + bool addMappingType(const QString &type); + bool deleteMappingType(int typeId); + bool addChild(const QVariant &name, const QModelIndex &parent); + bool deleteChild(const QModelIndex &idx); + + public slots: + void populate(); + void setType(int type) { mType = type; } + + signals: + void mappingTypesChanged(); + + private: + struct mappingType { + QVariant id; + QVariant name; + }; + void getMappingTypes(); + void getChildrenRecursive(SmTreeItem *item); + QSqlDatabase mDb; + QSqlQuery *mTypesQ; + QSqlQuery *mTypeParentsQ; + QSqlQuery *mChildrenQ; + QSqlQuery *mUpdateTypeQ; + QSqlQuery *mUpdateChildQ; + QSqlQuery *mAddMappingTypeQ; + QSqlQuery *mDeleteMappingTypeQ; + QSqlQuery *mAddChildQ; + QSqlQuery *mSelectChildQ; + QSqlQuery *mAddParentQ; + QSqlQuery *mDeleteChildQ; + QList<mappingType> mMappingTypes; + int mType; + +}; + +#endif // MAPPINGTREEMODEL_H @@ -35,7 +35,8 @@ SOURCES = main.cpp \ mappingtableeditor.cpp \ smdialog.cpp \ propertiesdialog.cpp \ - dbanalyzer.cpp + dbanalyzer.cpp \ + mappingtreemodel.cpp HEADERS = listitem.h \ filesystemdirproxy.h \ filesystemwidget.h \ @@ -66,6 +67,7 @@ HEADERS = listitem.h \ mappingtableeditor.h \ smdialog.h \ propertiesdialog.h \ - dbanalyzer.h + dbanalyzer.h \ + mappingtreemodel.h LIBS += -lmagic -lXfixes -lX11 RESOURCES = shemov.qrc |