00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "graph.h"
00021 #include "edge.h"
00022 #include "node.h"
00023 #include "NodeItem.h"
00024 #include "graphDocument.h"
00025 #include "DynamicPropertiesList.h"
00026 #include <QListIterator>
00027 #include <QHashIterator>
00028 #include <QMapIterator>
00029 #include <QByteArray>
00030 #include <QStringList>
00031 #include <QInputDialog>
00032 #include <KDebug>
00033 #include <QColor>
00034
00035 Graph::Graph( GraphDocument* parent ) : QObject( parent )
00036 {
00037 _directed = true;
00038 _automate = false;
00039 _readOnly = false;
00040 _document = parent;
00041 _listbox = 0;
00042 _begin = 0;
00043 calcRelativeCenter();
00044 _nodeDefaultColor = "blue";
00045 _edgeDefaultColor = "gray";
00046 _nodeNamesVisible = true;
00047 _nodeValuesVisible = true;
00048 _edgeNamesVisible = false;
00049 _edgeValuesVisible = true;
00050 }
00051
00052 Graph::~Graph()
00053 {
00054 foreach( Edge * e, _edges )
00055 {
00056 remove( e );
00057 }
00058
00059 foreach( Node * n, _nodes )
00060 {
00061 remove( n );
00062 }
00063 }
00064
00065 GraphDocument* Graph::document() const
00066 {
00067 return _document;
00068 }
00069
00070 void Graph::remove()
00071 {
00072 _document->removeOne( this );
00073 delete this;
00074 }
00075
00076 QList<Node*> Graph::nodes() const
00077 {
00078 return _nodes;
00079 }
00080
00081 QList<Edge*> Graph::edges() const
00082 {
00083 return _edges;
00084 }
00085
00086 void Graph::setNodesColor( QString c )
00087 {
00088 kDebug() << "Entrou no setNodesColor, com a cor " << c;
00089 foreach( Node * n, _nodes )
00090 {
00091 n->setColor( c );
00092 }
00093 }
00094
00095 void Graph::setEdgesColor( QString c )
00096 {
00097 kDebug() << "Entrou no setEdgesColor, com a cor " << c;
00098 foreach( Edge * e, _edges )
00099 {
00100 e->setColor( c );
00101 }
00102 }
00103
00104 void Graph::setKCB( KComboBox* list )
00105 {
00106 _listbox = list;
00107 }
00108
00109 Node* Graph::addNode( QString name )
00110 {
00111 if( _readOnly ) return 0;
00112
00113 Node* n = new Node( this );
00114 n->setName( name );
00115 _nodes.append( n );
00116 emit nodeCreated( n );
00117 connect( n, SIGNAL( changed() ), this, SIGNAL( changed() ) );
00118 return n;
00119 }
00120
00121 void Graph::addNode( QString name, QPointF pos )
00122 {
00123 Node* node = addNode( name );
00124 node->setPos( pos.x(), pos.y() );
00125 }
00126
00127 void Graph::addNode( QString name, QString type )
00128 {
00129 Node* node = addNode( name );
00130 QString key;
00131 node->setName( name );
00132 node->hideValue( false );
00133 node->setWidth( 0.5 );
00134 node->setType( type );
00135 if( _listbox == 0 )
00136 {
00137 emit iAmDisappoint();
00138 return;
00139 }
00140 if( type == "if" )
00141 {
00142 node->setValue( QVariant( "true" ) );
00143 node->hideValue( true );
00144 node->setValueHeader( "Test" );
00145 node->setMaxOutEdges( 2 );
00146 }
00147 QMap<QString, QVariant> nodelist;
00148 if( _listbox->isVisible() )
00149 {
00150 nodelist = _listbox->itemData( _listbox->currentIndex() ).toMap();
00151 }
00152 else
00153 {
00154 nodelist = _listbox->itemData( _listbox->findText( type ) ).toMap();
00155 }
00156 node->setIcon( nodelist["nodetypesvg"].toString() );
00157 QMapIterator<QString, QVariant> i( nodelist );
00158 while( i.hasNext() )
00159 {
00160 key = i.next().key();
00161 if( key != "nodetypesvg" )
00162 {
00163 node->addDynamicProperty( key, nodelist[key] );
00164 }
00165 }
00166 connect( this, SIGNAL( forceUpdate() ), node, SIGNAL( changed() ) );
00167 emit forceUpdate();
00168 }
00169
00170 void Graph::addNode( QString name, QPointF pos, QString type )
00171 {
00172 Node* node = addNode( name );
00173 QString key;
00174 node->setPos( pos.x(), pos.y() );
00175 node->setName( name );
00176 node->hideValue( false );
00177 node->setWidth( 0.5 );
00178 node->setType( type );
00179 if( _listbox == 0 )
00180 {
00181 emit iAmDisappoint();
00182 return;
00183 }
00184 if( type == "if" )
00185 {
00186 node->setValue( QVariant( "true" ) );
00187 node->hideValue( true );
00188 node->setValueHeader( "Test" );
00189 node->setMaxOutEdges( 2 );
00190 }
00191 QMap<QString, QVariant> nodelist;
00192 if( _listbox->isVisible() )
00193 {
00194 nodelist = _listbox->itemData( _listbox->currentIndex() ).toMap();
00195 }
00196 else
00197 {
00198 nodelist = _listbox->itemData( _listbox->findText( type ) ).toMap();
00199 }
00200 node->setIcon( nodelist["nodetypesvg"].toString() );
00201 QMapIterator<QString, QVariant> i( nodelist );
00202 while( i.hasNext() )
00203 {
00204 key = i.next().key();
00205 if( key != "nodetypesvg" )
00206 {
00207 node->addDynamicProperty( key, nodelist[key] );
00208 }
00209 }
00210 connect( this, SIGNAL( forceUpdate() ), node, SIGNAL( changed() ) );
00211 emit forceUpdate();
00212 }
00213
00214 Edge* Graph::addEdge( Node* from, Node* to, QGraphicsSvgItem* cFrom, QGraphicsSvgItem* cTo )
00215 {
00216 if( _readOnly ) return 0;
00217
00218 if( from == 0 || to == 0 )
00219 {
00220 return 0;
00221 }
00222
00223
00224 if(( from == to ) && ( !_directed ) )
00225 {
00226 return 0;
00227 }
00228 else if(( from->edges( to ).size() >= 1 ) && ( !_directed ) )
00229 {
00230 return 0;
00231 }
00232 else if(( _nodes.indexOf( from ) == -1 ) || ( _nodes.indexOf( to ) == -1 ) )
00233 {
00234 return 0;
00235 }
00236 else if( from->outEdgesCapacityReached() || to->inEdgesCapacityReached() )
00237 {
00238 emit iAmDisappoint();
00239 return 0;
00240 }
00241 else if( !connectionIsValid( true, cFrom ) || !connectionIsValid( false, cTo ) )
00242 {
00243 emit iAmDisappoint();
00244 return 0;
00245 }
00246 else if(( from == to ) && ( from->selfEdgesCapacityReached() ) )
00247 {
00248 emit iAmDisappoint();
00249 return 0;
00250 }
00251
00252 Edge* e = new Edge( this, from, to, cFrom, cTo );
00253
00254
00255
00256
00257 _edges.append( e );
00258 emit edgeCreated( e );
00259 connect( e, SIGNAL( changed() ), this, SIGNAL( changed() ) );
00260 emit forceUpdate();
00261 return e;
00262 }
00263
00264 bool Graph::connectionIsValid( bool direction, QGraphicsSvgItem* svg )
00265 {
00266 QHashIterator<QString, QGraphicsSvgItem*> iterator( qgraphicsitem_cast<NodeItem*>( svg->parentItem() )->connectors() );
00267 QString key;
00268 QListIterator<QByteArray> plist = qgraphicsitem_cast<NodeItem*>( svg->parentItem() )->node()->dynamicPropertyNames();
00269
00270 foreach( Edge * e, _edges )
00271 {
00272 if( direction == true )
00273 {
00274 if( e->connectorFrom() == svg )
00275 {
00276 return false;
00277 }
00278 }
00279 else
00280 {
00281 if( e->connectorTo() == svg )
00282 {
00283 return false;
00284 }
00285 }
00286 }
00287 if( direction == true )
00288 {
00289 while( iterator.hasNext() )
00290 {
00291 if( iterator.next().value() == svg )
00292 {
00293 key = iterator.key();
00294 while( plist.hasNext() )
00295 {
00296 if( plist.next() == key )
00297 {
00298 if( qgraphicsitem_cast<NodeItem*>( svg->parentItem() )->node()->property( key.toUtf8().data() ) == "in" ) return false;
00299 }
00300 }
00301 }
00302 }
00303 }
00304 else
00305 {
00306 while( iterator.hasNext() )
00307 {
00308 if( iterator.next().value() == svg )
00309 {
00310 key = iterator.key();
00311 while( plist.hasNext() )
00312 {
00313 if( plist.next() == key )
00314 {
00315 if( qgraphicsitem_cast<NodeItem*>( svg->parentItem() )->node()->property( key.toUtf8().data() ) == "out" ) return false;
00316 }
00317 }
00318 }
00319 }
00320 }
00321 return true;
00322 }
00323
00324 bool Graph::assignEdgeAction( Node* from, Edge* edge )
00325 {
00326 QListIterator<QByteArray> plist = from->dynamicPropertyNames();
00327 QListIterator<Edge*> elist = from->out_edges();
00328 QStringList middleman;
00329 QString temp;
00330 bool safe;
00331 bool okPressed;
00332 QString selectedProperty;
00333 if( !plist.hasNext() )
00334 {
00335 iAmDisappoint();
00336 return false;
00337 }
00338 else
00339 {
00340 while( plist.hasNext() )
00341 {
00342 safe = true;
00343 temp = QString( plist.next().data() );
00344 while( elist.hasNext() )
00345 {
00346 if( elist.next()->value() == temp )
00347 {
00348 safe = false;
00349 }
00350 }
00351 elist.toFront();
00352 if( safe )
00353 {
00354 middleman << temp;
00355 }
00356 }
00357 selectedProperty = QInputDialog::getItem( 0, "Select Action to Associate to:", "Select Action:", middleman, 0, false, &okPressed );
00358 }
00359 if( !okPressed )
00360 {
00361 return false;
00362 }
00363 else
00364 {
00365 edge->setValue( selectedProperty );
00366 return true;
00367 }
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 bool Graph::directed() const
00396 {
00397 return _directed;
00398 }
00399
00400 Node* Graph::node( const QString& name )
00401 {
00402 QString tmpName;
00403 foreach( Node * n, _nodes )
00404 {
00405 tmpName = n->name();
00406 if( tmpName == name )
00407 {
00408 return n;
00409 }
00410 }
00411 return 0;
00412 }
00413
00414 void Graph::remove( Node* n )
00415 {
00416 _nodes.removeOne( n );
00417 n->deleteLater();
00418 emit forceUpdate();
00419 }
00420
00421 void Graph::remove( Edge* e )
00422 {
00423 _edges.removeOne( e );
00424 delete e;
00425 emit forceUpdate();
00426 }
00427
00428 void Graph::setDirected( bool directed )
00429 {
00430
00431 foreach( Node * n1, _nodes )
00432 {
00433 foreach( Node * n2, n1->adjacent_nodes() )
00434 {
00435
00436 if(( n1->edges( n2 ).size() == 1 ) && ( n1 != n2 ) )
00437 {
00438 continue;
00439 }
00440
00441 QList<Edge*> listEdges = n1->edges( n2 );
00442 if( n1 != n2 )
00443 {
00444 listEdges.removeFirst();
00445 }
00446
00447 foreach( Edge * e, listEdges )
00448 {
00449 remove( e );
00450 }
00451 }
00452 }
00453 emit forceUpdate();
00454 _directed = directed;
00455 emit complexityChanged( directed );
00456 return;
00457 }
00458
00459 void Graph::calcRelativeCenter()
00460 {
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00475 if( parent() != 0 )
00476 {
00477 GraphDocument* gd = qobject_cast<GraphDocument*>( parent() );
00478 _relativeCenter.setY( gd->height() / 2 );
00479 _relativeCenter.setX( gd->width() / 2 );
00480 }
00481 else
00482 {
00483 _relativeCenter.setY( 0 );
00484 _relativeCenter.setX( 0 );
00485 }
00486 }
00487
00488 QPointF Graph::relativeCenter() const
00489 {
00490 return _relativeCenter;
00491 }
00492
00493 const QString& Graph::name() const
00494 {
00495 return _name;
00496 }
00497 void Graph::setName( const QString& s )
00498 {
00499 _name = s;
00500 }
00501
00502 bool Graph::setBegin( Node* n )
00503 {
00504 if( !n )
00505 {
00506 _begin = 0;
00507 return false;
00508 }
00509
00510 if( !_begin )
00511 {
00512 _begin = n;
00513 return true;
00514 }
00515 else if( _begin == n )
00516 {
00517 return false;
00518 }
00519
00520 _begin->setBegin( false );
00521 _begin = n;
00522 return true;
00523 }
00524
00525 Node* Graph::begin() const
00526 {
00527 return _begin;
00528 }
00529
00530 Node* Graph::addEnd( Node* n )
00531 {
00532 _ends.append( n );
00533 return n;
00534 }
00535
00536 void Graph::removeEnd( Node* n )
00537 {
00538 _ends.removeAll( n );
00539 }
00540
00541 void Graph::setNodeDefaultColor( const QString& color )
00542 {
00543 kDebug() << "Entrou com cor aqui painho." << color;
00544 _nodeDefaultColor = color;
00545 }
00546
00547 const QString& Graph::nodeDefaultColor() const
00548 {
00549 return _nodeDefaultColor;
00550 }
00551
00552 void Graph::setEdgeDefaultColor( const QString& color )
00553 {
00554 _edgeDefaultColor = color;
00555 }
00556 const QString& Graph::edgeDefaultColor() const
00557 {
00558 return _edgeDefaultColor;
00559 }
00560
00561 void Graph::setAutomate( bool b )
00562 {
00563 _automate = b;
00564 emit automateChanged( b );
00565 }
00566 bool Graph::automate()
00567 {
00568 return _automate;
00569 }
00570
00571 void Graph::addDynamicProperty( QString property, QVariant value )
00572 {
00573 this->setProperty( property.toUtf8(), value );
00574 if( value.isValid() )
00575 {
00576 DynamicPropertiesList::New()->addProperty( this, property );
00577 }
00578 }
00579
00580 void Graph::removeDynamicProperty( QString property )
00581 {
00582 this->addDynamicProperty( property, QVariant::Invalid );
00583 DynamicPropertiesList::New()->removeProperty( this, property );
00584 }
00585
00586 void Graph::addNodesDynamicProperty( QString property, QVariant value )
00587 {
00588 foreach( Node * n, _nodes )
00589 {
00590 n->addDynamicProperty( property, value );
00591 }
00592 }
00593
00594 void Graph::addEdgesDynamicProperty( QString property, QVariant value )
00595 {
00596 foreach( Edge * e, _edges )
00597 {
00598 e->addDynamicProperty( property, value );
00599 }
00600 }
00601
00602 void Graph::removeNodesDynamicProperty( QString property )
00603 {
00604 foreach( Node * n, _nodes )
00605 {
00606 n->removeDynamicProperty( property );
00607 }
00608 }
00609 void Graph::removeEdgesDynamicProperty( QString property )
00610 {
00611 foreach( Edge * e, _edges )
00612 {
00613 e->removeDynamicProperty( property );
00614 }
00615 }
00616
00617 void Graph::setNodeNameVisibility( bool b )
00618 {
00619 _nodeNamesVisible = b;
00620 foreach( Node * n, _nodes )
00621 {
00622 n->hideName( b );
00623 }
00624 }
00625
00626 bool Graph::nodeNameVisibility()
00627 {
00628 return _nodeNamesVisible;
00629 }
00630
00631 void Graph::setEdgeNameVisibility( bool b )
00632 {
00633 _edgeNamesVisible = b;
00634 foreach( Edge * n, _edges )
00635 {
00636 n->hideName( b );
00637 }
00638 }
00639
00640 bool Graph::edgeNameVisibility()
00641 {
00642 return _edgeNamesVisible;
00643 }
00644
00645 void Graph::setNodeValueVisibility( bool b )
00646 {
00647 _nodeValuesVisible = b;
00648 foreach( Node * n, _nodes )
00649 {
00650 n->hideValue( b );
00651 }
00652 }
00653 bool Graph::nodeValueVisibility()
00654 {
00655 return _nodeValuesVisible;
00656 }
00657
00658 void Graph::setEdgeValueVisibility( bool b )
00659 {
00660 _edgeValuesVisible = b;
00661 foreach( Edge * n, _edges )
00662 {
00663 n->hideValue( b );
00664 }
00665 }
00666
00667 bool Graph::edgeValueVisibility()
00668 {
00669 return _edgeValuesVisible;
00670 }