diff options
Diffstat (limited to 'sigmodr/tree/SigmodrTreeModel.cpp')
-rw-r--r-- | sigmodr/tree/SigmodrTreeModel.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/sigmodr/tree/SigmodrTreeModel.cpp b/sigmodr/tree/SigmodrTreeModel.cpp new file mode 100644 index 00000000..51bea45d --- /dev/null +++ b/sigmodr/tree/SigmodrTreeModel.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2008 Ben Boeckel <MathStuf@gmail.com> + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// Header include +#include "SigmodTreeModel.h" + +// Model includes +#include "models/RootModel.h" + +// Sigmod includes +#include "../sigmod/Sigmod.h" + +// Qt includes +#include <QtCore/QMimeData> +#include <QtCore/QStringList> +#include <QtCore/QUrl> +#include <QtXml/QDomDocument> + +Sigmodr::SigmodTreeModel::SigmodTreeModel(QObject* parent) : + QAbstractItemModel(parent), + m_root(new RootModel) +{ + connect(m_root, SIGNAL(rowsChanged(QList<int>)), this, SLOT(rowsChanged(QList<int>))); +} + +Sigmodr::SigmodTreeModel::~SigmodTreeModel() +{ + delete m_root; +} + +QVariant Sigmodr::SigmodTreeModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + BaseModel* object = static_cast<BaseModel*>(index.internalPointer()); + return object->data(role); +} + +QVariant Sigmodr::SigmodTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex Sigmodr::SigmodTreeModel::index(int row, int column, const QModelIndex& parent) const +{ + if ((row < -1) || (column < -1)) + return QModelIndex(); + if (row == -1) + return createIndex(row, 0, m_root); + BaseModel* model = getItem(parent); + if ((model->rowCount() <= row) || (1 <= column)) + return QModelIndex(); + BaseModel* object = model->childItem(row); + return createIndex(row, 0, object); +} + +QModelIndex Sigmodr::SigmodTreeModel::parent(const QModelIndex& index) const +{ + if (!index.isValid()) + return QModelIndex(); + BaseModel* parent = static_cast<BaseModel*>(index.internalPointer())->parent(); + if (!parent || (parent == m_root)) + return QModelIndex(); + return createIndex(parent->indexNumber(), 0, parent); +} + +int Sigmodr::SigmodTreeModel::rowCount(const QModelIndex& parent) const +{ + BaseModel* object = getItem(parent); + return object->rowCount(); +} + +int Sigmodr::SigmodTreeModel::columnCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent) + return 1; +} + +Qt::ItemFlags Sigmodr::SigmodTreeModel::flags(const QModelIndex& index) const +{ + if (!index.isValid()) + return 0; + BaseModel* object = static_cast<BaseModel*>(index.internalPointer()); + return object->flags(); +} + +bool Sigmodr::SigmodTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if (!index.isValid()) + return false; + BaseModel* object = static_cast<BaseModel*>(index.internalPointer()); + emit(layoutAboutToBeChanged()); + bool success = object->setData(value, role); + emit(layoutChanged()); + if (success) + { + emit(dataChanged(index, index)); + emit(dirty(findSigmod(index), true)); + } + return success; +} + +Sigmodr::BaseModel* Sigmodr::SigmodTreeModel::getItem(const QModelIndex& index) const +{ + if (index.isValid()) + { + BaseModel* object = static_cast<BaseModel*>(index.internalPointer()); + if (object) + return object; + } + return m_root; +} + +QStringList Sigmodr::SigmodTreeModel::mimeTypes() const +{ + return QStringList() << "application/x-sigmod+xml" << "text/uri-list"; +} + +QMimeData* Sigmodr::SigmodTreeModel::mimeData(const QModelIndexList& indexes) const +{ + QMimeData *mimeData = new QMimeData; + if ((indexes.size() == 1) && indexes[0].isValid()) + { + QDomDocument xml; + xml.setContent(data(indexes[0], Sigmodr::BaseModel::XmlRole).toString()); + mimeData->setData("application/x-sigmod+xml", xml.toByteArray()); + } + return mimeData; +} + +bool Sigmodr::SigmodTreeModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) +{ + Q_UNUSED(row) + Q_UNUSED(column) + if (action == Qt::IgnoreAction) + return true; + QString format; + bool success = false; + if (data->hasFormat("application/x-sigmod+xml")) + { + QByteArray mimeData = data->data("application/x-sigmod+xml"); + emit(layoutAboutToBeChanged()); + success = parent.isValid() ? setData(parent, mimeData, Sigmodr::BaseModel::XmlRole) : m_root->setData(mimeData, Sigmodr::BaseModel::XmlRole); + emit(layoutChanged()); + } + else if (data->hasFormat("text/uri-list")) + { + QList<QUrl> urls = data->urls(); + foreach (const QUrl& url, urls) + { + emit(layoutAboutToBeChanged()); + success = parent.isValid() ? setData(parent, url.toEncoded(), Sigmodr::BaseModel::XmlRole) : m_root->setData(url.toEncoded(), Sigmodr::BaseModel::XmlRole); + emit(layoutChanged()); + } + } + if (success) + emit(dirty(findSigmod(parent), true)); + return success; +} + +void Sigmodr::SigmodTreeModel::addSigmod(Sigmod::Sigmod* sigmod) +{ + m_root->addSigmod(sigmod); + reset(); +} + +void Sigmodr::SigmodTreeModel::deleteSigmod(const Sigmod::Sigmod* sigmod) +{ + m_root->deleteSigmod(sigmod); + reset(); +} + +const Sigmod::Sigmod* Sigmodr::SigmodTreeModel::findSigmod(const QModelIndex& index) const +{ + QModelIndex curIndex = index; + QModelIndex parIndex = parent(curIndex); + while (parIndex.isValid()) + { + curIndex = parIndex; + parIndex = parent(curIndex); + } + return qobject_cast<const Sigmod::Sigmod*>(getItem(curIndex)->object()); +} + +void Sigmodr::SigmodTreeModel::rowsChanged(const QList<int>& rows) +{ + QModelIndex curIndex; + foreach (int row, rows) + curIndex = index(row, 0, curIndex); + if (curIndex.isValid()) + { + emit(dataChanged(curIndex, curIndex)); + emit(dirty(findSigmod(curIndex), true)); + } + else + reset(); +} |