Example #1
0
    def __createLayout( self ):
        " Helper to create the viewer layout "

        self.funcViewer = FunctionsBrowser()

        # Toolbar part - buttons
        self.definitionButton = QAction(
                PixmapCache().getIcon( 'definition.png' ),
                'Jump to highlighted item definition', self )
        self.definitionButton.triggered.connect( self.__goToDefinition )
        self.findButton = QAction(
                PixmapCache().getIcon( 'findusage.png' ),
                'Find highlighted item occurences', self )
        self.findButton.triggered.connect( self.__findWhereUsed )
        self.copyPathButton = QAction(
                PixmapCache().getIcon( 'copytoclipboard.png' ),
                'Copy path to clipboard', self )
        self.copyPathButton.triggered.connect( self.funcViewer.copyToClipboard )

        self.findNotUsedButton = QAction(
                PixmapCache().getIcon( 'notused.png' ),
                'Unused function analysis', self )
        self.findNotUsedButton.triggered.connect( self.__findNotUsed )
        self.findNotUsedButton.setEnabled( False )

        self.toolbar = QToolBar( self )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.TopToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedHeight( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )
        self.toolbar.addAction( self.definitionButton )
        self.toolbar.addAction( self.findButton )
        self.toolbar.addAction( self.copyPathButton )

        filterLabel = QLabel( "  Filter " )
        self.toolbar.addWidget( filterLabel )
        self.filterEdit = CDMComboBox( True, self.toolbar )
        self.filterEdit.setSizePolicy( QSizePolicy.Expanding,
                                       QSizePolicy.Expanding )
        self.filterEdit.lineEdit().setToolTip( "Space separated regular expressions" )
        self.toolbar.addWidget( self.filterEdit )
        self.toolbar.addAction( self.findNotUsedButton )
        self.filterEdit.editTextChanged.connect( self.__filterChanged )
        self.filterEdit.itemAdded.connect( self.__filterItemAdded )
        self.filterEdit.enterClicked.connect( self.__enterInFilter )

        layout = QVBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        layout.addWidget( self.toolbar )
        layout.addWidget( self.funcViewer )

        self.setLayout( layout )
        return
Example #2
0
class FunctionsViewer( QWidget ):
    """ The free functions (including nested) viewer widget """

    def __init__( self, parent = None ):
        QWidget.__init__( self, parent )

        self.filterEdit = None
        self.definitionButton = None
        self.findButton = None
        self.copyPathButton = None
        self.funcViewer = None
        self.__createLayout()

        # create the context menu
        self.__menu = QMenu( self )
        self.__jumpMenuItem = self.__menu.addAction(
                                PixmapCache().getIcon( 'definition.png' ),
                                'Jump to definition', self.__goToDefinition )
        self.__menu.addSeparator()
        self.__findMenuItem = self.__menu.addAction(
                                PixmapCache().getIcon( 'findusage.png' ),
                                'Find occurences', self.__findWhereUsed )
        self.__menu.addSeparator()
        self.__disasmMenuItem = self.__menu.addAction(
                                PixmapCache().getIcon( 'disasmmenu.png' ),
                                'Disassemble',
                                self.__onDisassemble )
        self.__menu.addSeparator()
        self.__copyMenuItem = self.__menu.addAction(
                                PixmapCache().getIcon( 'copytoclipboard.png' ),
                                'Copy path to clipboard',
                                self.funcViewer.copyToClipboard )
        self.funcViewer.setContextMenuPolicy( Qt.CustomContextMenu )
        self.funcViewer.customContextMenuRequested.connect(
                                                self.__handleShowContextMenu )

        GlobalData().project.projectChanged.connect( self.__onProjectChanged )
        self.connect( self.funcViewer, SIGNAL( "selectionChanged" ),
                      self.__selectionChanged )
        self.funcViewer.openingItem.connect( self.itemActivated )
        self.connect( self.funcViewer, SIGNAL( "modelFilesChanged" ),
                      self.modelFilesChanged )

        self.filterEdit.lineEdit().setFocus()
        self.__contextItem = None
        return

    def setTooltips( self, switchOn ):
        " Triggers showing python objects tooltips "
        self.funcViewer.model().sourceModel().setTooltips( switchOn )
        return

    def __createLayout( self ):
        " Helper to create the viewer layout "

        self.funcViewer = FunctionsBrowser()

        # Toolbar part - buttons
        self.definitionButton = QAction(
                PixmapCache().getIcon( 'definition.png' ),
                'Jump to highlighted item definition', self )
        self.definitionButton.triggered.connect( self.__goToDefinition )
        self.findButton = QAction(
                PixmapCache().getIcon( 'findusage.png' ),
                'Find highlighted item occurences', self )
        self.findButton.triggered.connect( self.__findWhereUsed )
        self.copyPathButton = QAction(
                PixmapCache().getIcon( 'copytoclipboard.png' ),
                'Copy path to clipboard', self )
        self.copyPathButton.triggered.connect( self.funcViewer.copyToClipboard )

        self.findNotUsedButton = QAction(
                PixmapCache().getIcon( 'notused.png' ),
                'Unused function analysis', self )
        self.findNotUsedButton.triggered.connect( self.__findNotUsed )
        self.findNotUsedButton.setEnabled( False )

        self.toolbar = QToolBar( self )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.TopToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedHeight( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )
        self.toolbar.addAction( self.definitionButton )
        self.toolbar.addAction( self.findButton )
        self.toolbar.addAction( self.copyPathButton )

        filterLabel = QLabel( "  Filter " )
        self.toolbar.addWidget( filterLabel )
        self.filterEdit = CDMComboBox( True, self.toolbar )
        self.filterEdit.setSizePolicy( QSizePolicy.Expanding,
                                       QSizePolicy.Expanding )
        self.filterEdit.lineEdit().setToolTip( "Space separated regular expressions" )
        self.toolbar.addWidget( self.filterEdit )
        self.toolbar.addAction( self.findNotUsedButton )
        self.filterEdit.editTextChanged.connect( self.__filterChanged )
        self.filterEdit.itemAdded.connect( self.__filterItemAdded )
        self.filterEdit.enterClicked.connect( self.__enterInFilter )

        layout = QVBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        layout.addWidget( self.toolbar )
        layout.addWidget( self.funcViewer )

        self.setLayout( layout )
        return

    def __filterChanged( self, text ):
        " Triggers when the filter text changed "
        self.funcViewer.setFilter( text )
        self.funcViewer.updateCounter()
        return

    def __selectionChanged( self, index ):
        " Handles the changed selection "
        if index is None:
            self.__contextItem = None
        else:
            self.__contextItem = self.funcViewer.model().item( index )

        self.__updateButtons()
        return

    def getItemCount( self ):
        " Provides the number of items in the model - total, not only visible "
        return self.funcViewer.model().sourceModel().rowCount()

    def itemActivated( self, path, line ):
        " Handles the item activation "
        self.filterEdit.addItem( self.filterEdit.lineEdit().text() )
        return

    def __filterItemAdded( self ):
        " The filter item has been added "
        project = GlobalData().project
        if project.fileName != "":
            project.setFindFuncHistory( self.filterEdit.getItems() )
        return

    def __enterInFilter( self ):
        " ENTER key has been clicked in the filter "

        # check if there any records displayed
        if self.funcViewer.model().rowCount() == 0:
            return

        # Move the focus to the list and select the first row
        self.funcViewer.clearSelection()
        flags = QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows
        self.funcViewer.setSelection( QRect( 0, 0, self.funcViewer.width(), 1 ),
                                      flags )
        self.funcViewer.setFocus()
        return

    def __onProjectChanged( self, what ):
        " Triggered when a project is changed "

        if what == CodimensionProject.CompleteProject:
            self.__contextItem = None
            self.__updateButtons()
            self.filterEdit.clear()

            project = GlobalData().project
            if project.isLoaded():
                self.filterEdit.editTextChanged.disconnect(
                                                        self.__filterChanged )
                self.filterEdit.addItems( project.findFuncHistory )
                self.filterEdit.editTextChanged.connect( self.__filterChanged )
                self.findNotUsedButton.setEnabled( self.getItemCount() > 0 )
            else:
                self.findNotUsedButton.setEnabled( False )
            self.filterEdit.clearEditText()
        return

    def __handleShowContextMenu( self, coord ):
        """ Show the context menu """

        index = self.funcViewer.indexAt( coord )
        if not index.isValid():
            return

        # This will update the __contextItem
        self.__selectionChanged( index )

        if self.__contextItem is None:
            return

        self.__jumpMenuItem.setEnabled( self.definitionButton.isEnabled() )
        self.__findMenuItem.setEnabled( self.findButton.isEnabled() )
        self.__copyMenuItem.setEnabled( self.copyPathButton.isEnabled() )

        canDisassemble = self.__contextItem.canGetDisassembler()
        self.__disasmMenuItem.setEnabled( canDisassemble )

        self.__menu.popup( QCursor.pos() )
        return

    def __goToDefinition( self ):
        " Jump to definition context menu handler "
        if self.__contextItem is not None:
            self.funcViewer.openItem( self.__contextItem )
        return

    def __findWhereUsed( self ):
        """ Find where used context menu handler """
        if self.__contextItem is not None:
            GlobalData().mainWindow.findWhereUsed( \
                    self.__contextItem.getPath(),
                    self.__contextItem.sourceObj )
        return

    def __findNotUsed( self ):
        " Runs the unused function analysis "
        GlobalData().mainWindow.onNotUsedFunctions()
        return

    def __updateButtons( self ):
        " Updates the toolbar buttons depending on what is selected "

        self.definitionButton.setEnabled( False )
        self.findButton.setEnabled( False )
        self.copyPathButton.setEnabled( False )
        if self.__contextItem is None:
            return

        if self.__contextItem.itemType == DecoratorItemType:
            self.definitionButton.setEnabled( True )
            self.copyPathButton.setEnabled( True )
            return

        if self.__contextItem.itemType in [ FunctionItemType, ClassItemType,
                                            AttributeItemType, GlobalItemType ]:
            self.definitionButton.setEnabled( True )
            self.findButton.setEnabled( True )
            self.copyPathButton.setEnabled( True )
        return

    def onFileUpdated( self, fileName, uuid ):
        " Triggered when the file is updated "
        self.funcViewer.onFileUpdated( fileName )
        self.findNotUsedButton.setEnabled( GlobalData().project.isLoaded() and \
                                           self.getItemCount() > 0 )
        return

    def modelFilesChanged( self ):
        " Triggered when the source model has a file or files added or deleted "
        self.findNotUsedButton.setEnabled( GlobalData().project.isLoaded() and \
                                           self.getItemCount() > 0 )
        return

    def __onDisassemble( self ):
        " Disassembling has been requested "
        if self.__contextItem is not None:
            self.funcViewer.getDisassembled( self.__contextItem )