QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionHasChanged) { EdgeItem *edge; foreach(edge, inList) { edge->setToPoint( int(x()), int(y()) ); }
void MainWindow::on_actionLoad_XML_triggered() { scene->clear(); graph.clear(); QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", "Files (*.xml)", NULL); CFG cfg = parser.getCFG(fileName); // add all blocks for(Block block : cfg.getBlocks()) { Node* node = new Node(block.getName(), 50, 50); node->setX(qrand() % ((500 + 1) - (-500)) + (-500)); node->setY(qrand() % ((500 + 1) - (-500)) + (-500)); scene->addItem(node); graph.addNode(node); } // add all edges for(Block block : cfg.getBlocks()) { AbstractNode* from = graph.getNode(block.getName()); for(QString succName : block.getSuccessors()) { AbstractNode* to = graph.getNode(succName); EdgeItem* edge = new EdgeItem(from,to,true); edge->adjust(); scene->addItem(edge); graph.addEdge(from,to,edge); } } graph.setStart(graph.getNode(cfg.getStart().getName())); }
void MainWindow::generateRouteReport() { int totalCost = 0; QString route; // Check a route actually exists if (m_route.isEmpty() || !m_routeStart || !m_routeEnd) { postErrorMessage("Route has not been built."); return; } // Seed the route with the start node route = m_routeStart->text(); // Iterate over the route list updating the variables above QListIterator<EdgeItem*> i(m_route); while (i.hasNext()) { EdgeItem* edge = i.next(); // Add the target to the route route += edge->endNode()->text(); // Update the cost totalCost += edge->weight(); } // Print the result postInfoMessage(QString("Total route cost: %1").arg(totalCost)); postInfoMessage(QString("Route taken: %1").arg(route)); }
void MainWindow::setHighlightPath(bool highlight) { m_highlightPath = highlight; QListIterator<EdgeItem*> i(m_route); while (i.hasNext()) { EdgeItem* edge = i.next(); edge->setEmphasised(highlight); } }
QVariant NodeItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) { if (change == QGraphicsItem::ItemPositionHasChanged) { QListIterator<EdgeItem*> i(m_edges); while (i.hasNext()) { EdgeItem* edge = i.next(); edge->adjust(); } } return QGraphicsItem::itemChange(change, value); }
void Graph::reverseEdge(AbstractNode *from, AbstractNode *to) { from->removeSuccessor(to); to->removePredecessor(from); from->addPredecessor(to); to->addSuccessor(from); QPair<AbstractNode*, AbstractNode*> pair(from,to); EdgeItem* edge = edges.value(pair); edge->reverse(); edges.remove(pair); //add it to the set of reversed edges QPair<AbstractNode*, AbstractNode*> pairReversed(to,from); reversedEdges.insert(pairReversed,edge); }
void NodeItem::moveBy(double dx, double dy) { QCanvasEllipse::moveBy( dx, dy ); // 使用父類別的moveBy函數 QPtrListIterator<EdgeItem> it1( inList ); // 設定it1為指到QPtrList的指標變數 EdgeItem *edge; // 若it1指到的位置存放的EdgeItem的指標不是0時,則執行大括號內的指令,直到edge為空指標 while (( edge = it1.current() )) { ++it1; edge->setToPoint( int(x()), int(y()) ); } QPtrListIterator<EdgeItem> it2( outList ); while (( edge = it2.current() )) { ++it2; edge->setFromPoint( int(x()), int(y()) ); } }
QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionHasChanged) { Q3PtrListIterator<EdgeItem> it1( inList ); EdgeItem *edge; while (( edge = it1.current() )) { ++it1; edge->setToPoint( int(x()), int(y()) ); } Q3PtrListIterator<EdgeItem> it2( outList ); while (( edge = it2.current() )) { ++it2; edge->setFromPoint( int(x()), int(y()) ); } } return QGraphicsEllipseItem::itemChange(change, value); }
void GraphEditor::load(bool initgrid) // by default initgrid = true // when editing (erasing edges, vertices,reorienting) initgrid = false { if(!is_init) //MAC {gwp->canvas->setSceneRect(0,0,contentsRect().width(),contentsRect().height()); is_init=true; } //if(!is_init)return; clear();// delete all items if(gwp->pGG->nv() > staticData::MaxND) {Tprintf("Too big graph nv= %d (>%d)",gwp->pGG->nv(),staticData::MaxND);return;} GeometricGraph & G = *(gwp->pGG); if(initgrid) {Normalise(); InitGrid(current_grid); } DrawGrid(current_grid); if(ShowGrid)showGrid(true); Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM,(NodeItem *)NULL); Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM,(EdgeItem *)NULL); nodeitem.SetName("nodeitem");edgeitem.SetName("edgeitem"); for(tvertex v = 1;v <= G.nv();v++) nodeitem[v] = CreateNodeItem(v,gwp); for(tedge e = 1;e <= G.ne();e++) edgeitem[e] = CreateEdgeItem(e,gwp); if(staticData::ShowExtTbrin()) {tedge e = G.extbrin().GetEdge(); EdgeItem *edge = (G.extbrin() > 0) ? edgeitem[e] : edgeitem[e]->opp; edge->SetColor(color[Green],false); } Prop<bool> eoriented(G.Set(tedge()),PROP_ORIENTED,false); CreateColorItems(gwp,color_node,color_edge); G.vcolor.definit(color_node); G.vlabel.definit(0L); G.elabel.definit(0L); CreateThickItems(gwp,width_edge); G.ewidth.definit(width_edge); }
void GraphEditor::mousePressEvent(QMouseEvent* e) {GeometricGraph & G = *(gwp->pGG); QPoint p((int)e->pos().x(),(int)e->pos().y()); setFocus(); // as we might loose the focus ColorItem *coloritem; if(FindItem(p,coloritem) != 0) {if(e->button() == Qt::LeftButton) {if(coloritem->node) {gwp->NodeColorItem[color_node]->SetPenColor(White); coloritem->SetPenColor(coloritem->brush_color); color_node = coloritem->brush_color; G.vcolor.definit(color_node); } else {gwp->EdgeColorItem[color_edge]->SetPenColor(White); coloritem->SetPenColor(coloritem->brush_color); color_edge = coloritem->brush_color; G.ecolor.definit(color_edge); } return; } else if(e->button() == Qt::RightButton) {QString t; if(coloritem->node) t.sprintf("Vertex color:%s",ColorName[coloritem->brush_color]); else t.sprintf("Edge color:%s",ColorName[coloritem->brush_color]); gwp->info_item = CreateInfoItem(gwp,t,p); setCursor(QCursor(Qt::WhatsThisCursor)); return; } } ThickItem *thickitem; if(FindItem(p,thickitem) != 0) {if(e->button() == Qt::LeftButton) {gwp->EdgeThickItem[width_edge]->SetBrushColor(White); thickitem->SetBrushColor(Yellow); width_edge = thickitem->width; G.ewidth.definit(width_edge); return; } else if(e->button() == Qt::RightButton) {QString t; t.sprintf("Edge width:%d",thickitem->width); gwp->info_item = CreateInfoItem(gwp,t,p); setCursor(QCursor(Qt::WhatsThisCursor)); return; } } if(e->button() == Qt::RightButton ) {NodeItem* node; EdgeItem *edge; QString t; int rtt = FindItem(p,node,edge); if(rtt == 0)rtt = FindItem(p,edge);//augment the collision zone if(rtt == node_rtti) if (G.Set().exist(PROP_VSLABEL) && G.Set(tvertex()).exist(PROP_SLABEL)) {QString tt; Prop1<svector<tstring *> >vslabel(G.Set(),PROP_VSLABEL); Prop<int> slabel(G.Set(tvertex()),PROP_SLABEL,0); if (vslabel()[slabel[node->v]]==(tstring *)0) tt="(null)"; else tt=~(*(vslabel()[slabel[node->v]])); t.sprintf("vertex:%d Label:%d (%s)",(node->v)(),G.vlabel[node->v],(const char *)tt.toLatin1()); } else t.sprintf("vertex:%d Label:%d",(node->v)(),G.vlabel[node->v]); else if(rtt == edge_rtti) {double d = Distance(G.vcoord[G.vin[edge->e]],G.vcoord[G.vin[-(edge->e)]])+.5; t.sprintf("edge:%d Label:%d len:%d",(edge->e)(),G.elabel[edge->e],(int)d); } else {t.sprintf("(%d,%d)",(int)e->pos().x(),(int)e->pos().y()); setCursor(QCursor(Qt::BlankCursor)); } gwp->info_item = CreateInfoItem(gwp,t,p); return; } //GetMouseAction_1 returns the active radio button (0,5) int MouseAction = GetMouseAction_1(); bool Shift = e->modifiers() == Qt::ShiftModifier; bool Control = e->modifiers() == Qt::ControlModifier; bool SControl = e->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier); if(e->button() == Qt::MidButton) //move MouseAction = (Shift) ? -3 : 3; else if(Shift && MouseAction == 1) //add MouseAction = -1; // delete vertex or edge else if(Control && MouseAction == 1) MouseAction = 10; //duplicate graph else if(SControl && MouseAction == 1) MouseAction = 11; //duplicate + else if(Shift && MouseAction == 2) //Orient or reorient if oriented MouseAction = -2; //disorient else if(Shift && MouseAction == 3) //move vertices MouseAction = -3; //move colored vertices else if(Shift && MouseAction == 4) //bissect MouseAction = -4; //contract else if(Shift && MouseAction == 5) //define exterior face MouseAction = -5; //define extbrin else if(Shift && MouseAction == 6) //define a label MouseAction = -6; //reset all labels to indices if(MouseAction == 0) // color {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt == 0) //augment the collision zone {rtt = FindItem(p,edge); if(rtt == 0)return; } if(rtt == node_rtti) {mywindow->UndoTouch(false); G.vcolor[node->v] = color_node; node->SetColor(color[color_node]); } else if(rtt == edge_rtti) {mywindow->UndoTouch(false); G.ecolor[edge->e] = color_edge; G.ewidth[edge->e] = width_edge; if(edge->lower) edge->SetColor(color[color_edge]); else edge->opp->SetColor(color[color_edge]); } return; } else if(MouseAction == 1) // Start create an edge {mywindow->UndoTouch(false); Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM); NodeItem* node; EdgeItem *edge; tvertex v; int h = (int)gwp->canvas->height(); int rtt = FindItem(p,node,edge); if(rtt != node_rtti)// add a vertex {Tpoint pp((double)p.x(),(double)(h - p.y())); v = G.NewVertex(pp); ToGrid(v); nodeitem[v] = node = CreateNodeItem(v,gwp); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); } else v = node->v; start_position = QPoint((int)G.vcoord[v].x(),h-(int)G.vcoord[v].y()); node->SetColor(Qt::red); gwp->curs_item = new CursItem(v,start_position,gwp); } else if(MouseAction == -1) // Delete {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt == 0) //augment the collision zone {rtt = FindItem(p,edge); if(rtt == 0)return; } if(rtt == node_rtti) {mywindow->UndoTouch(true); G.DeleteVertex(node->v); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); } else {mywindow->UndoTouch(true); G.DeleteEdge(edge->e); } load(false); mywindow->information();// Informations PrintSizeGrid(); return; } else if(MouseAction == 3) // Start moving a vertex {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt != node_rtti)return; mywindow->UndoTouch(false); gwp->moving_item = node; start_position = p; return; } else if(MouseAction == -3) // Start moving a subgraph {mywindow->UndoTouch(false); gwp->moving_subgraph = true; start_position = p; return; } else if(MouseAction == 4) // Bissect an edge {mywindow->UndoTouch(true); if(FitToGrid)//and we are sure that ButtonFitGrid exists mywindow->mouse_actions->ButtonFitGrid->setChecked(false); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; G.BissectEdge(edge->e); DoNormalise = false; load(true); DoNormalise = true; mywindow->information();// Informations return; } else if(MouseAction == -4) // Contract an edge {EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; mywindow->UndoTouch(true); // provisoire if(edge->lower)G.ReverseEdge(edge->e); // end provisoire G.ContractEdge(edge->e); load(false); mywindow->information();// Informations return; } else if(MouseAction == 5) // Color Exterior face {GeometricGraph & G = *(gwp->pGG); Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM); Tpoint pp((double)p.x(),(double)(gwp->canvas->height()-p.y())); if(G.FindExteriorFace(pp) == 0)return; //ColorExteriorface tedge e; ForAllEdges(e,G)edgeitem[e]->SetColor(color[color_edge]); tbrin b0 = G.extbrin(); tbrin b = b0; do {e = b.GetEdge(); edgeitem[e]->SetColor(color[Red]); } while((b = G.cir[-b]) != b0); if(b0() > 0) edgeitem[b0.GetEdge()]->SetColor(color[Green],false); else edgeitem[b0.GetEdge()]->opp->SetColor(color[Green],false); return; } else if(MouseAction == -5) // Define Extbrin {EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM); tedge je; ForAllEdges(je,G)edgeitem[je]->SetColor(color[color_edge]); GeometricGraph & G = *(gwp->pGG); je = edge->e; // Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM); // NodeItem *n1 = nodeitem[G.vin[je]]; Tpoint p1(n1->x(),n1->y()); // NodeItem *n2 = nodeitem[G.vin[-je]]; Tpoint p2(n2->x(),n2->y()); // Tpoint pp((double)p.x(),(double)p.y()); // G.extbrin() = (Distance2(pp,p1) < Distance2(pp,p2)) ? je.firsttbrin() : je.secondtbrin(); G.extbrin() = (edge->lower ) ? je.firsttbrin() : je.secondtbrin(); edge->SetColor(color[Green],false); return; } else if(MouseAction == 6) // Modify label {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt != node_rtti)return; tvertex v = node->v; bool ok; //int res = QInputDialog::getInteger(this,"Pigale","Enter a number:",(int)G.vlabel[node->v],0,2147483647,1,&ok); int res = QInputDialog::getInt(this,"Pigale","Enter a number:",(int)G.vlabel[node->v],0,2147483647,1,&ok); if(!ok)return; G.vlabel[node->v] = res; QString t = getVertexLabel(G.Container(),v); node->SetText(t); return; } else if(MouseAction == -6) // Reset all labels {Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM); for(tvertex v = 1; v <= G.nv();v++) {G.vlabel[v] = v(); nodeitem[v]->SetText(QString("%1").arg(v())); } for(tedge e = 1; e <= G.ne();e++) G.elabel[e] = e(); } else if(MouseAction == 2 || MouseAction == -2) // Orient/Reverse or deorient {Prop<bool> eoriented(G.Set(tedge()),PROP_ORIENTED,false); Prop<bool> reoriented(G.Set(tedge()),PROP_REORIENTED); Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM); mywindow->setShowOrientation(true); EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; mywindow->UndoTouch(true); if(MouseAction == 2) {if(eoriented[edge->e]) {G.ReverseEdge(edge->e); eoriented[edge->e] = true; reoriented[edge->e] = false; edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); if(edge->arrow) scene()->removeItem(edge->arrow); else scene()->removeItem(edge->opp->arrow); scene()->removeItem(edge->opp);scene()->removeItem(edge); mywindow->information();// Informations return; } else {eoriented[edge->e] = true; if(edge->lower) {G.ReverseEdge(edge->e);reoriented[edge->e] = false;} edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); if(edge->arrow) scene()->removeItem(edge->arrow); else scene()->removeItem(edge->opp->arrow); scene()->removeItem(edge->opp);scene()->removeItem(edge); mywindow->information();// Informations return; } } else {eoriented[edge->e] = false; edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); if(edge->arrow) scene()->removeItem(edge->arrow); else scene()->removeItem(edge->opp->arrow); scene()->removeItem(edge->opp);scene()->removeItem(edge); mywindow->information();// Informations return; } } else if(MouseAction == 10)// Duplicate the sugraph of the current color {mywindow->UndoTouch(true); if(FitToGrid)//and we are sure that ButtonFitGrid exists mywindow->mouse_actions->ButtonFitGrid->setChecked(false); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); short vcol=0; G.vcolor.getinit(vcol); G.vcolor.definit((short)((vcol+1)%16)); GeometricGraph & G = *(gwp->pGG); Tpoint translate(this->width()/2.,0); int n = G.nv(); svector<tvertex> newvertex(1,n); tvertex v; for(v = 1; v <= n;v++)//translate all the graph G.vcoord[v] /= 2.; for(v = 1; v <= n;v++) {if(G.vcolor[v] != vcol)continue; newvertex[v] = G.NewVertex(G.vcoord[v] + translate); } int m = G.ne(); tvertex v1,v2; for(tedge e = 1; e <= m;e++) {v1 = G.vin[e];v2 = G.vin[-e]; if(G.vcolor[v1] == vcol && G.vcolor[v2] == vcol) G.NewEdge(newvertex[v1],newvertex[v2]); } load(true); mywindow->information();// Informations } else if(MouseAction == 11) //Duplicate the sugraph of the current color // and add edges between a new vertex and its father {mywindow->UndoTouch(true); if(FitToGrid)//and we are sure that ButtonFitGrid exists mywindow->mouse_actions->ButtonFitGrid->setChecked(false); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); mywindow->mouse_actions->ButtonFitGrid->setChecked(false); short vcol=0; G.vcolor.getinit(vcol); G.vcolor.definit((short)((vcol+1)%16)); GeometricGraph & G = *(gwp->pGG); Tpoint translate(this->width()/2.,0); int n = G.nv(); svector<tvertex> newvertex(1,n); tvertex v; for(v = 1; v <= n;v++)//translate all the graph G.vcoord[v] /= 2.; for(v = 1; v <= n;v++) {if(G.vcolor[v] != vcol)continue; newvertex[v] = G.NewVertex(G.vcoord[v] + translate); } int m = G.ne(); tvertex v1,v2; for(tedge e = 1; e <= m;e++) {v1 = G.vin[e];v2 = G.vin[-e]; if(G.vcolor[v1] == vcol && G.vcolor[v2] == vcol) G.NewEdge(newvertex[v1],newvertex[v2]); } for(v = 1; v <= n;v++) {if(G.vcolor[v] != vcol)continue; G.NewEdge(v,newvertex[v]); } load(true); mywindow->information();// Informations } }
void MainWindow::routeNetwork() { // Storage class for the metadata required by Dijkstra struct MetaData { int distance; EdgeItem* edge; NodeItem* previous; NodeItem* owner; MetaData() : distance(INT_MAX) , edge(nullptr) , previous(nullptr) , owner(nullptr) { } MetaData(NodeItem* owner_) : distance(INT_MAX) , edge(nullptr) , previous(nullptr) , owner(owner_) { } }; QMap<NodeItem*, MetaData> metadata; QList<NodeItem*> nodes; NodeItem* current; // Initialise data-structres postInfoMessage("Preparing to route..."); { QMapIterator<QString, NodeItem*> i(m_graphNodes); while (i.hasNext()) { auto item = i.next(); // Initialise the metadata MetaData md(item.value()); if (item.value() == m_routeStart) { // Need minimal distance for the start node md.distance = 0; } metadata[i.value()] = md; // Initialise the node list nodes.append(i.value()); } } // Dijkstra's algorithm: calculate all the distances while (!nodes.isEmpty()) { // Find node with smallest distance { int d = INT_MAX; auto elem = nodes.end(); for (auto it = nodes.begin(); it != nodes.end(); ++it) { int thisDistance = metadata[*it].distance; if (thisDistance < d) { d = thisDistance; elem = it; } } current = *elem; // If we hit the target, we can stop if (current == m_routeEnd) { postInfoMessage("Search complete; reached target node!"); break; } else { // Emshrinken the list nodes.erase(elem); } } postInfoMessage(QString("Considering node %1...") .arg(current->text())); // Visit the neighbours QListIterator<EdgeItem*> i(current->edges()); while (i.hasNext()) { EdgeItem* edge = i.next(); NodeItem* neighbour = edge->endNode(); int dist = metadata[current].distance + edge->weight(); if (dist < metadata[neighbour].distance) { metadata[neighbour].distance = dist; metadata[neighbour].edge = edge; metadata[neighbour].previous = current; } } } // Walk backwards from the target to the source, building the path postInfoMessage("Back-tracking to construct route..."); for (current = m_routeEnd; current; current = metadata[current].previous) { EdgeItem* edge = metadata[current].edge; if (edge) { m_route.prepend(edge); } } // All done! postSuccessMessage("Routing complete!"); // Update the display setHighlightStartNode(m_controlsDock->highlightStartNode()); setHighlightEndNode(m_controlsDock->highlightEndNode()); setHighlightPath(m_controlsDock->highlightPath()); }
int MainWindow::buildNetwork(const QString& description) { int result = Success; // Split into lines QStringList lines = description.split(QRegExp("[\\n|\\r]"), QString::SkipEmptyParts); if (lines.isEmpty()) { postErrorMessage("Problem specification is empty after whitespace " "removed!"); return ErrorEmpty; } // Validate the length of the specification int nodeCount = lines[0].toInt(); postInfoMessage(QString("Expecting %1x%1 adjacency matrix...") .arg(nodeCount)); if (lines.length() != (nodeCount + 2)) { postErrorMessage(QString("Expecting %1 lines in specification; read %2") .arg(nodeCount + 2) .arg(lines.length())); return ErrorSpecTooSmall; } // Clear the existing graph and scene if (boost::num_vertices(m_graph) != 0) { postWarningMessage("Existing network already loaded; must be cleared " "in order to continue."); int response = QMessageBox::question(this, "NetRoute", "There is " "already a graph in the explorer; the current data will have to " "be discared. Continue?"); if (response == QMessageBox::No) { postErrorMessage("Aborted by user."); return WarningAbort; } postInfoMessage("Discarding network."); clearNetwork(); } // Create the nodes postInfoMessage("Creating nodes..."); for (int i = 0; i < nodeCount; ++i) { QString name = QString("%1").arg(QChar('A' + i)); NodeItem* node = new NodeItem; node->setText(name); m_graphNodes[name] = node; boost::add_vertex(NodeProperties(node), m_graph); m_graphScene->addItem(node); } // Create the edges postInfoMessage("Creating edges from adjacency matrix..."); for (int i = 0; i < nodeCount; ++i) { QString line = lines[i + 1].trimmed(); QStringList weights = line.split(',', QString::SkipEmptyParts); // Sanity check if (weights.length() != nodeCount) { postErrorMessage( QString("Matrix row %1 has %2 columns; expecting %3.") .arg(i) .arg(weights.length()) .arg(nodeCount)); return ErrorRowTooShort; } // Actually create the edges postInfoMessage(QString("Creating edges for node %1") .arg(QChar('A' + i))); DigraphVertex vStart = boost::vertex(i, m_graph); for (int j = 0; j < nodeCount; ++j) { bool ok; int weight = weights[j].trimmed().toInt(&ok); if (ok && weight >= 0) { DigraphVertex vEnd = boost::vertex(j, m_graph); // Create the new edge item EdgeItem* edge = new EdgeItem; edge->setStartNode(m_graph[vStart].item); edge->setEndNode(m_graph[vEnd].item); edge->setWeight(weight); m_graphScene->addItem(edge); // Add it to the graph boost::add_edge(vStart, vEnd, EdgeProperties(edge), m_graph); } else if (!ok) { postWarningMessage(QString("Weight (%1,%2) is malformed: %3.") .arg(i) .arg(j) .arg(weights[j])); result |= WarningBadCell; } } } // Parse the final line of the description: the start/end nodes QStringList nodes = lines[lines.length() - 1].split(QRegExp("\\s+"), QString::SkipEmptyParts); if (nodes.length() != 2) { postWarningMessage("Start and end nodes line is malformed; " "routing will not take place."); result |= WarningBadStartEnd; } else { QString startNodeName = nodes[0]; QString endNodeName = nodes[1]; m_routeStart = m_graphNodes[startNodeName]; m_routeEnd = m_graphNodes[endNodeName]; if (!m_routeStart) { postWarningMessage(QString("Failed to find start node '%1'; " "routing will not take place.") .arg(startNodeName)); result |= WarningNoStartNode; } if (!m_routeEnd) { postWarningMessage(QString("Failed to find end node '%1'; " "routing will not take place.") .arg(endNodeName)); result |= WarningNoEndNode; } } // Graph was built successfully, even if some parsing errors arose. return result; }