297 lines
8.1 KiB
C++
297 lines
8.1 KiB
C++
|
#include "gtl_data_model.h"
|
||
|
|
||
|
namespace gtl
|
||
|
{
|
||
|
data_model::data_model(QObject *parent)
|
||
|
: QAbstractItemModel(parent)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
QVariant data_model::headerData(int section, Qt::Orientation orientation, int role) const
|
||
|
{
|
||
|
// FIXME: Implement me!
|
||
|
|
||
|
return QVariant();
|
||
|
}
|
||
|
|
||
|
QModelIndex data_model::index(int row, int column, const QModelIndex &parent) const
|
||
|
{
|
||
|
// FIXME: Implement me!
|
||
|
|
||
|
if(row >= rowCount(parent))
|
||
|
return QModelIndex();
|
||
|
|
||
|
if(parent.isValid())
|
||
|
{
|
||
|
return createIndex(row, column, static_cast<gtl::data_model_node*>(parent.internalPointer())->child(row));
|
||
|
}
|
||
|
|
||
|
return createIndex(row, column, _devices[row]);
|
||
|
}
|
||
|
|
||
|
QModelIndex data_model::parent(const QModelIndex &index) const
|
||
|
{
|
||
|
// FIXME: Implement me!
|
||
|
if(!index.isValid())
|
||
|
return QModelIndex();
|
||
|
|
||
|
gtl::data_model_node* node = static_cast<gtl::data_model_node*>(index.internalPointer());
|
||
|
|
||
|
if(node->parent_node() == NULL)
|
||
|
{
|
||
|
return QModelIndex();
|
||
|
}
|
||
|
else if(node->parent_node()->parent_node() == NULL)
|
||
|
{
|
||
|
int row = std::find(_devices.begin(), _devices.end(), node->parent_node()) - _devices.begin();
|
||
|
return createIndex(row, 0, node->parent_node());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
return createIndex(index_of(node->parent_node()), 0, node->parent_node());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QModelIndex data_model::index(data_model_node *node)
|
||
|
{
|
||
|
return index(index_of(node), 0, parent(node));
|
||
|
}
|
||
|
|
||
|
QModelIndex gtl::data_model::parent(data_model_node* node)
|
||
|
{
|
||
|
QModelIndex parent;
|
||
|
if(node->parent_node())
|
||
|
{
|
||
|
int row_parent = node->parent_node()->index_of();
|
||
|
if(row_parent < 0)
|
||
|
row_parent = index_of(node->parent_node());
|
||
|
|
||
|
parent = createIndex(row_parent, 0, node->parent_node());
|
||
|
}
|
||
|
|
||
|
return parent;
|
||
|
}
|
||
|
|
||
|
int data_model::rowCount(const QModelIndex &parent) const
|
||
|
{
|
||
|
if (parent.isValid())
|
||
|
return static_cast<data_model_node*>(parent.internalPointer())->count();
|
||
|
|
||
|
// FIXME: Implement me!
|
||
|
|
||
|
return (int)_devices.size();
|
||
|
}
|
||
|
|
||
|
int data_model::columnCount(const QModelIndex &parent) const
|
||
|
{
|
||
|
// FIXME: Implement me!
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
QVariant data_model::data(const QModelIndex &index, int role) const
|
||
|
{
|
||
|
if (!index.isValid())
|
||
|
return QVariant();
|
||
|
|
||
|
// FIXME: Implement me!
|
||
|
|
||
|
if(role == Qt::DisplayRole)
|
||
|
{
|
||
|
return static_cast<data_model_node*>(index.internalPointer())->name();
|
||
|
}
|
||
|
|
||
|
return QVariant();
|
||
|
}
|
||
|
|
||
|
bool data_model::setData(const QModelIndex &index, const QVariant &value, int role)
|
||
|
{
|
||
|
data_model_node* node = static_cast<data_model_node*>(index.internalPointer());
|
||
|
if(node)
|
||
|
{
|
||
|
if(role == Qt::EditRole && !value.toString().isEmpty())
|
||
|
{
|
||
|
node->set_name(value.toString());
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
|
||
|
Qt::ItemFlags data_model::flags(const QModelIndex &index) const
|
||
|
{
|
||
|
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
|
||
|
|
||
|
data_model_node* node = static_cast<data_model_node*>(index.internalPointer());
|
||
|
|
||
|
if(node->type() != data_model_node::device)
|
||
|
flags |= Qt::ItemFlag::ItemIsEditable;
|
||
|
|
||
|
while(node->type() == data_model_node::analog)
|
||
|
{
|
||
|
if(!node->is_enabled())
|
||
|
{
|
||
|
flags &= ~Qt::ItemFlag::ItemIsEnabled;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
node = node->parent_node();
|
||
|
if(node == nullptr)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return flags;
|
||
|
}
|
||
|
|
||
|
void data_model::clear()
|
||
|
{
|
||
|
beginResetModel();
|
||
|
|
||
|
_devices.clear();
|
||
|
|
||
|
endResetModel();
|
||
|
}
|
||
|
|
||
|
void data_model::add_device(device *d)
|
||
|
{
|
||
|
if(std::find(_devices.begin(), _devices.end(), d) == _devices.end())
|
||
|
{
|
||
|
beginInsertRows(QModelIndex(), (int)_devices.size(), (int)_devices.size());
|
||
|
|
||
|
_devices.push_back(d);
|
||
|
|
||
|
endInsertRows();
|
||
|
|
||
|
connect(d, &data_model_node::create_node, this, &data_model::create_node);
|
||
|
connect(d, &data_model_node::deleting, this, &data_model::deleting_device);
|
||
|
connect(d, &data_model_node::node_name_changed, this, &data_model::node_name_changed);
|
||
|
|
||
|
connect(d, &data_model_node::begin_insert_children, this, &data_model::begin_add_children);
|
||
|
connect(d, &data_model_node::end_insert_children, this, &data_model::end_add_children);
|
||
|
|
||
|
connect(d, &data_model_node::begin_remove_children, this, &data_model::begin_remove_children);
|
||
|
connect(d, &data_model_node::end_remove_children, this, &data_model::end_remove_children);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void data_model::remove(data_model_node *node)
|
||
|
{
|
||
|
if(node->parent_node())
|
||
|
node->parent_node()->remove(node);
|
||
|
else
|
||
|
{
|
||
|
int row = index_of(node);
|
||
|
beginRemoveRows(QModelIndex(), row, row);
|
||
|
_devices.erase(_devices.begin() + row);
|
||
|
endRemoveRows();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
data_model_node *data_model::node(QString path) const
|
||
|
{
|
||
|
|
||
|
QStringList tokens = path.split("/");
|
||
|
if(tokens.empty())
|
||
|
return NULL;
|
||
|
|
||
|
auto iter_device = std::find_if(_devices.cbegin(), _devices.cend(), [=](const gtl::device* d){return d->name() == tokens.first();});
|
||
|
|
||
|
if(iter_device == _devices.end())
|
||
|
return NULL;
|
||
|
|
||
|
data_model_node* node = *iter_device;
|
||
|
for(int i = 1; i < tokens.size(); i++)
|
||
|
{
|
||
|
node = node->child(tokens[i].toInt());
|
||
|
if(node == NULL)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return node;
|
||
|
|
||
|
}
|
||
|
|
||
|
int data_model::index_of(data_model_node *node) const
|
||
|
{
|
||
|
if(node->type() != data_model_node::device)
|
||
|
return node->index_of();
|
||
|
|
||
|
auto iter = std::find(_devices.cbegin(), _devices.cend(), static_cast<device*>(node));
|
||
|
if(iter == _devices.cend())
|
||
|
return -1;
|
||
|
|
||
|
return std::distance(_devices.cbegin(), iter);
|
||
|
}
|
||
|
|
||
|
data_model_node *data_model::node(const QModelIndex& index) const
|
||
|
{
|
||
|
return static_cast<gtl::data_model_node*>(index.internalPointer());
|
||
|
}
|
||
|
|
||
|
void data_model::save(QDomElement &root_element)
|
||
|
{
|
||
|
for(auto device_iter: _devices)
|
||
|
{
|
||
|
QDomElement device_element = root_element.ownerDocument().createElement("device");
|
||
|
root_element.appendChild(device_element);
|
||
|
|
||
|
device_iter->save(device_element);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void data_model::load(const QDomElement &root_element)
|
||
|
{
|
||
|
QDomElement device_element = root_element.firstChildElement("device");
|
||
|
while(!device_element.isNull())
|
||
|
{
|
||
|
gtl::data_model_node* device = NULL;
|
||
|
device = emit create_node(NULL, device_element);
|
||
|
if(device)
|
||
|
{
|
||
|
add_device(static_cast<gtl::device*>(device));
|
||
|
device->load(device_element);
|
||
|
}
|
||
|
|
||
|
device_element = device_element.nextSiblingElement("device");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void data_model::begin_add_children(data_model_node* parent, int begin, int end)
|
||
|
{
|
||
|
QModelIndex parent_index = data_model::index(parent);
|
||
|
beginInsertRows(parent_index, begin, end);
|
||
|
|
||
|
}
|
||
|
|
||
|
void data_model::end_add_children()
|
||
|
{
|
||
|
endInsertRows();
|
||
|
}
|
||
|
|
||
|
void data_model::begin_remove_children(data_model_node *parent, int begin, int end)
|
||
|
{
|
||
|
QModelIndex parent_index = data_model::index(parent);
|
||
|
beginRemoveRows(parent_index, begin, end);
|
||
|
}
|
||
|
|
||
|
void data_model::end_remove_children()
|
||
|
{
|
||
|
endRemoveRows();
|
||
|
}
|
||
|
|
||
|
void data_model::deleting_device()
|
||
|
{
|
||
|
remove(static_cast<gtl::data_model_node*>(sender()));
|
||
|
}
|
||
|
|
||
|
void data_model::node_name_changed(data_model_node *node)
|
||
|
{
|
||
|
QModelIndex node_index = index(node);
|
||
|
emit dataChanged(node_index, node_index, QList<int>() << Qt::DisplayRole);
|
||
|
}
|
||
|
}
|