current work on editor widges and data loading

This commit is contained in:
Marcel Otte 2016-10-13 23:31:48 +02:00
parent bd1e40685b
commit cc5b9dfa46
25 changed files with 895 additions and 176 deletions

View File

@ -6,7 +6,8 @@ set(SOURCES mainwindow.cpp
add_subdirectory(model)
add_subdirectory(editor)
add_subdirectory(protocol)
add_library(src ${HEADERS} ${SOURCES})
target_link_libraries(src model editor)
target_link_libraries(src model editor protocol)
qt5_use_modules(src Widgets)

View File

@ -1,21 +1,20 @@
set(HEADERS editormodel.h
editorelementdata.h
set(HEADERS editorelementdata.h
guidededitorelementview.h
guidededitorgroupview.h
editorgroup.h
flowlayout.h
editortreenode.h
EditorNode.h
EditorTree.h
EditorElementValue.h
)
set(SOURCES guidededitorelementview.cpp
guidededitorgroupview.cpp
editorelementdata.cpp
editormodel.cpp
editorgroup.cpp
guidededitorview.cpp
flowlayout.cpp
editortreenode.cpp
EditorNode.cpp
EditorTree.cpp
EditorElementValue.cpp
)
add_library(editor ${HEADERS} ${SOURCES})

View File

@ -0,0 +1,16 @@
#include "EditorElementValue.h"
EditorElementValue::EditorElementValue()
{
}
QString EditorElementValue::getValue() const
{
return value;
}
void EditorElementValue::setValue(const QString &value)
{
this->value = value;
}

View File

@ -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

209
src/editor/EditorNode.cpp Normal file
View File

@ -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;
}

74
src/editor/EditorNode.h Normal file
View File

@ -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

15
src/editor/EditorTree.cpp Normal file
View File

@ -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()
{
}

25
src/editor/EditorTree.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -1,22 +1,71 @@
#ifndef EDITORELEMENT_H
#define EDITORELEMENT_H
#include <QObject>
#include <QString>
#include <QMap>
#include <QList>
enum class ValueType {
BIN,OCT,DEC,HEX,TXT
};
class EditorElementData : public QObject
class EditorElementData
{
Q_OBJECT
public:
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:
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;
};

View File

@ -1,8 +0,0 @@
#include "editorgroup.h"
#include "cstdlib"
#include <QColor>
EditorGroup::EditorGroup(QObject *parent) : QObject(parent)
{
}

View File

@ -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

View File

@ -1,7 +0,0 @@
#include "editormodel.h"
EditorModel::EditorModel(QObject *parent) : QObject(parent)
{
}

View File

@ -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

View File

@ -1,7 +1,9 @@
#include "editortreenode.h"
template <typename T>
EditorTreeNode<T>::EditorTreeNode() {}
EditorTreeNode<T>::EditorTreeNode() {
parentNode = nullptr;
}
template <typename T>
EditorTreeNode<T>::EditorTreeNode(T v)
@ -18,7 +20,7 @@ EditorTreeNode<T>::~EditorTreeNode()
}
template <typename T>
const EditorTreeNode<T>* EditorTreeNode<T>::nextSibling()
const std::shared_ptr<EditorTreeNode<T> > EditorTreeNode<T>::nextSibling()
{
if (parent() != nullptr) {
uint i = parent()->children().indexOf(this);
@ -31,7 +33,7 @@ const EditorTreeNode<T>* EditorTreeNode<T>::nextSibling()
}
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)
// 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>
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)
node = node->parent();
return node;
}
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);
to->children().append(this);
}
template <typename T>
void EditorTreeNode<T>::moveChildren(EditorTreeNode<T>* to)
void EditorTreeNode<T>::moveChildren(std::shared_ptr<EditorTreeNode<T>> to)
{
for (auto child : childrenNodes)
child->move(to);
}
template <typename T>
void EditorTreeNode<T>::addChild(EditorTreeNode<T>* child)
void EditorTreeNode<T>::addChild(std::shared_ptr<EditorTreeNode<T>> child)
{
this->children().append(child);
child->setParen(this);
}
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);
}
@ -136,7 +138,7 @@ bool EditorTreeNode<T>::remove()
}
template <typename T>
EditorTreeNode<T>* EditorTreeNode<T>::nextOnSameLevel()
std::shared_ptr<EditorTreeNode<T>> EditorTreeNode<T>::nextOnSameLevel()
{
if (nextSibling() != nullptr)
return nextSibling();

View File

@ -2,12 +2,9 @@
#define EDITORTREENODE_H
#include <QList>
#include <memory>
#include <functional>
enum class TreeWalkStrategy {
depthFirst,
breadthFirst,
mixture
};
template <typename T>
class EditorTreeNode;
@ -17,34 +14,43 @@ class EditorTreeNode {
public:
explicit EditorTreeNode();
explicit EditorTreeNode(T v);
~EditorTreeNode();
virtual ~EditorTreeNode();
const EditorTreeNode<T>* nextSibling();
const EditorTreeNode<T>* parent() { return parentNode; }
QList<EditorTreeNode<T>*>& children() { return childrenNodes; }
void setParen(EditorTreeNode<T>* parent) { this->parentNode = parent; }
const std::shared_ptr<EditorTreeNode<T>> nextSibling();
const std::shared_ptr<EditorTreeNode<T>> parent() { return parentNode; }
QList<std::shared_ptr<EditorTreeNode<T>>>& children() { return childrenNodes; }
void setParen(std::shared_ptr<EditorTreeNode<T>> parent) { this->parentNode = parent; }
T& value() { return val; }
void setValue(const T &val);
const EditorTreeNode<T>* next(TreeWalkStrategy depth_first = TreeWalkStrategy::depthFirst);
const EditorTreeNode<T>* getRoot();
void move(EditorTreeNode<T>* to); // as child!
void moveChildren(EditorTreeNode<T>* to); // move all children
const std::shared_ptr<EditorTreeNode<T>> next(TreeWalkStrategy depth_first = TreeWalkStrategy::depthFirst);
const std::shared_ptr<EditorTreeNode<T>> getRoot();
void move(std::shared_ptr<EditorTreeNode<T>> to); // as child!
void moveChildren(std::shared_ptr<EditorTreeNode<T>> to); // move all children
//signals:
void nodeDataChanged(EditorTreeNode<T>* node);
void treeChanged(EditorTreeNode<T>* node);
//public slots:
void addChild(EditorTreeNode<T>* child);
bool removeChild(EditorTreeNode<T>* child);
void addChild(std::shared_ptr<EditorTreeNode<T>> child);
bool removeChild(std::shared_ptr<EditorTreeNode<T>> child);
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:
//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;
EditorTreeNode<T>* parentNode = nullptr;
QList<EditorTreeNode<T>*> childrenNodes;
EditorTreeNode<T>* nextOnSameLevel();
std::shared_ptr<EditorTreeNode<T>> parentNode = nullptr;
QList<std::shared_ptr<EditorTreeNode<T>>> childrenNodes;
std::shared_ptr<EditorTreeNode<T>> nextOnSameLevel();
};
#endif // EDITORTREENODE_H

View File

@ -1,5 +1,6 @@
#include "guidededitorelementview.h"
#include "flowlayout.h"
#include <QLabel>
#include <QRegExp>
#include <QRegExpValidator>
@ -8,23 +9,116 @@
#include <iostream>
GuidedEditorElementView::GuidedEditorElementView(const std::shared_ptr<EditorNode> &ref, QWidget* parent)
: GuidedEditorElementView(parent)
{
this->setReference(ref);
}
GuidedEditorElementView::GuidedEditorElementView(QWidget* parent)
: QWidget(parent)
{
this->validator = new QRegExpValidator();
this->layout = new QVBoxLayout(this);
this->setLayout(layout);
this->edit = nullptr;
this->line = nullptr;
this->title = new QLabel(this);
}
void GuidedEditorElementView::render()
{
for (QWidget* w : this->propertyViews.values())
this->layout->removeWidget(w);
for (QString prop : this->propertyOrder) {
this->layout->addWidget(this->propertyViews[prop]);
// TODO: add possibility to collapse a subtree
for (QObject* w : this->children())
if (w->isWidgetType()) {
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()
{
//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);
}
}

View File

@ -7,33 +7,40 @@
#include <QList>
#include <QVBoxLayout>
#include <QWidget>
#include <QTextEdit>
#include <memory>
#include "editorelementdata.h"
#include "editorgroup.h"
#include "guidededitorgroupview.h"
#include "EditorNode.h"
class GuidedEditorElementView : public QWidget {
Q_OBJECT
public:
explicit GuidedEditorElementView(const std::shared_ptr<EditorNode> &ref,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:
void inputChanged();
public slots:
void inputChanged();
void dataChanged();
void nodeChanged();
void render();
private:
// layout
QVBoxLayout* layout;
QList<QString> propertyOrder;
QMap<QString, QWidget*> propertyViews;
GuidedEditorGroupView* groupView;
EditorGroup* group;
EditorElementData* elementData;
QLabel* title;
QTextEdit* edit;
QLineEdit* line;
QMap<QString, QWidget*> otherWidgets;
QRegExpValidator* validator;
QWidget* subContainer;
std::shared_ptr<EditorNode> reference;
};
#endif // GUIDEDEDITORELEMENTVIEW_H

View File

@ -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);
}

View File

@ -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

View File

@ -24,11 +24,11 @@ GuidedEditorView::GuidedEditorView(QWidget* parent)
}
GuidedEditorView::GuidedEditorView(
EditorModel* model,
EditorTree* tree,
QWidget* parent)
: GuidedEditorView(parent)
{
this->model = model;
this->tree = tree;
}
GuidedEditorView::~GuidedEditorView() {}
@ -40,3 +40,37 @@ void GuidedEditorView::addElement(EditorElementData* element)
this->layout()->addWidget(elementView);
//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);
}
}
}

View File

@ -1,8 +1,8 @@
#ifndef GUIDEDEDITOR_H
#define GUIDEDEDITOR_H
#include "editormodel.h"
#include "EditorTree.h"
#include "editorelementdata.h"
#include "guidededitorelementview.h"
#include "flowlayout.h"
#include <QWidget>
#include <memory>
@ -11,18 +11,25 @@ class GuidedEditorView : public QWidget {
Q_OBJECT
public:
explicit GuidedEditorView(QWidget* parent = 0);
GuidedEditorView(EditorModel* model,
QWidget* parent = 0);
explicit GuidedEditorView(EditorTree* tree, QWidget* parent = 0);
~GuidedEditorView();
signals:
public slots:
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:
FlowLayout* editorLayout;
EditorModel* model;
EditorTree* tree;
QMap<std::shared_ptr<EditorNode>, GuidedEditorElementView*> nodeToViewMap;
};
#endif // GUIDEDEDITOR_H

View File

@ -0,0 +1,10 @@
set(HEADERS DataLoader.h
)
set(SOURCES DataLoader.cpp
)
add_library(protocol ${HEADERS} ${SOURCES})
qt5_use_modules(protocol Core)

107
src/protocol/DataLoader.cpp Normal file
View File

@ -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;
}

31
src/protocol/DataLoader.h Normal file
View File

@ -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