/* * Copyright 2008-2009 Ben Boeckel * * 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 . */ // Header include #include "SigmodrTreeModel.h" // Sigmodr tree includes #include "RootModel.h" // Sigmod includes #include // Qt includes #include #include #include #include using namespace Sigmod; using namespace Sigmodr::Tree; SigmodrTreeModel::SigmodrTreeModel(QObject* parent) : QAbstractItemModel(parent), m_root(new RootModel) { connect(m_root, SIGNAL(rowsChanged(QList)), this, SLOT(rowsChanged(QList))); } SigmodrTreeModel::~SigmodrTreeModel() { delete m_root; } QVariant SigmodrTreeModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); BaseModel* object = static_cast(index.internalPointer()); return object->data(role); } QVariant SigmodrTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_UNUSED(section) Q_UNUSED(orientation) Q_UNUSED(role) return QVariant(); } QModelIndex SigmodrTreeModel::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 SigmodrTreeModel::parent(const QModelIndex& index) const { if (!index.isValid()) return QModelIndex(); BaseModel* parent = static_cast(index.internalPointer())->parent(); if (!parent || (parent == m_root)) return QModelIndex(); return createIndex(parent->indexNumber(), 0, parent); } int SigmodrTreeModel::rowCount(const QModelIndex& parent) const { BaseModel* object = getItem(parent); return object->rowCount(); } int SigmodrTreeModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return 1; } Qt::ItemFlags SigmodrTreeModel::flags(const QModelIndex& index) const { if (!index.isValid()) return 0; BaseModel* object = static_cast(index.internalPointer()); return object->flags(); } bool SigmodrTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid()) return false; BaseModel* object = static_cast(index.internalPointer()); emit(layoutAboutToBeChanged()); bool success = object->setData(value, role); emit(layoutChanged()); if (success) { emit(dataChanged(index, index)); emit(dirty(findGame(index), true)); } return success; } BaseModel* SigmodrTreeModel::getItem(const QModelIndex& index) const { if (index.isValid()) { BaseModel* object = static_cast(index.internalPointer()); if (object) return object; } return m_root; } QStringList SigmodrTreeModel::mimeTypes() const { return QStringList() << "application/x-sigmod+xml" << "text/uri-list"; } QMimeData* SigmodrTreeModel::mimeData(const QModelIndexList& indexes) const { QMimeData *mimeData = new QMimeData; if ((indexes.size() == 1) && indexes[0].isValid()) { QDomDocument xml; xml.setContent(data(indexes[0], BaseModel::XmlRole).toString()); mimeData->setData("application/x-sigmod+xml", xml.toByteArray()); } return mimeData; } bool SigmodrTreeModel::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, BaseModel::XmlRole) : m_root->setData(mimeData, BaseModel::XmlRole); emit(layoutChanged()); } else if (data->hasFormat("text/uri-list")) { QList urls = data->urls(); foreach (const QUrl& url, urls) { emit(layoutAboutToBeChanged()); success = parent.isValid() ? setData(parent, url.toEncoded(), BaseModel::XmlRole) : m_root->setData(url.toEncoded(), BaseModel::XmlRole); emit(layoutChanged()); } } if (success) emit(dirty(findGame(parent), true)); return success; } void SigmodrTreeModel::addGame(Game* game) { m_root->addGame(game); reset(); } void SigmodrTreeModel::deleteGame(const Game* game) { m_root->deleteGame(game); reset(); } const Game* SigmodrTreeModel::findGame(const QModelIndex& index) const { QModelIndex curIndex = index; QModelIndex parIndex = parent(curIndex); while (parIndex.isValid()) { curIndex = parIndex; parIndex = parent(curIndex); } return qobject_cast(getItem(curIndex)->object()); } void SigmodrTreeModel::rowsChanged(const QList& rows) { QModelIndex curIndex; foreach (int row, rows) curIndex = index(row, 0, curIndex); if (curIndex.isValid()) { emit(dataChanged(curIndex, curIndex)); emit(dirty(findGame(curIndex), true)); } else reset(); }