current work on editor widges and data loading
This commit is contained in:
parent
bd1e40685b
commit
cc5b9dfa46
|
@ -6,7 +6,8 @@ set(SOURCES mainwindow.cpp
|
||||||
|
|
||||||
add_subdirectory(model)
|
add_subdirectory(model)
|
||||||
add_subdirectory(editor)
|
add_subdirectory(editor)
|
||||||
|
add_subdirectory(protocol)
|
||||||
|
|
||||||
add_library(src ${HEADERS} ${SOURCES})
|
add_library(src ${HEADERS} ${SOURCES})
|
||||||
target_link_libraries(src model editor)
|
target_link_libraries(src model editor protocol)
|
||||||
qt5_use_modules(src Widgets)
|
qt5_use_modules(src Widgets)
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
|
|
||||||
set(HEADERS editormodel.h
|
set(HEADERS editorelementdata.h
|
||||||
editorelementdata.h
|
|
||||||
guidededitorelementview.h
|
guidededitorelementview.h
|
||||||
guidededitorgroupview.h
|
|
||||||
editorgroup.h
|
|
||||||
flowlayout.h
|
flowlayout.h
|
||||||
editortreenode.h
|
EditorNode.h
|
||||||
|
EditorTree.h
|
||||||
|
EditorElementValue.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES guidededitorelementview.cpp
|
set(SOURCES guidededitorelementview.cpp
|
||||||
guidededitorgroupview.cpp
|
|
||||||
editorelementdata.cpp
|
editorelementdata.cpp
|
||||||
editormodel.cpp
|
|
||||||
editorgroup.cpp
|
|
||||||
guidededitorview.cpp
|
guidededitorview.cpp
|
||||||
flowlayout.cpp
|
flowlayout.cpp
|
||||||
editortreenode.cpp
|
EditorNode.cpp
|
||||||
|
EditorTree.cpp
|
||||||
|
EditorElementValue.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(editor ${HEADERS} ${SOURCES})
|
add_library(editor ${HEADERS} ${SOURCES})
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "EditorElementValue.h"
|
||||||
|
|
||||||
|
EditorElementValue::EditorElementValue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EditorElementValue::getValue() const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementValue::setValue(const QString &value)
|
||||||
|
{
|
||||||
|
this->value = value;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef EDITORELEMENTVALUE_H
|
||||||
|
#define EDITORELEMENTVALUE_H
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class EditorElementValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorElementValue();
|
||||||
|
|
||||||
|
QString getValue() const;
|
||||||
|
void setValue(const QString &value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDITORELEMENTVALUE_H
|
|
@ -0,0 +1,209 @@
|
||||||
|
#include "EditorNode.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
EditorNode::EditorNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorNode::EditorNode(std::shared_ptr<EditorElementData> data)
|
||||||
|
{
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorNode::~EditorNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<EditorNode> EditorNode::nextSibling()
|
||||||
|
{
|
||||||
|
if (parent != nullptr) {
|
||||||
|
int i = parent->getChildren().indexOf(std::shared_ptr<EditorNode>(this));
|
||||||
|
if (i + 1 < parent->getChildren().size())
|
||||||
|
return parent->getChildren().at(i + 1); //next sibling...
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<EditorNode> EditorNode::next(TreeWalkStrategy walkStrategy)
|
||||||
|
{
|
||||||
|
if (walkStrategy == TreeWalkStrategy::mixture)
|
||||||
|
// choose node, work through all siblings, choose next node, but don't change branches more than one parent away, except branch is at an end.
|
||||||
|
if (parent != nullptr) {
|
||||||
|
if (nextSibling() != nullptr) // next sibling
|
||||||
|
return nextSibling();
|
||||||
|
else // find next children
|
||||||
|
{
|
||||||
|
for (auto n : parent->getChildren())
|
||||||
|
if (n->getChildren().size() > 0)
|
||||||
|
return n->getChildren().first();
|
||||||
|
auto siblingOfParent = parent->nextSibling();
|
||||||
|
while (siblingOfParent != nullptr && siblingOfParent->getChildren().size() == 0) {
|
||||||
|
if (siblingOfParent->nextSibling() == nullptr)
|
||||||
|
siblingOfParent = siblingOfParent->getParent();
|
||||||
|
else
|
||||||
|
siblingOfParent = siblingOfParent->nextSibling();
|
||||||
|
}
|
||||||
|
if (siblingOfParent != nullptr)
|
||||||
|
return siblingOfParent->getChildren().first();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (getChildren().size() > 0)
|
||||||
|
return getChildren().first();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else if (walkStrategy == TreeWalkStrategy::depthFirst)
|
||||||
|
if (getChildren().size() > 0)
|
||||||
|
return getChildren().first();
|
||||||
|
else {
|
||||||
|
auto node = std::shared_ptr<EditorNode>(this);
|
||||||
|
while (node->nextSibling() == nullptr && node->getParent() != nullptr)
|
||||||
|
node = node->getParent();
|
||||||
|
return node->nextSibling();
|
||||||
|
}
|
||||||
|
else if (walkStrategy == TreeWalkStrategy::breadthFirst)
|
||||||
|
if (parent != nullptr) {
|
||||||
|
auto nextOnLvl = nextOnSameLevel();
|
||||||
|
if (nextOnLvl == nullptr){
|
||||||
|
for (auto n : this->getChildren())
|
||||||
|
if (n->getChildren().size() > 0)
|
||||||
|
return n->getChildren().first();
|
||||||
|
}
|
||||||
|
else return nextOnLvl;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<EditorNode> EditorNode::getRoot()
|
||||||
|
{
|
||||||
|
auto node = std::shared_ptr<EditorNode>(this);
|
||||||
|
while (node->getParent() != nullptr)
|
||||||
|
node = node->getParent();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::move(std::shared_ptr<EditorNode> to)
|
||||||
|
{
|
||||||
|
this->getParent()->getChildren().removeOne(std::shared_ptr<EditorNode>(this));
|
||||||
|
to->getChildren().append(std::shared_ptr<EditorNode>(this));
|
||||||
|
fireTreeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::moveChildren(std::shared_ptr<EditorNode> to)
|
||||||
|
{
|
||||||
|
for (auto child : getChildren())
|
||||||
|
child->move(to);
|
||||||
|
fireTreeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::addChild(std::shared_ptr<EditorNode> child)
|
||||||
|
{
|
||||||
|
this->getChildren().append(child);
|
||||||
|
child->setParent(std::shared_ptr<EditorNode>(this));
|
||||||
|
fireTreeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorNode::removeChild(std::shared_ptr<EditorNode> child)
|
||||||
|
{
|
||||||
|
bool ret = this->getChildren().removeOne(child);
|
||||||
|
if (ret) fireTreeChanged();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorNode::remove()
|
||||||
|
{
|
||||||
|
bool worked = true;
|
||||||
|
if (children.size() > 0) {
|
||||||
|
for (auto node : children) {
|
||||||
|
worked &= node->remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (worked && parent != nullptr) {
|
||||||
|
worked &= parent->getChildren().removeOne(std::shared_ptr<EditorNode>(this));
|
||||||
|
}
|
||||||
|
if (worked) fireTreeChanged();
|
||||||
|
return worked;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> EditorNode::getParent() const
|
||||||
|
{
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::setParent(const std::shared_ptr<EditorNode> &value)
|
||||||
|
{
|
||||||
|
parent = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorElementData> EditorNode::getData() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::setData(const std::shared_ptr<EditorElementData> &value)
|
||||||
|
{
|
||||||
|
fireNodeDataChanged();
|
||||||
|
data = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorElementValue> EditorNode::getValue() const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::setValue(const std::shared_ptr<EditorElementValue> &value)
|
||||||
|
{
|
||||||
|
fireNodeDataChanged();
|
||||||
|
this->value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<std::shared_ptr<EditorNode> > EditorNode::getChildren() const
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::fireNodeDataChanged()
|
||||||
|
{
|
||||||
|
if(this->getRoot()->getDataChangedSignal() != nullptr)
|
||||||
|
this->getRoot()->getDataChangedSignal()(std::shared_ptr<EditorNode>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorNode::fireTreeChanged()
|
||||||
|
{
|
||||||
|
if(this->getRoot()->getTreeChangedSignal() != nullptr)
|
||||||
|
this->getRoot()->getTreeChangedSignal()(std::shared_ptr<EditorNode>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> EditorNode::nextOnSameLevel()
|
||||||
|
{
|
||||||
|
if (nextSibling() != nullptr)
|
||||||
|
return nextSibling();
|
||||||
|
uint lvl = 1;
|
||||||
|
auto node = this->getParent();
|
||||||
|
auto pnode = std::shared_ptr<EditorNode>(this);
|
||||||
|
while (lvl > 0 && node != nullptr) {
|
||||||
|
if (node != pnode->getParent() && node->getChildren().size() > 0) {
|
||||||
|
node = node->getChildren().first();
|
||||||
|
--lvl;
|
||||||
|
} else {
|
||||||
|
pnode = node;
|
||||||
|
if (node->nextSibling() != nullptr)
|
||||||
|
node = node->nextSibling();
|
||||||
|
else {
|
||||||
|
if (node->getParent() != nullptr) {
|
||||||
|
node = node->getParent();
|
||||||
|
++lvl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef EDITORNODE_H
|
||||||
|
#define EDITORNODE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QList>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "editorelementdata.h"
|
||||||
|
#include "EditorElementValue.h"
|
||||||
|
|
||||||
|
class EditorNode;
|
||||||
|
|
||||||
|
enum class TreeWalkStrategy {
|
||||||
|
depthFirst,
|
||||||
|
breadthFirst,
|
||||||
|
mixture
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditorNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit EditorNode();
|
||||||
|
explicit EditorNode(std::shared_ptr<EditorElementData> data);
|
||||||
|
virtual ~EditorNode();
|
||||||
|
|
||||||
|
const std::shared_ptr<EditorNode> nextSibling();
|
||||||
|
|
||||||
|
const std::shared_ptr<EditorNode> next(TreeWalkStrategy walkStrategy = TreeWalkStrategy::depthFirst);
|
||||||
|
const std::shared_ptr<EditorNode> getRoot();
|
||||||
|
void move(std::shared_ptr<EditorNode> to); //as child
|
||||||
|
void moveChildren(std::shared_ptr<EditorNode> to); //all
|
||||||
|
|
||||||
|
void addChild(std::shared_ptr<EditorNode> child);
|
||||||
|
bool removeChild(std::shared_ptr<EditorNode> child);
|
||||||
|
bool remove();
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> getParent() const;
|
||||||
|
void setParent(const std::shared_ptr<EditorNode> &value);
|
||||||
|
|
||||||
|
std::shared_ptr<EditorElementData> getData() const;
|
||||||
|
void setData(const std::shared_ptr<EditorElementData> &value);
|
||||||
|
|
||||||
|
std::shared_ptr<EditorElementValue> getValue() const;
|
||||||
|
void setValue(const std::shared_ptr<EditorElementValue> &value);
|
||||||
|
|
||||||
|
QList<std::shared_ptr<EditorNode> > getChildren() const;
|
||||||
|
|
||||||
|
void setDataChangedSignal(std::function<void(std::shared_ptr<EditorNode>)> f)
|
||||||
|
{
|
||||||
|
nodeDataChanged = f;
|
||||||
|
}
|
||||||
|
void setTreeChangedSignal(std::function<void(std::shared_ptr<EditorNode>)> f)
|
||||||
|
{
|
||||||
|
treeChanged = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<void(std::shared_ptr<EditorNode>)> getTreeChangedSignal(){ return treeChanged; }
|
||||||
|
std::function<void(std::shared_ptr<EditorNode>)> getDataChangedSignal(){ return nodeDataChanged; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void fireNodeDataChanged();
|
||||||
|
void fireTreeChanged();
|
||||||
|
//signal callbacks only set in the root node
|
||||||
|
std::function<void(std::shared_ptr<EditorNode>)> nodeDataChanged;
|
||||||
|
std::function<void(std::shared_ptr<EditorNode>)> treeChanged;
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> nextOnSameLevel();
|
||||||
|
std::shared_ptr<EditorNode> parent;
|
||||||
|
std::shared_ptr<EditorElementData> data;
|
||||||
|
std::shared_ptr<EditorElementValue> value;
|
||||||
|
QList<std::shared_ptr<EditorNode>> children;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDITORNODE_H
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include "EditorTree.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
EditorTree::EditorTree(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
root = std::make_shared<EditorNode>(nullptr);
|
||||||
|
|
||||||
|
root->setDataChangedSignal([this](std::shared_ptr<EditorNode> node){ emit this->nodeDataChanged(node);});
|
||||||
|
root->setTreeChangedSignal([this](std::shared_ptr<EditorNode> node){ emit this->treeChanged(node);});
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorTree::~EditorTree()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef EDITORTREE_H
|
||||||
|
#define EDITORTREE_H
|
||||||
|
#include <memory>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "EditorNode.h"
|
||||||
|
|
||||||
|
class EditorTree : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit EditorTree(QObject *parent = 0);
|
||||||
|
virtual ~EditorTree();
|
||||||
|
|
||||||
|
const std::shared_ptr<EditorNode> getRoot() { return root; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void nodeDataChanged(std::shared_ptr<EditorNode> node);
|
||||||
|
void treeChanged(std::shared_ptr<EditorNode> node);
|
||||||
|
public slots:
|
||||||
|
private:
|
||||||
|
std::shared_ptr<EditorNode> root;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDITORTREE_H
|
|
@ -13,3 +13,123 @@ EditorElementData::~EditorElementData()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString EditorElementData::getTitle() const
|
||||||
|
{
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setTitle(const QString &value)
|
||||||
|
{
|
||||||
|
title = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EditorElementData::getId() const
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setId(const QString &value)
|
||||||
|
{
|
||||||
|
id = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> EditorElementData::getSyntaxes() const
|
||||||
|
{
|
||||||
|
return syntaxes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setSyntaxes(const QList<QString> &value)
|
||||||
|
{
|
||||||
|
syntaxes = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorElementData::isMultiLine() const
|
||||||
|
{
|
||||||
|
return multiline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setIsMultiLine(bool value)
|
||||||
|
{
|
||||||
|
multiline = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType EditorElementData::getType() const
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setType(const ValueType &value)
|
||||||
|
{
|
||||||
|
type = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EditorElementData::getRegex() const
|
||||||
|
{
|
||||||
|
return regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setRegex(const QString &value)
|
||||||
|
{
|
||||||
|
regex = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QString> EditorElementData::getHints() const
|
||||||
|
{
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setHint(const QString &key, const QString &value)
|
||||||
|
{
|
||||||
|
hints.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong EditorElementData::getBytes() const
|
||||||
|
{
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setBytes(const ulong &value)
|
||||||
|
{
|
||||||
|
bytes = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong EditorElementData::getBits() const
|
||||||
|
{
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setBits(const ulong &value)
|
||||||
|
{
|
||||||
|
bits = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorElementData::isData() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setData(bool value)
|
||||||
|
{
|
||||||
|
data = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorElementData::isNextLayer() const
|
||||||
|
{
|
||||||
|
return nextLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setNextLayer(bool value)
|
||||||
|
{
|
||||||
|
nextLayer = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorElementData::isOptional() const
|
||||||
|
{
|
||||||
|
return optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorElementData::setOptional(bool value)
|
||||||
|
{
|
||||||
|
optional = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,71 @@
|
||||||
#ifndef EDITORELEMENT_H
|
#ifndef EDITORELEMENT_H
|
||||||
#define EDITORELEMENT_H
|
#define EDITORELEMENT_H
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
enum class ValueType {
|
||||||
|
BIN,OCT,DEC,HEX,TXT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class EditorElementData
|
||||||
class EditorElementData : public QObject
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit EditorElementData();
|
explicit EditorElementData();
|
||||||
~EditorElementData();
|
virtual ~EditorElementData();
|
||||||
|
|
||||||
|
|
||||||
|
QString getTitle() const;
|
||||||
|
void setTitle(const QString &value);
|
||||||
|
|
||||||
|
QString getId() const;
|
||||||
|
void setId(const QString &value);
|
||||||
|
|
||||||
|
QList<QString> getSyntaxes() const;
|
||||||
|
void setSyntaxes(const QList<QString> &value);
|
||||||
|
|
||||||
|
bool isMultiLine() const;
|
||||||
|
void setIsMultiLine(bool value);
|
||||||
|
|
||||||
|
ValueType getType() const;
|
||||||
|
void setType(const ValueType &value);
|
||||||
|
|
||||||
|
QString getRegex() const;
|
||||||
|
void setRegex(const QString &value);
|
||||||
|
|
||||||
|
QMap<QString, QString> getHints() const;
|
||||||
|
void setHint(const QString &key, const QString &value);
|
||||||
|
|
||||||
|
ulong getBytes() const;
|
||||||
|
void setBytes(const ulong &value);
|
||||||
|
|
||||||
|
ulong getBits() const;
|
||||||
|
void setBits(const ulong &value);
|
||||||
|
|
||||||
|
bool isData() const;
|
||||||
|
void setData(bool value);
|
||||||
|
|
||||||
|
bool isNextLayer() const;
|
||||||
|
void setNextLayer(bool value);
|
||||||
|
|
||||||
|
bool isOptional() const;
|
||||||
|
void setOptional(bool value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString, QString> elements;
|
QString title;
|
||||||
|
QString id;
|
||||||
|
QList<QString> syntaxes;
|
||||||
|
bool multiline;
|
||||||
|
ValueType type;
|
||||||
|
ulong bytes;
|
||||||
|
ulong bits;
|
||||||
|
QString regex;
|
||||||
|
QMap<QString, QString> hints;
|
||||||
|
bool data;
|
||||||
|
bool nextLayer;
|
||||||
|
bool optional;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#include "editorgroup.h"
|
|
||||||
#include "cstdlib"
|
|
||||||
#include <QColor>
|
|
||||||
|
|
||||||
EditorGroup::EditorGroup(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef GUIDEDEDITORLAYER_H
|
|
||||||
#define GUIDEDEDITORLAYER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QColor>
|
|
||||||
|
|
||||||
#include "editorelementdata.h"
|
|
||||||
|
|
||||||
class EditorGroup : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit EditorGroup(QObject *parent = 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QMap<QString, QString> attributes;
|
|
||||||
QList<EditorElementData*> elements;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // GUIDEDEDITORLAYER_H
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "editormodel.h"
|
|
||||||
|
|
||||||
EditorModel::EditorModel(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef ABSTRACTGUIDEDEDITORMODEL_H
|
|
||||||
#define ABSTRACTGUIDEDEDITORMODEL_H
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <QObject>
|
|
||||||
#include <memory>
|
|
||||||
#include <list>
|
|
||||||
#include "editorelementdata.h"
|
|
||||||
#include "editorgroup.h"
|
|
||||||
|
|
||||||
class EditorModel : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit EditorModel(QObject *parent = 0);
|
|
||||||
virtual ~EditorModel();
|
|
||||||
|
|
||||||
virtual uint getCount()=0;
|
|
||||||
virtual EditorElementData& getElement(uint index) = 0;
|
|
||||||
virtual void setElementValue(const uint index, const QString value)= 0;
|
|
||||||
|
|
||||||
virtual const std::list<EditorElementData>& getAllElements() = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void dataChanged();
|
|
||||||
void dataChanged(uint index);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
private:
|
|
||||||
QList<EditorElementData*> data;
|
|
||||||
QList<EditorGroup*> groups;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ABSTRACTGUIDEDEDITORMODEL_H
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "editortreenode.h"
|
#include "editortreenode.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
EditorTreeNode<T>::EditorTreeNode() {}
|
EditorTreeNode<T>::EditorTreeNode() {
|
||||||
|
parentNode = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
EditorTreeNode<T>::EditorTreeNode(T v)
|
EditorTreeNode<T>::EditorTreeNode(T v)
|
||||||
|
@ -18,7 +20,7 @@ EditorTreeNode<T>::~EditorTreeNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const EditorTreeNode<T>* EditorTreeNode<T>::nextSibling()
|
const std::shared_ptr<EditorTreeNode<T> > EditorTreeNode<T>::nextSibling()
|
||||||
{
|
{
|
||||||
if (parent() != nullptr) {
|
if (parent() != nullptr) {
|
||||||
uint i = parent()->children().indexOf(this);
|
uint i = parent()->children().indexOf(this);
|
||||||
|
@ -31,7 +33,7 @@ const EditorTreeNode<T>* EditorTreeNode<T>::nextSibling()
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const EditorTreeNode<T>* EditorTreeNode<T>::next(TreeWalkStrategy walkStrategy)
|
const std::shared_ptr<EditorTreeNode<T>> EditorTreeNode<T>::next(TreeWalkStrategy walkStrategy)
|
||||||
{
|
{
|
||||||
if (walkStrategy == TreeWalkStrategy::mixture)
|
if (walkStrategy == TreeWalkStrategy::mixture)
|
||||||
// choose node, work through all siblings, choose next node, but don't change branches more than one parent away, except branch is at an end.
|
// choose node, work through all siblings, choose next node, but don't change branches more than one parent away, except branch is at an end.
|
||||||
|
@ -84,37 +86,37 @@ const EditorTreeNode<T>* EditorTreeNode<T>::next(TreeWalkStrategy walkStrategy)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const EditorTreeNode<T>* EditorTreeNode<T>::getRoot()
|
const std::shared_ptr<EditorTreeNode<T>> EditorTreeNode<T>::getRoot()
|
||||||
{
|
{
|
||||||
auto node = this;
|
auto node = std::shared_ptr<EditorTreeNode<T>>(this);
|
||||||
while (node->parent() != nullptr)
|
while (node->parent() != nullptr)
|
||||||
node = node->parent();
|
node = node->parent();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void EditorTreeNode<T>::move(EditorTreeNode<T>* to)
|
void EditorTreeNode<T>::move(std::shared_ptr<EditorTreeNode<T>> to)
|
||||||
{
|
{
|
||||||
this->parent()->children().removeOne(this);
|
this->parent()->children().removeOne(this);
|
||||||
to->children().append(this);
|
to->children().append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void EditorTreeNode<T>::moveChildren(EditorTreeNode<T>* to)
|
void EditorTreeNode<T>::moveChildren(std::shared_ptr<EditorTreeNode<T>> to)
|
||||||
{
|
{
|
||||||
for (auto child : childrenNodes)
|
for (auto child : childrenNodes)
|
||||||
child->move(to);
|
child->move(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void EditorTreeNode<T>::addChild(EditorTreeNode<T>* child)
|
void EditorTreeNode<T>::addChild(std::shared_ptr<EditorTreeNode<T>> child)
|
||||||
{
|
{
|
||||||
this->children().append(child);
|
this->children().append(child);
|
||||||
child->setParen(this);
|
child->setParen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool EditorTreeNode<T>::removeChild(EditorTreeNode<T>* child)
|
bool EditorTreeNode<T>::removeChild(std::shared_ptr<EditorTreeNode<T>> child)
|
||||||
{
|
{
|
||||||
return this->children().removeOne(child);
|
return this->children().removeOne(child);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +138,7 @@ bool EditorTreeNode<T>::remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
EditorTreeNode<T>* EditorTreeNode<T>::nextOnSameLevel()
|
std::shared_ptr<EditorTreeNode<T>> EditorTreeNode<T>::nextOnSameLevel()
|
||||||
{
|
{
|
||||||
if (nextSibling() != nullptr)
|
if (nextSibling() != nullptr)
|
||||||
return nextSibling();
|
return nextSibling();
|
||||||
|
|
|
@ -2,12 +2,9 @@
|
||||||
#define EDITORTREENODE_H
|
#define EDITORTREENODE_H
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
enum class TreeWalkStrategy {
|
|
||||||
depthFirst,
|
|
||||||
breadthFirst,
|
|
||||||
mixture
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class EditorTreeNode;
|
class EditorTreeNode;
|
||||||
|
@ -17,34 +14,43 @@ class EditorTreeNode {
|
||||||
public:
|
public:
|
||||||
explicit EditorTreeNode();
|
explicit EditorTreeNode();
|
||||||
explicit EditorTreeNode(T v);
|
explicit EditorTreeNode(T v);
|
||||||
~EditorTreeNode();
|
virtual ~EditorTreeNode();
|
||||||
|
|
||||||
const EditorTreeNode<T>* nextSibling();
|
|
||||||
const EditorTreeNode<T>* parent() { return parentNode; }
|
const std::shared_ptr<EditorTreeNode<T>> nextSibling();
|
||||||
QList<EditorTreeNode<T>*>& children() { return childrenNodes; }
|
const std::shared_ptr<EditorTreeNode<T>> parent() { return parentNode; }
|
||||||
void setParen(EditorTreeNode<T>* parent) { this->parentNode = parent; }
|
QList<std::shared_ptr<EditorTreeNode<T>>>& children() { return childrenNodes; }
|
||||||
|
void setParen(std::shared_ptr<EditorTreeNode<T>> parent) { this->parentNode = parent; }
|
||||||
|
|
||||||
T& value() { return val; }
|
T& value() { return val; }
|
||||||
|
void setValue(const T &val);
|
||||||
|
|
||||||
const EditorTreeNode<T>* next(TreeWalkStrategy depth_first = TreeWalkStrategy::depthFirst);
|
const std::shared_ptr<EditorTreeNode<T>> next(TreeWalkStrategy depth_first = TreeWalkStrategy::depthFirst);
|
||||||
const EditorTreeNode<T>* getRoot();
|
const std::shared_ptr<EditorTreeNode<T>> getRoot();
|
||||||
void move(EditorTreeNode<T>* to); // as child!
|
void move(std::shared_ptr<EditorTreeNode<T>> to); // as child!
|
||||||
void moveChildren(EditorTreeNode<T>* to); // move all children
|
void moveChildren(std::shared_ptr<EditorTreeNode<T>> to); // move all children
|
||||||
|
|
||||||
//signals:
|
void addChild(std::shared_ptr<EditorTreeNode<T>> child);
|
||||||
void nodeDataChanged(EditorTreeNode<T>* node);
|
bool removeChild(std::shared_ptr<EditorTreeNode<T>> child);
|
||||||
void treeChanged(EditorTreeNode<T>* node);
|
|
||||||
|
|
||||||
//public slots:
|
|
||||||
void addChild(EditorTreeNode<T>* child);
|
|
||||||
bool removeChild(EditorTreeNode<T>* child);
|
|
||||||
bool remove();
|
bool remove();
|
||||||
//*/
|
|
||||||
|
void setDataChangedSignal(std::function<void(std::shared_ptr<EditorTreeNode<T>>)> f)
|
||||||
|
{
|
||||||
|
nodeDataChanged = f;
|
||||||
|
}
|
||||||
|
void setTreeChangedSignal(std::function<void(std::shared_ptr<EditorTreeNode<T>>)> f)
|
||||||
|
{
|
||||||
|
treeChanged = f;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//signal callbacks only set in the root node
|
||||||
|
std::function<void(std::shared_ptr<EditorTreeNode<T>>)> nodeDataChanged;
|
||||||
|
std::function<void(std::shared_ptr<EditorTreeNode<T>>)> treeChanged;
|
||||||
T val;
|
T val;
|
||||||
EditorTreeNode<T>* parentNode = nullptr;
|
std::shared_ptr<EditorTreeNode<T>> parentNode = nullptr;
|
||||||
QList<EditorTreeNode<T>*> childrenNodes;
|
QList<std::shared_ptr<EditorTreeNode<T>>> childrenNodes;
|
||||||
EditorTreeNode<T>* nextOnSameLevel();
|
std::shared_ptr<EditorTreeNode<T>> nextOnSameLevel();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EDITORTREENODE_H
|
#endif // EDITORTREENODE_H
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "guidededitorelementview.h"
|
#include "guidededitorelementview.h"
|
||||||
|
|
||||||
|
#include "flowlayout.h"
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QRegExpValidator>
|
#include <QRegExpValidator>
|
||||||
|
@ -8,23 +9,116 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
GuidedEditorElementView::GuidedEditorElementView(const std::shared_ptr<EditorNode> &ref, QWidget* parent)
|
||||||
|
: GuidedEditorElementView(parent)
|
||||||
|
{
|
||||||
|
this->setReference(ref);
|
||||||
|
}
|
||||||
GuidedEditorElementView::GuidedEditorElementView(QWidget* parent)
|
GuidedEditorElementView::GuidedEditorElementView(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
|
this->validator = new QRegExpValidator();
|
||||||
this->layout = new QVBoxLayout(this);
|
this->layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
this->setLayout(layout);
|
this->setLayout(layout);
|
||||||
|
this->edit = nullptr;
|
||||||
|
this->line = nullptr;
|
||||||
|
this->title = new QLabel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuidedEditorElementView::render()
|
void GuidedEditorElementView::render()
|
||||||
{
|
{
|
||||||
for (QWidget* w : this->propertyViews.values())
|
// TODO: add possibility to collapse a subtree
|
||||||
this->layout->removeWidget(w);
|
for (QObject* w : this->children())
|
||||||
for (QString prop : this->propertyOrder) {
|
if (w->isWidgetType()) {
|
||||||
this->layout->addWidget(this->propertyViews[prop]);
|
this->layout->removeWidget((QWidget*)w);
|
||||||
|
}
|
||||||
|
|
||||||
|
//title
|
||||||
|
title->setText(reference->getData()->getTitle());
|
||||||
|
layout->addWidget(title);
|
||||||
|
|
||||||
|
if (reference->getChildren().size() == 0) {
|
||||||
|
// need global information about showing syntax, and other hints
|
||||||
|
|
||||||
|
if (reference->getData()->isMultiLine()) {
|
||||||
|
layout->addWidget(edit);
|
||||||
|
} else {
|
||||||
|
layout->addWidget(line);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//create container for subelements
|
||||||
|
if (subContainer == nullptr) {
|
||||||
|
subContainer = new QWidget(this);
|
||||||
|
FlowLayout* flayout = new FlowLayout(subContainer);
|
||||||
|
//create and render subelementviews! this is DEPTH_FIRST!!! TODO: make this breadth first!
|
||||||
|
for (std::shared_ptr<EditorNode> node : reference->getChildren()) {
|
||||||
|
GuidedEditorElementView* view = new GuidedEditorElementView(subContainer);
|
||||||
|
view->setReference(node);
|
||||||
|
flayout->addWidget(view);
|
||||||
|
view->render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout->addWidget(subContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuidedEditorElementView::inputChanged()
|
||||||
|
{
|
||||||
|
// run regex validation
|
||||||
|
if (!validator->regExp().isEmpty()) {
|
||||||
|
int pos;
|
||||||
|
QValidator::State state;
|
||||||
|
if (edit != nullptr) {
|
||||||
|
QString data = edit->document()->toPlainText();
|
||||||
|
state = validator->validate(data, pos);
|
||||||
|
if (state == QValidator::State::Invalid) {
|
||||||
|
edit->setTextColor(QColor(0xFF, 0, 0));
|
||||||
|
} else if (state == QValidator::State::Intermediate) {
|
||||||
|
edit->setTextColor(QColor(0xFF, 0xFF, 0));
|
||||||
|
} else {
|
||||||
|
line->setStyleSheet("color: #000000");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line != nullptr) {
|
||||||
|
QString data = line->text();
|
||||||
|
state = validator->validate(data, pos);
|
||||||
|
if (state == QValidator::State::Invalid) {
|
||||||
|
line->setStyleSheet("color: #FF0000");
|
||||||
|
} else if (state == QValidator::State::Intermediate) {
|
||||||
|
line->setStyleSheet("color: #FFFF00");
|
||||||
|
} else {
|
||||||
|
line->setStyleSheet("color: #000000");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuidedEditorElementView::dataChanged()
|
void GuidedEditorElementView::dataChanged()
|
||||||
{
|
{
|
||||||
|
//should be reload!
|
||||||
|
this->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuidedEditorElementView::nodeChanged()
|
||||||
|
{
|
||||||
|
this->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> GuidedEditorElementView::getReference() const
|
||||||
|
{
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuidedEditorElementView::setReference(const std::shared_ptr<EditorNode>& value)
|
||||||
|
{
|
||||||
|
reference = value;
|
||||||
|
QRegExp r(reference->getData()->getRegex());
|
||||||
|
validator->setRegExp(r);
|
||||||
|
if (reference->getData()->isMultiLine()) {
|
||||||
|
edit = new QTextEdit(this);
|
||||||
|
this->connect(edit, &QTextEdit::textChanged, this, &GuidedEditorElementView::dataChanged);
|
||||||
|
} else {
|
||||||
|
line = new QLineEdit(this);
|
||||||
|
this->connect(line, &QLineEdit::textChanged, this, &GuidedEditorElementView::dataChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,33 +7,40 @@
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QTextEdit>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "editorelementdata.h"
|
#include "editorelementdata.h"
|
||||||
#include "editorgroup.h"
|
#include "EditorNode.h"
|
||||||
#include "guidededitorgroupview.h"
|
|
||||||
|
|
||||||
class GuidedEditorElementView : public QWidget {
|
class GuidedEditorElementView : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
explicit GuidedEditorElementView(const std::shared_ptr<EditorNode> &ref,QWidget* parent = 0);
|
||||||
explicit GuidedEditorElementView(QWidget* parent = 0);
|
explicit GuidedEditorElementView(QWidget* parent = 0);
|
||||||
|
|
||||||
void render();
|
|
||||||
|
std::shared_ptr<EditorNode> getReference() const;
|
||||||
|
void setReference(const std::shared_ptr<EditorNode> &value);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void inputChanged();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void inputChanged();
|
||||||
void dataChanged();
|
void dataChanged();
|
||||||
|
void nodeChanged();
|
||||||
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// layout
|
// layout
|
||||||
QVBoxLayout* layout;
|
QVBoxLayout* layout;
|
||||||
QList<QString> propertyOrder;
|
QLabel* title;
|
||||||
QMap<QString, QWidget*> propertyViews;
|
QTextEdit* edit;
|
||||||
GuidedEditorGroupView* groupView;
|
QLineEdit* line;
|
||||||
EditorGroup* group;
|
QMap<QString, QWidget*> otherWidgets;
|
||||||
EditorElementData* elementData;
|
QRegExpValidator* validator;
|
||||||
|
QWidget* subContainer;
|
||||||
|
std::shared_ptr<EditorNode> reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GUIDEDEDITORELEMENTVIEW_H
|
#endif // GUIDEDEDITORELEMENTVIEW_H
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "guidededitorgroupview.h"
|
|
||||||
|
|
||||||
GuidedEditorGroupView::GuidedEditorGroupView(QObject* parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
this->color = new QColor(rand() % 20 * 10 + 50, rand() % 20 * 10 + 50, rand() % 20 * 10 + 50);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef GUIDEDEDITORGROUPVIEW_H
|
|
||||||
#define GUIDEDEDITORGROUPVIEW_H
|
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QObject>
|
|
||||||
class GuidedEditorGroupView : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit GuidedEditorGroupView(QObject* parent = 0);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
private:
|
|
||||||
QColor* color;
|
|
||||||
QString stylesheet;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // GUIDEDEDITORGROUPVIEW_H
|
|
|
@ -24,11 +24,11 @@ GuidedEditorView::GuidedEditorView(QWidget* parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
GuidedEditorView::GuidedEditorView(
|
GuidedEditorView::GuidedEditorView(
|
||||||
EditorModel* model,
|
EditorTree* tree,
|
||||||
QWidget* parent)
|
QWidget* parent)
|
||||||
: GuidedEditorView(parent)
|
: GuidedEditorView(parent)
|
||||||
{
|
{
|
||||||
this->model = model;
|
this->tree = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuidedEditorView::~GuidedEditorView() {}
|
GuidedEditorView::~GuidedEditorView() {}
|
||||||
|
@ -40,3 +40,37 @@ void GuidedEditorView::addElement(EditorElementData* element)
|
||||||
this->layout()->addWidget(elementView);
|
this->layout()->addWidget(elementView);
|
||||||
//this->update();
|
//this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GuidedEditorView::setTree(EditorTree* tree)
|
||||||
|
{
|
||||||
|
this->tree = tree;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuidedEditorView::treeDataChangedSlot(std::shared_ptr<EditorNode> node)
|
||||||
|
{
|
||||||
|
// get node view
|
||||||
|
auto view = nodeToViewMap[node];
|
||||||
|
if(view != nullptr)
|
||||||
|
view->dataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuidedEditorView::treeChangedSlot(std::shared_ptr<EditorNode> node)
|
||||||
|
{
|
||||||
|
// get node view
|
||||||
|
auto view = nodeToViewMap[node];
|
||||||
|
if(view != nullptr)
|
||||||
|
view->nodeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuidedEditorView::render()
|
||||||
|
{
|
||||||
|
if(tree != nullptr) {
|
||||||
|
// root node is invisible!
|
||||||
|
for(std::shared_ptr<EditorNode> node : tree->getRoot()->getChildren()){
|
||||||
|
auto view = new GuidedEditorElementView(node, this);
|
||||||
|
this->editorLayout->addWidget(view);
|
||||||
|
this->nodeToViewMap.insert(node, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef GUIDEDEDITOR_H
|
#ifndef GUIDEDEDITOR_H
|
||||||
#define GUIDEDEDITOR_H
|
#define GUIDEDEDITOR_H
|
||||||
|
#include "EditorTree.h"
|
||||||
#include "editormodel.h"
|
|
||||||
#include "editorelementdata.h"
|
#include "editorelementdata.h"
|
||||||
|
#include "guidededitorelementview.h"
|
||||||
#include "flowlayout.h"
|
#include "flowlayout.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -11,18 +11,25 @@ class GuidedEditorView : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GuidedEditorView(QWidget* parent = 0);
|
explicit GuidedEditorView(QWidget* parent = 0);
|
||||||
GuidedEditorView(EditorModel* model,
|
explicit GuidedEditorView(EditorTree* tree, QWidget* parent = 0);
|
||||||
QWidget* parent = 0);
|
|
||||||
~GuidedEditorView();
|
~GuidedEditorView();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addElement(EditorElementData* element);
|
void addElement(EditorElementData* element);
|
||||||
|
void setTree(EditorTree* tree);
|
||||||
|
|
||||||
|
void treeDataChangedSlot(std::shared_ptr<EditorNode> node);
|
||||||
|
void treeChangedSlot(std::shared_ptr<EditorNode> node);
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FlowLayout* editorLayout;
|
FlowLayout* editorLayout;
|
||||||
EditorModel* model;
|
EditorTree* tree;
|
||||||
|
QMap<std::shared_ptr<EditorNode>, GuidedEditorElementView*> nodeToViewMap;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GUIDEDEDITOR_H
|
#endif // GUIDEDEDITOR_H
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
set(HEADERS DataLoader.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES DataLoader.cpp
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(protocol ${HEADERS} ${SOURCES})
|
||||||
|
|
||||||
|
qt5_use_modules(protocol Core)
|
|
@ -0,0 +1,107 @@
|
||||||
|
#include "DataLoader.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
DataLoader::DataLoader()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DataLoader::DataLoader(QString directory)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataLoader::loadProtocolDirectory(QString directory)
|
||||||
|
{
|
||||||
|
// awaiting
|
||||||
|
QDir dir(directory);
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*osi*";
|
||||||
|
for(QString entry : dir.entryList(filters)){
|
||||||
|
if(QDir(entry).exists()) {
|
||||||
|
QDir cdir(entry);
|
||||||
|
QStringList ymlfilter;
|
||||||
|
ymlfilter << "*.yml";
|
||||||
|
for(QString file : cdir.entryList(ymlfilter)){
|
||||||
|
YAML::Node node = YAML::LoadFile(
|
||||||
|
QString(directory + QDir::separator() + entry + QDir::separator() + file).toStdString());
|
||||||
|
protocolList.append(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> DataLoader::generateTree(YAML::Node &node)
|
||||||
|
{
|
||||||
|
if(!node["protocol"])
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// root node containing the protocol.
|
||||||
|
std::shared_ptr<EditorNode> editorNode = std::shared_ptr<EditorNode>(new EditorNode());
|
||||||
|
std::shared_ptr<EditorElementData> data = std::shared_ptr<EditorElementData>(new EditorElementData());
|
||||||
|
|
||||||
|
data->setTitle(QString::fromStdString(node["protocol"]["name"].as<std::string>()));
|
||||||
|
if(node["protocol"]["longname"])
|
||||||
|
data->setHint("subtitle", QString::fromStdString(node["protocol"]["longname"].as<std::string>()));
|
||||||
|
editorNode->setData(data);
|
||||||
|
// add children containing the fields
|
||||||
|
auto fields = node["protocol"]["fields"];
|
||||||
|
for(YAML::Node n : fields) {
|
||||||
|
this->genNode(n, editorNode);
|
||||||
|
}
|
||||||
|
return editorNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataLoader::getProtocolByName(QString name, YAML::Node &node)
|
||||||
|
{
|
||||||
|
for(YAML::Node n : protocolList) {
|
||||||
|
if(n["protocol"]) {
|
||||||
|
if(name.toStdString().compare(n["protocol"]["name"].as<std::string>())) {
|
||||||
|
node = n;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DataLoader::getProtocolNames()
|
||||||
|
{
|
||||||
|
QStringList names;
|
||||||
|
for(YAML::Node node : protocolList) {
|
||||||
|
if(node["protocol"]) {
|
||||||
|
names << QString::fromStdString(node["protocol"]["name"].as<std::string>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> DataLoader::genNode(YAML::Node &n, std::shared_ptr<EditorNode> parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> newNode = std::shared_ptr<EditorNode>(new EditorNode());
|
||||||
|
newNode->setParent(parent);
|
||||||
|
std::shared_ptr<EditorElementData> newData = std::shared_ptr<EditorElementData>(new EditorElementData());
|
||||||
|
newData->setTitle(QString::fromStdString(n["field"].as<std::string>()));
|
||||||
|
if(n["desc"])
|
||||||
|
newData->setHint("desc", QString::fromStdString(n["desc"].as<std::string>()));
|
||||||
|
if(n["bytes"])
|
||||||
|
newData->setBytes(n["bytes"].as<ulong>());
|
||||||
|
else if (n["bits"])
|
||||||
|
newData->setBits(n["bits"].as<ulong>());
|
||||||
|
if(n["data"])
|
||||||
|
newData->setData(n["data"].as<bool>());
|
||||||
|
if(n["optional"])
|
||||||
|
newData->setOptional(n["data"].as<bool>());
|
||||||
|
if(n["nextlayer"])
|
||||||
|
newData->setNextLayer(n["nextlayer"].as<bool>());
|
||||||
|
newNode->setData(newData);
|
||||||
|
if(n["subfields"])
|
||||||
|
{
|
||||||
|
auto fields = n["subfields"];
|
||||||
|
for(YAML::Node subn : fields)
|
||||||
|
newNode->addChild(this->genNode(subn, newNode));
|
||||||
|
}
|
||||||
|
return newNode;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef DATALOADER_H
|
||||||
|
#define DATALOADER_H
|
||||||
|
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#include "../editor/EditorNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
class DataLoader {
|
||||||
|
public:
|
||||||
|
explicit DataLoader();
|
||||||
|
explicit DataLoader(QString directory);
|
||||||
|
|
||||||
|
void loadProtocolDirectory(QString directory);
|
||||||
|
|
||||||
|
std::shared_ptr<EditorNode> generateTree(YAML::Node &node);
|
||||||
|
|
||||||
|
bool getProtocolByName(QString name, YAML::Node &node);
|
||||||
|
QStringList getProtocolNames();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<EditorNode> genNode(YAML::Node& n, std::shared_ptr<EditorNode> parent = nullptr);
|
||||||
|
QString directory;
|
||||||
|
QList<YAML::Node> protocolList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DATALOADER_H
|
Reference in New Issue