diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88a4a42..39d0f3b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt index 6127fbe..c5fb1fa 100644 --- a/src/editor/CMakeLists.txt +++ b/src/editor/CMakeLists.txt @@ -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}) diff --git a/src/editor/EditorElementValue.cpp b/src/editor/EditorElementValue.cpp new file mode 100644 index 0000000..601811a --- /dev/null +++ b/src/editor/EditorElementValue.cpp @@ -0,0 +1,16 @@ +#include "EditorElementValue.h" + +EditorElementValue::EditorElementValue() +{ + +} + +QString EditorElementValue::getValue() const +{ + return value; +} + +void EditorElementValue::setValue(const QString &value) +{ + this->value = value; +} diff --git a/src/editor/EditorElementValue.h b/src/editor/EditorElementValue.h new file mode 100644 index 0000000..60e63dd --- /dev/null +++ b/src/editor/EditorElementValue.h @@ -0,0 +1,17 @@ +#ifndef EDITORELEMENTVALUE_H +#define EDITORELEMENTVALUE_H +#include + +class EditorElementValue +{ +public: + EditorElementValue(); + + QString getValue() const; + void setValue(const QString &value); + +private: + QString value; +}; + +#endif // EDITORELEMENTVALUE_H diff --git a/src/editor/EditorNode.cpp b/src/editor/EditorNode.cpp new file mode 100644 index 0000000..569dabc --- /dev/null +++ b/src/editor/EditorNode.cpp @@ -0,0 +1,209 @@ +#include "EditorNode.h" + +#include + +EditorNode::EditorNode() +{ + +} + +EditorNode::EditorNode(std::shared_ptr data) +{ + this->data = data; +} + +EditorNode::~EditorNode() +{ + +} + +const std::shared_ptr EditorNode::nextSibling() +{ + if (parent != nullptr) { + int i = parent->getChildren().indexOf(std::shared_ptr(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::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(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::getRoot() +{ + auto node = std::shared_ptr(this); + while (node->getParent() != nullptr) + node = node->getParent(); + return node; +} + +void EditorNode::move(std::shared_ptr to) +{ + this->getParent()->getChildren().removeOne(std::shared_ptr(this)); + to->getChildren().append(std::shared_ptr(this)); + fireTreeChanged(); +} + +void EditorNode::moveChildren(std::shared_ptr to) +{ + for (auto child : getChildren()) + child->move(to); + fireTreeChanged(); +} + +void EditorNode::addChild(std::shared_ptr child) +{ + this->getChildren().append(child); + child->setParent(std::shared_ptr(this)); + fireTreeChanged(); +} + +bool EditorNode::removeChild(std::shared_ptr 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(this)); + } + if (worked) fireTreeChanged(); + return worked; +} + +std::shared_ptr EditorNode::getParent() const +{ + return parent; +} + +void EditorNode::setParent(const std::shared_ptr &value) +{ + parent = value; +} + +std::shared_ptr EditorNode::getData() const +{ + return data; +} + +void EditorNode::setData(const std::shared_ptr &value) +{ + fireNodeDataChanged(); + data = value; +} + +std::shared_ptr EditorNode::getValue() const +{ + return value; +} + +void EditorNode::setValue(const std::shared_ptr &value) +{ + fireNodeDataChanged(); + this->value = value; +} + +QList > EditorNode::getChildren() const +{ + return children; +} + +void EditorNode::fireNodeDataChanged() +{ + if(this->getRoot()->getDataChangedSignal() != nullptr) + this->getRoot()->getDataChangedSignal()(std::shared_ptr(this)); +} + +void EditorNode::fireTreeChanged() +{ + if(this->getRoot()->getTreeChangedSignal() != nullptr) + this->getRoot()->getTreeChangedSignal()(std::shared_ptr(this)); +} + +std::shared_ptr EditorNode::nextOnSameLevel() +{ + if (nextSibling() != nullptr) + return nextSibling(); + uint lvl = 1; + auto node = this->getParent(); + auto pnode = std::shared_ptr(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; +} diff --git a/src/editor/EditorNode.h b/src/editor/EditorNode.h new file mode 100644 index 0000000..909c0d7 --- /dev/null +++ b/src/editor/EditorNode.h @@ -0,0 +1,74 @@ +#ifndef EDITORNODE_H +#define EDITORNODE_H + +#include +#include +#include + +#include "editorelementdata.h" +#include "EditorElementValue.h" + +class EditorNode; + +enum class TreeWalkStrategy { + depthFirst, + breadthFirst, + mixture +}; + +class EditorNode +{ +public: + explicit EditorNode(); + explicit EditorNode(std::shared_ptr data); + virtual ~EditorNode(); + + const std::shared_ptr nextSibling(); + + const std::shared_ptr next(TreeWalkStrategy walkStrategy = TreeWalkStrategy::depthFirst); + const std::shared_ptr getRoot(); + void move(std::shared_ptr to); //as child + void moveChildren(std::shared_ptr to); //all + + void addChild(std::shared_ptr child); + bool removeChild(std::shared_ptr child); + bool remove(); + + std::shared_ptr getParent() const; + void setParent(const std::shared_ptr &value); + + std::shared_ptr getData() const; + void setData(const std::shared_ptr &value); + + std::shared_ptr getValue() const; + void setValue(const std::shared_ptr &value); + + QList > getChildren() const; + + void setDataChangedSignal(std::function)> f) + { + nodeDataChanged = f; + } + void setTreeChangedSignal(std::function)> f) + { + treeChanged = f; + } + + std::function)> getTreeChangedSignal(){ return treeChanged; } + std::function)> getDataChangedSignal(){ return nodeDataChanged; } + +private: + void fireNodeDataChanged(); + void fireTreeChanged(); + //signal callbacks only set in the root node + std::function)> nodeDataChanged; + std::function)> treeChanged; + + std::shared_ptr nextOnSameLevel(); + std::shared_ptr parent; + std::shared_ptr data; + std::shared_ptr value; + QList> children; +}; + +#endif // EDITORNODE_H diff --git a/src/editor/EditorTree.cpp b/src/editor/EditorTree.cpp new file mode 100644 index 0000000..99433cd --- /dev/null +++ b/src/editor/EditorTree.cpp @@ -0,0 +1,15 @@ +#include "EditorTree.h" +#include + +EditorTree::EditorTree(QObject *parent) : QObject(parent) +{ + root = std::make_shared(nullptr); + + root->setDataChangedSignal([this](std::shared_ptr node){ emit this->nodeDataChanged(node);}); + root->setTreeChangedSignal([this](std::shared_ptr node){ emit this->treeChanged(node);}); +} + +EditorTree::~EditorTree() +{ + +} diff --git a/src/editor/EditorTree.h b/src/editor/EditorTree.h new file mode 100644 index 0000000..ab6b8d9 --- /dev/null +++ b/src/editor/EditorTree.h @@ -0,0 +1,25 @@ +#ifndef EDITORTREE_H +#define EDITORTREE_H +#include +#include + +#include "EditorNode.h" + +class EditorTree : public QObject +{ + Q_OBJECT +public: + explicit EditorTree(QObject *parent = 0); + virtual ~EditorTree(); + + const std::shared_ptr getRoot() { return root; } + +signals: + void nodeDataChanged(std::shared_ptr node); + void treeChanged(std::shared_ptr node); +public slots: +private: + std::shared_ptr root; +}; + +#endif // EDITORTREE_H diff --git a/src/editor/editorelementdata.cpp b/src/editor/editorelementdata.cpp index c47c1a8..034f06d 100644 --- a/src/editor/editorelementdata.cpp +++ b/src/editor/editorelementdata.cpp @@ -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 EditorElementData::getSyntaxes() const +{ + return syntaxes; +} + +void EditorElementData::setSyntaxes(const QList &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 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; +} + diff --git a/src/editor/editorelementdata.h b/src/editor/editorelementdata.h index 598f7b6..5189dd1 100644 --- a/src/editor/editorelementdata.h +++ b/src/editor/editorelementdata.h @@ -1,22 +1,71 @@ #ifndef EDITORELEMENT_H #define EDITORELEMENT_H -#include #include #include +#include + +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 getSyntaxes() const; + void setSyntaxes(const QList &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 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 elements; + QString title; + QString id; + QList syntaxes; + bool multiline; + ValueType type; + ulong bytes; + ulong bits; + QString regex; + QMap hints; + bool data; + bool nextLayer; + bool optional; }; diff --git a/src/editor/editorgroup.cpp b/src/editor/editorgroup.cpp deleted file mode 100644 index 0726503..0000000 --- a/src/editor/editorgroup.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "editorgroup.h" -#include "cstdlib" -#include - -EditorGroup::EditorGroup(QObject *parent) : QObject(parent) -{ - -} diff --git a/src/editor/editorgroup.h b/src/editor/editorgroup.h deleted file mode 100644 index b457c9a..0000000 --- a/src/editor/editorgroup.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef GUIDEDEDITORLAYER_H -#define GUIDEDEDITORLAYER_H - -#include -#include -#include - -#include "editorelementdata.h" - -class EditorGroup : public QObject -{ - Q_OBJECT -public: - explicit EditorGroup(QObject *parent = 0); - -private: - QMap attributes; - QList elements; - - - -signals: - -public slots: -}; - -#endif // GUIDEDEDITORLAYER_H diff --git a/src/editor/editormodel.cpp b/src/editor/editormodel.cpp deleted file mode 100644 index 8650dcd..0000000 --- a/src/editor/editormodel.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "editormodel.h" - -EditorModel::EditorModel(QObject *parent) : QObject(parent) -{ - -} - diff --git a/src/editor/editormodel.h b/src/editor/editormodel.h deleted file mode 100644 index 70914fd..0000000 --- a/src/editor/editormodel.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef ABSTRACTGUIDEDEDITORMODEL_H -#define ABSTRACTGUIDEDEDITORMODEL_H - -#include -#include -#include -#include -#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& getAllElements() = 0; - -signals: - void dataChanged(); - void dataChanged(uint index); - -public slots: -private: - QList data; - QList groups; - -}; - -#endif // ABSTRACTGUIDEDEDITORMODEL_H diff --git a/src/editor/editortreenode.cpp b/src/editor/editortreenode.cpp index 1504870..f27c072 100644 --- a/src/editor/editortreenode.cpp +++ b/src/editor/editortreenode.cpp @@ -1,7 +1,9 @@ #include "editortreenode.h" template -EditorTreeNode::EditorTreeNode() {} +EditorTreeNode::EditorTreeNode() { + parentNode = nullptr; +} template EditorTreeNode::EditorTreeNode(T v) @@ -18,7 +20,7 @@ EditorTreeNode::~EditorTreeNode() } template -const EditorTreeNode* EditorTreeNode::nextSibling() +const std::shared_ptr > EditorTreeNode::nextSibling() { if (parent() != nullptr) { uint i = parent()->children().indexOf(this); @@ -31,7 +33,7 @@ const EditorTreeNode* EditorTreeNode::nextSibling() } template -const EditorTreeNode* EditorTreeNode::next(TreeWalkStrategy walkStrategy) +const std::shared_ptr> EditorTreeNode::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* EditorTreeNode::next(TreeWalkStrategy walkStrategy) } template -const EditorTreeNode* EditorTreeNode::getRoot() +const std::shared_ptr> EditorTreeNode::getRoot() { - auto node = this; + auto node = std::shared_ptr>(this); while (node->parent() != nullptr) node = node->parent(); return node; } template -void EditorTreeNode::move(EditorTreeNode* to) +void EditorTreeNode::move(std::shared_ptr> to) { this->parent()->children().removeOne(this); to->children().append(this); } template -void EditorTreeNode::moveChildren(EditorTreeNode* to) +void EditorTreeNode::moveChildren(std::shared_ptr> to) { for (auto child : childrenNodes) child->move(to); } template -void EditorTreeNode::addChild(EditorTreeNode* child) +void EditorTreeNode::addChild(std::shared_ptr> child) { this->children().append(child); child->setParen(this); } template -bool EditorTreeNode::removeChild(EditorTreeNode* child) +bool EditorTreeNode::removeChild(std::shared_ptr> child) { return this->children().removeOne(child); } @@ -136,7 +138,7 @@ bool EditorTreeNode::remove() } template -EditorTreeNode* EditorTreeNode::nextOnSameLevel() +std::shared_ptr> EditorTreeNode::nextOnSameLevel() { if (nextSibling() != nullptr) return nextSibling(); diff --git a/src/editor/editortreenode.h b/src/editor/editortreenode.h index b1dfa43..49c3198 100644 --- a/src/editor/editortreenode.h +++ b/src/editor/editortreenode.h @@ -2,12 +2,9 @@ #define EDITORTREENODE_H #include +#include +#include -enum class TreeWalkStrategy { - depthFirst, - breadthFirst, - mixture -}; template class EditorTreeNode; @@ -17,34 +14,43 @@ class EditorTreeNode { public: explicit EditorTreeNode(); explicit EditorTreeNode(T v); - ~EditorTreeNode(); + virtual ~EditorTreeNode(); - const EditorTreeNode* nextSibling(); - const EditorTreeNode* parent() { return parentNode; } - QList*>& children() { return childrenNodes; } - void setParen(EditorTreeNode* parent) { this->parentNode = parent; } + + const std::shared_ptr> nextSibling(); + const std::shared_ptr> parent() { return parentNode; } + QList>>& children() { return childrenNodes; } + void setParen(std::shared_ptr> parent) { this->parentNode = parent; } T& value() { return val; } + void setValue(const T &val); - const EditorTreeNode* next(TreeWalkStrategy depth_first = TreeWalkStrategy::depthFirst); - const EditorTreeNode* getRoot(); - void move(EditorTreeNode* to); // as child! - void moveChildren(EditorTreeNode* to); // move all children + const std::shared_ptr> next(TreeWalkStrategy depth_first = TreeWalkStrategy::depthFirst); + const std::shared_ptr> getRoot(); + void move(std::shared_ptr> to); // as child! + void moveChildren(std::shared_ptr> to); // move all children -//signals: - void nodeDataChanged(EditorTreeNode* node); - void treeChanged(EditorTreeNode* node); - -//public slots: - void addChild(EditorTreeNode* child); - bool removeChild(EditorTreeNode* child); + void addChild(std::shared_ptr> child); + bool removeChild(std::shared_ptr> child); bool remove(); -//*/ + + void setDataChangedSignal(std::function>)> f) + { + nodeDataChanged = f; + } + void setTreeChangedSignal(std::function>)> f) + { + treeChanged = f; + } + private: + //signal callbacks only set in the root node + std::function>)> nodeDataChanged; + std::function>)> treeChanged; T val; - EditorTreeNode* parentNode = nullptr; - QList*> childrenNodes; - EditorTreeNode* nextOnSameLevel(); + std::shared_ptr> parentNode = nullptr; + QList>> childrenNodes; + std::shared_ptr> nextOnSameLevel(); }; #endif // EDITORTREENODE_H diff --git a/src/editor/guidededitorelementview.cpp b/src/editor/guidededitorelementview.cpp index 6c4cc4d..939a592 100644 --- a/src/editor/guidededitorelementview.cpp +++ b/src/editor/guidededitorelementview.cpp @@ -1,5 +1,6 @@ #include "guidededitorelementview.h" +#include "flowlayout.h" #include #include #include @@ -8,23 +9,116 @@ #include +GuidedEditorElementView::GuidedEditorElementView(const std::shared_ptr &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 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 GuidedEditorElementView::getReference() const +{ + return reference; +} + +void GuidedEditorElementView::setReference(const std::shared_ptr& 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); + } } diff --git a/src/editor/guidededitorelementview.h b/src/editor/guidededitorelementview.h index 9da5b30..57f5ee3 100644 --- a/src/editor/guidededitorelementview.h +++ b/src/editor/guidededitorelementview.h @@ -7,33 +7,40 @@ #include #include #include +#include #include #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 &ref,QWidget* parent = 0); explicit GuidedEditorElementView(QWidget* parent = 0); - void render(); + + std::shared_ptr getReference() const; + void setReference(const std::shared_ptr &value); signals: - void inputChanged(); public slots: + void inputChanged(); void dataChanged(); + void nodeChanged(); + void render(); private: // layout QVBoxLayout* layout; - QList propertyOrder; - QMap propertyViews; - GuidedEditorGroupView* groupView; - EditorGroup* group; - EditorElementData* elementData; + QLabel* title; + QTextEdit* edit; + QLineEdit* line; + QMap otherWidgets; + QRegExpValidator* validator; + QWidget* subContainer; + std::shared_ptr reference; }; #endif // GUIDEDEDITORELEMENTVIEW_H diff --git a/src/editor/guidededitorgroupview.cpp b/src/editor/guidededitorgroupview.cpp deleted file mode 100644 index e2626bc..0000000 --- a/src/editor/guidededitorgroupview.cpp +++ /dev/null @@ -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); -} diff --git a/src/editor/guidededitorgroupview.h b/src/editor/guidededitorgroupview.h deleted file mode 100644 index 637e7c2..0000000 --- a/src/editor/guidededitorgroupview.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef GUIDEDEDITORGROUPVIEW_H -#define GUIDEDEDITORGROUPVIEW_H - -#include -#include -class GuidedEditorGroupView : public QObject { - Q_OBJECT -public: - explicit GuidedEditorGroupView(QObject* parent = 0); - -signals: - -public slots: - -private: - QColor* color; - QString stylesheet; -}; - -#endif // GUIDEDEDITORGROUPVIEW_H diff --git a/src/editor/guidededitorview.cpp b/src/editor/guidededitorview.cpp index 132497a..57ceef5 100644 --- a/src/editor/guidededitorview.cpp +++ b/src/editor/guidededitorview.cpp @@ -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 node) +{ + // get node view + auto view = nodeToViewMap[node]; + if(view != nullptr) + view->dataChanged(); +} + +void GuidedEditorView::treeChangedSlot(std::shared_ptr 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 node : tree->getRoot()->getChildren()){ + auto view = new GuidedEditorElementView(node, this); + this->editorLayout->addWidget(view); + this->nodeToViewMap.insert(node, view); + } + } +} diff --git a/src/editor/guidededitorview.h b/src/editor/guidededitorview.h index d50d5e8..46f04d7 100644 --- a/src/editor/guidededitorview.h +++ b/src/editor/guidededitorview.h @@ -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 #include @@ -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 node); + void treeChangedSlot(std::shared_ptr node); + + void render(); private: FlowLayout* editorLayout; - EditorModel* model; + EditorTree* tree; + QMap, GuidedEditorElementView*> nodeToViewMap; + }; #endif // GUIDEDEDITOR_H diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt new file mode 100644 index 0000000..f6bea84 --- /dev/null +++ b/src/protocol/CMakeLists.txt @@ -0,0 +1,10 @@ +set(HEADERS DataLoader.h +) + +set(SOURCES DataLoader.cpp + +) + +add_library(protocol ${HEADERS} ${SOURCES}) + +qt5_use_modules(protocol Core) diff --git a/src/protocol/DataLoader.cpp b/src/protocol/DataLoader.cpp new file mode 100644 index 0000000..6a4194a --- /dev/null +++ b/src/protocol/DataLoader.cpp @@ -0,0 +1,107 @@ +#include "DataLoader.h" + +#include + +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 DataLoader::generateTree(YAML::Node &node) +{ + if(!node["protocol"]) + return nullptr; + + // root node containing the protocol. + std::shared_ptr editorNode = std::shared_ptr(new EditorNode()); + std::shared_ptr data = std::shared_ptr(new EditorElementData()); + + data->setTitle(QString::fromStdString(node["protocol"]["name"].as())); + if(node["protocol"]["longname"]) + data->setHint("subtitle", QString::fromStdString(node["protocol"]["longname"].as())); + 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())) { + 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()); + } + } + return names; +} + +std::shared_ptr DataLoader::genNode(YAML::Node &n, std::shared_ptr parent) +{ + + std::shared_ptr newNode = std::shared_ptr(new EditorNode()); + newNode->setParent(parent); + std::shared_ptr newData = std::shared_ptr(new EditorElementData()); + newData->setTitle(QString::fromStdString(n["field"].as())); + if(n["desc"]) + newData->setHint("desc", QString::fromStdString(n["desc"].as())); + if(n["bytes"]) + newData->setBytes(n["bytes"].as()); + else if (n["bits"]) + newData->setBits(n["bits"].as()); + if(n["data"]) + newData->setData(n["data"].as()); + if(n["optional"]) + newData->setOptional(n["data"].as()); + if(n["nextlayer"]) + newData->setNextLayer(n["nextlayer"].as()); + newNode->setData(newData); + if(n["subfields"]) + { + auto fields = n["subfields"]; + for(YAML::Node subn : fields) + newNode->addChild(this->genNode(subn, newNode)); + } + return newNode; +} diff --git a/src/protocol/DataLoader.h b/src/protocol/DataLoader.h new file mode 100644 index 0000000..a236aad --- /dev/null +++ b/src/protocol/DataLoader.h @@ -0,0 +1,31 @@ +#ifndef DATALOADER_H +#define DATALOADER_H + +#include + +#include +#include + +#include "../editor/EditorNode.h" + + +class DataLoader { +public: + explicit DataLoader(); + explicit DataLoader(QString directory); + + void loadProtocolDirectory(QString directory); + + std::shared_ptr generateTree(YAML::Node &node); + + bool getProtocolByName(QString name, YAML::Node &node); + QStringList getProtocolNames(); + +private: + std::shared_ptr genNode(YAML::Node& n, std::shared_ptr parent = nullptr); + QString directory; + QList protocolList; +}; + + +#endif // DATALOADER_H