AsmInstructionsBar.cpp

Go to the documentation of this file.
00001 
00002 #include "rose.h"
00003 
00004 #include <QMouseEvent>
00005 #include <QWheelEvent>
00006 #include <QGraphicsRectItem>
00007 #include <QGraphicsPolygonItem>
00008 #include <QPoint>
00009 #include <QPolygon>
00010 
00011 #include <iostream>
00012 #include <QDebug>
00013 
00014 #include "ItemModelHelper.h"
00015 #include "SgNodeUtil.h"
00016 #include "SageMimeData.h"
00017 
00018 #include "AsmInstructionsBar.h"
00019 
00020 #include <QSizePolicy>
00021 
00022 using namespace std;
00023 
00024 AsmInstructionsBar::AsmInstructionsBar( QWidget *parent )
00025    : QGraphicsView( parent ),
00026      indicatorBottom( NULL ),
00027      indicatorMiddle( NULL ),
00028      indicatorTop( NULL ),
00029      base_width( 20 ),
00030      height( base_width * 15 ),
00031      pressed( false )
00032 {
00033    setScene( &scene );
00034    //setDragMode( QGraphicsView::NoDrag );
00035    setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00036    setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00037 
00038    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
00039    setFixedHeight(base_width);
00040 
00041    setAcceptDrops( true );
00042    viewport()->setAcceptDrops( true );
00043 }
00044 
00045 AsmInstructionsBar::~AsmInstructionsBar()
00046 {}
00047 
00048 int AsmInstructionsBar::getNumberOfBlocks()
00049 {
00050     return blockList.size();
00051 }
00052 
00053 void AsmInstructionsBar::setRoot( SgNode *root_ )
00054 {
00055    cout << "setting up AsmInstructionsBar" << endl;
00056 
00057    if( isSourceNode( root_ ) ) return;
00058 
00059    qDeleteAll( blockList );
00060    blockList.clear();
00061 
00062    if( indicatorBottom )
00063    {
00064        delete indicatorBottom;
00065        indicatorBottom = NULL;
00066    }
00067    if( indicatorMiddle )
00068    {
00069        delete indicatorMiddle;
00070        indicatorMiddle = NULL;
00071    }
00072    if( indicatorTop )
00073    {
00074        delete indicatorTop;
00075        indicatorTop = NULL;
00076    }
00077 
00078    currentBlock = NULL;
00079 
00080    root = root_;
00081 
00082    if( !root ) return;
00083 
00084    typedef std::vector<SgAsmNode *>::const_iterator iterator;
00085 
00086    std::vector<SgAsmNode *> stmts;
00087 
00088    FindAsmStatementsHeaderVisitor visStat;
00089    AstQueryNamespace::querySubTree( root, std::bind2nd( visStat, &stmts ) );
00090 
00091    uint64_t offset( 0 );
00092    int id( 0 );
00093    for( iterator i = stmts.begin(); i != stmts.end(); ++i )
00094    {
00095        SgAsmNode *node( *i );
00096 
00097        uint64_t width( base_width );
00098        QPen   foreground( Qt::NoPen );
00099        QBrush background;
00100 
00101        if( isSgAsmBlock( node ) )
00102        {
00103            continue;
00104        }
00105        else if( isSgAsmFunctionDeclaration( node ) )
00106        {
00107            background = QBrush( QColor( 255, 216, 0 ) );
00108        }
00109        else if( isSgAsmInstruction( node ) )
00110        {
00111            SgAsmInstruction* instr( isSgAsmInstruction( node ) );
00112            background = QBrush( QColor( 128, 108, 0 ) );
00113 
00114            width *= instr->get_raw_bytes().size();
00115        }
00116        else if( isSgAsmElfSymbol( node ) )
00117        {
00118            background = QBrush( QColor( 0, 0, 255 ) );
00119        }
00120        else if( isSgAsmElfSection( node ) )
00121        {
00122            background = QBrush( QColor( 0, 132, 255 ) );
00123        }
00124        else if( isSgAsmElfSectionTableEntry( node ) )
00125        {
00126            background = QBrush( QColor( 0, 66, 128 ) );
00127        }
00128        else if( isSgAsmElfSegmentTableEntry( node ) )
00129        {
00130            background = QBrush( QColor( 64, 97, 128 ) );
00131        }
00132        else
00133        {
00134            // not interested in that node type ...
00135            continue;
00136        }
00137 
00138        blockList.push_back(
00139            scene.addRect( static_cast<float>( offset ), 0.0f,
00140                           static_cast<float>( width ) , height,
00141                           foreground, background )
00142            );
00143        blockList.back()->setData( SgNodeRole , QVariant::fromValue<SgNode *>( node ) );
00144        blockList.back()->setData( Qt::UserRole , id );
00145 
00146        offset += width;
00147        ++id;
00148    }
00149 
00150    currentBlock = blockList[0];
00151 
00152    if( indicatorMiddle )
00153         indicatorMiddle->scale( 0.1f, 0.1f );
00154 
00155     foreach( QGraphicsRectItem *block, blockList )
00156     {
00157         block->scale( 0.1f, 0.1f );
00158     }
00159 
00160    setIndicator();
00161 
00162 
00163    cout << "end setup AsmInstructionsBar" << endl;
00164 }
00165 
00166 void AsmInstructionsBar::setNode( SgNode *node )
00167 {
00168     if( isSourceNode( node ) )
00169     {
00170         SgNodeVector binaryNodes( getLinkedBinaryNodes( node ) );
00171         SgNodeVector::iterator i( binaryNodes.begin() );
00172         for( ; i != binaryNodes.end(); ++i )
00173         {
00174             if( isAncestor( root, *i ) )
00175             {
00176                 node = *i;
00177                 break;
00178             }
00179         }
00180         if( i == binaryNodes.end() ) return;
00181     }
00182 
00183     int id( 0 );
00184     foreach( QGraphicsRectItem *block, blockList )
00185     {
00186         SgNode *tmp = qvariant_cast<SgNode *>( block->data( SgNodeRole ) );
00187 
00188         if( tmp == node )
00189         {
00190             currentBlock = block;
00191             setIndicator();
00192 
00193             emit nodeActivated( node );
00194             emit clicked( id );
00195             return;
00196         }
00197         ++id;
00198     }
00199 }
00200 
00201 void AsmInstructionsBar::setNode( int id )
00202 {
00203     if( id < 0 || id >= blockList.size() )
00204         return;
00205 
00206     currentBlock = blockList[id];
00207     setIndicator();
00208 
00209     emit nodeActivated( qvariant_cast<SgNode *>( currentBlock->data( SgNodeRole ) ) );
00210     emit clicked( id );
00211 }
00212 
00213 void AsmInstructionsBar::setIndicator()
00214 {
00215    const float currentWidth( currentBlock->rect().width() );
00216    const float currentX    ( currentBlock->rect().x() );
00217 
00218    if( indicatorBottom )
00219    {
00220        delete indicatorBottom;
00221        indicatorBottom = NULL;
00222    }
00223    if( indicatorMiddle )
00224    {
00225        delete indicatorMiddle;
00226        indicatorMiddle = NULL;
00227    }
00228    if( indicatorTop )
00229    {
00230        delete indicatorTop;
00231         indicatorTop = NULL;
00232    }
00233 
00234    QPolygonF Bottom;
00235    QPolygonF Top;
00236 
00237    Top    << QPointF( -5.0f, -10.0f )
00238           << QPointF(  5.0f, -10.0f )
00239           << QPointF(  0.0f,  0.0f  );
00240 
00241    Bottom << QPointF( -5.0f,   0.0f )
00242           << QPointF(  5.0f,   0.0f )
00243           << QPointF(  0.0f, -10.0f );
00244 
00245    indicatorBottom = scene.addPolygon( Bottom, QPen(), QBrush( QColor( 0, 0, 0 ) ) );
00246 
00247    QPen indPen( QBrush( Qt::gray ), 2.0f );
00248    indPen.setCosmetic( true );
00249    indicatorMiddle = scene.addRect   ( currentX, 0.0f,
00250                                        currentWidth, height,
00251                                        indPen,
00252                                        QBrush( QColor( 255, 255, 255, 150 ) ) );
00253 
00254    indicatorTop    = scene.addPolygon( Top   , QPen(), QBrush( QColor( 0, 0, 0 ) ) );
00255 
00256 
00257    QPointF pos( indicatorBottom->mapFromItem( currentBlock, QPointF( currentX, 0.0f ) ) );
00258 
00259    //indicatorBottom->setTransform( currentBlock->transform() );
00260    indicatorMiddle->setTransform( currentBlock->transform() );
00261 
00262    QPointF posLeft ( indicatorBottom->mapFromItem( indicatorMiddle, indicatorMiddle->rect().bottomLeft() ) );
00263    QPointF posRight( indicatorBottom->mapFromItem( indicatorMiddle, indicatorMiddle->rect().bottomRight() ) );
00264    QPointF top     ( indicatorBottom->mapFromItem( indicatorMiddle, indicatorMiddle->rect().topLeft() ) );
00265 
00266    float width( ( posRight.x() - posLeft.x() ) * 0.5 );
00267    float currentHeight( ( posLeft.y() - top.y() ) );
00268 
00269    QPointF center( posLeft.x() + width, currentHeight * 0.5 );
00270 
00271    indicatorBottom->setPos( center.x(), currentHeight +10.0f );//currentX + ( currentWidth * 0.5f ), height+10.0f );
00272    indicatorTop->setPos   ( center.x(), 0.0f );//trans   ( currentX + ( currentWidth * 0.5f ), 0.0f );
00273    centerOn( center );
00274 
00275 
00276    centerOn( center );
00277 }
00278 
00279 /*void AsmInstructionsBar::resizeEvent( QResizeEvent * ev)
00280 {
00281    QGraphicsView::resizeEvent( ev );
00282 }*/
00283 
00284 void AsmInstructionsBar::mousePressEvent( QMouseEvent *e )
00285 {
00286     switch( e->button() )
00287     {
00288         case Qt::LeftButton:
00289             updatePosition( e->pos() );
00290             pressed = true;
00291             break;
00292         default:
00293             break;
00294     }
00295 
00296 }
00297 
00298 void AsmInstructionsBar::mouseReleaseEvent( QMouseEvent *e )
00299 {
00300     switch( e->button() )
00301     {
00302         case Qt::LeftButton:
00303             updatePosition( e->pos() );
00304             pressed = false;
00305             break;
00306         default:
00307             break;
00308     }
00309 
00310 }
00311 void AsmInstructionsBar::mouseMoveEvent( QMouseEvent *e )
00312 {
00313     if( pressed )
00314     {
00315         updatePosition( e->pos() );
00316     }
00317 
00318     QGraphicsView::mouseMoveEvent( e );
00319 }
00320 
00321 void AsmInstructionsBar::updatePosition( const QPoint& pos )
00322 {
00323     QGraphicsRectItem *clickedBlock;
00324 
00325     clickedBlock =
00326             dynamic_cast<QGraphicsRectItem *>( itemAt( pos ) );
00327 
00328     if( clickedBlock == NULL ) return;
00329     if( clickedBlock == indicatorMiddle ) return;
00330 
00331     currentBlock = clickedBlock;
00332     setIndicator();
00333 
00334     SgNode *node = qvariant_cast<SgNode *>( clickedBlock->data( SgNodeRole ) );
00335     int id = clickedBlock->data( Qt::UserRole ).toInt();
00336 
00337     emit nodeActivated( node );
00338     emit clicked( id );
00339 }
00340 
00341 void AsmInstructionsBar::wheelEvent( QWheelEvent *e )
00342 {
00343     float scaleFactor( 1.0f );
00344 
00345     if( e->delta() > 0 )
00346     {
00347         // zoom in
00348         scaleFactor = 1.2f ;
00349     }
00350     else
00351     {
00352         // zoom out
00353         scaleFactor = 0.8f ;
00354     }
00355 
00356     if( indicatorMiddle )
00357         indicatorMiddle->scale( scaleFactor, 1.0f );
00358 
00359     foreach( QGraphicsRectItem *block, blockList )
00360     {
00361         block->scale( scaleFactor, 1.0f );
00362     }
00363 
00364     setIndicator();
00365 }
00366 
00367 void AsmInstructionsBar::dropEvent( QDropEvent *ev )
00368 {
00369     if( ev->source()==this )
00370         return;
00371 
00372     SgNodeVector binNodes( getBinaryNodes( ev->mimeData() ) );
00373 
00374     if( binNodes.size() == 1 )
00375     {
00376         setRoot( binNodes[0] );
00377         return;
00378     }
00379 }
00380 
00381 void AsmInstructionsBar::dragEnterEvent( QDragEnterEvent *ev )
00382 {
00383     if (ev->mimeData()->hasFormat(SG_NODE_BINARY_MIMETYPE))
00384     {
00385         if( this != ev->source())
00386                 ev->accept();
00387     }
00388     else
00389         ev->ignore();
00390 }
00391 
00392 void AsmInstructionsBar::dragMoveEvent( QDragMoveEvent *ev )
00393 {
00394     QWidget::dragMoveEvent( ev );
00395     /*QGraphicsView::dragMoveEvent( ev );
00396 
00397     if (ev->mimeData()->hasFormat(SG_NODE_MIMETYPE))
00398     {
00399         if( this != ev->source())
00400         {
00401             QByteArray d = ev->mimeData()->data(SG_NODE_MIMETYPE);
00402             QDataStream s (d);
00403 
00404             SgNode * node = 0;
00405 
00406             int bytesRead = s.readRawData((char*)&node,sizeof(SgNode*));
00407             Q_ASSERT( bytesRead == sizeof(SgNode*));
00408             Q_ASSERT( s.atEnd() );
00409 
00410             if( isBinaryNode( node ) )
00411                 ev->accept();
00412             else
00413                 ev->ignore();
00414         }
00415     }*/
00416 }

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