SrcBinView.cpp

Go to the documentation of this file.
00001 
00002 #include "rose.h"
00003 
00004 #include <iostream>
00005 
00006 #include <QMenu>
00007 #include <QAction>
00008 #include <QDropEvent>
00009 #include <QDragMoveEvent>
00010 #include <QDragEnterEvent>
00011 
00012 #include <QDebug>
00013 
00014 #include "SgNodeUtil.h"
00015 #include "SageMimeData.h"
00016 #include "AsmToSourceMapper.h"
00017 
00018 #include "SrcBinView.h"
00019 #include "ui_SrcBinView.h"
00020 
00021 using namespace std;
00022 
00023 SrcBinView::SrcBinView( QWidget *parent )
00024     : srcBinView( new Ui::SrcBinView() ),
00025       binFile( NULL ),
00026       srcFile( NULL )
00027 {
00028     srcBinView->setupUi( this );
00029 
00030     /*for( int i( 0 ); i < project->numberOfFiles(); ++i )
00031     {
00032         SgFile *file( (*project)[i] );
00033         SgBinaryFile *binFiletmp( isSgBinaryFile( file ) );
00034         SgSourceFile *srcFiletmp( isSgSourceFile( file ) );
00035         
00036         if( binFiletmp )
00037             binFile = binFiletmp;
00038         if( srcFiletmp )
00039             srcFile = srcFiletmp;
00040     }
00041 
00042     AsmToSourceMapper map( binFile );
00043     map.annotate( srcFile );
00044 
00045     srcBinView->roseCodeEdit->setNode( srcFile );
00046     srcBinView->asmView->setNode( binFile );*/
00047 
00048     srcBinView->asmView->installEventFilter( this );
00049     srcBinView->asmView->viewport()->installEventFilter( this );
00050     srcBinView->roseCodeEdit->installEventFilter( this );
00051     srcBinView->roseCodeEdit->viewport()->installEventFilter( this );
00052 
00053     connect( srcBinView->asmView         , SIGNAL( nodeActivated( SgNode * ) ),
00054              this                        , SLOT  ( setBinaryNode( SgNode * ) ) );
00055     connect( srcBinView->roseCodeEdit    , SIGNAL( cursorPositionChanged() ),
00056              this                        , SLOT  ( getCursorPosition() ) );
00057 }
00058 
00059 SrcBinView::~SrcBinView()
00060 {}
00061 
00062 void SrcBinView::setSourceNode( SgNode *node, bool setCodeEdit )
00063 {
00064     typedef AstAttributeMechanism::iterator iterator;
00065 
00066     AstAttributeMechanism *attributes( node->get_attributeMechanism() );
00067 
00068     if( attributes )
00069     {
00070         for( iterator it( attributes->begin() ); it != attributes->end(); ++it )
00071         {
00072             AstBinaryNodeLink *nodeLink( dynamic_cast<AstBinaryNodeLink *>( it->second ) );
00073 
00074             if( nodeLink == NULL ) continue;
00075 
00076             if( nodeLink->size() == 1 )
00077             {
00078                 srcBinView->asmView->gotoNode( nodeLink->at( 0 ).first );
00079             }
00080         }
00081     }
00082 
00083     if( setCodeEdit )
00084         srcBinView->roseCodeEdit->setNode( node );
00085 }
00086 
00087 void SrcBinView::setBinaryNode( SgNode *node )
00088 {
00089     typedef AstAttributeMechanism::iterator iterator;
00090 
00091     AstAttributeMechanism *attributes( node->get_attributeMechanism() );
00092 
00093     if( attributes )
00094     {
00095         for( iterator it( attributes->begin() ); it != attributes->end(); ++it )
00096         {
00097             AstSourceNodeLink *nodeLink( dynamic_cast<AstSourceNodeLink *>( it->second ) );
00098 
00099             if( nodeLink == NULL ) continue;
00100 
00101             if( nodeLink->size() == 1 )
00102             {
00103                 srcBinView->roseCodeEdit->setNode( nodeLink->at( 0 ).first );
00104             }
00105             else
00106             {
00107                 for( vector<pair<SgNode *, SgNode *> >::iterator jt( nodeLink->begin() );
00108                      jt != nodeLink->end();
00109                      ++jt )
00110                 {
00111                     if( isSgBasicBlock( jt->first ) ) continue;
00112 
00113                     srcBinView->roseCodeEdit->setNode( jt->first );
00114                     break;
00115                 }    
00116             }
00117         }
00118     }
00119 
00120     srcBinView->asmView->gotoNode( node );
00121 }
00122 
00123 void SrcBinView::getCursorPosition()
00124 {
00125     const QDocumentCursor &cursor( srcBinView->roseCodeEdit->cursor() );
00126     int line( cursor.lineNumber() + 1 );
00127     int col( cursor.columnNumber() + 1 );
00128 
00129     SourceRange range_start;
00130     SourceRange range_end;
00131     //range.line_start = line+1;
00132     range_start.start.first = line;
00133     range_start.start.second = 0;
00134     range_end.start.first = line;
00135     range_end.start.second = srcBinView->roseCodeEdit->text( line - 1 ).length();
00136 
00137     multimap<SourceRange,SgNode *>::iterator begin( 
00138             lineColToSgNode.upper_bound( range_start ) );
00139     multimap<SourceRange,SgNode *>::iterator end( 
00140             lineColToSgNode.upper_bound( range_end ) );
00141 
00142     if( end != lineColToSgNode.end() ) ++end;
00143     //if( begin != lineColToSgNode.begin() ) --begin;
00144 
00145     if( begin != lineColToSgNode.end() )
00146     {
00147         for( multimap<SourceRange,SgNode *>::iterator it( begin ); it != end; ++it )
00148         {
00149             if( line >= it->first.start.first &&
00150                 line <= it->first.end.first &&
00151                 col  >= it->first.start.second &&
00152                 col  <= it->first.end.second )
00153             {
00154                 setSourceNode( it->second, false );
00155                 return;
00156             }
00157         }
00158 
00159         setSourceNode( begin->second, false );
00160     }
00161 }
00162 
00163 void SrcBinView::fillMap( SgNode *node )
00164 {
00165     if( node == NULL ) return;
00166 
00167     for( size_t idx( 0 ); idx < node->get_numberOfTraversalSuccessors(); ++idx )
00168     {
00169         fillMap( node->get_traversalSuccessorByIndex( idx ) );
00170     }
00171 
00172     if( isSgLocatedNode( node ) )
00173     {
00174         SourceRange range;
00175         
00176         range.start.first = node->get_startOfConstruct()->get_line();
00177         range.start.second = node->get_startOfConstruct()->get_col();
00178         range.end.first = node->get_endOfConstruct()->get_line();
00179         range.end.second = node->get_endOfConstruct()->get_col();
00180         
00181         lineColToSgNode.insert( make_pair( range, node ) );
00182     }
00183 }
00184 
00185 bool SrcBinView::eventFilter( QObject *object, QEvent *event )
00186 {
00187     if( object == srcBinView->asmView ||
00188         object == srcBinView->asmView->viewport() ||
00189         object == srcBinView->roseCodeEdit ||
00190         object == srcBinView->roseCodeEdit->viewport() )
00191     {
00192         if( event->type() == QEvent::Drop )
00193         {
00194             dropEvent( static_cast<QDropEvent *>( event ) );
00195             return true;
00196         }
00197         if( event->type() == QEvent::DragEnter )
00198         {
00199             dragEnterEvent( static_cast<QDragEnterEvent *>( event ) );
00200             return true;
00201         }
00202         if( event->type() == QEvent::DragMove )
00203         {
00204             dragMoveEvent( static_cast<QDragMoveEvent *>( event ) );
00205             return true;
00206         }
00207     }
00208     return false;
00209 }
00210 
00211 void SrcBinView::dropEvent( QDropEvent *ev )
00212 {
00213     if( ev->source()==this )
00214         return;
00215 
00216     SgNodeVector srcNodes( getSourceNodes( ev->mimeData() ) );
00217     SgNodeVector binNodes( getBinaryNodes( ev->mimeData() ) );
00218 
00219     
00220 
00221     /*QMenu *ctxMenu( new QMenu() );
00222 
00223     QMenu *srcMenu( ctxMenu->addMenu( "Source Node" ) );
00224     QMenu *binMenu( ctxMenu->addMenu( "Binary Node" ) );
00225 
00226     QActionGroup *srcGroup( new QActionGroup(ctxMenu) );
00227     QActionGroup *binGroup( new QActionGroup(ctxMenu) );
00228 
00229     for( SgNodeVector::const_iterator it( srcNodes.begin() );
00230          it != srcNodes.end();
00231          ++it )
00232     {
00233         QAction *tmp( srcGroup->addAction( (*it)->class_name().c_str() ) );
00234 
00235         tmp->setCheckable( true );
00236 
00237         tmp->setChecked( true );
00238 
00239         ctxMenu->addAction( tmp );
00240     }
00241     srcGroup->setExclusive( true );
00242 
00243     for( SgNodeVector::const_iterator it( binNodes.begin() );
00244          it != binNodes.end();
00245          ++it )
00246     {
00247         QAction *tmp( binGroup->addAction( (*it)->class_name().c_str() ) );
00248         
00249         tmp->setCheckable( true );
00250         
00251         tmp->setChecked( true );
00252 
00253         ctxMenu->addAction( tmp );
00254     }
00255     binGroup->setExclusive( true );
00256 
00257     ctxMenu->exec( mapToGlobal( ev->pos() ) );
00258 
00259     delete ctxMenu;*/
00260 
00261     srcFile = dynamic_cast<SgSourceFile *>( getSgFile( srcNodes.at( 0 ) ) );
00262     binFile = dynamic_cast<SgBinaryFile *>( getSgFile( binNodes.at( 0 ) ) );
00263     
00264     AsmToSourceMapper map( binFile );
00265     map.annotate( srcFile );
00266 
00267     srcBinView->roseCodeEdit->setNode( srcFile );
00268     srcBinView->asmView->setNode( binFile );
00269     
00270     fillMap( srcFile );
00271 }
00272 
00273 void SrcBinView::dragMoveEvent( QDragMoveEvent *ev )
00274 {
00275     QWidget::dragMoveEvent( ev );
00276 }
00277 
00278 void SrcBinView::dragEnterEvent( QDragEnterEvent *ev )
00279 {
00280     if ( ev->mimeData()->hasFormat( SG_NODE_SOURCE_MIMETYPE ) &&
00281          ev->mimeData()->hasFormat( SG_NODE_BINARY_MIMETYPE ) )
00282     {
00283         if( this != ev->source() )
00284         {
00285             ev->accept();
00286         }
00287     }
00288     else
00289         ev->ignore();
00290 }

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