flightgear/utils/fgqcanvas/canvastreemodel.cpp
2022-10-20 20:29:11 +08:00

184 lines
4.9 KiB
C++

//
// Copyright (C) 2017 James Turner zakalawe@mac.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 2 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "canvastreemodel.h"
#include <QDebug>
#include "localprop.h"
CanvasTreeModel::CanvasTreeModel(FGCanvasGroup* root) :
_root(root)
{
connect(_root, &FGCanvasGroup::childAdded, this, &CanvasTreeModel::onGroupChildAdded);
}
FGCanvasElement* CanvasTreeModel::elementFromIndex(const QModelIndex &index) const
{
if (!index.isValid()) {
return nullptr;
}
FGCanvasElement* e = static_cast<FGCanvasElement*>(index.internalPointer());
return e;
}
int CanvasTreeModel::rowCount(const QModelIndex &parent) const
{
FGCanvasElement* e = static_cast<FGCanvasElement*>(parent.internalPointer());
if (!e) {
return _root->childCount();
}
FGCanvasGroup* group = qobject_cast<FGCanvasGroup*>(e);
if (group) {
return group->childCount();
}
return 0;
}
int CanvasTreeModel::columnCount(const QModelIndex &parent) const
{
return 1;
}
QVariant CanvasTreeModel::data(const QModelIndex &index, int role) const
{
FGCanvasElement* e = static_cast<FGCanvasElement*>(index.internalPointer());
if (!e) {
return QVariant();
}
switch (role) {
case Qt::DisplayRole:
return e->property()->value("id", QVariant("<noid>"));
case Qt::CheckStateRole:
return e->property()->value("visible", true).toBool() ? Qt::Checked : Qt::Unchecked;
default:
break;
}
return QVariant();
}
bool CanvasTreeModel::hasChildren(const QModelIndex &parent) const
{
FGCanvasElement* e;
if (parent.isValid()) {
e = static_cast<FGCanvasElement*>(parent.internalPointer());
} else {
e = _root;
}
FGCanvasGroup* group = qobject_cast<FGCanvasGroup*>(e);
if (group) {
return group->hasChilden();
}
return false;
}
QModelIndex CanvasTreeModel::index(int row, int column, const QModelIndex &parent) const
{
FGCanvasGroup* group;
if (parent.isValid()) {
group = qobject_cast<FGCanvasGroup*>(static_cast<FGCanvasElement*>(parent.internalPointer()));
} else {
group = _root;
}
if (!group) {
return QModelIndex(); // invalid
}
if ((row < 0) || (row >= (int) group->childCount())) {
return QModelIndex(); // invalid
}
return createIndex(row, column, group->childAt(row));
}
QModelIndex CanvasTreeModel::parent(const QModelIndex &child) const
{
FGCanvasElement* e = static_cast<FGCanvasElement*>(child.internalPointer());
if (!child.isValid() || !e) {
return QModelIndex();
}
return indexForGroup(const_cast<FGCanvasGroup*>(e->parentGroup()));
}
Qt::ItemFlags CanvasTreeModel::flags(const QModelIndex &index) const
{
return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
}
bool CanvasTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
FGCanvasElement* e = static_cast<FGCanvasElement*>(index.internalPointer());
if (!e) {
return false;
}
qDebug() << Q_FUNC_INFO;
if (role == Qt::CheckStateRole) {
e->property()->changeValue("visible", (value.toInt() == Qt::Checked));
emit dataChanged(index, index, QVector<int>() << Qt::CheckStateRole);
return true;
}
return false;
}
QModelIndex CanvasTreeModel::indexForGroup(FGCanvasGroup* group) const
{
if (!group) {
return QModelIndex();
}
if (group->parentGroup()) {
int prIndex = group->parentGroup()->indexOfChild(group);
return createIndex(prIndex, 0, group);
} else {
return createIndex(0, 0, group);
}
}
void CanvasTreeModel::onGroupChildAdded()
{
FGCanvasGroup* group = qobject_cast<FGCanvasGroup*>(sender());
int newChild = group->childCount() - 1;
FGCanvasGroup* childGroup = qobject_cast<FGCanvasGroup*>(group->childAt(newChild));
if (childGroup) {
connect(childGroup, &FGCanvasGroup::childAdded, this, &CanvasTreeModel::onGroupChildAdded);
}
beginInsertRows(indexForGroup(group),
newChild, newChild);
endInsertRows();
}
void CanvasTreeModel::onGroupChildRemoved(int index)
{
FGCanvasGroup* group = qobject_cast<FGCanvasGroup*>(sender());
beginRemoveRows(indexForGroup(group), index, index);
}