MetricsKiviat.cpp

Go to the documentation of this file.
00001 #include "rose.h"
00002 
00003 #include <cmath>
00004 
00005 #include <QListWidget>
00006 #include <QGraphicsRectItem>
00007 #include <QGraphicsTextItem>
00008 #include <QMouseEvent>
00009 #include <QFileInfo>
00010 #include <QAction>
00011 #include <QMenu>
00012 
00013 #include <QDebug>
00014 
00015 #include "MetricsKiviat.h"
00016 #include "Project.h"
00017 
00018 #include "SageMimeData.h"
00019 
00020 
00021 using namespace std;
00022 
00023 MetricsKiviat::MetricsKiviat( QWidget *parent )
00024    : KiviatView( parent, 0 ),
00025      metricsConfig( "MetricsKiviat", ProjectManager::instance()->getMetricsConfig( 0 ) )
00026 {
00027     connect( this, SIGNAL( clickedOnData( int ) ), SLOT( setActiveItem( int ) ) );
00028 
00029     connect( this, SIGNAL( clickedOnData( int ) ), SLOT( updateView( int ) ) );
00030 
00031     connect( &metricsConfig, SIGNAL( configChanged() ), this, SLOT( configChanged() ) );
00032     
00033     legend = scene.addRect( QRect()/*, QPen( Qt::NoPen )*/ );
00034     //legend->setBrush( QBrush( QColor( 255, 255, 255, 180 ) ) );
00035     //legend->setZValue( 100 );
00036     
00037     init( NULL );
00038 }
00039 
00040 MetricsKiviat::~MetricsKiviat()
00041 {
00042     delete legend;
00043     //delete metricsConfig;
00044     //qDeleteAll( legendText );
00045 }
00046 
00047 void MetricsKiviat::init( SgNode *root )
00048 {
00049     currentNode = root;
00050 
00051     setAxisCount( metricsConfig.getMetricsInfoCount() );
00052 
00053     addData( QVector<float>(axisCount, 0.0f ) );
00054 
00055     configureMetrics( false );
00056 }
00057 
00058 /*
00059 void MetricsKiviat::setRoot( SgNode *root )
00060 {
00061     currentNode = root;
00062     collector.traverse( root, 0 );
00063 
00064     MetricAttributeCollector::const_iterator it( collector.begin() );
00065 
00066     for(int index( 0 ); it != collector.end(); ++it, ++index )
00067     {
00068         //attributes.push_back( info( it->first, true, it->second.first, it->second.second ) );
00069         //attributes[index].kiviatID = index;
00070     }
00071     //setAxisCount( attributes.size() );
00072 
00073     addData( QVector<float>(axisCount, 0.0f ) );
00074 
00075     configureMetrics( false );
00076 }*/
00077 
00078 
00079 void MetricsKiviat::updateView( int id )
00080 {
00081     if( id >= 0 && id < nodes.size() )
00082         updateView( nodes[id] );
00083 }
00084 
00085 void MetricsKiviat::updateView( SgNode *astNode )
00086 {
00087     if( astNode == currentNode || astNode == NULL )
00088         return;
00089 
00090     drawData( astNode );
00091 
00092     currentNode = astNode;
00093 }
00094 
00095 void MetricsKiviat::addNode( SgNode *astNode )
00096 {
00097     if( nodes.indexOf( astNode ) != -1 || astNode == NULL )
00098         return;
00099 
00100     int id( nodes.size() );
00101     nodes.push_back( astNode );
00102 
00103     int h = ( id * 35 ) % 360;
00104     setDataColor( id, QColor::fromHsv( h, 255, 255 ) );
00105     addData( QVector<float>( axisCount, 0.0f ) );
00106 
00107     drawData( astNode );
00108 
00109     emit nodeActivatedAlt( astNode );
00110 
00111     currentNode = astNode;
00112 }
00113 
00114 void MetricsKiviat::delNode( SgNode *astNode )
00115 {
00116     int idx( nodes.indexOf( astNode ) );
00117 
00118     if( idx == -1 ) return;
00119 
00120     delNode( idx );
00121 }
00122 
00123 void MetricsKiviat::delNode( int nodeId )
00124 {
00125     removeData( nodeId );
00126     nodes.remove( nodeId );
00127 
00128     drawData( currentNode );
00129 }
00130 
00131 void MetricsKiviat::configureMetrics( bool dialog )
00132 {
00133     if( dialog )
00134     {
00135         metricsConfig.configureMultiple();
00136 
00137         setAxisCount( metricsConfig.getMetricsInfoCount() );
00138     }
00139 
00140     QString maxLabel( "" );
00141     for( MetricsConfig::iterator it( metricsConfig.begin() );
00142          it != metricsConfig.end();
00143          ++it )
00144     {
00145         setAxisLabel( it->listId, it->caption );
00146     }
00147     resizeEvent( NULL );
00148 
00149     drawData( currentNode );
00150 }
00151 
00152 void MetricsKiviat::resizeEvent( QResizeEvent *ev )
00153 {
00154     KiviatView::resizeEvent( ev );
00155 }
00156 
00157 void MetricsKiviat::mousePressEvent( QMouseEvent *ev )
00158 {
00159    KiviatView::mousePressEvent( ev );
00160 
00161    QGraphicsTextItem * item = dynamic_cast<QGraphicsTextItem*> ( itemAt( ev->pos() ) );
00162 
00163    if(item==NULL)
00164       return;
00165 
00166    for( int i = 1; i < legendText.size(); ++i )
00167    {
00168        if( legendText[i] == item )
00169        {
00170            if( i-1 < nodes.size() )
00171            {
00172                drawData( nodes[i-1] );
00173            }
00174            else
00175                drawData( currentNode );
00176            break;
00177        }
00178    }
00179 }
00180 
00181 void MetricsKiviat::drawData( SgNode *astNode )
00182 {
00183     if( astNode == NULL ) return;
00184 
00185     int nodesId( nodes.indexOf( astNode ) );
00186     int id( nodesId );
00187     QString maxLabel( "" );
00188 
00189     if( id == -1 )
00190     {
00191         id = nodes.size();
00192         setDataColor( id, Qt::blue );
00193     }
00194 
00195     setActiveItem( id );
00196 
00197     for( MetricsConfig::iterator it( metricsConfig.begin() );
00198          it != metricsConfig.end();
00199          ++it )
00200     {
00201         int axisId = it->listId;
00202         const QString& metricName( it.name() );
00203 
00204         setDataPoint( nodes.size(), axisId, 0.0f );
00205 
00206         if( it->caption.length() > maxLabel.length() )
00207             maxLabel = it->caption;
00208 
00209         double newValue = it->eval( astNode, metricName );
00210 
00211         setDataPoint( id, axisId, (float)newValue );
00212         setToolTip( id, axisId, QString( "Relative Value: %1\n").arg( newValue ) +
00213                                 //QString( "Absolute Value: %1\n").arg( value ) +
00214                                 QString( "Minimum Value : %1\n").arg( it->minValue ) +
00215                                 QString( "Maximum Value : %1").arg( it->maxValue ) );
00216     }
00217 
00218     qDeleteAll( legendText );
00219     legendText.clear();
00220     qDeleteAll( legendColor );
00221     legendColor.clear();
00222 
00223     QGraphicsTextItem *text;
00224     QFont highlightFont( labelFont );
00225     highlightFont.setBold( true );
00226     highlightFont.setItalic( true );
00227 
00228     int height( labelFont.pointSize() + labelFont.pointSize()*0.8 );
00229     if( nodesId == -1 )
00230     {
00231         height = height * (nodes.size() + 1 );
00232     }
00233     else
00234     {
00235         height = height * nodes.size();
00236     }
00237 
00238     height += 2 * labelFont.pointSize();
00239 
00240     QFontMetrics metric( labelFont );
00241 
00242     const QPointF newPos( AXIS_LENGTH + metric.width( maxLabel ) + 25.0f,
00243                           -height/2 );
00244     legend->setPos( newPos );
00245 
00246     QFont legendFont( labelFont );
00247     legendFont.setPointSize( labelFont.pointSize() + 2 );
00248     legendFont.setUnderline( true );
00249     //legendFont.setBold( true );
00250     text = new QGraphicsTextItem( QString( "Legend:" ), legend );
00251     //text->setPos( 0.0f, -( labelFont.pointSize() * 2 ) );
00252     text->setFont( legendFont );
00253 
00254     legendText.push_back( text );
00255 
00256     qreal legendWidth( 0 );
00257 
00258     int nodeId( 0 );
00259     foreach( SgNode *node, nodes )
00260     {
00261         SgLocatedNode *locNode = dynamic_cast<SgLocatedNode *>( node );
00262         if( locNode )
00263         {
00264             Sg_File_Info *fileInfo = locNode->get_file_info();
00265 
00266             text = new QGraphicsTextItem( QString( "%1@%2:%3" ).arg( getSgVariant( node->variantT() ).c_str() )
00267                                                                .arg( QFileInfo( fileInfo->get_filenameString().c_str() ).fileName() )
00268                                                                .arg( fileInfo->get_line() ), legend );
00269         }
00270         else
00271             text = new QGraphicsTextItem( node->class_name().c_str(), legend );
00272 
00273         text->setPos( 40.0f, nodeId * ( labelFont.pointSize() + labelFont.pointSize()*0.8 ) + 3 * legendFont.pointSize());
00274 
00275         if( nodeId == id )
00276         {
00277             //text->setDefaultTextColor( Qt::gray );
00278             text->setFont( highlightFont );
00279         }
00280         else
00281             text->setFont( labelFont );
00282 
00283         if( text->boundingRect().width() > legendWidth )
00284             legendWidth = text->boundingRect().width();
00285 
00286         legendText.push_back( text );
00287 
00288         QGraphicsRectItem *rect = new QGraphicsRectItem( QRectF( 0.0f, 0.0f, 25.0f, labelFont.pointSize() ), legend );
00289         rect->setPos( 10.0f, nodeId * ( labelFont.pointSize() + labelFont.pointSize()* 0.8 ) + 3.7 * legendFont.pointSize() );
00290         rect->setPen( QPen( Qt::NoPen ) );
00291         rect->setBrush( getDataColor( nodeId ) );
00292         legendColor.push_back( rect );
00293 
00294         nodeId++;
00295 
00296     }
00297     if( nodesId == -1 )
00298     {
00299         SgLocatedNode *locNode = isSgLocatedNode( astNode );
00300         if( locNode )
00301         {
00302             Sg_File_Info *fileInfo = locNode->get_file_info();
00303 
00304             text = new QGraphicsTextItem( QString( "%1@%2:%3" ).arg( getSgVariant( astNode->variantT() ).c_str() )
00305                                                                .arg( QFileInfo( fileInfo->get_filenameString().c_str() ).fileName() )
00306                                                                .arg( fileInfo->get_line() ), legend );
00307         }
00308         else
00309             text = new QGraphicsTextItem( astNode->class_name().c_str(), legend );
00310 
00311         text->setFont( highlightFont );
00312 
00313         text->setPos( 40.0f, nodeId * ( labelFont.pointSize() + labelFont.pointSize()*0.8 ) + 3 * legendFont.pointSize() );
00314         //text->setDefaultTextColor( Qt::gray );
00315 
00316         if( text->boundingRect().width() > legendWidth )
00317             legendWidth = text->boundingRect().width();
00318 
00319         QGraphicsRectItem *rect = new QGraphicsRectItem( QRectF( 0.0f, 0.0f, 25.0f, labelFont.pointSize() ), legend );
00320         rect->setPos( 10.0f, nodeId * ( labelFont.pointSize() + labelFont.pointSize()* 0.8 ) + 3.7 * legendFont.pointSize() );
00321         rect->setPen( QPen( Qt::NoPen ) );
00322         rect->setBrush( Qt::blue );
00323         legendColor.push_back( rect );
00324 
00325         legendText.push_back( text );
00326 
00327         nodeId++;
00328     }
00329 
00330     legend->setRect( QRectF( 0.0f, 0.0f, legendWidth + 60, nodeId * ( labelFont.pointSize() + labelFont.pointSize()* 0.8 ) + 3.7 * legendFont.pointSize() ) );
00331 
00332     scene.setSceneRect( QRectF() );
00333 
00334     resizeEvent( NULL );
00335     emit nodeActivated( astNode );
00336 }
00337 
00338 void MetricsKiviat::contextMenuEvent( QContextMenuEvent *ev)
00339 {
00340     QList<QAction *> actions;
00341 
00342     QObject *parent( new QObject() );
00343     QAction *configMetrics( new QAction( "configure Metrics" , parent ) );
00344 
00345     actions << configMetrics;
00346 
00347     QAction *res( QMenu::exec( actions, mapToGlobal( ev->pos() ) ) );
00348 
00349     if( res == configMetrics )
00350     {
00351         configureMetrics();
00352     }
00353     else
00354     {
00355         qDebug() << "Unknown action ...";
00356     }
00357     
00358     delete parent;
00359 }
00360 
00361 void MetricsKiviat::dropEvent( QDropEvent *ev )
00362 {
00363     if( ev->source()==this )
00364         return;
00365 
00366     SgNode *node( getGeneralNode( ev->mimeData() ) );
00367 
00368     addNode( node );
00369 }
00370 
00371 void MetricsKiviat::dragEnterEvent( QDragEnterEvent *ev )
00372 {
00373     if (ev->mimeData()->hasFormat(SG_NODE_MIMETYPE))
00374     {
00375         if( this != ev->source())
00376                 ev->accept();
00377     }
00378     else
00379         ev->ignore();
00380 }
00381 
00382 void MetricsKiviat::dragMoveEvent( QDragMoveEvent *ev )
00383 {
00384     QWidget::dragMoveEvent( ev );
00385 }

Generated on Tue Sep 15 14:48:47 2009 for RoseQtWidgets by  doxygen 1.4.7