/** * Destructor. Corrects list of nodes in corresponding graph and deletes adjacent edges */ Node::~Node() { out ("deleting node# "); debugPrint(); out ("\n\n\n"); Edge *edge; /** delete incidient edges */ for ( edge = firstSucc(); isNotNullP( edge);) { Edge* next = edge->nextSucc(); edge->detachFromNode( GRAPH_DIR_DOWN);// Edge is detached from succ node delete edge; edge = next; } for ( edge = firstPred(); isNotNullP( edge);) { Edge* next = edge->nextPred(); edge->detachFromNode( GRAPH_DIR_UP);// Edge is detached from pred node delete edge; edge = next; } /** delete myself from graph */ graph->detachNode( this); }
/** Node checking routine */ bool Edge::checkNodes( Node* _pred, Node* _succ) { return isNotNullP( _pred) && isNotNullP( _succ) && areEqP( this->graph(), _pred->graph()) && areEqP( _pred->graph(), _succ->graph()); }
Node::~Node() { Edge *edge; //out("Deleted Node"); /** delete incidient edges */ for ( edge = firstSucc(); isNotNullP( edge);) { Edge* next = edge->nextSucc(); //edge->detachFromNode( GRAPH_DIR_DOWN);// Edge is detached from succ node graph()->deleteEdge( edge); edge = next; } for ( edge = firstPred(); isNotNullP( edge);) { Edge* next = edge->nextPred(); //edge->detachFromNode( GRAPH_DIR_UP);// Edge is detached from pred node graph()->deleteEdge( edge); edge = next; } element.parentNode().removeChild( element); /** delete myself from graph */ graph_p->detachNode( this); }
/** * The entry point for console version of ShowGraph */ static int doAll( int argc, char **argv) { QApplication app(argc, argv); app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); Conf conf; conf.addOption( new Option( OPT_STRING, "f", "file", "input graph description file name")); conf.addOption( new Option( OPT_STRING, "o", "output", "output image file name")); conf.readArgs( argc, argv); Option *fopt = conf.longOption("file"); Option *out_opt = conf.longOption("output"); assertd( isNotNullP( fopt)); assertd( isNotNullP( out_opt)); if ( fopt->isDefined()) { QString xmlname = fopt->string(); QString outname("image.png"); Renderer r; if ( out_opt->isDefined()) { outname = out_opt->string(); } r.render( xmlname, outname); } else { conf.printOpts(); // Print options to console } //return app.exec(); return 0; }
/** * Print edge in DOT format to stdout */ void Edge::debugPrint() { /** * Check that edge is printable * TODO: Implements graph states and in 'in process' state print node as '?' * Examples of such prints: 4->? ?->3 ?->? */ assert( isNotNullP( pred())); assert( isNotNullP( succ())); out("%llu->%llu;", pred()->id(), succ()->id()); }
/** * Destructor for node - removes edge controls on incidient edges and disconnects item from scene */ GNode::~GNode() { graph()->invalidateRanking(); if ( ( isEdgeControl() || isEdgeLabel()) && isNotNullP( firstPred()) && isNotNullP( firstSucc()) && isNotNullP( firstPred()->pred()) && isNotNullP( firstSucc()->succ())) { GRAPH_ASSERTD( areEqP( firstPred()->style(), firstSucc()->style()), "Different styles on the same edge"); GEdge *e = graph()->newEdge( firstPred()->pred(), firstSucc()->succ()); e->setStyle( firstPred()->style()); } else if ( isSimple()) { QList< GNode *> nodes; GEdge* edge; Marker m = graph()->newMarker(); for ( edge = firstSucc(); isNotNullP( edge); edge = edge->nextSucc()) { edge->item()->adjust(); GNode* succ = edge->succ(); while ( succ->isEdgeControl() || succ->isEdgeLabel()) { assert( isNotNullP( succ->firstSucc())); if ( succ->mark( m)) { nodes << succ; } succ = succ->firstSucc()->succ(); } } for ( edge = firstPred(); isNotNullP( edge); edge = edge->nextPred()) { if ( edge->isSelf()) // We've already processed this one in previous loop continue; edge->item()->adjust(); GNode* pred = edge->pred(); while ( pred->isEdgeControl() || pred->isEdgeLabel()) { assert( isNotNullP( pred->firstPred())); if ( pred->mark( m)) { nodes << pred; } pred = pred->firstPred()->pred(); } } foreach ( GNode *n, nodes) { graph()->deleteNode( n); } graph()->freeMarker( m); }
void CFG< MdesType>::toStream(ostream& os) { Numeration num = makeTopologicalNumeration(); std::vector< CFNode< MdesType> *> nodes( this->numNodes()); /* Fill array of node pointers */ for ( CFNode< MdesType> *node = this->firstNode(); isNotNullP( node); node = node->nextNode() ) { IR_ASSERTD( node->isNumbered( num)); nodes[ node->number( num)] = node; } /* Print reachable nodes */ for ( UInt32 i = startNode()->number( num); i < this->numNodes(); ++i) { CFNode< MdesType> *node = nodes[ i]; os << *node << endl; } for ( UInt32 i = 0, end = startNode()->number( num); i < end; ++i) { CFNode< MdesType> *node = nodes[ i]; os << "unreachable " << *node << endl; } this->freeNum( num); }
/** * Update DOM tree element */ void GEdge::updateElement() { #if 0 QDomElement e = elem(); int i = 0; QDomElement new_e = graph()->createElement( "edge"); QDomNode e2 = graph()->documentElement().removeChild( e); assert( !e2.isNull()); graph()->documentElement().appendChild( new_e); setElement( new_e); e = new_e; #endif /* Base class method call to print generic edge properties */ AuxEdge::updateElement(); QDomElement e = elem(); /** Save style that describes this edge only along with edge */ if ( isNotNullP( style())) { if ( 1 == style()->numItems()) { e.removeAttribute("style"); style()->writeElement( e, false); } else { e.setAttribute("style", style()->name()); } } }
QPainterPath EdgeItem::shape() const { QPainterPath path( srcP); QPainterPathStroker stroker; if ( srcP == dstP) return path; if ( edge()->isSelf()) { path = selfEdgePath(); } else { path.cubicTo( cp1, cp2, dstP); } if ( isNotNullP( edge()->style())) { stroker.setWidth( edge()->style()->pen().width() + 1); } else { stroker.setWidth( 2); } return stroker.createStroke( path); }
GEdge::~GEdge() { graph()->invalidateRanking(); item()->remove(); graph()->view()->deleteLaterEdgeItem( item()); if ( isNotNullP( _style)) _style->decNumItems(); }
/** * Add an edge to this node in specified direction */ void Node::addEdgeInDir( Edge *edge, GraphDir dir) { graphassert( isNotNullP( edge)); EdgeListItem *it = edge->getNodeIt( revDir( dir)); it->attach( edges[ dir]); edges[ dir] = it; }
/** * Test configuration and options parsing */ bool uTestConf() { Conf *conf = new Conf(); /** Create some example options */ conf->addOption( new Option( OPT_STRING, "o", "output", "output file name( string option example)")); conf->addOption( new Option( OPT_BOOL, "b", "boolean", "boolean option example")); conf->addOption( new Option( OPT_INT, "i", "integer", "integer option example")); conf->addOption( new Option( OPT_FLOAT, "f", "float", "float option example")); conf->printOpts(); // Print them to console /** Check that created options can be accessed */ assert( isNullP( conf->option( "file"))); assert( isNotNullP( conf->option("output"))); assert( isNotNullP( conf->shortOption( "o"))); assert( isNullP( conf->shortOption( "output"))); assert( isNotNullP( conf->longOption("output"))); /** Create array of arguments */ char *args[ 8]; args[ 0] = (char*)"string";// treated args[ 1] = (char*)"--output"; args[ 2] = (char*)"file"; args[ 3] = (char*)"-a"; args[ 4] = (char*)"--b"; args[ 5] = (char*)"-b"; args[ 6] = (char*)"-i"; args[ 7] = (char*)"80"; /** Read arguments from array and parse them */ conf->readArgs( 8, args); /** Check options values */ assert( conf->unknownOptsNum() == 2); // Check number of unknown arguments assert( !(conf->option( "output")->string().compare("file"))); Option *int_opt = conf->option( "integer"); assert( int_opt->isDefined()); assert( int_opt->intVal()== 80); assert( conf->option( "b")->isSet()); delete conf; return true; }
/** Make all styles of edges connected with edge control or label the same */ void GEdge::adjustStyles() { GNode* succ_n = succ(); while ( succ_n->isEdgeControl() || succ_n->isEdgeLabel()) { assert( isNotNullP( succ_n->firstSucc())); succ_n->firstSucc()->setStyle( style()); succ_n = succ_n->firstSucc()->succ(); } GNode* pred_n = pred(); while ( pred_n->isEdgeControl() || pred_n->isEdgeLabel()) { assert( isNotNullP( pred_n->firstPred())); pred_n->firstPred()->setStyle( style()); pred_n = pred_n->firstPred()->pred(); } }
/** * delete edge pointed by iterator in specidied direction */ void Node::deleteEdgeInDir( GraphDir dir, EdgeListItem* it) { graphassert( isNotNullP( it)); if( edges[ dir] == it) { edges[ dir] = it->next(); } if( e_it[ dir] == it) { e_it[ dir] = it->next(); } it->detach(); }
void CFNode< MdesType>::toStream(ostream& os) { /* Begin with node header */ os << "CF Node " << this->id(); /* Print node start/stop property */ if ( this->isStart() ) { os << " Start"; } else if ( this->isStop() ) { os << " Stop"; } /* Node header done */ os << endl; /* Iterating over predecessors */ for ( typename CFNode< MdesType>::Pred pred_iter = this->predsBegin(), pred_iter_end = this->predsEnd(); pred_iter != pred_iter_end; pred_iter++ ) { CFEdge< MdesType> *edge = *pred_iter; os << *edge; } /* Print all operations */ for ( Operation< MdesType> * oper = firstOper(); isNotNullP( oper); oper = oper->nextOper() ) { os << oper; if ( areEqP( oper, lastOper()) ) break; } /* Iterating over successors */ for ( typename CFNode< MdesType>::Succ succ_iter = this->succsBegin(), succ_iter_end = this->succsEnd(); succ_iter != succ_iter_end; ++succ_iter ) { CFEdge< MdesType> *edge = *succ_iter; os << *edge; } }
/** Destructor */ GGraph::~GGraph() { freeMarker( nodeTextIsShown); for ( GNode *node = firstNode(); isNotNullP( node); ) { GNode* next = node->nextNode(); int ir_id = node->irId(); deleteNode( node); node = next; } foreach ( GStyle *style, styles) { delete style; } }
void CFEdge< MdesType>::toStream(ostream& os) { os << "CF Edge " << this->id() << ": "; os << this->pred()->id() << "->" << this->succ()->id(); Operation< MdesType> *src = this->srcOper(); if ( isNotNullP( src) ) { os << ", src: " << src->id() << " "<< src->nameStr(); } else { os << ", fallthrough"; } os << endl; }
void CFNode<MdesType>::prepend( Operation<MdesType> *oper) { IR_ASSERTD( isNotNullP( oper)); if ( isNullP( first)) { IR_ASSERTD( isNullP( last)); // Node must be empty if there is no last operation oper->detachFromSeq(); first = oper; last = oper; } else { oper->insertBefore( first); first = oper; } oper->setNode( this); }
Numeration CFG<MdesType>::makeTopologicalNumeration() { /** * The algorithm makes an RPO numeration of nodes by * doing the depth-first search on the CFG and assigning numbers * to a node AFTER all successors of the node have been visited. */ Marker m = MarkerManager::newMarker(); Numeration num = NumManager::newNum(); GraphNum i = this->numNodes() - 1; /* * We use while loop instead of recursive implementation just to show off :) * So we will need a stack for saving temporary values. We save the edge to * be processed on the stack. If the edge is last unprocessed successor of some node * than node is considered done and a number is assigned to it. */ std::list< CFEdge< MdesType> *> stack; if ( isNotNullP( this->startNode()->firstSucc()) ) { stack.push_back( this->startNode()->firstSucc()); this->startNode()->mark( m); this->startNode()->firstSucc()->succ()->mark( m); while ( stack.size() != 0) { CFEdge< MdesType> *edge = stack.back(); /* * Add next succ to the stack, if it needs to be processed */ if ( isNotNullP( edge->nextSucc()) ) { CFEdge< MdesType> *succ = edge->nextSucc(); stack.pop_back(); while ( isNotNullP( succ)) { if ( !succ->succ()->isMarked( m)) { break; } else if ( isNullP( succ->nextSucc()) ) { succ->mark( m); break; } succ = succ->nextSucc(); } if ( isNotNullP( succ)) { stack.push_back( edge->nextSucc()); edge->nextSucc()->succ()->mark( m); } } /* * Check if the predecessor node is done. I.e. the current edge * is already processed and it is the last successor edge */ if ( edge->isMarked( m) && isNullP( edge->nextSucc()) ) { CFNode< MdesType> *pred = edge->pred(); pred->setNumber( num, i); IR_ASSERTD( pred->isMarked( m)); //cout << "RPO trav " << pred->id() << " is numbered " << i << endl; i--; stack.pop_back(); continue; } /** Add all successor edges of successor node to the stack */ bool succ_found = false; CFEdge< MdesType> *succ = edge->succ()->firstSucc(); while ( isNotNullP( succ)) { CFNode< MdesType> *succ_node = succ->succ(); if ( !succ_node->isMarked( m) ) { succ_node->mark( m); stack.push_back( succ); succ_found = true; break; } succ = succ->nextSucc(); } if ( !succ_found) { CFNode< MdesType> * succ = edge->succ(); succ->setNumber( num, i); IR_ASSERTD( succ->isMarked( m)); //cout << "RPO trav " << succ->id() << " is numbered " << i << endl; i--; } edge->mark( m); } } /* Number the rest of CFG nodes */ for ( CFNode< MdesType> *node = this->firstNode(); isNotNullP( node); node = node->nextNode() ) { //cout << "Checking " << node->id() << " " << ( node->isMarked( m)? "marked": "non-marked") << endl; if ( !node->isMarked( m) ) { node->setNumber( num, i); //cout << "RPO trav " << node->id() << " is numbered " << i << endl; i--; } } this->freeMarker( m); return num; }
/** * Constructor of group from a node. * Coordinates are computed with respect to pass direction */ NodeGroup::NodeGroup( AuxNode *n, // Parent node GraphDir dir, // Pass direction bool first_pass) // If this is the first run : node_list() { init(); addNode( n); /** Compute coordinates */ double sum = 0; unsigned int num_peers = 0; /** * On descending pass we compute center coordinate with respect to coordinates of predecessors, * on ascending - we look at successors */ GraphDir rdir = RevDir( dir); for ( AuxEdge* e = n->firstEdgeInDir( rdir); isNotNullP( e); e = e->nextEdgeInDir( rdir)) { if ( !e->isInverted()) { if ( !e->node( rdir)->isForPlacement()) continue; num_peers++; if ( e->node( rdir)->isEdgeLabel()) { sum+= ( e->node( rdir)->modelX()); } else { sum+= ( e->node( rdir)->modelX() + ( e->node( rdir)->width() / 2)); } } } for ( AuxEdge* e = n->firstEdgeInDir( dir); isNotNullP( e); e = e->nextEdgeInDir( dir)) { if ( e->isInverted()) { if ( !e->node( dir)->isForPlacement()) continue; num_peers++; if ( e->node( dir)->isEdgeLabel()) { sum+= ( e->node( dir)->modelX()); } else { sum+= ( e->node( dir)->modelX() + ( e->node( dir)->width() / 2)); } } } /** Barycenter heuristic */ double center = 0; edge_num = 1; if ( num_peers > 0) { edge_num = num_peers; center = sum / num_peers; } else if ( !first_pass) { edge_num = 1; center = n->modelX() + n->width() / 2; } if ( n->isEdgeLabel()) center += ( n->width() / 2); if ( n->isStable()) { center = n->modelX() + n->width() / 2; } n->setBc( center); barycenter = center; border_left = center - n->width() / 2; border_right = center + n->width() / 2; }
void TestParser::endNode() { ASSERTD( isNotNullP( curr_node)); curr_node->doc()->setPlainText( node_text); }
void EdgeItem::adjust() { prepareGeometryChange(); if ( edge()->pred()->item()->isVisible() && edge()->succ()->item()->isVisible()) { setVisible( true); } else { setVisible( false); return; } if ( edge()->isSelf()) { QPointF center = mapFromItem( pred()->item(), pred()->item()->borderRect().center()); QRectF r = pred()->item()->borderRect(); srcP = center + QPointF( 3 * r.width()/8, r.height() /2); dstP = center + QPointF( 3 * r.width()/8, -r.height() /2); topLeft = center + QPointF( 3 * r.width()/8, -r.height()/2 - SE_VERT_MARGIN); cp1 = center + QPointF( (r.width() / 2) + SE_HOR_MARGIN, 0); btmRight = cp1 + QPointF( 0, r.height()/2 + SE_VERT_MARGIN); update(); return; } srcP = mapFromItem( pred()->item(), pred()->item()->boundingRect().center()); dstP = mapFromItem( succ()->item(), succ()->item()->boundingRect().center()); topLeft = srcP; btmRight = dstP; QPointF srcCP = srcP; QPointF dstCP = dstP; if ( pred()->isEdgeLabel()) { srcP = mapFromItem( pred()->item(), pred()->item()->borderRect().left(), pred()->item()->borderRect().center().y()); qreal w = pred()->item()->borderRect().width(); //srcP += QPointF( -w, 0); srcCP = srcP; } if ( succ()->isEdgeLabel()) { dstP = mapFromItem( succ()->item(), succ()->item()->borderRect().left(), succ()->item()->borderRect().center().y()); dstCP = dstP; } if ( pred()->isSimple()) { QLineF line( srcP, dstP); QPolygonF endPolygon = mapFromItem( pred()->item(), pred()->item()->shape().toFillPolygon()); QPointF p1 = endPolygon.first(); QPointF p2; QPointF intersectPoint; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect( line, &srcP); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } } if ( succ()->isSimple()) { QLineF line2( srcP, dstP); QPolygonF endPolygon = mapFromItem( succ()->item(), succ()->item()->shape().toFillPolygon()); QPointF p1 = endPolygon.first();; QPointF p2; QLineF polyLine; for ( int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect( line2, &dstP); if ( intersectType == QLineF::BoundedIntersection) break; p1 = p2; } } topLeft.setX( min< qreal>( srcP.x(), dstP.x())); topLeft.setY( min< qreal>( srcP.y(), dstP.y())); btmRight.setX( max< qreal>( srcP.x(), dstP.x())); btmRight.setY( max< qreal>( srcP.y(), dstP.y())); QLineF mainLine = QLineF( srcP, dstP); if ( mainLine.length() < 1) return; qreal size = abs< qreal>(( min< qreal>( abs< qreal>( mainLine.dx()), abs< qreal>( mainLine.dy())))); //Stub if( size < 2* EdgeControlSize) { size = 2* EdgeControlSize; } if( size > 20 * EdgeControlSize) { size = 20 * EdgeControlSize; } NodeItem *next_pred = NULL; NodeItem *next_succ = NULL; if ( ( pred()->isEdgeControl() || pred()->isEdgeLabel()) && isNotNullP( pred()->firstPred())) { next_pred = pred()->firstPred()->pred()->item(); } if ( ( succ()->isEdgeControl() || succ()->isEdgeLabel()) && isNotNullP( succ()->firstSucc())) { next_succ = succ()->firstSucc()->succ()->item(); } /** Place cp1 */ if ( isNotNullP( next_pred)) { QPointF p1 = mapFromItem( next_pred, next_pred->borderRect().center()); QLineF line( p1, dstCP); QPointF cp1_offset = QPointF( (line.dx() * size)/ line.length(), (line.dy() * size)/ line.length()); cp1 = srcP + cp1_offset; } else { QPointF cp1_offset = QPointF( (mainLine.dx() * size)/ mainLine.length(), (mainLine.dy() * size)/ mainLine.length()); cp1 = srcP + cp1_offset; } topLeft.setX( min< qreal>( topLeft.x(), cp1.x())); topLeft.setY( min< qreal>( topLeft.y(), cp1.y())); btmRight.setX( max< qreal>( btmRight.x(), cp1.x())); btmRight.setY( max< qreal>( btmRight.y(), cp1.y())); /** Place cp2 */ if ( isNotNullP( next_succ)) { QPointF p2 = mapFromItem( next_succ, next_succ->borderRect().center()); QLineF line( p2, srcCP); QPointF cp2_offset = QPointF( (line.dx() * size)/ line.length(), (line.dy() * size)/ line.length()); cp2 = dstP + cp2_offset; } else { QPointF cp2_offset = QPointF( -(mainLine.dx() * size)/ mainLine.length(), -(mainLine.dy() * size)/ mainLine.length()); cp2 = dstP + cp2_offset; } topLeft.setX( min< qreal>( topLeft.x(), cp2.x())); topLeft.setY( min< qreal>( topLeft.y(), cp2.y())); btmRight.setX( max< qreal>( btmRight.x(), cp2.x())); btmRight.setY( max< qreal>( btmRight.y(), cp2.y())); update(); }
void TestParser::parseLineGCC( QString line) { QString n_str("Node "); QString e_str("Edge "); /** Node recognition */ QRegExp node_rx("^;; Start of basic block"); QRegExp preds_rx("^;; Pred edge "); QRegExp succs_rx("^;; Succ edge "); QTextStream stream( stdout); /** Expression recognition */ int pos = 0; if ( preds_rx.indexIn( line) == 0) { int index = preds_rx.matchedLength(); QRegExp num_rx(" (\\d+)"); while ( ( index = num_rx.indexIn( line, index) )!= -1) { index += num_rx.matchedLength(); assert( isNotNullP( curr_node)); int pred_num = num_rx.cap(1).toInt(); QString name = QString("%1->%2") .arg( pred_num) .arg( curr_node->irId()); QString pred_name = QString("Node %1").arg( pred_num); QString succ_name = QString("Node %1").arg( curr_node->irId()); /** Add edge to symtab */ if ( symtab.find( name) == symtab.end() && symtab.find( pred_name) != symtab.end() && symtab.find( succ_name) != symtab.end()) { SymEdge *edge = new SymEdge( name); edge->setPred( pred_name); edge->setSucc( succ_name); symtab[ name] = edge; /** Add edge to graph */ GNode* pred = static_cast< SymNode *>( symtab[ pred_name])->node(); GNode* succ = static_cast< SymNode *>( symtab[ succ_name])->node(); GEdge* e = graph->graph()->newEdge( pred, succ); #ifdef _DEBUG //stream << name << ": " << pred_name << "->" << succ_name << endl; #endif } } } else if ( succs_rx.indexIn( line) == 0) { int index = succs_rx.matchedLength(); QRegExp num_rx(" (\\d+)"); while ( ( index = num_rx.indexIn( line, index) )!= -1) { index += num_rx.matchedLength(); assert( isNotNullP( curr_node)); int pred_num = num_rx.cap(1).toInt(); QString name = QString("%1->%2") .arg( curr_node->irId()) .arg( pred_num); QString pred_name = QString("Node %1").arg( curr_node->irId()); QString succ_name = QString("Node %1").arg( pred_num); /** Add edge to symtab */ if ( symtab.find( name) == symtab.end() && symtab.find( pred_name) != symtab.end() && symtab.find( succ_name) != symtab.end()) { SymEdge *edge = new SymEdge( name); edge->setPred( pred_name); edge->setSucc( succ_name); symtab[ name] = edge; /** Add edge to graph */ GNode* pred = static_cast< SymNode *>( symtab[ pred_name])->node(); GNode* succ = static_cast< SymNode *>( symtab[ succ_name])->node(); GEdge* e = graph->graph()->newEdge( pred, succ); #ifdef _DEBUG //stream << name << ": " << pred_name << "->" << succ_name << endl; #endif } } } else if ( node_rx.indexIn( line) != -1 ) { QRegExp num_rx("-> (\\d+)"); if ( num_rx.indexIn( line) != -1) { bool good_id = false; int ir_id = num_rx.cap(1).toInt( &good_id); QString text = QString("Block ").append( num_rx.cap(1)); QString name = n_str.append( num_rx.cap(1)); /** Add node to symtab */ if ( symtab.find( name ) == symtab.end()) { SymNode* node = new SymNode( name); curr_node = static_cast<CFNode *>( graph->graph()->newNode()); curr_node->setDoc( new QTextDocument()); node->setNode( curr_node); node->node()->item()->setPlainText( text); if ( good_id) { node->node()->setIRId( ir_id); } symtab[ name] = node; #ifdef _DEBUG //stream << name << endl; #endif } } } else { if ( !isStateNode()) setStateDefault(); } if ( isStateNode()) { node_text.append( line).append( "\n"); } }
void EdgeItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { if ( option->levelOfDetail < 0.1) return; /** Do not draw edges when adjacent nodes intersect */ QPolygonF pred_rect = mapFromItem( pred()->item(), pred()->item()->boundingRect()); QPolygonF succ_rect = mapFromItem( succ()->item(), succ()->item()->boundingRect()); if ( !succ_rect.intersected( pred_rect).isEmpty()) return; static const qreal spline_detail_level = 0.4; static const qreal draw_arrow_detail_level = 0.3; QPointF curr_point; QLineF line = QLineF(); curr_point = srcP; QPointF nextToDst = srcP; qreal opacity = min<qreal>( edge()->pred()->item()->opacityLevel(), edge()->succ()->item()->opacityLevel()); line.setP1( nextToDst); line.setP2( dstP); QPainterPath path( srcP); QPainterPathStroker stroker; stroker.setWidth( 0); if ( edge()->isSelf()) { path = selfEdgePath(); } else if ( option->levelOfDetail >= spline_detail_level) { path.cubicTo( cp1, cp2, dstP); } //path = stroker.createStroke(path); if ( nextToDst == dstP) return; //Set opacity if ( edge()->graph()->view()->isContext()) painter->setOpacity( opacity); QPen pen( option->palette.foreground().color(), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); if ( isNotNullP( edge()->style())) { pen = edge()->style()->pen(); } // Draw the line itself if ( option->levelOfDetail >= spline_detail_level) { if ( option->state & QStyle::State_Selected) { pen.setWidthF( pen.widthF() + 1); } } else { pen = QPen( pen.color(),1); } painter->setPen( pen); //Draw edge if ( edge()->isSelf() || option->levelOfDetail >= spline_detail_level) { painter->drawPath( path); } else { painter->drawLine( line); } // Draw the arrows if there's enough room and level of detail is appropriate if ( option->levelOfDetail >= draw_arrow_detail_level) { double angle = ::acos(line.dx() / line.length()); if ( line.dy() >= 0) angle = TwoPi - angle; QPointF destArrowP1; QPointF destArrowP2; /* NOTE: Qt::black can be replaced by option->palette.foreground().color() */ if ( isNotNullP( edge()->style())) { painter->setBrush( edge()->style()->pen().color()); } else { painter->setBrush(option->palette.foreground().color()); } if ( edge()->isSelf()) { angle = -2* Pi/3; } destArrowP1 = dstP + QPointF( sin(angle - Pi / 3) * arrowSize, cos(angle - Pi / 3) * arrowSize); destArrowP2 = dstP + QPointF( sin(angle - Pi + Pi / 3) * arrowSize, cos(angle - Pi + Pi / 3) * arrowSize); pen.setStyle( Qt::SolidLine); painter->setPen( pen); if ( succ()->isSimple()) { QPainterPath arrow_path; arrow_path.addPolygon( QPolygonF() << dstP << destArrowP1 << destArrowP2 << dstP); //path = path.united( arrow_path); painter->drawPolygon(QPolygonF() << dstP << destArrowP1 << destArrowP2); } } painter->setOpacity( 1); #ifdef SHOW_CONTROL_POINTS /** For illustrative purposes */ painter->setPen(QPen(Qt::gray, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin)); if ( !edge()->isSelf()) { painter->drawLine( srcP, dstP); painter->drawLine( srcP, cp1); painter->drawLine( cp2, dstP); } painter->setPen(QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( srcP); painter->setPen(QPen(Qt::blue, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( dstP); painter->setPen(QPen(Qt::green, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( cp1); #endif }
void EdgeItem::keyPressEvent(QKeyEvent *event) { int key = event->key(); GNode *n = NULL; GEdge *e = NULL; VEdge vedge( edge()); NavSector sector = edge()->graph()->nodeNavigationSector(); GNode *curr_node = edge()->graph()->nodeInFocus(); NodeNav node_nav( curr_node, sector); switch( key) { case Qt::Key_Up: if ( isNotNullP( curr_node) && ( sector == LEFT_SECTOR || sector == RIGHT_SECTOR)) { e = node_nav.edgeInDir( edge(), NAV_DIR_UP); } else { n = vedge.nodeUp(); } break; case Qt::Key_Down: if ( isNotNullP( curr_node) && ( sector == LEFT_SECTOR || sector == RIGHT_SECTOR) ) { e = node_nav.edgeInDir( edge(), NAV_DIR_DOWN); } else { n = vedge.nodeDown(); } break; case Qt::Key_Left: if ( isNotNullP( curr_node) && ( sector == TOP_SECTOR || sector == BOTTOM_SECTOR) ) { e = node_nav.edgeInDir( edge(), NAV_DIR_LEFT); } else { n = vedge.nodeLeft(); } break; case Qt::Key_Right: if ( isNotNullP( curr_node) && ( sector == TOP_SECTOR || sector == BOTTOM_SECTOR) ) { e = node_nav.edgeInDir( edge(), NAV_DIR_RIGHT); } else { n = vedge.nodeRight(); } break; default: break; } if ( isNotNullP( n)) { if ( edge()->graph()->view()->isContext()) { edge()->graph()->emptySelection(); edge()->graph()->selectNode( n); edge()->graph()->view()->findContext(); } edge()->graph()->view()->focusOnNode( n, true); scene()->clearFocus(); scene()->clearSelection(); n->item()->setFocus(); n->item()->setSelected( true); } else if ( isNotNullP( e)) { // Get focus on edge scene()->clearFocus(); scene()->clearSelection(); e->item()->setFocus(); e->item()->setSelected( true); } //QGraphicsItem::keyPressEvent( event); }
void TestParser::parseLineLLVM( QString line) { /** Node recognition */ QRegExp node_rx("^([^:]+):"); QRegExp preds_rx("; preds = "); QTextStream stream( stdout); /** Expression recognition */ int pos = 0; if ( node_rx.indexIn( line) != -1 ) { QString name = node_rx.cap(1); /** Add node to symtab */ if ( symtab.find( name ) == symtab.end()) { SymNode* node = new SymNode( name); curr_node = static_cast<CFNode *>( graph->graph()->newNode()); curr_node->setDoc( new QTextDocument()); node->setNode( curr_node); node->node()->item()->setPlainText( name); symtab[ name] = node; #ifdef _DEBUG //stream << name << endl; #endif } else { curr_node = static_cast< SymNode *>( symtab[ name])->node(); } } if ( preds_rx.indexIn( line) != -1) { int index = preds_rx.matchedLength(); QRegExp name_rx("%([^,]+),?"); while ( ( index = name_rx.indexIn( line, index) )!= -1) { index += name_rx.matchedLength(); assert( isNotNullP( curr_node)); QString pred_name = name_rx.cap(1); QString succ_name = curr_node->item()->toPlainText(); QString name = QString("%1->%2") .arg( pred_name) .arg( succ_name); if ( symtab.find( pred_name) == symtab.end()) { SymNode* node = new SymNode( pred_name); CFNode * pred_node = static_cast<CFNode *>( graph->graph()->newNode()); pred_node->setDoc( new QTextDocument()); node->setNode( pred_node); node->node()->item()->setPlainText( pred_name); symtab[ pred_name] = node; } /** Add edge to symtab */ if ( symtab.find( name) == symtab.end() && symtab.find( pred_name) != symtab.end() && symtab.find( succ_name) != symtab.end()) { SymEdge *edge = new SymEdge( name); edge->setPred( pred_name); edge->setSucc( succ_name); symtab[ name] = edge; /** Add edge to graph */ GNode* pred = static_cast< SymNode *>( symtab[ pred_name])->node(); GNode* succ = static_cast< SymNode *>( symtab[ succ_name])->node(); GEdge* e = graph->graph()->newEdge( pred, succ); #ifdef _DEBUG //stream << name << ": " << pred_name << "->" << succ_name << endl; #endif } } } if ( !isStateNode()) setStateDefault(); if ( isStateNode()) { node_text.append( line).append( "\n"); } }