265 lines
6.8 KiB
C++
265 lines
6.8 KiB
C++
|
#include "gtl_data_model_node.h"
|
||
|
|
||
|
#include <QDebug>
|
||
|
|
||
|
#include "gtl_device.h"
|
||
|
|
||
|
namespace gtl
|
||
|
{
|
||
|
data_model_node::data_model_node(types type, data_model_node *parent, bool is_hidden)
|
||
|
: QObject(parent)
|
||
|
, _is_enabled(true)
|
||
|
, _type(type)
|
||
|
{
|
||
|
if(parent)
|
||
|
{
|
||
|
if(is_hidden)
|
||
|
{
|
||
|
parent->add_hidden_child(this);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
parent->add_child(this);
|
||
|
|
||
|
connect(this, &data_model_node::create_node, parent, &data_model_node::create_node);
|
||
|
connect(this, &data_model_node::deleting, parent, &data_model_node::deleting_child);
|
||
|
connect(this, &data_model_node::node_name_changed, parent, &data_model_node::node_name_changed);
|
||
|
|
||
|
connect(this, &data_model_node::begin_insert_children, parent, &data_model_node::begin_insert_children);
|
||
|
connect(this, &data_model_node::end_insert_children, parent, &data_model_node::end_insert_children);
|
||
|
|
||
|
connect(this, &data_model_node::begin_remove_children, parent, &data_model_node::begin_remove_children);
|
||
|
connect(this, &data_model_node::end_remove_children, parent, &data_model_node::end_remove_children);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
data_model_node::~data_model_node()
|
||
|
{
|
||
|
//for(auto it: _children)
|
||
|
while(_children.size() != 0)
|
||
|
delete _children[0];
|
||
|
|
||
|
emit deleting();
|
||
|
}
|
||
|
|
||
|
data_model_node *data_model_node::parent_node() const
|
||
|
{
|
||
|
return static_cast<data_model_node*>(parent());
|
||
|
}
|
||
|
|
||
|
void data_model_node::set_name(QString name)
|
||
|
{
|
||
|
if(_name != name)
|
||
|
{
|
||
|
_name = name;
|
||
|
emit name_changed();
|
||
|
emit node_name_changed(this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void data_model_node::deleting_hidden_child()
|
||
|
{
|
||
|
_hidden_children.erase(std::find(_hidden_children.begin(), _hidden_children.end(), sender()));
|
||
|
}
|
||
|
|
||
|
void data_model_node::deleting_child()
|
||
|
{
|
||
|
remove(static_cast<data_model_node*>(sender()));
|
||
|
}
|
||
|
|
||
|
QString data_model_node::name() const
|
||
|
{
|
||
|
return _name;
|
||
|
}
|
||
|
|
||
|
int data_model_node::count()
|
||
|
{
|
||
|
return (int)_children.size();
|
||
|
}
|
||
|
|
||
|
int data_model_node::index_of(const data_model_node *child) const
|
||
|
{
|
||
|
int idx = std::find(_children.begin(), _children.end(), child) - _children.begin();
|
||
|
if(idx == _children.size())
|
||
|
idx = -1;
|
||
|
|
||
|
return idx;
|
||
|
}
|
||
|
|
||
|
int data_model_node::index_of() const
|
||
|
{
|
||
|
data_model_node* parent = parent_node();
|
||
|
if(parent)
|
||
|
return parent->index_of(this);
|
||
|
|
||
|
return -1;
|
||
|
|
||
|
}
|
||
|
|
||
|
data_model_node *data_model_node::child(int idx)
|
||
|
{
|
||
|
if(idx < 0 || idx >= (int)_children.size())
|
||
|
return NULL;
|
||
|
|
||
|
return _children[idx];
|
||
|
}
|
||
|
|
||
|
void data_model_node::add_child(data_model_node *child)
|
||
|
{
|
||
|
emit begin_insert_children(this, _children.size(), _children.size());
|
||
|
_children.push_back(child);
|
||
|
emit end_insert_children();
|
||
|
}
|
||
|
|
||
|
void data_model_node::add_hidden_child(data_model_node *child)
|
||
|
{
|
||
|
_hidden_children.push_back(child);
|
||
|
connect(child, >l::data_model_node::deleting, this, >l::data_model_node::deleting_hidden_child);
|
||
|
}
|
||
|
|
||
|
data_model_node::types data_model_node::type() const
|
||
|
{
|
||
|
return _type;
|
||
|
}
|
||
|
|
||
|
QString data_model_node::path() const
|
||
|
{
|
||
|
std::vector<int> indices;
|
||
|
const data_model_node* node = this;
|
||
|
while(node->parent_node())
|
||
|
{
|
||
|
indices.push_back(node->parent_node()->index_of(node));
|
||
|
node = node->parent_node();
|
||
|
|
||
|
}
|
||
|
|
||
|
QString path = node->name();
|
||
|
for(auto it = indices.rbegin(); it != indices.rend(); it++)
|
||
|
path += "/" + QString::number(*it);
|
||
|
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
void data_model_node::save(QDomElement &root_element)
|
||
|
{
|
||
|
root_element.setAttribute("node", metaObject()->className());
|
||
|
root_element.setAttribute("name", _name);
|
||
|
save_childs(root_element);
|
||
|
}
|
||
|
|
||
|
void data_model_node::save_childs(QDomElement &root_element)
|
||
|
{
|
||
|
for(auto it: _children)
|
||
|
{
|
||
|
QDomElement child_element = root_element.ownerDocument().createElement("child");
|
||
|
root_element.appendChild(child_element);
|
||
|
|
||
|
(*it).save(child_element);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void data_model_node::load(const QDomElement &root_element)
|
||
|
{
|
||
|
_name = root_element.attribute("name", _name);
|
||
|
load_childs(root_element);
|
||
|
}
|
||
|
|
||
|
void data_model_node::load_childs(const QDomElement &root_element)
|
||
|
{
|
||
|
QDomElement child_element = root_element.firstChildElement("child");
|
||
|
int idx = 0;
|
||
|
while(!child_element.isNull())
|
||
|
{
|
||
|
if(idx < count())
|
||
|
{
|
||
|
child(idx)->load(child_element);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data_model_node* node = emit create_node(this, child_element);
|
||
|
if(node)
|
||
|
{
|
||
|
node->load(child_element);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
child_element = child_element.nextSiblingElement("child");
|
||
|
idx++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void data_model_node::get_state(QJsonObject &root)
|
||
|
{
|
||
|
root["name"] = _name;
|
||
|
root["node"] = metaObject()->className();
|
||
|
}
|
||
|
|
||
|
bool data_model_node::remove(data_model_node *child)
|
||
|
{
|
||
|
auto iter = std::find(_children.begin(), _children.end(), child);
|
||
|
if(iter == _children.end())
|
||
|
return false;
|
||
|
|
||
|
int idx = std::distance(_children.begin(), iter);
|
||
|
|
||
|
|
||
|
gtl::data_model_node* root = child->root();
|
||
|
if(root)
|
||
|
if(root->type() == device)
|
||
|
static_cast<gtl::device*>(root)->lock_ai();
|
||
|
|
||
|
|
||
|
emit begin_remove_children(this, idx, idx);
|
||
|
|
||
|
_children.erase(iter);
|
||
|
|
||
|
emit end_remove_children();
|
||
|
|
||
|
if(root)
|
||
|
if(root->type() == device)
|
||
|
static_cast<gtl::device*>(root)->unlock_ai();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void data_model_node::remove_children()
|
||
|
{
|
||
|
if(_children.empty())
|
||
|
return;
|
||
|
|
||
|
emit begin_remove_children(this, 0, (int)_children.size() - 1);
|
||
|
|
||
|
_children.clear();
|
||
|
|
||
|
emit end_remove_children();
|
||
|
}
|
||
|
|
||
|
bool data_model_node::is_child_name_exist(QString name)
|
||
|
{
|
||
|
return std::find_if(_children.begin(), _children.end(), [=](data_model_node* child){return child->name() == name;}) != _children.end();
|
||
|
}
|
||
|
|
||
|
void data_model_node::set_enabled(bool value)
|
||
|
{
|
||
|
_is_enabled = value;
|
||
|
}
|
||
|
|
||
|
bool data_model_node::is_enabled() const
|
||
|
{
|
||
|
return _is_enabled;
|
||
|
}
|
||
|
|
||
|
data_model_node *data_model_node::root()
|
||
|
{
|
||
|
data_model_node* node = this;
|
||
|
while(node->parent_node())
|
||
|
node = node->parent_node();
|
||
|
|
||
|
if(node->type() != device)
|
||
|
return nullptr;
|
||
|
|
||
|
return node;
|
||
|
}
|
||
|
}
|