ribi::cmap::QtNode * ribi::cmap::QtRateConceptMap::AddNode(const boost::shared_ptr<Node> node) { //const boost::shared_ptr<QtRateStrategy> display_strategy(new QtRateStrategy(node->GetConcept())); //assert(display_strategy); //QtNode * const qtnode = new QtNode(node,display_strategy); QtNode * const qtnode { IsCenterNode(node) ? new QtCenterNode(boost::dynamic_pointer_cast<CenterNode>(node)) : new QtNode(node,GetDisplayStrategy(node->GetConcept())) }; assert(qtnode); assert(IsCenterNode(qtnode->GetNode()) == IsQtCenterNode(qtnode) && "Should be equivalent"); //General: inform an Observer that this item has changed qtnode->m_signal_item_has_updated.connect( boost::bind(&QtConceptMap::OnItemRequestsUpdate,this,boost::lambda::_1)); //General: inform an Observer that a QGraphicsScene needs to be updated qtnode->m_signal_request_scene_update.connect( boost::bind(&QtConceptMap::OnRequestSceneUpdate,this)); //Specific: inform an Observer that the Node requests its Concept being rated qtnode->m_signal_node_requests_rate_concept.connect( boost::bind( &ribi::cmap::QtRateConceptMap::OnNodeRequestsRateConcept, this, boost::lambda::_1)); //Do not forget the placeholder! //Specific: inform an Observer that the Node requests its Examples being rated qtnode->m_signal_node_requests_rate_examples.connect( boost::bind( &ribi::cmap::QtRateConceptMap::OnNodeRequestsRateExamples, this, boost::lambda::_1)); //Do not forget the placeholder! assert(!qtnode->scene()); this->scene()->addItem(qtnode); assert(std::count( GetConceptMap()->GetNodes().begin(), GetConceptMap()->GetNodes().end(), node) == 1 && "Assume Node is already in the concept map"); //this->GetConceptMap()->AddNode(node); assert(qtnode->pos().x() == node->GetX()); assert(qtnode->pos().y() == node->GetY()); //Cannot test this: during construction not all nodes are put in //assert(Collect<QtNode>(this->scene()).size() == this->GetConceptMap()->GetNodes().size()); return qtnode; }
ribi::cmap::QtNode * ribi::cmap::QtConceptMap::GetCenterNode() noexcept { assert(scene()); assert(!scene()->items().isEmpty()); assert(scene()->items()[0]); QList<QGraphicsItem *> v = scene()->items(); const int n_centernodes{ static_cast<int>( std::count_if(v.begin(),v.end(), [this](const QGraphicsItem * const item) { return IsQtCenterNode(item); } ) ) }; assert(n_centernodes == 0 || n_centernodes == 1); if (n_centernodes == 0) return nullptr; assert(n_centernodes == 1); const auto iter = std::find_if(v.begin(),v.end(), [this](const QGraphicsItem * const item) { return IsQtCenterNode(item); } ); assert(iter != v.end()); QtNode * const center_node = dynamic_cast<QtNode*>(*iter); assert(center_node); assert(IsQtCenterNode(center_node)); return center_node; }
const ribi::cmap::QtNode * ribi::cmap::QtConceptMap::GetCenterNode() const { assert(scene()); assert(!scene()->items().isEmpty()); assert(scene()->items()[0]); QList<QGraphicsItem *> v = scene()->items(); assert(std::count_if(v.begin(),v.end(), [this](const QGraphicsItem * const item) { return this->IsQtCenterNode(item); } ) < 2 && "There is at most one center node (zero for most sub-concept maps, one for a complete concept map"); const auto iter = std::find_if(v.begin(),v.end(), [this](const QGraphicsItem * const item) { return this->IsQtCenterNode(item); } ); assert(iter != v.end()); const QtNode * const center_node = dynamic_cast<QtNode*>(*iter); assert(center_node); assert(IsQtCenterNode(center_node)); return center_node; }
void ribi::cmap::QtConceptMap::Shuffle() { const std::vector<QtNode*> nodes = Collect<QtNode>(scene()); std::for_each(nodes.begin(),nodes.end(), [this](QtNode* qtnode) { if (!IsQtCenterNode(qtnode)) { double x = qtnode->pos().x(); double y = qtnode->pos().y(); const int i = (std::rand() >> 4) % 4; switch(i) { case 0: x+= 1.0; break; case 1: y+= 1.0; break; case 2: x+=-1.0; break; case 3: y+=-1.0; break; default: assert(!"Should not get here"); } assert(QPointF(x,y) != qtnode->pos()); qtnode->SetPos(x,y); } }
void ribi::cmap::QtRateConceptMap::AddEdge( const boost::shared_ptr<Edge> edge) { const boost::shared_ptr<QtEditStrategy> qtconcept(new QtEditStrategy(edge->GetConcept())); assert(qtconcept); QtNode * const from = FindQtNode(edge->GetFrom().get()); assert(from); QtNode * const to = FindQtNode(edge->GetTo().get()); assert(to); assert(from != to); QtEdge * const qtedge = new QtEdge( edge, qtconcept, from, to ); assert(qtedge); //Edges connected to the center node do not show their concepts //Approaches should be equivalent #ifndef NDEBUG if(IsCenterNode(from->GetNode()) != IsQtCenterNode(from)) { TRACE("ERROR"); TRACE(IsCenterNode(from->GetNode())); TRACE(IsQtCenterNode(from)); } if(IsCenterNode(to->GetNode()) != IsQtCenterNode(to)) { TRACE("ERROR"); TRACE(IsCenterNode(to->GetNode())); TRACE(IsQtCenterNode(to)); } assert(IsCenterNode(from->GetNode()) == IsQtCenterNode(from)); assert(IsCenterNode(to->GetNode()) == IsQtCenterNode(to)); #endif if (IsQtCenterNode(from) || IsQtCenterNode(to)) { assert(qtconcept == qtedge->GetDisplayStrategy()); qtconcept->setVisible(false); } //General qtedge->m_signal_request_scene_update.connect( boost::bind(&QtConceptMap::OnRequestSceneUpdate,this)); //General: inform an Observer that this item has changed qtedge->m_signal_item_has_updated.connect( boost::bind(&QtConceptMap::OnItemRequestsUpdate,this,boost::lambda::_1)); //General: inform an Observer that a QGraphicsScene needs to be updated qtedge->m_signal_request_scene_update.connect( boost::bind(&QtConceptMap::OnRequestSceneUpdate,this)); //Specific: disable changing arrow heads qtedge->GetArrow()->setEnabled(false); //Do not connect m_signal_rate, because Edges will never be rated //Add the EdgeConcepts to the scene assert(!qtedge->scene()); this->scene()->addItem(qtedge); assert(std::count( this->GetConceptMap()->GetEdges().begin(), this->GetConceptMap()->GetEdges().end(), edge) == 1 && "Assume edge is already in the concept map"); #ifndef NDEBUG const double epsilon = 0.000001; #endif assert(std::abs(qtedge->pos().x() - edge->GetX()) < epsilon); assert(std::abs(qtedge->pos().y() - edge->GetY()) < epsilon); }