diff --git a/src/core/Tree.h b/src/core/Tree.h index f78fadd..fbc401f 100644 --- a/src/core/Tree.h +++ b/src/core/Tree.h @@ -12,6 +12,10 @@ public: virtual ~Tree(); const std::shared_ptr> getRoot() { return root; } + const std::shared_ptr> getFirst() { + if(root->getChildren()->size() > 0) return root->getChildren()->at(0); + return nullptr; + } void nodeDataChanged(std::shared_ptr> node); void treeChanged(std::shared_ptr> node); diff --git a/src/core/TreeNode.h b/src/core/TreeNode.h index 9726fb3..0892b20 100644 --- a/src/core/TreeNode.h +++ b/src/core/TreeNode.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include template @@ -12,8 +12,7 @@ class TreeNode; enum class TreeWalkStrategy { depthFirst, - breadthFirst, - mixture + breadthFirst }; template class TreeNode : public std::enable_shared_from_this> @@ -30,15 +29,15 @@ public: 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 children but not the 'executing' element + void move(const std::shared_ptr > &to); //as child + void moveChildren(const std::shared_ptr > &to); //all children but not the 'executing' element - void addChild(std::shared_ptr> child); - void addChildren(std::shared_ptr> nodeWithChildren); - bool removeChild(std::shared_ptr> child); - bool remove(); + void addChild(const std::shared_ptr > &child); + void addChildren(const std::shared_ptr > &nodeWithChildren); + void removeChild(const std::shared_ptr > &child); + void remove(); - void addChildObject(std::shared_ptr obj); + void addChildObject(const std::shared_ptr &obj); uint getDistanceFromRoot(); @@ -48,7 +47,7 @@ public: std::shared_ptr getData() const; void setData(const std::shared_ptr &value); - std::list> > getChildren() const; + std::shared_ptr > > > getChildren() const; void setDataChangedSignal(std::function>)> f) { @@ -72,7 +71,7 @@ private: std::shared_ptr> nextOnSameLevel(); std::shared_ptr> parent; std::shared_ptr data; - std::list>> children; + std::shared_ptr>>> children; }; template @@ -81,6 +80,7 @@ TreeNode::TreeNode() this->data = nullptr; this->nodeDataChanged = nullptr; this->treeChanged = nullptr; + this->children = std::make_shared>>>(); } template @@ -105,7 +105,7 @@ template std::shared_ptr > TreeNode::rcopy() { auto n = std::make_shared>(std::make_shared(*this->getData())); - for(auto c : this->getChildren()) + for(auto c : *children) n->addChild(c->rcopy()); return n; } @@ -114,9 +114,9 @@ template const std::shared_ptr> TreeNode::nextSibling() { if (parent != nullptr) { - auto l = parent->getChildren(); + auto l = *(parent->getChildren()); auto it = std::find(l.begin(), l.end(), this->shared_from_this()); - if (it != l.end() && ++it != l.end()) + if (it != l.end() && it+1 != l.end()) return *(++it); //next sibling... else return nullptr; @@ -128,41 +128,9 @@ const std::shared_ptr> TreeNode::nextSibling() template const std::shared_ptr> TreeNode::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().front(); - //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().front(); - //return siblingOfParent->getChildren().first(); - else - return nullptr; - } - } else { - if (getChildren().size() > 0) - return getChildren().front(); - //return getChildren().first(); - else - return nullptr; - } - else if (walkStrategy == TreeWalkStrategy::depthFirst) - if (getChildren().size() > 0) - return getChildren().front(); - //return getChildren().first(); + if (walkStrategy == TreeWalkStrategy::depthFirst) + if (getChildren()->size() > 0) + return getChildren()->front(); else { auto node = this->shared_from_this(); while (node->nextSibling() == nullptr && node->getParent() != nullptr) @@ -173,10 +141,9 @@ const std::shared_ptr> TreeNode::next(TreeWalkStrategy walkStrate if (parent != nullptr) { auto nextOnLvl = nextOnSameLevel(); if (nextOnLvl == nullptr){ - for (auto n : parent->getChildren()) - if (n->getChildren().size() > 0) - return n->getChildren().front(); - //return n->getChildren().first(); + for (auto n : *(parent->getChildren())) + if (n->getChildren()->size() > 0) + return n->getChildren()->front(); } else return nextOnLvl; } @@ -193,78 +160,77 @@ const std::shared_ptr> TreeNode::getRoot() } template -void TreeNode::move(std::shared_ptr> to) +void TreeNode::move(const std::shared_ptr> &to) { - this->getParent()->getChildren().remove(this->shared_from_this()); - //this->getParent()->getChildren().removeOne(std::shared_ptr(this)); - to->getChildren().push_back(this->shared_from_this()); - //to->getChildren().append(std::shared_ptr(this)); + this->getParent()->removeChild(this->shared_from_this()); + to->getChildren()->push_back(this->shared_from_this()); fireTreeChanged(); } template -void TreeNode::moveChildren(std::shared_ptr> to) +void TreeNode::moveChildren(const std::shared_ptr> &to) { - for (auto child : getChildren()) + for (auto child : getChildren().get()) child->move(to); fireTreeChanged(); } template -void TreeNode::addChild(std::shared_ptr> child) +void TreeNode::addChild(const std::shared_ptr>& child) { - - this->getChildren().push_back(child); - + this->getChildren()->push_back(child); child->setParent(this->shared_from_this()); - fireTreeChanged(); } template -void TreeNode::addChildren(std::shared_ptr> nodeWithChildren) +void TreeNode::addChildren(const std::shared_ptr>& nodeWithChildren) { - for(std::shared_ptr> child : nodeWithChildren->getChildren()) + for(std::shared_ptr> child : nodeWithChildren->getChildren().get()) { - this->getChildren().push_back(child); + this->getChildren()->push_back(child); child->setParent(this->shared_from_this()); } fireTreeChanged(); } template -bool TreeNode::removeChild(std::shared_ptr> child) +void TreeNode::removeChild(const std::shared_ptr>& child) { - this->getChildren().remove(child); - bool ret = true; //this->getChildren().removeOne(child); - if (ret) fireTreeChanged(); - return ret; + auto it = children->begin(); + while ( *it != child && it != children->end()) + ++it; + children->erase(it); + fireTreeChanged(); } template -bool TreeNode::remove() +void TreeNode::remove() { - bool worked = true; - if (children.size() > 0) { - for (auto node : children) { - worked &= node->remove(); + + if (children->size() > 0) { + for (auto node : *children) { + node->remove(); } } - if (worked && parent != nullptr) { - parent->getChildren().remove(this->shared_from_this()); - //worked &= parent->getChildren().removeOne(std::shared_ptr(this)); + + if (parent != nullptr) { + auto n = this->shared_from_this(); + auto it = getParent()->getChildren()->begin(); + while ( *it != n && it != getParent()->getChildren()->end()) + ++it; + fireTreeChanged(); + + parent->getChildren()->erase(it); + } - if (worked) fireTreeChanged(); - return worked; } template -void TreeNode::addChildObject(std::shared_ptr obj) +void TreeNode::addChildObject(const std::shared_ptr &obj) { - auto node = std::make_shared>(obj); - this->addChild(node); } @@ -289,12 +255,12 @@ std::shared_ptr TreeNode::getData() const template void TreeNode::setData(const std::shared_ptr &value) { - fireNodeDataChanged(); data = value; + fireNodeDataChanged(); } template -std::list>> TreeNode::getChildren() const +std::shared_ptr>>> TreeNode::getChildren() const { return children; } @@ -329,9 +295,8 @@ std::shared_ptr> TreeNode::nextOnSameLevel() auto node = this->getParent(); auto pnode = this->shared_from_this(); while (lvl > 0 && node != nullptr) { - if (node != pnode->getParent() && node->getChildren().size() > 0) { - node = node->getChildren().front(); - //node = node->getChildren().first(); + if (node != pnode && node != pnode->getParent() && node->getChildren()->size() > 0) { + node = node->getChildren()->front(); --lvl; } else { pnode = node; @@ -342,9 +307,11 @@ std::shared_ptr> TreeNode::nextOnSameLevel() node = node->getParent(); ++lvl; } + else return nullptr; } } } + if (lvl != 0) return nullptr; return node; } diff --git a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt index 8fb4b56..d04d9b0 100644 --- a/src/editor/CMakeLists.txt +++ b/src/editor/CMakeLists.txt @@ -1,16 +1,11 @@ -set(HEADERS editorelementdata.h - guidededitorelementview.h +set(HEADERS flowlayout.h - EditorElementValue.h StructureField.h ) -set(SOURCES guidededitorelementview.cpp - editorelementdata.cpp - guidededitorview.cpp +set(SOURCES flowlayout.cpp - EditorElementValue.cpp StructureField.cpp ) diff --git a/src/editor/guidededitorelementview.cpp b/src/editor/guidededitorelementview.cpp index 15fbe9d..713be37 100644 --- a/src/editor/guidededitorelementview.cpp +++ b/src/editor/guidededitorelementview.cpp @@ -37,7 +37,7 @@ void GuidedEditorElementView::render() title->setText(QString::fromStdString(reference->getData()->getName())); layout->addWidget(title); - if (reference->getChildren().size() == 0) { + if (reference->getChildren()->size() == 0) { // need global information about showing syntax, and other hints if (false ){// reference->getData()->isMultiLine()) { @@ -51,7 +51,7 @@ void GuidedEditorElementView::render() 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()) { + for (std::shared_ptr> node : reference->getChildren().get()) { GuidedEditorElementView* view = new GuidedEditorElementView(subContainer); view->setReference(node); flayout->addWidget(view); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 41aa565..477566e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5,15 +5,15 @@ void MainWindow::doSomething() { std::cout<<"sending nullptr"<editor->addElement(nullptr); + //this->editor->addElement(nullptr); std::cout<<"sent nullptr"<setCentralWidget(editor); + //editor = new GuidedEditorView(this); + //this->setCentralWidget(editor); dockWidget = new QDockWidget(this); this->addDockWidget(Qt::LeftDockWidgetArea, dockWidget); diff --git a/test/core/test_tree.cpp b/test/core/test_tree.cpp index 0e42eb4..3b00057 100644 --- a/test/core/test_tree.cpp +++ b/test/core/test_tree.cpp @@ -9,7 +9,16 @@ class TreeTest: public ::testing::Test { protected: virtual void SetUp(){ for(int i = 0; i < 5; ++i) { - t2.getRoot()->addChildObject(std::make_shared("blah")); + t2.getRoot()->addChildObject(std::make_shared("a"+std::to_string(i))); + } + for(int i = 0; i < 5; ++i) { + t3.getRoot()->addChildObject(std::make_shared("a"+std::to_string(i))); + } + for(int i = 0; i < 5; ++i) { + t3.getRoot()->getChildren()->at(2)->addChildObject(std::make_shared("b" + std::to_string(i))); + } + for(int i = 0; i < 3; ++i) { + t3.getRoot()->getChildren()->at(4)->addChildObject(std::make_shared("c" + std::to_string(i))); } } @@ -23,19 +32,82 @@ class TreeTest: public ::testing::Test { TEST_F(TreeTest, IsEmptyInitially) { EXPECT_EQ(0, t.getRoot()->getDistanceFromRoot()); - EXPECT_EQ(0, t.getRoot()->getChildren().size()); + EXPECT_EQ(0, t.getRoot()->getChildren()->size()); } -TEST_F(TreeTest, blah) { - EXPECT_EQ(5, t2.getRoot()->getChildren().size()); - auto last = t2.getRoot()->getChildren().back(); +TEST_F(TreeTest, AddingOneLayer) { + EXPECT_EQ(5, t2.getRoot()->getChildren()->size()); + auto last = t2.getRoot()->getChildren()->back(); EXPECT_EQ(1, last->getDistanceFromRoot()); } - - - -TEST(sample_test_case, sample_test) -{ - EXPECT_EQ(1, 1); +TEST_F(TreeTest, AddingTwoLayers) { + EXPECT_EQ(2, t3.getRoot()->getChildren()->at(2)->getChildren()->at(2)->getDistanceFromRoot()); +} + +TEST_F(TreeTest, RemovalSingleNode) { + auto node = t3.getRoot()->getChildren()->at(2)->getChildren()->at(2); + node->remove(); + EXPECT_EQ(4, t3.getRoot()->getChildren()->at(2)->getChildren()->size()); +} + +TEST_F(TreeTest, RecursiveRemoval) { + auto node = t3.getRoot()->getChildren()->at(2); + node->remove(); + EXPECT_EQ(4, t3.getRoot()->getChildren()->size()); +} + +TEST_F(TreeTest, SingleMovement) { + auto node = t3.getRoot()->getChildren()->at(2)->getChildren()->at(3); + auto to = t3.getRoot()->getChildren()->at(3); + node->move(to); + EXPECT_EQ(1, to->getChildren()->size()); +} +TEST_F(TreeTest, RecursiveMovement) { + auto node = t3.getRoot()->getChildren()->at(2); + auto to = t3.getRoot()->getChildren()->at(3); + node->move(to); + EXPECT_EQ(1, to->getChildren()->size()); + EXPECT_EQ(5, to->getChildren()->at(0)->getChildren()->size()); +} + +TEST_F(TreeTest, Copy) { + auto node = t3.getRoot()->getChildren()->at(2); + auto newnode = node->copy(); + EXPECT_EQ(0, newnode->getChildren()->size()); +} +TEST_F(TreeTest, RecursiveCopy) { + auto node = t3.getRoot()->getChildren()->at(2); + auto newnode = node->rcopy(); + EXPECT_EQ(5, newnode->getChildren()->size()); +} + +TEST_F(TreeTest, TraverseTreeDepth) { + EXPECT_EQ(5, t3.getRoot()->getChildren()->size()); + EXPECT_EQ(5, t3.getRoot()->getChildren()->at(2)->getChildren()->size()); + std::string expectedResult = " a0 a1 a2 b0 b1 b2 b3 b4 a3 a4 c0 c1 c2"; + std::string result = ""; + TreeWalkStrategy walk = TreeWalkStrategy::depthFirst; + auto node = t3.getFirst(); + while (node != nullptr) { + result = result + " " + node->getData()->c_str(); + node = node->next(walk); + } + std::cout << result <getChildren()->size()); + EXPECT_EQ(5, t3.getRoot()->getChildren()->at(2)->getChildren()->size()); + std::string expectedResult = " a0 a1 a2 a3 a4 b0 b1 b2 b3 b4 c0 c1 c2"; + std::string result = ""; + TreeWalkStrategy walk = TreeWalkStrategy::breadthFirst; + auto node = t3.getFirst(); + while (node != nullptr) { + result = result + " " + node->getData()->c_str(); + node = node->next(walk); + } + std::cout << result <